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