2008-06-25 20:53:48 +00:00
|
|
|
/* 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
|
|
|
|
};
|
|
|
|
|
2008-02-12 00:20:32 +00:00
|
|
|
const unsigned OperationCount = Return + 1;
|
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
enum UnaryOperation {
|
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,
|
2008-08-19 23:38:37 +00:00
|
|
|
JumpIfNotEqual
|
2008-02-11 17:21:41 +00:00
|
|
|
};
|
|
|
|
|
2008-08-19 23:38:37 +00:00
|
|
|
const unsigned UnaryOperationCount = JumpIfNotEqual + 1;
|
2008-02-12 00:20:32 +00:00
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
enum BinaryOperation {
|
2008-02-12 02:06:12 +00:00
|
|
|
Move,
|
|
|
|
MoveZ,
|
2008-05-12 13:54:47 +00:00
|
|
|
Swap,
|
2008-08-19 23:38:37 +00:00
|
|
|
Compare,
|
|
|
|
Negate
|
2008-08-16 17:45:36 +00:00
|
|
|
};
|
|
|
|
|
2008-08-19 23:38:37 +00:00
|
|
|
const unsigned BinaryOperationCount = Negate + 1;
|
2008-08-16 17:45:36 +00:00
|
|
|
|
|
|
|
enum TernaryOperation {
|
2008-06-12 16:56:48 +00:00
|
|
|
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-12 00:20:32 +00:00
|
|
|
|
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-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-03-13 23:43:11 +00:00
|
|
|
|
2008-08-17 19:32:40 +00:00
|
|
|
virtual int stack() = 0;
|
|
|
|
virtual int thread() = 0;
|
|
|
|
virtual int returnLow() = 0;
|
|
|
|
virtual int returnHigh() = 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;
|
|
|
|
|
2008-08-18 15:23:01 +00:00
|
|
|
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
|
|
|
|
2008-08-18 15:23:01 +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-05-04 19:09:12 +00:00
|
|
|
|
2008-08-17 19:32:40 +00:00
|
|
|
virtual void setClient(Client* client) = 0;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2008-08-19 23:38:37 +00:00
|
|
|
Assembler*
|
|
|
|
makeAssembler(System* system, Allocator* allocator, Zone* zone,
|
|
|
|
Assembler::Architecture* architecture);
|
|
|
|
|
2008-02-11 17:21:41 +00:00
|
|
|
} // namespace vm
|
|
|
|
|
|
|
|
#endif//ASSEMBLER_H
|