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:
Joshua Warner 2013-02-11 08:07:46 -07:00
parent aacfb9ec85
commit d7f088c9e7
14 changed files with 2530 additions and 2372 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View 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
View 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
View 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
View 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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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