darwin.md revision 169689
1218887Sdim/* Machine description patterns for PowerPC running Darwin (Mac OS X).
2218887Sdim   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3353358Sdim   Contributed by Apple Computer Inc.
4353358Sdim
5353358SdimThis file is part of GCC.
6218887Sdim
7218887SdimGNU CC is free software; you can redistribute it and/or modify
8218887Sdimit under the terms of the GNU General Public License as published by
9218887Sdimthe Free Software Foundation; either version 2, or (at your option)
10218887Sdimany later version.
11218887Sdim
12218887SdimGNU CC is distributed in the hope that it will be useful,
13218887Sdimbut WITHOUT ANY WARRANTY; without even the implied warranty of
14249423SdimMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15249423SdimGNU General Public License for more details.
16249423Sdim
17218887SdimYou should have received a copy of the GNU General Public License
18344779Sdimalong with GNU CC; see the file COPYING.  If not, write to
19249423Sdimthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
20249423SdimBoston, MA 02110-1301, USA.  */
21219077Sdim
22276479Sdim(define_insn "adddi3_high"
23218887Sdim  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
24218887Sdim        (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b")
25218887Sdim                 (high:DI (match_operand 2 "" ""))))]
26218887Sdim  "TARGET_MACHO && TARGET_64BIT"
27341825Sdim  "{cau|addis} %0,%1,ha16(%2)"
28344779Sdim  [(set_attr "length" "4")])
29344779Sdim
30341825Sdim(define_insn "movdf_low_si"
31341825Sdim  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
32341825Sdim        (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
33360784Sdim                           (match_operand 2 "" ""))))]
34218887Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_64BIT"
35353358Sdim  "*
36353358Sdim{
37218887Sdim  switch (which_alternative)
38353358Sdim    {
39353358Sdim      case 0:
40221345Sdim	return \"lfd %0,lo16(%2)(%1)\";
41221345Sdim      case 1:
42288943Sdim	{
43218887Sdim	  if (TARGET_POWERPC64 && TARGET_32BIT)
44219077Sdim	    /* Note, old assemblers didn't support relocation here.  */
45344779Sdim	    return \"ld %0,lo16(%2)(%1)\";
46353358Sdim	  else
47353358Sdim	    {
48353358Sdim	      output_asm_insn (\"{cal|la} %0,lo16(%2)(%1)\", operands);
49226633Sdim	      output_asm_insn (\"{l|lwz} %L0,4(%0)\", operands);
50226633Sdim	      return (\"{l|lwz} %0,0(%0)\");
51219077Sdim	    }
52353358Sdim	}
53353358Sdim      default:
54219077Sdim	gcc_unreachable ();
55314564Sdim    }
56314564Sdim}"
57314564Sdim  [(set_attr "type" "load")
58353358Sdim   (set_attr "length" "4,12")])
59353358Sdim
60353358Sdim
61314564Sdim(define_insn "movdf_low_di"
62314564Sdim  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
63353358Sdim        (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
64353358Sdim                           (match_operand 2 "" ""))))]
65314564Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
66344779Sdim  "*
67353358Sdim{
68353358Sdim  switch (which_alternative)
69353358Sdim    {
70353358Sdim      case 0:
71353358Sdim	return \"lfd %0,lo16(%2)(%1)\";
72353358Sdim      case 1:
73353358Sdim	return \"ld %0,lo16(%2)(%1)\";
74353358Sdim      default:
75353358Sdim	gcc_unreachable ();
76344779Sdim    }
77360784Sdim}"
78360784Sdim  [(set_attr "type" "load")
79360784Sdim   (set_attr "length" "4,4")])
80360784Sdim
81360784Sdim(define_insn "movdf_low_st_si"
82360784Sdim  [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
83344779Sdim                           (match_operand 2 "" "")))
84360784Sdim	(match_operand:DF 0 "gpc_reg_operand" "f"))]
85360784Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT"
86360784Sdim  "stfd %0,lo16(%2)(%1)"
87360784Sdim  [(set_attr "type" "store")
88360784Sdim   (set_attr "length" "4")])
89360784Sdim
90360784Sdim(define_insn "movdf_low_st_di"
91360784Sdim  [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
92360784Sdim                           (match_operand 2 "" "")))
93360784Sdim	(match_operand:DF 0 "gpc_reg_operand" "f"))]
94344779Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
95344779Sdim  "stfd %0,lo16(%2)(%1)"
96344779Sdim  [(set_attr "type" "store")
97344779Sdim   (set_attr "length" "4")])
98344779Sdim
99344779Sdim(define_insn "movsf_low_si"
100344779Sdim  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
101344779Sdim        (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
102344779Sdim                           (match_operand 2 "" ""))))]
103344779Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT"
104344779Sdim  "@
105344779Sdim   lfs %0,lo16(%2)(%1)
106344779Sdim   {l|lwz} %0,lo16(%2)(%1)"
107344779Sdim  [(set_attr "type" "load")
108344779Sdim   (set_attr "length" "4")])
109344779Sdim
110344779Sdim(define_insn "movsf_low_di"
111344779Sdim  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
112344779Sdim        (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
113344779Sdim                           (match_operand 2 "" ""))))]
114344779Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
115344779Sdim  "@
116344779Sdim   lfs %0,lo16(%2)(%1)
117344779Sdim   {l|lwz} %0,lo16(%2)(%1)"
118344779Sdim  [(set_attr "type" "load")
119344779Sdim   (set_attr "length" "4")])
120344779Sdim
121344779Sdim(define_insn "movsf_low_st_si"
122344779Sdim  [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
123344779Sdim                           (match_operand 2 "" "")))
124344779Sdim	(match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
125344779Sdim  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT"
126353358Sdim  "@
127353358Sdim   stfs %0,lo16(%2)(%1)
128353358Sdim   {st|stw} %0,lo16(%2)(%1)"
129353358Sdim  [(set_attr "type" "store")
130344779Sdim   (set_attr "length" "4")])
131344779Sdim
132(define_insn "movsf_low_st_di"
133  [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
134                           (match_operand 2 "" "")))
135	(match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
136  "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT"
137  "@
138   stfs %0,lo16(%2)(%1)
139   {st|stw} %0,lo16(%2)(%1)"
140  [(set_attr "type" "store")
141   (set_attr "length" "4")])
142
143;; 64-bit MachO load/store support
144(define_insn "movdi_low"
145  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
146        (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
147                           (match_operand 2 "" ""))))]
148  "TARGET_MACHO && TARGET_64BIT"
149  "{l|ld} %0,lo16(%2)(%1)"
150  [(set_attr "type" "load")
151   (set_attr "length" "4")])
152
153(define_insn "movsi_low_st"
154  [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
155                           (match_operand 2 "" "")))
156	(match_operand:SI 0 "gpc_reg_operand" "r"))]
157  "TARGET_MACHO && ! TARGET_64BIT"
158  "{st|stw} %0,lo16(%2)(%1)"
159  [(set_attr "type" "store")
160   (set_attr "length" "4")])
161
162(define_insn "movdi_low_st"
163  [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
164                           (match_operand 2 "" "")))
165	(match_operand:DI 0 "gpc_reg_operand" "r"))]
166  "TARGET_MACHO && TARGET_64BIT"
167  "{st|std} %0,lo16(%2)(%1)"
168  [(set_attr "type" "store")
169   (set_attr "length" "4")])
170
171;; Mach-O PIC trickery.
172(define_expand "macho_high"
173  [(set (match_operand 0 "" "")
174	(high (match_operand 1 "" "")))]
175  "TARGET_MACHO"
176{
177  if (TARGET_64BIT)
178    emit_insn (gen_macho_high_di (operands[0], operands[1]));
179  else
180    emit_insn (gen_macho_high_si (operands[0], operands[1]));
181
182  DONE;
183})
184
185(define_insn "macho_high_si"
186  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
187	(high:SI (match_operand 1 "" "")))]
188  "TARGET_MACHO && ! TARGET_64BIT"
189  "{liu|lis} %0,ha16(%1)")
190  
191
192(define_insn "macho_high_di"
193  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
194	(high:DI (match_operand 1 "" "")))]
195  "TARGET_MACHO && TARGET_64BIT"
196  "{liu|lis} %0,ha16(%1)")
197
198(define_expand "macho_low"
199  [(set (match_operand 0 "" "")
200	(lo_sum (match_operand 1 "" "")
201		   (match_operand 2 "" "")))]
202   "TARGET_MACHO"
203{
204  if (TARGET_64BIT)
205    emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2]));
206  else
207    emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2]));
208
209  DONE;
210})
211
212(define_insn "macho_low_si"
213  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
214	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
215		   (match_operand 2 "" "")))]
216   "TARGET_MACHO && ! TARGET_64BIT"
217   "@
218    {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)}
219    {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}")
220
221(define_insn "macho_low_di"
222  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
223	(lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
224		   (match_operand 2 "" "")))]
225   "TARGET_MACHO && TARGET_64BIT"
226   "@
227    {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)}
228    {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}")
229
230(define_split
231  [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand" "")
232			 (match_operand:DI 1 "short_cint_operand" "")))
233	(match_operand:V4SI 2 "register_operand" ""))
234   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
235  "TARGET_MACHO && TARGET_64BIT"
236  [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1)))
237   (set (mem:V4SI (match_dup 3))
238	(match_dup 2))]
239  "")
240
241(define_expand "load_macho_picbase"
242  [(set (match_operand 0 "" "")
243        (unspec [(match_operand 1 "" "")]
244                   UNSPEC_LD_MPIC))]
245  "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
246{
247  if (TARGET_32BIT)
248    emit_insn (gen_load_macho_picbase_si (operands[0], operands[1]));
249  else
250    emit_insn (gen_load_macho_picbase_di (operands[0], operands[1]));
251
252  DONE;
253})
254
255(define_insn "load_macho_picbase_si"
256  [(set (match_operand:SI 0 "register_operand" "=l")
257	(unspec:SI [(match_operand:SI 1 "immediate_operand" "s")
258		    (pc)] UNSPEC_LD_MPIC))]
259  "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
260  "bcl 20,31,%1\\n%1:"
261  [(set_attr "type" "branch")
262   (set_attr "length" "4")])
263
264(define_insn "load_macho_picbase_di"
265  [(set (match_operand:DI 0 "register_operand" "=l")
266	(unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
267		    (pc)] UNSPEC_LD_MPIC))]
268  "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
269  "bcl 20,31,%1\\n%1:"
270  [(set_attr "type" "branch")
271   (set_attr "length" "4")])
272
273(define_expand "macho_correct_pic"
274  [(set (match_operand 0 "" "")
275	(plus (match_operand 1 "" "")
276		 (unspec [(match_operand 2 "" "")
277			     (match_operand 3 "" "")]
278			    UNSPEC_MPIC_CORRECT)))]
279  "DEFAULT_ABI == ABI_DARWIN"
280{
281  if (TARGET_32BIT)
282    emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2],
283	       operands[3]));
284  else
285    emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2],
286	       operands[3]));
287
288  DONE;
289})
290
291(define_insn "macho_correct_pic_si"
292  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
293	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
294		 (unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
295			     (match_operand:SI 3 "immediate_operand" "s")]
296			    UNSPEC_MPIC_CORRECT)))]
297  "DEFAULT_ABI == ABI_DARWIN"
298  "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
299  [(set_attr "length" "8")])
300
301(define_insn "macho_correct_pic_di"
302  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
303	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
304		 (unspec:DI [(match_operand:DI 2 "immediate_operand" "s")
305			     (match_operand:DI 3 "immediate_operand" "s")]
306			    16)))]
307  "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
308  "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
309  [(set_attr "length" "8")])
310
311(define_insn "*call_indirect_nonlocal_darwin64"
312  [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l"))
313	 (match_operand 1 "" "g,g,g,g"))
314   (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
315   (clobber (match_scratch:SI 3 "=l,l,l,l"))]
316  "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
317{
318  return "b%T0l";
319}
320  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
321   (set_attr "length" "4,4,8,8")])
322
323(define_insn "*call_nonlocal_darwin64"
324  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
325	 (match_operand 1 "" "g,g"))
326   (use (match_operand:SI 2 "immediate_operand" "O,n"))
327   (clobber (match_scratch:SI 3 "=l,l"))]
328  "(DEFAULT_ABI == ABI_DARWIN)
329   && (INTVAL (operands[2]) & CALL_LONG) == 0"
330{
331#if TARGET_MACHO
332  return output_call(insn, operands, 0, 2);
333#else
334  gcc_unreachable ();
335#endif
336}
337  [(set_attr "type" "branch,branch")
338   (set_attr "length" "4,8")])
339
340(define_insn "*call_value_indirect_nonlocal_darwin64"
341  [(set (match_operand 0 "" "")
342	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l"))
343	      (match_operand 2 "" "g,g,g,g")))
344   (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
345   (clobber (match_scratch:SI 4 "=l,l,l,l"))]
346  "DEFAULT_ABI == ABI_DARWIN"
347{
348  return "b%T1l";
349}
350  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
351   (set_attr "length" "4,4,8,8")])
352
353(define_insn "*call_value_nonlocal_darwin64"
354  [(set (match_operand 0 "" "")
355	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
356	      (match_operand 2 "" "g,g")))
357   (use (match_operand:SI 3 "immediate_operand" "O,n"))
358   (clobber (match_scratch:SI 4 "=l,l"))]
359  "(DEFAULT_ABI == ABI_DARWIN)
360   && (INTVAL (operands[3]) & CALL_LONG) == 0"
361{
362#if TARGET_MACHO
363  return output_call(insn, operands, 1, 3);
364#else
365  gcc_unreachable ();
366#endif
367}
368  [(set_attr "type" "branch,branch")
369   (set_attr "length" "4,8")])
370
371(define_insn "*sibcall_nonlocal_darwin64"
372  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
373	 (match_operand 1 "" ""))
374   (use (match_operand 2 "immediate_operand" "O,n"))
375   (use (match_operand:SI 3 "register_operand" "l,l"))
376   (return)]
377  "(DEFAULT_ABI == ABI_DARWIN)
378   && (INTVAL (operands[2]) & CALL_LONG) == 0"
379{
380  return "b %z0";
381}
382  [(set_attr "type" "branch,branch")
383   (set_attr "length" "4,8")])
384
385(define_insn "*sibcall_value_nonlocal_darwin64"
386  [(set (match_operand 0 "" "")
387	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
388	      (match_operand 2 "" "")))
389   (use (match_operand:SI 3 "immediate_operand" "O,n"))
390   (use (match_operand:SI 4 "register_operand" "l,l"))
391   (return)]
392  "(DEFAULT_ABI == ABI_DARWIN)
393   && (INTVAL (operands[3]) & CALL_LONG) == 0"
394  "*
395{
396  return \"b %z1\";
397}"
398  [(set_attr "type" "branch,branch")
399   (set_attr "length" "4,8")])
400
401
402(define_insn "*sibcall_symbolic_64"
403  [(call (mem:SI (match_operand:DI 0 "call_operand" "s,c")) ; 64
404	 (match_operand 1 "" ""))
405   (use (match_operand 2 "" ""))
406   (use (match_operand:SI 3 "register_operand" "l,l"))
407   (return)]
408  "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
409  "*
410{
411  switch (which_alternative)
412    {
413      case 0:  return \"b %z0\";
414      case 1:  return \"b%T0\";
415      default:  gcc_unreachable ();
416    }
417}"
418  [(set_attr "type" "branch")
419   (set_attr "length" "4")])
420
421(define_insn "*sibcall_value_symbolic_64"
422  [(set (match_operand 0 "" "")
423	(call (mem:SI (match_operand:DI 1 "call_operand" "s,c"))
424	      (match_operand 2 "" "")))
425   (use (match_operand:SI 3 "" ""))
426   (use (match_operand:SI 4 "register_operand" "l,l"))
427   (return)]
428  "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
429  "*
430{
431  switch (which_alternative)
432    {
433      case 0:  return \"b %z1\";
434      case 1:  return \"b%T1\";
435      default:  gcc_unreachable ();
436    }
437}"
438  [(set_attr "type" "branch")
439   (set_attr "length" "4")])
440
441