diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-10-12 17:11:26 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-10-12 17:11:26 +0000 |
commit | 0de6ab3c43ed2143d661115dddf1480545236c91 (patch) | |
tree | 55b49bf275dc29e5346529bdc71950816a0b2554 /lib | |
parent | 77f42b52781b6923924a93b8ab338d183887a592 (diff) |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 10 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 55 |
2 files changed, 43 insertions, 22 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 2ed2bfac10..3d1ddda672 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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, diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index ad87b386d3..27ed551113 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -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 |