mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge branch 'master' into wip
Conflicts: src/compile.cpp src/compiler.cpp src/machine.h src/x86.cpp
This commit is contained in:
commit
325f93b4d1
@ -43,7 +43,14 @@ enum UnaryOperation {
|
|||||||
JumpIfLessOrEqual,
|
JumpIfLessOrEqual,
|
||||||
JumpIfGreaterOrEqual,
|
JumpIfGreaterOrEqual,
|
||||||
JumpIfEqual,
|
JumpIfEqual,
|
||||||
JumpIfNotEqual
|
JumpIfNotEqual,
|
||||||
|
JumpIfFloatUnordered,
|
||||||
|
JumpIfFloatLess,
|
||||||
|
JumpIfFloatGreater,
|
||||||
|
JumpIfFloatLessOrEqual,
|
||||||
|
JumpIfFloatGreaterOrEqual,
|
||||||
|
JumpIfFloatEqual,
|
||||||
|
JumpIfFloatNotEqual,
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned UnaryOperationCount = JumpIfNotEqual + 1;
|
const unsigned UnaryOperationCount = JumpIfNotEqual + 1;
|
||||||
@ -52,10 +59,24 @@ enum BinaryOperation {
|
|||||||
Move,
|
Move,
|
||||||
MoveZ,
|
MoveZ,
|
||||||
Compare,
|
Compare,
|
||||||
Negate
|
Negate,
|
||||||
|
|
||||||
|
//extensions:
|
||||||
|
FloatNegate,
|
||||||
|
FloatCompare,
|
||||||
|
Float2Float,
|
||||||
|
Float2Int,
|
||||||
|
Int2Float,
|
||||||
|
|
||||||
|
//intrinsic functions:
|
||||||
|
FloatSqrt,
|
||||||
|
FloatAbs,
|
||||||
|
Abs,
|
||||||
|
|
||||||
|
NoBinaryOperation = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned BinaryOperationCount = Negate + 1;
|
const unsigned BinaryOperationCount = Abs + 1;
|
||||||
|
|
||||||
enum TernaryOperation {
|
enum TernaryOperation {
|
||||||
LongCompare,
|
LongCompare,
|
||||||
@ -69,10 +90,23 @@ enum TernaryOperation {
|
|||||||
UnsignedShiftRight,
|
UnsignedShiftRight,
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
Xor
|
Xor,
|
||||||
|
|
||||||
|
//extensions:
|
||||||
|
FloatAdd,
|
||||||
|
FloatSubtract,
|
||||||
|
FloatMultiply,
|
||||||
|
FloatDivide,
|
||||||
|
FloatRemainder,
|
||||||
|
|
||||||
|
//intrinsic functions:
|
||||||
|
FloatMax,
|
||||||
|
FloatMin,
|
||||||
|
|
||||||
|
NoTernaryOperation = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned TernaryOperationCount = Xor + 1;
|
const unsigned TernaryOperationCount = FloatMin + 1;
|
||||||
|
|
||||||
enum OperandType {
|
enum OperandType {
|
||||||
ConstantOperand,
|
ConstantOperand,
|
||||||
@ -259,6 +293,11 @@ class Assembler {
|
|||||||
class Architecture {
|
class Architecture {
|
||||||
public:
|
public:
|
||||||
virtual unsigned registerCount() = 0;
|
virtual unsigned registerCount() = 0;
|
||||||
|
virtual unsigned generalRegisterCount() = 0;
|
||||||
|
virtual unsigned floatRegisterCount() = 0;
|
||||||
|
virtual uint64_t generalRegisters() = 0;
|
||||||
|
virtual uint64_t floatRegisters() = 0;
|
||||||
|
virtual uint64_t allRegisters() = 0;
|
||||||
|
|
||||||
virtual int stack() = 0;
|
virtual int stack() = 0;
|
||||||
virtual int thread() = 0;
|
virtual int thread() = 0;
|
||||||
@ -267,10 +306,13 @@ class Assembler {
|
|||||||
virtual int virtualCallTarget() = 0;
|
virtual int virtualCallTarget() = 0;
|
||||||
virtual int virtualCallIndex() = 0;
|
virtual int virtualCallIndex() = 0;
|
||||||
|
|
||||||
virtual bool condensedAddressing() = 0;
|
|
||||||
|
|
||||||
virtual bool bigEndian() = 0;
|
virtual bool bigEndian() = 0;
|
||||||
|
|
||||||
|
virtual bool supportsFloatCompare(unsigned size) = 0;
|
||||||
|
|
||||||
|
virtual bool alwaysCondensed(BinaryOperation op) = 0;
|
||||||
|
virtual bool alwaysCondensed(TernaryOperation op) = 0;
|
||||||
|
|
||||||
virtual bool reserved(int register_) = 0;
|
virtual bool reserved(int register_) = 0;
|
||||||
|
|
||||||
virtual unsigned frameFootprint(unsigned footprint) = 0;
|
virtual unsigned frameFootprint(unsigned footprint) = 0;
|
||||||
@ -298,23 +340,40 @@ class Assembler {
|
|||||||
virtual int framePointerOffset() = 0;
|
virtual int framePointerOffset() = 0;
|
||||||
virtual void nextFrame(void** stack, void** base) = 0;
|
virtual void nextFrame(void** stack, void** base) = 0;
|
||||||
|
|
||||||
|
virtual BinaryOperation binaryIntrinsic(const char* className,
|
||||||
|
const char* methodName,
|
||||||
|
const char* parameterSpec) = 0;
|
||||||
|
|
||||||
|
virtual TernaryOperation ternaryIntrinsic(const char* className,
|
||||||
|
const char* methodName,
|
||||||
|
const char* parameterSpec) = 0;
|
||||||
|
|
||||||
virtual void plan
|
virtual void plan
|
||||||
(UnaryOperation op,
|
(UnaryOperation op,
|
||||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
bool* thunk) = 0;
|
bool* thunk) = 0;
|
||||||
|
|
||||||
virtual void plan
|
virtual void planSource
|
||||||
(BinaryOperation op,
|
(BinaryOperation op,
|
||||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
unsigned bSize, bool* thunk) = 0;
|
||||||
bool* thunk) = 0;
|
|
||||||
|
|
||||||
virtual void plan
|
virtual void planDestination
|
||||||
|
(BinaryOperation op,
|
||||||
|
unsigned aSize, const uint8_t* aTypeMask, const uint64_t* aRegisterMask,
|
||||||
|
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask) = 0;
|
||||||
|
|
||||||
|
virtual void planSource
|
||||||
(TernaryOperation op,
|
(TernaryOperation op,
|
||||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
||||||
unsigned cSize, uint8_t* cTypeMask, uint64_t* cRegisterMask,
|
unsigned cSize, bool* thunk) = 0;
|
||||||
bool* thunk) = 0;
|
|
||||||
|
virtual void planDestination
|
||||||
|
(TernaryOperation op,
|
||||||
|
unsigned aSize, const uint8_t* aTypeMask, const uint64_t* aRegisterMask,
|
||||||
|
unsigned bSize, const uint8_t* bTypeMask, const uint64_t* bRegisterMask,
|
||||||
|
unsigned cSize, uint8_t* cTypeMask, uint64_t* cRegisterMask) = 0;
|
||||||
|
|
||||||
virtual void acquire() = 0;
|
virtual void acquire() = 0;
|
||||||
virtual void release() = 0;
|
virtual void release() = 0;
|
||||||
|
824
src/compile.cpp
824
src/compile.cpp
File diff suppressed because it is too large
Load Diff
598
src/compiler.cpp
598
src/compiler.cpp
File diff suppressed because it is too large
Load Diff
@ -27,13 +27,24 @@ class Compiler {
|
|||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0;
|
virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0;
|
||||||
virtual intptr_t getThunk(TernaryOperation op, unsigned size) = 0;
|
virtual intptr_t getThunk(BinaryOperation op, unsigned size,
|
||||||
|
unsigned resultSize) = 0;
|
||||||
|
virtual intptr_t getThunk(TernaryOperation op, unsigned size,
|
||||||
|
unsigned resultSize) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned Aligned = 1 << 0;
|
static const unsigned Aligned = 1 << 0;
|
||||||
static const unsigned NoReturn = 1 << 1;
|
static const unsigned NoReturn = 1 << 1;
|
||||||
static const unsigned TailJump = 1 << 2;
|
static const unsigned TailJump = 1 << 2;
|
||||||
|
|
||||||
|
enum OperandType {
|
||||||
|
ObjectType,
|
||||||
|
AddressType,
|
||||||
|
IntegerType,
|
||||||
|
FloatType,
|
||||||
|
VoidType
|
||||||
|
};
|
||||||
|
|
||||||
class Operand { };
|
class Operand { };
|
||||||
class State { };
|
class State { };
|
||||||
class Subroutine { };
|
class Subroutine { };
|
||||||
@ -56,10 +67,11 @@ class Compiler {
|
|||||||
virtual Promise* poolAppend(intptr_t value) = 0;
|
virtual Promise* poolAppend(intptr_t value) = 0;
|
||||||
virtual Promise* poolAppendPromise(Promise* value) = 0;
|
virtual Promise* poolAppendPromise(Promise* value) = 0;
|
||||||
|
|
||||||
virtual Operand* constant(int64_t value) = 0;
|
virtual Operand* constant(int64_t value, OperandType type) = 0;
|
||||||
virtual Operand* promiseConstant(Promise* value) = 0;
|
virtual Operand* promiseConstant(Promise* value, OperandType type) = 0;
|
||||||
virtual Operand* address(Promise* address) = 0;
|
virtual Operand* address(Promise* address) = 0;
|
||||||
virtual Operand* memory(Operand* base,
|
virtual Operand* memory(Operand* base,
|
||||||
|
OperandType type,
|
||||||
int displacement = 0,
|
int displacement = 0,
|
||||||
Operand* index = 0,
|
Operand* index = 0,
|
||||||
unsigned scale = 1) = 0;
|
unsigned scale = 1) = 0;
|
||||||
@ -79,6 +91,7 @@ class Compiler {
|
|||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
unsigned resultSize,
|
unsigned resultSize,
|
||||||
|
OperandType resultType,
|
||||||
unsigned argumentCount,
|
unsigned argumentCount,
|
||||||
...) = 0;
|
...) = 0;
|
||||||
|
|
||||||
@ -86,11 +99,12 @@ class Compiler {
|
|||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
unsigned resultSize,
|
unsigned resultSize,
|
||||||
|
OperandType resultType,
|
||||||
unsigned argumentFootprint) = 0;
|
unsigned argumentFootprint) = 0;
|
||||||
|
|
||||||
virtual void return_(unsigned size, Operand* value) = 0;
|
virtual void return_(unsigned size, Operand* value) = 0;
|
||||||
|
|
||||||
virtual void initLocal(unsigned size, unsigned index) = 0;
|
virtual void initLocal(unsigned size, unsigned index, OperandType type) = 0;
|
||||||
virtual void initLocalsFromLogicalIp(unsigned logicalIp) = 0;
|
virtual void initLocalsFromLogicalIp(unsigned logicalIp) = 0;
|
||||||
virtual void storeLocal(unsigned footprint, Operand* src,
|
virtual void storeLocal(unsigned footprint, Operand* src,
|
||||||
unsigned index) = 0;
|
unsigned index) = 0;
|
||||||
@ -108,12 +122,20 @@ class Compiler {
|
|||||||
unsigned dstSize) = 0;
|
unsigned dstSize) = 0;
|
||||||
virtual Operand* lcmp(Operand* a, Operand* b) = 0;
|
virtual Operand* lcmp(Operand* a, Operand* b) = 0;
|
||||||
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
|
virtual void fcmp(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual void jl(Operand* address) = 0;
|
virtual void jl(Operand* address) = 0;
|
||||||
virtual void jg(Operand* address) = 0;
|
virtual void jg(Operand* address) = 0;
|
||||||
virtual void jle(Operand* address) = 0;
|
virtual void jle(Operand* address) = 0;
|
||||||
virtual void jge(Operand* address) = 0;
|
virtual void jge(Operand* address) = 0;
|
||||||
virtual void je(Operand* address) = 0;
|
virtual void je(Operand* address) = 0;
|
||||||
virtual void jne(Operand* address) = 0;
|
virtual void jne(Operand* address) = 0;
|
||||||
|
virtual void fjl(Operand* address) = 0;
|
||||||
|
virtual void fjg(Operand* address) = 0;
|
||||||
|
virtual void fjle(Operand* address) = 0;
|
||||||
|
virtual void fjge(Operand* address) = 0;
|
||||||
|
virtual void fje(Operand* address) = 0;
|
||||||
|
virtual void fjne(Operand* address) = 0;
|
||||||
|
virtual void fjuo(Operand* address) = 0;
|
||||||
virtual void jmp(Operand* address) = 0;
|
virtual void jmp(Operand* address) = 0;
|
||||||
virtual void exit(Operand* address) = 0;
|
virtual void exit(Operand* address) = 0;
|
||||||
virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
@ -121,6 +143,11 @@ class Compiler {
|
|||||||
virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* div(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* div(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* rem(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* rem(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
|
virtual Operand* fadd(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
|
virtual Operand* fsub(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
|
virtual Operand* fmul(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
|
virtual Operand* fdiv(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
|
virtual Operand* frem(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* shl(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* shl(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* shr(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* shr(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
@ -128,6 +155,16 @@ class Compiler {
|
|||||||
virtual Operand* or_(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* or_(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) = 0;
|
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual Operand* neg(unsigned size, Operand* a) = 0;
|
virtual Operand* neg(unsigned size, Operand* a) = 0;
|
||||||
|
virtual Operand* fneg(unsigned size, Operand* a) = 0;
|
||||||
|
virtual Operand* operation(BinaryOperation op, unsigned aSize,
|
||||||
|
unsigned resSize, OperandType resType,
|
||||||
|
Operand* a) = 0;
|
||||||
|
virtual Operand* operation(TernaryOperation op, unsigned aSize,
|
||||||
|
unsigned bSize, unsigned resSize,
|
||||||
|
OperandType resType, Operand* a, Operand* b) = 0;
|
||||||
|
virtual Operand* f2f(unsigned aSize, unsigned resSize, Operand* a) = 0;
|
||||||
|
virtual Operand* f2i(unsigned aSize, unsigned resSize, Operand* a) = 0;
|
||||||
|
virtual Operand* i2f(unsigned aSize, unsigned resSize, Operand* a) = 0;
|
||||||
|
|
||||||
virtual void loadBarrier() = 0;
|
virtual void loadBarrier() = 0;
|
||||||
virtual void storeStoreBarrier() = 0;
|
virtual void storeStoreBarrier() = 0;
|
||||||
|
@ -826,8 +826,13 @@ object
|
|||||||
parsePool(Thread* t, Stream& s)
|
parsePool(Thread* t, Stream& s)
|
||||||
{
|
{
|
||||||
unsigned count = s.read2() - 1;
|
unsigned count = s.read2() - 1;
|
||||||
|
unsigned old;
|
||||||
object pool = makeSingletonOfSize(t, count);
|
unsigned floatMaskSize = 0;
|
||||||
|
do {
|
||||||
|
old = floatMaskSize;
|
||||||
|
floatMaskSize = singletonMaskSize(count + floatMaskSize);
|
||||||
|
} while (floatMaskSize != old);
|
||||||
|
object pool = makeSingletonOfSize(t, count + floatMaskSize);
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
@ -839,12 +844,18 @@ parsePool(Thread* t, Stream& s)
|
|||||||
switch (s.read1()) {
|
switch (s.read1()) {
|
||||||
case CONSTANT_Class:
|
case CONSTANT_Class:
|
||||||
case CONSTANT_String:
|
case CONSTANT_String:
|
||||||
|
assert(t, !singletonIsFloat(t, pool, i));
|
||||||
singletonMarkObject(t, pool, i);
|
singletonMarkObject(t, pool, i);
|
||||||
s.skip(2);
|
s.skip(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONSTANT_Integer:
|
case CONSTANT_Integer:
|
||||||
|
assert(t, !singletonIsFloat(t, pool, i));
|
||||||
|
s.skip(4);
|
||||||
|
break;
|
||||||
case CONSTANT_Float:
|
case CONSTANT_Float:
|
||||||
|
singletonMarkBit(t, pool, count, i);
|
||||||
|
assert(t, singletonIsFloat(t, pool, i));
|
||||||
s.skip(4);
|
s.skip(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -852,17 +863,27 @@ parsePool(Thread* t, Stream& s)
|
|||||||
case CONSTANT_Fieldref:
|
case CONSTANT_Fieldref:
|
||||||
case CONSTANT_Methodref:
|
case CONSTANT_Methodref:
|
||||||
case CONSTANT_InterfaceMethodref:
|
case CONSTANT_InterfaceMethodref:
|
||||||
|
assert(t, !singletonIsFloat(t, pool, i));
|
||||||
singletonMarkObject(t, pool, i);
|
singletonMarkObject(t, pool, i);
|
||||||
s.skip(4);
|
s.skip(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONSTANT_Long:
|
case CONSTANT_Long:
|
||||||
|
assert(t, !singletonIsFloat(t, pool, i));
|
||||||
|
s.skip(8);
|
||||||
|
++ i;
|
||||||
|
break;
|
||||||
case CONSTANT_Double:
|
case CONSTANT_Double:
|
||||||
|
singletonMarkBit(t, pool, count, i);
|
||||||
|
singletonMarkBit(t, pool, count, i + 1);
|
||||||
|
assert(t, singletonIsFloat(t, pool, i));
|
||||||
|
assert(t, singletonIsFloat(t, pool, i + 1));
|
||||||
s.skip(8);
|
s.skip(8);
|
||||||
++ i;
|
++ i;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONSTANT_Utf8:
|
case CONSTANT_Utf8:
|
||||||
|
assert(t, !singletonIsFloat(t, pool, i));
|
||||||
singletonMarkObject(t, pool, i);
|
singletonMarkObject(t, pool, i);
|
||||||
s.skip(s.read2());
|
s.skip(s.read2());
|
||||||
break;
|
break;
|
||||||
|
@ -2530,6 +2530,26 @@ makeSingletonOfSize(Thread* t, unsigned count)
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
singletonMarkBit(Thread* t, object singleton, unsigned start, unsigned index)
|
||||||
|
{
|
||||||
|
uintptr_t& val = singletonValue(t, singleton, start + (index / BitsPerWord));
|
||||||
|
val |= static_cast<uintptr_t>(1) << (index % BitsPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
singletonGetBit(Thread* t, object singleton, unsigned start, unsigned index)
|
||||||
|
{
|
||||||
|
uintptr_t& val = singletonValue(t, singleton, start + (index / BitsPerWord));
|
||||||
|
return (val & static_cast<uintptr_t>(1) << (index % BitsPerWord)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
singletonIsFloat(Thread* t, object singleton, unsigned index)
|
||||||
|
{
|
||||||
|
return singletonGetBit(t, singleton, singletonLength(t, singleton) - 2 * singletonMaskSize(t, singleton), index);
|
||||||
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
resolveClassInObject(Thread* t, object loader, object container,
|
resolveClassInObject(Thread* t, object loader, object container,
|
||||||
unsigned classOffset)
|
unsigned classOffset)
|
||||||
|
107
src/powerpc.cpp
107
src/powerpc.cpp
@ -1680,6 +1680,14 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual unsigned generalRegisterCount() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual unsigned floatRegisterCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int stack() {
|
virtual int stack() {
|
||||||
return StackRegister;
|
return StackRegister;
|
||||||
}
|
}
|
||||||
@ -1704,10 +1712,6 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool condensedAddressing() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool bigEndian() {
|
virtual bool bigEndian() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1742,6 +1746,18 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return index + 3;
|
return index + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual uint64_t generalRegisters() {
|
||||||
|
return (static_cast<uint64_t>(1) << 32) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint64_t floatRegisters() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint64_t allRegisters() {
|
||||||
|
return generalRegisters() | floatRegisters();
|
||||||
|
}
|
||||||
|
|
||||||
virtual unsigned stackAlignmentInWords() {
|
virtual unsigned stackAlignmentInWords() {
|
||||||
return StackAlignmentInWords;
|
return StackAlignmentInWords;
|
||||||
}
|
}
|
||||||
@ -1823,6 +1839,26 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
*stack = *static_cast<void**>(*stack);
|
*stack = *static_cast<void**>(*stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual BinaryOperation hasBinaryIntrinsic(Thread*, object) {
|
||||||
|
return NoBinaryOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual TernaryOperation hasTernaryIntrinsic(Thread*, object) {
|
||||||
|
return NoTernaryOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool supportsFloatCompare(unsigned) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool alwaysCondensed(BinaryOperation) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool alwaysCondensed(TernaryOperation) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void plan
|
virtual void plan
|
||||||
(UnaryOperation,
|
(UnaryOperation,
|
||||||
unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
@ -1833,42 +1869,62 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
*thunk = false;
|
*thunk = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void plan
|
virtual void planSource
|
||||||
(BinaryOperation op,
|
(BinaryOperation op,
|
||||||
unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
unsigned, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
unsigned, bool* thunk)
|
||||||
bool* thunk)
|
|
||||||
{
|
{
|
||||||
*aTypeMask = ~0;
|
*aTypeMask = ~0;
|
||||||
*aRegisterMask = ~static_cast<uint64_t>(0);
|
*aRegisterMask = ~static_cast<uint64_t>(0);
|
||||||
|
|
||||||
*bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
|
||||||
*bRegisterMask = ~static_cast<uint64_t>(0);
|
|
||||||
|
|
||||||
*thunk = false;
|
*thunk = false;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Compare:
|
case Compare:
|
||||||
*aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand);
|
*aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand);
|
||||||
*bTypeMask = (1 << RegisterOperand);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Negate:
|
case Negate:
|
||||||
*aTypeMask = (1 << RegisterOperand);
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
*bTypeMask = (1 << RegisterOperand);
|
|
||||||
break;
|
break;
|
||||||
|
case FloatCompare:
|
||||||
|
case FloatNegate:
|
||||||
|
case Float2Float:
|
||||||
|
case Float2Int:
|
||||||
|
case Int2Float:
|
||||||
|
*thunk = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void plan
|
virtual void planDestination
|
||||||
|
(BinaryOperation op,
|
||||||
|
unsigned, const uint8_t*, const uint64_t*,
|
||||||
|
unsigned, uint8_t* bTypeMask, uint64_t* bRegisterMask)
|
||||||
|
{
|
||||||
|
*bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||||
|
*bRegisterMask = ~static_cast<uint64_t>(0);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case Compare:
|
||||||
|
*bTypeMask = (1 << RegisterOperand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Negate:
|
||||||
|
*bTypeMask = (1 << RegisterOperand);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void planSource
|
||||||
(TernaryOperation op,
|
(TernaryOperation op,
|
||||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
unsigned, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
unsigned, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
||||||
unsigned, uint8_t* cTypeMask, uint64_t* cRegisterMask,
|
unsigned, bool* thunk)
|
||||||
bool* thunk)
|
|
||||||
{
|
{
|
||||||
*aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand);
|
*aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand);
|
||||||
*aRegisterMask = ~static_cast<uint64_t>(0);
|
*aRegisterMask = ~static_cast<uint64_t>(0);
|
||||||
@ -1904,12 +1960,27 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FloatAdd:
|
||||||
|
case FloatSubtract:
|
||||||
|
case FloatMultiply:
|
||||||
|
case FloatDivide:
|
||||||
|
case FloatRemainder:
|
||||||
|
*bTypeMask = ~0;
|
||||||
|
*thunk = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*cTypeMask = *bTypeMask;
|
virtual void planDestination
|
||||||
*cRegisterMask = *bRegisterMask;
|
(TernaryOperation,
|
||||||
|
unsigned, const uint8_t*, const uint64_t*,
|
||||||
|
unsigned, const uint8_t*, const uint64_t*,
|
||||||
|
unsigned, uint8_t* cTypeMask, uint64_t* cRegisterMask)
|
||||||
|
{
|
||||||
|
*cTypeMask = (1 << RegisterOperand);
|
||||||
|
*cRegisterMask = ~static_cast<uint64_t>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void acquire() {
|
virtual void acquire() {
|
||||||
|
88
src/x86.S
88
src/x86.S
@ -24,6 +24,37 @@
|
|||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
.globl GLOBAL(detectFeature)
|
||||||
|
GLOBAL(detectFeature):
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rbx
|
||||||
|
pushq %rsi
|
||||||
|
pushq %rdi
|
||||||
|
movl %ecx, %edi
|
||||||
|
movl %edx, %esi
|
||||||
|
movl $1, %eax
|
||||||
|
cpuid
|
||||||
|
andl %esi, %edx
|
||||||
|
andl %edi, %ecx
|
||||||
|
orl %edx, %ecx
|
||||||
|
test %ecx, %ecx
|
||||||
|
je LOCAL(NOSSE)
|
||||||
|
movl $1, %eax
|
||||||
|
jmp LOCAL(SSEEND)
|
||||||
|
LOCAL(NOSSE):
|
||||||
|
movl $0, %eax
|
||||||
|
LOCAL(SSEEND):
|
||||||
|
popq %rdi
|
||||||
|
popq %rsi
|
||||||
|
popq %rbx
|
||||||
|
popq %rcx
|
||||||
|
popq %rdx
|
||||||
|
movq %rbp,%rsp
|
||||||
|
popq %rbp
|
||||||
|
ret
|
||||||
|
|
||||||
.globl GLOBAL(vmNativeCall)
|
.globl GLOBAL(vmNativeCall)
|
||||||
GLOBAL(vmNativeCall):
|
GLOBAL(vmNativeCall):
|
||||||
@ -144,6 +175,31 @@ GLOBAL(vmJump):
|
|||||||
jmp *%rcx
|
jmp *%rcx
|
||||||
|
|
||||||
#else // not __MINGW32__
|
#else // not __MINGW32__
|
||||||
|
.globl GLOBAL(detectFeature)
|
||||||
|
GLOBAL(detectFeature):
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rbx
|
||||||
|
movl $1, %eax
|
||||||
|
cpuid
|
||||||
|
andl %esi, %edx
|
||||||
|
andl %edi, %ecx
|
||||||
|
orl %edx, %ecx
|
||||||
|
test %ecx, %ecx
|
||||||
|
je LOCAL(NOSSE)
|
||||||
|
movl $1, %eax
|
||||||
|
jmp LOCAL(SSEEND)
|
||||||
|
LOCAL(NOSSE):
|
||||||
|
movl $0, %eax
|
||||||
|
LOCAL(SSEEND):
|
||||||
|
popq %rbx
|
||||||
|
popq %rcx
|
||||||
|
popq %rdx
|
||||||
|
movq %rbp,%rsp
|
||||||
|
popq %rbp
|
||||||
|
ret
|
||||||
|
|
||||||
.globl GLOBAL(vmNativeCall)
|
.globl GLOBAL(vmNativeCall)
|
||||||
GLOBAL(vmNativeCall):
|
GLOBAL(vmNativeCall):
|
||||||
@ -255,6 +311,38 @@ GLOBAL(vmJump):
|
|||||||
|
|
||||||
#elif defined __i386__
|
#elif defined __i386__
|
||||||
|
|
||||||
|
.globl GLOBAL(detectFeature)
|
||||||
|
GLOBAL(detectFeature):
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp, %ebp
|
||||||
|
pushl %edx
|
||||||
|
pushl %ecx
|
||||||
|
pushl %ebx
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
movl 12(%ebp), %esi
|
||||||
|
movl 8(%ebp), %edi
|
||||||
|
movl $1, %eax
|
||||||
|
cpuid
|
||||||
|
andl %esi, %edx
|
||||||
|
andl %edi, %ecx
|
||||||
|
orl %edx, %ecx
|
||||||
|
test %ecx, %ecx
|
||||||
|
je LOCAL(NOSSE)
|
||||||
|
movl $1, %eax
|
||||||
|
jmp LOCAL(SSEEND)
|
||||||
|
LOCAL(NOSSE):
|
||||||
|
movl $0, %eax
|
||||||
|
LOCAL(SSEEND):
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
popl %ebx
|
||||||
|
popl %ecx
|
||||||
|
popl %edx
|
||||||
|
movl %ebp,%esp
|
||||||
|
popl %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
.globl GLOBAL(vmNativeCall)
|
.globl GLOBAL(vmNativeCall)
|
||||||
GLOBAL(vmNativeCall):
|
GLOBAL(vmNativeCall):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
|
785
src/x86.cpp
785
src/x86.cpp
File diff suppressed because it is too large
Load Diff
77
test/AllFloats.java
Normal file
77
test/AllFloats.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
public class AllFloats {
|
||||||
|
private static float multiplyByFive(float a) {return 5f * a;}
|
||||||
|
private static double multiplyByFive(double a) {return 5d * a;}
|
||||||
|
private static float multiply(float a, float b) {return a * b;}
|
||||||
|
private static double multiply(double a, double b) {return a * b;}
|
||||||
|
private static double multiply(float a, double b) {return a * b;}
|
||||||
|
private static float divide(float a, float b) {return a / b;}
|
||||||
|
private static double divide(double a, double b) {return a / b;}
|
||||||
|
private static double divide(float a, double b) {return a / b;}
|
||||||
|
private static float add(float a, float b) {return a + b;}
|
||||||
|
private static double add(double a, double b) {return a + b;}
|
||||||
|
private static double add(float a, double b) {return a + b;}
|
||||||
|
private static float subtract(float a, float b) {return a - b;}
|
||||||
|
private static double subtract(double a, double b) {return a - b;}
|
||||||
|
private static double subtract(float a, double b) {return a - b;}
|
||||||
|
private static float complex(float a, float b) {return (a - b) / (a * b) + (float)Math.sqrt(a);}
|
||||||
|
private static double complex(double a, double b) {return (a - b) / (a * b) + Math.sqrt(a);}
|
||||||
|
private static double complex(float a, double b) {return (a - b) / (a * b) + Math.sqrt(a);}
|
||||||
|
private static int f2i(float a) {return (int)a;}
|
||||||
|
private static long f2l(float a) {return (long)a;}
|
||||||
|
private static float i2f(int a) {return (float)a;}
|
||||||
|
private static double i2d(int a) {return (double)a;}
|
||||||
|
private static int d2i(double a) {return (int)a;}
|
||||||
|
private static long d2l(double a) {return (long)a;}
|
||||||
|
private static float l2f(long a) {return (float)a;}
|
||||||
|
private static double l2d(long a) {return (double)a;}
|
||||||
|
private static float negate(float a) {return -a;}
|
||||||
|
private static double negate(double a) {return -a;}
|
||||||
|
private static int abs(int a) {return Math.abs(a);}
|
||||||
|
private static float abs(float a) {return Math.abs(a);}
|
||||||
|
|
||||||
|
private static void expect(boolean v) {
|
||||||
|
if(!v)throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int last(){return 0;}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
expect(multiplyByFive(36f) == 5f * 36f);
|
||||||
|
expect(multiplyByFive(36d) == 5d * 36d);
|
||||||
|
expect(multiply(5f, 4f) == 5f*4f);
|
||||||
|
expect(multiply(5d, 4d) == 5d*4d);
|
||||||
|
expect(multiply(5f, 4d) == 5f*4d);
|
||||||
|
expect(divide(5f, 2f) == 5f/2f);
|
||||||
|
expect(divide(5d, 2d) == 5d/2d);
|
||||||
|
expect(divide(5f, 2d) == 5f/2d);
|
||||||
|
expect(add(5f, 4f) == 5f+4f);
|
||||||
|
expect(add(5d, 4d) == 5f+4d);
|
||||||
|
expect(add(5f, 4f) == 5f+4d);
|
||||||
|
expect(subtract(5f, 4f) == 5f-4f);
|
||||||
|
expect(subtract(5d, 4d) == 5f-4d);
|
||||||
|
expect(subtract(5f, 4f) == 5f-4d);
|
||||||
|
expect(complex(4f, 3f) == (4f-3f)/(4f*3f) + 2f);
|
||||||
|
expect(complex(4d, 3d) == (4d-3d)/(4d*3d) + 2d);
|
||||||
|
expect(complex(4f, 3d) == (4f-3d)/(4f*3d) + 2f);
|
||||||
|
|
||||||
|
expect(f2i(4f) == 4);
|
||||||
|
expect(f2l(4f) == 4);
|
||||||
|
expect(i2f(4) == 4f);
|
||||||
|
expect(i2d(4) == 4d);
|
||||||
|
|
||||||
|
expect(d2i(4d) == 4);
|
||||||
|
expect(d2l(4d) == 4);
|
||||||
|
expect(l2f(4) == 4f);
|
||||||
|
expect(l2d(4) == 4d);
|
||||||
|
|
||||||
|
expect(negate(4f) == -4f);
|
||||||
|
expect(negate(4d) == -4d);
|
||||||
|
|
||||||
|
expect(abs(-4) == 4);
|
||||||
|
expect(abs(12) == 12);
|
||||||
|
expect(abs(-4f) == 4f);
|
||||||
|
expect(abs(12f) == 12f);
|
||||||
|
|
||||||
|
int unused = last();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user