Extract independent runtime thunks into their own file

This commit is contained in:
Joshua Warner 2013-12-18 22:46:58 -07:00
parent f1c6b97373
commit fa65c67fbf
4 changed files with 346 additions and 288 deletions

View File

@ -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

View File

@ -1131,6 +1131,7 @@ compiler-sources = \
$(src)/codegen/compiler.cpp \ $(src)/codegen/compiler.cpp \
$(wildcard $(src)/codegen/compiler/*.cpp) \ $(wildcard $(src)/codegen/compiler/*.cpp) \
$(src)/codegen/registers.cpp \ $(src)/codegen/registers.cpp \
$(src)/codegen/runtime.cpp \
$(src)/codegen/targets.cpp $(src)/codegen/targets.cpp
x86-assembler-sources = $(wildcard $(src)/codegen/target/x86/*.cpp) x86-assembler-sources = $(wildcard $(src)/codegen/target/x86/*.cpp)

282
src/codegen/runtime.cpp Normal file
View File

@ -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 <avian/common.h>
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<float>(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<int32_t>(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<int64_t>(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<double>(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<int32_t>(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<int64_t>(f);
}
}
uint64_t intToDouble(int32_t a)
{
return vm::doubleToBits(static_cast<double>(a));
}
uint64_t intToFloat(int32_t a)
{
return vm::floatToBits(static_cast<float>(a));
}
uint64_t longToDouble(int64_t a)
{
return vm::doubleToBits(static_cast<double>(a));
}
uint64_t longToFloat(int64_t a)
{
return vm::floatToBits(static_cast<float>(a));
}
} // namespace runtime
} // namespace codegen
} // namespace avian

View File

@ -20,6 +20,7 @@
#include <avian/vm/codegen/compiler.h> #include <avian/vm/codegen/compiler.h>
#include <avian/vm/codegen/targets.h> #include <avian/vm/codegen/targets.h>
#include <avian/vm/codegen/lir.h> #include <avian/vm/codegen/lir.h>
#include <avian/vm/codegen/runtime.h>
#include <avian/util/runtime-array.h> #include <avian/util/runtime-array.h>
#include <avian/util/list.h> #include <avian/util/list.h>
@ -2460,232 +2461,6 @@ getJClassFromReference(MyThread* t, object pair)
referenceName(t, pairSecond(t, 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<float>(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<int32_t>(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<int64_t>(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 unsigned
traceSize(Thread* t) traceSize(Thread* t)
{ {
@ -2722,8 +2497,7 @@ throwArithmetic(MyThread* t)
} }
} }
int64_t int64_t divideLong(MyThread* t, int64_t b, int64_t a)
divideLong(MyThread* t, int64_t b, int64_t a)
{ {
if (LIKELY(b)) { if (LIKELY(b)) {
return a / b; return a / b;
@ -2732,8 +2506,7 @@ divideLong(MyThread* t, int64_t b, int64_t a)
} }
} }
int64_t int64_t divideInt(MyThread* t, int32_t b, int32_t a)
divideInt(MyThread* t, int32_t b, int32_t a)
{ {
if (LIKELY(b)) { if (LIKELY(b)) {
return a / b; return a / b;
@ -2742,8 +2515,7 @@ divideInt(MyThread* t, int32_t b, int32_t a)
} }
} }
int64_t int64_t moduloLong(MyThread* t, int64_t b, int64_t a)
moduloLong(MyThread* t, int64_t b, int64_t a)
{ {
if (LIKELY(b)) { if (LIKELY(b)) {
return a % b; return a % b;
@ -2752,8 +2524,7 @@ moduloLong(MyThread* t, int64_t b, int64_t a)
} }
} }
int64_t int64_t moduloInt(MyThread* t, int32_t b, int32_t a)
moduloInt(MyThread* t, int32_t b, int32_t a)
{ {
if (LIKELY(b)) { if (LIKELY(b)) {
return a % 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<double>(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<int32_t>(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<int64_t>(f);
}
}
uint64_t
intToDouble(int32_t a)
{
return doubleToBits(static_cast<double>(a));
}
uint64_t
intToFloat(int32_t a)
{
return floatToBits(static_cast<float>(a));
}
uint64_t
longToDouble(int64_t a)
{
return doubleToBits(static_cast<double>(a));
}
uint64_t
longToFloat(int64_t a)
{
return floatToBits(static_cast<float>(a));
}
uint64_t uint64_t
makeBlankObjectArray(MyThread* t, object class_, int32_t length) makeBlankObjectArray(MyThread* t, object class_, int32_t length)
{ {
@ -8803,6 +8521,9 @@ class MyProcessor: public Processor {
thunkTable[throwArrayIndexOutOfBoundsIndex] = voidPointer thunkTable[throwArrayIndexOutOfBoundsIndex] = voidPointer
(throwArrayIndexOutOfBounds); (throwArrayIndexOutOfBounds);
thunkTable[throwStackOverflowIndex] = voidPointer(throwStackOverflow); thunkTable[throwStackOverflowIndex] = voidPointer(throwStackOverflow);
using namespace avian::codegen::runtime;
#define THUNK(s) thunkTable[s##Index] = voidPointer(s); #define THUNK(s) thunkTable[s##Index] = voidPointer(s);
#include "thunks.cpp" #include "thunks.cpp"
#undef THUNK #undef THUNK
@ -8872,7 +8593,7 @@ class MyProcessor: public Processor {
"TARGET_THREAD_HEAPIMAGE") "TARGET_THREAD_HEAPIMAGE")
+ checkConstant(t, + checkConstant(t,
TARGET_THREAD_CODEIMAGE, TARGET_THREAD_CODEIMAGE,
&MyThread::codeImage,, &MyThread::codeImage,
"TARGET_THREAD_CODEIMAGE") "TARGET_THREAD_CODEIMAGE")
+ checkConstant(t, + checkConstant(t,
TARGET_THREAD_THUNKTABLE, TARGET_THREAD_THUNKTABLE,