forked from OSchip/llvm-project
parent
de36afc1fe
commit
eab9ca7ea6
|
@ -92,11 +92,10 @@ public:
|
|||
bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base,
|
||||
SDValue &OffImm);
|
||||
|
||||
bool SelectThumb2ShifterOperandReg(SDValue Op, SDValue N,
|
||||
SDValue &BaseReg, SDValue &Opc);
|
||||
|
||||
bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A,
|
||||
SDValue &B, SDValue &C);
|
||||
bool SelectT2ShifterOperandReg(SDValue Op, SDValue N,
|
||||
SDValue &BaseReg, SDValue &Opc);
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "ARMGenDAGISel.inc"
|
||||
|
@ -520,27 +519,6 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectThumb2ShifterOperandReg(SDValue Op,
|
||||
SDValue N,
|
||||
SDValue &BaseReg,
|
||||
SDValue &Opc) {
|
||||
ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
|
||||
|
||||
// Don't match base register only case. That is matched to a separate
|
||||
// lower complexity pattern with explicit register operand.
|
||||
if (ShOpcVal == ARM_AM::no_shift) return false;
|
||||
|
||||
BaseReg = N.getOperand(0);
|
||||
unsigned ShImmVal = 0;
|
||||
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
|
||||
ShImmVal = RHS->getZExtValue() & 31;
|
||||
Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
|
||||
SDValue N,
|
||||
SDValue &BaseReg,
|
||||
|
@ -565,6 +543,26 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N,
|
||||
SDValue &BaseReg,
|
||||
SDValue &Opc) {
|
||||
ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
|
||||
|
||||
// Don't match base register only case. That is matched to a separate
|
||||
// lower complexity pattern with explicit register operand.
|
||||
if (ShOpcVal == ARM_AM::no_shift) return false;
|
||||
|
||||
BaseReg = N.getOperand(0);
|
||||
unsigned ShImmVal = 0;
|
||||
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
|
||||
ShImmVal = RHS->getZExtValue() & 31;
|
||||
Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getAL - Returns a ARMCC::AL immediate node.
|
||||
static inline SDValue getAL(SelectionDAG *CurDAG) {
|
||||
return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32);
|
||||
|
|
|
@ -742,12 +742,12 @@ class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
|
|||
class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
|
||||
: ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
|
||||
|
||||
// ThumbPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
|
||||
class ThumbPat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
// TPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
|
||||
class TPat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
list<Predicate> Predicates = [IsThumb];
|
||||
}
|
||||
|
||||
class ThumbV5Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
list<Predicate> Predicates = [IsThumb, HasV5T];
|
||||
}
|
||||
|
||||
|
@ -769,7 +769,7 @@ class T1I<dag outs, dag ins, string asm, list<dag> pattern>
|
|||
class T1It<dag outs, dag ins, string asm, list<dag> pattern>
|
||||
: Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
|
||||
|
||||
class Thumb1Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
list<Predicate> Predicates = [IsThumb1Only];
|
||||
}
|
||||
|
||||
|
@ -819,8 +819,8 @@ class T2sI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
|
|||
class T2XI<dag oops, dag iops, string asm, list<dag> pattern>
|
||||
: Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, asm, "", pattern>;
|
||||
|
||||
// Thumb2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
|
||||
class Thumb2Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
|
||||
class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
list<Predicate> Predicates = [IsThumb, HasThumb2];
|
||||
}
|
||||
|
||||
|
|
|
@ -607,35 +607,35 @@ let isCall = 1,
|
|||
//
|
||||
|
||||
// ConstantPool, GlobalAddress
|
||||
def : ThumbPat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
|
||||
def : ThumbPat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>;
|
||||
def : TPat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
|
||||
def : TPat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>;
|
||||
|
||||
// JumpTable
|
||||
def : ThumbPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||
(tLEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||
def : TPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||
(tLEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||
|
||||
// Direct calls
|
||||
def : ThumbPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
|
||||
def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
|
||||
def : TPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
|
||||
def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
|
||||
|
||||
// Indirect calls to ARM routines
|
||||
def : ThumbV5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>;
|
||||
def : Tv5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>;
|
||||
|
||||
// zextload i1 -> zextload i8
|
||||
def : ThumbPat<(zextloadi1 t_addrmode_s1:$addr),
|
||||
(tLDRB t_addrmode_s1:$addr)>;
|
||||
def : TPat<(zextloadi1 t_addrmode_s1:$addr),
|
||||
(tLDRB t_addrmode_s1:$addr)>;
|
||||
|
||||
// extload -> zextload
|
||||
def : ThumbPat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>;
|
||||
def : ThumbPat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>;
|
||||
def : ThumbPat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>;
|
||||
def : TPat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>;
|
||||
def : TPat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>;
|
||||
def : TPat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>;
|
||||
|
||||
// Large immediate handling.
|
||||
|
||||
// Two piece imms.
|
||||
def : Thumb1Pat<(i32 thumb_immshifted:$src),
|
||||
(tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
|
||||
(thumb_immshifted_shamt imm:$src))>;
|
||||
def : T1Pat<(i32 thumb_immshifted:$src),
|
||||
(tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
|
||||
(thumb_immshifted_shamt imm:$src))>;
|
||||
|
||||
def : Thumb1Pat<(i32 imm0_255_comp:$src),
|
||||
(tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>;
|
||||
def : T1Pat<(i32 imm0_255_comp:$src),
|
||||
(tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>;
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
// Shifted operands. No register controlled shifts for Thumb2.
|
||||
// Note: We do not support rrx shifted operands yet.
|
||||
def t2_so_reg : Operand<i32>, // reg imm
|
||||
ComplexPattern<i32, 2, "SelectThumb2ShifterOperandReg",
|
||||
ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
|
||||
[shl,srl,sra,rotr]> {
|
||||
let PrintMethod = "printSOOperand";
|
||||
let PrintMethod = "printT2SOOperand";
|
||||
let MIOperandInfo = (ops GPR, i32imm);
|
||||
}
|
||||
|
||||
|
@ -126,8 +126,9 @@ def t2_lo16AllZero : PatLeaf<(i32 imm), [{
|
|||
return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
|
||||
}], t2_hi16>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Thumb2 to cover the functionality of the ARM instruction set.
|
||||
// Multiclass helpers...
|
||||
//
|
||||
|
||||
/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
|
||||
|
@ -358,6 +359,10 @@ multiclass T2I_cmp_is<string opc, PatFrag opnode> {
|
|||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Miscellaneous Instructions.
|
||||
//
|
||||
|
@ -400,6 +405,10 @@ def t2ADDrSPs : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
|
|||
[]>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Load / store Instructions.
|
||||
//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Move Instructions.
|
||||
//
|
||||
|
@ -445,10 +454,10 @@ defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
|
|||
defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
|
||||
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
|
||||
def : Thumb2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
def : Thumb2Pat<(add GPR:$src, imm0_4095_neg:$imm),
|
||||
(t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
|
||||
def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
|
||||
(t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -474,20 +483,20 @@ defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
|
|||
|
||||
defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
|
||||
|
||||
def : Thumb2Pat<(and GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2BICri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2BICri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
||||
|
||||
def : Thumb2Pat<(or GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
|
||||
let AddedComplexity = 1 in
|
||||
defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
|
||||
|
||||
def : Thumb2Pat<(t2_so_imm_not:$src),
|
||||
(t2MVNi t2_so_imm_not:$src)>;
|
||||
def : T2Pat<(t2_so_imm_not:$src),
|
||||
(t2MVNi t2_so_imm_not:$src)>;
|
||||
|
||||
// A8.6.17 BFC - Bitfield clear
|
||||
// FIXME: Also available in ARM mode.
|
||||
|
@ -562,11 +571,11 @@ defm t2CMN : T2I_cmp_is<"cmn",
|
|||
defm t2CMNnz : T2I_cmp_is<"cmn",
|
||||
BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
|
||||
|
||||
def : Thumb2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
|
||||
def : Thumb2Pat<(ARMcmpNZ GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
def : T2Pat<(ARMcmpNZ GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
|
||||
// FIXME: TST, TEQ, etc.
|
||||
|
||||
|
@ -582,13 +591,12 @@ def : Thumb2Pat<(ARMcmpNZ GPR:$src, t2_so_imm_neg:$imm),
|
|||
//
|
||||
|
||||
// ConstantPool, GlobalAddress, and JumpTable
|
||||
def : Thumb2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
|
||||
def : Thumb2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
|
||||
def : Thumb2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||
(t2LEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
|
||||
def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
|
||||
def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||
(t2LEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||
|
||||
// Large immediate handling.
|
||||
|
||||
def : Thumb2Pat<(i32 imm:$src),
|
||||
(t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)),
|
||||
(t2_hi16 imm:$src))>;
|
||||
def : T2Pat<(i32 imm:$src),
|
||||
(t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;
|
||||
|
|
|
@ -97,9 +97,7 @@ namespace {
|
|||
const char *Modifier = 0);
|
||||
void printSOImmOperand(const MachineInstr *MI, int opNum);
|
||||
void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
|
||||
void printSOOperand(const MachineInstr *MI, int OpNum);
|
||||
void printSORegOperand(const MachineInstr *MI, int opNum);
|
||||
void printT2SOImmOperand(const MachineInstr *MI, int opNum);
|
||||
void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
|
||||
void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
|
||||
void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
|
||||
|
@ -111,6 +109,7 @@ namespace {
|
|||
void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
|
||||
const char *Modifier = 0);
|
||||
void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNo);
|
||||
|
||||
void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
|
||||
void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
|
||||
unsigned Scale);
|
||||
|
@ -118,6 +117,10 @@ namespace {
|
|||
void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
|
||||
void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
|
||||
void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
|
||||
|
||||
void printT2SOImmOperand(const MachineInstr *MI, int opNum);
|
||||
void printT2SOOperand(const MachineInstr *MI, int OpNum);
|
||||
|
||||
void printPredicateOperand(const MachineInstr *MI, int opNum);
|
||||
void printSBitModifierOperand(const MachineInstr *MI, int opNum);
|
||||
void printPCLabel(const MachineInstr *MI, int opNum);
|
||||
|
@ -402,32 +405,10 @@ void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
|
|||
printSOImm(O, ARM_AM::getSOImmVal(V2), VerboseAsm, TAI);
|
||||
}
|
||||
|
||||
// Constant shifts so_reg is a 3-operand unit corresponding to register forms of
|
||||
// the A5.1 "Addressing Mode 1 - Data-processing operands" forms. This
|
||||
// includes:
|
||||
// REG 0 - e.g. R5
|
||||
// REG IMM, SH_OPC - e.g. R5, LSL #3
|
||||
void ARMAsmPrinter::printSOOperand(const MachineInstr *MI, int OpNum) {
|
||||
const MachineOperand &MO1 = MI->getOperand(OpNum);
|
||||
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
|
||||
|
||||
unsigned Reg = MO1.getReg();
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(Reg));
|
||||
O << TM.getRegisterInfo()->getAsmName(Reg);
|
||||
|
||||
// Print the shift opc.
|
||||
O << ", "
|
||||
<< ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
|
||||
<< " ";
|
||||
|
||||
assert(MO2.isImm() && "Not a valid t2_so_reg value!");
|
||||
O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
|
||||
}
|
||||
|
||||
// so_reg is a 4-operand unit corresponding to register forms of the A5.1
|
||||
// "Addressing Mode 1 - Data-processing operands" forms. This includes:
|
||||
// REG 0 0 - e.g. R5
|
||||
// REG REG 0,SH_OPC - e.g. R5, ROR R3
|
||||
// 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 ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
|
||||
const MachineOperand &MO1 = MI->getOperand(Op);
|
||||
|
@ -451,24 +432,6 @@ void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
|
|||
}
|
||||
}
|
||||
|
||||
static void printT2SOImm(raw_ostream &O, int64_t V) {
|
||||
unsigned Imm = ARM_AM::getT2SOImmValDecode(V);
|
||||
|
||||
// Always print the immediate directly, as the "rotate" form
|
||||
// is deprecated in some contexts.
|
||||
O << "#" << Imm;
|
||||
}
|
||||
|
||||
/// 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!");
|
||||
printT2SOImm(O, MO.getImm());
|
||||
}
|
||||
|
||||
void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
|
||||
const MachineOperand &MO1 = MI->getOperand(Op);
|
||||
const MachineOperand &MO2 = MI->getOperand(Op+1);
|
||||
|
@ -696,6 +659,42 @@ void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
|
|||
O << "]";
|
||||
}
|
||||
|
||||
/// 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
|
||||
// REG IMM, SH_OPC - e.g. R5, LSL #3
|
||||
void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum) {
|
||||
const MachineOperand &MO1 = MI->getOperand(OpNum);
|
||||
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
|
||||
|
||||
unsigned Reg = MO1.getReg();
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(Reg));
|
||||
O << TM.getRegisterInfo()->getAsmName(Reg);
|
||||
|
||||
// Print the shift opc.
|
||||
O << ", "
|
||||
<< ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
|
||||
<< " ";
|
||||
|
||||
assert(MO2.isImm() && "Not a valid t2_so_reg value!");
|
||||
O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
|
||||
}
|
||||
|
||||
|
||||
void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
|
||||
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
|
||||
if (CC != ARMCC::AL)
|
||||
|
|
Loading…
Reference in New Issue