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