forked from OSchip/llvm-project
Change how so_imm and t2_so_imm are handled. At instruction selection time, the immediates are no longer encoded in the imm8 + rot format, that are left as it is. The encoding is now done in ams printing and code emission time instead.
llvm-svn: 75048
This commit is contained in:
parent
0c9f367d62
commit
e3a53c448b
|
@ -273,29 +273,6 @@ namespace ARM_AM {
|
|||
return V >> getThumbImmValShift(V);
|
||||
}
|
||||
|
||||
/// getT2SOImmValDecode - Given a 12-bit encoded Thumb-2 modified immediate,
|
||||
/// return the corresponding 32-bit immediate value.
|
||||
/// See ARM Reference Manual A6.3.2.
|
||||
static inline unsigned getT2SOImmValDecode(unsigned Imm) {
|
||||
unsigned Base = Imm & 0xff;
|
||||
switch ((Imm >> 8) & 0xf) {
|
||||
case 0:
|
||||
return Base;
|
||||
case 1:
|
||||
return Base | (Base << 16);
|
||||
case 2:
|
||||
return (Base << 8) | (Base << 24);
|
||||
case 3:
|
||||
return Base | (Base << 8) | (Base << 16) | (Base << 24);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// shifted immediate
|
||||
unsigned RotAmount = ((Imm >> 7) & 0x1f) - 8;
|
||||
return (Base | 0x80) << (24 - RotAmount);
|
||||
}
|
||||
|
||||
/// getT2SOImmValSplat - Return the 12-bit encoded representation
|
||||
/// if the specified value can be obtained by splatting the low 8 bits
|
||||
/// into every other byte or every byte of a 32-bit value. i.e.,
|
||||
|
|
|
@ -91,15 +91,14 @@ ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
|||
bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
|
||||
unsigned Amt = ARM_AM::getAM2Offset(OffImm);
|
||||
if (OffReg == 0) {
|
||||
int SOImmVal = ARM_AM::getSOImmVal(Amt);
|
||||
if (SOImmVal == -1)
|
||||
if (ARM_AM::getSOImmVal(Amt) == -1)
|
||||
// Can't encode it in a so_imm operand. This transformation will
|
||||
// add more than 1 instruction. Abandon!
|
||||
return NULL;
|
||||
UpdateMI = BuildMI(MF, MI->getDebugLoc(),
|
||||
get(isSub ? getOpcode(ARMII::SUBri) :
|
||||
getOpcode(ARMII::ADDri)), WBReg)
|
||||
.addReg(BaseReg).addImm(SOImmVal)
|
||||
.addReg(BaseReg).addImm(Amt)
|
||||
.addImm(Pred).addReg(0).addReg(0);
|
||||
} else if (Amt != 0) {
|
||||
ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
|
||||
|
|
|
@ -942,13 +942,11 @@ void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
|
|||
// We will handle these bits from offset, clear them.
|
||||
NumBytes &= ~ThisVal;
|
||||
|
||||
// Get the properly encoded SOImmVal field.
|
||||
int SOImmVal = ARM_AM::getSOImmVal(ThisVal);
|
||||
assert(SOImmVal != -1 && "Bit extraction didn't work?");
|
||||
assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?");
|
||||
|
||||
// Build the new ADD / SUB.
|
||||
BuildMI(MBB, MBBI, dl, TII.get(TII.getOpcode(isSub ? ARMII::SUBri : ARMII::ADDri)), DestReg)
|
||||
.addReg(BaseReg, RegState::Kill).addImm(SOImmVal)
|
||||
.addReg(BaseReg, RegState::Kill).addImm(ThisVal)
|
||||
.addImm((unsigned)Pred).addReg(PredReg).addReg(0);
|
||||
BaseReg = DestReg;
|
||||
}
|
||||
|
@ -1071,11 +1069,10 @@ eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||
}
|
||||
|
||||
// Common case: small offset, fits into instruction.
|
||||
int ImmedOffset = ARM_AM::getSOImmVal(Offset);
|
||||
if (ImmedOffset != -1) {
|
||||
if (ARM_AM::getSOImmVal(Offset) != -1) {
|
||||
// Replace the FrameIndex with sp / fp
|
||||
MI.getOperand(i).ChangeToRegister(FrameReg, false);
|
||||
MI.getOperand(i+1).ChangeToImmediate(ImmedOffset);
|
||||
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1089,9 +1086,9 @@ eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||
Offset &= ~ThisImmVal;
|
||||
|
||||
// Get the properly encoded SOImmVal field.
|
||||
int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal);
|
||||
assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
|
||||
MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal);
|
||||
assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
|
||||
"Bit extraction didn't work?");
|
||||
MI.getOperand(i+1).ChangeToImmediate(ThisImmVal);
|
||||
} else {
|
||||
unsigned ImmIdx = 0;
|
||||
int InstrOffs = 0;
|
||||
|
|
|
@ -470,7 +470,8 @@ template<class CodeEmitter>
|
|||
void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
||||
const MachineOperand &MO0 = MI.getOperand(0);
|
||||
const MachineOperand &MO1 = MI.getOperand(1);
|
||||
assert(MO1.isImm() && "Not a valid so_imm value!");
|
||||
assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 &&
|
||||
"Not a valid so_imm value!");
|
||||
unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO1.getImm());
|
||||
unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO1.getImm());
|
||||
|
||||
|
@ -486,7 +487,7 @@ void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
|||
// Encode so_imm.
|
||||
// Set bit I(25) to identify this is the immediate form of <shifter_op>
|
||||
Binary |= 1 << ARMII::I_BitShift;
|
||||
Binary |= getMachineSoImmOpValue(ARM_AM::getSOImmVal(V1));
|
||||
Binary |= getMachineSoImmOpValue(V1);
|
||||
emitWordLE(Binary);
|
||||
|
||||
// Now the 'orr' instruction.
|
||||
|
@ -504,7 +505,7 @@ void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
|||
// Encode so_imm.
|
||||
// Set bit I(25) to identify this is the immediate form of <shifter_op>
|
||||
Binary |= 1 << ARMII::I_BitShift;
|
||||
Binary |= getMachineSoImmOpValue(ARM_AM::getSOImmVal(V2));
|
||||
Binary |= getMachineSoImmOpValue(V2);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
|
@ -714,12 +715,15 @@ unsigned Emitter<CodeEmitter>::getMachineSoRegOpValue(
|
|||
|
||||
template<class CodeEmitter>
|
||||
unsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) {
|
||||
int SoImmVal = ARM_AM::getSOImmVal(SoImm);
|
||||
assert(SoImmVal != -1 && "Not a valid so_imm value!");
|
||||
|
||||
// Encode rotate_imm.
|
||||
unsigned Binary = (ARM_AM::getSOImmValRot(SoImm) >> 1)
|
||||
unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
|
||||
<< ARMII::SoRotImmShift;
|
||||
|
||||
// Encode immed_8.
|
||||
Binary |= ARM_AM::getSOImmValImm(SoImm);
|
||||
Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
|
||||
return Binary;
|
||||
}
|
||||
|
||||
|
@ -796,8 +800,7 @@ void Emitter<CodeEmitter>::emitDataProcessingInstruction(
|
|||
}
|
||||
|
||||
// Encode so_imm.
|
||||
Binary |= 1 << ARMII::I_BitShift;
|
||||
Binary |= getMachineSoImmOpValue(MO.getImm());
|
||||
Binary |= getMachineSoImmOpValue((unsigned)MO.getImm());
|
||||
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
|
|
@ -1071,10 +1071,10 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
|||
}
|
||||
|
||||
// Pattern: (ARMcmov:i32 GPR:i32:$false,
|
||||
// (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true,
|
||||
// (imm:i32)<<P:Predicate_so_imm>>:$true,
|
||||
// (imm:i32):$cc)
|
||||
// Emits: (MOVCCi:i32 GPR:i32:$false,
|
||||
// (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc)
|
||||
// (so_imm:i32 (imm:i32):$true), (imm:i32):$cc)
|
||||
// Pattern complexity = 10 cost = 1 size = 0
|
||||
if (N3.getOpcode() == ISD::Constant) {
|
||||
if (Subtarget->isThumb()) {
|
||||
|
@ -1082,7 +1082,6 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
|||
SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned)
|
||||
cast<ConstantSDNode>(N1)->getZExtValue()),
|
||||
MVT::i32);
|
||||
Tmp1 = Transform_t2_so_imm_XFORM(Tmp1.getNode());
|
||||
SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
|
||||
cast<ConstantSDNode>(N2)->getZExtValue()),
|
||||
MVT::i32);
|
||||
|
@ -1095,7 +1094,6 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
|||
SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned)
|
||||
cast<ConstantSDNode>(N1)->getZExtValue()),
|
||||
MVT::i32);
|
||||
Tmp1 = Transform_so_imm_XFORM(Tmp1.getNode());
|
||||
SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
|
||||
cast<ConstantSDNode>(N2)->getZExtValue()),
|
||||
MVT::i32);
|
||||
|
|
|
@ -118,25 +118,16 @@ class RegConstraint<string C> {
|
|||
// ARM specific transformation functions and pattern fragments.
|
||||
//
|
||||
|
||||
// so_imm_XFORM - Return a so_imm value packed into the format described for
|
||||
// so_imm def below.
|
||||
def so_imm_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(N->getZExtValue()),
|
||||
MVT::i32);
|
||||
}]>;
|
||||
|
||||
// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
|
||||
// so_imm_neg def below.
|
||||
def so_imm_neg_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(-(int)N->getZExtValue()),
|
||||
MVT::i32);
|
||||
return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// so_imm_not_XFORM - Return a so_imm value packed into the format described for
|
||||
// so_imm_not def below.
|
||||
def so_imm_not_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(~(int)N->getZExtValue()),
|
||||
MVT::i32);
|
||||
return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
|
||||
|
@ -234,9 +225,9 @@ def so_reg : Operand<i32>, // reg reg imm
|
|||
// into so_imm instructions: the 8-bit immediate is the least significant bits
|
||||
// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
|
||||
def so_imm : Operand<i32>,
|
||||
PatLeaf<(imm),
|
||||
[{ return ARM_AM::getSOImmVal(N->getZExtValue()) != -1; }],
|
||||
so_imm_XFORM> {
|
||||
PatLeaf<(imm), [{
|
||||
return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
|
||||
}]> {
|
||||
let PrintMethod = "printSOImmOperand";
|
||||
}
|
||||
|
||||
|
@ -252,12 +243,12 @@ def so_imm2part : Operand<i32>,
|
|||
|
||||
def so_imm2part_1 : SDNodeXForm<imm, [{
|
||||
unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
|
||||
return CurDAG->getTargetConstant(V, MVT::i32);
|
||||
}]>;
|
||||
|
||||
def so_imm2part_2 : SDNodeXForm<imm, [{
|
||||
unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
|
||||
return CurDAG->getTargetConstant(V, MVT::i32);
|
||||
}]>;
|
||||
|
||||
|
||||
|
@ -1440,11 +1431,11 @@ def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
|
|||
[(set GPR:$dst, so_imm2part:$src)]>;
|
||||
|
||||
def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
|
||||
(ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
|
||||
(so_imm2part_2 imm:$RHS))>;
|
||||
(ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
|
||||
(so_imm2part_2 imm:$RHS))>;
|
||||
def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
|
||||
(EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
|
||||
(so_imm2part_2 imm:$RHS))>;
|
||||
(EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
|
||||
(so_imm2part_2 imm:$RHS))>;
|
||||
|
||||
// TODO: add,sub,and, 3-instr forms?
|
||||
|
||||
|
|
|
@ -20,23 +20,14 @@ def t2_so_reg : Operand<i32>, // reg imm
|
|||
let MIOperandInfo = (ops GPR, i32imm);
|
||||
}
|
||||
|
||||
// t2_so_imm_XFORM - Return a t2_so_imm value packed into the format
|
||||
// described for t2_so_imm def below.
|
||||
def t2_so_imm_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(
|
||||
ARM_AM::getT2SOImmVal(N->getZExtValue()), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
|
||||
def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(
|
||||
ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())), MVT::i32);
|
||||
return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
|
||||
def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(
|
||||
ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())), MVT::i32);
|
||||
return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// t2_so_imm - Match a 32-bit immediate operand, which is an
|
||||
|
@ -47,27 +38,21 @@ def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
|
|||
// [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
|
||||
def t2_so_imm : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
|
||||
}], t2_so_imm_XFORM> {
|
||||
let PrintMethod = "printT2SOImmOperand";
|
||||
}
|
||||
return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
|
||||
}]>;
|
||||
|
||||
// t2_so_imm_not - Match an immediate that is a complement
|
||||
// of a t2_so_imm.
|
||||
def t2_so_imm_not : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
|
||||
}], t2_so_imm_not_XFORM> {
|
||||
let PrintMethod = "printT2SOImmOperand";
|
||||
}
|
||||
return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
|
||||
}], t2_so_imm_not_XFORM>;
|
||||
|
||||
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
|
||||
def t2_so_imm_neg : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
|
||||
}], t2_so_imm_neg_XFORM> {
|
||||
let PrintMethod = "printT2SOImmOperand";
|
||||
}
|
||||
return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
|
||||
}], t2_so_imm_neg_XFORM>;
|
||||
|
||||
/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
|
||||
def imm1_31 : PatLeaf<(i32 imm), [{
|
||||
|
|
|
@ -171,12 +171,11 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||
BaseOpc = ARM::SUBri;
|
||||
Offset = - Offset;
|
||||
}
|
||||
int ImmedOffset = ARM_AM::getSOImmVal(Offset);
|
||||
if (ImmedOffset == -1)
|
||||
if (ARM_AM::getSOImmVal(Offset) == -1)
|
||||
return false; // Probably not worth it then.
|
||||
|
||||
BuildMI(MBB, MBBI, dl, TII->get(BaseOpc), NewBase)
|
||||
.addReg(Base, getKillRegState(BaseKill)).addImm(ImmedOffset)
|
||||
.addReg(Base, getKillRegState(BaseKill)).addImm(Offset)
|
||||
.addImm(Pred).addReg(PredReg).addReg(0);
|
||||
Base = NewBase;
|
||||
BaseKill = true; // New base is always killed right its use.
|
||||
|
|
|
@ -119,7 +119,6 @@ namespace {
|
|||
void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum);
|
||||
void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum);
|
||||
|
||||
void printT2SOImmOperand(const MachineInstr *MI, int OpNum);
|
||||
void printT2SOOperand(const MachineInstr *MI, int OpNum);
|
||||
void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum);
|
||||
void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum);
|
||||
|
@ -370,7 +369,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
|||
|
||||
static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
|
||||
const TargetAsmInfo *TAI) {
|
||||
assert(V < (1 << 12) && "Not a valid so_imm value!");
|
||||
// Break it up into two parts that make up a shifter immediate.
|
||||
V = ARM_AM::getSOImmVal(V);
|
||||
assert(V != -1 && "Not a valid so_imm value!");
|
||||
|
||||
unsigned Imm = ARM_AM::getSOImmValImm(V);
|
||||
unsigned Rot = ARM_AM::getSOImmValRot(V);
|
||||
|
||||
|
@ -402,7 +404,7 @@ void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
|
|||
assert(MO.isImm() && "Not a valid so_imm value!");
|
||||
unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
|
||||
unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
|
||||
printSOImm(O, ARM_AM::getSOImmVal(V1), VerboseAsm, TAI);
|
||||
printSOImm(O, V1, VerboseAsm, TAI);
|
||||
O << "\n\torr";
|
||||
printPredicateOperand(MI, 2);
|
||||
O << " ";
|
||||
|
@ -410,7 +412,7 @@ void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
|
|||
O << ", ";
|
||||
printOperand(MI, 0);
|
||||
O << ", ";
|
||||
printSOImm(O, ARM_AM::getSOImmVal(V2), VerboseAsm, TAI);
|
||||
printSOImm(O, V2, VerboseAsm, TAI);
|
||||
}
|
||||
|
||||
// so_reg is a 4-operand unit corresponding to register forms of the A5.1
|
||||
|
@ -687,20 +689,6 @@ void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
|
|||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// printT2SOImmOperand - T2SOImm is:
|
||||
/// 1. a 4-bit splat control value and 8 bit immediate value
|
||||
/// 2. a 5-bit rotate amount and a non-zero 8-bit immediate value
|
||||
/// represented by a normalizedin 7-bit value (msb is always 1)
|
||||
void ARMAsmPrinter::printT2SOImmOperand(const MachineInstr *MI, int OpNum) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
assert(MO.isImm() && "Not a valid so_imm value!");
|
||||
|
||||
unsigned Imm = ARM_AM::getT2SOImmValDecode(MO.getImm());
|
||||
// Always print the immediate directly, as the "rotate" form
|
||||
// is deprecated in some contexts.
|
||||
O << "#" << Imm;
|
||||
}
|
||||
|
||||
// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
|
||||
// register with shift forms.
|
||||
// REG 0 0 - e.g. R5
|
||||
|
|
Loading…
Reference in New Issue