introduce ir::Type and begin migrating i2f and friends to it

This commit is contained in:
Joshua Warner 2014-04-30 19:07:10 -06:00 committed by Joshua Warner
parent 73bcc766c1
commit 855534b152
4 changed files with 148 additions and 25 deletions

View File

@ -14,6 +14,7 @@
#include <avian/system/system.h>
#include "avian/zone.h"
#include "assembler.h"
#include "ir.h"
namespace avian {
namespace codegen {
@ -134,9 +135,9 @@ class Compiler {
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 Operand* f2f(unsigned aSize, ir::Type resType, Operand* a) = 0;
virtual Operand* f2i(unsigned aSize, ir::Type resType, Operand* a) = 0;
virtual Operand* i2f(unsigned aSize, ir::Type resType, Operand* a) = 0;
virtual void compile(uintptr_t stackOverflowHandler,
unsigned stackLimitOffset) = 0;

105
include/avian/codegen/ir.h Normal file
View File

@ -0,0 +1,105 @@
/* Copyright (c) 2008-2014, 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_IR_H
#define AVIAN_CODEGEN_IR_H
namespace avian {
namespace codegen {
namespace ir {
class Type {
public:
enum Flavor {
// A GC-visiible reference
Object,
// GC-invisible types
Integer,
Float
};
private:
uint8_t flavor_;
uint8_t size_;
friend class Types;
public:
Type(uint8_t flavor_, uint8_t size_) : flavor_(flavor_), size_(size_)
{
}
inline Flavor flavor() const
{
return (Flavor)flavor_;
}
inline unsigned size() const
{
return size_;
}
inline bool operator==(const Type& other) const
{
return flavor_ == other.flavor_ && size_ == other.size_;
}
inline bool operator!=(const Type& other) const
{
return !(*this == other);
}
};
class Types {
public:
// An object reference type, which will be treated as a GC root
Type object;
// A pointer-sized integer type (neither/both signed or unsigned)
// Note that these are just integers from the GC's perspective.
Type address;
// A 1-byte integer type (neither/both signed or unsigned)
Type i1;
// A 2-byte integer type (neither/both signed or unsigned)
Type i2;
// A 4-byte integer type (neither/both signed or unsigned)
Type i4;
// A 8-byte integer type (neither/both signed or unsigned)
Type i8;
// A 4-byte floating point type
Type f4;
// A 8-byte floating point type
Type f8;
Types(unsigned bytesPerWord)
: object(Type::Object, bytesPerWord),
address(Type::Integer, bytesPerWord),
i1(Type::Integer, 1),
i2(Type::Integer, 2),
i4(Type::Integer, 4),
i8(Type::Integer, 8),
f4(Type::Float, 4),
f8(Type::Float, 8)
{
}
};
} // namespace ir
} // namespace codegen
} // namespace avian
#endif // AVIAN_CODEGEN_IR_H

View File

@ -2630,28 +2630,43 @@ class MyCompiler: public Compiler {
appendTranslate(&c, type, size, static_cast<Value*>(a), size, result);
return result;
}
virtual Operand* f2f(unsigned aSize, unsigned resSize, Operand* a) {
virtual Operand* f2f(unsigned aSize, ir::Type resType, Operand* a)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueFloat);
appendTranslate
(&c, lir::Float2Float, aSize, static_cast<Value*>(a), resSize, result);
appendTranslate(&c,
lir::Float2Float,
aSize,
static_cast<Value*>(a),
resType.size(),
result);
return result;
}
virtual Operand* f2i(unsigned aSize, unsigned resSize, Operand* a) {
virtual Operand* f2i(unsigned aSize, ir::Type resType, Operand* a)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueFloat);
Value* result = value(&c, lir::ValueGeneral);
appendTranslate
(&c, lir::Float2Int, aSize, static_cast<Value*>(a), resSize, result);
appendTranslate(&c,
lir::Float2Int,
aSize,
static_cast<Value*>(a),
resType.size(),
result);
return result;
}
virtual Operand* i2f(unsigned aSize, unsigned resSize, Operand* a) {
virtual Operand* i2f(unsigned aSize, ir::Type resType, Operand* a)
{
assert(&c, static_cast<Value*>(a)->type == lir::ValueGeneral);
Value* result = value(&c, lir::ValueFloat);
appendTranslate
(&c, lir::Int2Float, aSize, static_cast<Value*>(a), resSize, result);
appendTranslate(&c,
lir::Int2Float,
aSize,
static_cast<Value*>(a),
resType.size(),
result);
return result;
}

View File

@ -4020,6 +4020,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
unsigned newIp;
stack.pushValue(Return);
ir::Types types(TargetBytesPerWord);
start:
uint8_t* stackMap = static_cast<uint8_t*>(stack.push(stackSize));
frame = new (stack.push(sizeof(Frame))) Frame(frame, stackMap);
@ -4374,15 +4376,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break;
case d2f: {
frame->pushInt(c->f2f(8, 4, frame->popLong()));
frame->pushInt(c->f2f(8, types.f4, frame->popLong()));
} break;
case d2i: {
frame->pushInt(c->f2i(8, 4, frame->popLong()));
frame->pushInt(c->f2i(8, types.f4, frame->popLong()));
} break;
case d2l: {
frame->pushLong(c->f2i(8, 8, frame->popLong()));
frame->pushLong(c->f2i(8, types.f8, frame->popLong()));
} break;
case dadd:
@ -4467,15 +4469,15 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
break;
case f2d: {
frame->pushLong(c->f2f(4, 8, frame->popInt()));
frame->pushLong(c->f2f(4, types.f8, frame->popInt()));
} break;
case f2i: {
frame->pushInt(c->f2i(4, 4, frame->popInt()));
frame->pushInt(c->f2i(4, types.f4, frame->popInt()));
} break;
case f2l: {
frame->pushLong(c->f2i(4, 8, frame->popInt()));
frame->pushLong(c->f2i(4, types.f8, frame->popInt()));
} break;
case fadd:
@ -4751,11 +4753,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break;
case i2d: {
frame->pushLong(c->i2f(4, 8, frame->popInt()));
frame->pushLong(c->i2f(4, types.f8, frame->popInt()));
} break;
case i2f: {
frame->pushInt(c->i2f(4, 4, frame->popInt()));
frame->pushInt(c->i2f(4, types.f4, frame->popInt()));
} break;
case i2l:
@ -5235,11 +5237,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} goto start;
case l2d: {
frame->pushLong(c->i2f(8, 8, frame->popLong()));
frame->pushLong(c->i2f(8, types.f8, frame->popLong()));
} break;
case l2f: {
frame->pushInt(c->i2f(8, 4, frame->popLong()));
frame->pushInt(c->i2f(8, types.f4, frame->popLong()));
} break;
case l2i: