mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
adjust package structure in codegen (vm -> avian::codegen and avian::codegen::lir)
The eventual intent with the lir namespace is to formalize some of the important bits of Assembler interface, to be tested, debug-printed, and potentially, serialized. Also, group arguments to apply(...) in OperandInfos
This commit is contained in:
parent
aacfb9ec85
commit
d7f088c9e7
File diff suppressed because it is too large
Load Diff
@ -8,13 +8,30 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#ifndef ASSEMBLER_H
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_H
|
||||||
#define ASSEMBLER_H
|
#define AVIAN_CODEGEN_ASSEMBLER_H
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
|
||||||
namespace vm {
|
#include "codegen/lir.h"
|
||||||
|
#include "codegen/promise.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
|
||||||
|
class OperandInfo {
|
||||||
|
public:
|
||||||
|
const unsigned size;
|
||||||
|
const lir::OperandType type;
|
||||||
|
lir::Operand* const operand;
|
||||||
|
|
||||||
|
inline OperandInfo(unsigned size, lir::OperandType type, lir::Operand* operand):
|
||||||
|
size(size),
|
||||||
|
type(type),
|
||||||
|
operand(operand)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef AVIAN_TAILS
|
#ifdef AVIAN_TAILS
|
||||||
const bool TailCalls = true;
|
const bool TailCalls = true;
|
||||||
@ -28,286 +45,8 @@ const bool UseFramePointer = true;
|
|||||||
const bool UseFramePointer = false;
|
const bool UseFramePointer = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum Operation {
|
|
||||||
Return,
|
|
||||||
LoadBarrier,
|
|
||||||
StoreStoreBarrier,
|
|
||||||
StoreLoadBarrier,
|
|
||||||
Trap
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned OperationCount = Trap + 1;
|
|
||||||
|
|
||||||
enum UnaryOperation {
|
|
||||||
Call,
|
|
||||||
LongCall,
|
|
||||||
AlignedLongCall,
|
|
||||||
AlignedCall,
|
|
||||||
Jump,
|
|
||||||
LongJump,
|
|
||||||
AlignedLongJump,
|
|
||||||
AlignedJump,
|
|
||||||
|
|
||||||
NoUnaryOperation = -1
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned UnaryOperationCount = AlignedJump + 1;
|
|
||||||
|
|
||||||
enum BinaryOperation {
|
|
||||||
Move,
|
|
||||||
MoveLow,
|
|
||||||
MoveHigh,
|
|
||||||
MoveZ,
|
|
||||||
Negate,
|
|
||||||
FloatNegate,
|
|
||||||
Float2Float,
|
|
||||||
Float2Int,
|
|
||||||
Int2Float,
|
|
||||||
FloatSquareRoot,
|
|
||||||
FloatAbsolute,
|
|
||||||
Absolute,
|
|
||||||
|
|
||||||
NoBinaryOperation = -1
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned BinaryOperationCount = Absolute + 1;
|
|
||||||
|
|
||||||
enum TernaryOperation {
|
|
||||||
Add,
|
|
||||||
Subtract,
|
|
||||||
Multiply,
|
|
||||||
Divide,
|
|
||||||
Remainder,
|
|
||||||
ShiftLeft,
|
|
||||||
ShiftRight,
|
|
||||||
UnsignedShiftRight,
|
|
||||||
And,
|
|
||||||
Or,
|
|
||||||
Xor,
|
|
||||||
FloatAdd,
|
|
||||||
FloatSubtract,
|
|
||||||
FloatMultiply,
|
|
||||||
FloatDivide,
|
|
||||||
FloatRemainder,
|
|
||||||
FloatMax,
|
|
||||||
FloatMin,
|
|
||||||
JumpIfLess,
|
|
||||||
JumpIfGreater,
|
|
||||||
JumpIfLessOrEqual,
|
|
||||||
JumpIfGreaterOrEqual,
|
|
||||||
JumpIfEqual,
|
|
||||||
JumpIfNotEqual,
|
|
||||||
JumpIfFloatEqual,
|
|
||||||
JumpIfFloatNotEqual,
|
|
||||||
JumpIfFloatLess,
|
|
||||||
JumpIfFloatGreater,
|
|
||||||
JumpIfFloatLessOrEqual,
|
|
||||||
JumpIfFloatGreaterOrEqual,
|
|
||||||
JumpIfFloatLessOrUnordered,
|
|
||||||
JumpIfFloatGreaterOrUnordered,
|
|
||||||
JumpIfFloatLessOrEqualOrUnordered,
|
|
||||||
JumpIfFloatGreaterOrEqualOrUnordered,
|
|
||||||
|
|
||||||
NoTernaryOperation = -1
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned TernaryOperationCount
|
|
||||||
= JumpIfFloatGreaterOrEqualOrUnordered + 1;
|
|
||||||
|
|
||||||
const unsigned NonBranchTernaryOperationCount = FloatMin + 1;
|
|
||||||
const unsigned BranchOperationCount
|
|
||||||
= JumpIfFloatGreaterOrEqualOrUnordered - FloatMin;
|
|
||||||
|
|
||||||
enum OperandType {
|
|
||||||
ConstantOperand,
|
|
||||||
AddressOperand,
|
|
||||||
RegisterOperand,
|
|
||||||
MemoryOperand
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ValueType {
|
|
||||||
ValueGeneral,
|
|
||||||
ValueFloat
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned OperandTypeCount = MemoryOperand + 1;
|
|
||||||
|
|
||||||
const int NoRegister = -1;
|
|
||||||
|
|
||||||
class Promise {
|
|
||||||
public:
|
|
||||||
class Listener {
|
|
||||||
public:
|
|
||||||
virtual bool resolve(int64_t value, void** location) = 0;
|
|
||||||
|
|
||||||
Listener* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual int64_t value() = 0;
|
|
||||||
virtual bool resolved() = 0;
|
|
||||||
virtual Listener* listen(unsigned) { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class ResolvedPromise: public Promise {
|
|
||||||
public:
|
|
||||||
ResolvedPromise(int64_t value): value_(value) { }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
return value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t value_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShiftMaskPromise: public Promise {
|
|
||||||
public:
|
|
||||||
ShiftMaskPromise(Promise* base, unsigned shift, int64_t mask):
|
|
||||||
base(base), shift(shift), mask(mask)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
return (base->value() >> shift) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return base->resolved();
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise* base;
|
|
||||||
unsigned shift;
|
|
||||||
int64_t mask;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CombinedPromise: public Promise {
|
|
||||||
public:
|
|
||||||
CombinedPromise(Promise* low, Promise* high):
|
|
||||||
low(low), high(high)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
return low->value() | (high->value() << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return low->resolved() and high->resolved();
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise* low;
|
|
||||||
Promise* high;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OffsetPromise: public Promise {
|
|
||||||
public:
|
|
||||||
OffsetPromise(Promise* base, int64_t offset):
|
|
||||||
base(base), offset(offset)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
return base->value() + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return base->resolved();
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise* base;
|
|
||||||
int64_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ListenPromise: public Promise {
|
|
||||||
public:
|
|
||||||
ListenPromise(System* s, Allocator* allocator):
|
|
||||||
s(s), allocator(allocator), listener(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
abort(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Listener* listen(unsigned sizeInBytes) {
|
|
||||||
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
|
|
||||||
l->next = listener;
|
|
||||||
listener = l;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
System* s;
|
|
||||||
Allocator* allocator;
|
|
||||||
Listener* listener;
|
|
||||||
Promise* promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DelayedPromise: public ListenPromise {
|
|
||||||
public:
|
|
||||||
DelayedPromise(System* s, Allocator* allocator, Promise* basis,
|
|
||||||
DelayedPromise* next):
|
|
||||||
ListenPromise(s, allocator), basis(basis), next(next)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
abort(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Listener* listen(unsigned sizeInBytes) {
|
|
||||||
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
|
|
||||||
l->next = listener;
|
|
||||||
listener = l;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise* basis;
|
|
||||||
DelayedPromise* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Assembler {
|
class Assembler {
|
||||||
public:
|
public:
|
||||||
class Operand { };
|
|
||||||
|
|
||||||
class Constant: public Operand {
|
|
||||||
public:
|
|
||||||
Constant(Promise* value): value(value) { }
|
|
||||||
|
|
||||||
Promise* value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Address: public Operand {
|
|
||||||
public:
|
|
||||||
Address(Promise* address): address(address) { }
|
|
||||||
|
|
||||||
Promise* address;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Register: public Operand {
|
|
||||||
public:
|
|
||||||
Register(int low, int high = NoRegister): low(low), high(high) { }
|
|
||||||
|
|
||||||
int low;
|
|
||||||
int high;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Memory: public Operand {
|
|
||||||
public:
|
|
||||||
Memory(int base, int offset, int index = NoRegister, unsigned scale = 1):
|
|
||||||
base(base), offset(offset), index(index), scale(scale)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
int base;
|
|
||||||
int offset;
|
|
||||||
int index;
|
|
||||||
unsigned scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
@ -342,8 +81,8 @@ class Assembler {
|
|||||||
|
|
||||||
virtual uintptr_t maximumImmediateJump() = 0;
|
virtual uintptr_t maximumImmediateJump() = 0;
|
||||||
|
|
||||||
virtual bool alwaysCondensed(BinaryOperation op) = 0;
|
virtual bool alwaysCondensed(lir::BinaryOperation op) = 0;
|
||||||
virtual bool alwaysCondensed(TernaryOperation op) = 0;
|
virtual bool alwaysCondensed(lir::TernaryOperation op) = 0;
|
||||||
|
|
||||||
virtual bool reserved(int register_) = 0;
|
virtual bool reserved(int register_) = 0;
|
||||||
|
|
||||||
@ -360,7 +99,7 @@ class Assembler {
|
|||||||
|
|
||||||
virtual bool matchCall(void* returnAddress, void* target) = 0;
|
virtual bool matchCall(void* returnAddress, void* target) = 0;
|
||||||
|
|
||||||
virtual void updateCall(UnaryOperation op, void* returnAddress,
|
virtual void updateCall(lir::UnaryOperation op, void* returnAddress,
|
||||||
void* newTarget) = 0;
|
void* newTarget) = 0;
|
||||||
|
|
||||||
virtual void setConstant(void* dst, uint64_t constant) = 0;
|
virtual void setConstant(void* dst, uint64_t constant) = 0;
|
||||||
@ -379,17 +118,17 @@ class Assembler {
|
|||||||
virtual int framePointerOffset() = 0;
|
virtual int framePointerOffset() = 0;
|
||||||
|
|
||||||
virtual void plan
|
virtual void plan
|
||||||
(UnaryOperation op,
|
(lir::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 planSource
|
virtual void planSource
|
||||||
(BinaryOperation op,
|
(lir::BinaryOperation op,
|
||||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||||
unsigned bSize, bool* thunk) = 0;
|
unsigned bSize, bool* thunk) = 0;
|
||||||
|
|
||||||
virtual void planDestination
|
virtual void planDestination
|
||||||
(BinaryOperation op,
|
(lir::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) = 0;
|
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask) = 0;
|
||||||
|
|
||||||
@ -399,18 +138,18 @@ class Assembler {
|
|||||||
uint8_t dstTypeMask, uint64_t dstRegisterMask) = 0;
|
uint8_t dstTypeMask, uint64_t dstRegisterMask) = 0;
|
||||||
|
|
||||||
virtual void planSource
|
virtual void planSource
|
||||||
(TernaryOperation op,
|
(lir::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, bool* thunk) = 0;
|
unsigned cSize, bool* thunk) = 0;
|
||||||
|
|
||||||
virtual void planDestination
|
virtual void planDestination
|
||||||
(TernaryOperation op,
|
(lir::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) = 0;
|
unsigned cSize, uint8_t* cTypeMask, uint64_t* cRegisterMask) = 0;
|
||||||
|
|
||||||
virtual Assembler* makeAssembler(Allocator*, Zone*) = 0;
|
virtual Assembler* makeAssembler(vm::Allocator*, vm::Zone*) = 0;
|
||||||
|
|
||||||
virtual void acquire() = 0;
|
virtual void acquire() = 0;
|
||||||
virtual void release() = 0;
|
virtual void release() = 0;
|
||||||
@ -437,19 +176,10 @@ class Assembler {
|
|||||||
unsigned stackOffsetFromThread)
|
unsigned stackOffsetFromThread)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
virtual void apply(Operation op) = 0;
|
virtual void apply(lir::Operation op) = 0;
|
||||||
|
virtual void apply(lir::UnaryOperation op, OperandInfo a) = 0;
|
||||||
virtual void apply(UnaryOperation op,
|
virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) = 0;
|
||||||
unsigned aSize, OperandType aType, Operand* aOperand) = 0;
|
virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) = 0;
|
||||||
|
|
||||||
virtual void apply(BinaryOperation op,
|
|
||||||
unsigned aSize, OperandType aType, Operand* aOperand,
|
|
||||||
unsigned bSize, OperandType bType, Operand* bOperand) = 0;
|
|
||||||
|
|
||||||
virtual void apply(TernaryOperation op,
|
|
||||||
unsigned aSize, OperandType aType, Operand* aOperand,
|
|
||||||
unsigned bSize, OperandType bType, Operand* bOperand,
|
|
||||||
unsigned cSize, OperandType cType, Operand* cOperand) = 0;
|
|
||||||
|
|
||||||
virtual void setDestination(uint8_t* dst) = 0;
|
virtual void setDestination(uint8_t* dst) = 0;
|
||||||
|
|
||||||
@ -468,6 +198,7 @@ class Assembler {
|
|||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
#endif//ASSEMBLER_H
|
#endif // AVIAN_CODEGEN_ASSEMBLER_H
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,8 @@
|
|||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
|
||||||
class TraceHandler {
|
class TraceHandler {
|
||||||
public:
|
public:
|
||||||
@ -26,10 +27,10 @@ class Compiler {
|
|||||||
public:
|
public:
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0;
|
virtual intptr_t getThunk(lir::UnaryOperation op, unsigned size) = 0;
|
||||||
virtual intptr_t getThunk(BinaryOperation op, unsigned size,
|
virtual intptr_t getThunk(lir::BinaryOperation op, unsigned size,
|
||||||
unsigned resultSize) = 0;
|
unsigned resultSize) = 0;
|
||||||
virtual intptr_t getThunk(TernaryOperation op, unsigned size,
|
virtual intptr_t getThunk(lir::TernaryOperation op, unsigned size,
|
||||||
unsigned resultSize, bool* threadParameter) = 0;
|
unsigned resultSize, bool* threadParameter) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -200,9 +201,10 @@ class Compiler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Compiler*
|
Compiler*
|
||||||
makeCompiler(System* system, Assembler* assembler, Zone* zone,
|
makeCompiler(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||||
Compiler::Client* client);
|
Compiler::Client* client);
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
#endif//COMPILER_H
|
#endif//COMPILER_H
|
||||||
|
62
src/codegen/lir-ops.inc.cpp
Normal file
62
src/codegen/lir-ops.inc.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
LIR_OP_0(Return)
|
||||||
|
LIR_OP_0(LoadBarrier)
|
||||||
|
LIR_OP_0(StoreStoreBarrier)
|
||||||
|
LIR_OP_0(StoreLoadBarrier)
|
||||||
|
LIR_OP_0(Trap)
|
||||||
|
|
||||||
|
LIR_OP_1(Call)
|
||||||
|
LIR_OP_1(LongCall)
|
||||||
|
LIR_OP_1(AlignedLongCall)
|
||||||
|
LIR_OP_1(AlignedCall)
|
||||||
|
LIR_OP_1(Jump)
|
||||||
|
LIR_OP_1(LongJump)
|
||||||
|
LIR_OP_1(AlignedLongJump)
|
||||||
|
LIR_OP_1(AlignedJump)
|
||||||
|
|
||||||
|
LIR_OP_2(Move)
|
||||||
|
LIR_OP_2(MoveLow)
|
||||||
|
LIR_OP_2(MoveHigh)
|
||||||
|
LIR_OP_2(MoveZ)
|
||||||
|
LIR_OP_2(Negate)
|
||||||
|
LIR_OP_2(FloatNegate)
|
||||||
|
LIR_OP_2(Float2Float)
|
||||||
|
LIR_OP_2(Float2Int)
|
||||||
|
LIR_OP_2(Int2Float)
|
||||||
|
LIR_OP_2(FloatSquareRoot)
|
||||||
|
LIR_OP_2(FloatAbsolute)
|
||||||
|
LIR_OP_2(Absolute)
|
||||||
|
|
||||||
|
LIR_OP_3(Add)
|
||||||
|
LIR_OP_3(Subtract)
|
||||||
|
LIR_OP_3(Multiply)
|
||||||
|
LIR_OP_3(Divide)
|
||||||
|
LIR_OP_3(Remainder)
|
||||||
|
LIR_OP_3(ShiftLeft)
|
||||||
|
LIR_OP_3(ShiftRight)
|
||||||
|
LIR_OP_3(UnsignedShiftRight)
|
||||||
|
LIR_OP_3(And)
|
||||||
|
LIR_OP_3(Or)
|
||||||
|
LIR_OP_3(Xor)
|
||||||
|
LIR_OP_3(FloatAdd)
|
||||||
|
LIR_OP_3(FloatSubtract)
|
||||||
|
LIR_OP_3(FloatMultiply)
|
||||||
|
LIR_OP_3(FloatDivide)
|
||||||
|
LIR_OP_3(FloatRemainder)
|
||||||
|
LIR_OP_3(FloatMax)
|
||||||
|
LIR_OP_3(FloatMin)
|
||||||
|
LIR_OP_3(JumpIfLess)
|
||||||
|
LIR_OP_3(JumpIfGreater)
|
||||||
|
LIR_OP_3(JumpIfLessOrEqual)
|
||||||
|
LIR_OP_3(JumpIfGreaterOrEqual)
|
||||||
|
LIR_OP_3(JumpIfEqual)
|
||||||
|
LIR_OP_3(JumpIfNotEqual)
|
||||||
|
LIR_OP_3(JumpIfFloatEqual)
|
||||||
|
LIR_OP_3(JumpIfFloatNotEqual)
|
||||||
|
LIR_OP_3(JumpIfFloatLess)
|
||||||
|
LIR_OP_3(JumpIfFloatGreater)
|
||||||
|
LIR_OP_3(JumpIfFloatLessOrEqual)
|
||||||
|
LIR_OP_3(JumpIfFloatGreaterOrEqual)
|
||||||
|
LIR_OP_3(JumpIfFloatLessOrUnordered)
|
||||||
|
LIR_OP_3(JumpIfFloatGreaterOrUnordered)
|
||||||
|
LIR_OP_3(JumpIfFloatLessOrEqualOrUnordered)
|
||||||
|
LIR_OP_3(JumpIfFloatGreaterOrEqualOrUnordered)
|
35
src/codegen/lir.cpp
Normal file
35
src/codegen/lir.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "lir.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char* lirOpcodeNames[] = {
|
||||||
|
#define LIR_OP_0(x) #x
|
||||||
|
#define LIR_OP_1(x) #x
|
||||||
|
#define LIR_OP_2(x) #x
|
||||||
|
#define LIR_OP_3(x) #x
|
||||||
|
#include "lir-ops.inc.cpp"
|
||||||
|
#undef LIR_OP_0
|
||||||
|
#undef LIR_OP_1
|
||||||
|
#undef LIR_OP_2
|
||||||
|
#undef LIR_OP_3
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
|
const char* LirInstr::opcodeName(Opcode op) {
|
||||||
|
return lirOpcodeNames[op];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
174
src/codegen/lir.h
Normal file
174
src/codegen/lir.h
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_LIR_H
|
||||||
|
#define AVIAN_CODEGEN_LIR_H
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
class Promise;
|
||||||
|
|
||||||
|
namespace lir {
|
||||||
|
enum Operation {
|
||||||
|
#define LIR_OP_0(x) x,
|
||||||
|
#define LIR_OP_1(x)
|
||||||
|
#define LIR_OP_2(x)
|
||||||
|
#define LIR_OP_3(x)
|
||||||
|
#include "lir-ops.inc.cpp"
|
||||||
|
#undef LIR_OP_0
|
||||||
|
#undef LIR_OP_1
|
||||||
|
#undef LIR_OP_2
|
||||||
|
#undef LIR_OP_3
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned OperationCount = Trap + 1;
|
||||||
|
|
||||||
|
enum UnaryOperation {
|
||||||
|
#define LIR_OP_0(x)
|
||||||
|
#define LIR_OP_1(x) x,
|
||||||
|
#define LIR_OP_2(x)
|
||||||
|
#define LIR_OP_3(x)
|
||||||
|
#include "lir-ops.inc.cpp"
|
||||||
|
#undef LIR_OP_0
|
||||||
|
#undef LIR_OP_1
|
||||||
|
#undef LIR_OP_2
|
||||||
|
#undef LIR_OP_3
|
||||||
|
|
||||||
|
NoUnaryOperation = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned UnaryOperationCount = AlignedJump + 1;
|
||||||
|
|
||||||
|
enum BinaryOperation {
|
||||||
|
#define LIR_OP_0(x)
|
||||||
|
#define LIR_OP_1(x)
|
||||||
|
#define LIR_OP_2(x) x,
|
||||||
|
#define LIR_OP_3(x)
|
||||||
|
#include "lir-ops.inc.cpp"
|
||||||
|
#undef LIR_OP_0
|
||||||
|
#undef LIR_OP_1
|
||||||
|
#undef LIR_OP_2
|
||||||
|
#undef LIR_OP_3
|
||||||
|
|
||||||
|
NoBinaryOperation = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned BinaryOperationCount = Absolute + 1;
|
||||||
|
|
||||||
|
enum TernaryOperation {
|
||||||
|
#define LIR_OP_0(x)
|
||||||
|
#define LIR_OP_1(x)
|
||||||
|
#define LIR_OP_2(x)
|
||||||
|
#define LIR_OP_3(x) x,
|
||||||
|
#include "lir-ops.inc.cpp"
|
||||||
|
#undef LIR_OP_0
|
||||||
|
#undef LIR_OP_1
|
||||||
|
#undef LIR_OP_2
|
||||||
|
#undef LIR_OP_3
|
||||||
|
|
||||||
|
NoTernaryOperation = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned TernaryOperationCount
|
||||||
|
= JumpIfFloatGreaterOrEqualOrUnordered + 1;
|
||||||
|
|
||||||
|
const unsigned NonBranchTernaryOperationCount = FloatMin + 1;
|
||||||
|
const unsigned BranchOperationCount
|
||||||
|
= JumpIfFloatGreaterOrEqualOrUnordered - FloatMin;
|
||||||
|
|
||||||
|
enum OperandType {
|
||||||
|
ConstantOperand,
|
||||||
|
AddressOperand,
|
||||||
|
RegisterOperand,
|
||||||
|
MemoryOperand
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ValueType {
|
||||||
|
ValueGeneral,
|
||||||
|
ValueFloat
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned OperandTypeCount = MemoryOperand + 1;
|
||||||
|
|
||||||
|
const int NoRegister = -1;
|
||||||
|
|
||||||
|
|
||||||
|
inline bool isBranch(lir::TernaryOperation op) {
|
||||||
|
return op > FloatMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isFloatBranch(lir::TernaryOperation op) {
|
||||||
|
return op > JumpIfNotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Operand { };
|
||||||
|
|
||||||
|
class Constant: public Operand {
|
||||||
|
public:
|
||||||
|
Constant(Promise* value): value(value) { }
|
||||||
|
|
||||||
|
Promise* value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Address: public Operand {
|
||||||
|
public:
|
||||||
|
Address(Promise* address): address(address) { }
|
||||||
|
|
||||||
|
Promise* address;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Register: public Operand {
|
||||||
|
public:
|
||||||
|
Register(int low, int high = NoRegister): low(low), high(high) { }
|
||||||
|
|
||||||
|
int low;
|
||||||
|
int high;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Memory: public Operand {
|
||||||
|
public:
|
||||||
|
Memory(int base, int offset, int index = NoRegister, unsigned scale = 1):
|
||||||
|
base(base), offset(offset), index(index), scale(scale)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
int base;
|
||||||
|
int offset;
|
||||||
|
int index;
|
||||||
|
unsigned scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Instr {
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Opcode {
|
||||||
|
#define LIR_OP_0(x) OP_##x,
|
||||||
|
#define LIR_OP_1(x) OP_##x,
|
||||||
|
#define LIR_OP_2(x) OP_##x,
|
||||||
|
#define LIR_OP_3(x) OP_##x,
|
||||||
|
#include "lir-ops.inc.cpp"
|
||||||
|
#undef LIR_OP_0
|
||||||
|
#undef LIR_OP_1
|
||||||
|
#undef LIR_OP_2
|
||||||
|
#undef LIR_OP_3
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* opcodeName(Opcode op);
|
||||||
|
|
||||||
|
static Opcode opcodeFromNullary(Operation op);
|
||||||
|
static Opcode opcodeFromUnary(UnaryOperation op);
|
||||||
|
static Opcode opcodeFromBinary(BinaryOperation op);
|
||||||
|
static Opcode opcodeFromTernary(TernaryOperation op);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lir
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_LIR_H
|
File diff suppressed because it is too large
Load Diff
159
src/codegen/promise.h
Normal file
159
src/codegen/promise.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_PROMISE_H
|
||||||
|
#define AVIAN_CODEGEN_PROMISE_H
|
||||||
|
|
||||||
|
#include "allocator.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
|
||||||
|
class Promise {
|
||||||
|
public:
|
||||||
|
class Listener {
|
||||||
|
public:
|
||||||
|
virtual bool resolve(int64_t value, void** location) = 0;
|
||||||
|
|
||||||
|
Listener* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual int64_t value() = 0;
|
||||||
|
virtual bool resolved() = 0;
|
||||||
|
virtual Listener* listen(unsigned) { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ResolvedPromise: public Promise {
|
||||||
|
public:
|
||||||
|
ResolvedPromise(int64_t value): value_(value) { }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShiftMaskPromise: public Promise {
|
||||||
|
public:
|
||||||
|
ShiftMaskPromise(Promise* base, unsigned shift, int64_t mask):
|
||||||
|
base(base), shift(shift), mask(mask)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
return (base->value() >> shift) & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return base->resolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise* base;
|
||||||
|
unsigned shift;
|
||||||
|
int64_t mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CombinedPromise: public Promise {
|
||||||
|
public:
|
||||||
|
CombinedPromise(Promise* low, Promise* high):
|
||||||
|
low(low), high(high)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
return low->value() | (high->value() << 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return low->resolved() and high->resolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise* low;
|
||||||
|
Promise* high;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OffsetPromise: public Promise {
|
||||||
|
public:
|
||||||
|
OffsetPromise(Promise* base, int64_t offset):
|
||||||
|
base(base), offset(offset)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
return base->value() + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return base->resolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise* base;
|
||||||
|
int64_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListenPromise: public Promise {
|
||||||
|
public:
|
||||||
|
ListenPromise(vm::System* s, vm::Allocator* allocator):
|
||||||
|
s(s), allocator(allocator), listener(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
abort(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Listener* listen(unsigned sizeInBytes) {
|
||||||
|
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
|
||||||
|
l->next = listener;
|
||||||
|
listener = l;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm::System* s;
|
||||||
|
vm::Allocator* allocator;
|
||||||
|
Listener* listener;
|
||||||
|
Promise* promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DelayedPromise: public ListenPromise {
|
||||||
|
public:
|
||||||
|
DelayedPromise(vm::System* s, vm::Allocator* allocator, Promise* basis,
|
||||||
|
DelayedPromise* next):
|
||||||
|
ListenPromise(s, allocator), basis(basis), next(next)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
abort(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Listener* listen(unsigned sizeInBytes) {
|
||||||
|
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
|
||||||
|
l->next = listener;
|
||||||
|
listener = l;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise* basis;
|
||||||
|
DelayedPromise* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_PROMISE_H
|
@ -14,7 +14,7 @@
|
|||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
|
||||||
vm::Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures UNUSED) {
|
Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures UNUSED) {
|
||||||
#ifndef AVIAN_TARGET_ARCH
|
#ifndef AVIAN_TARGET_ARCH
|
||||||
#error "Must specify native target!"
|
#error "Must specify native target!"
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
|
||||||
vm::Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures);
|
Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures);
|
||||||
|
|
||||||
vm::Assembler::Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures);
|
Assembler::Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures);
|
||||||
vm::Assembler::Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);
|
Assembler::Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);
|
||||||
vm::Assembler::Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures);
|
Assembler::Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures);
|
||||||
|
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
File diff suppressed because it is too large
Load Diff
416
src/compile.cpp
416
src/compile.cpp
File diff suppressed because it is too large
Load Diff
@ -18,9 +18,13 @@
|
|||||||
#include "heapwalk.h"
|
#include "heapwalk.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
|
||||||
namespace vm {
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
class DelayedPromise;
|
class DelayedPromise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
class Processor {
|
class Processor {
|
||||||
public:
|
public:
|
||||||
@ -143,7 +147,7 @@ class Processor {
|
|||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
compileMethod(Thread* t, Zone* zone, object* constants, object* calls,
|
compileMethod(Thread* t, Zone* zone, object* constants, object* calls,
|
||||||
DelayedPromise** addresses, object method,
|
avian::codegen::DelayedPromise** addresses, object method,
|
||||||
OffsetResolver* resolver) = 0;
|
OffsetResolver* resolver) = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
|
Loading…
Reference in New Issue
Block a user