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