]>
Commit | Line | Data |
---|---|---|
49bd1d27 | 1 | /* Machine description patterns for PowerPC running Darwin (Mac OS X). |
a5544970 | 2 | Copyright (C) 2004-2019 Free Software Foundation, Inc. |
49bd1d27 SS |
3 | Contributed by Apple Computer Inc. |
4 | ||
713e31f4 | 5 | This file is part of GCC. |
49bd1d27 SS |
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 | |
2f83c7d6 | 9 | the Free Software Foundation; either version 3, or (at your option) |
49bd1d27 SS |
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 | |
2f83c7d6 NC |
18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. */ | |
49bd1d27 SS |
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" | |
b24a46be | 26 | "addis %0,%1,ha16(%2)") |
49bd1d27 | 27 | |
b8a55285 | 28 | (define_insn "movdf_low_si" |
c5dce79b | 29 | [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") |
b8a55285 AP |
30 | (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") |
31 | (match_operand 2 "" ""))))] | |
11d8d07e | 32 | "TARGET_MACHO && TARGET_HARD_FLOAT && !TARGET_64BIT" |
b8a55285 AP |
33 | { |
34 | switch (which_alternative) | |
35 | { | |
36 | case 0: | |
6c332313 | 37 | return "lfd %0,lo16(%2)(%1)"; |
b8a55285 AP |
38 | case 1: |
39 | { | |
b8a55285 AP |
40 | if (TARGET_POWERPC64 && TARGET_32BIT) |
41 | /* Note, old assemblers didn't support relocation here. */ | |
6c332313 | 42 | return "ld %0,lo16(%2)(%1)"; |
b8a55285 | 43 | else |
af8e8908 | 44 | { |
6c332313 SB |
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)"); | |
af8e8908 | 48 | } |
b8a55285 AP |
49 | } |
50 | default: | |
992d08b1 | 51 | gcc_unreachable (); |
b8a55285 | 52 | } |
6c332313 | 53 | } |
b8a55285 AP |
54 | [(set_attr "type" "load") |
55 | (set_attr "length" "4,12")]) | |
56 | ||
57 | ||
49bd1d27 SS |
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 "" ""))))] | |
11d8d07e | 62 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
07a38de7 SB |
63 | "@ |
64 | lfd %0,lo16(%2)(%1) | |
65 | ld %0,lo16(%2)(%1)" | |
b24a46be | 66 | [(set_attr "type" "load")]) |
49bd1d27 | 67 | |
b8a55285 AP |
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"))] | |
11d8d07e | 72 | "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" |
b8a55285 | 73 | "stfd %0,lo16(%2)(%1)" |
b24a46be | 74 | [(set_attr "type" "store")]) |
b8a55285 | 75 | |
49bd1d27 SS |
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"))] | |
11d8d07e | 80 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
49bd1d27 | 81 | "stfd %0,lo16(%2)(%1)" |
b24a46be | 82 | [(set_attr "type" "store")]) |
49bd1d27 | 83 | |
b8a55285 AP |
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 "" ""))))] | |
11d8d07e | 88 | "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" |
b8a55285 AP |
89 | "@ |
90 | lfs %0,lo16(%2)(%1) | |
6b39bc38 | 91 | lwz %0,lo16(%2)(%1)" |
b24a46be | 92 | [(set_attr "type" "load")]) |
b8a55285 | 93 | |
49bd1d27 SS |
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 "" ""))))] | |
11d8d07e | 98 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
49bd1d27 SS |
99 | "@ |
100 | lfs %0,lo16(%2)(%1) | |
6b39bc38 | 101 | lwz %0,lo16(%2)(%1)" |
b24a46be | 102 | [(set_attr "type" "load")]) |
49bd1d27 | 103 | |
b8a55285 AP |
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"))] | |
11d8d07e | 108 | "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" |
b8a55285 AP |
109 | "@ |
110 | stfs %0,lo16(%2)(%1) | |
6b39bc38 | 111 | stw %0,lo16(%2)(%1)" |
b24a46be | 112 | [(set_attr "type" "store")]) |
b8a55285 | 113 | |
49bd1d27 SS |
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"))] | |
11d8d07e | 118 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
49bd1d27 SS |
119 | "@ |
120 | stfs %0,lo16(%2)(%1) | |
6b39bc38 | 121 | stw %0,lo16(%2)(%1)" |
b24a46be | 122 | [(set_attr "type" "store")]) |
49bd1d27 SS |
123 | |
124 | ;; 64-bit MachO load/store support | |
125 | (define_insn "movdi_low" | |
f4becba8 MM |
126 | [(set (match_operand:DI 0 "gpc_reg_operand" "=r,*!d") |
127 | (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") | |
49bd1d27 SS |
128 | (match_operand 2 "" ""))))] |
129 | "TARGET_MACHO && TARGET_64BIT" | |
f4becba8 | 130 | "@ |
6b39bc38 | 131 | ld %0,lo16(%2)(%1) |
f4becba8 | 132 | lfd %0,lo16(%2)(%1)" |
b24a46be | 133 | [(set_attr "type" "load")]) |
49bd1d27 | 134 | |
b8a55285 AP |
135 | (define_insn "movsi_low_st" |
136 | [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") | |
137 | (match_operand 2 "" ""))) | |
138 | (match_operand:SI 0 "gpc_reg_operand" "r"))] | |
139 | "TARGET_MACHO && ! TARGET_64BIT" | |
6b39bc38 | 140 | "stw %0,lo16(%2)(%1)" |
b24a46be | 141 | [(set_attr "type" "store")]) |
b8a55285 | 142 | |
49bd1d27 | 143 | (define_insn "movdi_low_st" |
f4becba8 | 144 | [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") |
49bd1d27 | 145 | (match_operand 2 "" ""))) |
f4becba8 | 146 | (match_operand:DI 0 "gpc_reg_operand" "r,*!d"))] |
49bd1d27 | 147 | "TARGET_MACHO && TARGET_64BIT" |
f4becba8 | 148 | "@ |
6b39bc38 | 149 | std %0,lo16(%2)(%1) |
f4becba8 | 150 | stfd %0,lo16(%2)(%1)" |
b24a46be | 151 | [(set_attr "type" "store")]) |
49bd1d27 | 152 | |
b8a55285 AP |
153 | ;; Mach-O PIC trickery. |
154 | (define_expand "macho_high" | |
ad18eed2 SB |
155 | [(set (match_operand 0 "") |
156 | (high (match_operand 1 "")))] | |
b8a55285 AP |
157 | "TARGET_MACHO" |
158 | { | |
159 | if (TARGET_64BIT) | |
160 | emit_insn (gen_macho_high_di (operands[0], operands[1])); | |
161 | else | |
162 | emit_insn (gen_macho_high_si (operands[0], operands[1])); | |
163 | ||
164 | DONE; | |
165 | }) | |
166 | ||
167 | (define_insn "macho_high_si" | |
168 | [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") | |
169 | (high:SI (match_operand 1 "" "")))] | |
170 | "TARGET_MACHO && ! TARGET_64BIT" | |
6b39bc38 | 171 | "lis %0,ha16(%1)") |
b8a55285 AP |
172 | |
173 | ||
49bd1d27 SS |
174 | (define_insn "macho_high_di" |
175 | [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") | |
176 | (high:DI (match_operand 1 "" "")))] | |
177 | "TARGET_MACHO && TARGET_64BIT" | |
6b39bc38 | 178 | "lis %0,ha16(%1)") |
49bd1d27 | 179 | |
b8a55285 | 180 | (define_expand "macho_low" |
ad18eed2 SB |
181 | [(set (match_operand 0 "") |
182 | (lo_sum (match_operand 1 "") | |
183 | (match_operand 2 "")))] | |
b8a55285 AP |
184 | "TARGET_MACHO" |
185 | { | |
186 | if (TARGET_64BIT) | |
187 | emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2])); | |
188 | else | |
189 | emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2])); | |
190 | ||
191 | DONE; | |
192 | }) | |
193 | ||
194 | (define_insn "macho_low_si" | |
76f93d99 SB |
195 | [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
196 | (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") | |
b8a55285 AP |
197 | (match_operand 2 "" "")))] |
198 | "TARGET_MACHO && ! TARGET_64BIT" | |
76f93d99 | 199 | "la %0,lo16(%2)(%1)") |
b8a55285 | 200 | |
49bd1d27 | 201 | (define_insn "macho_low_di" |
76f93d99 SB |
202 | [(set (match_operand:DI 0 "gpc_reg_operand" "=r") |
203 | (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") | |
49bd1d27 SS |
204 | (match_operand 2 "" "")))] |
205 | "TARGET_MACHO && TARGET_64BIT" | |
76f93d99 | 206 | "la %0,lo16(%2)(%1)") |
49bd1d27 SS |
207 | |
208 | (define_split | |
ad18eed2 SB |
209 | [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand") |
210 | (match_operand:DI 1 "short_cint_operand"))) | |
211 | (match_operand:V4SI 2 "register_operand")) | |
212 | (clobber (match_operand:DI 3 "gpc_reg_operand"))] | |
49bd1d27 SS |
213 | "TARGET_MACHO && TARGET_64BIT" |
214 | [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1))) | |
215 | (set (mem:V4SI (match_dup 3)) | |
216 | (match_dup 2))] | |
217 | "") | |
218 | ||
b8a55285 | 219 | (define_expand "load_macho_picbase" |
893fc0a0 | 220 | [(set (reg:SI LR_REGNO) |
ad18eed2 | 221 | (unspec [(match_operand 0 "")] |
b8a55285 AP |
222 | UNSPEC_LD_MPIC))] |
223 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" | |
224 | { | |
225 | if (TARGET_32BIT) | |
316fbf19 | 226 | emit_insn (gen_load_macho_picbase_si (operands[0])); |
b8a55285 | 227 | else |
316fbf19 | 228 | emit_insn (gen_load_macho_picbase_di (operands[0])); |
b8a55285 AP |
229 | |
230 | DONE; | |
231 | }) | |
232 | ||
233 | (define_insn "load_macho_picbase_si" | |
893fc0a0 | 234 | [(set (reg:SI LR_REGNO) |
e65a3857 | 235 | (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") |
d5b5b8bf | 236 | (pc)] UNSPEC_LD_MPIC))] |
b8a55285 | 237 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" |
e1c5c877 | 238 | { |
bd9534e2 | 239 | #if TARGET_MACHO |
e1c5c877 | 240 | machopic_should_output_picbase_label (); /* Update for new func. */ |
bd9534e2 IS |
241 | #else |
242 | gcc_unreachable (); | |
243 | #endif | |
6c332313 | 244 | return "bcl 20,31,%0\n%0:"; |
e1c5c877 | 245 | } |
b8a55285 | 246 | [(set_attr "type" "branch") |
a79db151 | 247 | (set_attr "cannot_copy" "yes")]) |
b8a55285 | 248 | |
49bd1d27 | 249 | (define_insn "load_macho_picbase_di" |
893fc0a0 | 250 | [(set (reg:DI LR_REGNO) |
e65a3857 | 251 | (unspec:DI [(match_operand:DI 0 "immediate_operand" "s") |
d5b5b8bf | 252 | (pc)] UNSPEC_LD_MPIC))] |
ac9e2cff | 253 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" |
e1c5c877 | 254 | { |
bd9534e2 | 255 | #if TARGET_MACHO |
e1c5c877 | 256 | machopic_should_output_picbase_label (); /* Update for new func. */ |
bd9534e2 IS |
257 | #else |
258 | gcc_unreachable (); | |
259 | #endif | |
6c332313 | 260 | return "bcl 20,31,%0\n%0:"; |
e1c5c877 | 261 | } |
49bd1d27 | 262 | [(set_attr "type" "branch") |
a79db151 | 263 | (set_attr "cannot_copy" "yes")]) |
49bd1d27 | 264 | |
b8a55285 | 265 | (define_expand "macho_correct_pic" |
ad18eed2 SB |
266 | [(set (match_operand 0 "") |
267 | (plus (match_operand 1 "") | |
268 | (unspec [(match_operand 2 "") | |
269 | (match_operand 3 "")] | |
b8a55285 AP |
270 | UNSPEC_MPIC_CORRECT)))] |
271 | "DEFAULT_ABI == ABI_DARWIN" | |
272 | { | |
273 | if (TARGET_32BIT) | |
274 | emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2], | |
275 | operands[3])); | |
276 | else | |
277 | emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2], | |
278 | operands[3])); | |
279 | ||
280 | DONE; | |
281 | }) | |
282 | ||
283 | (define_insn "macho_correct_pic_si" | |
284 | [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
285 | (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") | |
286 | (unspec:SI [(match_operand:SI 2 "immediate_operand" "s") | |
287 | (match_operand:SI 3 "immediate_operand" "s")] | |
288 | UNSPEC_MPIC_CORRECT)))] | |
289 | "DEFAULT_ABI == ABI_DARWIN" | |
290 | "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" | |
291 | [(set_attr "length" "8")]) | |
292 | ||
49bd1d27 SS |
293 | (define_insn "macho_correct_pic_di" |
294 | [(set (match_operand:DI 0 "gpc_reg_operand" "=r") | |
295 | (plus:DI (match_operand:DI 1 "gpc_reg_operand" "r") | |
296 | (unspec:DI [(match_operand:DI 2 "immediate_operand" "s") | |
297 | (match_operand:DI 3 "immediate_operand" "s")] | |
298 | 16)))] | |
ac9e2cff | 299 | "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" |
49bd1d27 SS |
300 | "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" |
301 | [(set_attr "length" "8")]) | |
302 | ||
e1c5c877 | 303 | (define_expand "reload_macho_picbase" |
893fc0a0 | 304 | [(set (reg:SI LR_REGNO) |
ad18eed2 | 305 | (unspec [(match_operand 0 "")] |
e1c5c877 IS |
306 | UNSPEC_RELD_MPIC))] |
307 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" | |
308 | { | |
309 | if (TARGET_32BIT) | |
310 | emit_insn (gen_reload_macho_picbase_si (operands[0])); | |
311 | else | |
312 | emit_insn (gen_reload_macho_picbase_di (operands[0])); | |
313 | ||
314 | DONE; | |
315 | }) | |
316 | ||
317 | (define_insn "reload_macho_picbase_si" | |
893fc0a0 | 318 | [(set (reg:SI LR_REGNO) |
e1c5c877 IS |
319 | (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") |
320 | (pc)] UNSPEC_RELD_MPIC))] | |
321 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" | |
322 | { | |
bd9534e2 | 323 | #if TARGET_MACHO |
e1c5c877 IS |
324 | if (machopic_should_output_picbase_label ()) |
325 | { | |
326 | static char tmp[64]; | |
327 | const char *cnam = machopic_get_function_picbase (); | |
6c332313 | 328 | snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam); |
e1c5c877 IS |
329 | return tmp; |
330 | } | |
331 | else | |
bd9534e2 IS |
332 | #else |
333 | gcc_unreachable (); | |
334 | #endif | |
6c332313 | 335 | return "bcl 20,31,%0\n%0:"; |
e1c5c877 IS |
336 | } |
337 | [(set_attr "type" "branch") | |
a79db151 | 338 | (set_attr "cannot_copy" "yes")]) |
e1c5c877 IS |
339 | |
340 | (define_insn "reload_macho_picbase_di" | |
893fc0a0 | 341 | [(set (reg:DI LR_REGNO) |
e1c5c877 IS |
342 | (unspec:DI [(match_operand:DI 0 "immediate_operand" "s") |
343 | (pc)] UNSPEC_RELD_MPIC))] | |
344 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" | |
345 | { | |
bd9534e2 | 346 | #if TARGET_MACHO |
e1c5c877 IS |
347 | if (machopic_should_output_picbase_label ()) |
348 | { | |
349 | static char tmp[64]; | |
350 | const char *cnam = machopic_get_function_picbase (); | |
6c332313 | 351 | snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam); |
e1c5c877 IS |
352 | return tmp; |
353 | } | |
354 | else | |
bd9534e2 IS |
355 | #else |
356 | gcc_unreachable (); | |
357 | #endif | |
6c332313 | 358 | return "bcl 20,31,%0\n%0:"; |
e1c5c877 IS |
359 | } |
360 | [(set_attr "type" "branch") | |
a79db151 | 361 | (set_attr "cannot_copy" "yes")]) |
e1c5c877 IS |
362 | |
363 | ;; We need to restore the PIC register, at the site of nonlocal label. | |
364 | ||
365 | (define_insn_and_split "nonlocal_goto_receiver" | |
366 | [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)] | |
367 | "TARGET_MACHO && flag_pic" | |
368 | "#" | |
369 | "&& reload_completed" | |
370 | [(const_int 0)] | |
371 | { | |
bd9534e2 | 372 | #if TARGET_MACHO |
e1c5c877 IS |
373 | if (crtl->uses_pic_offset_table) |
374 | { | |
375 | static unsigned n = 0; | |
376 | rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); | |
377 | rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); | |
378 | rtx tmplrtx; | |
379 | char tmplab[20]; | |
380 | ||
381 | ASM_GENERATE_INTERNAL_LABEL(tmplab, "Lnlgr", ++n); | |
382 | tmplrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); | |
383 | ||
384 | emit_insn (gen_reload_macho_picbase (tmplrtx)); | |
385 | emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); | |
386 | emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplrtx)); | |
387 | } | |
388 | else | |
389 | /* Not using PIC reg, no reload needed. */ | |
390 | emit_note (NOTE_INSN_DELETED); | |
bd9534e2 IS |
391 | #else |
392 | gcc_unreachable (); | |
393 | #endif | |
e1c5c877 IS |
394 | DONE; |
395 | }) |