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 04827f0..56ce189 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -133,8 +133,14 @@
       // If this operand is a constant, emit the code to copy the constant into
       // the register here...
       //
-      if (Constant *C = dyn_cast<Constant>(V))
+      if (Constant *C = dyn_cast<Constant>(V)) {
         copyConstantToRegister(C, Reg);
+      } else if (GlobalValue *GV = dyn_cast<GlobalValue>(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 7b0f1bf..d54da1d 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 @@
     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<GlobalValue>(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 3ab7506..6206059 100644
--- a/lib/Target/X86/Printer.cpp
+++ b/lib/Target/X86/Printer.cpp
@@ -96,6 +96,10 @@
                     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 @@
     // 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 3ab7506..6206059 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -96,6 +96,10 @@
                     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 @@
     // 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 7b0f1bf..d54da1d 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 @@
     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<GlobalValue>(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 04827f0..56ce189 100644
--- a/lib/Target/X86/X86ISelSimple.cpp
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -133,8 +133,14 @@
       // If this operand is a constant, emit the code to copy the constant into
       // the register here...
       //
-      if (Constant *C = dyn_cast<Constant>(V))
+      if (Constant *C = dyn_cast<Constant>(V)) {
         copyConstantToRegister(C, Reg);
+      } else if (GlobalValue *GV = dyn_cast<GlobalValue>(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;
     }