mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-14 15:38:57 +00:00
Implement getelementptr instruction as well as the load and store forms
that incorporate gep llvm-svn: 1036
This commit is contained in:
parent
fbbdca242a
commit
3f63736182
@ -568,10 +568,45 @@ static void executeFreeInst(FreeInst *I, ExecutionContext &SF) {
|
|||||||
free((void*)Value.ULongVal); // Free memory
|
free((void*)Value.ULongVal); // Free memory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// getElementOffset - The workhorse for getelementptr, load and store. This
|
||||||
|
// function returns the offset that arguments ArgOff+1 -> NumArgs specify for
|
||||||
|
// the pointer type specified by argument Arg.
|
||||||
|
//
|
||||||
|
static uint64_t getElementOffset(Instruction *I, unsigned ArgOff) {
|
||||||
|
assert(isa<PointerType>(I->getOperand(ArgOff)->getType()) &&
|
||||||
|
"Cannot getElementOffset of a nonpointer type!");
|
||||||
|
|
||||||
|
uint64_t Total = 0;
|
||||||
|
const Type *Ty =
|
||||||
|
cast<PointerType>(I->getOperand(ArgOff++)->getType())->getValueType();
|
||||||
|
|
||||||
|
while (ArgOff < I->getNumOperands()) {
|
||||||
|
const StructType *STy = cast<StructType>(Ty);
|
||||||
|
const StructLayout *SLO = TD.getStructLayout(STy);
|
||||||
|
|
||||||
|
// Indicies must be ubyte constants...
|
||||||
|
const ConstPoolUInt *CPU = cast<ConstPoolUInt>(I->getOperand(ArgOff++));
|
||||||
|
assert(CPU->getType() == Type::UByteTy);
|
||||||
|
Total += SLO->MemberOffsets[CPU->getValue()];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Total;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void executeGEPInst(GetElementPtrInst *I, ExecutionContext &SF) {
|
||||||
|
uint64_t SrcPtr = getOperandValue(I->getPtrOperand(), SF).ULongVal;
|
||||||
|
|
||||||
|
GenericValue Result;
|
||||||
|
Result.ULongVal = SrcPtr + getElementOffset(I, 0);
|
||||||
|
SetValue(I, Result, SF);
|
||||||
|
}
|
||||||
|
|
||||||
static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
|
static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
|
||||||
assert(I->getNumOperands() == 1 && "NI!");
|
uint64_t SrcPtr = getOperandValue(I->getPtrOperand(), SF).ULongVal;
|
||||||
GenericValue *Ptr =
|
SrcPtr += getElementOffset(I, 0); // Handle any structure indices
|
||||||
(GenericValue*)getOperandValue(I->getPtrOperand(), SF).ULongVal;
|
|
||||||
|
GenericValue *Ptr = (GenericValue*)SrcPtr;
|
||||||
GenericValue Result;
|
GenericValue Result;
|
||||||
|
|
||||||
switch (I->getType()->getPrimitiveID()) {
|
switch (I->getType()->getPrimitiveID()) {
|
||||||
@ -595,10 +630,11 @@ static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void executeStoreInst(StoreInst *I, ExecutionContext &SF) {
|
static void executeStoreInst(StoreInst *I, ExecutionContext &SF) {
|
||||||
GenericValue *Ptr =
|
uint64_t SrcPtr = getOperandValue(I->getPtrOperand(), SF).ULongVal;
|
||||||
(GenericValue *)getOperandValue(I->getPtrOperand(), SF).ULongVal;
|
SrcPtr += getElementOffset(I, 1); // Handle any structure indices
|
||||||
|
|
||||||
|
GenericValue *Ptr = (GenericValue *)SrcPtr;
|
||||||
GenericValue Val = getOperandValue(I->getOperand(0), SF);
|
GenericValue Val = getOperandValue(I->getOperand(0), SF);
|
||||||
assert(I->getNumOperands() == 2 && "NI!");
|
|
||||||
|
|
||||||
switch (I->getOperand(0)->getType()->getPrimitiveID()) {
|
switch (I->getOperand(0)->getType()->getPrimitiveID()) {
|
||||||
case Type::BoolTyID:
|
case Type::BoolTyID:
|
||||||
@ -850,6 +886,8 @@ bool Interpreter::executeInstruction() {
|
|||||||
case Instruction::Free: executeFreeInst (cast<FreeInst> (I), SF); break;
|
case Instruction::Free: executeFreeInst (cast<FreeInst> (I), SF); break;
|
||||||
case Instruction::Load: executeLoadInst (cast<LoadInst> (I), SF); break;
|
case Instruction::Load: executeLoadInst (cast<LoadInst> (I), SF); break;
|
||||||
case Instruction::Store: executeStoreInst (cast<StoreInst>(I), SF); break;
|
case Instruction::Store: executeStoreInst (cast<StoreInst>(I), SF); break;
|
||||||
|
case Instruction::GetElementPtr:
|
||||||
|
executeGEPInst(cast<GetElementPtrInst>(I), SF); break;
|
||||||
|
|
||||||
// Miscellaneous Instructions
|
// Miscellaneous Instructions
|
||||||
case Instruction::Call: executeCallInst (cast<CallInst> (I), SF); break;
|
case Instruction::Call: executeCallInst (cast<CallInst> (I), SF); break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user