diff --git a/include/avian/codegen/registers.h b/include/avian/codegen/registers.h index 34b74926cb..cc91b458a5 100644 --- a/include/avian/codegen/registers.h +++ b/include/avian/codegen/registers.h @@ -20,13 +20,13 @@ class RegisterMask; class Register { private: - int8_t index; + int8_t _index; public: - explicit constexpr Register(int8_t index) : index(index) {} - constexpr Register() : index(-1) {} + explicit constexpr Register(int8_t _index) : _index(_index) {} + constexpr Register() : _index(-1) {} constexpr bool operator == (Register o) const { - return index == o.index; + return _index == o._index; } constexpr bool operator != (Register o) const { @@ -35,8 +35,24 @@ public: constexpr RegisterMask operator | (Register o) const; - constexpr operator int8_t() const { - return index; + constexpr bool operator < (Register o) const { + return _index < o._index; + } + + constexpr bool operator > (Register o) const { + return _index > o._index; + } + + constexpr bool operator <= (Register o) const { + return _index <= o._index; + } + + constexpr bool operator >= (Register o) const { + return _index >= o._index; + } + + constexpr int index() const { + return _index; } }; @@ -48,7 +64,7 @@ private: public: constexpr RegisterMask(uint64_t mask) : mask(mask) {} constexpr RegisterMask() : mask(0) {} - constexpr RegisterMask(Register reg) : mask(static_cast(1) << (int8_t)reg) {} + constexpr RegisterMask(Register reg) : mask(static_cast(1) << reg.index()) {} constexpr RegisterMask operator &(RegisterMask o) const { return RegisterMask(mask & o.mask); @@ -64,19 +80,19 @@ public: } constexpr bool contains(Register reg) const { - return (mask & (static_cast(1) << (int8_t)reg)) != 0; + return (mask & (static_cast(1) << reg.index())) != 0; } constexpr bool containsExactly(Register reg) const { - return mask == (mask & (static_cast(1) << (int8_t)reg)); + return mask == (mask & (static_cast(1) << reg.index())); } constexpr RegisterMask excluding(Register reg) const { - return RegisterMask(mask & ~(static_cast(1) << (int8_t)reg)); + return RegisterMask(mask & ~(static_cast(1) << reg.index())); } constexpr RegisterMask including(Register reg) const { - return RegisterMask(mask | (static_cast(1) << (int8_t)reg)); + return RegisterMask(mask | (static_cast(1) << reg.index())); } constexpr explicit operator uint64_t() const { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index a5baccc155..389d57c3c4 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2216,18 +2216,18 @@ class Client : public Assembler::Client { Register r = pickRegisterTarget(c, 0, mask, &cost); expect(c, cost < Target::Impossible); save(r); - c->registerResources[(int8_t)r].increment(c); + c->registerResources[r.index()].increment(c); return r; } virtual void releaseTemporary(Register r) { - c->registerResources[(int8_t)r].decrement(c); + c->registerResources[r.index()].decrement(c); } virtual void save(Register r) { - RegisterResource* reg = c->registerResources + (int8_t)r; + RegisterResource* reg = c->registerResources + r.index(); assertT(c, reg->referenceCount == 0); assertT(c, reg->freezeCount == 0); diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index a0356c6de8..936c787e30 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -399,7 +399,7 @@ class CallEvent : public Event { Register number = c->arch->argumentRegister(index); if (DebugReads) { - fprintf(stderr, "reg %d arg read %p\n", (int8_t)number, v); + fprintf(stderr, "reg %d arg read %p\n", number.index(), v); } targetMask = SiteMask::fixedRegisterMask(number); diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 15143e2b48..13197c6b50 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -65,7 +65,7 @@ bool pickRegisterTarget(Context* c, CostCalculator* costCalculator) { if (mask.contains(i)) { - RegisterResource* r = c->registerResources + (int8_t)i; + RegisterResource* r = c->registerResources + i.index(); unsigned myCost = resourceCost( c, @@ -96,8 +96,8 @@ Register pickRegisterTarget(Context* c, if (mask & c->regFile->generalRegisters) { for (Register i = Register(c->regFile->generalRegisters.limit - 1); - (int8_t)i >= c->regFile->generalRegisters.start; - i = Register((int8_t)i - 1)) { + i.index() >= c->regFile->generalRegisters.start; + i = Register(i.index() - 1)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } @@ -106,8 +106,8 @@ Register pickRegisterTarget(Context* c, if (mask & c->regFile->floatRegisters) { for (Register i = Register(c->regFile->floatRegisters.start); - (int8_t)i < c->regFile->floatRegisters.limit; - i = Register((int8_t)i + 1)) { + i.index() < c->regFile->floatRegisters.limit; + i = Register(i.index() + 1)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; } diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h index c10105fb9d..b9b76fac8d 100644 --- a/src/codegen/compiler/regalloc.h +++ b/src/codegen/compiler/regalloc.h @@ -61,7 +61,7 @@ class Target { } Target(Register reg, unsigned cost) - : index((int8_t)reg), type(lir::Operand::Type::RegisterPair), cost(cost) + : index(reg.index()), type(lir::Operand::Type::RegisterPair), cost(cost) { } diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 17d99e60d8..745804fd65 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -306,28 +306,28 @@ void RegisterSite::release(Context* c, Value* v) { assertT(c, number != NoRegister); - compiler::release(c, c->registerResources + (int8_t)number, v, this); + compiler::release(c, c->registerResources + number.index(), v, this); } void RegisterSite::freeze(Context* c, Value* v) { assertT(c, number != NoRegister); - c->registerResources[(int8_t)number].freeze(c, v); + c->registerResources[number.index()].freeze(c, v); } void RegisterSite::thaw(Context* c, Value* v) { assertT(c, number != NoRegister); - c->registerResources[(int8_t)number].thaw(c, v); + c->registerResources[number.index()].thaw(c, v); } bool RegisterSite::frozen(Context* c UNUSED) { assertT(c, number != NoRegister); - return c->registerResources[(int8_t)number].freezeCount != 0; + return c->registerResources[number.index()].freezeCount != 0; } lir::Operand::Type RegisterSite::type(Context*) @@ -532,9 +532,9 @@ bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) void MemorySite::acquire(Context* c, Value* v) { - c->registerResources[(int8_t)base].increment(c); + c->registerResources[base.index()].increment(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].increment(c); + c->registerResources[index.index()].increment(c); } if (base == c->arch->stack()) { @@ -558,9 +558,9 @@ void MemorySite::release(Context* c, Value* v) c, c->frameResources + offsetToFrameIndex(c, offset), v, this); } - c->registerResources[(int8_t)base].decrement(c); + c->registerResources[base.index()].decrement(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].decrement(c); + c->registerResources[index.index()].decrement(c); } acquired = false; @@ -571,9 +571,9 @@ void MemorySite::freeze(Context* c, Value* v) if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); } else { - c->registerResources[(int8_t)base].increment(c); + c->registerResources[base.index()].increment(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].increment(c); + c->registerResources[index.index()].increment(c); } } } @@ -583,9 +583,9 @@ void MemorySite::thaw(Context* c, Value* v) if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); } else { - c->registerResources[(int8_t)base].decrement(c); + c->registerResources[base.index()].decrement(c); if (index != NoRegister) { - c->registerResources[(int8_t)index].decrement(c); + c->registerResources[index.index()].decrement(c); } } } diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index f18a54009c..b2c10ddc39 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -43,7 +43,7 @@ class SiteMask { static SiteMask fixedRegisterMask(Register number) { - return SiteMask(lir::Operand::RegisterPairMask, 1 << (int8_t)number, NoFrameIndex); + return SiteMask(lir::Operand::RegisterPairMask, 1 << number.index(), NoFrameIndex); } static SiteMask lowPart(const OperandMask& mask) diff --git a/src/codegen/target/arm/assembler.cpp b/src/codegen/target/arm/assembler.cpp index f4a3192656..2fd89a86db 100644 --- a/src/codegen/target/arm/assembler.cpp +++ b/src/codegen/target/arm/assembler.cpp @@ -216,11 +216,11 @@ class MyArchitecture : public Architecture { virtual bool reserved(Register register_) { - switch ((int8_t)register_) { - case LinkRegister: - case StackRegister: - case ThreadRegister: - case ProgramCounter: + switch (register_.index()) { + case LinkRegister.index(): + case StackRegister.index(): + case ThreadRegister.index(): + case ProgramCounter.index(): return true; default: diff --git a/src/codegen/target/arm/encode.h b/src/codegen/target/arm/encode.h index d7e7b82926..2ac2809157 100644 --- a/src/codegen/target/arm/encode.h +++ b/src/codegen/target/arm/encode.h @@ -48,18 +48,18 @@ enum SHIFTOP { LSL, LSR, ASR, ROR }; inline int DATA(int cond, int opcode, int S, Register Rn, Register Rd, int shift, int Sh, Register Rm) { - return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 - | Sh << 5 | (int8_t)Rm; + return cond << 28 | opcode << 21 | S << 20 | Rn.index() << 16 | Rd.index() << 12 | shift << 7 + | Sh << 5 | Rm.index(); } inline int DATAS(int cond, int opcode, int S, Register Rn, Register Rd, Register Rs, int Sh, Register Rm) { - return cond << 28 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (int8_t)Rs << 8 - | Sh << 5 | 1 << 4 | (int8_t)Rm; + return cond << 28 | opcode << 21 | S << 20 | Rn.index() << 16 | Rd.index() << 12 | Rs.index() << 8 + | Sh << 5 | 1 << 4 | Rm.index(); } inline int DATAI(int cond, int opcode, int S, Register Rn, Register Rd, int rot, int imm) { - return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 + return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | Rn.index() << 16 | Rd.index() << 12 | rot << 8 | (imm & 0xff); } inline int BRANCH(int cond, int L, int offset) @@ -68,12 +68,12 @@ inline int BRANCH(int cond, int L, int offset) } inline int BRANCHX(int cond, int L, Register Rm) { - return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | (int8_t)Rm; + return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | Rm.index(); } inline int MULTIPLY(int cond, int mul, int S, Register Rd, Register Rn, Register Rs, Register Rm) { - return cond << 28 | mul << 21 | S << 20 | (int8_t)Rd << 16 | (int8_t)Rn << 12 | (int8_t)Rs << 8 - | 9 << 4 | (int8_t)Rm; + return cond << 28 | mul << 21 | S << 20 | Rd.index() << 16 | Rn.index() << 12 | Rs.index() << 8 + | 9 << 4 | Rm.index(); } inline int XFER(int cond, int P, @@ -88,7 +88,7 @@ inline int XFER(int cond, Register Rm) { return cond << 28 | 3 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20 - | (int8_t)Rn << 16 | (int8_t)Rd << 12 | shift << 7 | Sh << 5 | (int8_t)Rm; + | Rn.index() << 16 | Rd.index() << 12 | shift << 7 | Sh << 5 | Rm.index(); } inline int XFERI(int cond, int P, @@ -101,7 +101,7 @@ inline int XFERI(int cond, int offset) { return cond << 28 | 2 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20 - | (int8_t)Rn << 16 | (int8_t)Rd << 12 | (offset & 0xfff); + | Rn.index() << 16 | Rd.index() << 12 | (offset & 0xfff); } inline int XFER2(int cond, int P, @@ -114,8 +114,8 @@ inline int XFER2(int cond, int H, Register Rm) { - return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | (int8_t)Rn << 16 - | (int8_t)Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (int8_t)Rm; + return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | Rn.index() << 16 + | Rd.index() << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | Rm.index(); } inline int XFER2I(int cond, int P, @@ -129,8 +129,8 @@ inline int XFER2I(int cond, int H, int offsetL) { - return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | (int8_t)Rn << 16 - | (int8_t)Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4 + return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | Rn.index() << 16 + | Rd.index() << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | (offsetL & 0xf); } inline int COOP(int cond, @@ -156,7 +156,7 @@ inline int COXFER(int cond, int offset) // offset is in words, not bytes { return cond << 28 | 0x6 << 25 | P << 24 | U << 23 | N << 22 | W << 21 - | L << 20 | (int8_t)Rn << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; + | L << 20 | Rn.index() << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2; } inline int COREG(int cond, int opcode_1, @@ -168,12 +168,12 @@ inline int COREG(int cond, int CRm) { return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | CRn << 16 - | (int8_t)Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm; + | Rd.index() << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm; } inline int COREG2(int cond, int L, Register Rn, Register Rd, int cp_num, int opcode, int CRm) { - return cond << 28 | 0xc4 << 20 | L << 20 | (int8_t)Rn << 16 | (int8_t)Rd << 12 | cp_num << 8 + return cond << 28 | 0xc4 << 20 | L << 20 | Rn.index() << 16 | Rd.index() << 12 | cp_num << 8 | opcode << 4 | CRm; } // FIELD CALCULATORS diff --git a/src/codegen/target/arm/registers.h b/src/codegen/target/arm/registers.h index adefa9b8cc..ad13db466a 100644 --- a/src/codegen/target/arm/registers.h +++ b/src/codegen/target/arm/registers.h @@ -28,12 +28,12 @@ const RegisterMask FPR_MASK = 0xffff0000; inline bool isFpr(lir::RegisterPair* reg) { - return (int8_t)reg->low >= N_GPRS; + return reg->low.index() >= N_GPRS; } inline int fpr64(Register reg) { - return (int8_t)reg - N_GPRS; + return reg.index() - N_GPRS; } inline int fpr64(lir::RegisterPair* reg) { diff --git a/src/codegen/target/x86/assembler.cpp b/src/codegen/target/x86/assembler.cpp index ead5765075..e78300f709 100644 --- a/src/codegen/target/x86/assembler.cpp +++ b/src/codegen/target/x86/assembler.cpp @@ -235,12 +235,12 @@ class MyArchitecture : public Architecture { virtual bool reserved(Register register_) { - switch ((int8_t)register_) { - case (int8_t)rbp: + switch (register_.index()) { + case rbp.index(): return UseFramePointer; - case (int8_t)rsp: - case (int8_t)rbx: + case rsp.index(): + case rbx.index(): return true; default: diff --git a/src/codegen/target/x86/encode.cpp b/src/codegen/target/x86/encode.cpp index 16e639876a..35525f5e1c 100644 --- a/src/codegen/target/x86/encode.cpp +++ b/src/codegen/target/x86/encode.cpp @@ -65,11 +65,11 @@ void maybeRex(Context* c, } else { byte = REX_NONE; } - if (a != NoRegister and ((int8_t)a & 8)) + if (a != NoRegister and (a.index() & 8)) byte |= REX_R; - if (index != NoRegister and ((int8_t)index & 8)) + if (index != NoRegister and (index.index() & 8)) byte |= REX_X; - if (base != NoRegister and ((int8_t)base & 8)) + if (base != NoRegister and (base.index() & 8)) byte |= REX_B; if (always or byte != REX_NONE) c->code.append(byte); @@ -93,7 +93,7 @@ void maybeRex(Context* c, unsigned size, lir::RegisterPair* a) void maybeRex(Context* c, unsigned size, lir::RegisterPair* a, lir::Memory* b) { - maybeRex(c, size, a->low, b->index, b->base, size == 1 and ((int8_t)a->low & 4)); + maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low.index() & 4)); } void maybeRex(Context* c, unsigned size, lir::Memory* a) @@ -121,7 +121,7 @@ void modrmSib(Context* c, int width, Register a, int scale, Register index, Regi { if (index == NoRegister) { modrm(c, width, base, a); - if (regCode(base) == rsp) { + if (regCode(base) == rsp.index()) { sib(c, 0x00, rsp, rsp); } } else { @@ -132,7 +132,7 @@ void modrmSib(Context* c, int width, Register a, int scale, Register index, Regi void modrmSibImm(Context* c, Register a, int scale, Register index, Register base, int offset) { - if (offset == 0 and regCode(base) != rbp) { + if (offset == 0 and regCode(base) != rbp.index()) { modrmSib(c, 0x00, a, scale, index, base); } else if (vm::fitsInInt8(offset)) { modrmSib(c, 0x40, a, scale, index, base); diff --git a/src/codegen/target/x86/encode.h b/src/codegen/target/x86/encode.h index 4e5f0e6c0c..c89af512cf 100644 --- a/src/codegen/target/x86/encode.h +++ b/src/codegen/target/x86/encode.h @@ -44,7 +44,7 @@ void maybeRex(Context* c, unsigned size, lir::Memory* a); inline int regCode(Register a) { - return (int8_t)a & 7; + return a.index() & 7; } inline int regCode(lir::RegisterPair* a) @@ -54,7 +54,7 @@ inline int regCode(lir::RegisterPair* a) inline bool isFloatReg(lir::RegisterPair* a) { - return (int8_t)a->low >= xmm0; + return a->low >= xmm0; } void modrm(Context* c, uint8_t mod, Register a, Register b); diff --git a/src/codegen/target/x86/operations.cpp b/src/codegen/target/x86/operations.cpp index 9906cc517e..f936be8d3d 100644 --- a/src/codegen/target/x86/operations.cpp +++ b/src/codegen/target/x86/operations.cpp @@ -308,8 +308,8 @@ void moveRR(Context* c, } else { switch (aSize) { case 1: - if (vm::TargetBytesPerWord == 4 and (int8_t)a->low > rbx) { - assertT(c, (int8_t)b->low <= rbx); + if (vm::TargetBytesPerWord == 4 and a->low > rbx) { + assertT(c, b->low <= rbx); moveRR(c, vm::TargetBytesPerWord, a, vm::TargetBytesPerWord, b); moveRR(c, 1, b, vm::TargetBytesPerWord, b); @@ -986,7 +986,7 @@ void multiplyRR(Context* c, addRR(c, 4, &bh, 4, scratch); // mul a->low,%eax%edx - opcode(c, 0xf7, 0xe0 + (int8_t)a->low); + opcode(c, 0xf7, 0xe0 + a->low.index()); addRR(c, 4, scratch, 4, &bh); moveRR(c, 4, &axdx, 4, b); @@ -1274,7 +1274,7 @@ void multiplyCR(Context* c, assertT(c, aSize == bSize); if (vm::TargetBytesPerWord == 4 and aSize == 8) { - const RegisterMask mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); + const RegisterMask mask = GeneralRegisterMask.excluding(rax).excluding(rdx); lir::RegisterPair tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); @@ -1403,7 +1403,7 @@ void shiftLeftRR(Context* c, modrm(c, 0xc0, b->high, b->low); // shl - opcode(c, 0xd3, 0xe0 + (int8_t)b->low); + opcode(c, 0xd3, 0xe0 + b->low.index()); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1454,7 +1454,7 @@ void shiftRightRR(Context* c, modrm(c, 0xc0, b->low, b->high); // sar - opcode(c, 0xd3, 0xf8 + (int8_t)b->high); + opcode(c, 0xd3, 0xf8 + b->high.index()); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1468,7 +1468,7 @@ void shiftRightRR(Context* c, moveRR(c, 4, &bh, 4, b); // 2 bytes // sar 31,high - opcode(c, 0xc1, 0xf8 + (int8_t)b->high); + opcode(c, 0xc1, 0xf8 + b->high.index()); c->code.append(31); } else { assertT(c, a->low == rcx); @@ -1508,7 +1508,7 @@ void unsignedShiftRightRR(Context* c, modrm(c, 0xc0, b->low, b->high); // shr - opcode(c, 0xd3, 0xe8 + (int8_t)b->high); + opcode(c, 0xd3, 0xe8 + b->high.index()); ResolvedPromise promise(32); lir::Constant constant(&promise); @@ -1746,7 +1746,7 @@ void absoluteRR(Context* c, lir::RegisterPair* b UNUSED) { assertT(c, aSize == bSize and a->low == rax and b->low == rax); - lir::RegisterPair d(c->client->acquireTemporary(static_cast(1) << rdx)); + lir::RegisterPair d(c->client->acquireTemporary(rdx)); maybeRex(c, aSize, a, b); opcode(c, 0x99); xorRR(c, aSize, &d, aSize, a); diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp index c7e9ec8d42..b648ef6e13 100644 --- a/unittest/codegen/registers-test.cpp +++ b/unittest/codegen/registers-test.cpp @@ -25,12 +25,12 @@ TEST(RegisterIterator) RegisterIterator it(regs); assertTrue(it.hasNext()); - assertEqual(0, (int8_t)it.next()); + assertEqual(0, it.next().index()); assertTrue(it.hasNext()); - assertEqual(2, (int8_t)it.next()); + assertEqual(2, it.next().index()); assertTrue(it.hasNext()); - assertEqual(4, (int8_t)it.next()); + assertEqual(4, it.next().index()); assertTrue(it.hasNext()); - assertEqual(6, (int8_t)it.next()); + assertEqual(6, it.next().index()); assertFalse(it.hasNext()); }