[llvm-commits] [llvm] r116313 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMMCCodeEmitter.cpp test/MC/ARM/simple-encoding.ll
Jim Grosbach
grosbach at apple.com
Tue Oct 12 10:11:26 PDT 2010
Author: grosbach
Date: Tue Oct 12 12:11:26 2010
New Revision: 116313
URL: http://llvm.org/viewvc/llvm-project?rev=116313&view=rev
Log:
Add encoding information for the remainder of the generic arithmetic
ARM instructions.
Modified:
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
llvm/trunk/test/MC/ARM/simple-encoding.ll
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=116313&r1=116312&r2=116313&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 12 12:11:26 2010
@@ -472,10 +472,14 @@
// The register-immediate version is re-materializable. This is useful
// in particular for taking the address of a local.
let isReMaterializable = 1 in {
- def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
- iii, opc, "\t$dst, $a, $b",
- [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
+ def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
+ iii, opc, "\t$Rd, $Rn, $imm",
+ [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> {
+ bits<4> Rd;
+ bits<4> Rn;
let Inst{25} = 1;
+ let Inst{15-12} = Rd;
+ let Inst{19-16} = Rn;
}
}
def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=116313&r1=116312&r2=116313&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Tue Oct 12 12:11:26 2010
@@ -39,6 +39,8 @@
~ARMMCCodeEmitter() {}
+ unsigned getMachineSoImmOpValue(unsigned SoImm) const;
+
// getBinaryCodeForInstr - TableGen'erated function for getting the
// binary encoding for an instruction.
unsigned getBinaryCodeForInstr(const MCInst &MI) const;
@@ -61,12 +63,6 @@
return rtn;
}
- static unsigned GetARMRegNum(const MCOperand &MO) {
- // FIXME: getARMRegisterNumbering() is sufficient?
- assert(0 && "ARMMCCodeEmitter::GetARMRegNum() not yet implemented.");
- return 0;
- }
-
void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const {
OS << (char)C;
++CurByte;
@@ -93,6 +89,18 @@
} // end anonymous namespace
+unsigned ARMMCCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) const {
+ int SoImmVal = ARM_AM::getSOImmVal(SoImm);
+ assert(SoImmVal != -1 && "Not a valid so_imm value!");
+
+ // Encode rotate_imm.
+ unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
+ << ARMII::SoRotImmShift;
+
+ // Encode immed_8.
+ Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
+ return Binary;
+}
MCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &,
TargetMachine &TM,
@@ -112,12 +120,10 @@
unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
const MCOperand &MO) const {
if (MO.isReg())
- // FIXME: Should shifted register stuff be handled as part of this? Maybe.
return getARMRegisterNumbering(MO.getReg());
- else if (MO.isImm())
- // FIXME: This is insufficient. Shifted immediates and all that... (blech).
+ else if (MO.isImm()) {
return static_cast<unsigned>(MO.getImm());
- else {
+ } else {
#ifndef NDEBUG
errs() << MO;
#endif
@@ -142,31 +148,42 @@
++MCNumEmitted; // Keep track of the # of mi's emitted
// FIXME: TableGen doesn't deal well with operands that expand to multiple
// machine instruction operands, so for now we'll fix those up here.
+ // Similarly, operands that are encoded as other than their literal
+ // values in the MI.
+ unsigned Value = getBinaryCodeForInstr(MI);
switch (Opcode) {
+ default: break;
+ case ARM::ADDri:
+ case ARM::ANDri:
+ case ARM::BICri:
+ case ARM::EORri:
+ case ARM::ORRri:
+ case ARM::SUBri:
+ // The 's' bit.
+ if (MI.getOperand(5).getReg() == ARM::CPSR)
+ Value |= 1 << ARMII::S_BitShift;
+ // The shifted immediate value.
+ Value |= getMachineSoImmOpValue((unsigned)MI.getOperand(2).getImm());
+ break;
case ARM::ADDrs:
case ARM::ANDrs:
case ARM::BICrs:
case ARM::EORrs:
case ARM::ORRrs:
case ARM::SUBrs: {
+ // The 's' bit.
+ if (MI.getOperand(7).getReg() == ARM::CPSR)
+ Value |= 1 << ARMII::S_BitShift;
// The so_reg operand needs the shift ammount encoded.
- unsigned Value = getBinaryCodeForInstr(MI);
unsigned ShVal = MI.getOperand(4).getImm();
unsigned ShType = ARM_AM::getShiftOpcEncoding(ARM_AM::getSORegShOp(ShVal));
unsigned ShAmt = ARM_AM::getSORegOffset(ShVal);
-
Value |= ShType << ARMII::ShiftTypeShift;
Value |= ShAmt << ARMII::ShiftShift;
-
- EmitConstant(Value, 4, CurByte, OS);
- break;
- }
- default: {
- unsigned Value = getBinaryCodeForInstr(MI);
- EmitConstant(Value, 4, CurByte, OS);
break;
}
}
+ EmitConstant(Value, 4, CurByte, OS);
}
// FIXME: These #defines shouldn't be necessary. Instead, tblgen should
Modified: llvm/trunk/test/MC/ARM/simple-encoding.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/simple-encoding.ll?rev=116313&r1=116312&r2=116313&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/simple-encoding.ll (original)
+++ llvm/trunk/test/MC/ARM/simple-encoding.ll Tue Oct 12 12:11:26 2010
@@ -35,4 +35,15 @@
ret i32 %add
}
+define i32 @f4(i32 %a, i32 %b) nounwind readnone ssp {
+entry:
+; CHECK: f4
+; CHECK: add r0, r0, #254, 28 @ encoding: [0xfe,0x0e,0x80,0xe2]
+; CHECK: @ 4064
+; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1]
+ %add = add nsw i32 %a, 4064
+ ret i32 %add
+}
+
+
declare void @llvm.trap() nounwind
More information about the llvm-commits
mailing list