ports/devel/llvm/patches/patch-lib_Target_Mips_MipsISelLowering_cpp

48 lines
2.2 KiB
Text

- Implement the 'h' register constraint on mips64. This lets clang build
pieces of software that use the constraint if the compiler claims
to be compatible with GCC 4.2.1.
Note that the constraint was removed in GCC 4.4. The reason was that
'h' could generate code whose result is unpredictable. The underlying
reason is that the HI and LO registers are special, and the optimizer
has to be careful when choosing the order of HI/LO accesses. It looks
that LLVM has the needed logic.
Index: lib/Target/Mips/MipsISelLowering.cpp
--- lib/Target/Mips/MipsISelLowering.cpp.orig
+++ lib/Target/Mips/MipsISelLowering.cpp
@@ -3925,6 +3925,7 @@ MipsTargetLowering::getConstraintType(StringRef Constr
// backwards compatibility.
// 'c' : A register suitable for use in an indirect
// jump. This will always be $25 for -mabicalls.
+ // 'h' : The hi register. 1 word storage.
// 'l' : The lo register. 1 word storage.
// 'x' : The hilo register pair. Double word storage.
if (Constraint.size() == 1) {
@@ -3934,6 +3935,7 @@ MipsTargetLowering::getConstraintType(StringRef Constr
case 'y':
case 'f':
case 'c':
+ case 'h':
case 'l':
case 'x':
return C_RegisterClass;
@@ -3979,6 +3981,7 @@ MipsTargetLowering::getSingleConstraintMatchWeight(
weight = CW_Register;
break;
case 'c': // $25 for indirect jumps
+ case 'h': // hi register
case 'l': // lo register
case 'x': // hilo register pair
if (type->isIntegerTy())
@@ -4153,6 +4156,11 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const
return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass);
// This will generate an error message
return std::make_pair(0U, nullptr);
+ case 'h': // use the `hi` register to store values
+ // that are no bigger than a word
+ if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)
+ return std::make_pair((unsigned)Mips::HI0, &Mips::HI32RegClass);
+ return std::make_pair((unsigned)Mips::HI0_64, &Mips::HI64RegClass);
case 'l': // use the `lo` register to store values
// that are no bigger than a word
if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)