From: Chris Lattner Date: Wed, 4 Dec 2002 06:45:19 +0000 (+0000) Subject: Add support for referencing global variables/functions X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dbf30f7b02e23a19eaa4f7b437a1f5682e4ee74c;p=oota-llvm.git Add support for referencing global variables/functions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4907 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 04827f03fcc..56ce189fca6 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -133,8 +133,14 @@ namespace { // If this operand is a constant, emit the code to copy the constant into // the register here... // - if (Constant *C = dyn_cast(V)) + if (Constant *C = dyn_cast(V)) { copyConstantToRegister(C, Reg); + } else if (GlobalValue *GV = dyn_cast(V)) { + // Move the address of the global into the register + BuildMI(BB, X86::MOVir32, 1, Reg).addReg(GV); + } else { + assert(0 && "Don't know how to handle a value of this type!"); + } return Reg; } diff --git a/lib/Target/X86/MachineCodeEmitter.cpp b/lib/Target/X86/MachineCodeEmitter.cpp index 7b0f1bfb443..d54da1db40e 100644 --- a/lib/Target/X86/MachineCodeEmitter.cpp +++ b/lib/Target/X86/MachineCodeEmitter.cpp @@ -11,6 +11,7 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Value.h" namespace { class Emitter : public FunctionPass { @@ -224,7 +225,12 @@ void Emitter::emitInstruction(MachineInstr &MI) { MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 2) { unsigned Size = 4; - emitConstant(MI.getOperand(1).getImmedValue(), Size); + if (Value *V = MI.getOperand(1).getVRegValue()) { + assert(Size == 4 && "Don't know how to emit non-pointer values!"); + MCE.emitGlobalAddress(cast(V)); + } else { + emitConstant(MI.getOperand(1).getImmedValue(), Size); + } } break; case X86II::MRMDestReg: diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp index 3ab75065d1e..62060594866 100644 --- a/lib/Target/X86/Printer.cpp +++ b/lib/Target/X86/Printer.cpp @@ -96,6 +96,10 @@ static void printOp(std::ostream &O, const MachineOperand &MO, const MRegisterInfo &RI) { switch (MO.getType()) { case MachineOperand::MO_VirtualRegister: + if (Value *V = MO.getVRegValue()) { + O << "<" << V->getName() << ">"; + return; + } case MachineOperand::MO_MachineRegister: if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) O << RI.get(MO.getReg()).Name; @@ -172,11 +176,15 @@ void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O, // There are currently two forms of acceptable AddRegFrm instructions. // Either the instruction JUST takes a single register (like inc, dec, etc), // or it takes a register and an immediate of the same size as the register - // (move immediate f.e.). + // (move immediate f.e.). Note that this immediate value might be stored as + // an LLVM value, to represent, for example, loading the address of a global + // into a register. // assert(isReg(MI->getOperand(0)) && (MI->getNumOperands() == 1 || - (MI->getNumOperands() == 2 && isImmediate(MI->getOperand(1)))) && + (MI->getNumOperands() == 2 && + (MI->getOperand(1).getVRegValue() || + isImmediate(MI->getOperand(1))))) && "Illegal form for AddRegFrm instruction!"); unsigned Reg = MI->getOperand(0).getReg(); diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 3ab75065d1e..62060594866 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -96,6 +96,10 @@ static void printOp(std::ostream &O, const MachineOperand &MO, const MRegisterInfo &RI) { switch (MO.getType()) { case MachineOperand::MO_VirtualRegister: + if (Value *V = MO.getVRegValue()) { + O << "<" << V->getName() << ">"; + return; + } case MachineOperand::MO_MachineRegister: if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) O << RI.get(MO.getReg()).Name; @@ -172,11 +176,15 @@ void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O, // There are currently two forms of acceptable AddRegFrm instructions. // Either the instruction JUST takes a single register (like inc, dec, etc), // or it takes a register and an immediate of the same size as the register - // (move immediate f.e.). + // (move immediate f.e.). Note that this immediate value might be stored as + // an LLVM value, to represent, for example, loading the address of a global + // into a register. // assert(isReg(MI->getOperand(0)) && (MI->getNumOperands() == 1 || - (MI->getNumOperands() == 2 && isImmediate(MI->getOperand(1)))) && + (MI->getNumOperands() == 2 && + (MI->getOperand(1).getVRegValue() || + isImmediate(MI->getOperand(1))))) && "Illegal form for AddRegFrm instruction!"); unsigned Reg = MI->getOperand(0).getReg(); diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 7b0f1bfb443..d54da1db40e 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -11,6 +11,7 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Value.h" namespace { class Emitter : public FunctionPass { @@ -224,7 +225,12 @@ void Emitter::emitInstruction(MachineInstr &MI) { MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 2) { unsigned Size = 4; - emitConstant(MI.getOperand(1).getImmedValue(), Size); + if (Value *V = MI.getOperand(1).getVRegValue()) { + assert(Size == 4 && "Don't know how to emit non-pointer values!"); + MCE.emitGlobalAddress(cast(V)); + } else { + emitConstant(MI.getOperand(1).getImmedValue(), Size); + } } break; case X86II::MRMDestReg: diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 04827f03fcc..56ce189fca6 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -133,8 +133,14 @@ namespace { // If this operand is a constant, emit the code to copy the constant into // the register here... // - if (Constant *C = dyn_cast(V)) + if (Constant *C = dyn_cast(V)) { copyConstantToRegister(C, Reg); + } else if (GlobalValue *GV = dyn_cast(V)) { + // Move the address of the global into the register + BuildMI(BB, X86::MOVir32, 1, Reg).addReg(GV); + } else { + assert(0 && "Don't know how to handle a value of this type!"); + } return Reg; }