diff options
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 100 | ||||
-rw-r--r-- | lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp | 22 | ||||
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Interpreter.h | 2 | ||||
-rw-r--r-- | lib/ExecutionEngine/Interpreter/UserInput.cpp | 2 | ||||
-rw-r--r-- | lib/ExecutionEngine/Makefile | 1 | ||||
-rw-r--r-- | tools/lli/Makefile | 1 | ||||
-rw-r--r-- | tools/lli/RuntimeLib.lc | 125 |
7 files changed, 216 insertions, 37 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 1f2d6f132d..a7ded5b705 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -51,7 +51,7 @@ static GenericValue getOperandValue(Value *V, ExecutionContext &SF) { GET_CONST_VAL(Double , ConstPoolFP); case Type::PointerTyID: if (isa<ConstPoolPointerNull>(CPV)) { - Result.PointerVal = 0; + Result.ULongVal = 0; } else if (ConstPoolPointerRef *CPR =dyn_cast<ConstPoolPointerRef>(CPV)) { assert(0 && "Not implemented!"); } else { @@ -66,7 +66,7 @@ static GenericValue getOperandValue(Value *V, ExecutionContext &SF) { GlobalAddress *Address = (GlobalAddress*)GV->getOrCreateAnnotation(GlobalAddressAID); GenericValue Result; - Result.PointerVal = (GenericValue*)Address->Ptr; + Result.ULongVal = (uint64_t)(GenericValue*)Address->Ptr; return Result; } else { unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value @@ -218,9 +218,6 @@ Annotation *GlobalAddress::Create(AnnotationID AID, const Annotable *O, void *){ #define IMPLEMENT_BINARY_OPERATOR(OP, TY) \ case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; break -#define IMPLEMENT_BINARY_PTR_OPERATOR(OP) \ - case Type::PointerTyID: Dest.PointerVal = \ - (GenericValue*)((unsigned long)Src1.PointerVal OP (unsigned long)Src2.PointerVal); break static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, const Type *Ty, ExecutionContext &SF) { @@ -236,7 +233,7 @@ static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, IMPLEMENT_BINARY_OPERATOR(+, Long); IMPLEMENT_BINARY_OPERATOR(+, Float); IMPLEMENT_BINARY_OPERATOR(+, Double); - IMPLEMENT_BINARY_PTR_OPERATOR(+); + IMPLEMENT_BINARY_OPERATOR(+, Pointer); default: cout << "Unhandled type for Add instruction: " << Ty << endl; } @@ -257,13 +254,55 @@ static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, IMPLEMENT_BINARY_OPERATOR(-, Long); IMPLEMENT_BINARY_OPERATOR(-, Float); IMPLEMENT_BINARY_OPERATOR(-, Double); - IMPLEMENT_BINARY_PTR_OPERATOR(-); + IMPLEMENT_BINARY_OPERATOR(-, Pointer); default: cout << "Unhandled type for Sub instruction: " << Ty << endl; } return Dest; } +static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, + const Type *Ty, ExecutionContext &SF) { + GenericValue Dest; + switch (Ty->getPrimitiveID()) { + IMPLEMENT_BINARY_OPERATOR(*, UByte); + IMPLEMENT_BINARY_OPERATOR(*, SByte); + IMPLEMENT_BINARY_OPERATOR(*, UShort); + IMPLEMENT_BINARY_OPERATOR(*, Short); + IMPLEMENT_BINARY_OPERATOR(*, UInt); + IMPLEMENT_BINARY_OPERATOR(*, Int); + IMPLEMENT_BINARY_OPERATOR(*, ULong); + IMPLEMENT_BINARY_OPERATOR(*, Long); + IMPLEMENT_BINARY_OPERATOR(*, Float); + IMPLEMENT_BINARY_OPERATOR(*, Double); + IMPLEMENT_BINARY_OPERATOR(*, Pointer); + default: + cout << "Unhandled type for Mul instruction: " << Ty << endl; + } + return Dest; +} + +static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2, + const Type *Ty, ExecutionContext &SF) { + GenericValue Dest; + switch (Ty->getPrimitiveID()) { + IMPLEMENT_BINARY_OPERATOR(/, UByte); + IMPLEMENT_BINARY_OPERATOR(/, SByte); + IMPLEMENT_BINARY_OPERATOR(/, UShort); + IMPLEMENT_BINARY_OPERATOR(/, Short); + IMPLEMENT_BINARY_OPERATOR(/, UInt); + IMPLEMENT_BINARY_OPERATOR(/, Int); + IMPLEMENT_BINARY_OPERATOR(/, ULong); + IMPLEMENT_BINARY_OPERATOR(/, Long); + IMPLEMENT_BINARY_OPERATOR(/, Float); + IMPLEMENT_BINARY_OPERATOR(/, Double); + IMPLEMENT_BINARY_OPERATOR(/, Pointer); + default: + cout << "Unhandled type for Mul instruction: " << Ty << endl; + } + return Dest; +} + #define IMPLEMENT_SETCC(OP, TY) \ case Type::TY##TyID: Dest.BoolVal = Src1.TY##Val OP Src2.TY##Val; break @@ -402,6 +441,8 @@ static void executeBinaryInst(BinaryOperator *I, ExecutionContext &SF) { switch (I->getOpcode()) { case Instruction::Add: R = executeAddInst(Src1, Src2, Ty, SF); break; case Instruction::Sub: R = executeSubInst(Src1, Src2, Ty, SF); break; + case Instruction::Mul: R = executeMulInst(Src1, Src2, Ty, SF); break; + case Instruction::Div: R = executeDivInst(Src1, Src2, Ty, SF); break; case Instruction::SetEQ: R = executeSetEQInst(Src1, Src2, Ty, SF); break; case Instruction::SetNE: R = executeSetNEInst(Src1, Src2, Ty, SF); break; case Instruction::SetLE: R = executeSetLEInst(Src1, Src2, Ty, SF); break; @@ -511,8 +552,8 @@ void Interpreter::executeAllocInst(AllocationInst *I, ExecutionContext &SF) { // Allocate enough memory to hold the type... GenericValue Result; - Result.PointerVal = (GenericValue*)malloc(NumElements * TD.getTypeSize(Ty)); - assert(Result.PointerVal != 0 && "Null pointer returned by malloc!"); + Result.ULongVal = (uint64_t)malloc(NumElements * TD.getTypeSize(Ty)); + assert(Result.ULongVal != 0 && "Null pointer returned by malloc!"); SetValue(I, Result, SF); if (I->getOpcode() == Instruction::Alloca) { @@ -524,12 +565,13 @@ static void executeFreeInst(FreeInst *I, ExecutionContext &SF) { assert(I->getOperand(0)->getType()->isPointerType() && "Freeing nonptr?"); GenericValue Value = getOperandValue(I->getOperand(0), SF); // TODO: Check to make sure memory is allocated - free(Value.PointerVal); // Free memory + free((void*)Value.ULongVal); // Free memory } static void executeLoadInst(LoadInst *I, ExecutionContext &SF) { assert(I->getNumOperands() == 1 && "NI!"); - GenericValue *Ptr = getOperandValue(I->getPtrOperand(), SF).PointerVal; + GenericValue *Ptr = + (GenericValue*)getOperandValue(I->getPtrOperand(), SF).ULongVal; GenericValue Result; switch (I->getType()->getPrimitiveID()) { @@ -541,10 +583,10 @@ static void executeLoadInst(LoadInst *I, ExecutionContext &SF) { case Type::UIntTyID: case Type::IntTyID: Result.IntVal = Ptr->IntVal; break; case Type::ULongTyID: - case Type::LongTyID: Result.LongVal = Ptr->LongVal; break; + case Type::LongTyID: + case Type::PointerTyID: Result.ULongVal = Ptr->ULongVal; break; case Type::FloatTyID: Result.FloatVal = Ptr->FloatVal; break; case Type::DoubleTyID: Result.DoubleVal = Ptr->DoubleVal; break; - case Type::PointerTyID: Result.PointerVal =(GenericValue*)Ptr->LongVal; break; default: cout << "Cannot load value of type " << I->getType() << "!\n"; } @@ -553,7 +595,8 @@ static void executeLoadInst(LoadInst *I, ExecutionContext &SF) { } static void executeStoreInst(StoreInst *I, ExecutionContext &SF) { - GenericValue *Ptr = getOperandValue(I->getPtrOperand(), SF).PointerVal; + GenericValue *Ptr = + (GenericValue *)getOperandValue(I->getPtrOperand(), SF).ULongVal; GenericValue Val = getOperandValue(I->getOperand(0), SF); assert(I->getNumOperands() == 2 && "NI!"); @@ -566,10 +609,10 @@ static void executeStoreInst(StoreInst *I, ExecutionContext &SF) { case Type::UIntTyID: case Type::IntTyID: Ptr->IntVal = Val.IntVal; break; case Type::ULongTyID: - case Type::LongTyID: Ptr->LongVal = Val.LongVal; break; + case Type::LongTyID: + case Type::PointerTyID: Ptr->LongVal = Val.LongVal; break; case Type::FloatTyID: Ptr->FloatVal = Val.FloatVal; break; case Type::DoubleTyID: Ptr->DoubleVal = Val.DoubleVal; break; - case Type::PointerTyID: Ptr->PointerVal = Val.PointerVal; break; default: cout << "Cannot store value of type " << I->getType() << "!\n"; } @@ -665,10 +708,8 @@ static void executeShrInst(ShiftInst *I, ExecutionContext &SF) { IMPLEMENT_CAST(DESTTY, DESTCTY, UInt); \ IMPLEMENT_CAST(DESTTY, DESTCTY, Int); \ IMPLEMENT_CAST(DESTTY, DESTCTY, ULong); \ - IMPLEMENT_CAST(DESTTY, DESTCTY, Long); - -#define IMPLEMENT_CAST_CASE_PTR_IMP(DESTTY, DESTCTY) \ - IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer) + IMPLEMENT_CAST(DESTTY, DESTCTY, Long); \ + IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer); #define IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY) \ IMPLEMENT_CAST(DESTTY, DESTCTY, Float); \ @@ -683,17 +724,6 @@ static void executeShrInst(ShiftInst *I, ExecutionContext &SF) { #define IMPLEMENT_CAST_CASE(DESTTY, DESTCTY) \ IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY); \ IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_PTR_IMP(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_END() - -#define IMPLEMENT_CAST_CASE_FP(DESTTY, DESTCTY) \ - IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_END() - -#define IMPLEMENT_CAST_CASE_PTR(DESTTY, DESTCTY) \ - IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_PTR_IMP(DESTTY, DESTCTY); \ IMPLEMENT_CAST_CASE_END() static void executeCastInst(CastInst *I, ExecutionContext &SF) { @@ -711,9 +741,9 @@ static void executeCastInst(CastInst *I, ExecutionContext &SF) { IMPLEMENT_CAST_CASE(Int , signed int ); IMPLEMENT_CAST_CASE(ULong , uint64_t ); IMPLEMENT_CAST_CASE(Long , int64_t ); - IMPLEMENT_CAST_CASE_FP(Float , float); - IMPLEMENT_CAST_CASE_FP(Double, double); - IMPLEMENT_CAST_CASE_PTR(Pointer, GenericValue *); + IMPLEMENT_CAST_CASE(Pointer, uint64_t); + IMPLEMENT_CAST_CASE(Float , float); + IMPLEMENT_CAST_CASE(Double, double); default: cout << "Unhandled dest type for cast instruction: " << Ty << endl; } @@ -944,7 +974,7 @@ void Interpreter::printValue(const Type *Ty, GenericValue V) { case Type::ULongTyID: cout << V.ULongVal; break; case Type::FloatTyID: cout << V.FloatVal; break; case Type::DoubleTyID: cout << V.DoubleVal; break; - case Type::PointerTyID:cout << V.PointerVal; break; + case Type::PointerTyID:cout << (void*)V.ULongVal; break; default: cout << "- Don't know how to print value of this type!"; break; diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index 973cca6842..662abc2291 100644 --- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -14,6 +14,7 @@ #include <map> #include <dlfcn.h> #include <link.h> +#include <math.h> typedef GenericValue (*ExFunc)(MethodType *, const vector<GenericValue> &); static map<const Method *, ExFunc> Functions; @@ -170,4 +171,25 @@ GenericValue lle_Vi_exit(MethodType *M, const vector<GenericValue> &Args) { return GenericValue(); } +// void *malloc(uint) +GenericValue lle_PI_malloc(MethodType *M, const vector<GenericValue> &Args) { + GenericValue GV; + GV.LongVal = (uint64_t)malloc(Args[0].UIntVal); + return GV; +} + +// void free(void *) +GenericValue lle_VP_free(MethodType *M, const vector<GenericValue> &Args) { + free((void*)Args[0].LongVal); + return GenericValue(); +} + +// double pow(double, double) +GenericValue lle_DDD_pow(MethodType *M, const vector<GenericValue> &Args) { + GenericValue GV; + GV.DoubleVal = pow(GV.DoubleVal, GV.DoubleVal); + return GV; +} + + } // End extern "C" diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index 5b123466aa..16cc569ad0 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -29,7 +29,7 @@ union GenericValue { int64_t LongVal; double DoubleVal; float FloatVal; - GenericValue *PointerVal; + uint64_t PointerVal; }; typedef vector<GenericValue> ValuePlaneTy; diff --git a/lib/ExecutionEngine/Interpreter/UserInput.cpp b/lib/ExecutionEngine/Interpreter/UserInput.cpp index efe7150c13..a24b311750 100644 --- a/lib/ExecutionEngine/Interpreter/UserInput.cpp +++ b/lib/ExecutionEngine/Interpreter/UserInput.cpp @@ -263,7 +263,7 @@ bool Interpreter::callMainMethod(const string &Name, return true; } - GenericValue GV; GV.PointerVal = (GenericValue*)CreateArgv(InputArgv); + GenericValue GV; GV.PointerVal = (uint64_t)CreateArgv(InputArgv); Args.push_back(GV); } // fallthrough diff --git a/lib/ExecutionEngine/Makefile b/lib/ExecutionEngine/Makefile index 3e70896c29..0fdcf8b5dd 100644 --- a/lib/ExecutionEngine/Makefile +++ b/lib/ExecutionEngine/Makefile @@ -12,6 +12,7 @@ Debug/RuntimeLib.c: RuntimeLib.lc cp -f $< $@ Debug/RuntimeLib.o: Debug/RuntimeLib.c + @-rm $@ /home/vadve/lattner/cvs/gcc_install/bin/gcc $< -c -o $@ $(LEVEL)/tools/Debug/RuntimeLib.bc: Debug/RuntimeLib.o diff --git a/tools/lli/Makefile b/tools/lli/Makefile index 3e70896c29..0fdcf8b5dd 100644 --- a/tools/lli/Makefile +++ b/tools/lli/Makefile @@ -12,6 +12,7 @@ Debug/RuntimeLib.c: RuntimeLib.lc cp -f $< $@ Debug/RuntimeLib.o: Debug/RuntimeLib.c + @-rm $@ /home/vadve/lattner/cvs/gcc_install/bin/gcc $< -c -o $@ $(LEVEL)/tools/Debug/RuntimeLib.bc: Debug/RuntimeLib.o diff --git a/tools/lli/RuntimeLib.lc b/tools/lli/RuntimeLib.lc index 38b28bfab1..f2611a8515 100644 --- a/tools/lli/RuntimeLib.lc +++ b/tools/lli/RuntimeLib.lc @@ -6,11 +6,22 @@ // // This file is compiled by the LLVM port of GCC to get LLVM code. // +// A lot of this code is ripped gratuitously from glibc and libiberty. +// //===----------------------------------------------------------------------===// + // Prototypes for functions exported by LLI directly. void exit(int Code); int putchar(int); +void *malloc(unsigned); +void free(void *); + +#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n') +#define isdigit(x) ((x) >= '0' || (x) <= '9') +#define isupper(x) ((x) >= 'A' || (x) <= 'Z') +#define islower(x) ((x) >= 'a' || (x) <= 'z') +#define isalpha(x) (isupper(x) || islower(x)) // The puts() function writes the string pointed to by s, followed by a // NEWLINE character, to the standard output stream stdout. On success the @@ -23,3 +34,117 @@ int puts(const char *S) { return Str+1-S; } + +#ifndef ULONG_MAX +#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ +#endif + +#ifndef LONG_MAX +#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */ +#endif + +#ifndef LONG_MIN +#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */ +#endif + +/* + * Convert a string to a long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long strtol(const char *nptr, char **endptr, int base) { + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); +} + + +/* Convert a string to an int. */ +int atoi(const char *nptr) { + return (int)strtol(nptr, 0, 10); +} + +/* Convert a string to a long int. */ +long int atol(const char *nptr) { + return strtol(nptr, 0, 10); +} + + + + + + +//===----------------------------------------------------------------------===// +// libm stuff... +//===----------------------------------------------------------------------===// + |