diff --git a/include/avian/vm/codegen/runtime.h b/include/avian/vm/codegen/runtime.h new file mode 100644 index 0000000000..1142fab3c7 --- /dev/null +++ b/include/avian/vm/codegen/runtime.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2008-2013, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#ifndef AVIAN_CODEGEN_RUNTIME_H +#define AVIAN_CODEGEN_RUNTIME_H + +namespace avian { +namespace codegen { +namespace runtime { + +int64_t compareDoublesG(uint64_t bi, uint64_t ai); +int64_t compareDoublesL(uint64_t bi, uint64_t ai); +int64_t compareFloatsG(uint32_t bi, uint32_t ai); +int64_t compareFloatsL(uint32_t bi, uint32_t ai); +int64_t compareLongs(uint64_t b, uint64_t a); +uint64_t addDouble(uint64_t b, uint64_t a); +uint64_t subtractDouble(uint64_t b, uint64_t a); +uint64_t multiplyDouble(uint64_t b, uint64_t a); +uint64_t divideDouble(uint64_t b, uint64_t a); +uint64_t moduloDouble(uint64_t b, uint64_t a); +uint64_t negateDouble(uint64_t a); +uint64_t squareRootDouble(uint64_t a); +uint64_t doubleToFloat(int64_t a); +int64_t doubleToInt(int64_t a); +int64_t doubleToLong(int64_t a); +uint64_t addFloat(uint32_t b, uint32_t a); +uint64_t subtractFloat(uint32_t b, uint32_t a); +uint64_t multiplyFloat(uint32_t b, uint32_t a); +uint64_t divideFloat(uint32_t b, uint32_t a); +uint64_t moduloFloat(uint32_t b, uint32_t a); +uint64_t negateFloat(uint32_t a); +uint64_t absoluteFloat(uint32_t a); +int64_t absoluteLong(int64_t a); +int64_t absoluteInt(int32_t a); +uint64_t floatToDouble(int32_t a); +int64_t floatToInt(int32_t a); +int64_t floatToLong(int32_t a); +uint64_t intToDouble(int32_t a); +uint64_t intToFloat(int32_t a); +uint64_t longToDouble(int64_t a); +uint64_t longToFloat(int64_t a); + +} // namespace runtime +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_RUNTIME_H diff --git a/makefile b/makefile index fc3495cef9..9f8f63749d 100755 --- a/makefile +++ b/makefile @@ -1131,6 +1131,7 @@ compiler-sources = \ $(src)/codegen/compiler.cpp \ $(wildcard $(src)/codegen/compiler/*.cpp) \ $(src)/codegen/registers.cpp \ + $(src)/codegen/runtime.cpp \ $(src)/codegen/targets.cpp x86-assembler-sources = $(wildcard $(src)/codegen/target/x86/*.cpp) diff --git a/src/codegen/runtime.cpp b/src/codegen/runtime.cpp new file mode 100644 index 0000000000..d18874ecc1 --- /dev/null +++ b/src/codegen/runtime.cpp @@ -0,0 +1,282 @@ +/* Copyright (c) 2008-2013, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include + +namespace avian { +namespace codegen { +namespace runtime { + +static bool isNaN(double v) +{ + return fpclassify(v) == FP_NAN; +} + +static bool isNaN(float v) +{ + return fpclassify(v) == FP_NAN; +} + +int64_t compareDoublesG(uint64_t bi, uint64_t ai) +{ + double a = vm::bitsToDouble(ai); + double b = vm::bitsToDouble(bi); + + if (isNaN(a) or isNaN(b)) { + return 1; + } else if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a == b) { + return 0; + } else { + return 1; + } +} + +int64_t compareDoublesL(uint64_t bi, uint64_t ai) +{ + double a = vm::bitsToDouble(ai); + double b = vm::bitsToDouble(bi); + + if (isNaN(a) or isNaN(b)) { + return -1; + } else if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a == b) { + return 0; + } else { + return -1; + } +} + +int64_t compareFloatsG(uint32_t bi, uint32_t ai) +{ + float a = vm::bitsToFloat(ai); + float b = vm::bitsToFloat(bi); + + if (isNaN(a) or isNaN(b)) { + return 1; + } + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a == b) { + return 0; + } else { + return 1; + } +} + +int64_t compareFloatsL(uint32_t bi, uint32_t ai) +{ + float a = vm::bitsToFloat(ai); + float b = vm::bitsToFloat(bi); + + if (isNaN(a) or isNaN(b)) { + return -1; + } + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a == b) { + return 0; + } else { + return -1; + } +} + +int64_t compareLongs(uint64_t b, uint64_t a) +{ + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else { + return 0; + } +} + +uint64_t addDouble(uint64_t b, uint64_t a) +{ + return vm::doubleToBits(vm::bitsToDouble(a) + vm::bitsToDouble(b)); +} + +uint64_t subtractDouble(uint64_t b, uint64_t a) +{ + return vm::doubleToBits(vm::bitsToDouble(a) - vm::bitsToDouble(b)); +} + +uint64_t multiplyDouble(uint64_t b, uint64_t a) +{ + return vm::doubleToBits(vm::bitsToDouble(a) * vm::bitsToDouble(b)); +} + +uint64_t divideDouble(uint64_t b, uint64_t a) +{ + return vm::doubleToBits(vm::bitsToDouble(a) / vm::bitsToDouble(b)); +} + +uint64_t moduloDouble(uint64_t b, uint64_t a) +{ + return vm::doubleToBits(fmod(vm::bitsToDouble(a), vm::bitsToDouble(b))); +} + +uint64_t negateDouble(uint64_t a) +{ + return vm::doubleToBits(-vm::bitsToDouble(a)); +} + +uint64_t squareRootDouble(uint64_t a) +{ + return vm::doubleToBits(sqrt(vm::bitsToDouble(a))); +} + +uint64_t doubleToFloat(int64_t a) +{ + return vm::floatToBits(static_cast(vm::bitsToDouble(a))); +} + +int64_t doubleToInt(int64_t a) +{ + double f = vm::bitsToDouble(a); + switch (fpclassify(f)) { + case FP_NAN: + return 0; + case FP_INFINITE: + return signbit(f) ? INT32_MIN : INT32_MAX; + default: + return f >= INT32_MAX + ? INT32_MAX + : (f <= INT32_MIN ? INT32_MIN : static_cast(f)); + } +} + +int64_t doubleToLong(int64_t a) +{ + double f = vm::bitsToDouble(a); + switch (fpclassify(f)) { + case FP_NAN: + return 0; + case FP_INFINITE: + return signbit(f) ? INT64_MIN : INT64_MAX; + default: + return f >= INT64_MAX + ? INT64_MAX + : (f <= INT64_MIN ? INT64_MIN : static_cast(f)); + } +} + +uint64_t addFloat(uint32_t b, uint32_t a) +{ + return vm::floatToBits(vm::bitsToFloat(a) + vm::bitsToFloat(b)); +} + +uint64_t subtractFloat(uint32_t b, uint32_t a) +{ + return vm::floatToBits(vm::bitsToFloat(a) - vm::bitsToFloat(b)); +} + +uint64_t multiplyFloat(uint32_t b, uint32_t a) +{ + return vm::floatToBits(vm::bitsToFloat(a) * vm::bitsToFloat(b)); +} + +uint64_t divideFloat(uint32_t b, uint32_t a) +{ + return vm::floatToBits(vm::bitsToFloat(a) / vm::bitsToFloat(b)); +} + +uint64_t moduloFloat(uint32_t b, uint32_t a) +{ + return vm::floatToBits(fmod(vm::bitsToFloat(a), vm::bitsToFloat(b))); +} + +uint64_t negateFloat(uint32_t a) +{ + return vm::floatToBits(-vm::bitsToFloat(a)); +} + +uint64_t absoluteFloat(uint32_t a) +{ + return vm::floatToBits(fabsf(vm::bitsToFloat(a))); +} + +int64_t absoluteLong(int64_t a) +{ + return a > 0 ? a : -a; +} + +int64_t absoluteInt(int32_t a) +{ + return a > 0 ? a : -a; +} + +uint64_t floatToDouble(int32_t a) +{ + return vm::doubleToBits(static_cast(vm::bitsToFloat(a))); +} + +int64_t floatToInt(int32_t a) +{ + float f = vm::bitsToFloat(a); + switch (fpclassify(f)) { + case FP_NAN: + return 0; + case FP_INFINITE: + return signbit(f) ? INT32_MIN : INT32_MAX; + default: + return f >= INT32_MAX + ? INT32_MAX + : (f <= INT32_MIN ? INT32_MIN : static_cast(f)); + } +} + +int64_t floatToLong(int32_t a) +{ + float f = vm::bitsToFloat(a); + switch (fpclassify(f)) { + case FP_NAN: + return 0; + case FP_INFINITE: + return signbit(f) ? INT64_MIN : INT64_MAX; + default: + return static_cast(f); + } +} + +uint64_t intToDouble(int32_t a) +{ + return vm::doubleToBits(static_cast(a)); +} + +uint64_t intToFloat(int32_t a) +{ + return vm::floatToBits(static_cast(a)); +} + +uint64_t longToDouble(int64_t a) +{ + return vm::doubleToBits(static_cast(a)); +} + +uint64_t longToFloat(int64_t a) +{ + return vm::floatToBits(static_cast(a)); +} + +} // namespace runtime +} // namespace codegen +} // namespace avian diff --git a/src/compile.cpp b/src/compile.cpp index 2cc9cb7eda..cfa1aef6c4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -2460,232 +2461,6 @@ getJClassFromReference(MyThread* t, object pair) referenceName(t, pairSecond(t, pair))))); } -bool -isNaN(double v) -{ - return fpclassify(v) == FP_NAN; -} - -bool -isNaN(float v) -{ - return fpclassify(v) == FP_NAN; -} - -int64_t -compareDoublesG(uint64_t bi, uint64_t ai) -{ - double a = bitsToDouble(ai); - double b = bitsToDouble(bi); - - if (isNaN(a) or isNaN(b)) { - return 1; - } else if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else if (a == b) { - return 0; - } else { - return 1; - } -} - -int64_t -compareDoublesL(uint64_t bi, uint64_t ai) -{ - double a = bitsToDouble(ai); - double b = bitsToDouble(bi); - - if (isNaN(a) or isNaN(b)) { - return -1; - } else if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else if (a == b) { - return 0; - } else { - return -1; - } -} - -int64_t -compareFloatsG(uint32_t bi, uint32_t ai) -{ - float a = bitsToFloat(ai); - float b = bitsToFloat(bi); - - if (isNaN(a) or isNaN(b)) { - return 1; - } if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else if (a == b) { - return 0; - } else { - return 1; - } -} - -int64_t -compareFloatsL(uint32_t bi, uint32_t ai) -{ - float a = bitsToFloat(ai); - float b = bitsToFloat(bi); - - if (isNaN(a) or isNaN(b)) { - return -1; - } if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else if (a == b) { - return 0; - } else { - return -1; - } -} - -int64_t -compareLongs(uint64_t b, uint64_t a) -{ - if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else { - return 0; - } -} - -uint64_t -addDouble(uint64_t b, uint64_t a) -{ - return doubleToBits(bitsToDouble(a) + bitsToDouble(b)); -} - -uint64_t -subtractDouble(uint64_t b, uint64_t a) -{ - return doubleToBits(bitsToDouble(a) - bitsToDouble(b)); -} - -uint64_t -multiplyDouble(uint64_t b, uint64_t a) -{ - return doubleToBits(bitsToDouble(a) * bitsToDouble(b)); -} - -uint64_t -divideDouble(uint64_t b, uint64_t a) -{ - return doubleToBits(bitsToDouble(a) / bitsToDouble(b)); -} - -uint64_t -moduloDouble(uint64_t b, uint64_t a) -{ - return doubleToBits(fmod(bitsToDouble(a), bitsToDouble(b))); -} - -uint64_t -negateDouble(uint64_t a) -{ - return doubleToBits(- bitsToDouble(a)); -} - -uint64_t -squareRootDouble(uint64_t a) -{ - return doubleToBits(sqrt(bitsToDouble(a))); -} - -uint64_t -doubleToFloat(int64_t a) -{ - return floatToBits(static_cast(bitsToDouble(a))); -} - -int64_t -doubleToInt(int64_t a) -{ - double f = bitsToDouble(a); - switch (fpclassify(f)) { - case FP_NAN: return 0; - case FP_INFINITE: return signbit(f) ? INT32_MIN : INT32_MAX; - default: return f >= INT32_MAX ? INT32_MAX - : (f <= INT32_MIN ? INT32_MIN : static_cast(f)); - } -} - -int64_t -doubleToLong(int64_t a) -{ - double f = bitsToDouble(a); - switch (fpclassify(f)) { - case FP_NAN: return 0; - case FP_INFINITE: return signbit(f) ? INT64_MIN : INT64_MAX; - default: return f >= INT64_MAX ? INT64_MAX - : (f <= INT64_MIN ? INT64_MIN : static_cast(f)); - } -} - -uint64_t -addFloat(uint32_t b, uint32_t a) -{ - return floatToBits(bitsToFloat(a) + bitsToFloat(b)); -} - -uint64_t -subtractFloat(uint32_t b, uint32_t a) -{ - return floatToBits(bitsToFloat(a) - bitsToFloat(b)); -} - -uint64_t -multiplyFloat(uint32_t b, uint32_t a) -{ - return floatToBits(bitsToFloat(a) * bitsToFloat(b)); -} - -uint64_t -divideFloat(uint32_t b, uint32_t a) -{ - return floatToBits(bitsToFloat(a) / bitsToFloat(b)); -} - -uint64_t -moduloFloat(uint32_t b, uint32_t a) -{ - return floatToBits(fmod(bitsToFloat(a), bitsToFloat(b))); -} - -uint64_t -negateFloat(uint32_t a) -{ - return floatToBits(- bitsToFloat(a)); -} - -uint64_t -absoluteFloat(uint32_t a) -{ - return floatToBits(fabsf(bitsToFloat(a))); -} - -int64_t -absoluteLong(int64_t a) -{ - return a > 0 ? a : -a; -} - -int64_t -absoluteInt(int32_t a) -{ - return a > 0 ? a : -a; -} - unsigned traceSize(Thread* t) { @@ -2722,8 +2497,7 @@ throwArithmetic(MyThread* t) } } -int64_t -divideLong(MyThread* t, int64_t b, int64_t a) +int64_t divideLong(MyThread* t, int64_t b, int64_t a) { if (LIKELY(b)) { return a / b; @@ -2732,8 +2506,7 @@ divideLong(MyThread* t, int64_t b, int64_t a) } } -int64_t -divideInt(MyThread* t, int32_t b, int32_t a) +int64_t divideInt(MyThread* t, int32_t b, int32_t a) { if (LIKELY(b)) { return a / b; @@ -2742,8 +2515,7 @@ divideInt(MyThread* t, int32_t b, int32_t a) } } -int64_t -moduloLong(MyThread* t, int64_t b, int64_t a) +int64_t moduloLong(MyThread* t, int64_t b, int64_t a) { if (LIKELY(b)) { return a % b; @@ -2752,8 +2524,7 @@ moduloLong(MyThread* t, int64_t b, int64_t a) } } -int64_t -moduloInt(MyThread* t, int32_t b, int32_t a) +int64_t moduloInt(MyThread* t, int32_t b, int32_t a) { if (LIKELY(b)) { return a % b; @@ -2762,59 +2533,6 @@ moduloInt(MyThread* t, int32_t b, int32_t a) } } -uint64_t -floatToDouble(int32_t a) -{ - return doubleToBits(static_cast(bitsToFloat(a))); -} - -int64_t -floatToInt(int32_t a) -{ - float f = bitsToFloat(a); - switch (fpclassify(f)) { - case FP_NAN: return 0; - case FP_INFINITE: return signbit(f) ? INT32_MIN : INT32_MAX; - default: return f >= INT32_MAX ? INT32_MAX - : (f <= INT32_MIN ? INT32_MIN : static_cast(f)); - } -} - -int64_t -floatToLong(int32_t a) -{ - float f = bitsToFloat(a); - switch (fpclassify(f)) { - case FP_NAN: return 0; - case FP_INFINITE: return signbit(f) ? INT64_MIN : INT64_MAX; - default: return static_cast(f); - } -} - -uint64_t -intToDouble(int32_t a) -{ - return doubleToBits(static_cast(a)); -} - -uint64_t -intToFloat(int32_t a) -{ - return floatToBits(static_cast(a)); -} - -uint64_t -longToDouble(int64_t a) -{ - return doubleToBits(static_cast(a)); -} - -uint64_t -longToFloat(int64_t a) -{ - return floatToBits(static_cast(a)); -} - uint64_t makeBlankObjectArray(MyThread* t, object class_, int32_t length) { @@ -8803,6 +8521,9 @@ class MyProcessor: public Processor { thunkTable[throwArrayIndexOutOfBoundsIndex] = voidPointer (throwArrayIndexOutOfBounds); thunkTable[throwStackOverflowIndex] = voidPointer(throwStackOverflow); + + using namespace avian::codegen::runtime; + #define THUNK(s) thunkTable[s##Index] = voidPointer(s); #include "thunks.cpp" #undef THUNK @@ -8872,7 +8593,7 @@ class MyProcessor: public Processor { "TARGET_THREAD_HEAPIMAGE") + checkConstant(t, TARGET_THREAD_CODEIMAGE, - &MyThread::codeImage,, + &MyThread::codeImage, "TARGET_THREAD_CODEIMAGE") + checkConstant(t, TARGET_THREAD_THUNKTABLE,