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