diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 508d0fbbf9..ebb272a3e0 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -476,3 +476,16 @@ Java_java_lang_Double_fillBufferWithDouble(JNIEnv* e, jclass, jdouble val, e->ReleaseByteArrayElements(buffer, buf, 0); return count; } + +extern "C" JNIEXPORT void JNICALL +Java_java_lang_Long_printLong(JNIEnv*, jclass, jlong v) +{ + fprintf(stderr, "DEBUG: %lld\n", v); +} + + +extern "C" JNIEXPORT void JNICALL +Java_java_lang_Long_printInt(JNIEnv*, jclass, jint v) +{ + fprintf(stderr, "DEBUG: %d\n", v); +} diff --git a/classpath/java/lang/Long.java b/classpath/java/lang/Long.java index 013ac883bb..4c006ea549 100644 --- a/classpath/java/lang/Long.java +++ b/classpath/java/lang/Long.java @@ -38,11 +38,16 @@ public final class Long extends Number implements Comparable { return String.valueOf(value); } + private static native void printLong(long v); + private static native void printInt(long v); + public static String toString(long v, int radix) { if (radix < 1 || radix > 36) { throw new IllegalArgumentException("radix " + radix + " not in [1,36]"); } + printLong(v); + if (v == 0) { return "0"; } @@ -53,10 +58,13 @@ public final class Long extends Number implements Comparable { int size = (negative ? 1 : 0); for (long n = v; n > 0; n /= radix) ++size; + printInt(size); + char[] array = new char[size]; int i = array.length - 1; for (long n = v; n > 0; n /= radix) { + printLong(n); long digit = n % radix; if (digit >= 0 && digit <= 9) { array[i] = (char) ('0' + digit); diff --git a/src/compile.cpp b/src/compile.cpp index a48398874e..ee81de2aa6 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -18,7 +18,7 @@ vmJump(void* address, void* base, void* stack, void* thread); namespace { -const bool Verbose = false; +const bool Verbose = true; const bool DebugTraces = false; class MyThread: public Thread { @@ -617,7 +617,7 @@ class Frame { } void pushLong(Operand* o) { - stack = c->push(stack, c->select8(o)); + stack = c->push(stack, o); if (BytesPerWord == 8) { stack = c->push(stack, 1); } @@ -654,7 +654,7 @@ class Frame { } Operand* popInt() { - Operand* tmp = c->temporary(); + Operand* tmp = c->select4(c->temporary()); popInt(tmp); return tmp; } @@ -695,7 +695,8 @@ class Frame { assert(t, index < codeMaxLocals(t, methodCode(t, method))); assert(t, index < parameterFootprint(t, method) or getBit(map, index - parameterFootprint(t, method)) == 0); - pushInt(c->memory(c->base(), localOffset(t, index, method))); + pushInt + (c->signExtend4(c->memory(c->base(), localOffset(t, index, method)))); } void loadLong(unsigned index) { @@ -1180,8 +1181,10 @@ compileThrowNew(MyThread* t, Frame* frame, Machine::Type type) } void -pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result) +pushReturnValue(MyThread* t, Frame* frame, unsigned code) { + Object* result = c->result(); + switch (code) { case ByteField: case BooleanField: @@ -1189,7 +1192,7 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result) case ShortField: case FloatField: case IntField: - frame->pushInt(result); + frame->pushInt(c->signExtend4(result)); break; case ObjectField: @@ -1198,7 +1201,7 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result) case LongField: case DoubleField: - frame->pushLong(result); + frame->pushLong(c->select8(result)); break; case VoidField: @@ -1207,6 +1210,8 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code, Operand* result) default: abort(t); } + + c->release(c); } void @@ -1275,15 +1280,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case faload: case iaload: - frame->pushInt(c->select4(c->memory(array, ArrayBody, index, 4))); + frame->pushInt(c->signExtend4(c->memory(array, ArrayBody, index, 4))); break; case baload: - frame->pushInt(c->select1(c->memory(array, ArrayBody, index, 1))); + frame->pushInt(c->signExtend1(c->memory(array, ArrayBody, index, 1))); break; case caload: - frame->pushInt(c->select2z(c->memory(array, ArrayBody, index, 2))); + frame->pushInt(c->zeroExtend2(c->memory(array, ArrayBody, index, 2))); break; case daload: @@ -1292,7 +1297,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) break; case saload: - frame->pushInt(c->select2(c->memory(array, ArrayBody, index, 2))); + frame->pushInt(c->signExtend2(c->memory(array, ArrayBody, index, 2))); break; } @@ -1350,21 +1355,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case fastore: case iastore: - c->mov(value, c->select4(c->memory(array, ArrayBody, index, 4))); + c->mov(c->select4(value), c->memory(array, ArrayBody, index, 4)); break; case bastore: - c->mov(value, c->select1(c->memory(array, ArrayBody, index, 1))); + c->mov(c->select1(value), c->memory(array, ArrayBody, index, 1)); break; case castore: case sastore: - c->mov(value, c->select2(c->memory(array, ArrayBody, index, 2))); + c->mov(c->select2(value), c->memory(array, ArrayBody, index, 2)); break; case dastore: case lastore: - c->mov(value, c->select8(c->memory(array, ArrayBody, index, 8))); + c->mov(c->select8(value), c->memory(array, ArrayBody, index, 8)); break; } @@ -1787,25 +1792,30 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) switch (fieldCode(t, field)) { case ByteField: case BooleanField: - frame->pushInt(c->select1(c->memory(table, fieldOffset(t, field)))); + frame->pushInt + (c->signExtend1(c->memory(table, fieldOffset(t, field)))); break; case CharField: - frame->pushInt(c->select2z(c->memory(table, fieldOffset(t, field)))); + frame->pushInt + (c->zeroExtend2(c->memory(table, fieldOffset(t, field)))); break; case ShortField: - frame->pushInt(c->select2(c->memory(table, fieldOffset(t, field)))); + frame->pushInt + (c->signExtend2(c->memory(table, fieldOffset(t, field)))); break; case FloatField: case IntField: - frame->pushInt(c->select4(c->memory(table, fieldOffset(t, field)))); + frame->pushInt + (c->signExtend4(c->memory(table, fieldOffset(t, field)))); break; case DoubleField: case LongField: - frame->pushLong(c->select8(c->memory(table, fieldOffset(t, field)))); + frame->pushLong + (c->select8(c->memory(table, fieldOffset(t, field)))); break; case ObjectField: @@ -1839,12 +1849,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case i2b: { Operand* top = frame->topInt(); - c->mov(c->select1(top), top); + c->mov(c->signExtend1(top), top); } break; case i2c: { Operand* top = frame->topInt(); - c->mov(c->select2z(top), top); + c->mov(c->zeroExtend2(top), top); } break; case i2d: { @@ -1865,13 +1875,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case i2l: { Operand* a = frame->popInt(); - frame->pushLong(a); + frame->pushLong(c->signExtend4(a)); c->release(a); } break; case i2s: { Operand* top = frame->topInt(); - c->mov(c->select2(top), top); + c->mov(c->signExtend2(top), top); } break; case iadd: { @@ -2739,22 +2749,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) switch (fieldCode(t, field)) { case ByteField: case BooleanField: - c->mov(value, c->select1(c->memory(table, fieldOffset(t, field)))); + c->mov(c->select1(value), c->memory(table, fieldOffset(t, field))); break; case CharField: case ShortField: - c->mov(value, c->select2(c->memory(table, fieldOffset(t, field)))); + c->mov(c->select2(value), c->memory(table, fieldOffset(t, field))); break; case FloatField: case IntField: - c->mov(value, c->select4(c->memory(table, fieldOffset(t, field)))); + c->mov(c->select4(value), c->memory(table, fieldOffset(t, field))); break; case DoubleField: case LongField: - c->mov(value, c->select8(c->memory(table, fieldOffset(t, field)))); + c->mov(c->select8(value), c->memory(table, fieldOffset(t, field))); break; case ObjectField: @@ -2997,13 +3007,13 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool, } // for debugging: - if (false and + if (//false and strcmp(reinterpret_cast (&byteArrayBody(t, className(t, methodClass(t, method)), 0)), - "java/lang/Throwable") == 0 and + "java/lang/Long") == 0 and strcmp(reinterpret_cast (&byteArrayBody(t, methodName(t, method), 0)), - "init") == 0) + "toString") == 0) { asm("int3"); } diff --git a/src/compiler.cpp b/src/compiler.cpp index e892c7279f..e1c54e19f2 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -27,11 +27,14 @@ enum Register { }; enum SelectionType { - S1Selection, - S2Selection, - Z2Selection, - S4Selection, - S8Selection + Select1, + Select2, + Select4, + Select8, + SignExtend1, + SignExtend2, + ZeroExtend2, + SignExtend4 }; const bool Verbose = false; @@ -1112,8 +1115,8 @@ RegisterOperand::apply(Context* c, Operation operation) case S8Selection: assert(c, selection == S8Selection); - register_(c, high(c))->apply(c, pop); register_(c, value(c))->apply(c, pop); + register_(c, high(c))->apply(c, pop); break; default: abort(c); @@ -1125,16 +1128,10 @@ RegisterOperand::apply(Context* c, Operation operation) if (selection == DefaultSelection) { c->code.append(0x50 | value(c)); } else { - switch (selection) { - case S8Selection: - assert(c, selection == S8Selection); + assert(c, selection == S8Selection); - register_(c, value(c))->apply(c, push); - register_(c, high(c))->apply(c, push); - break; - - default: abort(c); - } + register_(c, high(c))->apply(c, push); + register_(c, value(c))->apply(c, push); } break; @@ -1579,6 +1576,8 @@ ImmediateOperand::apply(Context* c, Operation operation) tmp->release(c); } } else { + assert(c, selection == S8Selection); + immediate(c, (value >> 32) & 0xFFFFFFFF)->apply(c, push); immediate(c, (value ) & 0xFFFFFFFF)->apply(c, push); } @@ -1678,11 +1677,24 @@ MemoryOperand::apply(Context* c, Operation operation) if (selection == DefaultSelection) { encode(c, 0xff, 6, this, false); } else { - RegisterOperand* tmp = temporary - (c, selection == S8Selection ? S8Selection : DefaultSelection); - tmp->accept(c, mov, this); - tmp->apply(c, operation); - tmp->release(c); + switch (selection) { + case S8Selection: { + MemoryOperand* low = memory(c, base, displacement, index, scale); + MemoryOperand* high = memory + (c, base, displacement + BytesPerWord, index, scale); + + high->apply(c, push); + low->apply(c, push); + } break; + + default: { + RegisterOperand* tmp = temporary + (c, selection == S8Selection ? S8Selection : DefaultSelection); + tmp->accept(c, mov, this); + tmp->apply(c, operation); + tmp->release(c); + } break; + } } break; @@ -2169,7 +2181,7 @@ class MyCompiler: public Compiler { (&c, static_cast(machineIp())); } - virtual Operand* indirectCall + virtual void indirectCall (Operand* address, unsigned argumentCount, ...) { va_list a; va_start(a, argumentCount); @@ -2180,8 +2192,6 @@ class MyCompiler: public Compiler { call(immediate(&c, c.indirectCaller)); add(immediate(&c, footprint), register_(&c, rsp)); - - return register_(&c, rax); } virtual void indirectCallNoReturn @@ -2196,7 +2206,7 @@ class MyCompiler: public Compiler { call(immediate(&c, c.indirectCaller)); } - virtual Operand* directCall + virtual void directCall (Operand* address, unsigned argumentCount, ...) { va_list a; va_start(a, argumentCount); @@ -2206,8 +2216,10 @@ class MyCompiler: public Compiler { call(address); add(immediate(&c, footprint), register_(&c, rsp)); + } - return register_(&c, rax); + virtual Operand* result() { + return ::temporary(&c, rax, rdx); } virtual void return_(Operand* v) { @@ -2216,14 +2228,12 @@ class MyCompiler: public Compiler { ret(); } - virtual Operand* call(Operand* v) { + virtual void call(Operand* v) { appendOperation(&c, MyOperand::call, v); - return register_(&c, rax); } - virtual Operand* alignedCall(Operand* v) { + virtual void alignedCall(Operand* v) { appendOperation(&c, MyOperand::alignedCall, v); - return register_(&c, rax); } virtual void ret() { @@ -2322,23 +2332,35 @@ class MyCompiler: public Compiler { } virtual Operand* select1(Operand* v) { - return static_cast(v)->select(&c, S1Selection); + return static_cast(v)->select(&c, Select1); } virtual Operand* select2(Operand* v) { - return static_cast(v)->select(&c, S2Selection); - } - - virtual Operand* select2z(Operand* v) { - return static_cast(v)->select(&c, Z2Selection); + return static_cast(v)->select(&c, Select2); } virtual Operand* select4(Operand* v) { - return static_cast(v)->select(&c, S4Selection); + return static_cast(v)->select(&c, Select4); } virtual Operand* select8(Operand* v) { - return static_cast(v)->select(&c, S8Selection); + return static_cast(v)->select(&c, Select8); + } + + virtual Operand* signExtend1(Operand* v) { + return static_cast(v)->select(&c, SignExtend1); + } + + virtual Operand* signExtend2(Operand* v) { + return static_cast(v)->select(&c, SignExtend2); + } + + virtual Operand* zeroExtend2(Operand* v) { + return static_cast(v)->select(&c, ZeroExtend2); + } + + virtual Operand* signExtend4(Operand* v) { + return static_cast(v)->select(&c, SignExtend4); } virtual void prologue() { diff --git a/src/compiler.h b/src/compiler.h index c22ba9034e..28b585f11c 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -36,29 +36,34 @@ class Compiler { virtual Operand* select1(Operand*) = 0; virtual Operand* select2(Operand*) = 0; - virtual Operand* select2z(Operand*) = 0; virtual Operand* select4(Operand*) = 0; virtual Operand* select8(Operand*) = 0; + virtual Operand* signExtend1(Operand*) = 0; + virtual Operand* signExtend2(Operand*) = 0; + virtual Operand* zeroExtend2(Operand*) = 0; + virtual Operand* signExtend4(Operand*) = 0; + virtual Operand* stack() = 0; virtual Operand* base() = 0; virtual Operand* thread() = 0; virtual Operand* indirectTarget() = 0; virtual Operand* temporary() = 0; + virtual Operand* result() = 0; virtual void release(Operand*) = 0; virtual Operand* label() = 0; virtual void mark(Operand*) = 0; - virtual Operand* indirectCall + virtual void indirectCall (Operand* address, unsigned argumentCount, ...) = 0; virtual void indirectCallNoReturn (Operand* address, unsigned argumentCount, ...) = 0; - virtual Operand* directCall + virtual void directCall (Operand* address, unsigned argumentCount, ...) = 0; - virtual Operand* call(Operand*) = 0; - virtual Operand* alignedCall(Operand*) = 0; + virtual void call(Operand*) = 0; + virtual void alignedCall(Operand*) = 0; virtual void return_(Operand*) = 0; virtual void ret() = 0;