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 --- |