From 855534b152e3f25e4549a249f2d889b569e53bff Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 30 Apr 2014 19:07:10 -0600 Subject: [PATCH] introduce ir::Type and begin migrating i2f and friends to it --- include/avian/codegen/compiler.h | 7 ++- include/avian/codegen/ir.h | 105 +++++++++++++++++++++++++++++++ src/codegen/compiler.cpp | 39 ++++++++---- src/compile.cpp | 22 ++++--- 4 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 include/avian/codegen/ir.h diff --git a/include/avian/codegen/compiler.h b/include/avian/codegen/compiler.h index f31d5fc320..f2962b9718 100644 --- a/include/avian/codegen/compiler.h +++ b/include/avian/codegen/compiler.h @@ -14,6 +14,7 @@ #include #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; diff --git a/include/avian/codegen/ir.h b/include/avian/codegen/ir.h new file mode 100644 index 0000000000..e3c6f0ed13 --- /dev/null +++ b/include/avian/codegen/ir.h @@ -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 diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index d987912257..cadcb3dc21 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2630,28 +2630,43 @@ class MyCompiler: public Compiler { appendTranslate(&c, type, size, static_cast(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(a)->type == lir::ValueFloat); Value* result = value(&c, lir::ValueFloat); - appendTranslate - (&c, lir::Float2Float, aSize, static_cast(a), resSize, result); + appendTranslate(&c, + lir::Float2Float, + aSize, + static_cast(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(a)->type == lir::ValueFloat); Value* result = value(&c, lir::ValueGeneral); - appendTranslate - (&c, lir::Float2Int, aSize, static_cast(a), resSize, result); + appendTranslate(&c, + lir::Float2Int, + aSize, + static_cast(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(a)->type == lir::ValueGeneral); Value* result = value(&c, lir::ValueFloat); - appendTranslate - (&c, lir::Int2Float, aSize, static_cast(a), resSize, result); + appendTranslate(&c, + lir::Int2Float, + aSize, + static_cast(a), + resType.size(), + result); return result; } diff --git a/src/compile.cpp b/src/compile.cpp index cd13d8f59a..752754d982 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(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: