mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
Merge branch 'master' of dice.ecovate.com:/home/dicej/git/vm
This commit is contained in:
commit
bd8b7ddfb0
399
src/compile.cpp
399
src/compile.cpp
@ -353,6 +353,18 @@ throw_(MyThread* t, object o)
|
|||||||
unwind(t);
|
unwind(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
divideLong(MyThread*, int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
moduloLong(MyThread*, int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return a % b;
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
makeBlankObjectArray(Thread* t, object class_, int32_t length)
|
makeBlankObjectArray(Thread* t, object class_, int32_t length)
|
||||||
{
|
{
|
||||||
@ -800,6 +812,25 @@ class Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adc(int32_t v, Register dst) {
|
||||||
|
assert(code.s, isByte(v)); // todo
|
||||||
|
|
||||||
|
rex();
|
||||||
|
code.append(0x83);
|
||||||
|
code.append(0xd0 | dst);
|
||||||
|
code.append(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void adc(Register src, Register dst, unsigned dstOffset) {
|
||||||
|
rex();
|
||||||
|
offsetInstruction(0x11, 0, 0x40, 0x80, src, dst, dstOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sub(Register src, Register dst, unsigned dstOffset) {
|
||||||
|
rex();
|
||||||
|
offsetInstruction(0x29, 0, 0x40, 0x80, src, dst, dstOffset);
|
||||||
|
}
|
||||||
|
|
||||||
void sub(Register src, Register dst) {
|
void sub(Register src, Register dst) {
|
||||||
rex();
|
rex();
|
||||||
code.append(0x29);
|
code.append(0x29);
|
||||||
@ -815,6 +846,11 @@ class Assembler {
|
|||||||
code.append(v);
|
code.append(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sbb(Register src, Register dst, unsigned dstOffset) {
|
||||||
|
rex();
|
||||||
|
offsetInstruction(0x19, 0, 0x40, 0x80, src, dst, dstOffset);
|
||||||
|
}
|
||||||
|
|
||||||
void or_(Register src, Register dst) {
|
void or_(Register src, Register dst) {
|
||||||
rex();
|
rex();
|
||||||
code.append(0x09);
|
code.append(0x09);
|
||||||
@ -944,6 +980,14 @@ class Assembler {
|
|||||||
conditional(javaIP, 0x8e);
|
conditional(javaIP, 0x8e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jb(Label& label) {
|
||||||
|
conditional(label, 0x82);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ja(Label& label) {
|
||||||
|
conditional(label, 0x87);
|
||||||
|
}
|
||||||
|
|
||||||
void cmp(int v, Register reg) {
|
void cmp(int v, Register reg) {
|
||||||
assert(code.s, isByte(v)); // todo
|
assert(code.s, isByte(v)); // todo
|
||||||
|
|
||||||
@ -962,6 +1006,48 @@ class Assembler {
|
|||||||
code.append(0xd0 | reg);
|
code.append(0xd0 | reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cdq() {
|
||||||
|
code.append(0x99);
|
||||||
|
}
|
||||||
|
|
||||||
|
void imul4(Register src, unsigned srcOffset, Register dst) {
|
||||||
|
code.append(0x0f);
|
||||||
|
offsetInstruction(0xaf, 0, 0x40, 0x80, dst, src, srcOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void imul(Register src, unsigned srcOffset, Register dst) {
|
||||||
|
rex();
|
||||||
|
imul4(src, srcOffset, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void imul(Register src) {
|
||||||
|
rex();
|
||||||
|
code.append(0xf7);
|
||||||
|
code.append(0xe8 | src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void idiv(Register src) {
|
||||||
|
rex();
|
||||||
|
code.append(0xf7);
|
||||||
|
code.append(0xf8 | src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mul(Register src, unsigned offset) {
|
||||||
|
rex();
|
||||||
|
offsetInstruction(0xf7, 0x20, 0x60, 0xa0, rax, src, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void neg(Register reg, unsigned offset) {
|
||||||
|
rex();
|
||||||
|
offsetInstruction(0xf7, 0x10, 0x50, 0x90, rax, reg, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void neg(Register reg) {
|
||||||
|
rex();
|
||||||
|
code.append(0xf7);
|
||||||
|
code.append(0xd8 | reg);
|
||||||
|
}
|
||||||
|
|
||||||
Buffer code;
|
Buffer code;
|
||||||
Buffer jumps;
|
Buffer jumps;
|
||||||
};
|
};
|
||||||
@ -1028,6 +1114,54 @@ class Compiler: public Assembler {
|
|||||||
pool(t->m->system, 256)
|
pool(t->m->system, 256)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void pushLong(uint64_t v) {
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
pushAddress(v);
|
||||||
|
sub(8, rsp);
|
||||||
|
} else {
|
||||||
|
push((v >> 32) & 0xFFFFFFFF);
|
||||||
|
push((v ) & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushLong(Register low, Register high) {
|
||||||
|
assert(t, BytesPerWord == 4);
|
||||||
|
push(high);
|
||||||
|
push(low);
|
||||||
|
}
|
||||||
|
|
||||||
|
void popLong(Register r) {
|
||||||
|
assert(t, BytesPerWord == 8);
|
||||||
|
add(8, rsp);
|
||||||
|
pop(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void popLong(Register low, Register high) {
|
||||||
|
assert(t, BytesPerWord == 4);
|
||||||
|
pop(low);
|
||||||
|
pop(high);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadLong(uint64_t index, unsigned parameterFootprint) {
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
push(rbp, localOffset(index, parameterFootprint));
|
||||||
|
sub(8, rsp);
|
||||||
|
} else {
|
||||||
|
push(rbp, localOffset(index + 1, parameterFootprint));
|
||||||
|
push(rbp, localOffset(index, parameterFootprint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void storeLong(uint64_t index, unsigned parameterFootprint) {
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
add(8, rsp);
|
||||||
|
pop(rbp, localOffset(index, parameterFootprint));
|
||||||
|
} else {
|
||||||
|
pop(rbp, localOffset(index, parameterFootprint));
|
||||||
|
pop(rbp, localOffset(index + 1, parameterFootprint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pushReturnValue(unsigned code) {
|
void pushReturnValue(unsigned code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case ByteField:
|
case ByteField:
|
||||||
@ -1087,6 +1221,10 @@ class Compiler: public Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void compileCall(void* function) {
|
||||||
|
compileCall2(function, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void compileCall(void* function, object arg1) {
|
void compileCall(void* function, object arg1) {
|
||||||
if (BytesPerWord == 4) {
|
if (BytesPerWord == 4) {
|
||||||
push(poolRegister(), poolReference(arg1));
|
push(poolRegister(), poolReference(arg1));
|
||||||
@ -1613,7 +1751,13 @@ class Compiler: public Assembler {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case i2l:
|
case i2l:
|
||||||
push(0);
|
if (BytesPerWord == 8) {
|
||||||
|
sub(8, rsp);
|
||||||
|
} else {
|
||||||
|
pop(rax);
|
||||||
|
cdq();
|
||||||
|
pushLong(rax, rdx);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iadd:
|
case iadd:
|
||||||
@ -1764,6 +1908,17 @@ class Compiler: public Assembler {
|
|||||||
add(c, rbp, localOffset(index, parameterFootprint));
|
add(c, rbp, localOffset(index, parameterFootprint));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case vm::imul:
|
||||||
|
pop(rax);
|
||||||
|
pop(rcx);
|
||||||
|
Assembler::imul(rcx);
|
||||||
|
push(rax);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ineg:
|
||||||
|
neg(rsp, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case instanceof: {
|
case instanceof: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
@ -1860,9 +2015,28 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
case isub:
|
case isub:
|
||||||
pop(rax);
|
pop(rax);
|
||||||
pop(rcx);
|
sub(rax, rsp, 0);
|
||||||
sub(rax, rcx);
|
break;
|
||||||
push(rcx);
|
|
||||||
|
case l2i:
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
add(BytesPerWord, rsp);
|
||||||
|
} else {
|
||||||
|
pop(rax);
|
||||||
|
mov(rax, rsp, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ladd:
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
add(8, rsp);
|
||||||
|
pop(rax);
|
||||||
|
add(rax, rsp, BytesPerWord);
|
||||||
|
} else {
|
||||||
|
popLong(rax, rdx);
|
||||||
|
add(rax, rsp, 0);
|
||||||
|
adc(rdx, rsp, BytesPerWord);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ldc:
|
case ldc:
|
||||||
@ -1901,91 +2075,190 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType))
|
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType))
|
||||||
{
|
{
|
||||||
push((longValue(t, v) ) & 0xFFFFFFFF);
|
pushLong(longValue(t, v));
|
||||||
push((longValue(t, v) >> 32) & 0xFFFFFFFF);
|
|
||||||
} else if (objectClass(t, v)
|
} else if (objectClass(t, v)
|
||||||
== arrayBody(t, t->m->types, Machine::DoubleType))
|
== arrayBody(t, t->m->types, Machine::DoubleType))
|
||||||
{
|
{
|
||||||
push((doubleValue(t, v) ) & 0xFFFFFFFF);
|
pushLong(doubleValue(t, v));
|
||||||
push((doubleValue(t, v) >> 32) & 0xFFFFFFFF);
|
|
||||||
} else {
|
} else {
|
||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lconst_0:
|
case lconst_0:
|
||||||
push(0);
|
pushLong(0);
|
||||||
push(0);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lconst_1:
|
case lconst_1:
|
||||||
push(0);
|
pushLong(1);
|
||||||
push(1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// todo:
|
case lcmp: {
|
||||||
// case lcmp: {
|
Label next(this);
|
||||||
// pop(rax);
|
Label less(this);
|
||||||
// pop(rdx);
|
Label greater(this);
|
||||||
|
|
||||||
// if (BytesPerWord == 8) {
|
if (BytesPerWord == 8) {
|
||||||
// shl(32, rax);
|
popLong(rdx);
|
||||||
// }
|
popLong(rax);
|
||||||
|
|
||||||
// pushInt(t, a > b ? 1 : a == b ? 0 : -1);
|
cmp(rax, rdx);
|
||||||
// } goto loop;
|
jl(less);
|
||||||
|
jg(greater);
|
||||||
|
|
||||||
case lload: {
|
push(0);
|
||||||
unsigned index = codeBody(t, code, ip++);
|
jmp(next);
|
||||||
push(rbp, localOffset(index, parameterFootprint));
|
|
||||||
push(rbp, localOffset(index + 1, parameterFootprint));
|
less.mark();
|
||||||
|
push(-1);
|
||||||
|
jmp(next);
|
||||||
|
|
||||||
|
greater.mark();
|
||||||
|
push(1);
|
||||||
|
|
||||||
|
next.mark();
|
||||||
|
} else {
|
||||||
|
popLong(rcx, rbx);
|
||||||
|
popLong(rax, rdx);
|
||||||
|
|
||||||
|
cmp(rdx, rbx);
|
||||||
|
jl(less);
|
||||||
|
jg(greater);
|
||||||
|
|
||||||
|
cmp(rax, rcx);
|
||||||
|
jb(less);
|
||||||
|
ja(greater);
|
||||||
|
|
||||||
|
push(0);
|
||||||
|
jmp(next);
|
||||||
|
|
||||||
|
less.mark();
|
||||||
|
push(-1);
|
||||||
|
jmp(next);
|
||||||
|
|
||||||
|
greater.mark();
|
||||||
|
push(1);
|
||||||
|
|
||||||
|
next.mark();
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lload_0: {
|
case ldiv_:
|
||||||
push(rbp, localOffset(0, parameterFootprint));
|
if (BytesPerWord == 8) {
|
||||||
push(rbp, localOffset(1, parameterFootprint));
|
popLong(rax);
|
||||||
} break;
|
popLong(rcx);
|
||||||
|
Assembler::idiv(rcx);
|
||||||
|
pushLong(rax);
|
||||||
|
} else {
|
||||||
|
compileCall(reinterpret_cast<void*>(divideLong));
|
||||||
|
add(4, rsp);
|
||||||
|
mov(rax, rsp, 0);
|
||||||
|
mov(rdx, rsp, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case lload_1: {
|
case lload:
|
||||||
push(rbp, localOffset(1, parameterFootprint));
|
loadLong(codeBody(t, code, ip++), parameterFootprint);
|
||||||
push(rbp, localOffset(2, parameterFootprint));
|
break;
|
||||||
} break;
|
|
||||||
|
|
||||||
case lload_2: {
|
case lload_0:
|
||||||
push(rbp, localOffset(2, parameterFootprint));
|
loadLong(0, parameterFootprint);
|
||||||
push(rbp, localOffset(3, parameterFootprint));
|
break;
|
||||||
} break;
|
|
||||||
|
|
||||||
case lload_3: {
|
case lload_1:
|
||||||
push(rbp, localOffset(3, parameterFootprint));
|
loadLong(1, parameterFootprint);
|
||||||
push(rbp, localOffset(4, parameterFootprint));
|
break;
|
||||||
} break;
|
|
||||||
|
|
||||||
case lstore: {
|
case lload_2:
|
||||||
unsigned index = codeBody(t, code, ip++);
|
loadLong(2, parameterFootprint);
|
||||||
pop(rbp, localOffset(index + 1, parameterFootprint));
|
break;
|
||||||
pop(rbp, localOffset(index, parameterFootprint));
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case lstore_0: {
|
case lload_3:
|
||||||
pop(rbp, localOffset(1, parameterFootprint));
|
loadLong(3, parameterFootprint);
|
||||||
pop(rbp, localOffset(0, parameterFootprint));
|
break;
|
||||||
} break;
|
|
||||||
|
|
||||||
case lstore_1: {
|
case lmul:
|
||||||
pop(rbp, localOffset(2, parameterFootprint));
|
if (BytesPerWord == 8) {
|
||||||
pop(rbp, localOffset(1, parameterFootprint));
|
popLong(rax);
|
||||||
} break;
|
popLong(rcx);
|
||||||
|
Assembler::imul(rcx);
|
||||||
|
pushLong(rax);
|
||||||
|
} else {
|
||||||
|
mov(rsp, 4, rcx);
|
||||||
|
Assembler::imul(rsp, 8, rcx);
|
||||||
|
mov(rsp, 12, rax);
|
||||||
|
Assembler::imul(rsp, 0, rax);
|
||||||
|
add(rax, rcx);
|
||||||
|
mov(rsp, 8, rax);
|
||||||
|
mul(rsp, 0);
|
||||||
|
add(rcx, rdx);
|
||||||
|
|
||||||
case lstore_2: {
|
add(4, rsp);
|
||||||
pop(rbp, localOffset(3, parameterFootprint));
|
mov(rax, rsp, 0);
|
||||||
pop(rbp, localOffset(2, parameterFootprint));
|
mov(rdx, rsp, 4);
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case lstore_3: {
|
case lneg:
|
||||||
pop(rbp, localOffset(4, parameterFootprint));
|
if (BytesPerWord == 8) {
|
||||||
pop(rbp, localOffset(3, parameterFootprint));
|
neg(rsp, 8);
|
||||||
} break;
|
} else {
|
||||||
|
mov(rsp, 0, rax);
|
||||||
|
mov(rsp, 4, rdx);
|
||||||
|
neg(rax);
|
||||||
|
adc(0, rdx);
|
||||||
|
neg(rdx);
|
||||||
|
|
||||||
|
mov(rax, rsp, 0);
|
||||||
|
mov(rdx, rsp, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lrem:
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
popLong(rax);
|
||||||
|
popLong(rcx);
|
||||||
|
Assembler::idiv(rcx);
|
||||||
|
pushLong(rdx);
|
||||||
|
} else {
|
||||||
|
compileCall(reinterpret_cast<void*>(moduloLong));
|
||||||
|
add(4, rsp);
|
||||||
|
mov(rax, rsp, 0);
|
||||||
|
mov(rdx, rsp, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lstore:
|
||||||
|
storeLong(codeBody(t, code, ip++), parameterFootprint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lstore_0:
|
||||||
|
storeLong(0, parameterFootprint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lstore_1:
|
||||||
|
storeLong(1, parameterFootprint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lstore_2:
|
||||||
|
storeLong(2, parameterFootprint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lstore_3:
|
||||||
|
storeLong(3, parameterFootprint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lsub:
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
add(8, rsp);
|
||||||
|
pop(rax);
|
||||||
|
sub(rax, rsp, BytesPerWord);
|
||||||
|
} else {
|
||||||
|
popLong(rax, rdx);
|
||||||
|
sub(rax, rsp, 0);
|
||||||
|
sbb(rdx, rsp, BytesPerWord);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case new_: {
|
case new_: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
@ -1266,6 +1266,9 @@ inline void
|
|||||||
dispose(Thread* t, Reference* r)
|
dispose(Thread* t, Reference* r)
|
||||||
{
|
{
|
||||||
*(r->handle) = r->next;
|
*(r->handle) = r->next;
|
||||||
|
if (r->next) {
|
||||||
|
r->next->handle = r->handle;
|
||||||
|
}
|
||||||
t->m->system->free(r);
|
t->m->system->free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user