aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMCodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMCodeEmitter.cpp')
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp263
1 files changed, 59 insertions, 204 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 96eb764..7359a11 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -57,7 +57,7 @@ namespace {
bool IsPIC;
bool IsThumb;
- void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineModuleInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -76,9 +76,9 @@ namespace {
/// machine instructions.
uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
- bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &MF) override;
- virtual const char *getPassName() const {
+ const char *getPassName() const override {
return "ARM Machine Code Emitter";
}
@@ -88,11 +88,9 @@ namespace {
void emitWordLE(unsigned Binary);
void emitDWordLE(uint64_t Binary);
- void emitConstantToMemory(unsigned CPI, const Constant *CV);
void emitConstPoolInstruction(const MachineInstr &MI);
void emitMOVi32immInstruction(const MachineInstr &MI);
void emitMOVi2piecesInstruction(const MachineInstr &MI);
- void emitLEApcrelInstruction(const MachineInstr &MI);
void emitLEApcrelJTInstruction(const MachineInstr &MI);
void emitPseudoMoveInstruction(const MachineInstr &MI);
void addPCLabel(unsigned LabelID);
@@ -141,8 +139,6 @@ namespace {
void emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI);
- void emitMiscInstruction(const MachineInstr &MI);
-
void emitNEONLaneInstruction(const MachineInstr &MI);
void emitNEONDupInstruction(const MachineInstr &MI);
void emitNEON1RegModImmInstruction(const MachineInstr &MI);
@@ -174,13 +170,7 @@ namespace {
unsigned NEONThumb2V8PostEncoder(const MachineInstr &MI,unsigned Val)
const { return 0; }
unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
- const {
- if (IsThumb) {
- Val &= 0x0FFFFFFF;
- Val |= 0xE0000000;
- }
- return Val;
- }
+ const { return 0; }
unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getThumbAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
@@ -217,8 +207,6 @@ namespace {
const { return 0; }
unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
- unsigned getT2AddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
- const { return 0; }
unsigned getT2AddrModeImm8OpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getT2Imm8s4OpValue(const MachineInstr &MI, unsigned Op)
@@ -229,8 +217,6 @@ namespace {
const { return 0; }
unsigned getT2AddrModeImm8OffsetOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
- unsigned getT2AddrModeImm12OffsetOpValue(const MachineInstr &MI,unsigned Op)
- const { return 0; }
unsigned getT2AddrModeSORegOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
@@ -248,10 +234,6 @@ namespace {
const { return 0; }
unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
unsigned Op) const { return 0; }
- unsigned getSsatBitPosValue(const MachineInstr &MI,
- unsigned Op) const { return 0; }
- uint32_t getLdStmModeOpValue(const MachineInstr &MI, unsigned OpIdx)
- const {return 0; }
uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx)
const { return 0; }
@@ -276,24 +258,10 @@ namespace {
return Binary;
}
- unsigned getHiLo16ImmOpValue(const MachineInstr &MI, unsigned Op)
- const {
- const MCInstrDesc &MCID = MI.getDesc();
- const MachineOperand &MO = MI.getOperand(Op);
-
- unsigned Reloc = (MCID.Opcode == ARM::MOVi16 ?
- ARM::reloc_arm_movw : ARM::reloc_arm_movt);
-
- if (!MO.isImm()) {
- emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
- return 0;
- }
- unsigned Imm16 = static_cast<unsigned>(MO.getImm());
- return Imm16;
+ unsigned getHiLo16ImmOpValue(const MachineInstr &MI, unsigned Op) const {
+ return 0;
}
- uint32_t getAddrMode2OpValue(const MachineInstr &MI, unsigned OpIdx)
- const { return 0;}
uint32_t getAddrMode2OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
const { return 0;}
uint32_t getPostIdxRegOpValue(const MachineInstr &MI, unsigned OpIdx)
@@ -304,17 +272,14 @@ namespace {
const { return 0; }
uint32_t getAddrModeThumbSPOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
- uint32_t getAddrModeSOpValue(const MachineInstr &MI, unsigned Op)
- const { return 0; }
uint32_t getAddrModeISOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
uint32_t getAddrModePCOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const {
- // {12-9} = reg
- // {8} = (U)nsigned (add == '1', sub == '0')
- // {7-0} = imm8
- uint32_t Binary = 0;
+ // {17-13} = reg
+ // {12} = (U)nsigned (add == '1', sub == '0')
+ // {11-0} = imm12
const MachineOperand &MO = MI.getOperand(Op);
const MachineOperand &MO1 = MI.getOperand(Op + 1);
if (!MO.isReg()) {
@@ -336,8 +301,10 @@ namespace {
isAdd = false;
}
- // If immediate offset is omitted, default to +0.
- Binary |= 1 << 8;
+ uint32_t Binary = Imm12 & 0xfff;
+ if (isAdd)
+ Binary |= (1 << 12);
+ Binary |= (Reg << 13);
return Binary;
}
unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op)
@@ -476,9 +443,6 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
return II->getRegisterInfo().getEncodingValue(MO.getReg());
else if (MO.isImm())
return static_cast<unsigned>(MO.getImm());
- else if (MO.isFPImm())
- return static_cast<unsigned>(MO.getFPImm()->getValueAPF()
- .bitcastToAPInt().getHiBits(32).getLimitedValue());
else if (MO.isGlobal())
emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false);
else if (MO.isSymbol())
@@ -631,9 +595,7 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
case ARMII::VFPLdStMulFrm:
emitVFPLoadStoreMultipleInstruction(MI);
break;
- case ARMII::VFPMiscFrm:
- emitMiscInstruction(MI);
- break;
+
// NEON instructions.
case ARMII::NGetLnFrm:
case ARMII::NSetLnFrm:
@@ -655,56 +617,6 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
-void ARMCodeEmitter::emitConstantToMemory(unsigned CPI, const Constant *C) {
- DEBUG({
- errs() << " ** Constant pool #" << CPI << " @ "
- << (void*)MCE.getCurrentPCValue() << " ";
- if (const Function *F = dyn_cast<Function>(C))
- errs() << F->getName();
- else
- errs() << *C;
- errs() << '\n';
- });
-
- switch (C->getValueID()) {
- default: {
- llvm_unreachable("Unable to handle this constantpool entry!");
- break;
- }
- case Value::GlobalVariableVal: {
- emitGlobalAddress(static_cast<const GlobalValue*>(C),
- ARM::reloc_arm_absolute, isa<Function>(C), false);
- emitWordLE(0);
- break;
- }
- case Value::ConstantIntVal: {
- const ConstantInt *CI = static_cast<const ConstantInt*>(C);
- uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
- emitWordLE(Val);
- break;
- }
- case Value::ConstantFPVal: {
- const ConstantFP *CFP = static_cast<const ConstantFP*>(C);
- if (CFP->getType()->isFloatTy())
- emitWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
- else if (CFP->getType()->isDoubleTy())
- emitDWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
- else {
- llvm_unreachable("Unable to handle this constantpool entry!");
- }
- break;
- }
- case Value::ConstantArrayVal: {
- const ConstantArray *CA = static_cast<const ConstantArray*>(C);
- for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
- emitConstantToMemory(CPI, CA->getOperand(i));
- break;
- }
- }
-
- return;
-}
-
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
unsigned CPI = MI.getOperand(0).getImm(); // CP instruction index.
unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index.
@@ -736,7 +648,35 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
}
emitWordLE(0);
} else {
- emitConstantToMemory(CPI, MCPE.Val.ConstVal);
+ const Constant *CV = MCPE.Val.ConstVal;
+
+ DEBUG({
+ errs() << " ** Constant pool #" << CPI << " @ "
+ << (void*)MCE.getCurrentPCValue() << " ";
+ if (const Function *F = dyn_cast<Function>(CV))
+ errs() << F->getName();
+ else
+ errs() << *CV;
+ errs() << '\n';
+ });
+
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
+ emitGlobalAddress(GV, ARM::reloc_arm_absolute, isa<Function>(GV), false);
+ emitWordLE(0);
+ } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ uint32_t Val = uint32_t(*CI->getValue().getRawData());
+ emitWordLE(Val);
+ } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+ if (CFP->getType()->isFloatTy())
+ emitWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
+ else if (CFP->getType()->isDoubleTy())
+ emitDWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
+ else {
+ llvm_unreachable("Unable to handle this constantpool entry!");
+ }
+ } else {
+ llvm_unreachable("Unable to handle this constantpool entry!");
+ }
}
}
@@ -818,32 +758,6 @@ void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-void ARMCodeEmitter::emitLEApcrelInstruction(const MachineInstr &MI) {
- // It's basically add r, pc, (LCPI - $+8)
- const MCInstrDesc &MCID = MI.getDesc();
-
- unsigned Binary = 0;
-
- // Set the conditional execution predicate
- Binary |= II->getPredicate(&MI) << ARMII::CondShift;
-
- // Encode S bit if MI modifies CPSR.
- Binary |= getAddrModeSBit(MI, MCID);
-
- // Encode Rd.
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
-
- // Encode Rn which is PC.
- Binary |= II->getRegisterInfo().getEncodingValue(ARM::PC) << ARMII::RegRnShift;
-
- // Encode the displacement which is a so_imm.
- // Set bit I(25) to identify this is the immediate form of <shifter_op>
- Binary |= 1 << ARMII::I_BitShift;
- emitConstPoolAddress(MI.getOperand(1).getIndex(), ARM::reloc_arm_so_imm_cp_entry);
-
- emitWordLE(Binary);
-}
-
void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
// It's basically add r, pc, (LJTI - $+8)
@@ -921,14 +835,6 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
switch (Opcode) {
default:
llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
- case ARM::B:
- emitBranchInstruction(MI);
- break;
- case ARM::BR_JTr:
- case ARM::BR_JTm:
- case ARM::BR_JTadd:
- emitMiscBranchInstruction(MI);
- break;
case ARM::BX_CALL:
case ARM::BMOVPCRX_CALL: {
// First emit mov lr, pc
@@ -948,7 +854,8 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
}
break;
}
- case TargetOpcode::PROLOG_LABEL:
+ case TargetOpcode::CFI_INSTRUCTION:
+ break;
case TargetOpcode::EH_LABEL:
MCE.emitLabel(MI.getOperand(0).getMCSymbol());
break;
@@ -959,9 +866,6 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
case ARM::CONSTPOOL_ENTRY:
emitConstPoolInstruction(MI);
break;
- case ARM::LDMIA_RET:
- emitLoadStoreMultipleInstruction(MI);
- break;
case ARM::PICADD: {
// Remember of the address of the PC label for relocation later.
addPCLabel(MI.getOperand(2).getImm());
@@ -997,10 +901,7 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
else
emitMOVi2piecesInstruction(MI);
break;
- case ARM::LEApcrel:
- // Materialize constantpool index address.
- emitLEApcrelInstruction(MI);
- break;
+
case ARM::LEApcrelJT:
// Materialize jumptable address.
emitLEApcrelJTInstruction(MI);
@@ -1101,11 +1002,6 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
- if (MCID.Opcode == ARM::MOVi16 || MCID.Opcode == ARM::MOVTi16) {
- emitWordLE(Binary);
- return;
- }
-
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
@@ -1208,17 +1104,11 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
// If this is an LDRi12, STRi12 or LDRcp, nothing more needs be done.
if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp ||
- MI.getOpcode() == ARM::STRi12 || MI.getOpcode() == ARM::LDRBi12 ||
- MI.getOpcode() == ARM::STRBi12) {
+ MI.getOpcode() == ARM::STRi12) {
emitWordLE(Binary);
return;
}
- if (MI.getOpcode() == ARM::BR_JTm)
- Binary = 0x710F000;
- else if (MI.getOpcode() == ARM::BR_JTr)
- Binary = 0x1A0F000;
-
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
@@ -1374,11 +1264,6 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
- if (MCID.getOpcode() == ARM::LDMIA_RET) {
- IsUpdating = true;
- Binary |= 0x8B00000;
- }
-
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
@@ -1586,10 +1471,6 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
- if (MCID.Opcode == ARM::B) {
- Binary = 0xEA000000;
- }
-
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
@@ -1664,10 +1545,9 @@ unsigned ARMCodeEmitter::encodeVFPRd(const MachineInstr &MI,
unsigned Binary = 0;
bool isSPVFP = ARM::SPRRegClass.contains(RegD);
RegD = II->getRegisterInfo().getEncodingValue(RegD);
- if (!isSPVFP) {
- Binary |= (RegD & 0x0F) << ARMII::RegRdShift;
- Binary |= ((RegD & 0x10) >> 4) << ARMII::D_BitShift;
- } else {
+ if (!isSPVFP)
+ Binary |= RegD << ARMII::RegRdShift;
+ else {
Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
Binary |= (RegD & 0x01) << ARMII::D_BitShift;
}
@@ -1680,10 +1560,9 @@ unsigned ARMCodeEmitter::encodeVFPRn(const MachineInstr &MI,
unsigned Binary = 0;
bool isSPVFP = ARM::SPRRegClass.contains(RegN);
RegN = II->getRegisterInfo().getEncodingValue(RegN);
- if (!isSPVFP) {
- Binary |= (RegN & 0x0F) << ARMII::RegRnShift;
- Binary |= ((RegN & 0x10) >> 4) << ARMII::N_BitShift;
- } else {
+ if (!isSPVFP)
+ Binary |= RegN << ARMII::RegRnShift;
+ else {
Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
Binary |= (RegN & 0x01) << ARMII::N_BitShift;
}
@@ -1696,10 +1575,9 @@ unsigned ARMCodeEmitter::encodeVFPRm(const MachineInstr &MI,
unsigned Binary = 0;
bool isSPVFP = ARM::SPRRegClass.contains(RegM);
RegM = II->getRegisterInfo().getEncodingValue(RegM);
- if (!isSPVFP) {
- Binary |= (RegM & 0x0F);
- Binary |= ((RegM & 0x10) >> 4) << ARMII::M_BitShift;
- } else {
+ if (!isSPVFP)
+ Binary |= RegM;
+ else {
Binary |= ((RegM & 0x1E) >> 1);
Binary |= (RegM & 0x01) << ARMII::M_BitShift;
}
@@ -1716,6 +1594,9 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
unsigned OpIdx = 0;
+ assert((Binary & ARMII::D_BitShift) == 0 &&
+ (Binary & ARMII::N_BitShift) == 0 &&
+ (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!");
// Encode Dd / Sd.
Binary |= encodeVFPRd(MI, OpIdx++);
@@ -1805,12 +1686,6 @@ void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
- if (MI.getOpcode() == ARM::VLDRS || MI.getOpcode() == ARM::VLDRD ||
- MI.getOpcode() == ARM::VSTRS || MI.getOpcode() == ARM::VSTRD){
- emitWordLE(Binary);
- return;
- }
-
unsigned OpIdx = 0;
// Encode Dd / Sd.
@@ -1886,26 +1761,6 @@ ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
- unsigned Opcode = MI.getDesc().Opcode;
- // Part of binary is determined by TableGn.
- unsigned Binary = getBinaryCodeForInstr(MI);
-
- if (Opcode == ARM::FCONSTS) {
- unsigned Imm = getMachineOpValue(MI, 1);
- Binary &= ~(0x780000 >> 19);
- Binary |= (Imm & 0x780000) >> 19;
- Binary &= ~(0x3800000 >> 7);
- Binary |= (Imm & 0x3800000) >> 7;
- Binary = VFPThumb2PostEncoder(MI, Binary);
- }
-
- // Set the conditional execution predicate
- Binary |= II->getPredicate(&MI) << ARMII::CondShift;
-
- emitWordLE(Binary);
-}
-
unsigned ARMCodeEmitter::encodeNEONRd(const MachineInstr &MI,
unsigned OpIdx) const {
unsigned RegD = MI.getOperand(OpIdx).getReg();