mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Get PIC jump table working.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58869 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -96,6 +96,7 @@ namespace { | |||||||
|                              const TargetInstrDesc &TID) const; |                              const TargetInstrDesc &TID) const; | ||||||
|  |  | ||||||
|     void emitDataProcessingInstruction(const MachineInstr &MI, |     void emitDataProcessingInstruction(const MachineInstr &MI, | ||||||
|  |                                        unsigned ImplicitRd = 0, | ||||||
|                                        unsigned ImplicitRn = 0); |                                        unsigned ImplicitRn = 0); | ||||||
|  |  | ||||||
|     void emitLoadStoreInstruction(const MachineInstr &MI, |     void emitLoadStoreInstruction(const MachineInstr &MI, | ||||||
| @@ -115,7 +116,7 @@ namespace { | |||||||
|  |  | ||||||
|     void emitBranchInstruction(const MachineInstr &MI); |     void emitBranchInstruction(const MachineInstr &MI); | ||||||
|  |  | ||||||
|     void emitInlineJumpTable(unsigned JTIndex, intptr_t JTBase); |     void emitInlineJumpTable(unsigned JTIndex); | ||||||
|  |  | ||||||
|     void emitMiscBranchInstruction(const MachineInstr &MI); |     void emitMiscBranchInstruction(const MachineInstr &MI); | ||||||
|  |  | ||||||
| @@ -137,16 +138,14 @@ namespace { | |||||||
|     unsigned getShiftOp(unsigned Imm) const ; |     unsigned getShiftOp(unsigned Imm) const ; | ||||||
|  |  | ||||||
|     /// Routines that handle operands which add machine relocations which are |     /// Routines that handle operands which add machine relocations which are | ||||||
|     /// fixed up by the JIT fixup stage. |     /// fixed up by the relocation stage. | ||||||
|     void emitGlobalAddress(GlobalValue *GV, unsigned Reloc, |     void emitGlobalAddress(GlobalValue *GV, unsigned Reloc, | ||||||
|                            bool NeedStub); |                            bool NeedStub, unsigned CPIdx = 0); | ||||||
|     void emitExternalSymbolAddress(const char *ES, unsigned Reloc); |     void emitExternalSymbolAddress(const char *ES, unsigned Reloc); | ||||||
|     void emitConstPoolAddress(unsigned CPI, unsigned Reloc, |     void emitConstPoolAddress(unsigned CPI, unsigned Reloc); | ||||||
|                               int Disp = 0, unsigned PCAdj = 0 ); |     void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc); | ||||||
|     void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc, |     void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc, | ||||||
|                               unsigned PCAdj = 0); |                                intptr_t JTBase = 0); | ||||||
|     void emitGlobalConstant(const Constant *CV); |  | ||||||
|     void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc); |  | ||||||
|   }; |   }; | ||||||
|   char ARMCodeEmitter::ID = 0; |   char ARMCodeEmitter::ID = 0; | ||||||
| } | } | ||||||
| @@ -227,9 +226,10 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI, | |||||||
| /// emitGlobalAddress - Emit the specified address to the code stream. | /// emitGlobalAddress - Emit the specified address to the code stream. | ||||||
| /// | /// | ||||||
| void ARMCodeEmitter::emitGlobalAddress(GlobalValue *GV, | void ARMCodeEmitter::emitGlobalAddress(GlobalValue *GV, | ||||||
|                                        unsigned Reloc, bool NeedStub) { |                                        unsigned Reloc, bool NeedStub, | ||||||
|  |                                        unsigned CPIdx) { | ||||||
|   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), |   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), | ||||||
|                                              Reloc, GV, 0, NeedStub)); |                                              Reloc, GV, CPIdx, NeedStub)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// emitExternalSymbolAddress - Arrange for the address of an external symbol to | /// emitExternalSymbolAddress - Arrange for the address of an external symbol to | ||||||
| @@ -243,28 +243,25 @@ void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) { | |||||||
| /// emitConstPoolAddress - Arrange for the address of an constant pool | /// emitConstPoolAddress - Arrange for the address of an constant pool | ||||||
| /// to be emitted to the current location in the function, and allow it to be PC | /// to be emitted to the current location in the function, and allow it to be PC | ||||||
| /// relative. | /// relative. | ||||||
| void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc, | void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) { | ||||||
|                                           int Disp /* = 0 */, |  | ||||||
|                                           unsigned PCAdj /* = 0 */) { |  | ||||||
|   // Tell JIT emitter we'll resolve the address. |   // Tell JIT emitter we'll resolve the address. | ||||||
|   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), |   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), | ||||||
|                                                     Reloc, CPI, PCAdj, true)); |                                                     Reloc, CPI, 0, true)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// emitJumpTableAddress - Arrange for the address of a jump table to | /// emitJumpTableAddress - Arrange for the address of a jump table to | ||||||
| /// be emitted to the current location in the function, and allow it to be PC | /// be emitted to the current location in the function, and allow it to be PC | ||||||
| /// relative. | /// relative. | ||||||
| void ARMCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc, | void ARMCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) { | ||||||
|                                           unsigned PCAdj /* = 0 */) { |  | ||||||
|   MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), |   MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), | ||||||
|                                                   Reloc, JTIndex, PCAdj, true)); |                                                     Reloc, JTIndex, 0, true)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// emitMachineBasicBlock - Emit the specified address basic block. | /// emitMachineBasicBlock - Emit the specified address basic block. | ||||||
| void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, | void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, | ||||||
|                                            unsigned Reloc) { |                                            unsigned Reloc, intptr_t JTBase) { | ||||||
|   MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), |   MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), | ||||||
|                                              Reloc, BB)); |                                              Reloc, BB, JTBase)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ARMCodeEmitter::emitWordLE(unsigned Binary) { | void ARMCodeEmitter::emitWordLE(unsigned Binary) { | ||||||
| @@ -321,8 +318,8 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { | void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { | ||||||
|   unsigned CPI = MI.getOperand(0).getImm(); |   unsigned CPI = MI.getOperand(0).getImm();       // CP instruction index. | ||||||
|   unsigned CPIndex = MI.getOperand(1).getIndex(); |   unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index. | ||||||
|   const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex]; |   const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex]; | ||||||
|    |    | ||||||
|   // Remember the CONSTPOOL_ENTRY address for later relocation. |   // Remember the CONSTPOOL_ENTRY address for later relocation. | ||||||
| @@ -335,14 +332,12 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { | |||||||
|       static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal); |       static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal); | ||||||
|  |  | ||||||
|     DOUT << "  ** ARM constant pool #" << CPI << " @ " |     DOUT << "  ** ARM constant pool #" << CPI << " @ " | ||||||
|          << (void*)MCE.getCurrentPCValue() << " " << *ACPV << "\n"; |          << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n'; | ||||||
|  |  | ||||||
|     GlobalValue *GV = ACPV->getGV(); |     GlobalValue *GV = ACPV->getGV(); | ||||||
|     if (GV) { |     if (GV) { | ||||||
|       assert(!ACPV->isStub() && "Don't know how to deal this yet!"); |       assert(!ACPV->isStub() && "Don't know how to deal this yet!"); | ||||||
|       MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), |       emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry, false, CPIndex); | ||||||
|                                                 ARM::reloc_arm_machine_cp_entry, |  | ||||||
|                                                 GV, CPIndex, false)); |  | ||||||
|      } else  { |      } else  { | ||||||
|       assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!"); |       assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!"); | ||||||
|       emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute); |       emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute); | ||||||
| @@ -352,7 +347,7 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { | |||||||
|     Constant *CV = MCPE.Val.ConstVal; |     Constant *CV = MCPE.Val.ConstVal; | ||||||
|  |  | ||||||
|     DOUT << "  ** Constant pool #" << CPI << " @ " |     DOUT << "  ** Constant pool #" << CPI << " @ " | ||||||
|          << (void*)MCE.getCurrentPCValue() << " " << *CV << "\n"; |          << (void*)MCE.getCurrentPCValue() << " " << *CV << '\n'; | ||||||
|  |  | ||||||
|     if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { |     if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { | ||||||
|       emitGlobalAddress(GV, ARM::reloc_arm_absolute, false); |       emitGlobalAddress(GV, ARM::reloc_arm_absolute, false); | ||||||
| @@ -454,7 +449,7 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { | |||||||
|     // Remember of the address of the PC label for relocation later. |     // Remember of the address of the PC label for relocation later. | ||||||
|     addPCLabel(MI.getOperand(2).getImm()); |     addPCLabel(MI.getOperand(2).getImm()); | ||||||
|     // PICADD is just an add instruction that implicitly read pc. |     // PICADD is just an add instruction that implicitly read pc. | ||||||
|     emitDataProcessingInstruction(MI, ARM::PC); |     emitDataProcessingInstruction(MI, 0, ARM::PC); | ||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
|   case ARM::PICLDR: |   case ARM::PICLDR: | ||||||
| @@ -568,6 +563,7 @@ unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI, | |||||||
| } | } | ||||||
|  |  | ||||||
| void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI, | void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI, | ||||||
|  |                                                    unsigned ImplicitRd, | ||||||
|                                                    unsigned ImplicitRn) { |                                                    unsigned ImplicitRn) { | ||||||
|   const TargetInstrDesc &TID = MI.getDesc(); |   const TargetInstrDesc &TID = MI.getDesc(); | ||||||
|  |  | ||||||
| @@ -583,10 +579,12 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI, | |||||||
|   // Encode register def if there is one. |   // Encode register def if there is one. | ||||||
|   unsigned NumDefs = TID.getNumDefs(); |   unsigned NumDefs = TID.getNumDefs(); | ||||||
|   unsigned OpIdx = 0; |   unsigned OpIdx = 0; | ||||||
|   if (NumDefs) { |   if (NumDefs) | ||||||
|     Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRdShift; |     Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; | ||||||
|     ++OpIdx; |   else if (ImplicitRd) | ||||||
|   } |     // Special handling for implicit use (e.g. PC). | ||||||
|  |     Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) | ||||||
|  |                << ARMII::RegRdShift); | ||||||
|  |  | ||||||
|   // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. |   // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. | ||||||
|   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) |   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) | ||||||
| @@ -904,17 +902,18 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) { | |||||||
|   emitWordLE(Binary); |   emitWordLE(Binary); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex, intptr_t JTBase) { | void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) { | ||||||
|   // Remember the base address of the inline jump table. |   // Remember the base address of the inline jump table. | ||||||
|   JTI->addJumpTableBaseAddr(JTIndex, MCE.getCurrentPCValue()); |   intptr_t JTBase = MCE.getCurrentPCValue(); | ||||||
|  |   JTI->addJumpTableBaseAddr(JTIndex, JTBase); | ||||||
|  |   DOUT << "  ** Jump Table #" << JTIndex << " @ " << (void*)JTBase << '\n'; | ||||||
|  |  | ||||||
|   // Now emit the jump table entries. |   // Now emit the jump table entries. | ||||||
|   const std::vector<MachineBasicBlock*> &MBBs = (*MJTEs)[JTIndex].MBBs; |   const std::vector<MachineBasicBlock*> &MBBs = (*MJTEs)[JTIndex].MBBs; | ||||||
|   for (unsigned i = 0, e = MBBs.size(); i != e; ++i) { |   for (unsigned i = 0, e = MBBs.size(); i != e; ++i) { | ||||||
|     if (IsPIC) |     if (IsPIC) | ||||||
|       // DestBB address - JT base. |       // DestBB address - JT base. | ||||||
|       MCE.addRelocation(MachineRelocation::getBB(JTBase, ARM::reloc_arm_pic_jt, |       emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_pic_jt, JTBase); | ||||||
|                                                  MBBs[i])); |  | ||||||
|     else |     else | ||||||
|       // Absolute DestBB address. |       // Absolute DestBB address. | ||||||
|       emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_absolute); |       emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_absolute); | ||||||
| @@ -924,17 +923,23 @@ void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex, intptr_t JTBase) { | |||||||
|  |  | ||||||
| void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) { | void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) { | ||||||
|   const TargetInstrDesc &TID = MI.getDesc(); |   const TargetInstrDesc &TID = MI.getDesc(); | ||||||
|   if (TID.Opcode == ARM::BX || |  | ||||||
|       TID.Opcode == ARM::BR_JTr || |  | ||||||
|       TID.Opcode == ARM::BR_JTadd) |  | ||||||
|     abort(); // FIXME |  | ||||||
|  |  | ||||||
|   if (TID.Opcode == ARM::BR_JTm) { |   // Handle jump tables. | ||||||
|  |   if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd) { | ||||||
|  |     // First emit a ldr pc, [] instruction. | ||||||
|  |     emitDataProcessingInstruction(MI, ARM::PC); | ||||||
|  |  | ||||||
|  |     // Then emit the inline jump table. | ||||||
|  |     unsigned JTIndex = (TID.Opcode == ARM::BR_JTr) | ||||||
|  |       ? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex(); | ||||||
|  |     emitInlineJumpTable(JTIndex); | ||||||
|  |     return; | ||||||
|  |   } else if (TID.Opcode == ARM::BR_JTm) { | ||||||
|     // First emit a ldr pc, [] instruction. |     // First emit a ldr pc, [] instruction. | ||||||
|     emitLoadStoreInstruction(MI, ARM::PC); |     emitLoadStoreInstruction(MI, ARM::PC); | ||||||
|  |  | ||||||
|     // Then emit the inline jump table. |     // Then emit the inline jump table. | ||||||
|     emitInlineJumpTable(MI.getOperand(3).getIndex(), MCE.getCurrentPCOffset()); |     emitInlineJumpTable(MI.getOperand(3).getIndex()); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -170,9 +170,14 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, | |||||||
|  |  | ||||||
| intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const { | intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const { | ||||||
|   ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType(); |   ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType(); | ||||||
|   if (RT == ARM::reloc_arm_jt_base) |   if (RT == ARM::reloc_arm_pic_jt) | ||||||
|  |     // Destination address - jump table base. | ||||||
|  |     return (intptr_t)(MR->getResultPointer()) - MR->getConstantVal(); | ||||||
|  |   else if (RT == ARM::reloc_arm_jt_base) | ||||||
|  |     // Jump table base address. | ||||||
|     return getJumpTableBaseAddr(MR->getJumpTableIndex()); |     return getJumpTableBaseAddr(MR->getJumpTableIndex()); | ||||||
|   else if (RT == ARM::reloc_arm_cp_entry) |   else if (RT == ARM::reloc_arm_cp_entry) | ||||||
|  |     // Constant pool entry address. | ||||||
|     return getConstantPoolEntryAddr(MR->getConstantPoolIndex()); |     return getConstantPoolEntryAddr(MR->getConstantPoolIndex()); | ||||||
|   else if (RT == ARM::reloc_arm_machine_cp_entry) { |   else if (RT == ARM::reloc_arm_machine_cp_entry) { | ||||||
|     const MachineConstantPoolEntry &MCPE = (*MCPEs)[MR->getConstantVal()]; |     const MachineConstantPoolEntry &MCPE = (*MCPEs)[MR->getConstantVal()]; | ||||||
| @@ -196,8 +201,6 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR, | |||||||
|                           unsigned NumRelocs, unsigned char* GOTBase) { |                           unsigned NumRelocs, unsigned char* GOTBase) { | ||||||
|   for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { |   for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { | ||||||
|     void *RelocPos = (char*)Function + MR->getMachineCodeOffset(); |     void *RelocPos = (char*)Function + MR->getMachineCodeOffset(); | ||||||
|     // If this is a constpool relocation, get the address of the |  | ||||||
|     // constpool_entry instruction. |  | ||||||
|     intptr_t ResultPtr = resolveRelocDestAddr(MR); |     intptr_t ResultPtr = resolveRelocDestAddr(MR); | ||||||
|     switch ((ARM::RelocationType)MR->getRelocationType()) { |     switch ((ARM::RelocationType)MR->getRelocationType()) { | ||||||
|     case ARM::reloc_arm_cp_entry: |     case ARM::reloc_arm_cp_entry: | ||||||
| @@ -220,6 +223,7 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR, | |||||||
|       *((unsigned*)RelocPos) |= 0xF << 16; |       *((unsigned*)RelocPos) |= 0xF << 16; | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|  |     case ARM::reloc_arm_pic_jt: | ||||||
|     case ARM::reloc_arm_machine_cp_entry: |     case ARM::reloc_arm_machine_cp_entry: | ||||||
|     case ARM::reloc_arm_absolute: { |     case ARM::reloc_arm_absolute: { | ||||||
|       // These addresses have already been resolved. |       // These addresses have already been resolved. | ||||||
| @@ -244,12 +248,6 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR, | |||||||
|       *((unsigned*)RelocPos) |= ResultPtr; |       *((unsigned*)RelocPos) |= ResultPtr; | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|     case ARM::reloc_arm_pic_jt: { |  | ||||||
|       // PIC JT entry is destination - JT base. |  | ||||||
|       ResultPtr = ResultPtr - (intptr_t)RelocPos; |  | ||||||
|       *((unsigned*)RelocPos) |= ResultPtr; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user