- 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)