mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
* Make pointer values work better by treating them uniformly as 64 bit values.
This causes code that is generated by gcc to work better. * Implement mul & div * Export malloc, free, and pow * add strtol, atoi, and atol to the runtime library llvm-svn: 988
This commit is contained in:
parent
de2726ed00
commit
9def26ab6b
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -29,7 +29,7 @@ union GenericValue {
|
||||
int64_t LongVal;
|
||||
double DoubleVal;
|
||||
float FloatVal;
|
||||
GenericValue *PointerVal;
|
||||
uint64_t PointerVal;
|
||||
};
|
||||
|
||||
typedef vector<GenericValue> ValuePlaneTy;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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...
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user