corda/src/assembler.h

256 lines
5.4 KiB
C
Raw Normal View History

/* Copyright (c) 2008, 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. */
2008-02-11 17:21:41 +00:00
#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#include "system.h"
#include "zone.h"
namespace vm {
enum Operation {
Return
};
const unsigned OperationCount = Return + 1;
2008-02-11 17:21:41 +00:00
enum UnaryOperation {
2008-02-17 22:29:04 +00:00
Call,
LongCall,
2008-02-17 22:29:04 +00:00
AlignedCall,
Jump,
LongJump,
2008-02-11 17:21:41 +00:00
JumpIfLess,
JumpIfGreater,
JumpIfLessOrEqual,
JumpIfGreaterOrEqual,
JumpIfEqual,
JumpIfNotEqual
2008-02-11 17:21:41 +00:00
};
const unsigned UnaryOperationCount = JumpIfNotEqual + 1;
2008-02-11 17:21:41 +00:00
enum BinaryOperation {
Move,
MoveZ,
Swap,
Compare,
Negate
2008-08-16 17:45:36 +00:00
};
const unsigned BinaryOperationCount = Negate + 1;
2008-08-16 17:45:36 +00:00
enum TernaryOperation {
LongCompare,
2008-02-11 17:21:41 +00:00
Add,
Subtract,
Multiply,
Divide,
Remainder,
ShiftLeft,
ShiftRight,
UnsignedShiftRight,
And,
Or,
Xor
};
2008-08-16 17:45:36 +00:00
const unsigned TernaryOperationCount = Xor + 1;
2008-02-11 17:21:41 +00:00
enum OperandType {
2008-04-17 02:55:38 +00:00
ConstantOperand,
AddressOperand,
RegisterOperand,
2008-04-18 03:47:42 +00:00
MemoryOperand
2008-02-11 17:21:41 +00:00
};
2008-04-17 22:07:32 +00:00
const unsigned OperandTypeCount = MemoryOperand + 1;
2008-02-11 17:21:41 +00:00
const int NoRegister = -1;
const int AnyRegister = -2;
class Promise {
public:
virtual ~Promise() { }
virtual int64_t value() = 0;
virtual bool resolved() = 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 TraceHandler {
public:
virtual ~TraceHandler() { }
virtual void handleTrace(Promise* address) = 0;
};
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 = 0):
base(base), offset(offset), index(index), scale(scale)
2008-02-11 17:21:41 +00:00
{ }
int base;
int offset;
int index;
unsigned scale;
};
class Client {
public:
virtual ~Client() { }
2008-05-06 21:13:02 +00:00
virtual int acquireTemporary
(uint32_t mask = ~static_cast<uint32_t>(0)) = 0;
virtual void releaseTemporary(int r) = 0;
virtual void save(int r) = 0;
virtual void restore(int r) = 0;
};
2008-08-16 17:45:36 +00:00
class Offset {
public:
virtual ~Offset() { }
virtual unsigned calculate(unsigned start) = 0;
};
2008-08-17 19:32:40 +00:00
class Architecture {
public:
virtual ~Architecture() { }
2008-02-11 17:21:41 +00:00
2008-08-17 19:32:40 +00:00
virtual unsigned registerCount() = 0;
2008-08-17 19:32:40 +00:00
virtual int stack() = 0;
virtual int thread() = 0;
virtual int returnLow() = 0;
virtual int returnHigh() = 0;
virtual bool reserved(int register_) = 0;
2008-02-11 17:21:41 +00:00
2008-08-17 19:32:40 +00:00
virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0;
2008-02-11 17:21:41 +00:00
2008-08-17 19:32:40 +00:00
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
2008-02-11 17:21:41 +00:00
2008-08-17 19:32:40 +00:00
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
virtual void* frameIp(void* stack) = 0;
virtual unsigned frameHeaderSize() = 0;
virtual unsigned frameFooterSize() = 0;
virtual void nextFrame(void** stack, void** base) = 0;
virtual void* popReturnAddress(void* stack) = 0;
2008-08-17 19:32:40 +00:00
virtual void plan
(UnaryOperation op,
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
bool* thunk) = 0;
virtual void plan
(BinaryOperation op,
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
bool* thunk) = 0;
virtual void plan
(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,
bool* thunk) = 0;
2008-08-16 18:46:14 +00:00
virtual void acquire() = 0;
virtual void release() = 0;
2008-08-17 19:32:40 +00:00
};
2008-07-05 20:21:13 +00:00
2008-08-17 19:32:40 +00:00
virtual ~Assembler() { }
2008-08-17 19:32:40 +00:00
virtual void setClient(Client* client) = 0;
virtual Architecture* arch() = 0;
2008-08-17 19:32:40 +00:00
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset);
virtual void pushFrame(unsigned argumentCount, ...);
virtual void popFrame();
2008-02-11 17:21:41 +00:00
virtual void apply(Operation op) = 0;
2008-08-16 17:45:36 +00:00
virtual void apply(UnaryOperation op,
unsigned aSize, OperandType aType, Operand* aOperand) = 0;
2008-02-11 17:21:41 +00:00
2008-08-16 17:45:36 +00:00
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;
2008-02-11 17:21:41 +00:00
virtual void writeTo(uint8_t* dst) = 0;
virtual unsigned length() = 0;
virtual void dispose() = 0;
};
2008-08-17 19:32:40 +00:00
Assembler::Architecture*
makeArchitecture(System* system);
Assembler*
makeAssembler(System* system, Allocator* allocator, Zone* zone,
Assembler::Architecture* architecture);
2008-02-11 17:21:41 +00:00
} // namespace vm
#endif//ASSEMBLER_H