mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
Merge pull request #142 from joshuawarner32/compiler-boilerplate
Remove boilerplate in Compiler interface
This commit is contained in:
commit
be549ecae3
@ -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;
|
||||
|
@ -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 {
|
||||
|
54
include/avian/vm/codegen/runtime.h
Normal file
54
include/avian/vm/codegen/runtime.h
Normal 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
|
1
makefile
1
makefile
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
282
src/codegen/runtime.cpp
Normal 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
|
884
src/compile.cpp
884
src/compile.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user