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