aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-12-14 00:36:49 +0000
committerOwen Anderson <resistor@mac.com>2010-12-14 00:36:49 +0000
commita838a25d59838adfa91463f6a918ae3adeb352c1 (patch)
tree2993f422e346bd2efa6a917c95c6a2b55bfcaccf
parent2d9220e8f5b45390d64e943fa4eef1562b87f04b (diff)
downloadexternal_llvm-a838a25d59838adfa91463f6a918ae3adeb352c1.zip
external_llvm-a838a25d59838adfa91463f6a918ae3adeb352c1.tar.gz
external_llvm-a838a25d59838adfa91463f6a918ae3adeb352c1.tar.bz2
Second attempt at make Thumb2 LEAs pseudos. This time, perform the lowering much later, which makes the entire
process cleaner. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121735 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMAsmBackend.cpp20
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp12
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp2
-rw-r--r--lib/Target/ARM/ARMFixupKinds.h3
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td41
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp15
-rw-r--r--utils/TableGen/EDEmitter.cpp1
7 files changed, 75 insertions, 19 deletions
diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp
index cb0c543..789bae0 100644
--- a/lib/Target/ARM/ARMAsmBackend.cpp
+++ b/lib/Target/ARM/ARMAsmBackend.cpp
@@ -136,6 +136,25 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
// Encode the immediate and shift the opcode into place.
return ARM_AM::getSOImmVal(Value) | (opc << 21);
}
+
+ case ARM::fixup_t2_adr_pcrel_12: {
+ Value -= 4;
+ unsigned opc = 0;
+ if ((int64_t)Value < 0) {
+ Value = -Value;
+ opc = 5;
+ }
+
+ uint32_t out = (opc << 21);
+ out |= (Value & 0x800) << 14;
+ out |= (Value & 0x700) << 4;
+ out |= (Value & 0x0FF);
+
+ uint64_t swapped = (out & 0xFFFF0000) >> 16;
+ swapped |= (out & 0x0000FFFF) << 16;
+ return swapped;
+ }
+
case ARM::fixup_arm_branch:
// These values don't encode the low two bits since they're always zero.
// Offset by 8 just as above.
@@ -356,6 +375,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
case ARM::fixup_t2_condbranch:
case ARM::fixup_t2_uncondbranch:
case ARM::fixup_t2_pcrel_10:
+ case ARM::fixup_t2_adr_pcrel_12:
case ARM::fixup_arm_thumb_bl:
case ARM::fixup_arm_thumb_blx:
return 4;
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index 09124e4..b211167 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -734,6 +734,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
return;
}
+ case ARM::t2LEApcrel:
case ARM::LEApcrel: {
// FIXME: Need to also handle globals and externals
assert (MI->getOperand(1).isCPI());
@@ -741,7 +742,10 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCSymbol *Sym = GetCPISymbol(LabelId);
const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Sym, OutContext);
MCInst TmpInst;
- TmpInst.setOpcode(ARM::ADR);
+ if (MI->getOpcode() == ARM::LEApcrel)
+ TmpInst.setOpcode(ARM::ADR);
+ else
+ TmpInst.setOpcode(ARM::t2ADR);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
// Add predicate operands.
@@ -750,13 +754,17 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitInstruction(TmpInst);
return;
}
+ case ARM::t2LEApcrelJT:
case ARM::LEApcrelJT: {
unsigned JTI = MI->getOperand(1).getIndex();
unsigned Id = MI->getOperand(2).getImm();
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, Id);
const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(JTISymbol, OutContext);
MCInst TmpInst;
- TmpInst.setOpcode(ARM::ADR);
+ if (MI->getOpcode() == ARM::LEApcrelJT)
+ TmpInst.setOpcode(ARM::ADR);
+ else
+ TmpInst.setOpcode(ARM::t2ADR);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
// Add predicate operands.
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 101c07b..5e302ae 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -213,6 +213,8 @@ namespace {
const { return 0; }
unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
+ unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
+ const { return 0; }
unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op)
diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h
index 48d4953..f535608 100644
--- a/lib/Target/ARM/ARMFixupKinds.h
+++ b/lib/Target/ARM/ARMFixupKinds.h
@@ -33,6 +33,9 @@ enum Fixups {
// fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
// instruction.
fixup_arm_adr_pcrel_12,
+ // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
+ // instruction.
+ fixup_t2_adr_pcrel_12,
// fixup_arm_branch - 24-bit PC relative relocation for direct branch
// instructions.
fixup_arm_branch,
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 2fedb53..faa143d 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -131,6 +131,12 @@ def t2addrmode_imm12 : Operand<i32>,
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
+// ADR instruction labels.
+def t2adrlabel : Operand<i32> {
+ let EncoderMethod = "getT2AdrLabelOpValue";
+}
+
+
// t2addrmode_imm8 := reg +/- imm8
def t2addrmode_imm8 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
@@ -1128,10 +1134,9 @@ class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin,
// LEApcrel - Load a pc-relative address into a register without offending the
// assembler.
-let neverHasSideEffects = 1 in {
-let isReMaterializable = 1 in
-def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi,
- "adr${p}.w\t$Rd, #$label", []> {
+def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
+ (ins t2adrlabel:$addr, pred:$p),
+ IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> {
let Inst{31-27} = 0b11110;
let Inst{25-24} = 0b10;
// Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
@@ -1139,21 +1144,23 @@ def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), II
let Inst{20} = 0;
let Inst{19-16} = 0b1111; // Rn
let Inst{15} = 0;
-
-
+
+ bits<4> Rd;
+ bits<13> addr;
+ let Inst{11-8} = Rd;
+ let Inst{23} = addr{12};
+ let Inst{21} = addr{12};
+ let Inst{26} = addr{11};
+ let Inst{14-12} = addr{10-8};
+ let Inst{7-0} = addr{7-0};
}
-} // neverHasSideEffects
-def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd),
+
+let neverHasSideEffects = 1, isReMaterializable = 1 in
+def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
+ IIC_iALUi, []>;
+def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd),
(ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
- "adr${p}.w\t$Rd, #${label}_${id}", []> {
- let Inst{31-27} = 0b11110;
- let Inst{25-24} = 0b10;
- // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
- let Inst{22} = 0;
- let Inst{20} = 0;
- let Inst{19-16} = 0b1111; // Rn
- let Inst{15} = 0;
-}
+ []>;
// FIXME: None of these add/sub SP special instructions should be necessary
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 7f34ee9..8dca2c3 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -56,6 +56,8 @@ public:
{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAligned},
{ "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAligned},
{ "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
@@ -133,6 +135,9 @@ public:
/// ADR label target.
uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
+ uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
/// operand.
@@ -544,6 +549,16 @@ getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
Fixups);
}
+/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
+/// target.
+uint32_t ARMMCCodeEmitter::
+getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
+ return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
+ Fixups);
+}
+
/// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand.
uint32_t ARMMCCodeEmitter::
getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index dede4b0..9c27515 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -584,6 +584,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("t_imm_s4");
IMM("pclabel");
IMM("adrlabel");
+ IMM("t2adrlabel");
IMM("shift_imm");
IMM("neon_vcvt_imm32");