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
|
|
|
|
};
|
|
|
|
|
2008-02-12 00:20:32 +00:00
|
|
|
const unsigned OperationCount = Return + 1;
|
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
enum UnaryOperation {
|
|
|
|
Push,
|
2008-02-12 15:21:51 +00:00
|
|
|
Pop,
|
2008-02-17 22:29:04 +00:00
|
|
|
Call,
|
2008-06-02 13:49:09 +00:00
|
|
|
LongCall,
|
2008-02-17 22:29:04 +00:00
|
|
|
AlignedCall,
|
|
|
|
Jump,
|
2008-06-02 13:49:09 +00:00
|
|
|
LongJump,
|
2008-02-11 17:21:41 +00:00
|
|
|
JumpIfLess,
|
|
|
|
JumpIfGreater,
|
|
|
|
JumpIfLessOrEqual,
|
|
|
|
JumpIfGreaterOrEqual,
|
|
|
|
JumpIfEqual,
|
|
|
|
JumpIfNotEqual,
|
|
|
|
Negate
|
|
|
|
};
|
|
|
|
|
2008-02-12 00:20:32 +00:00
|
|
|
const unsigned UnaryOperationCount = Negate + 1;
|
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
enum BinaryOperation {
|
|
|
|
LoadAddress,
|
2008-02-12 02:06:12 +00:00
|
|
|
Move,
|
|
|
|
MoveZ,
|
2008-02-12 00:20:32 +00:00
|
|
|
Move4To8,
|
2008-05-12 13:54:47 +00:00
|
|
|
Swap,
|
2008-06-12 16:56:48 +00:00
|
|
|
LongCompare,
|
2008-02-11 17:21:41 +00:00
|
|
|
Compare,
|
|
|
|
Add,
|
|
|
|
Subtract,
|
|
|
|
Multiply,
|
|
|
|
Divide,
|
|
|
|
Remainder,
|
|
|
|
ShiftLeft,
|
|
|
|
ShiftRight,
|
|
|
|
UnsignedShiftRight,
|
|
|
|
And,
|
|
|
|
Or,
|
|
|
|
Xor
|
|
|
|
};
|
|
|
|
|
2008-02-12 00:20:32 +00:00
|
|
|
const unsigned BinaryOperationCount = 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-12 00:20:32 +00:00
|
|
|
|
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:
|
2008-04-13 19:48:20 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2008-03-13 23:43:11 +00:00
|
|
|
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;
|
2008-03-13 23:43:11 +00:00
|
|
|
virtual void releaseTemporary(int r) = 0;
|
2008-04-27 20:15:18 +00:00
|
|
|
|
|
|
|
virtual void save(int r) = 0;
|
|
|
|
virtual void restore(int r) = 0;
|
2008-03-13 23:43:11 +00:00
|
|
|
};
|
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
virtual ~Assembler() { }
|
|
|
|
|
2008-03-13 23:43:11 +00:00
|
|
|
virtual void setClient(Client* client) = 0;
|
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
virtual unsigned registerCount() = 0;
|
|
|
|
|
|
|
|
virtual int base() = 0;
|
|
|
|
virtual int stack() = 0;
|
|
|
|
virtual int thread() = 0;
|
|
|
|
virtual int returnLow() = 0;
|
|
|
|
virtual int returnHigh() = 0;
|
|
|
|
|
|
|
|
virtual unsigned argumentRegisterCount() = 0;
|
|
|
|
virtual int argumentRegister(unsigned index) = 0;
|
|
|
|
|
2008-05-04 19:09:12 +00:00
|
|
|
virtual void plan(UnaryOperation op, unsigned size, uint8_t* typeMask,
|
2008-05-31 22:14:27 +00:00
|
|
|
uint64_t* registerMask, bool* thunk) = 0;
|
2008-05-04 19:09:12 +00:00
|
|
|
|
2008-05-06 21:13:02 +00:00
|
|
|
virtual void plan(BinaryOperation op, unsigned size, uint8_t* aTypeMask,
|
2008-05-04 19:09:12 +00:00
|
|
|
uint64_t* aRegisterMask, uint8_t* bTypeMask,
|
2008-05-31 22:14:27 +00:00
|
|
|
uint64_t* bRegisterMask, bool* thunk) = 0;
|
2008-02-11 17:21:41 +00:00
|
|
|
|
|
|
|
virtual void apply(Operation op) = 0;
|
|
|
|
|
|
|
|
virtual void apply(UnaryOperation op, unsigned size, OperandType type,
|
|
|
|
Operand* operand) = 0;
|
|
|
|
|
|
|
|
virtual void apply(BinaryOperation op, unsigned size, OperandType aType,
|
|
|
|
Operand* a, OperandType bType, Operand* b) = 0;
|
|
|
|
|
|
|
|
virtual void writeTo(uint8_t* dst) = 0;
|
|
|
|
|
|
|
|
virtual unsigned length() = 0;
|
|
|
|
|
|
|
|
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
|
|
|
|
|
|
|
|
virtual void dispose() = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
Assembler*
|
|
|
|
makeAssembler(System* system, Allocator* allocator, Zone* zone);
|
|
|
|
|
|
|
|
} // namespace vm
|
|
|
|
|
|
|
|
#endif//ASSEMBLER_H
|