Home | History | Annotate | Line # | Download | only in rs6000
darwin.md revision 1.9
      1 /* Machine description patterns for PowerPC running Darwin (Mac OS X).
      2    Copyright (C) 2004-2018 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_64BIT"
     34 {
     35   switch (which_alternative)
     36     {
     37       case 0:
     38 	return "lfd %0,lo16(%2)(%1)";
     39       case 1:
     40 	{
     41 	  if (TARGET_POWERPC64 && TARGET_32BIT)
     42 	    /* Note, old assemblers didn't support relocation here.  */
     43 	    return "ld %0,lo16(%2)(%1)";
     44 	  else
     45 	    {
     46 	      output_asm_insn ("la %0,lo16(%2)(%1)", operands);
     47 	      output_asm_insn ("lwz %L0,4(%0)", operands);
     48 	      return ("lwz %0,0(%0)");
     49 	    }
     50 	}
     51       default:
     52 	gcc_unreachable ();
     53     }
     54 }
     55   [(set_attr "type" "load")
     56    (set_attr "length" "4,12")])
     57 
     58 
     59 (define_insn "movdf_low_di"
     60   [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r")
     61         (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
     62                            (match_operand 2 "" ""))))]
     63   "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
     64 {
     65   switch (which_alternative)
     66     {
     67       case 0:
     68 	return "lfd %0,lo16(%2)(%1)";
     69       case 1:
     70 	return "ld %0,lo16(%2)(%1)";
     71       default:
     72 	gcc_unreachable ();
     73     }
     74 }
     75   [(set_attr "type" "load")
     76    (set_attr "length" "4,4")])
     77 
     78 (define_insn "movdf_low_st_si"
     79   [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
     80                            (match_operand 2 "" "")))
     81 	(match_operand:DF 0 "gpc_reg_operand" "f"))]
     82   "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
     83   "stfd %0,lo16(%2)(%1)"
     84   [(set_attr "type" "store")
     85    (set_attr "length" "4")])
     86 
     87 (define_insn "movdf_low_st_di"
     88   [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
     89                            (match_operand 2 "" "")))
     90 	(match_operand:DF 0 "gpc_reg_operand" "f"))]
     91   "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
     92   "stfd %0,lo16(%2)(%1)"
     93   [(set_attr "type" "store")
     94    (set_attr "length" "4")])
     95 
     96 (define_insn "movsf_low_si"
     97   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
     98         (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
     99                            (match_operand 2 "" ""))))]
    100   "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
    101   "@
    102    lfs %0,lo16(%2)(%1)
    103    lwz %0,lo16(%2)(%1)"
    104   [(set_attr "type" "load")
    105    (set_attr "length" "4")])
    106 
    107 (define_insn "movsf_low_di"
    108   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r")
    109         (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
    110                            (match_operand 2 "" ""))))]
    111   "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
    112   "@
    113    lfs %0,lo16(%2)(%1)
    114    lwz %0,lo16(%2)(%1)"
    115   [(set_attr "type" "load")
    116    (set_attr "length" "4")])
    117 
    118 (define_insn "movsf_low_st_si"
    119   [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b")
    120                            (match_operand 2 "" "")))
    121 	(match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
    122   "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
    123   "@
    124    stfs %0,lo16(%2)(%1)
    125    stw %0,lo16(%2)(%1)"
    126   [(set_attr "type" "store")
    127    (set_attr "length" "4")])
    128 
    129 (define_insn "movsf_low_st_di"
    130   [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b")
    131                            (match_operand 2 "" "")))
    132 	(match_operand:SF 0 "gpc_reg_operand" "f,!r"))]
    133   "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT"
    134   "@
    135    stfs %0,lo16(%2)(%1)
    136    stw %0,lo16(%2)(%1)"
    137   [(set_attr "type" "store")
    138    (set_attr "length" "4")])
    139 
    140 ;; Mach-O PIC trickery.
    141 (define_expand "macho_high"
    142   [(set (match_operand 0 "")
    143 	(high (match_operand 1 "")))]
    144   "TARGET_MACHO"
    145 {
    146   if (TARGET_64BIT)
    147     emit_insn (gen_macho_high_di (operands[0], operands[1]));
    148   else
    149     emit_insn (gen_macho_high_si (operands[0], operands[1]));
    150 
    151   DONE;
    152 })
    153 
    154 (define_insn "macho_high_si"
    155   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
    156 	(high:SI (match_operand 1 "" "")))]
    157   "TARGET_MACHO && ! TARGET_64BIT"
    158   "lis %0,ha16(%1)")
    159 
    160 
    161 (define_insn "macho_high_di"
    162   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
    163 	(high:DI (match_operand 1 "" "")))]
    164   "TARGET_MACHO && TARGET_64BIT"
    165   "lis %0,ha16(%1)")
    166 
    167 (define_expand "macho_low"
    168   [(set (match_operand 0 "")
    169 	(lo_sum (match_operand 1 "")
    170 		   (match_operand 2 "")))]
    171    "TARGET_MACHO"
    172 {
    173   if (TARGET_64BIT)
    174     emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2]));
    175   else
    176     emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2]));
    177 
    178   DONE;
    179 })
    180 
    181 (define_insn "macho_low_si"
    182   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
    183 	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
    184 		   (match_operand 2 "" "")))]
    185    "TARGET_MACHO && ! TARGET_64BIT"
    186    "la %0,lo16(%2)(%1)")
    187 
    188 (define_insn "macho_low_di"
    189   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
    190 	(lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
    191 		   (match_operand 2 "" "")))]
    192    "TARGET_MACHO && TARGET_64BIT"
    193    "la %0,lo16(%2)(%1)")
    194 
    195 (define_split
    196   [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand")
    197 			 (match_operand:DI 1 "short_cint_operand")))
    198 	(match_operand:V4SI 2 "register_operand"))
    199    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
    200   "TARGET_MACHO && TARGET_64BIT"
    201   [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1)))
    202    (set (mem:V4SI (match_dup 3))
    203 	(match_dup 2))]
    204   "")
    205 
    206 (define_expand "load_macho_picbase"
    207   [(set (reg:SI LR_REGNO)
    208         (unspec [(match_operand 0 "")]
    209                    UNSPEC_LD_MPIC))]
    210   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
    211 {
    212   if (TARGET_32BIT)
    213     emit_insn (gen_load_macho_picbase_si (operands[0]));
    214   else
    215     emit_insn (gen_load_macho_picbase_di (operands[0]));
    216 
    217   DONE;
    218 })
    219 
    220 (define_insn "load_macho_picbase_si"
    221   [(set (reg:SI LR_REGNO)
    222 	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
    223 		    (pc)] UNSPEC_LD_MPIC))]
    224   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
    225 {
    226 #if TARGET_MACHO
    227   machopic_should_output_picbase_label (); /* Update for new func.  */
    228 #else
    229   gcc_unreachable ();
    230 #endif
    231   return "bcl 20,31,%0\n%0:";
    232 }
    233   [(set_attr "type" "branch")
    234    (set_attr "cannot_copy" "yes")
    235    (set_attr "length" "4")])
    236 
    237 (define_insn "load_macho_picbase_di"
    238   [(set (reg:DI LR_REGNO)
    239 	(unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
    240 		    (pc)] UNSPEC_LD_MPIC))]
    241   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
    242 {
    243 #if TARGET_MACHO
    244   machopic_should_output_picbase_label (); /* Update for new func.  */
    245 #else
    246   gcc_unreachable ();
    247 #endif
    248   return "bcl 20,31,%0\n%0:";
    249 }
    250   [(set_attr "type" "branch")
    251    (set_attr "cannot_copy" "yes")
    252    (set_attr "length" "4")])
    253 
    254 (define_expand "macho_correct_pic"
    255   [(set (match_operand 0 "")
    256 	(plus (match_operand 1 "")
    257 		 (unspec [(match_operand 2 "")
    258 			     (match_operand 3 "")]
    259 			    UNSPEC_MPIC_CORRECT)))]
    260   "DEFAULT_ABI == ABI_DARWIN"
    261 {
    262   if (TARGET_32BIT)
    263     emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2],
    264 	       operands[3]));
    265   else
    266     emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2],
    267 	       operands[3]));
    268 
    269   DONE;
    270 })
    271 
    272 (define_insn "macho_correct_pic_si"
    273   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
    274 	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
    275 		 (unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
    276 			     (match_operand:SI 3 "immediate_operand" "s")]
    277 			    UNSPEC_MPIC_CORRECT)))]
    278   "DEFAULT_ABI == ABI_DARWIN"
    279   "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
    280   [(set_attr "length" "8")])
    281 
    282 (define_insn "macho_correct_pic_di"
    283   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
    284 	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
    285 		 (unspec:DI [(match_operand:DI 2 "immediate_operand" "s")
    286 			     (match_operand:DI 3 "immediate_operand" "s")]
    287 			    16)))]
    288   "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
    289   "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
    290   [(set_attr "length" "8")])
    291 
    292 (define_insn "*call_indirect_nonlocal_darwin64"
    293   [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l"))
    294 	 (match_operand 1 "" "g,g,g,g"))
    295    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
    296    (clobber (reg:SI LR_REGNO))]
    297   "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT"
    298 {
    299   return "b%T0l";
    300 }
    301   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    302    (set_attr "length" "4,4,8,8")])
    303 
    304 (define_insn "*call_nonlocal_darwin64"
    305   [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
    306 	 (match_operand 1 "" "g,g"))
    307    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    308    (clobber (reg:SI LR_REGNO))]
    309   "(DEFAULT_ABI == ABI_DARWIN)
    310    && (INTVAL (operands[2]) & CALL_LONG) == 0"
    311 {
    312 #if TARGET_MACHO
    313   return output_call(insn, operands, 0, 2);
    314 #else
    315   gcc_unreachable ();
    316 #endif
    317 }
    318   [(set_attr "type" "branch,branch")
    319    (set_attr "length" "4,8")])
    320 
    321 (define_insn "*call_value_indirect_nonlocal_darwin64"
    322   [(set (match_operand 0 "" "")
    323 	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l"))
    324 	      (match_operand 2 "" "g,g,g,g")))
    325    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
    326    (clobber (reg:SI LR_REGNO))]
    327   "DEFAULT_ABI == ABI_DARWIN"
    328 {
    329   return "b%T1l";
    330 }
    331   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    332    (set_attr "length" "4,4,8,8")])
    333 
    334 (define_insn "*call_value_nonlocal_darwin64"
    335   [(set (match_operand 0 "" "")
    336 	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
    337 	      (match_operand 2 "" "g,g")))
    338    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    339    (clobber (reg:SI LR_REGNO))]
    340   "(DEFAULT_ABI == ABI_DARWIN)
    341    && (INTVAL (operands[3]) & CALL_LONG) == 0"
    342 {
    343 #if TARGET_MACHO
    344   return output_call(insn, operands, 1, 3);
    345 #else
    346   gcc_unreachable ();
    347 #endif
    348 }
    349   [(set_attr "type" "branch,branch")
    350    (set_attr "length" "4,8")])
    351 
    352 (define_expand "reload_macho_picbase"
    353   [(set (reg:SI LR_REGNO)
    354         (unspec [(match_operand 0 "")]
    355                    UNSPEC_RELD_MPIC))]
    356   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
    357 {
    358   if (TARGET_32BIT)
    359     emit_insn (gen_reload_macho_picbase_si (operands[0]));
    360   else
    361     emit_insn (gen_reload_macho_picbase_di (operands[0]));
    362 
    363   DONE;
    364 })
    365 
    366 (define_insn "reload_macho_picbase_si"
    367   [(set (reg:SI LR_REGNO)
    368         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
    369 		    (pc)] UNSPEC_RELD_MPIC))]
    370   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
    371 {
    372 #if TARGET_MACHO
    373   if (machopic_should_output_picbase_label ())
    374     {
    375       static char tmp[64];
    376       const char *cnam = machopic_get_function_picbase ();
    377       snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam);
    378       return tmp;
    379     }
    380   else
    381 #else
    382   gcc_unreachable ();
    383 #endif
    384     return "bcl 20,31,%0\n%0:";
    385 }
    386   [(set_attr "type" "branch")
    387    (set_attr "cannot_copy" "yes")
    388    (set_attr "length" "4")])
    389 
    390 (define_insn "reload_macho_picbase_di"
    391   [(set (reg:DI LR_REGNO)
    392 	(unspec:DI [(match_operand:DI 0 "immediate_operand" "s")
    393 		    (pc)] UNSPEC_RELD_MPIC))]
    394   "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT"
    395 {
    396 #if TARGET_MACHO
    397   if (machopic_should_output_picbase_label ())
    398     {
    399       static char tmp[64];
    400       const char *cnam = machopic_get_function_picbase ();
    401       snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam);
    402       return tmp;
    403     }
    404   else
    405 #else
    406   gcc_unreachable ();
    407 #endif
    408     return "bcl 20,31,%0\n%0:";
    409 }
    410   [(set_attr "type" "branch")
    411    (set_attr "cannot_copy" "yes")
    412    (set_attr "length" "4")])
    413 
    414 ;; We need to restore the PIC register, at the site of nonlocal label.
    415 
    416 (define_insn_and_split "nonlocal_goto_receiver"
    417   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
    418   "TARGET_MACHO && flag_pic"
    419   "#"
    420   "&& reload_completed"
    421   [(const_int 0)]
    422 {
    423 #if TARGET_MACHO
    424   if (crtl->uses_pic_offset_table)
    425     {
    426       static unsigned n = 0;
    427       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
    428       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
    429       rtx tmplrtx;
    430       char tmplab[20];
    431 
    432       ASM_GENERATE_INTERNAL_LABEL(tmplab, "Lnlgr", ++n);
    433       tmplrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
    434 
    435       emit_insn (gen_reload_macho_picbase (tmplrtx));
    436       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
    437       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplrtx));
    438     }
    439   else
    440     /* Not using PIC reg, no reload needed.  */
    441     emit_note (NOTE_INSN_DELETED);
    442 #else
    443   gcc_unreachable ();
    444 #endif
    445   DONE;
    446 })
    447