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