diff --git a/include/avian/vm/codegen/compiler.h b/include/avian/vm/codegen/compiler.h index e9feb85d53..8691530cc7 100644 --- a/include/avian/vm/codegen/compiler.h +++ b/include/avian/vm/codegen/compiler.h @@ -124,39 +124,8 @@ 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; diff --git a/include/avian/vm/codegen/lir.h b/include/avian/vm/codegen/lir.h index 530f72eeab..51bc103b65 100644 --- a/include/avian/vm/codegen/lir.h +++ b/include/avian/vm/codegen/lir.h @@ -108,6 +108,10 @@ inline bool isFloatBranch(lir::TernaryOperation op) { return op > JumpIfNotEqual; } +inline bool isGeneralBranch(lir::TernaryOperation op) { + return isBranch(op) && !isFloatBranch(op); +} + class Operand { }; class Constant: public Operand { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index cf2bca6f03..818f02afe1 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.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(a)->type == lir::ValueGeneral - and static_cast(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(a), + appendBranch(&c, type, size, static_cast(a), static_cast(b), static_cast(address)); } - virtual void jumpIfNotEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueGeneral - and static_cast(b)->type == lir::ValueGeneral); - - appendBranch(&c, lir::JumpIfNotEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfLess(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueGeneral - and static_cast(b)->type == lir::ValueGeneral); - - appendBranch(&c, lir::JumpIfLess, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfGreater(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueGeneral - and static_cast(b)->type == lir::ValueGeneral); - - appendBranch(&c, lir::JumpIfGreater, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfLessOrEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueGeneral - and static_cast(b)->type == lir::ValueGeneral); - - appendBranch(&c, lir::JumpIfLessOrEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfGreaterOrEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueGeneral - and static_cast(b)->type == lir::ValueGeneral); - - appendBranch(&c, lir::JumpIfGreaterOrEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatNotEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatNotEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatLess(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatLess, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatGreater(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatGreater, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatLessOrEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatLessOrEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatGreaterOrEqual(unsigned size, Operand* a, Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatGreaterOrEqual, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatLessOrUnordered(unsigned size, Operand* a, - Operand* b, Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatLessOrUnordered, size, static_cast(a), - static_cast(b), static_cast(address)); - } - - virtual void jumpIfFloatGreaterOrUnordered(unsigned size, Operand* a, - Operand* b, Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatGreaterOrUnordered, size, - static_cast(a), static_cast(b), - static_cast(address)); - } - - virtual void jumpIfFloatLessOrEqualOrUnordered(unsigned size, Operand* a, - Operand* b, Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatLessOrEqualOrUnordered, size, - static_cast(a), static_cast(b), - static_cast(address)); - } - - virtual void jumpIfFloatGreaterOrEqualOrUnordered(unsigned size, Operand* a, - Operand* b, - Operand* address) - { - assert(&c, static_cast(a)->type == lir::ValueFloat - and static_cast(b)->type == lir::ValueFloat); - - appendBranch(&c, lir::JumpIfFloatGreaterOrEqualOrUnordered, size, - static_cast(a), static_cast(b), - static_cast(address)); - } - virtual void jmp(Operand* address) { appendJump(&c, lir::Jump, static_cast(address)); } diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h index 6c702bf13f..e9ff43f19b 100644 --- a/src/codegen/compiler/value.h +++ b/src/codegen/compiler/value.h @@ -67,6 +67,13 @@ class Value: public Compiler::Operand { }; +inline bool isGeneralValue(Compiler::Operand* a) { + return static_cast(a)->type == lir::ValueGeneral; +} + +inline bool isFloatValue(Compiler::Operand* a) { + return static_cast(a)->type == lir::ValueFloat; +} Value* value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0); diff --git a/src/compile.cpp b/src/compile.cpp index 6cce909980..9301276088 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -40,7 +41,7 @@ vmJumpAndInvoke(void* thread, void* function, void* stack, unsigned argumentFootprint, uintptr_t* arguments, unsigned frameSize); -using avian::codegen::Compiler; +using namespace avian::codegen; namespace { @@ -3833,27 +3834,27 @@ integerBranch(MyThread* t, Frame* frame, object code, unsigned& ip, switch (instruction) { case ifeq: - c->jumpIfEqual(size, a, b, target); + c->condJump(lir::JumpIfEqual, size, a, b, target); break; case ifne: - c->jumpIfNotEqual(size, a, b, target); + c->condJump(lir::JumpIfNotEqual, size, a, b, target); break; case ifgt: - c->jumpIfGreater(size, a, b, target); + c->condJump(lir::JumpIfGreater, size, a, b, target); break; case ifge: - c->jumpIfGreaterOrEqual(size, a, b, target); + c->condJump(lir::JumpIfGreaterOrEqual, size, a, b, target); break; case iflt: - c->jumpIfLess(size, a, b, target); + c->condJump(lir::JumpIfLess, size, a, b, target); break; case ifle: - c->jumpIfLessOrEqual(size, a, b, target); + c->condJump(lir::JumpIfLessOrEqual, size, a, b, target); break; default: @@ -3884,42 +3885,42 @@ floatBranch(MyThread* t, Frame* frame, object code, unsigned& ip, switch (instruction) { case ifeq: - c->jumpIfFloatEqual(size, a, b, target); + c->condJump(lir::JumpIfFloatEqual, size, a, b, target); break; case ifne: - c->jumpIfFloatNotEqual(size, a, b, target); + c->condJump(lir::JumpIfFloatNotEqual, size, a, b, target); break; case ifgt: if (lessIfUnordered) { - c->jumpIfFloatGreater(size, a, b, target); + c->condJump(lir::JumpIfFloatGreater, size, a, b, target); } else { - c->jumpIfFloatGreaterOrUnordered(size, a, b, target); + c->condJump(lir::JumpIfFloatGreaterOrUnordered, size, a, b, target); } break; case ifge: if (lessIfUnordered) { - c->jumpIfFloatGreaterOrEqual(size, a, b, target); + c->condJump(lir::JumpIfFloatGreaterOrEqual, size, a, b, target); } else { - c->jumpIfFloatGreaterOrEqualOrUnordered(size, a, b, target); + c->condJump(lir::JumpIfFloatGreaterOrEqualOrUnordered, size, a, b, target); } break; case iflt: if (lessIfUnordered) { - c->jumpIfFloatLessOrUnordered(size, a, b, target); + c->condJump(lir::JumpIfFloatLessOrUnordered, size, a, b, target); } else { - c->jumpIfFloatLess(size, a, b, target); + c->condJump(lir::JumpIfFloatLess, size, a, b, target); } break; case ifle: if (lessIfUnordered) { - c->jumpIfFloatLessOrEqualOrUnordered(size, a, b, target); + c->condJump(lir::JumpIfFloatLessOrEqualOrUnordered, size, a, b, target); } else { - c->jumpIfFloatLessOrEqual(size, a, b, target); + c->condJump(lir::JumpIfFloatLessOrEqual, size, a, b, target); } break; @@ -5081,9 +5082,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, Compiler::Operand* target = frame->machineIp(newIp); if (instruction == if_acmpeq) { - c->jumpIfEqual(TargetBytesPerWord, a, b, target); + c->condJump(lir::JumpIfEqual, TargetBytesPerWord, a, b, target); } else { - c->jumpIfNotEqual(TargetBytesPerWord, a, b, target); + c->condJump(lir::JumpIfNotEqual, TargetBytesPerWord, a, b, target); } } goto branch; @@ -5107,22 +5108,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, switch (instruction) { case if_icmpeq: - c->jumpIfEqual(4, a, b, target); + c->condJump(lir::JumpIfEqual, 4, a, b, target); break; case if_icmpne: - c->jumpIfNotEqual(4, a, b, target); + c->condJump(lir::JumpIfNotEqual, 4, a, b, target); break; case if_icmpgt: - c->jumpIfGreater(4, a, b, target); + c->condJump(lir::JumpIfGreater, 4, a, b, target); break; case if_icmpge: - c->jumpIfGreaterOrEqual(4, a, b, target); + c->condJump(lir::JumpIfGreaterOrEqual, 4, a, b, target); break; case if_icmplt: - c->jumpIfLess(4, a, b, target); + c->condJump(lir::JumpIfLess, 4, a, b, target); break; case if_icmple: - c->jumpIfLessOrEqual(4, a, b, target); + c->condJump(lir::JumpIfLessOrEqual, 4, a, b, target); break; default: abort(t); @@ -5150,22 +5151,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, switch (instruction) { case ifeq: - c->jumpIfEqual(4, a, b, target); + c->condJump(lir::JumpIfEqual, 4, a, b, target); break; case ifne: - c->jumpIfNotEqual(4, a, b, target); + c->condJump(lir::JumpIfNotEqual, 4, a, b, target); break; case ifgt: - c->jumpIfGreater(4, a, b, target); + c->condJump(lir::JumpIfGreater, 4, a, b, target); break; case ifge: - c->jumpIfGreaterOrEqual(4, a, b, target); + c->condJump(lir::JumpIfGreaterOrEqual, 4, a, b, target); break; case iflt: - c->jumpIfLess(4, a, b, target); + c->condJump(lir::JumpIfLess, 4, a, b, target); break; case ifle: - c->jumpIfLessOrEqual(4, a, b, target); + c->condJump(lir::JumpIfLessOrEqual, 4, a, b, target); break; default: abort(t); @@ -5187,9 +5188,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, Compiler::Operand* target = frame->machineIp(newIp); if (instruction == ifnull) { - c->jumpIfEqual(TargetBytesPerWord, a, b, target); + c->condJump(lir::JumpIfEqual, TargetBytesPerWord, a, b, target); } else { - c->jumpIfNotEqual(TargetBytesPerWord, a, b, target); + c->condJump(lir::JumpIfNotEqual, TargetBytesPerWord, a, b, target); } } goto branch; @@ -6303,7 +6304,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, Compiler::Operand* key = frame->popInt(); - c->jumpIfLess(4, c->constant(bottom, Compiler::IntegerType), key, + c->condJump(lir::JumpIfLess, 4, c->constant(bottom, Compiler::IntegerType), key, frame->machineIp(defaultIp)); c->save(1, key); @@ -6390,7 +6391,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, c->restoreState(s->state); - c->jumpIfGreater(4, c->constant(s->top, Compiler::IntegerType), s->key, + c->condJump(lir::JumpIfGreater, 4, c->constant(s->top, Compiler::IntegerType), s->key, frame->machineIp(s->defaultIp)); c->save(1, s->key);