2002-12-04 06:09:04 +00:00
|
|
|
//===-- GlobalVars.cpp - Code to emit global variables to memory ----------===//
|
|
|
|
//
|
|
|
|
// This file contains the code to generate global variables to memory.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/Module.h"
|
|
|
|
#include "llvm/DerivedTypes.h"
|
|
|
|
#include "llvm/Constants.h"
|
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2002-12-13 13:15:36 +00:00
|
|
|
#include "Support/Statistic.h"
|
2002-12-04 06:09:04 +00:00
|
|
|
#include "VM.h"
|
This checkin is brought to you by the brian gaeke allnighter fund.
(lib/Target/X86) InstSelectSimple.cpp:
Include llvm/DerivedTypes.h and iostream.
Refactor visitMul out into a wrapper around doMultiply(), so that we
can do multiplications on temporary values when we are doing
getelementptrs.
Refactor part of getReg out into makeAnotherReg, so that we can create
registers willy-nilly to hold temporary values, when we are doing
getelementptrs.
Add stub implementations of visitMallocInst and visitAllocaInst.
Add initial implementation of visitGetElementPtrInst.
In copyConstantToRegister:
We throw a *lot* of our asserts here. So, when we want to throw an
assert, print out to stderr whatever expr or whatever constant made
us barf.
Support copying ConstantPointerNull to register, using a move immediate
of zero.
Rename FLDr4 and FLDr8 to FLDr32 and FLDr64, so that they match the meanings
of the numbers in the other instruction names. All uses modified.
Teach visitCallInst to extract byte- and short-class return values
from subregs of EAX. Add a FIXME note about how we would do it for
float-class return values.
Add a FIXME note about how we would cast float to int and back.
X86InstrInfo.def:
Rename FLDr4 and FLDr8 to FLDr32 and FLDr64, so that they match the meanings
of the numbers in the other instruction names. All uses modified.
(tools/jello) GlobalVars.cpp:
Include iostream.
If we have to emit a floating-point constant to memory, gamble and use
the same method as for ints.
If we have to emit a ConstantPointerNull to memory, try using a "void *"
and "NULL".
Otherwise, if we are going to throw an assert, print out whatever constant
made us barf, first.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4973 91177308-0d34-0410-b5e6-96231b3b80d8
2002-12-12 15:33:40 +00:00
|
|
|
#include <iostream>
|
2002-12-04 06:09:04 +00:00
|
|
|
|
|
|
|
/// EmitGlobals - Emit all of the global variables to memory, storing their
|
|
|
|
/// addresses into GlobalAddress. This must make sure to copy the contents of
|
|
|
|
/// their initializers into the memory.
|
|
|
|
///
|
|
|
|
void VM::emitGlobals() {
|
|
|
|
const TargetData &TD = TM.getTargetData();
|
|
|
|
|
|
|
|
// Loop over all of the global variables in the program, allocating the memory
|
|
|
|
// to hold them.
|
|
|
|
for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
|
|
|
|
if (!I->isExternal()) {
|
|
|
|
// Get the type of the global...
|
|
|
|
const Type *Ty = I->getType()->getElementType();
|
|
|
|
|
|
|
|
// Allocate some memory for it!
|
|
|
|
GlobalAddress[I] = new char[TD.getTypeSize(Ty)];
|
|
|
|
|
2002-12-13 13:15:36 +00:00
|
|
|
DEBUG(std::cerr << "Allocated global '" << I->getName()
|
|
|
|
<< "' to addr 0x" << std::hex << GlobalAddress[I] << std::dec
|
|
|
|
<< "\n");
|
2002-12-04 06:09:04 +00:00
|
|
|
} else {
|
|
|
|
assert(0 && "References to external globals not handled yet!");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now that all of the globals are set up in memory, loop through them all and
|
|
|
|
// initialize their contents.
|
|
|
|
for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
|
|
|
|
if (!I->isExternal())
|
|
|
|
emitConstantToMemory(I->getInitializer(), GlobalAddress[I]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// emitConstantToMemory - Use the specified LLVM constant to initialize the
|
|
|
|
/// specified region of memory.
|
|
|
|
///
|
|
|
|
void VM::emitConstantToMemory(Constant *Init, void *Addr) {
|
|
|
|
const TargetData &TD = TM.getTargetData();
|
|
|
|
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(Init)) {
|
|
|
|
switch (CI->getType()->getPrimitiveID()) {
|
|
|
|
case Type::BoolTyID:
|
|
|
|
*(char*)Addr = cast<ConstantBool>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::UByteTyID:
|
|
|
|
*(unsigned char*)Addr = cast<ConstantUInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::SByteTyID:
|
|
|
|
*( signed char*)Addr = cast<ConstantSInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::UShortTyID:
|
|
|
|
*(unsigned short*)Addr = cast<ConstantUInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::ShortTyID:
|
|
|
|
*( signed short*)Addr = cast<ConstantSInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::UIntTyID:
|
|
|
|
*(unsigned int*)Addr = cast<ConstantUInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::IntTyID:
|
|
|
|
*( signed int*)Addr = cast<ConstantSInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::ULongTyID:
|
|
|
|
*(uint64_t*)Addr = cast<ConstantUInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
case Type::LongTyID:
|
|
|
|
*(int64_t*)Addr = cast<ConstantSInt>(CI)->getValue();
|
|
|
|
return;
|
|
|
|
default: break;
|
|
|
|
}
|
This checkin is brought to you by the brian gaeke allnighter fund.
(lib/Target/X86) InstSelectSimple.cpp:
Include llvm/DerivedTypes.h and iostream.
Refactor visitMul out into a wrapper around doMultiply(), so that we
can do multiplications on temporary values when we are doing
getelementptrs.
Refactor part of getReg out into makeAnotherReg, so that we can create
registers willy-nilly to hold temporary values, when we are doing
getelementptrs.
Add stub implementations of visitMallocInst and visitAllocaInst.
Add initial implementation of visitGetElementPtrInst.
In copyConstantToRegister:
We throw a *lot* of our asserts here. So, when we want to throw an
assert, print out to stderr whatever expr or whatever constant made
us barf.
Support copying ConstantPointerNull to register, using a move immediate
of zero.
Rename FLDr4 and FLDr8 to FLDr32 and FLDr64, so that they match the meanings
of the numbers in the other instruction names. All uses modified.
Teach visitCallInst to extract byte- and short-class return values
from subregs of EAX. Add a FIXME note about how we would do it for
float-class return values.
Add a FIXME note about how we would cast float to int and back.
X86InstrInfo.def:
Rename FLDr4 and FLDr8 to FLDr32 and FLDr64, so that they match the meanings
of the numbers in the other instruction names. All uses modified.
(tools/jello) GlobalVars.cpp:
Include iostream.
If we have to emit a floating-point constant to memory, gamble and use
the same method as for ints.
If we have to emit a ConstantPointerNull to memory, try using a "void *"
and "NULL".
Otherwise, if we are going to throw an assert, print out whatever constant
made us barf, first.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4973 91177308-0d34-0410-b5e6-96231b3b80d8
2002-12-12 15:33:40 +00:00
|
|
|
} else if (ConstantFP *CF = dyn_cast <ConstantFP> (Init)) {
|
|
|
|
switch (CF->getType ()->getPrimitiveID ()) {
|
|
|
|
case Type::FloatTyID:
|
|
|
|
*(float*)Addr = CF->getValue ();
|
|
|
|
return;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
*(double*)Addr = CF->getValue ();
|
|
|
|
return;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
} else if (ConstantPointerNull *CP = dyn_cast <ConstantPointerNull> (Init)) {
|
|
|
|
// Fill the space with a NULL pointer.
|
|
|
|
*(void **)Addr = NULL;
|
|
|
|
return;
|
2002-12-04 06:09:04 +00:00
|
|
|
} else if (ConstantArray *CA = dyn_cast<ConstantArray>(Init)) {
|
|
|
|
unsigned ElementSize = TD.getTypeSize(CA->getType()->getElementType());
|
|
|
|
for (unsigned i = 0, e = CA->getType()->getNumElements(); i != e; ++i) {
|
|
|
|
emitConstantToMemory(cast<Constant>(CA->getOperand(i)), Addr);
|
|
|
|
Addr = (char*)Addr+ElementSize;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
This checkin is brought to you by the brian gaeke allnighter fund.
(lib/Target/X86) InstSelectSimple.cpp:
Include llvm/DerivedTypes.h and iostream.
Refactor visitMul out into a wrapper around doMultiply(), so that we
can do multiplications on temporary values when we are doing
getelementptrs.
Refactor part of getReg out into makeAnotherReg, so that we can create
registers willy-nilly to hold temporary values, when we are doing
getelementptrs.
Add stub implementations of visitMallocInst and visitAllocaInst.
Add initial implementation of visitGetElementPtrInst.
In copyConstantToRegister:
We throw a *lot* of our asserts here. So, when we want to throw an
assert, print out to stderr whatever expr or whatever constant made
us barf.
Support copying ConstantPointerNull to register, using a move immediate
of zero.
Rename FLDr4 and FLDr8 to FLDr32 and FLDr64, so that they match the meanings
of the numbers in the other instruction names. All uses modified.
Teach visitCallInst to extract byte- and short-class return values
from subregs of EAX. Add a FIXME note about how we would do it for
float-class return values.
Add a FIXME note about how we would cast float to int and back.
X86InstrInfo.def:
Rename FLDr4 and FLDr8 to FLDr32 and FLDr64, so that they match the meanings
of the numbers in the other instruction names. All uses modified.
(tools/jello) GlobalVars.cpp:
Include iostream.
If we have to emit a floating-point constant to memory, gamble and use
the same method as for ints.
If we have to emit a ConstantPointerNull to memory, try using a "void *"
and "NULL".
Otherwise, if we are going to throw an assert, print out whatever constant
made us barf, first.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4973 91177308-0d34-0410-b5e6-96231b3b80d8
2002-12-12 15:33:40 +00:00
|
|
|
std::cerr << "Offending constant: " << Init << "\n";
|
2002-12-04 06:09:04 +00:00
|
|
|
assert(0 && "Don't know how to emit this constant to memory!");
|
|
|
|
}
|