Merge branch 'master' of dice.ecovate.com:/home/dicej/git/vm

This commit is contained in:
Eric Scharff 2007-10-08 15:46:20 -06:00
commit bd8b7ddfb0
2 changed files with 339 additions and 63 deletions

View File

@ -353,6 +353,18 @@ throw_(MyThread* t, object o)
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
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) {
rex();
code.append(0x29);
@ -815,6 +846,11 @@ class Assembler {
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) {
rex();
code.append(0x09);
@ -944,6 +980,14 @@ class Assembler {
conditional(javaIP, 0x8e);
}
void jb(Label& label) {
conditional(label, 0x82);
}
void ja(Label& label) {
conditional(label, 0x87);
}
void cmp(int v, Register reg) {
assert(code.s, isByte(v)); // todo
@ -962,6 +1006,48 @@ class Assembler {
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 jumps;
};
@ -1028,6 +1114,54 @@ class Compiler: public Assembler {
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) {
switch (code) {
case ByteField:
@ -1087,6 +1221,10 @@ class Compiler: public Assembler {
}
}
void compileCall(void* function) {
compileCall2(function, 1);
}
void compileCall(void* function, object arg1) {
if (BytesPerWord == 4) {
push(poolRegister(), poolReference(arg1));
@ -1613,7 +1751,13 @@ class Compiler: public Assembler {
break;
case i2l:
push(0);
if (BytesPerWord == 8) {
sub(8, rsp);
} else {
pop(rax);
cdq();
pushLong(rax, rdx);
}
break;
case iadd:
@ -1764,6 +1908,17 @@ class Compiler: public Assembler {
add(c, rbp, localOffset(index, parameterFootprint));
} break;
case vm::imul:
pop(rax);
pop(rcx);
Assembler::imul(rcx);
push(rax);
break;
case ineg:
neg(rsp, 0);
break;
case instanceof: {
uint16_t index = codeReadInt16(t, code, ip);
@ -1860,9 +2015,28 @@ class Compiler: public Assembler {
case isub:
pop(rax);
pop(rcx);
sub(rax, rcx);
push(rcx);
sub(rax, rsp, 0);
break;
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;
case ldc:
@ -1901,91 +2075,190 @@ class Compiler: public Assembler {
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType))
{
push((longValue(t, v) ) & 0xFFFFFFFF);
push((longValue(t, v) >> 32) & 0xFFFFFFFF);
pushLong(longValue(t, v));
} else if (objectClass(t, v)
== arrayBody(t, t->m->types, Machine::DoubleType))
{
push((doubleValue(t, v) ) & 0xFFFFFFFF);
push((doubleValue(t, v) >> 32) & 0xFFFFFFFF);
pushLong(doubleValue(t, v));
} else {
abort(t);
}
} break;
case lconst_0:
push(0);
push(0);
pushLong(0);
break;
case lconst_1:
push(0);
push(1);
pushLong(1);
break;
// todo:
// case lcmp: {
// pop(rax);
// pop(rdx);
case lcmp: {
Label next(this);
Label less(this);
Label greater(this);
// if (BytesPerWord == 8) {
// shl(32, rax);
// }
// pushInt(t, a > b ? 1 : a == b ? 0 : -1);
// } goto loop;
if (BytesPerWord == 8) {
popLong(rdx);
popLong(rax);
cmp(rax, rdx);
jl(less);
jg(greater);
case lload: {
unsigned index = codeBody(t, code, ip++);
push(rbp, localOffset(index, parameterFootprint));
push(rbp, localOffset(index + 1, parameterFootprint));
push(0);
jmp(next);
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;
case lload_0: {
push(rbp, localOffset(0, parameterFootprint));
push(rbp, localOffset(1, parameterFootprint));
} break;
case ldiv_:
if (BytesPerWord == 8) {
popLong(rax);
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: {
push(rbp, localOffset(1, parameterFootprint));
push(rbp, localOffset(2, parameterFootprint));
} break;
case lload:
loadLong(codeBody(t, code, ip++), parameterFootprint);
break;
case lload_2: {
push(rbp, localOffset(2, parameterFootprint));
push(rbp, localOffset(3, parameterFootprint));
} break;
case lload_0:
loadLong(0, parameterFootprint);
break;
case lload_3: {
push(rbp, localOffset(3, parameterFootprint));
push(rbp, localOffset(4, parameterFootprint));
} break;
case lload_1:
loadLong(1, parameterFootprint);
break;
case lstore: {
unsigned index = codeBody(t, code, ip++);
pop(rbp, localOffset(index + 1, parameterFootprint));
pop(rbp, localOffset(index, parameterFootprint));
} break;
case lload_2:
loadLong(2, parameterFootprint);
break;
case lstore_0: {
pop(rbp, localOffset(1, parameterFootprint));
pop(rbp, localOffset(0, parameterFootprint));
} break;
case lload_3:
loadLong(3, parameterFootprint);
break;
case lstore_1: {
pop(rbp, localOffset(2, parameterFootprint));
pop(rbp, localOffset(1, parameterFootprint));
} break;
case lmul:
if (BytesPerWord == 8) {
popLong(rax);
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: {
pop(rbp, localOffset(3, parameterFootprint));
pop(rbp, localOffset(2, parameterFootprint));
} break;
add(4, rsp);
mov(rax, rsp, 0);
mov(rdx, rsp, 4);
}
break;
case lstore_3: {
pop(rbp, localOffset(4, parameterFootprint));
pop(rbp, localOffset(3, parameterFootprint));
} break;
case lneg:
if (BytesPerWord == 8) {
neg(rsp, 8);
} 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_: {
uint16_t index = codeReadInt16(t, code, ip);

View File

@ -1266,6 +1266,9 @@ inline void
dispose(Thread* t, Reference* r)
{
*(r->handle) = r->next;
if (r->next) {
r->next->handle = r->handle;
}
t->m->system->free(r);
}