Deleted Added
full compact
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)))>;