164 165def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 166 NoItinerary, "@ add\t$dst, $rhs", []>; 167 168let Defs = [CPSR] in 169def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 170 NoItinerary, "@ and\t$dst, $rhs", []>; 171} // usesCustomInserter 172 173//===----------------------------------------------------------------------===// 174// Control Flow Instructions. 175// 176 177let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 178 def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; 179 // Alternative return instruction used by vararg functions. 180 def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>; 181} 182 183// Indirect branches 184let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 185 def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", 186 [(brind GPR:$dst)]>; 187} 188 189// FIXME: remove when we have a way to marking a MI with these properties. 190let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 191 hasExtraDefRegAllocReq = 1 in 192def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 193 "pop${p}\t$wb", []>; 194 195let isCall = 1, 196 Defs = [R0, R1, R2, R3, R12, LR, 197 D0, D1, D2, D3, D4, D5, D6, D7, 198 D16, D17, D18, D19, D20, D21, D22, D23, 199 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 200 // Also used for Thumb2 201 def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 202 "bl\t${func:call}", 203 [(ARMtcall tglobaladdr:$func)]>, 204 Requires<[IsThumb, IsNotDarwin]>; 205 206 // ARMv5T and above, also used for Thumb2 207 def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 208 "blx\t${func:call}", 209 [(ARMcall tglobaladdr:$func)]>, 210 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 211 212 // Also used for Thumb2 213 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 214 "blx\t$func", 215 [(ARMtcall GPR:$func)]>, 216 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 217 218 // ARMv4T 219 def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 220 "mov\tlr, pc\n\tbx\t$func", 221 [(ARMcall_nolink tGPR:$func)]>, 222 Requires<[IsThumb1Only, IsNotDarwin]>; 223} 224 225// On Darwin R9 is call-clobbered. 226let isCall = 1, 227 Defs = [R0, R1, R2, R3, R9, R12, LR, 228 D0, D1, D2, D3, D4, D5, D6, D7, 229 D16, D17, D18, D19, D20, D21, D22, D23, 230 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 231 // Also used for Thumb2 232 def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 233 "bl\t${func:call}", 234 [(ARMtcall tglobaladdr:$func)]>, 235 Requires<[IsThumb, IsDarwin]>; 236 237 // ARMv5T and above, also used for Thumb2 238 def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 239 "blx\t${func:call}", 240 [(ARMcall tglobaladdr:$func)]>, 241 Requires<[IsThumb, HasV5T, IsDarwin]>; 242 243 // Also used for Thumb2 244 def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 245 "blx\t$func", 246 [(ARMtcall GPR:$func)]>, 247 Requires<[IsThumb, HasV5T, IsDarwin]>; 248 249 // ARMv4T 250 def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 251 "mov\tlr, pc\n\tbx\t$func", 252 [(ARMcall_nolink tGPR:$func)]>, 253 Requires<[IsThumb1Only, IsDarwin]>; 254} 255 256let isBranch = 1, isTerminator = 1 in { 257 let isBarrier = 1 in { 258 let isPredicable = 1 in 259 def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 260 "b\t$target", [(br bb:$target)]>; 261 262 // Far jump 263 let Defs = [LR] in 264 def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 265 "bl\t$target\t@ far jump",[]>; 266 267 def tBR_JTr : T1JTI<(outs), 268 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 269 IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", 270 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; 271 } 272} 273 274// FIXME: should be able to write a pattern for ARMBrcond, but can't use 275// a two-value operand where a dag node expects two operands. :( 276let isBranch = 1, isTerminator = 1 in 277 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 278 "b$cc\t$target", 279 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 280 281// Compare and branch on zero / non-zero 282let isBranch = 1, isTerminator = 1 in { 283 def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 284 "cbz\t$cmp, $target", []>; 285 286 def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 287 "cbnz\t$cmp, $target", []>; 288} 289 290//===----------------------------------------------------------------------===// 291// Load Store Instructions. 292// 293 294let canFoldAsLoad = 1 in 295def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 296 "ldr", "\t$dst, $addr", 297 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 298 299def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 300 "ldrb", "\t$dst, $addr", 301 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 302 303def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 304 "ldrh", "\t$dst, $addr", 305 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 306 307let AddedComplexity = 10 in 308def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 309 "ldrsb", "\t$dst, $addr", 310 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 311 312let AddedComplexity = 10 in 313def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 314 "ldrsh", "\t$dst, $addr", 315 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 316 317let canFoldAsLoad = 1 in 318def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 319 "ldr", "\t$dst, $addr", 320 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 321 322// Special instruction for restore. It cannot clobber condition register 323// when it's expanded by eliminateCallFramePseudoInstr(). 324let canFoldAsLoad = 1, mayLoad = 1 in 325def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 326 "ldr", "\t$dst, $addr", []>; 327 328// Load tconstpool 329// FIXME: Use ldr.n to work around a Darwin assembler bug. 330let canFoldAsLoad = 1 in 331def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 332 "ldr", ".n\t$dst, $addr", 333 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 334 335// Special LDR for loads from non-pc-relative constpools. 336let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in 337def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 338 "ldr", "\t$dst, $addr", []>; 339 340def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 341 "str", "\t$src, $addr", 342 [(store tGPR:$src, t_addrmode_s4:$addr)]>; 343 344def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 345 "strb", "\t$src, $addr", 346 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 347 348def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 349 "strh", "\t$src, $addr", 350 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 351 352def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 353 "str", "\t$src, $addr", 354 [(store tGPR:$src, t_addrmode_sp:$addr)]>; 355 356let mayStore = 1 in { 357// Special instruction for spill. It cannot clobber condition register 358// when it's expanded by eliminateCallFramePseudoInstr(). 359def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 360 "str", "\t$src, $addr", []>; 361} 362 363//===----------------------------------------------------------------------===// 364// Load / store multiple Instructions. 365// 366 367// These requires base address to be written back or one of the loaded regs. 368let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 369def tLDM : T1I<(outs), 370 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 371 IIC_iLoadm, 372 "ldm${addr:submode}${p}\t$addr, $wb", []>; 373 374let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 375def tSTM : T1I<(outs), 376 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 377 IIC_iStorem, 378 "stm${addr:submode}${p}\t$addr, $wb", []>; 379 380let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 381def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 382 "pop${p}\t$wb", []>; 383 384let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 385def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 386 "push${p}\t$wb", []>; 387 388//===----------------------------------------------------------------------===// 389// Arithmetic Instructions. 390// 391 392// Add with carry register 393let isCommutable = 1, Uses = [CPSR] in 394def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 395 "adc", "\t$dst, $rhs", 396 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; 397 398// Add immediate 399def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 400 "add", "\t$dst, $lhs, $rhs", 401 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; 402 403def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 404 "add", "\t$dst, $rhs", 405 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; 406 407// Add register 408let isCommutable = 1 in 409def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 410 "add", "\t$dst, $lhs, $rhs", 411 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; 412 413let neverHasSideEffects = 1 in 414def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 415 "add", "\t$dst, $rhs", []>; 416 417// And register 418let isCommutable = 1 in 419def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 420 "and", "\t$dst, $rhs", 421 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; 422 423// ASR immediate 424def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 425 "asr", "\t$dst, $lhs, $rhs", 426 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; 427 428// ASR register 429def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 430 "asr", "\t$dst, $rhs", 431 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; 432 433// BIC register 434def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 435 "bic", "\t$dst, $rhs", 436 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 437 438// CMN register 439let Defs = [CPSR] in { 440def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 441 "cmn", "\t$lhs, $rhs", 442 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; 443def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 444 "cmn", "\t$lhs, $rhs", 445 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; 446} 447 448// CMP immediate 449let Defs = [CPSR] in { 450def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 451 "cmp", "\t$lhs, $rhs", 452 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; 453def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 454 "cmp", "\t$lhs, $rhs", 455 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; 456 457} 458 459// CMP register 460let Defs = [CPSR] in { 461def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 462 "cmp", "\t$lhs, $rhs", 463 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; 464def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 465 "cmp", "\t$lhs, $rhs", 466 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; 467 468def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 469 "cmp", "\t$lhs, $rhs", []>; 470def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 471 "cmp", "\t$lhs, $rhs", []>; 472} 473 474 475// XOR register 476let isCommutable = 1 in 477def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 478 "eor", "\t$dst, $rhs", 479 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; 480 481// LSL immediate 482def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 483 "lsl", "\t$dst, $lhs, $rhs", 484 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; 485 486// LSL register 487def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 488 "lsl", "\t$dst, $rhs", 489 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; 490 491// LSR immediate 492def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 493 "lsr", "\t$dst, $lhs, $rhs", 494 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; 495 496// LSR register 497def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 498 "lsr", "\t$dst, $rhs", 499 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; 500 501// move register 502def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 503 "mov", "\t$dst, $src", 504 [(set tGPR:$dst, imm0_255:$src)]>; 505 506// TODO: A7-73: MOV(2) - mov setting flag. 507 508 509let neverHasSideEffects = 1 in { 510// FIXME: Make this predicable. 511def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 512 "mov\t$dst, $src", []>; 513let Defs = [CPSR] in 514def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 515 "movs\t$dst, $src", []>; 516 517// FIXME: Make these predicable. 518def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 519 "mov\t$dst, $src", []>; 520def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 521 "mov\t$dst, $src", []>; 522def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 523 "mov\t$dst, $src", []>; 524} // neverHasSideEffects 525 526// multiply register 527let isCommutable = 1 in 528def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 529 "mul", "\t$dst, $rhs", 530 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; 531 532// move inverse register 533def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 534 "mvn", "\t$dst, $src", 535 [(set tGPR:$dst, (not tGPR:$src))]>; 536 537// bitwise or register 538let isCommutable = 1 in 539def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 540 "orr", "\t$dst, $rhs", 541 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; 542 543// swaps 544def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 545 "rev", "\t$dst, $src", 546 [(set tGPR:$dst, (bswap tGPR:$src))]>, 547 Requires<[IsThumb1Only, HasV6]>; 548 549def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 550 "rev16", "\t$dst, $src", 551 [(set tGPR:$dst, 552 (or (and (srl tGPR:$src, (i32 8)), 0xFF), 553 (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 554 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 555 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 556 Requires<[IsThumb1Only, HasV6]>; 557 558def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 559 "revsh", "\t$dst, $src", 560 [(set tGPR:$dst, 561 (sext_inreg 562 (or (srl (and tGPR:$src, 0xFF00), (i32 8)), 563 (shl tGPR:$src, (i32 8))), i16))]>, 564 Requires<[IsThumb1Only, HasV6]>; 565 566// rotate right register 567def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 568 "ror", "\t$dst, $rhs", 569 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; 570 571// negate register 572def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, 573 "rsb", "\t$dst, $src, #0", 574 [(set tGPR:$dst, (ineg tGPR:$src))]>; 575 576// Subtract with carry register 577let Uses = [CPSR] in 578def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 579 "sbc", "\t$dst, $rhs", 580 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; 581 582// Subtract immediate 583def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 584 "sub", "\t$dst, $lhs, $rhs", 585 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; 586 587def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 588 "sub", "\t$dst, $rhs", 589 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>; 590 591// subtract register 592def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 593 "sub", "\t$dst, $lhs, $rhs", 594 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; 595 596// TODO: A7-96: STMIA - store multiple. 597 598// sign-extend byte 599def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 600 "sxtb", "\t$dst, $src", 601 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 602 Requires<[IsThumb1Only, HasV6]>; 603 604// sign-extend short 605def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 606 "sxth", "\t$dst, $src", 607 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 608 Requires<[IsThumb1Only, HasV6]>; 609 610// test 611let isCommutable = 1, Defs = [CPSR] in 612def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 613 "tst", "\t$lhs, $rhs", 614 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; 615 616// zero-extend byte 617def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 618 "uxtb", "\t$dst, $src", 619 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 620 Requires<[IsThumb1Only, HasV6]>; 621 622// zero-extend short 623def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 624 "uxth", "\t$dst, $src", 625 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 626 Requires<[IsThumb1Only, HasV6]>; 627 628 629// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. 630// Expanded after instruction selection into a branch sequence. 631let usesCustomInserter = 1 in // Expanded after instruction selection. 632 def tMOVCCr_pseudo : 633 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 634 NoItinerary, "@ tMOVCCr $cc", 635 [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 636 637 638// 16-bit movcc in IT blocks for Thumb2. 639def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 640 "mov", "\t$dst, $rhs", []>; 641 642def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 643 "mov", "\t$dst, $rhs", []>; 644 645// tLEApcrel - Load a pc-relative address into a register without offending the 646// assembler. 647def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, 648 "adr$p\t$dst, #$label", []>; 649 650def tLEApcrelJT : T1I<(outs tGPR:$dst), 651 (ins i32imm:$label, nohash_imm:$id, pred:$p), 652 IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>; 653 654//===----------------------------------------------------------------------===// 655// TLS Instructions 656// 657 658// __aeabi_read_tp preserves the registers r1-r3. 659let isCall = 1, 660 Defs = [R0, LR] in { 661 def tTPsoft : TIx2<(outs), (ins), IIC_Br, 662 "bl\t__aeabi_read_tp", 663 [(set R0, ARMthread_pointer)]>; 664} 665 666//===----------------------------------------------------------------------===// 667// Non-Instruction Patterns 668// 669 670// Add with carry 671def : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 672 (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 673def : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 674 (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 675def : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 676 (tADDrr tGPR:$lhs, tGPR:$rhs)>; 677 678// Subtract with carry 679def : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 680 (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 681def : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 682 (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 683def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 684 (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 685 686// ConstantPool, GlobalAddress 687def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 688def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 689 690// JumpTable 691def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 692 (tLEApcrelJT tjumptable:$dst, imm:$id)>; 693 694// Direct calls 695def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 696 Requires<[IsThumb, IsNotDarwin]>; 697def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 698 Requires<[IsThumb, IsDarwin]>; 699 700def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 701 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 702def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 703 Requires<[IsThumb, HasV5T, IsDarwin]>; 704 705// Indirect calls to ARM routines 706def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 707 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 708def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 709 Requires<[IsThumb, HasV5T, IsDarwin]>; 710 711// zextload i1 -> zextload i8 712def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 713 (tLDRB t_addrmode_s1:$addr)>; 714 715// extload -> zextload 716def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 717def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 718def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 719 720// If it's impossible to use [r,r] address mode for sextload, select to 721// ldr{b|h} + sxt{b|h} instead. 722def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 723 (tSXTB (tLDRB t_addrmode_s1:$addr))>, 724 Requires<[IsThumb1Only, HasV6]>; 725def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 726 (tSXTH (tLDRH t_addrmode_s2:$addr))>, 727 Requires<[IsThumb1Only, HasV6]>; 728 729def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 730 (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 731def : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 732 (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 733 734// Large immediate handling. 735 736// Two piece imms. 737def : T1Pat<(i32 thumb_immshifted:$src), 738 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 739 (thumb_immshifted_shamt imm:$src))>; 740 741def : T1Pat<(i32 imm0_255_comp:$src), 742 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 743 744// Pseudo instruction that combines ldr from constpool and add pc. This should 745// be expanded into two instructions late to allow if-conversion and 746// scheduling. 747let isReMaterializable = 1 in 748def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 749 NoItinerary, "@ ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc", 750 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 751 imm:$cp))]>, 752 Requires<[IsThumb1Only]>;
| 169 170def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 171 NoItinerary, "@ add\t$dst, $rhs", []>; 172 173let Defs = [CPSR] in 174def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 175 NoItinerary, "@ and\t$dst, $rhs", []>; 176} // usesCustomInserter 177 178//===----------------------------------------------------------------------===// 179// Control Flow Instructions. 180// 181 182let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 183 def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; 184 // Alternative return instruction used by vararg functions. 185 def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>; 186} 187 188// Indirect branches 189let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 190 def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", 191 [(brind GPR:$dst)]>; 192} 193 194// FIXME: remove when we have a way to marking a MI with these properties. 195let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 196 hasExtraDefRegAllocReq = 1 in 197def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 198 "pop${p}\t$wb", []>; 199 200let isCall = 1, 201 Defs = [R0, R1, R2, R3, R12, LR, 202 D0, D1, D2, D3, D4, D5, D6, D7, 203 D16, D17, D18, D19, D20, D21, D22, D23, 204 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 205 // Also used for Thumb2 206 def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 207 "bl\t${func:call}", 208 [(ARMtcall tglobaladdr:$func)]>, 209 Requires<[IsThumb, IsNotDarwin]>; 210 211 // ARMv5T and above, also used for Thumb2 212 def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 213 "blx\t${func:call}", 214 [(ARMcall tglobaladdr:$func)]>, 215 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 216 217 // Also used for Thumb2 218 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 219 "blx\t$func", 220 [(ARMtcall GPR:$func)]>, 221 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 222 223 // ARMv4T 224 def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 225 "mov\tlr, pc\n\tbx\t$func", 226 [(ARMcall_nolink tGPR:$func)]>, 227 Requires<[IsThumb1Only, IsNotDarwin]>; 228} 229 230// On Darwin R9 is call-clobbered. 231let isCall = 1, 232 Defs = [R0, R1, R2, R3, R9, R12, LR, 233 D0, D1, D2, D3, D4, D5, D6, D7, 234 D16, D17, D18, D19, D20, D21, D22, D23, 235 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 236 // Also used for Thumb2 237 def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 238 "bl\t${func:call}", 239 [(ARMtcall tglobaladdr:$func)]>, 240 Requires<[IsThumb, IsDarwin]>; 241 242 // ARMv5T and above, also used for Thumb2 243 def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 244 "blx\t${func:call}", 245 [(ARMcall tglobaladdr:$func)]>, 246 Requires<[IsThumb, HasV5T, IsDarwin]>; 247 248 // Also used for Thumb2 249 def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 250 "blx\t$func", 251 [(ARMtcall GPR:$func)]>, 252 Requires<[IsThumb, HasV5T, IsDarwin]>; 253 254 // ARMv4T 255 def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 256 "mov\tlr, pc\n\tbx\t$func", 257 [(ARMcall_nolink tGPR:$func)]>, 258 Requires<[IsThumb1Only, IsDarwin]>; 259} 260 261let isBranch = 1, isTerminator = 1 in { 262 let isBarrier = 1 in { 263 let isPredicable = 1 in 264 def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 265 "b\t$target", [(br bb:$target)]>; 266 267 // Far jump 268 let Defs = [LR] in 269 def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 270 "bl\t$target\t@ far jump",[]>; 271 272 def tBR_JTr : T1JTI<(outs), 273 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 274 IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", 275 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; 276 } 277} 278 279// FIXME: should be able to write a pattern for ARMBrcond, but can't use 280// a two-value operand where a dag node expects two operands. :( 281let isBranch = 1, isTerminator = 1 in 282 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 283 "b$cc\t$target", 284 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 285 286// Compare and branch on zero / non-zero 287let isBranch = 1, isTerminator = 1 in { 288 def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 289 "cbz\t$cmp, $target", []>; 290 291 def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 292 "cbnz\t$cmp, $target", []>; 293} 294 295//===----------------------------------------------------------------------===// 296// Load Store Instructions. 297// 298 299let canFoldAsLoad = 1 in 300def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 301 "ldr", "\t$dst, $addr", 302 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 303 304def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 305 "ldrb", "\t$dst, $addr", 306 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 307 308def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 309 "ldrh", "\t$dst, $addr", 310 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 311 312let AddedComplexity = 10 in 313def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 314 "ldrsb", "\t$dst, $addr", 315 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 316 317let AddedComplexity = 10 in 318def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 319 "ldrsh", "\t$dst, $addr", 320 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 321 322let canFoldAsLoad = 1 in 323def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 324 "ldr", "\t$dst, $addr", 325 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 326 327// Special instruction for restore. It cannot clobber condition register 328// when it's expanded by eliminateCallFramePseudoInstr(). 329let canFoldAsLoad = 1, mayLoad = 1 in 330def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 331 "ldr", "\t$dst, $addr", []>; 332 333// Load tconstpool 334// FIXME: Use ldr.n to work around a Darwin assembler bug. 335let canFoldAsLoad = 1 in 336def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 337 "ldr", ".n\t$dst, $addr", 338 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 339 340// Special LDR for loads from non-pc-relative constpools. 341let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in 342def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 343 "ldr", "\t$dst, $addr", []>; 344 345def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 346 "str", "\t$src, $addr", 347 [(store tGPR:$src, t_addrmode_s4:$addr)]>; 348 349def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 350 "strb", "\t$src, $addr", 351 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 352 353def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 354 "strh", "\t$src, $addr", 355 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 356 357def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 358 "str", "\t$src, $addr", 359 [(store tGPR:$src, t_addrmode_sp:$addr)]>; 360 361let mayStore = 1 in { 362// Special instruction for spill. It cannot clobber condition register 363// when it's expanded by eliminateCallFramePseudoInstr(). 364def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 365 "str", "\t$src, $addr", []>; 366} 367 368//===----------------------------------------------------------------------===// 369// Load / store multiple Instructions. 370// 371 372// These requires base address to be written back or one of the loaded regs. 373let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 374def tLDM : T1I<(outs), 375 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 376 IIC_iLoadm, 377 "ldm${addr:submode}${p}\t$addr, $wb", []>; 378 379let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 380def tSTM : T1I<(outs), 381 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 382 IIC_iStorem, 383 "stm${addr:submode}${p}\t$addr, $wb", []>; 384 385let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 386def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 387 "pop${p}\t$wb", []>; 388 389let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 390def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 391 "push${p}\t$wb", []>; 392 393//===----------------------------------------------------------------------===// 394// Arithmetic Instructions. 395// 396 397// Add with carry register 398let isCommutable = 1, Uses = [CPSR] in 399def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 400 "adc", "\t$dst, $rhs", 401 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; 402 403// Add immediate 404def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 405 "add", "\t$dst, $lhs, $rhs", 406 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; 407 408def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 409 "add", "\t$dst, $rhs", 410 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; 411 412// Add register 413let isCommutable = 1 in 414def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 415 "add", "\t$dst, $lhs, $rhs", 416 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; 417 418let neverHasSideEffects = 1 in 419def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 420 "add", "\t$dst, $rhs", []>; 421 422// And register 423let isCommutable = 1 in 424def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 425 "and", "\t$dst, $rhs", 426 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; 427 428// ASR immediate 429def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 430 "asr", "\t$dst, $lhs, $rhs", 431 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; 432 433// ASR register 434def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 435 "asr", "\t$dst, $rhs", 436 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; 437 438// BIC register 439def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 440 "bic", "\t$dst, $rhs", 441 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 442 443// CMN register 444let Defs = [CPSR] in { 445def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 446 "cmn", "\t$lhs, $rhs", 447 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; 448def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 449 "cmn", "\t$lhs, $rhs", 450 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; 451} 452 453// CMP immediate 454let Defs = [CPSR] in { 455def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 456 "cmp", "\t$lhs, $rhs", 457 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; 458def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 459 "cmp", "\t$lhs, $rhs", 460 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; 461 462} 463 464// CMP register 465let Defs = [CPSR] in { 466def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 467 "cmp", "\t$lhs, $rhs", 468 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; 469def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 470 "cmp", "\t$lhs, $rhs", 471 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; 472 473def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 474 "cmp", "\t$lhs, $rhs", []>; 475def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 476 "cmp", "\t$lhs, $rhs", []>; 477} 478 479 480// XOR register 481let isCommutable = 1 in 482def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 483 "eor", "\t$dst, $rhs", 484 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; 485 486// LSL immediate 487def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 488 "lsl", "\t$dst, $lhs, $rhs", 489 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; 490 491// LSL register 492def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 493 "lsl", "\t$dst, $rhs", 494 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; 495 496// LSR immediate 497def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 498 "lsr", "\t$dst, $lhs, $rhs", 499 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; 500 501// LSR register 502def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 503 "lsr", "\t$dst, $rhs", 504 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; 505 506// move register 507def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 508 "mov", "\t$dst, $src", 509 [(set tGPR:$dst, imm0_255:$src)]>; 510 511// TODO: A7-73: MOV(2) - mov setting flag. 512 513 514let neverHasSideEffects = 1 in { 515// FIXME: Make this predicable. 516def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 517 "mov\t$dst, $src", []>; 518let Defs = [CPSR] in 519def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 520 "movs\t$dst, $src", []>; 521 522// FIXME: Make these predicable. 523def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 524 "mov\t$dst, $src", []>; 525def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 526 "mov\t$dst, $src", []>; 527def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 528 "mov\t$dst, $src", []>; 529} // neverHasSideEffects 530 531// multiply register 532let isCommutable = 1 in 533def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 534 "mul", "\t$dst, $rhs", 535 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; 536 537// move inverse register 538def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 539 "mvn", "\t$dst, $src", 540 [(set tGPR:$dst, (not tGPR:$src))]>; 541 542// bitwise or register 543let isCommutable = 1 in 544def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 545 "orr", "\t$dst, $rhs", 546 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; 547 548// swaps 549def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 550 "rev", "\t$dst, $src", 551 [(set tGPR:$dst, (bswap tGPR:$src))]>, 552 Requires<[IsThumb1Only, HasV6]>; 553 554def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 555 "rev16", "\t$dst, $src", 556 [(set tGPR:$dst, 557 (or (and (srl tGPR:$src, (i32 8)), 0xFF), 558 (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 559 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 560 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 561 Requires<[IsThumb1Only, HasV6]>; 562 563def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 564 "revsh", "\t$dst, $src", 565 [(set tGPR:$dst, 566 (sext_inreg 567 (or (srl (and tGPR:$src, 0xFF00), (i32 8)), 568 (shl tGPR:$src, (i32 8))), i16))]>, 569 Requires<[IsThumb1Only, HasV6]>; 570 571// rotate right register 572def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 573 "ror", "\t$dst, $rhs", 574 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; 575 576// negate register 577def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, 578 "rsb", "\t$dst, $src, #0", 579 [(set tGPR:$dst, (ineg tGPR:$src))]>; 580 581// Subtract with carry register 582let Uses = [CPSR] in 583def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 584 "sbc", "\t$dst, $rhs", 585 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; 586 587// Subtract immediate 588def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 589 "sub", "\t$dst, $lhs, $rhs", 590 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; 591 592def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 593 "sub", "\t$dst, $rhs", 594 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>; 595 596// subtract register 597def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 598 "sub", "\t$dst, $lhs, $rhs", 599 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; 600 601// TODO: A7-96: STMIA - store multiple. 602 603// sign-extend byte 604def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 605 "sxtb", "\t$dst, $src", 606 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 607 Requires<[IsThumb1Only, HasV6]>; 608 609// sign-extend short 610def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 611 "sxth", "\t$dst, $src", 612 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 613 Requires<[IsThumb1Only, HasV6]>; 614 615// test 616let isCommutable = 1, Defs = [CPSR] in 617def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 618 "tst", "\t$lhs, $rhs", 619 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; 620 621// zero-extend byte 622def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 623 "uxtb", "\t$dst, $src", 624 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 625 Requires<[IsThumb1Only, HasV6]>; 626 627// zero-extend short 628def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 629 "uxth", "\t$dst, $src", 630 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 631 Requires<[IsThumb1Only, HasV6]>; 632 633 634// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. 635// Expanded after instruction selection into a branch sequence. 636let usesCustomInserter = 1 in // Expanded after instruction selection. 637 def tMOVCCr_pseudo : 638 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 639 NoItinerary, "@ tMOVCCr $cc", 640 [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 641 642 643// 16-bit movcc in IT blocks for Thumb2. 644def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 645 "mov", "\t$dst, $rhs", []>; 646 647def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 648 "mov", "\t$dst, $rhs", []>; 649 650// tLEApcrel - Load a pc-relative address into a register without offending the 651// assembler. 652def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, 653 "adr$p\t$dst, #$label", []>; 654 655def tLEApcrelJT : T1I<(outs tGPR:$dst), 656 (ins i32imm:$label, nohash_imm:$id, pred:$p), 657 IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>; 658 659//===----------------------------------------------------------------------===// 660// TLS Instructions 661// 662 663// __aeabi_read_tp preserves the registers r1-r3. 664let isCall = 1, 665 Defs = [R0, LR] in { 666 def tTPsoft : TIx2<(outs), (ins), IIC_Br, 667 "bl\t__aeabi_read_tp", 668 [(set R0, ARMthread_pointer)]>; 669} 670 671//===----------------------------------------------------------------------===// 672// Non-Instruction Patterns 673// 674 675// Add with carry 676def : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 677 (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 678def : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 679 (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 680def : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 681 (tADDrr tGPR:$lhs, tGPR:$rhs)>; 682 683// Subtract with carry 684def : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 685 (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 686def : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 687 (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 688def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 689 (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 690 691// ConstantPool, GlobalAddress 692def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 693def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 694 695// JumpTable 696def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 697 (tLEApcrelJT tjumptable:$dst, imm:$id)>; 698 699// Direct calls 700def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 701 Requires<[IsThumb, IsNotDarwin]>; 702def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 703 Requires<[IsThumb, IsDarwin]>; 704 705def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 706 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 707def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 708 Requires<[IsThumb, HasV5T, IsDarwin]>; 709 710// Indirect calls to ARM routines 711def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 712 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 713def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 714 Requires<[IsThumb, HasV5T, IsDarwin]>; 715 716// zextload i1 -> zextload i8 717def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 718 (tLDRB t_addrmode_s1:$addr)>; 719 720// extload -> zextload 721def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 722def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 723def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 724 725// If it's impossible to use [r,r] address mode for sextload, select to 726// ldr{b|h} + sxt{b|h} instead. 727def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 728 (tSXTB (tLDRB t_addrmode_s1:$addr))>, 729 Requires<[IsThumb1Only, HasV6]>; 730def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 731 (tSXTH (tLDRH t_addrmode_s2:$addr))>, 732 Requires<[IsThumb1Only, HasV6]>; 733 734def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 735 (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 736def : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 737 (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 738 739// Large immediate handling. 740 741// Two piece imms. 742def : T1Pat<(i32 thumb_immshifted:$src), 743 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 744 (thumb_immshifted_shamt imm:$src))>; 745 746def : T1Pat<(i32 imm0_255_comp:$src), 747 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 748 749// Pseudo instruction that combines ldr from constpool and add pc. This should 750// be expanded into two instructions late to allow if-conversion and 751// scheduling. 752let isReMaterializable = 1 in 753def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 754 NoItinerary, "@ ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc", 755 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 756 imm:$cp))]>, 757 Requires<[IsThumb1Only]>;
|