Index: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp @@ -3513,6 +3513,22 @@ return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint, VT); } + if (name.substr(0, 1).equals("f") && + !name.substr(1).getAsInteger(10, intVal) && intVal <= 63) { + std::string newConstraint; + + if (VT == MVT::f32) { + newConstraint = "{f" + utostr(intVal) + "}"; + } else if (VT == MVT::f64 && (intVal % 2 == 0)) { + newConstraint = "{d" + utostr(intVal / 2) + "}"; + } else if (VT == MVT::f128 && (intVal % 4 == 0)) { + newConstraint = "{q" + utostr(intVal / 4) + "}"; + } else { + return std::make_pair(0U, nullptr); + } + return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint, + VT); + } } return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); Index: llvm/trunk/test/CodeGen/SPARC/inlineasm-bad.ll =================================================================== --- llvm/trunk/test/CodeGen/SPARC/inlineasm-bad.ll +++ llvm/trunk/test/CodeGen/SPARC/inlineasm-bad.ll @@ -0,0 +1,13 @@ +; RUN: not llc -march=sparc <%s 2>&1 | FileCheck %s +; RUN: not llc -march=sparcv9 <%s 2>&1 | FileCheck %s + +; CHECK: error: couldn't allocate input reg for constraint '{f32}' +; CHECK: error: couldn't allocate input reg for constraint '{f21}' +; CHECK: error: couldn't allocate input reg for constraint '{f38}' +define void @test_constraint_float_reg() { +entry: + tail call void asm sideeffect "fadds $0,$1,$2", "{f32},{f0},{f0}"(float 6.0, float 7.0, float 8.0) + tail call void asm sideeffect "faddd $0,$1,$2", "{f21},{f0},{f0}"(double 9.0, double 10.0, double 11.0) + tail call void asm sideeffect "faddq $0,$1,$2", "{f38},{f0},{f0}"(fp128 0xL0, fp128 0xL0, fp128 0xL0) + ret void +} Index: llvm/trunk/test/CodeGen/SPARC/inlineasm-v9.ll =================================================================== --- llvm/trunk/test/CodeGen/SPARC/inlineasm-v9.ll +++ llvm/trunk/test/CodeGen/SPARC/inlineasm-v9.ll @@ -28,3 +28,14 @@ ret double %2 } +; CHECK-LABEL: test_constraint_float_reg: +; CHECK: fadds %f20, %f20, %f20 +; CHECK: faddd %f20, %f20, %f20 +; CHECK: faddq %f40, %f40, %f40 +define void @test_constraint_float_reg() { +entry: + tail call void asm sideeffect "fadds $0,$1,$2", "{f20},{f20},{f20}"(float 6.0, float 7.0, float 8.0) + tail call void asm sideeffect "faddd $0,$1,$2", "{f20},{f20},{f20}"(double 9.0, double 10.0, double 11.0) + tail call void asm sideeffect "faddq $0,$1,$2", "{f40},{f40},{f40}"(fp128 0xL0, fp128 0xL0, fp128 0xL0) + ret void +} Index: llvm/trunk/test/CodeGen/SPARC/inlineasm.ll =================================================================== --- llvm/trunk/test/CodeGen/SPARC/inlineasm.ll +++ llvm/trunk/test/CodeGen/SPARC/inlineasm.ll @@ -120,3 +120,13 @@ call void asm "std %l0, $0", "=*m,r"(i64* nonnull %out, i64 0) ret void } + +; CHECK-LABEL: test_constraint_float_reg: +; CHECK: fadds %f20, %f20, %f20 +; CHECK: faddd %f20, %f20, %f20 +define void @test_constraint_float_reg() { +entry: + tail call void asm sideeffect "fadds $0,$1,$2", "{f20},{f20},{f20}"(float 6.0, float 7.0, float 8.0) + tail call void asm sideeffect "faddd $0,$1,$2", "{f20},{f20},{f20}"(double 9.0, double 10.0, double 11.0) + ret void +}