diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2011-03-05 18:43:43 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2011-03-05 18:43:43 +0000 |
commit | 7a764168b9b3b3ebeaea224ed8c6ef93381c74d4 (patch) | |
tree | ee19af61b0510b772a2fe0fe494df930a5ca3ec2 /lib/Target/ARM | |
parent | 7503fcb890155ac1b62542550c7248db4df890f8 (diff) | |
download | external_llvm-7a764168b9b3b3ebeaea224ed8c6ef93381c74d4.zip external_llvm-7a764168b9b3b3ebeaea224ed8c6ef93381c74d4.tar.gz external_llvm-7a764168b9b3b3ebeaea224ed8c6ef93381c74d4.tar.bz2 |
Add unwind information emission for thumb stuff
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 9285556..3d065d8 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -819,9 +819,16 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); unsigned FramePtr = RegInfo->getFrameRegister(MF); - unsigned SrcReg = MI->getOperand(1).getReg(); - unsigned DstReg = MI->getOperand(0).getReg(); unsigned Opc = MI->getOpcode(); + unsigned SrcReg, DstReg; + + // Special case: tPUSH does not have src/dst regs. + if (Opc == ARM::tPUSH) { + SrcReg = DstReg = ARM::SP; + } else { + SrcReg = MI->getOperand(1).getReg(); + DstReg = MI->getOperand(0).getReg(); + } // Try to figure out the unwinding opcode out of src / dst regs. if (MI->getDesc().mayStore()) { @@ -830,15 +837,25 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { "Only stack pointer as a destination reg is supported"); SmallVector<unsigned, 4> RegList; + // Skip src & dst reg, and pred ops. + unsigned StartOp = 2 + 2; + // Use all the operands. + unsigned NumOffset = 0; + switch (Opc) { default: MI->dump(); assert(0 && "Unsupported opcode for unwinding information"); + case ARM::tPUSH: + // Special case here: no src & dst reg, but two extra imp ops. + StartOp = 2; NumOffset = 2; case ARM::STMDB_UPD: + case ARM::t2STMDB_UPD: case ARM::VSTMDDB_UPD: assert(SrcReg == ARM::SP && "Only stack pointer as a source reg is supported"); - for (unsigned i = 4, NumOps = MI->getNumOperands(); i != NumOps; ++i) + for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; + i != NumOps; ++i) RegList.push_back(MI->getOperand(i).getReg()); break; case ARM::STR_PRE: @@ -857,14 +874,23 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { MI->dump(); assert(0 && "Unsupported opcode for unwinding information"); case ARM::MOVr: + case ARM::tMOVgpr2gpr: Offset = 0; break; case ARM::ADDri: Offset = -MI->getOperand(2).getImm(); break; case ARM::SUBri: + case ARM::t2SUBrSPi: Offset = MI->getOperand(2).getImm(); break; + case ARM::tSUBspi: + Offset = MI->getOperand(2).getImm()*4; + break; + case ARM::tADDspi: + case ARM::tADDrSPi: + Offset = -MI->getOperand(2).getImm()*4; + break; } if (DstReg == FramePtr && FramePtr != ARM::SP) |