Add encoding information for the remainder of the generic arithmetic

ARM instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116313 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2010-10-12 17:11:26 +00:00
parent 77f42b5278
commit 0de6ab3c43
3 changed files with 54 additions and 22 deletions

View File

@ -472,10 +472,14 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
// 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,

View File

@ -39,6 +39,8 @@ public:
~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 @@ public:
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 @@ public:
} // 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 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
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 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
++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

View File

@ -35,4 +35,15 @@ entry:
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