[llvm-commits] [llvm] r116377 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMInstrInfo.td ARMMCCodeEmitter.cpp
Jim Grosbach
grosbach at apple.com
Tue Oct 12 16:53:58 PDT 2010
Author: grosbach
Date: Tue Oct 12 18:53:58 2010
New Revision: 116377
URL: http://llvm.org/viewvc/llvm-project?rev=116377&view=rev
Log:
Add the rest of the ARM so_reg encoding options (register shifted register)
and move to a custom operand encoder. Remove the last of the special handling
stuff from ARMMCCodeEmitter::EncodeInstruction.
Modified:
llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=116377&r1=116376&r2=116377&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Oct 12 18:53:58 2010
@@ -168,6 +168,8 @@
const { return 0; }
unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
+ unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op)
+ const { return 0; }
/// getMovi32Value - Return binary encoding of operand for movw/movt. If the
/// machine operand requires relocation, record the relocation and return
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=116377&r1=116376&r2=116377&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 12 18:53:58 2010
@@ -313,6 +313,7 @@
def so_reg : Operand<i32>, // reg reg imm
ComplexPattern<i32, 3, "SelectShifterOperandReg",
[shl,srl,sra,rotr]> {
+ string EncoderMethod = "getSORegOpValue";
let PrintMethod = "printSORegOperand";
let MIOperandInfo = (ops GPR, GPR, i32imm);
}
@@ -498,14 +499,14 @@
let Inst{15-12} = Rd;
let Inst{19-16} = Rn;
}
- def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
- iis, opc, "\t$dst, $a, $b",
- [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
+ def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
+ iis, opc, "\t$Rd, $Rn, $shift",
+ [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
bits<4> Rd;
bits<4> Rn;
- bits<4> Rm;
+ bits<12> shift;
let Inst{25} = 0;
- let Inst{3-0} = Rm;
+ let Inst{11-0} = shift;
let Inst{15-12} = Rd;
let Inst{19-16} = Rn;
}
Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=116377&r1=116376&r2=116377&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Tue Oct 12 18:53:58 2010
@@ -55,6 +55,7 @@
// '1' respectively.
return MI.getOperand(Op).getReg() == ARM::CPSR;
}
+
/// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
unsigned getSOImmOpValue(const MCInst &MI, unsigned Op) const {
unsigned SoImm = MI.getOperand(Op).getImm();
@@ -70,6 +71,9 @@
return Binary;
}
+ /// getSORegOpValue - Return an encoded so_reg shifted register value.
+ unsigned getSORegOpValue(const MCInst &MI, unsigned Op) const;
+
unsigned getNumFixupKinds() const {
assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented.");
return 0;
@@ -137,6 +141,76 @@
return 0;
}
+
+unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI,
+ unsigned OpIdx) const {
+ // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg
+ // to be shifted. The second is either Rs, the amount to shift by, or
+ // reg0 in which case the imm contains the amount to shift by.
+ // {3-0} = Rm.
+ // {4} = 1 if reg shift, 0 if imm shift
+ // {6-5} = type
+ // If reg shift:
+ // {7} = 0
+ // {11-8} = Rs
+ // else (imm shift)
+ // {11-7} = imm
+
+ const MCOperand &MO = MI.getOperand(OpIdx);
+ const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
+ const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
+ ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
+
+ // Encode Rm.
+ unsigned Binary = getARMRegisterNumbering(MO.getReg());
+
+ // Encode the shift opcode.
+ unsigned SBits = 0;
+ unsigned Rs = MO1.getReg();
+ if (Rs) {
+ // Set shift operand (bit[7:4]).
+ // LSL - 0001
+ // LSR - 0011
+ // ASR - 0101
+ // ROR - 0111
+ // RRX - 0110 and bit[11:8] clear.
+ switch (SOpc) {
+ default: llvm_unreachable("Unknown shift opc!");
+ case ARM_AM::lsl: SBits = 0x1; break;
+ case ARM_AM::lsr: SBits = 0x3; break;
+ case ARM_AM::asr: SBits = 0x5; break;
+ case ARM_AM::ror: SBits = 0x7; break;
+ case ARM_AM::rrx: SBits = 0x6; break;
+ }
+ } else {
+ // Set shift operand (bit[6:4]).
+ // LSL - 000
+ // LSR - 010
+ // ASR - 100
+ // ROR - 110
+ switch (SOpc) {
+ default: llvm_unreachable("Unknown shift opc!");
+ case ARM_AM::lsl: SBits = 0x0; break;
+ case ARM_AM::lsr: SBits = 0x2; break;
+ case ARM_AM::asr: SBits = 0x4; break;
+ case ARM_AM::ror: SBits = 0x6; break;
+ }
+ }
+ Binary |= SBits << 4;
+ if (SOpc == ARM_AM::rrx)
+ return Binary;
+
+ // Encode the shift operation Rs or shift_imm (except rrx).
+ if (Rs) {
+ // Encode Rs bit[11:8].
+ assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
+ return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
+ }
+
+ // Encode shift_imm bit[11:7].
+ return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
+}
+
void ARMMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const {
@@ -151,27 +225,9 @@
return;
++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::ADDrs:
- case ARM::ANDrs:
- case ARM::BICrs:
- case ARM::EORrs:
- case ARM::ORRrs:
- case ARM::SUBrs: {
- // The so_reg operand needs the shift ammount encoded.
- 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;
- break;
- }
}
EmitConstant(Value, 4, CurByte, OS);
}
More information about the llvm-commits
mailing list