Home | History | Annotate | Line # | Download | only in rs6000
darwin.md revision 1.5
      1 /* Machine description patterns for PowerPC running Darwin (Mac OS X).
      2    Copyright (C) 2004-2015 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   [(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 (\"la %0,lo16(%2)(%1)\", operands);
     48 	      output_asm_insn (\"lwz %L0,4(%0)\", operands);
     49 	      return (\"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    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    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    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    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,*!d")
    145         (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
    146                            (match_operand 2 "" ""))))]
    147   "TARGET_MACHO && TARGET_64BIT"
    148   "@
    149    ld %0,lo16(%2)(%1)
    150    lfd %0,lo16(%2)(%1)"
    151   [(set_attr "type" "load")
    152    (set_attr "length" "4")])
    153 
    154 (define_insn "movsi_low_st"
    155   [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
    156                            (match_operand 2 "" "")))
    157 	(match_operand:SI 0 "gpc_reg_operand" "r"))]
    158   "TARGET_MACHO && ! TARGET_64BIT"
    159   "stw %0,lo16(%2)(%1)"
    160   [(set_attr "type" "store")
    161    (set_attr "length" "4")])
    162 
    163 (define_insn "movdi_low_st"
    164   [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
    165                            (match_operand 2 "" "")))
    166 	(match_operand:DI 0 "gpc_reg_operand" "r,*!d"))]
    167   "TARGET_MACHO && TARGET_64BIT"
    168   "@
    169    std %0,lo16(%2)(%1)
    170    stfd %0,lo16(%2)(%1)"
    171   [(set_attr "type" "store")
    172    (set_attr "length" "4")])
    173 
    174 ;; Mach-O PIC trickery.
    175 (define_expand "macho_high"
    176   [(set (match_operand 0 "" "")
    177 	(high (match_operand 1 "" "")))]
    178   "TARGET_MACHO"
    179 {
    180   if (TARGET_64BIT)
    181     emit_insn (gen_macho_high_di (operands[0], operands[1]));
    182   else
    183     emit_insn (gen_macho_high_si (operands[0], operands[1]));
    184 
    185   DONE;
    186 })
    187 
    188 (define_insn "macho_high_si"
    189   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
    190 	(high:SI (match_operand 1 "" "")))]
    191   "TARGET_MACHO && ! TARGET_64BIT"
    192   "lis %0,ha16(%1)")
    193 
    194 
    195 (define_insn "macho_high_di"
    196   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
    197 	(high:DI (match_operand 1 "" "")))]
    198   "TARGET_MACHO && TARGET_64BIT"
    199   "lis %0,ha16(%1)")
    200 
    201 (define_expand "macho_low"
    202   [(set (match_operand 0 "" "")
    203 	(lo_sum (match_operand 1 "" "")
    204 		   (match_operand 2 "" "")))]
    205    "TARGET_MACHO"
    206 {
    207   if (TARGET_64BIT)
    208     emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2]));
    209   else
    210     emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2]));
    211 
    212   DONE;
    213 })
    214 
    215 (define_insn "macho_low_si"
    216   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
    217 	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
    218 		   (match_operand 2 "" "")))]
    219    "TARGET_MACHO && ! TARGET_64BIT"
    220    "la %0,lo16(%2)(%1)")
    221 
    222 (define_insn "macho_low_di"
    223   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
    224 	(lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
    225 		   (match_operand 2 "" "")))]
    226    "TARGET_MACHO && TARGET_64BIT"
    227    "la %0,lo16(%2)(%1)")
    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 {
    260 #if TARGET_MACHO
    261   machopic_should_output_picbase_label (); /* Update for new func.  */
    262 #else
    263   gcc_unreachable ();
    264 #endif
    265   return "bcl 20,31,%0\\n%0:";
    266 }
    267   [(set_attr "type" "branch")
    268    (set_attr "length" "4")])
    269 
    270 (define_insn "load_macho_picbase_di"
    271   [(set (reg:DI 65)
    272 	(unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
    273 		    (pc)] UNSPEC_LD_MPIC))]
    274   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
    275 {
    276 #if TARGET_MACHO
    277   machopic_should_output_picbase_label (); /* Update for new func.  */
    278 #else
    279   gcc_unreachable ();
    280 #endif
    281   return "bcl 20,31,%0\\n%0:";
    282 }
    283   [(set_attr "type" "branch")
    284    (set_attr "length" "4")])
    285 
    286 (define_expand "macho_correct_pic"
    287   [(set (match_operand 0 "" "")
    288 	(plus (match_operand 1 "" "")
    289 		 (unspec [(match_operand 2 "" "")
    290 			     (match_operand 3 "" "")]
    291 			    UNSPEC_MPIC_CORRECT)))]
    292   "DEFAULT_ABI == ABI_DARWIN"
    293 {
    294   if (TARGET_32BIT)
    295     emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2],
    296 	       operands[3]));
    297   else
    298     emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2],
    299 	       operands[3]));
    300 
    301   DONE;
    302 })
    303 
    304 (define_insn "macho_correct_pic_si"
    305   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
    306 	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
    307 		 (unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
    308 			     (match_operand:SI 3 "immediate_operand" "s")]
    309 			    UNSPEC_MPIC_CORRECT)))]
    310   "DEFAULT_ABI == ABI_DARWIN"
    311   "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
    312   [(set_attr "length" "8")])
    313 
    314 (define_insn "macho_correct_pic_di"
    315   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
    316 	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
    317 		 (unspec:DI [(match_operand:DI 2 "immediate_operand" "s")
    318 			     (match_operand:DI 3 "immediate_operand" "s")]
    319 			    16)))]
    320   "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
    321   "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
    322   [(set_attr "length" "8")])
    323 
    324 (define_insn "*call_indirect_nonlocal_darwin64"
    325   [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l"))
    326 	 (match_operand 1 "" "g,g,g,g"))
    327    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
    328    (clobber (reg:SI 65))]
    329   "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
    330 {
    331   return "b%T0l";
    332 }
    333   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    334    (set_attr "length" "4,4,8,8")])
    335 
    336 (define_insn "*call_nonlocal_darwin64"
    337   [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
    338 	 (match_operand 1 "" "g,g"))
    339    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    340    (clobber (reg:SI 65))]
    341   "(DEFAULT_ABI == ABI_DARWIN)
    342    && (INTVAL (operands[2]) & CALL_LONG) == 0"
    343 {
    344 #if TARGET_MACHO
    345   return output_call(insn, operands, 0, 2);
    346 #else
    347   gcc_unreachable ();
    348 #endif
    349 }
    350   [(set_attr "type" "branch,branch")
    351    (set_attr "length" "4,8")])
    352 
    353 (define_insn "*call_value_indirect_nonlocal_darwin64"
    354   [(set (match_operand 0 "" "")
    355 	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l"))
    356 	      (match_operand 2 "" "g,g,g,g")))
    357    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
    358    (clobber (reg:SI 65))]
    359   "DEFAULT_ABI == ABI_DARWIN"
    360 {
    361   return "b%T1l";
    362 }
    363   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    364    (set_attr "length" "4,4,8,8")])
    365 
    366 (define_insn "*call_value_nonlocal_darwin64"
    367   [(set (match_operand 0 "" "")
    368 	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
    369 	      (match_operand 2 "" "g,g")))
    370    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    371    (clobber (reg:SI 65))]
    372   "(DEFAULT_ABI == ABI_DARWIN)
    373    && (INTVAL (operands[3]) & CALL_LONG) == 0"
    374 {
    375 #if TARGET_MACHO
    376   return output_call(insn, operands, 1, 3);
    377 #else
    378   gcc_unreachable ();
    379 #endif
    380 }
    381   [(set_attr "type" "branch,branch")
    382    (set_attr "length" "4,8")])
    383 
    384 (define_expand "reload_macho_picbase"
    385   [(set (reg:SI 65)
    386         (unspec [(match_operand 0 "" "")]
    387                    UNSPEC_RELD_MPIC))]
    388   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
    389 {
    390   if (TARGET_32BIT)
    391     emit_insn (gen_reload_macho_picbase_si (operands[0]));
    392   else
    393     emit_insn (gen_reload_macho_picbase_di (operands[0]));
    394 
    395   DONE;
    396 })
    397 
    398 (define_insn "reload_macho_picbase_si"
    399   [(set (reg:SI 65)
    400         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
    401 		    (pc)] UNSPEC_RELD_MPIC))]
    402   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
    403 {
    404 #if TARGET_MACHO
    405   if (machopic_should_output_picbase_label ())
    406     {
    407       static char tmp[64];
    408       const char *cnam = machopic_get_function_picbase ();
    409       snprintf (tmp, 64, "bcl 20,31,%s\\n%s:\\n%%0:", cnam, cnam);
    410       return tmp;
    411     }
    412   else
    413 #else
    414   gcc_unreachable ();
    415 #endif
    416     return "bcl 20,31,%0\\n%0:";
    417 }
    418   [(set_attr "type" "branch")
    419    (set_attr "length" "4")])
    420 
    421 (define_insn "reload_macho_picbase_di"
    422   [(set (reg:DI 65)
    423 	(unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
    424 		    (pc)] UNSPEC_RELD_MPIC))]
    425   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
    426 {
    427 #if TARGET_MACHO
    428   if (machopic_should_output_picbase_label ())
    429     {
    430       static char tmp[64];
    431       const char *cnam = machopic_get_function_picbase ();
    432       snprintf (tmp, 64, "bcl 20,31,%s\\n%s:\\n%%0:", cnam, cnam);
    433       return tmp;
    434     }
    435   else
    436 #else
    437   gcc_unreachable ();
    438 #endif
    439     return "bcl 20,31,%0\\n%0:";
    440 }
    441   [(set_attr "type" "branch")
    442    (set_attr "length" "4")])
    443 
    444 ;; We need to restore the PIC register, at the site of nonlocal label.
    445 
    446 (define_insn_and_split "nonlocal_goto_receiver"
    447   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
    448   "TARGET_MACHO && flag_pic"
    449   "#"
    450   "&& reload_completed"
    451   [(const_int 0)]
    452 {
    453 #if TARGET_MACHO
    454   if (crtl->uses_pic_offset_table)
    455     {
    456       static unsigned n = 0;
    457       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
    458       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
    459       rtx tmplrtx;
    460       char tmplab[20];
    461 
    462       ASM_GENERATE_INTERNAL_LABEL(tmplab, "Lnlgr", ++n);
    463       tmplrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
    464 
    465       emit_insn (gen_reload_macho_picbase (tmplrtx));
    466       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
    467       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplrtx));
    468     }
    469   else
    470     /* Not using PIC reg, no reload needed.  */
    471     emit_note (NOTE_INSN_DELETED);
    472 #else
    473   gcc_unreachable ();
    474 #endif
    475   DONE;
    476 })
    477