Merge pull request #142 from joshuawarner32/compiler-boilerplate

Remove boilerplate in Compiler interface
This commit is contained in:
Joel Dice 2013-12-20 13:33:30 -08:00
commit be549ecae3
8 changed files with 669 additions and 1009 deletions

View File

@ -124,73 +124,20 @@ class Compiler {
virtual Operand* loadz(unsigned size, unsigned srcSelectSize, Operand* src,
unsigned dstSize) = 0;
virtual void jumpIfEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfNotEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfLess
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfGreater
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfLessOrEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfGreaterOrEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatNotEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatLess
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatGreater
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatLessOrEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatGreaterOrEqual
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatLessOrUnordered
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatGreaterOrUnordered
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatLessOrEqualOrUnordered
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jumpIfFloatGreaterOrEqualOrUnordered
(unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void condJump(lir::TernaryOperation type, unsigned size, Operand* a, Operand* b, Operand* address) = 0;
virtual void jmp(Operand* address) = 0;
virtual void exit(Operand* address) = 0;
virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* sub(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* div(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* rem(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* fadd(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* fsub(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* fmul(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* fdiv(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* frem(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* shl(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* shr(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* and_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* or_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* neg(unsigned size, Operand* a) = 0;
virtual Operand* fneg(unsigned size, Operand* a) = 0;
virtual Operand* abs(unsigned size, Operand* a) = 0;
virtual Operand* fabs(unsigned size, Operand* a) = 0;
virtual Operand* fsqrt(unsigned size, Operand* a) = 0;
virtual Operand* binaryOp(lir::TernaryOperation type, unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* unaryOp(lir::BinaryOperation type, unsigned size, Operand* a) = 0;
virtual void nullaryOp(lir::Operation type) = 0;
virtual Operand* f2f(unsigned aSize, unsigned resSize, Operand* a) = 0;
virtual Operand* f2i(unsigned aSize, unsigned resSize, Operand* a) = 0;
virtual Operand* i2f(unsigned aSize, unsigned resSize, Operand* a) = 0;
virtual void trap() = 0;
virtual void loadBarrier() = 0;
virtual void storeStoreBarrier() = 0;
virtual void storeLoadBarrier() = 0;
virtual void compile(uintptr_t stackOverflowHandler,
unsigned stackLimitOffset) = 0;
virtual unsigned resolve(uint8_t* dst) = 0;

View File

@ -99,7 +99,6 @@ const unsigned OperandTypeCount = MemoryOperand + 1;
const int NoRegister = -1;
inline bool isBranch(lir::TernaryOperation op) {
return op > FloatMin;
}
@ -108,6 +107,26 @@ inline bool isFloatBranch(lir::TernaryOperation op) {
return op > JumpIfNotEqual;
}
inline bool isGeneralBranch(lir::TernaryOperation op) {
return isBranch(op) && !isFloatBranch(op);
}
inline bool isGeneralBinaryOp(lir::TernaryOperation op) {
return op < FloatAdd;
}
inline bool isFloatBinaryOp(lir::TernaryOperation op) {
return op >= FloatAdd && op <= FloatMin;
}
inline bool isGeneralUnaryOp(lir::BinaryOperation op) {
return op == Negate || op == Absolute;
}
inline bool isFloatUnaryOp(lir::BinaryOperation op) {
return op == FloatNegate || op == FloatSquareRoot || op == FloatAbsolute;
}
class Operand { };
class Constant: public Operand {

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

@ -1132,6 +1132,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)

View File

@ -2592,170 +2592,17 @@ class MyCompiler: public Compiler {
return dst;
}
virtual void jumpIfEqual(unsigned size, Operand* a, Operand* b,
virtual void condJump(lir::TernaryOperation type, unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
assert(&c,
(isGeneralBranch(type) and isGeneralValue(a) and isGeneralValue(b))
or (isFloatBranch(type) and isFloatValue(a) and isFloatValue(b)));
appendBranch(&c, lir::JumpIfEqual, size, static_cast<Value*>(a),
appendBranch(&c, type, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfNotEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
appendBranch(&c, lir::JumpIfNotEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfLess(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
appendBranch(&c, lir::JumpIfLess, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfGreater(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
appendBranch(&c, lir::JumpIfGreater, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfLessOrEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
appendBranch(&c, lir::JumpIfLessOrEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfGreaterOrEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
appendBranch(&c, lir::JumpIfGreaterOrEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatNotEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatNotEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatLess(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatLess, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatGreater(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatGreater, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatLessOrEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatLessOrEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatGreaterOrEqual(unsigned size, Operand* a, Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatGreaterOrEqual, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatLessOrUnordered(unsigned size, Operand* a,
Operand* b, Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatLessOrUnordered, size, static_cast<Value*>(a),
static_cast<Value*>(b), static_cast<Value*>(address));
}
virtual void jumpIfFloatGreaterOrUnordered(unsigned size, Operand* a,
Operand* b, Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatGreaterOrUnordered, size,
static_cast<Value*>(a), static_cast<Value*>(b),
static_cast<Value*>(address));
}
virtual void jumpIfFloatLessOrEqualOrUnordered(unsigned size, Operand* a,
Operand* b, Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatLessOrEqualOrUnordered, size,
static_cast<Value*>(a), static_cast<Value*>(b),
static_cast<Value*>(address));
}
virtual void jumpIfFloatGreaterOrEqualOrUnordered(unsigned size, Operand* a,
Operand* b,
Operand* address)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
appendBranch(&c, lir::JumpIfFloatGreaterOrEqualOrUnordered, size,
static_cast<Value*>(a), static_cast<Value*>(b),
static_cast<Value*>(address));
}
virtual void jmp(Operand* address) {
appendJump(&c, lir::Jump, static_cast<Value*>(address));
}
@ -2764,182 +2611,23 @@ class MyCompiler: public Compiler {
appendJump(&c, lir::Jump, static_cast<Value*>(address), true);
}
virtual Operand* add(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Add, size, static_cast<Value*>(a),
virtual Operand* binaryOp(lir::TernaryOperation type, unsigned size, Operand* a, Operand* b) {
assert(&c,
(isGeneralBinaryOp(type) and isGeneralValue(a) and isGeneralValue(b))
or (isFloatBinaryOp(type) and isFloatValue(a) and isFloatValue(b)));
Value* result = value(&c, static_cast<Value*>(a)->type);
appendCombine(&c, type, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* sub(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Subtract, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* mul(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Multiply, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* div(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Divide, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* rem(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral
and static_cast<Value*>(b)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Remainder, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* fadd(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = lir::ValueFloat;
appendCombine(&c, lir::FloatAdd, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* fsub(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = lir::ValueFloat;
appendCombine(&c, lir::FloatSubtract, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* fmul(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = lir::ValueFloat;
appendCombine(&c, lir::FloatMultiply, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* fdiv(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
appendCombine(&c, lir::FloatDivide, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* frem(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat
and static_cast<Value*>(b)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
appendCombine(&c, lir::FloatRemainder, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::ShiftLeft, TargetBytesPerWord, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* shr(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::ShiftRight, TargetBytesPerWord, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine
(&c, lir::UnsignedShiftRight, TargetBytesPerWord, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* and_(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::And, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* or_(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Or, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendCombine(&c, lir::Xor, size, static_cast<Value*>(a),
size, static_cast<Value*>(b), size, result);
return result;
}
virtual Operand* neg(unsigned size, Operand* a) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendTranslate(&c, lir::Negate, size, static_cast<Value*>(a), size, result);
return result;
}
virtual Operand* fneg(unsigned size, Operand* a) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
appendTranslate(&c, lir::FloatNegate, size, static_cast<Value*>(a), size, result);
return result;
}
virtual Operand* abs(unsigned size, Operand* a) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueGeneral);
appendTranslate(&c, lir::Absolute, size, static_cast<Value*>(a), size, result);
return result;
}
virtual Operand* fabs(unsigned size, Operand* a) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
appendTranslate
(&c, lir::FloatAbsolute, size, static_cast<Value*>(a), size, result);
return result;
}
virtual Operand* fsqrt(unsigned size, Operand* a) {
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
appendTranslate
(&c, lir::FloatSquareRoot, size, static_cast<Value*>(a), size, result);
virtual Operand* unaryOp(lir::BinaryOperation type, unsigned size, Operand* a) {
assert(&c, (isGeneralUnaryOp(type) and isGeneralValue(a))or(
isFloatUnaryOp(type) and isFloatValue(a)));
Value* result = value(&c, static_cast<Value*>(a)->type);
appendTranslate(&c, type, size, static_cast<Value*>(a), size, result);
return result;
}
@ -2967,20 +2655,8 @@ class MyCompiler: public Compiler {
return result;
}
virtual void trap() {
appendOperation(&c, lir::Trap);
}
virtual void loadBarrier() {
appendOperation(&c, lir::LoadBarrier);
}
virtual void storeStoreBarrier() {
appendOperation(&c, lir::StoreStoreBarrier);
}
virtual void storeLoadBarrier() {
appendOperation(&c, lir::StoreLoadBarrier);
virtual void nullaryOp(lir::Operation type) {
appendOperation(&c, type);
}
virtual void compile(uintptr_t stackOverflowHandler,

View File

@ -67,6 +67,13 @@ class Value: public Compiler::Operand {
};
inline bool isGeneralValue(Compiler::Operand* a) {
return static_cast<Value*>(a)->type == lir::ValueGeneral;
}
inline bool isFloatValue(Compiler::Operand* a) {
return static_cast<Value*>(a)->type == lir::ValueFloat;
}
Value* value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0);

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

File diff suppressed because it is too large Load Diff