1169689Skan/* Machine description patterns for PowerPC running Darwin (Mac OS X). 2169689Skan Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3169689Skan Contributed by Apple Computer Inc. 4169689Skan 5169689SkanThis file is part of GCC. 6169689Skan 7169689SkanGNU CC is free software; you can redistribute it and/or modify 8169689Skanit under the terms of the GNU General Public License as published by 9169689Skanthe Free Software Foundation; either version 2, or (at your option) 10169689Skanany later version. 11169689Skan 12169689SkanGNU CC is distributed in the hope that it will be useful, 13169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of 14169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15169689SkanGNU General Public License for more details. 16169689Skan 17169689SkanYou should have received a copy of the GNU General Public License 18169689Skanalong with GNU CC; see the file COPYING. If not, write to 19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 20169689SkanBoston, MA 02110-1301, USA. */ 21169689Skan 22169689Skan(define_insn "adddi3_high" 23169689Skan [(set (match_operand:DI 0 "gpc_reg_operand" "=b") 24169689Skan (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") 25169689Skan (high:DI (match_operand 2 "" ""))))] 26169689Skan "TARGET_MACHO && TARGET_64BIT" 27169689Skan "{cau|addis} %0,%1,ha16(%2)" 28169689Skan [(set_attr "length" "4")]) 29169689Skan 30169689Skan(define_insn "movdf_low_si" 31169689Skan [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") 32169689Skan (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") 33169689Skan (match_operand 2 "" ""))))] 34169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_64BIT" 35169689Skan "* 36169689Skan{ 37169689Skan switch (which_alternative) 38169689Skan { 39169689Skan case 0: 40169689Skan return \"lfd %0,lo16(%2)(%1)\"; 41169689Skan case 1: 42169689Skan { 43169689Skan if (TARGET_POWERPC64 && TARGET_32BIT) 44169689Skan /* Note, old assemblers didn't support relocation here. */ 45169689Skan return \"ld %0,lo16(%2)(%1)\"; 46169689Skan else 47169689Skan { 48169689Skan output_asm_insn (\"{cal|la} %0,lo16(%2)(%1)\", operands); 49169689Skan output_asm_insn (\"{l|lwz} %L0,4(%0)\", operands); 50169689Skan return (\"{l|lwz} %0,0(%0)\"); 51169689Skan } 52169689Skan } 53169689Skan default: 54169689Skan gcc_unreachable (); 55169689Skan } 56169689Skan}" 57169689Skan [(set_attr "type" "load") 58169689Skan (set_attr "length" "4,12")]) 59169689Skan 60169689Skan 61169689Skan(define_insn "movdf_low_di" 62169689Skan [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") 63169689Skan (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") 64169689Skan (match_operand 2 "" ""))))] 65169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" 66169689Skan "* 67169689Skan{ 68169689Skan switch (which_alternative) 69169689Skan { 70169689Skan case 0: 71169689Skan return \"lfd %0,lo16(%2)(%1)\"; 72169689Skan case 1: 73169689Skan return \"ld %0,lo16(%2)(%1)\"; 74169689Skan default: 75169689Skan gcc_unreachable (); 76169689Skan } 77169689Skan}" 78169689Skan [(set_attr "type" "load") 79169689Skan (set_attr "length" "4,4")]) 80169689Skan 81169689Skan(define_insn "movdf_low_st_si" 82169689Skan [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 83169689Skan (match_operand 2 "" ""))) 84169689Skan (match_operand:DF 0 "gpc_reg_operand" "f"))] 85169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" 86169689Skan "stfd %0,lo16(%2)(%1)" 87169689Skan [(set_attr "type" "store") 88169689Skan (set_attr "length" "4")]) 89169689Skan 90169689Skan(define_insn "movdf_low_st_di" 91169689Skan [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 92169689Skan (match_operand 2 "" ""))) 93169689Skan (match_operand:DF 0 "gpc_reg_operand" "f"))] 94169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" 95169689Skan "stfd %0,lo16(%2)(%1)" 96169689Skan [(set_attr "type" "store") 97169689Skan (set_attr "length" "4")]) 98169689Skan 99169689Skan(define_insn "movsf_low_si" 100169689Skan [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") 101169689Skan (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") 102169689Skan (match_operand 2 "" ""))))] 103169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" 104169689Skan "@ 105169689Skan lfs %0,lo16(%2)(%1) 106169689Skan {l|lwz} %0,lo16(%2)(%1)" 107169689Skan [(set_attr "type" "load") 108169689Skan (set_attr "length" "4")]) 109169689Skan 110169689Skan(define_insn "movsf_low_di" 111169689Skan [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") 112169689Skan (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") 113169689Skan (match_operand 2 "" ""))))] 114169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" 115169689Skan "@ 116169689Skan lfs %0,lo16(%2)(%1) 117169689Skan {l|lwz} %0,lo16(%2)(%1)" 118169689Skan [(set_attr "type" "load") 119169689Skan (set_attr "length" "4")]) 120169689Skan 121169689Skan(define_insn "movsf_low_st_si" 122169689Skan [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") 123169689Skan (match_operand 2 "" ""))) 124169689Skan (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] 125169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" 126169689Skan "@ 127169689Skan stfs %0,lo16(%2)(%1) 128169689Skan {st|stw} %0,lo16(%2)(%1)" 129169689Skan [(set_attr "type" "store") 130169689Skan (set_attr "length" "4")]) 131169689Skan 132169689Skan(define_insn "movsf_low_st_di" 133169689Skan [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") 134169689Skan (match_operand 2 "" ""))) 135169689Skan (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] 136169689Skan "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" 137169689Skan "@ 138169689Skan stfs %0,lo16(%2)(%1) 139169689Skan {st|stw} %0,lo16(%2)(%1)" 140169689Skan [(set_attr "type" "store") 141169689Skan (set_attr "length" "4")]) 142169689Skan 143169689Skan;; 64-bit MachO load/store support 144169689Skan(define_insn "movdi_low" 145169689Skan [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 146169689Skan (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 147169689Skan (match_operand 2 "" ""))))] 148169689Skan "TARGET_MACHO && TARGET_64BIT" 149169689Skan "{l|ld} %0,lo16(%2)(%1)" 150169689Skan [(set_attr "type" "load") 151169689Skan (set_attr "length" "4")]) 152169689Skan 153169689Skan(define_insn "movsi_low_st" 154169689Skan [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 155169689Skan (match_operand 2 "" ""))) 156169689Skan (match_operand:SI 0 "gpc_reg_operand" "r"))] 157169689Skan "TARGET_MACHO && ! TARGET_64BIT" 158169689Skan "{st|stw} %0,lo16(%2)(%1)" 159169689Skan [(set_attr "type" "store") 160169689Skan (set_attr "length" "4")]) 161169689Skan 162169689Skan(define_insn "movdi_low_st" 163169689Skan [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 164169689Skan (match_operand 2 "" ""))) 165169689Skan (match_operand:DI 0 "gpc_reg_operand" "r"))] 166169689Skan "TARGET_MACHO && TARGET_64BIT" 167169689Skan "{st|std} %0,lo16(%2)(%1)" 168169689Skan [(set_attr "type" "store") 169169689Skan (set_attr "length" "4")]) 170169689Skan 171169689Skan;; Mach-O PIC trickery. 172169689Skan(define_expand "macho_high" 173169689Skan [(set (match_operand 0 "" "") 174169689Skan (high (match_operand 1 "" "")))] 175169689Skan "TARGET_MACHO" 176169689Skan{ 177169689Skan if (TARGET_64BIT) 178169689Skan emit_insn (gen_macho_high_di (operands[0], operands[1])); 179169689Skan else 180169689Skan emit_insn (gen_macho_high_si (operands[0], operands[1])); 181169689Skan 182169689Skan DONE; 183169689Skan}) 184169689Skan 185169689Skan(define_insn "macho_high_si" 186169689Skan [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 187169689Skan (high:SI (match_operand 1 "" "")))] 188169689Skan "TARGET_MACHO && ! TARGET_64BIT" 189169689Skan "{liu|lis} %0,ha16(%1)") 190169689Skan 191169689Skan 192169689Skan(define_insn "macho_high_di" 193169689Skan [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 194169689Skan (high:DI (match_operand 1 "" "")))] 195169689Skan "TARGET_MACHO && TARGET_64BIT" 196169689Skan "{liu|lis} %0,ha16(%1)") 197169689Skan 198169689Skan(define_expand "macho_low" 199169689Skan [(set (match_operand 0 "" "") 200169689Skan (lo_sum (match_operand 1 "" "") 201169689Skan (match_operand 2 "" "")))] 202169689Skan "TARGET_MACHO" 203169689Skan{ 204169689Skan if (TARGET_64BIT) 205169689Skan emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2])); 206169689Skan else 207169689Skan emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2])); 208169689Skan 209169689Skan DONE; 210169689Skan}) 211169689Skan 212169689Skan(define_insn "macho_low_si" 213169689Skan [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 214169689Skan (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") 215169689Skan (match_operand 2 "" "")))] 216169689Skan "TARGET_MACHO && ! TARGET_64BIT" 217169689Skan "@ 218169689Skan {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)} 219169689Skan {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}") 220169689Skan 221169689Skan(define_insn "macho_low_di" 222169689Skan [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 223169689Skan (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r") 224169689Skan (match_operand 2 "" "")))] 225169689Skan "TARGET_MACHO && TARGET_64BIT" 226169689Skan "@ 227169689Skan {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)} 228169689Skan {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}") 229169689Skan 230169689Skan(define_split 231169689Skan [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand" "") 232169689Skan (match_operand:DI 1 "short_cint_operand" ""))) 233169689Skan (match_operand:V4SI 2 "register_operand" "")) 234169689Skan (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 235169689Skan "TARGET_MACHO && TARGET_64BIT" 236169689Skan [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1))) 237169689Skan (set (mem:V4SI (match_dup 3)) 238169689Skan (match_dup 2))] 239169689Skan "") 240169689Skan 241169689Skan(define_expand "load_macho_picbase" 242169689Skan [(set (match_operand 0 "" "") 243169689Skan (unspec [(match_operand 1 "" "")] 244169689Skan UNSPEC_LD_MPIC))] 245169689Skan "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" 246169689Skan{ 247169689Skan if (TARGET_32BIT) 248169689Skan emit_insn (gen_load_macho_picbase_si (operands[0], operands[1])); 249169689Skan else 250169689Skan emit_insn (gen_load_macho_picbase_di (operands[0], operands[1])); 251169689Skan 252169689Skan DONE; 253169689Skan}) 254169689Skan 255169689Skan(define_insn "load_macho_picbase_si" 256169689Skan [(set (match_operand:SI 0 "register_operand" "=l") 257169689Skan (unspec:SI [(match_operand:SI 1 "immediate_operand" "s") 258169689Skan (pc)] UNSPEC_LD_MPIC))] 259169689Skan "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" 260169689Skan "bcl 20,31,%1\\n%1:" 261169689Skan [(set_attr "type" "branch") 262169689Skan (set_attr "length" "4")]) 263169689Skan 264169689Skan(define_insn "load_macho_picbase_di" 265169689Skan [(set (match_operand:DI 0 "register_operand" "=l") 266169689Skan (unspec:DI [(match_operand:DI 1 "immediate_operand" "s") 267169689Skan (pc)] UNSPEC_LD_MPIC))] 268169689Skan "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" 269169689Skan "bcl 20,31,%1\\n%1:" 270169689Skan [(set_attr "type" "branch") 271169689Skan (set_attr "length" "4")]) 272169689Skan 273169689Skan(define_expand "macho_correct_pic" 274169689Skan [(set (match_operand 0 "" "") 275169689Skan (plus (match_operand 1 "" "") 276169689Skan (unspec [(match_operand 2 "" "") 277169689Skan (match_operand 3 "" "")] 278169689Skan UNSPEC_MPIC_CORRECT)))] 279169689Skan "DEFAULT_ABI == ABI_DARWIN" 280169689Skan{ 281169689Skan if (TARGET_32BIT) 282169689Skan emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2], 283169689Skan operands[3])); 284169689Skan else 285169689Skan emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2], 286169689Skan operands[3])); 287169689Skan 288169689Skan DONE; 289169689Skan}) 290169689Skan 291169689Skan(define_insn "macho_correct_pic_si" 292169689Skan [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 293169689Skan (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") 294169689Skan (unspec:SI [(match_operand:SI 2 "immediate_operand" "s") 295169689Skan (match_operand:SI 3 "immediate_operand" "s")] 296169689Skan UNSPEC_MPIC_CORRECT)))] 297169689Skan "DEFAULT_ABI == ABI_DARWIN" 298169689Skan "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" 299169689Skan [(set_attr "length" "8")]) 300169689Skan 301169689Skan(define_insn "macho_correct_pic_di" 302169689Skan [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 303169689Skan (plus:DI (match_operand:DI 1 "gpc_reg_operand" "r") 304169689Skan (unspec:DI [(match_operand:DI 2 "immediate_operand" "s") 305169689Skan (match_operand:DI 3 "immediate_operand" "s")] 306169689Skan 16)))] 307169689Skan "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" 308169689Skan "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" 309169689Skan [(set_attr "length" "8")]) 310169689Skan 311169689Skan(define_insn "*call_indirect_nonlocal_darwin64" 312169689Skan [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l")) 313169689Skan (match_operand 1 "" "g,g,g,g")) 314169689Skan (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) 315169689Skan (clobber (match_scratch:SI 3 "=l,l,l,l"))] 316169689Skan "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" 317169689Skan{ 318169689Skan return "b%T0l"; 319169689Skan} 320169689Skan [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 321169689Skan (set_attr "length" "4,4,8,8")]) 322169689Skan 323169689Skan(define_insn "*call_nonlocal_darwin64" 324169689Skan [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) 325169689Skan (match_operand 1 "" "g,g")) 326169689Skan (use (match_operand:SI 2 "immediate_operand" "O,n")) 327169689Skan (clobber (match_scratch:SI 3 "=l,l"))] 328169689Skan "(DEFAULT_ABI == ABI_DARWIN) 329169689Skan && (INTVAL (operands[2]) & CALL_LONG) == 0" 330169689Skan{ 331169689Skan#if TARGET_MACHO 332169689Skan return output_call(insn, operands, 0, 2); 333169689Skan#else 334169689Skan gcc_unreachable (); 335169689Skan#endif 336169689Skan} 337169689Skan [(set_attr "type" "branch,branch") 338169689Skan (set_attr "length" "4,8")]) 339169689Skan 340169689Skan(define_insn "*call_value_indirect_nonlocal_darwin64" 341169689Skan [(set (match_operand 0 "" "") 342169689Skan (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l")) 343169689Skan (match_operand 2 "" "g,g,g,g"))) 344169689Skan (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) 345169689Skan (clobber (match_scratch:SI 4 "=l,l,l,l"))] 346169689Skan "DEFAULT_ABI == ABI_DARWIN" 347169689Skan{ 348169689Skan return "b%T1l"; 349169689Skan} 350169689Skan [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 351169689Skan (set_attr "length" "4,4,8,8")]) 352169689Skan 353169689Skan(define_insn "*call_value_nonlocal_darwin64" 354169689Skan [(set (match_operand 0 "" "") 355169689Skan (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) 356169689Skan (match_operand 2 "" "g,g"))) 357169689Skan (use (match_operand:SI 3 "immediate_operand" "O,n")) 358169689Skan (clobber (match_scratch:SI 4 "=l,l"))] 359169689Skan "(DEFAULT_ABI == ABI_DARWIN) 360169689Skan && (INTVAL (operands[3]) & CALL_LONG) == 0" 361169689Skan{ 362169689Skan#if TARGET_MACHO 363169689Skan return output_call(insn, operands, 1, 3); 364169689Skan#else 365169689Skan gcc_unreachable (); 366169689Skan#endif 367169689Skan} 368169689Skan [(set_attr "type" "branch,branch") 369169689Skan (set_attr "length" "4,8")]) 370169689Skan 371169689Skan(define_insn "*sibcall_nonlocal_darwin64" 372169689Skan [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) 373169689Skan (match_operand 1 "" "")) 374169689Skan (use (match_operand 2 "immediate_operand" "O,n")) 375169689Skan (use (match_operand:SI 3 "register_operand" "l,l")) 376169689Skan (return)] 377169689Skan "(DEFAULT_ABI == ABI_DARWIN) 378169689Skan && (INTVAL (operands[2]) & CALL_LONG) == 0" 379169689Skan{ 380169689Skan return "b %z0"; 381169689Skan} 382169689Skan [(set_attr "type" "branch,branch") 383169689Skan (set_attr "length" "4,8")]) 384169689Skan 385169689Skan(define_insn "*sibcall_value_nonlocal_darwin64" 386169689Skan [(set (match_operand 0 "" "") 387169689Skan (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) 388169689Skan (match_operand 2 "" ""))) 389169689Skan (use (match_operand:SI 3 "immediate_operand" "O,n")) 390169689Skan (use (match_operand:SI 4 "register_operand" "l,l")) 391169689Skan (return)] 392169689Skan "(DEFAULT_ABI == ABI_DARWIN) 393169689Skan && (INTVAL (operands[3]) & CALL_LONG) == 0" 394169689Skan "* 395169689Skan{ 396169689Skan return \"b %z1\"; 397169689Skan}" 398169689Skan [(set_attr "type" "branch,branch") 399169689Skan (set_attr "length" "4,8")]) 400169689Skan 401169689Skan 402169689Skan(define_insn "*sibcall_symbolic_64" 403169689Skan [(call (mem:SI (match_operand:DI 0 "call_operand" "s,c")) ; 64 404169689Skan (match_operand 1 "" "")) 405169689Skan (use (match_operand 2 "" "")) 406169689Skan (use (match_operand:SI 3 "register_operand" "l,l")) 407169689Skan (return)] 408169689Skan "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN" 409169689Skan "* 410169689Skan{ 411169689Skan switch (which_alternative) 412169689Skan { 413169689Skan case 0: return \"b %z0\"; 414169689Skan case 1: return \"b%T0\"; 415169689Skan default: gcc_unreachable (); 416169689Skan } 417169689Skan}" 418169689Skan [(set_attr "type" "branch") 419169689Skan (set_attr "length" "4")]) 420169689Skan 421169689Skan(define_insn "*sibcall_value_symbolic_64" 422169689Skan [(set (match_operand 0 "" "") 423169689Skan (call (mem:SI (match_operand:DI 1 "call_operand" "s,c")) 424169689Skan (match_operand 2 "" ""))) 425169689Skan (use (match_operand:SI 3 "" "")) 426169689Skan (use (match_operand:SI 4 "register_operand" "l,l")) 427169689Skan (return)] 428169689Skan "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN" 429169689Skan "* 430169689Skan{ 431169689Skan switch (which_alternative) 432169689Skan { 433169689Skan case 0: return \"b %z1\"; 434169689Skan case 1: return \"b%T1\"; 435169689Skan default: gcc_unreachable (); 436169689Skan } 437169689Skan}" 438169689Skan [(set_attr "type" "branch") 439169689Skan (set_attr "length" "4")]) 440169689Skan 441