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