1 /* 2 * Xtensa ISA: 3 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm 4 * 5 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * * Neither the name of the Open Source and Linux Lab nor the 16 * names of its contributors may be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "qemu/osdep.h" 32 33 #include "cpu.h" 34 #include "exec/exec-all.h" 35 #include "disas/disas.h" 36 #include "tcg/tcg-op.h" 37 #include "qemu/log.h" 38 #include "qemu/qemu-print.h" 39 #include "exec/cpu_ldst.h" 40 #include "semihosting/semihost.h" 41 #include "exec/translator.h" 42 43 #include "exec/helper-proto.h" 44 #include "exec/helper-gen.h" 45 46 #include "trace-tcg.h" 47 #include "exec/log.h" 48 49 50 struct DisasContext { 51 DisasContextBase base; 52 const XtensaConfig *config; 53 uint32_t pc; 54 int cring; 55 int ring; 56 uint32_t lbeg_off; 57 uint32_t lend; 58 59 bool sar_5bit; 60 bool sar_m32_5bit; 61 bool sar_m32_allocated; 62 TCGv_i32 sar_m32; 63 64 unsigned window; 65 unsigned callinc; 66 bool cwoe; 67 68 bool debug; 69 bool icount; 70 TCGv_i32 next_icount; 71 72 unsigned cpenable; 73 74 uint32_t op_flags; 75 xtensa_insnbuf_word insnbuf[MAX_INSNBUF_LENGTH]; 76 xtensa_insnbuf_word slotbuf[MAX_INSNBUF_LENGTH]; 77 }; 78 79 static TCGv_i32 cpu_pc; 80 static TCGv_i32 cpu_R[16]; 81 static TCGv_i32 cpu_FR[16]; 82 static TCGv_i64 cpu_FRD[16]; 83 static TCGv_i32 cpu_MR[4]; 84 static TCGv_i32 cpu_BR[16]; 85 static TCGv_i32 cpu_BR4[4]; 86 static TCGv_i32 cpu_BR8[2]; 87 static TCGv_i32 cpu_SR[256]; 88 static TCGv_i32 cpu_UR[256]; 89 static TCGv_i32 cpu_windowbase_next; 90 static TCGv_i32 cpu_exclusive_addr; 91 static TCGv_i32 cpu_exclusive_val; 92 93 static GHashTable *xtensa_regfile_table; 94 95 #include "exec/gen-icount.h" 96 97 static char *sr_name[256]; 98 static char *ur_name[256]; 99 100 void xtensa_collect_sr_names(const XtensaConfig *config) 101 { 102 xtensa_isa isa = config->isa; 103 int n = xtensa_isa_num_sysregs(isa); 104 int i; 105 106 for (i = 0; i < n; ++i) { 107 int sr = xtensa_sysreg_number(isa, i); 108 109 if (sr >= 0 && sr < 256) { 110 const char *name = xtensa_sysreg_name(isa, i); 111 char **pname = 112 (xtensa_sysreg_is_user(isa, i) ? ur_name : sr_name) + sr; 113 114 if (*pname) { 115 if (strstr(*pname, name) == NULL) { 116 char *new_name = 117 malloc(strlen(*pname) + strlen(name) + 2); 118 119 strcpy(new_name, *pname); 120 strcat(new_name, "/"); 121 strcat(new_name, name); 122 free(*pname); 123 *pname = new_name; 124 } 125 } else { 126 *pname = strdup(name); 127 } 128 } 129 } 130 } 131 132 void xtensa_translate_init(void) 133 { 134 static const char * const regnames[] = { 135 "ar0", "ar1", "ar2", "ar3", 136 "ar4", "ar5", "ar6", "ar7", 137 "ar8", "ar9", "ar10", "ar11", 138 "ar12", "ar13", "ar14", "ar15", 139 }; 140 static const char * const fregnames[] = { 141 "f0", "f1", "f2", "f3", 142 "f4", "f5", "f6", "f7", 143 "f8", "f9", "f10", "f11", 144 "f12", "f13", "f14", "f15", 145 }; 146 static const char * const mregnames[] = { 147 "m0", "m1", "m2", "m3", 148 }; 149 static const char * const bregnames[] = { 150 "b0", "b1", "b2", "b3", 151 "b4", "b5", "b6", "b7", 152 "b8", "b9", "b10", "b11", 153 "b12", "b13", "b14", "b15", 154 }; 155 int i; 156 157 cpu_pc = tcg_global_mem_new_i32(cpu_env, 158 offsetof(CPUXtensaState, pc), "pc"); 159 160 for (i = 0; i < 16; i++) { 161 cpu_R[i] = tcg_global_mem_new_i32(cpu_env, 162 offsetof(CPUXtensaState, regs[i]), 163 regnames[i]); 164 } 165 166 for (i = 0; i < 16; i++) { 167 cpu_FR[i] = tcg_global_mem_new_i32(cpu_env, 168 offsetof(CPUXtensaState, 169 fregs[i].f32[FP_F32_LOW]), 170 fregnames[i]); 171 } 172 173 for (i = 0; i < 16; i++) { 174 cpu_FRD[i] = tcg_global_mem_new_i64(cpu_env, 175 offsetof(CPUXtensaState, 176 fregs[i].f64), 177 fregnames[i]); 178 } 179 180 for (i = 0; i < 4; i++) { 181 cpu_MR[i] = tcg_global_mem_new_i32(cpu_env, 182 offsetof(CPUXtensaState, 183 sregs[MR + i]), 184 mregnames[i]); 185 } 186 187 for (i = 0; i < 16; i++) { 188 cpu_BR[i] = tcg_global_mem_new_i32(cpu_env, 189 offsetof(CPUXtensaState, 190 sregs[BR]), 191 bregnames[i]); 192 if (i % 4 == 0) { 193 cpu_BR4[i / 4] = tcg_global_mem_new_i32(cpu_env, 194 offsetof(CPUXtensaState, 195 sregs[BR]), 196 bregnames[i]); 197 } 198 if (i % 8 == 0) { 199 cpu_BR8[i / 8] = tcg_global_mem_new_i32(cpu_env, 200 offsetof(CPUXtensaState, 201 sregs[BR]), 202 bregnames[i]); 203 } 204 } 205 206 for (i = 0; i < 256; ++i) { 207 if (sr_name[i]) { 208 cpu_SR[i] = tcg_global_mem_new_i32(cpu_env, 209 offsetof(CPUXtensaState, 210 sregs[i]), 211 sr_name[i]); 212 } 213 } 214 215 for (i = 0; i < 256; ++i) { 216 if (ur_name[i]) { 217 cpu_UR[i] = tcg_global_mem_new_i32(cpu_env, 218 offsetof(CPUXtensaState, 219 uregs[i]), 220 ur_name[i]); 221 } 222 } 223 224 cpu_windowbase_next = 225 tcg_global_mem_new_i32(cpu_env, 226 offsetof(CPUXtensaState, windowbase_next), 227 "windowbase_next"); 228 cpu_exclusive_addr = 229 tcg_global_mem_new_i32(cpu_env, 230 offsetof(CPUXtensaState, exclusive_addr), 231 "exclusive_addr"); 232 cpu_exclusive_val = 233 tcg_global_mem_new_i32(cpu_env, 234 offsetof(CPUXtensaState, exclusive_val), 235 "exclusive_val"); 236 } 237 238 void **xtensa_get_regfile_by_name(const char *name, int entries, int bits) 239 { 240 char *geometry_name; 241 void **res; 242 243 if (xtensa_regfile_table == NULL) { 244 xtensa_regfile_table = g_hash_table_new(g_str_hash, g_str_equal); 245 /* 246 * AR is special. Xtensa translator uses it as a current register 247 * window, but configuration overlays represent it as a complete 248 * physical register file. 249 */ 250 g_hash_table_insert(xtensa_regfile_table, 251 (void *)"AR 16x32", (void *)cpu_R); 252 g_hash_table_insert(xtensa_regfile_table, 253 (void *)"AR 32x32", (void *)cpu_R); 254 g_hash_table_insert(xtensa_regfile_table, 255 (void *)"AR 64x32", (void *)cpu_R); 256 257 g_hash_table_insert(xtensa_regfile_table, 258 (void *)"MR 4x32", (void *)cpu_MR); 259 260 g_hash_table_insert(xtensa_regfile_table, 261 (void *)"FR 16x32", (void *)cpu_FR); 262 g_hash_table_insert(xtensa_regfile_table, 263 (void *)"FR 16x64", (void *)cpu_FRD); 264 265 g_hash_table_insert(xtensa_regfile_table, 266 (void *)"BR 16x1", (void *)cpu_BR); 267 g_hash_table_insert(xtensa_regfile_table, 268 (void *)"BR4 4x4", (void *)cpu_BR4); 269 g_hash_table_insert(xtensa_regfile_table, 270 (void *)"BR8 2x8", (void *)cpu_BR8); 271 } 272 273 geometry_name = g_strdup_printf("%s %dx%d", name, entries, bits); 274 res = (void **)g_hash_table_lookup(xtensa_regfile_table, geometry_name); 275 g_free(geometry_name); 276 return res; 277 } 278 279 static inline bool option_enabled(DisasContext *dc, int opt) 280 { 281 return xtensa_option_enabled(dc->config, opt); 282 } 283 284 static void init_sar_tracker(DisasContext *dc) 285 { 286 dc->sar_5bit = false; 287 dc->sar_m32_5bit = false; 288 dc->sar_m32_allocated = false; 289 } 290 291 static void reset_sar_tracker(DisasContext *dc) 292 { 293 if (dc->sar_m32_allocated) { 294 tcg_temp_free(dc->sar_m32); 295 } 296 } 297 298 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa) 299 { 300 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f); 301 if (dc->sar_m32_5bit) { 302 tcg_gen_discard_i32(dc->sar_m32); 303 } 304 dc->sar_5bit = true; 305 dc->sar_m32_5bit = false; 306 } 307 308 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa) 309 { 310 TCGv_i32 tmp = tcg_const_i32(32); 311 if (!dc->sar_m32_allocated) { 312 dc->sar_m32 = tcg_temp_local_new_i32(); 313 dc->sar_m32_allocated = true; 314 } 315 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f); 316 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32); 317 dc->sar_5bit = false; 318 dc->sar_m32_5bit = true; 319 tcg_temp_free(tmp); 320 } 321 322 static void gen_exception(DisasContext *dc, int excp) 323 { 324 TCGv_i32 tmp = tcg_const_i32(excp); 325 gen_helper_exception(cpu_env, tmp); 326 tcg_temp_free(tmp); 327 } 328 329 static void gen_exception_cause(DisasContext *dc, uint32_t cause) 330 { 331 TCGv_i32 tpc = tcg_const_i32(dc->pc); 332 TCGv_i32 tcause = tcg_const_i32(cause); 333 gen_helper_exception_cause(cpu_env, tpc, tcause); 334 tcg_temp_free(tpc); 335 tcg_temp_free(tcause); 336 if (cause == ILLEGAL_INSTRUCTION_CAUSE || 337 cause == SYSCALL_CAUSE) { 338 dc->base.is_jmp = DISAS_NORETURN; 339 } 340 } 341 342 static void gen_debug_exception(DisasContext *dc, uint32_t cause) 343 { 344 TCGv_i32 tpc = tcg_const_i32(dc->pc); 345 TCGv_i32 tcause = tcg_const_i32(cause); 346 gen_helper_debug_exception(cpu_env, tpc, tcause); 347 tcg_temp_free(tpc); 348 tcg_temp_free(tcause); 349 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) { 350 dc->base.is_jmp = DISAS_NORETURN; 351 } 352 } 353 354 static bool gen_check_privilege(DisasContext *dc) 355 { 356 #ifndef CONFIG_USER_ONLY 357 if (!dc->cring) { 358 return true; 359 } 360 #endif 361 gen_exception_cause(dc, PRIVILEGED_CAUSE); 362 dc->base.is_jmp = DISAS_NORETURN; 363 return false; 364 } 365 366 static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask) 367 { 368 cp_mask &= ~dc->cpenable; 369 370 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) && cp_mask) { 371 gen_exception_cause(dc, COPROCESSOR0_DISABLED + ctz32(cp_mask)); 372 dc->base.is_jmp = DISAS_NORETURN; 373 return false; 374 } 375 return true; 376 } 377 378 static int gen_postprocess(DisasContext *dc, int slot); 379 380 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) 381 { 382 tcg_gen_mov_i32(cpu_pc, dest); 383 if (dc->icount) { 384 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); 385 } 386 if (dc->base.singlestep_enabled) { 387 gen_exception(dc, EXCP_DEBUG); 388 } else { 389 if (dc->op_flags & XTENSA_OP_POSTPROCESS) { 390 slot = gen_postprocess(dc, slot); 391 } 392 if (slot >= 0) { 393 tcg_gen_goto_tb(slot); 394 tcg_gen_exit_tb(dc->base.tb, slot); 395 } else { 396 tcg_gen_exit_tb(NULL, 0); 397 } 398 } 399 dc->base.is_jmp = DISAS_NORETURN; 400 } 401 402 static void gen_jump(DisasContext *dc, TCGv dest) 403 { 404 gen_jump_slot(dc, dest, -1); 405 } 406 407 static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot) 408 { 409 if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) { 410 return -1; 411 } else { 412 return slot; 413 } 414 } 415 416 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot) 417 { 418 TCGv_i32 tmp = tcg_const_i32(dest); 419 gen_jump_slot(dc, tmp, adjust_jump_slot(dc, dest, slot)); 420 tcg_temp_free(tmp); 421 } 422 423 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest, 424 int slot) 425 { 426 TCGv_i32 tcallinc = tcg_const_i32(callinc); 427 428 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS], 429 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN); 430 tcg_temp_free(tcallinc); 431 tcg_gen_movi_i32(cpu_R[callinc << 2], 432 (callinc << 30) | (dc->base.pc_next & 0x3fffffff)); 433 gen_jump_slot(dc, dest, slot); 434 } 435 436 static bool gen_check_loop_end(DisasContext *dc, int slot) 437 { 438 if (dc->base.pc_next == dc->lend) { 439 TCGLabel *label = gen_new_label(); 440 441 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); 442 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); 443 if (dc->lbeg_off) { 444 gen_jumpi(dc, dc->base.pc_next - dc->lbeg_off, slot); 445 } else { 446 gen_jump(dc, cpu_SR[LBEG]); 447 } 448 gen_set_label(label); 449 gen_jumpi(dc, dc->base.pc_next, -1); 450 return true; 451 } 452 return false; 453 } 454 455 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot) 456 { 457 if (!gen_check_loop_end(dc, slot)) { 458 gen_jumpi(dc, dc->base.pc_next, slot); 459 } 460 } 461 462 static void gen_brcond(DisasContext *dc, TCGCond cond, 463 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr) 464 { 465 TCGLabel *label = gen_new_label(); 466 467 tcg_gen_brcond_i32(cond, t0, t1, label); 468 gen_jumpi_check_loop_end(dc, 0); 469 gen_set_label(label); 470 gen_jumpi(dc, addr, 1); 471 } 472 473 static void gen_brcondi(DisasContext *dc, TCGCond cond, 474 TCGv_i32 t0, uint32_t t1, uint32_t addr) 475 { 476 TCGv_i32 tmp = tcg_const_i32(t1); 477 gen_brcond(dc, cond, t0, tmp, addr); 478 tcg_temp_free(tmp); 479 } 480 481 static uint32_t test_exceptions_sr(DisasContext *dc, const OpcodeArg arg[], 482 const uint32_t par[]) 483 { 484 return xtensa_option_enabled(dc->config, par[1]) ? 0 : XTENSA_OP_ILL; 485 } 486 487 static uint32_t test_exceptions_ccompare(DisasContext *dc, 488 const OpcodeArg arg[], 489 const uint32_t par[]) 490 { 491 unsigned n = par[0] - CCOMPARE; 492 493 if (n >= dc->config->nccompare) { 494 return XTENSA_OP_ILL; 495 } 496 return test_exceptions_sr(dc, arg, par); 497 } 498 499 static uint32_t test_exceptions_dbreak(DisasContext *dc, const OpcodeArg arg[], 500 const uint32_t par[]) 501 { 502 unsigned n = MAX_NDBREAK; 503 504 if (par[0] >= DBREAKA && par[0] < DBREAKA + MAX_NDBREAK) { 505 n = par[0] - DBREAKA; 506 } 507 if (par[0] >= DBREAKC && par[0] < DBREAKC + MAX_NDBREAK) { 508 n = par[0] - DBREAKC; 509 } 510 if (n >= dc->config->ndbreak) { 511 return XTENSA_OP_ILL; 512 } 513 return test_exceptions_sr(dc, arg, par); 514 } 515 516 static uint32_t test_exceptions_ibreak(DisasContext *dc, const OpcodeArg arg[], 517 const uint32_t par[]) 518 { 519 unsigned n = par[0] - IBREAKA; 520 521 if (n >= dc->config->nibreak) { 522 return XTENSA_OP_ILL; 523 } 524 return test_exceptions_sr(dc, arg, par); 525 } 526 527 static uint32_t test_exceptions_hpi(DisasContext *dc, const OpcodeArg arg[], 528 const uint32_t par[]) 529 { 530 unsigned n = MAX_NLEVEL + 1; 531 532 if (par[0] >= EXCSAVE1 && par[0] < EXCSAVE1 + MAX_NLEVEL) { 533 n = par[0] - EXCSAVE1 + 1; 534 } 535 if (par[0] >= EPC1 && par[0] < EPC1 + MAX_NLEVEL) { 536 n = par[0] - EPC1 + 1; 537 } 538 if (par[0] >= EPS2 && par[0] < EPS2 + MAX_NLEVEL - 1) { 539 n = par[0] - EPS2 + 2; 540 } 541 if (n > dc->config->nlevel) { 542 return XTENSA_OP_ILL; 543 } 544 return test_exceptions_sr(dc, arg, par); 545 } 546 547 static MemOp gen_load_store_alignment(DisasContext *dc, MemOp mop, 548 TCGv_i32 addr) 549 { 550 if ((mop & MO_SIZE) == MO_8) { 551 return mop; 552 } 553 if ((mop & MO_AMASK) == MO_UNALN && 554 !option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT)) { 555 mop |= MO_ALIGN; 556 } 557 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) { 558 tcg_gen_andi_i32(addr, addr, ~0 << get_alignment_bits(mop)); 559 } 560 return mop; 561 } 562 563 #ifndef CONFIG_USER_ONLY 564 static void gen_waiti(DisasContext *dc, uint32_t imm4) 565 { 566 TCGv_i32 pc = tcg_const_i32(dc->base.pc_next); 567 TCGv_i32 intlevel = tcg_const_i32(imm4); 568 569 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 570 gen_io_start(); 571 } 572 gen_helper_waiti(cpu_env, pc, intlevel); 573 tcg_temp_free(pc); 574 tcg_temp_free(intlevel); 575 } 576 #endif 577 578 static bool gen_window_check(DisasContext *dc, uint32_t mask) 579 { 580 unsigned r = 31 - clz32(mask); 581 582 if (r / 4 > dc->window) { 583 TCGv_i32 pc = tcg_const_i32(dc->pc); 584 TCGv_i32 w = tcg_const_i32(r / 4); 585 586 gen_helper_window_check(cpu_env, pc, w); 587 dc->base.is_jmp = DISAS_NORETURN; 588 return false; 589 } 590 return true; 591 } 592 593 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned) 594 { 595 TCGv_i32 m = tcg_temp_new_i32(); 596 597 if (hi) { 598 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16); 599 } else { 600 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v); 601 } 602 return m; 603 } 604 605 static void gen_zero_check(DisasContext *dc, const OpcodeArg arg[]) 606 { 607 TCGLabel *label = gen_new_label(); 608 609 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0, label); 610 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE); 611 gen_set_label(label); 612 } 613 614 static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0) 615 { 616 return xtensa_isa_length_from_chars(dc->config->isa, &op0); 617 } 618 619 static int gen_postprocess(DisasContext *dc, int slot) 620 { 621 uint32_t op_flags = dc->op_flags; 622 623 #ifndef CONFIG_USER_ONLY 624 if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { 625 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 626 gen_io_start(); 627 } 628 gen_helper_check_interrupts(cpu_env); 629 } 630 #endif 631 if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) { 632 gen_helper_sync_windowbase(cpu_env); 633 } 634 if (op_flags & XTENSA_OP_EXIT_TB_M1) { 635 slot = -1; 636 } 637 return slot; 638 } 639 640 struct opcode_arg_copy { 641 uint32_t resource; 642 void *temp; 643 OpcodeArg *arg; 644 }; 645 646 struct opcode_arg_info { 647 uint32_t resource; 648 int index; 649 }; 650 651 struct slot_prop { 652 XtensaOpcodeOps *ops; 653 OpcodeArg arg[MAX_OPCODE_ARGS]; 654 struct opcode_arg_info in[MAX_OPCODE_ARGS]; 655 struct opcode_arg_info out[MAX_OPCODE_ARGS]; 656 unsigned n_in; 657 unsigned n_out; 658 uint32_t op_flags; 659 }; 660 661 enum resource_type { 662 RES_REGFILE, 663 RES_STATE, 664 RES_MAX, 665 }; 666 667 static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n) 668 { 669 assert(r < RES_MAX && g < 256 && n < 65536); 670 return (r << 24) | (g << 16) | n; 671 } 672 673 static enum resource_type get_resource_type(uint32_t resource) 674 { 675 return resource >> 24; 676 } 677 678 /* 679 * a depends on b if b must be executed before a, 680 * because a's side effects will destroy b's inputs. 681 */ 682 static bool op_depends_on(const struct slot_prop *a, 683 const struct slot_prop *b) 684 { 685 unsigned i = 0; 686 unsigned j = 0; 687 688 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) { 689 return true; 690 } 691 if ((a->op_flags & XTENSA_OP_LOAD_STORE) < 692 (b->op_flags & XTENSA_OP_LOAD_STORE)) { 693 return true; 694 } 695 while (i < a->n_out && j < b->n_in) { 696 if (a->out[i].resource < b->in[j].resource) { 697 ++i; 698 } else if (a->out[i].resource > b->in[j].resource) { 699 ++j; 700 } else { 701 return true; 702 } 703 } 704 return false; 705 } 706 707 /* 708 * Try to break a dependency on b, append temporary register copy records 709 * to the end of copy and update n_copy in case of success. 710 * This is not always possible: e.g. control flow must always be the last, 711 * load/store must be first and state dependencies are not supported yet. 712 */ 713 static bool break_dependency(struct slot_prop *a, 714 struct slot_prop *b, 715 struct opcode_arg_copy *copy, 716 unsigned *n_copy) 717 { 718 unsigned i = 0; 719 unsigned j = 0; 720 unsigned n = *n_copy; 721 bool rv = false; 722 723 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) { 724 return false; 725 } 726 if ((a->op_flags & XTENSA_OP_LOAD_STORE) < 727 (b->op_flags & XTENSA_OP_LOAD_STORE)) { 728 return false; 729 } 730 while (i < a->n_out && j < b->n_in) { 731 if (a->out[i].resource < b->in[j].resource) { 732 ++i; 733 } else if (a->out[i].resource > b->in[j].resource) { 734 ++j; 735 } else { 736 int index = b->in[j].index; 737 738 if (get_resource_type(a->out[i].resource) != RES_REGFILE || 739 index < 0) { 740 return false; 741 } 742 copy[n].resource = b->in[j].resource; 743 copy[n].arg = b->arg + index; 744 ++n; 745 ++j; 746 rv = true; 747 } 748 } 749 *n_copy = n; 750 return rv; 751 } 752 753 /* 754 * Calculate evaluation order for slot opcodes. 755 * Build opcode order graph and output its nodes in topological sort order. 756 * An edge a -> b in the graph means that opcode a must be followed by 757 * opcode b. 758 */ 759 static bool tsort(struct slot_prop *slot, 760 struct slot_prop *sorted[], 761 unsigned n, 762 struct opcode_arg_copy *copy, 763 unsigned *n_copy) 764 { 765 struct tsnode { 766 unsigned n_in_edge; 767 unsigned n_out_edge; 768 unsigned out_edge[MAX_INSN_SLOTS]; 769 } node[MAX_INSN_SLOTS]; 770 771 unsigned in[MAX_INSN_SLOTS]; 772 unsigned i, j; 773 unsigned n_in = 0; 774 unsigned n_out = 0; 775 unsigned n_edge = 0; 776 unsigned in_idx = 0; 777 unsigned node_idx = 0; 778 779 for (i = 0; i < n; ++i) { 780 node[i].n_in_edge = 0; 781 node[i].n_out_edge = 0; 782 } 783 784 for (i = 0; i < n; ++i) { 785 unsigned n_out_edge = 0; 786 787 for (j = 0; j < n; ++j) { 788 if (i != j && op_depends_on(slot + j, slot + i)) { 789 node[i].out_edge[n_out_edge] = j; 790 ++node[j].n_in_edge; 791 ++n_out_edge; 792 ++n_edge; 793 } 794 } 795 node[i].n_out_edge = n_out_edge; 796 } 797 798 for (i = 0; i < n; ++i) { 799 if (!node[i].n_in_edge) { 800 in[n_in] = i; 801 ++n_in; 802 } 803 } 804 805 again: 806 for (; in_idx < n_in; ++in_idx) { 807 i = in[in_idx]; 808 sorted[n_out] = slot + i; 809 ++n_out; 810 for (j = 0; j < node[i].n_out_edge; ++j) { 811 --n_edge; 812 if (--node[node[i].out_edge[j]].n_in_edge == 0) { 813 in[n_in] = node[i].out_edge[j]; 814 ++n_in; 815 } 816 } 817 } 818 if (n_edge) { 819 for (; node_idx < n; ++node_idx) { 820 struct tsnode *cnode = node + node_idx; 821 822 if (cnode->n_in_edge) { 823 for (j = 0; j < cnode->n_out_edge; ++j) { 824 unsigned k = cnode->out_edge[j]; 825 826 if (break_dependency(slot + k, slot + node_idx, 827 copy, n_copy) && 828 --node[k].n_in_edge == 0) { 829 in[n_in] = k; 830 ++n_in; 831 --n_edge; 832 cnode->out_edge[j] = 833 cnode->out_edge[cnode->n_out_edge - 1]; 834 --cnode->n_out_edge; 835 goto again; 836 } 837 } 838 } 839 } 840 } 841 return n_edge == 0; 842 } 843 844 static void opcode_add_resource(struct slot_prop *op, 845 uint32_t resource, char direction, 846 int index) 847 { 848 switch (direction) { 849 case 'm': 850 case 'i': 851 assert(op->n_in < ARRAY_SIZE(op->in)); 852 op->in[op->n_in].resource = resource; 853 op->in[op->n_in].index = index; 854 ++op->n_in; 855 /* fall through */ 856 case 'o': 857 if (direction == 'm' || direction == 'o') { 858 assert(op->n_out < ARRAY_SIZE(op->out)); 859 op->out[op->n_out].resource = resource; 860 op->out[op->n_out].index = index; 861 ++op->n_out; 862 } 863 break; 864 default: 865 g_assert_not_reached(); 866 } 867 } 868 869 static int resource_compare(const void *a, const void *b) 870 { 871 const struct opcode_arg_info *pa = a; 872 const struct opcode_arg_info *pb = b; 873 874 return pa->resource < pb->resource ? 875 -1 : (pa->resource > pb->resource ? 1 : 0); 876 } 877 878 static int arg_copy_compare(const void *a, const void *b) 879 { 880 const struct opcode_arg_copy *pa = a; 881 const struct opcode_arg_copy *pb = b; 882 883 return pa->resource < pb->resource ? 884 -1 : (pa->resource > pb->resource ? 1 : 0); 885 } 886 887 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) 888 { 889 xtensa_isa isa = dc->config->isa; 890 unsigned char b[MAX_INSN_LENGTH] = {translator_ldub(env, dc->pc)}; 891 unsigned len = xtensa_op0_insn_len(dc, b[0]); 892 xtensa_format fmt; 893 int slot, slots; 894 unsigned i; 895 uint32_t op_flags = 0; 896 struct slot_prop slot_prop[MAX_INSN_SLOTS]; 897 struct slot_prop *ordered[MAX_INSN_SLOTS]; 898 struct opcode_arg_copy arg_copy[MAX_INSN_SLOTS * MAX_OPCODE_ARGS]; 899 unsigned n_arg_copy = 0; 900 uint32_t debug_cause = 0; 901 uint32_t windowed_register = 0; 902 uint32_t coprocessor = 0; 903 904 if (len == XTENSA_UNDEFINED) { 905 qemu_log_mask(LOG_GUEST_ERROR, 906 "unknown instruction length (pc = %08x)\n", 907 dc->pc); 908 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 909 dc->base.pc_next = dc->pc + 1; 910 return; 911 } 912 913 dc->base.pc_next = dc->pc + len; 914 for (i = 1; i < len; ++i) { 915 b[i] = translator_ldub(env, dc->pc + i); 916 } 917 xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len); 918 fmt = xtensa_format_decode(isa, dc->insnbuf); 919 if (fmt == XTENSA_UNDEFINED) { 920 qemu_log_mask(LOG_GUEST_ERROR, 921 "unrecognized instruction format (pc = %08x)\n", 922 dc->pc); 923 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 924 return; 925 } 926 slots = xtensa_format_num_slots(isa, fmt); 927 for (slot = 0; slot < slots; ++slot) { 928 xtensa_opcode opc; 929 int opnd, vopnd, opnds; 930 OpcodeArg *arg = slot_prop[slot].arg; 931 XtensaOpcodeOps *ops; 932 933 xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf); 934 opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf); 935 if (opc == XTENSA_UNDEFINED) { 936 qemu_log_mask(LOG_GUEST_ERROR, 937 "unrecognized opcode in slot %d (pc = %08x)\n", 938 slot, dc->pc); 939 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 940 return; 941 } 942 opnds = xtensa_opcode_num_operands(isa, opc); 943 944 for (opnd = vopnd = 0; opnd < opnds; ++opnd) { 945 void **register_file = NULL; 946 xtensa_regfile rf; 947 948 if (xtensa_operand_is_register(isa, opc, opnd)) { 949 rf = xtensa_operand_regfile(isa, opc, opnd); 950 register_file = dc->config->regfile[rf]; 951 952 if (rf == dc->config->a_regfile) { 953 uint32_t v; 954 955 xtensa_operand_get_field(isa, opc, opnd, fmt, slot, 956 dc->slotbuf, &v); 957 xtensa_operand_decode(isa, opc, opnd, &v); 958 windowed_register |= 1u << v; 959 } 960 } 961 if (xtensa_operand_is_visible(isa, opc, opnd)) { 962 uint32_t v; 963 964 xtensa_operand_get_field(isa, opc, opnd, fmt, slot, 965 dc->slotbuf, &v); 966 xtensa_operand_decode(isa, opc, opnd, &v); 967 arg[vopnd].raw_imm = v; 968 if (xtensa_operand_is_PCrelative(isa, opc, opnd)) { 969 xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc); 970 } 971 arg[vopnd].imm = v; 972 if (register_file) { 973 arg[vopnd].in = register_file[v]; 974 arg[vopnd].out = register_file[v]; 975 arg[vopnd].num_bits = xtensa_regfile_num_bits(isa, rf); 976 } else { 977 arg[vopnd].num_bits = 32; 978 } 979 ++vopnd; 980 } 981 } 982 ops = dc->config->opcode_ops[opc]; 983 slot_prop[slot].ops = ops; 984 985 if (ops) { 986 op_flags |= ops->op_flags; 987 if (ops->test_exceptions) { 988 op_flags |= ops->test_exceptions(dc, arg, ops->par); 989 } 990 } else { 991 qemu_log_mask(LOG_UNIMP, 992 "unimplemented opcode '%s' in slot %d (pc = %08x)\n", 993 xtensa_opcode_name(isa, opc), slot, dc->pc); 994 op_flags |= XTENSA_OP_ILL; 995 } 996 if (op_flags & XTENSA_OP_ILL) { 997 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 998 return; 999 } 1000 if (op_flags & XTENSA_OP_DEBUG_BREAK) { 1001 debug_cause |= ops->par[0]; 1002 } 1003 if (ops->test_overflow) { 1004 windowed_register |= ops->test_overflow(dc, arg, ops->par); 1005 } 1006 coprocessor |= ops->coprocessor; 1007 1008 if (slots > 1) { 1009 slot_prop[slot].n_in = 0; 1010 slot_prop[slot].n_out = 0; 1011 slot_prop[slot].op_flags = ops->op_flags & XTENSA_OP_LOAD_STORE; 1012 1013 opnds = xtensa_opcode_num_operands(isa, opc); 1014 1015 for (opnd = vopnd = 0; opnd < opnds; ++opnd) { 1016 bool visible = xtensa_operand_is_visible(isa, opc, opnd); 1017 1018 if (xtensa_operand_is_register(isa, opc, opnd)) { 1019 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); 1020 uint32_t v = 0; 1021 1022 xtensa_operand_get_field(isa, opc, opnd, fmt, slot, 1023 dc->slotbuf, &v); 1024 xtensa_operand_decode(isa, opc, opnd, &v); 1025 opcode_add_resource(slot_prop + slot, 1026 encode_resource(RES_REGFILE, rf, v), 1027 xtensa_operand_inout(isa, opc, opnd), 1028 visible ? vopnd : -1); 1029 } 1030 if (visible) { 1031 ++vopnd; 1032 } 1033 } 1034 1035 opnds = xtensa_opcode_num_stateOperands(isa, opc); 1036 1037 for (opnd = 0; opnd < opnds; ++opnd) { 1038 xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd); 1039 1040 opcode_add_resource(slot_prop + slot, 1041 encode_resource(RES_STATE, 0, state), 1042 xtensa_stateOperand_inout(isa, opc, opnd), 1043 -1); 1044 } 1045 if (xtensa_opcode_is_branch(isa, opc) || 1046 xtensa_opcode_is_jump(isa, opc) || 1047 xtensa_opcode_is_loop(isa, opc) || 1048 xtensa_opcode_is_call(isa, opc)) { 1049 slot_prop[slot].op_flags |= XTENSA_OP_CONTROL_FLOW; 1050 } 1051 1052 qsort(slot_prop[slot].in, slot_prop[slot].n_in, 1053 sizeof(slot_prop[slot].in[0]), resource_compare); 1054 qsort(slot_prop[slot].out, slot_prop[slot].n_out, 1055 sizeof(slot_prop[slot].out[0]), resource_compare); 1056 } 1057 } 1058 1059 if (slots > 1) { 1060 if (!tsort(slot_prop, ordered, slots, arg_copy, &n_arg_copy)) { 1061 qemu_log_mask(LOG_UNIMP, 1062 "Circular resource dependencies (pc = %08x)\n", 1063 dc->pc); 1064 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1065 return; 1066 } 1067 } else { 1068 ordered[0] = slot_prop + 0; 1069 } 1070 1071 if ((op_flags & XTENSA_OP_PRIVILEGED) && 1072 !gen_check_privilege(dc)) { 1073 return; 1074 } 1075 1076 if (op_flags & XTENSA_OP_SYSCALL) { 1077 gen_exception_cause(dc, SYSCALL_CAUSE); 1078 return; 1079 } 1080 1081 if ((op_flags & XTENSA_OP_DEBUG_BREAK) && dc->debug) { 1082 gen_debug_exception(dc, debug_cause); 1083 return; 1084 } 1085 1086 if (windowed_register && !gen_window_check(dc, windowed_register)) { 1087 return; 1088 } 1089 1090 if (op_flags & XTENSA_OP_UNDERFLOW) { 1091 TCGv_i32 tmp = tcg_const_i32(dc->pc); 1092 1093 gen_helper_test_underflow_retw(cpu_env, tmp); 1094 tcg_temp_free(tmp); 1095 } 1096 1097 if (op_flags & XTENSA_OP_ALLOCA) { 1098 TCGv_i32 tmp = tcg_const_i32(dc->pc); 1099 1100 gen_helper_movsp(cpu_env, tmp); 1101 tcg_temp_free(tmp); 1102 } 1103 1104 if (coprocessor && !gen_check_cpenable(dc, coprocessor)) { 1105 return; 1106 } 1107 1108 if (n_arg_copy) { 1109 uint32_t resource; 1110 void *temp; 1111 unsigned j; 1112 1113 qsort(arg_copy, n_arg_copy, sizeof(*arg_copy), arg_copy_compare); 1114 for (i = j = 0; i < n_arg_copy; ++i) { 1115 if (i == 0 || arg_copy[i].resource != resource) { 1116 resource = arg_copy[i].resource; 1117 if (arg_copy[i].arg->num_bits <= 32) { 1118 temp = tcg_temp_local_new_i32(); 1119 tcg_gen_mov_i32(temp, arg_copy[i].arg->in); 1120 } else if (arg_copy[i].arg->num_bits <= 64) { 1121 temp = tcg_temp_local_new_i64(); 1122 tcg_gen_mov_i64(temp, arg_copy[i].arg->in); 1123 } else { 1124 g_assert_not_reached(); 1125 } 1126 arg_copy[i].temp = temp; 1127 1128 if (i != j) { 1129 arg_copy[j] = arg_copy[i]; 1130 } 1131 ++j; 1132 } 1133 arg_copy[i].arg->in = temp; 1134 } 1135 n_arg_copy = j; 1136 } 1137 1138 if (op_flags & XTENSA_OP_DIVIDE_BY_ZERO) { 1139 for (slot = 0; slot < slots; ++slot) { 1140 if (slot_prop[slot].ops->op_flags & XTENSA_OP_DIVIDE_BY_ZERO) { 1141 gen_zero_check(dc, slot_prop[slot].arg); 1142 } 1143 } 1144 } 1145 1146 dc->op_flags = op_flags; 1147 1148 for (slot = 0; slot < slots; ++slot) { 1149 struct slot_prop *pslot = ordered[slot]; 1150 XtensaOpcodeOps *ops = pslot->ops; 1151 1152 ops->translate(dc, pslot->arg, ops->par); 1153 } 1154 1155 for (i = 0; i < n_arg_copy; ++i) { 1156 if (arg_copy[i].arg->num_bits <= 32) { 1157 tcg_temp_free_i32(arg_copy[i].temp); 1158 } else if (arg_copy[i].arg->num_bits <= 64) { 1159 tcg_temp_free_i64(arg_copy[i].temp); 1160 } else { 1161 g_assert_not_reached(); 1162 } 1163 } 1164 1165 if (dc->base.is_jmp == DISAS_NEXT) { 1166 gen_postprocess(dc, 0); 1167 dc->op_flags = 0; 1168 if (op_flags & XTENSA_OP_EXIT_TB_M1) { 1169 /* Change in mmu index, memory mapping or tb->flags; exit tb */ 1170 gen_jumpi_check_loop_end(dc, -1); 1171 } else if (op_flags & XTENSA_OP_EXIT_TB_0) { 1172 gen_jumpi_check_loop_end(dc, 0); 1173 } else { 1174 gen_check_loop_end(dc, 0); 1175 } 1176 } 1177 dc->pc = dc->base.pc_next; 1178 } 1179 1180 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc) 1181 { 1182 uint8_t b0 = cpu_ldub_code(env, dc->pc); 1183 return xtensa_op0_insn_len(dc, b0); 1184 } 1185 1186 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc) 1187 { 1188 unsigned i; 1189 1190 for (i = 0; i < dc->config->nibreak; ++i) { 1191 if ((env->sregs[IBREAKENABLE] & (1 << i)) && 1192 env->sregs[IBREAKA + i] == dc->pc) { 1193 gen_debug_exception(dc, DEBUGCAUSE_IB); 1194 break; 1195 } 1196 } 1197 } 1198 1199 static void xtensa_tr_init_disas_context(DisasContextBase *dcbase, 1200 CPUState *cpu) 1201 { 1202 DisasContext *dc = container_of(dcbase, DisasContext, base); 1203 CPUXtensaState *env = cpu->env_ptr; 1204 uint32_t tb_flags = dc->base.tb->flags; 1205 1206 dc->config = env->config; 1207 dc->pc = dc->base.pc_first; 1208 dc->ring = tb_flags & XTENSA_TBFLAG_RING_MASK; 1209 dc->cring = (tb_flags & XTENSA_TBFLAG_EXCM) ? 0 : dc->ring; 1210 dc->lbeg_off = (dc->base.tb->cs_base & XTENSA_CSBASE_LBEG_OFF_MASK) >> 1211 XTENSA_CSBASE_LBEG_OFF_SHIFT; 1212 dc->lend = (dc->base.tb->cs_base & XTENSA_CSBASE_LEND_MASK) + 1213 (dc->base.pc_first & TARGET_PAGE_MASK); 1214 dc->debug = tb_flags & XTENSA_TBFLAG_DEBUG; 1215 dc->icount = tb_flags & XTENSA_TBFLAG_ICOUNT; 1216 dc->cpenable = (tb_flags & XTENSA_TBFLAG_CPENABLE_MASK) >> 1217 XTENSA_TBFLAG_CPENABLE_SHIFT; 1218 dc->window = ((tb_flags & XTENSA_TBFLAG_WINDOW_MASK) >> 1219 XTENSA_TBFLAG_WINDOW_SHIFT); 1220 dc->cwoe = tb_flags & XTENSA_TBFLAG_CWOE; 1221 dc->callinc = ((tb_flags & XTENSA_TBFLAG_CALLINC_MASK) >> 1222 XTENSA_TBFLAG_CALLINC_SHIFT); 1223 init_sar_tracker(dc); 1224 } 1225 1226 static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu) 1227 { 1228 DisasContext *dc = container_of(dcbase, DisasContext, base); 1229 1230 if (dc->icount) { 1231 dc->next_icount = tcg_temp_local_new_i32(); 1232 } 1233 } 1234 1235 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 1236 { 1237 tcg_gen_insn_start(dcbase->pc_next); 1238 } 1239 1240 static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, 1241 const CPUBreakpoint *bp) 1242 { 1243 DisasContext *dc = container_of(dcbase, DisasContext, base); 1244 1245 tcg_gen_movi_i32(cpu_pc, dc->base.pc_next); 1246 gen_exception(dc, EXCP_DEBUG); 1247 dc->base.is_jmp = DISAS_NORETURN; 1248 /* The address covered by the breakpoint must be included in 1249 [tb->pc, tb->pc + tb->size) in order to for it to be 1250 properly cleared -- thus we increment the PC here so that 1251 the logic setting tb->size below does the right thing. */ 1252 dc->base.pc_next += 2; 1253 return true; 1254 } 1255 1256 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 1257 { 1258 DisasContext *dc = container_of(dcbase, DisasContext, base); 1259 CPUXtensaState *env = cpu->env_ptr; 1260 target_ulong page_start; 1261 1262 /* These two conditions only apply to the first insn in the TB, 1263 but this is the first TranslateOps hook that allows exiting. */ 1264 if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT) 1265 && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) { 1266 gen_exception(dc, EXCP_YIELD); 1267 dc->base.pc_next = dc->pc + 1; 1268 dc->base.is_jmp = DISAS_NORETURN; 1269 return; 1270 } 1271 1272 if (dc->icount) { 1273 TCGLabel *label = gen_new_label(); 1274 1275 tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1); 1276 tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label); 1277 tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]); 1278 if (dc->debug) { 1279 gen_debug_exception(dc, DEBUGCAUSE_IC); 1280 } 1281 gen_set_label(label); 1282 } 1283 1284 if (dc->debug) { 1285 gen_ibreak_check(env, dc); 1286 } 1287 1288 disas_xtensa_insn(env, dc); 1289 1290 if (dc->icount) { 1291 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); 1292 } 1293 1294 /* End the TB if the next insn will cross into the next page. */ 1295 page_start = dc->base.pc_first & TARGET_PAGE_MASK; 1296 if (dc->base.is_jmp == DISAS_NEXT && 1297 (dc->pc - page_start >= TARGET_PAGE_SIZE || 1298 dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) { 1299 dc->base.is_jmp = DISAS_TOO_MANY; 1300 } 1301 } 1302 1303 static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 1304 { 1305 DisasContext *dc = container_of(dcbase, DisasContext, base); 1306 1307 reset_sar_tracker(dc); 1308 if (dc->icount) { 1309 tcg_temp_free(dc->next_icount); 1310 } 1311 1312 switch (dc->base.is_jmp) { 1313 case DISAS_NORETURN: 1314 break; 1315 case DISAS_TOO_MANY: 1316 if (dc->base.singlestep_enabled) { 1317 tcg_gen_movi_i32(cpu_pc, dc->pc); 1318 gen_exception(dc, EXCP_DEBUG); 1319 } else { 1320 gen_jumpi(dc, dc->pc, 0); 1321 } 1322 break; 1323 default: 1324 g_assert_not_reached(); 1325 } 1326 } 1327 1328 static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) 1329 { 1330 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 1331 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); 1332 } 1333 1334 static const TranslatorOps xtensa_translator_ops = { 1335 .init_disas_context = xtensa_tr_init_disas_context, 1336 .tb_start = xtensa_tr_tb_start, 1337 .insn_start = xtensa_tr_insn_start, 1338 .breakpoint_check = xtensa_tr_breakpoint_check, 1339 .translate_insn = xtensa_tr_translate_insn, 1340 .tb_stop = xtensa_tr_tb_stop, 1341 .disas_log = xtensa_tr_disas_log, 1342 }; 1343 1344 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) 1345 { 1346 DisasContext dc = {}; 1347 translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns); 1348 } 1349 1350 void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags) 1351 { 1352 XtensaCPU *cpu = XTENSA_CPU(cs); 1353 CPUXtensaState *env = &cpu->env; 1354 xtensa_isa isa = env->config->isa; 1355 int i, j; 1356 1357 qemu_fprintf(f, "PC=%08x\n\n", env->pc); 1358 1359 for (i = j = 0; i < xtensa_isa_num_sysregs(isa); ++i) { 1360 const uint32_t *reg = 1361 xtensa_sysreg_is_user(isa, i) ? env->uregs : env->sregs; 1362 int regno = xtensa_sysreg_number(isa, i); 1363 1364 if (regno >= 0) { 1365 qemu_fprintf(f, "%12s=%08x%c", 1366 xtensa_sysreg_name(isa, i), 1367 reg[regno], 1368 (j++ % 4) == 3 ? '\n' : ' '); 1369 } 1370 } 1371 1372 qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); 1373 1374 for (i = 0; i < 16; ++i) { 1375 qemu_fprintf(f, " A%02d=%08x%c", 1376 i, env->regs[i], (i % 4) == 3 ? '\n' : ' '); 1377 } 1378 1379 xtensa_sync_phys_from_window(env); 1380 qemu_fprintf(f, "\n"); 1381 1382 for (i = 0; i < env->config->nareg; ++i) { 1383 qemu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]); 1384 if (i % 4 == 3) { 1385 bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0; 1386 bool cw = env->sregs[WINDOW_BASE] == i / 4; 1387 1388 qemu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' '); 1389 } 1390 } 1391 1392 if ((flags & CPU_DUMP_FPU) && 1393 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) { 1394 qemu_fprintf(f, "\n"); 1395 1396 for (i = 0; i < 16; ++i) { 1397 qemu_fprintf(f, "F%02d=%08x (%-+15.8e)%c", i, 1398 float32_val(env->fregs[i].f32[FP_F32_LOW]), 1399 *(float *)(env->fregs[i].f32 + FP_F32_LOW), 1400 (i % 2) == 1 ? '\n' : ' '); 1401 } 1402 } 1403 1404 if ((flags & CPU_DUMP_FPU) && 1405 xtensa_option_enabled(env->config, XTENSA_OPTION_DFP_COPROCESSOR) && 1406 !xtensa_option_enabled(env->config, XTENSA_OPTION_DFPU_SINGLE_ONLY)) { 1407 qemu_fprintf(f, "\n"); 1408 1409 for (i = 0; i < 16; ++i) { 1410 qemu_fprintf(f, "F%02d=%016"PRIx64" (%-+24.16le)%c", i, 1411 float64_val(env->fregs[i].f64), 1412 *(double *)(&env->fregs[i].f64), 1413 (i % 2) == 1 ? '\n' : ' '); 1414 } 1415 } 1416 } 1417 1418 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, 1419 target_ulong *data) 1420 { 1421 env->pc = data[0]; 1422 } 1423 1424 static void translate_abs(DisasContext *dc, const OpcodeArg arg[], 1425 const uint32_t par[]) 1426 { 1427 tcg_gen_abs_i32(arg[0].out, arg[1].in); 1428 } 1429 1430 static void translate_add(DisasContext *dc, const OpcodeArg arg[], 1431 const uint32_t par[]) 1432 { 1433 tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in); 1434 } 1435 1436 static void translate_addi(DisasContext *dc, const OpcodeArg arg[], 1437 const uint32_t par[]) 1438 { 1439 tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm); 1440 } 1441 1442 static void translate_addx(DisasContext *dc, const OpcodeArg arg[], 1443 const uint32_t par[]) 1444 { 1445 TCGv_i32 tmp = tcg_temp_new_i32(); 1446 tcg_gen_shli_i32(tmp, arg[1].in, par[0]); 1447 tcg_gen_add_i32(arg[0].out, tmp, arg[2].in); 1448 tcg_temp_free(tmp); 1449 } 1450 1451 static void translate_all(DisasContext *dc, const OpcodeArg arg[], 1452 const uint32_t par[]) 1453 { 1454 uint32_t shift = par[1]; 1455 TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1].imm); 1456 TCGv_i32 tmp = tcg_temp_new_i32(); 1457 1458 tcg_gen_and_i32(tmp, arg[1].in, mask); 1459 if (par[0]) { 1460 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1].imm); 1461 } else { 1462 tcg_gen_add_i32(tmp, tmp, mask); 1463 } 1464 tcg_gen_shri_i32(tmp, tmp, arg[1].imm + shift); 1465 tcg_gen_deposit_i32(arg[0].out, arg[0].out, 1466 tmp, arg[0].imm, 1); 1467 tcg_temp_free(mask); 1468 tcg_temp_free(tmp); 1469 } 1470 1471 static void translate_and(DisasContext *dc, const OpcodeArg arg[], 1472 const uint32_t par[]) 1473 { 1474 tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in); 1475 } 1476 1477 static void translate_ball(DisasContext *dc, const OpcodeArg arg[], 1478 const uint32_t par[]) 1479 { 1480 TCGv_i32 tmp = tcg_temp_new_i32(); 1481 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in); 1482 gen_brcond(dc, par[0], tmp, arg[1].in, arg[2].imm); 1483 tcg_temp_free(tmp); 1484 } 1485 1486 static void translate_bany(DisasContext *dc, const OpcodeArg arg[], 1487 const uint32_t par[]) 1488 { 1489 TCGv_i32 tmp = tcg_temp_new_i32(); 1490 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in); 1491 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); 1492 tcg_temp_free(tmp); 1493 } 1494 1495 static void translate_b(DisasContext *dc, const OpcodeArg arg[], 1496 const uint32_t par[]) 1497 { 1498 gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm); 1499 } 1500 1501 static void translate_bb(DisasContext *dc, const OpcodeArg arg[], 1502 const uint32_t par[]) 1503 { 1504 #ifdef TARGET_WORDS_BIGENDIAN 1505 TCGv_i32 bit = tcg_const_i32(0x80000000u); 1506 #else 1507 TCGv_i32 bit = tcg_const_i32(0x00000001u); 1508 #endif 1509 TCGv_i32 tmp = tcg_temp_new_i32(); 1510 tcg_gen_andi_i32(tmp, arg[1].in, 0x1f); 1511 #ifdef TARGET_WORDS_BIGENDIAN 1512 tcg_gen_shr_i32(bit, bit, tmp); 1513 #else 1514 tcg_gen_shl_i32(bit, bit, tmp); 1515 #endif 1516 tcg_gen_and_i32(tmp, arg[0].in, bit); 1517 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); 1518 tcg_temp_free(tmp); 1519 tcg_temp_free(bit); 1520 } 1521 1522 static void translate_bbi(DisasContext *dc, const OpcodeArg arg[], 1523 const uint32_t par[]) 1524 { 1525 TCGv_i32 tmp = tcg_temp_new_i32(); 1526 #ifdef TARGET_WORDS_BIGENDIAN 1527 tcg_gen_andi_i32(tmp, arg[0].in, 0x80000000u >> arg[1].imm); 1528 #else 1529 tcg_gen_andi_i32(tmp, arg[0].in, 0x00000001u << arg[1].imm); 1530 #endif 1531 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); 1532 tcg_temp_free(tmp); 1533 } 1534 1535 static void translate_bi(DisasContext *dc, const OpcodeArg arg[], 1536 const uint32_t par[]) 1537 { 1538 gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm); 1539 } 1540 1541 static void translate_bz(DisasContext *dc, const OpcodeArg arg[], 1542 const uint32_t par[]) 1543 { 1544 gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm); 1545 } 1546 1547 enum { 1548 BOOLEAN_AND, 1549 BOOLEAN_ANDC, 1550 BOOLEAN_OR, 1551 BOOLEAN_ORC, 1552 BOOLEAN_XOR, 1553 }; 1554 1555 static void translate_boolean(DisasContext *dc, const OpcodeArg arg[], 1556 const uint32_t par[]) 1557 { 1558 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = { 1559 [BOOLEAN_AND] = tcg_gen_and_i32, 1560 [BOOLEAN_ANDC] = tcg_gen_andc_i32, 1561 [BOOLEAN_OR] = tcg_gen_or_i32, 1562 [BOOLEAN_ORC] = tcg_gen_orc_i32, 1563 [BOOLEAN_XOR] = tcg_gen_xor_i32, 1564 }; 1565 1566 TCGv_i32 tmp1 = tcg_temp_new_i32(); 1567 TCGv_i32 tmp2 = tcg_temp_new_i32(); 1568 1569 tcg_gen_shri_i32(tmp1, arg[1].in, arg[1].imm); 1570 tcg_gen_shri_i32(tmp2, arg[2].in, arg[2].imm); 1571 op[par[0]](tmp1, tmp1, tmp2); 1572 tcg_gen_deposit_i32(arg[0].out, arg[0].out, tmp1, arg[0].imm, 1); 1573 tcg_temp_free(tmp1); 1574 tcg_temp_free(tmp2); 1575 } 1576 1577 static void translate_bp(DisasContext *dc, const OpcodeArg arg[], 1578 const uint32_t par[]) 1579 { 1580 TCGv_i32 tmp = tcg_temp_new_i32(); 1581 1582 tcg_gen_andi_i32(tmp, arg[0].in, 1 << arg[0].imm); 1583 gen_brcondi(dc, par[0], tmp, 0, arg[1].imm); 1584 tcg_temp_free(tmp); 1585 } 1586 1587 static void translate_call0(DisasContext *dc, const OpcodeArg arg[], 1588 const uint32_t par[]) 1589 { 1590 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next); 1591 gen_jumpi(dc, arg[0].imm, 0); 1592 } 1593 1594 static void translate_callw(DisasContext *dc, const OpcodeArg arg[], 1595 const uint32_t par[]) 1596 { 1597 TCGv_i32 tmp = tcg_const_i32(arg[0].imm); 1598 gen_callw_slot(dc, par[0], tmp, adjust_jump_slot(dc, arg[0].imm, 0)); 1599 tcg_temp_free(tmp); 1600 } 1601 1602 static void translate_callx0(DisasContext *dc, const OpcodeArg arg[], 1603 const uint32_t par[]) 1604 { 1605 TCGv_i32 tmp = tcg_temp_new_i32(); 1606 tcg_gen_mov_i32(tmp, arg[0].in); 1607 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next); 1608 gen_jump(dc, tmp); 1609 tcg_temp_free(tmp); 1610 } 1611 1612 static void translate_callxw(DisasContext *dc, const OpcodeArg arg[], 1613 const uint32_t par[]) 1614 { 1615 TCGv_i32 tmp = tcg_temp_new_i32(); 1616 1617 tcg_gen_mov_i32(tmp, arg[0].in); 1618 gen_callw_slot(dc, par[0], tmp, -1); 1619 tcg_temp_free(tmp); 1620 } 1621 1622 static void translate_clamps(DisasContext *dc, const OpcodeArg arg[], 1623 const uint32_t par[]) 1624 { 1625 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2].imm); 1626 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2].imm) - 1); 1627 1628 tcg_gen_smax_i32(tmp1, tmp1, arg[1].in); 1629 tcg_gen_smin_i32(arg[0].out, tmp1, tmp2); 1630 tcg_temp_free(tmp1); 1631 tcg_temp_free(tmp2); 1632 } 1633 1634 static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[], 1635 const uint32_t par[]) 1636 { 1637 /* TODO: GPIO32 may be a part of coprocessor */ 1638 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm)); 1639 } 1640 1641 static void translate_clrex(DisasContext *dc, const OpcodeArg arg[], 1642 const uint32_t par[]) 1643 { 1644 tcg_gen_movi_i32(cpu_exclusive_addr, -1); 1645 } 1646 1647 static void translate_const16(DisasContext *dc, const OpcodeArg arg[], 1648 const uint32_t par[]) 1649 { 1650 TCGv_i32 c = tcg_const_i32(arg[1].imm); 1651 1652 tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16); 1653 tcg_temp_free(c); 1654 } 1655 1656 static void translate_dcache(DisasContext *dc, const OpcodeArg arg[], 1657 const uint32_t par[]) 1658 { 1659 TCGv_i32 addr = tcg_temp_new_i32(); 1660 TCGv_i32 res = tcg_temp_new_i32(); 1661 1662 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm); 1663 tcg_gen_qemu_ld8u(res, addr, dc->cring); 1664 tcg_temp_free(addr); 1665 tcg_temp_free(res); 1666 } 1667 1668 static void translate_depbits(DisasContext *dc, const OpcodeArg arg[], 1669 const uint32_t par[]) 1670 { 1671 tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in, 1672 arg[2].imm, arg[3].imm); 1673 } 1674 1675 static void translate_diwbuip(DisasContext *dc, const OpcodeArg arg[], 1676 const uint32_t par[]) 1677 { 1678 tcg_gen_addi_i32(arg[0].out, arg[0].in, dc->config->dcache_line_bytes); 1679 } 1680 1681 static uint32_t test_exceptions_entry(DisasContext *dc, const OpcodeArg arg[], 1682 const uint32_t par[]) 1683 { 1684 if (arg[0].imm > 3 || !dc->cwoe) { 1685 qemu_log_mask(LOG_GUEST_ERROR, 1686 "Illegal entry instruction(pc = %08x)\n", dc->pc); 1687 return XTENSA_OP_ILL; 1688 } else { 1689 return 0; 1690 } 1691 } 1692 1693 static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[], 1694 const uint32_t par[]) 1695 { 1696 return 1 << (dc->callinc * 4); 1697 } 1698 1699 static void translate_entry(DisasContext *dc, const OpcodeArg arg[], 1700 const uint32_t par[]) 1701 { 1702 TCGv_i32 pc = tcg_const_i32(dc->pc); 1703 TCGv_i32 s = tcg_const_i32(arg[0].imm); 1704 TCGv_i32 imm = tcg_const_i32(arg[1].imm); 1705 gen_helper_entry(cpu_env, pc, s, imm); 1706 tcg_temp_free(imm); 1707 tcg_temp_free(s); 1708 tcg_temp_free(pc); 1709 } 1710 1711 static void translate_extui(DisasContext *dc, const OpcodeArg arg[], 1712 const uint32_t par[]) 1713 { 1714 int maskimm = (1 << arg[3].imm) - 1; 1715 1716 TCGv_i32 tmp = tcg_temp_new_i32(); 1717 tcg_gen_shri_i32(tmp, arg[1].in, arg[2].imm); 1718 tcg_gen_andi_i32(arg[0].out, tmp, maskimm); 1719 tcg_temp_free(tmp); 1720 } 1721 1722 static void translate_getex(DisasContext *dc, const OpcodeArg arg[], 1723 const uint32_t par[]) 1724 { 1725 TCGv_i32 tmp = tcg_temp_new_i32(); 1726 1727 tcg_gen_extract_i32(tmp, cpu_SR[ATOMCTL], 8, 1); 1728 tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], arg[0].in, 8, 1); 1729 tcg_gen_mov_i32(arg[0].out, tmp); 1730 tcg_temp_free(tmp); 1731 } 1732 1733 static void translate_icache(DisasContext *dc, const OpcodeArg arg[], 1734 const uint32_t par[]) 1735 { 1736 #ifndef CONFIG_USER_ONLY 1737 TCGv_i32 addr = tcg_temp_new_i32(); 1738 1739 tcg_gen_movi_i32(cpu_pc, dc->pc); 1740 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm); 1741 gen_helper_itlb_hit_test(cpu_env, addr); 1742 tcg_temp_free(addr); 1743 #endif 1744 } 1745 1746 static void translate_itlb(DisasContext *dc, const OpcodeArg arg[], 1747 const uint32_t par[]) 1748 { 1749 #ifndef CONFIG_USER_ONLY 1750 TCGv_i32 dtlb = tcg_const_i32(par[0]); 1751 1752 gen_helper_itlb(cpu_env, arg[0].in, dtlb); 1753 tcg_temp_free(dtlb); 1754 #endif 1755 } 1756 1757 static void translate_j(DisasContext *dc, const OpcodeArg arg[], 1758 const uint32_t par[]) 1759 { 1760 gen_jumpi(dc, arg[0].imm, 0); 1761 } 1762 1763 static void translate_jx(DisasContext *dc, const OpcodeArg arg[], 1764 const uint32_t par[]) 1765 { 1766 gen_jump(dc, arg[0].in); 1767 } 1768 1769 static void translate_l32e(DisasContext *dc, const OpcodeArg arg[], 1770 const uint32_t par[]) 1771 { 1772 TCGv_i32 addr = tcg_temp_new_i32(); 1773 MemOp mop; 1774 1775 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 1776 mop = gen_load_store_alignment(dc, MO_TEUL, addr); 1777 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, mop); 1778 tcg_temp_free(addr); 1779 } 1780 1781 #ifdef CONFIG_USER_ONLY 1782 static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write) 1783 { 1784 } 1785 #else 1786 static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write) 1787 { 1788 if (!option_enabled(dc, XTENSA_OPTION_MPU)) { 1789 TCGv_i32 tpc = tcg_const_i32(dc->pc); 1790 TCGv_i32 write = tcg_const_i32(is_write); 1791 1792 gen_helper_check_exclusive(cpu_env, tpc, addr, write); 1793 tcg_temp_free(tpc); 1794 tcg_temp_free(write); 1795 } 1796 } 1797 #endif 1798 1799 static void translate_l32ex(DisasContext *dc, const OpcodeArg arg[], 1800 const uint32_t par[]) 1801 { 1802 TCGv_i32 addr = tcg_temp_new_i32(); 1803 MemOp mop; 1804 1805 tcg_gen_mov_i32(addr, arg[1].in); 1806 mop = gen_load_store_alignment(dc, MO_TEUL | MO_ALIGN, addr); 1807 gen_check_exclusive(dc, addr, false); 1808 tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->cring, mop); 1809 tcg_gen_mov_i32(cpu_exclusive_addr, addr); 1810 tcg_gen_mov_i32(cpu_exclusive_val, arg[0].out); 1811 tcg_temp_free(addr); 1812 } 1813 1814 static void translate_ldst(DisasContext *dc, const OpcodeArg arg[], 1815 const uint32_t par[]) 1816 { 1817 TCGv_i32 addr = tcg_temp_new_i32(); 1818 MemOp mop; 1819 1820 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 1821 mop = gen_load_store_alignment(dc, par[0], addr); 1822 1823 if (par[2]) { 1824 if (par[1]) { 1825 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL); 1826 } 1827 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop); 1828 } else { 1829 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop); 1830 if (par[1]) { 1831 tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL); 1832 } 1833 } 1834 tcg_temp_free(addr); 1835 } 1836 1837 static void translate_l32r(DisasContext *dc, const OpcodeArg arg[], 1838 const uint32_t par[]) 1839 { 1840 TCGv_i32 tmp; 1841 1842 if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) { 1843 tmp = tcg_const_i32(arg[1].raw_imm - 1); 1844 tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp); 1845 } else { 1846 tmp = tcg_const_i32(arg[1].imm); 1847 } 1848 tcg_gen_qemu_ld32u(arg[0].out, tmp, dc->cring); 1849 tcg_temp_free(tmp); 1850 } 1851 1852 static void translate_loop(DisasContext *dc, const OpcodeArg arg[], 1853 const uint32_t par[]) 1854 { 1855 uint32_t lend = arg[1].imm; 1856 1857 tcg_gen_subi_i32(cpu_SR[LCOUNT], arg[0].in, 1); 1858 tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next); 1859 tcg_gen_movi_i32(cpu_SR[LEND], lend); 1860 1861 if (par[0] != TCG_COND_NEVER) { 1862 TCGLabel *label = gen_new_label(); 1863 tcg_gen_brcondi_i32(par[0], arg[0].in, 0, label); 1864 gen_jumpi(dc, lend, 1); 1865 gen_set_label(label); 1866 } 1867 1868 gen_jumpi(dc, dc->base.pc_next, 0); 1869 } 1870 1871 enum { 1872 MAC16_UMUL, 1873 MAC16_MUL, 1874 MAC16_MULA, 1875 MAC16_MULS, 1876 MAC16_NONE, 1877 }; 1878 1879 enum { 1880 MAC16_LL, 1881 MAC16_HL, 1882 MAC16_LH, 1883 MAC16_HH, 1884 1885 MAC16_HX = 0x1, 1886 MAC16_XH = 0x2, 1887 }; 1888 1889 static void translate_mac16(DisasContext *dc, const OpcodeArg arg[], 1890 const uint32_t par[]) 1891 { 1892 int op = par[0]; 1893 unsigned half = par[1]; 1894 uint32_t ld_offset = par[2]; 1895 unsigned off = ld_offset ? 2 : 0; 1896 TCGv_i32 vaddr = tcg_temp_new_i32(); 1897 TCGv_i32 mem32 = tcg_temp_new_i32(); 1898 1899 if (ld_offset) { 1900 MemOp mop; 1901 1902 tcg_gen_addi_i32(vaddr, arg[1].in, ld_offset); 1903 mop = gen_load_store_alignment(dc, MO_TEUL, vaddr); 1904 tcg_gen_qemu_ld_tl(mem32, vaddr, dc->cring, mop); 1905 } 1906 if (op != MAC16_NONE) { 1907 TCGv_i32 m1 = gen_mac16_m(arg[off].in, 1908 half & MAC16_HX, op == MAC16_UMUL); 1909 TCGv_i32 m2 = gen_mac16_m(arg[off + 1].in, 1910 half & MAC16_XH, op == MAC16_UMUL); 1911 1912 if (op == MAC16_MUL || op == MAC16_UMUL) { 1913 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2); 1914 if (op == MAC16_UMUL) { 1915 tcg_gen_movi_i32(cpu_SR[ACCHI], 0); 1916 } else { 1917 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31); 1918 } 1919 } else { 1920 TCGv_i32 lo = tcg_temp_new_i32(); 1921 TCGv_i32 hi = tcg_temp_new_i32(); 1922 1923 tcg_gen_mul_i32(lo, m1, m2); 1924 tcg_gen_sari_i32(hi, lo, 31); 1925 if (op == MAC16_MULA) { 1926 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 1927 cpu_SR[ACCLO], cpu_SR[ACCHI], 1928 lo, hi); 1929 } else { 1930 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 1931 cpu_SR[ACCLO], cpu_SR[ACCHI], 1932 lo, hi); 1933 } 1934 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]); 1935 1936 tcg_temp_free_i32(lo); 1937 tcg_temp_free_i32(hi); 1938 } 1939 tcg_temp_free(m1); 1940 tcg_temp_free(m2); 1941 } 1942 if (ld_offset) { 1943 tcg_gen_mov_i32(arg[1].out, vaddr); 1944 tcg_gen_mov_i32(cpu_SR[MR + arg[0].imm], mem32); 1945 } 1946 tcg_temp_free(vaddr); 1947 tcg_temp_free(mem32); 1948 } 1949 1950 static void translate_memw(DisasContext *dc, const OpcodeArg arg[], 1951 const uint32_t par[]) 1952 { 1953 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL); 1954 } 1955 1956 static void translate_smin(DisasContext *dc, const OpcodeArg arg[], 1957 const uint32_t par[]) 1958 { 1959 tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in); 1960 } 1961 1962 static void translate_umin(DisasContext *dc, const OpcodeArg arg[], 1963 const uint32_t par[]) 1964 { 1965 tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in); 1966 } 1967 1968 static void translate_smax(DisasContext *dc, const OpcodeArg arg[], 1969 const uint32_t par[]) 1970 { 1971 tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in); 1972 } 1973 1974 static void translate_umax(DisasContext *dc, const OpcodeArg arg[], 1975 const uint32_t par[]) 1976 { 1977 tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in); 1978 } 1979 1980 static void translate_mov(DisasContext *dc, const OpcodeArg arg[], 1981 const uint32_t par[]) 1982 { 1983 tcg_gen_mov_i32(arg[0].out, arg[1].in); 1984 } 1985 1986 static void translate_movcond(DisasContext *dc, const OpcodeArg arg[], 1987 const uint32_t par[]) 1988 { 1989 TCGv_i32 zero = tcg_const_i32(0); 1990 1991 tcg_gen_movcond_i32(par[0], arg[0].out, 1992 arg[2].in, zero, arg[1].in, arg[0].in); 1993 tcg_temp_free(zero); 1994 } 1995 1996 static void translate_movi(DisasContext *dc, const OpcodeArg arg[], 1997 const uint32_t par[]) 1998 { 1999 tcg_gen_movi_i32(arg[0].out, arg[1].imm); 2000 } 2001 2002 static void translate_movp(DisasContext *dc, const OpcodeArg arg[], 2003 const uint32_t par[]) 2004 { 2005 TCGv_i32 zero = tcg_const_i32(0); 2006 TCGv_i32 tmp = tcg_temp_new_i32(); 2007 2008 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm); 2009 tcg_gen_movcond_i32(par[0], 2010 arg[0].out, tmp, zero, 2011 arg[1].in, arg[0].in); 2012 tcg_temp_free(tmp); 2013 tcg_temp_free(zero); 2014 } 2015 2016 static void translate_movsp(DisasContext *dc, const OpcodeArg arg[], 2017 const uint32_t par[]) 2018 { 2019 tcg_gen_mov_i32(arg[0].out, arg[1].in); 2020 } 2021 2022 static void translate_mul16(DisasContext *dc, const OpcodeArg arg[], 2023 const uint32_t par[]) 2024 { 2025 TCGv_i32 v1 = tcg_temp_new_i32(); 2026 TCGv_i32 v2 = tcg_temp_new_i32(); 2027 2028 if (par[0]) { 2029 tcg_gen_ext16s_i32(v1, arg[1].in); 2030 tcg_gen_ext16s_i32(v2, arg[2].in); 2031 } else { 2032 tcg_gen_ext16u_i32(v1, arg[1].in); 2033 tcg_gen_ext16u_i32(v2, arg[2].in); 2034 } 2035 tcg_gen_mul_i32(arg[0].out, v1, v2); 2036 tcg_temp_free(v2); 2037 tcg_temp_free(v1); 2038 } 2039 2040 static void translate_mull(DisasContext *dc, const OpcodeArg arg[], 2041 const uint32_t par[]) 2042 { 2043 tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in); 2044 } 2045 2046 static void translate_mulh(DisasContext *dc, const OpcodeArg arg[], 2047 const uint32_t par[]) 2048 { 2049 TCGv_i32 lo = tcg_temp_new(); 2050 2051 if (par[0]) { 2052 tcg_gen_muls2_i32(lo, arg[0].out, arg[1].in, arg[2].in); 2053 } else { 2054 tcg_gen_mulu2_i32(lo, arg[0].out, arg[1].in, arg[2].in); 2055 } 2056 tcg_temp_free(lo); 2057 } 2058 2059 static void translate_neg(DisasContext *dc, const OpcodeArg arg[], 2060 const uint32_t par[]) 2061 { 2062 tcg_gen_neg_i32(arg[0].out, arg[1].in); 2063 } 2064 2065 static void translate_nop(DisasContext *dc, const OpcodeArg arg[], 2066 const uint32_t par[]) 2067 { 2068 } 2069 2070 static void translate_nsa(DisasContext *dc, const OpcodeArg arg[], 2071 const uint32_t par[]) 2072 { 2073 tcg_gen_clrsb_i32(arg[0].out, arg[1].in); 2074 } 2075 2076 static void translate_nsau(DisasContext *dc, const OpcodeArg arg[], 2077 const uint32_t par[]) 2078 { 2079 tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32); 2080 } 2081 2082 static void translate_or(DisasContext *dc, const OpcodeArg arg[], 2083 const uint32_t par[]) 2084 { 2085 tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in); 2086 } 2087 2088 static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[], 2089 const uint32_t par[]) 2090 { 2091 #ifndef CONFIG_USER_ONLY 2092 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2093 2094 tcg_gen_movi_i32(cpu_pc, dc->pc); 2095 gen_helper_ptlb(arg[0].out, cpu_env, arg[1].in, dtlb); 2096 tcg_temp_free(dtlb); 2097 #endif 2098 } 2099 2100 static void translate_pptlb(DisasContext *dc, const OpcodeArg arg[], 2101 const uint32_t par[]) 2102 { 2103 #ifndef CONFIG_USER_ONLY 2104 tcg_gen_movi_i32(cpu_pc, dc->pc); 2105 gen_helper_pptlb(arg[0].out, cpu_env, arg[1].in); 2106 #endif 2107 } 2108 2109 static void translate_quos(DisasContext *dc, const OpcodeArg arg[], 2110 const uint32_t par[]) 2111 { 2112 TCGLabel *label1 = gen_new_label(); 2113 TCGLabel *label2 = gen_new_label(); 2114 2115 tcg_gen_brcondi_i32(TCG_COND_NE, arg[1].in, 0x80000000, 2116 label1); 2117 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0xffffffff, 2118 label1); 2119 tcg_gen_movi_i32(arg[0].out, 2120 par[0] ? 0x80000000 : 0); 2121 tcg_gen_br(label2); 2122 gen_set_label(label1); 2123 if (par[0]) { 2124 tcg_gen_div_i32(arg[0].out, 2125 arg[1].in, arg[2].in); 2126 } else { 2127 tcg_gen_rem_i32(arg[0].out, 2128 arg[1].in, arg[2].in); 2129 } 2130 gen_set_label(label2); 2131 } 2132 2133 static void translate_quou(DisasContext *dc, const OpcodeArg arg[], 2134 const uint32_t par[]) 2135 { 2136 tcg_gen_divu_i32(arg[0].out, 2137 arg[1].in, arg[2].in); 2138 } 2139 2140 static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[], 2141 const uint32_t par[]) 2142 { 2143 /* TODO: GPIO32 may be a part of coprocessor */ 2144 tcg_gen_movi_i32(arg[0].out, 0); 2145 } 2146 2147 static void translate_remu(DisasContext *dc, const OpcodeArg arg[], 2148 const uint32_t par[]) 2149 { 2150 tcg_gen_remu_i32(arg[0].out, 2151 arg[1].in, arg[2].in); 2152 } 2153 2154 static void translate_rer(DisasContext *dc, const OpcodeArg arg[], 2155 const uint32_t par[]) 2156 { 2157 gen_helper_rer(arg[0].out, cpu_env, arg[1].in); 2158 } 2159 2160 static void translate_ret(DisasContext *dc, const OpcodeArg arg[], 2161 const uint32_t par[]) 2162 { 2163 gen_jump(dc, cpu_R[0]); 2164 } 2165 2166 static uint32_t test_exceptions_retw(DisasContext *dc, const OpcodeArg arg[], 2167 const uint32_t par[]) 2168 { 2169 if (!dc->cwoe) { 2170 qemu_log_mask(LOG_GUEST_ERROR, 2171 "Illegal retw instruction(pc = %08x)\n", dc->pc); 2172 return XTENSA_OP_ILL; 2173 } else { 2174 TCGv_i32 tmp = tcg_const_i32(dc->pc); 2175 2176 gen_helper_test_ill_retw(cpu_env, tmp); 2177 tcg_temp_free(tmp); 2178 return 0; 2179 } 2180 } 2181 2182 static void translate_retw(DisasContext *dc, const OpcodeArg arg[], 2183 const uint32_t par[]) 2184 { 2185 TCGv_i32 tmp = tcg_const_i32(1); 2186 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); 2187 tcg_gen_andc_i32(cpu_SR[WINDOW_START], 2188 cpu_SR[WINDOW_START], tmp); 2189 tcg_gen_movi_i32(tmp, dc->pc); 2190 tcg_gen_deposit_i32(tmp, tmp, cpu_R[0], 0, 30); 2191 gen_helper_retw(cpu_env, cpu_R[0]); 2192 gen_jump(dc, tmp); 2193 tcg_temp_free(tmp); 2194 } 2195 2196 static void translate_rfde(DisasContext *dc, const OpcodeArg arg[], 2197 const uint32_t par[]) 2198 { 2199 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]); 2200 } 2201 2202 static void translate_rfe(DisasContext *dc, const OpcodeArg arg[], 2203 const uint32_t par[]) 2204 { 2205 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 2206 gen_jump(dc, cpu_SR[EPC1]); 2207 } 2208 2209 static void translate_rfi(DisasContext *dc, const OpcodeArg arg[], 2210 const uint32_t par[]) 2211 { 2212 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0].imm - 2]); 2213 gen_jump(dc, cpu_SR[EPC1 + arg[0].imm - 1]); 2214 } 2215 2216 static void translate_rfw(DisasContext *dc, const OpcodeArg arg[], 2217 const uint32_t par[]) 2218 { 2219 TCGv_i32 tmp = tcg_const_i32(1); 2220 2221 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 2222 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); 2223 2224 if (par[0]) { 2225 tcg_gen_andc_i32(cpu_SR[WINDOW_START], 2226 cpu_SR[WINDOW_START], tmp); 2227 } else { 2228 tcg_gen_or_i32(cpu_SR[WINDOW_START], 2229 cpu_SR[WINDOW_START], tmp); 2230 } 2231 2232 tcg_temp_free(tmp); 2233 gen_helper_restore_owb(cpu_env); 2234 gen_jump(dc, cpu_SR[EPC1]); 2235 } 2236 2237 static void translate_rotw(DisasContext *dc, const OpcodeArg arg[], 2238 const uint32_t par[]) 2239 { 2240 tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm); 2241 } 2242 2243 static void translate_rsil(DisasContext *dc, const OpcodeArg arg[], 2244 const uint32_t par[]) 2245 { 2246 tcg_gen_mov_i32(arg[0].out, cpu_SR[PS]); 2247 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL); 2248 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm); 2249 } 2250 2251 static void translate_rsr(DisasContext *dc, const OpcodeArg arg[], 2252 const uint32_t par[]) 2253 { 2254 if (sr_name[par[0]]) { 2255 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); 2256 } else { 2257 tcg_gen_movi_i32(arg[0].out, 0); 2258 } 2259 } 2260 2261 static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[], 2262 const uint32_t par[]) 2263 { 2264 #ifndef CONFIG_USER_ONLY 2265 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 2266 gen_io_start(); 2267 } 2268 gen_helper_update_ccount(cpu_env); 2269 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); 2270 #endif 2271 } 2272 2273 static void translate_rsr_ptevaddr(DisasContext *dc, const OpcodeArg arg[], 2274 const uint32_t par[]) 2275 { 2276 #ifndef CONFIG_USER_ONLY 2277 TCGv_i32 tmp = tcg_temp_new_i32(); 2278 2279 tcg_gen_shri_i32(tmp, cpu_SR[EXCVADDR], 10); 2280 tcg_gen_or_i32(tmp, tmp, cpu_SR[PTEVADDR]); 2281 tcg_gen_andi_i32(arg[0].out, tmp, 0xfffffffc); 2282 tcg_temp_free(tmp); 2283 #endif 2284 } 2285 2286 static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[], 2287 const uint32_t par[]) 2288 { 2289 #ifndef CONFIG_USER_ONLY 2290 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1, 2291 TCGv_i32 a2) = { 2292 gen_helper_rtlb0, 2293 gen_helper_rtlb1, 2294 }; 2295 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2296 2297 helper[par[1]](arg[0].out, cpu_env, arg[1].in, dtlb); 2298 tcg_temp_free(dtlb); 2299 #endif 2300 } 2301 2302 static void translate_rptlb0(DisasContext *dc, const OpcodeArg arg[], 2303 const uint32_t par[]) 2304 { 2305 #ifndef CONFIG_USER_ONLY 2306 gen_helper_rptlb0(arg[0].out, cpu_env, arg[1].in); 2307 #endif 2308 } 2309 2310 static void translate_rptlb1(DisasContext *dc, const OpcodeArg arg[], 2311 const uint32_t par[]) 2312 { 2313 #ifndef CONFIG_USER_ONLY 2314 gen_helper_rptlb1(arg[0].out, cpu_env, arg[1].in); 2315 #endif 2316 } 2317 2318 static void translate_rur(DisasContext *dc, const OpcodeArg arg[], 2319 const uint32_t par[]) 2320 { 2321 tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]); 2322 } 2323 2324 static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[], 2325 const uint32_t par[]) 2326 { 2327 /* TODO: GPIO32 may be a part of coprocessor */ 2328 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm); 2329 } 2330 2331 #ifdef CONFIG_USER_ONLY 2332 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr) 2333 { 2334 } 2335 #else 2336 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr) 2337 { 2338 TCGv_i32 tpc = tcg_const_i32(dc->pc); 2339 2340 gen_helper_check_atomctl(cpu_env, tpc, addr); 2341 tcg_temp_free(tpc); 2342 } 2343 #endif 2344 2345 static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[], 2346 const uint32_t par[]) 2347 { 2348 TCGv_i32 tmp = tcg_temp_local_new_i32(); 2349 TCGv_i32 addr = tcg_temp_local_new_i32(); 2350 MemOp mop; 2351 2352 tcg_gen_mov_i32(tmp, arg[0].in); 2353 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 2354 mop = gen_load_store_alignment(dc, MO_TEUL | MO_ALIGN, addr); 2355 gen_check_atomctl(dc, addr); 2356 tcg_gen_atomic_cmpxchg_i32(arg[0].out, addr, cpu_SR[SCOMPARE1], 2357 tmp, dc->cring, mop); 2358 tcg_temp_free(addr); 2359 tcg_temp_free(tmp); 2360 } 2361 2362 static void translate_s32e(DisasContext *dc, const OpcodeArg arg[], 2363 const uint32_t par[]) 2364 { 2365 TCGv_i32 addr = tcg_temp_new_i32(); 2366 MemOp mop; 2367 2368 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 2369 mop = gen_load_store_alignment(dc, MO_TEUL, addr); 2370 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->ring, mop); 2371 tcg_temp_free(addr); 2372 } 2373 2374 static void translate_s32ex(DisasContext *dc, const OpcodeArg arg[], 2375 const uint32_t par[]) 2376 { 2377 TCGv_i32 prev = tcg_temp_new_i32(); 2378 TCGv_i32 addr = tcg_temp_local_new_i32(); 2379 TCGv_i32 res = tcg_temp_local_new_i32(); 2380 TCGLabel *label = gen_new_label(); 2381 MemOp mop; 2382 2383 tcg_gen_movi_i32(res, 0); 2384 tcg_gen_mov_i32(addr, arg[1].in); 2385 mop = gen_load_store_alignment(dc, MO_TEUL | MO_ALIGN, addr); 2386 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, label); 2387 gen_check_exclusive(dc, addr, true); 2388 tcg_gen_atomic_cmpxchg_i32(prev, cpu_exclusive_addr, cpu_exclusive_val, 2389 arg[0].in, dc->cring, mop); 2390 tcg_gen_setcond_i32(TCG_COND_EQ, res, prev, cpu_exclusive_val); 2391 tcg_gen_movcond_i32(TCG_COND_EQ, cpu_exclusive_val, 2392 prev, cpu_exclusive_val, prev, cpu_exclusive_val); 2393 tcg_gen_movi_i32(cpu_exclusive_addr, -1); 2394 gen_set_label(label); 2395 tcg_gen_extract_i32(arg[0].out, cpu_SR[ATOMCTL], 8, 1); 2396 tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], res, 8, 1); 2397 tcg_temp_free(prev); 2398 tcg_temp_free(addr); 2399 tcg_temp_free(res); 2400 } 2401 2402 static void translate_salt(DisasContext *dc, const OpcodeArg arg[], 2403 const uint32_t par[]) 2404 { 2405 tcg_gen_setcond_i32(par[0], 2406 arg[0].out, 2407 arg[1].in, arg[2].in); 2408 } 2409 2410 static void translate_sext(DisasContext *dc, const OpcodeArg arg[], 2411 const uint32_t par[]) 2412 { 2413 int shift = 31 - arg[2].imm; 2414 2415 if (shift == 24) { 2416 tcg_gen_ext8s_i32(arg[0].out, arg[1].in); 2417 } else if (shift == 16) { 2418 tcg_gen_ext16s_i32(arg[0].out, arg[1].in); 2419 } else { 2420 TCGv_i32 tmp = tcg_temp_new_i32(); 2421 tcg_gen_shli_i32(tmp, arg[1].in, shift); 2422 tcg_gen_sari_i32(arg[0].out, tmp, shift); 2423 tcg_temp_free(tmp); 2424 } 2425 } 2426 2427 static uint32_t test_exceptions_simcall(DisasContext *dc, 2428 const OpcodeArg arg[], 2429 const uint32_t par[]) 2430 { 2431 #ifdef CONFIG_USER_ONLY 2432 bool ill = true; 2433 #else 2434 /* Between RE.2 and RE.3 simcall opcode's become nop for the hardware. */ 2435 bool ill = dc->config->hw_version <= 250002 && !semihosting_enabled(); 2436 #endif 2437 if (ill || !semihosting_enabled()) { 2438 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n"); 2439 } 2440 return ill ? XTENSA_OP_ILL : 0; 2441 } 2442 2443 static void translate_simcall(DisasContext *dc, const OpcodeArg arg[], 2444 const uint32_t par[]) 2445 { 2446 #ifndef CONFIG_USER_ONLY 2447 if (semihosting_enabled()) { 2448 gen_helper_simcall(cpu_env); 2449 } 2450 #endif 2451 } 2452 2453 /* 2454 * Note: 64 bit ops are used here solely because SAR values 2455 * have range 0..63 2456 */ 2457 #define gen_shift_reg(cmd, reg) do { \ 2458 TCGv_i64 tmp = tcg_temp_new_i64(); \ 2459 tcg_gen_extu_i32_i64(tmp, reg); \ 2460 tcg_gen_##cmd##_i64(v, v, tmp); \ 2461 tcg_gen_extrl_i64_i32(arg[0].out, v); \ 2462 tcg_temp_free_i64(v); \ 2463 tcg_temp_free_i64(tmp); \ 2464 } while (0) 2465 2466 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR]) 2467 2468 static void translate_sll(DisasContext *dc, const OpcodeArg arg[], 2469 const uint32_t par[]) 2470 { 2471 if (dc->sar_m32_5bit) { 2472 tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32); 2473 } else { 2474 TCGv_i64 v = tcg_temp_new_i64(); 2475 TCGv_i32 s = tcg_const_i32(32); 2476 tcg_gen_sub_i32(s, s, cpu_SR[SAR]); 2477 tcg_gen_andi_i32(s, s, 0x3f); 2478 tcg_gen_extu_i32_i64(v, arg[1].in); 2479 gen_shift_reg(shl, s); 2480 tcg_temp_free(s); 2481 } 2482 } 2483 2484 static void translate_slli(DisasContext *dc, const OpcodeArg arg[], 2485 const uint32_t par[]) 2486 { 2487 if (arg[2].imm == 32) { 2488 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n", 2489 arg[0].imm, arg[1].imm); 2490 } 2491 tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f); 2492 } 2493 2494 static void translate_sra(DisasContext *dc, const OpcodeArg arg[], 2495 const uint32_t par[]) 2496 { 2497 if (dc->sar_m32_5bit) { 2498 tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]); 2499 } else { 2500 TCGv_i64 v = tcg_temp_new_i64(); 2501 tcg_gen_ext_i32_i64(v, arg[1].in); 2502 gen_shift(sar); 2503 } 2504 } 2505 2506 static void translate_srai(DisasContext *dc, const OpcodeArg arg[], 2507 const uint32_t par[]) 2508 { 2509 tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm); 2510 } 2511 2512 static void translate_src(DisasContext *dc, const OpcodeArg arg[], 2513 const uint32_t par[]) 2514 { 2515 TCGv_i64 v = tcg_temp_new_i64(); 2516 tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in); 2517 gen_shift(shr); 2518 } 2519 2520 static void translate_srl(DisasContext *dc, const OpcodeArg arg[], 2521 const uint32_t par[]) 2522 { 2523 if (dc->sar_m32_5bit) { 2524 tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]); 2525 } else { 2526 TCGv_i64 v = tcg_temp_new_i64(); 2527 tcg_gen_extu_i32_i64(v, arg[1].in); 2528 gen_shift(shr); 2529 } 2530 } 2531 2532 #undef gen_shift 2533 #undef gen_shift_reg 2534 2535 static void translate_srli(DisasContext *dc, const OpcodeArg arg[], 2536 const uint32_t par[]) 2537 { 2538 tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm); 2539 } 2540 2541 static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[], 2542 const uint32_t par[]) 2543 { 2544 TCGv_i32 tmp = tcg_temp_new_i32(); 2545 tcg_gen_shli_i32(tmp, arg[0].in, 3); 2546 gen_left_shift_sar(dc, tmp); 2547 tcg_temp_free(tmp); 2548 } 2549 2550 static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[], 2551 const uint32_t par[]) 2552 { 2553 TCGv_i32 tmp = tcg_temp_new_i32(); 2554 tcg_gen_shli_i32(tmp, arg[0].in, 3); 2555 gen_right_shift_sar(dc, tmp); 2556 tcg_temp_free(tmp); 2557 } 2558 2559 static void translate_ssai(DisasContext *dc, const OpcodeArg arg[], 2560 const uint32_t par[]) 2561 { 2562 TCGv_i32 tmp = tcg_const_i32(arg[0].imm); 2563 gen_right_shift_sar(dc, tmp); 2564 tcg_temp_free(tmp); 2565 } 2566 2567 static void translate_ssl(DisasContext *dc, const OpcodeArg arg[], 2568 const uint32_t par[]) 2569 { 2570 gen_left_shift_sar(dc, arg[0].in); 2571 } 2572 2573 static void translate_ssr(DisasContext *dc, const OpcodeArg arg[], 2574 const uint32_t par[]) 2575 { 2576 gen_right_shift_sar(dc, arg[0].in); 2577 } 2578 2579 static void translate_sub(DisasContext *dc, const OpcodeArg arg[], 2580 const uint32_t par[]) 2581 { 2582 tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in); 2583 } 2584 2585 static void translate_subx(DisasContext *dc, const OpcodeArg arg[], 2586 const uint32_t par[]) 2587 { 2588 TCGv_i32 tmp = tcg_temp_new_i32(); 2589 tcg_gen_shli_i32(tmp, arg[1].in, par[0]); 2590 tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in); 2591 tcg_temp_free(tmp); 2592 } 2593 2594 static void translate_waiti(DisasContext *dc, const OpcodeArg arg[], 2595 const uint32_t par[]) 2596 { 2597 #ifndef CONFIG_USER_ONLY 2598 gen_waiti(dc, arg[0].imm); 2599 #endif 2600 } 2601 2602 static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[], 2603 const uint32_t par[]) 2604 { 2605 #ifndef CONFIG_USER_ONLY 2606 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2607 2608 gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb); 2609 tcg_temp_free(dtlb); 2610 #endif 2611 } 2612 2613 static void translate_wptlb(DisasContext *dc, const OpcodeArg arg[], 2614 const uint32_t par[]) 2615 { 2616 #ifndef CONFIG_USER_ONLY 2617 gen_helper_wptlb(cpu_env, arg[0].in, arg[1].in); 2618 #endif 2619 } 2620 2621 static void translate_wer(DisasContext *dc, const OpcodeArg arg[], 2622 const uint32_t par[]) 2623 { 2624 gen_helper_wer(cpu_env, arg[0].in, arg[1].in); 2625 } 2626 2627 static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[], 2628 const uint32_t par[]) 2629 { 2630 /* TODO: GPIO32 may be a part of coprocessor */ 2631 tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in); 2632 } 2633 2634 static void translate_wsr(DisasContext *dc, const OpcodeArg arg[], 2635 const uint32_t par[]) 2636 { 2637 if (sr_name[par[0]]) { 2638 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); 2639 } 2640 } 2641 2642 static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[], 2643 const uint32_t par[]) 2644 { 2645 if (sr_name[par[0]]) { 2646 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]); 2647 } 2648 } 2649 2650 static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[], 2651 const uint32_t par[]) 2652 { 2653 tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in); 2654 } 2655 2656 static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[], 2657 const uint32_t par[]) 2658 { 2659 #ifndef CONFIG_USER_ONLY 2660 uint32_t id = par[0] - CCOMPARE; 2661 TCGv_i32 tmp = tcg_const_i32(id); 2662 2663 assert(id < dc->config->nccompare); 2664 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 2665 gen_io_start(); 2666 } 2667 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); 2668 gen_helper_update_ccompare(cpu_env, tmp); 2669 tcg_temp_free(tmp); 2670 #endif 2671 } 2672 2673 static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[], 2674 const uint32_t par[]) 2675 { 2676 #ifndef CONFIG_USER_ONLY 2677 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 2678 gen_io_start(); 2679 } 2680 gen_helper_wsr_ccount(cpu_env, arg[0].in); 2681 #endif 2682 } 2683 2684 static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[], 2685 const uint32_t par[]) 2686 { 2687 #ifndef CONFIG_USER_ONLY 2688 unsigned id = par[0] - DBREAKA; 2689 TCGv_i32 tmp = tcg_const_i32(id); 2690 2691 assert(id < dc->config->ndbreak); 2692 gen_helper_wsr_dbreaka(cpu_env, tmp, arg[0].in); 2693 tcg_temp_free(tmp); 2694 #endif 2695 } 2696 2697 static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[], 2698 const uint32_t par[]) 2699 { 2700 #ifndef CONFIG_USER_ONLY 2701 unsigned id = par[0] - DBREAKC; 2702 TCGv_i32 tmp = tcg_const_i32(id); 2703 2704 assert(id < dc->config->ndbreak); 2705 gen_helper_wsr_dbreakc(cpu_env, tmp, arg[0].in); 2706 tcg_temp_free(tmp); 2707 #endif 2708 } 2709 2710 static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[], 2711 const uint32_t par[]) 2712 { 2713 #ifndef CONFIG_USER_ONLY 2714 unsigned id = par[0] - IBREAKA; 2715 TCGv_i32 tmp = tcg_const_i32(id); 2716 2717 assert(id < dc->config->nibreak); 2718 gen_helper_wsr_ibreaka(cpu_env, tmp, arg[0].in); 2719 tcg_temp_free(tmp); 2720 #endif 2721 } 2722 2723 static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[], 2724 const uint32_t par[]) 2725 { 2726 #ifndef CONFIG_USER_ONLY 2727 gen_helper_wsr_ibreakenable(cpu_env, arg[0].in); 2728 #endif 2729 } 2730 2731 static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[], 2732 const uint32_t par[]) 2733 { 2734 #ifndef CONFIG_USER_ONLY 2735 if (dc->icount) { 2736 tcg_gen_mov_i32(dc->next_icount, arg[0].in); 2737 } else { 2738 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); 2739 } 2740 #endif 2741 } 2742 2743 static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[], 2744 const uint32_t par[]) 2745 { 2746 #ifndef CONFIG_USER_ONLY 2747 gen_helper_intclear(cpu_env, arg[0].in); 2748 #endif 2749 } 2750 2751 static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[], 2752 const uint32_t par[]) 2753 { 2754 #ifndef CONFIG_USER_ONLY 2755 gen_helper_intset(cpu_env, arg[0].in); 2756 #endif 2757 } 2758 2759 static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[], 2760 const uint32_t par[]) 2761 { 2762 #ifndef CONFIG_USER_ONLY 2763 gen_helper_wsr_memctl(cpu_env, arg[0].in); 2764 #endif 2765 } 2766 2767 static void translate_wsr_mpuenb(DisasContext *dc, const OpcodeArg arg[], 2768 const uint32_t par[]) 2769 { 2770 #ifndef CONFIG_USER_ONLY 2771 gen_helper_wsr_mpuenb(cpu_env, arg[0].in); 2772 #endif 2773 } 2774 2775 static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[], 2776 const uint32_t par[]) 2777 { 2778 #ifndef CONFIG_USER_ONLY 2779 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB | 2780 PS_UM | PS_EXCM | PS_INTLEVEL; 2781 2782 if (option_enabled(dc, XTENSA_OPTION_MMU) || 2783 option_enabled(dc, XTENSA_OPTION_MPU)) { 2784 mask |= PS_RING; 2785 } 2786 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask); 2787 #endif 2788 } 2789 2790 static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[], 2791 const uint32_t par[]) 2792 { 2793 #ifndef CONFIG_USER_ONLY 2794 gen_helper_wsr_rasid(cpu_env, arg[0].in); 2795 #endif 2796 } 2797 2798 static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[], 2799 const uint32_t par[]) 2800 { 2801 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f); 2802 if (dc->sar_m32_5bit) { 2803 tcg_gen_discard_i32(dc->sar_m32); 2804 } 2805 dc->sar_5bit = false; 2806 dc->sar_m32_5bit = false; 2807 } 2808 2809 static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[], 2810 const uint32_t par[]) 2811 { 2812 #ifndef CONFIG_USER_ONLY 2813 tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in); 2814 #endif 2815 } 2816 2817 static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[], 2818 const uint32_t par[]) 2819 { 2820 #ifndef CONFIG_USER_ONLY 2821 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 2822 (1 << dc->config->nareg / 4) - 1); 2823 #endif 2824 } 2825 2826 static void translate_wur(DisasContext *dc, const OpcodeArg arg[], 2827 const uint32_t par[]) 2828 { 2829 tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in); 2830 } 2831 2832 static void translate_xor(DisasContext *dc, const OpcodeArg arg[], 2833 const uint32_t par[]) 2834 { 2835 tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in); 2836 } 2837 2838 static void translate_xsr(DisasContext *dc, const OpcodeArg arg[], 2839 const uint32_t par[]) 2840 { 2841 if (sr_name[par[0]]) { 2842 TCGv_i32 tmp = tcg_temp_new_i32(); 2843 2844 tcg_gen_mov_i32(tmp, arg[0].in); 2845 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); 2846 tcg_gen_mov_i32(cpu_SR[par[0]], tmp); 2847 tcg_temp_free(tmp); 2848 } else { 2849 tcg_gen_movi_i32(arg[0].out, 0); 2850 } 2851 } 2852 2853 static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[], 2854 const uint32_t par[]) 2855 { 2856 if (sr_name[par[0]]) { 2857 TCGv_i32 tmp = tcg_temp_new_i32(); 2858 2859 tcg_gen_mov_i32(tmp, arg[0].in); 2860 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); 2861 tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]); 2862 tcg_temp_free(tmp); 2863 } else { 2864 tcg_gen_movi_i32(arg[0].out, 0); 2865 } 2866 } 2867 2868 static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[], 2869 const uint32_t par[]) 2870 { 2871 #ifndef CONFIG_USER_ONLY 2872 TCGv_i32 tmp = tcg_temp_new_i32(); 2873 2874 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 2875 gen_io_start(); 2876 } 2877 2878 gen_helper_update_ccount(cpu_env); 2879 tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); 2880 gen_helper_wsr_ccount(cpu_env, arg[0].in); 2881 tcg_gen_mov_i32(arg[0].out, tmp); 2882 tcg_temp_free(tmp); 2883 2884 #endif 2885 } 2886 2887 #define gen_translate_xsr(name) \ 2888 static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \ 2889 const uint32_t par[]) \ 2890 { \ 2891 TCGv_i32 tmp = tcg_temp_new_i32(); \ 2892 \ 2893 if (sr_name[par[0]]) { \ 2894 tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \ 2895 } else { \ 2896 tcg_gen_movi_i32(tmp, 0); \ 2897 } \ 2898 translate_wsr_##name(dc, arg, par); \ 2899 tcg_gen_mov_i32(arg[0].out, tmp); \ 2900 tcg_temp_free(tmp); \ 2901 } 2902 2903 gen_translate_xsr(acchi) 2904 gen_translate_xsr(ccompare) 2905 gen_translate_xsr(dbreaka) 2906 gen_translate_xsr(dbreakc) 2907 gen_translate_xsr(ibreaka) 2908 gen_translate_xsr(ibreakenable) 2909 gen_translate_xsr(icount) 2910 gen_translate_xsr(memctl) 2911 gen_translate_xsr(mpuenb) 2912 gen_translate_xsr(ps) 2913 gen_translate_xsr(rasid) 2914 gen_translate_xsr(sar) 2915 gen_translate_xsr(windowbase) 2916 gen_translate_xsr(windowstart) 2917 2918 #undef gen_translate_xsr 2919 2920 static const XtensaOpcodeOps core_ops[] = { 2921 { 2922 .name = "abs", 2923 .translate = translate_abs, 2924 }, { 2925 .name = (const char * const[]) { 2926 "add", "add.n", NULL, 2927 }, 2928 .translate = translate_add, 2929 .op_flags = XTENSA_OP_NAME_ARRAY, 2930 }, { 2931 .name = (const char * const[]) { 2932 "addi", "addi.n", NULL, 2933 }, 2934 .translate = translate_addi, 2935 .op_flags = XTENSA_OP_NAME_ARRAY, 2936 }, { 2937 .name = "addmi", 2938 .translate = translate_addi, 2939 }, { 2940 .name = "addx2", 2941 .translate = translate_addx, 2942 .par = (const uint32_t[]){1}, 2943 }, { 2944 .name = "addx4", 2945 .translate = translate_addx, 2946 .par = (const uint32_t[]){2}, 2947 }, { 2948 .name = "addx8", 2949 .translate = translate_addx, 2950 .par = (const uint32_t[]){3}, 2951 }, { 2952 .name = "all4", 2953 .translate = translate_all, 2954 .par = (const uint32_t[]){true, 4}, 2955 }, { 2956 .name = "all8", 2957 .translate = translate_all, 2958 .par = (const uint32_t[]){true, 8}, 2959 }, { 2960 .name = "and", 2961 .translate = translate_and, 2962 }, { 2963 .name = "andb", 2964 .translate = translate_boolean, 2965 .par = (const uint32_t[]){BOOLEAN_AND}, 2966 }, { 2967 .name = "andbc", 2968 .translate = translate_boolean, 2969 .par = (const uint32_t[]){BOOLEAN_ANDC}, 2970 }, { 2971 .name = "any4", 2972 .translate = translate_all, 2973 .par = (const uint32_t[]){false, 4}, 2974 }, { 2975 .name = "any8", 2976 .translate = translate_all, 2977 .par = (const uint32_t[]){false, 8}, 2978 }, { 2979 .name = (const char * const[]) { 2980 "ball", "ball.w15", "ball.w18", NULL, 2981 }, 2982 .translate = translate_ball, 2983 .par = (const uint32_t[]){TCG_COND_EQ}, 2984 .op_flags = XTENSA_OP_NAME_ARRAY, 2985 }, { 2986 .name = (const char * const[]) { 2987 "bany", "bany.w15", "bany.w18", NULL, 2988 }, 2989 .translate = translate_bany, 2990 .par = (const uint32_t[]){TCG_COND_NE}, 2991 .op_flags = XTENSA_OP_NAME_ARRAY, 2992 }, { 2993 .name = (const char * const[]) { 2994 "bbc", "bbc.w15", "bbc.w18", NULL, 2995 }, 2996 .translate = translate_bb, 2997 .par = (const uint32_t[]){TCG_COND_EQ}, 2998 .op_flags = XTENSA_OP_NAME_ARRAY, 2999 }, { 3000 .name = (const char * const[]) { 3001 "bbci", "bbci.w15", "bbci.w18", NULL, 3002 }, 3003 .translate = translate_bbi, 3004 .par = (const uint32_t[]){TCG_COND_EQ}, 3005 .op_flags = XTENSA_OP_NAME_ARRAY, 3006 }, { 3007 .name = (const char * const[]) { 3008 "bbs", "bbs.w15", "bbs.w18", NULL, 3009 }, 3010 .translate = translate_bb, 3011 .par = (const uint32_t[]){TCG_COND_NE}, 3012 .op_flags = XTENSA_OP_NAME_ARRAY, 3013 }, { 3014 .name = (const char * const[]) { 3015 "bbsi", "bbsi.w15", "bbsi.w18", NULL, 3016 }, 3017 .translate = translate_bbi, 3018 .par = (const uint32_t[]){TCG_COND_NE}, 3019 .op_flags = XTENSA_OP_NAME_ARRAY, 3020 }, { 3021 .name = (const char * const[]) { 3022 "beq", "beq.w15", "beq.w18", NULL, 3023 }, 3024 .translate = translate_b, 3025 .par = (const uint32_t[]){TCG_COND_EQ}, 3026 .op_flags = XTENSA_OP_NAME_ARRAY, 3027 }, { 3028 .name = (const char * const[]) { 3029 "beqi", "beqi.w15", "beqi.w18", NULL, 3030 }, 3031 .translate = translate_bi, 3032 .par = (const uint32_t[]){TCG_COND_EQ}, 3033 .op_flags = XTENSA_OP_NAME_ARRAY, 3034 }, { 3035 .name = (const char * const[]) { 3036 "beqz", "beqz.n", "beqz.w15", "beqz.w18", NULL, 3037 }, 3038 .translate = translate_bz, 3039 .par = (const uint32_t[]){TCG_COND_EQ}, 3040 .op_flags = XTENSA_OP_NAME_ARRAY, 3041 }, { 3042 .name = "bf", 3043 .translate = translate_bp, 3044 .par = (const uint32_t[]){TCG_COND_EQ}, 3045 }, { 3046 .name = (const char * const[]) { 3047 "bge", "bge.w15", "bge.w18", NULL, 3048 }, 3049 .translate = translate_b, 3050 .par = (const uint32_t[]){TCG_COND_GE}, 3051 .op_flags = XTENSA_OP_NAME_ARRAY, 3052 }, { 3053 .name = (const char * const[]) { 3054 "bgei", "bgei.w15", "bgei.w18", NULL, 3055 }, 3056 .translate = translate_bi, 3057 .par = (const uint32_t[]){TCG_COND_GE}, 3058 .op_flags = XTENSA_OP_NAME_ARRAY, 3059 }, { 3060 .name = (const char * const[]) { 3061 "bgeu", "bgeu.w15", "bgeu.w18", NULL, 3062 }, 3063 .translate = translate_b, 3064 .par = (const uint32_t[]){TCG_COND_GEU}, 3065 .op_flags = XTENSA_OP_NAME_ARRAY, 3066 }, { 3067 .name = (const char * const[]) { 3068 "bgeui", "bgeui.w15", "bgeui.w18", NULL, 3069 }, 3070 .translate = translate_bi, 3071 .par = (const uint32_t[]){TCG_COND_GEU}, 3072 .op_flags = XTENSA_OP_NAME_ARRAY, 3073 }, { 3074 .name = (const char * const[]) { 3075 "bgez", "bgez.w15", "bgez.w18", NULL, 3076 }, 3077 .translate = translate_bz, 3078 .par = (const uint32_t[]){TCG_COND_GE}, 3079 .op_flags = XTENSA_OP_NAME_ARRAY, 3080 }, { 3081 .name = (const char * const[]) { 3082 "blt", "blt.w15", "blt.w18", NULL, 3083 }, 3084 .translate = translate_b, 3085 .par = (const uint32_t[]){TCG_COND_LT}, 3086 .op_flags = XTENSA_OP_NAME_ARRAY, 3087 }, { 3088 .name = (const char * const[]) { 3089 "blti", "blti.w15", "blti.w18", NULL, 3090 }, 3091 .translate = translate_bi, 3092 .par = (const uint32_t[]){TCG_COND_LT}, 3093 .op_flags = XTENSA_OP_NAME_ARRAY, 3094 }, { 3095 .name = (const char * const[]) { 3096 "bltu", "bltu.w15", "bltu.w18", NULL, 3097 }, 3098 .translate = translate_b, 3099 .par = (const uint32_t[]){TCG_COND_LTU}, 3100 .op_flags = XTENSA_OP_NAME_ARRAY, 3101 }, { 3102 .name = (const char * const[]) { 3103 "bltui", "bltui.w15", "bltui.w18", NULL, 3104 }, 3105 .translate = translate_bi, 3106 .par = (const uint32_t[]){TCG_COND_LTU}, 3107 .op_flags = XTENSA_OP_NAME_ARRAY, 3108 }, { 3109 .name = (const char * const[]) { 3110 "bltz", "bltz.w15", "bltz.w18", NULL, 3111 }, 3112 .translate = translate_bz, 3113 .par = (const uint32_t[]){TCG_COND_LT}, 3114 .op_flags = XTENSA_OP_NAME_ARRAY, 3115 }, { 3116 .name = (const char * const[]) { 3117 "bnall", "bnall.w15", "bnall.w18", NULL, 3118 }, 3119 .translate = translate_ball, 3120 .par = (const uint32_t[]){TCG_COND_NE}, 3121 .op_flags = XTENSA_OP_NAME_ARRAY, 3122 }, { 3123 .name = (const char * const[]) { 3124 "bne", "bne.w15", "bne.w18", NULL, 3125 }, 3126 .translate = translate_b, 3127 .par = (const uint32_t[]){TCG_COND_NE}, 3128 .op_flags = XTENSA_OP_NAME_ARRAY, 3129 }, { 3130 .name = (const char * const[]) { 3131 "bnei", "bnei.w15", "bnei.w18", NULL, 3132 }, 3133 .translate = translate_bi, 3134 .par = (const uint32_t[]){TCG_COND_NE}, 3135 .op_flags = XTENSA_OP_NAME_ARRAY, 3136 }, { 3137 .name = (const char * const[]) { 3138 "bnez", "bnez.n", "bnez.w15", "bnez.w18", NULL, 3139 }, 3140 .translate = translate_bz, 3141 .par = (const uint32_t[]){TCG_COND_NE}, 3142 .op_flags = XTENSA_OP_NAME_ARRAY, 3143 }, { 3144 .name = (const char * const[]) { 3145 "bnone", "bnone.w15", "bnone.w18", NULL, 3146 }, 3147 .translate = translate_bany, 3148 .par = (const uint32_t[]){TCG_COND_EQ}, 3149 .op_flags = XTENSA_OP_NAME_ARRAY, 3150 }, { 3151 .name = "break", 3152 .translate = translate_nop, 3153 .par = (const uint32_t[]){DEBUGCAUSE_BI}, 3154 .op_flags = XTENSA_OP_DEBUG_BREAK, 3155 }, { 3156 .name = "break.n", 3157 .translate = translate_nop, 3158 .par = (const uint32_t[]){DEBUGCAUSE_BN}, 3159 .op_flags = XTENSA_OP_DEBUG_BREAK, 3160 }, { 3161 .name = "bt", 3162 .translate = translate_bp, 3163 .par = (const uint32_t[]){TCG_COND_NE}, 3164 }, { 3165 .name = "call0", 3166 .translate = translate_call0, 3167 }, { 3168 .name = "call12", 3169 .translate = translate_callw, 3170 .par = (const uint32_t[]){3}, 3171 }, { 3172 .name = "call4", 3173 .translate = translate_callw, 3174 .par = (const uint32_t[]){1}, 3175 }, { 3176 .name = "call8", 3177 .translate = translate_callw, 3178 .par = (const uint32_t[]){2}, 3179 }, { 3180 .name = "callx0", 3181 .translate = translate_callx0, 3182 }, { 3183 .name = "callx12", 3184 .translate = translate_callxw, 3185 .par = (const uint32_t[]){3}, 3186 }, { 3187 .name = "callx4", 3188 .translate = translate_callxw, 3189 .par = (const uint32_t[]){1}, 3190 }, { 3191 .name = "callx8", 3192 .translate = translate_callxw, 3193 .par = (const uint32_t[]){2}, 3194 }, { 3195 .name = "clamps", 3196 .translate = translate_clamps, 3197 }, { 3198 .name = "clrb_expstate", 3199 .translate = translate_clrb_expstate, 3200 }, { 3201 .name = "clrex", 3202 .translate = translate_clrex, 3203 }, { 3204 .name = "const16", 3205 .translate = translate_const16, 3206 }, { 3207 .name = "depbits", 3208 .translate = translate_depbits, 3209 }, { 3210 .name = "dhi", 3211 .translate = translate_dcache, 3212 .op_flags = XTENSA_OP_PRIVILEGED, 3213 }, { 3214 .name = "dhi.b", 3215 .translate = translate_nop, 3216 }, { 3217 .name = "dhu", 3218 .translate = translate_dcache, 3219 .op_flags = XTENSA_OP_PRIVILEGED, 3220 }, { 3221 .name = "dhwb", 3222 .translate = translate_dcache, 3223 }, { 3224 .name = "dhwb.b", 3225 .translate = translate_nop, 3226 }, { 3227 .name = "dhwbi", 3228 .translate = translate_dcache, 3229 }, { 3230 .name = "dhwbi.b", 3231 .translate = translate_nop, 3232 }, { 3233 .name = "dii", 3234 .translate = translate_nop, 3235 .op_flags = XTENSA_OP_PRIVILEGED, 3236 }, { 3237 .name = "diu", 3238 .translate = translate_nop, 3239 .op_flags = XTENSA_OP_PRIVILEGED, 3240 }, { 3241 .name = "diwb", 3242 .translate = translate_nop, 3243 .op_flags = XTENSA_OP_PRIVILEGED, 3244 }, { 3245 .name = "diwbi", 3246 .translate = translate_nop, 3247 .op_flags = XTENSA_OP_PRIVILEGED, 3248 }, { 3249 .name = "diwbui.p", 3250 .translate = translate_diwbuip, 3251 .op_flags = XTENSA_OP_PRIVILEGED, 3252 }, { 3253 .name = "dpfl", 3254 .translate = translate_dcache, 3255 .op_flags = XTENSA_OP_PRIVILEGED, 3256 }, { 3257 .name = "dpfm.b", 3258 .translate = translate_nop, 3259 }, { 3260 .name = "dpfm.bf", 3261 .translate = translate_nop, 3262 }, { 3263 .name = "dpfr", 3264 .translate = translate_nop, 3265 }, { 3266 .name = "dpfr.b", 3267 .translate = translate_nop, 3268 }, { 3269 .name = "dpfr.bf", 3270 .translate = translate_nop, 3271 }, { 3272 .name = "dpfro", 3273 .translate = translate_nop, 3274 }, { 3275 .name = "dpfw", 3276 .translate = translate_nop, 3277 }, { 3278 .name = "dpfw.b", 3279 .translate = translate_nop, 3280 }, { 3281 .name = "dpfw.bf", 3282 .translate = translate_nop, 3283 }, { 3284 .name = "dpfwo", 3285 .translate = translate_nop, 3286 }, { 3287 .name = "dsync", 3288 .translate = translate_nop, 3289 }, { 3290 .name = "entry", 3291 .translate = translate_entry, 3292 .test_exceptions = test_exceptions_entry, 3293 .test_overflow = test_overflow_entry, 3294 .op_flags = XTENSA_OP_EXIT_TB_M1 | 3295 XTENSA_OP_SYNC_REGISTER_WINDOW, 3296 }, { 3297 .name = "esync", 3298 .translate = translate_nop, 3299 }, { 3300 .name = "excw", 3301 .translate = translate_nop, 3302 }, { 3303 .name = "extui", 3304 .translate = translate_extui, 3305 }, { 3306 .name = "extw", 3307 .translate = translate_memw, 3308 }, { 3309 .name = "getex", 3310 .translate = translate_getex, 3311 }, { 3312 .name = "hwwdtlba", 3313 .op_flags = XTENSA_OP_ILL, 3314 }, { 3315 .name = "hwwitlba", 3316 .op_flags = XTENSA_OP_ILL, 3317 }, { 3318 .name = "idtlb", 3319 .translate = translate_itlb, 3320 .par = (const uint32_t[]){true}, 3321 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 3322 }, { 3323 .name = "ihi", 3324 .translate = translate_icache, 3325 }, { 3326 .name = "ihu", 3327 .translate = translate_icache, 3328 .op_flags = XTENSA_OP_PRIVILEGED, 3329 }, { 3330 .name = "iii", 3331 .translate = translate_nop, 3332 .op_flags = XTENSA_OP_PRIVILEGED, 3333 }, { 3334 .name = "iitlb", 3335 .translate = translate_itlb, 3336 .par = (const uint32_t[]){false}, 3337 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 3338 }, { 3339 .name = "iiu", 3340 .translate = translate_nop, 3341 .op_flags = XTENSA_OP_PRIVILEGED, 3342 }, { 3343 .name = (const char * const[]) { 3344 "ill", "ill.n", NULL, 3345 }, 3346 .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY, 3347 }, { 3348 .name = "ipf", 3349 .translate = translate_nop, 3350 }, { 3351 .name = "ipfl", 3352 .translate = translate_icache, 3353 .op_flags = XTENSA_OP_PRIVILEGED, 3354 }, { 3355 .name = "isync", 3356 .translate = translate_nop, 3357 }, { 3358 .name = "j", 3359 .translate = translate_j, 3360 }, { 3361 .name = "jx", 3362 .translate = translate_jx, 3363 }, { 3364 .name = "l16si", 3365 .translate = translate_ldst, 3366 .par = (const uint32_t[]){MO_TESW, false, false}, 3367 .op_flags = XTENSA_OP_LOAD, 3368 }, { 3369 .name = "l16ui", 3370 .translate = translate_ldst, 3371 .par = (const uint32_t[]){MO_TEUW, false, false}, 3372 .op_flags = XTENSA_OP_LOAD, 3373 }, { 3374 .name = "l32ai", 3375 .translate = translate_ldst, 3376 .par = (const uint32_t[]){MO_TEUL | MO_ALIGN, true, false}, 3377 .op_flags = XTENSA_OP_LOAD, 3378 }, { 3379 .name = "l32e", 3380 .translate = translate_l32e, 3381 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD, 3382 }, { 3383 .name = "l32ex", 3384 .translate = translate_l32ex, 3385 .op_flags = XTENSA_OP_LOAD, 3386 }, { 3387 .name = (const char * const[]) { 3388 "l32i", "l32i.n", NULL, 3389 }, 3390 .translate = translate_ldst, 3391 .par = (const uint32_t[]){MO_TEUL, false, false}, 3392 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD, 3393 }, { 3394 .name = "l32r", 3395 .translate = translate_l32r, 3396 .op_flags = XTENSA_OP_LOAD, 3397 }, { 3398 .name = "l8ui", 3399 .translate = translate_ldst, 3400 .par = (const uint32_t[]){MO_UB, false, false}, 3401 .op_flags = XTENSA_OP_LOAD, 3402 }, { 3403 .name = "lddec", 3404 .translate = translate_mac16, 3405 .par = (const uint32_t[]){MAC16_NONE, 0, -4}, 3406 .op_flags = XTENSA_OP_LOAD, 3407 }, { 3408 .name = "ldinc", 3409 .translate = translate_mac16, 3410 .par = (const uint32_t[]){MAC16_NONE, 0, 4}, 3411 .op_flags = XTENSA_OP_LOAD, 3412 }, { 3413 .name = "ldpte", 3414 .op_flags = XTENSA_OP_ILL, 3415 }, { 3416 .name = (const char * const[]) { 3417 "loop", "loop.w15", NULL, 3418 }, 3419 .translate = translate_loop, 3420 .par = (const uint32_t[]){TCG_COND_NEVER}, 3421 .op_flags = XTENSA_OP_NAME_ARRAY, 3422 }, { 3423 .name = (const char * const[]) { 3424 "loopgtz", "loopgtz.w15", NULL, 3425 }, 3426 .translate = translate_loop, 3427 .par = (const uint32_t[]){TCG_COND_GT}, 3428 .op_flags = XTENSA_OP_NAME_ARRAY, 3429 }, { 3430 .name = (const char * const[]) { 3431 "loopnez", "loopnez.w15", NULL, 3432 }, 3433 .translate = translate_loop, 3434 .par = (const uint32_t[]){TCG_COND_NE}, 3435 .op_flags = XTENSA_OP_NAME_ARRAY, 3436 }, { 3437 .name = "max", 3438 .translate = translate_smax, 3439 }, { 3440 .name = "maxu", 3441 .translate = translate_umax, 3442 }, { 3443 .name = "memw", 3444 .translate = translate_memw, 3445 }, { 3446 .name = "min", 3447 .translate = translate_smin, 3448 }, { 3449 .name = "minu", 3450 .translate = translate_umin, 3451 }, { 3452 .name = (const char * const[]) { 3453 "mov", "mov.n", NULL, 3454 }, 3455 .translate = translate_mov, 3456 .op_flags = XTENSA_OP_NAME_ARRAY, 3457 }, { 3458 .name = "moveqz", 3459 .translate = translate_movcond, 3460 .par = (const uint32_t[]){TCG_COND_EQ}, 3461 }, { 3462 .name = "movf", 3463 .translate = translate_movp, 3464 .par = (const uint32_t[]){TCG_COND_EQ}, 3465 }, { 3466 .name = "movgez", 3467 .translate = translate_movcond, 3468 .par = (const uint32_t[]){TCG_COND_GE}, 3469 }, { 3470 .name = "movi", 3471 .translate = translate_movi, 3472 }, { 3473 .name = "movi.n", 3474 .translate = translate_movi, 3475 }, { 3476 .name = "movltz", 3477 .translate = translate_movcond, 3478 .par = (const uint32_t[]){TCG_COND_LT}, 3479 }, { 3480 .name = "movnez", 3481 .translate = translate_movcond, 3482 .par = (const uint32_t[]){TCG_COND_NE}, 3483 }, { 3484 .name = "movsp", 3485 .translate = translate_movsp, 3486 .op_flags = XTENSA_OP_ALLOCA, 3487 }, { 3488 .name = "movt", 3489 .translate = translate_movp, 3490 .par = (const uint32_t[]){TCG_COND_NE}, 3491 }, { 3492 .name = "mul.aa.hh", 3493 .translate = translate_mac16, 3494 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3495 }, { 3496 .name = "mul.aa.hl", 3497 .translate = translate_mac16, 3498 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3499 }, { 3500 .name = "mul.aa.lh", 3501 .translate = translate_mac16, 3502 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3503 }, { 3504 .name = "mul.aa.ll", 3505 .translate = translate_mac16, 3506 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3507 }, { 3508 .name = "mul.ad.hh", 3509 .translate = translate_mac16, 3510 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3511 }, { 3512 .name = "mul.ad.hl", 3513 .translate = translate_mac16, 3514 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3515 }, { 3516 .name = "mul.ad.lh", 3517 .translate = translate_mac16, 3518 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3519 }, { 3520 .name = "mul.ad.ll", 3521 .translate = translate_mac16, 3522 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3523 }, { 3524 .name = "mul.da.hh", 3525 .translate = translate_mac16, 3526 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3527 }, { 3528 .name = "mul.da.hl", 3529 .translate = translate_mac16, 3530 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3531 }, { 3532 .name = "mul.da.lh", 3533 .translate = translate_mac16, 3534 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3535 }, { 3536 .name = "mul.da.ll", 3537 .translate = translate_mac16, 3538 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3539 }, { 3540 .name = "mul.dd.hh", 3541 .translate = translate_mac16, 3542 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3543 }, { 3544 .name = "mul.dd.hl", 3545 .translate = translate_mac16, 3546 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3547 }, { 3548 .name = "mul.dd.lh", 3549 .translate = translate_mac16, 3550 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3551 }, { 3552 .name = "mul.dd.ll", 3553 .translate = translate_mac16, 3554 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3555 }, { 3556 .name = "mul16s", 3557 .translate = translate_mul16, 3558 .par = (const uint32_t[]){true}, 3559 }, { 3560 .name = "mul16u", 3561 .translate = translate_mul16, 3562 .par = (const uint32_t[]){false}, 3563 }, { 3564 .name = "mula.aa.hh", 3565 .translate = translate_mac16, 3566 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3567 }, { 3568 .name = "mula.aa.hl", 3569 .translate = translate_mac16, 3570 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3571 }, { 3572 .name = "mula.aa.lh", 3573 .translate = translate_mac16, 3574 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3575 }, { 3576 .name = "mula.aa.ll", 3577 .translate = translate_mac16, 3578 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3579 }, { 3580 .name = "mula.ad.hh", 3581 .translate = translate_mac16, 3582 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3583 }, { 3584 .name = "mula.ad.hl", 3585 .translate = translate_mac16, 3586 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3587 }, { 3588 .name = "mula.ad.lh", 3589 .translate = translate_mac16, 3590 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3591 }, { 3592 .name = "mula.ad.ll", 3593 .translate = translate_mac16, 3594 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3595 }, { 3596 .name = "mula.da.hh", 3597 .translate = translate_mac16, 3598 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3599 }, { 3600 .name = "mula.da.hh.lddec", 3601 .translate = translate_mac16, 3602 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4}, 3603 }, { 3604 .name = "mula.da.hh.ldinc", 3605 .translate = translate_mac16, 3606 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4}, 3607 }, { 3608 .name = "mula.da.hl", 3609 .translate = translate_mac16, 3610 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3611 }, { 3612 .name = "mula.da.hl.lddec", 3613 .translate = translate_mac16, 3614 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4}, 3615 }, { 3616 .name = "mula.da.hl.ldinc", 3617 .translate = translate_mac16, 3618 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4}, 3619 }, { 3620 .name = "mula.da.lh", 3621 .translate = translate_mac16, 3622 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3623 }, { 3624 .name = "mula.da.lh.lddec", 3625 .translate = translate_mac16, 3626 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4}, 3627 }, { 3628 .name = "mula.da.lh.ldinc", 3629 .translate = translate_mac16, 3630 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4}, 3631 }, { 3632 .name = "mula.da.ll", 3633 .translate = translate_mac16, 3634 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3635 }, { 3636 .name = "mula.da.ll.lddec", 3637 .translate = translate_mac16, 3638 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4}, 3639 }, { 3640 .name = "mula.da.ll.ldinc", 3641 .translate = translate_mac16, 3642 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4}, 3643 }, { 3644 .name = "mula.dd.hh", 3645 .translate = translate_mac16, 3646 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3647 }, { 3648 .name = "mula.dd.hh.lddec", 3649 .translate = translate_mac16, 3650 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4}, 3651 }, { 3652 .name = "mula.dd.hh.ldinc", 3653 .translate = translate_mac16, 3654 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4}, 3655 }, { 3656 .name = "mula.dd.hl", 3657 .translate = translate_mac16, 3658 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3659 }, { 3660 .name = "mula.dd.hl.lddec", 3661 .translate = translate_mac16, 3662 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4}, 3663 }, { 3664 .name = "mula.dd.hl.ldinc", 3665 .translate = translate_mac16, 3666 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4}, 3667 }, { 3668 .name = "mula.dd.lh", 3669 .translate = translate_mac16, 3670 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3671 }, { 3672 .name = "mula.dd.lh.lddec", 3673 .translate = translate_mac16, 3674 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4}, 3675 }, { 3676 .name = "mula.dd.lh.ldinc", 3677 .translate = translate_mac16, 3678 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4}, 3679 }, { 3680 .name = "mula.dd.ll", 3681 .translate = translate_mac16, 3682 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3683 }, { 3684 .name = "mula.dd.ll.lddec", 3685 .translate = translate_mac16, 3686 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4}, 3687 }, { 3688 .name = "mula.dd.ll.ldinc", 3689 .translate = translate_mac16, 3690 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4}, 3691 }, { 3692 .name = "mull", 3693 .translate = translate_mull, 3694 }, { 3695 .name = "muls.aa.hh", 3696 .translate = translate_mac16, 3697 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3698 }, { 3699 .name = "muls.aa.hl", 3700 .translate = translate_mac16, 3701 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3702 }, { 3703 .name = "muls.aa.lh", 3704 .translate = translate_mac16, 3705 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3706 }, { 3707 .name = "muls.aa.ll", 3708 .translate = translate_mac16, 3709 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3710 }, { 3711 .name = "muls.ad.hh", 3712 .translate = translate_mac16, 3713 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3714 }, { 3715 .name = "muls.ad.hl", 3716 .translate = translate_mac16, 3717 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3718 }, { 3719 .name = "muls.ad.lh", 3720 .translate = translate_mac16, 3721 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3722 }, { 3723 .name = "muls.ad.ll", 3724 .translate = translate_mac16, 3725 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3726 }, { 3727 .name = "muls.da.hh", 3728 .translate = translate_mac16, 3729 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3730 }, { 3731 .name = "muls.da.hl", 3732 .translate = translate_mac16, 3733 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3734 }, { 3735 .name = "muls.da.lh", 3736 .translate = translate_mac16, 3737 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3738 }, { 3739 .name = "muls.da.ll", 3740 .translate = translate_mac16, 3741 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3742 }, { 3743 .name = "muls.dd.hh", 3744 .translate = translate_mac16, 3745 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3746 }, { 3747 .name = "muls.dd.hl", 3748 .translate = translate_mac16, 3749 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3750 }, { 3751 .name = "muls.dd.lh", 3752 .translate = translate_mac16, 3753 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3754 }, { 3755 .name = "muls.dd.ll", 3756 .translate = translate_mac16, 3757 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3758 }, { 3759 .name = "mulsh", 3760 .translate = translate_mulh, 3761 .par = (const uint32_t[]){true}, 3762 }, { 3763 .name = "muluh", 3764 .translate = translate_mulh, 3765 .par = (const uint32_t[]){false}, 3766 }, { 3767 .name = "neg", 3768 .translate = translate_neg, 3769 }, { 3770 .name = (const char * const[]) { 3771 "nop", "nop.n", NULL, 3772 }, 3773 .translate = translate_nop, 3774 .op_flags = XTENSA_OP_NAME_ARRAY, 3775 }, { 3776 .name = "nsa", 3777 .translate = translate_nsa, 3778 }, { 3779 .name = "nsau", 3780 .translate = translate_nsau, 3781 }, { 3782 .name = "or", 3783 .translate = translate_or, 3784 }, { 3785 .name = "orb", 3786 .translate = translate_boolean, 3787 .par = (const uint32_t[]){BOOLEAN_OR}, 3788 }, { 3789 .name = "orbc", 3790 .translate = translate_boolean, 3791 .par = (const uint32_t[]){BOOLEAN_ORC}, 3792 }, { 3793 .name = "pdtlb", 3794 .translate = translate_ptlb, 3795 .par = (const uint32_t[]){true}, 3796 .op_flags = XTENSA_OP_PRIVILEGED, 3797 }, { 3798 .name = "pfend.a", 3799 .translate = translate_nop, 3800 }, { 3801 .name = "pfend.o", 3802 .translate = translate_nop, 3803 }, { 3804 .name = "pfnxt.f", 3805 .translate = translate_nop, 3806 }, { 3807 .name = "pfwait.a", 3808 .translate = translate_nop, 3809 }, { 3810 .name = "pfwait.r", 3811 .translate = translate_nop, 3812 }, { 3813 .name = "pitlb", 3814 .translate = translate_ptlb, 3815 .par = (const uint32_t[]){false}, 3816 .op_flags = XTENSA_OP_PRIVILEGED, 3817 }, { 3818 .name = "pptlb", 3819 .translate = translate_pptlb, 3820 .op_flags = XTENSA_OP_PRIVILEGED, 3821 }, { 3822 .name = "quos", 3823 .translate = translate_quos, 3824 .par = (const uint32_t[]){true}, 3825 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3826 }, { 3827 .name = "quou", 3828 .translate = translate_quou, 3829 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3830 }, { 3831 .name = "rdtlb0", 3832 .translate = translate_rtlb, 3833 .par = (const uint32_t[]){true, 0}, 3834 .op_flags = XTENSA_OP_PRIVILEGED, 3835 }, { 3836 .name = "rdtlb1", 3837 .translate = translate_rtlb, 3838 .par = (const uint32_t[]){true, 1}, 3839 .op_flags = XTENSA_OP_PRIVILEGED, 3840 }, { 3841 .name = "read_impwire", 3842 .translate = translate_read_impwire, 3843 }, { 3844 .name = "rems", 3845 .translate = translate_quos, 3846 .par = (const uint32_t[]){false}, 3847 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3848 }, { 3849 .name = "remu", 3850 .translate = translate_remu, 3851 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3852 }, { 3853 .name = "rer", 3854 .translate = translate_rer, 3855 .op_flags = XTENSA_OP_PRIVILEGED, 3856 }, { 3857 .name = (const char * const[]) { 3858 "ret", "ret.n", NULL, 3859 }, 3860 .translate = translate_ret, 3861 .op_flags = XTENSA_OP_NAME_ARRAY, 3862 }, { 3863 .name = (const char * const[]) { 3864 "retw", "retw.n", NULL, 3865 }, 3866 .translate = translate_retw, 3867 .test_exceptions = test_exceptions_retw, 3868 .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY, 3869 }, { 3870 .name = "rfdd", 3871 .op_flags = XTENSA_OP_ILL, 3872 }, { 3873 .name = "rfde", 3874 .translate = translate_rfde, 3875 .op_flags = XTENSA_OP_PRIVILEGED, 3876 }, { 3877 .name = "rfdo", 3878 .op_flags = XTENSA_OP_ILL, 3879 }, { 3880 .name = "rfe", 3881 .translate = translate_rfe, 3882 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3883 }, { 3884 .name = "rfi", 3885 .translate = translate_rfi, 3886 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3887 }, { 3888 .name = "rfwo", 3889 .translate = translate_rfw, 3890 .par = (const uint32_t[]){true}, 3891 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3892 }, { 3893 .name = "rfwu", 3894 .translate = translate_rfw, 3895 .par = (const uint32_t[]){false}, 3896 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3897 }, { 3898 .name = "ritlb0", 3899 .translate = translate_rtlb, 3900 .par = (const uint32_t[]){false, 0}, 3901 .op_flags = XTENSA_OP_PRIVILEGED, 3902 }, { 3903 .name = "ritlb1", 3904 .translate = translate_rtlb, 3905 .par = (const uint32_t[]){false, 1}, 3906 .op_flags = XTENSA_OP_PRIVILEGED, 3907 }, { 3908 .name = "rptlb0", 3909 .translate = translate_rptlb0, 3910 .op_flags = XTENSA_OP_PRIVILEGED, 3911 }, { 3912 .name = "rptlb1", 3913 .translate = translate_rptlb1, 3914 .op_flags = XTENSA_OP_PRIVILEGED, 3915 }, { 3916 .name = "rotw", 3917 .translate = translate_rotw, 3918 .op_flags = XTENSA_OP_PRIVILEGED | 3919 XTENSA_OP_EXIT_TB_M1 | 3920 XTENSA_OP_SYNC_REGISTER_WINDOW, 3921 }, { 3922 .name = "rsil", 3923 .translate = translate_rsil, 3924 .op_flags = 3925 XTENSA_OP_PRIVILEGED | 3926 XTENSA_OP_EXIT_TB_0 | 3927 XTENSA_OP_CHECK_INTERRUPTS, 3928 }, { 3929 .name = "rsr.176", 3930 .translate = translate_rsr, 3931 .par = (const uint32_t[]){176}, 3932 .op_flags = XTENSA_OP_PRIVILEGED, 3933 }, { 3934 .name = "rsr.208", 3935 .translate = translate_rsr, 3936 .par = (const uint32_t[]){208}, 3937 .op_flags = XTENSA_OP_PRIVILEGED, 3938 }, { 3939 .name = "rsr.acchi", 3940 .translate = translate_rsr, 3941 .test_exceptions = test_exceptions_sr, 3942 .par = (const uint32_t[]){ 3943 ACCHI, 3944 XTENSA_OPTION_MAC16, 3945 }, 3946 }, { 3947 .name = "rsr.acclo", 3948 .translate = translate_rsr, 3949 .test_exceptions = test_exceptions_sr, 3950 .par = (const uint32_t[]){ 3951 ACCLO, 3952 XTENSA_OPTION_MAC16, 3953 }, 3954 }, { 3955 .name = "rsr.atomctl", 3956 .translate = translate_rsr, 3957 .test_exceptions = test_exceptions_sr, 3958 .par = (const uint32_t[]){ 3959 ATOMCTL, 3960 XTENSA_OPTION_ATOMCTL, 3961 }, 3962 .op_flags = XTENSA_OP_PRIVILEGED, 3963 }, { 3964 .name = "rsr.br", 3965 .translate = translate_rsr, 3966 .test_exceptions = test_exceptions_sr, 3967 .par = (const uint32_t[]){ 3968 BR, 3969 XTENSA_OPTION_BOOLEAN, 3970 }, 3971 }, { 3972 .name = "rsr.cacheadrdis", 3973 .translate = translate_rsr, 3974 .test_exceptions = test_exceptions_sr, 3975 .par = (const uint32_t[]){ 3976 CACHEADRDIS, 3977 XTENSA_OPTION_MPU, 3978 }, 3979 .op_flags = XTENSA_OP_PRIVILEGED, 3980 }, { 3981 .name = "rsr.cacheattr", 3982 .translate = translate_rsr, 3983 .test_exceptions = test_exceptions_sr, 3984 .par = (const uint32_t[]){ 3985 CACHEATTR, 3986 XTENSA_OPTION_CACHEATTR, 3987 }, 3988 .op_flags = XTENSA_OP_PRIVILEGED, 3989 }, { 3990 .name = "rsr.ccompare0", 3991 .translate = translate_rsr, 3992 .test_exceptions = test_exceptions_ccompare, 3993 .par = (const uint32_t[]){ 3994 CCOMPARE, 3995 XTENSA_OPTION_TIMER_INTERRUPT, 3996 }, 3997 .op_flags = XTENSA_OP_PRIVILEGED, 3998 }, { 3999 .name = "rsr.ccompare1", 4000 .translate = translate_rsr, 4001 .test_exceptions = test_exceptions_ccompare, 4002 .par = (const uint32_t[]){ 4003 CCOMPARE + 1, 4004 XTENSA_OPTION_TIMER_INTERRUPT, 4005 }, 4006 .op_flags = XTENSA_OP_PRIVILEGED, 4007 }, { 4008 .name = "rsr.ccompare2", 4009 .translate = translate_rsr, 4010 .test_exceptions = test_exceptions_ccompare, 4011 .par = (const uint32_t[]){ 4012 CCOMPARE + 2, 4013 XTENSA_OPTION_TIMER_INTERRUPT, 4014 }, 4015 .op_flags = XTENSA_OP_PRIVILEGED, 4016 }, { 4017 .name = "rsr.ccount", 4018 .translate = translate_rsr_ccount, 4019 .test_exceptions = test_exceptions_sr, 4020 .par = (const uint32_t[]){ 4021 CCOUNT, 4022 XTENSA_OPTION_TIMER_INTERRUPT, 4023 }, 4024 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4025 }, { 4026 .name = "rsr.configid0", 4027 .translate = translate_rsr, 4028 .par = (const uint32_t[]){CONFIGID0}, 4029 .op_flags = XTENSA_OP_PRIVILEGED, 4030 }, { 4031 .name = "rsr.configid1", 4032 .translate = translate_rsr, 4033 .par = (const uint32_t[]){CONFIGID1}, 4034 .op_flags = XTENSA_OP_PRIVILEGED, 4035 }, { 4036 .name = "rsr.cpenable", 4037 .translate = translate_rsr, 4038 .test_exceptions = test_exceptions_sr, 4039 .par = (const uint32_t[]){ 4040 CPENABLE, 4041 XTENSA_OPTION_COPROCESSOR, 4042 }, 4043 .op_flags = XTENSA_OP_PRIVILEGED, 4044 }, { 4045 .name = "rsr.dbreaka0", 4046 .translate = translate_rsr, 4047 .test_exceptions = test_exceptions_dbreak, 4048 .par = (const uint32_t[]){ 4049 DBREAKA, 4050 XTENSA_OPTION_DEBUG, 4051 }, 4052 .op_flags = XTENSA_OP_PRIVILEGED, 4053 }, { 4054 .name = "rsr.dbreaka1", 4055 .translate = translate_rsr, 4056 .test_exceptions = test_exceptions_dbreak, 4057 .par = (const uint32_t[]){ 4058 DBREAKA + 1, 4059 XTENSA_OPTION_DEBUG, 4060 }, 4061 .op_flags = XTENSA_OP_PRIVILEGED, 4062 }, { 4063 .name = "rsr.dbreakc0", 4064 .translate = translate_rsr, 4065 .test_exceptions = test_exceptions_dbreak, 4066 .par = (const uint32_t[]){ 4067 DBREAKC, 4068 XTENSA_OPTION_DEBUG, 4069 }, 4070 .op_flags = XTENSA_OP_PRIVILEGED, 4071 }, { 4072 .name = "rsr.dbreakc1", 4073 .translate = translate_rsr, 4074 .test_exceptions = test_exceptions_dbreak, 4075 .par = (const uint32_t[]){ 4076 DBREAKC + 1, 4077 XTENSA_OPTION_DEBUG, 4078 }, 4079 .op_flags = XTENSA_OP_PRIVILEGED, 4080 }, { 4081 .name = "rsr.ddr", 4082 .translate = translate_rsr, 4083 .test_exceptions = test_exceptions_sr, 4084 .par = (const uint32_t[]){ 4085 DDR, 4086 XTENSA_OPTION_DEBUG, 4087 }, 4088 .op_flags = XTENSA_OP_PRIVILEGED, 4089 }, { 4090 .name = "rsr.debugcause", 4091 .translate = translate_rsr, 4092 .test_exceptions = test_exceptions_sr, 4093 .par = (const uint32_t[]){ 4094 DEBUGCAUSE, 4095 XTENSA_OPTION_DEBUG, 4096 }, 4097 .op_flags = XTENSA_OP_PRIVILEGED, 4098 }, { 4099 .name = "rsr.depc", 4100 .translate = translate_rsr, 4101 .test_exceptions = test_exceptions_sr, 4102 .par = (const uint32_t[]){ 4103 DEPC, 4104 XTENSA_OPTION_EXCEPTION, 4105 }, 4106 .op_flags = XTENSA_OP_PRIVILEGED, 4107 }, { 4108 .name = "rsr.dtlbcfg", 4109 .translate = translate_rsr, 4110 .test_exceptions = test_exceptions_sr, 4111 .par = (const uint32_t[]){ 4112 DTLBCFG, 4113 XTENSA_OPTION_MMU, 4114 }, 4115 .op_flags = XTENSA_OP_PRIVILEGED, 4116 }, { 4117 .name = "rsr.epc1", 4118 .translate = translate_rsr, 4119 .test_exceptions = test_exceptions_sr, 4120 .par = (const uint32_t[]){ 4121 EPC1, 4122 XTENSA_OPTION_EXCEPTION, 4123 }, 4124 .op_flags = XTENSA_OP_PRIVILEGED, 4125 }, { 4126 .name = "rsr.epc2", 4127 .translate = translate_rsr, 4128 .test_exceptions = test_exceptions_hpi, 4129 .par = (const uint32_t[]){ 4130 EPC1 + 1, 4131 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4132 }, 4133 .op_flags = XTENSA_OP_PRIVILEGED, 4134 }, { 4135 .name = "rsr.epc3", 4136 .translate = translate_rsr, 4137 .test_exceptions = test_exceptions_hpi, 4138 .par = (const uint32_t[]){ 4139 EPC1 + 2, 4140 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4141 }, 4142 .op_flags = XTENSA_OP_PRIVILEGED, 4143 }, { 4144 .name = "rsr.epc4", 4145 .translate = translate_rsr, 4146 .test_exceptions = test_exceptions_hpi, 4147 .par = (const uint32_t[]){ 4148 EPC1 + 3, 4149 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4150 }, 4151 .op_flags = XTENSA_OP_PRIVILEGED, 4152 }, { 4153 .name = "rsr.epc5", 4154 .translate = translate_rsr, 4155 .test_exceptions = test_exceptions_hpi, 4156 .par = (const uint32_t[]){ 4157 EPC1 + 4, 4158 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4159 }, 4160 .op_flags = XTENSA_OP_PRIVILEGED, 4161 }, { 4162 .name = "rsr.epc6", 4163 .translate = translate_rsr, 4164 .test_exceptions = test_exceptions_hpi, 4165 .par = (const uint32_t[]){ 4166 EPC1 + 5, 4167 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4168 }, 4169 .op_flags = XTENSA_OP_PRIVILEGED, 4170 }, { 4171 .name = "rsr.epc7", 4172 .translate = translate_rsr, 4173 .test_exceptions = test_exceptions_hpi, 4174 .par = (const uint32_t[]){ 4175 EPC1 + 6, 4176 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4177 }, 4178 .op_flags = XTENSA_OP_PRIVILEGED, 4179 }, { 4180 .name = "rsr.eps2", 4181 .translate = translate_rsr, 4182 .test_exceptions = test_exceptions_hpi, 4183 .par = (const uint32_t[]){ 4184 EPS2, 4185 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4186 }, 4187 .op_flags = XTENSA_OP_PRIVILEGED, 4188 }, { 4189 .name = "rsr.eps3", 4190 .translate = translate_rsr, 4191 .test_exceptions = test_exceptions_hpi, 4192 .par = (const uint32_t[]){ 4193 EPS2 + 1, 4194 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4195 }, 4196 .op_flags = XTENSA_OP_PRIVILEGED, 4197 }, { 4198 .name = "rsr.eps4", 4199 .translate = translate_rsr, 4200 .test_exceptions = test_exceptions_hpi, 4201 .par = (const uint32_t[]){ 4202 EPS2 + 2, 4203 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4204 }, 4205 .op_flags = XTENSA_OP_PRIVILEGED, 4206 }, { 4207 .name = "rsr.eps5", 4208 .translate = translate_rsr, 4209 .test_exceptions = test_exceptions_hpi, 4210 .par = (const uint32_t[]){ 4211 EPS2 + 3, 4212 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4213 }, 4214 .op_flags = XTENSA_OP_PRIVILEGED, 4215 }, { 4216 .name = "rsr.eps6", 4217 .translate = translate_rsr, 4218 .test_exceptions = test_exceptions_hpi, 4219 .par = (const uint32_t[]){ 4220 EPS2 + 4, 4221 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4222 }, 4223 .op_flags = XTENSA_OP_PRIVILEGED, 4224 }, { 4225 .name = "rsr.eps7", 4226 .translate = translate_rsr, 4227 .test_exceptions = test_exceptions_hpi, 4228 .par = (const uint32_t[]){ 4229 EPS2 + 5, 4230 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4231 }, 4232 .op_flags = XTENSA_OP_PRIVILEGED, 4233 }, { 4234 .name = "rsr.eraccess", 4235 .translate = translate_rsr, 4236 .par = (const uint32_t[]){ERACCESS}, 4237 .op_flags = XTENSA_OP_PRIVILEGED, 4238 }, { 4239 .name = "rsr.exccause", 4240 .translate = translate_rsr, 4241 .test_exceptions = test_exceptions_sr, 4242 .par = (const uint32_t[]){ 4243 EXCCAUSE, 4244 XTENSA_OPTION_EXCEPTION, 4245 }, 4246 .op_flags = XTENSA_OP_PRIVILEGED, 4247 }, { 4248 .name = "rsr.excsave1", 4249 .translate = translate_rsr, 4250 .test_exceptions = test_exceptions_sr, 4251 .par = (const uint32_t[]){ 4252 EXCSAVE1, 4253 XTENSA_OPTION_EXCEPTION, 4254 }, 4255 .op_flags = XTENSA_OP_PRIVILEGED, 4256 }, { 4257 .name = "rsr.excsave2", 4258 .translate = translate_rsr, 4259 .test_exceptions = test_exceptions_hpi, 4260 .par = (const uint32_t[]){ 4261 EXCSAVE1 + 1, 4262 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4263 }, 4264 .op_flags = XTENSA_OP_PRIVILEGED, 4265 }, { 4266 .name = "rsr.excsave3", 4267 .translate = translate_rsr, 4268 .test_exceptions = test_exceptions_hpi, 4269 .par = (const uint32_t[]){ 4270 EXCSAVE1 + 2, 4271 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4272 }, 4273 .op_flags = XTENSA_OP_PRIVILEGED, 4274 }, { 4275 .name = "rsr.excsave4", 4276 .translate = translate_rsr, 4277 .test_exceptions = test_exceptions_hpi, 4278 .par = (const uint32_t[]){ 4279 EXCSAVE1 + 3, 4280 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4281 }, 4282 .op_flags = XTENSA_OP_PRIVILEGED, 4283 }, { 4284 .name = "rsr.excsave5", 4285 .translate = translate_rsr, 4286 .test_exceptions = test_exceptions_hpi, 4287 .par = (const uint32_t[]){ 4288 EXCSAVE1 + 4, 4289 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4290 }, 4291 .op_flags = XTENSA_OP_PRIVILEGED, 4292 }, { 4293 .name = "rsr.excsave6", 4294 .translate = translate_rsr, 4295 .test_exceptions = test_exceptions_hpi, 4296 .par = (const uint32_t[]){ 4297 EXCSAVE1 + 5, 4298 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4299 }, 4300 .op_flags = XTENSA_OP_PRIVILEGED, 4301 }, { 4302 .name = "rsr.excsave7", 4303 .translate = translate_rsr, 4304 .test_exceptions = test_exceptions_hpi, 4305 .par = (const uint32_t[]){ 4306 EXCSAVE1 + 6, 4307 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 4308 }, 4309 .op_flags = XTENSA_OP_PRIVILEGED, 4310 }, { 4311 .name = "rsr.excvaddr", 4312 .translate = translate_rsr, 4313 .test_exceptions = test_exceptions_sr, 4314 .par = (const uint32_t[]){ 4315 EXCVADDR, 4316 XTENSA_OPTION_EXCEPTION, 4317 }, 4318 .op_flags = XTENSA_OP_PRIVILEGED, 4319 }, { 4320 .name = "rsr.ibreaka0", 4321 .translate = translate_rsr, 4322 .test_exceptions = test_exceptions_ibreak, 4323 .par = (const uint32_t[]){ 4324 IBREAKA, 4325 XTENSA_OPTION_DEBUG, 4326 }, 4327 .op_flags = XTENSA_OP_PRIVILEGED, 4328 }, { 4329 .name = "rsr.ibreaka1", 4330 .translate = translate_rsr, 4331 .test_exceptions = test_exceptions_ibreak, 4332 .par = (const uint32_t[]){ 4333 IBREAKA + 1, 4334 XTENSA_OPTION_DEBUG, 4335 }, 4336 .op_flags = XTENSA_OP_PRIVILEGED, 4337 }, { 4338 .name = "rsr.ibreakenable", 4339 .translate = translate_rsr, 4340 .test_exceptions = test_exceptions_sr, 4341 .par = (const uint32_t[]){ 4342 IBREAKENABLE, 4343 XTENSA_OPTION_DEBUG, 4344 }, 4345 .op_flags = XTENSA_OP_PRIVILEGED, 4346 }, { 4347 .name = "rsr.icount", 4348 .translate = translate_rsr, 4349 .test_exceptions = test_exceptions_sr, 4350 .par = (const uint32_t[]){ 4351 ICOUNT, 4352 XTENSA_OPTION_DEBUG, 4353 }, 4354 .op_flags = XTENSA_OP_PRIVILEGED, 4355 }, { 4356 .name = "rsr.icountlevel", 4357 .translate = translate_rsr, 4358 .test_exceptions = test_exceptions_sr, 4359 .par = (const uint32_t[]){ 4360 ICOUNTLEVEL, 4361 XTENSA_OPTION_DEBUG, 4362 }, 4363 .op_flags = XTENSA_OP_PRIVILEGED, 4364 }, { 4365 .name = "rsr.intclear", 4366 .translate = translate_rsr, 4367 .test_exceptions = test_exceptions_sr, 4368 .par = (const uint32_t[]){ 4369 INTCLEAR, 4370 XTENSA_OPTION_INTERRUPT, 4371 }, 4372 .op_flags = XTENSA_OP_PRIVILEGED, 4373 }, { 4374 .name = "rsr.intenable", 4375 .translate = translate_rsr, 4376 .test_exceptions = test_exceptions_sr, 4377 .par = (const uint32_t[]){ 4378 INTENABLE, 4379 XTENSA_OPTION_INTERRUPT, 4380 }, 4381 .op_flags = XTENSA_OP_PRIVILEGED, 4382 }, { 4383 .name = "rsr.interrupt", 4384 .translate = translate_rsr_ccount, 4385 .test_exceptions = test_exceptions_sr, 4386 .par = (const uint32_t[]){ 4387 INTSET, 4388 XTENSA_OPTION_INTERRUPT, 4389 }, 4390 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4391 }, { 4392 .name = "rsr.intset", 4393 .translate = translate_rsr_ccount, 4394 .test_exceptions = test_exceptions_sr, 4395 .par = (const uint32_t[]){ 4396 INTSET, 4397 XTENSA_OPTION_INTERRUPT, 4398 }, 4399 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4400 }, { 4401 .name = "rsr.itlbcfg", 4402 .translate = translate_rsr, 4403 .test_exceptions = test_exceptions_sr, 4404 .par = (const uint32_t[]){ 4405 ITLBCFG, 4406 XTENSA_OPTION_MMU, 4407 }, 4408 .op_flags = XTENSA_OP_PRIVILEGED, 4409 }, { 4410 .name = "rsr.lbeg", 4411 .translate = translate_rsr, 4412 .test_exceptions = test_exceptions_sr, 4413 .par = (const uint32_t[]){ 4414 LBEG, 4415 XTENSA_OPTION_LOOP, 4416 }, 4417 }, { 4418 .name = "rsr.lcount", 4419 .translate = translate_rsr, 4420 .test_exceptions = test_exceptions_sr, 4421 .par = (const uint32_t[]){ 4422 LCOUNT, 4423 XTENSA_OPTION_LOOP, 4424 }, 4425 }, { 4426 .name = "rsr.lend", 4427 .translate = translate_rsr, 4428 .test_exceptions = test_exceptions_sr, 4429 .par = (const uint32_t[]){ 4430 LEND, 4431 XTENSA_OPTION_LOOP, 4432 }, 4433 }, { 4434 .name = "rsr.litbase", 4435 .translate = translate_rsr, 4436 .test_exceptions = test_exceptions_sr, 4437 .par = (const uint32_t[]){ 4438 LITBASE, 4439 XTENSA_OPTION_EXTENDED_L32R, 4440 }, 4441 }, { 4442 .name = "rsr.m0", 4443 .translate = translate_rsr, 4444 .test_exceptions = test_exceptions_sr, 4445 .par = (const uint32_t[]){ 4446 MR, 4447 XTENSA_OPTION_MAC16, 4448 }, 4449 }, { 4450 .name = "rsr.m1", 4451 .translate = translate_rsr, 4452 .test_exceptions = test_exceptions_sr, 4453 .par = (const uint32_t[]){ 4454 MR + 1, 4455 XTENSA_OPTION_MAC16, 4456 }, 4457 }, { 4458 .name = "rsr.m2", 4459 .translate = translate_rsr, 4460 .test_exceptions = test_exceptions_sr, 4461 .par = (const uint32_t[]){ 4462 MR + 2, 4463 XTENSA_OPTION_MAC16, 4464 }, 4465 }, { 4466 .name = "rsr.m3", 4467 .translate = translate_rsr, 4468 .test_exceptions = test_exceptions_sr, 4469 .par = (const uint32_t[]){ 4470 MR + 3, 4471 XTENSA_OPTION_MAC16, 4472 }, 4473 }, { 4474 .name = "rsr.memctl", 4475 .translate = translate_rsr, 4476 .par = (const uint32_t[]){MEMCTL}, 4477 .op_flags = XTENSA_OP_PRIVILEGED, 4478 }, { 4479 .name = "rsr.mecr", 4480 .translate = translate_rsr, 4481 .test_exceptions = test_exceptions_sr, 4482 .par = (const uint32_t[]){ 4483 MECR, 4484 XTENSA_OPTION_MEMORY_ECC_PARITY, 4485 }, 4486 .op_flags = XTENSA_OP_PRIVILEGED, 4487 }, { 4488 .name = "rsr.mepc", 4489 .translate = translate_rsr, 4490 .test_exceptions = test_exceptions_sr, 4491 .par = (const uint32_t[]){ 4492 MEPC, 4493 XTENSA_OPTION_MEMORY_ECC_PARITY, 4494 }, 4495 .op_flags = XTENSA_OP_PRIVILEGED, 4496 }, { 4497 .name = "rsr.meps", 4498 .translate = translate_rsr, 4499 .test_exceptions = test_exceptions_sr, 4500 .par = (const uint32_t[]){ 4501 MEPS, 4502 XTENSA_OPTION_MEMORY_ECC_PARITY, 4503 }, 4504 .op_flags = XTENSA_OP_PRIVILEGED, 4505 }, { 4506 .name = "rsr.mesave", 4507 .translate = translate_rsr, 4508 .test_exceptions = test_exceptions_sr, 4509 .par = (const uint32_t[]){ 4510 MESAVE, 4511 XTENSA_OPTION_MEMORY_ECC_PARITY, 4512 }, 4513 .op_flags = XTENSA_OP_PRIVILEGED, 4514 }, { 4515 .name = "rsr.mesr", 4516 .translate = translate_rsr, 4517 .test_exceptions = test_exceptions_sr, 4518 .par = (const uint32_t[]){ 4519 MESR, 4520 XTENSA_OPTION_MEMORY_ECC_PARITY, 4521 }, 4522 .op_flags = XTENSA_OP_PRIVILEGED, 4523 }, { 4524 .name = "rsr.mevaddr", 4525 .translate = translate_rsr, 4526 .test_exceptions = test_exceptions_sr, 4527 .par = (const uint32_t[]){ 4528 MESR, 4529 XTENSA_OPTION_MEMORY_ECC_PARITY, 4530 }, 4531 .op_flags = XTENSA_OP_PRIVILEGED, 4532 }, { 4533 .name = "rsr.misc0", 4534 .translate = translate_rsr, 4535 .test_exceptions = test_exceptions_sr, 4536 .par = (const uint32_t[]){ 4537 MISC, 4538 XTENSA_OPTION_MISC_SR, 4539 }, 4540 .op_flags = XTENSA_OP_PRIVILEGED, 4541 }, { 4542 .name = "rsr.misc1", 4543 .translate = translate_rsr, 4544 .test_exceptions = test_exceptions_sr, 4545 .par = (const uint32_t[]){ 4546 MISC + 1, 4547 XTENSA_OPTION_MISC_SR, 4548 }, 4549 .op_flags = XTENSA_OP_PRIVILEGED, 4550 }, { 4551 .name = "rsr.misc2", 4552 .translate = translate_rsr, 4553 .test_exceptions = test_exceptions_sr, 4554 .par = (const uint32_t[]){ 4555 MISC + 2, 4556 XTENSA_OPTION_MISC_SR, 4557 }, 4558 .op_flags = XTENSA_OP_PRIVILEGED, 4559 }, { 4560 .name = "rsr.misc3", 4561 .translate = translate_rsr, 4562 .test_exceptions = test_exceptions_sr, 4563 .par = (const uint32_t[]){ 4564 MISC + 3, 4565 XTENSA_OPTION_MISC_SR, 4566 }, 4567 .op_flags = XTENSA_OP_PRIVILEGED, 4568 }, { 4569 .name = "rsr.mpucfg", 4570 .translate = translate_rsr, 4571 .test_exceptions = test_exceptions_sr, 4572 .par = (const uint32_t[]){ 4573 MPUCFG, 4574 XTENSA_OPTION_MPU, 4575 }, 4576 .op_flags = XTENSA_OP_PRIVILEGED, 4577 }, { 4578 .name = "rsr.mpuenb", 4579 .translate = translate_rsr, 4580 .test_exceptions = test_exceptions_sr, 4581 .par = (const uint32_t[]){ 4582 MPUENB, 4583 XTENSA_OPTION_MPU, 4584 }, 4585 .op_flags = XTENSA_OP_PRIVILEGED, 4586 }, { 4587 .name = "rsr.prefctl", 4588 .translate = translate_rsr, 4589 .par = (const uint32_t[]){PREFCTL}, 4590 }, { 4591 .name = "rsr.prid", 4592 .translate = translate_rsr, 4593 .test_exceptions = test_exceptions_sr, 4594 .par = (const uint32_t[]){ 4595 PRID, 4596 XTENSA_OPTION_PROCESSOR_ID, 4597 }, 4598 .op_flags = XTENSA_OP_PRIVILEGED, 4599 }, { 4600 .name = "rsr.ps", 4601 .translate = translate_rsr, 4602 .test_exceptions = test_exceptions_sr, 4603 .par = (const uint32_t[]){ 4604 PS, 4605 XTENSA_OPTION_EXCEPTION, 4606 }, 4607 .op_flags = XTENSA_OP_PRIVILEGED, 4608 }, { 4609 .name = "rsr.ptevaddr", 4610 .translate = translate_rsr_ptevaddr, 4611 .test_exceptions = test_exceptions_sr, 4612 .par = (const uint32_t[]){ 4613 PTEVADDR, 4614 XTENSA_OPTION_MMU, 4615 }, 4616 .op_flags = XTENSA_OP_PRIVILEGED, 4617 }, { 4618 .name = "rsr.rasid", 4619 .translate = translate_rsr, 4620 .test_exceptions = test_exceptions_sr, 4621 .par = (const uint32_t[]){ 4622 RASID, 4623 XTENSA_OPTION_MMU, 4624 }, 4625 .op_flags = XTENSA_OP_PRIVILEGED, 4626 }, { 4627 .name = "rsr.sar", 4628 .translate = translate_rsr, 4629 .par = (const uint32_t[]){SAR}, 4630 }, { 4631 .name = "rsr.scompare1", 4632 .translate = translate_rsr, 4633 .test_exceptions = test_exceptions_sr, 4634 .par = (const uint32_t[]){ 4635 SCOMPARE1, 4636 XTENSA_OPTION_CONDITIONAL_STORE, 4637 }, 4638 }, { 4639 .name = "rsr.vecbase", 4640 .translate = translate_rsr, 4641 .test_exceptions = test_exceptions_sr, 4642 .par = (const uint32_t[]){ 4643 VECBASE, 4644 XTENSA_OPTION_RELOCATABLE_VECTOR, 4645 }, 4646 .op_flags = XTENSA_OP_PRIVILEGED, 4647 }, { 4648 .name = "rsr.windowbase", 4649 .translate = translate_rsr, 4650 .test_exceptions = test_exceptions_sr, 4651 .par = (const uint32_t[]){ 4652 WINDOW_BASE, 4653 XTENSA_OPTION_WINDOWED_REGISTER, 4654 }, 4655 .op_flags = XTENSA_OP_PRIVILEGED, 4656 }, { 4657 .name = "rsr.windowstart", 4658 .translate = translate_rsr, 4659 .test_exceptions = test_exceptions_sr, 4660 .par = (const uint32_t[]){ 4661 WINDOW_START, 4662 XTENSA_OPTION_WINDOWED_REGISTER, 4663 }, 4664 .op_flags = XTENSA_OP_PRIVILEGED, 4665 }, { 4666 .name = "rsync", 4667 .translate = translate_nop, 4668 }, { 4669 .name = "rur.expstate", 4670 .translate = translate_rur, 4671 .par = (const uint32_t[]){EXPSTATE}, 4672 }, { 4673 .name = "rur.threadptr", 4674 .translate = translate_rur, 4675 .par = (const uint32_t[]){THREADPTR}, 4676 }, { 4677 .name = "s16i", 4678 .translate = translate_ldst, 4679 .par = (const uint32_t[]){MO_TEUW, false, true}, 4680 .op_flags = XTENSA_OP_STORE, 4681 }, { 4682 .name = "s32c1i", 4683 .translate = translate_s32c1i, 4684 .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE, 4685 }, { 4686 .name = "s32e", 4687 .translate = translate_s32e, 4688 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE, 4689 }, { 4690 .name = "s32ex", 4691 .translate = translate_s32ex, 4692 .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE, 4693 }, { 4694 .name = (const char * const[]) { 4695 "s32i", "s32i.n", "s32nb", NULL, 4696 }, 4697 .translate = translate_ldst, 4698 .par = (const uint32_t[]){MO_TEUL, false, true}, 4699 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE, 4700 }, { 4701 .name = "s32ri", 4702 .translate = translate_ldst, 4703 .par = (const uint32_t[]){MO_TEUL | MO_ALIGN, true, true}, 4704 .op_flags = XTENSA_OP_STORE, 4705 }, { 4706 .name = "s8i", 4707 .translate = translate_ldst, 4708 .par = (const uint32_t[]){MO_UB, false, true}, 4709 .op_flags = XTENSA_OP_STORE, 4710 }, { 4711 .name = "salt", 4712 .translate = translate_salt, 4713 .par = (const uint32_t[]){TCG_COND_LT}, 4714 }, { 4715 .name = "saltu", 4716 .translate = translate_salt, 4717 .par = (const uint32_t[]){TCG_COND_LTU}, 4718 }, { 4719 .name = "setb_expstate", 4720 .translate = translate_setb_expstate, 4721 }, { 4722 .name = "sext", 4723 .translate = translate_sext, 4724 }, { 4725 .name = "simcall", 4726 .translate = translate_simcall, 4727 .test_exceptions = test_exceptions_simcall, 4728 .op_flags = XTENSA_OP_PRIVILEGED, 4729 }, { 4730 .name = "sll", 4731 .translate = translate_sll, 4732 }, { 4733 .name = "slli", 4734 .translate = translate_slli, 4735 }, { 4736 .name = "sra", 4737 .translate = translate_sra, 4738 }, { 4739 .name = "srai", 4740 .translate = translate_srai, 4741 }, { 4742 .name = "src", 4743 .translate = translate_src, 4744 }, { 4745 .name = "srl", 4746 .translate = translate_srl, 4747 }, { 4748 .name = "srli", 4749 .translate = translate_srli, 4750 }, { 4751 .name = "ssa8b", 4752 .translate = translate_ssa8b, 4753 }, { 4754 .name = "ssa8l", 4755 .translate = translate_ssa8l, 4756 }, { 4757 .name = "ssai", 4758 .translate = translate_ssai, 4759 }, { 4760 .name = "ssl", 4761 .translate = translate_ssl, 4762 }, { 4763 .name = "ssr", 4764 .translate = translate_ssr, 4765 }, { 4766 .name = "sub", 4767 .translate = translate_sub, 4768 }, { 4769 .name = "subx2", 4770 .translate = translate_subx, 4771 .par = (const uint32_t[]){1}, 4772 }, { 4773 .name = "subx4", 4774 .translate = translate_subx, 4775 .par = (const uint32_t[]){2}, 4776 }, { 4777 .name = "subx8", 4778 .translate = translate_subx, 4779 .par = (const uint32_t[]){3}, 4780 }, { 4781 .name = "syscall", 4782 .op_flags = XTENSA_OP_SYSCALL, 4783 }, { 4784 .name = "umul.aa.hh", 4785 .translate = translate_mac16, 4786 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0}, 4787 }, { 4788 .name = "umul.aa.hl", 4789 .translate = translate_mac16, 4790 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0}, 4791 }, { 4792 .name = "umul.aa.lh", 4793 .translate = translate_mac16, 4794 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0}, 4795 }, { 4796 .name = "umul.aa.ll", 4797 .translate = translate_mac16, 4798 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0}, 4799 }, { 4800 .name = "waiti", 4801 .translate = translate_waiti, 4802 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4803 }, { 4804 .name = "wdtlb", 4805 .translate = translate_wtlb, 4806 .par = (const uint32_t[]){true}, 4807 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4808 }, { 4809 .name = "wer", 4810 .translate = translate_wer, 4811 .op_flags = XTENSA_OP_PRIVILEGED, 4812 }, { 4813 .name = "witlb", 4814 .translate = translate_wtlb, 4815 .par = (const uint32_t[]){false}, 4816 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4817 }, { 4818 .name = "wptlb", 4819 .translate = translate_wptlb, 4820 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4821 }, { 4822 .name = "wrmsk_expstate", 4823 .translate = translate_wrmsk_expstate, 4824 }, { 4825 .name = "wsr.176", 4826 .op_flags = XTENSA_OP_ILL, 4827 }, { 4828 .name = "wsr.208", 4829 .op_flags = XTENSA_OP_ILL, 4830 }, { 4831 .name = "wsr.acchi", 4832 .translate = translate_wsr_acchi, 4833 .test_exceptions = test_exceptions_sr, 4834 .par = (const uint32_t[]){ 4835 ACCHI, 4836 XTENSA_OPTION_MAC16, 4837 }, 4838 }, { 4839 .name = "wsr.acclo", 4840 .translate = translate_wsr, 4841 .test_exceptions = test_exceptions_sr, 4842 .par = (const uint32_t[]){ 4843 ACCLO, 4844 XTENSA_OPTION_MAC16, 4845 }, 4846 }, { 4847 .name = "wsr.atomctl", 4848 .translate = translate_wsr_mask, 4849 .test_exceptions = test_exceptions_sr, 4850 .par = (const uint32_t[]){ 4851 ATOMCTL, 4852 XTENSA_OPTION_ATOMCTL, 4853 0x3f, 4854 }, 4855 .op_flags = XTENSA_OP_PRIVILEGED, 4856 }, { 4857 .name = "wsr.br", 4858 .translate = translate_wsr_mask, 4859 .test_exceptions = test_exceptions_sr, 4860 .par = (const uint32_t[]){ 4861 BR, 4862 XTENSA_OPTION_BOOLEAN, 4863 0xffff, 4864 }, 4865 }, { 4866 .name = "wsr.cacheadrdis", 4867 .translate = translate_wsr_mask, 4868 .test_exceptions = test_exceptions_sr, 4869 .par = (const uint32_t[]){ 4870 CACHEADRDIS, 4871 XTENSA_OPTION_MPU, 4872 0xff, 4873 }, 4874 .op_flags = XTENSA_OP_PRIVILEGED, 4875 }, { 4876 .name = "wsr.cacheattr", 4877 .translate = translate_wsr, 4878 .test_exceptions = test_exceptions_sr, 4879 .par = (const uint32_t[]){ 4880 CACHEATTR, 4881 XTENSA_OPTION_CACHEATTR, 4882 }, 4883 .op_flags = XTENSA_OP_PRIVILEGED, 4884 }, { 4885 .name = "wsr.ccompare0", 4886 .translate = translate_wsr_ccompare, 4887 .test_exceptions = test_exceptions_ccompare, 4888 .par = (const uint32_t[]){ 4889 CCOMPARE, 4890 XTENSA_OPTION_TIMER_INTERRUPT, 4891 }, 4892 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4893 }, { 4894 .name = "wsr.ccompare1", 4895 .translate = translate_wsr_ccompare, 4896 .test_exceptions = test_exceptions_ccompare, 4897 .par = (const uint32_t[]){ 4898 CCOMPARE + 1, 4899 XTENSA_OPTION_TIMER_INTERRUPT, 4900 }, 4901 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4902 }, { 4903 .name = "wsr.ccompare2", 4904 .translate = translate_wsr_ccompare, 4905 .test_exceptions = test_exceptions_ccompare, 4906 .par = (const uint32_t[]){ 4907 CCOMPARE + 2, 4908 XTENSA_OPTION_TIMER_INTERRUPT, 4909 }, 4910 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4911 }, { 4912 .name = "wsr.ccount", 4913 .translate = translate_wsr_ccount, 4914 .test_exceptions = test_exceptions_sr, 4915 .par = (const uint32_t[]){ 4916 CCOUNT, 4917 XTENSA_OPTION_TIMER_INTERRUPT, 4918 }, 4919 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4920 }, { 4921 .name = "wsr.configid0", 4922 .op_flags = XTENSA_OP_ILL, 4923 }, { 4924 .name = "wsr.configid1", 4925 .op_flags = XTENSA_OP_ILL, 4926 }, { 4927 .name = "wsr.cpenable", 4928 .translate = translate_wsr_mask, 4929 .test_exceptions = test_exceptions_sr, 4930 .par = (const uint32_t[]){ 4931 CPENABLE, 4932 XTENSA_OPTION_COPROCESSOR, 4933 0xff, 4934 }, 4935 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4936 }, { 4937 .name = "wsr.dbreaka0", 4938 .translate = translate_wsr_dbreaka, 4939 .test_exceptions = test_exceptions_dbreak, 4940 .par = (const uint32_t[]){ 4941 DBREAKA, 4942 XTENSA_OPTION_DEBUG, 4943 }, 4944 .op_flags = XTENSA_OP_PRIVILEGED, 4945 }, { 4946 .name = "wsr.dbreaka1", 4947 .translate = translate_wsr_dbreaka, 4948 .test_exceptions = test_exceptions_dbreak, 4949 .par = (const uint32_t[]){ 4950 DBREAKA + 1, 4951 XTENSA_OPTION_DEBUG, 4952 }, 4953 .op_flags = XTENSA_OP_PRIVILEGED, 4954 }, { 4955 .name = "wsr.dbreakc0", 4956 .translate = translate_wsr_dbreakc, 4957 .test_exceptions = test_exceptions_dbreak, 4958 .par = (const uint32_t[]){ 4959 DBREAKC, 4960 XTENSA_OPTION_DEBUG, 4961 }, 4962 .op_flags = XTENSA_OP_PRIVILEGED, 4963 }, { 4964 .name = "wsr.dbreakc1", 4965 .translate = translate_wsr_dbreakc, 4966 .test_exceptions = test_exceptions_dbreak, 4967 .par = (const uint32_t[]){ 4968 DBREAKC + 1, 4969 XTENSA_OPTION_DEBUG, 4970 }, 4971 .op_flags = XTENSA_OP_PRIVILEGED, 4972 }, { 4973 .name = "wsr.ddr", 4974 .translate = translate_wsr, 4975 .test_exceptions = test_exceptions_sr, 4976 .par = (const uint32_t[]){ 4977 DDR, 4978 XTENSA_OPTION_DEBUG, 4979 }, 4980 .op_flags = XTENSA_OP_PRIVILEGED, 4981 }, { 4982 .name = "wsr.debugcause", 4983 .op_flags = XTENSA_OP_ILL, 4984 }, { 4985 .name = "wsr.depc", 4986 .translate = translate_wsr, 4987 .test_exceptions = test_exceptions_sr, 4988 .par = (const uint32_t[]){ 4989 DEPC, 4990 XTENSA_OPTION_EXCEPTION, 4991 }, 4992 .op_flags = XTENSA_OP_PRIVILEGED, 4993 }, { 4994 .name = "wsr.dtlbcfg", 4995 .translate = translate_wsr_mask, 4996 .test_exceptions = test_exceptions_sr, 4997 .par = (const uint32_t[]){ 4998 DTLBCFG, 4999 XTENSA_OPTION_MMU, 5000 0x01130000, 5001 }, 5002 .op_flags = XTENSA_OP_PRIVILEGED, 5003 }, { 5004 .name = "wsr.epc1", 5005 .translate = translate_wsr, 5006 .test_exceptions = test_exceptions_sr, 5007 .par = (const uint32_t[]){ 5008 EPC1, 5009 XTENSA_OPTION_EXCEPTION, 5010 }, 5011 .op_flags = XTENSA_OP_PRIVILEGED, 5012 }, { 5013 .name = "wsr.epc2", 5014 .translate = translate_wsr, 5015 .test_exceptions = test_exceptions_hpi, 5016 .par = (const uint32_t[]){ 5017 EPC1 + 1, 5018 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5019 }, 5020 .op_flags = XTENSA_OP_PRIVILEGED, 5021 }, { 5022 .name = "wsr.epc3", 5023 .translate = translate_wsr, 5024 .test_exceptions = test_exceptions_hpi, 5025 .par = (const uint32_t[]){ 5026 EPC1 + 2, 5027 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5028 }, 5029 .op_flags = XTENSA_OP_PRIVILEGED, 5030 }, { 5031 .name = "wsr.epc4", 5032 .translate = translate_wsr, 5033 .test_exceptions = test_exceptions_hpi, 5034 .par = (const uint32_t[]){ 5035 EPC1 + 3, 5036 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5037 }, 5038 .op_flags = XTENSA_OP_PRIVILEGED, 5039 }, { 5040 .name = "wsr.epc5", 5041 .translate = translate_wsr, 5042 .test_exceptions = test_exceptions_hpi, 5043 .par = (const uint32_t[]){ 5044 EPC1 + 4, 5045 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5046 }, 5047 .op_flags = XTENSA_OP_PRIVILEGED, 5048 }, { 5049 .name = "wsr.epc6", 5050 .translate = translate_wsr, 5051 .test_exceptions = test_exceptions_hpi, 5052 .par = (const uint32_t[]){ 5053 EPC1 + 5, 5054 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5055 }, 5056 .op_flags = XTENSA_OP_PRIVILEGED, 5057 }, { 5058 .name = "wsr.epc7", 5059 .translate = translate_wsr, 5060 .test_exceptions = test_exceptions_hpi, 5061 .par = (const uint32_t[]){ 5062 EPC1 + 6, 5063 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5064 }, 5065 .op_flags = XTENSA_OP_PRIVILEGED, 5066 }, { 5067 .name = "wsr.eps2", 5068 .translate = translate_wsr, 5069 .test_exceptions = test_exceptions_hpi, 5070 .par = (const uint32_t[]){ 5071 EPS2, 5072 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5073 }, 5074 .op_flags = XTENSA_OP_PRIVILEGED, 5075 }, { 5076 .name = "wsr.eps3", 5077 .translate = translate_wsr, 5078 .test_exceptions = test_exceptions_hpi, 5079 .par = (const uint32_t[]){ 5080 EPS2 + 1, 5081 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5082 }, 5083 .op_flags = XTENSA_OP_PRIVILEGED, 5084 }, { 5085 .name = "wsr.eps4", 5086 .translate = translate_wsr, 5087 .test_exceptions = test_exceptions_hpi, 5088 .par = (const uint32_t[]){ 5089 EPS2 + 2, 5090 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5091 }, 5092 .op_flags = XTENSA_OP_PRIVILEGED, 5093 }, { 5094 .name = "wsr.eps5", 5095 .translate = translate_wsr, 5096 .test_exceptions = test_exceptions_hpi, 5097 .par = (const uint32_t[]){ 5098 EPS2 + 3, 5099 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5100 }, 5101 .op_flags = XTENSA_OP_PRIVILEGED, 5102 }, { 5103 .name = "wsr.eps6", 5104 .translate = translate_wsr, 5105 .test_exceptions = test_exceptions_hpi, 5106 .par = (const uint32_t[]){ 5107 EPS2 + 4, 5108 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5109 }, 5110 .op_flags = XTENSA_OP_PRIVILEGED, 5111 }, { 5112 .name = "wsr.eps7", 5113 .translate = translate_wsr, 5114 .test_exceptions = test_exceptions_hpi, 5115 .par = (const uint32_t[]){ 5116 EPS2 + 5, 5117 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5118 }, 5119 .op_flags = XTENSA_OP_PRIVILEGED, 5120 }, { 5121 .name = "wsr.eraccess", 5122 .translate = translate_wsr_mask, 5123 .par = (const uint32_t[]){ 5124 ERACCESS, 5125 0, 5126 0xffff, 5127 }, 5128 .op_flags = XTENSA_OP_PRIVILEGED, 5129 }, { 5130 .name = "wsr.exccause", 5131 .translate = translate_wsr, 5132 .test_exceptions = test_exceptions_sr, 5133 .par = (const uint32_t[]){ 5134 EXCCAUSE, 5135 XTENSA_OPTION_EXCEPTION, 5136 }, 5137 .op_flags = XTENSA_OP_PRIVILEGED, 5138 }, { 5139 .name = "wsr.excsave1", 5140 .translate = translate_wsr, 5141 .test_exceptions = test_exceptions_sr, 5142 .par = (const uint32_t[]){ 5143 EXCSAVE1, 5144 XTENSA_OPTION_EXCEPTION, 5145 }, 5146 .op_flags = XTENSA_OP_PRIVILEGED, 5147 }, { 5148 .name = "wsr.excsave2", 5149 .translate = translate_wsr, 5150 .test_exceptions = test_exceptions_hpi, 5151 .par = (const uint32_t[]){ 5152 EXCSAVE1 + 1, 5153 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5154 }, 5155 .op_flags = XTENSA_OP_PRIVILEGED, 5156 }, { 5157 .name = "wsr.excsave3", 5158 .translate = translate_wsr, 5159 .test_exceptions = test_exceptions_hpi, 5160 .par = (const uint32_t[]){ 5161 EXCSAVE1 + 2, 5162 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5163 }, 5164 .op_flags = XTENSA_OP_PRIVILEGED, 5165 }, { 5166 .name = "wsr.excsave4", 5167 .translate = translate_wsr, 5168 .test_exceptions = test_exceptions_hpi, 5169 .par = (const uint32_t[]){ 5170 EXCSAVE1 + 3, 5171 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5172 }, 5173 .op_flags = XTENSA_OP_PRIVILEGED, 5174 }, { 5175 .name = "wsr.excsave5", 5176 .translate = translate_wsr, 5177 .test_exceptions = test_exceptions_hpi, 5178 .par = (const uint32_t[]){ 5179 EXCSAVE1 + 4, 5180 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5181 }, 5182 .op_flags = XTENSA_OP_PRIVILEGED, 5183 }, { 5184 .name = "wsr.excsave6", 5185 .translate = translate_wsr, 5186 .test_exceptions = test_exceptions_hpi, 5187 .par = (const uint32_t[]){ 5188 EXCSAVE1 + 5, 5189 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5190 }, 5191 .op_flags = XTENSA_OP_PRIVILEGED, 5192 }, { 5193 .name = "wsr.excsave7", 5194 .translate = translate_wsr, 5195 .test_exceptions = test_exceptions_hpi, 5196 .par = (const uint32_t[]){ 5197 EXCSAVE1 + 6, 5198 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5199 }, 5200 .op_flags = XTENSA_OP_PRIVILEGED, 5201 }, { 5202 .name = "wsr.excvaddr", 5203 .translate = translate_wsr, 5204 .test_exceptions = test_exceptions_sr, 5205 .par = (const uint32_t[]){ 5206 EXCVADDR, 5207 XTENSA_OPTION_EXCEPTION, 5208 }, 5209 .op_flags = XTENSA_OP_PRIVILEGED, 5210 }, { 5211 .name = "wsr.ibreaka0", 5212 .translate = translate_wsr_ibreaka, 5213 .test_exceptions = test_exceptions_ibreak, 5214 .par = (const uint32_t[]){ 5215 IBREAKA, 5216 XTENSA_OPTION_DEBUG, 5217 }, 5218 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5219 }, { 5220 .name = "wsr.ibreaka1", 5221 .translate = translate_wsr_ibreaka, 5222 .test_exceptions = test_exceptions_ibreak, 5223 .par = (const uint32_t[]){ 5224 IBREAKA + 1, 5225 XTENSA_OPTION_DEBUG, 5226 }, 5227 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5228 }, { 5229 .name = "wsr.ibreakenable", 5230 .translate = translate_wsr_ibreakenable, 5231 .test_exceptions = test_exceptions_sr, 5232 .par = (const uint32_t[]){ 5233 IBREAKENABLE, 5234 XTENSA_OPTION_DEBUG, 5235 }, 5236 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5237 }, { 5238 .name = "wsr.icount", 5239 .translate = translate_wsr_icount, 5240 .test_exceptions = test_exceptions_sr, 5241 .par = (const uint32_t[]){ 5242 ICOUNT, 5243 XTENSA_OPTION_DEBUG, 5244 }, 5245 .op_flags = XTENSA_OP_PRIVILEGED, 5246 }, { 5247 .name = "wsr.icountlevel", 5248 .translate = translate_wsr_mask, 5249 .test_exceptions = test_exceptions_sr, 5250 .par = (const uint32_t[]){ 5251 ICOUNTLEVEL, 5252 XTENSA_OPTION_DEBUG, 5253 0xf, 5254 }, 5255 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5256 }, { 5257 .name = "wsr.intclear", 5258 .translate = translate_wsr_intclear, 5259 .test_exceptions = test_exceptions_sr, 5260 .par = (const uint32_t[]){ 5261 INTCLEAR, 5262 XTENSA_OPTION_INTERRUPT, 5263 }, 5264 .op_flags = 5265 XTENSA_OP_PRIVILEGED | 5266 XTENSA_OP_EXIT_TB_0 | 5267 XTENSA_OP_CHECK_INTERRUPTS, 5268 }, { 5269 .name = "wsr.intenable", 5270 .translate = translate_wsr, 5271 .test_exceptions = test_exceptions_sr, 5272 .par = (const uint32_t[]){ 5273 INTENABLE, 5274 XTENSA_OPTION_INTERRUPT, 5275 }, 5276 .op_flags = 5277 XTENSA_OP_PRIVILEGED | 5278 XTENSA_OP_EXIT_TB_0 | 5279 XTENSA_OP_CHECK_INTERRUPTS, 5280 }, { 5281 .name = "wsr.interrupt", 5282 .translate = translate_wsr, 5283 .test_exceptions = test_exceptions_sr, 5284 .par = (const uint32_t[]){ 5285 INTSET, 5286 XTENSA_OPTION_INTERRUPT, 5287 }, 5288 .op_flags = 5289 XTENSA_OP_PRIVILEGED | 5290 XTENSA_OP_EXIT_TB_0 | 5291 XTENSA_OP_CHECK_INTERRUPTS, 5292 }, { 5293 .name = "wsr.intset", 5294 .translate = translate_wsr_intset, 5295 .test_exceptions = test_exceptions_sr, 5296 .par = (const uint32_t[]){ 5297 INTSET, 5298 XTENSA_OPTION_INTERRUPT, 5299 }, 5300 .op_flags = 5301 XTENSA_OP_PRIVILEGED | 5302 XTENSA_OP_EXIT_TB_0 | 5303 XTENSA_OP_CHECK_INTERRUPTS, 5304 }, { 5305 .name = "wsr.itlbcfg", 5306 .translate = translate_wsr_mask, 5307 .test_exceptions = test_exceptions_sr, 5308 .par = (const uint32_t[]){ 5309 ITLBCFG, 5310 XTENSA_OPTION_MMU, 5311 0x01130000, 5312 }, 5313 .op_flags = XTENSA_OP_PRIVILEGED, 5314 }, { 5315 .name = "wsr.lbeg", 5316 .translate = translate_wsr, 5317 .test_exceptions = test_exceptions_sr, 5318 .par = (const uint32_t[]){ 5319 LBEG, 5320 XTENSA_OPTION_LOOP, 5321 }, 5322 .op_flags = XTENSA_OP_EXIT_TB_M1, 5323 }, { 5324 .name = "wsr.lcount", 5325 .translate = translate_wsr, 5326 .test_exceptions = test_exceptions_sr, 5327 .par = (const uint32_t[]){ 5328 LCOUNT, 5329 XTENSA_OPTION_LOOP, 5330 }, 5331 }, { 5332 .name = "wsr.lend", 5333 .translate = translate_wsr, 5334 .test_exceptions = test_exceptions_sr, 5335 .par = (const uint32_t[]){ 5336 LEND, 5337 XTENSA_OPTION_LOOP, 5338 }, 5339 .op_flags = XTENSA_OP_EXIT_TB_M1, 5340 }, { 5341 .name = "wsr.litbase", 5342 .translate = translate_wsr_mask, 5343 .test_exceptions = test_exceptions_sr, 5344 .par = (const uint32_t[]){ 5345 LITBASE, 5346 XTENSA_OPTION_EXTENDED_L32R, 5347 0xfffff001, 5348 }, 5349 .op_flags = XTENSA_OP_EXIT_TB_M1, 5350 }, { 5351 .name = "wsr.m0", 5352 .translate = translate_wsr, 5353 .test_exceptions = test_exceptions_sr, 5354 .par = (const uint32_t[]){ 5355 MR, 5356 XTENSA_OPTION_MAC16, 5357 }, 5358 }, { 5359 .name = "wsr.m1", 5360 .translate = translate_wsr, 5361 .test_exceptions = test_exceptions_sr, 5362 .par = (const uint32_t[]){ 5363 MR + 1, 5364 XTENSA_OPTION_MAC16, 5365 }, 5366 }, { 5367 .name = "wsr.m2", 5368 .translate = translate_wsr, 5369 .test_exceptions = test_exceptions_sr, 5370 .par = (const uint32_t[]){ 5371 MR + 2, 5372 XTENSA_OPTION_MAC16, 5373 }, 5374 }, { 5375 .name = "wsr.m3", 5376 .translate = translate_wsr, 5377 .test_exceptions = test_exceptions_sr, 5378 .par = (const uint32_t[]){ 5379 MR + 3, 5380 XTENSA_OPTION_MAC16, 5381 }, 5382 }, { 5383 .name = "wsr.memctl", 5384 .translate = translate_wsr_memctl, 5385 .par = (const uint32_t[]){MEMCTL}, 5386 .op_flags = XTENSA_OP_PRIVILEGED, 5387 }, { 5388 .name = "wsr.mecr", 5389 .translate = translate_wsr, 5390 .test_exceptions = test_exceptions_sr, 5391 .par = (const uint32_t[]){ 5392 MECR, 5393 XTENSA_OPTION_MEMORY_ECC_PARITY, 5394 }, 5395 .op_flags = XTENSA_OP_PRIVILEGED, 5396 }, { 5397 .name = "wsr.mepc", 5398 .translate = translate_wsr, 5399 .test_exceptions = test_exceptions_sr, 5400 .par = (const uint32_t[]){ 5401 MEPC, 5402 XTENSA_OPTION_MEMORY_ECC_PARITY, 5403 }, 5404 .op_flags = XTENSA_OP_PRIVILEGED, 5405 }, { 5406 .name = "wsr.meps", 5407 .translate = translate_wsr, 5408 .test_exceptions = test_exceptions_sr, 5409 .par = (const uint32_t[]){ 5410 MEPS, 5411 XTENSA_OPTION_MEMORY_ECC_PARITY, 5412 }, 5413 .op_flags = XTENSA_OP_PRIVILEGED, 5414 }, { 5415 .name = "wsr.mesave", 5416 .translate = translate_wsr, 5417 .test_exceptions = test_exceptions_sr, 5418 .par = (const uint32_t[]){ 5419 MESAVE, 5420 XTENSA_OPTION_MEMORY_ECC_PARITY, 5421 }, 5422 .op_flags = XTENSA_OP_PRIVILEGED, 5423 }, { 5424 .name = "wsr.mesr", 5425 .translate = translate_wsr, 5426 .test_exceptions = test_exceptions_sr, 5427 .par = (const uint32_t[]){ 5428 MESR, 5429 XTENSA_OPTION_MEMORY_ECC_PARITY, 5430 }, 5431 .op_flags = XTENSA_OP_PRIVILEGED, 5432 }, { 5433 .name = "wsr.mevaddr", 5434 .translate = translate_wsr, 5435 .test_exceptions = test_exceptions_sr, 5436 .par = (const uint32_t[]){ 5437 MESR, 5438 XTENSA_OPTION_MEMORY_ECC_PARITY, 5439 }, 5440 .op_flags = XTENSA_OP_PRIVILEGED, 5441 }, { 5442 .name = "wsr.misc0", 5443 .translate = translate_wsr, 5444 .test_exceptions = test_exceptions_sr, 5445 .par = (const uint32_t[]){ 5446 MISC, 5447 XTENSA_OPTION_MISC_SR, 5448 }, 5449 .op_flags = XTENSA_OP_PRIVILEGED, 5450 }, { 5451 .name = "wsr.misc1", 5452 .translate = translate_wsr, 5453 .test_exceptions = test_exceptions_sr, 5454 .par = (const uint32_t[]){ 5455 MISC + 1, 5456 XTENSA_OPTION_MISC_SR, 5457 }, 5458 .op_flags = XTENSA_OP_PRIVILEGED, 5459 }, { 5460 .name = "wsr.misc2", 5461 .translate = translate_wsr, 5462 .test_exceptions = test_exceptions_sr, 5463 .par = (const uint32_t[]){ 5464 MISC + 2, 5465 XTENSA_OPTION_MISC_SR, 5466 }, 5467 .op_flags = XTENSA_OP_PRIVILEGED, 5468 }, { 5469 .name = "wsr.misc3", 5470 .translate = translate_wsr, 5471 .test_exceptions = test_exceptions_sr, 5472 .par = (const uint32_t[]){ 5473 MISC + 3, 5474 XTENSA_OPTION_MISC_SR, 5475 }, 5476 .op_flags = XTENSA_OP_PRIVILEGED, 5477 }, { 5478 .name = "wsr.mmid", 5479 .translate = translate_wsr, 5480 .test_exceptions = test_exceptions_sr, 5481 .par = (const uint32_t[]){ 5482 MMID, 5483 XTENSA_OPTION_TRACE_PORT, 5484 }, 5485 .op_flags = XTENSA_OP_PRIVILEGED, 5486 }, { 5487 .name = "wsr.mpuenb", 5488 .translate = translate_wsr_mpuenb, 5489 .test_exceptions = test_exceptions_sr, 5490 .par = (const uint32_t[]){ 5491 MPUENB, 5492 XTENSA_OPTION_MPU, 5493 }, 5494 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5495 }, { 5496 .name = "wsr.prefctl", 5497 .translate = translate_wsr, 5498 .par = (const uint32_t[]){PREFCTL}, 5499 }, { 5500 .name = "wsr.prid", 5501 .op_flags = XTENSA_OP_ILL, 5502 }, { 5503 .name = "wsr.ps", 5504 .translate = translate_wsr_ps, 5505 .test_exceptions = test_exceptions_sr, 5506 .par = (const uint32_t[]){ 5507 PS, 5508 XTENSA_OPTION_EXCEPTION, 5509 }, 5510 .op_flags = 5511 XTENSA_OP_PRIVILEGED | 5512 XTENSA_OP_EXIT_TB_M1 | 5513 XTENSA_OP_CHECK_INTERRUPTS, 5514 }, { 5515 .name = "wsr.ptevaddr", 5516 .translate = translate_wsr_mask, 5517 .test_exceptions = test_exceptions_sr, 5518 .par = (const uint32_t[]){ 5519 PTEVADDR, 5520 XTENSA_OPTION_MMU, 5521 0xffc00000, 5522 }, 5523 .op_flags = XTENSA_OP_PRIVILEGED, 5524 }, { 5525 .name = "wsr.rasid", 5526 .translate = translate_wsr_rasid, 5527 .test_exceptions = test_exceptions_sr, 5528 .par = (const uint32_t[]){ 5529 RASID, 5530 XTENSA_OPTION_MMU, 5531 }, 5532 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5533 }, { 5534 .name = "wsr.sar", 5535 .translate = translate_wsr_sar, 5536 .par = (const uint32_t[]){SAR}, 5537 }, { 5538 .name = "wsr.scompare1", 5539 .translate = translate_wsr, 5540 .test_exceptions = test_exceptions_sr, 5541 .par = (const uint32_t[]){ 5542 SCOMPARE1, 5543 XTENSA_OPTION_CONDITIONAL_STORE, 5544 }, 5545 }, { 5546 .name = "wsr.vecbase", 5547 .translate = translate_wsr, 5548 .test_exceptions = test_exceptions_sr, 5549 .par = (const uint32_t[]){ 5550 VECBASE, 5551 XTENSA_OPTION_RELOCATABLE_VECTOR, 5552 }, 5553 .op_flags = XTENSA_OP_PRIVILEGED, 5554 }, { 5555 .name = "wsr.windowbase", 5556 .translate = translate_wsr_windowbase, 5557 .test_exceptions = test_exceptions_sr, 5558 .par = (const uint32_t[]){ 5559 WINDOW_BASE, 5560 XTENSA_OPTION_WINDOWED_REGISTER, 5561 }, 5562 .op_flags = XTENSA_OP_PRIVILEGED | 5563 XTENSA_OP_EXIT_TB_M1 | 5564 XTENSA_OP_SYNC_REGISTER_WINDOW, 5565 }, { 5566 .name = "wsr.windowstart", 5567 .translate = translate_wsr_windowstart, 5568 .test_exceptions = test_exceptions_sr, 5569 .par = (const uint32_t[]){ 5570 WINDOW_START, 5571 XTENSA_OPTION_WINDOWED_REGISTER, 5572 }, 5573 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5574 }, { 5575 .name = "wur.expstate", 5576 .translate = translate_wur, 5577 .par = (const uint32_t[]){EXPSTATE}, 5578 }, { 5579 .name = "wur.threadptr", 5580 .translate = translate_wur, 5581 .par = (const uint32_t[]){THREADPTR}, 5582 }, { 5583 .name = "xor", 5584 .translate = translate_xor, 5585 }, { 5586 .name = "xorb", 5587 .translate = translate_boolean, 5588 .par = (const uint32_t[]){BOOLEAN_XOR}, 5589 }, { 5590 .name = "xsr.176", 5591 .op_flags = XTENSA_OP_ILL, 5592 }, { 5593 .name = "xsr.208", 5594 .op_flags = XTENSA_OP_ILL, 5595 }, { 5596 .name = "xsr.acchi", 5597 .translate = translate_xsr_acchi, 5598 .test_exceptions = test_exceptions_sr, 5599 .par = (const uint32_t[]){ 5600 ACCHI, 5601 XTENSA_OPTION_MAC16, 5602 }, 5603 }, { 5604 .name = "xsr.acclo", 5605 .translate = translate_xsr, 5606 .test_exceptions = test_exceptions_sr, 5607 .par = (const uint32_t[]){ 5608 ACCLO, 5609 XTENSA_OPTION_MAC16, 5610 }, 5611 }, { 5612 .name = "xsr.atomctl", 5613 .translate = translate_xsr_mask, 5614 .test_exceptions = test_exceptions_sr, 5615 .par = (const uint32_t[]){ 5616 ATOMCTL, 5617 XTENSA_OPTION_ATOMCTL, 5618 0x3f, 5619 }, 5620 .op_flags = XTENSA_OP_PRIVILEGED, 5621 }, { 5622 .name = "xsr.br", 5623 .translate = translate_xsr_mask, 5624 .test_exceptions = test_exceptions_sr, 5625 .par = (const uint32_t[]){ 5626 BR, 5627 XTENSA_OPTION_BOOLEAN, 5628 0xffff, 5629 }, 5630 }, { 5631 .name = "xsr.cacheadrdis", 5632 .translate = translate_xsr_mask, 5633 .test_exceptions = test_exceptions_sr, 5634 .par = (const uint32_t[]){ 5635 CACHEADRDIS, 5636 XTENSA_OPTION_MPU, 5637 0xff, 5638 }, 5639 .op_flags = XTENSA_OP_PRIVILEGED, 5640 }, { 5641 .name = "xsr.cacheattr", 5642 .translate = translate_xsr, 5643 .test_exceptions = test_exceptions_sr, 5644 .par = (const uint32_t[]){ 5645 CACHEATTR, 5646 XTENSA_OPTION_CACHEATTR, 5647 }, 5648 .op_flags = XTENSA_OP_PRIVILEGED, 5649 }, { 5650 .name = "xsr.ccompare0", 5651 .translate = translate_xsr_ccompare, 5652 .test_exceptions = test_exceptions_ccompare, 5653 .par = (const uint32_t[]){ 5654 CCOMPARE, 5655 XTENSA_OPTION_TIMER_INTERRUPT, 5656 }, 5657 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5658 }, { 5659 .name = "xsr.ccompare1", 5660 .translate = translate_xsr_ccompare, 5661 .test_exceptions = test_exceptions_ccompare, 5662 .par = (const uint32_t[]){ 5663 CCOMPARE + 1, 5664 XTENSA_OPTION_TIMER_INTERRUPT, 5665 }, 5666 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5667 }, { 5668 .name = "xsr.ccompare2", 5669 .translate = translate_xsr_ccompare, 5670 .test_exceptions = test_exceptions_ccompare, 5671 .par = (const uint32_t[]){ 5672 CCOMPARE + 2, 5673 XTENSA_OPTION_TIMER_INTERRUPT, 5674 }, 5675 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5676 }, { 5677 .name = "xsr.ccount", 5678 .translate = translate_xsr_ccount, 5679 .test_exceptions = test_exceptions_sr, 5680 .par = (const uint32_t[]){ 5681 CCOUNT, 5682 XTENSA_OPTION_TIMER_INTERRUPT, 5683 }, 5684 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5685 }, { 5686 .name = "xsr.configid0", 5687 .op_flags = XTENSA_OP_ILL, 5688 }, { 5689 .name = "xsr.configid1", 5690 .op_flags = XTENSA_OP_ILL, 5691 }, { 5692 .name = "xsr.cpenable", 5693 .translate = translate_xsr_mask, 5694 .test_exceptions = test_exceptions_sr, 5695 .par = (const uint32_t[]){ 5696 CPENABLE, 5697 XTENSA_OPTION_COPROCESSOR, 5698 0xff, 5699 }, 5700 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5701 }, { 5702 .name = "xsr.dbreaka0", 5703 .translate = translate_xsr_dbreaka, 5704 .test_exceptions = test_exceptions_dbreak, 5705 .par = (const uint32_t[]){ 5706 DBREAKA, 5707 XTENSA_OPTION_DEBUG, 5708 }, 5709 .op_flags = XTENSA_OP_PRIVILEGED, 5710 }, { 5711 .name = "xsr.dbreaka1", 5712 .translate = translate_xsr_dbreaka, 5713 .test_exceptions = test_exceptions_dbreak, 5714 .par = (const uint32_t[]){ 5715 DBREAKA + 1, 5716 XTENSA_OPTION_DEBUG, 5717 }, 5718 .op_flags = XTENSA_OP_PRIVILEGED, 5719 }, { 5720 .name = "xsr.dbreakc0", 5721 .translate = translate_xsr_dbreakc, 5722 .test_exceptions = test_exceptions_dbreak, 5723 .par = (const uint32_t[]){ 5724 DBREAKC, 5725 XTENSA_OPTION_DEBUG, 5726 }, 5727 .op_flags = XTENSA_OP_PRIVILEGED, 5728 }, { 5729 .name = "xsr.dbreakc1", 5730 .translate = translate_xsr_dbreakc, 5731 .test_exceptions = test_exceptions_dbreak, 5732 .par = (const uint32_t[]){ 5733 DBREAKC + 1, 5734 XTENSA_OPTION_DEBUG, 5735 }, 5736 .op_flags = XTENSA_OP_PRIVILEGED, 5737 }, { 5738 .name = "xsr.ddr", 5739 .translate = translate_xsr, 5740 .test_exceptions = test_exceptions_sr, 5741 .par = (const uint32_t[]){ 5742 DDR, 5743 XTENSA_OPTION_DEBUG, 5744 }, 5745 .op_flags = XTENSA_OP_PRIVILEGED, 5746 }, { 5747 .name = "xsr.debugcause", 5748 .op_flags = XTENSA_OP_ILL, 5749 }, { 5750 .name = "xsr.depc", 5751 .translate = translate_xsr, 5752 .test_exceptions = test_exceptions_sr, 5753 .par = (const uint32_t[]){ 5754 DEPC, 5755 XTENSA_OPTION_EXCEPTION, 5756 }, 5757 .op_flags = XTENSA_OP_PRIVILEGED, 5758 }, { 5759 .name = "xsr.dtlbcfg", 5760 .translate = translate_xsr_mask, 5761 .test_exceptions = test_exceptions_sr, 5762 .par = (const uint32_t[]){ 5763 DTLBCFG, 5764 XTENSA_OPTION_MMU, 5765 0x01130000, 5766 }, 5767 .op_flags = XTENSA_OP_PRIVILEGED, 5768 }, { 5769 .name = "xsr.epc1", 5770 .translate = translate_xsr, 5771 .test_exceptions = test_exceptions_sr, 5772 .par = (const uint32_t[]){ 5773 EPC1, 5774 XTENSA_OPTION_EXCEPTION, 5775 }, 5776 .op_flags = XTENSA_OP_PRIVILEGED, 5777 }, { 5778 .name = "xsr.epc2", 5779 .translate = translate_xsr, 5780 .test_exceptions = test_exceptions_hpi, 5781 .par = (const uint32_t[]){ 5782 EPC1 + 1, 5783 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5784 }, 5785 .op_flags = XTENSA_OP_PRIVILEGED, 5786 }, { 5787 .name = "xsr.epc3", 5788 .translate = translate_xsr, 5789 .test_exceptions = test_exceptions_hpi, 5790 .par = (const uint32_t[]){ 5791 EPC1 + 2, 5792 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5793 }, 5794 .op_flags = XTENSA_OP_PRIVILEGED, 5795 }, { 5796 .name = "xsr.epc4", 5797 .translate = translate_xsr, 5798 .test_exceptions = test_exceptions_hpi, 5799 .par = (const uint32_t[]){ 5800 EPC1 + 3, 5801 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5802 }, 5803 .op_flags = XTENSA_OP_PRIVILEGED, 5804 }, { 5805 .name = "xsr.epc5", 5806 .translate = translate_xsr, 5807 .test_exceptions = test_exceptions_hpi, 5808 .par = (const uint32_t[]){ 5809 EPC1 + 4, 5810 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5811 }, 5812 .op_flags = XTENSA_OP_PRIVILEGED, 5813 }, { 5814 .name = "xsr.epc6", 5815 .translate = translate_xsr, 5816 .test_exceptions = test_exceptions_hpi, 5817 .par = (const uint32_t[]){ 5818 EPC1 + 5, 5819 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5820 }, 5821 .op_flags = XTENSA_OP_PRIVILEGED, 5822 }, { 5823 .name = "xsr.epc7", 5824 .translate = translate_xsr, 5825 .test_exceptions = test_exceptions_hpi, 5826 .par = (const uint32_t[]){ 5827 EPC1 + 6, 5828 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5829 }, 5830 .op_flags = XTENSA_OP_PRIVILEGED, 5831 }, { 5832 .name = "xsr.eps2", 5833 .translate = translate_xsr, 5834 .test_exceptions = test_exceptions_hpi, 5835 .par = (const uint32_t[]){ 5836 EPS2, 5837 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5838 }, 5839 .op_flags = XTENSA_OP_PRIVILEGED, 5840 }, { 5841 .name = "xsr.eps3", 5842 .translate = translate_xsr, 5843 .test_exceptions = test_exceptions_hpi, 5844 .par = (const uint32_t[]){ 5845 EPS2 + 1, 5846 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5847 }, 5848 .op_flags = XTENSA_OP_PRIVILEGED, 5849 }, { 5850 .name = "xsr.eps4", 5851 .translate = translate_xsr, 5852 .test_exceptions = test_exceptions_hpi, 5853 .par = (const uint32_t[]){ 5854 EPS2 + 2, 5855 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5856 }, 5857 .op_flags = XTENSA_OP_PRIVILEGED, 5858 }, { 5859 .name = "xsr.eps5", 5860 .translate = translate_xsr, 5861 .test_exceptions = test_exceptions_hpi, 5862 .par = (const uint32_t[]){ 5863 EPS2 + 3, 5864 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5865 }, 5866 .op_flags = XTENSA_OP_PRIVILEGED, 5867 }, { 5868 .name = "xsr.eps6", 5869 .translate = translate_xsr, 5870 .test_exceptions = test_exceptions_hpi, 5871 .par = (const uint32_t[]){ 5872 EPS2 + 4, 5873 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5874 }, 5875 .op_flags = XTENSA_OP_PRIVILEGED, 5876 }, { 5877 .name = "xsr.eps7", 5878 .translate = translate_xsr, 5879 .test_exceptions = test_exceptions_hpi, 5880 .par = (const uint32_t[]){ 5881 EPS2 + 5, 5882 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5883 }, 5884 .op_flags = XTENSA_OP_PRIVILEGED, 5885 }, { 5886 .name = "xsr.eraccess", 5887 .translate = translate_xsr_mask, 5888 .par = (const uint32_t[]){ 5889 ERACCESS, 5890 0, 5891 0xffff, 5892 }, 5893 .op_flags = XTENSA_OP_PRIVILEGED, 5894 }, { 5895 .name = "xsr.exccause", 5896 .translate = translate_xsr, 5897 .test_exceptions = test_exceptions_sr, 5898 .par = (const uint32_t[]){ 5899 EXCCAUSE, 5900 XTENSA_OPTION_EXCEPTION, 5901 }, 5902 .op_flags = XTENSA_OP_PRIVILEGED, 5903 }, { 5904 .name = "xsr.excsave1", 5905 .translate = translate_xsr, 5906 .test_exceptions = test_exceptions_sr, 5907 .par = (const uint32_t[]){ 5908 EXCSAVE1, 5909 XTENSA_OPTION_EXCEPTION, 5910 }, 5911 .op_flags = XTENSA_OP_PRIVILEGED, 5912 }, { 5913 .name = "xsr.excsave2", 5914 .translate = translate_xsr, 5915 .test_exceptions = test_exceptions_hpi, 5916 .par = (const uint32_t[]){ 5917 EXCSAVE1 + 1, 5918 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5919 }, 5920 .op_flags = XTENSA_OP_PRIVILEGED, 5921 }, { 5922 .name = "xsr.excsave3", 5923 .translate = translate_xsr, 5924 .test_exceptions = test_exceptions_hpi, 5925 .par = (const uint32_t[]){ 5926 EXCSAVE1 + 2, 5927 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5928 }, 5929 .op_flags = XTENSA_OP_PRIVILEGED, 5930 }, { 5931 .name = "xsr.excsave4", 5932 .translate = translate_xsr, 5933 .test_exceptions = test_exceptions_hpi, 5934 .par = (const uint32_t[]){ 5935 EXCSAVE1 + 3, 5936 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5937 }, 5938 .op_flags = XTENSA_OP_PRIVILEGED, 5939 }, { 5940 .name = "xsr.excsave5", 5941 .translate = translate_xsr, 5942 .test_exceptions = test_exceptions_hpi, 5943 .par = (const uint32_t[]){ 5944 EXCSAVE1 + 4, 5945 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5946 }, 5947 .op_flags = XTENSA_OP_PRIVILEGED, 5948 }, { 5949 .name = "xsr.excsave6", 5950 .translate = translate_xsr, 5951 .test_exceptions = test_exceptions_hpi, 5952 .par = (const uint32_t[]){ 5953 EXCSAVE1 + 5, 5954 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5955 }, 5956 .op_flags = XTENSA_OP_PRIVILEGED, 5957 }, { 5958 .name = "xsr.excsave7", 5959 .translate = translate_xsr, 5960 .test_exceptions = test_exceptions_hpi, 5961 .par = (const uint32_t[]){ 5962 EXCSAVE1 + 6, 5963 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 5964 }, 5965 .op_flags = XTENSA_OP_PRIVILEGED, 5966 }, { 5967 .name = "xsr.excvaddr", 5968 .translate = translate_xsr, 5969 .test_exceptions = test_exceptions_sr, 5970 .par = (const uint32_t[]){ 5971 EXCVADDR, 5972 XTENSA_OPTION_EXCEPTION, 5973 }, 5974 .op_flags = XTENSA_OP_PRIVILEGED, 5975 }, { 5976 .name = "xsr.ibreaka0", 5977 .translate = translate_xsr_ibreaka, 5978 .test_exceptions = test_exceptions_ibreak, 5979 .par = (const uint32_t[]){ 5980 IBREAKA, 5981 XTENSA_OPTION_DEBUG, 5982 }, 5983 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5984 }, { 5985 .name = "xsr.ibreaka1", 5986 .translate = translate_xsr_ibreaka, 5987 .test_exceptions = test_exceptions_ibreak, 5988 .par = (const uint32_t[]){ 5989 IBREAKA + 1, 5990 XTENSA_OPTION_DEBUG, 5991 }, 5992 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5993 }, { 5994 .name = "xsr.ibreakenable", 5995 .translate = translate_xsr_ibreakenable, 5996 .test_exceptions = test_exceptions_sr, 5997 .par = (const uint32_t[]){ 5998 IBREAKENABLE, 5999 XTENSA_OPTION_DEBUG, 6000 }, 6001 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 6002 }, { 6003 .name = "xsr.icount", 6004 .translate = translate_xsr_icount, 6005 .test_exceptions = test_exceptions_sr, 6006 .par = (const uint32_t[]){ 6007 ICOUNT, 6008 XTENSA_OPTION_DEBUG, 6009 }, 6010 .op_flags = XTENSA_OP_PRIVILEGED, 6011 }, { 6012 .name = "xsr.icountlevel", 6013 .translate = translate_xsr_mask, 6014 .test_exceptions = test_exceptions_sr, 6015 .par = (const uint32_t[]){ 6016 ICOUNTLEVEL, 6017 XTENSA_OPTION_DEBUG, 6018 0xf, 6019 }, 6020 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 6021 }, { 6022 .name = "xsr.intclear", 6023 .op_flags = XTENSA_OP_ILL, 6024 }, { 6025 .name = "xsr.intenable", 6026 .translate = translate_xsr, 6027 .test_exceptions = test_exceptions_sr, 6028 .par = (const uint32_t[]){ 6029 INTENABLE, 6030 XTENSA_OPTION_INTERRUPT, 6031 }, 6032 .op_flags = 6033 XTENSA_OP_PRIVILEGED | 6034 XTENSA_OP_EXIT_TB_0 | 6035 XTENSA_OP_CHECK_INTERRUPTS, 6036 }, { 6037 .name = "xsr.interrupt", 6038 .op_flags = XTENSA_OP_ILL, 6039 }, { 6040 .name = "xsr.intset", 6041 .op_flags = XTENSA_OP_ILL, 6042 }, { 6043 .name = "xsr.itlbcfg", 6044 .translate = translate_xsr_mask, 6045 .test_exceptions = test_exceptions_sr, 6046 .par = (const uint32_t[]){ 6047 ITLBCFG, 6048 XTENSA_OPTION_MMU, 6049 0x01130000, 6050 }, 6051 .op_flags = XTENSA_OP_PRIVILEGED, 6052 }, { 6053 .name = "xsr.lbeg", 6054 .translate = translate_xsr, 6055 .test_exceptions = test_exceptions_sr, 6056 .par = (const uint32_t[]){ 6057 LBEG, 6058 XTENSA_OPTION_LOOP, 6059 }, 6060 .op_flags = XTENSA_OP_EXIT_TB_M1, 6061 }, { 6062 .name = "xsr.lcount", 6063 .translate = translate_xsr, 6064 .test_exceptions = test_exceptions_sr, 6065 .par = (const uint32_t[]){ 6066 LCOUNT, 6067 XTENSA_OPTION_LOOP, 6068 }, 6069 }, { 6070 .name = "xsr.lend", 6071 .translate = translate_xsr, 6072 .test_exceptions = test_exceptions_sr, 6073 .par = (const uint32_t[]){ 6074 LEND, 6075 XTENSA_OPTION_LOOP, 6076 }, 6077 .op_flags = XTENSA_OP_EXIT_TB_M1, 6078 }, { 6079 .name = "xsr.litbase", 6080 .translate = translate_xsr_mask, 6081 .test_exceptions = test_exceptions_sr, 6082 .par = (const uint32_t[]){ 6083 LITBASE, 6084 XTENSA_OPTION_EXTENDED_L32R, 6085 0xfffff001, 6086 }, 6087 .op_flags = XTENSA_OP_EXIT_TB_M1, 6088 }, { 6089 .name = "xsr.m0", 6090 .translate = translate_xsr, 6091 .test_exceptions = test_exceptions_sr, 6092 .par = (const uint32_t[]){ 6093 MR, 6094 XTENSA_OPTION_MAC16, 6095 }, 6096 }, { 6097 .name = "xsr.m1", 6098 .translate = translate_xsr, 6099 .test_exceptions = test_exceptions_sr, 6100 .par = (const uint32_t[]){ 6101 MR + 1, 6102 XTENSA_OPTION_MAC16, 6103 }, 6104 }, { 6105 .name = "xsr.m2", 6106 .translate = translate_xsr, 6107 .test_exceptions = test_exceptions_sr, 6108 .par = (const uint32_t[]){ 6109 MR + 2, 6110 XTENSA_OPTION_MAC16, 6111 }, 6112 }, { 6113 .name = "xsr.m3", 6114 .translate = translate_xsr, 6115 .test_exceptions = test_exceptions_sr, 6116 .par = (const uint32_t[]){ 6117 MR + 3, 6118 XTENSA_OPTION_MAC16, 6119 }, 6120 }, { 6121 .name = "xsr.memctl", 6122 .translate = translate_xsr_memctl, 6123 .par = (const uint32_t[]){MEMCTL}, 6124 .op_flags = XTENSA_OP_PRIVILEGED, 6125 }, { 6126 .name = "xsr.mecr", 6127 .translate = translate_xsr, 6128 .test_exceptions = test_exceptions_sr, 6129 .par = (const uint32_t[]){ 6130 MECR, 6131 XTENSA_OPTION_MEMORY_ECC_PARITY, 6132 }, 6133 .op_flags = XTENSA_OP_PRIVILEGED, 6134 }, { 6135 .name = "xsr.mepc", 6136 .translate = translate_xsr, 6137 .test_exceptions = test_exceptions_sr, 6138 .par = (const uint32_t[]){ 6139 MEPC, 6140 XTENSA_OPTION_MEMORY_ECC_PARITY, 6141 }, 6142 .op_flags = XTENSA_OP_PRIVILEGED, 6143 }, { 6144 .name = "xsr.meps", 6145 .translate = translate_xsr, 6146 .test_exceptions = test_exceptions_sr, 6147 .par = (const uint32_t[]){ 6148 MEPS, 6149 XTENSA_OPTION_MEMORY_ECC_PARITY, 6150 }, 6151 .op_flags = XTENSA_OP_PRIVILEGED, 6152 }, { 6153 .name = "xsr.mesave", 6154 .translate = translate_xsr, 6155 .test_exceptions = test_exceptions_sr, 6156 .par = (const uint32_t[]){ 6157 MESAVE, 6158 XTENSA_OPTION_MEMORY_ECC_PARITY, 6159 }, 6160 .op_flags = XTENSA_OP_PRIVILEGED, 6161 }, { 6162 .name = "xsr.mesr", 6163 .translate = translate_xsr, 6164 .test_exceptions = test_exceptions_sr, 6165 .par = (const uint32_t[]){ 6166 MESR, 6167 XTENSA_OPTION_MEMORY_ECC_PARITY, 6168 }, 6169 .op_flags = XTENSA_OP_PRIVILEGED, 6170 }, { 6171 .name = "xsr.mevaddr", 6172 .translate = translate_xsr, 6173 .test_exceptions = test_exceptions_sr, 6174 .par = (const uint32_t[]){ 6175 MESR, 6176 XTENSA_OPTION_MEMORY_ECC_PARITY, 6177 }, 6178 .op_flags = XTENSA_OP_PRIVILEGED, 6179 }, { 6180 .name = "xsr.misc0", 6181 .translate = translate_xsr, 6182 .test_exceptions = test_exceptions_sr, 6183 .par = (const uint32_t[]){ 6184 MISC, 6185 XTENSA_OPTION_MISC_SR, 6186 }, 6187 .op_flags = XTENSA_OP_PRIVILEGED, 6188 }, { 6189 .name = "xsr.misc1", 6190 .translate = translate_xsr, 6191 .test_exceptions = test_exceptions_sr, 6192 .par = (const uint32_t[]){ 6193 MISC + 1, 6194 XTENSA_OPTION_MISC_SR, 6195 }, 6196 .op_flags = XTENSA_OP_PRIVILEGED, 6197 }, { 6198 .name = "xsr.misc2", 6199 .translate = translate_xsr, 6200 .test_exceptions = test_exceptions_sr, 6201 .par = (const uint32_t[]){ 6202 MISC + 2, 6203 XTENSA_OPTION_MISC_SR, 6204 }, 6205 .op_flags = XTENSA_OP_PRIVILEGED, 6206 }, { 6207 .name = "xsr.misc3", 6208 .translate = translate_xsr, 6209 .test_exceptions = test_exceptions_sr, 6210 .par = (const uint32_t[]){ 6211 MISC + 3, 6212 XTENSA_OPTION_MISC_SR, 6213 }, 6214 .op_flags = XTENSA_OP_PRIVILEGED, 6215 }, { 6216 .name = "xsr.mpuenb", 6217 .translate = translate_xsr_mpuenb, 6218 .test_exceptions = test_exceptions_sr, 6219 .par = (const uint32_t[]){ 6220 MPUENB, 6221 XTENSA_OPTION_MPU, 6222 }, 6223 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 6224 }, { 6225 .name = "xsr.prefctl", 6226 .translate = translate_xsr, 6227 .par = (const uint32_t[]){PREFCTL}, 6228 }, { 6229 .name = "xsr.prid", 6230 .op_flags = XTENSA_OP_ILL, 6231 }, { 6232 .name = "xsr.ps", 6233 .translate = translate_xsr_ps, 6234 .test_exceptions = test_exceptions_sr, 6235 .par = (const uint32_t[]){ 6236 PS, 6237 XTENSA_OPTION_EXCEPTION, 6238 }, 6239 .op_flags = 6240 XTENSA_OP_PRIVILEGED | 6241 XTENSA_OP_EXIT_TB_M1 | 6242 XTENSA_OP_CHECK_INTERRUPTS, 6243 }, { 6244 .name = "xsr.ptevaddr", 6245 .translate = translate_xsr_mask, 6246 .test_exceptions = test_exceptions_sr, 6247 .par = (const uint32_t[]){ 6248 PTEVADDR, 6249 XTENSA_OPTION_MMU, 6250 0xffc00000, 6251 }, 6252 .op_flags = XTENSA_OP_PRIVILEGED, 6253 }, { 6254 .name = "xsr.rasid", 6255 .translate = translate_xsr_rasid, 6256 .test_exceptions = test_exceptions_sr, 6257 .par = (const uint32_t[]){ 6258 RASID, 6259 XTENSA_OPTION_MMU, 6260 }, 6261 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 6262 }, { 6263 .name = "xsr.sar", 6264 .translate = translate_xsr_sar, 6265 .par = (const uint32_t[]){SAR}, 6266 }, { 6267 .name = "xsr.scompare1", 6268 .translate = translate_xsr, 6269 .test_exceptions = test_exceptions_sr, 6270 .par = (const uint32_t[]){ 6271 SCOMPARE1, 6272 XTENSA_OPTION_CONDITIONAL_STORE, 6273 }, 6274 }, { 6275 .name = "xsr.vecbase", 6276 .translate = translate_xsr, 6277 .test_exceptions = test_exceptions_sr, 6278 .par = (const uint32_t[]){ 6279 VECBASE, 6280 XTENSA_OPTION_RELOCATABLE_VECTOR, 6281 }, 6282 .op_flags = XTENSA_OP_PRIVILEGED, 6283 }, { 6284 .name = "xsr.windowbase", 6285 .translate = translate_xsr_windowbase, 6286 .test_exceptions = test_exceptions_sr, 6287 .par = (const uint32_t[]){ 6288 WINDOW_BASE, 6289 XTENSA_OPTION_WINDOWED_REGISTER, 6290 }, 6291 .op_flags = XTENSA_OP_PRIVILEGED | 6292 XTENSA_OP_EXIT_TB_M1 | 6293 XTENSA_OP_SYNC_REGISTER_WINDOW, 6294 }, { 6295 .name = "xsr.windowstart", 6296 .translate = translate_xsr_windowstart, 6297 .test_exceptions = test_exceptions_sr, 6298 .par = (const uint32_t[]){ 6299 WINDOW_START, 6300 XTENSA_OPTION_WINDOWED_REGISTER, 6301 }, 6302 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 6303 }, 6304 }; 6305 6306 const XtensaOpcodeTranslators xtensa_core_opcodes = { 6307 .num_opcodes = ARRAY_SIZE(core_ops), 6308 .opcode = core_ops, 6309 }; 6310 6311 6312 static inline void get_f32_o1_i3(const OpcodeArg *arg, OpcodeArg *arg32, 6313 int o0, int i0, int i1, int i2) 6314 { 6315 if ((i0 >= 0 && arg[i0].num_bits == 64) || 6316 (o0 >= 0 && arg[o0].num_bits == 64)) { 6317 if (o0 >= 0) { 6318 arg32[o0].out = tcg_temp_new_i32(); 6319 } 6320 if (i0 >= 0) { 6321 arg32[i0].in = tcg_temp_new_i32(); 6322 tcg_gen_extrl_i64_i32(arg32[i0].in, arg[i0].in); 6323 } 6324 if (i1 >= 0) { 6325 arg32[i1].in = tcg_temp_new_i32(); 6326 tcg_gen_extrl_i64_i32(arg32[i1].in, arg[i1].in); 6327 } 6328 if (i2 >= 0) { 6329 arg32[i2].in = tcg_temp_new_i32(); 6330 tcg_gen_extrl_i64_i32(arg32[i2].in, arg[i2].in); 6331 } 6332 } else { 6333 if (o0 >= 0) { 6334 arg32[o0].out = arg[o0].out; 6335 } 6336 if (i0 >= 0) { 6337 arg32[i0].in = arg[i0].in; 6338 } 6339 if (i1 >= 0) { 6340 arg32[i1].in = arg[i1].in; 6341 } 6342 if (i2 >= 0) { 6343 arg32[i2].in = arg[i2].in; 6344 } 6345 } 6346 } 6347 6348 static inline void put_f32_o1_i3(const OpcodeArg *arg, const OpcodeArg *arg32, 6349 int o0, int i0, int i1, int i2) 6350 { 6351 if ((i0 >= 0 && arg[i0].num_bits == 64) || 6352 (o0 >= 0 && arg[o0].num_bits == 64)) { 6353 if (o0 >= 0) { 6354 tcg_gen_extu_i32_i64(arg[o0].out, arg32[o0].out); 6355 tcg_temp_free_i32(arg32[o0].out); 6356 } 6357 if (i0 >= 0) { 6358 tcg_temp_free_i32(arg32[i0].in); 6359 } 6360 if (i1 >= 0) { 6361 tcg_temp_free_i32(arg32[i1].in); 6362 } 6363 if (i2 >= 0) { 6364 tcg_temp_free_i32(arg32[i2].in); 6365 } 6366 } 6367 } 6368 6369 static inline void get_f32_o1_i2(const OpcodeArg *arg, OpcodeArg *arg32, 6370 int o0, int i0, int i1) 6371 { 6372 get_f32_o1_i3(arg, arg32, o0, i0, i1, -1); 6373 } 6374 6375 static inline void put_f32_o1_i2(const OpcodeArg *arg, const OpcodeArg *arg32, 6376 int o0, int i0, int i1) 6377 { 6378 put_f32_o1_i3(arg, arg32, o0, i0, i1, -1); 6379 } 6380 6381 static inline void get_f32_o1_i1(const OpcodeArg *arg, OpcodeArg *arg32, 6382 int o0, int i0) 6383 { 6384 get_f32_o1_i2(arg, arg32, o0, i0, -1); 6385 } 6386 6387 static inline void put_f32_o1_i1(const OpcodeArg *arg, const OpcodeArg *arg32, 6388 int o0, int i0) 6389 { 6390 put_f32_o1_i2(arg, arg32, o0, i0, -1); 6391 } 6392 6393 static inline void get_f32_o1(const OpcodeArg *arg, OpcodeArg *arg32, 6394 int o0) 6395 { 6396 get_f32_o1_i1(arg, arg32, o0, -1); 6397 } 6398 6399 static inline void put_f32_o1(const OpcodeArg *arg, const OpcodeArg *arg32, 6400 int o0) 6401 { 6402 put_f32_o1_i1(arg, arg32, o0, -1); 6403 } 6404 6405 static inline void get_f32_i2(const OpcodeArg *arg, OpcodeArg *arg32, 6406 int i0, int i1) 6407 { 6408 get_f32_o1_i2(arg, arg32, -1, i0, i1); 6409 } 6410 6411 static inline void put_f32_i2(const OpcodeArg *arg, const OpcodeArg *arg32, 6412 int i0, int i1) 6413 { 6414 put_f32_o1_i2(arg, arg32, -1, i0, i1); 6415 } 6416 6417 static inline void get_f32_i1(const OpcodeArg *arg, OpcodeArg *arg32, 6418 int i0) 6419 { 6420 get_f32_i2(arg, arg32, i0, -1); 6421 } 6422 6423 static inline void put_f32_i1(const OpcodeArg *arg, const OpcodeArg *arg32, 6424 int i0) 6425 { 6426 put_f32_i2(arg, arg32, i0, -1); 6427 } 6428 6429 6430 static void translate_abs_d(DisasContext *dc, const OpcodeArg arg[], 6431 const uint32_t par[]) 6432 { 6433 gen_helper_abs_d(arg[0].out, arg[1].in); 6434 } 6435 6436 static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[], 6437 const uint32_t par[]) 6438 { 6439 OpcodeArg arg32[2]; 6440 6441 get_f32_o1_i1(arg, arg32, 0, 1); 6442 gen_helper_abs_s(arg32[0].out, arg32[1].in); 6443 put_f32_o1_i1(arg, arg32, 0, 1); 6444 } 6445 6446 static void translate_fpu2k_add_s(DisasContext *dc, const OpcodeArg arg[], 6447 const uint32_t par[]) 6448 { 6449 gen_helper_fpu2k_add_s(arg[0].out, cpu_env, 6450 arg[1].in, arg[2].in); 6451 } 6452 6453 enum { 6454 COMPARE_UN, 6455 COMPARE_OEQ, 6456 COMPARE_UEQ, 6457 COMPARE_OLT, 6458 COMPARE_ULT, 6459 COMPARE_OLE, 6460 COMPARE_ULE, 6461 }; 6462 6463 static void translate_compare_d(DisasContext *dc, const OpcodeArg arg[], 6464 const uint32_t par[]) 6465 { 6466 static void (* const helper[])(TCGv_i32 res, TCGv_env env, 6467 TCGv_i64 s, TCGv_i64 t) = { 6468 [COMPARE_UN] = gen_helper_un_d, 6469 [COMPARE_OEQ] = gen_helper_oeq_d, 6470 [COMPARE_UEQ] = gen_helper_ueq_d, 6471 [COMPARE_OLT] = gen_helper_olt_d, 6472 [COMPARE_ULT] = gen_helper_ult_d, 6473 [COMPARE_OLE] = gen_helper_ole_d, 6474 [COMPARE_ULE] = gen_helper_ule_d, 6475 }; 6476 TCGv_i32 zero = tcg_const_i32(0); 6477 TCGv_i32 res = tcg_temp_new_i32(); 6478 TCGv_i32 set_br = tcg_temp_new_i32(); 6479 TCGv_i32 clr_br = tcg_temp_new_i32(); 6480 6481 tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm); 6482 tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm)); 6483 6484 helper[par[0]](res, cpu_env, arg[1].in, arg[2].in); 6485 tcg_gen_movcond_i32(TCG_COND_NE, 6486 arg[0].out, res, zero, 6487 set_br, clr_br); 6488 tcg_temp_free(zero); 6489 tcg_temp_free(res); 6490 tcg_temp_free(set_br); 6491 tcg_temp_free(clr_br); 6492 } 6493 6494 static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[], 6495 const uint32_t par[]) 6496 { 6497 static void (* const helper[])(TCGv_i32 res, TCGv_env env, 6498 TCGv_i32 s, TCGv_i32 t) = { 6499 [COMPARE_UN] = gen_helper_un_s, 6500 [COMPARE_OEQ] = gen_helper_oeq_s, 6501 [COMPARE_UEQ] = gen_helper_ueq_s, 6502 [COMPARE_OLT] = gen_helper_olt_s, 6503 [COMPARE_ULT] = gen_helper_ult_s, 6504 [COMPARE_OLE] = gen_helper_ole_s, 6505 [COMPARE_ULE] = gen_helper_ule_s, 6506 }; 6507 OpcodeArg arg32[3]; 6508 TCGv_i32 zero = tcg_const_i32(0); 6509 TCGv_i32 res = tcg_temp_new_i32(); 6510 TCGv_i32 set_br = tcg_temp_new_i32(); 6511 TCGv_i32 clr_br = tcg_temp_new_i32(); 6512 6513 tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm); 6514 tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm)); 6515 6516 get_f32_i2(arg, arg32, 1, 2); 6517 helper[par[0]](res, cpu_env, arg32[1].in, arg32[2].in); 6518 tcg_gen_movcond_i32(TCG_COND_NE, 6519 arg[0].out, res, zero, 6520 set_br, clr_br); 6521 put_f32_i2(arg, arg32, 1, 2); 6522 tcg_temp_free(zero); 6523 tcg_temp_free(res); 6524 tcg_temp_free(set_br); 6525 tcg_temp_free(clr_br); 6526 } 6527 6528 static void translate_const_d(DisasContext *dc, const OpcodeArg arg[], 6529 const uint32_t par[]) 6530 { 6531 static const uint64_t v[] = { 6532 UINT64_C(0x0000000000000000), 6533 UINT64_C(0x3ff0000000000000), 6534 UINT64_C(0x4000000000000000), 6535 UINT64_C(0x3fe0000000000000), 6536 }; 6537 6538 tcg_gen_movi_i64(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]); 6539 if (arg[1].imm >= ARRAY_SIZE(v)) { 6540 qemu_log_mask(LOG_GUEST_ERROR, 6541 "const.d f%d, #%d, immediate value is reserved\n", 6542 arg[0].imm, arg[1].imm); 6543 } 6544 } 6545 6546 static void translate_const_s(DisasContext *dc, const OpcodeArg arg[], 6547 const uint32_t par[]) 6548 { 6549 static const uint32_t v[] = { 6550 0x00000000, 6551 0x3f800000, 6552 0x40000000, 6553 0x3f000000, 6554 }; 6555 6556 if (arg[0].num_bits == 32) { 6557 tcg_gen_movi_i32(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]); 6558 } else { 6559 tcg_gen_movi_i64(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]); 6560 } 6561 if (arg[1].imm >= ARRAY_SIZE(v)) { 6562 qemu_log_mask(LOG_GUEST_ERROR, 6563 "const.s f%d, #%d, immediate value is reserved\n", 6564 arg[0].imm, arg[1].imm); 6565 } 6566 } 6567 6568 static void translate_float_d(DisasContext *dc, const OpcodeArg arg[], 6569 const uint32_t par[]) 6570 { 6571 TCGv_i32 scale = tcg_const_i32(-arg[2].imm); 6572 6573 if (par[0]) { 6574 gen_helper_uitof_d(arg[0].out, cpu_env, arg[1].in, scale); 6575 } else { 6576 gen_helper_itof_d(arg[0].out, cpu_env, arg[1].in, scale); 6577 } 6578 tcg_temp_free(scale); 6579 } 6580 6581 static void translate_float_s(DisasContext *dc, const OpcodeArg arg[], 6582 const uint32_t par[]) 6583 { 6584 TCGv_i32 scale = tcg_const_i32(-arg[2].imm); 6585 OpcodeArg arg32[1]; 6586 6587 get_f32_o1(arg, arg32, 0); 6588 if (par[0]) { 6589 gen_helper_uitof_s(arg32[0].out, cpu_env, arg[1].in, scale); 6590 } else { 6591 gen_helper_itof_s(arg32[0].out, cpu_env, arg[1].in, scale); 6592 } 6593 put_f32_o1(arg, arg32, 0); 6594 tcg_temp_free(scale); 6595 } 6596 6597 static void translate_ftoi_d(DisasContext *dc, const OpcodeArg arg[], 6598 const uint32_t par[]) 6599 { 6600 TCGv_i32 rounding_mode = tcg_const_i32(par[0]); 6601 TCGv_i32 scale = tcg_const_i32(arg[2].imm); 6602 6603 if (par[1]) { 6604 gen_helper_ftoui_d(arg[0].out, cpu_env, arg[1].in, 6605 rounding_mode, scale); 6606 } else { 6607 gen_helper_ftoi_d(arg[0].out, cpu_env, arg[1].in, 6608 rounding_mode, scale); 6609 } 6610 tcg_temp_free(rounding_mode); 6611 tcg_temp_free(scale); 6612 } 6613 6614 static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[], 6615 const uint32_t par[]) 6616 { 6617 TCGv_i32 rounding_mode = tcg_const_i32(par[0]); 6618 TCGv_i32 scale = tcg_const_i32(arg[2].imm); 6619 OpcodeArg arg32[2]; 6620 6621 get_f32_i1(arg, arg32, 1); 6622 if (par[1]) { 6623 gen_helper_ftoui_s(arg[0].out, cpu_env, arg32[1].in, 6624 rounding_mode, scale); 6625 } else { 6626 gen_helper_ftoi_s(arg[0].out, cpu_env, arg32[1].in, 6627 rounding_mode, scale); 6628 } 6629 put_f32_i1(arg, arg32, 1); 6630 tcg_temp_free(rounding_mode); 6631 tcg_temp_free(scale); 6632 } 6633 6634 static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[], 6635 const uint32_t par[]) 6636 { 6637 TCGv_i32 addr = tcg_temp_new_i32(); 6638 MemOp mop; 6639 6640 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 6641 mop = gen_load_store_alignment(dc, MO_TEUL, addr); 6642 if (par[0]) { 6643 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop); 6644 } else { 6645 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop); 6646 } 6647 if (par[1]) { 6648 tcg_gen_mov_i32(arg[1].out, addr); 6649 } 6650 tcg_temp_free(addr); 6651 } 6652 6653 static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[], 6654 const uint32_t par[]) 6655 { 6656 TCGv_i32 addr = tcg_temp_new_i32(); 6657 MemOp mop; 6658 6659 tcg_gen_add_i32(addr, arg[1].in, arg[2].in); 6660 mop = gen_load_store_alignment(dc, MO_TEUL, addr); 6661 if (par[0]) { 6662 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop); 6663 } else { 6664 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop); 6665 } 6666 if (par[1]) { 6667 tcg_gen_mov_i32(arg[1].out, addr); 6668 } 6669 tcg_temp_free(addr); 6670 } 6671 6672 static void translate_fpu2k_madd_s(DisasContext *dc, const OpcodeArg arg[], 6673 const uint32_t par[]) 6674 { 6675 gen_helper_fpu2k_madd_s(arg[0].out, cpu_env, 6676 arg[0].in, arg[1].in, arg[2].in); 6677 } 6678 6679 static void translate_mov_d(DisasContext *dc, const OpcodeArg arg[], 6680 const uint32_t par[]) 6681 { 6682 tcg_gen_mov_i64(arg[0].out, arg[1].in); 6683 } 6684 6685 static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[], 6686 const uint32_t par[]) 6687 { 6688 if (arg[0].num_bits == 32) { 6689 tcg_gen_mov_i32(arg[0].out, arg[1].in); 6690 } else { 6691 tcg_gen_mov_i64(arg[0].out, arg[1].in); 6692 } 6693 } 6694 6695 static void translate_movcond_d(DisasContext *dc, const OpcodeArg arg[], 6696 const uint32_t par[]) 6697 { 6698 TCGv_i64 zero = tcg_const_i64(0); 6699 TCGv_i64 arg2 = tcg_temp_new_i64(); 6700 6701 tcg_gen_ext_i32_i64(arg2, arg[2].in); 6702 tcg_gen_movcond_i64(par[0], arg[0].out, 6703 arg2, zero, 6704 arg[1].in, arg[0].in); 6705 tcg_temp_free_i64(zero); 6706 tcg_temp_free_i64(arg2); 6707 } 6708 6709 static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[], 6710 const uint32_t par[]) 6711 { 6712 if (arg[0].num_bits == 32) { 6713 TCGv_i32 zero = tcg_const_i32(0); 6714 6715 tcg_gen_movcond_i32(par[0], arg[0].out, 6716 arg[2].in, zero, 6717 arg[1].in, arg[0].in); 6718 tcg_temp_free(zero); 6719 } else { 6720 translate_movcond_d(dc, arg, par); 6721 } 6722 } 6723 6724 static void translate_movp_d(DisasContext *dc, const OpcodeArg arg[], 6725 const uint32_t par[]) 6726 { 6727 TCGv_i64 zero = tcg_const_i64(0); 6728 TCGv_i32 tmp1 = tcg_temp_new_i32(); 6729 TCGv_i64 tmp2 = tcg_temp_new_i64(); 6730 6731 tcg_gen_andi_i32(tmp1, arg[2].in, 1 << arg[2].imm); 6732 tcg_gen_extu_i32_i64(tmp2, tmp1); 6733 tcg_gen_movcond_i64(par[0], 6734 arg[0].out, tmp2, zero, 6735 arg[1].in, arg[0].in); 6736 tcg_temp_free_i64(zero); 6737 tcg_temp_free_i32(tmp1); 6738 tcg_temp_free_i64(tmp2); 6739 } 6740 6741 static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[], 6742 const uint32_t par[]) 6743 { 6744 if (arg[0].num_bits == 32) { 6745 TCGv_i32 zero = tcg_const_i32(0); 6746 TCGv_i32 tmp = tcg_temp_new_i32(); 6747 6748 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm); 6749 tcg_gen_movcond_i32(par[0], 6750 arg[0].out, tmp, zero, 6751 arg[1].in, arg[0].in); 6752 tcg_temp_free(tmp); 6753 tcg_temp_free(zero); 6754 } else { 6755 translate_movp_d(dc, arg, par); 6756 } 6757 } 6758 6759 static void translate_fpu2k_mul_s(DisasContext *dc, const OpcodeArg arg[], 6760 const uint32_t par[]) 6761 { 6762 gen_helper_fpu2k_mul_s(arg[0].out, cpu_env, 6763 arg[1].in, arg[2].in); 6764 } 6765 6766 static void translate_fpu2k_msub_s(DisasContext *dc, const OpcodeArg arg[], 6767 const uint32_t par[]) 6768 { 6769 gen_helper_fpu2k_msub_s(arg[0].out, cpu_env, 6770 arg[0].in, arg[1].in, arg[2].in); 6771 } 6772 6773 static void translate_neg_d(DisasContext *dc, const OpcodeArg arg[], 6774 const uint32_t par[]) 6775 { 6776 gen_helper_neg_d(arg[0].out, arg[1].in); 6777 } 6778 6779 static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[], 6780 const uint32_t par[]) 6781 { 6782 OpcodeArg arg32[2]; 6783 6784 get_f32_o1_i1(arg, arg32, 0, 1); 6785 gen_helper_neg_s(arg32[0].out, arg32[1].in); 6786 put_f32_o1_i1(arg, arg32, 0, 1); 6787 } 6788 6789 static void translate_rfr_d(DisasContext *dc, const OpcodeArg arg[], 6790 const uint32_t par[]) 6791 { 6792 tcg_gen_extrh_i64_i32(arg[0].out, arg[1].in); 6793 } 6794 6795 static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[], 6796 const uint32_t par[]) 6797 { 6798 if (arg[1].num_bits == 32) { 6799 tcg_gen_mov_i32(arg[0].out, arg[1].in); 6800 } else { 6801 tcg_gen_extrl_i64_i32(arg[0].out, arg[1].in); 6802 } 6803 } 6804 6805 static void translate_fpu2k_sub_s(DisasContext *dc, const OpcodeArg arg[], 6806 const uint32_t par[]) 6807 { 6808 gen_helper_fpu2k_sub_s(arg[0].out, cpu_env, 6809 arg[1].in, arg[2].in); 6810 } 6811 6812 static void translate_wfr_d(DisasContext *dc, const OpcodeArg arg[], 6813 const uint32_t par[]) 6814 { 6815 tcg_gen_concat_i32_i64(arg[0].out, arg[2].in, arg[1].in); 6816 } 6817 6818 static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[], 6819 const uint32_t par[]) 6820 { 6821 if (arg[0].num_bits == 32) { 6822 tcg_gen_mov_i32(arg[0].out, arg[1].in); 6823 } else { 6824 tcg_gen_ext_i32_i64(arg[0].out, arg[1].in); 6825 } 6826 } 6827 6828 static void translate_wur_fpu2k_fcr(DisasContext *dc, const OpcodeArg arg[], 6829 const uint32_t par[]) 6830 { 6831 gen_helper_wur_fpu2k_fcr(cpu_env, arg[0].in); 6832 } 6833 6834 static void translate_wur_fpu2k_fsr(DisasContext *dc, const OpcodeArg arg[], 6835 const uint32_t par[]) 6836 { 6837 tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80); 6838 } 6839 6840 static const XtensaOpcodeOps fpu2000_ops[] = { 6841 { 6842 .name = "abs.s", 6843 .translate = translate_abs_s, 6844 .coprocessor = 0x1, 6845 }, { 6846 .name = "add.s", 6847 .translate = translate_fpu2k_add_s, 6848 .coprocessor = 0x1, 6849 }, { 6850 .name = "ceil.s", 6851 .translate = translate_ftoi_s, 6852 .par = (const uint32_t[]){float_round_up, false}, 6853 .coprocessor = 0x1, 6854 }, { 6855 .name = "float.s", 6856 .translate = translate_float_s, 6857 .par = (const uint32_t[]){false}, 6858 .coprocessor = 0x1, 6859 }, { 6860 .name = "floor.s", 6861 .translate = translate_ftoi_s, 6862 .par = (const uint32_t[]){float_round_down, false}, 6863 .coprocessor = 0x1, 6864 }, { 6865 .name = "lsi", 6866 .translate = translate_ldsti, 6867 .par = (const uint32_t[]){false, false}, 6868 .op_flags = XTENSA_OP_LOAD, 6869 .coprocessor = 0x1, 6870 }, { 6871 .name = "lsiu", 6872 .translate = translate_ldsti, 6873 .par = (const uint32_t[]){false, true}, 6874 .op_flags = XTENSA_OP_LOAD, 6875 .coprocessor = 0x1, 6876 }, { 6877 .name = "lsx", 6878 .translate = translate_ldstx, 6879 .par = (const uint32_t[]){false, false}, 6880 .op_flags = XTENSA_OP_LOAD, 6881 .coprocessor = 0x1, 6882 }, { 6883 .name = "lsxu", 6884 .translate = translate_ldstx, 6885 .par = (const uint32_t[]){false, true}, 6886 .op_flags = XTENSA_OP_LOAD, 6887 .coprocessor = 0x1, 6888 }, { 6889 .name = "madd.s", 6890 .translate = translate_fpu2k_madd_s, 6891 .coprocessor = 0x1, 6892 }, { 6893 .name = "mov.s", 6894 .translate = translate_mov_s, 6895 .coprocessor = 0x1, 6896 }, { 6897 .name = "moveqz.s", 6898 .translate = translate_movcond_s, 6899 .par = (const uint32_t[]){TCG_COND_EQ}, 6900 .coprocessor = 0x1, 6901 }, { 6902 .name = "movf.s", 6903 .translate = translate_movp_s, 6904 .par = (const uint32_t[]){TCG_COND_EQ}, 6905 .coprocessor = 0x1, 6906 }, { 6907 .name = "movgez.s", 6908 .translate = translate_movcond_s, 6909 .par = (const uint32_t[]){TCG_COND_GE}, 6910 .coprocessor = 0x1, 6911 }, { 6912 .name = "movltz.s", 6913 .translate = translate_movcond_s, 6914 .par = (const uint32_t[]){TCG_COND_LT}, 6915 .coprocessor = 0x1, 6916 }, { 6917 .name = "movnez.s", 6918 .translate = translate_movcond_s, 6919 .par = (const uint32_t[]){TCG_COND_NE}, 6920 .coprocessor = 0x1, 6921 }, { 6922 .name = "movt.s", 6923 .translate = translate_movp_s, 6924 .par = (const uint32_t[]){TCG_COND_NE}, 6925 .coprocessor = 0x1, 6926 }, { 6927 .name = "msub.s", 6928 .translate = translate_fpu2k_msub_s, 6929 .coprocessor = 0x1, 6930 }, { 6931 .name = "mul.s", 6932 .translate = translate_fpu2k_mul_s, 6933 .coprocessor = 0x1, 6934 }, { 6935 .name = "neg.s", 6936 .translate = translate_neg_s, 6937 .coprocessor = 0x1, 6938 }, { 6939 .name = "oeq.s", 6940 .translate = translate_compare_s, 6941 .par = (const uint32_t[]){COMPARE_OEQ}, 6942 .coprocessor = 0x1, 6943 }, { 6944 .name = "ole.s", 6945 .translate = translate_compare_s, 6946 .par = (const uint32_t[]){COMPARE_OLE}, 6947 .coprocessor = 0x1, 6948 }, { 6949 .name = "olt.s", 6950 .translate = translate_compare_s, 6951 .par = (const uint32_t[]){COMPARE_OLT}, 6952 .coprocessor = 0x1, 6953 }, { 6954 .name = "rfr", 6955 .translate = translate_rfr_s, 6956 .coprocessor = 0x1, 6957 }, { 6958 .name = "round.s", 6959 .translate = translate_ftoi_s, 6960 .par = (const uint32_t[]){float_round_nearest_even, false}, 6961 .coprocessor = 0x1, 6962 }, { 6963 .name = "rur.fcr", 6964 .translate = translate_rur, 6965 .par = (const uint32_t[]){FCR}, 6966 .coprocessor = 0x1, 6967 }, { 6968 .name = "rur.fsr", 6969 .translate = translate_rur, 6970 .par = (const uint32_t[]){FSR}, 6971 .coprocessor = 0x1, 6972 }, { 6973 .name = "ssi", 6974 .translate = translate_ldsti, 6975 .par = (const uint32_t[]){true, false}, 6976 .op_flags = XTENSA_OP_STORE, 6977 .coprocessor = 0x1, 6978 }, { 6979 .name = "ssiu", 6980 .translate = translate_ldsti, 6981 .par = (const uint32_t[]){true, true}, 6982 .op_flags = XTENSA_OP_STORE, 6983 .coprocessor = 0x1, 6984 }, { 6985 .name = "ssx", 6986 .translate = translate_ldstx, 6987 .par = (const uint32_t[]){true, false}, 6988 .op_flags = XTENSA_OP_STORE, 6989 .coprocessor = 0x1, 6990 }, { 6991 .name = "ssxu", 6992 .translate = translate_ldstx, 6993 .par = (const uint32_t[]){true, true}, 6994 .op_flags = XTENSA_OP_STORE, 6995 .coprocessor = 0x1, 6996 }, { 6997 .name = "sub.s", 6998 .translate = translate_fpu2k_sub_s, 6999 .coprocessor = 0x1, 7000 }, { 7001 .name = "trunc.s", 7002 .translate = translate_ftoi_s, 7003 .par = (const uint32_t[]){float_round_to_zero, false}, 7004 .coprocessor = 0x1, 7005 }, { 7006 .name = "ueq.s", 7007 .translate = translate_compare_s, 7008 .par = (const uint32_t[]){COMPARE_UEQ}, 7009 .coprocessor = 0x1, 7010 }, { 7011 .name = "ufloat.s", 7012 .translate = translate_float_s, 7013 .par = (const uint32_t[]){true}, 7014 .coprocessor = 0x1, 7015 }, { 7016 .name = "ule.s", 7017 .translate = translate_compare_s, 7018 .par = (const uint32_t[]){COMPARE_ULE}, 7019 .coprocessor = 0x1, 7020 }, { 7021 .name = "ult.s", 7022 .translate = translate_compare_s, 7023 .par = (const uint32_t[]){COMPARE_ULT}, 7024 .coprocessor = 0x1, 7025 }, { 7026 .name = "un.s", 7027 .translate = translate_compare_s, 7028 .par = (const uint32_t[]){COMPARE_UN}, 7029 .coprocessor = 0x1, 7030 }, { 7031 .name = "utrunc.s", 7032 .translate = translate_ftoi_s, 7033 .par = (const uint32_t[]){float_round_to_zero, true}, 7034 .coprocessor = 0x1, 7035 }, { 7036 .name = "wfr", 7037 .translate = translate_wfr_s, 7038 .coprocessor = 0x1, 7039 }, { 7040 .name = "wur.fcr", 7041 .translate = translate_wur_fpu2k_fcr, 7042 .par = (const uint32_t[]){FCR}, 7043 .coprocessor = 0x1, 7044 }, { 7045 .name = "wur.fsr", 7046 .translate = translate_wur_fpu2k_fsr, 7047 .par = (const uint32_t[]){FSR}, 7048 .coprocessor = 0x1, 7049 }, 7050 }; 7051 7052 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = { 7053 .num_opcodes = ARRAY_SIZE(fpu2000_ops), 7054 .opcode = fpu2000_ops, 7055 }; 7056 7057 static void translate_add_d(DisasContext *dc, const OpcodeArg arg[], 7058 const uint32_t par[]) 7059 { 7060 gen_helper_add_d(arg[0].out, cpu_env, arg[1].in, arg[2].in); 7061 } 7062 7063 static void translate_add_s(DisasContext *dc, const OpcodeArg arg[], 7064 const uint32_t par[]) 7065 { 7066 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) { 7067 gen_helper_fpu2k_add_s(arg[0].out, cpu_env, 7068 arg[1].in, arg[2].in); 7069 } else { 7070 OpcodeArg arg32[3]; 7071 7072 get_f32_o1_i2(arg, arg32, 0, 1, 2); 7073 gen_helper_add_s(arg32[0].out, cpu_env, arg32[1].in, arg32[2].in); 7074 put_f32_o1_i2(arg, arg32, 0, 1, 2); 7075 } 7076 } 7077 7078 static void translate_cvtd_s(DisasContext *dc, const OpcodeArg arg[], 7079 const uint32_t par[]) 7080 { 7081 TCGv_i32 v = tcg_temp_new_i32(); 7082 7083 tcg_gen_extrl_i64_i32(v, arg[1].in); 7084 gen_helper_cvtd_s(arg[0].out, cpu_env, v); 7085 tcg_temp_free_i32(v); 7086 } 7087 7088 static void translate_cvts_d(DisasContext *dc, const OpcodeArg arg[], 7089 const uint32_t par[]) 7090 { 7091 TCGv_i32 v = tcg_temp_new_i32(); 7092 7093 gen_helper_cvts_d(v, cpu_env, arg[1].in); 7094 tcg_gen_extu_i32_i64(arg[0].out, v); 7095 tcg_temp_free_i32(v); 7096 } 7097 7098 static void translate_ldsti_d(DisasContext *dc, const OpcodeArg arg[], 7099 const uint32_t par[]) 7100 { 7101 TCGv_i32 addr; 7102 MemOp mop; 7103 7104 if (par[1]) { 7105 addr = tcg_temp_new_i32(); 7106 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 7107 } else { 7108 addr = arg[1].in; 7109 } 7110 mop = gen_load_store_alignment(dc, MO_TEQ, addr); 7111 if (par[0]) { 7112 tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop); 7113 } else { 7114 tcg_gen_qemu_ld_i64(arg[0].out, addr, dc->cring, mop); 7115 } 7116 if (par[2]) { 7117 if (par[1]) { 7118 tcg_gen_mov_i32(arg[1].out, addr); 7119 } else { 7120 tcg_gen_addi_i32(arg[1].out, arg[1].in, arg[2].imm); 7121 } 7122 } 7123 if (par[1]) { 7124 tcg_temp_free(addr); 7125 } 7126 } 7127 7128 static void translate_ldsti_s(DisasContext *dc, const OpcodeArg arg[], 7129 const uint32_t par[]) 7130 { 7131 TCGv_i32 addr; 7132 OpcodeArg arg32[1]; 7133 MemOp mop; 7134 7135 if (par[1]) { 7136 addr = tcg_temp_new_i32(); 7137 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 7138 } else { 7139 addr = arg[1].in; 7140 } 7141 mop = gen_load_store_alignment(dc, MO_TEUL, addr); 7142 if (par[0]) { 7143 get_f32_i1(arg, arg32, 0); 7144 tcg_gen_qemu_st_tl(arg32[0].in, addr, dc->cring, mop); 7145 put_f32_i1(arg, arg32, 0); 7146 } else { 7147 get_f32_o1(arg, arg32, 0); 7148 tcg_gen_qemu_ld_tl(arg32[0].out, addr, dc->cring, mop); 7149 put_f32_o1(arg, arg32, 0); 7150 } 7151 if (par[2]) { 7152 if (par[1]) { 7153 tcg_gen_mov_i32(arg[1].out, addr); 7154 } else { 7155 tcg_gen_addi_i32(arg[1].out, arg[1].in, arg[2].imm); 7156 } 7157 } 7158 if (par[1]) { 7159 tcg_temp_free(addr); 7160 } 7161 } 7162 7163 static void translate_ldstx_d(DisasContext *dc, const OpcodeArg arg[], 7164 const uint32_t par[]) 7165 { 7166 TCGv_i32 addr; 7167 MemOp mop; 7168 7169 if (par[1]) { 7170 addr = tcg_temp_new_i32(); 7171 tcg_gen_add_i32(addr, arg[1].in, arg[2].in); 7172 } else { 7173 addr = arg[1].in; 7174 } 7175 mop = gen_load_store_alignment(dc, MO_TEQ, addr); 7176 if (par[0]) { 7177 tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop); 7178 } else { 7179 tcg_gen_qemu_ld_i64(arg[0].out, addr, dc->cring, mop); 7180 } 7181 if (par[2]) { 7182 if (par[1]) { 7183 tcg_gen_mov_i32(arg[1].out, addr); 7184 } else { 7185 tcg_gen_add_i32(arg[1].out, arg[1].in, arg[2].in); 7186 } 7187 } 7188 if (par[1]) { 7189 tcg_temp_free(addr); 7190 } 7191 } 7192 7193 static void translate_ldstx_s(DisasContext *dc, const OpcodeArg arg[], 7194 const uint32_t par[]) 7195 { 7196 TCGv_i32 addr; 7197 OpcodeArg arg32[1]; 7198 MemOp mop; 7199 7200 if (par[1]) { 7201 addr = tcg_temp_new_i32(); 7202 tcg_gen_add_i32(addr, arg[1].in, arg[2].in); 7203 } else { 7204 addr = arg[1].in; 7205 } 7206 mop = gen_load_store_alignment(dc, MO_TEUL, addr); 7207 if (par[0]) { 7208 get_f32_i1(arg, arg32, 0); 7209 tcg_gen_qemu_st_tl(arg32[0].in, addr, dc->cring, mop); 7210 put_f32_i1(arg, arg32, 0); 7211 } else { 7212 get_f32_o1(arg, arg32, 0); 7213 tcg_gen_qemu_ld_tl(arg32[0].out, addr, dc->cring, mop); 7214 put_f32_o1(arg, arg32, 0); 7215 } 7216 if (par[2]) { 7217 if (par[1]) { 7218 tcg_gen_mov_i32(arg[1].out, addr); 7219 } else { 7220 tcg_gen_add_i32(arg[1].out, arg[1].in, arg[2].in); 7221 } 7222 } 7223 if (par[1]) { 7224 tcg_temp_free(addr); 7225 } 7226 } 7227 7228 static void translate_madd_d(DisasContext *dc, const OpcodeArg arg[], 7229 const uint32_t par[]) 7230 { 7231 gen_helper_madd_d(arg[0].out, cpu_env, 7232 arg[0].in, arg[1].in, arg[2].in); 7233 } 7234 7235 static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[], 7236 const uint32_t par[]) 7237 { 7238 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) { 7239 gen_helper_fpu2k_madd_s(arg[0].out, cpu_env, 7240 arg[0].in, arg[1].in, arg[2].in); 7241 } else { 7242 OpcodeArg arg32[3]; 7243 7244 get_f32_o1_i3(arg, arg32, 0, 0, 1, 2); 7245 gen_helper_madd_s(arg32[0].out, cpu_env, 7246 arg32[0].in, arg32[1].in, arg32[2].in); 7247 put_f32_o1_i3(arg, arg32, 0, 0, 1, 2); 7248 } 7249 } 7250 7251 static void translate_mul_d(DisasContext *dc, const OpcodeArg arg[], 7252 const uint32_t par[]) 7253 { 7254 gen_helper_mul_d(arg[0].out, cpu_env, arg[1].in, arg[2].in); 7255 } 7256 7257 static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[], 7258 const uint32_t par[]) 7259 { 7260 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) { 7261 gen_helper_fpu2k_mul_s(arg[0].out, cpu_env, 7262 arg[1].in, arg[2].in); 7263 } else { 7264 OpcodeArg arg32[3]; 7265 7266 get_f32_o1_i2(arg, arg32, 0, 1, 2); 7267 gen_helper_mul_s(arg32[0].out, cpu_env, arg32[1].in, arg32[2].in); 7268 put_f32_o1_i2(arg, arg32, 0, 1, 2); 7269 } 7270 } 7271 7272 static void translate_msub_d(DisasContext *dc, const OpcodeArg arg[], 7273 const uint32_t par[]) 7274 { 7275 gen_helper_msub_d(arg[0].out, cpu_env, 7276 arg[0].in, arg[1].in, arg[2].in); 7277 } 7278 7279 static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[], 7280 const uint32_t par[]) 7281 { 7282 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) { 7283 gen_helper_fpu2k_msub_s(arg[0].out, cpu_env, 7284 arg[0].in, arg[1].in, arg[2].in); 7285 } else { 7286 OpcodeArg arg32[3]; 7287 7288 get_f32_o1_i3(arg, arg32, 0, 0, 1, 2); 7289 gen_helper_msub_s(arg32[0].out, cpu_env, 7290 arg32[0].in, arg32[1].in, arg32[2].in); 7291 put_f32_o1_i3(arg, arg32, 0, 0, 1, 2); 7292 } 7293 } 7294 7295 static void translate_sub_d(DisasContext *dc, const OpcodeArg arg[], 7296 const uint32_t par[]) 7297 { 7298 gen_helper_sub_d(arg[0].out, cpu_env, arg[1].in, arg[2].in); 7299 } 7300 7301 static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[], 7302 const uint32_t par[]) 7303 { 7304 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) { 7305 gen_helper_fpu2k_sub_s(arg[0].out, cpu_env, 7306 arg[1].in, arg[2].in); 7307 } else { 7308 OpcodeArg arg32[3]; 7309 7310 get_f32_o1_i2(arg, arg32, 0, 1, 2); 7311 gen_helper_sub_s(arg32[0].out, cpu_env, arg32[1].in, arg32[2].in); 7312 put_f32_o1_i2(arg, arg32, 0, 1, 2); 7313 } 7314 } 7315 7316 static void translate_mkdadj_d(DisasContext *dc, const OpcodeArg arg[], 7317 const uint32_t par[]) 7318 { 7319 gen_helper_mkdadj_d(arg[0].out, cpu_env, arg[0].in, arg[1].in); 7320 } 7321 7322 static void translate_mkdadj_s(DisasContext *dc, const OpcodeArg arg[], 7323 const uint32_t par[]) 7324 { 7325 OpcodeArg arg32[2]; 7326 7327 get_f32_o1_i2(arg, arg32, 0, 0, 1); 7328 gen_helper_mkdadj_s(arg32[0].out, cpu_env, arg32[0].in, arg32[1].in); 7329 put_f32_o1_i2(arg, arg32, 0, 0, 1); 7330 } 7331 7332 static void translate_mksadj_d(DisasContext *dc, const OpcodeArg arg[], 7333 const uint32_t par[]) 7334 { 7335 gen_helper_mksadj_d(arg[0].out, cpu_env, arg[1].in); 7336 } 7337 7338 static void translate_mksadj_s(DisasContext *dc, const OpcodeArg arg[], 7339 const uint32_t par[]) 7340 { 7341 OpcodeArg arg32[2]; 7342 7343 get_f32_o1_i1(arg, arg32, 0, 1); 7344 gen_helper_mksadj_s(arg32[0].out, cpu_env, arg32[1].in); 7345 put_f32_o1_i1(arg, arg32, 0, 1); 7346 } 7347 7348 static void translate_wur_fpu_fcr(DisasContext *dc, const OpcodeArg arg[], 7349 const uint32_t par[]) 7350 { 7351 gen_helper_wur_fpu_fcr(cpu_env, arg[0].in); 7352 } 7353 7354 static void translate_rur_fpu_fsr(DisasContext *dc, const OpcodeArg arg[], 7355 const uint32_t par[]) 7356 { 7357 gen_helper_rur_fpu_fsr(arg[0].out, cpu_env); 7358 } 7359 7360 static void translate_wur_fpu_fsr(DisasContext *dc, const OpcodeArg arg[], 7361 const uint32_t par[]) 7362 { 7363 gen_helper_wur_fpu_fsr(cpu_env, arg[0].in); 7364 } 7365 7366 static const XtensaOpcodeOps fpu_ops[] = { 7367 { 7368 .name = "abs.d", 7369 .translate = translate_abs_d, 7370 .coprocessor = 0x1, 7371 }, { 7372 .name = "abs.s", 7373 .translate = translate_abs_s, 7374 .coprocessor = 0x1, 7375 }, { 7376 .name = "add.d", 7377 .translate = translate_add_d, 7378 .coprocessor = 0x1, 7379 }, { 7380 .name = "add.s", 7381 .translate = translate_add_s, 7382 .coprocessor = 0x1, 7383 }, { 7384 .name = "addexp.d", 7385 .translate = translate_nop, 7386 .coprocessor = 0x1, 7387 }, { 7388 .name = "addexp.s", 7389 .translate = translate_nop, 7390 .coprocessor = 0x1, 7391 }, { 7392 .name = "addexpm.d", 7393 .translate = translate_mov_s, 7394 .coprocessor = 0x1, 7395 }, { 7396 .name = "addexpm.s", 7397 .translate = translate_mov_s, 7398 .coprocessor = 0x1, 7399 }, { 7400 .name = "ceil.d", 7401 .translate = translate_ftoi_d, 7402 .par = (const uint32_t[]){float_round_up, false}, 7403 .coprocessor = 0x1, 7404 }, { 7405 .name = "ceil.s", 7406 .translate = translate_ftoi_s, 7407 .par = (const uint32_t[]){float_round_up, false}, 7408 .coprocessor = 0x1, 7409 }, { 7410 .name = "const.d", 7411 .translate = translate_const_d, 7412 .coprocessor = 0x1, 7413 }, { 7414 .name = "const.s", 7415 .translate = translate_const_s, 7416 .coprocessor = 0x1, 7417 }, { 7418 .name = "cvtd.s", 7419 .translate = translate_cvtd_s, 7420 .coprocessor = 0x1, 7421 }, { 7422 .name = "cvts.d", 7423 .translate = translate_cvts_d, 7424 .coprocessor = 0x1, 7425 }, { 7426 .name = "div0.d", 7427 .translate = translate_nop, 7428 .coprocessor = 0x1, 7429 }, { 7430 .name = "div0.s", 7431 .translate = translate_nop, 7432 .coprocessor = 0x1, 7433 }, { 7434 .name = "divn.d", 7435 .translate = translate_nop, 7436 .coprocessor = 0x1, 7437 }, { 7438 .name = "divn.s", 7439 .translate = translate_nop, 7440 .coprocessor = 0x1, 7441 }, { 7442 .name = "float.d", 7443 .translate = translate_float_d, 7444 .par = (const uint32_t[]){false}, 7445 .coprocessor = 0x1, 7446 }, { 7447 .name = "float.s", 7448 .translate = translate_float_s, 7449 .par = (const uint32_t[]){false}, 7450 .coprocessor = 0x1, 7451 }, { 7452 .name = "floor.d", 7453 .translate = translate_ftoi_d, 7454 .par = (const uint32_t[]){float_round_down, false}, 7455 .coprocessor = 0x1, 7456 }, { 7457 .name = "floor.s", 7458 .translate = translate_ftoi_s, 7459 .par = (const uint32_t[]){float_round_down, false}, 7460 .coprocessor = 0x1, 7461 }, { 7462 .name = "ldi", 7463 .translate = translate_ldsti_d, 7464 .par = (const uint32_t[]){false, true, false}, 7465 .op_flags = XTENSA_OP_LOAD, 7466 .coprocessor = 0x1, 7467 }, { 7468 .name = "ldip", 7469 .translate = translate_ldsti_d, 7470 .par = (const uint32_t[]){false, false, true}, 7471 .op_flags = XTENSA_OP_LOAD, 7472 .coprocessor = 0x1, 7473 }, { 7474 .name = "ldiu", 7475 .translate = translate_ldsti_d, 7476 .par = (const uint32_t[]){false, true, true}, 7477 .op_flags = XTENSA_OP_LOAD, 7478 .coprocessor = 0x1, 7479 }, { 7480 .name = "ldx", 7481 .translate = translate_ldstx_d, 7482 .par = (const uint32_t[]){false, true, false}, 7483 .op_flags = XTENSA_OP_LOAD, 7484 .coprocessor = 0x1, 7485 }, { 7486 .name = "ldxp", 7487 .translate = translate_ldstx_d, 7488 .par = (const uint32_t[]){false, false, true}, 7489 .op_flags = XTENSA_OP_LOAD, 7490 .coprocessor = 0x1, 7491 }, { 7492 .name = "ldxu", 7493 .translate = translate_ldstx_d, 7494 .par = (const uint32_t[]){false, true, true}, 7495 .op_flags = XTENSA_OP_LOAD, 7496 .coprocessor = 0x1, 7497 }, { 7498 .name = "lsi", 7499 .translate = translate_ldsti_s, 7500 .par = (const uint32_t[]){false, true, false}, 7501 .op_flags = XTENSA_OP_LOAD, 7502 .coprocessor = 0x1, 7503 }, { 7504 .name = "lsip", 7505 .translate = translate_ldsti_s, 7506 .par = (const uint32_t[]){false, false, true}, 7507 .op_flags = XTENSA_OP_LOAD, 7508 .coprocessor = 0x1, 7509 }, { 7510 .name = "lsiu", 7511 .translate = translate_ldsti_s, 7512 .par = (const uint32_t[]){false, true, true}, 7513 .op_flags = XTENSA_OP_LOAD, 7514 .coprocessor = 0x1, 7515 }, { 7516 .name = "lsx", 7517 .translate = translate_ldstx_s, 7518 .par = (const uint32_t[]){false, true, false}, 7519 .op_flags = XTENSA_OP_LOAD, 7520 .coprocessor = 0x1, 7521 }, { 7522 .name = "lsxp", 7523 .translate = translate_ldstx_s, 7524 .par = (const uint32_t[]){false, false, true}, 7525 .op_flags = XTENSA_OP_LOAD, 7526 .coprocessor = 0x1, 7527 }, { 7528 .name = "lsxu", 7529 .translate = translate_ldstx_s, 7530 .par = (const uint32_t[]){false, true, true}, 7531 .op_flags = XTENSA_OP_LOAD, 7532 .coprocessor = 0x1, 7533 }, { 7534 .name = "madd.d", 7535 .translate = translate_madd_d, 7536 .coprocessor = 0x1, 7537 }, { 7538 .name = "madd.s", 7539 .translate = translate_madd_s, 7540 .coprocessor = 0x1, 7541 }, { 7542 .name = "maddn.d", 7543 .translate = translate_nop, 7544 .coprocessor = 0x1, 7545 }, { 7546 .name = "maddn.s", 7547 .translate = translate_nop, 7548 .coprocessor = 0x1, 7549 }, { 7550 .name = "mkdadj.d", 7551 .translate = translate_mkdadj_d, 7552 .coprocessor = 0x1, 7553 }, { 7554 .name = "mkdadj.s", 7555 .translate = translate_mkdadj_s, 7556 .coprocessor = 0x1, 7557 }, { 7558 .name = "mksadj.d", 7559 .translate = translate_mksadj_d, 7560 .coprocessor = 0x1, 7561 }, { 7562 .name = "mksadj.s", 7563 .translate = translate_mksadj_s, 7564 .coprocessor = 0x1, 7565 }, { 7566 .name = "mov.d", 7567 .translate = translate_mov_d, 7568 .coprocessor = 0x1, 7569 }, { 7570 .name = "mov.s", 7571 .translate = translate_mov_s, 7572 .coprocessor = 0x1, 7573 }, { 7574 .name = "moveqz.d", 7575 .translate = translate_movcond_d, 7576 .par = (const uint32_t[]){TCG_COND_EQ}, 7577 .coprocessor = 0x1, 7578 }, { 7579 .name = "moveqz.s", 7580 .translate = translate_movcond_s, 7581 .par = (const uint32_t[]){TCG_COND_EQ}, 7582 .coprocessor = 0x1, 7583 }, { 7584 .name = "movf.d", 7585 .translate = translate_movp_d, 7586 .par = (const uint32_t[]){TCG_COND_EQ}, 7587 .coprocessor = 0x1, 7588 }, { 7589 .name = "movf.s", 7590 .translate = translate_movp_s, 7591 .par = (const uint32_t[]){TCG_COND_EQ}, 7592 .coprocessor = 0x1, 7593 }, { 7594 .name = "movgez.d", 7595 .translate = translate_movcond_d, 7596 .par = (const uint32_t[]){TCG_COND_GE}, 7597 .coprocessor = 0x1, 7598 }, { 7599 .name = "movgez.s", 7600 .translate = translate_movcond_s, 7601 .par = (const uint32_t[]){TCG_COND_GE}, 7602 .coprocessor = 0x1, 7603 }, { 7604 .name = "movltz.d", 7605 .translate = translate_movcond_d, 7606 .par = (const uint32_t[]){TCG_COND_LT}, 7607 .coprocessor = 0x1, 7608 }, { 7609 .name = "movltz.s", 7610 .translate = translate_movcond_s, 7611 .par = (const uint32_t[]){TCG_COND_LT}, 7612 .coprocessor = 0x1, 7613 }, { 7614 .name = "movnez.d", 7615 .translate = translate_movcond_d, 7616 .par = (const uint32_t[]){TCG_COND_NE}, 7617 .coprocessor = 0x1, 7618 }, { 7619 .name = "movnez.s", 7620 .translate = translate_movcond_s, 7621 .par = (const uint32_t[]){TCG_COND_NE}, 7622 .coprocessor = 0x1, 7623 }, { 7624 .name = "movt.d", 7625 .translate = translate_movp_d, 7626 .par = (const uint32_t[]){TCG_COND_NE}, 7627 .coprocessor = 0x1, 7628 }, { 7629 .name = "movt.s", 7630 .translate = translate_movp_s, 7631 .par = (const uint32_t[]){TCG_COND_NE}, 7632 .coprocessor = 0x1, 7633 }, { 7634 .name = "msub.d", 7635 .translate = translate_msub_d, 7636 .coprocessor = 0x1, 7637 }, { 7638 .name = "msub.s", 7639 .translate = translate_msub_s, 7640 .coprocessor = 0x1, 7641 }, { 7642 .name = "mul.d", 7643 .translate = translate_mul_d, 7644 .coprocessor = 0x1, 7645 }, { 7646 .name = "mul.s", 7647 .translate = translate_mul_s, 7648 .coprocessor = 0x1, 7649 }, { 7650 .name = "neg.d", 7651 .translate = translate_neg_d, 7652 .coprocessor = 0x1, 7653 }, { 7654 .name = "neg.s", 7655 .translate = translate_neg_s, 7656 .coprocessor = 0x1, 7657 }, { 7658 .name = "nexp01.d", 7659 .translate = translate_nop, 7660 .coprocessor = 0x1, 7661 }, { 7662 .name = "nexp01.s", 7663 .translate = translate_nop, 7664 .coprocessor = 0x1, 7665 }, { 7666 .name = "oeq.d", 7667 .translate = translate_compare_d, 7668 .par = (const uint32_t[]){COMPARE_OEQ}, 7669 .coprocessor = 0x1, 7670 }, { 7671 .name = "oeq.s", 7672 .translate = translate_compare_s, 7673 .par = (const uint32_t[]){COMPARE_OEQ}, 7674 .coprocessor = 0x1, 7675 }, { 7676 .name = "ole.d", 7677 .translate = translate_compare_d, 7678 .par = (const uint32_t[]){COMPARE_OLE}, 7679 .coprocessor = 0x1, 7680 }, { 7681 .name = "ole.s", 7682 .translate = translate_compare_s, 7683 .par = (const uint32_t[]){COMPARE_OLE}, 7684 .coprocessor = 0x1, 7685 }, { 7686 .name = "olt.d", 7687 .translate = translate_compare_d, 7688 .par = (const uint32_t[]){COMPARE_OLT}, 7689 .coprocessor = 0x1, 7690 }, { 7691 .name = "olt.s", 7692 .translate = translate_compare_s, 7693 .par = (const uint32_t[]){COMPARE_OLT}, 7694 .coprocessor = 0x1, 7695 }, { 7696 .name = "rfr", 7697 .translate = translate_rfr_s, 7698 .coprocessor = 0x1, 7699 }, { 7700 .name = "rfrd", 7701 .translate = translate_rfr_d, 7702 .coprocessor = 0x1, 7703 }, { 7704 .name = "round.d", 7705 .translate = translate_ftoi_d, 7706 .par = (const uint32_t[]){float_round_nearest_even, false}, 7707 .coprocessor = 0x1, 7708 }, { 7709 .name = "round.s", 7710 .translate = translate_ftoi_s, 7711 .par = (const uint32_t[]){float_round_nearest_even, false}, 7712 .coprocessor = 0x1, 7713 }, { 7714 .name = "rur.fcr", 7715 .translate = translate_rur, 7716 .par = (const uint32_t[]){FCR}, 7717 .coprocessor = 0x1, 7718 }, { 7719 .name = "rur.fsr", 7720 .translate = translate_rur_fpu_fsr, 7721 .coprocessor = 0x1, 7722 }, { 7723 .name = "sdi", 7724 .translate = translate_ldsti_d, 7725 .par = (const uint32_t[]){true, true, false}, 7726 .op_flags = XTENSA_OP_STORE, 7727 .coprocessor = 0x1, 7728 }, { 7729 .name = "sdip", 7730 .translate = translate_ldsti_d, 7731 .par = (const uint32_t[]){true, false, true}, 7732 .op_flags = XTENSA_OP_STORE, 7733 .coprocessor = 0x1, 7734 }, { 7735 .name = "sdiu", 7736 .translate = translate_ldsti_d, 7737 .par = (const uint32_t[]){true, true, true}, 7738 .op_flags = XTENSA_OP_STORE, 7739 .coprocessor = 0x1, 7740 }, { 7741 .name = "sdx", 7742 .translate = translate_ldstx_d, 7743 .par = (const uint32_t[]){true, true, false}, 7744 .op_flags = XTENSA_OP_STORE, 7745 .coprocessor = 0x1, 7746 }, { 7747 .name = "sdxp", 7748 .translate = translate_ldstx_d, 7749 .par = (const uint32_t[]){true, false, true}, 7750 .op_flags = XTENSA_OP_STORE, 7751 .coprocessor = 0x1, 7752 }, { 7753 .name = "sdxu", 7754 .translate = translate_ldstx_d, 7755 .par = (const uint32_t[]){true, true, true}, 7756 .op_flags = XTENSA_OP_STORE, 7757 .coprocessor = 0x1, 7758 }, { 7759 .name = "sqrt0.d", 7760 .translate = translate_nop, 7761 .coprocessor = 0x1, 7762 }, { 7763 .name = "sqrt0.s", 7764 .translate = translate_nop, 7765 .coprocessor = 0x1, 7766 }, { 7767 .name = "ssi", 7768 .translate = translate_ldsti_s, 7769 .par = (const uint32_t[]){true, true, false}, 7770 .op_flags = XTENSA_OP_STORE, 7771 .coprocessor = 0x1, 7772 }, { 7773 .name = "ssip", 7774 .translate = translate_ldsti_s, 7775 .par = (const uint32_t[]){true, false, true}, 7776 .op_flags = XTENSA_OP_STORE, 7777 .coprocessor = 0x1, 7778 }, { 7779 .name = "ssiu", 7780 .translate = translate_ldsti_s, 7781 .par = (const uint32_t[]){true, true, true}, 7782 .op_flags = XTENSA_OP_STORE, 7783 .coprocessor = 0x1, 7784 }, { 7785 .name = "ssx", 7786 .translate = translate_ldstx_s, 7787 .par = (const uint32_t[]){true, true, false}, 7788 .op_flags = XTENSA_OP_STORE, 7789 .coprocessor = 0x1, 7790 }, { 7791 .name = "ssxp", 7792 .translate = translate_ldstx_s, 7793 .par = (const uint32_t[]){true, false, true}, 7794 .op_flags = XTENSA_OP_STORE, 7795 .coprocessor = 0x1, 7796 }, { 7797 .name = "ssxu", 7798 .translate = translate_ldstx_s, 7799 .par = (const uint32_t[]){true, true, true}, 7800 .op_flags = XTENSA_OP_STORE, 7801 .coprocessor = 0x1, 7802 }, { 7803 .name = "sub.d", 7804 .translate = translate_sub_d, 7805 .coprocessor = 0x1, 7806 }, { 7807 .name = "sub.s", 7808 .translate = translate_sub_s, 7809 .coprocessor = 0x1, 7810 }, { 7811 .name = "trunc.d", 7812 .translate = translate_ftoi_d, 7813 .par = (const uint32_t[]){float_round_to_zero, false}, 7814 .coprocessor = 0x1, 7815 }, { 7816 .name = "trunc.s", 7817 .translate = translate_ftoi_s, 7818 .par = (const uint32_t[]){float_round_to_zero, false}, 7819 .coprocessor = 0x1, 7820 }, { 7821 .name = "ueq.d", 7822 .translate = translate_compare_d, 7823 .par = (const uint32_t[]){COMPARE_UEQ}, 7824 .coprocessor = 0x1, 7825 }, { 7826 .name = "ueq.s", 7827 .translate = translate_compare_s, 7828 .par = (const uint32_t[]){COMPARE_UEQ}, 7829 .coprocessor = 0x1, 7830 }, { 7831 .name = "ufloat.d", 7832 .translate = translate_float_d, 7833 .par = (const uint32_t[]){true}, 7834 .coprocessor = 0x1, 7835 }, { 7836 .name = "ufloat.s", 7837 .translate = translate_float_s, 7838 .par = (const uint32_t[]){true}, 7839 .coprocessor = 0x1, 7840 }, { 7841 .name = "ule.d", 7842 .translate = translate_compare_d, 7843 .par = (const uint32_t[]){COMPARE_ULE}, 7844 .coprocessor = 0x1, 7845 }, { 7846 .name = "ule.s", 7847 .translate = translate_compare_s, 7848 .par = (const uint32_t[]){COMPARE_ULE}, 7849 .coprocessor = 0x1, 7850 }, { 7851 .name = "ult.d", 7852 .translate = translate_compare_d, 7853 .par = (const uint32_t[]){COMPARE_ULT}, 7854 .coprocessor = 0x1, 7855 }, { 7856 .name = "ult.s", 7857 .translate = translate_compare_s, 7858 .par = (const uint32_t[]){COMPARE_ULT}, 7859 .coprocessor = 0x1, 7860 }, { 7861 .name = "un.d", 7862 .translate = translate_compare_d, 7863 .par = (const uint32_t[]){COMPARE_UN}, 7864 .coprocessor = 0x1, 7865 }, { 7866 .name = "un.s", 7867 .translate = translate_compare_s, 7868 .par = (const uint32_t[]){COMPARE_UN}, 7869 .coprocessor = 0x1, 7870 }, { 7871 .name = "utrunc.d", 7872 .translate = translate_ftoi_d, 7873 .par = (const uint32_t[]){float_round_to_zero, true}, 7874 .coprocessor = 0x1, 7875 }, { 7876 .name = "utrunc.s", 7877 .translate = translate_ftoi_s, 7878 .par = (const uint32_t[]){float_round_to_zero, true}, 7879 .coprocessor = 0x1, 7880 }, { 7881 .name = "wfr", 7882 .translate = translate_wfr_s, 7883 .coprocessor = 0x1, 7884 }, { 7885 .name = "wfrd", 7886 .translate = translate_wfr_d, 7887 .coprocessor = 0x1, 7888 }, { 7889 .name = "wur.fcr", 7890 .translate = translate_wur_fpu_fcr, 7891 .par = (const uint32_t[]){FCR}, 7892 .coprocessor = 0x1, 7893 }, { 7894 .name = "wur.fsr", 7895 .translate = translate_wur_fpu_fsr, 7896 .coprocessor = 0x1, 7897 }, 7898 }; 7899 7900 const XtensaOpcodeTranslators xtensa_fpu_opcodes = { 7901 .num_opcodes = ARRAY_SIZE(fpu_ops), 7902 .opcode = fpu_ops, 7903 }; 7904