mirror of
https://github.com/corda/corda.git
synced 2025-05-02 08:43:15 +00:00
working towards compiling simple methods
This commit is contained in:
parent
e13b755048
commit
ed806ca740
@ -857,7 +857,7 @@ class Frame {
|
|||||||
context->eventLog.append(PopEvent);
|
context->eventLog.append(PopEvent);
|
||||||
context->eventLog.appendAddress(c->top());
|
context->eventLog.appendAddress(c->top());
|
||||||
|
|
||||||
Compiler::Operand* r = c->pop(8);
|
Compiler::Operand* r = c->pop(size);
|
||||||
|
|
||||||
if (size == 8 and BytesPerWord == 8) {
|
if (size == 8 and BytesPerWord == 8) {
|
||||||
context->eventLog.append(PopEvent);
|
context->eventLog.append(PopEvent);
|
||||||
|
@ -161,6 +161,8 @@ class Read {
|
|||||||
next(0), value(0), event(0), eventNext(0)
|
next(0), value(0), event(0), eventNext(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
virtual ~Read() { }
|
||||||
|
|
||||||
virtual Site* pickSite(Context* c, Value* v) = 0;
|
virtual Site* pickSite(Context* c, Value* v) = 0;
|
||||||
|
|
||||||
virtual Site* allocateSite(Context* c) = 0;
|
virtual Site* allocateSite(Context* c) = 0;
|
||||||
|
361
src/x86.cpp
361
src/x86.cpp
@ -69,10 +69,6 @@ typedef void (*UnaryOperationType)(Context*, unsigned, Assembler::Operand*);
|
|||||||
typedef void (*BinaryOperationType)
|
typedef void (*BinaryOperationType)
|
||||||
(Context*, unsigned, Assembler::Operand*, unsigned, Assembler::Operand*);
|
(Context*, unsigned, Assembler::Operand*, unsigned, Assembler::Operand*);
|
||||||
|
|
||||||
typedef void (*TernaryOperationType)
|
|
||||||
(Context*, unsigned, Assembler::Operand*, unsigned, Assembler::Operand*,
|
|
||||||
unsigned, Assembler::Operand*);
|
|
||||||
|
|
||||||
class ArchitectureContext {
|
class ArchitectureContext {
|
||||||
public:
|
public:
|
||||||
ArchitectureContext(System* s): s(s) { }
|
ArchitectureContext(System* s): s(s) { }
|
||||||
@ -81,13 +77,10 @@ class ArchitectureContext {
|
|||||||
OperationType operations[OperationCount];
|
OperationType operations[OperationCount];
|
||||||
UnaryOperationType unaryOperations[UnaryOperationCount
|
UnaryOperationType unaryOperations[UnaryOperationCount
|
||||||
* OperandTypeCount];
|
* OperandTypeCount];
|
||||||
BinaryOperationType binaryOperations[BinaryOperationCount
|
BinaryOperationType binaryOperations
|
||||||
* OperandTypeCount
|
[(BinaryOperationCount + TernaryOperationCount)
|
||||||
* OperandTypeCount];
|
* OperandTypeCount
|
||||||
TernaryOperationType ternaryOperations[TernaryOperationCount
|
* OperandTypeCount];
|
||||||
* OperandTypeCount
|
|
||||||
* OperandTypeCount
|
|
||||||
* OperandTypeCount];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void NO_RETURN
|
inline void NO_RETURN
|
||||||
@ -332,20 +325,88 @@ index(BinaryOperation operation,
|
|||||||
OperandType operand2)
|
OperandType operand2)
|
||||||
{
|
{
|
||||||
return operation
|
return operation
|
||||||
+ (BinaryOperationCount * operand1)
|
+ ((BinaryOperationCount + TernaryOperationCount) * operand1)
|
||||||
+ (BinaryOperationCount * OperandTypeCount * operand2);
|
+ ((BinaryOperationCount + TernaryOperationCount)
|
||||||
|
* OperandTypeCount * operand2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
index(TernaryOperation operation,
|
index(TernaryOperation operation,
|
||||||
OperandType operand1,
|
OperandType operand1,
|
||||||
OperandType operand2,
|
OperandType operand2)
|
||||||
OperandType operand3)
|
|
||||||
{
|
{
|
||||||
return operation
|
return operation
|
||||||
+ (TernaryOperationCount * operand1)
|
+ ((BinaryOperationCount + TernaryOperationCount) * operand1)
|
||||||
+ (TernaryOperationCount * OperandTypeCount * operand2)
|
+ ((BinaryOperationCount + TernaryOperationCount)
|
||||||
+ (TernaryOperationCount * OperandTypeCount * OperandTypeCount * operand3);
|
* OperandTypeCount * operand2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
if (a->low & 8) rex(c, 0x40, a->low);
|
||||||
|
c->code.append(0xff);
|
||||||
|
c->code.append(0xe0 | (a->low & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
unconditional(c, 0xe9, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
moveCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||||
|
unsigned bSize, Assembler::Register* b);
|
||||||
|
|
||||||
|
void
|
||||||
|
longJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
Assembler::Register r(r10);
|
||||||
|
moveCR(c, size, a, size, &r);
|
||||||
|
jumpR(c, size, &r);
|
||||||
|
} else {
|
||||||
|
jumpC(c, size, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
callR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
if (a->low & 8) rex(c, 0x40, a->low);
|
||||||
|
c->code.append(0xff);
|
||||||
|
c->code.append(0xd0 | (a->low & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
unconditional(c, 0xe8, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
longCallC(Context* c, unsigned size, Assembler::Constant* a)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
Assembler::Register r(r10);
|
||||||
|
moveCR(c, size, a, size, &r);
|
||||||
|
callR(c, size, &r);
|
||||||
|
} else {
|
||||||
|
callC(c, size, a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -361,6 +422,26 @@ pushR(Context* c, unsigned size, Assembler::Register* a)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||||
|
unsigned bSize, Assembler::Register* b);
|
||||||
|
|
||||||
|
void
|
||||||
|
popR(Context* c, unsigned size, Assembler::Register* a)
|
||||||
|
{
|
||||||
|
if (BytesPerWord == 4 and size == 8) {
|
||||||
|
Assembler::Register ah(a->high);
|
||||||
|
|
||||||
|
popR(c, 4, a);
|
||||||
|
popR(c, 4, &ah);
|
||||||
|
} else {
|
||||||
|
c->code.append(0x58 | a->low);
|
||||||
|
if (BytesPerWord == 8 and size == 4) {
|
||||||
|
moveRR(c, 4, a, 8, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||||
unsigned bSize, Assembler::Register* b)
|
unsigned bSize, Assembler::Register* b)
|
||||||
@ -424,34 +505,236 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
popR(Context* c, unsigned size, Assembler::Register* a)
|
moveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
||||||
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
if (BytesPerWord == 4 and size == 8) {
|
assert(c, aSize == bSize);
|
||||||
Assembler::Register ah(a->high);
|
|
||||||
|
|
||||||
popR(c, 4, a);
|
switch (aSize) {
|
||||||
popR(c, 4, &ah);
|
case 1:
|
||||||
|
encode2(c, 0x0fbe, b->low, a, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
encode2(c, 0x0fbf, b->low, a, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
|
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
|
||||||
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
|
moveMR(c, 4, a, 4, b);
|
||||||
|
moveMR(c, 4, &ah, 4, &bh);
|
||||||
|
} else if (BytesPerWord == 8 and aSize == 4) {
|
||||||
|
encode(c, 0x63, b->low, a, true);
|
||||||
|
} else {
|
||||||
|
encode(c, 0x8b, b->low, a, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: abort(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
moveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
||||||
|
unsigned bSize UNUSED, Assembler::Memory* b)
|
||||||
|
{
|
||||||
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
|
Assembler::Register ah(a->high);
|
||||||
|
Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale);
|
||||||
|
|
||||||
|
moveRM(c, 4, a, 4, b);
|
||||||
|
moveRM(c, 4, &ah, 4, &bh);
|
||||||
|
} else if (BytesPerWord == 8 and aSize == 4) {
|
||||||
|
encode(c, 0x89, a->low, b, false);
|
||||||
} else {
|
} else {
|
||||||
c->code.append(0x58 | a->low);
|
switch (aSize) {
|
||||||
if (BytesPerWord == 8 and size == 4) {
|
case 1:
|
||||||
moveRR(c, 4, a, 8, a);
|
if (BytesPerWord == 8) {
|
||||||
|
if (a->low > rbx) {
|
||||||
|
encode2(c, 0x4088, a->low, b, false);
|
||||||
|
} else {
|
||||||
|
encode(c, 0x88, a->low, b, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(c, a->low <= rbx);
|
||||||
|
|
||||||
|
encode(c, 0x88, a->low, b, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
encode2(c, 0x6689, a->low, b, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BytesPerWord:
|
||||||
|
encode(c, 0x89, a->low, b, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
populateTables(ArchitectureContext*)
|
moveCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||||
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
// todo
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
// const int Constant = ConstantOperand;
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
// const int Address = AddressOperand;
|
int64_t v = a->value->value();
|
||||||
// const int Register = RegisterOperand;
|
|
||||||
// const int Memory = MemoryOperand;
|
|
||||||
|
|
||||||
// #define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
// #define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
Assembler::Constant ah(&high);
|
||||||
// #define CAST3(x) reinterpret_cast<TernaryOperationType>(x)
|
|
||||||
|
ResolvedPromise low(v & 0xFFFFFFFF);
|
||||||
|
Assembler::Constant al(&low);
|
||||||
|
|
||||||
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
|
moveCR(c, 4, &al, 4, b);
|
||||||
|
moveCR(c, 4, &ah, 4, &bh);
|
||||||
|
} else {
|
||||||
|
rex(c, 0x48, b->low);
|
||||||
|
c->code.append(0xb8 | b->low);
|
||||||
|
if (a->value->resolved()) {
|
||||||
|
c->code.appendAddress(a->value->value());
|
||||||
|
} else {
|
||||||
|
appendImmediateTask(c, a->value, c->code.length());
|
||||||
|
c->code.appendAddress(static_cast<uintptr_t>(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
subtractBorrowCR(Context* c, unsigned aSize UNUSED, Assembler::Constant* a,
|
||||||
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, aSize == bSize);
|
||||||
|
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||||
|
|
||||||
|
int64_t v = a->value->value();
|
||||||
|
if (isInt8(v)) {
|
||||||
|
c->code.append(0x83);
|
||||||
|
c->code.append(0xd8 | b->low);
|
||||||
|
c->code.append(v);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
subtractRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||||
|
unsigned bSize, Assembler::Register* b);
|
||||||
|
|
||||||
|
void
|
||||||
|
subtractCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||||
|
unsigned bSize, Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
|
int64_t v = a->value->value();
|
||||||
|
if (v) {
|
||||||
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
|
Assembler::Constant ah(&high);
|
||||||
|
|
||||||
|
ResolvedPromise low(v & 0xFFFFFFFF);
|
||||||
|
Assembler::Constant al(&low);
|
||||||
|
|
||||||
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
|
subtractCR(c, 4, &al, 4, b);
|
||||||
|
subtractBorrowCR(c, 4, &ah, 4, &bh);
|
||||||
|
} else {
|
||||||
|
if (aSize == 8) rex(c);
|
||||||
|
if (isInt8(v)) {
|
||||||
|
c->code.append(0x83);
|
||||||
|
c->code.append(0xe8 | b->low);
|
||||||
|
c->code.append(v);
|
||||||
|
} else if (isInt32(v)) {
|
||||||
|
c->code.append(0x81);
|
||||||
|
c->code.append(0xe8 | b->low);
|
||||||
|
c->code.append4(v);
|
||||||
|
} else {
|
||||||
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
|
moveCR(c, aSize, a, aSize, &tmp);
|
||||||
|
subtractRR(c, aSize, &tmp, bSize, b);
|
||||||
|
c->client->releaseTemporary(tmp.low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
subtractBorrowRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
||||||
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, aSize == bSize);
|
||||||
|
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||||
|
|
||||||
|
if (aSize == 8) rex(c);
|
||||||
|
c->code.append(0x19);
|
||||||
|
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
subtractRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||||
|
unsigned bSize, Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
|
Assembler::Register ah(a->high);
|
||||||
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
|
subtractRR(c, 4, a, 4, b);
|
||||||
|
subtractBorrowRR(c, 4, &ah, 4, &bh);
|
||||||
|
} else {
|
||||||
|
if (aSize == 8) rex(c);
|
||||||
|
c->code.append(0x29);
|
||||||
|
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
populateTables(ArchitectureContext* c)
|
||||||
|
{
|
||||||
|
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
||||||
|
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
||||||
|
|
||||||
|
const OperandType C = ConstantOperand;
|
||||||
|
//const OperandType A = AddressOperand;
|
||||||
|
const OperandType R = RegisterOperand;
|
||||||
|
const OperandType M = MemoryOperand;
|
||||||
|
|
||||||
|
OperationType* zo = c->operations;
|
||||||
|
UnaryOperationType* uo = c->unaryOperations;
|
||||||
|
BinaryOperationType* bo = c->binaryOperations;
|
||||||
|
|
||||||
|
zo[Return] = return_;
|
||||||
|
|
||||||
|
uo[index(Call, C)] = CAST1(callC);
|
||||||
|
|
||||||
|
uo[index(LongCall, C)] = CAST1(longCallC);
|
||||||
|
|
||||||
|
uo[index(Jump, R)] = CAST1(jumpR);
|
||||||
|
|
||||||
|
uo[index(Jump, C)] = CAST1(jumpC);
|
||||||
|
|
||||||
|
uo[index(LongJump, C)] = CAST1(longJumpC);
|
||||||
|
|
||||||
|
bo[index(Move, R, R)] = CAST2(moveRR);
|
||||||
|
bo[index(Move, M, R)] = CAST2(moveMR);
|
||||||
|
bo[index(Move, R, M)] = CAST2(moveRM);
|
||||||
|
|
||||||
|
bo[index(Subtract, C, R)] = CAST2(subtractCR);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyArchitecture: public Assembler::Architecture {
|
class MyArchitecture: public Assembler::Architecture {
|
||||||
@ -742,8 +1025,12 @@ class MyAssembler: public Assembler {
|
|||||||
unsigned bSize, OperandType bType, Operand* bOperand,
|
unsigned bSize, OperandType bType, Operand* bOperand,
|
||||||
unsigned cSize, OperandType cType, Operand* cOperand)
|
unsigned cSize, OperandType cType, Operand* cOperand)
|
||||||
{
|
{
|
||||||
arch_->c.ternaryOperations[index(op, aType, bType, cType)]
|
assert(&c, bSize == cSize);
|
||||||
(&c, aSize, aOperand, bSize, bOperand, cSize, cOperand);
|
assert(&c, bType == cType);
|
||||||
|
assert(&c, bOperand == cOperand);
|
||||||
|
|
||||||
|
arch_->c.binaryOperations[index(op, aType, bType)]
|
||||||
|
(&c, aSize, aOperand, bSize, bOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void writeTo(uint8_t* dst) {
|
virtual void writeTo(uint8_t* dst) {
|
||||||
|
7
test/Simple.java
Normal file
7
test/Simple.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
public class Simple {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 1;
|
||||||
|
int b = 2;
|
||||||
|
int c = a + b;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user