1 /* 2 * MIPS SIMD Architecture Module Instruction emulation helpers for QEMU. 3 * 4 * Copyright (c) 2014 Imagination Technologies 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "cpu.h" 22 #include "internal.h" 23 #include "fpu/softfloat.h" 24 #include "fpu_helper.h" 25 26 void msa_reset(CPUMIPSState *env) 27 { 28 if (!ase_msa_available(env)) { 29 return; 30 } 31 32 #ifdef CONFIG_USER_ONLY 33 /* MSA access enabled */ 34 env->CP0_Config5 |= 1 << CP0C5_MSAEn; 35 env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR); 36 #endif 37 38 /* 39 * MSA CSR: 40 * - non-signaling floating point exception mode off (NX bit is 0) 41 * - Cause, Enables, and Flags are all 0 42 * - round to nearest / ties to even (RM bits are 0) 43 */ 44 env->active_tc.msacsr = 0; 45 46 restore_msa_fp_status(env); 47 48 /* tininess detected after rounding.*/ 49 set_float_detect_tininess(float_tininess_after_rounding, 50 &env->active_tc.msa_fp_status); 51 /* 52 * MSACSR.FS detects tiny results to flush to zero before rounding 53 * (per "MIPS Architecture for Programmers Volume IV-j: The MIPS64 SIMD 54 * Architecture Module, Revision 1.1" section 3.5.4), even though it 55 * detects tininess after rounding for underflow purposes (section 3.4.2 56 * table 3.3). 57 */ 58 set_float_ftz_detection(float_ftz_before_rounding, 59 &env->active_tc.msa_fp_status); 60 61 /* 62 * According to MIPS specifications, if one of the two operands is 63 * a sNaN, a new qNaN has to be generated. This is done in 64 * floatXX_silence_nan(). For qNaN inputs the specifications 65 * says: "When possible, this QNaN result is one of the operand QNaN 66 * values." In practice it seems that most implementations choose 67 * the first operand if both operands are qNaN. In short this gives 68 * the following rules: 69 * 1. A if it is signaling 70 * 2. B if it is signaling 71 * 3. A (quiet) 72 * 4. B (quiet) 73 * A signaling NaN is always silenced before returning it. 74 */ 75 set_float_2nan_prop_rule(float_2nan_prop_s_ab, 76 &env->active_tc.msa_fp_status); 77 78 set_float_3nan_prop_rule(float_3nan_prop_s_cab, 79 &env->active_tc.msa_fp_status); 80 81 /* clear float_status exception flags */ 82 set_float_exception_flags(0, &env->active_tc.msa_fp_status); 83 84 /* clear float_status nan mode */ 85 set_default_nan_mode(0, &env->active_tc.msa_fp_status); 86 87 /* set proper signanling bit meaning ("1" means "quiet") */ 88 set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); 89 90 /* Inf * 0 + NaN returns the input NaN */ 91 set_float_infzeronan_rule(float_infzeronan_dnan_never, 92 &env->active_tc.msa_fp_status); 93 /* Default NaN: sign bit clear, frac msb set */ 94 set_float_default_nan_pattern(0b01000000, 95 &env->active_tc.msa_fp_status); 96 } 97