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