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