diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 092ff17edc6..1b9bcc99660 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -7482,6 +7482,7 @@ ARMTargetLowering::getConstraintType(const std::string &Constraint) const { default: break; case 'l': return C_RegisterClass; case 'w': return C_RegisterClass; + case 'h': return C_RegisterClass; } } else if (Constraint.size() == 2) { switch (Constraint[0]) { @@ -7534,11 +7535,16 @@ ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, if (Constraint.size() == 1) { // GCC ARM Constraint Letters switch (Constraint[0]) { - case 'l': + case 'l': // Low regs or general regs. if (Subtarget->isThumb()) return Pair(0U, ARM::tGPRRegisterClass); else return Pair(0U, ARM::GPRRegisterClass); + case 'h': // High regs or no regs. + if (Subtarget->isThumb()) + return Pair(0U, ARM::hGPRRegisterClass); + else + return Pair(0u, static_cast(0)); case 'r': return Pair(0U, ARM::GPRRegisterClass); case 'w': diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 77414108aae..76eb496bde4 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -228,6 +228,9 @@ def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> { // the general GPR register class above (MOV, e.g.) def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)>; +// The high registers in thumb mode, R8-R15. +def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)>; + // For tail calls, we can't use callee-saved registers, as they are restored // to the saved value before the tail call, which would clobber a call address. // Note, getMinimalPhysRegClass(R0) returns tGPR because of the names of diff --git a/test/CodeGen/Thumb/inlineasm-thumb.ll b/test/CodeGen/Thumb/inlineasm-thumb.ll new file mode 100644 index 00000000000..f2683c8dd8c --- /dev/null +++ b/test/CodeGen/Thumb/inlineasm-thumb.ll @@ -0,0 +1,7 @@ +; RUN: llc < %s -march=thumb | FileCheck %s +define i32 @t1(i32 %x, i32 %y) nounwind { +entry: + ; CHECK: mov r0, r12 + %0 = tail call i32 asm "mov $0, $1", "=l,h"(i32 %y) nounwind + ret i32 %0 +}