darwin.md revision 1.10 1 /* Machine description patterns for PowerPC running Darwin (Mac OS X).
2 Copyright (C) 2004-2019 Free Software Foundation, Inc.
3 Contributed by Apple Computer Inc.
4
5 This file is part of GCC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>. */
20
21 (define_insn "adddi3_high"
22 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
23 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b")
24 (high:DI (match_operand 2 "" ""))))]
25 "TARGET_MACHO && TARGET_64BIT"
26 "addis %0,%1,ha16(%2)")
27
28 (define_insn "movdf_low_si"
29 [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
30 (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
31 (match_operand 2 "" ""))))]
32 "TARGET_MACHO && TARGET_HARD_FLOAT && !TARGET_64BIT"
33 {
34 switch (which_alternative)
35 {
36 case 0:
37 return "lfd %0,lo16(%2)(%1)";
38 case 1:
39 {
40 if (TARGET_POWERPC64 && TARGET_32BIT)
41 /* Note, old assemblers didn't support relocation here. */
42 return "ld %0,lo16(%2)(%1)";
43 else
44 {
45 output_asm_insn ("la %0,lo16(%2)(%1)", operands);
46 output_asm_insn ("lwz %L0,4(%0)", operands);
47 return ("lwz %0,0(%0)");
48 }
49 }
50 default:
51 gcc_unreachable ();
52 }
53 }
54 [(set_attr "type" "load")
55 (set_attr "length" "4,12")])
56
57
58 (define_insn "movdf_low_di"
59 [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
60 (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
61 (match_operand 2 "" ""))))]
62 "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
63 "@
64 lfd %0,lo16(%2)(%1)
65 ld %0,lo16(%2)(%1)"
66 [(set_attr "type" "load")])
67
68 (define_insn "movdf_low_st_si"
69 [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
70 (match_operand 2 "" "")))
71 (match_operand:DF 0 "gpc_reg_operand" "f"))]
72 "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
73 "stfd %0,lo16(%2)(%1)"
74 [(set_attr "type" "store")])
75
76 (define_insn "movdf_low_st_di"
77 [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
78 (match_operand 2 "" "")))
79 (match_operand:DF 0 "gpc_reg_operand" "f"))]
80 "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
81 "stfd %0,lo16(%2)(%1)"
82 [(set_attr "type" "store")])
83
84 (define_insn "movsf_low_si"
85 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
86 (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
87 (match_operand 2 "" ""))))]
88 "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
89 "@
90 lfs %0,lo16(%2)(%1)
91 lwz %0,lo16(%2)(%1)"
92 [(set_attr "type" "load")])
93
94 (define_insn "movsf_low_di"
95 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
96 (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
97 (match_operand 2 "" ""))))]
98 "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
99 "@
100 lfs %0,lo16(%2)(%1)
101 lwz %0,lo16(%2)(%1)"
102 [(set_attr "type" "load")])
103
104 (define_insn "movsf_low_st_si"
105 [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
106 (match_operand 2 "" "")))
107 (match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
108 "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
109 "@
110 stfs %0,lo16(%2)(%1)
111 stw %0,lo16(%2)(%1)"
112 [(set_attr "type" "store")])
113
114 (define_insn "movsf_low_st_di"
115 [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
116 (match_operand 2 "" "")))
117 (match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
118 "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
119 "@
120 stfs %0,lo16(%2)(%1)
121 stw %0,lo16(%2)(%1)"
122 [(set_attr "type" "store")])
123
124 ;; 64-bit MachO load/store support
125
126 ;; Mach-O PIC trickery.
127 (define_expand "macho_high"
128 [(set (match_operand 0 "")
129 (high (match_operand 1 "")))]
130 "TARGET_MACHO"
131 {
132 if (TARGET_64BIT)
133 emit_insn (gen_macho_high_di (operands[0], operands[1]));
134 else
135 emit_insn (gen_macho_high_si (operands[0], operands[1]));
136
137 DONE;
138 })
139
140 (define_insn "macho_high_si"
141 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
142 (high:SI (match_operand 1 "" "")))]
143 "TARGET_MACHO && ! TARGET_64BIT"
144 "lis %0,ha16(%1)")
145
146
147 (define_insn "macho_high_di"
148 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
149 (high:DI (match_operand 1 "" "")))]
150 "TARGET_MACHO && TARGET_64BIT"
151 "lis %0,ha16(%1)")
152
153 (define_expand "macho_low"
154 [(set (match_operand 0 "")
155 (lo_sum (match_operand 1 "")
156 (match_operand 2 "")))]
157 "TARGET_MACHO"
158 {
159 if (TARGET_64BIT)
160 emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2]));
161 else
162 emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2]));
163
164 DONE;
165 })
166
167 (define_insn "macho_low_si"
168 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
169 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
170 (match_operand 2 "" "")))]
171 "TARGET_MACHO && ! TARGET_64BIT"
172 "la %0,lo16(%2)(%1)")
173
174 (define_insn "macho_low_di"
175 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
176 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
177 (match_operand 2 "" "")))]
178 "TARGET_MACHO && TARGET_64BIT"
179 "la %0,lo16(%2)(%1)")
180
181 (define_split
182 [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand")
183 (match_operand:DI 1 "short_cint_operand")))
184 (match_operand:V4SI 2 "register_operand"))
185 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
186 "TARGET_MACHO && TARGET_64BIT"
187 [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1)))
188 (set (mem:V4SI (match_dup 3))
189 (match_dup 2))]
190 "")
191
192 (define_expand "load_macho_picbase"
193 [(set (reg:SI LR_REGNO)
194 (unspec [(match_operand 0 "")]
195 UNSPEC_LD_MPIC))]
196 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
197 {
198 if (TARGET_32BIT)
199 emit_insn (gen_load_macho_picbase_si (operands[0]));
200 else
201 emit_insn (gen_load_macho_picbase_di (operands[0]));
202
203 DONE;
204 })
205
206 (define_insn "load_macho_picbase_si"
207 [(set (reg:SI LR_REGNO)
208 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
209 (pc)] UNSPEC_LD_MPIC))]
210 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
211 {
212 #if TARGET_MACHO
213 machopic_should_output_picbase_label (); /* Update for new func. */
214 #else
215 gcc_unreachable ();
216 #endif
217 return "bcl 20,31,%0\n%0:";
218 }
219 [(set_attr "type" "branch")
220 (set_attr "cannot_copy" "yes")])
221
222 (define_insn "load_macho_picbase_di"
223 [(set (reg:DI LR_REGNO)
224 (unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
225 (pc)] UNSPEC_LD_MPIC))]
226 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
227 {
228 #if TARGET_MACHO
229 machopic_should_output_picbase_label (); /* Update for new func. */
230 #else
231 gcc_unreachable ();
232 #endif
233 return "bcl 20,31,%0\n%0:";
234 }
235 [(set_attr "type" "branch")
236 (set_attr "cannot_copy" "yes")])
237
238 (define_expand "macho_correct_pic"
239 [(set (match_operand 0 "")
240 (plus (match_operand 1 "")
241 (unspec [(match_operand 2 "")
242 (match_operand 3 "")]
243 UNSPEC_MPIC_CORRECT)))]
244 "DEFAULT_ABI == ABI_DARWIN"
245 {
246 if (TARGET_32BIT)
247 emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2],
248 operands[3]));
249 else
250 emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2],
251 operands[3]));
252
253 DONE;
254 })
255
256 (define_insn "macho_correct_pic_si"
257 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
258 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
259 (unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
260 (match_operand:SI 3 "immediate_operand" "s")]
261 UNSPEC_MPIC_CORRECT)))]
262 "DEFAULT_ABI == ABI_DARWIN"
263 "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
264 [(set_attr "length" "8")])
265
266 (define_insn "macho_correct_pic_di"
267 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
268 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
269 (unspec:DI [(match_operand:DI 2 "immediate_operand" "s")
270 (match_operand:DI 3 "immediate_operand" "s")]
271 16)))]
272 "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
273 "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
274 [(set_attr "length" "8")])
275
276 (define_expand "reload_macho_picbase"
277 [(set (reg:SI LR_REGNO)
278 (unspec [(match_operand 0 "")]
279 UNSPEC_RELD_MPIC))]
280 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
281 {
282 if (TARGET_32BIT)
283 emit_insn (gen_reload_macho_picbase_si (operands[0]));
284 else
285 emit_insn (gen_reload_macho_picbase_di (operands[0]));
286
287 DONE;
288 })
289
290 (define_insn "reload_macho_picbase_si"
291 [(set (reg:SI LR_REGNO)
292 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
293 (pc)] UNSPEC_RELD_MPIC))]
294 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
295 {
296 #if TARGET_MACHO
297 if (machopic_should_output_picbase_label ())
298 {
299 static char tmp[64];
300 const char *cnam = machopic_get_function_picbase ();
301 snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam);
302 return tmp;
303 }
304 else
305 #else
306 gcc_unreachable ();
307 #endif
308 return "bcl 20,31,%0\n%0:";
309 }
310 [(set_attr "type" "branch")
311 (set_attr "cannot_copy" "yes")])
312
313 (define_insn "reload_macho_picbase_di"
314 [(set (reg:DI LR_REGNO)
315 (unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
316 (pc)] UNSPEC_RELD_MPIC))]
317 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
318 {
319 #if TARGET_MACHO
320 if (machopic_should_output_picbase_label ())
321 {
322 static char tmp[64];
323 const char *cnam = machopic_get_function_picbase ();
324 snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam);
325 return tmp;
326 }
327 else
328 #else
329 gcc_unreachable ();
330 #endif
331 return "bcl 20,31,%0\n%0:";
332 }
333 [(set_attr "type" "branch")
334 (set_attr "cannot_copy" "yes")])
335
336 ;; We need to restore the PIC register, at the site of nonlocal label.
337
338 (define_insn_and_split "nonlocal_goto_receiver"
339 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
340 "TARGET_MACHO && flag_pic"
341 "#"
342 "&& reload_completed"
343 [(const_int 0)]
344 {
345 #if TARGET_MACHO
346 if (crtl->uses_pic_offset_table)
347 {
348 static unsigned n = 0;
349 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
350 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
351 rtx tmplrtx;
352 char tmplab[20];
353
354 ASM_GENERATE_INTERNAL_LABEL(tmplab, "Lnlgr", ++n);
355 tmplrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
356
357 emit_insn (gen_reload_macho_picbase (tmplrtx));
358 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
359 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplrtx));
360 }
361 else
362 /* Not using PIC reg, no reload needed. */
363 emit_note (NOTE_INSN_DELETED);
364 #else
365 gcc_unreachable ();
366 #endif
367 DONE;
368 })
369