llvm.org GIT mirror llvm / c5d0c88
[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 James Y Knight 3 years ago
5 changed file(s) with 77 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
36723672
36733673 - ``I``: An immediate 13-bit signed integer.
36743674 - ``r``: A 32-bit integer register.
3675 - ``f``: Any floating-point register on SparcV8, or a floating point
3676 register in the "low" half of the registers on SparcV9.
3677 - ``e``: Any floating point register. (Same as ``f`` on SparcV8.)
36753678
36763679 SystemZ:
36773680
33833383 if (Constraint.size() == 1) {
33843384 switch (Constraint[0]) {
33853385 default: break;
3386 case 'r': return C_RegisterClass;
3386 case 'r':
3387 case 'f':
3388 case 'e':
3389 return C_RegisterClass;
33873390 case 'I': // SIMM13
33883391 return C_Other;
33893392 }
34623465 return std::make_pair(0U, &SP::IntPairRegClass);
34633466 else
34643467 return std::make_pair(0U, &SP::IntRegsRegClass);
3468 case 'f':
3469 if (VT == MVT::f32)
3470 return std::make_pair(0U, &SP::FPRegsRegClass);
3471 else if (VT == MVT::f64)
3472 return std::make_pair(0U, &SP::LowDFPRegsRegClass);
3473 else if (VT == MVT::f128)
3474 return std::make_pair(0U, &SP::LowQFPRegsRegClass);
3475 llvm_unreachable("Unknown ValueType for f-register-type!");
3476 break;
3477 case 'e':
3478 if (VT == MVT::f32)
3479 return std::make_pair(0U, &SP::FPRegsRegClass);
3480 else if (VT == MVT::f64)
3481 return std::make_pair(0U, &SP::DFPRegsRegClass);
3482 else if (VT == MVT::f128)
3483 return std::make_pair(0U, &SP::QFPRegsRegClass);
3484 llvm_unreachable("Unknown ValueType for e-register-type!");
3485 break;
34653486 }
34663487 } else if (!Constraint.empty() && Constraint.size() <= 5
34673488 && Constraint[0] == '{' && *(Constraint.end()-1) == '}') {
345345
346346 // Floating point register classes.
347347 def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>;
348
349348 def DFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 31)>;
350
351349 def QFPRegs : RegisterClass<"SP", [f128], 128, (sequence "Q%u", 0, 15)>;
350
351 // The Low?FPRegs classes are used only for inline-asm constraints.
352 def LowDFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 15)>;
353 def LowQFPRegs : RegisterClass<"SP", [f128], 128, (sequence "Q%u", 0, 7)>;
352354
353355 // Floating point control register classes.
354356 def FCCRegs : RegisterClass<"SP", [i1], 1, (sequence "FCC%u", 0, 3)>;
0 ; RUN: llc -march=sparcv9 <%s | FileCheck %s
1
2 ;; Ensures that inline-asm accepts and uses 'f' and 'e' register constraints.
3 ; CHECK-LABEL: faddd:
4 ; CHECK: faddd %f0, %f2, %f0
5 define double @faddd(double, double) local_unnamed_addr #2 {
6 entry:
7 %2 = tail call double asm sideeffect "faddd $1, $2, $0;", "=f,f,e"(double %0, double %1) #7
8 ret double %2
9 }
10
11 ; CHECK-LABEL: faddq:
12 ; CHECK: faddq %f0, %f4, %f0
13 define fp128 @faddq(fp128, fp128) local_unnamed_addr #2 {
14 entry:
15 %2 = tail call fp128 asm sideeffect "faddq $1, $2, $0;", "=f,f,e"(fp128 %0, fp128 %1) #7
16 ret fp128 %2
17 }
18
19 ;; Ensure that 'e' can indeed go in the high area, and 'f' cannot.
20 ; CHECK-LABEL: faddd_high:
21 ; CHECK: fmovd %f2, %f32
22 ; CHECK: fmovd %f0, %f2
23 ; CHECK: faddd %f2, %f32, %f2
24 define double @faddd_high(double, double) local_unnamed_addr #2 {
25 entry:
26 %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
27 ret double %2
28 }
29
9393 %0 = call i64 asm sideeffect "xor $1, %g0, $0", "=r,0,~{i1}"(i64 5);
9494 ret i64 %0
9595 }
96
97
98 ;; Ensures that inline-asm accepts and uses 'f' and 'e' register constraints.
99 ; CHECK-LABEL: fadds:
100 ; CHECK: fadds %f0, %f1, %f0
101 define float @fadds(float, float) local_unnamed_addr #2 {
102 entry:
103 %2 = tail call float asm sideeffect "fadds $1, $2, $0;", "=f,f,e"(float %0, float %1) #7
104 ret float %2
105 }
106
107 ; CHECK-LABEL: faddd:
108 ; CHECK: faddd %f0, %f2, %f0
109 define double @faddd(double, double) local_unnamed_addr #2 {
110 entry:
111 %2 = tail call double asm sideeffect "faddd $1, $2, $0;", "=f,f,e"(double %0, double %1) #7
112 ret double %2
113 }