2 * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 #include "qemu/osdep.h"
20 #include "exec/exec-all.h"
21 #include "exec/cpu_ldst.h"
22 #include "exec/helper-proto.h"
23 #include "fpu/softfloat.h"
28 #include "hex_arch_types.h"
30 #include "mmvec/mmvec.h"
31 #include "mmvec/macros.h"
32 #include "op_helper.h"
33 #include "translate.h"
36 #define SF_MANTBITS 23
38 /* Exceptions processing helpers */
40 void do_raise_exception_err(CPUHexagonState
*env
,
44 CPUState
*cs
= env_cpu(env
);
45 qemu_log_mask(CPU_LOG_INT
, "%s: %d\n", __func__
, exception
);
46 cs
->exception_index
= exception
;
47 cpu_loop_exit_restore(cs
, pc
);
50 G_NORETURN
void HELPER(raise_exception
)(CPUHexagonState
*env
, uint32_t excp
)
52 do_raise_exception_err(env
, excp
, 0);
55 void log_store32(CPUHexagonState
*env
, target_ulong addr
,
56 target_ulong val
, int width
, int slot
)
58 HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx
59 ", %" PRId32
" [0x08%" PRIx32
"])\n",
60 width
, addr
, val
, val
);
61 env
->mem_log_stores
[slot
].va
= addr
;
62 env
->mem_log_stores
[slot
].width
= width
;
63 env
->mem_log_stores
[slot
].data32
= val
;
66 void log_store64(CPUHexagonState
*env
, target_ulong addr
,
67 int64_t val
, int width
, int slot
)
69 HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx
70 ", %" PRId64
" [0x016%" PRIx64
"])\n",
71 width
, addr
, val
, val
);
72 env
->mem_log_stores
[slot
].va
= addr
;
73 env
->mem_log_stores
[slot
].width
= width
;
74 env
->mem_log_stores
[slot
].data64
= val
;
77 /* Handy place to set a breakpoint */
78 void HELPER(debug_start_packet
)(CPUHexagonState
*env
)
80 HEX_DEBUG_LOG("Start packet: pc = 0x" TARGET_FMT_lx
"\n",
81 env
->gpr
[HEX_REG_PC
]);
83 for (int i
= 0; i
< TOTAL_PER_THREAD_REGS
; i
++) {
84 env
->reg_written
[i
] = 0;
88 /* Checks for bookkeeping errors between disassembly context and runtime */
89 void HELPER(debug_check_store_width
)(CPUHexagonState
*env
, int slot
, int check
)
91 if (env
->mem_log_stores
[slot
].width
!= check
) {
92 HEX_DEBUG_LOG("ERROR: %d != %d\n",
93 env
->mem_log_stores
[slot
].width
, check
);
94 g_assert_not_reached();
98 static void commit_store(CPUHexagonState
*env
, int slot_num
, uintptr_t ra
)
100 uint8_t width
= env
->mem_log_stores
[slot_num
].width
;
101 target_ulong va
= env
->mem_log_stores
[slot_num
].va
;
105 cpu_stb_data_ra(env
, va
, env
->mem_log_stores
[slot_num
].data32
, ra
);
108 cpu_stw_data_ra(env
, va
, env
->mem_log_stores
[slot_num
].data32
, ra
);
111 cpu_stl_data_ra(env
, va
, env
->mem_log_stores
[slot_num
].data32
, ra
);
114 cpu_stq_data_ra(env
, va
, env
->mem_log_stores
[slot_num
].data64
, ra
);
117 g_assert_not_reached();
121 void HELPER(commit_store
)(CPUHexagonState
*env
, int slot_num
)
123 uintptr_t ra
= GETPC();
124 commit_store(env
, slot_num
, ra
);
127 void HELPER(gather_store
)(CPUHexagonState
*env
, uint32_t addr
, int slot
)
129 mem_gather_store(env
, addr
, slot
);
132 void HELPER(commit_hvx_stores
)(CPUHexagonState
*env
)
134 uintptr_t ra
= GETPC();
136 /* Normal (possibly masked) vector store */
137 for (int i
= 0; i
< VSTORES_MAX
; i
++) {
138 if (env
->vstore_pending
[i
]) {
139 env
->vstore_pending
[i
] = 0;
140 target_ulong va
= env
->vstore
[i
].va
;
141 int size
= env
->vstore
[i
].size
;
142 for (int j
= 0; j
< size
; j
++) {
143 if (test_bit(j
, env
->vstore
[i
].mask
)) {
144 cpu_stb_data_ra(env
, va
+ j
, env
->vstore
[i
].data
.ub
[j
], ra
);
151 if (env
->vtcm_pending
) {
152 env
->vtcm_pending
= false;
153 if (env
->vtcm_log
.op
) {
154 /* Need to perform the scatter read/modify/write at commit time */
155 if (env
->vtcm_log
.op_size
== 2) {
156 SCATTER_OP_WRITE_TO_MEM(uint16_t);
157 } else if (env
->vtcm_log
.op_size
== 4) {
158 /* Word Scatter += */
159 SCATTER_OP_WRITE_TO_MEM(uint32_t);
161 g_assert_not_reached();
164 for (int i
= 0; i
< sizeof(MMVector
); i
++) {
165 if (test_bit(i
, env
->vtcm_log
.mask
)) {
166 cpu_stb_data_ra(env
, env
->vtcm_log
.va
[i
],
167 env
->vtcm_log
.data
.ub
[i
], ra
);
168 clear_bit(i
, env
->vtcm_log
.mask
);
169 env
->vtcm_log
.data
.ub
[i
] = 0;
177 static void print_store(CPUHexagonState
*env
, int slot
)
179 if (!(env
->slot_cancelled
& (1 << slot
))) {
180 uint8_t width
= env
->mem_log_stores
[slot
].width
;
182 uint32_t data
= env
->mem_log_stores
[slot
].data32
& 0xff;
183 HEX_DEBUG_LOG("\tmemb[0x" TARGET_FMT_lx
"] = %" PRId32
184 " (0x%02" PRIx32
")\n",
185 env
->mem_log_stores
[slot
].va
, data
, data
);
186 } else if (width
== 2) {
187 uint32_t data
= env
->mem_log_stores
[slot
].data32
& 0xffff;
188 HEX_DEBUG_LOG("\tmemh[0x" TARGET_FMT_lx
"] = %" PRId32
189 " (0x%04" PRIx32
")\n",
190 env
->mem_log_stores
[slot
].va
, data
, data
);
191 } else if (width
== 4) {
192 uint32_t data
= env
->mem_log_stores
[slot
].data32
;
193 HEX_DEBUG_LOG("\tmemw[0x" TARGET_FMT_lx
"] = %" PRId32
194 " (0x%08" PRIx32
")\n",
195 env
->mem_log_stores
[slot
].va
, data
, data
);
196 } else if (width
== 8) {
197 HEX_DEBUG_LOG("\tmemd[0x" TARGET_FMT_lx
"] = %" PRId64
198 " (0x%016" PRIx64
")\n",
199 env
->mem_log_stores
[slot
].va
,
200 env
->mem_log_stores
[slot
].data64
,
201 env
->mem_log_stores
[slot
].data64
);
203 HEX_DEBUG_LOG("\tBad store width %d\n", width
);
204 g_assert_not_reached();
209 /* This function is a handy place to set a breakpoint */
210 void HELPER(debug_commit_end
)(CPUHexagonState
*env
, uint32_t this_PC
,
211 int pred_written
, int has_st0
, int has_st1
)
213 bool reg_printed
= false;
214 bool pred_printed
= false;
217 HEX_DEBUG_LOG("Packet committed: pc = 0x" TARGET_FMT_lx
"\n", this_PC
);
218 HEX_DEBUG_LOG("slot_cancelled = %d\n", env
->slot_cancelled
);
220 for (i
= 0; i
< TOTAL_PER_THREAD_REGS
; i
++) {
221 if (env
->reg_written
[i
]) {
223 HEX_DEBUG_LOG("Regs written\n");
226 HEX_DEBUG_LOG("\tr%d = " TARGET_FMT_ld
" (0x" TARGET_FMT_lx
")\n",
227 i
, env
->gpr
[i
], env
->gpr
[i
]);
231 for (i
= 0; i
< NUM_PREGS
; i
++) {
232 if (pred_written
& (1 << i
)) {
234 HEX_DEBUG_LOG("Predicates written\n");
237 HEX_DEBUG_LOG("\tp%d = 0x" TARGET_FMT_lx
"\n",
242 if (has_st0
|| has_st1
) {
243 HEX_DEBUG_LOG("Stores\n");
252 HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx
"\n", env
->gpr
[HEX_REG_PC
]);
253 HEX_DEBUG_LOG("Exec counters: pkt = " TARGET_FMT_lx
254 ", insn = " TARGET_FMT_lx
255 ", hvx = " TARGET_FMT_lx
"\n",
256 env
->gpr
[HEX_REG_QEMU_PKT_CNT
],
257 env
->gpr
[HEX_REG_QEMU_INSN_CNT
],
258 env
->gpr
[HEX_REG_QEMU_HVX_CNT
]);
262 int32_t HELPER(fcircadd
)(int32_t RxV
, int32_t offset
, int32_t M
, int32_t CS
)
264 uint32_t K_const
= extract32(M
, 24, 4);
265 uint32_t length
= extract32(M
, 0, 17);
266 uint32_t new_ptr
= RxV
+ offset
;
270 if (K_const
== 0 && length
>= 4) {
272 end_addr
= start_addr
+ length
;
275 * Versions v3 and earlier used the K value to specify a power-of-2 size
276 * 2^(K+2) that is greater than the buffer length
278 int32_t mask
= (1 << (K_const
+ 2)) - 1;
279 start_addr
= RxV
& (~mask
);
280 end_addr
= start_addr
| length
;
283 if (new_ptr
>= end_addr
) {
285 } else if (new_ptr
< start_addr
) {
292 uint32_t HELPER(fbrev
)(uint32_t addr
)
295 * Bit reverse the low 16 bits of the address
297 return deposit32(addr
, 0, 16, revbit16(addr
));
300 static float32
build_float32(uint8_t sign
, uint32_t exp
, uint32_t mant
)
304 ((exp
& 0xff) << SF_MANTBITS
) |
305 (mant
& ((1 << SF_MANTBITS
) - 1)));
309 * sfrecipa, sfinvsqrta have two 32-bit results
310 * r0,p0=sfrecipa(r1,r2)
311 * r0,p0=sfinvsqrta(r1)
313 * Since helpers can only return a single value, we pack the two results
314 * into a 64-bit value.
316 uint64_t HELPER(sfrecipa
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
325 arch_fpop_start(env
);
326 if (arch_sf_recip_common(&RsV
, &RtV
, &RdV
, &adjust
, &env
->fp_status
)) {
328 idx
= (RtV
>> 16) & 0x7f;
329 mant
= (recip_lookup_table
[idx
] << 15) | 1;
330 exp
= SF_BIAS
- (float32_getexp(RtV
) - SF_BIAS
) - 1;
331 RdV
= build_float32(extract32(RtV
, 31, 1), exp
, mant
);
334 return ((uint64_t)RdV
<< 32) | PeV
;
337 uint64_t HELPER(sfinvsqrta
)(CPUHexagonState
*env
, float32 RsV
)
346 arch_fpop_start(env
);
347 if (arch_sf_invsqrt_common(&RsV
, &RdV
, &adjust
, &env
->fp_status
)) {
349 idx
= (RsV
>> 17) & 0x7f;
350 mant
= (invsqrt_lookup_table
[idx
] << 15);
351 exp
= SF_BIAS
- ((float32_getexp(RsV
) - SF_BIAS
) >> 1) - 1;
352 RdV
= build_float32(extract32(RsV
, 31, 1), exp
, mant
);
355 return ((uint64_t)RdV
<< 32) | PeV
;
358 int64_t HELPER(vacsh_val
)(CPUHexagonState
*env
,
359 int64_t RxxV
, int64_t RssV
, int64_t RttV
,
360 uint32_t pkt_need_commit
)
362 for (int i
= 0; i
< 4; i
++) {
363 int xv
= sextract64(RxxV
, i
* 16, 16);
364 int sv
= sextract64(RssV
, i
* 16, 16);
365 int tv
= sextract64(RttV
, i
* 16, 16);
369 max
= xv
> sv
? xv
: sv
;
370 /* Note that fSATH can set the OVF bit in usr */
371 RxxV
= deposit64(RxxV
, i
* 16, 16, fSATH(max
));
376 int32_t HELPER(vacsh_pred
)(CPUHexagonState
*env
,
377 int64_t RxxV
, int64_t RssV
, int64_t RttV
)
380 for (int i
= 0; i
< 4; i
++) {
381 int xv
= sextract64(RxxV
, i
* 16, 16);
382 int sv
= sextract64(RssV
, i
* 16, 16);
383 int tv
= sextract64(RttV
, i
* 16, 16);
386 PeV
= deposit32(PeV
, i
* 2, 1, (xv
> sv
));
387 PeV
= deposit32(PeV
, i
* 2 + 1, 1, (xv
> sv
));
392 int64_t HELPER(cabacdecbin_val
)(int64_t RssV
, int64_t RttV
)
403 state
= fEXTRACTU_RANGE(fGETWORD(1, RttV
), 5, 0);
404 valMPS
= fEXTRACTU_RANGE(fGETWORD(1, RttV
), 8, 8);
405 bitpos
= fEXTRACTU_RANGE(fGETWORD(0, RttV
), 4, 0);
406 range
= fGETWORD(0, RssV
);
407 offset
= fGETWORD(1, RssV
);
412 rLPS
= rLPS_table_64x4
[state
][(range
>> 29) & 3];
413 rLPS
= rLPS
<< 23; /* left aligned */
416 rMPS
= (range
& 0xff800000) - rLPS
;
418 /* most probable region */
420 RddV
= AC_next_state_MPS_64
[state
];
421 fINSERT_RANGE(RddV
, 8, 8, valMPS
);
422 fINSERT_RANGE(RddV
, 31, 23, (rMPS
>> 23));
423 fSETWORD(1, RddV
, offset
);
425 /* least probable region */
427 RddV
= AC_next_state_LPS_64
[state
];
428 fINSERT_RANGE(RddV
, 8, 8, ((!state
) ? (1 - valMPS
) : (valMPS
)));
429 fINSERT_RANGE(RddV
, 31, 23, (rLPS
>> 23));
430 fSETWORD(1, RddV
, (offset
- rMPS
));
435 int32_t HELPER(cabacdecbin_pred
)(int64_t RssV
, int64_t RttV
)
446 state
= fEXTRACTU_RANGE(fGETWORD(1, RttV
), 5, 0);
447 valMPS
= fEXTRACTU_RANGE(fGETWORD(1, RttV
), 8, 8);
448 bitpos
= fEXTRACTU_RANGE(fGETWORD(0, RttV
), 4, 0);
449 range
= fGETWORD(0, RssV
);
450 offset
= fGETWORD(1, RssV
);
455 rLPS
= rLPS_table_64x4
[state
][(range
>> 29) & 3];
456 rLPS
= rLPS
<< 23; /* left aligned */
459 rMPS
= (range
& 0xff800000) - rLPS
;
461 /* most probable region */
466 /* least probable region */
473 static void probe_store(CPUHexagonState
*env
, int slot
, int mmu_idx
,
474 bool is_predicated
, uintptr_t retaddr
)
476 if (!is_predicated
|| !(env
->slot_cancelled
& (1 << slot
))) {
477 size1u_t width
= env
->mem_log_stores
[slot
].width
;
478 target_ulong va
= env
->mem_log_stores
[slot
].va
;
479 probe_write(env
, va
, width
, mmu_idx
, retaddr
);
484 * Called from a mem_noshuf packet to make sure the load doesn't
487 void HELPER(probe_noshuf_load
)(CPUHexagonState
*env
, target_ulong va
,
488 int size
, int mmu_idx
)
490 uintptr_t retaddr
= GETPC();
491 probe_read(env
, va
, size
, mmu_idx
, retaddr
);
494 /* Called during packet commit when there are two scalar stores */
495 void HELPER(probe_pkt_scalar_store_s0
)(CPUHexagonState
*env
, int args
)
497 int mmu_idx
= FIELD_EX32(args
, PROBE_PKT_SCALAR_STORE_S0
, MMU_IDX
);
499 FIELD_EX32(args
, PROBE_PKT_SCALAR_STORE_S0
, IS_PREDICATED
);
500 uintptr_t ra
= GETPC();
501 probe_store(env
, 0, mmu_idx
, is_predicated
, ra
);
504 static void probe_hvx_stores(CPUHexagonState
*env
, int mmu_idx
,
507 /* Normal (possibly masked) vector store */
508 for (int i
= 0; i
< VSTORES_MAX
; i
++) {
509 if (env
->vstore_pending
[i
]) {
510 target_ulong va
= env
->vstore
[i
].va
;
511 int size
= env
->vstore
[i
].size
;
512 for (int j
= 0; j
< size
; j
++) {
513 if (test_bit(j
, env
->vstore
[i
].mask
)) {
514 probe_write(env
, va
+ j
, 1, mmu_idx
, retaddr
);
521 if (env
->vtcm_pending
) {
522 if (env
->vtcm_log
.op
) {
523 /* Need to perform the scatter read/modify/write at commit time */
524 if (env
->vtcm_log
.op_size
== 2) {
525 SCATTER_OP_PROBE_MEM(size2u_t
, mmu_idx
, retaddr
);
526 } else if (env
->vtcm_log
.op_size
== 4) {
527 /* Word Scatter += */
528 SCATTER_OP_PROBE_MEM(size4u_t
, mmu_idx
, retaddr
);
530 g_assert_not_reached();
533 for (int i
= 0; i
< sizeof(MMVector
); i
++) {
534 if (test_bit(i
, env
->vtcm_log
.mask
)) {
535 probe_write(env
, env
->vtcm_log
.va
[i
], 1, mmu_idx
, retaddr
);
543 void HELPER(probe_hvx_stores
)(CPUHexagonState
*env
, int mmu_idx
)
545 uintptr_t retaddr
= GETPC();
546 probe_hvx_stores(env
, mmu_idx
, retaddr
);
549 void HELPER(probe_pkt_scalar_hvx_stores
)(CPUHexagonState
*env
, int mask
)
551 bool has_st0
= FIELD_EX32(mask
, PROBE_PKT_SCALAR_HVX_STORES
, HAS_ST0
);
552 bool has_st1
= FIELD_EX32(mask
, PROBE_PKT_SCALAR_HVX_STORES
, HAS_ST1
);
553 bool has_hvx_stores
=
554 FIELD_EX32(mask
, PROBE_PKT_SCALAR_HVX_STORES
, HAS_HVX_STORES
);
555 bool s0_is_pred
= FIELD_EX32(mask
, PROBE_PKT_SCALAR_HVX_STORES
, S0_IS_PRED
);
556 bool s1_is_pred
= FIELD_EX32(mask
, PROBE_PKT_SCALAR_HVX_STORES
, S1_IS_PRED
);
557 int mmu_idx
= FIELD_EX32(mask
, PROBE_PKT_SCALAR_HVX_STORES
, MMU_IDX
);
558 uintptr_t ra
= GETPC();
561 probe_store(env
, 0, mmu_idx
, s0_is_pred
, ra
);
564 probe_store(env
, 1, mmu_idx
, s1_is_pred
, ra
);
566 if (has_hvx_stores
) {
567 probe_hvx_stores(env
, mmu_idx
, ra
);
571 #ifndef CONFIG_HEXAGON_IDEF_PARSER
574 * Section 5.5 of the Hexagon V67 Programmer's Reference Manual
576 * If the load is in slot 0 and there is a store in slot1 (that
577 * wasn't cancelled), we have to do the store first.
579 static void check_noshuf(CPUHexagonState
*env
, bool pkt_has_store_s1
,
580 uint32_t slot
, target_ulong vaddr
, int size
,
583 if (slot
== 0 && pkt_has_store_s1
&&
584 ((env
->slot_cancelled
& (1 << 1)) == 0)) {
585 probe_read(env
, vaddr
, size
, MMU_USER_IDX
, ra
);
586 commit_store(env
, 1, ra
);
592 float64
HELPER(conv_sf2df
)(CPUHexagonState
*env
, float32 RsV
)
595 arch_fpop_start(env
);
596 out_f64
= float32_to_float64(RsV
, &env
->fp_status
);
601 float32
HELPER(conv_df2sf
)(CPUHexagonState
*env
, float64 RssV
)
604 arch_fpop_start(env
);
605 out_f32
= float64_to_float32(RssV
, &env
->fp_status
);
610 float32
HELPER(conv_uw2sf
)(CPUHexagonState
*env
, int32_t RsV
)
613 arch_fpop_start(env
);
614 RdV
= uint32_to_float32(RsV
, &env
->fp_status
);
619 float64
HELPER(conv_uw2df
)(CPUHexagonState
*env
, int32_t RsV
)
622 arch_fpop_start(env
);
623 RddV
= uint32_to_float64(RsV
, &env
->fp_status
);
628 float32
HELPER(conv_w2sf
)(CPUHexagonState
*env
, int32_t RsV
)
631 arch_fpop_start(env
);
632 RdV
= int32_to_float32(RsV
, &env
->fp_status
);
637 float64
HELPER(conv_w2df
)(CPUHexagonState
*env
, int32_t RsV
)
640 arch_fpop_start(env
);
641 RddV
= int32_to_float64(RsV
, &env
->fp_status
);
646 float32
HELPER(conv_ud2sf
)(CPUHexagonState
*env
, int64_t RssV
)
649 arch_fpop_start(env
);
650 RdV
= uint64_to_float32(RssV
, &env
->fp_status
);
655 float64
HELPER(conv_ud2df
)(CPUHexagonState
*env
, int64_t RssV
)
658 arch_fpop_start(env
);
659 RddV
= uint64_to_float64(RssV
, &env
->fp_status
);
664 float32
HELPER(conv_d2sf
)(CPUHexagonState
*env
, int64_t RssV
)
667 arch_fpop_start(env
);
668 RdV
= int64_to_float32(RssV
, &env
->fp_status
);
673 float64
HELPER(conv_d2df
)(CPUHexagonState
*env
, int64_t RssV
)
676 arch_fpop_start(env
);
677 RddV
= int64_to_float64(RssV
, &env
->fp_status
);
682 uint32_t HELPER(conv_sf2uw
)(CPUHexagonState
*env
, float32 RsV
)
685 arch_fpop_start(env
);
686 /* Hexagon checks the sign before rounding */
687 if (float32_is_neg(RsV
) && !float32_is_any_nan(RsV
)) {
688 float_raise(float_flag_invalid
, &env
->fp_status
);
691 RdV
= float32_to_uint32(RsV
, &env
->fp_status
);
697 int32_t HELPER(conv_sf2w
)(CPUHexagonState
*env
, float32 RsV
)
700 arch_fpop_start(env
);
701 /* Hexagon returns -1 for NaN */
702 if (float32_is_any_nan(RsV
)) {
703 float_raise(float_flag_invalid
, &env
->fp_status
);
706 RdV
= float32_to_int32(RsV
, &env
->fp_status
);
712 uint64_t HELPER(conv_sf2ud
)(CPUHexagonState
*env
, float32 RsV
)
715 arch_fpop_start(env
);
716 /* Hexagon checks the sign before rounding */
717 if (float32_is_neg(RsV
) && !float32_is_any_nan(RsV
)) {
718 float_raise(float_flag_invalid
, &env
->fp_status
);
721 RddV
= float32_to_uint64(RsV
, &env
->fp_status
);
727 int64_t HELPER(conv_sf2d
)(CPUHexagonState
*env
, float32 RsV
)
730 arch_fpop_start(env
);
731 /* Hexagon returns -1 for NaN */
732 if (float32_is_any_nan(RsV
)) {
733 float_raise(float_flag_invalid
, &env
->fp_status
);
736 RddV
= float32_to_int64(RsV
, &env
->fp_status
);
742 uint32_t HELPER(conv_df2uw
)(CPUHexagonState
*env
, float64 RssV
)
745 arch_fpop_start(env
);
746 /* Hexagon checks the sign before rounding */
747 if (float64_is_neg(RssV
) && !float64_is_any_nan(RssV
)) {
748 float_raise(float_flag_invalid
, &env
->fp_status
);
751 RdV
= float64_to_uint32(RssV
, &env
->fp_status
);
757 int32_t HELPER(conv_df2w
)(CPUHexagonState
*env
, float64 RssV
)
760 arch_fpop_start(env
);
761 /* Hexagon returns -1 for NaN */
762 if (float64_is_any_nan(RssV
)) {
763 float_raise(float_flag_invalid
, &env
->fp_status
);
766 RdV
= float64_to_int32(RssV
, &env
->fp_status
);
772 uint64_t HELPER(conv_df2ud
)(CPUHexagonState
*env
, float64 RssV
)
775 arch_fpop_start(env
);
776 /* Hexagon checks the sign before rounding */
777 if (float64_is_neg(RssV
) && !float64_is_any_nan(RssV
)) {
778 float_raise(float_flag_invalid
, &env
->fp_status
);
781 RddV
= float64_to_uint64(RssV
, &env
->fp_status
);
787 int64_t HELPER(conv_df2d
)(CPUHexagonState
*env
, float64 RssV
)
790 arch_fpop_start(env
);
791 /* Hexagon returns -1 for NaN */
792 if (float64_is_any_nan(RssV
)) {
793 float_raise(float_flag_invalid
, &env
->fp_status
);
796 RddV
= float64_to_int64(RssV
, &env
->fp_status
);
802 uint32_t HELPER(conv_sf2uw_chop
)(CPUHexagonState
*env
, float32 RsV
)
805 arch_fpop_start(env
);
806 /* Hexagon checks the sign before rounding */
807 if (float32_is_neg(RsV
) && !float32_is_any_nan(RsV
)) {
808 float_raise(float_flag_invalid
, &env
->fp_status
);
811 RdV
= float32_to_uint32_round_to_zero(RsV
, &env
->fp_status
);
817 int32_t HELPER(conv_sf2w_chop
)(CPUHexagonState
*env
, float32 RsV
)
820 arch_fpop_start(env
);
821 /* Hexagon returns -1 for NaN */
822 if (float32_is_any_nan(RsV
)) {
823 float_raise(float_flag_invalid
, &env
->fp_status
);
826 RdV
= float32_to_int32_round_to_zero(RsV
, &env
->fp_status
);
832 uint64_t HELPER(conv_sf2ud_chop
)(CPUHexagonState
*env
, float32 RsV
)
835 arch_fpop_start(env
);
836 /* Hexagon checks the sign before rounding */
837 if (float32_is_neg(RsV
) && !float32_is_any_nan(RsV
)) {
838 float_raise(float_flag_invalid
, &env
->fp_status
);
841 RddV
= float32_to_uint64_round_to_zero(RsV
, &env
->fp_status
);
847 int64_t HELPER(conv_sf2d_chop
)(CPUHexagonState
*env
, float32 RsV
)
850 arch_fpop_start(env
);
851 /* Hexagon returns -1 for NaN */
852 if (float32_is_any_nan(RsV
)) {
853 float_raise(float_flag_invalid
, &env
->fp_status
);
856 RddV
= float32_to_int64_round_to_zero(RsV
, &env
->fp_status
);
862 uint32_t HELPER(conv_df2uw_chop
)(CPUHexagonState
*env
, float64 RssV
)
865 arch_fpop_start(env
);
866 /* Hexagon checks the sign before rounding */
867 if (float64_is_neg(RssV
) && !float64_is_any_nan(RssV
)) {
868 float_raise(float_flag_invalid
, &env
->fp_status
);
871 RdV
= float64_to_uint32_round_to_zero(RssV
, &env
->fp_status
);
877 int32_t HELPER(conv_df2w_chop
)(CPUHexagonState
*env
, float64 RssV
)
880 arch_fpop_start(env
);
881 /* Hexagon returns -1 for NaN */
882 if (float64_is_any_nan(RssV
)) {
883 float_raise(float_flag_invalid
, &env
->fp_status
);
886 RdV
= float64_to_int32_round_to_zero(RssV
, &env
->fp_status
);
892 uint64_t HELPER(conv_df2ud_chop
)(CPUHexagonState
*env
, float64 RssV
)
895 arch_fpop_start(env
);
896 /* Hexagon checks the sign before rounding */
897 if (float64_is_neg(RssV
) && !float64_is_any_nan(RssV
)) {
898 float_raise(float_flag_invalid
, &env
->fp_status
);
901 RddV
= float64_to_uint64_round_to_zero(RssV
, &env
->fp_status
);
907 int64_t HELPER(conv_df2d_chop
)(CPUHexagonState
*env
, float64 RssV
)
910 arch_fpop_start(env
);
911 /* Hexagon returns -1 for NaN */
912 if (float64_is_any_nan(RssV
)) {
913 float_raise(float_flag_invalid
, &env
->fp_status
);
916 RddV
= float64_to_int64_round_to_zero(RssV
, &env
->fp_status
);
922 float32
HELPER(sfadd
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
925 arch_fpop_start(env
);
926 RdV
= float32_add(RsV
, RtV
, &env
->fp_status
);
931 float32
HELPER(sfsub
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
934 arch_fpop_start(env
);
935 RdV
= float32_sub(RsV
, RtV
, &env
->fp_status
);
940 int32_t HELPER(sfcmpeq
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
943 arch_fpop_start(env
);
944 PdV
= f8BITSOF(float32_eq_quiet(RsV
, RtV
, &env
->fp_status
));
949 int32_t HELPER(sfcmpgt
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
953 arch_fpop_start(env
);
954 cmp
= float32_compare_quiet(RsV
, RtV
, &env
->fp_status
);
955 PdV
= f8BITSOF(cmp
== float_relation_greater
);
960 int32_t HELPER(sfcmpge
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
964 arch_fpop_start(env
);
965 cmp
= float32_compare_quiet(RsV
, RtV
, &env
->fp_status
);
966 PdV
= f8BITSOF(cmp
== float_relation_greater
||
967 cmp
== float_relation_equal
);
972 int32_t HELPER(sfcmpuo
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
975 arch_fpop_start(env
);
976 PdV
= f8BITSOF(float32_unordered_quiet(RsV
, RtV
, &env
->fp_status
));
981 float32
HELPER(sfmax
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
984 arch_fpop_start(env
);
985 RdV
= float32_maximum_number(RsV
, RtV
, &env
->fp_status
);
990 float32
HELPER(sfmin
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
993 arch_fpop_start(env
);
994 RdV
= float32_minimum_number(RsV
, RtV
, &env
->fp_status
);
999 int32_t HELPER(sfclass
)(CPUHexagonState
*env
, float32 RsV
, int32_t uiV
)
1002 arch_fpop_start(env
);
1003 if (fGETBIT(0, uiV
) && float32_is_zero(RsV
)) {
1006 if (fGETBIT(1, uiV
) && float32_is_normal(RsV
)) {
1009 if (fGETBIT(2, uiV
) && float32_is_denormal(RsV
)) {
1012 if (fGETBIT(3, uiV
) && float32_is_infinity(RsV
)) {
1015 if (fGETBIT(4, uiV
) && float32_is_any_nan(RsV
)) {
1018 set_float_exception_flags(0, &env
->fp_status
);
1023 float32
HELPER(sffixupn
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
1027 arch_fpop_start(env
);
1028 arch_sf_recip_common(&RsV
, &RtV
, &RdV
, &adjust
, &env
->fp_status
);
1034 float32
HELPER(sffixupd
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
1038 arch_fpop_start(env
);
1039 arch_sf_recip_common(&RsV
, &RtV
, &RdV
, &adjust
, &env
->fp_status
);
1045 float32
HELPER(sffixupr
)(CPUHexagonState
*env
, float32 RsV
)
1049 arch_fpop_start(env
);
1050 arch_sf_invsqrt_common(&RsV
, &RdV
, &adjust
, &env
->fp_status
);
1056 float64
HELPER(dfadd
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1059 arch_fpop_start(env
);
1060 RddV
= float64_add(RssV
, RttV
, &env
->fp_status
);
1065 float64
HELPER(dfsub
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1068 arch_fpop_start(env
);
1069 RddV
= float64_sub(RssV
, RttV
, &env
->fp_status
);
1074 float64
HELPER(dfmax
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1077 arch_fpop_start(env
);
1078 RddV
= float64_maximum_number(RssV
, RttV
, &env
->fp_status
);
1083 float64
HELPER(dfmin
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1086 arch_fpop_start(env
);
1087 RddV
= float64_minimum_number(RssV
, RttV
, &env
->fp_status
);
1092 int32_t HELPER(dfcmpeq
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1095 arch_fpop_start(env
);
1096 PdV
= f8BITSOF(float64_eq_quiet(RssV
, RttV
, &env
->fp_status
));
1101 int32_t HELPER(dfcmpgt
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1105 arch_fpop_start(env
);
1106 cmp
= float64_compare_quiet(RssV
, RttV
, &env
->fp_status
);
1107 PdV
= f8BITSOF(cmp
== float_relation_greater
);
1112 int32_t HELPER(dfcmpge
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1116 arch_fpop_start(env
);
1117 cmp
= float64_compare_quiet(RssV
, RttV
, &env
->fp_status
);
1118 PdV
= f8BITSOF(cmp
== float_relation_greater
||
1119 cmp
== float_relation_equal
);
1124 int32_t HELPER(dfcmpuo
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1127 arch_fpop_start(env
);
1128 PdV
= f8BITSOF(float64_unordered_quiet(RssV
, RttV
, &env
->fp_status
));
1133 int32_t HELPER(dfclass
)(CPUHexagonState
*env
, float64 RssV
, int32_t uiV
)
1136 arch_fpop_start(env
);
1137 if (fGETBIT(0, uiV
) && float64_is_zero(RssV
)) {
1140 if (fGETBIT(1, uiV
) && float64_is_normal(RssV
)) {
1143 if (fGETBIT(2, uiV
) && float64_is_denormal(RssV
)) {
1146 if (fGETBIT(3, uiV
) && float64_is_infinity(RssV
)) {
1149 if (fGETBIT(4, uiV
) && float64_is_any_nan(RssV
)) {
1152 set_float_exception_flags(0, &env
->fp_status
);
1157 float32
HELPER(sfmpy
)(CPUHexagonState
*env
, float32 RsV
, float32 RtV
)
1160 arch_fpop_start(env
);
1161 RdV
= internal_mpyf(RsV
, RtV
, &env
->fp_status
);
1166 float32
HELPER(sffma
)(CPUHexagonState
*env
, float32 RxV
,
1167 float32 RsV
, float32 RtV
)
1169 arch_fpop_start(env
);
1170 RxV
= internal_fmafx(RsV
, RtV
, RxV
, 0, &env
->fp_status
);
1175 static bool is_zero_prod(float32 a
, float32 b
)
1177 return ((float32_is_zero(a
) && is_finite(b
)) ||
1178 (float32_is_zero(b
) && is_finite(a
)));
1181 static float32
check_nan(float32 dst
, float32 x
, float_status
*fp_status
)
1184 if (float32_is_any_nan(x
)) {
1185 if (extract32(x
, 22, 1) == 0) {
1186 float_raise(float_flag_invalid
, fp_status
);
1188 ret
= make_float32(0xffffffff); /* nan */
1193 float32
HELPER(sffma_sc
)(CPUHexagonState
*env
, float32 RxV
,
1194 float32 RsV
, float32 RtV
, float32 PuV
)
1197 arch_fpop_start(env
);
1198 RxV
= check_nan(RxV
, RxV
, &env
->fp_status
);
1199 RxV
= check_nan(RxV
, RsV
, &env
->fp_status
);
1200 RxV
= check_nan(RxV
, RtV
, &env
->fp_status
);
1201 tmp
= internal_fmafx(RsV
, RtV
, RxV
, fSXTN(8, 64, PuV
), &env
->fp_status
);
1202 if (!(float32_is_zero(RxV
) && is_zero_prod(RsV
, RtV
))) {
1209 float32
HELPER(sffms
)(CPUHexagonState
*env
, float32 RxV
,
1210 float32 RsV
, float32 RtV
)
1213 arch_fpop_start(env
);
1214 neg_RsV
= float32_set_sign(RsV
, float32_is_neg(RsV
) ? 0 : 1);
1215 RxV
= internal_fmafx(neg_RsV
, RtV
, RxV
, 0, &env
->fp_status
);
1220 static bool is_inf_prod(int32_t a
, int32_t b
)
1222 return (float32_is_infinity(a
) && float32_is_infinity(b
)) ||
1223 (float32_is_infinity(a
) && is_finite(b
) && !float32_is_zero(b
)) ||
1224 (float32_is_infinity(b
) && is_finite(a
) && !float32_is_zero(a
));
1227 float32
HELPER(sffma_lib
)(CPUHexagonState
*env
, float32 RxV
,
1228 float32 RsV
, float32 RtV
)
1234 arch_fpop_start(env
);
1235 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
1236 infminusinf
= float32_is_infinity(RxV
) &&
1237 is_inf_prod(RsV
, RtV
) &&
1238 (fGETBIT(31, RsV
^ RxV
^ RtV
) != 0);
1239 infinp
= float32_is_infinity(RxV
) ||
1240 float32_is_infinity(RtV
) ||
1241 float32_is_infinity(RsV
);
1242 RxV
= check_nan(RxV
, RxV
, &env
->fp_status
);
1243 RxV
= check_nan(RxV
, RsV
, &env
->fp_status
);
1244 RxV
= check_nan(RxV
, RtV
, &env
->fp_status
);
1245 tmp
= internal_fmafx(RsV
, RtV
, RxV
, 0, &env
->fp_status
);
1246 if (!(float32_is_zero(RxV
) && is_zero_prod(RsV
, RtV
))) {
1249 set_float_exception_flags(0, &env
->fp_status
);
1250 if (float32_is_infinity(RxV
) && !infinp
) {
1260 float32
HELPER(sffms_lib
)(CPUHexagonState
*env
, float32 RxV
,
1261 float32 RsV
, float32 RtV
)
1267 arch_fpop_start(env
);
1268 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
1269 infminusinf
= float32_is_infinity(RxV
) &&
1270 is_inf_prod(RsV
, RtV
) &&
1271 (fGETBIT(31, RsV
^ RxV
^ RtV
) == 0);
1272 infinp
= float32_is_infinity(RxV
) ||
1273 float32_is_infinity(RtV
) ||
1274 float32_is_infinity(RsV
);
1275 RxV
= check_nan(RxV
, RxV
, &env
->fp_status
);
1276 RxV
= check_nan(RxV
, RsV
, &env
->fp_status
);
1277 RxV
= check_nan(RxV
, RtV
, &env
->fp_status
);
1278 float32 minus_RsV
= float32_sub(float32_zero
, RsV
, &env
->fp_status
);
1279 tmp
= internal_fmafx(minus_RsV
, RtV
, RxV
, 0, &env
->fp_status
);
1280 if (!(float32_is_zero(RxV
) && is_zero_prod(RsV
, RtV
))) {
1283 set_float_exception_flags(0, &env
->fp_status
);
1284 if (float32_is_infinity(RxV
) && !infinp
) {
1294 float64
HELPER(dfmpyfix
)(CPUHexagonState
*env
, float64 RssV
, float64 RttV
)
1297 arch_fpop_start(env
);
1298 if (float64_is_denormal(RssV
) &&
1299 (float64_getexp(RttV
) >= 512) &&
1300 float64_is_normal(RttV
)) {
1301 RddV
= float64_mul(RssV
, make_float64(0x4330000000000000),
1303 } else if (float64_is_denormal(RttV
) &&
1304 (float64_getexp(RssV
) >= 512) &&
1305 float64_is_normal(RssV
)) {
1306 RddV
= float64_mul(RssV
, make_float64(0x3cb0000000000000),
1315 float64
HELPER(dfmpyhh
)(CPUHexagonState
*env
, float64 RxxV
,
1316 float64 RssV
, float64 RttV
)
1318 arch_fpop_start(env
);
1319 RxxV
= internal_mpyhh(RssV
, RttV
, RxxV
, &env
->fp_status
);
1324 /* Histogram instructions */
1326 void HELPER(vhist
)(CPUHexagonState
*env
)
1328 MMVector
*input
= &env
->tmp_VRegs
[0];
1330 for (int lane
= 0; lane
< 8; lane
++) {
1331 for (int i
= 0; i
< sizeof(MMVector
) / 8; ++i
) {
1332 unsigned char value
= input
->ub
[(sizeof(MMVector
) / 8) * lane
+ i
];
1333 unsigned char regno
= value
>> 3;
1334 unsigned char element
= value
& 7;
1336 env
->VRegs
[regno
].uh
[(sizeof(MMVector
) / 16) * lane
+ element
]++;
1341 void HELPER(vhistq
)(CPUHexagonState
*env
)
1343 MMVector
*input
= &env
->tmp_VRegs
[0];
1345 for (int lane
= 0; lane
< 8; lane
++) {
1346 for (int i
= 0; i
< sizeof(MMVector
) / 8; ++i
) {
1347 unsigned char value
= input
->ub
[(sizeof(MMVector
) / 8) * lane
+ i
];
1348 unsigned char regno
= value
>> 3;
1349 unsigned char element
= value
& 7;
1351 if (fGETQBIT(env
->qtmp
, sizeof(MMVector
) / 8 * lane
+ i
)) {
1352 env
->VRegs
[regno
].uh
[
1353 (sizeof(MMVector
) / 16) * lane
+ element
]++;
1359 void HELPER(vwhist256
)(CPUHexagonState
*env
)
1361 MMVector
*input
= &env
->tmp_VRegs
[0];
1363 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1364 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1365 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1366 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1367 unsigned int elindex
= ((i
>> 0) & (~7)) | ((bucket
>> 0) & 7);
1369 env
->VRegs
[vindex
].uh
[elindex
] =
1370 env
->VRegs
[vindex
].uh
[elindex
] + weight
;
1374 void HELPER(vwhist256q
)(CPUHexagonState
*env
)
1376 MMVector
*input
= &env
->tmp_VRegs
[0];
1378 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1379 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1380 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1381 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1382 unsigned int elindex
= ((i
>> 0) & (~7)) | ((bucket
>> 0) & 7);
1384 if (fGETQBIT(env
->qtmp
, 2 * i
)) {
1385 env
->VRegs
[vindex
].uh
[elindex
] =
1386 env
->VRegs
[vindex
].uh
[elindex
] + weight
;
1391 void HELPER(vwhist256_sat
)(CPUHexagonState
*env
)
1393 MMVector
*input
= &env
->tmp_VRegs
[0];
1395 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1396 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1397 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1398 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1399 unsigned int elindex
= ((i
>> 0) & (~7)) | ((bucket
>> 0) & 7);
1401 env
->VRegs
[vindex
].uh
[elindex
] =
1402 fVSATUH(env
->VRegs
[vindex
].uh
[elindex
] + weight
);
1406 void HELPER(vwhist256q_sat
)(CPUHexagonState
*env
)
1408 MMVector
*input
= &env
->tmp_VRegs
[0];
1410 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1411 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1412 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1413 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1414 unsigned int elindex
= ((i
>> 0) & (~7)) | ((bucket
>> 0) & 7);
1416 if (fGETQBIT(env
->qtmp
, 2 * i
)) {
1417 env
->VRegs
[vindex
].uh
[elindex
] =
1418 fVSATUH(env
->VRegs
[vindex
].uh
[elindex
] + weight
);
1423 void HELPER(vwhist128
)(CPUHexagonState
*env
)
1425 MMVector
*input
= &env
->tmp_VRegs
[0];
1427 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1428 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1429 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1430 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1431 unsigned int elindex
= ((i
>> 1) & (~3)) | ((bucket
>> 1) & 3);
1433 env
->VRegs
[vindex
].uw
[elindex
] =
1434 env
->VRegs
[vindex
].uw
[elindex
] + weight
;
1438 void HELPER(vwhist128q
)(CPUHexagonState
*env
)
1440 MMVector
*input
= &env
->tmp_VRegs
[0];
1442 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1443 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1444 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1445 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1446 unsigned int elindex
= ((i
>> 1) & (~3)) | ((bucket
>> 1) & 3);
1448 if (fGETQBIT(env
->qtmp
, 2 * i
)) {
1449 env
->VRegs
[vindex
].uw
[elindex
] =
1450 env
->VRegs
[vindex
].uw
[elindex
] + weight
;
1455 void HELPER(vwhist128m
)(CPUHexagonState
*env
, int32_t uiV
)
1457 MMVector
*input
= &env
->tmp_VRegs
[0];
1459 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1460 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1461 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1462 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1463 unsigned int elindex
= ((i
>> 1) & (~3)) | ((bucket
>> 1) & 3);
1465 if ((bucket
& 1) == uiV
) {
1466 env
->VRegs
[vindex
].uw
[elindex
] =
1467 env
->VRegs
[vindex
].uw
[elindex
] + weight
;
1472 void HELPER(vwhist128qm
)(CPUHexagonState
*env
, int32_t uiV
)
1474 MMVector
*input
= &env
->tmp_VRegs
[0];
1476 for (int i
= 0; i
< (sizeof(MMVector
) / 2); i
++) {
1477 unsigned int bucket
= fGETUBYTE(0, input
->h
[i
]);
1478 unsigned int weight
= fGETUBYTE(1, input
->h
[i
]);
1479 unsigned int vindex
= (bucket
>> 3) & 0x1F;
1480 unsigned int elindex
= ((i
>> 1) & (~3)) | ((bucket
>> 1) & 3);
1482 if (((bucket
& 1) == uiV
) && fGETQBIT(env
->qtmp
, 2 * i
)) {
1483 env
->VRegs
[vindex
].uw
[elindex
] =
1484 env
->VRegs
[vindex
].uw
[elindex
] + weight
;
1489 /* These macros can be referenced in the generated helper functions */
1490 #define warn(...) /* Nothing */
1491 #define fatal(...) g_assert_not_reached();
1493 #define BOGUS_HELPER(tag) \
1494 printf("ERROR: bogus helper: " #tag "\n")
1496 #include "helper_funcs_generated.c.inc"