mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-17 18:24:34 +00:00
Move getX86RegNum into X86RegisterInfo and use it
in the trampoline lowering. Lookup the jump and mov opcodes for the trampoline rather than hard coding them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41577 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -13,7 +13,6 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#define DEBUG_TYPE "x86-emitter"
|
#define DEBUG_TYPE "x86-emitter"
|
||||||
#include "X86CodeEmitter.h"
|
|
||||||
#include "X86InstrInfo.h"
|
#include "X86InstrInfo.h"
|
||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
#include "X86TargetMachine.h"
|
#include "X86TargetMachine.h"
|
||||||
@@ -193,60 +192,8 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
|
|||||||
MCE.emitWordLE(0); // The relocated value will be added to the displacement
|
MCE.emitWordLE(0); // The relocated value will be added to the displacement
|
||||||
}
|
}
|
||||||
|
|
||||||
// getX86RegNum - This function maps LLVM register identifiers to their X86
|
|
||||||
// specific numbering, which is used in various places encoding instructions.
|
|
||||||
//
|
|
||||||
unsigned Emitter::getX86RegNum(unsigned RegNo) {
|
unsigned Emitter::getX86RegNum(unsigned RegNo) {
|
||||||
switch(RegNo) {
|
return ((X86RegisterInfo&)II->getRegisterInfo()).getX86RegNum(RegNo);
|
||||||
case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
|
|
||||||
case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
|
|
||||||
case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
|
|
||||||
case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
|
|
||||||
case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
|
|
||||||
return N86::ESP;
|
|
||||||
case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
|
|
||||||
return N86::EBP;
|
|
||||||
case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
|
|
||||||
return N86::ESI;
|
|
||||||
case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
|
|
||||||
return N86::EDI;
|
|
||||||
|
|
||||||
case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
|
|
||||||
return N86::EAX;
|
|
||||||
case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
|
|
||||||
return N86::ECX;
|
|
||||||
case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
|
|
||||||
return N86::EDX;
|
|
||||||
case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
|
|
||||||
return N86::EBX;
|
|
||||||
case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
|
|
||||||
return N86::ESP;
|
|
||||||
case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
|
|
||||||
return N86::EBP;
|
|
||||||
case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
|
|
||||||
return N86::ESI;
|
|
||||||
case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
|
|
||||||
return N86::EDI;
|
|
||||||
|
|
||||||
case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
|
|
||||||
case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
|
|
||||||
return RegNo-X86::ST0;
|
|
||||||
|
|
||||||
case X86::XMM0: case X86::XMM1: case X86::XMM2: case X86::XMM3:
|
|
||||||
case X86::XMM4: case X86::XMM5: case X86::XMM6: case X86::XMM7:
|
|
||||||
return II->getRegisterInfo().getDwarfRegNum(RegNo) -
|
|
||||||
II->getRegisterInfo().getDwarfRegNum(X86::XMM0);
|
|
||||||
case X86::XMM8: case X86::XMM9: case X86::XMM10: case X86::XMM11:
|
|
||||||
case X86::XMM12: case X86::XMM13: case X86::XMM14: case X86::XMM15:
|
|
||||||
return II->getRegisterInfo().getDwarfRegNum(RegNo) -
|
|
||||||
II->getRegisterInfo().getDwarfRegNum(X86::XMM8);
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(MRegisterInfo::isVirtualRegister(RegNo) &&
|
|
||||||
"Unknown physical register!");
|
|
||||||
assert(0 && "Register allocator hasn't allocated reg correctly yet!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
|
inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
//===-- X86CodeEmitter.h - X86 DAG Lowering Interface -----------*- C++ -*-===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file was developed by Duncan Sands and is distributed under
|
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// This file defines utilities for X86 code emission.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef X86CODEEMITTER_H
|
|
||||||
#define X86CODEEMITTER_H
|
|
||||||
|
|
||||||
/// N86 namespace - Native X86 Register numbers... used by X86 backend.
|
|
||||||
///
|
|
||||||
namespace N86 {
|
|
||||||
enum {
|
|
||||||
EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // X86CODEEMITTER_H
|
|
@@ -13,7 +13,6 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
#include "X86CodeEmitter.h"
|
|
||||||
#include "X86InstrBuilder.h"
|
#include "X86InstrBuilder.h"
|
||||||
#include "X86ISelLowering.h"
|
#include "X86ISelLowering.h"
|
||||||
#include "X86MachineFunctionInfo.h"
|
#include "X86MachineFunctionInfo.h"
|
||||||
@@ -4330,7 +4329,7 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
|||||||
Function *Func = (Function *)
|
Function *Func = (Function *)
|
||||||
cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
|
cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
|
||||||
unsigned CC = Func->getCallingConv();
|
unsigned CC = Func->getCallingConv();
|
||||||
unsigned char NestReg;
|
unsigned NestReg;
|
||||||
|
|
||||||
switch (CC) {
|
switch (CC) {
|
||||||
default:
|
default:
|
||||||
@@ -4340,7 +4339,7 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
|||||||
case CallingConv::X86_StdCall: {
|
case CallingConv::X86_StdCall: {
|
||||||
// Pass 'nest' parameter in ECX.
|
// Pass 'nest' parameter in ECX.
|
||||||
// Must be kept in sync with X86CallingConv.td
|
// Must be kept in sync with X86CallingConv.td
|
||||||
NestReg = N86::ECX;
|
NestReg = X86::ECX;
|
||||||
|
|
||||||
// Check that ECX wasn't needed by an 'inreg' parameter.
|
// Check that ECX wasn't needed by an 'inreg' parameter.
|
||||||
const FunctionType *FTy = Func->getFunctionType();
|
const FunctionType *FTy = Func->getFunctionType();
|
||||||
@@ -4366,26 +4365,29 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
|||||||
case CallingConv::X86_FastCall:
|
case CallingConv::X86_FastCall:
|
||||||
// Pass 'nest' parameter in EAX.
|
// Pass 'nest' parameter in EAX.
|
||||||
// Must be kept in sync with X86CallingConv.td
|
// Must be kept in sync with X86CallingConv.td
|
||||||
NestReg = N86::EAX;
|
NestReg = X86::EAX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const X86InstrInfo *TII =
|
||||||
|
((X86TargetMachine&)getTargetMachine()).getInstrInfo();
|
||||||
|
|
||||||
SDOperand OutChains[4];
|
SDOperand OutChains[4];
|
||||||
SDOperand Addr, Disp;
|
SDOperand Addr, Disp;
|
||||||
|
|
||||||
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(10, MVT::i32));
|
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(10, MVT::i32));
|
||||||
Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr);
|
Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr);
|
||||||
|
|
||||||
const unsigned char MOV32ri = 0xB8;
|
unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
|
||||||
const unsigned char JMP = 0xE9;
|
unsigned char N86Reg = ((X86RegisterInfo&)RegInfo).getX86RegNum(NestReg);
|
||||||
|
OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
|
||||||
OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|NestReg, MVT::i8),
|
|
||||||
Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
|
Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
|
||||||
|
|
||||||
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(1, MVT::i32));
|
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(1, MVT::i32));
|
||||||
OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
|
OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
|
||||||
TrmpSV->getOffset() + 1, false, 1);
|
TrmpSV->getOffset() + 1, false, 1);
|
||||||
|
|
||||||
|
unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
|
||||||
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32));
|
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32));
|
||||||
OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr,
|
OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr,
|
||||||
TrmpSV->getValue() + 5, TrmpSV->getOffset());
|
TrmpSV->getValue() + 5, TrmpSV->getOffset());
|
||||||
|
@@ -275,11 +275,14 @@ public:
|
|||||||
const TargetRegisterClass *getPointerRegClass() const;
|
const TargetRegisterClass *getPointerRegClass() const;
|
||||||
|
|
||||||
// getBaseOpcodeFor - This function returns the "base" X86 opcode for the
|
// getBaseOpcodeFor - This function returns the "base" X86 opcode for the
|
||||||
// specified opcode number.
|
// specified machine instruction.
|
||||||
//
|
//
|
||||||
unsigned char getBaseOpcodeFor(const TargetInstrDescriptor *TID) const {
|
unsigned char getBaseOpcodeFor(const TargetInstrDescriptor *TID) const {
|
||||||
return TID->TSFlags >> X86II::OpcodeShift;
|
return TID->TSFlags >> X86II::OpcodeShift;
|
||||||
}
|
}
|
||||||
|
unsigned char getBaseOpcodeFor(MachineOpCode Opcode) const {
|
||||||
|
return getBaseOpcodeFor(&get(Opcode));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@@ -65,6 +65,59 @@ X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getX86RegNum - This function maps LLVM register identifiers to their X86
|
||||||
|
// specific numbering, which is used in various places encoding instructions.
|
||||||
|
//
|
||||||
|
unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) {
|
||||||
|
switch(RegNo) {
|
||||||
|
case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
|
||||||
|
case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
|
||||||
|
case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
|
||||||
|
case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
|
||||||
|
case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
|
||||||
|
return N86::ESP;
|
||||||
|
case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
|
||||||
|
return N86::EBP;
|
||||||
|
case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
|
||||||
|
return N86::ESI;
|
||||||
|
case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
|
||||||
|
return N86::EDI;
|
||||||
|
|
||||||
|
case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
|
||||||
|
return N86::EAX;
|
||||||
|
case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
|
||||||
|
return N86::ECX;
|
||||||
|
case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
|
||||||
|
return N86::EDX;
|
||||||
|
case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
|
||||||
|
return N86::EBX;
|
||||||
|
case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
|
||||||
|
return N86::ESP;
|
||||||
|
case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
|
||||||
|
return N86::EBP;
|
||||||
|
case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
|
||||||
|
return N86::ESI;
|
||||||
|
case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
|
||||||
|
return N86::EDI;
|
||||||
|
|
||||||
|
case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
|
||||||
|
case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
|
||||||
|
return RegNo-X86::ST0;
|
||||||
|
|
||||||
|
case X86::XMM0: case X86::XMM1: case X86::XMM2: case X86::XMM3:
|
||||||
|
case X86::XMM4: case X86::XMM5: case X86::XMM6: case X86::XMM7:
|
||||||
|
return getDwarfRegNum(RegNo) - getDwarfRegNum(X86::XMM0);
|
||||||
|
case X86::XMM8: case X86::XMM9: case X86::XMM10: case X86::XMM11:
|
||||||
|
case X86::XMM12: case X86::XMM13: case X86::XMM14: case X86::XMM15:
|
||||||
|
return getDwarfRegNum(RegNo) - getDwarfRegNum(X86::XMM8);
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(isVirtualRegister(RegNo) && "Unknown physical register!");
|
||||||
|
assert(0 && "Register allocator hasn't allocated reg correctly yet!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool X86RegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool X86RegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI) const {
|
||||||
|
@@ -22,6 +22,14 @@ namespace llvm {
|
|||||||
class TargetInstrInfo;
|
class TargetInstrInfo;
|
||||||
class X86TargetMachine;
|
class X86TargetMachine;
|
||||||
|
|
||||||
|
/// N86 namespace - Native X86 register numbers
|
||||||
|
///
|
||||||
|
namespace N86 {
|
||||||
|
enum {
|
||||||
|
EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class X86RegisterInfo : public X86GenRegisterInfo {
|
class X86RegisterInfo : public X86GenRegisterInfo {
|
||||||
public:
|
public:
|
||||||
X86TargetMachine &TM;
|
X86TargetMachine &TM;
|
||||||
@@ -43,6 +51,10 @@ private:
|
|||||||
public:
|
public:
|
||||||
X86RegisterInfo(X86TargetMachine &tm, const TargetInstrInfo &tii);
|
X86RegisterInfo(X86TargetMachine &tm, const TargetInstrInfo &tii);
|
||||||
|
|
||||||
|
/// getX86RegNum - Returns the native X86 register number for the given LLVM
|
||||||
|
/// register identifier.
|
||||||
|
unsigned getX86RegNum(unsigned RegNo);
|
||||||
|
|
||||||
/// Code Generation virtual methods...
|
/// Code Generation virtual methods...
|
||||||
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
|
Reference in New Issue
Block a user