2001-08-24 01:05:04 +08:00
|
|
|
//===-- Execution.cpp - Implement code to simulate the program ------------===//
|
2005-04-22 06:43:08 +08:00
|
|
|
//
|
2003-10-21 03:43:21 +08:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-22 06:43:08 +08:00
|
|
|
//
|
2003-10-21 03:43:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2005-04-22 06:43:08 +08:00
|
|
|
//
|
2001-08-24 01:05:04 +08:00
|
|
|
// This file contains the actual instruction interpreter.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Interpreter.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/APInt.h"
|
|
|
|
#include "llvm/ADT/Statistic.h"
|
|
|
|
#include "llvm/CodeGen/IntrinsicLowering.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Constants.h"
|
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
2014-03-04 18:40:04 +08:00
|
|
|
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Instructions.h"
|
2008-07-09 01:25:49 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2004-09-02 06:55:40 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2009-07-11 21:10:19 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2015-03-24 03:32:43 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2007-10-12 03:40:35 +08:00
|
|
|
#include <algorithm>
|
2008-02-20 19:08:44 +08:00
|
|
|
#include <cmath>
|
2003-11-26 04:44:56 +08:00
|
|
|
using namespace llvm;
|
2002-12-24 07:59:41 +08:00
|
|
|
|
2014-04-22 11:04:17 +08:00
|
|
|
#define DEBUG_TYPE "interpreter"
|
|
|
|
|
2006-12-20 06:56:53 +08:00
|
|
|
STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
|
2003-11-12 06:41:34 +08:00
|
|
|
|
2008-07-09 01:25:49 +08:00
|
|
|
static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
|
|
|
|
cl::desc("make the interpreter print every volatile load and store"));
|
|
|
|
|
2001-10-15 21:25:40 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-03-03 14:22:22 +08:00
|
|
|
// Various Helper Functions
|
2001-10-15 21:25:40 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2003-12-28 17:44:37 +08:00
|
|
|
|
2001-10-15 21:25:40 +08:00
|
|
|
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
|
2003-10-25 03:59:01 +08:00
|
|
|
SF.Values[V] = Val;
|
2001-10-15 21:25:40 +08:00
|
|
|
}
|
|
|
|
|
2001-08-24 01:05:04 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Binary Instruction Implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
|
2007-03-06 11:09:31 +08:00
|
|
|
case Type::TY##TyID: \
|
|
|
|
Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; \
|
|
|
|
break
|
2001-08-24 01:05:04 +08:00
|
|
|
|
2009-06-05 06:49:04 +08:00
|
|
|
static void executeFAddInst(GenericValue &Dest, GenericValue Src1,
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Src2, Type *Ty) {
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2001-08-24 01:05:04 +08:00
|
|
|
IMPLEMENT_BINARY_OPERATOR(+, Float);
|
|
|
|
IMPLEMENT_BINARY_OPERATOR(+, Double);
|
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FAdd instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-05 06:49:04 +08:00
|
|
|
static void executeFSubInst(GenericValue &Dest, GenericValue Src1,
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Src2, Type *Ty) {
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2001-08-24 01:05:04 +08:00
|
|
|
IMPLEMENT_BINARY_OPERATOR(-, Float);
|
|
|
|
IMPLEMENT_BINARY_OPERATOR(-, Double);
|
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FSub instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-05 06:49:04 +08:00
|
|
|
static void executeFMulInst(GenericValue &Dest, GenericValue Src1,
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Src2, Type *Ty) {
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2001-10-27 16:28:11 +08:00
|
|
|
IMPLEMENT_BINARY_OPERATOR(*, Float);
|
|
|
|
IMPLEMENT_BINARY_OPERATOR(*, Double);
|
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FMul instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-10-27 16:28:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-03 14:22:22 +08:00
|
|
|
static void executeFDivInst(GenericValue &Dest, GenericValue Src1,
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Src2, Type *Ty) {
|
2006-10-26 14:15:43 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2001-10-27 16:28:11 +08:00
|
|
|
IMPLEMENT_BINARY_OPERATOR(/, Float);
|
|
|
|
IMPLEMENT_BINARY_OPERATOR(/, Double);
|
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FDiv instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-10-31 04:27:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-03 14:22:22 +08:00
|
|
|
static void executeFRemInst(GenericValue &Dest, GenericValue Src1,
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Src2, Type *Ty) {
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2001-10-31 04:27:31 +08:00
|
|
|
case Type::FloatTyID:
|
|
|
|
Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal);
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
Dest.DoubleVal = fmod(Src1.DoubleVal, Src2.DoubleVal);
|
|
|
|
break;
|
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-10-27 16:28:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-06 11:09:31 +08:00
|
|
|
#define IMPLEMENT_INTEGER_ICMP(OP, TY) \
|
|
|
|
case Type::IntegerTyID: \
|
|
|
|
Dest.IntVal = APInt(1,Src1.IntVal.OP(Src2.IntVal)); \
|
|
|
|
break;
|
2001-08-24 01:05:04 +08:00
|
|
|
|
2013-04-27 04:19:41 +08:00
|
|
|
#define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY) \
|
|
|
|
case Type::VectorTyID: { \
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
|
|
|
|
Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \
|
|
|
|
for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++) \
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1, \
|
|
|
|
Src1.AggregateVal[_i].IntVal.OP(Src2.AggregateVal[_i].IntVal));\
|
|
|
|
} break;
|
|
|
|
|
2003-04-24 03:55:35 +08:00
|
|
|
// 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.
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
#define IMPLEMENT_POINTER_ICMP(OP) \
|
2003-04-24 03:55:35 +08:00
|
|
|
case Type::PointerTyID: \
|
2007-03-06 11:09:31 +08:00
|
|
|
Dest.IntVal = APInt(1,(void*)(intptr_t)Src1.PointerVal OP \
|
|
|
|
(void*)(intptr_t)Src2.PointerVal); \
|
|
|
|
break;
|
2003-04-24 03:55:35 +08:00
|
|
|
|
2006-12-23 14:05:41 +08:00
|
|
|
static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(eq,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(eq,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(==);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(ne,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(ne,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(!=);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(ult,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(ult,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(<);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(slt,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(slt,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(<);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(ugt,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(ugt,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(>);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(sgt,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(sgt,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(>);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(ule,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(ule,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(<=);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(sle,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(sle,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(<=);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(uge,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(uge,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(>=);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
switch (Ty->getTypeID()) {
|
2007-03-06 11:09:31 +08:00
|
|
|
IMPLEMENT_INTEGER_ICMP(sge,Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_INTEGER_ICMP(sge,Ty);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
IMPLEMENT_POINTER_ICMP(>=);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2006-12-31 13:51:36 +08:00
|
|
|
void Interpreter::visitICmpInst(ICmpInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = I.getOperand(0)->getType();
|
2006-12-31 13:51:36 +08:00
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue R; // Result
|
|
|
|
|
|
|
|
switch (I.getPredicate()) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
|
|
|
|
case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
|
2006-12-31 13:51:36 +08:00
|
|
|
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;
|
|
|
|
case ICmpInst::ICMP_SGT: R = executeICMP_SGT(Src1, Src2, Ty); break;
|
|
|
|
case ICmpInst::ICMP_ULE: R = executeICMP_ULE(Src1, Src2, Ty); break;
|
|
|
|
case ICmpInst::ICMP_SLE: R = executeICMP_SLE(Src1, Src2, Ty); break;
|
|
|
|
case ICmpInst::ICMP_UGE: R = executeICMP_UGE(Src1, Src2, Ty); break;
|
|
|
|
case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
|
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Don't know how to handle this ICmp predicate!\n-->" << I;
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-31 13:51:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SetValue(&I, R, SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define IMPLEMENT_FCMP(OP, TY) \
|
2007-03-06 11:09:31 +08:00
|
|
|
case Type::TY##TyID: \
|
|
|
|
Dest.IntVal = APInt(1,Src1.TY##Val OP Src2.TY##Val); \
|
|
|
|
break
|
2006-12-23 14:05:41 +08:00
|
|
|
|
2013-04-27 04:19:41 +08:00
|
|
|
#define IMPLEMENT_VECTOR_FCMP_T(OP, TY) \
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \
|
|
|
|
Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \
|
|
|
|
for( uint32_t _i=0;_i<Src1.AggregateVal.size();_i++) \
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1, \
|
|
|
|
Src1.AggregateVal[_i].TY##Val OP Src2.AggregateVal[_i].TY##Val);\
|
|
|
|
break;
|
|
|
|
|
|
|
|
#define IMPLEMENT_VECTOR_FCMP(OP) \
|
|
|
|
case Type::VectorTyID: \
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP_T(OP, Float); \
|
|
|
|
} else { \
|
|
|
|
IMPLEMENT_VECTOR_FCMP_T(OP, Double); \
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Dest;
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2006-12-31 13:51:36 +08:00
|
|
|
IMPLEMENT_FCMP(==, Float);
|
|
|
|
IMPLEMENT_FCMP(==, Double);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP(==);
|
2001-08-24 01:05:04 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2013-04-27 04:19:41 +08:00
|
|
|
#define IMPLEMENT_SCALAR_NANS(TY, X,Y) \
|
|
|
|
if (TY->isFloatTy()) { \
|
|
|
|
if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
|
|
|
|
Dest.IntVal = APInt(1,false); \
|
|
|
|
return Dest; \
|
|
|
|
} \
|
|
|
|
} else { \
|
|
|
|
if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
|
|
|
|
Dest.IntVal = APInt(1,false); \
|
|
|
|
return Dest; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MASK_VECTOR_NANS_T(X,Y, TZ, FLAG) \
|
|
|
|
assert(X.AggregateVal.size() == Y.AggregateVal.size()); \
|
|
|
|
Dest.AggregateVal.resize( X.AggregateVal.size() ); \
|
|
|
|
for( uint32_t _i=0;_i<X.AggregateVal.size();_i++) { \
|
|
|
|
if (X.AggregateVal[_i].TZ##Val != X.AggregateVal[_i].TZ##Val || \
|
|
|
|
Y.AggregateVal[_i].TZ##Val != Y.AggregateVal[_i].TZ##Val) \
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,FLAG); \
|
|
|
|
else { \
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,!FLAG); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MASK_VECTOR_NANS(TY, X,Y, FLAG) \
|
|
|
|
if (TY->isVectorTy()) { \
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS_T(X, Y, Float, FLAG) \
|
|
|
|
} else { \
|
|
|
|
MASK_VECTOR_NANS_T(X, Y, Double, FLAG) \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2,
|
2013-04-27 04:19:41 +08:00
|
|
|
Type *Ty)
|
|
|
|
{
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Dest;
|
2013-04-27 04:19:41 +08:00
|
|
|
// if input is scalar value and Src1 or Src2 is NaN return false
|
|
|
|
IMPLEMENT_SCALAR_NANS(Ty, Src1, Src2)
|
|
|
|
// if vector input detect NaNs and fill mask
|
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, false)
|
|
|
|
GenericValue DestMask = Dest;
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2006-12-31 13:51:36 +08:00
|
|
|
IMPLEMENT_FCMP(!=, Float);
|
|
|
|
IMPLEMENT_FCMP(!=, Double);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP(!=);
|
|
|
|
default:
|
|
|
|
dbgs() << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2013-04-13 06:02:26 +08:00
|
|
|
}
|
2013-04-27 04:19:41 +08:00
|
|
|
// in vector case mask out NaN elements
|
|
|
|
if (Ty->isVectorTy())
|
|
|
|
for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
|
|
|
|
if (DestMask.AggregateVal[_i].IntVal == false)
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,false);
|
|
|
|
|
2001-08-24 01:05:04 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Dest;
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2006-12-31 13:51:36 +08:00
|
|
|
IMPLEMENT_FCMP(<=, Float);
|
|
|
|
IMPLEMENT_FCMP(<=, Double);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP(<=);
|
2001-08-24 01:05:04 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Dest;
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2006-12-31 13:51:36 +08:00
|
|
|
IMPLEMENT_FCMP(>=, Float);
|
|
|
|
IMPLEMENT_FCMP(>=, Double);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP(>=);
|
2001-08-24 01:05:04 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Dest;
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2006-12-31 13:51:36 +08:00
|
|
|
IMPLEMENT_FCMP(<, Float);
|
|
|
|
IMPLEMENT_FCMP(<, Double);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP(<);
|
2001-08-24 01:05:04 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Dest;
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2006-12-31 13:51:36 +08:00
|
|
|
IMPLEMENT_FCMP(>, Float);
|
|
|
|
IMPLEMENT_FCMP(>, Double);
|
2013-04-27 04:19:41 +08:00
|
|
|
IMPLEMENT_VECTOR_FCMP(>);
|
2001-08-24 01:05:04 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2008-02-20 19:10:28 +08:00
|
|
|
#define IMPLEMENT_UNORDERED(TY, X,Y) \
|
2009-10-05 13:54:46 +08:00
|
|
|
if (TY->isFloatTy()) { \
|
2008-02-20 19:10:28 +08:00
|
|
|
if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
|
|
|
|
Dest.IntVal = APInt(1,true); \
|
|
|
|
return Dest; \
|
|
|
|
} \
|
|
|
|
} else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
|
|
|
|
Dest.IntVal = APInt(1,true); \
|
|
|
|
return Dest; \
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
|
2015-03-17 02:06:57 +08:00
|
|
|
#define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC) \
|
|
|
|
if (TY->isVectorTy()) { \
|
|
|
|
GenericValue DestMask = Dest; \
|
|
|
|
Dest = FUNC(Src1, Src2, Ty); \
|
|
|
|
for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
|
|
|
|
if (DestMask.AggregateVal[_i].IntVal == true) \
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1, true); \
|
|
|
|
return Dest; \
|
2013-04-27 04:19:41 +08:00
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
|
|
|
|
static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
IMPLEMENT_UNORDERED(Ty, Src1, Src2)
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, true)
|
|
|
|
IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OEQ)
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return executeFCMP_OEQ(Src1, Src2, Ty);
|
2013-04-27 04:19:41 +08:00
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
IMPLEMENT_UNORDERED(Ty, Src1, Src2)
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, true)
|
|
|
|
IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_ONE)
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return executeFCMP_ONE(Src1, Src2, Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
IMPLEMENT_UNORDERED(Ty, Src1, Src2)
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, true)
|
|
|
|
IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLE)
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return executeFCMP_OLE(Src1, Src2, Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
IMPLEMENT_UNORDERED(Ty, Src1, Src2)
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, true)
|
|
|
|
IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGE)
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return executeFCMP_OGE(Src1, Src2, Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
IMPLEMENT_UNORDERED(Ty, Src1, Src2)
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, true)
|
|
|
|
IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OLT)
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return executeFCMP_OLT(Src1, Src2, Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
IMPLEMENT_UNORDERED(Ty, Src1, Src2)
|
2013-04-27 04:19:41 +08:00
|
|
|
MASK_VECTOR_NANS(Ty, Src1, Src2, true)
|
|
|
|
IMPLEMENT_VECTOR_UNORDERED(Ty, Src1, Src2, executeFCMP_OGT)
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return executeFCMP_OGT(Src1, Src2, Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
2013-04-27 04:19:41 +08:00
|
|
|
if(Ty->isVectorTy()) {
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
|
|
|
|
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
|
2013-04-27 04:19:41 +08:00
|
|
|
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,
|
|
|
|
( (Src1.AggregateVal[_i].FloatVal ==
|
|
|
|
Src1.AggregateVal[_i].FloatVal) &&
|
|
|
|
(Src2.AggregateVal[_i].FloatVal ==
|
|
|
|
Src2.AggregateVal[_i].FloatVal)));
|
|
|
|
} else {
|
|
|
|
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,
|
|
|
|
( (Src1.AggregateVal[_i].DoubleVal ==
|
|
|
|
Src1.AggregateVal[_i].DoubleVal) &&
|
|
|
|
(Src2.AggregateVal[_i].DoubleVal ==
|
|
|
|
Src2.AggregateVal[_i].DoubleVal)));
|
|
|
|
}
|
|
|
|
} else if (Ty->isFloatTy())
|
2007-03-06 11:09:31 +08:00
|
|
|
Dest.IntVal = APInt(1,(Src1.FloatVal == Src1.FloatVal &&
|
|
|
|
Src2.FloatVal == Src2.FloatVal));
|
2013-04-27 04:19:41 +08:00
|
|
|
else {
|
2007-03-06 11:09:31 +08:00
|
|
|
Dest.IntVal = APInt(1,(Src1.DoubleVal == Src1.DoubleVal &&
|
|
|
|
Src2.DoubleVal == Src2.DoubleVal));
|
2013-04-27 04:19:41 +08:00
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2,
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty) {
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest;
|
2013-04-27 04:19:41 +08:00
|
|
|
if(Ty->isVectorTy()) {
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
|
|
|
|
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
|
2013-04-27 04:19:41 +08:00
|
|
|
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,
|
|
|
|
( (Src1.AggregateVal[_i].FloatVal !=
|
|
|
|
Src1.AggregateVal[_i].FloatVal) ||
|
|
|
|
(Src2.AggregateVal[_i].FloatVal !=
|
|
|
|
Src2.AggregateVal[_i].FloatVal)));
|
|
|
|
} else {
|
|
|
|
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,
|
|
|
|
( (Src1.AggregateVal[_i].DoubleVal !=
|
|
|
|
Src1.AggregateVal[_i].DoubleVal) ||
|
|
|
|
(Src2.AggregateVal[_i].DoubleVal !=
|
|
|
|
Src2.AggregateVal[_i].DoubleVal)));
|
|
|
|
}
|
|
|
|
} else if (Ty->isFloatTy())
|
2007-03-06 11:09:31 +08:00
|
|
|
Dest.IntVal = APInt(1,(Src1.FloatVal != Src1.FloatVal ||
|
|
|
|
Src2.FloatVal != Src2.FloatVal));
|
2013-04-27 04:19:41 +08:00
|
|
|
else {
|
2007-03-06 11:09:31 +08:00
|
|
|
Dest.IntVal = APInt(1,(Src1.DoubleVal != Src1.DoubleVal ||
|
|
|
|
Src2.DoubleVal != Src2.DoubleVal));
|
2013-04-27 04:19:41 +08:00
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2013-04-27 04:19:41 +08:00
|
|
|
static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2,
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *Ty, const bool val) {
|
2013-04-27 04:19:41 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
if(Ty->isVectorTy()) {
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
|
|
|
|
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
|
|
|
|
for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++)
|
|
|
|
Dest.AggregateVal[_i].IntVal = APInt(1,val);
|
|
|
|
} else {
|
|
|
|
Dest.IntVal = APInt(1, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2006-12-23 14:05:41 +08:00
|
|
|
void Interpreter::visitFCmpInst(FCmpInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = I.getOperand(0)->getType();
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue R; // Result
|
|
|
|
|
|
|
|
switch (I.getPredicate()) {
|
2013-04-27 04:19:41 +08:00
|
|
|
default:
|
|
|
|
dbgs() << "Don't know how to handle this FCmp predicate!\n-->" << I;
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2013-04-27 04:19:41 +08:00
|
|
|
break;
|
|
|
|
case FCmpInst::FCMP_FALSE: R = executeFCMP_BOOL(Src1, Src2, Ty, false);
|
|
|
|
break;
|
|
|
|
case FCmpInst::FCMP_TRUE: R = executeFCMP_BOOL(Src1, Src2, Ty, true);
|
|
|
|
break;
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
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;
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SetValue(&I, R, SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Src2, Type *Ty) {
|
2006-12-23 14:05:41 +08:00
|
|
|
GenericValue Result;
|
|
|
|
switch (predicate) {
|
|
|
|
case ICmpInst::ICMP_EQ: return executeICMP_EQ(Src1, Src2, Ty);
|
|
|
|
case ICmpInst::ICMP_NE: return executeICMP_NE(Src1, Src2, Ty);
|
|
|
|
case ICmpInst::ICMP_UGT: return executeICMP_UGT(Src1, Src2, Ty);
|
|
|
|
case ICmpInst::ICMP_SGT: return executeICMP_SGT(Src1, Src2, Ty);
|
|
|
|
case ICmpInst::ICMP_ULT: return executeICMP_ULT(Src1, Src2, Ty);
|
|
|
|
case ICmpInst::ICMP_SLT: return executeICMP_SLT(Src1, Src2, Ty);
|
|
|
|
case ICmpInst::ICMP_UGE: return executeICMP_UGE(Src1, Src2, Ty);
|
|
|
|
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);
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
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);
|
2013-04-27 04:19:41 +08:00
|
|
|
case FCmpInst::FCMP_FALSE: return executeFCMP_BOOL(Src1, Src2, Ty, false);
|
|
|
|
case FCmpInst::FCMP_TRUE: return executeFCMP_BOOL(Src1, Src2, Ty, true);
|
2006-12-23 14:05:41 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled Cmp predicate\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2006-12-23 14:05:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitBinaryOperator(BinaryOperator &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = I.getOperand(0)->getType();
|
2002-06-26 00:13:21 +08:00
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue R; // Result
|
|
|
|
|
2013-04-27 04:19:41 +08:00
|
|
|
// First process vector operation
|
|
|
|
if (Ty->isVectorTy()) {
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
|
|
|
|
R.AggregateVal.resize(Src1.AggregateVal.size());
|
|
|
|
|
|
|
|
// Macros to execute binary operation 'OP' over integer vectors
|
|
|
|
#define INTEGER_VECTOR_OPERATION(OP) \
|
|
|
|
for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
|
|
|
|
R.AggregateVal[i].IntVal = \
|
|
|
|
Src1.AggregateVal[i].IntVal OP Src2.AggregateVal[i].IntVal;
|
|
|
|
|
|
|
|
// Additional macros to execute binary operations udiv/sdiv/urem/srem since
|
|
|
|
// they have different notation.
|
|
|
|
#define INTEGER_VECTOR_FUNCTION(OP) \
|
|
|
|
for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
|
|
|
|
R.AggregateVal[i].IntVal = \
|
|
|
|
Src1.AggregateVal[i].IntVal.OP(Src2.AggregateVal[i].IntVal);
|
|
|
|
|
|
|
|
// Macros to execute binary operation 'OP' over floating point type TY
|
|
|
|
// (float or double) vectors
|
|
|
|
#define FLOAT_VECTOR_FUNCTION(OP, TY) \
|
|
|
|
for (unsigned i = 0; i < R.AggregateVal.size(); ++i) \
|
|
|
|
R.AggregateVal[i].TY = \
|
|
|
|
Src1.AggregateVal[i].TY OP Src2.AggregateVal[i].TY;
|
|
|
|
|
|
|
|
// Macros to choose appropriate TY: float or double and run operation
|
|
|
|
// execution
|
|
|
|
#define FLOAT_VECTOR_OP(OP) { \
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
|
2013-04-27 04:19:41 +08:00
|
|
|
FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
|
|
|
|
else { \
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
|
2013-04-27 04:19:41 +08:00
|
|
|
FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
|
|
|
|
else { \
|
|
|
|
dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
|
|
|
|
llvm_unreachable(0); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(I.getOpcode()){
|
|
|
|
default:
|
|
|
|
dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2013-04-27 04:19:41 +08:00
|
|
|
break;
|
|
|
|
case Instruction::Add: INTEGER_VECTOR_OPERATION(+) break;
|
|
|
|
case Instruction::Sub: INTEGER_VECTOR_OPERATION(-) break;
|
|
|
|
case Instruction::Mul: INTEGER_VECTOR_OPERATION(*) break;
|
|
|
|
case Instruction::UDiv: INTEGER_VECTOR_FUNCTION(udiv) break;
|
|
|
|
case Instruction::SDiv: INTEGER_VECTOR_FUNCTION(sdiv) break;
|
|
|
|
case Instruction::URem: INTEGER_VECTOR_FUNCTION(urem) break;
|
|
|
|
case Instruction::SRem: INTEGER_VECTOR_FUNCTION(srem) break;
|
|
|
|
case Instruction::And: INTEGER_VECTOR_OPERATION(&) break;
|
|
|
|
case Instruction::Or: INTEGER_VECTOR_OPERATION(|) break;
|
|
|
|
case Instruction::Xor: INTEGER_VECTOR_OPERATION(^) break;
|
|
|
|
case Instruction::FAdd: FLOAT_VECTOR_OP(+) break;
|
|
|
|
case Instruction::FSub: FLOAT_VECTOR_OP(-) break;
|
|
|
|
case Instruction::FMul: FLOAT_VECTOR_OP(*) break;
|
|
|
|
case Instruction::FDiv: FLOAT_VECTOR_OP(/) break;
|
|
|
|
case Instruction::FRem:
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
|
2013-04-27 04:19:41 +08:00
|
|
|
for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
|
|
|
|
R.AggregateVal[i].FloatVal =
|
|
|
|
fmod(Src1.AggregateVal[i].FloatVal, Src2.AggregateVal[i].FloatVal);
|
|
|
|
else {
|
2015-04-10 19:24:51 +08:00
|
|
|
if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
|
2013-04-27 04:19:41 +08:00
|
|
|
for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
|
|
|
|
R.AggregateVal[i].DoubleVal =
|
|
|
|
fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
|
|
|
|
else {
|
|
|
|
dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2013-04-27 04:19:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (I.getOpcode()) {
|
|
|
|
default:
|
|
|
|
dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2013-04-27 04:19:41 +08:00
|
|
|
break;
|
|
|
|
case Instruction::Add: R.IntVal = Src1.IntVal + Src2.IntVal; break;
|
|
|
|
case Instruction::Sub: R.IntVal = Src1.IntVal - Src2.IntVal; break;
|
|
|
|
case Instruction::Mul: R.IntVal = Src1.IntVal * Src2.IntVal; break;
|
|
|
|
case Instruction::FAdd: executeFAddInst(R, Src1, Src2, Ty); break;
|
|
|
|
case Instruction::FSub: executeFSubInst(R, Src1, Src2, Ty); break;
|
|
|
|
case Instruction::FMul: executeFMulInst(R, Src1, Src2, Ty); break;
|
|
|
|
case Instruction::FDiv: executeFDivInst(R, Src1, Src2, Ty); break;
|
|
|
|
case Instruction::FRem: executeFRemInst(R, Src1, Src2, Ty); break;
|
|
|
|
case Instruction::UDiv: R.IntVal = Src1.IntVal.udiv(Src2.IntVal); break;
|
|
|
|
case Instruction::SDiv: R.IntVal = Src1.IntVal.sdiv(Src2.IntVal); break;
|
|
|
|
case Instruction::URem: R.IntVal = Src1.IntVal.urem(Src2.IntVal); break;
|
|
|
|
case Instruction::SRem: R.IntVal = Src1.IntVal.srem(Src2.IntVal); break;
|
|
|
|
case Instruction::And: R.IntVal = Src1.IntVal & Src2.IntVal; break;
|
|
|
|
case Instruction::Or: R.IntVal = Src1.IntVal | Src2.IntVal; break;
|
|
|
|
case Instruction::Xor: R.IntVal = Src1.IntVal ^ Src2.IntVal; break;
|
|
|
|
}
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
2002-06-26 00:13:21 +08:00
|
|
|
SetValue(&I, R, SF);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
|
2005-04-22 06:43:08 +08:00
|
|
|
static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
|
2015-08-02 06:20:21 +08:00
|
|
|
GenericValue Src3, Type *Ty) {
|
2013-09-02 14:40:09 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
if(Ty->isVectorTy()) {
|
|
|
|
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
|
|
|
|
assert(Src2.AggregateVal.size() == Src3.AggregateVal.size());
|
|
|
|
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
|
|
|
|
for (size_t i = 0; i < Src1.AggregateVal.size(); ++i)
|
|
|
|
Dest.AggregateVal[i] = (Src1.AggregateVal[i].IntVal == 0) ?
|
|
|
|
Src3.AggregateVal[i] : Src2.AggregateVal[i];
|
|
|
|
} else {
|
|
|
|
Dest = (Src1.IntVal == 0) ? Src3 : Src2;
|
|
|
|
}
|
|
|
|
return Dest;
|
2004-04-21 00:43:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitSelectInst(SelectInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2015-08-02 06:20:21 +08:00
|
|
|
Type * Ty = I.getOperand(0)->getType();
|
2004-04-21 00:43:21 +08:00
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
|
2013-09-02 14:40:09 +08:00
|
|
|
GenericValue R = executeSelectInst(Src1, Src2, Src3, Ty);
|
2004-04-21 00:43:21 +08:00
|
|
|
SetValue(&I, R, SF);
|
|
|
|
}
|
|
|
|
|
2001-08-24 01:05:04 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Terminator Instruction Implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2001-10-27 12:15:57 +08:00
|
|
|
void Interpreter::exitCalled(GenericValue GV) {
|
2004-02-13 13:48:00 +08:00
|
|
|
// runAtExitHandlers() assumes there are no stack frames, but
|
|
|
|
// if exit() was called, then it had a stack frame. Blow away
|
|
|
|
// the stack before interpreting atexit handlers.
|
2009-10-29 13:26:09 +08:00
|
|
|
ECStack.clear();
|
|
|
|
runAtExitHandlers();
|
|
|
|
exit(GV.IntVal.zextOrTrunc(32).getZExtValue());
|
2001-10-27 12:15:57 +08:00
|
|
|
}
|
|
|
|
|
2003-11-07 13:22:49 +08:00
|
|
|
/// Pop the last stack frame off of ECStack and then copy the result
|
|
|
|
/// back into the result variable if we are not returning void. The
|
2006-02-07 13:29:44 +08:00
|
|
|
/// result variable may be the ExitValue, or the Value of the calling
|
2003-11-08 04:44:58 +08:00
|
|
|
/// CallInst if there was a previous stack frame. This method may
|
|
|
|
/// invalidate any ECStack iterators you have. This method also takes
|
|
|
|
/// care of switching to the normal destination BB, if we are returning
|
|
|
|
/// from an invoke.
|
2003-11-07 13:22:49 +08:00
|
|
|
///
|
2011-07-18 12:54:35 +08:00
|
|
|
void Interpreter::popStackAndReturnValueToCaller(Type *RetTy,
|
2009-10-29 13:26:09 +08:00
|
|
|
GenericValue Result) {
|
2003-11-07 13:22:49 +08:00
|
|
|
// Pop the current stack frame.
|
|
|
|
ECStack.pop_back();
|
|
|
|
|
2005-04-22 06:43:08 +08:00
|
|
|
if (ECStack.empty()) { // Finished main. Put result into exit code...
|
2010-06-18 10:01:10 +08:00
|
|
|
if (RetTy && !RetTy->isVoidTy()) { // Nonvoid return type?
|
2006-02-07 13:29:44 +08:00
|
|
|
ExitValue = Result; // Capture the exit value of the program
|
2005-04-22 06:43:08 +08:00
|
|
|
} else {
|
2007-06-02 06:23:29 +08:00
|
|
|
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
|
2005-04-22 06:43:08 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// If we have a previous stack frame, and we have a previous call,
|
|
|
|
// fill in the return value...
|
2003-11-07 13:22:49 +08:00
|
|
|
ExecutionContext &CallingSF = ECStack.back();
|
2003-11-08 04:44:58 +08:00
|
|
|
if (Instruction *I = CallingSF.Caller.getInstruction()) {
|
2009-08-14 05:58:54 +08:00
|
|
|
// Save result...
|
2010-01-05 21:12:22 +08:00
|
|
|
if (!CallingSF.Caller.getType()->isVoidTy())
|
2003-11-08 04:44:58 +08:00
|
|
|
SetValue(I, Result, CallingSF);
|
|
|
|
if (InvokeInst *II = dyn_cast<InvokeInst> (I))
|
|
|
|
SwitchToNewBasicBlock (II->getNormalDest (), CallingSF);
|
2003-11-08 03:26:23 +08:00
|
|
|
CallingSF.Caller = CallSite(); // We returned from the call...
|
2003-11-07 13:22:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitReturnInst(ReturnInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *RetTy = Type::getVoidTy(I.getContext());
|
2001-08-24 01:05:04 +08:00
|
|
|
GenericValue Result;
|
|
|
|
|
|
|
|
// Save away the return value... (if we are not 'ret void')
|
2002-06-26 00:13:21 +08:00
|
|
|
if (I.getNumOperands()) {
|
|
|
|
RetTy = I.getReturnValue()->getType();
|
|
|
|
Result = getOperandValue(I.getReturnValue(), SF);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
|
2003-11-07 13:22:49 +08:00
|
|
|
popStackAndReturnValueToCaller(RetTy, Result);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
|
2004-10-17 02:21:33 +08:00
|
|
|
void Interpreter::visitUnreachableInst(UnreachableInst &I) {
|
2010-04-08 06:58:41 +08:00
|
|
|
report_fatal_error("Program executed an 'unreachable' instruction!");
|
2004-10-17 02:21:33 +08:00
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitBranchInst(BranchInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2001-08-24 01:05:04 +08:00
|
|
|
BasicBlock *Dest;
|
|
|
|
|
2002-06-26 00:13:21 +08:00
|
|
|
Dest = I.getSuccessor(0); // Uncond branches have a fixed dest...
|
|
|
|
if (!I.isUnconditional()) {
|
|
|
|
Value *Cond = I.getCondition();
|
2007-03-06 11:09:31 +08:00
|
|
|
if (getOperandValue(Cond, SF).IntVal == 0) // If false cond...
|
2005-04-22 06:43:08 +08:00
|
|
|
Dest = I.getSuccessor(1);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
2003-05-11 04:21:16 +08:00
|
|
|
SwitchToNewBasicBlock(Dest, SF);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitSwitchInst(SwitchInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2011-09-30 04:21:17 +08:00
|
|
|
Value* Cond = I.getCondition();
|
|
|
|
Type *ElTy = Cond->getType();
|
|
|
|
GenericValue CondVal = getOperandValue(Cond, SF);
|
2003-04-23 04:34:47 +08:00
|
|
|
|
|
|
|
// Check to see if any of the cases match...
|
2014-04-24 14:44:33 +08:00
|
|
|
BasicBlock *Dest = nullptr;
|
2017-04-12 15:27:28 +08:00
|
|
|
for (auto Case : I.cases()) {
|
|
|
|
GenericValue CaseVal = getOperandValue(Case.getCaseValue(), SF);
|
Revert patches to add case-range support for PR1255.
The work on this project was left in an unfinished and inconsistent state.
Hopefully someone will eventually get a chance to implement this feature, but
in the meantime, it is better to put things back the way the were. I have
left support in the bitcode reader to handle the case-range bitcode format,
so that we do not lose bitcode compatibility with the llvm 3.3 release.
This reverts the following commits: 155464, 156374, 156377, 156613, 156704,
156757, 156804 156808, 156985, 157046, 157112, 157183, 157315, 157384, 157575,
157576, 157586, 157612, 157810, 157814, 157815, 157880, 157881, 157882, 157884,
157887, 157901, 158979, 157987, 157989, 158986, 158997, 159076, 159101, 159100,
159200, 159201, 159207, 159527, 159532, 159540, 159583, 159618, 159658, 159659,
159660, 159661, 159703, 159704, 160076, 167356, 172025, 186736
llvm-svn: 190328
2013-09-10 03:14:35 +08:00
|
|
|
if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
|
2017-04-12 15:27:28 +08:00
|
|
|
Dest = cast<BasicBlock>(Case.getCaseSuccessor());
|
Revert patches to add case-range support for PR1255.
The work on this project was left in an unfinished and inconsistent state.
Hopefully someone will eventually get a chance to implement this feature, but
in the meantime, it is better to put things back the way the were. I have
left support in the bitcode reader to handle the case-range bitcode format,
so that we do not lose bitcode compatibility with the llvm 3.3 release.
This reverts the following commits: 155464, 156374, 156377, 156613, 156704,
156757, 156804 156808, 156985, 157046, 157112, 157183, 157315, 157384, 157575,
157576, 157586, 157612, 157810, 157814, 157815, 157880, 157881, 157882, 157884,
157887, 157901, 158979, 157987, 157989, 158986, 158997, 159076, 159101, 159100,
159200, 159201, 159207, 159527, 159532, 159540, 159583, 159618, 159658, 159659,
159660, 159661, 159703, 159704, 160076, 167356, 172025, 186736
llvm-svn: 190328
2013-09-10 03:14:35 +08:00
|
|
|
break;
|
2003-04-23 04:34:47 +08:00
|
|
|
}
|
2011-09-30 04:21:17 +08:00
|
|
|
}
|
2003-04-23 04:34:47 +08:00
|
|
|
if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
|
2003-05-11 04:21:16 +08:00
|
|
|
SwitchToNewBasicBlock(Dest, SF);
|
|
|
|
}
|
|
|
|
|
2009-10-29 13:26:09 +08:00
|
|
|
void Interpreter::visitIndirectBrInst(IndirectBrInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
void *Dest = GVTOP(getOperandValue(I.getAddress(), SF));
|
|
|
|
SwitchToNewBasicBlock((BasicBlock*)Dest, SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-11 04:21:16 +08:00
|
|
|
// SwitchToNewBasicBlock - This method is used to jump to a new basic block.
|
|
|
|
// This function handles the actual updating of block and instruction iterators
|
|
|
|
// as well as execution of all of the PHI nodes in the destination block.
|
|
|
|
//
|
|
|
|
// This method does this because all of the PHI nodes must be executed
|
|
|
|
// atomically, reading their inputs before any of the results are updated. Not
|
|
|
|
// doing this can cause problems if the PHI nodes depend on other PHI nodes for
|
|
|
|
// their inputs. If the input PHI node is updated before it is read, incorrect
|
|
|
|
// results can happen. Thus we use a two phase approach.
|
|
|
|
//
|
|
|
|
void Interpreter::SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF){
|
|
|
|
BasicBlock *PrevBB = SF.CurBB; // Remember where we came from...
|
|
|
|
SF.CurBB = Dest; // Update CurBB to branch destination
|
|
|
|
SF.CurInst = SF.CurBB->begin(); // Update new instruction ptr...
|
|
|
|
|
|
|
|
if (!isa<PHINode>(SF.CurInst)) return; // Nothing fancy to do
|
|
|
|
|
|
|
|
// Loop over all of the PHI nodes in the current block, reading their inputs.
|
|
|
|
std::vector<GenericValue> ResultValues;
|
|
|
|
|
|
|
|
for (; PHINode *PN = dyn_cast<PHINode>(SF.CurInst); ++SF.CurInst) {
|
|
|
|
// Search for the value corresponding to this previous bb...
|
|
|
|
int i = PN->getBasicBlockIndex(PrevBB);
|
|
|
|
assert(i != -1 && "PHINode doesn't contain entry for predecessor??");
|
|
|
|
Value *IncomingValue = PN->getIncomingValue(i);
|
2005-04-22 06:43:08 +08:00
|
|
|
|
2003-05-11 04:21:16 +08:00
|
|
|
// Save the incoming value for this PHI node...
|
|
|
|
ResultValues.push_back(getOperandValue(IncomingValue, SF));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now loop over all of the PHI nodes setting their values...
|
|
|
|
SF.CurInst = SF.CurBB->begin();
|
2004-09-16 01:06:42 +08:00
|
|
|
for (unsigned i = 0; isa<PHINode>(SF.CurInst); ++SF.CurInst, ++i) {
|
|
|
|
PHINode *PN = cast<PHINode>(SF.CurInst);
|
2003-05-11 04:21:16 +08:00
|
|
|
SetValue(PN, ResultValues[i], SF);
|
2004-09-16 01:06:42 +08:00
|
|
|
}
|
2003-04-23 04:34:47 +08:00
|
|
|
}
|
|
|
|
|
2001-08-27 13:16:50 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Memory Instruction Implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-10-24 05:09:37 +08:00
|
|
|
void Interpreter::visitAllocaInst(AllocaInst &I) {
|
2003-05-11 05:22:39 +08:00
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = I.getType()->getElementType(); // Type to be allocated
|
2001-08-27 13:16:50 +08:00
|
|
|
|
2002-04-29 05:57:33 +08:00
|
|
|
// Get the number of elements being allocated by the array...
|
2007-03-06 11:09:31 +08:00
|
|
|
unsigned NumElements =
|
|
|
|
getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue();
|
|
|
|
|
2015-07-17 00:34:23 +08:00
|
|
|
unsigned TypeSize = (size_t)getDataLayout().getTypeAllocSize(Ty);
|
2007-03-06 11:09:31 +08:00
|
|
|
|
2007-10-12 03:40:35 +08:00
|
|
|
// Avoid malloc-ing zero bytes, use max()...
|
|
|
|
unsigned MemToAlloc = std::max(1U, NumElements * TypeSize);
|
2001-08-27 13:16:50 +08:00
|
|
|
|
|
|
|
// Allocate enough memory to hold the type...
|
Report fatal error in the case of out of memory
This is the second part of recommit of r325224. The previous part was
committed in r325426, which deals with C++ memory allocation. Solution
for C memory allocation involved functions `llvm::malloc` and similar.
This was a fragile solution because it caused ambiguity errors in some
cases. In this commit the new functions have names like `llvm::safe_malloc`.
The relevant part of original comment is below, updated for new function
names.
Analysis of fails in the case of out of memory errors can be tricky on
Windows. Such error emerges at the point where memory allocation function
fails, but manifests itself when null pointer is used. These two points
may be distant from each other. Besides, next runs may not exhibit
allocation error.
In some cases memory is allocated by a call to some of C allocation
functions, malloc, calloc and realloc. They are used for interoperability
with C code, when allocated object has variable size and when it is
necessary to avoid call of constructors. In many calls the result is not
checked for null pointer. To simplify checks, new functions are defined
in the namespace 'llvm': `safe_malloc`, `safe_calloc` and `safe_realloc`.
They behave as corresponding standard functions but produce fatal error if
allocation fails. This change replaces the standard functions like 'malloc'
in the cases when the result of the allocation function is not checked
for null pointer.
Finally, there are plain C code, that uses malloc and similar functions. If
the result is not checked, assert statement is added.
Differential Revision: https://reviews.llvm.org/D43010
llvm-svn: 325551
2018-02-20 13:41:26 +08:00
|
|
|
void *Memory = safe_malloc(MemToAlloc);
|
2007-03-06 11:09:31 +08:00
|
|
|
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "Allocated Type: " << *Ty << " (" << TypeSize
|
|
|
|
<< " bytes) x " << NumElements << " (Total: " << MemToAlloc
|
|
|
|
<< ") at " << uintptr_t(Memory) << '\n');
|
2002-02-20 02:50:09 +08:00
|
|
|
|
2002-12-24 07:59:41 +08:00
|
|
|
GenericValue Result = PTOGV(Memory);
|
2014-04-28 12:05:08 +08:00
|
|
|
assert(Result.PointerVal && "Null pointer returned by malloc!");
|
2002-06-26 00:13:21 +08:00
|
|
|
SetValue(&I, Result, SF);
|
2001-08-27 13:16:50 +08:00
|
|
|
|
2002-06-26 00:13:21 +08:00
|
|
|
if (I.getOpcode() == Instruction::Alloca)
|
2002-02-20 02:50:09 +08:00
|
|
|
ECStack.back().Allocas.add(Memory);
|
2001-08-27 13:16:50 +08:00
|
|
|
}
|
|
|
|
|
2002-08-28 06:33:45 +08:00
|
|
|
// getElementOffset - The workhorse for getelementptr.
|
2001-10-30 03:32:19 +08:00
|
|
|
//
|
2003-11-26 04:44:56 +08:00
|
|
|
GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
|
2005-04-22 06:43:08 +08:00
|
|
|
gep_type_iterator E,
|
|
|
|
ExecutionContext &SF) {
|
2010-02-16 19:11:14 +08:00
|
|
|
assert(Ptr->getType()->isPointerTy() &&
|
2001-10-30 03:32:19 +08:00
|
|
|
"Cannot getElementOffset of a nonpointer type!");
|
|
|
|
|
2007-03-06 11:09:31 +08:00
|
|
|
uint64_t Total = 0;
|
2002-08-28 06:33:45 +08:00
|
|
|
|
|
|
|
for (; I != E; ++I) {
|
2016-12-02 10:24:42 +08:00
|
|
|
if (StructType *STy = I.getStructTypeOrNull()) {
|
2015-07-17 00:34:23 +08:00
|
|
|
const StructLayout *SLO = getDataLayout().getStructLayout(STy);
|
2005-04-22 06:43:08 +08:00
|
|
|
|
2006-10-20 15:07:24 +08:00
|
|
|
const ConstantInt *CPU = cast<ConstantInt>(I.getOperand());
|
|
|
|
unsigned Index = unsigned(CPU->getZExtValue());
|
2005-04-22 06:43:08 +08:00
|
|
|
|
2007-03-06 11:09:31 +08:00
|
|
|
Total += SLO->getElementOffset(Index);
|
2003-11-26 04:44:56 +08:00
|
|
|
} else {
|
2003-02-26 05:14:59 +08:00
|
|
|
// Get the index number for the array... which must be long type...
|
2003-11-26 04:44:56 +08:00
|
|
|
GenericValue IdxGV = getOperandValue(I.getOperand(), SF);
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
int64_t Idx;
|
|
|
|
unsigned BitWidth =
|
|
|
|
cast<IntegerType>(I.getOperand()->getType())->getBitWidth();
|
2007-01-18 09:25:42 +08:00
|
|
|
if (BitWidth == 32)
|
2007-03-06 11:09:31 +08:00
|
|
|
Idx = (int64_t)(int32_t)IdxGV.IntVal.getZExtValue();
|
2008-04-07 05:50:58 +08:00
|
|
|
else {
|
|
|
|
assert(BitWidth == 64 && "Invalid index type for getelementptr");
|
2007-03-06 11:09:31 +08:00
|
|
|
Idx = (int64_t)IdxGV.IntVal.getZExtValue();
|
2008-04-07 05:50:58 +08:00
|
|
|
}
|
2016-12-02 10:24:42 +08:00
|
|
|
Total += getDataLayout().getTypeAllocSize(I.getIndexedType()) * Idx;
|
2003-10-25 03:59:01 +08:00
|
|
|
}
|
2001-10-30 03:32:19 +08:00
|
|
|
}
|
|
|
|
|
2002-08-28 06:33:45 +08:00
|
|
|
GenericValue Result;
|
2007-03-06 11:09:31 +08:00
|
|
|
Result.PointerVal = ((char*)getOperandValue(Ptr, SF).PointerVal) + Total;
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "GEP Index " << Total << " bytes.\n");
|
2002-08-28 06:33:45 +08:00
|
|
|
return Result;
|
2001-10-30 03:32:19 +08:00
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2009-06-27 00:46:15 +08:00
|
|
|
SetValue(&I, executeGEPOperation(I.getPointerOperand(),
|
2003-11-26 04:44:56 +08:00
|
|
|
gep_type_begin(I), gep_type_end(I), SF), SF);
|
2001-10-30 03:32:19 +08:00
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitLoadInst(LoadInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2002-06-26 00:13:21 +08:00
|
|
|
GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
|
2002-12-24 07:59:41 +08:00
|
|
|
GenericValue *Ptr = (GenericValue*)GVTOP(SRC);
|
2007-03-03 16:38:04 +08:00
|
|
|
GenericValue Result;
|
|
|
|
LoadValueFromMemory(Result, Ptr, I.getType());
|
2002-06-26 00:13:21 +08:00
|
|
|
SetValue(&I, Result, SF);
|
2008-07-09 01:25:49 +08:00
|
|
|
if (I.isVolatile() && PrintVolatile)
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Volatile load " << I;
|
2001-08-27 13:16:50 +08:00
|
|
|
}
|
|
|
|
|
2003-05-11 05:22:39 +08:00
|
|
|
void Interpreter::visitStoreInst(StoreInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
2002-06-26 00:13:21 +08:00
|
|
|
GenericValue Val = getOperandValue(I.getOperand(0), SF);
|
2002-10-16 04:34:05 +08:00
|
|
|
GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
|
2002-12-24 07:59:41 +08:00
|
|
|
StoreValueToMemory(Val, (GenericValue *)GVTOP(SRC),
|
2002-10-26 09:57:15 +08:00
|
|
|
I.getOperand(0)->getType());
|
2008-07-09 01:25:49 +08:00
|
|
|
if (I.isVolatile() && PrintVolatile)
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Volatile store: " << I;
|
2001-08-27 13:16:50 +08:00
|
|
|
}
|
|
|
|
|
2001-08-24 01:05:04 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Miscellaneous Instruction Implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2003-11-08 04:04:22 +08:00
|
|
|
void Interpreter::visitCallSite(CallSite CS) {
|
2003-05-11 05:22:39 +08:00
|
|
|
ExecutionContext &SF = ECStack.back();
|
2003-12-28 17:44:37 +08:00
|
|
|
|
|
|
|
// Check to see if this is an intrinsic function call...
|
2007-04-17 05:50:40 +08:00
|
|
|
Function *F = CS.getCalledFunction();
|
2009-10-29 13:26:09 +08:00
|
|
|
if (F && F->isDeclaration())
|
2003-12-28 17:44:37 +08:00
|
|
|
switch (F->getIntrinsicID()) {
|
2004-01-14 14:02:53 +08:00
|
|
|
case Intrinsic::not_intrinsic:
|
|
|
|
break;
|
2004-03-13 08:24:00 +08:00
|
|
|
case Intrinsic::vastart: { // va_start
|
2004-02-26 07:01:48 +08:00
|
|
|
GenericValue ArgIndex;
|
|
|
|
ArgIndex.UIntPairVal.first = ECStack.size() - 1;
|
|
|
|
ArgIndex.UIntPairVal.second = 0;
|
|
|
|
SetValue(CS.getInstruction(), ArgIndex, SF);
|
2003-12-28 17:44:37 +08:00
|
|
|
return;
|
2004-02-26 07:01:48 +08:00
|
|
|
}
|
2004-03-13 08:24:00 +08:00
|
|
|
case Intrinsic::vaend: // va_end is a noop for the interpreter
|
2003-12-28 17:44:37 +08:00
|
|
|
return;
|
2004-03-13 08:24:00 +08:00
|
|
|
case Intrinsic::vacopy: // va_copy: dest = src
|
2003-12-28 17:44:37 +08:00
|
|
|
SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF);
|
|
|
|
return;
|
|
|
|
default:
|
2004-01-14 14:02:53 +08:00
|
|
|
// If it is an unknown intrinsic function, use the intrinsic lowering
|
2003-12-28 17:44:37 +08:00
|
|
|
// class to transform it into hopefully tasty LLVM code.
|
|
|
|
//
|
2007-04-18 01:38:28 +08:00
|
|
|
BasicBlock::iterator me(CS.getInstruction());
|
2003-12-28 17:44:37 +08:00
|
|
|
BasicBlock *Parent = CS.getInstruction()->getParent();
|
2007-04-18 01:38:28 +08:00
|
|
|
bool atBegin(Parent->begin() == me);
|
|
|
|
if (!atBegin)
|
|
|
|
--me;
|
2003-12-28 17:44:37 +08:00
|
|
|
IL->LowerIntrinsicCall(cast<CallInst>(CS.getInstruction()));
|
|
|
|
|
|
|
|
// Restore the CurInst pointer to the first instruction newly inserted, if
|
|
|
|
// any.
|
2007-04-18 01:38:28 +08:00
|
|
|
if (atBegin) {
|
2003-12-28 17:44:37 +08:00
|
|
|
SF.CurInst = Parent->begin();
|
|
|
|
} else {
|
2007-04-18 01:38:28 +08:00
|
|
|
SF.CurInst = me;
|
2003-12-28 17:44:37 +08:00
|
|
|
++SF.CurInst;
|
|
|
|
}
|
2004-04-24 02:05:28 +08:00
|
|
|
return;
|
2003-12-28 17:44:37 +08:00
|
|
|
}
|
|
|
|
|
2007-04-17 05:50:40 +08:00
|
|
|
|
2003-11-08 04:04:22 +08:00
|
|
|
SF.Caller = CS;
|
2003-04-23 05:22:33 +08:00
|
|
|
std::vector<GenericValue> ArgVals;
|
2003-11-08 03:59:08 +08:00
|
|
|
const unsigned NumArgs = SF.Caller.arg_size();
|
|
|
|
ArgVals.reserve(NumArgs);
|
2007-04-17 05:50:40 +08:00
|
|
|
uint16_t pNum = 1;
|
2003-11-08 03:59:08 +08:00
|
|
|
for (CallSite::arg_iterator i = SF.Caller.arg_begin(),
|
2007-04-17 05:50:40 +08:00
|
|
|
e = SF.Caller.arg_end(); i != e; ++i, ++pNum) {
|
2003-11-08 03:59:08 +08:00
|
|
|
Value *V = *i;
|
|
|
|
ArgVals.push_back(getOperandValue(V, SF));
|
2003-01-13 08:58:52 +08:00
|
|
|
}
|
2001-09-10 12:49:44 +08:00
|
|
|
|
2005-04-22 06:43:08 +08:00
|
|
|
// To handle indirect calls, we must get the pointer value from the argument
|
2002-04-08 04:49:59 +08:00
|
|
|
// and treat it as a function pointer.
|
2005-04-22 06:43:08 +08:00
|
|
|
GenericValue SRC = getOperandValue(SF.Caller.getCalledValue(), SF);
|
2003-05-09 00:18:31 +08:00
|
|
|
callFunction((Function*)GVTOP(SRC), ArgVals);
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
|
2014-01-25 01:20:08 +08:00
|
|
|
// auxiliary function for shift operations
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
static unsigned getShiftAmount(uint64_t orgShiftAmount,
|
|
|
|
llvm::APInt valueToShift) {
|
|
|
|
unsigned valueWidth = valueToShift.getBitWidth();
|
|
|
|
if (orgShiftAmount < (uint64_t)valueWidth)
|
|
|
|
return orgShiftAmount;
|
|
|
|
// according to the llvm documentation, if orgShiftAmount > valueWidth,
|
|
|
|
// the result is undfeined. but we do shift by this rule:
|
|
|
|
return (NextPowerOf2(valueWidth-1) - 1) & orgShiftAmount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-02 10:16:23 +08:00
|
|
|
void Interpreter::visitShl(BinaryOperator &I) {
|
2003-12-11 08:22:59 +08:00
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Dest;
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *Ty = I.getType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
if (Ty->isVectorTy()) {
|
|
|
|
uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
|
|
|
|
assert(src1Size == Src2.AggregateVal.size());
|
|
|
|
for (unsigned i = 0; i < src1Size; i++) {
|
|
|
|
GenericValue Result;
|
|
|
|
uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
|
|
|
|
llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
|
|
|
|
Result.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
|
|
|
|
Dest.AggregateVal.push_back(Result);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
uint64_t shiftAmount = Src2.IntVal.getZExtValue();
|
|
|
|
llvm::APInt valueToShift = Src1.IntVal;
|
|
|
|
Dest.IntVal = valueToShift.shl(getShiftAmount(shiftAmount, valueToShift));
|
|
|
|
}
|
|
|
|
|
2003-12-11 08:22:59 +08:00
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
2007-02-02 10:16:23 +08:00
|
|
|
void Interpreter::visitLShr(BinaryOperator &I) {
|
2006-11-08 14:47:33 +08:00
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Dest;
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *Ty = I.getType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
if (Ty->isVectorTy()) {
|
|
|
|
uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
|
|
|
|
assert(src1Size == Src2.AggregateVal.size());
|
|
|
|
for (unsigned i = 0; i < src1Size; i++) {
|
|
|
|
GenericValue Result;
|
|
|
|
uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
|
|
|
|
llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
|
|
|
|
Result.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
|
|
|
|
Dest.AggregateVal.push_back(Result);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
uint64_t shiftAmount = Src2.IntVal.getZExtValue();
|
|
|
|
llvm::APInt valueToShift = Src1.IntVal;
|
|
|
|
Dest.IntVal = valueToShift.lshr(getShiftAmount(shiftAmount, valueToShift));
|
|
|
|
}
|
|
|
|
|
2006-11-08 14:47:33 +08:00
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
2007-02-02 10:16:23 +08:00
|
|
|
void Interpreter::visitAShr(BinaryOperator &I) {
|
2003-12-11 08:22:59 +08:00
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
2009-01-17 04:17:02 +08:00
|
|
|
GenericValue Dest;
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *Ty = I.getType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
if (Ty->isVectorTy()) {
|
|
|
|
size_t src1Size = Src1.AggregateVal.size();
|
|
|
|
assert(src1Size == Src2.AggregateVal.size());
|
|
|
|
for (unsigned i = 0; i < src1Size; i++) {
|
|
|
|
GenericValue Result;
|
|
|
|
uint64_t shiftAmount = Src2.AggregateVal[i].IntVal.getZExtValue();
|
|
|
|
llvm::APInt valueToShift = Src1.AggregateVal[i].IntVal;
|
|
|
|
Result.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
|
|
|
|
Dest.AggregateVal.push_back(Result);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
uint64_t shiftAmount = Src2.IntVal.getZExtValue();
|
|
|
|
llvm::APInt valueToShift = Src1.IntVal;
|
|
|
|
Dest.IntVal = valueToShift.ashr(getShiftAmount(shiftAmount, valueToShift));
|
|
|
|
}
|
|
|
|
|
2002-06-26 00:13:21 +08:00
|
|
|
SetValue(&I, Dest, SF);
|
2001-08-27 13:16:50 +08:00
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeTruncInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
Type *SrcTy = SrcVal->getType();
|
|
|
|
if (SrcTy->isVectorTy()) {
|
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
|
|
|
unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
|
|
|
|
unsigned NumElts = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal
|
|
|
|
Dest.AggregateVal.resize(NumElts);
|
|
|
|
for (unsigned i = 0; i < NumElts; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.trunc(DBitWidth);
|
|
|
|
} else {
|
|
|
|
IntegerType *DITy = cast<IntegerType>(DstTy);
|
|
|
|
unsigned DBitWidth = DITy->getBitWidth();
|
|
|
|
Dest.IntVal = Src.IntVal.trunc(DBitWidth);
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
2001-08-27 13:16:50 +08:00
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeSExtInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *SrcTy = SrcVal->getType();
|
2002-08-28 06:33:45 +08:00
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
if (SrcTy->isVectorTy()) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
|
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal.
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.sext(DBitWidth);
|
|
|
|
} else {
|
2015-08-02 06:20:21 +08:00
|
|
|
auto *DITy = cast<IntegerType>(DstTy);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned DBitWidth = DITy->getBitWidth();
|
|
|
|
Dest.IntVal = Src.IntVal.sext(DBitWidth);
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
2001-08-27 13:16:50 +08:00
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeZExtInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *SrcTy = SrcVal->getType();
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
if (SrcTy->isVectorTy()) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
|
|
|
|
|
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal.
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.zext(DBitWidth);
|
|
|
|
} else {
|
2015-08-02 06:20:21 +08:00
|
|
|
auto *DITy = cast<IntegerType>(DstTy);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned DBitWidth = DITy->getBitWidth();
|
|
|
|
Dest.IntVal = Src.IntVal.zext(DBitWidth);
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
2002-08-28 06:33:45 +08:00
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
|
|
|
|
assert(SrcVal->getType()->getScalarType()->isDoubleTy() &&
|
|
|
|
DstTy->getScalarType()->isFloatTy() &&
|
|
|
|
"Invalid FPTrunc instruction");
|
|
|
|
|
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal.
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].FloatVal = (float)Src.AggregateVal[i].DoubleVal;
|
|
|
|
} else {
|
|
|
|
assert(SrcVal->getType()->isDoubleTy() && DstTy->isFloatTy() &&
|
|
|
|
"Invalid FPTrunc instruction");
|
|
|
|
Dest.FloatVal = (float)Src.DoubleVal;
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeFPExtInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
|
|
|
|
assert(SrcVal->getType()->getScalarType()->isFloatTy() &&
|
|
|
|
DstTy->getScalarType()->isDoubleTy() && "Invalid FPExt instruction");
|
|
|
|
|
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal.
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].DoubleVal = (double)Src.AggregateVal[i].FloatVal;
|
|
|
|
} else {
|
|
|
|
assert(SrcVal->getType()->isFloatTy() && DstTy->isDoubleTy() &&
|
|
|
|
"Invalid FPExt instruction");
|
|
|
|
Dest.DoubleVal = (double)Src.FloatVal;
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *SrcTy = SrcVal->getType();
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
2007-03-03 16:38:04 +08:00
|
|
|
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
if (SrcTy->getTypeID() == Type::VectorTyID) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
|
|
|
Type *SrcVecTy = SrcTy->getScalarType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
|
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal.
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
|
|
|
|
if (SrcVecTy->getTypeID() == Type::FloatTyID) {
|
|
|
|
assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToUI instruction");
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
|
|
|
|
Src.AggregateVal[i].FloatVal, DBitWidth);
|
|
|
|
} else {
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
|
|
|
|
Src.AggregateVal[i].DoubleVal, DBitWidth);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
|
|
|
|
assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction");
|
|
|
|
|
|
|
|
if (SrcTy->getTypeID() == Type::FloatTyID)
|
|
|
|
Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
|
|
|
|
else {
|
|
|
|
Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *SrcTy = SrcVal->getType();
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
2007-03-03 16:38:04 +08:00
|
|
|
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
if (SrcTy->getTypeID() == Type::VectorTyID) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
|
|
|
Type *SrcVecTy = SrcTy->getScalarType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
|
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
|
|
|
|
if (SrcVecTy->getTypeID() == Type::FloatTyID) {
|
|
|
|
assert(SrcVecTy->isFloatingPointTy() && "Invalid FPToSI instruction");
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = APIntOps::RoundFloatToAPInt(
|
|
|
|
Src.AggregateVal[i].FloatVal, DBitWidth);
|
|
|
|
} else {
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].IntVal = APIntOps::RoundDoubleToAPInt(
|
|
|
|
Src.AggregateVal[i].DoubleVal, DBitWidth);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
unsigned DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
|
|
|
|
assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction");
|
|
|
|
|
|
|
|
if (SrcTy->getTypeID() == Type::FloatTyID)
|
|
|
|
Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
|
|
|
|
else {
|
|
|
|
Dest.IntVal = APIntOps::RoundDoubleToAPInt(Src.DoubleVal, DBitWidth);
|
|
|
|
}
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
2007-03-03 16:38:04 +08:00
|
|
|
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
|
|
|
|
if (DstVecTy->getTypeID() == Type::FloatTyID) {
|
|
|
|
assert(DstVecTy->isFloatingPointTy() && "Invalid UIToFP instruction");
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].FloatVal =
|
|
|
|
APIntOps::RoundAPIntToFloat(Src.AggregateVal[i].IntVal);
|
|
|
|
} else {
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].DoubleVal =
|
|
|
|
APIntOps::RoundAPIntToDouble(Src.AggregateVal[i].IntVal);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction");
|
|
|
|
if (DstTy->getTypeID() == Type::FloatTyID)
|
|
|
|
Dest.FloatVal = APIntOps::RoundAPIntToFloat(Src.IntVal);
|
|
|
|
else {
|
|
|
|
Dest.DoubleVal = APIntOps::RoundAPIntToDouble(Src.IntVal);
|
|
|
|
}
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
2007-03-03 16:38:04 +08:00
|
|
|
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *DstVecTy = DstTy->getScalarType();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned size = Src.AggregateVal.size();
|
|
|
|
// the sizes of src and dst vectors must be equal
|
|
|
|
Dest.AggregateVal.resize(size);
|
|
|
|
|
|
|
|
if (DstVecTy->getTypeID() == Type::FloatTyID) {
|
|
|
|
assert(DstVecTy->isFloatingPointTy() && "Invalid SIToFP instruction");
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].FloatVal =
|
|
|
|
APIntOps::RoundSignedAPIntToFloat(Src.AggregateVal[i].IntVal);
|
|
|
|
} else {
|
|
|
|
for (unsigned i = 0; i < size; i++)
|
|
|
|
Dest.AggregateVal[i].DoubleVal =
|
|
|
|
APIntOps::RoundSignedAPIntToDouble(Src.AggregateVal[i].IntVal);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// scalar
|
|
|
|
assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction");
|
|
|
|
|
|
|
|
if (DstTy->getTypeID() == Type::FloatTyID)
|
|
|
|
Dest.FloatVal = APIntOps::RoundSignedAPIntToFloat(Src.IntVal);
|
|
|
|
else {
|
|
|
|
Dest.DoubleVal = APIntOps::RoundSignedAPIntToDouble(Src.IntVal);
|
|
|
|
}
|
|
|
|
}
|
2007-03-06 11:09:31 +08:00
|
|
|
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
return Dest;
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
2007-03-06 11:09:31 +08:00
|
|
|
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
2010-02-16 19:11:14 +08:00
|
|
|
assert(SrcVal->getType()->isPointerTy() && "Invalid PtrToInt instruction");
|
2007-03-03 16:38:04 +08:00
|
|
|
|
2007-03-06 11:09:31 +08:00
|
|
|
Dest.IntVal = APInt(DBitWidth, (intptr_t) Src.PointerVal);
|
2002-08-28 06:33:45 +08:00
|
|
|
return Dest;
|
2001-08-27 13:16:50 +08:00
|
|
|
}
|
2001-08-24 01:05:04 +08:00
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
2010-02-16 19:11:14 +08:00
|
|
|
assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction");
|
2007-03-03 16:38:04 +08:00
|
|
|
|
2015-07-17 00:34:23 +08:00
|
|
|
uint32_t PtrSize = getDataLayout().getPointerSizeInBits();
|
2007-03-06 11:41:50 +08:00
|
|
|
if (PtrSize != Src.IntVal.getBitWidth())
|
2007-03-06 11:46:41 +08:00
|
|
|
Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
|
2007-03-06 11:41:50 +08:00
|
|
|
|
2007-04-27 02:19:35 +08:00
|
|
|
Dest.PointerVal = PointerTy(intptr_t(Src.IntVal.getZExtValue()));
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
2011-07-18 12:54:35 +08:00
|
|
|
GenericValue Interpreter::executeBitCastInst(Value *SrcVal, Type *DstTy,
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
ExecutionContext &SF) {
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
// This instruction supports bitwise conversion of vectors to integers and
|
|
|
|
// to vectors of other types (as long as they have the same size)
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *SrcTy = SrcVal->getType();
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
if ((SrcTy->getTypeID() == Type::VectorTyID) ||
|
|
|
|
(DstTy->getTypeID() == Type::VectorTyID)) {
|
|
|
|
// vector src bitcast to vector dst or vector src bitcast to scalar dst or
|
|
|
|
// scalar src bitcast to vector dst
|
2015-07-17 00:34:23 +08:00
|
|
|
bool isLittleEndian = getDataLayout().isLittleEndian();
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
GenericValue TempDst, TempSrc, SrcVec;
|
2015-08-02 06:20:21 +08:00
|
|
|
Type *SrcElemTy;
|
|
|
|
Type *DstElemTy;
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
unsigned SrcBitSize;
|
|
|
|
unsigned DstBitSize;
|
|
|
|
unsigned SrcNum;
|
|
|
|
unsigned DstNum;
|
|
|
|
|
|
|
|
if (SrcTy->getTypeID() == Type::VectorTyID) {
|
|
|
|
SrcElemTy = SrcTy->getScalarType();
|
|
|
|
SrcBitSize = SrcTy->getScalarSizeInBits();
|
|
|
|
SrcNum = Src.AggregateVal.size();
|
|
|
|
SrcVec = Src;
|
|
|
|
} else {
|
|
|
|
// if src is scalar value, make it vector <1 x type>
|
|
|
|
SrcElemTy = SrcTy;
|
|
|
|
SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
|
|
|
SrcNum = 1;
|
|
|
|
SrcVec.AggregateVal.push_back(Src);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DstTy->getTypeID() == Type::VectorTyID) {
|
|
|
|
DstElemTy = DstTy->getScalarType();
|
|
|
|
DstBitSize = DstTy->getScalarSizeInBits();
|
|
|
|
DstNum = (SrcNum * SrcBitSize) / DstBitSize;
|
|
|
|
} else {
|
|
|
|
DstElemTy = DstTy;
|
|
|
|
DstBitSize = DstTy->getPrimitiveSizeInBits();
|
|
|
|
DstNum = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SrcNum * SrcBitSize != DstNum * DstBitSize)
|
2009-07-15 00:55:14 +08:00
|
|
|
llvm_unreachable("Invalid BitCast");
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
|
|
|
|
// If src is floating point, cast to integer first.
|
|
|
|
TempSrc.AggregateVal.resize(SrcNum);
|
|
|
|
if (SrcElemTy->isFloatTy()) {
|
|
|
|
for (unsigned i = 0; i < SrcNum; i++)
|
|
|
|
TempSrc.AggregateVal[i].IntVal =
|
|
|
|
APInt::floatToBits(SrcVec.AggregateVal[i].FloatVal);
|
|
|
|
|
|
|
|
} else if (SrcElemTy->isDoubleTy()) {
|
|
|
|
for (unsigned i = 0; i < SrcNum; i++)
|
|
|
|
TempSrc.AggregateVal[i].IntVal =
|
|
|
|
APInt::doubleToBits(SrcVec.AggregateVal[i].DoubleVal);
|
|
|
|
} else if (SrcElemTy->isIntegerTy()) {
|
|
|
|
for (unsigned i = 0; i < SrcNum; i++)
|
|
|
|
TempSrc.AggregateVal[i].IntVal = SrcVec.AggregateVal[i].IntVal;
|
|
|
|
} else {
|
|
|
|
// Pointers are not allowed as the element type of vector.
|
|
|
|
llvm_unreachable("Invalid Bitcast");
|
|
|
|
}
|
|
|
|
|
|
|
|
// now TempSrc is integer type vector
|
|
|
|
if (DstNum < SrcNum) {
|
|
|
|
// Example: bitcast <4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>
|
|
|
|
unsigned Ratio = SrcNum / DstNum;
|
|
|
|
unsigned SrcElt = 0;
|
|
|
|
for (unsigned i = 0; i < DstNum; i++) {
|
|
|
|
GenericValue Elt;
|
|
|
|
Elt.IntVal = 0;
|
|
|
|
Elt.IntVal = Elt.IntVal.zext(DstBitSize);
|
|
|
|
unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize * (Ratio - 1);
|
|
|
|
for (unsigned j = 0; j < Ratio; j++) {
|
|
|
|
APInt Tmp;
|
|
|
|
Tmp = Tmp.zext(SrcBitSize);
|
|
|
|
Tmp = TempSrc.AggregateVal[SrcElt++].IntVal;
|
|
|
|
Tmp = Tmp.zext(DstBitSize);
|
2017-04-28 11:36:24 +08:00
|
|
|
Tmp <<= ShiftAmt;
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
|
|
|
|
Elt.IntVal |= Tmp;
|
|
|
|
}
|
|
|
|
TempDst.AggregateVal.push_back(Elt);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Example: bitcast <2 x i64> <i64 0, i64 1> to <4 x i32>
|
|
|
|
unsigned Ratio = DstNum / SrcNum;
|
|
|
|
for (unsigned i = 0; i < SrcNum; i++) {
|
|
|
|
unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize * (Ratio - 1);
|
|
|
|
for (unsigned j = 0; j < Ratio; j++) {
|
|
|
|
GenericValue Elt;
|
|
|
|
Elt.IntVal = Elt.IntVal.zext(SrcBitSize);
|
|
|
|
Elt.IntVal = TempSrc.AggregateVal[i].IntVal;
|
2017-04-19 01:14:21 +08:00
|
|
|
Elt.IntVal.lshrInPlace(ShiftAmt);
|
LLVM Interpreter: This patch implements vector support for cast operations (zext, sext, uitofp, sitofp, trunc, fpext, fptosi, fptrunc, bitcast) and shift operations (shl, ashr, lshr) for integer and floating point data types.
Added tests.
Done by Yuri Veselov (mailto:Yuri.Veselov@intel.com).
llvm-svn: 187724
2013-08-05 20:17:06 +08:00
|
|
|
// it could be DstBitSize == SrcBitSize, so check it
|
|
|
|
if (DstBitSize < SrcBitSize)
|
|
|
|
Elt.IntVal = Elt.IntVal.trunc(DstBitSize);
|
|
|
|
ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
|
|
|
|
TempDst.AggregateVal.push_back(Elt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// convert result from integer to specified type
|
|
|
|
if (DstTy->getTypeID() == Type::VectorTyID) {
|
|
|
|
if (DstElemTy->isDoubleTy()) {
|
|
|
|
Dest.AggregateVal.resize(DstNum);
|
|
|
|
for (unsigned i = 0; i < DstNum; i++)
|
|
|
|
Dest.AggregateVal[i].DoubleVal =
|
|
|
|
TempDst.AggregateVal[i].IntVal.bitsToDouble();
|
|
|
|
} else if (DstElemTy->isFloatTy()) {
|
|
|
|
Dest.AggregateVal.resize(DstNum);
|
|
|
|
for (unsigned i = 0; i < DstNum; i++)
|
|
|
|
Dest.AggregateVal[i].FloatVal =
|
|
|
|
TempDst.AggregateVal[i].IntVal.bitsToFloat();
|
|
|
|
} else {
|
|
|
|
Dest = TempDst;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (DstElemTy->isDoubleTy())
|
|
|
|
Dest.DoubleVal = TempDst.AggregateVal[0].IntVal.bitsToDouble();
|
|
|
|
else if (DstElemTy->isFloatTy()) {
|
|
|
|
Dest.FloatVal = TempDst.AggregateVal[0].IntVal.bitsToFloat();
|
|
|
|
} else {
|
|
|
|
Dest.IntVal = TempDst.AggregateVal[0].IntVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else { // if ((SrcTy->getTypeID() == Type::VectorTyID) ||
|
|
|
|
// (DstTy->getTypeID() == Type::VectorTyID))
|
|
|
|
|
|
|
|
// scalar src bitcast to scalar dst
|
|
|
|
if (DstTy->isPointerTy()) {
|
|
|
|
assert(SrcTy->isPointerTy() && "Invalid BitCast");
|
|
|
|
Dest.PointerVal = Src.PointerVal;
|
|
|
|
} else if (DstTy->isIntegerTy()) {
|
|
|
|
if (SrcTy->isFloatTy())
|
|
|
|
Dest.IntVal = APInt::floatToBits(Src.FloatVal);
|
|
|
|
else if (SrcTy->isDoubleTy()) {
|
|
|
|
Dest.IntVal = APInt::doubleToBits(Src.DoubleVal);
|
|
|
|
} else if (SrcTy->isIntegerTy()) {
|
|
|
|
Dest.IntVal = Src.IntVal;
|
|
|
|
} else {
|
|
|
|
llvm_unreachable("Invalid BitCast");
|
|
|
|
}
|
|
|
|
} else if (DstTy->isFloatTy()) {
|
|
|
|
if (SrcTy->isIntegerTy())
|
|
|
|
Dest.FloatVal = Src.IntVal.bitsToFloat();
|
|
|
|
else {
|
|
|
|
Dest.FloatVal = Src.FloatVal;
|
|
|
|
}
|
|
|
|
} else if (DstTy->isDoubleTy()) {
|
|
|
|
if (SrcTy->isIntegerTy())
|
|
|
|
Dest.DoubleVal = Src.IntVal.bitsToDouble();
|
|
|
|
else {
|
|
|
|
Dest.DoubleVal = Src.DoubleVal;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
llvm_unreachable("Invalid Bitcast");
|
|
|
|
}
|
|
|
|
}
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
|
|
|
|
return Dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitTruncInst(TruncInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeTruncInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitSExtInst(SExtInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeSExtInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitZExtInst(ZExtInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeZExtInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitFPTruncInst(FPTruncInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeFPTruncInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitFPExtInst(FPExtInst &I) {
|
2003-05-11 05:22:39 +08:00
|
|
|
ExecutionContext &SF = ECStack.back();
|
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.
llvm-svn: 33113
2007-01-12 15:05:14 +08:00
|
|
|
SetValue(&I, executeFPExtInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitUIToFPInst(UIToFPInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeUIToFPInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitSIToFPInst(SIToFPInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeSIToFPInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitFPToUIInst(FPToUIInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeFPToUIInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitFPToSIInst(FPToSIInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeFPToSIInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitPtrToIntInst(PtrToIntInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executePtrToIntInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitIntToPtrInst(IntToPtrInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeIntToPtrInst(I.getOperand(0), I.getType(), SF), SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitBitCastInst(BitCastInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
SetValue(&I, executeBitCastInst(I.getOperand(0), I.getType(), SF), SF);
|
2002-08-28 06:33:45 +08:00
|
|
|
}
|
2001-08-24 01:05:04 +08:00
|
|
|
|
2003-11-08 05:20:47 +08:00
|
|
|
#define IMPLEMENT_VAARG(TY) \
|
|
|
|
case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break
|
|
|
|
|
|
|
|
void Interpreter::visitVAArgInst(VAArgInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
|
2004-02-26 07:01:48 +08:00
|
|
|
// Get the incoming valist parameter. LLI treats the valist as a
|
|
|
|
// (ec-stack-depth var-arg-index) pair.
|
2003-11-08 05:20:47 +08:00
|
|
|
GenericValue VAList = getOperandValue(I.getOperand(0), SF);
|
2004-02-26 07:01:48 +08:00
|
|
|
GenericValue Dest;
|
|
|
|
GenericValue Src = ECStack[VAList.UIntPairVal.first]
|
2007-03-06 11:09:31 +08:00
|
|
|
.VarArgs[VAList.UIntPairVal.second];
|
2011-07-18 12:54:35 +08:00
|
|
|
Type *Ty = I.getType();
|
2004-06-18 02:19:28 +08:00
|
|
|
switch (Ty->getTypeID()) {
|
2013-02-01 03:46:59 +08:00
|
|
|
case Type::IntegerTyID:
|
|
|
|
Dest.IntVal = Src.IntVal;
|
|
|
|
break;
|
2013-02-02 02:57:06 +08:00
|
|
|
IMPLEMENT_VAARG(Pointer);
|
|
|
|
IMPLEMENT_VAARG(Float);
|
|
|
|
IMPLEMENT_VAARG(Double);
|
2003-11-08 05:20:47 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2003-11-08 05:20:47 +08:00
|
|
|
}
|
2005-04-22 06:43:08 +08:00
|
|
|
|
2003-11-08 05:20:47 +08:00
|
|
|
// Set the Value of this Instruction.
|
|
|
|
SetValue(&I, Dest, SF);
|
2005-06-19 02:34:52 +08:00
|
|
|
|
|
|
|
// Move the pointer to the next vararg.
|
|
|
|
++VAList.UIntPairVal.second;
|
2003-11-08 05:20:47 +08:00
|
|
|
}
|
|
|
|
|
2013-04-01 23:53:30 +08:00
|
|
|
void Interpreter::visitExtractElementInst(ExtractElementInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Dest;
|
|
|
|
|
|
|
|
Type *Ty = I.getType();
|
|
|
|
const unsigned indx = unsigned(Src2.IntVal.getZExtValue());
|
|
|
|
|
|
|
|
if(Src1.AggregateVal.size() > indx) {
|
|
|
|
switch (Ty->getTypeID()) {
|
|
|
|
default:
|
|
|
|
dbgs() << "Unhandled destination type for extractelement instruction: "
|
|
|
|
<< *Ty << "\n";
|
2014-04-28 12:05:08 +08:00
|
|
|
llvm_unreachable(nullptr);
|
2013-04-01 23:53:30 +08:00
|
|
|
break;
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
Dest.IntVal = Src1.AggregateVal[indx].IntVal;
|
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
Dest.FloatVal = Src1.AggregateVal[indx].FloatVal;
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
Dest.DoubleVal = Src1.AggregateVal[indx].DoubleVal;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dbgs() << "Invalid index in extractelement instruction\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
2013-09-02 14:40:09 +08:00
|
|
|
void Interpreter::visitInsertElementInst(InsertElementInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
Type *Ty = I.getType();
|
|
|
|
|
|
|
|
if(!(Ty->isVectorTy()) )
|
|
|
|
llvm_unreachable("Unhandled dest type for insertelement instruction");
|
|
|
|
|
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
|
|
|
|
GenericValue Dest;
|
|
|
|
|
|
|
|
Type *TyContained = Ty->getContainedType(0);
|
|
|
|
|
|
|
|
const unsigned indx = unsigned(Src3.IntVal.getZExtValue());
|
|
|
|
Dest.AggregateVal = Src1.AggregateVal;
|
|
|
|
|
|
|
|
if(Src1.AggregateVal.size() <= indx)
|
|
|
|
llvm_unreachable("Invalid index in insertelement instruction");
|
|
|
|
switch (TyContained->getTypeID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled dest type for insertelement instruction");
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
Dest.AggregateVal[indx].IntVal = Src2.IntVal;
|
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
Dest.AggregateVal[indx].FloatVal = Src2.FloatVal;
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
Dest.AggregateVal[indx].DoubleVal = Src2.DoubleVal;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
|
|
|
|
Type *Ty = I.getType();
|
|
|
|
if(!(Ty->isVectorTy()))
|
|
|
|
llvm_unreachable("Unhandled dest type for shufflevector instruction");
|
|
|
|
|
|
|
|
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
|
|
|
|
GenericValue Dest;
|
|
|
|
|
|
|
|
// There is no need to check types of src1 and src2, because the compiled
|
|
|
|
// bytecode can't contain different types for src1 and src2 for a
|
|
|
|
// shufflevector instruction.
|
|
|
|
|
|
|
|
Type *TyContained = Ty->getContainedType(0);
|
|
|
|
unsigned src1Size = (unsigned)Src1.AggregateVal.size();
|
|
|
|
unsigned src2Size = (unsigned)Src2.AggregateVal.size();
|
|
|
|
unsigned src3Size = (unsigned)Src3.AggregateVal.size();
|
|
|
|
|
|
|
|
Dest.AggregateVal.resize(src3Size);
|
|
|
|
|
|
|
|
switch (TyContained->getTypeID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled dest type for insertelement instruction");
|
|
|
|
break;
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
for( unsigned i=0; i<src3Size; i++) {
|
|
|
|
unsigned j = Src3.AggregateVal[i].IntVal.getZExtValue();
|
|
|
|
if(j < src1Size)
|
|
|
|
Dest.AggregateVal[i].IntVal = Src1.AggregateVal[j].IntVal;
|
|
|
|
else if(j < src1Size + src2Size)
|
|
|
|
Dest.AggregateVal[i].IntVal = Src2.AggregateVal[j-src1Size].IntVal;
|
|
|
|
else
|
|
|
|
// The selector may not be greater than sum of lengths of first and
|
|
|
|
// second operands and llasm should not allow situation like
|
|
|
|
// %tmp = shufflevector <2 x i32> <i32 3, i32 4>, <2 x i32> undef,
|
|
|
|
// <2 x i32> < i32 0, i32 5 >,
|
|
|
|
// where i32 5 is invalid, but let it be additional check here:
|
|
|
|
llvm_unreachable("Invalid mask in shufflevector instruction");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
for( unsigned i=0; i<src3Size; i++) {
|
|
|
|
unsigned j = Src3.AggregateVal[i].IntVal.getZExtValue();
|
|
|
|
if(j < src1Size)
|
|
|
|
Dest.AggregateVal[i].FloatVal = Src1.AggregateVal[j].FloatVal;
|
|
|
|
else if(j < src1Size + src2Size)
|
|
|
|
Dest.AggregateVal[i].FloatVal = Src2.AggregateVal[j-src1Size].FloatVal;
|
|
|
|
else
|
|
|
|
llvm_unreachable("Invalid mask in shufflevector instruction");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
for( unsigned i=0; i<src3Size; i++) {
|
|
|
|
unsigned j = Src3.AggregateVal[i].IntVal.getZExtValue();
|
|
|
|
if(j < src1Size)
|
|
|
|
Dest.AggregateVal[i].DoubleVal = Src1.AggregateVal[j].DoubleVal;
|
|
|
|
else if(j < src1Size + src2Size)
|
|
|
|
Dest.AggregateVal[i].DoubleVal =
|
|
|
|
Src2.AggregateVal[j-src1Size].DoubleVal;
|
|
|
|
else
|
|
|
|
llvm_unreachable("Invalid mask in shufflevector instruction");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
2013-09-12 18:48:23 +08:00
|
|
|
void Interpreter::visitExtractValueInst(ExtractValueInst &I) {
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
Value *Agg = I.getAggregateOperand();
|
|
|
|
GenericValue Dest;
|
|
|
|
GenericValue Src = getOperandValue(Agg, SF);
|
|
|
|
|
|
|
|
ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
|
|
|
|
unsigned Num = I.getNumIndices();
|
|
|
|
GenericValue *pSrc = &Src;
|
|
|
|
|
|
|
|
for (unsigned i = 0 ; i < Num; ++i) {
|
|
|
|
pSrc = &pSrc->AggregateVal[*IdxBegin];
|
|
|
|
++IdxBegin;
|
|
|
|
}
|
|
|
|
|
|
|
|
Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
|
|
|
|
switch (IndexedType->getTypeID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled dest type for extractelement instruction");
|
|
|
|
break;
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
Dest.IntVal = pSrc->IntVal;
|
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
Dest.FloatVal = pSrc->FloatVal;
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
Dest.DoubleVal = pSrc->DoubleVal;
|
|
|
|
break;
|
|
|
|
case Type::ArrayTyID:
|
|
|
|
case Type::StructTyID:
|
|
|
|
case Type::VectorTyID:
|
|
|
|
Dest.AggregateVal = pSrc->AggregateVal;
|
|
|
|
break;
|
|
|
|
case Type::PointerTyID:
|
|
|
|
Dest.PointerVal = pSrc->PointerVal;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interpreter::visitInsertValueInst(InsertValueInst &I) {
|
|
|
|
|
|
|
|
ExecutionContext &SF = ECStack.back();
|
|
|
|
Value *Agg = I.getAggregateOperand();
|
|
|
|
|
|
|
|
GenericValue Src1 = getOperandValue(Agg, SF);
|
|
|
|
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
|
|
|
GenericValue Dest = Src1; // Dest is a slightly changed Src1
|
|
|
|
|
|
|
|
ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
|
|
|
|
unsigned Num = I.getNumIndices();
|
|
|
|
|
|
|
|
GenericValue *pDest = &Dest;
|
|
|
|
for (unsigned i = 0 ; i < Num; ++i) {
|
|
|
|
pDest = &pDest->AggregateVal[*IdxBegin];
|
|
|
|
++IdxBegin;
|
|
|
|
}
|
|
|
|
// pDest points to the target value in the Dest now
|
|
|
|
|
|
|
|
Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
|
|
|
|
|
|
|
|
switch (IndexedType->getTypeID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled dest type for insertelement instruction");
|
|
|
|
break;
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
pDest->IntVal = Src2.IntVal;
|
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
pDest->FloatVal = Src2.FloatVal;
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
pDest->DoubleVal = Src2.DoubleVal;
|
|
|
|
break;
|
|
|
|
case Type::ArrayTyID:
|
|
|
|
case Type::StructTyID:
|
|
|
|
case Type::VectorTyID:
|
|
|
|
pDest->AggregateVal = Src2.AggregateVal;
|
|
|
|
break;
|
|
|
|
case Type::PointerTyID:
|
|
|
|
pDest->PointerVal = Src2.PointerVal;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetValue(&I, Dest, SF);
|
|
|
|
}
|
|
|
|
|
2007-03-03 14:22:22 +08:00
|
|
|
GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
|
|
|
|
ExecutionContext &SF) {
|
|
|
|
switch (CE->getOpcode()) {
|
2013-09-02 14:40:09 +08:00
|
|
|
case Instruction::Trunc:
|
2007-03-03 14:22:22 +08:00
|
|
|
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 executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
|
|
|
|
case Instruction::GetElementPtr:
|
|
|
|
return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
|
|
|
|
gep_type_end(CE), SF);
|
2007-03-03 16:38:04 +08:00
|
|
|
case Instruction::FCmp:
|
|
|
|
case Instruction::ICmp:
|
|
|
|
return executeCmpInst(CE->getPredicate(),
|
|
|
|
getOperandValue(CE->getOperand(0), SF),
|
|
|
|
getOperandValue(CE->getOperand(1), SF),
|
|
|
|
CE->getOperand(0)->getType());
|
|
|
|
case Instruction::Select:
|
|
|
|
return executeSelectInst(getOperandValue(CE->getOperand(0), SF),
|
|
|
|
getOperandValue(CE->getOperand(1), SF),
|
2013-09-02 14:40:09 +08:00
|
|
|
getOperandValue(CE->getOperand(2), SF),
|
|
|
|
CE->getOperand(0)->getType());
|
2007-03-03 14:22:22 +08:00
|
|
|
default :
|
|
|
|
break;
|
|
|
|
}
|
2007-03-03 16:38:04 +08:00
|
|
|
|
|
|
|
// The cases below here require a GenericValue parameter for the result
|
|
|
|
// so we initialize one, compute it and then return it.
|
2007-03-06 11:09:31 +08:00
|
|
|
GenericValue Op0 = getOperandValue(CE->getOperand(0), SF);
|
|
|
|
GenericValue Op1 = getOperandValue(CE->getOperand(1), SF);
|
2007-03-03 14:22:22 +08:00
|
|
|
GenericValue Dest;
|
2011-07-18 12:54:35 +08:00
|
|
|
Type * Ty = CE->getOperand(0)->getType();
|
2007-03-03 14:22:22 +08:00
|
|
|
switch (CE->getOpcode()) {
|
2009-06-05 06:49:04 +08:00
|
|
|
case Instruction::Add: Dest.IntVal = Op0.IntVal + Op1.IntVal; break;
|
|
|
|
case Instruction::Sub: Dest.IntVal = Op0.IntVal - Op1.IntVal; break;
|
|
|
|
case Instruction::Mul: Dest.IntVal = Op0.IntVal * Op1.IntVal; break;
|
|
|
|
case Instruction::FAdd: executeFAddInst(Dest, Op0, Op1, Ty); break;
|
|
|
|
case Instruction::FSub: executeFSubInst(Dest, Op0, Op1, Ty); break;
|
|
|
|
case Instruction::FMul: executeFMulInst(Dest, Op0, Op1, Ty); break;
|
2007-03-06 11:09:31 +08:00
|
|
|
case Instruction::FDiv: executeFDivInst(Dest, Op0, Op1, Ty); break;
|
|
|
|
case Instruction::FRem: executeFRemInst(Dest, Op0, Op1, Ty); break;
|
|
|
|
case Instruction::SDiv: Dest.IntVal = Op0.IntVal.sdiv(Op1.IntVal); break;
|
|
|
|
case Instruction::UDiv: Dest.IntVal = Op0.IntVal.udiv(Op1.IntVal); break;
|
|
|
|
case Instruction::URem: Dest.IntVal = Op0.IntVal.urem(Op1.IntVal); break;
|
|
|
|
case Instruction::SRem: Dest.IntVal = Op0.IntVal.srem(Op1.IntVal); break;
|
2009-06-05 06:49:04 +08:00
|
|
|
case Instruction::And: Dest.IntVal = Op0.IntVal & Op1.IntVal; break;
|
|
|
|
case Instruction::Or: Dest.IntVal = Op0.IntVal | Op1.IntVal; break;
|
|
|
|
case Instruction::Xor: Dest.IntVal = Op0.IntVal ^ Op1.IntVal; break;
|
2007-03-06 11:09:31 +08:00
|
|
|
case Instruction::Shl:
|
|
|
|
Dest.IntVal = Op0.IntVal.shl(Op1.IntVal.getZExtValue());
|
|
|
|
break;
|
|
|
|
case Instruction::LShr:
|
|
|
|
Dest.IntVal = Op0.IntVal.lshr(Op1.IntVal.getZExtValue());
|
|
|
|
break;
|
|
|
|
case Instruction::AShr:
|
|
|
|
Dest.IntVal = Op0.IntVal.ashr(Op1.IntVal.getZExtValue());
|
|
|
|
break;
|
2007-03-03 14:22:22 +08:00
|
|
|
default:
|
2010-01-05 09:27:23 +08:00
|
|
|
dbgs() << "Unhandled ConstantExpr: " << *CE << "\n";
|
2012-02-19 19:37:01 +08:00
|
|
|
llvm_unreachable("Unhandled ConstantExpr");
|
2007-03-03 14:22:22 +08:00
|
|
|
}
|
2007-03-03 16:38:04 +08:00
|
|
|
return Dest;
|
2007-03-03 14:22:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
|
|
|
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
|
|
|
return getConstantExprValue(CE, SF);
|
|
|
|
} else if (Constant *CPV = dyn_cast<Constant>(V)) {
|
|
|
|
return getConstantValue(CPV);
|
|
|
|
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
|
|
|
|
return PTOGV(getPointerToGlobal(GV));
|
|
|
|
} else {
|
|
|
|
return SF.Values[V];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-24 01:05:04 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Dispatch and Execution Code
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2003-05-09 00:18:31 +08:00
|
|
|
// callFunction - Execute the specified function...
|
2001-08-24 01:05:04 +08:00
|
|
|
//
|
2015-06-14 03:50:29 +08:00
|
|
|
void Interpreter::callFunction(Function *F, ArrayRef<GenericValue> ArgVals) {
|
2014-04-28 12:05:08 +08:00
|
|
|
assert((ECStack.empty() || !ECStack.back().Caller.getInstruction() ||
|
2005-04-22 06:43:08 +08:00
|
|
|
ECStack.back().Caller.arg_size() == ArgVals.size()) &&
|
|
|
|
"Incorrect number of arguments passed into function call!");
|
2003-09-18 01:26:22 +08:00
|
|
|
// Make a new stack frame... and fill it in.
|
2015-05-30 03:43:39 +08:00
|
|
|
ECStack.emplace_back();
|
2003-09-18 01:26:22 +08:00
|
|
|
ExecutionContext &StackFrame = ECStack.back();
|
2003-05-09 00:18:31 +08:00
|
|
|
StackFrame.CurFunction = F;
|
2003-11-07 13:22:49 +08:00
|
|
|
|
|
|
|
// Special handling for external functions.
|
2007-01-31 04:08:39 +08:00
|
|
|
if (F->isDeclaration()) {
|
2003-11-07 13:22:49 +08:00
|
|
|
GenericValue Result = callExternalFunction (F, ArgVals);
|
|
|
|
// Simulate a 'ret' instruction of the appropriate type.
|
|
|
|
popStackAndReturnValueToCaller (F->getReturnType (), Result);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get pointers to first LLVM BB & Instruction in function.
|
2015-10-14 01:33:41 +08:00
|
|
|
StackFrame.CurBB = &F->front();
|
2001-08-24 01:05:04 +08:00
|
|
|
StackFrame.CurInst = StackFrame.CurBB->begin();
|
2001-09-10 12:49:44 +08:00
|
|
|
|
2002-04-08 04:49:59 +08:00
|
|
|
// Run through the function arguments and initialize their values...
|
2005-03-15 12:54:21 +08:00
|
|
|
assert((ArgVals.size() == F->arg_size() ||
|
2005-04-22 06:43:08 +08:00
|
|
|
(ArgVals.size() > F->arg_size() && F->getFunctionType()->isVarArg()))&&
|
2002-04-08 04:49:59 +08:00
|
|
|
"Invalid number of values passed to function invocation!");
|
2003-05-09 00:06:52 +08:00
|
|
|
|
|
|
|
// Handle non-varargs arguments...
|
2001-09-10 12:49:44 +08:00
|
|
|
unsigned i = 0;
|
2007-04-17 05:50:40 +08:00
|
|
|
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
|
|
|
|
AI != E; ++AI, ++i)
|
2015-10-14 01:33:41 +08:00
|
|
|
SetValue(&*AI, ArgVals[i], StackFrame);
|
2003-05-09 00:06:52 +08:00
|
|
|
|
|
|
|
// Handle varargs arguments...
|
|
|
|
StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end());
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
|
2007-05-16 10:05:13 +08:00
|
|
|
|
2001-08-24 01:05:04 +08:00
|
|
|
void Interpreter::run() {
|
2003-09-05 07:15:40 +08:00
|
|
|
while (!ECStack.empty()) {
|
2003-10-25 03:59:01 +08:00
|
|
|
// Interpret a single instruction & increment the "PC".
|
|
|
|
ExecutionContext &SF = ECStack.back(); // Current stack frame
|
|
|
|
Instruction &I = *SF.CurInst++; // Increment before execute
|
2005-04-22 06:43:08 +08:00
|
|
|
|
2003-10-25 03:59:01 +08:00
|
|
|
// Track the number of dynamic instructions executed.
|
|
|
|
++NumDynamicInsts;
|
2001-08-24 01:05:04 +08:00
|
|
|
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "About to interpret: " << I);
|
2003-10-25 03:59:01 +08:00
|
|
|
visit(I); // Dispatch to one of the visit* methods...
|
2001-08-24 01:05:04 +08:00
|
|
|
}
|
|
|
|
}
|