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 : T1I<(outs), (ins brtarget:$target), "b $target", 191 [(br bb:$target)]>; |
192 193 // Far jump |
194 def tBfar : T1Ix2<(outs), (ins brtarget:$target), 195 "bl $target\t@ far jump",[]>; |
196 |
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)]>; |
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 |
207 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), "b$cc $target", |
208 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 209 210//===----------------------------------------------------------------------===// 211// Load Store Instructions. 212// 213 214let canFoldAsLoad = 1 in |
215def tLDR : T1I4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), |
216 "ldr $dst, $addr", 217 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 218 |
219def tLDRB : T1I1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), |
220 "ldrb $dst, $addr", 221 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 222 |
223def tLDRH : T1I2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), |
224 "ldrh $dst, $addr", 225 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 226 |
227def tLDRSB : T1I1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), |
228 "ldrsb $dst, $addr", 229 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 230 |
231def tLDRSH : T1I2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), |
232 "ldrsh $dst, $addr", 233 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 234 235let canFoldAsLoad = 1 in |
236def tLDRspi : T1Is<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), |
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 |
243def tRestore : T1Is<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), |
244 "ldr $dst, $addr", []>; 245 246// Load tconstpool 247let canFoldAsLoad = 1 in |
248def tLDRpci : T1Is<(outs tGPR:$dst), (ins i32imm:$addr), |
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 |
254def tLDRcp : T1Is<(outs tGPR:$dst), (ins i32imm:$addr), |
255 "ldr $dst, $addr", []>; 256 |
257def tSTR : T1I4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), |
258 "str $src, $addr", 259 [(store tGPR:$src, t_addrmode_s4:$addr)]>; 260 |
261def tSTRB : T1I1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), |
262 "strb $src, $addr", 263 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 264 |
265def tSTRH : T1I2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), |
266 "strh $src, $addr", 267 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 268 |
269def tSTRspi : T1Is<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), |
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(). |
276def tSpill : T1Is<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), |
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))]>; |
366def tCMNZ : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 367 "cmn $lhs, $rhs", 368 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$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)]>; |
376def tCMPZi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs), 377 "cmp $lhs, $rhs", 378 [(ARMcmpZ tGPR:$lhs, imm0_255:$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)]>; |
387def tCMPZr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs), 388 "cmp $lhs, $rhs", 389 [(ARMcmpZ tGPR:$lhs, tGPR:$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", |
555 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; |
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 |
626def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 627 (tLDRB t_addrmode_s1:$addr)>; |
628 629// extload -> zextload |
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)>; |
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)))>; |