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