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