1/* Machine description patterns for PowerPC running Darwin (Mac OS X). 2 Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. 3 Contributed by Apple Computer Inc. 4 5This file is part of GCC. 6 7GNU CC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GNU CC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You 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 "{cau|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 (\"{cal|la} %0,lo16(%2)(%1)\", operands); 48 output_asm_insn (\"{l|lwz} %L0,4(%0)\", operands); 49 return (\"{l|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 {l|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 {l|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 {st|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 {st|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") 145 (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 146 (match_operand 2 "" ""))))] 147 "TARGET_MACHO && TARGET_64BIT" 148 "{l|ld} %0,lo16(%2)(%1)" 149 [(set_attr "type" "load") 150 (set_attr "length" "4")]) 151 152(define_insn "movsi_low_st" 153 [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 154 (match_operand 2 "" ""))) 155 (match_operand:SI 0 "gpc_reg_operand" "r"))] 156 "TARGET_MACHO && ! TARGET_64BIT" 157 "{st|stw} %0,lo16(%2)(%1)" 158 [(set_attr "type" "store") 159 (set_attr "length" "4")]) 160 161(define_insn "movdi_low_st" 162 [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 163 (match_operand 2 "" ""))) 164 (match_operand:DI 0 "gpc_reg_operand" "r"))] 165 "TARGET_MACHO && TARGET_64BIT" 166 "{st|std} %0,lo16(%2)(%1)" 167 [(set_attr "type" "store") 168 (set_attr "length" "4")]) 169 170;; Mach-O PIC trickery. 171(define_expand "macho_high" 172 [(set (match_operand 0 "" "") 173 (high (match_operand 1 "" "")))] 174 "TARGET_MACHO" 175{ 176 if (TARGET_64BIT) 177 emit_insn (gen_macho_high_di (operands[0], operands[1])); 178 else 179 emit_insn (gen_macho_high_si (operands[0], operands[1])); 180 181 DONE; 182}) 183 184(define_insn "macho_high_si" 185 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 186 (high:SI (match_operand 1 "" "")))] 187 "TARGET_MACHO && ! TARGET_64BIT" 188 "{liu|lis} %0,ha16(%1)") 189 190 191(define_insn "macho_high_di" 192 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 193 (high:DI (match_operand 1 "" "")))] 194 "TARGET_MACHO && TARGET_64BIT" 195 "{liu|lis} %0,ha16(%1)") 196 197(define_expand "macho_low" 198 [(set (match_operand 0 "" "") 199 (lo_sum (match_operand 1 "" "") 200 (match_operand 2 "" "")))] 201 "TARGET_MACHO" 202{ 203 if (TARGET_64BIT) 204 emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2])); 205 else 206 emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2])); 207 208 DONE; 209}) 210 211(define_insn "macho_low_si" 212 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 213 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") 214 (match_operand 2 "" "")))] 215 "TARGET_MACHO && ! TARGET_64BIT" 216 "@ 217 {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)} 218 {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}") 219 220(define_insn "macho_low_di" 221 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 222 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r") 223 (match_operand 2 "" "")))] 224 "TARGET_MACHO && TARGET_64BIT" 225 "@ 226 {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)} 227 {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}") 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 "bcl 20,31,%0\\n%0:" 260 [(set_attr "type" "branch") 261 (set_attr "length" "4")]) 262 263(define_insn "load_macho_picbase_di" 264 [(set (reg:DI 65) 265 (unspec:DI [(match_operand:DI 0 "immediate_operand" "s") 266 (pc)] UNSPEC_LD_MPIC))] 267 "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" 268 "bcl 20,31,%0\\n%0:" 269 [(set_attr "type" "branch") 270 (set_attr "length" "4")]) 271 272(define_expand "macho_correct_pic" 273 [(set (match_operand 0 "" "") 274 (plus (match_operand 1 "" "") 275 (unspec [(match_operand 2 "" "") 276 (match_operand 3 "" "")] 277 UNSPEC_MPIC_CORRECT)))] 278 "DEFAULT_ABI == ABI_DARWIN" 279{ 280 if (TARGET_32BIT) 281 emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2], 282 operands[3])); 283 else 284 emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2], 285 operands[3])); 286 287 DONE; 288}) 289 290(define_insn "macho_correct_pic_si" 291 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 292 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") 293 (unspec:SI [(match_operand:SI 2 "immediate_operand" "s") 294 (match_operand:SI 3 "immediate_operand" "s")] 295 UNSPEC_MPIC_CORRECT)))] 296 "DEFAULT_ABI == ABI_DARWIN" 297 "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" 298 [(set_attr "length" "8")]) 299 300(define_insn "macho_correct_pic_di" 301 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 302 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "r") 303 (unspec:DI [(match_operand:DI 2 "immediate_operand" "s") 304 (match_operand:DI 3 "immediate_operand" "s")] 305 16)))] 306 "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" 307 "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" 308 [(set_attr "length" "8")]) 309 310(define_insn "*call_indirect_nonlocal_darwin64" 311 [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l")) 312 (match_operand 1 "" "g,g,g,g")) 313 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) 314 (clobber (reg:SI 65))] 315 "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" 316{ 317 return "b%T0l"; 318} 319 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 320 (set_attr "length" "4,4,8,8")]) 321 322(define_insn "*call_nonlocal_darwin64" 323 [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) 324 (match_operand 1 "" "g,g")) 325 (use (match_operand:SI 2 "immediate_operand" "O,n")) 326 (clobber (reg:SI 65))] 327 "(DEFAULT_ABI == ABI_DARWIN) 328 && (INTVAL (operands[2]) & CALL_LONG) == 0" 329{ 330#if TARGET_MACHO 331 return output_call(insn, operands, 0, 2); 332#else 333 gcc_unreachable (); 334#endif 335} 336 [(set_attr "type" "branch,branch") 337 (set_attr "length" "4,8")]) 338 339(define_insn "*call_value_indirect_nonlocal_darwin64" 340 [(set (match_operand 0 "" "") 341 (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l")) 342 (match_operand 2 "" "g,g,g,g"))) 343 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) 344 (clobber (reg:SI 65))] 345 "DEFAULT_ABI == ABI_DARWIN" 346{ 347 return "b%T1l"; 348} 349 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 350 (set_attr "length" "4,4,8,8")]) 351 352(define_insn "*call_value_nonlocal_darwin64" 353 [(set (match_operand 0 "" "") 354 (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) 355 (match_operand 2 "" "g,g"))) 356 (use (match_operand:SI 3 "immediate_operand" "O,n")) 357 (clobber (reg:SI 65))] 358 "(DEFAULT_ABI == ABI_DARWIN) 359 && (INTVAL (operands[3]) & CALL_LONG) == 0" 360{ 361#if TARGET_MACHO 362 return output_call(insn, operands, 1, 3); 363#else 364 gcc_unreachable (); 365#endif 366} 367 [(set_attr "type" "branch,branch") 368 (set_attr "length" "4,8")]) 369 370(define_insn "*sibcall_nonlocal_darwin64" 371 [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) 372 (match_operand 1 "" "")) 373 (use (match_operand 2 "immediate_operand" "O,n")) 374 (use (reg:SI 65)) 375 (return)] 376 "(DEFAULT_ABI == ABI_DARWIN) 377 && (INTVAL (operands[2]) & CALL_LONG) == 0" 378{ 379 return "b %z0"; 380} 381 [(set_attr "type" "branch,branch") 382 (set_attr "length" "4,8")]) 383 384(define_insn "*sibcall_value_nonlocal_darwin64" 385 [(set (match_operand 0 "" "") 386 (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) 387 (match_operand 2 "" ""))) 388 (use (match_operand:SI 3 "immediate_operand" "O,n")) 389 (use (reg:SI 65)) 390 (return)] 391 "(DEFAULT_ABI == ABI_DARWIN) 392 && (INTVAL (operands[3]) & CALL_LONG) == 0" 393 "* 394{ 395 return \"b %z1\"; 396}" 397 [(set_attr "type" "branch,branch") 398 (set_attr "length" "4,8")]) 399 400 401(define_insn "*sibcall_symbolic_64" 402 [(call (mem:SI (match_operand:DI 0 "call_operand" "s,c")) ; 64 403 (match_operand 1 "" "")) 404 (use (match_operand 2 "" "")) 405 (use (reg:SI 65)) 406 (return)] 407 "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN" 408 "* 409{ 410 switch (which_alternative) 411 { 412 case 0: return \"b %z0\"; 413 case 1: return \"b%T0\"; 414 default: gcc_unreachable (); 415 } 416}" 417 [(set_attr "type" "branch") 418 (set_attr "length" "4")]) 419 420(define_insn "*sibcall_value_symbolic_64" 421 [(set (match_operand 0 "" "") 422 (call (mem:SI (match_operand:DI 1 "call_operand" "s,c")) 423 (match_operand 2 "" ""))) 424 (use (match_operand:SI 3 "" "")) 425 (use (reg:SI 65)) 426 (return)] 427 "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN" 428 "* 429{ 430 switch (which_alternative) 431 { 432 case 0: return \"b %z1\"; 433 case 1: return \"b%T1\"; 434 default: gcc_unreachable (); 435 } 436}" 437 [(set_attr "type" "branch") 438 (set_attr "length" "4")]) 439