From ee1aae820b08055583e6c9be7a3118d1e975a45d Mon Sep 17 00:00:00 2001 From: Jim Stichnoth Date: Tue, 2 Feb 2016 09:29:21 -0800 Subject: [PATCH] Subzero: Improve x86-32's implementation of getGprForType(). Replaces the hacky implementation with essentially the less hacky x86-64 implementation, minus the i64 handling. Also does a couple of cleanups on the x86-64 side, including removing special-casing for rbp. BUG= none R=jpp@chromium.org Review URL: https://codereview.chromium.org/1657833002 . --- src/IceTargetLoweringX8632Traits.h | 86 ++++++++++++++++++++++---------------- src/IceTargetLoweringX8664Traits.h | 12 ++---- src/IceTargetLoweringX86BaseImpl.h | 4 +- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h index 5531959e8..897aa3b76 100644 --- a/src/IceTargetLoweringX8632Traits.h +++ b/src/IceTargetLoweringX8632Traits.h @@ -363,11 +363,30 @@ struct TargetX8632Traits { return BaseRegs[RegNum]; } +private: + static int32_t getFirstGprForType(Type Ty) { + switch (Ty) { + default: + llvm_unreachable("Invalid type for GPR."); + case IceType_i1: + case IceType_i8: + return RegisterSet::Reg_al; + case IceType_i16: + return RegisterSet::Reg_ax; + case IceType_i32: + return RegisterSet::Reg_eax; + } + } + +public: // Return a register in RegNum's alias set that is suitable for Ty. static int32_t getGprForType(Type Ty, int32_t RegNum) { assert(RegNum != Variable::NoRegister); - // TODO(stichnot): Rewrite this as a table lookup from a table computed in a - // TargetLowering static initializer. + + if (!isScalarIntegerType(Ty)) { + return RegNum; + } + // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions. switch (RegNum) { default: @@ -379,42 +398,35 @@ struct TargetX8632Traits { assert(isByteSizedType(Ty)); return RegNum; } - RegNum = getBaseReg(RegNum); - if (isByteSizedType(Ty)) { - switch (RegNum) { - default: - assert(0); - case RegisterSet::Reg_eax: - return RegisterSet::Reg_al; - case RegisterSet::Reg_ecx: - return RegisterSet::Reg_cl; - case RegisterSet::Reg_edx: - return RegisterSet::Reg_dl; - case RegisterSet::Reg_ebx: - return RegisterSet::Reg_bl; - } - } - if (Ty == IceType_i16) { - switch (RegNum) { - default: - assert(0); - case RegisterSet::Reg_eax: - return RegisterSet::Reg_ax; - case RegisterSet::Reg_ecx: - return RegisterSet::Reg_cx; - case RegisterSet::Reg_edx: - return RegisterSet::Reg_dx; - case RegisterSet::Reg_ebx: - return RegisterSet::Reg_bx; - case RegisterSet::Reg_ebp: - return RegisterSet::Reg_bp; - case RegisterSet::Reg_esi: - return RegisterSet::Reg_si; - case RegisterSet::Reg_edi: - return RegisterSet::Reg_di; - } + + const int32_t FirstGprForType = getFirstGprForType(Ty); + + switch (RegNum) { + default: + llvm::report_fatal_error("Unknown register."); +#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ + isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ + isTrunc8Rcvr, isAhRcvr, aliases) \ + case RegisterSet::val: { \ + if (!isGPR) \ + return RegisterSet::val; \ + assert((is32) || (is16) || (is8) || \ + getBaseReg(RegisterSet::val) == RegisterSet::Reg_esp); \ + constexpr int32_t FirstGprWithRegNumSize = \ + (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ + ? RegisterSet::Reg_eax \ + : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ + ? RegisterSet::Reg_ax \ + : RegisterSet::Reg_al)); \ + const int32_t NewRegNum = \ + RegNum - FirstGprWithRegNumSize + FirstGprForType; \ + assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ + "Error involving " #val); \ + return NewRegNum; \ + } + REGX8632_TABLE +#undef X } - return RegNum; } private: diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h index 44316b40f..0d2b18de7 100644 --- a/src/IceTargetLoweringX8664Traits.h +++ b/src/IceTargetLoweringX8664Traits.h @@ -437,17 +437,13 @@ public: if (!isGPR) \ return RegisterSet::val; \ assert((is64) || (is32) || (is16) || (is8) || \ - getBaseReg(RegisterSet::val) == RegisterSet::Reg_rsp || \ - getBaseReg(RegisterSet::val) == RegisterSet::Reg_rbp); \ + getBaseReg(RegisterSet::val) == RegisterSet::Reg_rsp); \ constexpr int32_t FirstGprWithRegNumSize = \ - ((is64) || RegisterSet::val == RegisterSet::Reg_rsp || \ - RegisterSet::val == RegisterSet::Reg_rbp) \ + ((is64) || RegisterSet::val == RegisterSet::Reg_rsp) \ ? RegisterSet::Reg_rax \ - : (((is32) || RegisterSet::val == RegisterSet::Reg_esp || \ - RegisterSet::val == RegisterSet::Reg_ebp) \ + : (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ ? RegisterSet::Reg_eax \ - : (((is16) || RegisterSet::val == RegisterSet::Reg_sp || \ - RegisterSet::val == RegisterSet::Reg_bp) \ + : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ ? RegisterSet::Reg_ax \ : RegisterSet::Reg_al)); \ const int32_t NewRegNum = \ diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h index d2a353021..ad0602a3e 100644 --- a/src/IceTargetLoweringX86BaseImpl.h +++ b/src/IceTargetLoweringX86BaseImpl.h @@ -2569,9 +2569,7 @@ void TargetX86Base::lowerCall(const InstCall *Instr) { break; case IceType_i64: if (Traits::Is64Bit) { - ReturnReg = makeReg( - IceType_i64, - Traits::getGprForType(IceType_i64, Traits::RegisterSet::Reg_eax)); + ReturnReg = makeReg(IceType_i64, Traits::getRaxOrDie()); } else { ReturnReg = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax); ReturnRegHi = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx); -- 2.11.0