llvm.org GIT mirror llvm / 446c428
Major changes to Thumb (not Thumb2). Many 16-bit instructions either modifies CPSR when they are outside the IT blocks, or they can predicated when in Thumb2. Move the implicit def of CPSR to an optional def which defaults CPSR. This allows the 's' bit to be toggled dynamically. A side-effect of this change is asm printer is now using unified assembly. There are some minor clean ups and fixes as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75359 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
14 changed file(s) with 469 addition(s) and 323 deletion(s). Raw diff Collapse all Expand all
867867 return 0;
868868 }
869869
870
870 // FIXME: Dup in ARMBaseInstrInfo.cpp
871871 static inline
872872 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
873873 return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
458458 // wouldn't work without additional code to position the node within
459459 // ISel's topological ordering in a place where ISel will process it
460460 // normally. Instead, just explicitly issue a tMOVri8 node!
461 Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, dl, MVT::i32,
462 CurDAG->getTargetConstant(0, MVT::i32)), 0);
461 SDValue CC = CurDAG->getRegister(ARM::CPSR, MVT::i32);
462 SDValue Pred = CurDAG->getTargetConstant(0xEULL, MVT::i32);
463 SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
464 SDValue Ops[] = { CC, CurDAG->getTargetConstant(0, MVT::i32), Pred, PredReg };
465 Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, dl, MVT::i32, Ops,4),0);
463466 return true;
464467 }
465468
870873 TLI.getPointerTy());
871874
872875 SDNode *ResNode;
873 if (Subtarget->isThumb1Only())
876 if (Subtarget->isThumb1Only()) {
877 SDValue Pred = CurDAG->getTargetConstant(0xEULL, MVT::i32);
878 SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
879 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() };
874880 ResNode = CurDAG->getTargetNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other,
875 CPIdx, CurDAG->getEntryNode());
876 else {
881 Ops, 4);
882 } else {
877883 SDValue Ops[] = {
878884 CPIdx,
879885 CurDAG->getRegister(0, MVT::i32),
900906 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI,
901907 CurDAG->getTargetConstant(0, MVT::i32));
902908 } else {
909 unsigned Opc = Subtarget->hasThumb2() ? ARM::t2ADDri : ARM::ADDri;
903910 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
904 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
905 CurDAG->getRegister(0, MVT::i32) };
906 return CurDAG->SelectNodeTo(N, (Subtarget->hasThumb2()) ? ARM::t2ADDri : ARM::ADDri,
907 MVT::i32, Ops, 5);
911 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
912 CurDAG->getRegister(0, MVT::i32) };
913 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
908914 }
909915 }
910916 case ISD::ADD: {
921927 }
922928 if (RHSR && RHSR->getReg() == ARM::SP) {
923929 SDValue Val = SDValue(CurDAG->getTargetNode(ARM::tMOVlor2hir, dl,
924 Op.getValueType(), N0, N0), 0);
930 Op.getValueType(), N0, N0),0);
925931 return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), Val, N1);
926932 }
927933 break;
109109
110110 //===----------------------------------------------------------------------===//
111111
112 // ARM special operands.
113 //
114
115 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
116 // register whose default is 0 (no register).
117 def pred : PredicateOperand
118 (ops (i32 14), (i32 zero_reg))> {
119 let PrintMethod = "printPredicateOperand";
120 }
121
122 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
123 def cc_out : OptionalDefOperand {
124 let PrintMethod = "printSBitModifierOperand";
125 }
126
127 // Same as cc_out except it defaults to setting CPSR.
128 def s_cc_out : OptionalDefOperand {
129 let PrintMethod = "printSBitModifierOperand";
130 }
131
132 //===----------------------------------------------------------------------===//
133
112134 // ARM Instruction templates.
113135 //
114136
772794
773795 // TI - Thumb instruction.
774796
775 class ThumbIuts, dag ins, AddrMode am, SizeFlagVal sz,
797 class ThumbIops, dag iops, AddrMode am, SizeFlagVal sz,
776798 string asm, string cstr, list pattern>
777799 : InstARM {
778 let OutOperandList = outs;
779 let InOperandList = ins;
800 let OutOperandList = oops;
801 let InOperandList = iops;
780802 let AsmString = asm;
781803 let Pattern = pattern;
782804 list Predicates = [IsThumb];
783805 }
784806
785 class TI pattern>
786 : ThumbI;
807 class TI pattern>
808 : ThumbI;
787809
788810 // BL, BLX(1) are translated by assembler into two instructions
789 class TIx2 pattern>
790 : ThumbI;
811 class TIx2 pattern>
812 : ThumbI;
791813
792814 // BR_JT instructions
793 class TJTI pattern>
794 : ThumbI;
815 class TJTI pattern>
816 : ThumbI;
795817
796818 // TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
797819 class TPat : Pat {
803825 }
804826
805827 // Thumb1 only
806 class Thumb1Iuts, dag ins, AddrMode am, SizeFlagVal sz,
828 class Thumb1Iops, dag iops, AddrMode am, SizeFlagVal sz,
807829 string asm, string cstr, list pattern>
808830 : InstARM {
809 let OutOperandList = outs;
810 let InOperandList = ins;
831 let OutOperandList = oops;
832 let InOperandList = iops;
811833 let AsmString = asm;
812834 let Pattern = pattern;
813835 list Predicates = [IsThumb1Only];
814836 }
815837
816 class T1I pattern>
817 : Thumb1I;
818 class T1I1 pattern>
819 : Thumb1I;
820 class T1I2 pattern>
821 : Thumb1I;
822 class T1I4 pattern>
823 : Thumb1I;
824 class T1Is pattern>
825 : Thumb1I;
826 class T1Ix2 pattern>
827 : Thumb1I;
828 class T1JTI pattern>
829 : Thumb1I;
838 class T1I pattern>
839 : Thumb1I;
840 class T1Ix2 pattern>
841 : Thumb1I;
842 class T1JTI pattern>
843 : Thumb1I;
830844
831845 // Two-address instructions
832 class T1It pattern>
833 : Thumb1I;
846 class T1It pattern>
847 : Thumb1I;
848
849 // Thumb1 instruction that can either be predicated or set CPSR.
850 class Thumb1sI
851 string opc, string asm, string cstr, list pattern>
852 : InstARM {
853 let OutOperandList = !con(oops, (ops s_cc_out:$s));
854 let InOperandList = !con(iops, (ops pred:$p));
855 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
856 let Pattern = pattern;
857 list Predicates = [IsThumb1Only];
858 }
859
860 class T1sI pattern>
861 : Thumb1sI;
862
863 // Two-address instructions
864 class T1sIt pattern>
865 : Thumb1sI
866 "$lhs = $dst", pattern>;
867
868 // Thumb1 instruction that can be predicated.
869 class Thumb1pI
870 string opc, string asm, string cstr, list pattern>
871 : InstARM {
872 let OutOperandList = oops;
873 let InOperandList = !con(iops, (ops pred:$p));
874 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
875 let Pattern = pattern;
876 list Predicates = [IsThumb1Only];
877 }
878
879 class T1pI pattern>
880 : Thumb1pI;
881
882 // Two-address instructions
883 class T1pIt pattern>
884 : Thumb1pI
885 "$lhs = $dst", pattern>;
886
887 class T1pI1 pattern>
888 : Thumb1pI;
889 class T1pI2 pattern>
890 : Thumb1pI;
891 class T1pI4 pattern>
892 : Thumb1pI;
893 class T1pIs pattern>
894 : Thumb1pI;
834895
835896 class T1Pat : Pat {
836897 list Predicates = [IsThumb1Only];
313313 ComplexPattern {
314314 let PrintMethod = "printAddrModePCOperand";
315315 let MIOperandInfo = (ops GPR, i32imm);
316 }
317
318 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
319 // register whose default is 0 (no register).
320 def pred : PredicateOperand
321 (ops (i32 14), (i32 zero_reg))> {
322 let PrintMethod = "printPredicateOperand";
323 }
324
325 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
326 //
327 def cc_out : OptionalDefOperand {
328 let PrintMethod = "printSBitModifierOperand";
329316 }
330317
331318 //===----------------------------------------------------------------------===//
154154 //
155155
156156 let isReturn = 1, isTerminator = 1 in {
157 def tBX_RET : T1I<(outs), (ins), "bx lr", [(ARMretflag)]>;
157 def tBX_RET : TI<(outs), (ins), "bx lr", [(ARMretflag)]>;
158158 // Alternative return instruction used by vararg functions.
159 def tBX_RET_vararg : T1I<(outs), (ins tGPR:$target), "bx $target", []>;
159 def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), "bx $target", []>;
160160 }
161161
162162 // FIXME: remove when we have a way to marking a MI with these properties.
211211 //
212212
213213 let canFoldAsLoad = 1 in
214 def tLDR : T1I4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr),
215 "ldr $dst, $addr",
214 def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr),
215 "ldr", " $dst, $addr",
216216 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>;
217217
218 def tLDRB : T1I1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr),
219 "ldrb $dst, $addr",
218 def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr),
219 "ldrb", " $dst, $addr",
220220 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
221221
222 def tLDRH : T1I2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr),
223 "ldrh $dst, $addr",
222 def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr),
223 "ldrh", " $dst, $addr",
224224 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
225225
226 def tLDRSB : T1I1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
227 "ldrsb $dst, $addr",
226 def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
227 "ldrsb", " $dst, $addr",
228228 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
229229
230 def tLDRSH : T1I2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
231 "ldrsh $dst, $addr",
230 def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
231 "ldrsh", " $dst, $addr",
232232 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
233233
234234 let canFoldAsLoad = 1 in
235 def tLDRspi : T1Is<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
236 "ldr $dst, $addr",
235 def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
236 "ldr", " $dst, $addr",
237237 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>;
238238
239239 // Special instruction for restore. It cannot clobber condition register
240240 // when it's expanded by eliminateCallFramePseudoInstr().
241241 let canFoldAsLoad = 1, mayLoad = 1 in
242 def tRestore : T1Is<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
243 "ldr $dst, $addr", []>;
242 def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
243 "ldr", " $dst, $addr", []>;
244244
245245 // Load tconstpool
246246 let canFoldAsLoad = 1 in
247 def tLDRpci : T1Is<(outs tGPR:$dst), (ins i32imm:$addr),
248 "ldr $dst, $addr",
247 def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr),
248 "ldr", " $dst, $addr",
249249 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
250250
251251 // Special LDR for loads from non-pc-relative constpools.
252252 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
253 def tLDRcp : T1Is<(outs tGPR:$dst), (ins i32imm:$addr),
254 "ldr $dst, $addr", []>;
255
256 def tSTR : T1I4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr),
257 "str $src, $addr",
253 def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr),
254 "ldr", " $dst, $addr", []>;
255
256 def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr),
257 "str", " $src, $addr",
258258 [(store tGPR:$src, t_addrmode_s4:$addr)]>;
259259
260 def tSTRB : T1I1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr),
261 "strb $src, $addr",
260 def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr),
261 "strb", " $src, $addr",
262262 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
263263
264 def tSTRH : T1I2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr),
265 "strh $src, $addr",
264 def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr),
265 "strh", " $src, $addr",
266266 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
267267
268 def tSTRspi : T1Is<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
269 "str $src, $addr",
268 def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
269 "str", " $src, $addr",
270270 [(store tGPR:$src, t_addrmode_sp:$addr)]>;
271271
272272 let mayStore = 1 in {
273273 // Special instruction for spill. It cannot clobber condition register
274274 // when it's expanded by eliminateCallFramePseudoInstr().
275 def tSpill : T1Is<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
276 "str $src, $addr", []>;
275 def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
276 "str", " $src, $addr", []>;
277277 }
278278
279279 //===----------------------------------------------------------------------===//
281281 //
282282
283283 // TODO: A7-44: LDMIA - load multiple
284 // TODO: Allow these to be predicated
284285
285286 let mayLoad = 1 in
286287 def tPOP : T1I<(outs reglist:$dst1, variable_ops), (ins),
295296 //
296297
297298 // Add with carry register
298 let isCommutable = 1, Defs = [CPSR], Uses = [CPSR] in
299 def tADCS : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
300 "adc $dst, $rhs",
299 let isCommutable = 1, Uses = [CPSR] in
300 def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
301 "adc", " $dst, $rhs",
301302 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>;
302303
303304 // Add immediate
304 let Defs = [CPSR] in
305 def tADDi3 : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
306 "add $dst, $lhs, $rhs",
307 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
308
309 let Defs = [CPSR] in
310 def tADDi8 : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
311 "add $dst, $rhs",
312 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
305 def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
306 "add", " $dst, $lhs, $rhs",
307 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
308
309 def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
310 "add", " $dst, $rhs",
311 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
313312
314313 // Add register
315 let isCommutable = 1, Defs = [CPSR] in
316 def tADDrr : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
317 "add $dst, $lhs, $rhs",
318 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
314 let isCommutable = 1 in
315 def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
316 "add", " $dst, $lhs, $rhs",
317 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
319318
320319 let neverHasSideEffects = 1 in
321 def tADDhirr : T1It<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs),
322 "add $dst, $rhs @ addhirr", []>;
320 def tADDhirr : T1pIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs),
321 "add", " $dst, $rhs @ addhirr", []>;
323322
324323 // And register
325 let isCommutable = 1, Defs = [CPSR] in
326 def tAND : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
327 "and $dst, $rhs",
328 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
324 let isCommutable = 1 in
325 def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
326 "and", " $dst, $rhs",
327 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
329328
330329 // ASR immediate
331 let Defs = [CPSR] in
332 def tASRri : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
333 "asr $dst, $lhs, $rhs",
334 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>;
330 def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
331 "asr", " $dst, $lhs, $rhs",
332 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>;
335333
336334 // ASR register
337 let Defs = [CPSR] in
338 def tASRrr : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
339 "asr $dst, $rhs",
340 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
335 def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
336 "asr", " $dst, $rhs",
337 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
341338
342339 // BIC register
343 let Defs = [CPSR] in
344 def tBIC : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
345 "bic $dst, $rhs",
346 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
340 def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
341 "bic", " $dst, $rhs",
342 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
347343
348344 // CMN register
349345 let Defs = [CPSR] in {
350 def tCMN : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
351 "cmn $lhs, $rhs",
352 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
353 def tCMNZ : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
354 "cmn $lhs, $rhs",
355 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
346 def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
347 "cmn", " $lhs, $rhs",
348 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
349 def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
350 "cmn", " $lhs, $rhs",
351 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
356352 }
357353
358354 // CMP immediate
359355 let Defs = [CPSR] in {
360 def tCMPi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs),
361 "cmp $lhs, $rhs",
362 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
363 def tCMPZi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs),
364 "cmp $lhs, $rhs",
365 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
356 def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
357 "cmp", " $lhs, $rhs",
358 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
359 def tCMPZi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
360 "cmp", " $lhs, $rhs",
361 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
366362
367363 }
368364
369365 // CMP register
370366 let Defs = [CPSR] in {
371 def tCMPr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
372 "cmp $lhs, $rhs",
373 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
374 def tCMPZr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
375 "cmp $lhs, $rhs",
376 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
377 }
378
379 // TODO: A7-37: CMP(3) - cmp hi regs
367 def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
368 "cmp", " $lhs, $rhs",
369 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
370 def tCMPZr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
371 "cmp", " $lhs, $rhs",
372 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
373
374 // TODO: Make use of the followings cmp hi regs
375 def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs),
376 "cmp", " $lhs, $rhs", []>;
377 def tCMPZhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs),
378 "cmp", " $lhs, $rhs", []>;
379 }
380
380381
381382 // XOR register
382 let isCommutable = 1, Defs = [CPSR] in
383 def tEOR : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
384 "eor $dst, $rhs",
385 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
383 let isCommutable = 1 in
384 def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
385 "eor", " $dst, $rhs",
386 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
386387
387388 // LSL immediate
389 def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
390 "lsl", " $dst, $lhs, $rhs",
391 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>;
392
393 // LSL register
394 def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
395 "lsl", " $dst, $rhs",
396 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
397
398 // LSR immediate
399 def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
400 "lsr", " $dst, $lhs, $rhs",
401 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>;
402
403 // LSR register
404 def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
405 "lsr", " $dst, $rhs",
406 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
407
408 // move register
409 def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src),
410 "mov", " $dst, $src",
411 [(set tGPR:$dst, imm0_255:$src)]>;
412
413 // TODO: A7-73: MOV(2) - mov setting flag.
414
415
416 let neverHasSideEffects = 1 in {
417 // FIXME: Make this predicable.
418 def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src),
419 "mov $dst, $src", []>;
388420 let Defs = [CPSR] in
389 def tLSLri : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
390 "lsl $dst, $lhs, $rhs",
391 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>;
392
393 // LSL register
394 let Defs = [CPSR] in
395 def tLSLrr : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
396 "lsl $dst, $rhs",
397 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
398
399 // LSR immediate
400 let Defs = [CPSR] in
401 def tLSRri : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
402 "lsr $dst, $lhs, $rhs",
403 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>;
404
405 // LSR register
406 let Defs = [CPSR] in
407 def tLSRrr : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
408 "lsr $dst, $rhs",
409 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
410
411 // move register
412 let Defs = [CPSR] in
413 def tMOVi8 : T1I<(outs tGPR:$dst), (ins i32imm:$src),
414 "mov $dst, $src",
415 [(set tGPR:$dst, imm0_255:$src)]>;
416
417 // TODO: A7-73: MOV(2) - mov setting flag.
418
419
420 // Note: MOV(2) of two low regs updates the flags, so we emit this as 'cpy',
421 // which is MOV(3). This also supports high registers.
422 let neverHasSideEffects = 1 in {
423 def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src),
424 "cpy $dst, $src", []>;
421 def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src),
422 "movs $dst, $src", []>;
423
424 // FIXME: Make these predicable.
425425 def tMOVhir2lor : T1I<(outs tGPR:$dst), (ins GPR:$src),
426 "cpy $dst, $src\t@ hir2lor", []>;
426 "mov $dst, $src\t@ hir2lor", []>;
427427 def tMOVlor2hir : T1I<(outs GPR:$dst), (ins tGPR:$src),
428 "cpy $dst, $src\t@ lor2hir", []>;
428 "mov $dst, $src\t@ lor2hir", []>;
429429 def tMOVhir2hir : T1I<(outs GPR:$dst), (ins GPR:$src),
430 "cpy $dst, $src\t@ hir2hir", []>;
430 "mov $dst, $src\t@ hir2hir", []>;
431431 } // neverHasSideEffects
432432
433433 // multiply register
434 let isCommutable = 1, Defs = [CPSR] in
435 def tMUL : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
436 "mul $dst, $rhs",
437 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
434 let isCommutable = 1 in
435 def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
436 "mul", " $dst, $rhs",
437 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
438438
439439 // move inverse register
440 let Defs = [CPSR] in
441 def tMVN : T1I<(outs tGPR:$dst), (ins tGPR:$src),
442 "mvn $dst, $src",
443 [(set tGPR:$dst, (not tGPR:$src))]>;
440 def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src),
441 "mvn", " $dst, $src",
442 [(set tGPR:$dst, (not tGPR:$src))]>;
443
444 // bitwise or register
445 let isCommutable = 1 in
446 def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
447 "orr", " $dst, $rhs",
448 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
449
450 // swaps
451 def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
452 "rev", " $dst, $src",
453 [(set tGPR:$dst, (bswap tGPR:$src))]>,
454 Requires<[IsThumb1Only, HasV6]>;
455
456 def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
457 "rev16", " $dst, $src",
458 [(set tGPR:$dst,
459 (or (and (srl tGPR:$src, (i32 8)), 0xFF),
460 (or (and (shl tGPR:$src, (i32 8)), 0xFF00),
461 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000),
462 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>,
463 Requires<[IsThumb1Only, HasV6]>;
464
465 def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
466 "revsh", " $dst, $src",
467 [(set tGPR:$dst,
468 (sext_inreg
469 (or (srl (and tGPR:$src, 0xFFFF), (i32 8)),
470 (shl tGPR:$src, (i32 8))), i16))]>,
471 Requires<[IsThumb1Only, HasV6]>;
472
473 // rotate right register
474 def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
475 "ror", " $dst, $rhs",
476 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
444477
445478 // negate register
446 let Defs = [CPSR] in
447 def tNEG : T1I<(outs tGPR:$dst), (ins tGPR:$src),
448 "neg $dst, $src",
449 [(set tGPR:$dst, (ineg tGPR:$src))]>;
450
451 // bitwise or register
452 let isCommutable = 1, Defs = [CPSR] in
453 def tORR : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
454 "orr $dst, $rhs",
455 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
456
457 // swaps
458 def tREV : T1I<(outs tGPR:$dst), (ins tGPR:$src),
459 "rev $dst, $src",
460 [(set tGPR:$dst, (bswap tGPR:$src))]>,
461 Requires<[IsThumb1Only, HasV6]>;
462
463 def tREV16 : T1I<(outs tGPR:$dst), (ins tGPR:$src),
464 "rev16 $dst, $src",
465 [(set tGPR:$dst,
466 (or (and (srl tGPR:$src, (i32 8)), 0xFF),
467 (or (and (shl tGPR:$src, (i32 8)), 0xFF00),
468 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000),
469 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>,
470 Requires<[IsThumb1Only, HasV6]>;
471
472 def tREVSH : T1I<(outs tGPR:$dst), (ins tGPR:$src),
473 "revsh $dst, $src",
474 [(set tGPR:$dst,
475 (sext_inreg
476 (or (srl (and tGPR:$src, 0xFFFF), (i32 8)),
477 (shl tGPR:$src, (i32 8))), i16))]>,
478 Requires<[IsThumb1Only, HasV6]>;
479
480 // rotate right register
481 let Defs = [CPSR] in
482 def tROR : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
483 "ror $dst, $rhs",
484 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
479 def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src),
480 "rsb", " $dst, $src, #0",
481 [(set tGPR:$dst, (ineg tGPR:$src))]>;
485482
486483 // Subtract with carry register
487 let Defs = [CPSR], Uses = [CPSR] in
488 def tSBCS : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
489 "sbc $dst, $rhs",
490 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
484 let Uses = [CPSR] in
485 def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
486 "sbc", " $dst, $rhs",
487 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
491488
492489 // Subtract immediate
493 let Defs = [CPSR] in
494 def tSUBi3 : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
495 "sub $dst, $lhs, $rhs",
496 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
497
498 let Defs = [CPSR] in
499 def tSUBi8 : T1It<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
500 "sub $dst, $rhs",
501 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
490 def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
491 "sub", " $dst, $lhs, $rhs",
492 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
493
494 def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
495 "sub", " $dst, $rhs",
496 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
502497
503498 // subtract register
504 let Defs = [CPSR] in
505 def tSUBrr : T1I<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
506 "sub $dst, $lhs, $rhs",
507 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
499 def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
500 "sub", " $dst, $lhs, $rhs",
501 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
508502
509503 // TODO: A7-96: STMIA - store multiple.
510504
512506 "sub $dst, $rhs * 4", []>;
513507
514508 // sign-extend byte
515 def tSXTB : T1I<(outs tGPR:$dst), (ins tGPR:$src),
516 "sxtb $dst, $src",
517 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
518 Requires<[IsThumb1Only, HasV6]>;
509 def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
510 "sxtb", " $dst, $src",
511 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
512 Requires<[IsThumb1Only, HasV6]>;
519513
520514 // sign-extend short
521 def tSXTH : T1I<(outs tGPR:$dst), (ins tGPR:$src),
522 "sxth $dst, $src",
523 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
524 Requires<[IsThumb1Only, HasV6]>;
515 def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
516 "sxth", " $dst, $src",
517 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
518 Requires<[IsThumb1Only, HasV6]>;
525519
526520 // test
527521 let isCommutable = 1, Defs = [CPSR] in
528 def tTST : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
529 "tst $lhs, $rhs",
530 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
522 def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
523 "tst", " $lhs, $rhs",
524 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
531525
532526 // zero-extend byte
533 def tUXTB : T1I<(outs tGPR:$dst), (ins tGPR:$src),
534 "uxtb $dst, $src",
535 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
536 Requires<[IsThumb1Only, HasV6]>;
527 def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
528 "uxtb", " $dst, $src",
529 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
530 Requires<[IsThumb1Only, HasV6]>;
537531
538532 // zero-extend short
539 def tUXTH : T1I<(outs tGPR:$dst), (ins tGPR:$src),
540 "uxth $dst, $src",
541 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
542 Requires<[IsThumb1Only, HasV6]>;
533 def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
534 "uxth", " $dst, $src",
535 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
536 Requires<[IsThumb1Only, HasV6]>;
543537
544538
545539 // Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
546540 // Expanded by the scheduler into a branch sequence.
541 // FIXME: Add actual movcc in IT blocks for Thumb2.
547542 let usesCustomDAGSchedInserter = 1 in // Expanded by the scheduler.
548543 def tMOVCCr :
549544 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
552547
553548 // tLEApcrel - Load a pc-relative address into a register without offending the
554549 // assembler.
550 let Defs = [CPSR] in {
555551 def tLEApcrel : T1Ix2<(outs tGPR:$dst), (ins i32imm:$label),
556552 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
557553 "${:private}PCRELL${:uid}+4))\n"),
558 !strconcat("\tmov $dst, #PCRELV${:uid}\n",
554 !strconcat("\tmovs $dst, #PCRELV${:uid}\n",
559555 "${:private}PCRELL${:uid}:\n\tadd $dst, pc")),
560556 []>;
561557
562558 def tLEApcrelJT : T1Ix2<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id),
563559 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
564560 "${:private}PCRELL${:uid}+4))\n"),
565 !strconcat("\tmov $dst, #PCRELV${:uid}\n",
561 !strconcat("\tmovs $dst, #PCRELV${:uid}\n",
566562 "${:private}PCRELL${:uid}:\n\tadd $dst, pc")),
567563 []>;
564 }
568565
569566 //===----------------------------------------------------------------------===//
570567 // TLS Instructions
10581058 // Control-Flow Instructions
10591059 //
10601060
1061 let isReturn = 1, isTerminator = 1 in
1062 def t2BX_RET : T2XI<(outs), (ins), "bx lr", [(ARMretflag)]>;
1063
10641061 // FIXME: remove when we have a way to marking a MI with these properties.
10651062 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
10661063 // operand list.
10051005
10061006 MachineBasicBlock::iterator MBBI = prior(MBB.end());
10071007 if (MBBI != MBB.begin() &&
1008 (MBBI->getOpcode() == ARM::BX_RET || MBBI->getOpcode() == ARM::t2BX_RET)){
1008 (MBBI->getOpcode() == ARM::BX_RET || MBBI->getOpcode() == ARM::tBX_RET)) {
10091009 MachineInstr *PrevMI = prior(MBBI);
10101010 if (PrevMI->getOpcode() == ARM::LDM || PrevMI->getOpcode() == ARM::t2LDM) {
10111011 MachineOperand &MO = PrevMI->getOperand(PrevMI->getNumOperands()-1);
973973 bool Result = AsmPrinter::doInitialization(M);
974974 DW = getAnalysisIfAvailable();
975975
976 // Thumb-2 instructions are supported only in unified assembler syntax mode.
977 if (Subtarget->hasThumb2())
976 // Use unified assembler syntax mode for Thumb.
977 if (Subtarget->isThumb())
978978 O << "\t.syntax unified\n";
979979
980980 // Emit ARM Build Attributes
237237 We need to make (some of the) Thumb1 instructions predicable. That will allow
238238 shrinking of predicated Thumb2 instructions. To allow this, we need to be able
239239 to toggle the 's' bit since they do not set CPSR when they are inside IT blocks.
240
241 //===---------------------------------------------------------------------===//
242
243 Make use of hi register variants of cmp: tCMPhir / tCMPZhir.
244
245 //===---------------------------------------------------------------------===//
246
247 Rather than generating ldrsb, sometimes it's better to select to ldrb + sxtb.
248 The problem is ldrsb addressing mode [r, r] means the zero offset requires an
249 extra move. e.g. ldr_ext.ll test3:
250 movs r1, #0
251 ldrsb r0, [r0, r1]
252 =>
253 ldrb r0, [r0, #0]
254 sxtb r0, r0
2121
2222 using namespace llvm;
2323
24 static inline
25 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
26 return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
27 }
28
2429 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
2530 : ARMBaseInstrInfo(STI), RI(*this, STI) {
2631 }
2732
28 unsigned Thumb1InstrInfo::
29 getUnindexedOpcode(unsigned Opc) const {
33 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
3034 return 0;
3135 }
3236
33 unsigned Thumb1InstrInfo::
34 getOpcode(ARMII::Op Op) const {
37 unsigned Thumb1InstrInfo::getOpcode(ARMII::Op Op) const {
3538 switch (Op) {
3639 case ARMII::ADDri: return ARM::tADDi8;
3740 case ARMII::ADDrs: return 0;
206209 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
207210
208211 if (RC == ARM::tGPRRegisterClass) {
209 BuildMI(MBB, I, DL, get(ARM::tSpill))
210 .addReg(SrcReg, getKillRegState(isKill))
211 .addFrameIndex(FI).addImm(0);
212 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSpill))
213 .addReg(SrcReg, getKillRegState(isKill))
214 .addFrameIndex(FI).addImm(0));
212215 }
213216 }
214217
229232 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
230233 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
231234 MIB.addOperand(Addr[i]);
235 AddDefaultPred(MIB);
232236 NewMIs.push_back(MIB);
233237 return;
234238 }
243247 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
244248
245249 if (RC == ARM::tGPRRegisterClass) {
246 BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
247 .addFrameIndex(FI).addImm(0);
250 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
251 .addFrameIndex(FI).addImm(0));
248252 }
249253 }
250254
263267 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
264268 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
265269 MIB.addOperand(Addr[i]);
270 AddDefaultPred(MIB);
266271 NewMIs.push_back(MIB);
267272 return;
268273 }
338343 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
339344 // tSpill cannot take a high register operand.
340345 break;
341 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
342 .addReg(SrcReg, getKillRegState(isKill))
343 .addFrameIndex(FI).addImm(0);
346 NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
347 .addReg(SrcReg, getKillRegState(isKill))
348 .addFrameIndex(FI).addImm(0));
344349 } else { // move -> load
345350 unsigned DstReg = MI->getOperand(0).getReg();
346351 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
347352 // tRestore cannot target a high register operand.
348353 break;
349354 bool isDead = MI->getOperand(0).isDead();
350 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
351 .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
352 .addFrameIndex(FI).addImm(0);
355 NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
356 .addReg(DstReg,
357 RegState::Define | getDeadRegState(isDead))
358 .addFrameIndex(FI).addImm(0));
353359 }
354360 break;
355361 }
4444 : ARMBaseRegisterInfo(tii, sti) {
4545 }
4646
47 static inline
48 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
49 return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
50 }
51
52 static inline
53 const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
54 return MIB.addReg(ARM::CPSR);
55 }
56
4757 /// emitLoadConstPool - Emits a load from constpool to materialize the
4858 /// specified immediate.
4959 void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
5868 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
5969
6070 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp), DestReg)
61 .addConstantPoolIndex(Idx);
71 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
6272 }
6373
6474 const TargetRegisterClass*
93103
94104 return !MF.getFrameInfo()->hasVarSizedObjects();
95105 }
106
96107
97108 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
98109 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
126137 }
127138
128139 if (NumBytes <= 255 && NumBytes >= 0)
129 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
140 AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
141 .addImm(NumBytes);
130142 else if (NumBytes < 0 && NumBytes >= -255) {
131 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
132 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
143 AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
144 .addImm(NumBytes);
145 AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
133146 .addReg(LdReg, RegState::Kill);
134147 } else
135148 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, NumBytes);
136149
137150 // Emit add / sub.
138151 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
139 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
140 TII.get(Opc), DestReg);
152 MachineInstrBuilder MIB =
153 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
154 if (Opc != ARM::tADDhirr)
155 MIB = AddDefaultCC(MIB);
141156 if (DestReg == ARM::SP || isSub)
142157 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
143158 else
144159 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
160 AddDefaultPred(MIB);
161
145162 if (DestReg == ARM::SP)
146163 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
147164 .addReg(ARM::R12, RegState::Kill);
190207 unsigned Scale = 1;
191208 int Opc = 0;
192209 int ExtraOpc = 0;
210 bool NeedCC = false;
211 bool NeedPred = false;
193212
194213 if (DestReg == BaseReg && BaseReg == ARM::SP) {
195214 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
217236 DstNotEqBase = true;
218237 NumBits = 8;
219238 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
239 NeedPred = NeedCC = true;
220240 isTwoAddr = true;
221241 }
222242
236256 unsigned Chunk = (1 << 3) - 1;
237257 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
238258 Bytes -= ThisVal;
239 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
240 .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
259 const TargetInstrDesc &TID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
260 const MachineInstrBuilder MIB =
261 AddDefaultCC(BuildMI(MBB, MBBI, dl, TID, DestReg));
262 AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
241263 } else {
242264 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
243265 .addReg(BaseReg, RegState::Kill);
251273 Bytes -= ThisVal;
252274 ThisVal /= Scale;
253275 // Build the new tADD / tSUB.
254 if (isTwoAddr)
255 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
256 .addReg(DestReg).addImm(ThisVal);
276 if (isTwoAddr) {
277 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
278 if (NeedCC)
279 MIB = AddDefaultCC(MIB);
280 MIB .addReg(DestReg).addImm(ThisVal);
281 if (NeedPred)
282 MIB = AddDefaultPred(MIB);
283 }
257284 else {
258285 bool isKill = BaseReg != ARM::SP;
259 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
260 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
286 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
287 if (NeedCC)
288 MIB = AddDefaultCC(MIB);
289 MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
290 if (NeedPred)
291 MIB = AddDefaultPred(MIB);
261292 BaseReg = DestReg;
262293
263294 if (Opc == ARM::tADDrSPi) {
268299 Scale = 1;
269300 Chunk = ((1 << NumBits) - 1) * Scale;
270301 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
271 isTwoAddr = true;
302 NeedPred = NeedCC = isTwoAddr = true;
272303 }
273304 }
274305 }
275306
276 if (ExtraOpc)
277 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
278 .addReg(DestReg, RegState::Kill)
279 .addImm(((unsigned)NumBytes) & 3);
307 if (ExtraOpc) {
308 const TargetInstrDesc &TID = TII.get(ExtraOpc);
309 AddDefaultPred(AddDefaultCC(BuildMI(MBB, MBBI, dl, TID, DestReg))
310 .addReg(DestReg, RegState::Kill)
311 .addImm(((unsigned)NumBytes) & 3));
312 }
280313 }
281314
282315 static void emitSPUpdate(MachineBasicBlock &MBB,
332365 int Chunk = (1 << 8) - 1;
333366 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
334367 Imm -= ThisVal;
335 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
368 AddDefaultPred(AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8),
369 DestReg))
370 .addImm(ThisVal));
336371 if (Imm > 0)
337372 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
338 if (isSub)
339 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
340 .addReg(DestReg, RegState::Kill);
373 if (isSub) {
374 const TargetInstrDesc &TID = TII.get(ARM::tRSB);
375 AddDefaultPred(AddDefaultCC(BuildMI(MBB, MBBI, dl, TID, DestReg))
376 .addReg(DestReg, RegState::Kill));
377 }
378 }
379
380 static void removeOperands(MachineInstr &MI, unsigned i) {
381 unsigned Op = i;
382 for (unsigned e = MI.getNumOperands(); i != e; ++i)
383 MI.RemoveOperand(Op);
341384 }
342385
343386 void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
383426 unsigned Scale = 1;
384427 if (FrameReg != ARM::SP) {
385428 Opcode = ARM::tADDi3;
386 MI.setDesc(TII.get(ARM::tADDi3));
429 MI.setDesc(TII.get(Opcode));
387430 NumBits = 3;
388431 } else {
389432 NumBits = 8;
404447 unsigned Mask = (1 << NumBits) - 1;
405448 if (((Offset / Scale) & ~Mask) == 0) {
406449 // Replace the FrameIndex with sp / fp
407 MI.getOperand(i).ChangeToRegister(FrameReg, false);
408 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
450 if (Opcode == ARM::tADDi3) {
451 removeOperands(MI, i);
452 MachineInstrBuilder MIB(&MI);
453 AddDefaultPred(AddDefaultCC(MIB).addReg(FrameReg).addImm(Offset/Scale));
454 } else {
455 MI.getOperand(i).ChangeToRegister(FrameReg, false);
456 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
457 }
409458 return;
410459 }
411460
425474 // Translate r0 = add sp, imm to
426475 // r0 = add sp, 255*4
427476 // r0 = add r0, (imm - 255*4)
428 MI.getOperand(i).ChangeToRegister(FrameReg, false);
429 MI.getOperand(i+1).ChangeToImmediate(Mask);
477 if (Opcode == ARM::tADDi3) {
478 removeOperands(MI, i);
479 MachineInstrBuilder MIB(&MI);
480 AddDefaultPred(AddDefaultCC(MIB).addReg(FrameReg).addImm(Mask));
481 } else {
482 MI.getOperand(i).ChangeToRegister(FrameReg, false);
483 MI.getOperand(i+1).ChangeToImmediate(Mask);
484 }
430485 Offset = (Offset - Mask * Scale);
431486 MachineBasicBlock::iterator NII = next(II);
432487 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
497552 // SP+LargeImm.
498553 assert(Offset && "This code isn't needed if offset already handled!");
499554
555 // Remove predicate first.
556 int PIdx = MI.findFirstPredOperandIdx();
557 if (PIdx != -1)
558 removeOperands(MI, PIdx);
559
500560 if (Desc.mayLoad()) {
501561 // Use the destination register to materialize sp + offset.
502562 unsigned TmpReg = MI.getOperand(0).getReg();
509569 emitLoadConstPool(MBB, II, dl, TmpReg, Offset);
510570 UseRR = true;
511571 }
512 } else
572 } else {
513573 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
514574 *this, dl);
575 }
576
515577 MI.setDesc(TII.get(ARM::tLDR));
516578 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
517579 if (UseRR)
566628 .addReg(ARM::R12, RegState::Kill);
567629 } else
568630 assert(false && "Unexpected opcode!");
631
632 // Add predicate back if it's needed.
633 if (MI.getDesc().isPredicable()) {
634 MachineInstrBuilder MIB(&MI);
635 AddDefaultPred(MIB);
636 }
569637 }
570638
571639 void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
2525 : ARMBaseInstrInfo(STI), RI(*this, STI) {
2626 }
2727
28 unsigned Thumb2InstrInfo::
29 getUnindexedOpcode(unsigned Opc) const {
28 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
3029 // FIXME
3130 return 0;
3231 }
3332
34 unsigned Thumb2InstrInfo::
35 getOpcode(ARMII::Op Op) const {
33 unsigned Thumb2InstrInfo::getOpcode(ARMII::Op Op) const {
3634 switch (Op) {
3735 case ARMII::ADDri: return ARM::t2ADDri;
3836 case ARMII::ADDrs: return ARM::t2ADDrs;
4240 case ARMII::BR_JTr: return ARM::t2BR_JTr;
4341 case ARMII::BR_JTm: return ARM::t2BR_JTm;
4442 case ARMII::BR_JTadd: return ARM::t2BR_JTadd;
45 case ARMII::BX_RET: return ARM::t2BX_RET;
43 case ARMII::BX_RET: return ARM::tBX_RET;
4644 case ARMII::FCPYS: return ARM::FCPYS;
4745 case ARMII::FCPYD: return ARM::FCPYD;
4846 case ARMII::FLDD: return ARM::FLDD;
7068
7169 // FIXME
7270 switch (MBB.back().getOpcode()) {
73 case ARM::t2BX_RET:
7471 case ARM::t2LDM_RET:
7572 case ARM::t2B: // Uncond branch.
7673 case ARM::t2BR_JTr: // Jumptable branch.
None ; RUN: llvm-as < %s | llc -march=thumb | grep {lsr r0, r0, #31}
0 ; RUN: llvm-as < %s | llc -march=thumb | FileCheck %s
11
22 define i32 @test1(i32 %X) {
33 entry:
4 ; CHECK: test1:
5 ; CHECK: lsrs r0, r0, #31
46 icmp slt i32 %X, 0 ; :0 [#uses=1]
57 zext i1 %0 to i32 ; :1 [#uses=1]
68 ret i32 %1
None ; RUN: llvm-as < %s | llc -march=thumb | grep cpy | count 2
0 ; RUN: llvm-as < %s | llc -march=thumb | FileCheck %s
11
22 define i32 @f1() {
3 ; CHECK: f1:
4 ; CHECK: ldr r0
35 %buf = alloca [32 x i32], align 4
46 %tmp = getelementptr [32 x i32]* %buf, i32 0, i32 0
57 %tmp1 = load i32* %tmp
79 }
810
911 define i32 @f2() {
12 ; CHECK: f2:
13 ; CHECK: mov r0
14 ; CHECK: ldrb
1015 %buf = alloca [32 x i8], align 4
1116 %tmp = getelementptr [32 x i8]* %buf, i32 0, i32 0
1217 %tmp1 = load i8* %tmp
1520 }
1621
1722 define i32 @f3() {
23 ; CHECK: f3:
24 ; CHECK: ldr r0
1825 %buf = alloca [32 x i32], align 4
1926 %tmp = getelementptr [32 x i32]* %buf, i32 0, i32 32
2027 %tmp1 = load i32* %tmp
2229 }
2330
2431 define i32 @f4() {
32 ; CHECK: f4:
33 ; CHECK: mov r0
34 ; CHECK: ldrb
2535 %buf = alloca [32 x i8], align 4
2636 %tmp = getelementptr [32 x i8]* %buf, i32 0, i32 2
2737 %tmp1 = load i8* %tmp