1b5ed786fSTaylor Simpson /*
2*6146060aSMatheus Tavares Bernardino * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
3b5ed786fSTaylor Simpson *
4b5ed786fSTaylor Simpson * This program is free software; you can redistribute it and/or modify
5b5ed786fSTaylor Simpson * it under the terms of the GNU General Public License as published by
6b5ed786fSTaylor Simpson * the Free Software Foundation; either version 2 of the License, or
7b5ed786fSTaylor Simpson * (at your option) any later version.
8b5ed786fSTaylor Simpson *
9b5ed786fSTaylor Simpson * This program is distributed in the hope that it will be useful,
10b5ed786fSTaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of
11b5ed786fSTaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12b5ed786fSTaylor Simpson * GNU General Public License for more details.
13b5ed786fSTaylor Simpson *
14b5ed786fSTaylor Simpson * You should have received a copy of the GNU General Public License
15b5ed786fSTaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>.
16b5ed786fSTaylor Simpson */
17b5ed786fSTaylor Simpson
18b5ed786fSTaylor Simpson #include "qemu/osdep.h"
1925fc9b79SPeter Maydell #include "qemu/log.h"
2025fc9b79SPeter Maydell #include "exec/exec-all.h"
214699a927STaylor Simpson #include "exec/cpu_ldst.h"
22b5ed786fSTaylor Simpson #include "exec/helper-proto.h"
23b5ed786fSTaylor Simpson #include "fpu/softfloat.h"
24b5ed786fSTaylor Simpson #include "cpu.h"
25b5ed786fSTaylor Simpson #include "internal.h"
26b5ed786fSTaylor Simpson #include "macros.h"
27b5ed786fSTaylor Simpson #include "arch.h"
28b5ed786fSTaylor Simpson #include "hex_arch_types.h"
29b5ed786fSTaylor Simpson #include "fma_emu.h"
3033e9ed11STaylor Simpson #include "mmvec/mmvec.h"
3133e9ed11STaylor Simpson #include "mmvec/macros.h"
327e8b3b39SPaolo Montesel #include "op_helper.h"
337b84fd04STaylor Simpson #include "translate.h"
34b5ed786fSTaylor Simpson
35b5ed786fSTaylor Simpson #define SF_BIAS 127
36b5ed786fSTaylor Simpson #define SF_MANTBITS 23
37b5ed786fSTaylor Simpson
38b5ed786fSTaylor Simpson /* Exceptions processing helpers */
hexagon_raise_exception_err(CPUHexagonState * env,uint32_t exception,uintptr_t pc)39e1b526f1SMatheus Tavares Bernardino G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
40b5ed786fSTaylor Simpson uint32_t exception,
41b5ed786fSTaylor Simpson uintptr_t pc)
42b5ed786fSTaylor Simpson {
437d9ab202STaylor Simpson CPUState *cs = env_cpu(env);
44b5ed786fSTaylor Simpson qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
45b5ed786fSTaylor Simpson cs->exception_index = exception;
46b5ed786fSTaylor Simpson cpu_loop_exit_restore(cs, pc);
47b5ed786fSTaylor Simpson }
48b5ed786fSTaylor Simpson
HELPER(raise_exception)498905770bSMarc-André Lureau G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp)
50b5ed786fSTaylor Simpson {
51e1b526f1SMatheus Tavares Bernardino hexagon_raise_exception_err(env, excp, 0);
52b5ed786fSTaylor Simpson }
53b5ed786fSTaylor Simpson
log_store32(CPUHexagonState * env,target_ulong addr,target_ulong val,int width,int slot)547e8b3b39SPaolo Montesel void log_store32(CPUHexagonState *env, target_ulong addr,
55b5ed786fSTaylor Simpson target_ulong val, int width, int slot)
56b5ed786fSTaylor Simpson {
57b5ed786fSTaylor Simpson HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx
58b5ed786fSTaylor Simpson ", %" PRId32 " [0x08%" PRIx32 "])\n",
59b5ed786fSTaylor Simpson width, addr, val, val);
60b5ed786fSTaylor Simpson env->mem_log_stores[slot].va = addr;
61b5ed786fSTaylor Simpson env->mem_log_stores[slot].width = width;
62b5ed786fSTaylor Simpson env->mem_log_stores[slot].data32 = val;
63b5ed786fSTaylor Simpson }
64b5ed786fSTaylor Simpson
log_store64(CPUHexagonState * env,target_ulong addr,int64_t val,int width,int slot)657e8b3b39SPaolo Montesel void log_store64(CPUHexagonState *env, target_ulong addr,
66b5ed786fSTaylor Simpson int64_t val, int width, int slot)
67b5ed786fSTaylor Simpson {
68b5ed786fSTaylor Simpson HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx
69b5ed786fSTaylor Simpson ", %" PRId64 " [0x016%" PRIx64 "])\n",
70b5ed786fSTaylor Simpson width, addr, val, val);
71b5ed786fSTaylor Simpson env->mem_log_stores[slot].va = addr;
72b5ed786fSTaylor Simpson env->mem_log_stores[slot].width = width;
73b5ed786fSTaylor Simpson env->mem_log_stores[slot].data64 = val;
74b5ed786fSTaylor Simpson }
75b5ed786fSTaylor Simpson
76b5ed786fSTaylor Simpson /* Handy place to set a breakpoint */
HELPER(debug_start_packet)77b5ed786fSTaylor Simpson void HELPER(debug_start_packet)(CPUHexagonState *env)
78b5ed786fSTaylor Simpson {
79b5ed786fSTaylor Simpson HEX_DEBUG_LOG("Start packet: pc = 0x" TARGET_FMT_lx "\n",
80b5ed786fSTaylor Simpson env->gpr[HEX_REG_PC]);
81b5ed786fSTaylor Simpson
82b5ed786fSTaylor Simpson for (int i = 0; i < TOTAL_PER_THREAD_REGS; i++) {
83b5ed786fSTaylor Simpson env->reg_written[i] = 0;
84b5ed786fSTaylor Simpson }
85b5ed786fSTaylor Simpson }
86b5ed786fSTaylor Simpson
87b5ed786fSTaylor Simpson /* Checks for bookkeeping errors between disassembly context and runtime */
HELPER(debug_check_store_width)88b5ed786fSTaylor Simpson void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check)
89b5ed786fSTaylor Simpson {
90b5ed786fSTaylor Simpson if (env->mem_log_stores[slot].width != check) {
91b5ed786fSTaylor Simpson HEX_DEBUG_LOG("ERROR: %d != %d\n",
92b5ed786fSTaylor Simpson env->mem_log_stores[slot].width, check);
93b5ed786fSTaylor Simpson g_assert_not_reached();
94b5ed786fSTaylor Simpson }
95b5ed786fSTaylor Simpson }
96b5ed786fSTaylor Simpson
commit_store(CPUHexagonState * env,int slot_num,uintptr_t ra)973bd83593SMatheus Tavares Bernardino static void commit_store(CPUHexagonState *env, int slot_num, uintptr_t ra)
98b5ed786fSTaylor Simpson {
994699a927STaylor Simpson uint8_t width = env->mem_log_stores[slot_num].width;
1004699a927STaylor Simpson target_ulong va = env->mem_log_stores[slot_num].va;
1014699a927STaylor Simpson
1024699a927STaylor Simpson switch (width) {
103b5ed786fSTaylor Simpson case 1:
1044699a927STaylor Simpson cpu_stb_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
105b5ed786fSTaylor Simpson break;
106b5ed786fSTaylor Simpson case 2:
1074699a927STaylor Simpson cpu_stw_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
108b5ed786fSTaylor Simpson break;
109b5ed786fSTaylor Simpson case 4:
1104699a927STaylor Simpson cpu_stl_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
111b5ed786fSTaylor Simpson break;
112b5ed786fSTaylor Simpson case 8:
1134699a927STaylor Simpson cpu_stq_data_ra(env, va, env->mem_log_stores[slot_num].data64, ra);
114b5ed786fSTaylor Simpson break;
115b5ed786fSTaylor Simpson default:
116b5ed786fSTaylor Simpson g_assert_not_reached();
117b5ed786fSTaylor Simpson }
118b5ed786fSTaylor Simpson }
119b5ed786fSTaylor Simpson
HELPER(commit_store)1203bd83593SMatheus Tavares Bernardino void HELPER(commit_store)(CPUHexagonState *env, int slot_num)
1213bd83593SMatheus Tavares Bernardino {
1223bd83593SMatheus Tavares Bernardino uintptr_t ra = GETPC();
1233bd83593SMatheus Tavares Bernardino commit_store(env, slot_num, ra);
1243bd83593SMatheus Tavares Bernardino }
1253bd83593SMatheus Tavares Bernardino
HELPER(gather_store)12633e9ed11STaylor Simpson void HELPER(gather_store)(CPUHexagonState *env, uint32_t addr, int slot)
12733e9ed11STaylor Simpson {
12833e9ed11STaylor Simpson mem_gather_store(env, addr, slot);
12933e9ed11STaylor Simpson }
13033e9ed11STaylor Simpson
HELPER(commit_hvx_stores)13133e9ed11STaylor Simpson void HELPER(commit_hvx_stores)(CPUHexagonState *env)
13233e9ed11STaylor Simpson {
13333e9ed11STaylor Simpson uintptr_t ra = GETPC();
13433e9ed11STaylor Simpson
13533e9ed11STaylor Simpson /* Normal (possibly masked) vector store */
13620c34a92SBrian Cain for (int i = 0; i < VSTORES_MAX; i++) {
13733e9ed11STaylor Simpson if (env->vstore_pending[i]) {
13833e9ed11STaylor Simpson env->vstore_pending[i] = 0;
13933e9ed11STaylor Simpson target_ulong va = env->vstore[i].va;
14033e9ed11STaylor Simpson int size = env->vstore[i].size;
14133e9ed11STaylor Simpson for (int j = 0; j < size; j++) {
14233e9ed11STaylor Simpson if (test_bit(j, env->vstore[i].mask)) {
14333e9ed11STaylor Simpson cpu_stb_data_ra(env, va + j, env->vstore[i].data.ub[j], ra);
14433e9ed11STaylor Simpson }
14533e9ed11STaylor Simpson }
14633e9ed11STaylor Simpson }
14733e9ed11STaylor Simpson }
14833e9ed11STaylor Simpson
14933e9ed11STaylor Simpson /* Scatter store */
15033e9ed11STaylor Simpson if (env->vtcm_pending) {
15133e9ed11STaylor Simpson env->vtcm_pending = false;
15233e9ed11STaylor Simpson if (env->vtcm_log.op) {
15333e9ed11STaylor Simpson /* Need to perform the scatter read/modify/write at commit time */
15433e9ed11STaylor Simpson if (env->vtcm_log.op_size == 2) {
15533e9ed11STaylor Simpson SCATTER_OP_WRITE_TO_MEM(uint16_t);
15633e9ed11STaylor Simpson } else if (env->vtcm_log.op_size == 4) {
15733e9ed11STaylor Simpson /* Word Scatter += */
15833e9ed11STaylor Simpson SCATTER_OP_WRITE_TO_MEM(uint32_t);
15933e9ed11STaylor Simpson } else {
16033e9ed11STaylor Simpson g_assert_not_reached();
16133e9ed11STaylor Simpson }
16233e9ed11STaylor Simpson } else {
16320c34a92SBrian Cain for (int i = 0; i < sizeof(MMVector); i++) {
16433e9ed11STaylor Simpson if (test_bit(i, env->vtcm_log.mask)) {
16533e9ed11STaylor Simpson cpu_stb_data_ra(env, env->vtcm_log.va[i],
16633e9ed11STaylor Simpson env->vtcm_log.data.ub[i], ra);
16733e9ed11STaylor Simpson clear_bit(i, env->vtcm_log.mask);
16833e9ed11STaylor Simpson env->vtcm_log.data.ub[i] = 0;
16933e9ed11STaylor Simpson }
17033e9ed11STaylor Simpson
17133e9ed11STaylor Simpson }
17233e9ed11STaylor Simpson }
17333e9ed11STaylor Simpson }
17433e9ed11STaylor Simpson }
17533e9ed11STaylor Simpson
print_store(CPUHexagonState * env,int slot)176b5ed786fSTaylor Simpson static void print_store(CPUHexagonState *env, int slot)
177b5ed786fSTaylor Simpson {
178b5ed786fSTaylor Simpson if (!(env->slot_cancelled & (1 << slot))) {
179b5ed786fSTaylor Simpson uint8_t width = env->mem_log_stores[slot].width;
180b5ed786fSTaylor Simpson if (width == 1) {
181b5ed786fSTaylor Simpson uint32_t data = env->mem_log_stores[slot].data32 & 0xff;
182b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tmemb[0x" TARGET_FMT_lx "] = %" PRId32
183b5ed786fSTaylor Simpson " (0x%02" PRIx32 ")\n",
184b5ed786fSTaylor Simpson env->mem_log_stores[slot].va, data, data);
185b5ed786fSTaylor Simpson } else if (width == 2) {
186b5ed786fSTaylor Simpson uint32_t data = env->mem_log_stores[slot].data32 & 0xffff;
187b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tmemh[0x" TARGET_FMT_lx "] = %" PRId32
188b5ed786fSTaylor Simpson " (0x%04" PRIx32 ")\n",
189b5ed786fSTaylor Simpson env->mem_log_stores[slot].va, data, data);
190b5ed786fSTaylor Simpson } else if (width == 4) {
191b5ed786fSTaylor Simpson uint32_t data = env->mem_log_stores[slot].data32;
192b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tmemw[0x" TARGET_FMT_lx "] = %" PRId32
193b5ed786fSTaylor Simpson " (0x%08" PRIx32 ")\n",
194b5ed786fSTaylor Simpson env->mem_log_stores[slot].va, data, data);
195b5ed786fSTaylor Simpson } else if (width == 8) {
196b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tmemd[0x" TARGET_FMT_lx "] = %" PRId64
197b5ed786fSTaylor Simpson " (0x%016" PRIx64 ")\n",
198b5ed786fSTaylor Simpson env->mem_log_stores[slot].va,
199b5ed786fSTaylor Simpson env->mem_log_stores[slot].data64,
200b5ed786fSTaylor Simpson env->mem_log_stores[slot].data64);
201b5ed786fSTaylor Simpson } else {
202b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tBad store width %d\n", width);
203b5ed786fSTaylor Simpson g_assert_not_reached();
204b5ed786fSTaylor Simpson }
205b5ed786fSTaylor Simpson }
206b5ed786fSTaylor Simpson }
207b5ed786fSTaylor Simpson
208b5ed786fSTaylor Simpson /* This function is a handy place to set a breakpoint */
HELPER(debug_commit_end)2090fc56c43STaylor Simpson void HELPER(debug_commit_end)(CPUHexagonState *env, uint32_t this_PC,
210842b206fSTaylor Simpson int pred_written, int has_st0, int has_st1)
211b5ed786fSTaylor Simpson {
212b5ed786fSTaylor Simpson bool reg_printed = false;
213b5ed786fSTaylor Simpson bool pred_printed = false;
214b5ed786fSTaylor Simpson int i;
215b5ed786fSTaylor Simpson
2160fc56c43STaylor Simpson HEX_DEBUG_LOG("Packet committed: pc = 0x" TARGET_FMT_lx "\n", this_PC);
217b5ed786fSTaylor Simpson HEX_DEBUG_LOG("slot_cancelled = %d\n", env->slot_cancelled);
218b5ed786fSTaylor Simpson
219b5ed786fSTaylor Simpson for (i = 0; i < TOTAL_PER_THREAD_REGS; i++) {
220b5ed786fSTaylor Simpson if (env->reg_written[i]) {
221b5ed786fSTaylor Simpson if (!reg_printed) {
222b5ed786fSTaylor Simpson HEX_DEBUG_LOG("Regs written\n");
223b5ed786fSTaylor Simpson reg_printed = true;
224b5ed786fSTaylor Simpson }
225b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tr%d = " TARGET_FMT_ld " (0x" TARGET_FMT_lx ")\n",
226d54c5615STaylor Simpson i, env->gpr[i], env->gpr[i]);
227b5ed786fSTaylor Simpson }
228b5ed786fSTaylor Simpson }
229b5ed786fSTaylor Simpson
230b5ed786fSTaylor Simpson for (i = 0; i < NUM_PREGS; i++) {
231842b206fSTaylor Simpson if (pred_written & (1 << i)) {
232b5ed786fSTaylor Simpson if (!pred_printed) {
233b5ed786fSTaylor Simpson HEX_DEBUG_LOG("Predicates written\n");
234b5ed786fSTaylor Simpson pred_printed = true;
235b5ed786fSTaylor Simpson }
236b5ed786fSTaylor Simpson HEX_DEBUG_LOG("\tp%d = 0x" TARGET_FMT_lx "\n",
237e22edc7cSTaylor Simpson i, env->pred[i]);
238b5ed786fSTaylor Simpson }
239b5ed786fSTaylor Simpson }
240b5ed786fSTaylor Simpson
241b5ed786fSTaylor Simpson if (has_st0 || has_st1) {
242b5ed786fSTaylor Simpson HEX_DEBUG_LOG("Stores\n");
243b5ed786fSTaylor Simpson if (has_st0) {
244b5ed786fSTaylor Simpson print_store(env, 0);
245b5ed786fSTaylor Simpson }
246b5ed786fSTaylor Simpson if (has_st1) {
247b5ed786fSTaylor Simpson print_store(env, 1);
248b5ed786fSTaylor Simpson }
249b5ed786fSTaylor Simpson }
250b5ed786fSTaylor Simpson
251613653e5STaylor Simpson HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->gpr[HEX_REG_PC]);
252b5ed786fSTaylor Simpson HEX_DEBUG_LOG("Exec counters: pkt = " TARGET_FMT_lx
253b5ed786fSTaylor Simpson ", insn = " TARGET_FMT_lx
25433e9ed11STaylor Simpson ", hvx = " TARGET_FMT_lx "\n",
255b5ed786fSTaylor Simpson env->gpr[HEX_REG_QEMU_PKT_CNT],
25633e9ed11STaylor Simpson env->gpr[HEX_REG_QEMU_INSN_CNT],
25733e9ed11STaylor Simpson env->gpr[HEX_REG_QEMU_HVX_CNT]);
258b5ed786fSTaylor Simpson
259b5ed786fSTaylor Simpson }
260b5ed786fSTaylor Simpson
HELPER(fcircadd)261b5ed786fSTaylor Simpson int32_t HELPER(fcircadd)(int32_t RxV, int32_t offset, int32_t M, int32_t CS)
262b5ed786fSTaylor Simpson {
26358ff2981SMichael Lambert uint32_t K_const = extract32(M, 24, 4);
26458ff2981SMichael Lambert uint32_t length = extract32(M, 0, 17);
265b5ed786fSTaylor Simpson uint32_t new_ptr = RxV + offset;
26646ef47e2STaylor Simpson uint32_t start_addr;
26746ef47e2STaylor Simpson uint32_t end_addr;
268b5ed786fSTaylor Simpson
269b5ed786fSTaylor Simpson if (K_const == 0 && length >= 4) {
27046ef47e2STaylor Simpson start_addr = CS;
27146ef47e2STaylor Simpson end_addr = start_addr + length;
27246ef47e2STaylor Simpson } else {
27346ef47e2STaylor Simpson /*
27446ef47e2STaylor Simpson * Versions v3 and earlier used the K value to specify a power-of-2 size
27546ef47e2STaylor Simpson * 2^(K+2) that is greater than the buffer length
27646ef47e2STaylor Simpson */
27746ef47e2STaylor Simpson int32_t mask = (1 << (K_const + 2)) - 1;
27846ef47e2STaylor Simpson start_addr = RxV & (~mask);
27946ef47e2STaylor Simpson end_addr = start_addr | length;
280b5ed786fSTaylor Simpson }
281b5ed786fSTaylor Simpson
282b5ed786fSTaylor Simpson if (new_ptr >= end_addr) {
283b5ed786fSTaylor Simpson new_ptr -= length;
284b5ed786fSTaylor Simpson } else if (new_ptr < start_addr) {
285b5ed786fSTaylor Simpson new_ptr += length;
286b5ed786fSTaylor Simpson }
287b5ed786fSTaylor Simpson
288b5ed786fSTaylor Simpson return new_ptr;
289b5ed786fSTaylor Simpson }
290b5ed786fSTaylor Simpson
HELPER(fbrev)291af7f1821STaylor Simpson uint32_t HELPER(fbrev)(uint32_t addr)
292af7f1821STaylor Simpson {
293af7f1821STaylor Simpson /*
294af7f1821STaylor Simpson * Bit reverse the low 16 bits of the address
295af7f1821STaylor Simpson */
296af7f1821STaylor Simpson return deposit32(addr, 0, 16, revbit16(addr));
297af7f1821STaylor Simpson }
298af7f1821STaylor Simpson
build_float32(uint8_t sign,uint32_t exp,uint32_t mant)299d934c16dSTaylor Simpson static float32 build_float32(uint8_t sign, uint32_t exp, uint32_t mant)
300d934c16dSTaylor Simpson {
301d934c16dSTaylor Simpson return make_float32(
302d934c16dSTaylor Simpson ((sign & 1) << 31) |
303d934c16dSTaylor Simpson ((exp & 0xff) << SF_MANTBITS) |
304d934c16dSTaylor Simpson (mant & ((1 << SF_MANTBITS) - 1)));
305d934c16dSTaylor Simpson }
306d934c16dSTaylor Simpson
307d934c16dSTaylor Simpson /*
308d934c16dSTaylor Simpson * sfrecipa, sfinvsqrta have two 32-bit results
309d934c16dSTaylor Simpson * r0,p0=sfrecipa(r1,r2)
310d934c16dSTaylor Simpson * r0,p0=sfinvsqrta(r1)
311d934c16dSTaylor Simpson *
312d934c16dSTaylor Simpson * Since helpers can only return a single value, we pack the two results
313d934c16dSTaylor Simpson * into a 64-bit value.
314d934c16dSTaylor Simpson */
HELPER(sfrecipa)315d934c16dSTaylor Simpson uint64_t HELPER(sfrecipa)(CPUHexagonState *env, float32 RsV, float32 RtV)
316d934c16dSTaylor Simpson {
317d934c16dSTaylor Simpson int32_t PeV = 0;
318d934c16dSTaylor Simpson float32 RdV;
319d934c16dSTaylor Simpson int idx;
320d934c16dSTaylor Simpson int adjust;
321d934c16dSTaylor Simpson int mant;
322d934c16dSTaylor Simpson int exp;
323d934c16dSTaylor Simpson
324d934c16dSTaylor Simpson arch_fpop_start(env);
325d934c16dSTaylor Simpson if (arch_sf_recip_common(&RsV, &RtV, &RdV, &adjust, &env->fp_status)) {
326d934c16dSTaylor Simpson PeV = adjust;
327d934c16dSTaylor Simpson idx = (RtV >> 16) & 0x7f;
328d934c16dSTaylor Simpson mant = (recip_lookup_table[idx] << 15) | 1;
329d934c16dSTaylor Simpson exp = SF_BIAS - (float32_getexp(RtV) - SF_BIAS) - 1;
330d934c16dSTaylor Simpson RdV = build_float32(extract32(RtV, 31, 1), exp, mant);
331d934c16dSTaylor Simpson }
332d934c16dSTaylor Simpson arch_fpop_end(env);
333d934c16dSTaylor Simpson return ((uint64_t)RdV << 32) | PeV;
334d934c16dSTaylor Simpson }
335d934c16dSTaylor Simpson
HELPER(sfinvsqrta)336dd8705bdSTaylor Simpson uint64_t HELPER(sfinvsqrta)(CPUHexagonState *env, float32 RsV)
337dd8705bdSTaylor Simpson {
338dd8705bdSTaylor Simpson int PeV = 0;
339dd8705bdSTaylor Simpson float32 RdV;
340dd8705bdSTaylor Simpson int idx;
341dd8705bdSTaylor Simpson int adjust;
342dd8705bdSTaylor Simpson int mant;
343dd8705bdSTaylor Simpson int exp;
344dd8705bdSTaylor Simpson
345dd8705bdSTaylor Simpson arch_fpop_start(env);
346dd8705bdSTaylor Simpson if (arch_sf_invsqrt_common(&RsV, &RdV, &adjust, &env->fp_status)) {
347dd8705bdSTaylor Simpson PeV = adjust;
348dd8705bdSTaylor Simpson idx = (RsV >> 17) & 0x7f;
349dd8705bdSTaylor Simpson mant = (invsqrt_lookup_table[idx] << 15);
350dd8705bdSTaylor Simpson exp = SF_BIAS - ((float32_getexp(RsV) - SF_BIAS) >> 1) - 1;
351dd8705bdSTaylor Simpson RdV = build_float32(extract32(RsV, 31, 1), exp, mant);
352dd8705bdSTaylor Simpson }
353dd8705bdSTaylor Simpson arch_fpop_end(env);
354dd8705bdSTaylor Simpson return ((uint64_t)RdV << 32) | PeV;
355dd8705bdSTaylor Simpson }
356dd8705bdSTaylor Simpson
HELPER(vacsh_val)357da74cd2dSTaylor Simpson int64_t HELPER(vacsh_val)(CPUHexagonState *env,
358d54c5615STaylor Simpson int64_t RxxV, int64_t RssV, int64_t RttV,
359d54c5615STaylor Simpson uint32_t pkt_need_commit)
360da74cd2dSTaylor Simpson {
361da74cd2dSTaylor Simpson for (int i = 0; i < 4; i++) {
362da74cd2dSTaylor Simpson int xv = sextract64(RxxV, i * 16, 16);
363da74cd2dSTaylor Simpson int sv = sextract64(RssV, i * 16, 16);
364da74cd2dSTaylor Simpson int tv = sextract64(RttV, i * 16, 16);
365da74cd2dSTaylor Simpson int max;
366da74cd2dSTaylor Simpson xv = xv + tv;
367da74cd2dSTaylor Simpson sv = sv - tv;
368da74cd2dSTaylor Simpson max = xv > sv ? xv : sv;
369da74cd2dSTaylor Simpson /* Note that fSATH can set the OVF bit in usr */
370da74cd2dSTaylor Simpson RxxV = deposit64(RxxV, i * 16, 16, fSATH(max));
371da74cd2dSTaylor Simpson }
372da74cd2dSTaylor Simpson return RxxV;
373da74cd2dSTaylor Simpson }
374da74cd2dSTaylor Simpson
HELPER(vacsh_pred)375da74cd2dSTaylor Simpson int32_t HELPER(vacsh_pred)(CPUHexagonState *env,
376da74cd2dSTaylor Simpson int64_t RxxV, int64_t RssV, int64_t RttV)
377da74cd2dSTaylor Simpson {
378da74cd2dSTaylor Simpson int32_t PeV = 0;
379da74cd2dSTaylor Simpson for (int i = 0; i < 4; i++) {
380da74cd2dSTaylor Simpson int xv = sextract64(RxxV, i * 16, 16);
381da74cd2dSTaylor Simpson int sv = sextract64(RssV, i * 16, 16);
382da74cd2dSTaylor Simpson int tv = sextract64(RttV, i * 16, 16);
383da74cd2dSTaylor Simpson xv = xv + tv;
384da74cd2dSTaylor Simpson sv = sv - tv;
385da74cd2dSTaylor Simpson PeV = deposit32(PeV, i * 2, 1, (xv > sv));
386da74cd2dSTaylor Simpson PeV = deposit32(PeV, i * 2 + 1, 1, (xv > sv));
387da74cd2dSTaylor Simpson }
388da74cd2dSTaylor Simpson return PeV;
389da74cd2dSTaylor Simpson }
390da74cd2dSTaylor Simpson
HELPER(cabacdecbin_val)391d24f0b2bSTaylor Simpson int64_t HELPER(cabacdecbin_val)(int64_t RssV, int64_t RttV)
392d24f0b2bSTaylor Simpson {
393d24f0b2bSTaylor Simpson int64_t RddV = 0;
394d24f0b2bSTaylor Simpson size4u_t state;
395d24f0b2bSTaylor Simpson size4u_t valMPS;
396d24f0b2bSTaylor Simpson size4u_t bitpos;
397d24f0b2bSTaylor Simpson size4u_t range;
398d24f0b2bSTaylor Simpson size4u_t offset;
399d24f0b2bSTaylor Simpson size4u_t rLPS;
400d24f0b2bSTaylor Simpson size4u_t rMPS;
401d24f0b2bSTaylor Simpson
402d24f0b2bSTaylor Simpson state = fEXTRACTU_RANGE(fGETWORD(1, RttV), 5, 0);
403d24f0b2bSTaylor Simpson valMPS = fEXTRACTU_RANGE(fGETWORD(1, RttV), 8, 8);
404d24f0b2bSTaylor Simpson bitpos = fEXTRACTU_RANGE(fGETWORD(0, RttV), 4, 0);
405d24f0b2bSTaylor Simpson range = fGETWORD(0, RssV);
406d24f0b2bSTaylor Simpson offset = fGETWORD(1, RssV);
407d24f0b2bSTaylor Simpson
408d24f0b2bSTaylor Simpson /* calculate rLPS */
409d24f0b2bSTaylor Simpson range <<= bitpos;
410d24f0b2bSTaylor Simpson offset <<= bitpos;
411d24f0b2bSTaylor Simpson rLPS = rLPS_table_64x4[state][(range >> 29) & 3];
412d24f0b2bSTaylor Simpson rLPS = rLPS << 23; /* left aligned */
413d24f0b2bSTaylor Simpson
414d24f0b2bSTaylor Simpson /* calculate rMPS */
415d24f0b2bSTaylor Simpson rMPS = (range & 0xff800000) - rLPS;
416d24f0b2bSTaylor Simpson
417d24f0b2bSTaylor Simpson /* most probable region */
418d24f0b2bSTaylor Simpson if (offset < rMPS) {
419d24f0b2bSTaylor Simpson RddV = AC_next_state_MPS_64[state];
420d24f0b2bSTaylor Simpson fINSERT_RANGE(RddV, 8, 8, valMPS);
421d24f0b2bSTaylor Simpson fINSERT_RANGE(RddV, 31, 23, (rMPS >> 23));
422d24f0b2bSTaylor Simpson fSETWORD(1, RddV, offset);
423d24f0b2bSTaylor Simpson }
424d24f0b2bSTaylor Simpson /* least probable region */
425d24f0b2bSTaylor Simpson else {
426d24f0b2bSTaylor Simpson RddV = AC_next_state_LPS_64[state];
427d24f0b2bSTaylor Simpson fINSERT_RANGE(RddV, 8, 8, ((!state) ? (1 - valMPS) : (valMPS)));
428d24f0b2bSTaylor Simpson fINSERT_RANGE(RddV, 31, 23, (rLPS >> 23));
429d24f0b2bSTaylor Simpson fSETWORD(1, RddV, (offset - rMPS));
430d24f0b2bSTaylor Simpson }
431d24f0b2bSTaylor Simpson return RddV;
432d24f0b2bSTaylor Simpson }
433d24f0b2bSTaylor Simpson
HELPER(cabacdecbin_pred)434d24f0b2bSTaylor Simpson int32_t HELPER(cabacdecbin_pred)(int64_t RssV, int64_t RttV)
435d24f0b2bSTaylor Simpson {
436d24f0b2bSTaylor Simpson int32_t p0 = 0;
437d24f0b2bSTaylor Simpson size4u_t state;
438d24f0b2bSTaylor Simpson size4u_t valMPS;
439d24f0b2bSTaylor Simpson size4u_t bitpos;
440d24f0b2bSTaylor Simpson size4u_t range;
441d24f0b2bSTaylor Simpson size4u_t offset;
442d24f0b2bSTaylor Simpson size4u_t rLPS;
443d24f0b2bSTaylor Simpson size4u_t rMPS;
444d24f0b2bSTaylor Simpson
445d24f0b2bSTaylor Simpson state = fEXTRACTU_RANGE(fGETWORD(1, RttV), 5, 0);
446d24f0b2bSTaylor Simpson valMPS = fEXTRACTU_RANGE(fGETWORD(1, RttV), 8, 8);
447d24f0b2bSTaylor Simpson bitpos = fEXTRACTU_RANGE(fGETWORD(0, RttV), 4, 0);
448d24f0b2bSTaylor Simpson range = fGETWORD(0, RssV);
449d24f0b2bSTaylor Simpson offset = fGETWORD(1, RssV);
450d24f0b2bSTaylor Simpson
451d24f0b2bSTaylor Simpson /* calculate rLPS */
452d24f0b2bSTaylor Simpson range <<= bitpos;
453d24f0b2bSTaylor Simpson offset <<= bitpos;
454d24f0b2bSTaylor Simpson rLPS = rLPS_table_64x4[state][(range >> 29) & 3];
455d24f0b2bSTaylor Simpson rLPS = rLPS << 23; /* left aligned */
456d24f0b2bSTaylor Simpson
457d24f0b2bSTaylor Simpson /* calculate rMPS */
458d24f0b2bSTaylor Simpson rMPS = (range & 0xff800000) - rLPS;
459d24f0b2bSTaylor Simpson
460d24f0b2bSTaylor Simpson /* most probable region */
461d24f0b2bSTaylor Simpson if (offset < rMPS) {
462d24f0b2bSTaylor Simpson p0 = valMPS;
463d24f0b2bSTaylor Simpson
464d24f0b2bSTaylor Simpson }
465d24f0b2bSTaylor Simpson /* least probable region */
466d24f0b2bSTaylor Simpson else {
467d24f0b2bSTaylor Simpson p0 = valMPS ^ 1;
468d24f0b2bSTaylor Simpson }
469d24f0b2bSTaylor Simpson return p0;
470d24f0b2bSTaylor Simpson }
471d24f0b2bSTaylor Simpson
probe_store(CPUHexagonState * env,int slot,int mmu_idx,bool is_predicated,uintptr_t retaddr)4727b84fd04STaylor Simpson static void probe_store(CPUHexagonState *env, int slot, int mmu_idx,
4733bd83593SMatheus Tavares Bernardino bool is_predicated, uintptr_t retaddr)
474c23b5764STaylor Simpson {
4757b84fd04STaylor Simpson if (!is_predicated || !(env->slot_cancelled & (1 << slot))) {
476c23b5764STaylor Simpson size1u_t width = env->mem_log_stores[slot].width;
477c23b5764STaylor Simpson target_ulong va = env->mem_log_stores[slot].va;
4783bd83593SMatheus Tavares Bernardino probe_write(env, va, width, mmu_idx, retaddr);
479c23b5764STaylor Simpson }
480c23b5764STaylor Simpson }
481c23b5764STaylor Simpson
48215fc6badSTaylor Simpson /*
48315fc6badSTaylor Simpson * Called from a mem_noshuf packet to make sure the load doesn't
48415fc6badSTaylor Simpson * raise an exception
48515fc6badSTaylor Simpson */
HELPER(probe_noshuf_load)48615fc6badSTaylor Simpson void HELPER(probe_noshuf_load)(CPUHexagonState *env, target_ulong va,
48715fc6badSTaylor Simpson int size, int mmu_idx)
48815fc6badSTaylor Simpson {
48915fc6badSTaylor Simpson uintptr_t retaddr = GETPC();
49015fc6badSTaylor Simpson probe_read(env, va, size, mmu_idx, retaddr);
49115fc6badSTaylor Simpson }
49215fc6badSTaylor Simpson
493c23b5764STaylor Simpson /* Called during packet commit when there are two scalar stores */
HELPER(probe_pkt_scalar_store_s0)4947b84fd04STaylor Simpson void HELPER(probe_pkt_scalar_store_s0)(CPUHexagonState *env, int args)
495c23b5764STaylor Simpson {
4967b84fd04STaylor Simpson int mmu_idx = FIELD_EX32(args, PROBE_PKT_SCALAR_STORE_S0, MMU_IDX);
4977b84fd04STaylor Simpson bool is_predicated =
4987b84fd04STaylor Simpson FIELD_EX32(args, PROBE_PKT_SCALAR_STORE_S0, IS_PREDICATED);
4993bd83593SMatheus Tavares Bernardino uintptr_t ra = GETPC();
5003bd83593SMatheus Tavares Bernardino probe_store(env, 0, mmu_idx, is_predicated, ra);
501c23b5764STaylor Simpson }
502c23b5764STaylor Simpson
probe_hvx_stores(CPUHexagonState * env,int mmu_idx,uintptr_t retaddr)5033bd83593SMatheus Tavares Bernardino static void probe_hvx_stores(CPUHexagonState *env, int mmu_idx,
5043bd83593SMatheus Tavares Bernardino uintptr_t retaddr)
50533e9ed11STaylor Simpson {
50633e9ed11STaylor Simpson /* Normal (possibly masked) vector store */
50720c34a92SBrian Cain for (int i = 0; i < VSTORES_MAX; i++) {
50833e9ed11STaylor Simpson if (env->vstore_pending[i]) {
50933e9ed11STaylor Simpson target_ulong va = env->vstore[i].va;
51033e9ed11STaylor Simpson int size = env->vstore[i].size;
51133e9ed11STaylor Simpson for (int j = 0; j < size; j++) {
51233e9ed11STaylor Simpson if (test_bit(j, env->vstore[i].mask)) {
51333e9ed11STaylor Simpson probe_write(env, va + j, 1, mmu_idx, retaddr);
51433e9ed11STaylor Simpson }
51533e9ed11STaylor Simpson }
51633e9ed11STaylor Simpson }
51733e9ed11STaylor Simpson }
51833e9ed11STaylor Simpson
51933e9ed11STaylor Simpson /* Scatter store */
52033e9ed11STaylor Simpson if (env->vtcm_pending) {
52133e9ed11STaylor Simpson if (env->vtcm_log.op) {
52233e9ed11STaylor Simpson /* Need to perform the scatter read/modify/write at commit time */
52333e9ed11STaylor Simpson if (env->vtcm_log.op_size == 2) {
52433e9ed11STaylor Simpson SCATTER_OP_PROBE_MEM(size2u_t, mmu_idx, retaddr);
52533e9ed11STaylor Simpson } else if (env->vtcm_log.op_size == 4) {
52633e9ed11STaylor Simpson /* Word Scatter += */
52733e9ed11STaylor Simpson SCATTER_OP_PROBE_MEM(size4u_t, mmu_idx, retaddr);
52833e9ed11STaylor Simpson } else {
52933e9ed11STaylor Simpson g_assert_not_reached();
53033e9ed11STaylor Simpson }
53133e9ed11STaylor Simpson } else {
53233e9ed11STaylor Simpson for (int i = 0; i < sizeof(MMVector); i++) {
53333e9ed11STaylor Simpson if (test_bit(i, env->vtcm_log.mask)) {
53433e9ed11STaylor Simpson probe_write(env, env->vtcm_log.va[i], 1, mmu_idx, retaddr);
53533e9ed11STaylor Simpson }
53633e9ed11STaylor Simpson
53733e9ed11STaylor Simpson }
53833e9ed11STaylor Simpson }
53933e9ed11STaylor Simpson }
54033e9ed11STaylor Simpson }
54133e9ed11STaylor Simpson
HELPER(probe_hvx_stores)5423bd83593SMatheus Tavares Bernardino void HELPER(probe_hvx_stores)(CPUHexagonState *env, int mmu_idx)
5433bd83593SMatheus Tavares Bernardino {
5443bd83593SMatheus Tavares Bernardino uintptr_t retaddr = GETPC();
5453bd83593SMatheus Tavares Bernardino probe_hvx_stores(env, mmu_idx, retaddr);
5463bd83593SMatheus Tavares Bernardino }
5473bd83593SMatheus Tavares Bernardino
HELPER(probe_pkt_scalar_hvx_stores)5482bda44e8STaylor Simpson void HELPER(probe_pkt_scalar_hvx_stores)(CPUHexagonState *env, int mask)
54933e9ed11STaylor Simpson {
5507b84fd04STaylor Simpson bool has_st0 = FIELD_EX32(mask, PROBE_PKT_SCALAR_HVX_STORES, HAS_ST0);
5517b84fd04STaylor Simpson bool has_st1 = FIELD_EX32(mask, PROBE_PKT_SCALAR_HVX_STORES, HAS_ST1);
5527b84fd04STaylor Simpson bool has_hvx_stores =
5537b84fd04STaylor Simpson FIELD_EX32(mask, PROBE_PKT_SCALAR_HVX_STORES, HAS_HVX_STORES);
5547b84fd04STaylor Simpson bool s0_is_pred = FIELD_EX32(mask, PROBE_PKT_SCALAR_HVX_STORES, S0_IS_PRED);
5557b84fd04STaylor Simpson bool s1_is_pred = FIELD_EX32(mask, PROBE_PKT_SCALAR_HVX_STORES, S1_IS_PRED);
5562bda44e8STaylor Simpson int mmu_idx = FIELD_EX32(mask, PROBE_PKT_SCALAR_HVX_STORES, MMU_IDX);
5573bd83593SMatheus Tavares Bernardino uintptr_t ra = GETPC();
55833e9ed11STaylor Simpson
55933e9ed11STaylor Simpson if (has_st0) {
5603bd83593SMatheus Tavares Bernardino probe_store(env, 0, mmu_idx, s0_is_pred, ra);
56133e9ed11STaylor Simpson }
56233e9ed11STaylor Simpson if (has_st1) {
5633bd83593SMatheus Tavares Bernardino probe_store(env, 1, mmu_idx, s1_is_pred, ra);
56433e9ed11STaylor Simpson }
56533e9ed11STaylor Simpson if (has_hvx_stores) {
5663bd83593SMatheus Tavares Bernardino probe_hvx_stores(env, mmu_idx, ra);
56733e9ed11STaylor Simpson }
56833e9ed11STaylor Simpson }
56933e9ed11STaylor Simpson
5703bd83593SMatheus Tavares Bernardino #ifndef CONFIG_HEXAGON_IDEF_PARSER
571b5ed786fSTaylor Simpson /*
572b5ed786fSTaylor Simpson * mem_noshuf
573b5ed786fSTaylor Simpson * Section 5.5 of the Hexagon V67 Programmer's Reference Manual
574b5ed786fSTaylor Simpson *
575b5ed786fSTaylor Simpson * If the load is in slot 0 and there is a store in slot1 (that
576b5ed786fSTaylor Simpson * wasn't cancelled), we have to do the store first.
577b5ed786fSTaylor Simpson */
check_noshuf(CPUHexagonState * env,bool pkt_has_store_s1,uint32_t slot,target_ulong vaddr,int size,uintptr_t ra)578e5d0d78dSTaylor Simpson static void check_noshuf(CPUHexagonState *env, bool pkt_has_store_s1,
5793bd83593SMatheus Tavares Bernardino uint32_t slot, target_ulong vaddr, int size,
5803bd83593SMatheus Tavares Bernardino uintptr_t ra)
581b5ed786fSTaylor Simpson {
582e5d0d78dSTaylor Simpson if (slot == 0 && pkt_has_store_s1 &&
583b5ed786fSTaylor Simpson ((env->slot_cancelled & (1 << 1)) == 0)) {
5843bd83593SMatheus Tavares Bernardino probe_read(env, vaddr, size, MMU_USER_IDX, ra);
5853bd83593SMatheus Tavares Bernardino commit_store(env, 1, ra);
586b5ed786fSTaylor Simpson }
587b5ed786fSTaylor Simpson }
5883bd83593SMatheus Tavares Bernardino #endif
589b5ed786fSTaylor Simpson
590b5ed786fSTaylor Simpson /* Floating point */
HELPER(conv_sf2df)591b5ed786fSTaylor Simpson float64 HELPER(conv_sf2df)(CPUHexagonState *env, float32 RsV)
592b5ed786fSTaylor Simpson {
593b5ed786fSTaylor Simpson float64 out_f64;
594b5ed786fSTaylor Simpson arch_fpop_start(env);
595b5ed786fSTaylor Simpson out_f64 = float32_to_float64(RsV, &env->fp_status);
596b5ed786fSTaylor Simpson arch_fpop_end(env);
597b5ed786fSTaylor Simpson return out_f64;
598b5ed786fSTaylor Simpson }
599b5ed786fSTaylor Simpson
HELPER(conv_df2sf)600b5ed786fSTaylor Simpson float32 HELPER(conv_df2sf)(CPUHexagonState *env, float64 RssV)
601b5ed786fSTaylor Simpson {
602b5ed786fSTaylor Simpson float32 out_f32;
603b5ed786fSTaylor Simpson arch_fpop_start(env);
604b5ed786fSTaylor Simpson out_f32 = float64_to_float32(RssV, &env->fp_status);
605b5ed786fSTaylor Simpson arch_fpop_end(env);
606b5ed786fSTaylor Simpson return out_f32;
607b5ed786fSTaylor Simpson }
608b5ed786fSTaylor Simpson
HELPER(conv_uw2sf)609b5ed786fSTaylor Simpson float32 HELPER(conv_uw2sf)(CPUHexagonState *env, int32_t RsV)
610b5ed786fSTaylor Simpson {
611b5ed786fSTaylor Simpson float32 RdV;
612b5ed786fSTaylor Simpson arch_fpop_start(env);
613b5ed786fSTaylor Simpson RdV = uint32_to_float32(RsV, &env->fp_status);
614b5ed786fSTaylor Simpson arch_fpop_end(env);
615b5ed786fSTaylor Simpson return RdV;
616b5ed786fSTaylor Simpson }
617b5ed786fSTaylor Simpson
HELPER(conv_uw2df)618b5ed786fSTaylor Simpson float64 HELPER(conv_uw2df)(CPUHexagonState *env, int32_t RsV)
619b5ed786fSTaylor Simpson {
620b5ed786fSTaylor Simpson float64 RddV;
621b5ed786fSTaylor Simpson arch_fpop_start(env);
622b5ed786fSTaylor Simpson RddV = uint32_to_float64(RsV, &env->fp_status);
623b5ed786fSTaylor Simpson arch_fpop_end(env);
624b5ed786fSTaylor Simpson return RddV;
625b5ed786fSTaylor Simpson }
626b5ed786fSTaylor Simpson
HELPER(conv_w2sf)627b5ed786fSTaylor Simpson float32 HELPER(conv_w2sf)(CPUHexagonState *env, int32_t RsV)
628b5ed786fSTaylor Simpson {
629b5ed786fSTaylor Simpson float32 RdV;
630b5ed786fSTaylor Simpson arch_fpop_start(env);
631b5ed786fSTaylor Simpson RdV = int32_to_float32(RsV, &env->fp_status);
632b5ed786fSTaylor Simpson arch_fpop_end(env);
633b5ed786fSTaylor Simpson return RdV;
634b5ed786fSTaylor Simpson }
635b5ed786fSTaylor Simpson
HELPER(conv_w2df)636b5ed786fSTaylor Simpson float64 HELPER(conv_w2df)(CPUHexagonState *env, int32_t RsV)
637b5ed786fSTaylor Simpson {
638b5ed786fSTaylor Simpson float64 RddV;
639b5ed786fSTaylor Simpson arch_fpop_start(env);
640b5ed786fSTaylor Simpson RddV = int32_to_float64(RsV, &env->fp_status);
641b5ed786fSTaylor Simpson arch_fpop_end(env);
642b5ed786fSTaylor Simpson return RddV;
643b5ed786fSTaylor Simpson }
644b5ed786fSTaylor Simpson
HELPER(conv_ud2sf)645b5ed786fSTaylor Simpson float32 HELPER(conv_ud2sf)(CPUHexagonState *env, int64_t RssV)
646b5ed786fSTaylor Simpson {
647b5ed786fSTaylor Simpson float32 RdV;
648b5ed786fSTaylor Simpson arch_fpop_start(env);
649b5ed786fSTaylor Simpson RdV = uint64_to_float32(RssV, &env->fp_status);
650b5ed786fSTaylor Simpson arch_fpop_end(env);
651b5ed786fSTaylor Simpson return RdV;
652b5ed786fSTaylor Simpson }
653b5ed786fSTaylor Simpson
HELPER(conv_ud2df)654b5ed786fSTaylor Simpson float64 HELPER(conv_ud2df)(CPUHexagonState *env, int64_t RssV)
655b5ed786fSTaylor Simpson {
656b5ed786fSTaylor Simpson float64 RddV;
657b5ed786fSTaylor Simpson arch_fpop_start(env);
658b5ed786fSTaylor Simpson RddV = uint64_to_float64(RssV, &env->fp_status);
659b5ed786fSTaylor Simpson arch_fpop_end(env);
660b5ed786fSTaylor Simpson return RddV;
661b5ed786fSTaylor Simpson }
662b5ed786fSTaylor Simpson
HELPER(conv_d2sf)663b5ed786fSTaylor Simpson float32 HELPER(conv_d2sf)(CPUHexagonState *env, int64_t RssV)
664b5ed786fSTaylor Simpson {
665b5ed786fSTaylor Simpson float32 RdV;
666b5ed786fSTaylor Simpson arch_fpop_start(env);
667b5ed786fSTaylor Simpson RdV = int64_to_float32(RssV, &env->fp_status);
668b5ed786fSTaylor Simpson arch_fpop_end(env);
669b5ed786fSTaylor Simpson return RdV;
670b5ed786fSTaylor Simpson }
671b5ed786fSTaylor Simpson
HELPER(conv_d2df)672b5ed786fSTaylor Simpson float64 HELPER(conv_d2df)(CPUHexagonState *env, int64_t RssV)
673b5ed786fSTaylor Simpson {
674b5ed786fSTaylor Simpson float64 RddV;
675b5ed786fSTaylor Simpson arch_fpop_start(env);
676b5ed786fSTaylor Simpson RddV = int64_to_float64(RssV, &env->fp_status);
677b5ed786fSTaylor Simpson arch_fpop_end(env);
678b5ed786fSTaylor Simpson return RddV;
679b5ed786fSTaylor Simpson }
680b5ed786fSTaylor Simpson
HELPER(conv_sf2uw)681b3f37abdSTaylor Simpson uint32_t HELPER(conv_sf2uw)(CPUHexagonState *env, float32 RsV)
682b5ed786fSTaylor Simpson {
683b3f37abdSTaylor Simpson uint32_t RdV;
684b5ed786fSTaylor Simpson arch_fpop_start(env);
685b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
686*6146060aSMatheus Tavares Bernardino if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
687b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
688b3f37abdSTaylor Simpson RdV = 0;
689b3f37abdSTaylor Simpson } else {
690b3f37abdSTaylor Simpson RdV = float32_to_uint32(RsV, &env->fp_status);
691b3f37abdSTaylor Simpson }
692b5ed786fSTaylor Simpson arch_fpop_end(env);
693b5ed786fSTaylor Simpson return RdV;
694b5ed786fSTaylor Simpson }
695b5ed786fSTaylor Simpson
HELPER(conv_sf2w)696b5ed786fSTaylor Simpson int32_t HELPER(conv_sf2w)(CPUHexagonState *env, float32 RsV)
697b5ed786fSTaylor Simpson {
698b5ed786fSTaylor Simpson int32_t RdV;
699b5ed786fSTaylor Simpson arch_fpop_start(env);
700b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
701b3f37abdSTaylor Simpson if (float32_is_any_nan(RsV)) {
702b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
703b3f37abdSTaylor Simpson RdV = -1;
704b3f37abdSTaylor Simpson } else {
705b3f37abdSTaylor Simpson RdV = float32_to_int32(RsV, &env->fp_status);
706b3f37abdSTaylor Simpson }
707b5ed786fSTaylor Simpson arch_fpop_end(env);
708b5ed786fSTaylor Simpson return RdV;
709b5ed786fSTaylor Simpson }
710b5ed786fSTaylor Simpson
HELPER(conv_sf2ud)711b3f37abdSTaylor Simpson uint64_t HELPER(conv_sf2ud)(CPUHexagonState *env, float32 RsV)
712b5ed786fSTaylor Simpson {
713b3f37abdSTaylor Simpson uint64_t RddV;
714b5ed786fSTaylor Simpson arch_fpop_start(env);
715b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
716*6146060aSMatheus Tavares Bernardino if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
717b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
718b3f37abdSTaylor Simpson RddV = 0;
719b3f37abdSTaylor Simpson } else {
720b3f37abdSTaylor Simpson RddV = float32_to_uint64(RsV, &env->fp_status);
721b3f37abdSTaylor Simpson }
722b5ed786fSTaylor Simpson arch_fpop_end(env);
723b5ed786fSTaylor Simpson return RddV;
724b5ed786fSTaylor Simpson }
725b5ed786fSTaylor Simpson
HELPER(conv_sf2d)726b5ed786fSTaylor Simpson int64_t HELPER(conv_sf2d)(CPUHexagonState *env, float32 RsV)
727b5ed786fSTaylor Simpson {
728b5ed786fSTaylor Simpson int64_t RddV;
729b5ed786fSTaylor Simpson arch_fpop_start(env);
730b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
731b3f37abdSTaylor Simpson if (float32_is_any_nan(RsV)) {
732b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
733b3f37abdSTaylor Simpson RddV = -1;
734b3f37abdSTaylor Simpson } else {
735b3f37abdSTaylor Simpson RddV = float32_to_int64(RsV, &env->fp_status);
736b3f37abdSTaylor Simpson }
737b5ed786fSTaylor Simpson arch_fpop_end(env);
738b5ed786fSTaylor Simpson return RddV;
739b5ed786fSTaylor Simpson }
740b5ed786fSTaylor Simpson
HELPER(conv_df2uw)741b3f37abdSTaylor Simpson uint32_t HELPER(conv_df2uw)(CPUHexagonState *env, float64 RssV)
742b5ed786fSTaylor Simpson {
743b3f37abdSTaylor Simpson uint32_t RdV;
744b5ed786fSTaylor Simpson arch_fpop_start(env);
745b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
746*6146060aSMatheus Tavares Bernardino if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
747b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
748b3f37abdSTaylor Simpson RdV = 0;
749b3f37abdSTaylor Simpson } else {
750b3f37abdSTaylor Simpson RdV = float64_to_uint32(RssV, &env->fp_status);
751b3f37abdSTaylor Simpson }
752b5ed786fSTaylor Simpson arch_fpop_end(env);
753b5ed786fSTaylor Simpson return RdV;
754b5ed786fSTaylor Simpson }
755b5ed786fSTaylor Simpson
HELPER(conv_df2w)756b5ed786fSTaylor Simpson int32_t HELPER(conv_df2w)(CPUHexagonState *env, float64 RssV)
757b5ed786fSTaylor Simpson {
758b5ed786fSTaylor Simpson int32_t RdV;
759b5ed786fSTaylor Simpson arch_fpop_start(env);
760b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
761b3f37abdSTaylor Simpson if (float64_is_any_nan(RssV)) {
762b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
763b3f37abdSTaylor Simpson RdV = -1;
764b3f37abdSTaylor Simpson } else {
765b3f37abdSTaylor Simpson RdV = float64_to_int32(RssV, &env->fp_status);
766b3f37abdSTaylor Simpson }
767b5ed786fSTaylor Simpson arch_fpop_end(env);
768b5ed786fSTaylor Simpson return RdV;
769b5ed786fSTaylor Simpson }
770b5ed786fSTaylor Simpson
HELPER(conv_df2ud)771b3f37abdSTaylor Simpson uint64_t HELPER(conv_df2ud)(CPUHexagonState *env, float64 RssV)
772b5ed786fSTaylor Simpson {
773b3f37abdSTaylor Simpson uint64_t RddV;
774b5ed786fSTaylor Simpson arch_fpop_start(env);
775b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
776*6146060aSMatheus Tavares Bernardino if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
777b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
778b3f37abdSTaylor Simpson RddV = 0;
779b3f37abdSTaylor Simpson } else {
780b3f37abdSTaylor Simpson RddV = float64_to_uint64(RssV, &env->fp_status);
781b3f37abdSTaylor Simpson }
782b5ed786fSTaylor Simpson arch_fpop_end(env);
783b5ed786fSTaylor Simpson return RddV;
784b5ed786fSTaylor Simpson }
785b5ed786fSTaylor Simpson
HELPER(conv_df2d)786b5ed786fSTaylor Simpson int64_t HELPER(conv_df2d)(CPUHexagonState *env, float64 RssV)
787b5ed786fSTaylor Simpson {
788b5ed786fSTaylor Simpson int64_t RddV;
789b5ed786fSTaylor Simpson arch_fpop_start(env);
790b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
791b3f37abdSTaylor Simpson if (float64_is_any_nan(RssV)) {
792b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
793b3f37abdSTaylor Simpson RddV = -1;
794b3f37abdSTaylor Simpson } else {
795b3f37abdSTaylor Simpson RddV = float64_to_int64(RssV, &env->fp_status);
796b3f37abdSTaylor Simpson }
797b5ed786fSTaylor Simpson arch_fpop_end(env);
798b5ed786fSTaylor Simpson return RddV;
799b5ed786fSTaylor Simpson }
800b5ed786fSTaylor Simpson
HELPER(conv_sf2uw_chop)801b3f37abdSTaylor Simpson uint32_t HELPER(conv_sf2uw_chop)(CPUHexagonState *env, float32 RsV)
802b5ed786fSTaylor Simpson {
803b3f37abdSTaylor Simpson uint32_t RdV;
804b5ed786fSTaylor Simpson arch_fpop_start(env);
805b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
806*6146060aSMatheus Tavares Bernardino if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
807b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
808b3f37abdSTaylor Simpson RdV = 0;
809b3f37abdSTaylor Simpson } else {
810b3f37abdSTaylor Simpson RdV = float32_to_uint32_round_to_zero(RsV, &env->fp_status);
811b3f37abdSTaylor Simpson }
812b5ed786fSTaylor Simpson arch_fpop_end(env);
813b5ed786fSTaylor Simpson return RdV;
814b5ed786fSTaylor Simpson }
815b5ed786fSTaylor Simpson
HELPER(conv_sf2w_chop)816b5ed786fSTaylor Simpson int32_t HELPER(conv_sf2w_chop)(CPUHexagonState *env, float32 RsV)
817b5ed786fSTaylor Simpson {
818b5ed786fSTaylor Simpson int32_t RdV;
819b5ed786fSTaylor Simpson arch_fpop_start(env);
820b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
821b3f37abdSTaylor Simpson if (float32_is_any_nan(RsV)) {
822b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
823b3f37abdSTaylor Simpson RdV = -1;
824b3f37abdSTaylor Simpson } else {
825b3f37abdSTaylor Simpson RdV = float32_to_int32_round_to_zero(RsV, &env->fp_status);
826b3f37abdSTaylor Simpson }
827b5ed786fSTaylor Simpson arch_fpop_end(env);
828b5ed786fSTaylor Simpson return RdV;
829b5ed786fSTaylor Simpson }
830b5ed786fSTaylor Simpson
HELPER(conv_sf2ud_chop)831b3f37abdSTaylor Simpson uint64_t HELPER(conv_sf2ud_chop)(CPUHexagonState *env, float32 RsV)
832b5ed786fSTaylor Simpson {
833b3f37abdSTaylor Simpson uint64_t RddV;
834b5ed786fSTaylor Simpson arch_fpop_start(env);
835b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
836*6146060aSMatheus Tavares Bernardino if (float32_is_neg(RsV) && !float32_is_any_nan(RsV) && !float32_is_zero(RsV)) {
837b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
838b3f37abdSTaylor Simpson RddV = 0;
839b3f37abdSTaylor Simpson } else {
840b3f37abdSTaylor Simpson RddV = float32_to_uint64_round_to_zero(RsV, &env->fp_status);
841b3f37abdSTaylor Simpson }
842b5ed786fSTaylor Simpson arch_fpop_end(env);
843b5ed786fSTaylor Simpson return RddV;
844b5ed786fSTaylor Simpson }
845b5ed786fSTaylor Simpson
HELPER(conv_sf2d_chop)846b5ed786fSTaylor Simpson int64_t HELPER(conv_sf2d_chop)(CPUHexagonState *env, float32 RsV)
847b5ed786fSTaylor Simpson {
848b5ed786fSTaylor Simpson int64_t RddV;
849b5ed786fSTaylor Simpson arch_fpop_start(env);
850b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
851b3f37abdSTaylor Simpson if (float32_is_any_nan(RsV)) {
852b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
853b3f37abdSTaylor Simpson RddV = -1;
854b3f37abdSTaylor Simpson } else {
855b3f37abdSTaylor Simpson RddV = float32_to_int64_round_to_zero(RsV, &env->fp_status);
856b3f37abdSTaylor Simpson }
857b5ed786fSTaylor Simpson arch_fpop_end(env);
858b5ed786fSTaylor Simpson return RddV;
859b5ed786fSTaylor Simpson }
860b5ed786fSTaylor Simpson
HELPER(conv_df2uw_chop)861b3f37abdSTaylor Simpson uint32_t HELPER(conv_df2uw_chop)(CPUHexagonState *env, float64 RssV)
862b5ed786fSTaylor Simpson {
863b3f37abdSTaylor Simpson uint32_t RdV;
864b5ed786fSTaylor Simpson arch_fpop_start(env);
865b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
866*6146060aSMatheus Tavares Bernardino if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
867b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
868b3f37abdSTaylor Simpson RdV = 0;
869b3f37abdSTaylor Simpson } else {
870b3f37abdSTaylor Simpson RdV = float64_to_uint32_round_to_zero(RssV, &env->fp_status);
871b3f37abdSTaylor Simpson }
872b5ed786fSTaylor Simpson arch_fpop_end(env);
873b5ed786fSTaylor Simpson return RdV;
874b5ed786fSTaylor Simpson }
875b5ed786fSTaylor Simpson
HELPER(conv_df2w_chop)876b5ed786fSTaylor Simpson int32_t HELPER(conv_df2w_chop)(CPUHexagonState *env, float64 RssV)
877b5ed786fSTaylor Simpson {
878b5ed786fSTaylor Simpson int32_t RdV;
879b5ed786fSTaylor Simpson arch_fpop_start(env);
880b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
881b3f37abdSTaylor Simpson if (float64_is_any_nan(RssV)) {
882b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
883b3f37abdSTaylor Simpson RdV = -1;
884b3f37abdSTaylor Simpson } else {
885b3f37abdSTaylor Simpson RdV = float64_to_int32_round_to_zero(RssV, &env->fp_status);
886b3f37abdSTaylor Simpson }
887b5ed786fSTaylor Simpson arch_fpop_end(env);
888b5ed786fSTaylor Simpson return RdV;
889b5ed786fSTaylor Simpson }
890b5ed786fSTaylor Simpson
HELPER(conv_df2ud_chop)891b3f37abdSTaylor Simpson uint64_t HELPER(conv_df2ud_chop)(CPUHexagonState *env, float64 RssV)
892b5ed786fSTaylor Simpson {
893b3f37abdSTaylor Simpson uint64_t RddV;
894b5ed786fSTaylor Simpson arch_fpop_start(env);
895b3f37abdSTaylor Simpson /* Hexagon checks the sign before rounding */
896*6146060aSMatheus Tavares Bernardino if (float64_is_neg(RssV) && !float64_is_any_nan(RssV) && !float64_is_zero(RssV)) {
897b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
898b3f37abdSTaylor Simpson RddV = 0;
899b3f37abdSTaylor Simpson } else {
900b3f37abdSTaylor Simpson RddV = float64_to_uint64_round_to_zero(RssV, &env->fp_status);
901b3f37abdSTaylor Simpson }
902b5ed786fSTaylor Simpson arch_fpop_end(env);
903b5ed786fSTaylor Simpson return RddV;
904b5ed786fSTaylor Simpson }
905b5ed786fSTaylor Simpson
HELPER(conv_df2d_chop)906b5ed786fSTaylor Simpson int64_t HELPER(conv_df2d_chop)(CPUHexagonState *env, float64 RssV)
907b5ed786fSTaylor Simpson {
908b5ed786fSTaylor Simpson int64_t RddV;
909b5ed786fSTaylor Simpson arch_fpop_start(env);
910b3f37abdSTaylor Simpson /* Hexagon returns -1 for NaN */
911b3f37abdSTaylor Simpson if (float64_is_any_nan(RssV)) {
912b3f37abdSTaylor Simpson float_raise(float_flag_invalid, &env->fp_status);
913b3f37abdSTaylor Simpson RddV = -1;
914b3f37abdSTaylor Simpson } else {
915b3f37abdSTaylor Simpson RddV = float64_to_int64_round_to_zero(RssV, &env->fp_status);
916b3f37abdSTaylor Simpson }
917b5ed786fSTaylor Simpson arch_fpop_end(env);
918b5ed786fSTaylor Simpson return RddV;
919b5ed786fSTaylor Simpson }
920b5ed786fSTaylor Simpson
HELPER(sfadd)921b5ed786fSTaylor Simpson float32 HELPER(sfadd)(CPUHexagonState *env, float32 RsV, float32 RtV)
922b5ed786fSTaylor Simpson {
923b5ed786fSTaylor Simpson float32 RdV;
924b5ed786fSTaylor Simpson arch_fpop_start(env);
925b5ed786fSTaylor Simpson RdV = float32_add(RsV, RtV, &env->fp_status);
926b5ed786fSTaylor Simpson arch_fpop_end(env);
927b5ed786fSTaylor Simpson return RdV;
928b5ed786fSTaylor Simpson }
929b5ed786fSTaylor Simpson
HELPER(sfsub)930b5ed786fSTaylor Simpson float32 HELPER(sfsub)(CPUHexagonState *env, float32 RsV, float32 RtV)
931b5ed786fSTaylor Simpson {
932b5ed786fSTaylor Simpson float32 RdV;
933b5ed786fSTaylor Simpson arch_fpop_start(env);
934b5ed786fSTaylor Simpson RdV = float32_sub(RsV, RtV, &env->fp_status);
935b5ed786fSTaylor Simpson arch_fpop_end(env);
936b5ed786fSTaylor Simpson return RdV;
937b5ed786fSTaylor Simpson }
938b5ed786fSTaylor Simpson
HELPER(sfcmpeq)939b5ed786fSTaylor Simpson int32_t HELPER(sfcmpeq)(CPUHexagonState *env, float32 RsV, float32 RtV)
940b5ed786fSTaylor Simpson {
941b5ed786fSTaylor Simpson int32_t PdV;
942b5ed786fSTaylor Simpson arch_fpop_start(env);
943b5ed786fSTaylor Simpson PdV = f8BITSOF(float32_eq_quiet(RsV, RtV, &env->fp_status));
944b5ed786fSTaylor Simpson arch_fpop_end(env);
945b5ed786fSTaylor Simpson return PdV;
946b5ed786fSTaylor Simpson }
947b5ed786fSTaylor Simpson
HELPER(sfcmpgt)948b5ed786fSTaylor Simpson int32_t HELPER(sfcmpgt)(CPUHexagonState *env, float32 RsV, float32 RtV)
949b5ed786fSTaylor Simpson {
950b5ed786fSTaylor Simpson int cmp;
951b5ed786fSTaylor Simpson int32_t PdV;
952b5ed786fSTaylor Simpson arch_fpop_start(env);
953b5ed786fSTaylor Simpson cmp = float32_compare_quiet(RsV, RtV, &env->fp_status);
954b5ed786fSTaylor Simpson PdV = f8BITSOF(cmp == float_relation_greater);
955b5ed786fSTaylor Simpson arch_fpop_end(env);
956b5ed786fSTaylor Simpson return PdV;
957b5ed786fSTaylor Simpson }
958b5ed786fSTaylor Simpson
HELPER(sfcmpge)959b5ed786fSTaylor Simpson int32_t HELPER(sfcmpge)(CPUHexagonState *env, float32 RsV, float32 RtV)
960b5ed786fSTaylor Simpson {
961b5ed786fSTaylor Simpson int cmp;
962b5ed786fSTaylor Simpson int32_t PdV;
963b5ed786fSTaylor Simpson arch_fpop_start(env);
964b5ed786fSTaylor Simpson cmp = float32_compare_quiet(RsV, RtV, &env->fp_status);
965b5ed786fSTaylor Simpson PdV = f8BITSOF(cmp == float_relation_greater ||
966b5ed786fSTaylor Simpson cmp == float_relation_equal);
967b5ed786fSTaylor Simpson arch_fpop_end(env);
968b5ed786fSTaylor Simpson return PdV;
969b5ed786fSTaylor Simpson }
970b5ed786fSTaylor Simpson
HELPER(sfcmpuo)971b5ed786fSTaylor Simpson int32_t HELPER(sfcmpuo)(CPUHexagonState *env, float32 RsV, float32 RtV)
972b5ed786fSTaylor Simpson {
973b5ed786fSTaylor Simpson int32_t PdV;
974b5ed786fSTaylor Simpson arch_fpop_start(env);
9759a659903STaylor Simpson PdV = f8BITSOF(float32_unordered_quiet(RsV, RtV, &env->fp_status));
976b5ed786fSTaylor Simpson arch_fpop_end(env);
977b5ed786fSTaylor Simpson return PdV;
978b5ed786fSTaylor Simpson }
979b5ed786fSTaylor Simpson
HELPER(sfmax)980b5ed786fSTaylor Simpson float32 HELPER(sfmax)(CPUHexagonState *env, float32 RsV, float32 RtV)
981b5ed786fSTaylor Simpson {
982b5ed786fSTaylor Simpson float32 RdV;
983b5ed786fSTaylor Simpson arch_fpop_start(env);
984d76dd816STaylor Simpson RdV = float32_maximum_number(RsV, RtV, &env->fp_status);
985b5ed786fSTaylor Simpson arch_fpop_end(env);
986b5ed786fSTaylor Simpson return RdV;
987b5ed786fSTaylor Simpson }
988b5ed786fSTaylor Simpson
HELPER(sfmin)989b5ed786fSTaylor Simpson float32 HELPER(sfmin)(CPUHexagonState *env, float32 RsV, float32 RtV)
990b5ed786fSTaylor Simpson {
991b5ed786fSTaylor Simpson float32 RdV;
992b5ed786fSTaylor Simpson arch_fpop_start(env);
993d76dd816STaylor Simpson RdV = float32_minimum_number(RsV, RtV, &env->fp_status);
994b5ed786fSTaylor Simpson arch_fpop_end(env);
995b5ed786fSTaylor Simpson return RdV;
996b5ed786fSTaylor Simpson }
997b5ed786fSTaylor Simpson
HELPER(sfclass)998b5ed786fSTaylor Simpson int32_t HELPER(sfclass)(CPUHexagonState *env, float32 RsV, int32_t uiV)
999b5ed786fSTaylor Simpson {
1000b5ed786fSTaylor Simpson int32_t PdV = 0;
1001b5ed786fSTaylor Simpson arch_fpop_start(env);
1002b5ed786fSTaylor Simpson if (fGETBIT(0, uiV) && float32_is_zero(RsV)) {
1003b5ed786fSTaylor Simpson PdV = 0xff;
1004b5ed786fSTaylor Simpson }
1005b5ed786fSTaylor Simpson if (fGETBIT(1, uiV) && float32_is_normal(RsV)) {
1006b5ed786fSTaylor Simpson PdV = 0xff;
1007b5ed786fSTaylor Simpson }
1008b5ed786fSTaylor Simpson if (fGETBIT(2, uiV) && float32_is_denormal(RsV)) {
1009b5ed786fSTaylor Simpson PdV = 0xff;
1010b5ed786fSTaylor Simpson }
1011b5ed786fSTaylor Simpson if (fGETBIT(3, uiV) && float32_is_infinity(RsV)) {
1012b5ed786fSTaylor Simpson PdV = 0xff;
1013b5ed786fSTaylor Simpson }
1014b5ed786fSTaylor Simpson if (fGETBIT(4, uiV) && float32_is_any_nan(RsV)) {
1015b5ed786fSTaylor Simpson PdV = 0xff;
1016b5ed786fSTaylor Simpson }
1017b5ed786fSTaylor Simpson set_float_exception_flags(0, &env->fp_status);
1018b5ed786fSTaylor Simpson arch_fpop_end(env);
1019b5ed786fSTaylor Simpson return PdV;
1020b5ed786fSTaylor Simpson }
1021b5ed786fSTaylor Simpson
HELPER(sffixupn)1022b5ed786fSTaylor Simpson float32 HELPER(sffixupn)(CPUHexagonState *env, float32 RsV, float32 RtV)
1023b5ed786fSTaylor Simpson {
1024b5ed786fSTaylor Simpson float32 RdV = 0;
1025b5ed786fSTaylor Simpson int adjust;
1026b5ed786fSTaylor Simpson arch_fpop_start(env);
1027b5ed786fSTaylor Simpson arch_sf_recip_common(&RsV, &RtV, &RdV, &adjust, &env->fp_status);
1028b5ed786fSTaylor Simpson RdV = RsV;
1029b5ed786fSTaylor Simpson arch_fpop_end(env);
1030b5ed786fSTaylor Simpson return RdV;
1031b5ed786fSTaylor Simpson }
1032b5ed786fSTaylor Simpson
HELPER(sffixupd)1033b5ed786fSTaylor Simpson float32 HELPER(sffixupd)(CPUHexagonState *env, float32 RsV, float32 RtV)
1034b5ed786fSTaylor Simpson {
1035b5ed786fSTaylor Simpson float32 RdV = 0;
1036b5ed786fSTaylor Simpson int adjust;
1037b5ed786fSTaylor Simpson arch_fpop_start(env);
1038b5ed786fSTaylor Simpson arch_sf_recip_common(&RsV, &RtV, &RdV, &adjust, &env->fp_status);
1039b5ed786fSTaylor Simpson RdV = RtV;
1040b5ed786fSTaylor Simpson arch_fpop_end(env);
1041b5ed786fSTaylor Simpson return RdV;
1042b5ed786fSTaylor Simpson }
1043b5ed786fSTaylor Simpson
HELPER(sffixupr)1044b5ed786fSTaylor Simpson float32 HELPER(sffixupr)(CPUHexagonState *env, float32 RsV)
1045b5ed786fSTaylor Simpson {
1046b5ed786fSTaylor Simpson float32 RdV = 0;
1047b5ed786fSTaylor Simpson int adjust;
1048b5ed786fSTaylor Simpson arch_fpop_start(env);
1049b5ed786fSTaylor Simpson arch_sf_invsqrt_common(&RsV, &RdV, &adjust, &env->fp_status);
1050b5ed786fSTaylor Simpson RdV = RsV;
1051b5ed786fSTaylor Simpson arch_fpop_end(env);
1052b5ed786fSTaylor Simpson return RdV;
1053b5ed786fSTaylor Simpson }
1054b5ed786fSTaylor Simpson
HELPER(dfadd)1055b5ed786fSTaylor Simpson float64 HELPER(dfadd)(CPUHexagonState *env, float64 RssV, float64 RttV)
1056b5ed786fSTaylor Simpson {
1057b5ed786fSTaylor Simpson float64 RddV;
1058b5ed786fSTaylor Simpson arch_fpop_start(env);
1059b5ed786fSTaylor Simpson RddV = float64_add(RssV, RttV, &env->fp_status);
1060b5ed786fSTaylor Simpson arch_fpop_end(env);
1061b5ed786fSTaylor Simpson return RddV;
1062b5ed786fSTaylor Simpson }
1063b5ed786fSTaylor Simpson
HELPER(dfsub)1064b5ed786fSTaylor Simpson float64 HELPER(dfsub)(CPUHexagonState *env, float64 RssV, float64 RttV)
1065b5ed786fSTaylor Simpson {
1066b5ed786fSTaylor Simpson float64 RddV;
1067b5ed786fSTaylor Simpson arch_fpop_start(env);
1068b5ed786fSTaylor Simpson RddV = float64_sub(RssV, RttV, &env->fp_status);
1069b5ed786fSTaylor Simpson arch_fpop_end(env);
1070b5ed786fSTaylor Simpson return RddV;
1071b5ed786fSTaylor Simpson }
1072b5ed786fSTaylor Simpson
HELPER(dfmax)1073b5ed786fSTaylor Simpson float64 HELPER(dfmax)(CPUHexagonState *env, float64 RssV, float64 RttV)
1074b5ed786fSTaylor Simpson {
1075b5ed786fSTaylor Simpson float64 RddV;
1076b5ed786fSTaylor Simpson arch_fpop_start(env);
1077d76dd816STaylor Simpson RddV = float64_maximum_number(RssV, RttV, &env->fp_status);
1078b5ed786fSTaylor Simpson arch_fpop_end(env);
1079b5ed786fSTaylor Simpson return RddV;
1080b5ed786fSTaylor Simpson }
1081b5ed786fSTaylor Simpson
HELPER(dfmin)1082b5ed786fSTaylor Simpson float64 HELPER(dfmin)(CPUHexagonState *env, float64 RssV, float64 RttV)
1083b5ed786fSTaylor Simpson {
1084b5ed786fSTaylor Simpson float64 RddV;
1085b5ed786fSTaylor Simpson arch_fpop_start(env);
1086d76dd816STaylor Simpson RddV = float64_minimum_number(RssV, RttV, &env->fp_status);
1087b5ed786fSTaylor Simpson arch_fpop_end(env);
1088b5ed786fSTaylor Simpson return RddV;
1089b5ed786fSTaylor Simpson }
1090b5ed786fSTaylor Simpson
HELPER(dfcmpeq)1091b5ed786fSTaylor Simpson int32_t HELPER(dfcmpeq)(CPUHexagonState *env, float64 RssV, float64 RttV)
1092b5ed786fSTaylor Simpson {
1093b5ed786fSTaylor Simpson int32_t PdV;
1094b5ed786fSTaylor Simpson arch_fpop_start(env);
1095b5ed786fSTaylor Simpson PdV = f8BITSOF(float64_eq_quiet(RssV, RttV, &env->fp_status));
1096b5ed786fSTaylor Simpson arch_fpop_end(env);
1097b5ed786fSTaylor Simpson return PdV;
1098b5ed786fSTaylor Simpson }
1099b5ed786fSTaylor Simpson
HELPER(dfcmpgt)1100b5ed786fSTaylor Simpson int32_t HELPER(dfcmpgt)(CPUHexagonState *env, float64 RssV, float64 RttV)
1101b5ed786fSTaylor Simpson {
1102b5ed786fSTaylor Simpson int cmp;
1103b5ed786fSTaylor Simpson int32_t PdV;
1104b5ed786fSTaylor Simpson arch_fpop_start(env);
1105b5ed786fSTaylor Simpson cmp = float64_compare_quiet(RssV, RttV, &env->fp_status);
1106b5ed786fSTaylor Simpson PdV = f8BITSOF(cmp == float_relation_greater);
1107b5ed786fSTaylor Simpson arch_fpop_end(env);
1108b5ed786fSTaylor Simpson return PdV;
1109b5ed786fSTaylor Simpson }
1110b5ed786fSTaylor Simpson
HELPER(dfcmpge)1111b5ed786fSTaylor Simpson int32_t HELPER(dfcmpge)(CPUHexagonState *env, float64 RssV, float64 RttV)
1112b5ed786fSTaylor Simpson {
1113b5ed786fSTaylor Simpson int cmp;
1114b5ed786fSTaylor Simpson int32_t PdV;
1115b5ed786fSTaylor Simpson arch_fpop_start(env);
1116b5ed786fSTaylor Simpson cmp = float64_compare_quiet(RssV, RttV, &env->fp_status);
1117b5ed786fSTaylor Simpson PdV = f8BITSOF(cmp == float_relation_greater ||
1118b5ed786fSTaylor Simpson cmp == float_relation_equal);
1119b5ed786fSTaylor Simpson arch_fpop_end(env);
1120b5ed786fSTaylor Simpson return PdV;
1121b5ed786fSTaylor Simpson }
1122b5ed786fSTaylor Simpson
HELPER(dfcmpuo)1123b5ed786fSTaylor Simpson int32_t HELPER(dfcmpuo)(CPUHexagonState *env, float64 RssV, float64 RttV)
1124b5ed786fSTaylor Simpson {
1125b5ed786fSTaylor Simpson int32_t PdV;
1126b5ed786fSTaylor Simpson arch_fpop_start(env);
11279a659903STaylor Simpson PdV = f8BITSOF(float64_unordered_quiet(RssV, RttV, &env->fp_status));
1128b5ed786fSTaylor Simpson arch_fpop_end(env);
1129b5ed786fSTaylor Simpson return PdV;
1130b5ed786fSTaylor Simpson }
1131b5ed786fSTaylor Simpson
HELPER(dfclass)1132b5ed786fSTaylor Simpson int32_t HELPER(dfclass)(CPUHexagonState *env, float64 RssV, int32_t uiV)
1133b5ed786fSTaylor Simpson {
1134b5ed786fSTaylor Simpson int32_t PdV = 0;
1135b5ed786fSTaylor Simpson arch_fpop_start(env);
1136b5ed786fSTaylor Simpson if (fGETBIT(0, uiV) && float64_is_zero(RssV)) {
1137b5ed786fSTaylor Simpson PdV = 0xff;
1138b5ed786fSTaylor Simpson }
1139b5ed786fSTaylor Simpson if (fGETBIT(1, uiV) && float64_is_normal(RssV)) {
1140b5ed786fSTaylor Simpson PdV = 0xff;
1141b5ed786fSTaylor Simpson }
1142b5ed786fSTaylor Simpson if (fGETBIT(2, uiV) && float64_is_denormal(RssV)) {
1143b5ed786fSTaylor Simpson PdV = 0xff;
1144b5ed786fSTaylor Simpson }
1145b5ed786fSTaylor Simpson if (fGETBIT(3, uiV) && float64_is_infinity(RssV)) {
1146b5ed786fSTaylor Simpson PdV = 0xff;
1147b5ed786fSTaylor Simpson }
1148b5ed786fSTaylor Simpson if (fGETBIT(4, uiV) && float64_is_any_nan(RssV)) {
1149b5ed786fSTaylor Simpson PdV = 0xff;
1150b5ed786fSTaylor Simpson }
1151b5ed786fSTaylor Simpson set_float_exception_flags(0, &env->fp_status);
1152b5ed786fSTaylor Simpson arch_fpop_end(env);
1153b5ed786fSTaylor Simpson return PdV;
1154b5ed786fSTaylor Simpson }
1155b5ed786fSTaylor Simpson
HELPER(sfmpy)1156b5ed786fSTaylor Simpson float32 HELPER(sfmpy)(CPUHexagonState *env, float32 RsV, float32 RtV)
1157b5ed786fSTaylor Simpson {
1158b5ed786fSTaylor Simpson float32 RdV;
1159b5ed786fSTaylor Simpson arch_fpop_start(env);
1160b5ed786fSTaylor Simpson RdV = internal_mpyf(RsV, RtV, &env->fp_status);
1161b5ed786fSTaylor Simpson arch_fpop_end(env);
1162b5ed786fSTaylor Simpson return RdV;
1163b5ed786fSTaylor Simpson }
1164b5ed786fSTaylor Simpson
HELPER(sffma)1165b5ed786fSTaylor Simpson float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
1166b5ed786fSTaylor Simpson float32 RsV, float32 RtV)
1167b5ed786fSTaylor Simpson {
1168b5ed786fSTaylor Simpson arch_fpop_start(env);
1169b5ed786fSTaylor Simpson RxV = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
1170b5ed786fSTaylor Simpson arch_fpop_end(env);
1171b5ed786fSTaylor Simpson return RxV;
1172b5ed786fSTaylor Simpson }
1173b5ed786fSTaylor Simpson
is_zero_prod(float32 a,float32 b)1174b5ed786fSTaylor Simpson static bool is_zero_prod(float32 a, float32 b)
1175b5ed786fSTaylor Simpson {
1176b5ed786fSTaylor Simpson return ((float32_is_zero(a) && is_finite(b)) ||
1177b5ed786fSTaylor Simpson (float32_is_zero(b) && is_finite(a)));
1178b5ed786fSTaylor Simpson }
1179b5ed786fSTaylor Simpson
check_nan(float32 dst,float32 x,float_status * fp_status)1180b5ed786fSTaylor Simpson static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
1181b5ed786fSTaylor Simpson {
1182b5ed786fSTaylor Simpson float32 ret = dst;
1183b5ed786fSTaylor Simpson if (float32_is_any_nan(x)) {
1184b5ed786fSTaylor Simpson if (extract32(x, 22, 1) == 0) {
1185b5ed786fSTaylor Simpson float_raise(float_flag_invalid, fp_status);
1186b5ed786fSTaylor Simpson }
1187b5ed786fSTaylor Simpson ret = make_float32(0xffffffff); /* nan */
1188b5ed786fSTaylor Simpson }
1189b5ed786fSTaylor Simpson return ret;
1190b5ed786fSTaylor Simpson }
1191b5ed786fSTaylor Simpson
HELPER(sffma_sc)1192b5ed786fSTaylor Simpson float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
1193b5ed786fSTaylor Simpson float32 RsV, float32 RtV, float32 PuV)
1194b5ed786fSTaylor Simpson {
1195b5ed786fSTaylor Simpson size4s_t tmp;
1196b5ed786fSTaylor Simpson arch_fpop_start(env);
1197b5ed786fSTaylor Simpson RxV = check_nan(RxV, RxV, &env->fp_status);
1198b5ed786fSTaylor Simpson RxV = check_nan(RxV, RsV, &env->fp_status);
1199b5ed786fSTaylor Simpson RxV = check_nan(RxV, RtV, &env->fp_status);
1200b5ed786fSTaylor Simpson tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status);
1201b5ed786fSTaylor Simpson if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
1202b5ed786fSTaylor Simpson RxV = tmp;
1203b5ed786fSTaylor Simpson }
1204b5ed786fSTaylor Simpson arch_fpop_end(env);
1205b5ed786fSTaylor Simpson return RxV;
1206b5ed786fSTaylor Simpson }
1207b5ed786fSTaylor Simpson
HELPER(sffms)1208b5ed786fSTaylor Simpson float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
1209b5ed786fSTaylor Simpson float32 RsV, float32 RtV)
1210b5ed786fSTaylor Simpson {
1211b5ed786fSTaylor Simpson float32 neg_RsV;
1212b5ed786fSTaylor Simpson arch_fpop_start(env);
12131a442c09STaylor Simpson neg_RsV = float32_set_sign(RsV, float32_is_neg(RsV) ? 0 : 1);
1214b5ed786fSTaylor Simpson RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status);
1215b5ed786fSTaylor Simpson arch_fpop_end(env);
1216b5ed786fSTaylor Simpson return RxV;
1217b5ed786fSTaylor Simpson }
1218b5ed786fSTaylor Simpson
is_inf_prod(int32_t a,int32_t b)12192d27cebbSTaylor Simpson static bool is_inf_prod(int32_t a, int32_t b)
1220b5ed786fSTaylor Simpson {
1221b5ed786fSTaylor Simpson return (float32_is_infinity(a) && float32_is_infinity(b)) ||
1222b5ed786fSTaylor Simpson (float32_is_infinity(a) && is_finite(b) && !float32_is_zero(b)) ||
1223b5ed786fSTaylor Simpson (float32_is_infinity(b) && is_finite(a) && !float32_is_zero(a));
1224b5ed786fSTaylor Simpson }
1225b5ed786fSTaylor Simpson
HELPER(sffma_lib)1226b5ed786fSTaylor Simpson float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV,
1227b5ed786fSTaylor Simpson float32 RsV, float32 RtV)
1228b5ed786fSTaylor Simpson {
122992cfa25fSTaylor Simpson bool infinp;
123092cfa25fSTaylor Simpson bool infminusinf;
1231b5ed786fSTaylor Simpson float32 tmp;
1232b5ed786fSTaylor Simpson
1233b5ed786fSTaylor Simpson arch_fpop_start(env);
1234b5ed786fSTaylor Simpson set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1235b5ed786fSTaylor Simpson infminusinf = float32_is_infinity(RxV) &&
1236b5ed786fSTaylor Simpson is_inf_prod(RsV, RtV) &&
1237b5ed786fSTaylor Simpson (fGETBIT(31, RsV ^ RxV ^ RtV) != 0);
1238b5ed786fSTaylor Simpson infinp = float32_is_infinity(RxV) ||
1239b5ed786fSTaylor Simpson float32_is_infinity(RtV) ||
1240b5ed786fSTaylor Simpson float32_is_infinity(RsV);
1241b5ed786fSTaylor Simpson RxV = check_nan(RxV, RxV, &env->fp_status);
1242b5ed786fSTaylor Simpson RxV = check_nan(RxV, RsV, &env->fp_status);
1243b5ed786fSTaylor Simpson RxV = check_nan(RxV, RtV, &env->fp_status);
1244b5ed786fSTaylor Simpson tmp = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
1245b5ed786fSTaylor Simpson if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
1246b5ed786fSTaylor Simpson RxV = tmp;
1247b5ed786fSTaylor Simpson }
1248b5ed786fSTaylor Simpson set_float_exception_flags(0, &env->fp_status);
1249b5ed786fSTaylor Simpson if (float32_is_infinity(RxV) && !infinp) {
1250b5ed786fSTaylor Simpson RxV = RxV - 1;
1251b5ed786fSTaylor Simpson }
1252b5ed786fSTaylor Simpson if (infminusinf) {
1253b5ed786fSTaylor Simpson RxV = 0;
1254b5ed786fSTaylor Simpson }
1255b5ed786fSTaylor Simpson arch_fpop_end(env);
1256b5ed786fSTaylor Simpson return RxV;
1257b5ed786fSTaylor Simpson }
1258b5ed786fSTaylor Simpson
HELPER(sffms_lib)1259b5ed786fSTaylor Simpson float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV,
1260b5ed786fSTaylor Simpson float32 RsV, float32 RtV)
1261b5ed786fSTaylor Simpson {
126292cfa25fSTaylor Simpson bool infinp;
126392cfa25fSTaylor Simpson bool infminusinf;
1264b5ed786fSTaylor Simpson float32 tmp;
1265b5ed786fSTaylor Simpson
1266b5ed786fSTaylor Simpson arch_fpop_start(env);
1267b5ed786fSTaylor Simpson set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1268b5ed786fSTaylor Simpson infminusinf = float32_is_infinity(RxV) &&
1269b5ed786fSTaylor Simpson is_inf_prod(RsV, RtV) &&
1270b5ed786fSTaylor Simpson (fGETBIT(31, RsV ^ RxV ^ RtV) == 0);
1271b5ed786fSTaylor Simpson infinp = float32_is_infinity(RxV) ||
1272b5ed786fSTaylor Simpson float32_is_infinity(RtV) ||
1273b5ed786fSTaylor Simpson float32_is_infinity(RsV);
1274b5ed786fSTaylor Simpson RxV = check_nan(RxV, RxV, &env->fp_status);
1275b5ed786fSTaylor Simpson RxV = check_nan(RxV, RsV, &env->fp_status);
1276b5ed786fSTaylor Simpson RxV = check_nan(RxV, RtV, &env->fp_status);
1277b5ed786fSTaylor Simpson float32 minus_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
1278b5ed786fSTaylor Simpson tmp = internal_fmafx(minus_RsV, RtV, RxV, 0, &env->fp_status);
1279b5ed786fSTaylor Simpson if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
1280b5ed786fSTaylor Simpson RxV = tmp;
1281b5ed786fSTaylor Simpson }
1282b5ed786fSTaylor Simpson set_float_exception_flags(0, &env->fp_status);
1283b5ed786fSTaylor Simpson if (float32_is_infinity(RxV) && !infinp) {
1284b5ed786fSTaylor Simpson RxV = RxV - 1;
1285b5ed786fSTaylor Simpson }
1286b5ed786fSTaylor Simpson if (infminusinf) {
1287b5ed786fSTaylor Simpson RxV = 0;
1288b5ed786fSTaylor Simpson }
1289b5ed786fSTaylor Simpson arch_fpop_end(env);
1290b5ed786fSTaylor Simpson return RxV;
1291b5ed786fSTaylor Simpson }
1292b5ed786fSTaylor Simpson
HELPER(dfmpyfix)1293b5ed786fSTaylor Simpson float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV)
1294b5ed786fSTaylor Simpson {
1295b5ed786fSTaylor Simpson int64_t RddV;
1296b5ed786fSTaylor Simpson arch_fpop_start(env);
1297b5ed786fSTaylor Simpson if (float64_is_denormal(RssV) &&
1298b5ed786fSTaylor Simpson (float64_getexp(RttV) >= 512) &&
1299b5ed786fSTaylor Simpson float64_is_normal(RttV)) {
1300b5ed786fSTaylor Simpson RddV = float64_mul(RssV, make_float64(0x4330000000000000),
1301b5ed786fSTaylor Simpson &env->fp_status);
1302b5ed786fSTaylor Simpson } else if (float64_is_denormal(RttV) &&
1303b5ed786fSTaylor Simpson (float64_getexp(RssV) >= 512) &&
1304b5ed786fSTaylor Simpson float64_is_normal(RssV)) {
1305b5ed786fSTaylor Simpson RddV = float64_mul(RssV, make_float64(0x3cb0000000000000),
1306b5ed786fSTaylor Simpson &env->fp_status);
1307b5ed786fSTaylor Simpson } else {
1308b5ed786fSTaylor Simpson RddV = RssV;
1309b5ed786fSTaylor Simpson }
1310b5ed786fSTaylor Simpson arch_fpop_end(env);
1311b5ed786fSTaylor Simpson return RddV;
1312b5ed786fSTaylor Simpson }
1313b5ed786fSTaylor Simpson
HELPER(dfmpyhh)1314b5ed786fSTaylor Simpson float64 HELPER(dfmpyhh)(CPUHexagonState *env, float64 RxxV,
1315b5ed786fSTaylor Simpson float64 RssV, float64 RttV)
1316b5ed786fSTaylor Simpson {
1317b5ed786fSTaylor Simpson arch_fpop_start(env);
1318b5ed786fSTaylor Simpson RxxV = internal_mpyhh(RssV, RttV, RxxV, &env->fp_status);
1319b5ed786fSTaylor Simpson arch_fpop_end(env);
1320b5ed786fSTaylor Simpson return RxxV;
1321b5ed786fSTaylor Simpson }
1322b5ed786fSTaylor Simpson
132333e9ed11STaylor Simpson /* Histogram instructions */
132433e9ed11STaylor Simpson
HELPER(vhist)132533e9ed11STaylor Simpson void HELPER(vhist)(CPUHexagonState *env)
132633e9ed11STaylor Simpson {
132733e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
132833e9ed11STaylor Simpson
132933e9ed11STaylor Simpson for (int lane = 0; lane < 8; lane++) {
133033e9ed11STaylor Simpson for (int i = 0; i < sizeof(MMVector) / 8; ++i) {
133133e9ed11STaylor Simpson unsigned char value = input->ub[(sizeof(MMVector) / 8) * lane + i];
133233e9ed11STaylor Simpson unsigned char regno = value >> 3;
133333e9ed11STaylor Simpson unsigned char element = value & 7;
133433e9ed11STaylor Simpson
133533e9ed11STaylor Simpson env->VRegs[regno].uh[(sizeof(MMVector) / 16) * lane + element]++;
133633e9ed11STaylor Simpson }
133733e9ed11STaylor Simpson }
133833e9ed11STaylor Simpson }
133933e9ed11STaylor Simpson
HELPER(vhistq)134033e9ed11STaylor Simpson void HELPER(vhistq)(CPUHexagonState *env)
134133e9ed11STaylor Simpson {
134233e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
134333e9ed11STaylor Simpson
134433e9ed11STaylor Simpson for (int lane = 0; lane < 8; lane++) {
134533e9ed11STaylor Simpson for (int i = 0; i < sizeof(MMVector) / 8; ++i) {
134633e9ed11STaylor Simpson unsigned char value = input->ub[(sizeof(MMVector) / 8) * lane + i];
134733e9ed11STaylor Simpson unsigned char regno = value >> 3;
134833e9ed11STaylor Simpson unsigned char element = value & 7;
134933e9ed11STaylor Simpson
135033e9ed11STaylor Simpson if (fGETQBIT(env->qtmp, sizeof(MMVector) / 8 * lane + i)) {
135133e9ed11STaylor Simpson env->VRegs[regno].uh[
135233e9ed11STaylor Simpson (sizeof(MMVector) / 16) * lane + element]++;
135333e9ed11STaylor Simpson }
135433e9ed11STaylor Simpson }
135533e9ed11STaylor Simpson }
135633e9ed11STaylor Simpson }
135733e9ed11STaylor Simpson
HELPER(vwhist256)135833e9ed11STaylor Simpson void HELPER(vwhist256)(CPUHexagonState *env)
135933e9ed11STaylor Simpson {
136033e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
136133e9ed11STaylor Simpson
136233e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
136333e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
136433e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
136533e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
136633e9ed11STaylor Simpson unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);
136733e9ed11STaylor Simpson
136833e9ed11STaylor Simpson env->VRegs[vindex].uh[elindex] =
136933e9ed11STaylor Simpson env->VRegs[vindex].uh[elindex] + weight;
137033e9ed11STaylor Simpson }
137133e9ed11STaylor Simpson }
137233e9ed11STaylor Simpson
HELPER(vwhist256q)137333e9ed11STaylor Simpson void HELPER(vwhist256q)(CPUHexagonState *env)
137433e9ed11STaylor Simpson {
137533e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
137633e9ed11STaylor Simpson
137733e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
137833e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
137933e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
138033e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
138133e9ed11STaylor Simpson unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);
138233e9ed11STaylor Simpson
138333e9ed11STaylor Simpson if (fGETQBIT(env->qtmp, 2 * i)) {
138433e9ed11STaylor Simpson env->VRegs[vindex].uh[elindex] =
138533e9ed11STaylor Simpson env->VRegs[vindex].uh[elindex] + weight;
138633e9ed11STaylor Simpson }
138733e9ed11STaylor Simpson }
138833e9ed11STaylor Simpson }
138933e9ed11STaylor Simpson
HELPER(vwhist256_sat)139033e9ed11STaylor Simpson void HELPER(vwhist256_sat)(CPUHexagonState *env)
139133e9ed11STaylor Simpson {
139233e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
139333e9ed11STaylor Simpson
139433e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
139533e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
139633e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
139733e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
139833e9ed11STaylor Simpson unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);
139933e9ed11STaylor Simpson
140033e9ed11STaylor Simpson env->VRegs[vindex].uh[elindex] =
140133e9ed11STaylor Simpson fVSATUH(env->VRegs[vindex].uh[elindex] + weight);
140233e9ed11STaylor Simpson }
140333e9ed11STaylor Simpson }
140433e9ed11STaylor Simpson
HELPER(vwhist256q_sat)140533e9ed11STaylor Simpson void HELPER(vwhist256q_sat)(CPUHexagonState *env)
140633e9ed11STaylor Simpson {
140733e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
140833e9ed11STaylor Simpson
140933e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
141033e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
141133e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
141233e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
141333e9ed11STaylor Simpson unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);
141433e9ed11STaylor Simpson
141533e9ed11STaylor Simpson if (fGETQBIT(env->qtmp, 2 * i)) {
141633e9ed11STaylor Simpson env->VRegs[vindex].uh[elindex] =
141733e9ed11STaylor Simpson fVSATUH(env->VRegs[vindex].uh[elindex] + weight);
141833e9ed11STaylor Simpson }
141933e9ed11STaylor Simpson }
142033e9ed11STaylor Simpson }
142133e9ed11STaylor Simpson
HELPER(vwhist128)142233e9ed11STaylor Simpson void HELPER(vwhist128)(CPUHexagonState *env)
142333e9ed11STaylor Simpson {
142433e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
142533e9ed11STaylor Simpson
142633e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
142733e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
142833e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
142933e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
143033e9ed11STaylor Simpson unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);
143133e9ed11STaylor Simpson
143233e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] =
143333e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] + weight;
143433e9ed11STaylor Simpson }
143533e9ed11STaylor Simpson }
143633e9ed11STaylor Simpson
HELPER(vwhist128q)143733e9ed11STaylor Simpson void HELPER(vwhist128q)(CPUHexagonState *env)
143833e9ed11STaylor Simpson {
143933e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
144033e9ed11STaylor Simpson
144133e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
144233e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
144333e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
144433e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
144533e9ed11STaylor Simpson unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);
144633e9ed11STaylor Simpson
144733e9ed11STaylor Simpson if (fGETQBIT(env->qtmp, 2 * i)) {
144833e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] =
144933e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] + weight;
145033e9ed11STaylor Simpson }
145133e9ed11STaylor Simpson }
145233e9ed11STaylor Simpson }
145333e9ed11STaylor Simpson
HELPER(vwhist128m)145433e9ed11STaylor Simpson void HELPER(vwhist128m)(CPUHexagonState *env, int32_t uiV)
145533e9ed11STaylor Simpson {
145633e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
145733e9ed11STaylor Simpson
145833e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
145933e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
146033e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
146133e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
146233e9ed11STaylor Simpson unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);
146333e9ed11STaylor Simpson
146433e9ed11STaylor Simpson if ((bucket & 1) == uiV) {
146533e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] =
146633e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] + weight;
146733e9ed11STaylor Simpson }
146833e9ed11STaylor Simpson }
146933e9ed11STaylor Simpson }
147033e9ed11STaylor Simpson
HELPER(vwhist128qm)147133e9ed11STaylor Simpson void HELPER(vwhist128qm)(CPUHexagonState *env, int32_t uiV)
147233e9ed11STaylor Simpson {
147333e9ed11STaylor Simpson MMVector *input = &env->tmp_VRegs[0];
147433e9ed11STaylor Simpson
147533e9ed11STaylor Simpson for (int i = 0; i < (sizeof(MMVector) / 2); i++) {
147633e9ed11STaylor Simpson unsigned int bucket = fGETUBYTE(0, input->h[i]);
147733e9ed11STaylor Simpson unsigned int weight = fGETUBYTE(1, input->h[i]);
147833e9ed11STaylor Simpson unsigned int vindex = (bucket >> 3) & 0x1F;
147933e9ed11STaylor Simpson unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);
148033e9ed11STaylor Simpson
148133e9ed11STaylor Simpson if (((bucket & 1) == uiV) && fGETQBIT(env->qtmp, 2 * i)) {
148233e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] =
148333e9ed11STaylor Simpson env->VRegs[vindex].uw[elindex] + weight;
148433e9ed11STaylor Simpson }
148533e9ed11STaylor Simpson }
148633e9ed11STaylor Simpson }
148733e9ed11STaylor Simpson
1488b5ed786fSTaylor Simpson /* These macros can be referenced in the generated helper functions */
1489b5ed786fSTaylor Simpson #define warn(...) /* Nothing */
1490b5ed786fSTaylor Simpson #define fatal(...) g_assert_not_reached();
1491b5ed786fSTaylor Simpson
1492b5ed786fSTaylor Simpson #define BOGUS_HELPER(tag) \
1493b5ed786fSTaylor Simpson printf("ERROR: bogus helper: " #tag "\n")
1494b5ed786fSTaylor Simpson
1495b5ed786fSTaylor Simpson #include "helper_funcs_generated.c.inc"
1496