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 .
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h
index 5531959..897aa3b 100644
--- a/src/IceTargetLoweringX8632Traits.h
+++ b/src/IceTargetLoweringX8632Traits.h
@@ -363,11 +363,30 @@
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 @@
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;
- }
+
+ 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
}
- 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;
- }
- }
- return RegNum;
}
private:
diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h
index 44316b4..0d2b18d 100644
--- a/src/IceTargetLoweringX8664Traits.h
+++ b/src/IceTargetLoweringX8664Traits.h
@@ -437,17 +437,13 @@
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 d2a3530..ad0602a 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -2569,9 +2569,7 @@
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);