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