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