ARMInstrThumb.td (195098) | ARMInstrThumb.td (195340) |
---|---|
1//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 173 unchanged lines hidden (view full) --- 182 def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), 183 "cpy lr, pc\n\tbx $func", 184 [(ARMcall_nolink tGPR:$func)]>; 185} 186 187let isBranch = 1, isTerminator = 1 in { 188 let isBarrier = 1 in { 189 let isPredicable = 1 in | 1//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 173 unchanged lines hidden (view full) --- 182 def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), 183 "cpy lr, pc\n\tbx $func", 184 [(ARMcall_nolink tGPR:$func)]>; 185} 186 187let isBranch = 1, isTerminator = 1 in { 188 let isBarrier = 1 in { 189 let isPredicable = 1 in |
190 def tB : TI<(outs), (ins brtarget:$target), "b $target", 191 [(br bb:$target)]>; | 190 def tB : T1I<(outs), (ins brtarget:$target), "b $target", 191 [(br bb:$target)]>; |
192 193 // Far jump | 192 193 // Far jump |
194 def tBfar : TIx2<(outs), (ins brtarget:$target), "bl $target\t@ far jump",[]>; | 194 def tBfar : T1Ix2<(outs), (ins brtarget:$target), 195 "bl $target\t@ far jump",[]>; |
195 | 196 |
196 def tBR_JTr : TJTI<(outs), 197 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 198 "cpy pc, $target \n\t.align\t2\n$jt", 199 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; | 197 def tBR_JTr : T1JTI<(outs), 198 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 199 "cpy pc, $target \n\t.align\t2\n$jt", 200 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; |
200 } 201} 202 203// FIXME: should be able to write a pattern for ARMBrcond, but can't use 204// a two-value operand where a dag node expects two operands. :( 205let isBranch = 1, isTerminator = 1 in | 201 } 202} 203 204// FIXME: should be able to write a pattern for ARMBrcond, but can't use 205// a two-value operand where a dag node expects two operands. :( 206let isBranch = 1, isTerminator = 1 in |
206 def tBcc : TI<(outs), (ins brtarget:$target, pred:$cc), "b$cc $target", | 207 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), "b$cc $target", |
207 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 208 209//===----------------------------------------------------------------------===// 210// Load Store Instructions. 211// 212 213let canFoldAsLoad = 1 in | 208 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 209 210//===----------------------------------------------------------------------===// 211// Load Store Instructions. 212// 213 214let canFoldAsLoad = 1 in |
214def tLDR : TI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), | 215def tLDR : T1I4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), |
215 "ldr $dst, $addr", 216 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 217 | 216 "ldr $dst, $addr", 217 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 218 |
218def tLDRB : TI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), | 219def tLDRB : T1I1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), |
219 "ldrb $dst, $addr", 220 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 221 | 220 "ldrb $dst, $addr", 221 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 222 |
222def tLDRH : TI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), | 223def tLDRH : T1I2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), |
223 "ldrh $dst, $addr", 224 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 225 | 224 "ldrh $dst, $addr", 225 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 226 |
226def tLDRSB : TI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), | 227def tLDRSB : T1I1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), |
227 "ldrsb $dst, $addr", 228 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 229 | 228 "ldrsb $dst, $addr", 229 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 230 |
230def tLDRSH : TI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), | 231def tLDRSH : T1I2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), |
231 "ldrsh $dst, $addr", 232 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 233 234let canFoldAsLoad = 1 in | 232 "ldrsh $dst, $addr", 233 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 234 235let canFoldAsLoad = 1 in |
235def tLDRspi : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), | 236def tLDRspi : T1Is<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), |
236 "ldr $dst, $addr", 237 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 238 239// Special instruction for restore. It cannot clobber condition register 240// when it's expanded by eliminateCallFramePseudoInstr(). 241let canFoldAsLoad = 1, mayLoad = 1 in | 237 "ldr $dst, $addr", 238 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 239 240// Special instruction for restore. It cannot clobber condition register 241// when it's expanded by eliminateCallFramePseudoInstr(). 242let canFoldAsLoad = 1, mayLoad = 1 in |
242def tRestore : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), | 243def tRestore : T1Is<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), |
243 "ldr $dst, $addr", []>; 244 245// Load tconstpool 246let canFoldAsLoad = 1 in | 244 "ldr $dst, $addr", []>; 245 246// Load tconstpool 247let canFoldAsLoad = 1 in |
247def tLDRpci : TIs<(outs tGPR:$dst), (ins i32imm:$addr), | 248def tLDRpci : T1Is<(outs tGPR:$dst), (ins i32imm:$addr), |
248 "ldr $dst, $addr", 249 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 250 251// Special LDR for loads from non-pc-relative constpools. 252let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in | 249 "ldr $dst, $addr", 250 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 251 252// Special LDR for loads from non-pc-relative constpools. 253let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in |
253def tLDRcp : TIs<(outs tGPR:$dst), (ins i32imm:$addr), | 254def tLDRcp : T1Is<(outs tGPR:$dst), (ins i32imm:$addr), |
254 "ldr $dst, $addr", []>; 255 | 255 "ldr $dst, $addr", []>; 256 |
256def tSTR : TI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), | 257def tSTR : T1I4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), |
257 "str $src, $addr", 258 [(store tGPR:$src, t_addrmode_s4:$addr)]>; 259 | 258 "str $src, $addr", 259 [(store tGPR:$src, t_addrmode_s4:$addr)]>; 260 |
260def tSTRB : TI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), | 261def tSTRB : T1I1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), |
261 "strb $src, $addr", 262 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 263 | 262 "strb $src, $addr", 263 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 264 |
264def tSTRH : TI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), | 265def tSTRH : T1I2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), |
265 "strh $src, $addr", 266 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 267 | 266 "strh $src, $addr", 267 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 268 |
268def tSTRspi : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), | 269def tSTRspi : T1Is<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), |
269 "str $src, $addr", 270 [(store tGPR:$src, t_addrmode_sp:$addr)]>; 271 272let mayStore = 1 in { 273// Special instruction for spill. It cannot clobber condition register 274// when it's expanded by eliminateCallFramePseudoInstr(). | 270 "str $src, $addr", 271 [(store tGPR:$src, t_addrmode_sp:$addr)]>; 272 273let mayStore = 1 in { 274// Special instruction for spill. It cannot clobber condition register 275// when it's expanded by eliminateCallFramePseudoInstr(). |
275def tSpill : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), | 276def tSpill : T1Is<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), |
276 "str $src, $addr", []>; 277} 278 279//===----------------------------------------------------------------------===// 280// Load / store multiple Instructions. 281// 282 283// TODO: A7-44: LDMIA - load multiple --- 73 unchanged lines hidden (view full) --- 357 "bic $dst, $rhs", 358 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 359 360// CMN register 361let Defs = [CPSR] in { 362def tCMN : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 363 "cmn $lhs, $rhs", 364 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; | 277 "str $src, $addr", []>; 278} 279 280//===----------------------------------------------------------------------===// 281// Load / store multiple Instructions. 282// 283 284// TODO: A7-44: LDMIA - load multiple --- 73 unchanged lines hidden (view full) --- 358 "bic $dst, $rhs", 359 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 360 361// CMN register 362let Defs = [CPSR] in { 363def tCMN : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 364 "cmn $lhs, $rhs", 365 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; |
365def tCMNNZ : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 366 "cmn $lhs, $rhs", 367 [(ARMcmpNZ tGPR:$lhs, (ineg tGPR:$rhs))]>; | 366def tCMNZ : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 367 "cmn $lhs, $rhs", 368 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; |
368} 369 370// CMP immediate 371let Defs = [CPSR] in { 372def tCMPi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs), 373 "cmp $lhs, $rhs", 374 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; | 369} 370 371// CMP immediate 372let Defs = [CPSR] in { 373def tCMPi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs), 374 "cmp $lhs, $rhs", 375 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; |
375def tCMPNZi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs), 376 "cmp $lhs, $rhs", 377 [(ARMcmpNZ tGPR:$lhs, imm0_255:$rhs)]>; | 376def tCMPZi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs), 377 "cmp $lhs, $rhs", 378 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; |
378 379} 380 381// CMP register 382let Defs = [CPSR] in { 383def tCMPr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 384 "cmp $lhs, $rhs", 385 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; | 379 380} 381 382// CMP register 383let Defs = [CPSR] in { 384def tCMPr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 385 "cmp $lhs, $rhs", 386 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; |
386def tCMPNZr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 387 "cmp $lhs, $rhs", 388 [(ARMcmpNZ tGPR:$lhs, tGPR:$rhs)]>; | 387def tCMPZr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 388 "cmp $lhs, $rhs", 389 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; |
389} 390 391// TODO: A7-37: CMP(3) - cmp hi regs 392 393// XOR register 394let isCommutable = 1, Defs = [CPSR] in 395def tEOR : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 396 "eor $dst, $rhs", --- 149 unchanged lines hidden (view full) --- 546 "sxth $dst, $src", 547 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 548 Requires<[IsThumb, HasV6]>; 549 550// test 551let isCommutable = 1, Defs = [CPSR] in 552def tTST : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 553 "tst $lhs, $rhs", | 390} 391 392// TODO: A7-37: CMP(3) - cmp hi regs 393 394// XOR register 395let isCommutable = 1, Defs = [CPSR] in 396def tEOR : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 397 "eor $dst, $rhs", --- 149 unchanged lines hidden (view full) --- 547 "sxth $dst, $src", 548 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 549 Requires<[IsThumb, HasV6]>; 550 551// test 552let isCommutable = 1, Defs = [CPSR] in 553def tTST : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 554 "tst $lhs, $rhs", |
554 [(ARMcmpNZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; | 555 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; |
555 556// zero-extend byte 557def tUXTB : T1I<(outs tGPR:$dst), (ins tGPR:$src), 558 "uxtb $dst, $src", 559 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 560 Requires<[IsThumb, HasV6]>; 561 562// zero-extend short --- 54 unchanged lines hidden (view full) --- 617// Direct calls 618def : TPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>; 619def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>; 620 621// Indirect calls to ARM routines 622def : Tv5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>; 623 624// zextload i1 -> zextload i8 | 556 557// zero-extend byte 558def tUXTB : T1I<(outs tGPR:$dst), (ins tGPR:$src), 559 "uxtb $dst, $src", 560 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 561 Requires<[IsThumb, HasV6]>; 562 563// zero-extend short --- 54 unchanged lines hidden (view full) --- 618// Direct calls 619def : TPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>; 620def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>; 621 622// Indirect calls to ARM routines 623def : Tv5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>; 624 625// zextload i1 -> zextload i8 |
625def : TPat<(zextloadi1 t_addrmode_s1:$addr), 626 (tLDRB t_addrmode_s1:$addr)>; | 626def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 627 (tLDRB t_addrmode_s1:$addr)>; |
627 628// extload -> zextload | 628 629// extload -> zextload |
629def : TPat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 630def : TPat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 631def : TPat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; | 630def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 631def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 632def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; |
632 633// Large immediate handling. 634 635// Two piece imms. 636def : T1Pat<(i32 thumb_immshifted:$src), 637 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 638 (thumb_immshifted_shamt imm:$src))>; 639 640def : T1Pat<(i32 imm0_255_comp:$src), 641 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; | 633 634// Large immediate handling. 635 636// Two piece imms. 637def : T1Pat<(i32 thumb_immshifted:$src), 638 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 639 (thumb_immshifted_shamt imm:$src))>; 640 641def : T1Pat<(i32 imm0_255_comp:$src), 642 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; |