1*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mipsel -mcpu=mips32 -mattr=+fp64,+msa,-nooddspreg \ 2*9880d681SAndroid Build Coastguard Worker; RUN: -no-integrated-as -relocation-model=pic < %s | \ 3*9880d681SAndroid Build Coastguard Worker; RUN: FileCheck %s -check-prefixes=ALL,ODDSPREG 4*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mipsel -mcpu=mips32 -mattr=+fp64,+msa,+nooddspreg \ 5*9880d681SAndroid Build Coastguard Worker; RUN: -no-integrated-as -relocation-model=pic < %s | \ 6*9880d681SAndroid Build Coastguard Worker; RUN: FileCheck %s -check-prefixes=ALL,NOODDSPREG 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker@v4f32 = global <4 x float> zeroinitializer 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workerdefine void @msa_insert_0(float %a) { 11*9880d681SAndroid Build Coastguard Workerentry: 12*9880d681SAndroid Build Coastguard Worker ; Force the float into an odd-numbered register using named registers and 13*9880d681SAndroid Build Coastguard Worker ; load the vector. 14*9880d681SAndroid Build Coastguard Worker %b = call float asm sideeffect "mov.s $0, $1", "={$f13},{$f12}" (float %a) 15*9880d681SAndroid Build Coastguard Worker %0 = load volatile <4 x float>, <4 x float>* @v4f32 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker ; Clobber all except $f12/$w12 and $f13 18*9880d681SAndroid Build Coastguard Worker ; 19*9880d681SAndroid Build Coastguard Worker ; The intention is that if odd single precision registers are permitted, the 20*9880d681SAndroid Build Coastguard Worker ; allocator will choose $f12/$w12 for the vector and $f13 for the float to 21*9880d681SAndroid Build Coastguard Worker ; avoid the spill/reload. 22*9880d681SAndroid Build Coastguard Worker ; 23*9880d681SAndroid Build Coastguard Worker ; On the other hand, if odd single precision registers are not permitted, it 24*9880d681SAndroid Build Coastguard Worker ; must copy $f13 to an even-numbered register before inserting into the 25*9880d681SAndroid Build Coastguard Worker ; vector. 26*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "teqi $$zero, 1", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() 27*9880d681SAndroid Build Coastguard Worker %1 = insertelement <4 x float> %0, float %b, i32 0 28*9880d681SAndroid Build Coastguard Worker store <4 x float> %1, <4 x float>* @v4f32 29*9880d681SAndroid Build Coastguard Worker ret void 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: msa_insert_0: 33*9880d681SAndroid Build Coastguard Worker; ALL: mov.s $f13, $f12 34*9880d681SAndroid Build Coastguard Worker; ALL: lw $[[R0:[0-9]+]], %got(v4f32)( 35*9880d681SAndroid Build Coastguard Worker; ALL: ld.w $w[[W0:[0-9]+]], 0($[[R0]]) 36*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: mov.s $f[[F0:[0-9]+]], $f13 37*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: insve.w $w[[W0]][0], $w[[F0]][0] 38*9880d681SAndroid Build Coastguard Worker; ODDSPREG: insve.w $w[[W0]][0], $w13[0] 39*9880d681SAndroid Build Coastguard Worker; ALL: teqi $zero, 1 40*9880d681SAndroid Build Coastguard Worker; ALL-NOT: sdc1 41*9880d681SAndroid Build Coastguard Worker; ALL-NOT: ldc1 42*9880d681SAndroid Build Coastguard Worker; ALL: st.w $w[[W0]], 0($[[R0]]) 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Workerdefine void @msa_insert_1(float %a) { 45*9880d681SAndroid Build Coastguard Workerentry: 46*9880d681SAndroid Build Coastguard Worker ; Force the float into an odd-numbered register using named registers and 47*9880d681SAndroid Build Coastguard Worker ; load the vector. 48*9880d681SAndroid Build Coastguard Worker %b = call float asm sideeffect "mov.s $0, $1", "={$f13},{$f12}" (float %a) 49*9880d681SAndroid Build Coastguard Worker %0 = load volatile <4 x float>, <4 x float>* @v4f32 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker ; Clobber all except $f12/$w12 and $f13 52*9880d681SAndroid Build Coastguard Worker ; 53*9880d681SAndroid Build Coastguard Worker ; The intention is that if odd single precision registers are permitted, the 54*9880d681SAndroid Build Coastguard Worker ; allocator will choose $f12/$w12 for the vector and $f13 for the float to 55*9880d681SAndroid Build Coastguard Worker ; avoid the spill/reload. 56*9880d681SAndroid Build Coastguard Worker ; 57*9880d681SAndroid Build Coastguard Worker ; On the other hand, if odd single precision registers are not permitted, it 58*9880d681SAndroid Build Coastguard Worker ; must copy $f13 to an even-numbered register before inserting into the 59*9880d681SAndroid Build Coastguard Worker ; vector. 60*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "teqi $$zero, 1", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() 61*9880d681SAndroid Build Coastguard Worker %1 = insertelement <4 x float> %0, float %b, i32 1 62*9880d681SAndroid Build Coastguard Worker store <4 x float> %1, <4 x float>* @v4f32 63*9880d681SAndroid Build Coastguard Worker ret void 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: msa_insert_1: 67*9880d681SAndroid Build Coastguard Worker; ALL: mov.s $f13, $f12 68*9880d681SAndroid Build Coastguard Worker; ALL: lw $[[R0:[0-9]+]], %got(v4f32)( 69*9880d681SAndroid Build Coastguard Worker; ALL: ld.w $w[[W0:[0-9]+]], 0($[[R0]]) 70*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: mov.s $f[[F0:[0-9]+]], $f13 71*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: insve.w $w[[W0]][1], $w[[F0]][0] 72*9880d681SAndroid Build Coastguard Worker; ODDSPREG: insve.w $w[[W0]][1], $w13[0] 73*9880d681SAndroid Build Coastguard Worker; ALL: teqi $zero, 1 74*9880d681SAndroid Build Coastguard Worker; ALL-NOT: sdc1 75*9880d681SAndroid Build Coastguard Worker; ALL-NOT: ldc1 76*9880d681SAndroid Build Coastguard Worker; ALL: st.w $w[[W0]], 0($[[R0]]) 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerdefine float @msa_extract_0() { 79*9880d681SAndroid Build Coastguard Workerentry: 80*9880d681SAndroid Build Coastguard Worker %0 = load volatile <4 x float>, <4 x float>* @v4f32 81*9880d681SAndroid Build Coastguard Worker %1 = call <4 x float> asm sideeffect "move.v $0, $1", "={$w13},{$w12}" (<4 x float> %0) 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker ; Clobber all except $f12, and $f13 84*9880d681SAndroid Build Coastguard Worker ; 85*9880d681SAndroid Build Coastguard Worker ; The intention is that if odd single precision registers are permitted, the 86*9880d681SAndroid Build Coastguard Worker ; allocator will choose $f13/$w13 for the vector since that saves on moves. 87*9880d681SAndroid Build Coastguard Worker ; 88*9880d681SAndroid Build Coastguard Worker ; On the other hand, if odd single precision registers are not permitted, it 89*9880d681SAndroid Build Coastguard Worker ; must move it to $f12/$w12. 90*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "teqi $$zero, 1", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker %2 = extractelement <4 x float> %1, i32 0 93*9880d681SAndroid Build Coastguard Worker ret float %2 94*9880d681SAndroid Build Coastguard Worker} 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: msa_extract_0: 97*9880d681SAndroid Build Coastguard Worker; ALL: lw $[[R0:[0-9]+]], %got(v4f32)( 98*9880d681SAndroid Build Coastguard Worker; ALL: ld.w $w12, 0($[[R0]]) 99*9880d681SAndroid Build Coastguard Worker; ALL: move.v $w[[W0:13]], $w12 100*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: move.v $w[[W0:12]], $w13 101*9880d681SAndroid Build Coastguard Worker; ALL: teqi $zero, 1 102*9880d681SAndroid Build Coastguard Worker; ALL-NOT: st.w 103*9880d681SAndroid Build Coastguard Worker; ALL-NOT: ld.w 104*9880d681SAndroid Build Coastguard Worker; ALL: mov.s $f0, $f[[W0]] 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Workerdefine float @msa_extract_1() { 107*9880d681SAndroid Build Coastguard Workerentry: 108*9880d681SAndroid Build Coastguard Worker %0 = load volatile <4 x float>, <4 x float>* @v4f32 109*9880d681SAndroid Build Coastguard Worker %1 = call <4 x float> asm sideeffect "move.v $0, $1", "={$w13},{$w12}" (<4 x float> %0) 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker ; Clobber all except $f13 112*9880d681SAndroid Build Coastguard Worker ; 113*9880d681SAndroid Build Coastguard Worker ; The intention is that if odd single precision registers are permitted, the 114*9880d681SAndroid Build Coastguard Worker ; allocator will choose $f13/$w13 for the vector since that saves on moves. 115*9880d681SAndroid Build Coastguard Worker ; 116*9880d681SAndroid Build Coastguard Worker ; On the other hand, if odd single precision registers are not permitted, it 117*9880d681SAndroid Build Coastguard Worker ; must be spilled. 118*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "teqi $$zero, 1", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f12},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker %2 = extractelement <4 x float> %1, i32 1 121*9880d681SAndroid Build Coastguard Worker ret float %2 122*9880d681SAndroid Build Coastguard Worker} 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: msa_extract_1: 125*9880d681SAndroid Build Coastguard Worker; ALL: lw $[[R0:[0-9]+]], %got(v4f32)( 126*9880d681SAndroid Build Coastguard Worker; ALL: ld.w $w12, 0($[[R0]]) 127*9880d681SAndroid Build Coastguard Worker; ALL: splati.w $w[[W0:[0-9]+]], $w13[1] 128*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: st.w $w[[W0]], 0($sp) 129*9880d681SAndroid Build Coastguard Worker; ODDSPREG-NOT: st.w 130*9880d681SAndroid Build Coastguard Worker; ODDSPREG-NOT: ld.w 131*9880d681SAndroid Build Coastguard Worker; ALL: teqi $zero, 1 132*9880d681SAndroid Build Coastguard Worker; ODDSPREG-NOT: st.w 133*9880d681SAndroid Build Coastguard Worker; ODDSPREG-NOT: ld.w 134*9880d681SAndroid Build Coastguard Worker; NOODDSPREG: ld.w $w0, 0($sp) 135*9880d681SAndroid Build Coastguard Worker; ODDSPREG: mov.s $f0, $f[[W0]] 136