Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 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. |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 9 | |
Yuanfang Chen | 6e24c60 | 2020-01-15 17:46:18 -0800 | [diff] [blame] | 10 | ; RUN: not llc -march=mips -mcpu=mips32 -mattr=fp64 < %s 2>&1 | FileCheck %s -check-prefix=32R1-FP64 |
Daniel Sanders | 0d97270 | 2016-06-24 12:23:17 +0000 | [diff] [blame] | 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 |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 15 | |
Daniel Sanders | 0d97270 | 2016-06-24 12:23:17 +0000 | [diff] [blame] | 16 | ; RUN: llc -march=mips64 -mcpu=mips64 -mattr=fp64 < %s | FileCheck %s -check-prefixes=ALL,64-NO-FP64A |
Yuanfang Chen | 6e24c60 | 2020-01-15 17:46:18 -0800 | [diff] [blame] | 17 | ; RUN: not llc -march=mips64 -mcpu=mips64 -mattr=fp64,nooddspreg < %s 2>&1 | FileCheck %s -check-prefix=64-FP64A |
Daniel Sanders | 0d97270 | 2016-06-24 12:23:17 +0000 | [diff] [blame] | 18 | ; RUN: llc -march=mips64el -mcpu=mips64 -mattr=fp64 < %s | FileCheck %s -check-prefixes=ALL,64-NO-FP64A |
Yuanfang Chen | 6e24c60 | 2020-01-15 17:46:18 -0800 | [diff] [blame] | 19 | ; RUN: not llc -march=mips64el -mcpu=mips64 -mattr=fp64,nooddspreg < %s 2>&1 | FileCheck %s -check-prefix=64-FP64A |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 20 | |
Simon Atanasyan | e3892d8 | 2019-07-09 15:48:16 +0000 | [diff] [blame] | 21 | ; 32R1-FP64: LLVM ERROR: FPU with 64-bit registers is not available on MIPS32 pre revision 2. Use -mcpu=mips32r2 or greater. |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 22 | ; 64-FP64A: LLVM ERROR: -mattr=+nooddspreg requires the O32 ABI. |
| 23 | |
| 24 | declare double @dbl(); |
| 25 | |
| 26 | define 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 | |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 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) |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 43 | |
| 44 | ; 64-NO-FP64A: daddiu $sp, $sp, -64 |
| 45 | ; 64-NO-FP64A: mov.d $f0, $f12 |
| 46 | } |
| 47 | |
| 48 | define 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 | |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 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) |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 63 | |
| 64 | ; 64-NO-FP64A-NOT: daddiu $sp, $sp |
| 65 | ; 64-NO-FP64A: mov.d $f0, $f13 |
| 66 | } |
| 67 | |
| 68 | define 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 | |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 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) |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 83 | |
| 84 | ; 64-NO-FP64A-NOT: daddiu $sp, $sp |
| 85 | ; 64-NO-FP64A: mov.d $f0, $f14 |
| 86 | } |
| 87 | |
| 88 | define 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 | |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 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) |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 103 | |
| 104 | ; 64-NO-FP64A: daddiu $sp, $sp, -48 |
| 105 | ; 64-NO-FP64A: mov.d $f0, $f13 |
| 106 | } |
| 107 | |
| 108 | define 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 | |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 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]] |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 134 | |
| 135 | ; 64-NO-FP64A: sub.d $f0, $f12, $f13 |
| 136 | } |
| 137 | |
| 138 | define 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 | |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 151 | ; 32R2-FP64A: addiu $sp, $sp, -32 |
| 152 | ; 32R2-FP64A: sdc1 $f0, 16($sp) |
| 153 | ; 32R2-FP64A: lw $6, 16($sp) |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 154 | ; FIXME: This store is redundant |
Vasileios Kalintiris | 167c372 | 2014-10-16 15:41:51 +0000 | [diff] [blame] | 155 | ; 32R2-FP64A: sdc1 $f0, 16($sp) |
| 156 | ; 32R2-FP64A: lw $7, 20($sp) |
Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 157 | |
| 158 | ; 64-NO-FP64A: mov.d $f13, $f0 |
| 159 | } |