• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Test that the FP64A ABI performs double precision moves via a spill/reload.
2; The requirement is really that odd-numbered double precision registers do not
3; use mfc1/mtc1 to move the bottom 32-bits (because the hardware will redirect
4; this to the top 32-bits of the even register) but we have to make the decision
5; before register allocation so we do this for all double-precision values.
6
7; We don't test MIPS32r1 since support for 64-bit coprocessors (such as a 64-bit
8; FPU) on a 32-bit architecture was added in MIPS32r2.
9
10; RUN: not --crash llc -march=mips -mcpu=mips32 -mattr=fp64 < %s 2>&1 | FileCheck %s -check-prefix=32R1-FP64
11; RUN: llc -march=mips -mcpu=mips32r2 -mattr=fp64 < %s | FileCheck %s -check-prefixes=ALL,32R2-NO-FP64A-BE
12; RUN: llc -march=mips -mcpu=mips32r2 -mattr=fp64,nooddspreg < %s | FileCheck %s -check-prefixes=ALL,32R2-FP64A
13; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=fp64 < %s | FileCheck %s -check-prefixes=ALL,32R2-NO-FP64A-LE
14; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=fp64,nooddspreg < %s | FileCheck %s -check-prefixes=ALL,32R2-FP64A
15
16; RUN: llc -march=mips64 -mcpu=mips64 -mattr=fp64 < %s | FileCheck %s -check-prefixes=ALL,64-NO-FP64A
17; RUN: not --crash llc -march=mips64 -mcpu=mips64 -mattr=fp64,nooddspreg < %s 2>&1 | FileCheck %s -check-prefix=64-FP64A
18; RUN: llc -march=mips64el -mcpu=mips64 -mattr=fp64 < %s | FileCheck %s -check-prefixes=ALL,64-NO-FP64A
19; RUN: not --crash llc -march=mips64el -mcpu=mips64 -mattr=fp64,nooddspreg < %s 2>&1 | FileCheck %s -check-prefix=64-FP64A
20
21; 32R1-FP64: LLVM ERROR: FPU with 64-bit registers is not available on MIPS32 pre revision 2. Use -mcpu=mips32r2 or greater.
22; 64-FP64A: LLVM ERROR: -mattr=+nooddspreg requires the O32 ABI.
23
24declare double @dbl();
25
26define double @call1(double %d, ...) {
27  ret double %d
28
29; ALL-LABEL:            call1:
30
31; 32R2-NO-FP64A-LE-NOT:     addiu   $sp, $sp
32; 32R2-NO-FP64A-LE:         mtc1    $4, $f0
33; 32R2-NO-FP64A-LE:         mthc1   $5, $f0
34
35; 32R2-NO-FP64A-BE-NOT:     addiu   $sp, $sp
36; 32R2-NO-FP64A-BE:         mtc1    $5, $f0
37; 32R2-NO-FP64A-BE:         mthc1   $4, $f0
38
39; 32R2-FP64A:               addiu   $sp, $sp, -8
40; 32R2-FP64A:               sw      $4, 0($sp)
41; 32R2-FP64A:               sw      $5, 4($sp)
42; 32R2-FP64A:               ldc1    $f0, 0($sp)
43
44; 64-NO-FP64A:              daddiu  $sp, $sp, -64
45; 64-NO-FP64A:              mov.d   $f0, $f12
46}
47
48define double @call2(i32 %i, double %d) {
49  ret double %d
50
51; ALL-LABEL:        call2:
52
53; 32R2-NO-FP64A-LE:     mtc1    $6, $f0
54; 32R2-NO-FP64A-LE:     mthc1   $7, $f0
55
56; 32R2-NO-FP64A-BE:     mtc1    $7, $f0
57; 32R2-NO-FP64A-BE:     mthc1   $6, $f0
58
59; 32R2-FP64A:           addiu   $sp, $sp, -8
60; 32R2-FP64A:           sw      $6, 0($sp)
61; 32R2-FP64A:           sw      $7, 4($sp)
62; 32R2-FP64A:           ldc1    $f0, 0($sp)
63
64; 64-NO-FP64A-NOT:      daddiu  $sp, $sp
65; 64-NO-FP64A:          mov.d   $f0, $f13
66}
67
68define double @call3(float %f1, float %f2, double %d) {
69  ret double %d
70
71; ALL-LABEL:        call3:
72
73; 32R2-NO-FP64A-LE:     mtc1    $6, $f0
74; 32R2-NO-FP64A-LE:     mthc1   $7, $f0
75
76; 32R2-NO-FP64A-BE:     mtc1    $7, $f0
77; 32R2-NO-FP64A-BE:     mthc1   $6, $f0
78
79; 32R2-FP64A:           addiu   $sp, $sp, -8
80; 32R2-FP64A:           sw      $6, 0($sp)
81; 32R2-FP64A:           sw      $7, 4($sp)
82; 32R2-FP64A:           ldc1    $f0, 0($sp)
83
84; 64-NO-FP64A-NOT:      daddiu  $sp, $sp
85; 64-NO-FP64A:          mov.d   $f0, $f14
86}
87
88define double @call4(float %f, double %d, ...) {
89  ret double %d
90
91; ALL-LABEL:        call4:
92
93; 32R2-NO-FP64A-LE:     mtc1    $6, $f0
94; 32R2-NO-FP64A-LE:     mthc1   $7, $f0
95
96; 32R2-NO-FP64A-BE:     mtc1    $7, $f0
97; 32R2-NO-FP64A-BE:     mthc1   $6, $f0
98
99; 32R2-FP64A:           addiu   $sp, $sp, -8
100; 32R2-FP64A:           sw      $6, 0($sp)
101; 32R2-FP64A:           sw      $7, 4($sp)
102; 32R2-FP64A:           ldc1    $f0, 0($sp)
103
104; 64-NO-FP64A:          daddiu  $sp, $sp, -48
105; 64-NO-FP64A:          mov.d   $f0, $f13
106}
107
108define double @call5(double %a, double %b, ...) {
109  %1 = fsub double %a, %b
110  ret double %1
111
112; ALL-LABEL:            call5:
113
114; 32R2-NO-FP64A-LE-DAG:     mtc1    $4, $[[T0:f[0-9]+]]
115; 32R2-NO-FP64A-LE-DAG:     mthc1   $5, $[[T0:f[0-9]+]]
116; 32R2-NO-FP64A-LE-DAG:     mtc1    $6, $[[T1:f[0-9]+]]
117; 32R2-NO-FP64A-LE-DAG:     mthc1   $7, $[[T1:f[0-9]+]]
118; 32R2-NO-FP64A-LE:         sub.d   $f0, $[[T0]], $[[T1]]
119
120; 32R2-NO-FP64A-BE-DAG:     mtc1    $5, $[[T0:f[0-9]+]]
121; 32R2-NO-FP64A-BE-DAG:     mthc1   $4, $[[T0:f[0-9]+]]
122; 32R2-NO-FP64A-BE-DAG:     mtc1    $7, $[[T1:f[0-9]+]]
123; 32R2-NO-FP64A-BE-DAG:     mthc1   $6, $[[T1:f[0-9]+]]
124; 32R2-NO-FP64A-BE:         sub.d   $f0, $[[T0]], $[[T1]]
125
126; 32R2-FP64A:               addiu   $sp, $sp, -8
127; 32R2-FP64A:               sw      $6, 0($sp)
128; 32R2-FP64A:               sw      $7, 4($sp)
129; 32R2-FP64A:               ldc1    $[[T1:f[0-9]+]], 0($sp)
130; 32R2-FP64A:               sw      $4, 0($sp)
131; 32R2-FP64A:               sw      $5, 4($sp)
132; 32R2-FP64A:               ldc1    $[[T0:f[0-9]+]], 0($sp)
133; 32R2-FP64A:               sub.d   $f0, $[[T0]], $[[T1]]
134
135; 64-NO-FP64A:              sub.d   $f0, $f12, $f13
136}
137
138define double @move_from(double %d) {
139  %1 = call double @dbl()
140  %2 = call double @call2(i32 0, double %1)
141  ret double %2
142
143; ALL-LABEL:        move_from:
144
145; 32R2-NO-FP64A-LE-DAG: mfc1    $6, $f0
146; 32R2-NO-FP64A-LE-DAG: mfhc1   $7, $f0
147
148; 32R2-NO-FP64A-BE-DAG: mfc1    $7, $f0
149; 32R2-NO-FP64A-BE-DAG: mfhc1   $6, $f0
150
151; 32R2-FP64A:           addiu   $sp, $sp, -32
152; 32R2-FP64A:           sdc1    $f0, 16($sp)
153; 32R2-FP64A:           lw      $6, 16($sp)
154; FIXME: This store is redundant
155; 32R2-FP64A:           sdc1    $f0, 16($sp)
156; 32R2-FP64A:           lw      $7, 20($sp)
157
158; 64-NO-FP64A:          mov.d   $f13, $f0
159}
160