Get rid of the extraneous GPR operand on so_reg_imm operands, which in turn necessitates a lot of changes to related bits.

llvm-svn: 135722
This commit is contained in:
Owen Anderson 2011-07-21 23:38:37 +00:00
parent e106aee6f5
commit 0491270f99
13 changed files with 269 additions and 106 deletions

View File

@ -195,7 +195,9 @@ namespace {
const { return 0; }
unsigned getT2SOImmOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op)
unsigned getSORegRegOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getSORegImmOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }

View File

@ -741,9 +741,22 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MI.eraseFromParent();
return true;
}
case ARM::MOVCCsi:
case ARM::MOVCCsi: {
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
(MI.getOperand(1).getReg()))
.addReg(MI.getOperand(2).getReg(),
getKillRegState(MI.getOperand(2).isKill()))
.addImm(MI.getOperand(3).getImm())
.addImm(MI.getOperand(4).getImm()) // 'pred'
.addReg(MI.getOperand(5).getReg())
.addReg(0); // 's' bit
MI.eraseFromParent();
return true;
}
case ARM::MOVCCsr: {
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs),
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsr),
(MI.getOperand(1).getReg()))
.addReg(MI.getOperand(2).getReg(),
getKillRegState(MI.getOperand(2).isKill()))
@ -838,10 +851,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
case ARM::MOVsrl_flag:
case ARM::MOVsra_flag: {
// These are just fancy MOVs insructions.
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs),
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
MI.getOperand(0).getReg())
.addOperand(MI.getOperand(1))
.addReg(0)
.addImm(ARM_AM::getSORegOpc((Opcode == ARM::MOVsrl_flag ?
ARM_AM::lsr : ARM_AM::asr),
1)))
@ -852,10 +864,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
case ARM::RRX: {
// This encodes as "MOVs Rd, Rm, rrx
MachineInstrBuilder MIB =
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs),
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
MI.getOperand(0).getReg())
.addOperand(MI.getOperand(1))
.addOperand(MI.getOperand(1))
.addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0)))
.addReg(0);
TransferImpOps(MI, MIB, MIB);

View File

@ -94,16 +94,16 @@ public:
SDValue &B, SDValue &C,
bool CheckProfitability = true);
bool SelectImmShifterOperand(SDValue N, SDValue &A,
SDValue &B, SDValue &C,
bool CheckProfitability = true);
bool SelectShiftShifterOperandReg(SDValue N, SDValue &A,
SDValue &B, bool CheckProfitability = true);
bool SelectShiftRegShifterOperand(SDValue N, SDValue &A,
SDValue &B, SDValue &C) {
// Don't apply the profitability check
if (SelectImmShifterOperand(N, A, B, C, false))
return true;
else if (SelectRegShifterOperand(N, A, B, C, false))
return true;
return false;
return SelectRegShifterOperand(N, A, B, C, false);
}
bool SelectShiftImmShifterOperand(SDValue N, SDValue &A,
SDValue &B) {
// Don't apply the profitability check
return SelectImmShifterOperand(N, A, B, false);
}
bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
@ -374,7 +374,6 @@ bool ARMDAGToDAGISel::isShifterOpProfitable(const SDValue &Shift,
bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N,
SDValue &BaseReg,
SDValue &ShReg,
SDValue &Opc,
bool CheckProfitability) {
if (DisableShifterOp)
@ -390,7 +389,6 @@ bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N,
unsigned ShImmVal = 0;
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
if (!RHS) return false;
ShReg = CurDAG->getRegister(0, MVT::i32);
ShImmVal = RHS->getZExtValue() & 31;
Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
MVT::i32);
@ -2067,7 +2065,7 @@ SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
SDValue CPTmp0;
SDValue CPTmp1;
SDValue CPTmp2;
if (SelectImmShifterOperand(TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
if (SelectImmShifterOperand(TrueVal, CPTmp0, CPTmp2)) {
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag };
return CurDAG->SelectNodeTo(N, ARM::MOVCCsi, MVT::i32, Ops, 7);

View File

@ -25,7 +25,7 @@ def BrFrm : Format<2>;
def BrMiscFrm : Format<3>;
def DPFrm : Format<4>;
def DPSoRegFrm : Format<5>;
def DPSoRegRegFrm : Format<5>;
def LdFrm : Format<6>;
def StFrm : Format<7>;
@ -68,6 +68,7 @@ def N3RegVShFrm : Format<38>;
def NVExtFrm : Format<39>;
def NVMulSLFrm : Format<40>;
def NVTBLFrm : Format<41>;
def DPSoRegImmFrm : Format<42>;
// Misc flags.

View File

@ -431,30 +431,40 @@ def ShiftedImmAsmOperand : AsmOperandClass {
def so_reg_reg : Operand<i32>, // reg reg imm
ComplexPattern<i32, 3, "SelectRegShifterOperand",
[shl, srl, sra, rotr]> {
let EncoderMethod = "getSORegOpValue";
let PrintMethod = "printSORegOperand";
let EncoderMethod = "getSORegRegOpValue";
let PrintMethod = "printSORegRegOperand";
let ParserMatchClass = ShiftedRegAsmOperand;
let MIOperandInfo = (ops GPR, GPR, shift_imm);
}
def so_reg_imm : Operand<i32>, // reg imm
ComplexPattern<i32, 3, "SelectImmShifterOperand",
ComplexPattern<i32, 2, "SelectImmShifterOperand",
[shl, srl, sra, rotr]> {
let EncoderMethod = "getSORegOpValue";
let PrintMethod = "printSORegOperand";
let EncoderMethod = "getSORegImmOpValue";
let PrintMethod = "printSORegImmOperand";
let ParserMatchClass = ShiftedImmAsmOperand;
let MIOperandInfo = (ops GPR, shift_imm);
}
// FIXME: Does this need to be distinct from so_reg?
def shift_so_reg_reg : Operand<i32>, // reg reg imm
ComplexPattern<i32, 3, "SelectShiftRegShifterOperand",
[shl,srl,sra,rotr]> {
let EncoderMethod = "getSORegRegOpValue";
let PrintMethod = "printSORegRegOperand";
let MIOperandInfo = (ops GPR, GPR, shift_imm);
}
// FIXME: Does this need to be distinct from so_reg?
def shift_so_reg : Operand<i32>, // reg reg imm
ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
def shift_so_reg_imm : Operand<i32>, // reg reg imm
ComplexPattern<i32, 2, "SelectShiftImmShifterOperand",
[shl,srl,sra,rotr]> {
let EncoderMethod = "getSORegOpValue";
let PrintMethod = "printSORegOperand";
let MIOperandInfo = (ops GPR, GPR, shift_imm);
let EncoderMethod = "getSORegImmOpValue";
let PrintMethod = "printSORegImmOperand";
let MIOperandInfo = (ops GPR, shift_imm);
}
// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
// 8-bit immediate rotated by an arbitrary number of bits.
def SOImmAsmOperand: AsmOperandClass { let Name = "ARMSOImm"; }
@ -772,7 +782,7 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
}
def rsi : AsI1<opcod, (outs GPR:$Rd),
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegFrm,
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
iis, opc, "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
bits<4> Rd;
@ -787,7 +797,7 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
}
def rsr : AsI1<opcod, (outs GPR:$Rd),
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegFrm,
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
iis, opc, "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
bits<4> Rd;
@ -861,7 +871,7 @@ multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
let Inst{3-0} = Rm;
}
def rsi : AI1<opcod, (outs GPR:$Rd),
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegFrm,
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
iis, opc, "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
bits<4> Rd;
@ -877,7 +887,7 @@ multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
}
def rsr : AI1<opcod, (outs GPR:$Rd),
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegFrm,
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
iis, opc, "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
bits<4> Rd;
@ -928,7 +938,7 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc,
let Inst{3-0} = Rm;
}
def rsi : AI1<opcod, (outs),
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegFrm, iis,
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, iis,
opc, "\t$Rn, $shift",
[(opnode GPR:$Rn, so_reg_imm:$shift)]> {
bits<4> Rn;
@ -942,7 +952,7 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc,
let Inst{3-0} = shift{3-0};
}
def rsr : AI1<opcod, (outs),
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegFrm, iis,
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, iis,
opc, "\t$Rn, $shift",
[(opnode GPR:$Rn, so_reg_reg:$shift)]> {
bits<4> Rn;
@ -1094,7 +1104,7 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
}
def rsi : AsI1<opcod, (outs GPR:$Rd),
(ins GPR:$Rn, so_reg_imm:$shift),
DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
DPSoRegImmFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]>,
Requires<[IsARM]> {
bits<4> Rd;
@ -1109,7 +1119,7 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
}
def rsr : AsI1<opcod, (outs GPR:$Rd),
(ins GPR:$Rn, so_reg_reg:$shift),
DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
DPSoRegRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]>,
Requires<[IsARM]> {
bits<4> Rd;
@ -2215,18 +2225,38 @@ def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm,
let Inst{15-12} = Rd;
}
def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src),
DPSoRegFrm, IIC_iMOVsr,
"mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>,
def MOVsr : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_reg:$src),
DPSoRegRegFrm, IIC_iMOVsr,
"mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_reg:$src)]>,
UnaryDP {
bits<4> Rd;
bits<12> src;
let Inst{15-12} = Rd;
let Inst{19-16} = 0b0000;
let Inst{11-0} = src;
let Inst{11-8} = src{11-8};
let Inst{7} = 0;
let Inst{6-5} = src{6-5};
let Inst{4} = 1;
let Inst{3-0} = src{3-0};
let Inst{25} = 0;
}
def MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src),
DPSoRegImmFrm, IIC_iMOVsr,
"mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>,
UnaryDP {
bits<4> Rd;
bits<12> src;
let Inst{15-12} = Rd;
let Inst{19-16} = 0b0000;
let Inst{11-5} = src{11-5};
let Inst{4} = 0;
let Inst{3-0} = src{3-0};
let Inst{25} = 0;
}
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
"mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP {
@ -2450,7 +2480,7 @@ def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
}
def RSBrsi : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
DPSoRegImmFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (sub so_reg_imm:$shift, GPR:$Rn))]> {
bits<4> Rd;
bits<4> Rn;
@ -2464,7 +2494,7 @@ def RSBrsi : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
}
def RSBrsr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
DPSoRegRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (sub so_reg_reg:$shift, GPR:$Rn))]> {
bits<4> Rd;
bits<4> Rn;
@ -2524,7 +2554,7 @@ def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
let Inst{19-16} = Rn;
}
def RSCrsi : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
DPSoRegImmFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (sube_dead_carry so_reg_imm:$shift, GPR:$Rn))]>,
Requires<[IsARM]> {
bits<4> Rd;
@ -2538,7 +2568,7 @@ def RSCrsi : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
let Inst{3-0} = shift{3-0};
}
def RSCrsr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
DPSoRegRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
[(set GPR:$Rd, (sube_dead_carry so_reg_reg:$shift, GPR:$Rn))]>,
Requires<[IsARM]> {
bits<4> Rd;
@ -2838,7 +2868,7 @@ def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
let Inst{15-12} = Rd;
let Inst{3-0} = Rm;
}
def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), DPSoRegFrm,
def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), DPSoRegImmFrm,
IIC_iMVNsr, "mvn", "\t$Rd, $shift",
[(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP {
bits<4> Rd;
@ -2850,7 +2880,7 @@ def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), DPSoRegFrm,
let Inst{4} = 0;
let Inst{3-0} = shift{3-0};
}
def MVNsr : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift), DPSoRegFrm,
def MVNsr : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift), DPSoRegRegFrm,
IIC_iMVNsr, "mvn", "\t$Rd, $shift",
[(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP {
bits<4> Rd;

View File

@ -251,7 +251,9 @@ public:
SmallVectorImpl<MCFixup> &Fixups) const;
/// getSORegOpValue - Return an encoded so_reg shifted register value.
unsigned getSORegOpValue(const MCInst &MI, unsigned Op,
unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
@ -934,7 +936,7 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
}
unsigned ARMMCCodeEmitter::
getSORegOpValue(const MCInst &MI, unsigned OpIdx,
getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) 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
@ -966,45 +968,72 @@ getSORegOpValue(const MCInst &MI, unsigned OpIdx,
// 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 Rs bit[11:8].
assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
}
unsigned ARMMCCodeEmitter::
getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) 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:
// {11-8} = Rs
// {7} = 0
// else (imm shift)
// {11-7} = imm
const MCOperand &MO = MI.getOperand(OpIdx);
const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
// Encode Rm.
unsigned Binary = getARMRegisterNumbering(MO.getReg());
// Encode the shift opcode.
unsigned SBits = 0;
// Set shift operand (bit[6:4]).
// LSL - 000
// LSR - 010
// ASR - 100
// ROR - 110
// RRX - 110 and bit[11:8] clear.
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;
case ARM_AM::rrx:
Binary |= 0x60;
return Binary;
}
// Encode shift_imm bit[11:7].
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
Binary |= SBits << 4;
return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
}
unsigned ARMMCCodeEmitter::
getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups) const {

View File

@ -626,13 +626,9 @@ public:
}
void addShiftedImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 3 && "Invalid number of operands!");
assert(N == 2 && "Invalid number of operands!");
assert(isShiftedImm() && "addShiftedImmOperands() on non ShiftedImm!");
Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
if (ShiftedImm.ShiftTy == ARM_AM::rrx)
Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
else
Inst.addOperand(MCOperand::CreateReg(0));
Inst.addOperand(MCOperand::CreateImm(
ARM_AM::getSORegOpc(ShiftedImm.ShiftTy, ShiftedImm.ShiftImm)));
}

View File

@ -1090,7 +1090,7 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
static bool DisassembleDPSoRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
static bool DisassembleDPSoRegRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const MCInstrDesc &MCID = ARMInsts[Opcode];
@ -1180,6 +1180,69 @@ static bool DisassembleDPSoRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
static bool DisassembleDPSoRegImmFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const MCInstrDesc &MCID = ARMInsts[Opcode];
unsigned short NumDefs = MCID.getNumDefs();
bool isUnary = isUnaryDP(MCID.TSFlags);
const MCOperandInfo *OpInfo = MCID.OpInfo;
unsigned &OpIdx = NumOpsAdded;
OpIdx = 0;
// Disassemble register def if there is one.
if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
}
// Disassemble the src operands.
if (OpIdx >= NumOps)
return false;
// BinaryDP has an Rn operand.
if (!isUnary) {
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
// If this is a two-address operand, skip it, e.g., MOVCCs operand 1.
if (isUnary && (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)) {
MI.addOperand(MCOperand::CreateReg(0));
++OpIdx;
}
// Disassemble operand 2, which consists of two components.
if (OpIdx + 1 >= NumOps)
return false;
assert((OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) &&
(OpInfo[OpIdx+1].RegClass < 0) &&
"Expect 2 reg operands");
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
// Inst{6-5} encodes the shift opcode.
ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
// Inst{11-7} encodes the imm5 shift amount.
unsigned ShImm = slice(insn, 11, 7);
// A8.4.1. Possible rrx or shift amount of 32...
getImmShiftSE(ShOp, ShImm);
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShImm)));
OpIdx += 2;
return true;
}
static bool BadRegsLdStFrm(unsigned Opcode, uint32_t insn, bool Store, bool WBack,
bool Imm) {
const StringRef Name = ARMInsts[Opcode].Name;
@ -3484,7 +3547,7 @@ static const DisassembleFP FuncPtrs[] = {
&DisassembleBrFrm,
&DisassembleBrMiscFrm,
&DisassembleDPFrm,
&DisassembleDPSoRegFrm,
&DisassembleDPSoRegRegFrm,
&DisassembleLdFrm,
&DisassembleStFrm,
&DisassembleLdMiscFrm,
@ -3552,6 +3615,9 @@ static const DisassembleFP FuncPtrs[] = {
// values in a table and generate a new vector.
&DisassembleNVTBLFrm,
&DisassembleDPSoRegImmFrm,
NULL
};

View File

@ -51,7 +51,7 @@ public:
ENTRY(ARM_FORMAT_BRFRM, 2) \
ENTRY(ARM_FORMAT_BRMISCFRM, 3) \
ENTRY(ARM_FORMAT_DPFRM, 4) \
ENTRY(ARM_FORMAT_DPSOREGFRM, 5) \
ENTRY(ARM_FORMAT_DPSOREGREGFRM, 5) \
ENTRY(ARM_FORMAT_LDFRM, 6) \
ENTRY(ARM_FORMAT_STFRM, 7) \
ENTRY(ARM_FORMAT_LDMISCFRM, 8) \
@ -87,7 +87,8 @@ public:
ENTRY(ARM_FORMAT_N3RegVecSh, 38) \
ENTRY(ARM_FORMAT_NVecExtract, 39) \
ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
ENTRY(ARM_FORMAT_NVTBL, 41)
ENTRY(ARM_FORMAT_NVTBL, 41) \
ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42)
// ARM instruction format specifies the encoding used by the instruction.
#define ENTRY(n, v) n = v,

View File

@ -37,7 +37,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
unsigned Opcode = MI->getOpcode();
// Check for MOVs and print canonical forms, instead.
if (Opcode == ARM::MOVs) {
if (Opcode == ARM::MOVsr) {
// FIXME: Thumb variants?
const MCOperand &Dst = MI->getOperand(0);
const MCOperand &MO1 = MI->getOperand(1);
@ -51,20 +51,32 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
O << '\t' << getRegisterName(Dst.getReg())
<< ", " << getRegisterName(MO1.getReg());
if (ARM_AM::getSORegShOp(MO3.getImm()) == ARM_AM::rrx)
return;
O << ", ";
if (MO2.getReg()) {
O << getRegisterName(MO2.getReg());
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
} else {
O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
}
O << ", " << getRegisterName(MO2.getReg());
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
return;
}
if (Opcode == ARM::MOVsi) {
// FIXME: Thumb variants?
const MCOperand &Dst = MI->getOperand(0);
const MCOperand &MO1 = MI->getOperand(1);
const MCOperand &MO2 = MI->getOperand(2);
O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
printSBitModifierOperand(MI, 5, O);
printPredicateOperand(MI, 3, O);
O << '\t' << getRegisterName(Dst.getReg())
<< ", " << getRegisterName(MO1.getReg());
if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx)
return;
O << ", #" << ARM_AM::getSORegOffset(MO2.getImm());
return;
}
// A8.6.123 PUSH
if ((Opcode == ARM::STMDB_UPD || Opcode == ARM::t2STMDB_UPD) &&
MI->getOperand(0).getReg() == ARM::SP) {
@ -154,7 +166,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
// REG 0 0 - e.g. R5
// REG REG 0,SH_OPC - e.g. R5, ROR R3
// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@ -167,14 +179,27 @@ void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum,
O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
if (ShOpc == ARM_AM::rrx)
return;
if (MO2.getReg()) {
O << ' ' << getRegisterName(MO2.getReg());
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
} else if (ShOpc != ARM_AM::rrx) {
O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
}
O << ' ' << getRegisterName(MO2.getReg());
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
}
void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
O << getRegisterName(MO1.getReg());
// Print the shift opc.
ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
if (ShOpc == ARM_AM::rrx)
return;
O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
}
//===--------------------------------------------------------------------===//
// Addressing Mode #2
//===--------------------------------------------------------------------===//

View File

@ -38,7 +38,8 @@ public:
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printSORegRegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printSORegImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);

View File

@ -41,7 +41,7 @@ using namespace llvm;
ENTRY(ARM_FORMAT_BRFRM, 2) \
ENTRY(ARM_FORMAT_BRMISCFRM, 3) \
ENTRY(ARM_FORMAT_DPFRM, 4) \
ENTRY(ARM_FORMAT_DPSOREGFRM, 5) \
ENTRY(ARM_FORMAT_DPSOREGREGFRM, 5) \
ENTRY(ARM_FORMAT_LDFRM, 6) \
ENTRY(ARM_FORMAT_STFRM, 7) \
ENTRY(ARM_FORMAT_LDMISCFRM, 8) \
@ -77,7 +77,8 @@ using namespace llvm;
ENTRY(ARM_FORMAT_N3RegVecSh, 38) \
ENTRY(ARM_FORMAT_NVecExtract, 39) \
ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
ENTRY(ARM_FORMAT_NVTBL, 41)
ENTRY(ARM_FORMAT_NVTBL, 41) \
ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42)
// ARM instruction format specifies the encoding used by the instruction.
#define ENTRY(n, v) n = v,

View File

@ -623,9 +623,10 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
MISC("t_bltarget", "kOperandTypeARMBranchTarget"); // ?
MISC("t_blxtarget", "kOperandTypeARMBranchTarget"); // ?
MISC("so_reg_imm", "kOperandTypeARMSoReg"); // R, R, I
MISC("so_reg_reg", "kOperandTypeARMSoReg"); // R, R, I
MISC("shift_so_reg", "kOperandTypeARMSoReg"); // R, R, I
MISC("so_reg_imm", "kOperandTypeARMSoRegReg"); // R, R, I
MISC("so_reg_reg", "kOperandTypeARMSoRegImm"); // R, R, I
MISC("shift_so_reg_reg", "kOperandTypeARMSoRegReg"); // R, R, I
MISC("shift_so_reg_imm", "kOperandTypeARMSoRegImm"); // R, R, I
MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I
MISC("so_imm", "kOperandTypeARMSoImm"); // I
MISC("rot_imm", "kOperandTypeARMRotImm"); // I
@ -854,7 +855,8 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) {
operandTypes.addEntry("kOperandTypeX86EffectiveAddress");
operandTypes.addEntry("kOperandTypeX86PCRelative");
operandTypes.addEntry("kOperandTypeARMBranchTarget");
operandTypes.addEntry("kOperandTypeARMSoReg");
operandTypes.addEntry("kOperandTypeARMSoRegReg");
operandTypes.addEntry("kOperandTypeARMSoRegImm");
operandTypes.addEntry("kOperandTypeARMSoImm");
operandTypes.addEntry("kOperandTypeARMRotImm");
operandTypes.addEntry("kOperandTypeARMSoImm2Part");