translate.c (1dcdc92c72af5311666df64f5f04d6600af262ed) translate.c (1e536334ccb0a1606f814a38a4996b3b818e9fab)
1/*
2 * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
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.
8 *

--- 195 unchanged lines hidden (view full) ---

204 return check_for_attrib(pkt, A_CONDEXEC);
205}
206
207static bool need_pred_written(Packet *pkt)
208{
209 return check_for_attrib(pkt, A_WRITES_PRED_REG);
210}
211
1/*
2 * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
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.
8 *

--- 195 unchanged lines hidden (view full) ---

204 return check_for_attrib(pkt, A_CONDEXEC);
205}
206
207static bool need_pred_written(Packet *pkt)
208{
209 return check_for_attrib(pkt, A_WRITES_PRED_REG);
210}
211
212static void gen_start_packet(DisasContext *ctx, Packet *pkt)
212static void gen_start_packet(DisasContext *ctx)
213{
213{
214 Packet *pkt = ctx->pkt;
214 target_ulong next_PC = ctx->base.pc_next + pkt->encod_pkt_size_in_bytes;
215 int i;
216
217 /* Clear out the disassembly context */
218 ctx->reg_log_idx = 0;
219 bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
220 ctx->preg_log_idx = 0;
221 bitmap_zero(ctx->pregs_written, NUM_PREGS);

--- 33 unchanged lines hidden (view full) ---

255 }
256
257 if (pkt->pkt_has_hvx) {
258 tcg_gen_movi_tl(hex_VRegs_updated, 0);
259 tcg_gen_movi_tl(hex_QRegs_updated, 0);
260 }
261}
262
215 target_ulong next_PC = ctx->base.pc_next + pkt->encod_pkt_size_in_bytes;
216 int i;
217
218 /* Clear out the disassembly context */
219 ctx->reg_log_idx = 0;
220 bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
221 ctx->preg_log_idx = 0;
222 bitmap_zero(ctx->pregs_written, NUM_PREGS);

--- 33 unchanged lines hidden (view full) ---

256 }
257
258 if (pkt->pkt_has_hvx) {
259 tcg_gen_movi_tl(hex_VRegs_updated, 0);
260 tcg_gen_movi_tl(hex_QRegs_updated, 0);
261 }
262}
263
263bool is_gather_store_insn(Insn *insn, Packet *pkt)
264bool is_gather_store_insn(DisasContext *ctx)
264{
265{
266 Packet *pkt = ctx->pkt;
267 Insn *insn = ctx->insn;
265 if (GET_ATTRIB(insn->opcode, A_CVI_NEW) &&
266 insn->new_value_producer_slot == 1) {
267 /* Look for gather instruction */
268 for (int i = 0; i < pkt->num_insns; i++) {
269 Insn *in = &pkt->insn[i];
270 if (GET_ATTRIB(in->opcode, A_CVI_GATHER) && in->slot == 1) {
271 return true;
272 }
273 }
274 }
275 return false;
276}
277
278/*
279 * The LOG_*_WRITE macros mark most of the writes in a packet
280 * However, there are some implicit writes marked as attributes
281 * of the applicable instructions.
282 */
268 if (GET_ATTRIB(insn->opcode, A_CVI_NEW) &&
269 insn->new_value_producer_slot == 1) {
270 /* Look for gather instruction */
271 for (int i = 0; i < pkt->num_insns; i++) {
272 Insn *in = &pkt->insn[i];
273 if (GET_ATTRIB(in->opcode, A_CVI_GATHER) && in->slot == 1) {
274 return true;
275 }
276 }
277 }
278 return false;
279}
280
281/*
282 * The LOG_*_WRITE macros mark most of the writes in a packet
283 * However, there are some implicit writes marked as attributes
284 * of the applicable instructions.
285 */
283static void mark_implicit_reg_write(DisasContext *ctx, Insn *insn,
284 int attrib, int rnum)
286static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum)
285{
287{
286 if (GET_ATTRIB(insn->opcode, attrib)) {
288 uint16_t opcode = ctx->insn->opcode;
289 if (GET_ATTRIB(opcode, attrib)) {
287 /*
288 * USR is used to set overflow and FP exceptions,
289 * so treat it as conditional
290 */
290 /*
291 * USR is used to set overflow and FP exceptions,
292 * so treat it as conditional
293 */
291 bool is_predicated = GET_ATTRIB(insn->opcode, A_CONDEXEC) ||
294 bool is_predicated = GET_ATTRIB(opcode, A_CONDEXEC) ||
292 rnum == HEX_REG_USR;
293 if (is_predicated && !is_preloaded(ctx, rnum)) {
294 tcg_gen_mov_tl(hex_new_value[rnum], hex_gpr[rnum]);
295 }
296
297 ctx_log_reg_write(ctx, rnum);
298 }
299}
300
295 rnum == HEX_REG_USR;
296 if (is_predicated && !is_preloaded(ctx, rnum)) {
297 tcg_gen_mov_tl(hex_new_value[rnum], hex_gpr[rnum]);
298 }
299
300 ctx_log_reg_write(ctx, rnum);
301 }
302}
303
301static void mark_implicit_pred_write(DisasContext *ctx, Insn *insn,
302 int attrib, int pnum)
304static void mark_implicit_pred_write(DisasContext *ctx, int attrib, int pnum)
303{
305{
304 if (GET_ATTRIB(insn->opcode, attrib)) {
306 if (GET_ATTRIB(ctx->insn->opcode, attrib)) {
305 ctx_log_pred_write(ctx, pnum);
306 }
307}
308
307 ctx_log_pred_write(ctx, pnum);
308 }
309}
310
309static void mark_implicit_reg_writes(DisasContext *ctx, Insn *insn)
311static void mark_implicit_reg_writes(DisasContext *ctx)
310{
312{
311 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_FP, HEX_REG_FP);
312 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SP, HEX_REG_SP);
313 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LR, HEX_REG_LR);
314 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC0, HEX_REG_LC0);
315 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0);
316 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1);
317 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1);
318 mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_USR, HEX_REG_USR);
319 mark_implicit_reg_write(ctx, insn, A_FPOP, HEX_REG_USR);
313 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_FP, HEX_REG_FP);
314 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SP, HEX_REG_SP);
315 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LR, HEX_REG_LR);
316 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LC0, HEX_REG_LC0);
317 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0);
318 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1);
319 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1);
320 mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_USR, HEX_REG_USR);
321 mark_implicit_reg_write(ctx, A_FPOP, HEX_REG_USR);
320}
321
322}
323
322static void mark_implicit_pred_writes(DisasContext *ctx, Insn *insn)
324static void mark_implicit_pred_writes(DisasContext *ctx)
323{
325{
324 mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P0, 0);
325 mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P1, 1);
326 mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P2, 2);
327 mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P3, 3);
326 mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P0, 0);
327 mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P1, 1);
328 mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P2, 2);
329 mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P3, 3);
328}
329
330}
331
330static void mark_store_width(DisasContext *ctx, Insn *insn)
332static void mark_store_width(DisasContext *ctx)
331{
333{
332 uint16_t opcode = insn->opcode;
333 uint32_t slot = insn->slot;
334 uint16_t opcode = ctx->insn->opcode;
335 uint32_t slot = ctx->insn->slot;
334 uint8_t width = 0;
335
336 if (GET_ATTRIB(opcode, A_SCALAR_STORE)) {
337 if (GET_ATTRIB(opcode, A_MEMSIZE_1B)) {
338 width |= 1;
339 }
340 if (GET_ATTRIB(opcode, A_MEMSIZE_2B)) {
341 width |= 2;

--- 4 unchanged lines hidden (view full) ---

346 if (GET_ATTRIB(opcode, A_MEMSIZE_8B)) {
347 width |= 8;
348 }
349 tcg_debug_assert(is_power_of_2(width));
350 ctx->store_width[slot] = width;
351 }
352}
353
336 uint8_t width = 0;
337
338 if (GET_ATTRIB(opcode, A_SCALAR_STORE)) {
339 if (GET_ATTRIB(opcode, A_MEMSIZE_1B)) {
340 width |= 1;
341 }
342 if (GET_ATTRIB(opcode, A_MEMSIZE_2B)) {
343 width |= 2;

--- 4 unchanged lines hidden (view full) ---

348 if (GET_ATTRIB(opcode, A_MEMSIZE_8B)) {
349 width |= 8;
350 }
351 tcg_debug_assert(is_power_of_2(width));
352 ctx->store_width[slot] = width;
353 }
354}
355
354static void gen_insn(CPUHexagonState *env, DisasContext *ctx,
355 Insn *insn, Packet *pkt)
356static void gen_insn(DisasContext *ctx)
356{
357{
357 if (insn->generate) {
358 mark_implicit_reg_writes(ctx, insn);
359 insn->generate(env, ctx, insn, pkt);
360 mark_implicit_pred_writes(ctx, insn);
361 mark_store_width(ctx, insn);
358 if (ctx->insn->generate) {
359 mark_implicit_reg_writes(ctx);
360 ctx->insn->generate(ctx);
361 mark_implicit_pred_writes(ctx);
362 mark_store_width(ctx);
362 } else {
363 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_OPCODE);
364 }
365}
366
367/*
368 * Helpers for generating the packet commit
369 */
370static void gen_reg_writes(DisasContext *ctx)
371{
372 int i;
373
374 for (i = 0; i < ctx->reg_log_idx; i++) {
375 int reg_num = ctx->reg_log[i];
376
377 tcg_gen_mov_tl(hex_gpr[reg_num], hex_new_value[reg_num]);
378 }
379}
380
363 } else {
364 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_OPCODE);
365 }
366}
367
368/*
369 * Helpers for generating the packet commit
370 */
371static void gen_reg_writes(DisasContext *ctx)
372{
373 int i;
374
375 for (i = 0; i < ctx->reg_log_idx; i++) {
376 int reg_num = ctx->reg_log[i];
377
378 tcg_gen_mov_tl(hex_gpr[reg_num], hex_new_value[reg_num]);
379 }
380}
381
381static void gen_pred_writes(DisasContext *ctx, Packet *pkt)
382static void gen_pred_writes(DisasContext *ctx)
382{
383 int i;
384
385 /* Early exit if the log is empty */
386 if (!ctx->preg_log_idx) {
387 return;
388 }
389
390 /*
391 * Only endloop instructions will conditionally
392 * write a predicate. If there are no endloop
393 * instructions, we can use the non-conditional
394 * write of the predicates.
395 */
383{
384 int i;
385
386 /* Early exit if the log is empty */
387 if (!ctx->preg_log_idx) {
388 return;
389 }
390
391 /*
392 * Only endloop instructions will conditionally
393 * write a predicate. If there are no endloop
394 * instructions, we can use the non-conditional
395 * write of the predicates.
396 */
396 if (pkt->pkt_has_endloop) {
397 if (ctx->pkt->pkt_has_endloop) {
397 TCGv zero = tcg_constant_tl(0);
398 TCGv pred_written = tcg_temp_new();
399 for (i = 0; i < ctx->preg_log_idx; i++) {
400 int pred_num = ctx->preg_log[i];
401
402 tcg_gen_andi_tl(pred_written, hex_pred_written, 1 << pred_num);
403 tcg_gen_movcond_tl(TCG_COND_NE, hex_pred[pred_num],
404 pred_written, zero,

--- 29 unchanged lines hidden (view full) ---

434 if (pkt->insn[i].slot == slot_num) {
435 return GET_ATTRIB(pkt->insn[i].opcode, A_CONDEXEC);
436 }
437 }
438 /* If we get to here, we didn't find an instruction in the requested slot */
439 g_assert_not_reached();
440}
441
398 TCGv zero = tcg_constant_tl(0);
399 TCGv pred_written = tcg_temp_new();
400 for (i = 0; i < ctx->preg_log_idx; i++) {
401 int pred_num = ctx->preg_log[i];
402
403 tcg_gen_andi_tl(pred_written, hex_pred_written, 1 << pred_num);
404 tcg_gen_movcond_tl(TCG_COND_NE, hex_pred[pred_num],
405 pred_written, zero,

--- 29 unchanged lines hidden (view full) ---

435 if (pkt->insn[i].slot == slot_num) {
436 return GET_ATTRIB(pkt->insn[i].opcode, A_CONDEXEC);
437 }
438 }
439 /* If we get to here, we didn't find an instruction in the requested slot */
440 g_assert_not_reached();
441}
442
442void process_store(DisasContext *ctx, Packet *pkt, int slot_num)
443void process_store(DisasContext *ctx, int slot_num)
443{
444{
444 bool is_predicated = slot_is_predicated(pkt, slot_num);
445 bool is_predicated = slot_is_predicated(ctx->pkt, slot_num);
445 TCGLabel *label_end = NULL;
446
447 /*
448 * We may have already processed this store
449 * See CHECK_NOSHUF in macros.h
450 */
451 if (slot_num == 1 && ctx->s1_store_processed) {
452 return;

--- 59 unchanged lines hidden (view full) ---

512 }
513 tcg_temp_free(address);
514 }
515 if (is_predicated) {
516 gen_set_label(label_end);
517 }
518}
519
446 TCGLabel *label_end = NULL;
447
448 /*
449 * We may have already processed this store
450 * See CHECK_NOSHUF in macros.h
451 */
452 if (slot_num == 1 && ctx->s1_store_processed) {
453 return;

--- 59 unchanged lines hidden (view full) ---

513 }
514 tcg_temp_free(address);
515 }
516 if (is_predicated) {
517 gen_set_label(label_end);
518 }
519}
520
520static void process_store_log(DisasContext *ctx, Packet *pkt)
521static void process_store_log(DisasContext *ctx)
521{
522 /*
523 * When a packet has two stores, the hardware processes
524 * slot 1 and then slot 0. This will be important when
525 * the memory accesses overlap.
526 */
522{
523 /*
524 * When a packet has two stores, the hardware processes
525 * slot 1 and then slot 0. This will be important when
526 * the memory accesses overlap.
527 */
528 Packet *pkt = ctx->pkt;
527 if (pkt->pkt_has_store_s1) {
528 g_assert(!pkt->pkt_has_dczeroa);
529 if (pkt->pkt_has_store_s1) {
530 g_assert(!pkt->pkt_has_dczeroa);
529 process_store(ctx, pkt, 1);
531 process_store(ctx, 1);
530 }
531 if (pkt->pkt_has_store_s0) {
532 g_assert(!pkt->pkt_has_dczeroa);
532 }
533 if (pkt->pkt_has_store_s0) {
534 g_assert(!pkt->pkt_has_dczeroa);
533 process_store(ctx, pkt, 0);
535 process_store(ctx, 0);
534 }
535}
536
537/* Zero out a 32-bit cache line */
536 }
537}
538
539/* Zero out a 32-bit cache line */
538static void process_dczeroa(DisasContext *ctx, Packet *pkt)
540static void process_dczeroa(DisasContext *ctx)
539{
541{
540 if (pkt->pkt_has_dczeroa) {
542 if (ctx->pkt->pkt_has_dczeroa) {
541 /* Store 32 bytes of zero starting at (addr & ~0x1f) */
542 TCGv addr = tcg_temp_new();
543 TCGv_i64 zero = tcg_constant_i64(0);
544
545 tcg_gen_andi_tl(addr, hex_dczero_addr, ~0x1f);
546 tcg_gen_qemu_st64(zero, addr, ctx->mem_idx);
547 tcg_gen_addi_tl(addr, addr, 8);
548 tcg_gen_qemu_st64(zero, addr, ctx->mem_idx);

--- 13 unchanged lines hidden (view full) ---

562 int opcode = pkt->insn[i].opcode;
563 if (GET_ATTRIB(opcode, A_CVI) && GET_ATTRIB(opcode, A_STORE)) {
564 return true;
565 }
566 }
567 return false;
568}
569
543 /* Store 32 bytes of zero starting at (addr & ~0x1f) */
544 TCGv addr = tcg_temp_new();
545 TCGv_i64 zero = tcg_constant_i64(0);
546
547 tcg_gen_andi_tl(addr, hex_dczero_addr, ~0x1f);
548 tcg_gen_qemu_st64(zero, addr, ctx->mem_idx);
549 tcg_gen_addi_tl(addr, addr, 8);
550 tcg_gen_qemu_st64(zero, addr, ctx->mem_idx);

--- 13 unchanged lines hidden (view full) ---

564 int opcode = pkt->insn[i].opcode;
565 if (GET_ATTRIB(opcode, A_CVI) && GET_ATTRIB(opcode, A_STORE)) {
566 return true;
567 }
568 }
569 return false;
570}
571
570static void gen_commit_hvx(DisasContext *ctx, Packet *pkt)
572static void gen_commit_hvx(DisasContext *ctx)
571{
572 int i;
573
574 /*
575 * for (i = 0; i < ctx->vreg_log_idx; i++) {
576 * int rnum = ctx->vreg_log[i];
577 * if (ctx->vreg_is_predicated[i]) {
578 * if (env->VRegs_updated & (1 << rnum)) {

--- 53 unchanged lines hidden (view full) ---

632 tcg_temp_free(cmp);
633 tcg_gen_gvec_mov(MO_64, dstoff, srcoff, size, size);
634 gen_set_label(label_skip);
635 } else {
636 tcg_gen_gvec_mov(MO_64, dstoff, srcoff, size, size);
637 }
638 }
639
573{
574 int i;
575
576 /*
577 * for (i = 0; i < ctx->vreg_log_idx; i++) {
578 * int rnum = ctx->vreg_log[i];
579 * if (ctx->vreg_is_predicated[i]) {
580 * if (env->VRegs_updated & (1 << rnum)) {

--- 53 unchanged lines hidden (view full) ---

634 tcg_temp_free(cmp);
635 tcg_gen_gvec_mov(MO_64, dstoff, srcoff, size, size);
636 gen_set_label(label_skip);
637 } else {
638 tcg_gen_gvec_mov(MO_64, dstoff, srcoff, size, size);
639 }
640 }
641
640 if (pkt_has_hvx_store(pkt)) {
642 if (pkt_has_hvx_store(ctx->pkt)) {
641 gen_helper_commit_hvx_stores(cpu_env);
642 }
643}
644
643 gen_helper_commit_hvx_stores(cpu_env);
644 }
645}
646
645static void update_exec_counters(DisasContext *ctx, Packet *pkt)
647static void update_exec_counters(DisasContext *ctx)
646{
648{
649 Packet *pkt = ctx->pkt;
647 int num_insns = pkt->num_insns;
648 int num_real_insns = 0;
649 int num_hvx_insns = 0;
650
651 for (int i = 0; i < num_insns; i++) {
652 if (!pkt->insn[i].is_endloop &&
653 !pkt->insn[i].part1 &&
654 !GET_ATTRIB(pkt->insn[i].opcode, A_IT_NOP)) {

--- 4 unchanged lines hidden (view full) ---

659 }
660 }
661
662 ctx->num_packets++;
663 ctx->num_insns += num_real_insns;
664 ctx->num_hvx_insns += num_hvx_insns;
665}
666
650 int num_insns = pkt->num_insns;
651 int num_real_insns = 0;
652 int num_hvx_insns = 0;
653
654 for (int i = 0; i < num_insns; i++) {
655 if (!pkt->insn[i].is_endloop &&
656 !pkt->insn[i].part1 &&
657 !GET_ATTRIB(pkt->insn[i].opcode, A_IT_NOP)) {

--- 4 unchanged lines hidden (view full) ---

662 }
663 }
664
665 ctx->num_packets++;
666 ctx->num_insns += num_real_insns;
667 ctx->num_hvx_insns += num_hvx_insns;
668}
669
667static void gen_commit_packet(CPUHexagonState *env, DisasContext *ctx,
668 Packet *pkt)
670static void gen_commit_packet(DisasContext *ctx)
669{
670 /*
671 * If there is more than one store in a packet, make sure they are all OK
672 * before proceeding with the rest of the packet commit.
673 *
674 * dczeroa has to be the only store operation in the packet, so we go
675 * ahead and process that first.
676 *
677 * When there is an HVX store, there can also be a scalar store in either
678 * slot 0 or slot1, so we create a mask for the helper to indicate what
679 * work to do.
680 *
681 * When there are two scalar stores, we probe the one in slot 0.
682 *
683 * Note that we don't call the probe helper for packets with only one
684 * store. Therefore, we call process_store_log before anything else
685 * involved in committing the packet.
686 */
671{
672 /*
673 * If there is more than one store in a packet, make sure they are all OK
674 * before proceeding with the rest of the packet commit.
675 *
676 * dczeroa has to be the only store operation in the packet, so we go
677 * ahead and process that first.
678 *
679 * When there is an HVX store, there can also be a scalar store in either
680 * slot 0 or slot1, so we create a mask for the helper to indicate what
681 * work to do.
682 *
683 * When there are two scalar stores, we probe the one in slot 0.
684 *
685 * Note that we don't call the probe helper for packets with only one
686 * store. Therefore, we call process_store_log before anything else
687 * involved in committing the packet.
688 */
689 Packet *pkt = ctx->pkt;
687 bool has_store_s0 = pkt->pkt_has_store_s0;
688 bool has_store_s1 = (pkt->pkt_has_store_s1 && !ctx->s1_store_processed);
689 bool has_hvx_store = pkt_has_hvx_store(pkt);
690 if (pkt->pkt_has_dczeroa) {
691 /*
692 * The dczeroa will be the store in slot 0, check that we don't have
693 * a store in slot 1 or an HVX store.
694 */
695 g_assert(!has_store_s1 && !has_hvx_store);
690 bool has_store_s0 = pkt->pkt_has_store_s0;
691 bool has_store_s1 = (pkt->pkt_has_store_s1 && !ctx->s1_store_processed);
692 bool has_hvx_store = pkt_has_hvx_store(pkt);
693 if (pkt->pkt_has_dczeroa) {
694 /*
695 * The dczeroa will be the store in slot 0, check that we don't have
696 * a store in slot 1 or an HVX store.
697 */
698 g_assert(!has_store_s1 && !has_hvx_store);
696 process_dczeroa(ctx, pkt);
699 process_dczeroa(ctx);
697 } else if (has_hvx_store) {
698 TCGv mem_idx = tcg_constant_tl(ctx->mem_idx);
699
700 if (!has_store_s0 && !has_store_s1) {
701 gen_helper_probe_hvx_stores(cpu_env, mem_idx);
702 } else {
703 int mask = 0;
704 TCGv mask_tcgv;

--- 14 unchanged lines hidden (view full) ---

719 /*
720 * process_store_log will execute the slot 1 store first,
721 * so we only have to probe the store in slot 0
722 */
723 TCGv mem_idx = tcg_constant_tl(ctx->mem_idx);
724 gen_helper_probe_pkt_scalar_store_s0(cpu_env, mem_idx);
725 }
726
700 } else if (has_hvx_store) {
701 TCGv mem_idx = tcg_constant_tl(ctx->mem_idx);
702
703 if (!has_store_s0 && !has_store_s1) {
704 gen_helper_probe_hvx_stores(cpu_env, mem_idx);
705 } else {
706 int mask = 0;
707 TCGv mask_tcgv;

--- 14 unchanged lines hidden (view full) ---

722 /*
723 * process_store_log will execute the slot 1 store first,
724 * so we only have to probe the store in slot 0
725 */
726 TCGv mem_idx = tcg_constant_tl(ctx->mem_idx);
727 gen_helper_probe_pkt_scalar_store_s0(cpu_env, mem_idx);
728 }
729
727 process_store_log(ctx, pkt);
730 process_store_log(ctx);
728
729 gen_reg_writes(ctx);
731
732 gen_reg_writes(ctx);
730 gen_pred_writes(ctx, pkt);
733 gen_pred_writes(ctx);
731 if (pkt->pkt_has_hvx) {
734 if (pkt->pkt_has_hvx) {
732 gen_commit_hvx(ctx, pkt);
735 gen_commit_hvx(ctx);
733 }
736 }
734 update_exec_counters(ctx, pkt);
737 update_exec_counters(ctx);
735 if (HEX_DEBUG) {
736 TCGv has_st0 =
737 tcg_constant_tl(pkt->pkt_has_store_s0 && !pkt->pkt_has_dczeroa);
738 TCGv has_st1 =
739 tcg_constant_tl(pkt->pkt_has_store_s1 && !pkt->pkt_has_dczeroa);
740
741 /* Handy place to set a breakpoint at the end of execution */
742 gen_helper_debug_commit_end(cpu_env, has_st0, has_st1);
743 }
744
745 if (pkt->vhist_insn != NULL) {
746 ctx->pre_commit = false;
738 if (HEX_DEBUG) {
739 TCGv has_st0 =
740 tcg_constant_tl(pkt->pkt_has_store_s0 && !pkt->pkt_has_dczeroa);
741 TCGv has_st1 =
742 tcg_constant_tl(pkt->pkt_has_store_s1 && !pkt->pkt_has_dczeroa);
743
744 /* Handy place to set a breakpoint at the end of execution */
745 gen_helper_debug_commit_end(cpu_env, has_st0, has_st1);
746 }
747
748 if (pkt->vhist_insn != NULL) {
749 ctx->pre_commit = false;
747 pkt->vhist_insn->generate(env, ctx, pkt->vhist_insn, pkt);
750 ctx->insn = pkt->vhist_insn;
751 pkt->vhist_insn->generate(ctx);
748 }
749
750 if (pkt->pkt_has_cof) {
751 gen_end_tb(ctx);
752 }
753}
754
755static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx)

--- 6 unchanged lines hidden (view full) ---

762 nwords = read_packet_words(env, ctx, words);
763 if (!nwords) {
764 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET);
765 return;
766 }
767
768 if (decode_packet(nwords, words, &pkt, false) > 0) {
769 HEX_DEBUG_PRINT_PKT(&pkt);
752 }
753
754 if (pkt->pkt_has_cof) {
755 gen_end_tb(ctx);
756 }
757}
758
759static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx)

--- 6 unchanged lines hidden (view full) ---

766 nwords = read_packet_words(env, ctx, words);
767 if (!nwords) {
768 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET);
769 return;
770 }
771
772 if (decode_packet(nwords, words, &pkt, false) > 0) {
773 HEX_DEBUG_PRINT_PKT(&pkt);
770 gen_start_packet(ctx, &pkt);
774 ctx->pkt = &pkt;
775 gen_start_packet(ctx);
771 for (i = 0; i < pkt.num_insns; i++) {
776 for (i = 0; i < pkt.num_insns; i++) {
772 gen_insn(env, ctx, &pkt.insn[i], &pkt);
777 ctx->insn = &pkt.insn[i];
778 gen_insn(ctx);
773 }
779 }
774 gen_commit_packet(env, ctx, &pkt);
780 gen_commit_packet(ctx);
775 ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
776 } else {
777 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET);
778 }
779}
780
781static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
782 CPUState *cs)

--- 215 unchanged lines hidden ---
781 ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
782 } else {
783 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET);
784 }
785}
786
787static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
788 CPUState *cs)

--- 215 unchanged lines hidden ---