mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
* Implement array indexing in lli
* Add external atoi method as well as floor, and srand git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1355 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -764,34 +764,54 @@ static void executeFreeInst(FreeInst *I, ExecutionContext &SF) {
|
|||||||
// function returns the offset that arguments ArgOff+1 -> NumArgs specify for
|
// function returns the offset that arguments ArgOff+1 -> NumArgs specify for
|
||||||
// the pointer type specified by argument Arg.
|
// the pointer type specified by argument Arg.
|
||||||
//
|
//
|
||||||
static PointerTy getElementOffset(Instruction *I, unsigned ArgOff) {
|
static PointerTy getElementOffset(MemAccessInst *I, ExecutionContext &SF) {
|
||||||
assert(isa<PointerType>(I->getOperand(ArgOff)->getType()) &&
|
assert(isa<PointerType>(I->getPointerOperand()->getType()) &&
|
||||||
"Cannot getElementOffset of a nonpointer type!");
|
"Cannot getElementOffset of a nonpointer type!");
|
||||||
|
|
||||||
PointerTy Total = 0;
|
PointerTy Total = 0;
|
||||||
const Type *Ty =
|
const Type *Ty =
|
||||||
cast<PointerType>(I->getOperand(ArgOff++)->getType())->getValueType();
|
cast<PointerType>(I->getPointerOperand()->getType())->getValueType();
|
||||||
|
|
||||||
|
unsigned ArgOff = I->getFirstIndexOperandNumber();
|
||||||
while (ArgOff < I->getNumOperands()) {
|
while (ArgOff < I->getNumOperands()) {
|
||||||
const StructType *STy = cast<StructType>(Ty);
|
if (const StructType *STy = dyn_cast<StructType>(Ty)) {
|
||||||
const StructLayout *SLO = TD.getStructLayout(STy);
|
const StructLayout *SLO = TD.getStructLayout(STy);
|
||||||
|
|
||||||
// Indicies must be ubyte constants...
|
// Indicies must be ubyte constants...
|
||||||
const ConstPoolUInt *CPU = cast<ConstPoolUInt>(I->getOperand(ArgOff++));
|
const ConstPoolUInt *CPU = cast<ConstPoolUInt>(I->getOperand(ArgOff++));
|
||||||
assert(CPU->getType() == Type::UByteTy);
|
assert(CPU->getType() == Type::UByteTy);
|
||||||
unsigned Index = CPU->getValue();
|
unsigned Index = CPU->getValue();
|
||||||
|
|
||||||
#ifdef PROFILE_STRUCTURE_FIELDS
|
#ifdef PROFILE_STRUCTURE_FIELDS
|
||||||
if (ProfileStructureFields) {
|
if (ProfileStructureFields) {
|
||||||
// Do accounting for this field...
|
// Do accounting for this field...
|
||||||
vector<unsigned> &OfC = FieldAccessCounts[STy];
|
vector<unsigned> &OfC = FieldAccessCounts[STy];
|
||||||
if (OfC.size() == 0) OfC.resize(STy->getElementTypes().size());
|
if (OfC.size() == 0) OfC.resize(STy->getElementTypes().size());
|
||||||
OfC[Index]++;
|
OfC[Index]++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Total += SLO->MemberOffsets[Index];
|
||||||
|
Ty = STy->getElementTypes()[Index];
|
||||||
|
} else {
|
||||||
|
const ArrayType *AT = cast<ArrayType>(Ty);
|
||||||
|
|
||||||
Total += SLO->MemberOffsets[Index];
|
// Get the index number for the array... which must be uint type...
|
||||||
Ty = STy->getElementTypes()[Index];
|
assert(I->getOperand(ArgOff)->getType() == Type::UIntTy);
|
||||||
|
unsigned Idx = getOperandValue(I->getOperand(ArgOff++), SF).UIntVal;
|
||||||
|
if (AT->isSized() && Idx >= (unsigned)AT->getNumElements()) {
|
||||||
|
cerr << "Out of range memory access to element #" << Idx
|
||||||
|
<< " of a " << AT->getNumElements() << " element array."
|
||||||
|
<< " Subscript #" << (ArgOff-I->getFirstIndexOperandNumber())
|
||||||
|
<< "\n";
|
||||||
|
// Get outta here!!!
|
||||||
|
siglongjmp(SignalRecoverBuffer, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ty = AT->getElementType();
|
||||||
|
unsigned Size = TD.getTypeSize(Ty);
|
||||||
|
Total += Size*Idx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Total;
|
return Total;
|
||||||
@@ -802,14 +822,14 @@ static void executeGEPInst(GetElementPtrInst *I, ExecutionContext &SF) {
|
|||||||
PointerTy SrcPtr = SRC.PointerVal;
|
PointerTy SrcPtr = SRC.PointerVal;
|
||||||
|
|
||||||
GenericValue Result;
|
GenericValue Result;
|
||||||
Result.PointerVal = SrcPtr + getElementOffset(I, 0);
|
Result.PointerVal = SrcPtr + getElementOffset(I, SF);
|
||||||
SetValue(I, Result, SF);
|
SetValue(I, Result, SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
|
static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
|
||||||
GenericValue SRC = getOperandValue(I->getPointerOperand(), SF);
|
GenericValue SRC = getOperandValue(I->getPointerOperand(), SF);
|
||||||
PointerTy SrcPtr = SRC.PointerVal;
|
PointerTy SrcPtr = SRC.PointerVal;
|
||||||
PointerTy Offset = getElementOffset(I, 0); // Handle any structure indices
|
PointerTy Offset = getElementOffset(I, SF); // Handle any structure indices
|
||||||
SrcPtr += Offset;
|
SrcPtr += Offset;
|
||||||
|
|
||||||
GenericValue *Ptr = (GenericValue*)SrcPtr;
|
GenericValue *Ptr = (GenericValue*)SrcPtr;
|
||||||
@@ -838,7 +858,7 @@ static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
|
|||||||
static void executeStoreInst(StoreInst *I, ExecutionContext &SF) {
|
static void executeStoreInst(StoreInst *I, ExecutionContext &SF) {
|
||||||
GenericValue SRC = getOperandValue(I->getPointerOperand(), SF);
|
GenericValue SRC = getOperandValue(I->getPointerOperand(), SF);
|
||||||
PointerTy SrcPtr = SRC.PointerVal;
|
PointerTy SrcPtr = SRC.PointerVal;
|
||||||
SrcPtr += getElementOffset(I, 1); // Handle any structure indices
|
SrcPtr += getElementOffset(I, SF); // Handle any structure indices
|
||||||
|
|
||||||
GenericValue *Ptr = (GenericValue *)SrcPtr;
|
GenericValue *Ptr = (GenericValue *)SrcPtr;
|
||||||
GenericValue Val = getOperandValue(I->getOperand(0), SF);
|
GenericValue Val = getOperandValue(I->getOperand(0), SF);
|
||||||
@@ -1117,10 +1137,10 @@ bool Interpreter::executeInstruction() {
|
|||||||
//
|
//
|
||||||
if (int SigNo = sigsetjmp(SignalRecoverBuffer, 1)) {
|
if (int SigNo = sigsetjmp(SignalRecoverBuffer, 1)) {
|
||||||
--SF.CurInst; // Back up to erroring instruction
|
--SF.CurInst; // Back up to erroring instruction
|
||||||
if (SigNo != SIGINT) {
|
if (SigNo != SIGINT && SigNo != -1) {
|
||||||
cout << "EXCEPTION OCCURRED [" << _sys_siglistp[SigNo] << "]:\n";
|
cout << "EXCEPTION OCCURRED [" << _sys_siglistp[SigNo] << "]:\n";
|
||||||
printStackTrace();
|
printStackTrace();
|
||||||
} else {
|
} else if (SigNo == SIGINT) {
|
||||||
cout << "CTRL-C Detected, execution halted.\n";
|
cout << "CTRL-C Detected, execution halted.\n";
|
||||||
}
|
}
|
||||||
InInstruction = false;
|
InInstruction = false;
|
||||||
|
@@ -213,6 +213,14 @@ GenericValue lle_X_free(MethodType *M, const vector<GenericValue> &Args) {
|
|||||||
return GenericValue();
|
return GenericValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int atoi(char *)
|
||||||
|
GenericValue lle_X_atoi(MethodType *M, const vector<GenericValue> &Args) {
|
||||||
|
assert(Args.size() == 1);
|
||||||
|
GenericValue GV;
|
||||||
|
GV.IntVal = atoi((char*)Args[0].PointerVal);
|
||||||
|
return GV;
|
||||||
|
}
|
||||||
|
|
||||||
// double pow(double, double)
|
// double pow(double, double)
|
||||||
GenericValue lle_X_pow(MethodType *M, const vector<GenericValue> &Args) {
|
GenericValue lle_X_pow(MethodType *M, const vector<GenericValue> &Args) {
|
||||||
assert(Args.size() == 2);
|
assert(Args.size() == 2);
|
||||||
@@ -237,6 +245,14 @@ GenericValue lle_X_log(MethodType *M, const vector<GenericValue> &Args) {
|
|||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// double floor(double)
|
||||||
|
GenericValue lle_X_floor(MethodType *M, const vector<GenericValue> &Args) {
|
||||||
|
assert(Args.size() == 1);
|
||||||
|
GenericValue GV;
|
||||||
|
GV.DoubleVal = floor(Args[0].DoubleVal);
|
||||||
|
return GV;
|
||||||
|
}
|
||||||
|
|
||||||
// double drand48()
|
// double drand48()
|
||||||
GenericValue lle_X_drand48(MethodType *M, const vector<GenericValue> &Args) {
|
GenericValue lle_X_drand48(MethodType *M, const vector<GenericValue> &Args) {
|
||||||
assert(Args.size() == 0);
|
assert(Args.size() == 0);
|
||||||
@@ -260,6 +276,12 @@ GenericValue lle_X_srand48(MethodType *M, const vector<GenericValue> &Args) {
|
|||||||
return GenericValue();
|
return GenericValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void srand(uint)
|
||||||
|
GenericValue lle_X_srand(MethodType *M, const vector<GenericValue> &Args) {
|
||||||
|
assert(Args.size() == 1);
|
||||||
|
srand(Args[0].UIntVal);
|
||||||
|
return GenericValue();
|
||||||
|
}
|
||||||
|
|
||||||
// int printf(sbyte *, ...) - a very rough implementation to make output useful.
|
// int printf(sbyte *, ...) - a very rough implementation to make output useful.
|
||||||
GenericValue lle_X_printf(MethodType *M, const vector<GenericValue> &Args) {
|
GenericValue lle_X_printf(MethodType *M, const vector<GenericValue> &Args) {
|
||||||
@@ -352,8 +374,11 @@ void Interpreter::initializeExternalMethods() {
|
|||||||
FuncNames["lle_X_exit"] = lle_X_exit;
|
FuncNames["lle_X_exit"] = lle_X_exit;
|
||||||
FuncNames["lle_X_malloc"] = lle_X_malloc;
|
FuncNames["lle_X_malloc"] = lle_X_malloc;
|
||||||
FuncNames["lle_X_free"] = lle_X_free;
|
FuncNames["lle_X_free"] = lle_X_free;
|
||||||
|
FuncNames["lle_X_atoi"] = lle_X_atoi;
|
||||||
FuncNames["lle_X_pow"] = lle_X_pow;
|
FuncNames["lle_X_pow"] = lle_X_pow;
|
||||||
FuncNames["lle_X_log"] = lle_X_log;
|
FuncNames["lle_X_log"] = lle_X_log;
|
||||||
|
FuncNames["lle_X_floor"] = lle_X_floor;
|
||||||
|
FuncNames["lle_X_srand"] = lle_X_srand;
|
||||||
FuncNames["lle_X_drand48"] = lle_X_drand48;
|
FuncNames["lle_X_drand48"] = lle_X_drand48;
|
||||||
FuncNames["lle_X_srand48"] = lle_X_srand48;
|
FuncNames["lle_X_srand48"] = lle_X_srand48;
|
||||||
FuncNames["lle_X_lrand48"] = lle_X_lrand48;
|
FuncNames["lle_X_lrand48"] = lle_X_lrand48;
|
||||||
|
Reference in New Issue
Block a user