mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +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
|
||||
details. */
|
||||
|
||||
#ifndef ASSEMBLER_H
|
||||
#define ASSEMBLER_H
|
||||
#ifndef AVIAN_CODEGEN_ASSEMBLER_H
|
||||
#define AVIAN_CODEGEN_ASSEMBLER_H
|
||||
|
||||
#include "system.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
|
||||
const bool TailCalls = true;
|
||||
@ -28,286 +45,8 @@ const bool UseFramePointer = true;
|
||||
const bool UseFramePointer = false;
|
||||
#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 {
|
||||
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 {
|
||||
public:
|
||||
@ -342,8 +81,8 @@ class Assembler {
|
||||
|
||||
virtual uintptr_t maximumImmediateJump() = 0;
|
||||
|
||||
virtual bool alwaysCondensed(BinaryOperation op) = 0;
|
||||
virtual bool alwaysCondensed(TernaryOperation op) = 0;
|
||||
virtual bool alwaysCondensed(lir::BinaryOperation op) = 0;
|
||||
virtual bool alwaysCondensed(lir::TernaryOperation op) = 0;
|
||||
|
||||
virtual bool reserved(int register_) = 0;
|
||||
|
||||
@ -360,7 +99,7 @@ class Assembler {
|
||||
|
||||
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;
|
||||
|
||||
virtual void setConstant(void* dst, uint64_t constant) = 0;
|
||||
@ -379,17 +118,17 @@ class Assembler {
|
||||
virtual int framePointerOffset() = 0;
|
||||
|
||||
virtual void plan
|
||||
(UnaryOperation op,
|
||||
(lir::UnaryOperation op,
|
||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||
bool* thunk) = 0;
|
||||
|
||||
virtual void planSource
|
||||
(BinaryOperation op,
|
||||
(lir::BinaryOperation op,
|
||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||
unsigned bSize, bool* thunk) = 0;
|
||||
|
||||
virtual void planDestination
|
||||
(BinaryOperation op,
|
||||
(lir::BinaryOperation op,
|
||||
unsigned aSize, uint8_t aTypeMask, uint64_t aRegisterMask,
|
||||
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask) = 0;
|
||||
|
||||
@ -399,18 +138,18 @@ class Assembler {
|
||||
uint8_t dstTypeMask, uint64_t dstRegisterMask) = 0;
|
||||
|
||||
virtual void planSource
|
||||
(TernaryOperation op,
|
||||
(lir::TernaryOperation op,
|
||||
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
|
||||
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
|
||||
unsigned cSize, bool* thunk) = 0;
|
||||
|
||||
virtual void planDestination
|
||||
(TernaryOperation op,
|
||||
(lir::TernaryOperation op,
|
||||
unsigned aSize, uint8_t aTypeMask, uint64_t aRegisterMask,
|
||||
unsigned bSize, uint8_t bTypeMask, uint64_t bRegisterMask,
|
||||
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 release() = 0;
|
||||
@ -437,19 +176,10 @@ class Assembler {
|
||||
unsigned stackOffsetFromThread)
|
||||
= 0;
|
||||
|
||||
virtual void apply(Operation op) = 0;
|
||||
|
||||
virtual void apply(UnaryOperation op,
|
||||
unsigned aSize, OperandType aType, Operand* aOperand) = 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 apply(lir::Operation op) = 0;
|
||||
virtual void apply(lir::UnaryOperation op, OperandInfo a) = 0;
|
||||
virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) = 0;
|
||||
virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) = 0;
|
||||
|
||||
virtual void setDestination(uint8_t* dst) = 0;
|
||||
|
||||
@ -468,6 +198,7 @@ class Assembler {
|
||||
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 "assembler.h"
|
||||
|
||||
namespace vm {
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
|
||||
class TraceHandler {
|
||||
public:
|
||||
@ -26,10 +27,10 @@ class Compiler {
|
||||
public:
|
||||
class Client {
|
||||
public:
|
||||
virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0;
|
||||
virtual intptr_t getThunk(BinaryOperation op, unsigned size,
|
||||
virtual intptr_t getThunk(lir::UnaryOperation op, unsigned size) = 0;
|
||||
virtual intptr_t getThunk(lir::BinaryOperation op, unsigned size,
|
||||
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;
|
||||
};
|
||||
|
||||
@ -200,9 +201,10 @@ class Compiler {
|
||||
};
|
||||
|
||||
Compiler*
|
||||
makeCompiler(System* system, Assembler* assembler, Zone* zone,
|
||||
makeCompiler(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||
Compiler::Client* client);
|
||||
|
||||
} // namespace vm
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
||||
#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 codegen {
|
||||
|
||||
vm::Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures UNUSED) {
|
||||
Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures UNUSED) {
|
||||
#ifndef AVIAN_TARGET_ARCH
|
||||
#error "Must specify native target!"
|
||||
#endif
|
||||
|
@ -16,11 +16,11 @@
|
||||
namespace avian {
|
||||
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);
|
||||
vm::Assembler::Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);
|
||||
vm::Assembler::Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures);
|
||||
Assembler::Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures);
|
||||
Assembler::Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);
|
||||
Assembler::Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures);
|
||||
|
||||
} // namespace codegen
|
||||
} // 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 "zone.h"
|
||||
|
||||
namespace vm {
|
||||
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
class DelayedPromise;
|
||||
}
|
||||
}
|
||||
|
||||
namespace vm {
|
||||
|
||||
class Processor {
|
||||
public:
|
||||
@ -143,7 +147,7 @@ class Processor {
|
||||
|
||||
virtual void
|
||||
compileMethod(Thread* t, Zone* zone, object* constants, object* calls,
|
||||
DelayedPromise** addresses, object method,
|
||||
avian::codegen::DelayedPromise** addresses, object method,
|
||||
OffsetResolver* resolver) = 0;
|
||||
|
||||
virtual void
|
||||
|
Loading…
Reference in New Issue
Block a user