mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
added floating point support, instrinsics support
This commit is contained in:
parent
c3a389429e
commit
7483fa154d
346
src/compile.cpp
346
src/compile.cpp
@ -27,7 +27,7 @@ vmCall();
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const bool DebugCompile = false;
|
const bool DebugCompile = true;
|
||||||
const bool DebugNatives = false;
|
const bool DebugNatives = false;
|
||||||
const bool DebugCallTable = false;
|
const bool DebugCallTable = false;
|
||||||
const bool DebugMethodTree = false;
|
const bool DebugMethodTree = false;
|
||||||
@ -562,20 +562,86 @@ class Context {
|
|||||||
virtual intptr_t getThunk(UnaryOperation, unsigned) {
|
virtual intptr_t getThunk(UnaryOperation, unsigned) {
|
||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual intptr_t getThunk(BinaryOperation op, unsigned size, unsigned resultSize) {
|
||||||
|
switch(op) {
|
||||||
|
case FloatNegate:
|
||||||
|
if (size == 4) {
|
||||||
|
return ::getThunk(t, negateFloatThunk);
|
||||||
|
} else {
|
||||||
|
return ::getThunk(t, negateDoubleThunk);
|
||||||
|
}
|
||||||
|
case Float2Float:
|
||||||
|
if (size == 4 && resultSize == 8) {
|
||||||
|
return ::getThunk(t, floatToDoubleThunk);
|
||||||
|
} else if(size == 8 && resultSize == 4) {
|
||||||
|
return ::getThunk(t, doubleToFloatThunk);
|
||||||
|
}
|
||||||
|
case Float2Int:
|
||||||
|
if (size == 4 && resultSize == 4) {
|
||||||
|
return ::getThunk(t, floatToIntThunk);
|
||||||
|
} else if(size == 4 && resultSize == 8) {
|
||||||
|
return ::getThunk(t, floatToLongThunk);
|
||||||
|
} else if(size == 8 && resultSize == 4) {
|
||||||
|
return ::getThunk(t, doubleToIntThunk);
|
||||||
|
} else if(size == 8 && resultSize == 8) {
|
||||||
|
return ::getThunk(t, doubleToLongThunk);
|
||||||
|
}
|
||||||
|
case Int2Float:
|
||||||
|
if (size == 4 && resultSize == 4) {
|
||||||
|
return ::getThunk(t, intToFloatThunk);
|
||||||
|
} else if(size == 4 && resultSize == 8) {
|
||||||
|
return ::getThunk(t, intToDoubleThunk);
|
||||||
|
} else if(size == 8 && resultSize == 4) {
|
||||||
|
return ::getThunk(t, longToFloatThunk);
|
||||||
|
} else if(size == 8 && resultSize == 8) {
|
||||||
|
return ::getThunk(t, longToDoubleThunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
|
|
||||||
virtual intptr_t getThunk(TernaryOperation op, unsigned size) {
|
virtual intptr_t getThunk(TernaryOperation op, unsigned size UNUSED, unsigned resultSize) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Divide:
|
case Divide:
|
||||||
if (size == 8) {
|
if (resultSize == 8) {
|
||||||
return ::getThunk(t, divideLongThunk);
|
return ::getThunk(t, divideLongThunk);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Remainder:
|
case Remainder:
|
||||||
if (size == 8) {
|
if (resultSize == 8) {
|
||||||
return ::getThunk(t, moduloLongThunk);
|
return ::getThunk(t, moduloLongThunk);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FloatAdd:
|
||||||
|
if(resultSize == 4) {
|
||||||
|
return ::getThunk(t, addFloatThunk);
|
||||||
|
} else {
|
||||||
|
return ::getThunk(t, addDoubleThunk);
|
||||||
|
}
|
||||||
|
case FloatSubtract:
|
||||||
|
if(resultSize == 4) {
|
||||||
|
return ::getThunk(t, subtractFloatThunk);
|
||||||
|
} else {
|
||||||
|
return ::getThunk(t, subtractDoubleThunk);
|
||||||
|
}
|
||||||
|
case FloatMultiply:
|
||||||
|
if(resultSize == 4) {
|
||||||
|
return ::getThunk(t, multiplyFloatThunk);
|
||||||
|
} else {
|
||||||
|
return ::getThunk(t, multiplyDoubleThunk);
|
||||||
|
}
|
||||||
|
case FloatDivide:
|
||||||
|
if(resultSize == 4) {
|
||||||
|
return ::getThunk(t, divideFloatThunk);
|
||||||
|
} else {
|
||||||
|
return ::getThunk(t, divideDoubleThunk);
|
||||||
|
}
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@ -1008,7 +1074,7 @@ class Frame {
|
|||||||
poppedLong();
|
poppedLong();
|
||||||
return popLongQuiet();
|
return popLongQuiet();
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiler::Operand* popObject() {
|
Compiler::Operand* popObject() {
|
||||||
poppedObject();
|
poppedObject();
|
||||||
return popQuiet(1);
|
return popQuiet(1);
|
||||||
@ -2071,6 +2137,22 @@ saveStateAndCompile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
initialFrame->c->restoreState(state);
|
initialFrame->c->restoreState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isCJump(unsigned instruction)
|
||||||
|
{
|
||||||
|
switch(instruction) {
|
||||||
|
case ifeq:
|
||||||
|
case ifne:
|
||||||
|
case ifgt:
|
||||||
|
case ifge:
|
||||||
|
case iflt:
|
||||||
|
case ifle:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||||
int exceptionHandlerStart)
|
int exceptionHandlerStart)
|
||||||
@ -2084,6 +2166,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
object code = methodCode(t, context->method);
|
object code = methodCode(t, context->method);
|
||||||
PROTECT(t, code);
|
PROTECT(t, code);
|
||||||
|
|
||||||
|
int lastFcmpl = 1, lastFcmpg = 1;
|
||||||
|
|
||||||
while (ip < codeLength(t, code)) {
|
while (ip < codeLength(t, code)) {
|
||||||
if (context->visitTable[ip] ++) {
|
if (context->visitTable[ip] ++) {
|
||||||
@ -2108,6 +2192,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
0,
|
0,
|
||||||
1, c->thread());
|
1, c->thread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++ lastFcmpl;
|
||||||
|
++ lastFcmpg;
|
||||||
|
|
||||||
// fprintf(stderr, "ip: %d map: %ld\n", ip, *(frame->map));
|
// fprintf(stderr, "ip: %d map: %ld\n", ip, *(frame->map));
|
||||||
|
|
||||||
@ -2341,63 +2428,56 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2f: {
|
case d2f: {
|
||||||
frame->pushInt
|
frame->pushInt(c->f2f(8, 4, frame->popLong()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, doubleToFloatThunk)),
|
|
||||||
0, 0, 4, 2,
|
|
||||||
static_cast<Compiler::Operand*>(0), frame->popLong()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2i: {
|
case d2i: {
|
||||||
frame->pushInt
|
frame->pushInt(c->f2i(8, 4, frame->popLong()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, doubleToIntThunk)),
|
|
||||||
0, 0, 4, 2,
|
|
||||||
static_cast<Compiler::Operand*>(0), frame->popLong()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2l: {
|
case d2l: {
|
||||||
frame->pushLong
|
frame->pushLong(c->f2i(8, 8, frame->popLong()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, doubleToLongThunk)),
|
|
||||||
0, 0, 8, 2,
|
|
||||||
static_cast<Compiler::Operand*>(0), frame->popLong()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dadd: {
|
case dadd: {
|
||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushLong
|
frame->pushLong(c->fadd(8, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, addDoubleThunk)),
|
|
||||||
0, 0, 8, 4,
|
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dcmpg: {
|
case dcmpg: {
|
||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushInt
|
if(t->arch->supportsFloatCompare(8) && isCJump(codeBody(t, code, ip))) {
|
||||||
(c->call
|
c->fcmp(8, a, b);
|
||||||
(c->constant(getThunk(t, compareDoublesGThunk)),
|
lastFcmpg = 0;
|
||||||
0, 0, 4, 4,
|
} else {
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
frame->pushInt
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
(c->call
|
||||||
|
(c->constant(getThunk(t, compareDoublesGThunk)),
|
||||||
|
0, 0, 4, 4,
|
||||||
|
static_cast<Compiler::Operand*>(0), a,
|
||||||
|
static_cast<Compiler::Operand*>(0), b));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dcmpl: {
|
case dcmpl: {
|
||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushInt
|
if(t->arch->supportsFloatCompare(8) && isCJump(codeBody(t, code, ip))) {
|
||||||
(c->call
|
c->fcmp(8, a, b);
|
||||||
(c->constant(getThunk(t, compareDoublesLThunk)),
|
lastFcmpl = 0;
|
||||||
0, 0, 4, 4,
|
} else {
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
frame->pushInt
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
(c->call
|
||||||
|
(c->constant(getThunk(t, compareDoublesLThunk)),
|
||||||
|
0, 0, 4, 4,
|
||||||
|
static_cast<Compiler::Operand*>(0), a,
|
||||||
|
static_cast<Compiler::Operand*>(0), b));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dconst_0:
|
case dconst_0:
|
||||||
@ -2412,56 +2492,32 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushLong
|
frame->pushLong(c->fdiv(8, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, divideDoubleThunk)),
|
|
||||||
0, 0, 8, 4,
|
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dmul: {
|
case dmul: {
|
||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushLong
|
frame->pushLong(c->fmul(8, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, multiplyDoubleThunk)),
|
|
||||||
0, 0, 8, 4,
|
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dneg: {
|
case dneg: {
|
||||||
frame->pushLong
|
frame->pushLong(c->fneg(8, frame->popLong()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, negateDoubleThunk)),
|
|
||||||
0, 0, 8, 2,
|
|
||||||
static_cast<Compiler::Operand*>(0), frame->popLong()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case vm::drem: {
|
case vm::drem: {
|
||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushLong
|
frame->pushLong(c->frem(8, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, moduloDoubleThunk)),
|
|
||||||
0, 0, 8, 4,
|
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dsub: {
|
case dsub: {
|
||||||
Compiler::Operand* a = frame->popLong();
|
Compiler::Operand* a = frame->popLong();
|
||||||
Compiler::Operand* b = frame->popLong();
|
Compiler::Operand* b = frame->popLong();
|
||||||
|
|
||||||
frame->pushLong
|
frame->pushLong(c->fsub(8, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, subtractDoubleThunk)),
|
|
||||||
0, 0, 8, 4,
|
|
||||||
static_cast<Compiler::Operand*>(0), a,
|
|
||||||
static_cast<Compiler::Operand*>(0), b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dup:
|
case dup:
|
||||||
@ -2489,54 +2545,52 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case f2d: {
|
case f2d: {
|
||||||
frame->pushLong
|
frame->pushLong(c->f2f(4, 8, frame->popInt()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, floatToDoubleThunk)),
|
|
||||||
0, 0, 8, 1, frame->popInt()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case f2i: {
|
case f2i: {
|
||||||
frame->pushInt
|
frame->pushInt(c->f2i(4, 4, frame->popInt()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, floatToIntThunk)),
|
|
||||||
0, 0, 4, 1, frame->popInt()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case f2l: {
|
case f2l: {
|
||||||
frame->pushLong
|
frame->pushLong(c->f2i(4, 8, frame->popInt()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, floatToLongThunk)),
|
|
||||||
0, 0, 8, 1, frame->popInt()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fadd: {
|
case fadd: {
|
||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
frame->pushInt(c->fadd(4, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, addFloatThunk)),
|
|
||||||
0, 0, 4, 2, a, b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fcmpg: {
|
case fcmpg: {
|
||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
if(t->arch->supportsFloatCompare(4) && isCJump(codeBody(t, code, ip))) {
|
||||||
(c->call
|
c->fcmp(4, a, b);
|
||||||
(c->constant(getThunk(t, compareFloatsGThunk)),
|
lastFcmpg = 0;
|
||||||
0, 0, 4, 2, a, b));
|
} else {
|
||||||
|
frame->pushInt
|
||||||
|
(c->call
|
||||||
|
(c->constant(getThunk(t, compareFloatsGThunk)),
|
||||||
|
0, 0, 4, 2, a, b));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fcmpl: {
|
case fcmpl: {
|
||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
if(t->arch->supportsFloatCompare(4) && isCJump(codeBody(t, code, ip))) {
|
||||||
(c->call
|
c->fcmp(4, a, b);
|
||||||
(c->constant(getThunk(t, compareFloatsLThunk)),
|
lastFcmpl = 0;
|
||||||
0, 0, 4, 2, a, b));
|
} else {
|
||||||
|
frame->pushInt
|
||||||
|
(c->call
|
||||||
|
(c->constant(getThunk(t, compareFloatsLThunk)),
|
||||||
|
0, 0, 4, 2, a, b));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fconst_0:
|
case fconst_0:
|
||||||
@ -2555,47 +2609,32 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
frame->pushInt(c->fdiv(4, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, divideFloatThunk)),
|
|
||||||
0, 0, 4, 2, a, b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fmul: {
|
case fmul: {
|
||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
frame->pushInt(c->fmul(4, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, multiplyFloatThunk)),
|
|
||||||
0, 0, 4, 2, a, b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fneg: {
|
case fneg: {
|
||||||
frame->pushInt
|
frame->pushInt(c->fneg(4, frame->popInt()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, negateFloatThunk)),
|
|
||||||
0, 0, 4, 1, frame->popInt()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case vm::frem: {
|
case vm::frem: {
|
||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
frame->pushInt(c->frem(4, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, moduloFloatThunk)),
|
|
||||||
0, 0, 4, 2, a, b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fsub: {
|
case fsub: {
|
||||||
Compiler::Operand* a = frame->popInt();
|
Compiler::Operand* a = frame->popInt();
|
||||||
Compiler::Operand* b = frame->popInt();
|
Compiler::Operand* b = frame->popInt();
|
||||||
|
|
||||||
frame->pushInt
|
frame->pushInt(c->fsub(4, a, b));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, subtractFloatThunk)),
|
|
||||||
0, 0, 4, 2, a, b));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case getfield:
|
case getfield:
|
||||||
@ -2731,17 +2770,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2d: {
|
case i2d: {
|
||||||
frame->pushLong
|
frame->pushLong(c->i2f(4, 8, frame->popInt()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, intToDoubleThunk)),
|
|
||||||
0, 0, 8, 1, frame->popInt()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2f: {
|
case i2f: {
|
||||||
frame->pushInt
|
frame->pushInt(c->i2f(4, 4, frame->popInt()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, intToFloatThunk)),
|
|
||||||
0, 0, 4, 1, frame->popInt()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2l:
|
case i2l:
|
||||||
@ -2869,27 +2902,48 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
uint32_t newIp = (ip - 3) + offset;
|
uint32_t newIp = (ip - 3) + offset;
|
||||||
assert(t, newIp < codeLength(t, code));
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
Compiler::Operand* a = frame->popInt();
|
|
||||||
Compiler::Operand* target = frame->machineIp(newIp);
|
Compiler::Operand* target = frame->machineIp(newIp);
|
||||||
|
Compiler::Operand* cont = frame->machineIp(ip);
|
||||||
|
|
||||||
c->cmp(4, c->constant(0), a);
|
if(lastFcmpl != 1 && lastFcmpg != 1) {
|
||||||
|
Compiler::Operand* a = frame->popInt();
|
||||||
|
c->cmp(4, c->constant(0), a);
|
||||||
|
}
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
case ifeq:
|
case ifeq:
|
||||||
|
if(lastFcmpl == 1 || lastFcmpg == 1) {
|
||||||
|
c->juo(cont);
|
||||||
|
}
|
||||||
c->je(target);
|
c->je(target);
|
||||||
break;
|
break;
|
||||||
case ifne:
|
case ifne:
|
||||||
|
if(lastFcmpl == 1 || lastFcmpg == 1) {
|
||||||
|
c->juo(cont);
|
||||||
|
}
|
||||||
c->jne(target);
|
c->jne(target);
|
||||||
break;
|
break;
|
||||||
case ifgt:
|
case ifgt:
|
||||||
|
if(lastFcmpl == 1) {
|
||||||
|
c->juo(cont);
|
||||||
|
}
|
||||||
c->jg(target);
|
c->jg(target);
|
||||||
break;
|
break;
|
||||||
case ifge:
|
case ifge:
|
||||||
|
if(lastFcmpl == 1) {
|
||||||
|
c->juo(cont);
|
||||||
|
}
|
||||||
c->jge(target);
|
c->jge(target);
|
||||||
break;
|
break;
|
||||||
case iflt:
|
case iflt:
|
||||||
|
if(lastFcmpg == 1) {
|
||||||
|
c->juo(cont);
|
||||||
|
}
|
||||||
c->jl(target);
|
c->jl(target);
|
||||||
break;
|
break;
|
||||||
case ifle:
|
case ifle:
|
||||||
|
if(lastFcmpg == 1) {
|
||||||
|
c->juo(cont);
|
||||||
|
}
|
||||||
c->jle(target);
|
c->jle(target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3033,8 +3087,40 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
assert(t, methodFlags(t, target) & ACC_STATIC);
|
assert(t, methodFlags(t, target) & ACC_STATIC);
|
||||||
|
int params = methodParameterCount(t, target);
|
||||||
compileDirectInvoke(t, frame, target);
|
if(params == 1) {//TODO: Get number of method params
|
||||||
|
BinaryOperation op = t->arch->hasBinaryIntrinsic(t, target);
|
||||||
|
if(op != NoBinaryOperation) {
|
||||||
|
printf("Could use binary intrinsic %i.\n", op);
|
||||||
|
int opSize = methodParameterFootprint(t, target) * BytesPerWord;
|
||||||
|
int resSize = resultSize(t, methodReturnCode(t, target));
|
||||||
|
Compiler::Operand* param;
|
||||||
|
if(opSize == 4) {
|
||||||
|
param = frame->popInt();
|
||||||
|
} else {
|
||||||
|
param = frame->popLong();
|
||||||
|
}
|
||||||
|
if(resSize == 4) {
|
||||||
|
frame->pushInt(c->operation(op, opSize, resSize, param));
|
||||||
|
} else {
|
||||||
|
frame->pushLong(c->operation(op, opSize, resSize, param));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
compileDirectInvoke(t, frame, target);
|
||||||
|
}
|
||||||
|
} else if(params == 2) { //TODO: Get number of method params
|
||||||
|
TernaryOperation op = t->arch->hasTernaryIntrinsic(t, target);
|
||||||
|
if(op != NoTernaryOperation) {
|
||||||
|
printf("Could use ternary intrinsic %i.\n", op);
|
||||||
|
//int aSize, bSize;
|
||||||
|
//int resSize = resultSize(t, methodReturnCode(t, target));
|
||||||
|
compileDirectInvoke(t, frame, target); //TODO: use intrinsic
|
||||||
|
} else {
|
||||||
|
compileDirectInvoke(t, frame, target);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
compileDirectInvoke(t, frame, target);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case invokevirtual: {
|
case invokevirtual: {
|
||||||
@ -3187,19 +3273,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2d: {
|
case l2d: {
|
||||||
frame->pushLong
|
frame->pushLong(c->i2f(8, 8, frame->popLong()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, longToDoubleThunk)),
|
|
||||||
0, 0, 8, 2,
|
|
||||||
static_cast<Compiler::Operand*>(0), frame->popLong()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2f: {
|
case l2f: {
|
||||||
frame->pushInt
|
frame->pushInt(c->i2f(8, 4, frame->popLong()));
|
||||||
(c->call
|
|
||||||
(c->constant(getThunk(t, longToFloatThunk)),
|
|
||||||
0, 0, 4, 2,
|
|
||||||
static_cast<Compiler::Operand*>(0), frame->popLong()));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2i:
|
case l2i:
|
||||||
@ -4095,7 +4173,6 @@ clearBit(MyThread* t, object map, unsigned count, unsigned size, unsigned i,
|
|||||||
intArrayBody(t, map, count + (index / 32))
|
intArrayBody(t, map, count + (index / 32))
|
||||||
&= ~(static_cast<int32_t>(1) << (index % 32));
|
&= ~(static_cast<int32_t>(1) << (index % 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t*
|
uint8_t*
|
||||||
finish(MyThread* t, Allocator* allocator, Context* context)
|
finish(MyThread* t, Allocator* allocator, Context* context)
|
||||||
{
|
{
|
||||||
@ -4260,6 +4337,7 @@ finish(MyThread* t, Allocator* allocator, Context* context)
|
|||||||
"printStackTrace") == 0)
|
"printStackTrace") == 0)
|
||||||
{
|
{
|
||||||
trap();
|
trap();
|
||||||
|
printf("Address: %p\n", ::vmAddressFromLine(t, (object)(context->method), 1176));
|
||||||
}
|
}
|
||||||
|
|
||||||
syncInstructionCache(start, codeSize);
|
syncInstructionCache(start, codeSize);
|
||||||
|
Loading…
Reference in New Issue
Block a user