mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-31 15:53:42 +00:00
[SPARC] Support 'f' and 'e' inline asm constraints.
Based on patch by Patrick Boettcher and Chris Dewhurst. Differential Revision: https://reviews.llvm.org/D29116 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302911 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0ee4a484f7
commit
c5d0c88a98
@ -3673,6 +3673,9 @@ Sparc:
|
||||
|
||||
- ``I``: An immediate 13-bit signed integer.
|
||||
- ``r``: A 32-bit integer register.
|
||||
- ``f``: Any floating-point register on SparcV8, or a floating point
|
||||
register in the "low" half of the registers on SparcV9.
|
||||
- ``e``: Any floating point register. (Same as ``f`` on SparcV8.)
|
||||
|
||||
SystemZ:
|
||||
|
||||
|
@ -3384,7 +3384,10 @@ SparcTargetLowering::getConstraintType(StringRef Constraint) const {
|
||||
if (Constraint.size() == 1) {
|
||||
switch (Constraint[0]) {
|
||||
default: break;
|
||||
case 'r': return C_RegisterClass;
|
||||
case 'r':
|
||||
case 'f':
|
||||
case 'e':
|
||||
return C_RegisterClass;
|
||||
case 'I': // SIMM13
|
||||
return C_Other;
|
||||
}
|
||||
@ -3463,6 +3466,24 @@ SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
||||
return std::make_pair(0U, &SP::IntPairRegClass);
|
||||
else
|
||||
return std::make_pair(0U, &SP::IntRegsRegClass);
|
||||
case 'f':
|
||||
if (VT == MVT::f32)
|
||||
return std::make_pair(0U, &SP::FPRegsRegClass);
|
||||
else if (VT == MVT::f64)
|
||||
return std::make_pair(0U, &SP::LowDFPRegsRegClass);
|
||||
else if (VT == MVT::f128)
|
||||
return std::make_pair(0U, &SP::LowQFPRegsRegClass);
|
||||
llvm_unreachable("Unknown ValueType for f-register-type!");
|
||||
break;
|
||||
case 'e':
|
||||
if (VT == MVT::f32)
|
||||
return std::make_pair(0U, &SP::FPRegsRegClass);
|
||||
else if (VT == MVT::f64)
|
||||
return std::make_pair(0U, &SP::DFPRegsRegClass);
|
||||
else if (VT == MVT::f128)
|
||||
return std::make_pair(0U, &SP::QFPRegsRegClass);
|
||||
llvm_unreachable("Unknown ValueType for e-register-type!");
|
||||
break;
|
||||
}
|
||||
} else if (!Constraint.empty() && Constraint.size() <= 5
|
||||
&& Constraint[0] == '{' && *(Constraint.end()-1) == '}') {
|
||||
|
@ -346,11 +346,13 @@ def I64Regs : RegisterClass<"SP", [i64], 64, (add IntRegs)>;
|
||||
|
||||
// Floating point register classes.
|
||||
def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>;
|
||||
|
||||
def DFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 31)>;
|
||||
|
||||
def QFPRegs : RegisterClass<"SP", [f128], 128, (sequence "Q%u", 0, 15)>;
|
||||
|
||||
// The Low?FPRegs classes are used only for inline-asm constraints.
|
||||
def LowDFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 15)>;
|
||||
def LowQFPRegs : RegisterClass<"SP", [f128], 128, (sequence "Q%u", 0, 7)>;
|
||||
|
||||
// Floating point control register classes.
|
||||
def FCCRegs : RegisterClass<"SP", [i1], 1, (sequence "FCC%u", 0, 3)>;
|
||||
|
||||
|
30
test/CodeGen/SPARC/inlineasm-v9.ll
Normal file
30
test/CodeGen/SPARC/inlineasm-v9.ll
Normal file
@ -0,0 +1,30 @@
|
||||
; RUN: llc -march=sparcv9 <%s | FileCheck %s
|
||||
|
||||
;; Ensures that inline-asm accepts and uses 'f' and 'e' register constraints.
|
||||
; CHECK-LABEL: faddd:
|
||||
; CHECK: faddd %f0, %f2, %f0
|
||||
define double @faddd(double, double) local_unnamed_addr #2 {
|
||||
entry:
|
||||
%2 = tail call double asm sideeffect "faddd $1, $2, $0;", "=f,f,e"(double %0, double %1) #7
|
||||
ret double %2
|
||||
}
|
||||
|
||||
; CHECK-LABEL: faddq:
|
||||
; CHECK: faddq %f0, %f4, %f0
|
||||
define fp128 @faddq(fp128, fp128) local_unnamed_addr #2 {
|
||||
entry:
|
||||
%2 = tail call fp128 asm sideeffect "faddq $1, $2, $0;", "=f,f,e"(fp128 %0, fp128 %1) #7
|
||||
ret fp128 %2
|
||||
}
|
||||
|
||||
;; Ensure that 'e' can indeed go in the high area, and 'f' cannot.
|
||||
; CHECK-LABEL: faddd_high:
|
||||
; CHECK: fmovd %f2, %f32
|
||||
; CHECK: fmovd %f0, %f2
|
||||
; CHECK: faddd %f2, %f32, %f2
|
||||
define double @faddd_high(double, double) local_unnamed_addr #2 {
|
||||
entry:
|
||||
%2 = tail call double asm sideeffect "faddd $1, $2, $0;", "=f,f,e,~{d0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7}"(double %0, double %1) #7
|
||||
ret double %2
|
||||
}
|
||||
|
@ -94,3 +94,21 @@ entry:
|
||||
%0 = call i64 asm sideeffect "xor $1, %g0, $0", "=r,0,~{i1}"(i64 5);
|
||||
ret i64 %0
|
||||
}
|
||||
|
||||
|
||||
;; Ensures that inline-asm accepts and uses 'f' and 'e' register constraints.
|
||||
; CHECK-LABEL: fadds:
|
||||
; CHECK: fadds %f0, %f1, %f0
|
||||
define float @fadds(float, float) local_unnamed_addr #2 {
|
||||
entry:
|
||||
%2 = tail call float asm sideeffect "fadds $1, $2, $0;", "=f,f,e"(float %0, float %1) #7
|
||||
ret float %2
|
||||
}
|
||||
|
||||
; CHECK-LABEL: faddd:
|
||||
; CHECK: faddd %f0, %f2, %f0
|
||||
define double @faddd(double, double) local_unnamed_addr #2 {
|
||||
entry:
|
||||
%2 = tail call double asm sideeffect "faddd $1, $2, $0;", "=f,f,e"(double %0, double %1) #7
|
||||
ret double %2
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user