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