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