forked from OSchip/llvm-project
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:
parent
e106aee6f5
commit
0491270f99
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue