diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-01-12 07:05:14 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-01-12 07:05:14 +0000 |
commit | a54b7cbd452b3adb2f51346140d996b29c2cdb30 (patch) | |
tree | 00514e24a3fab3804f1a99557ebd343382d0dc27 /lib/ExecutionEngine/Interpreter/Execution.cpp | |
parent | ed3098989580ecaee7fc89de548afb4c811bea31 (diff) |
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/Interpreter/Execution.cpp')
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 1065 |
1 files changed, 686 insertions, 379 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 0a0fbce134..681fb67b92 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include <cmath> using namespace llvm; @@ -69,20 +70,30 @@ static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, ExecutionContext &SF) { switch (CE->getOpcode()) { - case Instruction::Trunc: + case Instruction::Trunc: + return executeTruncInst(CE->getOperand(0), CE->getType(), SF); case Instruction::ZExt: + return executeZExtInst(CE->getOperand(0), CE->getType(), SF); case Instruction::SExt: + return executeSExtInst(CE->getOperand(0), CE->getType(), SF); case Instruction::FPTrunc: + return executeFPTruncInst(CE->getOperand(0), CE->getType(), SF); case Instruction::FPExt: + return executeFPExtInst(CE->getOperand(0), CE->getType(), SF); case Instruction::UIToFP: + return executeUIToFPInst(CE->getOperand(0), CE->getType(), SF); case Instruction::SIToFP: + return executeSIToFPInst(CE->getOperand(0), CE->getType(), SF); case Instruction::FPToUI: + return executeFPToUIInst(CE->getOperand(0), CE->getType(), SF); case Instruction::FPToSI: + return executeFPToSIInst(CE->getOperand(0), CE->getType(), SF); case Instruction::PtrToInt: + return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF); case Instruction::IntToPtr: + return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF); case Instruction::BitCast: - return executeCastOperation(Instruction::CastOps(CE->getOpcode()), - CE->getOperand(0), CE->getType(), SF); + return executeBitCastInst(CE->getOperand(0), CE->getType(), SF); case Instruction::GetElementPtr: return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE), gep_type_end(CE), SF); @@ -190,14 +201,69 @@ void Interpreter::initializeExecutionEngine() { #define IMPLEMENT_BINARY_OPERATOR(OP, TY) \ case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; break +#define IMPLEMENT_INTEGER_BINOP(OP, TY) \ + case Type::IntegerTyID: { \ + unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \ + if (BitWidth == 1) \ + Dest.Int1Val = Src1.Int1Val OP Src2.Int1Val; \ + else if (BitWidth <= 8) \ + Dest.Int8Val = Src1.Int8Val OP Src2.Int8Val; \ + else if (BitWidth <= 16) \ + Dest.Int16Val = Src1.Int16Val OP Src2.Int16Val; \ + else if (BitWidth <= 32) \ + Dest.Int32Val = Src1.Int32Val OP Src2.Int32Val; \ + else if (BitWidth <= 64) \ + Dest.Int64Val = Src1.Int64Val OP Src2.Int64Val; \ + else \ + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ + break; \ + } + +#define IMPLEMENT_SIGNED_BINOP(OP, TY) \ + if (const IntegerType *ITy = dyn_cast<IntegerType>(TY)) { \ + unsigned BitWidth = ITy->getBitWidth(); \ + if (BitWidth <= 8) \ + Dest.Int8Val = ((int8_t)Src1.Int8Val) OP ((int8_t)Src2.Int8Val); \ + else if (BitWidth <= 16) \ + Dest.Int16Val = ((int16_t)Src1.Int16Val) OP ((int16_t)Src2.Int16Val); \ + else if (BitWidth <= 32) \ + Dest.Int32Val = ((int32_t)Src1.Int32Val) OP ((int32_t)Src2.Int32Val); \ + else if (BitWidth <= 64) \ + Dest.Int64Val = ((int64_t)Src1.Int64Val) OP ((int64_t)Src2.Int64Val); \ + else { \ + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ + abort(); \ + } \ + } else { \ + cerr << "Unhandled type for " #OP " operator: " << *Ty << "\n"; \ + abort(); \ + } + +#define IMPLEMENT_UNSIGNED_BINOP(OP, TY) \ + if (const IntegerType *ITy = dyn_cast<IntegerType>(TY)) { \ + unsigned BitWidth = ITy->getBitWidth(); \ + if (BitWidth <= 8) \ + Dest.Int8Val = ((uint8_t)Src1.Int8Val) OP ((uint8_t)Src2.Int8Val); \ + else if (BitWidth <= 16) \ + Dest.Int16Val = ((uint16_t)Src1.Int16Val) OP ((uint16_t)Src2.Int16Val); \ + else if (BitWidth <= 32) \ + Dest.Int32Val = ((uint32_t)Src1.Int32Val) OP ((uint32_t)Src2.Int32Val); \ + else if (BitWidth <= 64) \ + Dest.Int64Val = ((uint64_t)Src1.Int64Val) OP ((uint64_t)Src2.Int64Val); \ + else { \ + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ + abort(); \ + } \ + } else { \ + cerr << "Unhandled type for " #OP " operator: " << *Ty << "\n"; \ + abort(); \ + } + static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_BINARY_OPERATOR(+, Int8); - IMPLEMENT_BINARY_OPERATOR(+, Int16); - IMPLEMENT_BINARY_OPERATOR(+, Int32); - IMPLEMENT_BINARY_OPERATOR(+, Int64); + IMPLEMENT_INTEGER_BINOP(+, Ty); IMPLEMENT_BINARY_OPERATOR(+, Float); IMPLEMENT_BINARY_OPERATOR(+, Double); default: @@ -211,10 +277,7 @@ static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_BINARY_OPERATOR(-, Int8); - IMPLEMENT_BINARY_OPERATOR(-, Int16); - IMPLEMENT_BINARY_OPERATOR(-, Int32); - IMPLEMENT_BINARY_OPERATOR(-, Int64); + IMPLEMENT_INTEGER_BINOP(-, Ty); IMPLEMENT_BINARY_OPERATOR(-, Float); IMPLEMENT_BINARY_OPERATOR(-, Double); default: @@ -228,10 +291,7 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_BINARY_OPERATOR(*, Int8); - IMPLEMENT_BINARY_OPERATOR(*, Int16); - IMPLEMENT_BINARY_OPERATOR(*, Int32); - IMPLEMENT_BINARY_OPERATOR(*, Int64); + IMPLEMENT_INTEGER_BINOP(*, Ty); IMPLEMENT_BINARY_OPERATOR(*, Float); IMPLEMENT_BINARY_OPERATOR(*, Double); default: @@ -241,37 +301,17 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, return Dest; } -#define IMPLEMENT_SIGNLESS_BINOP(OP, TY, CAST) \ - case Type::TY##TyID: Dest.TY##Val = \ - ((CAST)Src1.TY##Val) OP ((CAST)Src2.TY##Val); break - static GenericValue executeUDivInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SIGNLESS_BINOP(/, Int8, uint8_t); - IMPLEMENT_SIGNLESS_BINOP(/, Int16, uint16_t); - IMPLEMENT_SIGNLESS_BINOP(/, Int32, uint32_t); - IMPLEMENT_SIGNLESS_BINOP(/, Int64, uint64_t); - default: - cerr << "Unhandled type for UDiv instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_UNSIGNED_BINOP(/,Ty) return Dest; } static GenericValue executeSDivInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SIGNLESS_BINOP(/, Int8, int8_t); - IMPLEMENT_SIGNLESS_BINOP(/, Int16, int16_t); - IMPLEMENT_SIGNLESS_BINOP(/, Int32, int32_t); - IMPLEMENT_SIGNLESS_BINOP(/, Int64, int64_t); - default: - cerr << "Unhandled type for SDiv instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_SIGNED_BINOP(/,Ty) return Dest; } @@ -282,7 +322,7 @@ static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2, IMPLEMENT_BINARY_OPERATOR(/, Float); IMPLEMENT_BINARY_OPERATOR(/, Double); default: - cerr << "Unhandled type for Div instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FDiv instruction: " << *Ty << "\n"; abort(); } return Dest; @@ -291,30 +331,14 @@ static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2, static GenericValue executeURemInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SIGNLESS_BINOP(%, Int8, uint8_t); - IMPLEMENT_SIGNLESS_BINOP(%, Int16, uint16_t); - IMPLEMENT_SIGNLESS_BINOP(%, Int32, uint32_t); - IMPLEMENT_SIGNLESS_BINOP(%, Int64, uint64_t ); - default: - cerr << "Unhandled type for URem instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_UNSIGNED_BINOP(%, Ty) return Dest; } static GenericValue executeSRemInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SIGNLESS_BINOP(%, Int8, int8_t); - IMPLEMENT_SIGNLESS_BINOP(%, Int16, int16_t); - IMPLEMENT_SIGNLESS_BINOP(%, Int32, int32_t); - IMPLEMENT_SIGNLESS_BINOP(%, Int64, int64_t); - default: - cerr << "Unhandled type for Rem instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_SIGNED_BINOP(%, Ty) return Dest; } @@ -338,60 +362,69 @@ static GenericValue executeFRemInst(GenericValue Src1, GenericValue Src2, static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_BINARY_OPERATOR(&, Int1); - IMPLEMENT_BINARY_OPERATOR(&, Int8); - IMPLEMENT_BINARY_OPERATOR(&, Int16); - IMPLEMENT_BINARY_OPERATOR(&, Int32); - IMPLEMENT_BINARY_OPERATOR(&, Int64); - default: - cerr << "Unhandled type for And instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_UNSIGNED_BINOP(&, Ty) return Dest; } static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_BINARY_OPERATOR(|, Int1); - IMPLEMENT_BINARY_OPERATOR(|, Int8); - IMPLEMENT_BINARY_OPERATOR(|, Int16); - IMPLEMENT_BINARY_OPERATOR(|, Int32); - IMPLEMENT_BINARY_OPERATOR(|, Int64); - default: - cerr << "Unhandled type for Or instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_UNSIGNED_BINOP(|, Ty) return Dest; } static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_BINARY_OPERATOR(^, Int1); - IMPLEMENT_BINARY_OPERATOR(^, Int8); - IMPLEMENT_BINARY_OPERATOR(^, Int16); - IMPLEMENT_BINARY_OPERATOR(^, Int32); - IMPLEMENT_BINARY_OPERATOR(^, Int64); - default: - cerr << "Unhandled type for Xor instruction: " << *Ty << "\n"; - abort(); - } + IMPLEMENT_UNSIGNED_BINOP(^, Ty) return Dest; } -#define IMPLEMENT_ICMP(OP, TY, CAST) \ - case Type::TY##TyID: Dest.Int1Val = \ - ((CAST)Src1.TY##Val) OP ((CAST)Src2.TY##Val); break +#define IMPLEMENT_SIGNED_ICMP(OP, TY) \ + case Type::IntegerTyID: { \ + unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \ + if (BitWidth == 1) \ + Dest.Int1Val = ((int8_t)Src1.Int1Val) OP ((int8_t)Src2.Int1Val); \ + else if (BitWidth <= 8) \ + Dest.Int1Val = ((int8_t)Src1.Int8Val) OP ((int8_t)Src2.Int8Val); \ + else if (BitWidth <= 16) \ + Dest.Int1Val = ((int16_t)Src1.Int16Val) OP ((int16_t)Src2.Int16Val); \ + else if (BitWidth <= 32) \ + Dest.Int1Val = ((int32_t)Src1.Int32Val) OP ((int32_t)Src2.Int32Val); \ + else if (BitWidth <= 64) \ + Dest.Int1Val = ((int64_t)Src1.Int64Val) OP ((int64_t)Src2.Int64Val); \ + else { \ + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ + abort(); \ + } \ + break; \ + } + +#define IMPLEMENT_UNSIGNED_ICMP(OP, TY) \ + case Type::IntegerTyID: { \ + unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \ + if (BitWidth == 1) \ + Dest.Int1Val = ((uint8_t)Src1.Int1Val) OP ((uint8_t)Src2.Int1Val); \ + else if (BitWidth <= 8) \ + Dest.Int1Val = ((uint8_t)Src1.Int8Val) OP ((uint8_t)Src2.Int8Val); \ + else if (BitWidth <= 16) \ + Dest.Int1Val = ((uint16_t)Src1.Int16Val) OP ((uint16_t)Src2.Int16Val); \ + else if (BitWidth <= 32) \ + Dest.Int1Val = ((uint32_t)Src1.Int32Val) OP ((uint32_t)Src2.Int32Val); \ + else if (BitWidth <= 64) \ + Dest.Int1Val = ((uint64_t)Src1.Int64Val) OP ((uint64_t)Src2.Int64Val); \ + else { \ + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ + abort(); \ + } \ + break; \ + } // Handle pointers specially because they must be compared with only as much // width as the host has. We _do not_ want to be comparing 64 bit values when // running on a 32-bit target, otherwise the upper 32 bits might mess up // comparisons if they contain garbage. -#define IMPLEMENT_POINTERCMP(OP) \ +#define IMPLEMENT_POINTER_ICMP(OP) \ case Type::PointerTyID: \ Dest.Int1Val = (void*)(intptr_t)Src1.PointerVal OP \ (void*)(intptr_t)Src2.PointerVal; break @@ -400,11 +433,8 @@ static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(==, Int8, uint8_t); - IMPLEMENT_ICMP(==, Int16, uint16_t); - IMPLEMENT_ICMP(==, Int32, uint32_t); - IMPLEMENT_ICMP(==, Int64, uint64_t); - IMPLEMENT_POINTERCMP(==); + IMPLEMENT_UNSIGNED_ICMP(==, Ty); + IMPLEMENT_POINTER_ICMP(==); default: cerr << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n"; abort(); @@ -416,11 +446,8 @@ static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(!=, Int8, uint8_t); - IMPLEMENT_ICMP(!=, Int16, uint16_t); - IMPLEMENT_ICMP(!=, Int32, uint32_t); - IMPLEMENT_ICMP(!=, Int64, uint64_t); - IMPLEMENT_POINTERCMP(!=); + IMPLEMENT_UNSIGNED_ICMP(!=, Ty); + IMPLEMENT_POINTER_ICMP(!=); default: cerr << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n"; abort(); @@ -432,11 +459,8 @@ static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(<, Int8, uint8_t); - IMPLEMENT_ICMP(<, Int16, uint16_t); - IMPLEMENT_ICMP(<, Int32, uint32_t); - IMPLEMENT_ICMP(<, Int64, uint64_t); - IMPLEMENT_POINTERCMP(<); + IMPLEMENT_UNSIGNED_ICMP(<, Ty); + IMPLEMENT_POINTER_ICMP(<); default: cerr << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n"; abort(); @@ -448,11 +472,8 @@ static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(<, Int8, int8_t); - IMPLEMENT_ICMP(<, Int16, int16_t); - IMPLEMENT_ICMP(<, Int32, int32_t); - IMPLEMENT_ICMP(<, Int64, int64_t); - IMPLEMENT_POINTERCMP(<); + IMPLEMENT_SIGNED_ICMP(<, Ty); + IMPLEMENT_POINTER_ICMP(<); default: cerr << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n"; abort(); @@ -464,11 +485,8 @@ static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(>, Int8, uint8_t); - IMPLEMENT_ICMP(>, Int16, uint16_t); - IMPLEMENT_ICMP(>, Int32, uint32_t); - IMPLEMENT_ICMP(>, Int64, uint64_t); - IMPLEMENT_POINTERCMP(>); + IMPLEMENT_UNSIGNED_ICMP(>, Ty); + IMPLEMENT_POINTER_ICMP(>); default: cerr << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n"; abort(); @@ -480,11 +498,8 @@ static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(>, Int8, int8_t); - IMPLEMENT_ICMP(>, Int16, int16_t); - IMPLEMENT_ICMP(>, Int32, int32_t); - IMPLEMENT_ICMP(>, Int64, int64_t); - IMPLEMENT_POINTERCMP(>); + IMPLEMENT_SIGNED_ICMP(>, Ty); + IMPLEMENT_POINTER_ICMP(>); default: cerr << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n"; abort(); @@ -496,11 +511,8 @@ static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(<=, Int8, uint8_t); - IMPLEMENT_ICMP(<=, Int16, uint16_t); - IMPLEMENT_ICMP(<=, Int32, uint32_t); - IMPLEMENT_ICMP(<=, Int64, uint64_t); - IMPLEMENT_POINTERCMP(<=); + IMPLEMENT_UNSIGNED_ICMP(<=, Ty); + IMPLEMENT_POINTER_ICMP(<=); default: cerr << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n"; abort(); @@ -512,11 +524,8 @@ static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(<=, Int8, int8_t); - IMPLEMENT_ICMP(<=, Int16, int16_t); - IMPLEMENT_ICMP(<=, Int32, int32_t); - IMPLEMENT_ICMP(<=, Int64, int64_t); - IMPLEMENT_POINTERCMP(<=); + IMPLEMENT_SIGNED_ICMP(<=, Ty); + IMPLEMENT_POINTER_ICMP(<=); default: cerr << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n"; abort(); @@ -528,11 +537,8 @@ static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(>=, Int8, uint8_t); - IMPLEMENT_ICMP(>=, Int16, uint16_t); - IMPLEMENT_ICMP(>=, Int32, uint32_t); - IMPLEMENT_ICMP(>=, Int64, uint64_t); - IMPLEMENT_POINTERCMP(>=); + IMPLEMENT_UNSIGNED_ICMP(>=,Ty); + IMPLEMENT_POINTER_ICMP(>=); default: cerr << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n"; abort(); @@ -544,11 +550,8 @@ static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { - IMPLEMENT_ICMP(>=, Int8, int8_t); - IMPLEMENT_ICMP(>=, Int16, int16_t); - IMPLEMENT_ICMP(>=, Int32, int32_t); - IMPLEMENT_ICMP(>=, Int64, int64_t); - IMPLEMENT_POINTERCMP(>=); + IMPLEMENT_SIGNED_ICMP(>=, Ty); + IMPLEMENT_POINTER_ICMP(>=); default: cerr << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n"; abort(); @@ -564,8 +567,8 @@ void Interpreter::visitICmpInst(ICmpInst &I) { GenericValue R; // Result switch (I.getPredicate()) { - case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break; - case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break; + case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break; + case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break; case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break; case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break; case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break; @@ -585,20 +588,20 @@ void Interpreter::visitICmpInst(ICmpInst &I) { #define IMPLEMENT_FCMP(OP, TY) \ case Type::TY##TyID: Dest.Int1Val = Src1.TY##Val OP Src2.TY##Val; break -static GenericValue executeFCMP_EQ(GenericValue Src1, GenericValue Src2, +static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(==, Float); IMPLEMENT_FCMP(==, Double); default: - cerr << "Unhandled type for SetEQ instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n"; abort(); } return Dest; } -static GenericValue executeFCMP_NE(GenericValue Src1, GenericValue Src2, +static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { @@ -606,64 +609,142 @@ static GenericValue executeFCMP_NE(GenericValue Src1, GenericValue Src2, IMPLEMENT_FCMP(!=, Double); default: - cerr << "Unhandled type for SetNE instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FCmp NE instruction: " << *Ty << "\n"; abort(); } return Dest; } -static GenericValue executeFCMP_LE(GenericValue Src1, GenericValue Src2, +static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(<=, Float); IMPLEMENT_FCMP(<=, Double); default: - cerr << "Unhandled type for SetLE instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FCmp LE instruction: " << *Ty << "\n"; abort(); } return Dest; } -static GenericValue executeFCMP_GE(GenericValue Src1, GenericValue Src2, +static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(>=, Float); IMPLEMENT_FCMP(>=, Double); default: - cerr << "Unhandled type for SetGE instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FCmp GE instruction: " << *Ty << "\n"; abort(); } return Dest; } -static GenericValue executeFCMP_LT(GenericValue Src1, GenericValue Src2, +static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(<, Float); IMPLEMENT_FCMP(<, Double); default: - cerr << "Unhandled type for SetLT instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FCmp LT instruction: " << *Ty << "\n"; abort(); } return Dest; } -static GenericValue executeFCMP_GT(GenericValue Src1, GenericValue Src2, +static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(>, Float); IMPLEMENT_FCMP(>, Double); default: - cerr << "Unhandled type for SetGT instruction: " << *Ty << "\n"; + cerr << "Unhandled type for FCmp GT instruction: " << *Ty << "\n"; abort(); } return Dest; } +#define IMPLEMENT_UNORDERED(TY, X,Y) \ + if (TY == Type::FloatTy) \ + if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \ + Dest.Int1Val = true; \ + return Dest; \ + } \ + else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \ + Dest.Int1Val = true; \ + return Dest; \ + } + + +static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + IMPLEMENT_UNORDERED(Ty, Src1, Src2) + return executeFCMP_OEQ(Src1, Src2, Ty); +} + +static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + IMPLEMENT_UNORDERED(Ty, Src1, Src2) + return executeFCMP_ONE(Src1, Src2, Ty); +} + +static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + IMPLEMENT_UNORDERED(Ty, Src1, Src2) + return executeFCMP_OLE(Src1, Src2, Ty); +} + +static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + IMPLEMENT_UNORDERED(Ty, Src1, Src2) + return executeFCMP_OGE(Src1, Src2, Ty); +} + +static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + IMPLEMENT_UNORDERED(Ty, Src1, Src2) + return executeFCMP_OLT(Src1, Src2, Ty); +} + +static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + IMPLEMENT_UNORDERED(Ty, Src1, Src2) + return executeFCMP_OGT(Src1, Src2, Ty); +} + +static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + if (Ty == Type::FloatTy) + Dest.Int1Val = (Src1.FloatVal == Src1.FloatVal && + Src2.FloatVal == Src2.FloatVal); + else + Dest.Int1Val = (Src1.DoubleVal == Src1.DoubleVal && + Src2.DoubleVal == Src2.DoubleVal); + return Dest; +} + +static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2, + const Type *Ty) { + GenericValue Dest; + if (Ty == Type::FloatTy) + Dest.Int1Val = (Src1.FloatVal != Src1.FloatVal || + Src2.FloatVal != Src2.FloatVal); + else + Dest.Int1Val = (Src1.DoubleVal != Src1.DoubleVal || + Src2.DoubleVal != Src2.DoubleVal); + return Dest; +} + void Interpreter::visitFCmpInst(FCmpInst &I) { ExecutionContext &SF = ECStack.back(); const Type *Ty = I.getOperand(0)->getType(); @@ -672,22 +753,22 @@ void Interpreter::visitFCmpInst(FCmpInst &I) { GenericValue R; // Result switch (I.getPredicate()) { - case FCmpInst::FCMP_FALSE: R.Int1Val = false; - case FCmpInst::FCMP_ORD: R = executeFCMP_EQ(Src1, Src2, Ty); break; ///??? - case FCmpInst::FCMP_UNO: R = executeFCMP_NE(Src1, Src2, Ty); break; ///??? - case FCmpInst::FCMP_OEQ: - case FCmpInst::FCMP_UEQ: R = executeFCMP_EQ(Src1, Src2, Ty); break; - case FCmpInst::FCMP_ONE: - case FCmpInst::FCMP_UNE: R = executeFCMP_NE(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OLT: - case FCmpInst::FCMP_ULT: R = executeFCMP_LT(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OGT: - case FCmpInst::FCMP_UGT: R = executeFCMP_GT(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OLE: - case FCmpInst::FCMP_ULE: R = executeFCMP_LE(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OGE: - case FCmpInst::FCMP_UGE: R = executeFCMP_GE(Src1, Src2, Ty); break; - case FCmpInst::FCMP_TRUE: R.Int1Val = true; + case FCmpInst::FCMP_FALSE: R.Int1Val = false; break; + case FCmpInst::FCMP_TRUE: R.Int1Val = true; break; + case FCmpInst::FCMP_ORD: R = executeFCMP_ORD(Src1, Src2, Ty); break; + case FCmpInst::FCMP_UNO: R = executeFCMP_UNO(Src1, Src2, Ty); break; + case FCmpInst::FCMP_UEQ: R = executeFCMP_UEQ(Src1, Src2, Ty); break; + case FCmpInst::FCMP_OEQ: R = executeFCMP_OEQ(Src1, Src2, Ty); break; + case FCmpInst::FCMP_UNE: R = executeFCMP_UNE(Src1, Src2, Ty); break; + case FCmpInst::FCMP_ONE: R = executeFCMP_ONE(Src1, Src2, Ty); break; + case FCmpInst::FCMP_ULT: R = executeFCMP_ULT(Src1, Src2, Ty); break; + case FCmpInst::FCMP_OLT: R = executeFCMP_OLT(Src1, Src2, Ty); break; + case FCmpInst::FCMP_UGT: R = executeFCMP_UGT(Src1, Src2, Ty); break; + case FCmpInst::FCMP_OGT: R = executeFCMP_OGT(Src1, Src2, Ty); break; + case FCmpInst::FCMP_ULE: R = executeFCMP_ULE(Src1, Src2, Ty); break; + case FCmpInst::FCMP_OLE: R = executeFCMP_OLE(Src1, Src2, Ty); break; + case FCmpInst::FCMP_UGE: R = executeFCMP_UGE(Src1, Src2, Ty); break; + case FCmpInst::FCMP_OGE: R = executeFCMP_OGE(Src1, Src2, Ty); break; default: cerr << "Don't know how to handle this FCmp predicate!\n-->" << I; abort(); @@ -710,20 +791,20 @@ static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1, case ICmpInst::ICMP_SGE: return executeICMP_SGE(Src1, Src2, Ty); case ICmpInst::ICMP_ULE: return executeICMP_ULE(Src1, Src2, Ty); case ICmpInst::ICMP_SLE: return executeICMP_SLE(Src1, Src2, Ty); - case FCmpInst::FCMP_ORD: return executeFCMP_EQ(Src1, Src2, Ty); break; - case FCmpInst::FCMP_UNO: return executeFCMP_NE(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OEQ: - case FCmpInst::FCMP_UEQ: return executeFCMP_EQ(Src1, Src2, Ty); break; - case FCmpInst::FCMP_ONE: - case FCmpInst::FCMP_UNE: return executeFCMP_NE(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OLT: - case FCmpInst::FCMP_ULT: return executeFCMP_LT(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OGT: - case FCmpInst::FCMP_UGT: return executeFCMP_GT(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OLE: - case FCmpInst::FCMP_ULE: return executeFCMP_LE(Src1, Src2, Ty); break; - case FCmpInst::FCMP_OGE: - case FCmpInst::FCMP_UGE: return executeFCMP_GE(Src1, Src2, Ty); break; + case FCmpInst::FCMP_ORD: return executeFCMP_ORD(Src1, Src2, Ty); + case FCmpInst::FCMP_UNO: return executeFCMP_UNO(Src1, Src2, Ty); + case FCmpInst::FCMP_OEQ: return executeFCMP_OEQ(Src1, Src2, Ty); + case FCmpInst::FCMP_UEQ: return executeFCMP_UEQ(Src1, Src2, Ty); + case FCmpInst::FCMP_ONE: return executeFCMP_ONE(Src1, Src2, Ty); + case FCmpInst::FCMP_UNE: return executeFCMP_UNE(Src1, Src2, Ty); + case FCmpInst::FCMP_OLT: return executeFCMP_OLT(Src1, Src2, Ty); + case FCmpInst::FCMP_ULT: return executeFCMP_ULT(Src1, Src2, Ty); + case FCmpInst::FCMP_OGT: return executeFCMP_OGT(Src1, Src2, Ty); + case FCmpInst::FCMP_UGT: return executeFCMP_UGT(Src1, Src2, Ty); + case FCmpInst::FCMP_OLE: return executeFCMP_OLE(Src1, Src2, Ty); + case FCmpInst::FCMP_ULE: return executeFCMP_ULE(Src1, Src2, Ty); + case FCmpInst::FCMP_OGE: return executeFCMP_OGE(Src1, Src2, Ty); + case FCmpInst::FCMP_UGE: return executeFCMP_UGE(Src1, Src2, Ty); case FCmpInst::FCMP_FALSE: { GenericValue Result; Result.Int1Val = false; @@ -989,14 +1070,19 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, // Get the index number for the array... which must be long type... GenericValue IdxGV = getOperandValue(I.getOperand(), SF); - uint64_t Idx; - switch (I.getOperand()->getType()->getTypeID()) { - default: assert(0 && "Illegal getelementptr index for sequential type!"); - case Type::Int8TyID: Idx = IdxGV.Int8Val; break; - case Type::Int16TyID: Idx = IdxGV.Int16Val; break; - case Type::Int32TyID: Idx = IdxGV.Int32Val; break; - case Type::Int64TyID: Idx = IdxGV.Int64Val; break; - } + int64_t Idx; + unsigned BitWidth = + cast<IntegerType>(I.getOperand()->getType())->getBitWidth(); + if (BitWidth <= 8) + Idx = (int64_t)(int8_t)IdxGV.Int8Val; + else if (BitWidth <= 16) + Idx = (int64_t)(int16_t)IdxGV.Int16Val; + else if (BitWidth <= 32) + Idx = (int64_t)(int32_t)IdxGV.Int32Val; + else if (BitWidth <= 64) + Idx = (int64_t)IdxGV.Int64Val; + else + assert(0 && "Integer types >64 bits not supported"); Total += PointerTy(TD.getTypeSize(ST->getElementType())*Idx); } } @@ -1084,15 +1170,13 @@ void Interpreter::visitCallSite(CallSite CS) { // this by zero or sign extending the value as appropriate according to the // source type. const Type *Ty = V->getType(); - if (Ty->isIntegral() && Ty->getPrimitiveSize() < 4) { - if (Ty == Type::Int16Ty) - ArgVals.back().Int32Val = ArgVals.back().Int16Val; - else if (Ty == Type::Int8Ty) - ArgVals.back().Int32Val = ArgVals.back().Int8Val; - else if (Ty == Type::Int1Ty) + if (Ty->isIntegral()) { + if (Ty->getPrimitiveSizeInBits() == 1) ArgVals.back().Int32Val = ArgVals.back().Int1Val; - else - assert(0 && "Unknown type!"); + else if (Ty->getPrimitiveSizeInBits() <= 8) + ArgVals.back().Int32Val = ArgVals.back().Int8Val; + else if (Ty->getPrimitiveSizeInBits() <= 16) + ArgVals.back().Int32Val = ArgVals.back().Int16Val; } } @@ -1102,23 +1186,26 @@ void Interpreter::visitCallSite(CallSite CS) { callFunction((Function*)GVTOP(SRC), ArgVals); } -#define IMPLEMENT_SHIFT(OP, TY) \ - case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.Int8Val; break - -#define IMPLEMENT_SIGNLESS_SHIFT(OP, TY, CAST) \ - case Type::TY##TyID: Dest.TY##Val = ((CAST)Src1.TY##Val) OP Src2.Int8Val; \ - break - static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SHIFT(<<, Int8); - IMPLEMENT_SHIFT(<<, Int16); - IMPLEMENT_SHIFT(<<, Int32); - IMPLEMENT_SHIFT(<<, Int64); - default: + if (const IntegerType *ITy = cast<IntegerType>(Ty)) { + unsigned BitWidth = ITy->getBitWidth(); + if (BitWidth <= 8) + Dest.Int8Val = ((uint8_t)Src1.Int8Val) << ((uint32_t)Src2.Int8Val); + else if (BitWidth <= 16) + Dest.Int16Val = ((uint16_t)Src1.Int16Val) << ((uint32_t)Src2.Int8Val); + else if (BitWidth <= 32) + Dest.Int32Val = ((uint32_t)Src1.Int32Val) << ((uint32_t)Src2.Int8Val); + else if (BitWidth <= 64) + Dest.Int64Val = ((uint64_t)Src1.Int64Val) << ((uint32_t)Src2.Int8Val); + else { + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; + abort(); + } + } else { cerr << "Unhandled type for Shl instruction: " << *Ty << "\n"; + abort(); } return Dest; } @@ -1126,12 +1213,21 @@ static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2, static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SIGNLESS_SHIFT(>>, Int8, uint8_t); - IMPLEMENT_SIGNLESS_SHIFT(>>, Int16, uint16_t); - IMPLEMENT_SIGNLESS_SHIFT(>>, Int32, uint32_t); - IMPLEMENT_SIGNLESS_SHIFT(>>, Int64, uint64_t); - default: + if (const IntegerType *ITy = cast<IntegerType>(Ty)) { + unsigned BitWidth = ITy->getBitWidth(); + if (BitWidth <= 8) + Dest.Int8Val = ((uint8_t)Src1.Int8Val) >> ((uint32_t)Src2.Int8Val); + else if (BitWidth <= 16) + Dest.Int16Val = ((uint16_t)Src1.Int16Val) >> ((uint32_t)Src2.Int8Val); + else if (BitWidth <= 32) + Dest.Int32Val = ((uint32_t)Src1.Int32Val) >> ((uint32_t)Src2.Int8Val); + else if (BitWidth <= 64) + Dest.Int64Val = ((uint64_t)Src1.Int64Val) >> ((uint32_t)Src2.Int8Val); + else { + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; + abort(); + } + } else { cerr << "Unhandled type for LShr instruction: " << *Ty << "\n"; abort(); } @@ -1141,12 +1237,21 @@ static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2, static GenericValue executeAShrInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; - switch (Ty->getTypeID()) { - IMPLEMENT_SIGNLESS_SHIFT(>>, Int8, int8_t); - IMPLEMENT_SIGNLESS_SHIFT(>>, Int16, int16_t); - IMPLEMENT_SIGNLESS_SHIFT(>>, Int32, int32_t); - IMPLEMENT_SIGNLESS_SHIFT(>>, Int64, int64_t); - default: + if (const IntegerType *ITy = cast<IntegerType>(Ty)) { + unsigned BitWidth = ITy->getBitWidth(); + if (BitWidth <= 8) + Dest.Int8Val = ((int8_t)Src1.Int8Val) >> ((int32_t)Src2.Int8Val); + else if (BitWidth <= 16) + Dest.Int16Val = ((int16_t)Src1.Int16Val) >> ((int32_t)Src2.Int8Val); + else if (BitWidth <= 32) + Dest.Int32Val = ((int32_t)Src1.Int32Val) >> ((int32_t)Src2.Int8Val); + else if (BitWidth <= 64) + Dest.Int64Val = ((int64_t)Src1.Int64Val) >> ((int32_t)Src2.Int8Val); + else { + cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ + abort(); + } + } else |