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