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