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