target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions.
This adds support for the ARMv8 floating point VMAXNM and VMINNM instructions. Signed-off-by: Will Newton <will.newton@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1386158099-9239-6-git-send-email-will.newton@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									e17ab310e9
								
							
						
					
					
						commit
						40cfacdd80
					
				@ -4085,3 +4085,28 @@ float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp)
 | 
				
			|||||||
    float_status *fpst = fpstp;
 | 
					    float_status *fpst = fpstp;
 | 
				
			||||||
    return float64_muladd(a, b, c, 0, fpst);
 | 
					    return float64_muladd(a, b, c, 0, fpst);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ARMv8 VMAXNM/VMINNM */
 | 
				
			||||||
 | 
					float32 VFP_HELPER(maxnm, s)(float32 a, float32 b, void *fpstp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *fpst = fpstp;
 | 
				
			||||||
 | 
					    return float32_maxnum(a, b, fpst);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(maxnm, d)(float64 a, float64 b, void *fpstp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *fpst = fpstp;
 | 
				
			||||||
 | 
					    return float64_maxnum(a, b, fpst);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(minnm, s)(float32 a, float32 b, void *fpstp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *fpst = fpstp;
 | 
				
			||||||
 | 
					    return float32_minnum(a, b, fpst);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(minnm, d)(float64 a, float64 b, void *fpstp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *fpst = fpstp;
 | 
				
			||||||
 | 
					    return float64_minnum(a, b, fpst);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -132,6 +132,11 @@ DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env)
 | 
				
			|||||||
DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
 | 
					DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
 | 
				
			||||||
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
 | 
					DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_3(vfp_maxnmd, f64, f64, f64, ptr)
 | 
				
			||||||
 | 
					DEF_HELPER_3(vfp_maxnms, f32, f32, f32, ptr)
 | 
				
			||||||
 | 
					DEF_HELPER_3(vfp_minnmd, f64, f64, f64, ptr)
 | 
				
			||||||
 | 
					DEF_HELPER_3(vfp_minnms, f32, f32, f32, ptr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_3(recps_f32, f32, f32, f32, env)
 | 
					DEF_HELPER_3(recps_f32, f32, f32, f32, env)
 | 
				
			||||||
DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
 | 
					DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
 | 
				
			||||||
DEF_HELPER_2(recpe_f32, f32, f32, env)
 | 
					DEF_HELPER_2(recpe_f32, f32, f32, env)
 | 
				
			||||||
 | 
				
			|||||||
@ -2723,6 +2723,54 @@ static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
 | 
				
			||||||
 | 
					                            uint32_t rm, uint32_t dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t vmin = extract32(insn, 6, 1);
 | 
				
			||||||
 | 
					    TCGv_ptr fpst = get_fpstatus_ptr(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dp) {
 | 
				
			||||||
 | 
					        TCGv_i64 frn, frm, dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        frn = tcg_temp_new_i64();
 | 
				
			||||||
 | 
					        frm = tcg_temp_new_i64();
 | 
				
			||||||
 | 
					        dest = tcg_temp_new_i64();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
 | 
				
			||||||
 | 
					        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
 | 
				
			||||||
 | 
					        if (vmin) {
 | 
				
			||||||
 | 
					            gen_helper_vfp_minnmd(dest, frn, frm, fpst);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(frn);
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(frm);
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(dest);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        TCGv_i32 frn, frm, dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        frn = tcg_temp_new_i32();
 | 
				
			||||||
 | 
					        frm = tcg_temp_new_i32();
 | 
				
			||||||
 | 
					        dest = tcg_temp_new_i32();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
 | 
				
			||||||
 | 
					        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
 | 
				
			||||||
 | 
					        if (vmin) {
 | 
				
			||||||
 | 
					            gen_helper_vfp_minnms(dest, frn, frm, fpst);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            gen_helper_vfp_maxnms(dest, frn, frm, fpst);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
 | 
				
			||||||
 | 
					        tcg_temp_free_i32(frn);
 | 
				
			||||||
 | 
					        tcg_temp_free_i32(frm);
 | 
				
			||||||
 | 
					        tcg_temp_free_i32(dest);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tcg_temp_free_ptr(fpst);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 | 
					static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
 | 
					    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
 | 
				
			||||||
@ -2743,6 +2791,8 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if ((insn & 0x0f800e50) == 0x0e000a00) {
 | 
					    if ((insn & 0x0f800e50) == 0x0e000a00) {
 | 
				
			||||||
        return handle_vsel(insn, rd, rn, rm, dp);
 | 
					        return handle_vsel(insn, rd, rn, rm, dp);
 | 
				
			||||||
 | 
					    } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
 | 
				
			||||||
 | 
					        return handle_vminmaxnm(insn, rd, rn, rm, dp);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user