diff options
Diffstat (limited to 'lib/Target/ARM/ARMCodeEmitter.cpp')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 263 |
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(); |