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