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