llvm.org GIT mirror llvm / 63b46fa
Thumb1 register to register MOV instruction is predicable. Fix a FIXME and allow predication (in Thumb2) for the T1 register to register MOV instructions. This allows some better codegen with if-conversion (as seen in the test updates), plus it lays the groundwork for pseudo-izing the tMOVCC instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134197 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 9 years ago
10 changed file(s) with 67 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
12221222 TmpInst.setOpcode(ARM::tMOVr);
12231223 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
12241224 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1225 // Add predicate operands.
1226 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1227 TmpInst.addOperand(MCOperand::CreateReg(0));
12251228 OutStreamer.EmitInstruction(TmpInst);
12261229 }
12271230 {
16091612 TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
16101613 TmpInst.addOperand(MCOperand::CreateReg(ValReg));
16111614 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1612 // 's' bit operand
1613 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1615 // Predicate.
1616 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1617 TmpInst.addOperand(MCOperand::CreateReg(0));
16141618 OutStreamer.AddComment("eh_setjmp begin");
16151619 OutStreamer.EmitInstruction(TmpInst);
16161620 }
267267 // bic r4, r4, MaxAlign
268268 // mov sp, r4
269269 // FIXME: It will be better just to find spare register here.
270 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R4)
271 .addReg(ARM::SP, RegState::Kill);
270 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R4)
271 .addReg(ARM::SP, RegState::Kill));
272272 AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
273273 TII.get(ARM::t2BICri), ARM::R4)
274274 .addReg(ARM::R4, RegState::Kill)
275275 .addImm(MaxAlign-1)));
276 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
277 .addReg(ARM::R4, RegState::Kill);
276 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
277 .addReg(ARM::R4, RegState::Kill));
278278 }
279279
280280 AFI->setShouldRestoreSPFromFP(true);
292292 .addReg(ARM::SP)
293293 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
294294 else
295 BuildMI(MBB, MBBI, dl,
296 TII.get(ARM::tMOVgpr2gpr), RegInfo->getBaseRegister())
297 .addReg(ARM::SP);
295 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),
296 RegInfo->getBaseRegister())
297 .addReg(ARM::SP));
298298 }
299299
300300 // If the frame has variable sized objects then the epilogue must restore
363363 "No scratch register to restore SP from FP!");
364364 emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
365365 ARMCC::AL, 0, TII);
366 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
367 .addReg(ARM::R4);
366 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),
367 ARM::SP)
368 .addReg(ARM::R4));
368369 }
369370 } else {
370371 // Thumb2 or ARM.
372373 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
373374 .addReg(FramePtr).addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
374375 else
375 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
376 .addReg(FramePtr);
376 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),
377 ARM::SP)
378 .addReg(FramePtr));
377379 }
378380 } else if (NumBytes)
379381 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
408408 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
409409 hasExtraDefRegAllocReq = 1 in
410410 def tPOP_RET : tPseudoInst<(outs), (ins pred:$p, reglist:$regs, variable_ops),
411 Size4Bytes, IIC_iPop_Br, []>;
411 Size2Bytes, IIC_iPop_Br, []>;
412412
413413 // All calls clobber the non-callee saved registers. SP is marked as a use to
414414 // prevent stack-pointer assignments that appear immediately before calls from
10531053 // TODO: A7-73: MOV(2) - mov setting flag.
10541054
10551055 let neverHasSideEffects = 1 in {
1056 // FIXME: Make this predicable.
1057 def tMOVr : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr,
1058 "mov\t$Rd, $Rm", []>,
1056 def tMOVr : Thumb1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), AddrModeNone,
1057 Size2Bytes, IIC_iMOVr,
1058 "mov", "\t$Rd, $Rm", "", []>,
10591059 T1Special<0b1000> {
10601060 // A8.6.97
10611061 bits<4> Rd;
10751075 let Inst{2-0} = Rd;
10761076 }
10771077
1078 // FIXME: Make these predicable.
1079 def tMOVgpr2tgpr : T1I<(outs tGPR:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1080 "mov\t$Rd, $Rm", []>,
1078 // FIXME: Do we really need separate instructions for GPR<-->tGPR like this?
1079 // They all map to the same instruction (MOV encoding T1).
1080 def tMOVgpr2tgpr : Thumb1pI<(outs tGPR:$Rd), (ins GPR:$Rm), AddrModeNone,
1081 Size2Bytes, IIC_iMOVr, "mov", "\t$Rd, $Rm", "", []>,
10811082 T1Special<{1,0,0,?}> {
10821083 // A8.6.97
10831084 bits<4> Rd;
10861087 let Inst{6-3} = Rm;
10871088 let Inst{2-0} = Rd{2-0};
10881089 }
1089 def tMOVtgpr2gpr : T1I<(outs GPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr,
1090 "mov\t$Rd, $Rm", []>,
1090 def tMOVtgpr2gpr : Thumb1pI<(outs GPR:$Rd), (ins tGPR:$Rm), AddrModeNone,
1091 Size2Bytes, IIC_iMOVr, "mov", "\t$Rd, $Rm", "", []>,
10911092 T1Special<{1,0,?,0}> {
10921093 // A8.6.97
10931094 bits<4> Rd;
10971098 let Inst{5-3} = Rm{2-0};
10981099 let Inst{2-0} = Rd{2-0};
10991100 }
1100 def tMOVgpr2gpr : T1I<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1101 "mov\t$Rd, $Rm", []>,
1101 def tMOVgpr2gpr : Thumb1pI<(outs GPR:$Rd), (ins GPR:$Rm), AddrModeNone,
1102 Size2Bytes, IIC_iMOVr, "mov", "\t$Rd, $Rm", "", []>,
11021103 T1Special<{1,0,?,?}> {
11031104 // A8.6.97
11041105 bits<4> Rd;
18811881
18821882 if (isThumb)
18831883 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
1884 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp" ||
1885 (Mnemonic == "mov" && isThumbOne))
1884 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
18861885 CanAcceptPredicationCode = false;
18871886 }
18881887
159159 // will be allocated after this, so we can still use the base pointer
160160 // to reference locals.
161161 if (RegInfo->hasBasePointer(MF))
162 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), BasePtr).addReg(ARM::SP);
162 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), BasePtr)
163 .addReg(ARM::SP));
163164
164165 // If the frame has variable sized objects then the epilogue must restore
165166 // the sp from fp. We can assume there's an FP here since hasFP already
238239 "No scratch register to restore SP from FP!");
239240 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
240241 TII, *RegInfo);
241 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
242 .addReg(ARM::R4);
242 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr),
243 ARM::SP)
244 .addReg(ARM::R4));
243245 } else
244 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
245 .addReg(FramePtr);
246 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr),
247 ARM::SP)
248 .addReg(FramePtr));
246249 } else {
247250 if (MBBI->getOpcode() == ARM::tBX_RET &&
248251 &MBB.front() != MBBI &&
4545 else if (tDest)
4646 Opc = ARM::tMOVgpr2tgpr;
4747
48 BuildMI(MBB, I, DL, get(Opc), DestReg)
49 .addReg(SrcReg, getKillRegState(KillSrc));
48 AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg)
49 .addReg(SrcReg, getKillRegState(KillSrc)));
5050 assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
5151 "Thumb1 can only copy GPR registers");
5252 }
243243 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg).setMIFlags(MIFlags));
244244 AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
245245 } else {
246 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
247 .addReg(BaseReg, RegState::Kill)
246 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
247 .addReg(BaseReg, RegState::Kill))
248248 .setMIFlags(MIFlags);
249249 }
250250 BaseReg = DestReg;
418418 // Turn it into a move.
419419 MI.setDesc(TII.get(ARM::tMOVgpr2tgpr));
420420 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
421 // Remove offset and remaining explicit predicate operands.
422 do MI.RemoveOperand(FrameRegIdx+1);
423 while (MI.getNumOperands() > FrameRegIdx+1 &&
424 (!MI.getOperand(FrameRegIdx+1).isReg() ||
425 !MI.getOperand(FrameRegIdx+1).isImm()));
421 // Remove offset and add predicate operands.
422 MI.RemoveOperand(FrameRegIdx+1);
423 MachineInstrBuilder MIB(&MI);
424 AddDefaultPred(MIB);
426425 return true;
427426 }
428427
564563 // the function, the offset will be negative. Use R12 instead since that's
565564 // a call clobbered register that we know won't be used in Thumb1 mode.
566565 DebugLoc DL;
567 BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)).
568 addReg(ARM::R12, RegState::Define).addReg(Reg, RegState::Kill);
566 AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr))
567 .addReg(ARM::R12, RegState::Define)
568 .addReg(Reg, RegState::Kill));
569569
570570 // The UseMI is where we would like to restore the register. If there's
571571 // interference with R12 before then, however, we'll need to restore it
588588 }
589589 }
590590 // Restore the register from R12
591 BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)).
592 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill);
591 AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)).
592 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill));
593593
594594 return true;
595595 }
121121 else if (tDest)
122122 Opc = ARM::tMOVgpr2tgpr;
123123
124 BuildMI(MBB, I, DL, get(Opc), DestReg)
125 .addReg(SrcReg, getKillRegState(KillSrc));
124 AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg)
125 .addReg(SrcReg, getKillRegState(KillSrc)));
126126 }
127127
128128 void Thumb2InstrInfo::
230230 unsigned Opc = 0;
231231 if (DestReg == ARM::SP && BaseReg != ARM::SP) {
232232 // mov sp, rn. Note t2MOVr cannot be used.
233 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg)
234 .addReg(BaseReg).setMIFlags(MIFlags);
233 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg)
234 .addReg(BaseReg).setMIFlags(MIFlags));
235235 BaseReg = ARM::SP;
236236 continue;
237237 }
412412 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
413413 // Remove offset and remaining explicit predicate operands.
414414 do MI.RemoveOperand(FrameRegIdx+1);
415 while (MI.getNumOperands() > FrameRegIdx+1 &&
416 (!MI.getOperand(FrameRegIdx+1).isReg() ||
417 !MI.getOperand(FrameRegIdx+1).isImm()));
415 while (MI.getNumOperands() > FrameRegIdx+1);
416 MachineInstrBuilder MIB(&MI);
417 AddDefaultPred(MIB);
418418 return true;
419419 }
420420
None ; RUN: llc < %s | FileCheck %s
1 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
2 target triple = "thumbv7-apple-darwin10"
0 ; RUN: llc -mtriple=thumbv7-apple-darwin10 < %s | FileCheck %s
31
42 %struct.op = type { %struct.op*, %struct.op*, %struct.op* ()*, i32, i16, i16, i8, i8 }
53
64 ; CHECK: Perl_ck_sort
7 ; CHECK: ldr
8 ; CHECK: mov [[REGISTER:(r[0-9]+)|(lr)]]
9 ; CHECK: str {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24
5 ; CHECK: ldreq
6 ; CHECK: moveq [[REGISTER:(r[0-9]+)|(lr)]]
7 ; CHECK: streq {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24
108
119 define void @Perl_ck_sort() nounwind optsize {
1210 entry:
6969 define void @t3(i32 %a, i32 %b) nounwind {
7070 entry:
7171 ; CHECK: t3:
72 ; CHECK: it lt
73 ; CHECK: poplt {r7, pc}
72 ; CHECK: itt ge
73 ; CHECK: movge r0, r1
74 ; CHECK: blge _foo
7475 %tmp1 = icmp sgt i32 %a, 10 ; [#uses=1]
7576 br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
7677