xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/rs6000/darwin.md (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1/* Machine description patterns for PowerPC running Darwin (Mac OS X).
2   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
3   Contributed by Apple Computer Inc.
4
5This file is part of GCC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You 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  "{cau|addis} %0,%1,ha16(%2)"
27  [(set_attr "length" "4")])
28
29(define_insn "movdf_low_si"
30  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
31        (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
32                           (match_operand 2 "" ""))))]
33  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_64BIT"
34  "*
35{
36  switch (which_alternative)
37    {
38      case 0:
39	return \"lfd %0,lo16(%2)(%1)\";
40      case 1:
41	{
42	  if (TARGET_POWERPC64 && TARGET_32BIT)
43	    /* Note, old assemblers didn't support relocation here.  */
44	    return \"ld %0,lo16(%2)(%1)\";
45	  else
46	    {
47	      output_asm_insn (\"{cal|la} %0,lo16(%2)(%1)\", operands);
48	      output_asm_insn (\"{l|lwz} %L0,4(%0)\", operands);
49	      return (\"{l|lwz} %0,0(%0)\");
50	    }
51	}
52      default:
53	gcc_unreachable ();
54    }
55}"
56  [(set_attr "type" "load")
57   (set_attr "length" "4,12")])
58
59
60(define_insn "movdf_low_di"
61  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
62        (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
63                           (match_operand 2 "" ""))))]
64  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
65  "*
66{
67  switch (which_alternative)
68    {
69      case 0:
70	return \"lfd %0,lo16(%2)(%1)\";
71      case 1:
72	return \"ld %0,lo16(%2)(%1)\";
73      default:
74	gcc_unreachable ();
75    }
76}"
77  [(set_attr "type" "load")
78   (set_attr "length" "4,4")])
79
80(define_insn "movdf_low_st_si"
81  [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
82                           (match_operand 2 "" "")))
83	(match_operand:DF 0 "gpc_reg_operand" "f"))]
84  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT"
85  "stfd %0,lo16(%2)(%1)"
86  [(set_attr "type" "store")
87   (set_attr "length" "4")])
88
89(define_insn "movdf_low_st_di"
90  [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
91                           (match_operand 2 "" "")))
92	(match_operand:DF 0 "gpc_reg_operand" "f"))]
93  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
94  "stfd %0,lo16(%2)(%1)"
95  [(set_attr "type" "store")
96   (set_attr "length" "4")])
97
98(define_insn "movsf_low_si"
99  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
100        (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
101                           (match_operand 2 "" ""))))]
102  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT"
103  "@
104   lfs %0,lo16(%2)(%1)
105   {l|lwz} %0,lo16(%2)(%1)"
106  [(set_attr "type" "load")
107   (set_attr "length" "4")])
108
109(define_insn "movsf_low_di"
110  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
111        (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
112                           (match_operand 2 "" ""))))]
113  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
114  "@
115   lfs %0,lo16(%2)(%1)
116   {l|lwz} %0,lo16(%2)(%1)"
117  [(set_attr "type" "load")
118   (set_attr "length" "4")])
119
120(define_insn "movsf_low_st_si"
121  [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
122                           (match_operand 2 "" "")))
123	(match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
124  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT"
125  "@
126   stfs %0,lo16(%2)(%1)
127   {st|stw} %0,lo16(%2)(%1)"
128  [(set_attr "type" "store")
129   (set_attr "length" "4")])
130
131(define_insn "movsf_low_st_di"
132  [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
133                           (match_operand 2 "" "")))
134	(match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
135  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
136  "@
137   stfs %0,lo16(%2)(%1)
138   {st|stw} %0,lo16(%2)(%1)"
139  [(set_attr "type" "store")
140   (set_attr "length" "4")])
141
142;; 64-bit MachO load/store support
143(define_insn "movdi_low"
144  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
145        (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
146                           (match_operand 2 "" ""))))]
147  "TARGET_MACHO && TARGET_64BIT"
148  "{l|ld} %0,lo16(%2)(%1)"
149  [(set_attr "type" "load")
150   (set_attr "length" "4")])
151
152(define_insn "movsi_low_st"
153  [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
154                           (match_operand 2 "" "")))
155	(match_operand:SI 0 "gpc_reg_operand" "r"))]
156  "TARGET_MACHO && ! TARGET_64BIT"
157  "{st|stw} %0,lo16(%2)(%1)"
158  [(set_attr "type" "store")
159   (set_attr "length" "4")])
160
161(define_insn "movdi_low_st"
162  [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
163                           (match_operand 2 "" "")))
164	(match_operand:DI 0 "gpc_reg_operand" "r"))]
165  "TARGET_MACHO && TARGET_64BIT"
166  "{st|std} %0,lo16(%2)(%1)"
167  [(set_attr "type" "store")
168   (set_attr "length" "4")])
169
170;; Mach-O PIC trickery.
171(define_expand "macho_high"
172  [(set (match_operand 0 "" "")
173	(high (match_operand 1 "" "")))]
174  "TARGET_MACHO"
175{
176  if (TARGET_64BIT)
177    emit_insn (gen_macho_high_di (operands[0], operands[1]));
178  else
179    emit_insn (gen_macho_high_si (operands[0], operands[1]));
180
181  DONE;
182})
183
184(define_insn "macho_high_si"
185  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
186	(high:SI (match_operand 1 "" "")))]
187  "TARGET_MACHO && ! TARGET_64BIT"
188  "{liu|lis} %0,ha16(%1)")
189
190
191(define_insn "macho_high_di"
192  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
193	(high:DI (match_operand 1 "" "")))]
194  "TARGET_MACHO && TARGET_64BIT"
195  "{liu|lis} %0,ha16(%1)")
196
197(define_expand "macho_low"
198  [(set (match_operand 0 "" "")
199	(lo_sum (match_operand 1 "" "")
200		   (match_operand 2 "" "")))]
201   "TARGET_MACHO"
202{
203  if (TARGET_64BIT)
204    emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2]));
205  else
206    emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2]));
207
208  DONE;
209})
210
211(define_insn "macho_low_si"
212  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
213	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
214		   (match_operand 2 "" "")))]
215   "TARGET_MACHO && ! TARGET_64BIT"
216   "@
217    {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)}
218    {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}")
219
220(define_insn "macho_low_di"
221  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
222	(lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
223		   (match_operand 2 "" "")))]
224   "TARGET_MACHO && TARGET_64BIT"
225   "@
226    {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)}
227    {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}")
228
229(define_split
230  [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand" "")
231			 (match_operand:DI 1 "short_cint_operand" "")))
232	(match_operand:V4SI 2 "register_operand" ""))
233   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
234  "TARGET_MACHO && TARGET_64BIT"
235  [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1)))
236   (set (mem:V4SI (match_dup 3))
237	(match_dup 2))]
238  "")
239
240(define_expand "load_macho_picbase"
241  [(set (reg:SI 65)
242        (unspec [(match_operand 0 "" "")]
243                   UNSPEC_LD_MPIC))]
244  "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
245{
246  if (TARGET_32BIT)
247    emit_insn (gen_load_macho_picbase_si (operands[0]));
248  else
249    emit_insn (gen_load_macho_picbase_di (operands[0]));
250
251  DONE;
252})
253
254(define_insn "load_macho_picbase_si"
255  [(set (reg:SI 65)
256	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
257		    (pc)] UNSPEC_LD_MPIC))]
258  "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
259  "bcl 20,31,%0\\n%0:"
260  [(set_attr "type" "branch")
261   (set_attr "length" "4")])
262
263(define_insn "load_macho_picbase_di"
264  [(set (reg:DI 65)
265	(unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
266		    (pc)] UNSPEC_LD_MPIC))]
267  "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
268  "bcl 20,31,%0\\n%0:"
269  [(set_attr "type" "branch")
270   (set_attr "length" "4")])
271
272(define_expand "macho_correct_pic"
273  [(set (match_operand 0 "" "")
274	(plus (match_operand 1 "" "")
275		 (unspec [(match_operand 2 "" "")
276			     (match_operand 3 "" "")]
277			    UNSPEC_MPIC_CORRECT)))]
278  "DEFAULT_ABI == ABI_DARWIN"
279{
280  if (TARGET_32BIT)
281    emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2],
282	       operands[3]));
283  else
284    emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2],
285	       operands[3]));
286
287  DONE;
288})
289
290(define_insn "macho_correct_pic_si"
291  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
292	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
293		 (unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
294			     (match_operand:SI 3 "immediate_operand" "s")]
295			    UNSPEC_MPIC_CORRECT)))]
296  "DEFAULT_ABI == ABI_DARWIN"
297  "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
298  [(set_attr "length" "8")])
299
300(define_insn "macho_correct_pic_di"
301  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
302	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
303		 (unspec:DI [(match_operand:DI 2 "immediate_operand" "s")
304			     (match_operand:DI 3 "immediate_operand" "s")]
305			    16)))]
306  "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
307  "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
308  [(set_attr "length" "8")])
309
310(define_insn "*call_indirect_nonlocal_darwin64"
311  [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l"))
312	 (match_operand 1 "" "g,g,g,g"))
313   (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
314   (clobber (reg:SI 65))]
315  "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
316{
317  return "b%T0l";
318}
319  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
320   (set_attr "length" "4,4,8,8")])
321
322(define_insn "*call_nonlocal_darwin64"
323  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
324	 (match_operand 1 "" "g,g"))
325   (use (match_operand:SI 2 "immediate_operand" "O,n"))
326   (clobber (reg:SI 65))]
327  "(DEFAULT_ABI == ABI_DARWIN)
328   && (INTVAL (operands[2]) & CALL_LONG) == 0"
329{
330#if TARGET_MACHO
331  return output_call(insn, operands, 0, 2);
332#else
333  gcc_unreachable ();
334#endif
335}
336  [(set_attr "type" "branch,branch")
337   (set_attr "length" "4,8")])
338
339(define_insn "*call_value_indirect_nonlocal_darwin64"
340  [(set (match_operand 0 "" "")
341	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l"))
342	      (match_operand 2 "" "g,g,g,g")))
343   (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
344   (clobber (reg:SI 65))]
345  "DEFAULT_ABI == ABI_DARWIN"
346{
347  return "b%T1l";
348}
349  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
350   (set_attr "length" "4,4,8,8")])
351
352(define_insn "*call_value_nonlocal_darwin64"
353  [(set (match_operand 0 "" "")
354	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
355	      (match_operand 2 "" "g,g")))
356   (use (match_operand:SI 3 "immediate_operand" "O,n"))
357   (clobber (reg:SI 65))]
358  "(DEFAULT_ABI == ABI_DARWIN)
359   && (INTVAL (operands[3]) & CALL_LONG) == 0"
360{
361#if TARGET_MACHO
362  return output_call(insn, operands, 1, 3);
363#else
364  gcc_unreachable ();
365#endif
366}
367  [(set_attr "type" "branch,branch")
368   (set_attr "length" "4,8")])
369
370(define_insn "*sibcall_nonlocal_darwin64"
371  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
372	 (match_operand 1 "" ""))
373   (use (match_operand 2 "immediate_operand" "O,n"))
374   (use (reg:SI 65))
375   (return)]
376  "(DEFAULT_ABI == ABI_DARWIN)
377   && (INTVAL (operands[2]) & CALL_LONG) == 0"
378{
379  return "b %z0";
380}
381  [(set_attr "type" "branch,branch")
382   (set_attr "length" "4,8")])
383
384(define_insn "*sibcall_value_nonlocal_darwin64"
385  [(set (match_operand 0 "" "")
386	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
387	      (match_operand 2 "" "")))
388   (use (match_operand:SI 3 "immediate_operand" "O,n"))
389   (use (reg:SI 65))
390   (return)]
391  "(DEFAULT_ABI == ABI_DARWIN)
392   && (INTVAL (operands[3]) & CALL_LONG) == 0"
393  "*
394{
395  return \"b %z1\";
396}"
397  [(set_attr "type" "branch,branch")
398   (set_attr "length" "4,8")])
399
400
401(define_insn "*sibcall_symbolic_64"
402  [(call (mem:SI (match_operand:DI 0 "call_operand" "s,c")) ; 64
403	 (match_operand 1 "" ""))
404   (use (match_operand 2 "" ""))
405   (use (reg:SI 65))
406   (return)]
407  "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
408  "*
409{
410  switch (which_alternative)
411    {
412      case 0:  return \"b %z0\";
413      case 1:  return \"b%T0\";
414      default:  gcc_unreachable ();
415    }
416}"
417  [(set_attr "type" "branch")
418   (set_attr "length" "4")])
419
420(define_insn "*sibcall_value_symbolic_64"
421  [(set (match_operand 0 "" "")
422	(call (mem:SI (match_operand:DI 1 "call_operand" "s,c"))
423	      (match_operand 2 "" "")))
424   (use (match_operand:SI 3 "" ""))
425   (use (reg:SI 65))
426   (return)]
427  "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
428  "*
429{
430  switch (which_alternative)
431    {
432      case 0:  return \"b %z1\";
433      case 1:  return \"b%T1\";
434      default:  gcc_unreachable ();
435    }
436}"
437  [(set_attr "type" "branch")
438   (set_attr "length" "4")])
439