diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 39098ca4c4..74a3c9d838 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -482,16 +482,3 @@ 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 4c006ea549..013ac883bb 100644 --- a/classpath/java/lang/Long.java +++ b/classpath/java/lang/Long.java @@ -38,16 +38,11 @@ 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"; } @@ -58,13 +53,10 @@ 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 ee81de2aa6..5c9ad91a3f 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 = true; +const bool Verbose = false; const bool DebugTraces = false; class MyThread: public Thread { @@ -643,7 +643,7 @@ class Frame { assert(t, sp - 2 >= localSize(t, method)); assert(t, getBit(map, sp - 1) == 0); assert(t, getBit(map, sp - 2) == 0); - return c->stack(stack, 1); + return c->stack(stack, 0); } Operand* topObject() { @@ -695,8 +695,7 @@ 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->signExtend4(c->memory(c->base(), localOffset(t, index, method)))); + pushInt(c->select4(c->memory(c->base(), localOffset(t, index, method)))); } void loadLong(unsigned index) { @@ -706,7 +705,11 @@ class Frame { or getBit(map, index - parameterFootprint(t, method)) == 0); assert(t, index < parameterFootprint(t, method) or getBit(map, index + 1 - parameterFootprint(t, method)) == 0); - pushLong(c->select8(c->memory(c->base(), localOffset(t, index, method)))); + pushLong + (c->select8 + (c->memory + (c->base(), + localOffset(t, index + (4 / BytesPerWord), method)))); } void loadObject(unsigned index) { @@ -722,7 +725,11 @@ class Frame { } void storeLong(unsigned index) { - popLong(c->select8(c->memory(c->base(), localOffset(t, index, method)))); + popLong + (c->select8 + (c->memory + (c->base(), + localOffset(t, index + (4 / BytesPerWord), method)))); storedInt(index); storedInt(index + 1); } @@ -1180,10 +1187,18 @@ compileThrowNew(MyThread* t, Frame* frame, Machine::Type type) frame->trace(); } +void +checkCast(MyThread* t, object class_, object o) +{ + if (UNLIKELY(o and not isAssignableFrom(t, class_, objectClass(t, o)))) { + throwNew(t, arrayBody(t, t->m->types, Machine::ClassCastExceptionType)); + } +} + void pushReturnValue(MyThread* t, Frame* frame, unsigned code) { - Object* result = c->result(); + Operand* result = frame->c->result(); switch (code) { case ByteField: @@ -1192,7 +1207,7 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code) case ShortField: case FloatField: case IntField: - frame->pushInt(c->signExtend4(result)); + frame->pushInt(frame->c->select4(result)); break; case ObjectField: @@ -1201,7 +1216,7 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code) case LongField: case DoubleField: - frame->pushLong(c->select8(result)); + frame->pushLong(frame->c->select8(result)); break; case VoidField: @@ -1211,13 +1226,13 @@ pushReturnValue(MyThread* t, Frame* frame, unsigned code) abort(t); } - c->release(c); + frame->c->release(result); } void compileDirectInvoke(MyThread* t, Frame* frame, object target) { - Operand* result = frame->c->alignedCall + frame->c->alignedCall (frame->c->constant (reinterpret_cast (&singletonBody(t, methodCompiled(t, target), 0)))); @@ -1226,7 +1241,7 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target) frame->pop(methodParameterFootprint(t, target)); - pushReturnValue(t, frame, methodReturnCode(t, target), result); + pushReturnValue(t, frame, methodReturnCode(t, target)); } void @@ -1280,15 +1295,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case faload: case iaload: - frame->pushInt(c->signExtend4(c->memory(array, ArrayBody, index, 4))); + frame->pushInt(c->select4(c->memory(array, ArrayBody, index, 4))); break; case baload: - frame->pushInt(c->signExtend1(c->memory(array, ArrayBody, index, 1))); + frame->pushInt(c->select1(c->memory(array, ArrayBody, index, 1))); break; case caload: - frame->pushInt(c->zeroExtend2(c->memory(array, ArrayBody, index, 2))); + frame->pushInt(c->select2z(c->memory(array, ArrayBody, index, 2))); break; case daload: @@ -1297,7 +1312,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) break; case saload: - frame->pushInt(c->signExtend2(c->memory(array, ArrayBody, index, 2))); + frame->pushInt(c->select2(c->memory(array, ArrayBody, index, 2))); break; } @@ -1425,15 +1440,18 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) c->mark(nonnegative); - Operand* r = c->indirectCall + c->indirectCall (c->constant(reinterpret_cast(makeBlankObjectArray)), 3, c->thread(), frame->append(class_), length); + Operand* result = c->result(); + c->release(length); frame->trace(); - frame->pushObject(r); + frame->pushObject(result); + c->release(result); } break; case areturn: { @@ -1489,68 +1507,63 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) object class_ = resolveClassInPool(t, codePool(t, code), index - 1); if (UNLIKELY(t->exception)) return; - Operand* next = c->label(); - Operand* instance = frame->topObject(); - Operand* tmp = c->temporary(); - - c->mov(instance, tmp); - - c->cmp(c->constant(0), tmp); - c->je(next); Operand* classOperand = frame->append(class_); - c->mov(c->memory(tmp), tmp); - c->and_(c->constant(PointerMask), tmp); + c->indirectCall + (c->constant(reinterpret_cast(checkCast)), + 3, c->thread(), classOperand, instance); - c->cmp(classOperand, tmp); - c->je(next); - - Operand* result = c->directCall - (c->constant(reinterpret_cast(isAssignableFrom)), - 3, c->thread(), classOperand, tmp); - - c->release(tmp); - - c->cmp(c->constant(0), result); - c->jne(next); - - compileThrowNew(t, frame, Machine::ClassCastExceptionType); - - c->mark(next); + frame->trace(); } break; case d2f: { Operand* a = frame->popLong(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(doubleToFloat)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(doubleToFloat)), 1, a); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); } break; case d2i: { Operand* a = frame->popLong(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(doubleToInt)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(doubleToInt)), 1, a); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); } break; case d2l: { Operand* a = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(doubleToLong)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(doubleToLong)), 1, a); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); } break; case dadd: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(addDouble)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(addDouble)), 2, a, b); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1558,9 +1571,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case dcmpg: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(compareDoublesG)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(compareDoublesG)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1568,9 +1585,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case dcmpl: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(compareDoublesL)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(compareDoublesL)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1586,9 +1607,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case ddiv: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(divideDouble)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(divideDouble)), 2, a, b); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1596,27 +1621,39 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case dmul: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(multiplyDouble)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(multiplyDouble)), 2, a, b); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); c->release(b); } break; case dneg: { Operand* a = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(negateDouble)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(negateDouble)), 1, a); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); } break; case vm::drem: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(moduloDouble)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(moduloDouble)), 2, a, b); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1624,9 +1661,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case dsub: { Operand* a = frame->popLong(); Operand* b = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(subtractDouble)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(subtractDouble)), 2, a, b); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1657,34 +1698,50 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case f2d: { Operand* a = frame->popInt(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(floatToDouble)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(floatToDouble)), 1, a); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); } break; case f2i: { Operand* a = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(floatToInt)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(floatToInt)), 1, a); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); } break; case f2l: { Operand* a = frame->popInt(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(floatToLong)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(floatToLong)), 1, a); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); } break; case fadd: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(addFloat)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(addFloat)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1692,9 +1749,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case fcmpg: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(compareFloatsG)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(compareFloatsG)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1702,9 +1763,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case fcmpl: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(compareFloatsL)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(compareFloatsL)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1724,9 +1789,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case fdiv: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(divideFloat)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(divideFloat)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1734,27 +1803,39 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case fmul: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(multiplyFloat)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(multiplyFloat)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; case fneg: { Operand* a = frame->popLong(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(negateFloat)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(negateFloat)), 1, a); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); } break; case vm::frem: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(moduloFloat)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(moduloFloat)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1762,9 +1843,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case fsub: { Operand* a = frame->popInt(); Operand* b = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(subtractFloat)), 2, a, b)); + + c->directCall + (c->constant(reinterpret_cast(subtractFloat)), 2, a, b); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); c->release(b); } break; @@ -1793,23 +1878,23 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case ByteField: case BooleanField: frame->pushInt - (c->signExtend1(c->memory(table, fieldOffset(t, field)))); + (c->select1(c->memory(table, fieldOffset(t, field)))); break; case CharField: frame->pushInt - (c->zeroExtend2(c->memory(table, fieldOffset(t, field)))); + (c->select2z(c->memory(table, fieldOffset(t, field)))); break; case ShortField: frame->pushInt - (c->signExtend2(c->memory(table, fieldOffset(t, field)))); + (c->select2(c->memory(table, fieldOffset(t, field)))); break; case FloatField: case IntField: frame->pushInt - (c->signExtend4(c->memory(table, fieldOffset(t, field)))); + (c->select4(c->memory(table, fieldOffset(t, field)))); break; case DoubleField: @@ -1849,39 +1934,47 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case i2b: { Operand* top = frame->topInt(); - c->mov(c->signExtend1(top), top); + c->mov(c->select1(top), top); } break; case i2c: { Operand* top = frame->topInt(); - c->mov(c->zeroExtend2(top), top); + c->mov(c->select2z(top), top); } break; case i2d: { Operand* a = frame->popInt(); - frame->pushLong - (c->directCall - (c->constant(reinterpret_cast(intToDouble)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(intToDouble)), 1, a); + + Operand* result = c->select8(c->result()); + frame->pushLong(result); + c->release(result); c->release(a); } break; case i2f: { Operand* a = frame->popInt(); - frame->pushInt - (c->directCall - (c->constant(reinterpret_cast(intToFloat)), 1, a)); + + c->directCall + (c->constant(reinterpret_cast(intToFloat)), 1, a); + + Operand* result = c->select4(c->result()); + frame->pushInt(result); + c->release(result); c->release(a); } break; case i2l: { Operand* a = frame->popInt(); - frame->pushLong(c->signExtend4(a)); + frame->pushLong(c->select8From4(a)); c->release(a); } break; case i2s: { Operand* top = frame->topInt(); - c->mov(c->signExtend2(top), top); + c->mov(c->select2(top), top); } break; case iadd: { @@ -2096,50 +2189,18 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) object class_ = resolveClassInPool(t, codePool(t, code), index - 1); if (UNLIKELY(t->exception)) return; - Operand* call = c->label(); - Operand* next = c->label(); - Operand* zero = c->label(); - Operand* instance = frame->popObject(); - Operand* tmp = c->temporary(); - Operand* result = c->temporary(); - - c->mov(instance, tmp); - - c->cmp(c->constant(0), tmp); - c->je(zero); Operand* classOperand = frame->append(class_); - c->mov(c->memory(tmp), tmp); - c->and_(c->constant(PointerMask), tmp); + c->directCall + (c->constant(reinterpret_cast(instanceOf)), + 3, c->thread(), classOperand, instance); - c->cmp(classOperand, tmp); - c->jne(call); - - c->mov(c->constant(1), result); - c->jmp(next); - - c->mark(call); - - c->mov - (c->directCall - (c->constant(reinterpret_cast(isAssignableFrom)), - 3, c->thread(), classOperand, tmp), result); - - c->release(tmp); - c->release(instance); - - c->jmp(next); - - c->mark(zero); - - c->mov(c->constant(0), result); - - c->mark(next); + Operand* result = c->select4(c->result()); frame->pushInt(result); - c->release(result); + c->release(instance); } break; case invokeinterface: { @@ -2153,18 +2214,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) unsigned instance = parameterFootprint - 1; - Operand* result = c->call - (c->directCall + c->directCall (c->constant (reinterpret_cast(findInterfaceMethodFromInstance)), 3, c->thread(), frame->append(target), - c->stack(frame->stack, instance))); + c->stack(frame->stack, instance)); + + Operand* result = c->result(); + c->call(result); + c->release(result); frame->trace(target, true); frame->pop(parameterFootprint); - pushReturnValue(t, frame, methodReturnCode(t, target), result); + pushReturnValue(t, frame, methodReturnCode(t, target)); } break; case invokespecial: { @@ -2213,7 +2277,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) c->mov(c->memory(instance), class_); c->and_(c->constant(PointerMask), class_); - Operand* result = c->call(c->memory(class_, offset)); + c->call(c->memory(class_, offset)); frame->trace(target, true); @@ -2221,7 +2285,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) frame->pop(parameterFootprint); - pushReturnValue(t, frame, methodReturnCode(t, target), result); + pushReturnValue(t, frame, methodReturnCode(t, target)); } break; case ior: { @@ -2349,11 +2413,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) } break; case lconst_0: - frame->pushLong(c->constant(0)); + frame->pushLong(c->select8(c->constant(0))); break; case lconst_1: - frame->pushLong(c->constant(1)); + frame->pushLong(c->select8(c->constant(1))); break; case ldc: @@ -2392,7 +2456,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) uint64_t v; memcpy(&v, &singletonValue(t, pool, index - 1), 8); - frame->pushLong(c->constant(v)); + frame->pushLong(c->select8(c->constant(v))); } break; case ldiv_: { @@ -2469,10 +2533,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) } assert(t, start); - c->jmp - (c->directCall - (c->constant(reinterpret_cast(lookUpAddress)), - 4, key, start, c->constant(pairCount), default_)); + c->directCall + (c->constant(reinterpret_cast(lookUpAddress)), + 4, key, start, c->constant(pairCount), default_); + + Operand* result = c->result(); + c->jmp(result); + c->release(result); c->release(key); @@ -2587,15 +2654,18 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) if (UNLIKELY(t->exception)) return; PROTECT(t, class_); - Operand* result = c->indirectCall + c->indirectCall (c->constant(reinterpret_cast(makeMultidimensionalArray)), 4, c->thread(), frame->append(class_), c->stack(), c->constant(dimensions)); + Operand* result = c->result(); + frame->trace(); frame->pop(dimensions); frame->pushObject(result); + c->release(result); } break; case new_: { @@ -2608,20 +2678,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) initClass(t, class_); if (UNLIKELY(t->exception)) return; - Operand* result; if (classVmFlags(t, class_) & WeakReferenceFlag) { - result = c->indirectCall + c->indirectCall (c->constant(reinterpret_cast(makeNewWeakReference)), 2, c->thread(), frame->append(class_)); } else { - result = c->indirectCall + c->indirectCall (c->constant(reinterpret_cast(makeNew)), 2, c->thread(), frame->append(class_)); } + Operand* result = c->result(); + frame->trace(); frame->pushObject(result); + c->release(result); } break; case newarray: { @@ -2675,16 +2747,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) default: abort(t); } - Operand* result = c->indirectCall + c->indirectCall (c->constant(reinterpret_cast(makeBlankArray)), 3, c->thread(), c->constant(reinterpret_cast(constructor)), size); + + Operand* result = c->result(); c->release(size); frame->trace(); frame->pushObject(result); + c->release(result); } break; case nop: break; @@ -3007,13 +3082,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/Long") == 0 and + "java/lang/String") == 0 and strcmp(reinterpret_cast (&byteArrayBody(t, methodName(t, method), 0)), - "toString") == 0) + "getBytes") == 0) { asm("int3"); } @@ -3182,7 +3257,11 @@ invokeNative2(MyThread* t, object method) case INT64_TYPE: case DOUBLE_TYPE: { - memcpy(args + argOffset, sp, 8); + if (BytesPerWord == 8) { + memcpy(args + argOffset, sp, 8); + } else { + memcpy(args + argOffset, sp - 1, 8); + } argOffset += (8 / BytesPerWord); sp -= 2; } break; @@ -3363,10 +3442,13 @@ compileDefault(MyThread* t, Compiler* c) c->mov(c->base(), c->memory(c->thread(), difference(&(t->base), t))); c->mov(c->stack(), c->memory(c->thread(), difference(&(t->stack), t))); - c->jmp - (c->directCall + c->directCall (c->constant(reinterpret_cast(compileMethod)), - 1, c->thread())); + 1, c->thread()); + + Operand* result = c->result(); + c->jmp(result); + c->release(result); return finish(t, c); } diff --git a/src/compiler.cpp b/src/compiler.cpp index c622a687cf..31f4b06c8b 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -29,12 +29,10 @@ enum Register { enum SelectionType { Select1, Select2, + Select2z, Select4, Select8, - SignExtend1, - SignExtend2, - ZeroExtend2, - SignExtend4 + Select8From4 }; const bool Verbose = false; @@ -42,7 +40,7 @@ const bool Verbose = false; const unsigned RegisterCount = BytesPerWord * 2; const unsigned GprParameterCount = 6; const SelectionType DefaultSelection -= (BytesPerWord == 8 ? S8Selection : S4Selection); += (BytesPerWord == 8 ? Select8 : Select4); class Context; class MyOperand; @@ -55,6 +53,19 @@ class CodePromise; class MyPromise; class RegisterReference; +inline unsigned +footprint(SelectionType selection) +{ + switch (selection) { + case Select8: + case Select8From4: + return 8; + + default: + return BytesPerWord; + } +} + int64_t divideLong(int64_t a, int64_t b) { @@ -320,7 +331,7 @@ RegisterOperand* register_(Context* c, RegisterReference*, SelectionType = DefaultSelection); RegisterOperand* -register_(Context* c, Register, Register = NoRegister, +register_(Context* c, Register = NoRegister, Register = NoRegister, SelectionType = DefaultSelection); MemoryOperand* @@ -429,38 +440,63 @@ release(Context* c, Register v) class RegisterReference { public: RegisterReference(Register value = NoRegister, Register high = NoRegister): - value_(value), high_(high), acquireHigh(false) + value_(value), defaultValue(value), high_(high), defaultHigh(high), + acquired(true) { } void acquire(Context* c) { - value_ = ::acquire(c); - if (acquireHigh) { - high_ = ::acquire(c); + if (defaultValue != NoRegister) { + ::acquire(c, defaultValue); } + + if (defaultHigh != NoRegister) { + ::acquire(c, defaultHigh); + } + + value_ = defaultValue; + high_ = defaultHigh; + + acquired = true; } void release(Context* c) { - ::release(c, value_); - value_ = NoRegister; + assert(c, acquired); + + if (value_ != NoRegister) { + ::release(c, value_); + } if (high_ != NoRegister) { ::release(c, high_); } + + value_ = NoRegister; + high_ = NoRegister; + + acquired = false; } - Register value(Context* c UNUSED) { - assert(c, value_ != NoRegister); + Register value(Context* c) { + assert(c, acquired); + if (value_ == NoRegister) { + value_ = ::acquire(c); + } return value_; } - Register high(Context* c UNUSED) { - assert(c, high_ != NoRegister); + Register high(Context* c) { + assert(c, acquired); + if (high_ == NoRegister) { + high_ = ::acquire(c); + } return high_; } Register value_; + Register defaultValue; Register high_; - bool acquireHigh; + Register defaultHigh; + bool acquired; }; class RegisterOperand: public MyOperand { @@ -478,7 +514,7 @@ class RegisterOperand: public MyOperand { } virtual unsigned footprint(Context*) { - return (selection == S8Selection ? 8 : BytesPerWord); + return ::footprint(selection); } virtual Register asRegister(Context* c) { @@ -489,9 +525,6 @@ class RegisterOperand: public MyOperand { if (selection == this->selection) { return this; } else { - if (selection == S8Selection and BytesPerWord == 4) { - reference->acquireHigh = true; - } return register_(c, reference, selection); } } @@ -528,7 +561,7 @@ class ImmediateOperand: public MyOperand { { } virtual unsigned footprint(Context*) { - return (selection == S8Selection ? 8 : BytesPerWord); + return ::footprint(selection); } virtual MyOperand* select(Context* c, SelectionType selection) { @@ -610,7 +643,7 @@ class MemoryOperand: public MyOperand { { } virtual unsigned footprint(Context*) { - return (selection == S8Selection ? 8 : BytesPerWord); + return ::footprint(selection); } virtual Register asRegister(Context*); @@ -698,7 +731,7 @@ temporary(Context* c) RegisterOperand* temporary(Context* c, SelectionType selection) { - if (BytesPerWord == 4 and selection == S8Selection) { + if (BytesPerWord == 4 and selection == Select8) { return register_(c, acquire(c), acquire(c), selection); } else { return register_(c, acquire(c), NoRegister, selection); @@ -712,6 +745,14 @@ temporary(Context* c, Register v) return register_(c, v); } +RegisterOperand* +temporary(Context* c, Register v, Register h) +{ + acquire(c, v); + acquire(c, h); + return register_(c, v, h); +} + Segment* currentSegment(Context* c) { @@ -793,6 +834,9 @@ class AcquireEvent: public Event { { } virtual void run(Context* c) { + if (Verbose) { + fprintf(stderr, "acquire register\n"); + } operand->reference->acquire(c); } @@ -807,6 +851,9 @@ class ReleaseEvent: public Event { { } virtual void run(Context* c) { + if (Verbose) { + fprintf(stderr, "release register\n"); + } operand->release(c); } @@ -954,18 +1001,38 @@ appendArgumentEvent(Context* c, MyOperand** arguments, unsigned count) ArgumentEvent(arguments, count, s->event); } -MyStack* -pushed(Context* c, MyStack* stack, unsigned footprint) +void +logStack(Context* c, MyStack* stack) { - int index = (stack ? - stack->index + (stack->value->footprint(c) / BytesPerWord) : - 0); + fprintf(stderr, "ip %3d: ", currentSegment(c)->logicalIp); + + if (stack) { + fprintf(stderr, " %d", + static_cast(stack->value)->displacement); + } + + for (MyStack* s = stack; s; s = s->next) { + fprintf(stderr, "*"); + } + + fprintf(stderr, "\n"); +} + +MyStack* +pushed(Context* c, MyStack* stack) +{ + int index = (stack ? stack->index + 1 : 0); MyOperand* value = memory - (c, register_(c, rbp), - (c->reserved + index + 1) * BytesPerWord, 0, 1, - footprint == (BytesPerWord * 2) ? S8Selection : DefaultSelection); + (c, register_(c, rbp), - (c->reserved + index + 1) * BytesPerWord, 0, 1); - return new (c->zone.allocate(sizeof(MyStack))) MyStack(value, index, stack); + stack = new (c->zone.allocate(sizeof(MyStack))) MyStack(value, index, stack); + + if (Verbose) { + logStack(c, stack); + } + + return stack; } MyStack* @@ -973,7 +1040,10 @@ push(Context* c, MyStack* stack, MyOperand* v) { appendOperation(c, MyOperand::push, v); - return pushed(c, stack, v->footprint(c)); + if ((v->footprint(c) / BytesPerWord) == 2) { + stack = pushed(c, stack); + } + return pushed(c, stack); } MyStack* @@ -983,11 +1053,15 @@ pop(Context* c, MyStack* stack, int count) (c, MyOperand::add, immediate(c, count * BytesPerWord), register_(c, rsp)); while (count) { - count -= (stack->value->footprint(c) / BytesPerWord); + -- count; assert(c, count >= 0); stack = stack->next; } + if (Verbose) { + logStack(c, stack); + } + return stack; } @@ -996,6 +1070,14 @@ pop(Context* c, MyStack* stack, MyOperand* dst) { appendOperation(c, MyOperand::pop, dst); + if (dst->footprint(c) / BytesPerWord == 2) { + stack = stack->next; + } + + if (Verbose) { + logStack(c, stack->next); + } + return stack->next; } @@ -1031,6 +1113,17 @@ rex(Context* c) } } +void +rex(Context* c, SelectionType selection) +{ + if (selection == Select8) { + assert(c, BytesPerWord == 8); + rex(c); + } else { + assert(c, selection == Select4); + } +} + void encode(Context* c, uint8_t* instruction, unsigned length, int a, Register b, int32_t displacement, int index, unsigned scale) @@ -1077,6 +1170,15 @@ encode(Context* c, uint8_t instruction, int a, MemoryOperand* b, bool rex) encode(c, &instruction, 1, a, r, b->displacement, index, b->scale); } +void +encode(Context* c, uint8_t instruction, int a, MemoryOperand* b, + SelectionType selection) +{ + assert(c, selection == DefaultSelection or selection == Select4); + + encode(c, instruction, a, b, selection == DefaultSelection); +} + void encode2(Context* c, uint16_t instruction, int a, MemoryOperand* b, bool rex) { @@ -1092,51 +1194,64 @@ encode2(Context* c, uint16_t instruction, int a, MemoryOperand* b, bool rex) void RegisterOperand::apply(Context* c, Operation operation) { - assert(c, operation == push - or operation == pop - or selection == DefaultSelection); - switch (operation) { case call: + assert(c, selection == DefaultSelection); + c->code.append(0xff); c->code.append(0xd0 | value(c)); break; case jmp: + assert(c, selection == DefaultSelection); + c->code.append(0xff); c->code.append(0xe0 | value(c)); break; case pop: - if (selection == DefaultSelection) { + if (selection == DefaultSelection or selection == Select4) { c->code.append(0x58 | value(c)); } else { - switch (selection) { - case S8Selection: - assert(c, selection == S8Selection); + assert(c, selection == Select8); - register_(c, value(c))->apply(c, pop); - register_(c, high(c))->apply(c, pop); + register_(c, value(c))->apply(c, pop); + register_(c, high(c))->apply(c, pop); + } + break; + + case push: + if (selection == DefaultSelection or selection == Select4 + or (BytesPerWord == 8 and selection == Select8From4)) + { + c->code.append(0x50 | value(c)); + } else { + switch (selection) { + case Select8: + register_(c, high(c))->apply(c, push); + register_(c, value(c))->apply(c, push); break; + case Select8From4: { + RegisterOperand* ax = temporary(c, rax); + RegisterOperand* dx = temporary(c, rdx); + + ax->accept(c, mov, register_(c, value(c))); + c->code.append(0x99); // cdq + dx->apply(c, push); + ax->apply(c, push); + + ax->release(c); + dx->release(c); + } break; + default: abort(c); } } break; - case push: - if (selection == DefaultSelection or selection == S4Selection) { - c->code.append(0x50 | value(c)); - } else { - assert(c, selection == S8Selection); - - register_(c, high(c))->apply(c, push); - register_(c, value(c))->apply(c, push); - } - break; - case neg: - rex(c); + rex(c, selection); c->code.append(0xf7); c->code.append(0xd8 | value(c)); break; @@ -1151,21 +1266,27 @@ RegisterOperand::accept(Context* c, Operation operation, { switch (operation) { case add: - rex(c); + assert(c, selection == operand->selection); + + rex(c, operand->selection); c->code.append(0x01); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); break; case cmp: - if (selection == DefaultSelection) { - rex(c); + assert(c, selection == operand->selection); + + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + rex(c, operand->selection); c->code.append(0x39); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); } else { - assert(c, selection == S8Selection); + assert(c, operand->selection == Select8); register_(c, high(c))->accept - (c, mov, register_(c, operand->high(c))); + (c, cmp, register_(c, operand->high(c))); // if the high order bits are equal, we compare the low order // bits; otherwise, we jump past that comparison @@ -1174,41 +1295,41 @@ RegisterOperand::accept(Context* c, Operation operation, c->code.append4(2); register_(c, value(c))->accept - (c, mov, register_(c, operand->value(c))); + (c, cmp, register_(c, operand->value(c))); } break; case mov: if (value(c) != operand->value(c) or selection != operand->selection) { - if (operand->selection == DefaultSelection) { - rex(c); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + rex(c, selection); c->code.append(0x89); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); } else { switch (operand->selection) { - case S1Selection: + case Select1: c->code.append(0xbe); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); break; - case S2Selection: + case Select2: c->code.append(0xbf); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); break; - case Z2Selection: + case Select2z: c->code.append(0xb7); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); break; - case S4Selection: + case Select4: c->code.append(0x89); c->code.append(0xc0 | (operand->value(c) << 3) | value(c)); break; - case S8Selection: - assert(c, selection == S8Selection); - + case Select8: register_(c, value(c))->accept (c, mov, register_(c, operand->value(c))); @@ -1223,7 +1344,9 @@ RegisterOperand::accept(Context* c, Operation operation, break; case mul: - rex(c); + assert(c, selection == operand->selection); + + rex(c, selection); c->code.append(0x0f); c->code.append(0xaf); c->code.append(0xc0 | (value(c) << 3) | operand->value(c)); @@ -1349,6 +1472,8 @@ void RegisterOperand::accept(Context* c, Operation operation, AddressOperand* operand) { + assert(c, selection == DefaultSelection); + switch (operation) { case mov: { accept(c, operation, ::value(c, operand)); @@ -1362,38 +1487,43 @@ void RegisterOperand::accept(Context* c, Operation operation, MemoryOperand* operand) { - assert(c, operation == mov or selection == DefaultSelection); - assert(c, operation == mov or operand->selection == DefaultSelection); + assert(c, selection == DefaultSelection); switch (operation) { case cmp: { - encode(c, 0x3b, value(c), operand, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x3b, value(c), operand, operand->selection); + } else { + abort(c); + } } break; case mov: { - if (operand->selection == DefaultSelection) { + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { encode(c, 0x8b, value(c), operand, true); } else { switch (operand->selection) { - case S1Selection: + case Select1: encode2(c, 0x0fbe, value(c), operand, true); break; - case S2Selection: + case Select2: encode2(c, 0x0fbf, value(c), operand, true); break; - case Z2Selection: + case Select2z: encode2(c, 0x0fb7, value(c), operand, true); break; - case S4Selection: + case Select4: encode(c, 0x63, value(c), operand, true); break; - case S8Selection: - assert(c, selection == S8Selection); - + case Select8: register_(c, value(c))->accept (c, mov, memory (c, operand->base, operand->displacement, @@ -1551,12 +1681,12 @@ AddressOperand::asRegister(Context* c) void ImmediateOperand::apply(Context* c, Operation operation) { - assert(c, operation == push or selection == DefaultSelection); - switch (operation) { case alignedCall: case call: case jmp: + assert(c, selection == DefaultSelection); + address(c, new (c->zone.allocate(sizeof(ResolvedPromise))) ResolvedPromise(value))->apply(c, operation); break; @@ -1576,7 +1706,7 @@ ImmediateOperand::apply(Context* c, Operation operation) tmp->release(c); } } else { - assert(c, selection == S8Selection); + assert(c, selection == Select8); immediate(c, (value >> 32) & 0xFFFFFFFF)->apply(c, push); immediate(c, (value ) & 0xFFFFFFFF)->apply(c, push); @@ -1634,18 +1764,22 @@ MemoryOperand::apply(Context* c, Operation operation) { switch (operation) { case call: + assert(c, selection == DefaultSelection); + encode(c, 0xff, 2, this, false); break; case jmp: + assert(c, selection == DefaultSelection); + encode(c, 0xff, 4, this, false); break; case neg: if (selection == DefaultSelection) { - encode(c, 0xf7, 2, this, true); + encode(c, 0xf7, 2, this, selection); } else { - assert(c, selection == S8Selection); + assert(c, selection == Select8); RegisterOperand* ax = temporary(c, rax); RegisterOperand* dx = temporary(c, rdx); @@ -1670,7 +1804,18 @@ MemoryOperand::apply(Context* c, Operation operation) break; case pop: - encode(c, 0x8f, 0, this, false); + if (selection == DefaultSelection) { + encode(c, 0x8f, 0, this, false); + } else { + assert(c, selection == Select8); + + MemoryOperand* low = memory(c, base, displacement, index, scale); + MemoryOperand* high = memory + (c, base, displacement + BytesPerWord, index, scale); + + low->apply(c, pop); + high->apply(c, pop); + } break; case push: @@ -1678,7 +1823,7 @@ MemoryOperand::apply(Context* c, Operation operation) encode(c, 0xff, 6, this, false); } else { switch (selection) { - case S8Selection: { + case Select8: { MemoryOperand* low = memory(c, base, displacement, index, scale); MemoryOperand* high = memory (c, base, displacement + BytesPerWord, index, scale); @@ -1689,7 +1834,7 @@ MemoryOperand::apply(Context* c, Operation operation) default: { RegisterOperand* tmp = temporary - (c, selection == S8Selection ? S8Selection : DefaultSelection); + (c, selection == Select8 ? Select8 : DefaultSelection); tmp->accept(c, mov, this); tmp->apply(c, operation); tmp->release(c); @@ -1708,14 +1853,22 @@ MemoryOperand::accept(Context* c, Operation operation, { switch (operation) { case and_: { - encode(c, 0x21, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x21, operand->value(c), this, operand->selection); + } else { + abort(c); + } } break; case add: { - if (selection == DefaultSelection) { - encode(c, 0x01, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x01, operand->value(c), this, operand->selection); } else { - assert(c, selection == S8Selection); + assert(c, operand->selection == Select8); RegisterOperand* ax = temporary(c, rax); RegisterOperand* dx = temporary(c, rdx); @@ -1733,22 +1886,26 @@ MemoryOperand::accept(Context* c, Operation operation, } break; case addc: - if (operand->selection == DefaultSelection) { - encode(c, 0x11, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x11, operand->value(c), this, operand->selection); } else { abort(c); } break; case div: { - if (selection == DefaultSelection) { + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { RegisterOperand* ax = temporary(c, rax); RegisterOperand* dx = temporary(c, rdx); ax->accept(c, mov, this); - rex(c); + rex(c, operand->selection); c->code.append(0x99); - rex(c); + rex(c, operand->selection); c->code.append(0xf7); c->code.append(0xf8 | operand->value(c)); @@ -1757,40 +1914,52 @@ MemoryOperand::accept(Context* c, Operation operation, ax->release(c); dx->release(c); } else { - assert(c, selection == S8Selection); + assert(c, operand->selection == Select8); operand->apply(c, push); - apply(c, push); + memory(c, base, displacement, index, scale, Select8)->apply(c, push); immediate(c, reinterpret_cast(divideLong))->apply(c, call); - accept(c, mov, register_(c, rax, rdx, S8Selection)); + register_(c, rsp)->accept(c, add, immediate(c, 16)); + accept(c, mov, register_(c, rax, rdx, Select8)); } } break; case mov: { - if (selection == DefaultSelection) { - encode(c, 0x89, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x89, operand->value(c), this, operand->selection); } else { - switch (selection) { - case S1Selection: - if (operand->value(c) > rbx) { - c->code.append(0x40); + switch (operand->selection) { + case Select1: + if (BytesPerWord == 8) { + if (operand->value(c) > rbx) { + c->code.append(0x40); + } + encode(c, 0x88, operand->value(c), this, false); + } else { + if (operand->value(c) > rbx) { + RegisterOperand* ax = temporary(c, rax); + ax->accept(c, mov, register_(c, operand->value(c))); + accept(c, mov, register_(c, rax, NoRegister, Select1)); + ax->release(c); + } else { + encode(c, 0x88, operand->value(c), this, false); + } } - encode(c, 0x88, operand->value(c), this, false); break; - case S2Selection: - case Z2Selection: + case Select2: + case Select2z: c->code.append(0x66); encode(c, 0x89, operand->value(c), this, false); break; - case S4Selection: + case Select4: encode(c, 0x89, operand->value(c), this, false); break; - case S8Selection: - assert(c, operand->selection == S8Selection); - + case Select8: memory(c, base, displacement, index, scale)->accept (c, mov, register_(c, operand->value(c))); @@ -1804,7 +1973,9 @@ MemoryOperand::accept(Context* c, Operation operation, } break; case mul: { - if (selection == DefaultSelection) { + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { RegisterOperand* tmp = temporary(c); tmp->accept(c, mov, this); @@ -1813,6 +1984,8 @@ MemoryOperand::accept(Context* c, Operation operation, tmp->release(c); } else { + assert(c, operand->selection == Select8); + RegisterOperand* tmp = temporary(c); RegisterOperand* ax = temporary(c, rax); RegisterOperand* dx = temporary(c, rdx); @@ -1843,11 +2016,19 @@ MemoryOperand::accept(Context* c, Operation operation, } break; case or_: { - encode(c, 0x09, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x09, operand->value(c), this, operand->selection); + } else { + abort(c); + } } break; case rem: { - if (selection == DefaultSelection) { + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { RegisterOperand* ax = temporary(c, rax); RegisterOperand* dx = temporary(c, rdx); ax->accept(c, mov, this); @@ -1863,41 +2044,62 @@ MemoryOperand::accept(Context* c, Operation operation, ax->release(c); dx->release(c); } else { - assert(c, selection == S8Selection); + assert(c, operand->selection == Select8); operand->apply(c, push); - apply(c, push); + memory(c, base, displacement, index, scale, Select8)->apply(c, push); immediate(c, reinterpret_cast(moduloLong))->apply(c, call); - accept(c, mov, register_(c, rax, rdx, S8Selection)); + register_(c, rsp)->accept(c, add, immediate(c, 16)); + accept(c, mov, register_(c, rax, rdx, Select8)); } } break; case shl: { - RegisterOperand* cx = temporary(c, rcx); - cx->accept(c, mov, operand); - encode(c, 0xd3, 4, this, true); - cx->release(c); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + RegisterOperand* cx = temporary(c, rcx); + cx->accept(c, mov, operand); + encode(c, 0xd3, 4, this, operand->selection); + cx->release(c); + } else { + abort(c); + } } break; case shr: { - RegisterOperand* cx = temporary(c, rcx); - cx->accept(c, mov, operand); - encode(c, 0xd3, 5, this, true); - cx->release(c); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + RegisterOperand* cx = temporary(c, rcx); + cx->accept(c, mov, operand); + encode(c, 0xd3, 5, this, operand->selection); + cx->release(c); + } else { + abort(c); + } } break; case ushr: { - RegisterOperand* cx = temporary(c, rcx); - cx->accept(c, mov, operand); - encode(c, 0xd3, 7, this, true); - cx->release(c); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + RegisterOperand* cx = temporary(c, rcx); + cx->accept(c, mov, operand); + encode(c, 0xd3, 7, this, operand->selection); + cx->release(c); + } else { + abort(c); + } } break; case sub: { - if (selection == DefaultSelection) { - encode(c, 0x29, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x29, operand->value(c), this, operand->selection); } else { - assert(c, selection == S8Selection); + assert(c, operand->selection == Select8); RegisterOperand* ax = temporary(c, rax); RegisterOperand* dx = temporary(c, rdx); @@ -1915,15 +2117,23 @@ MemoryOperand::accept(Context* c, Operation operation, } break; case subb: - if (operand->selection == DefaultSelection) { - encode(c, 0x19, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x19, operand->value(c), this, operand->selection); } else { abort(c); } break; case xor_: { - encode(c, 0x31, operand->value(c), this, true); + if (operand->selection == DefaultSelection + or operand->selection == Select4) + { + encode(c, 0x31, operand->value(c), this, operand->selection); + } else { + abort(c); + } } break; default: abort(c); @@ -2111,7 +2321,7 @@ class MyCompiler: public Compiler { MyStack* stack = static_cast(s); while (count) { -- count; - stack = ::pushed(&c, stack, BytesPerWord); + stack = ::pushed(&c, stack); } return stack; } @@ -2122,17 +2332,10 @@ class MyCompiler: public Compiler { virtual Operand* stack(Stack* s, unsigned index) { MyStack* stack = static_cast(s); - unsigned i = 0; - if (stack->value->footprint(&c) / BytesPerWord == 2) { - ++ i; - } - - for (; i < index; ++i) { + while (index) { + -- index; stack = stack->next; - if (stack->value->footprint(&c) / BytesPerWord == 2) { - ++ i; - } } return stack->value; @@ -2163,7 +2366,7 @@ class MyCompiler: public Compiler { } virtual Operand* temporary() { - RegisterOperand* r = register_(&c, NoRegister); + RegisterOperand* r = register_(&c); appendAcquire(&c, r); return r; } @@ -2219,7 +2422,9 @@ class MyCompiler: public Compiler { } virtual Operand* result() { - return ::temporary(&c, rax, rdx); + RegisterOperand* r = register_(&c, rax, rdx); + appendAcquire(&c, r); + return r; } virtual void return_(Operand* v) { @@ -2339,6 +2544,10 @@ class MyCompiler: public Compiler { return static_cast(v)->select(&c, Select2); } + virtual Operand* select2z(Operand* v) { + return static_cast(v)->select(&c, Select2z); + } + virtual Operand* select4(Operand* v) { return static_cast(v)->select(&c, Select4); } @@ -2347,20 +2556,8 @@ class MyCompiler: public Compiler { 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 Operand* select8From4(Operand* v) { + return static_cast(v)->select(&c, Select8From4); } virtual void prologue() { diff --git a/src/compiler.h b/src/compiler.h index 28b585f11c..5dce7d484a 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -36,13 +36,10 @@ 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* select8From4(Operand*) = 0; virtual Operand* stack() = 0; virtual Operand* base() = 0;