mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-13 22:00:14 +00:00
Make two piece constant generation as a single instruction. It's re-materialized as a load from constantpool.
llvm-svn: 35207
This commit is contained in:
parent
39eb62ea3b
commit
9e7b838469
@ -82,6 +82,7 @@ namespace {
|
||||
void printOperand(const MachineInstr *MI, int opNum,
|
||||
const char *Modifier = 0);
|
||||
void printSOImmOperand(const MachineInstr *MI, int opNum);
|
||||
void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
|
||||
void printSORegOperand(const MachineInstr *MI, int opNum);
|
||||
void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
|
||||
void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
|
||||
@ -309,14 +310,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
||||
}
|
||||
}
|
||||
|
||||
/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
|
||||
/// immediate in bits 0-7.
|
||||
void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
assert(MO.isImmediate() && (MO.getImmedValue() < (1 << 12)) &&
|
||||
"Not a valid so_imm value!");
|
||||
unsigned Imm = ARM_AM::getSOImmValImm(MO.getImmedValue());
|
||||
unsigned Rot = ARM_AM::getSOImmValRot(MO.getImmedValue());
|
||||
static void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) {
|
||||
assert(V < (1 << 12) && "Not a valid so_imm value!");
|
||||
unsigned Imm = ARM_AM::getSOImmValImm(V);
|
||||
unsigned Rot = ARM_AM::getSOImmValRot(V);
|
||||
|
||||
// Print low-level immediate formation info, per
|
||||
// A5.1.3: "Data-processing operands - Immediate".
|
||||
@ -329,6 +326,30 @@ void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
|
||||
}
|
||||
}
|
||||
|
||||
/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
|
||||
/// immediate in bits 0-7.
|
||||
void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
assert(MO.isImmediate() && "Not a valid so_imm value!");
|
||||
printSOImm(O, MO.getImmedValue(), TAI);
|
||||
}
|
||||
|
||||
/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
|
||||
/// followed by a or to materialize.
|
||||
void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
assert(MO.isImmediate() && "Not a valid so_imm value!");
|
||||
unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue());
|
||||
unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue());
|
||||
printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
|
||||
O << "\n\torr ";
|
||||
printOperand(MI, 0);
|
||||
O << ", ";
|
||||
printOperand(MI, 0);
|
||||
O << ", ";
|
||||
printSOImm(O, ARM_AM::getSOImmVal(V2), TAI);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -147,24 +147,6 @@ def sext_16_node : PatLeaf<(i32 GPR:$a), [{
|
||||
}]>;
|
||||
|
||||
|
||||
// Break so_imm's up into two pieces. This handles immediates with up to 16
|
||||
// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
|
||||
// get the first/second pieces.
|
||||
def so_imm2part : PatLeaf<(imm), [{
|
||||
return ARM_AM::isSOImmTwoPartVal((unsigned)N->getValue());
|
||||
}]>;
|
||||
|
||||
def so_imm2part_1 : SDNodeXForm<imm, [{
|
||||
unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getValue());
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def so_imm2part_2 : SDNodeXForm<imm, [{
|
||||
unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getValue());
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
|
||||
}]>;
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Operand Definitions.
|
||||
@ -217,6 +199,25 @@ def so_imm : Operand<i32>,
|
||||
let PrintMethod = "printSOImmOperand";
|
||||
}
|
||||
|
||||
// Break so_imm's up into two pieces. This handles immediates with up to 16
|
||||
// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
|
||||
// get the first/second pieces.
|
||||
def so_imm2part : Operand<i32>,
|
||||
PatLeaf<(imm),
|
||||
[{ return ARM_AM::isSOImmTwoPartVal((unsigned)N->getValue()); }]> {
|
||||
let PrintMethod = "printSOImm2PartOperand";
|
||||
}
|
||||
|
||||
def so_imm2part_1 : SDNodeXForm<imm, [{
|
||||
unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getValue());
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def so_imm2part_2 : SDNodeXForm<imm, [{
|
||||
unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getValue());
|
||||
return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
|
||||
}]>;
|
||||
|
||||
|
||||
// Define ARM specific addressing modes.
|
||||
|
||||
@ -371,6 +372,8 @@ class AI4<dag ops, string asm, list<dag> pattern>
|
||||
: I<ops, AddrMode4, Size4Bytes, IndexModeNone, asm, "", pattern>;
|
||||
class AIx2<dag ops, string asm, list<dag> pattern>
|
||||
: I<ops, AddrModeNone, Size8Bytes, IndexModeNone, asm, "", pattern>;
|
||||
class AI1x2<dag ops, string asm, list<dag> pattern>
|
||||
: I<ops, AddrMode1, Size8Bytes, IndexModeNone, asm, "", pattern>;
|
||||
|
||||
// Pre-indexed ops
|
||||
class AI2pr<dag ops, string asm, string cstr, list<dag> pattern>
|
||||
@ -1064,14 +1067,15 @@ def LEApcrelJT : AI1<(ops GPR:$dst, i32imm:$label, i32imm:$id),
|
||||
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
|
||||
def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
|
||||
def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||
(LEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||
(LEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||
|
||||
// Large immediate handling.
|
||||
|
||||
// Two piece so_imms.
|
||||
def : ARMPat<(i32 so_imm2part:$src),
|
||||
(ORRri (MOVi (so_imm2part_1 imm:$src)),
|
||||
(so_imm2part_2 imm:$src))>;
|
||||
let isReMaterializable = 1 in
|
||||
def MOVi2pieces : AI1x2<(ops GPR:$dst, so_imm2part:$src),
|
||||
"mov $dst, $src",
|
||||
[(set GPR:$dst, so_imm2part:$src)]>;
|
||||
|
||||
def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
|
||||
(ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user