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