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