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-op.h" 37 #include "qemu/log.h" 38 #include "qemu/qemu-print.h" 39 #include "sysemu/sysemu.h" 40 #include "exec/cpu_ldst.h" 41 #include "exec/semihost.h" 42 #include "exec/translator.h" 43 44 #include "exec/helper-proto.h" 45 #include "exec/helper-gen.h" 46 47 #include "trace-tcg.h" 48 #include "exec/log.h" 49 50 51 struct DisasContext { 52 DisasContextBase base; 53 const XtensaConfig *config; 54 uint32_t pc; 55 int cring; 56 int ring; 57 uint32_t lbeg_off; 58 uint32_t lend; 59 60 bool sar_5bit; 61 bool sar_m32_5bit; 62 bool sar_m32_allocated; 63 TCGv_i32 sar_m32; 64 65 unsigned window; 66 unsigned callinc; 67 bool cwoe; 68 69 bool debug; 70 bool icount; 71 TCGv_i32 next_icount; 72 73 unsigned cpenable; 74 75 uint32_t op_flags; 76 xtensa_insnbuf insnbuf; 77 xtensa_insnbuf slotbuf; 78 }; 79 80 static TCGv_i32 cpu_pc; 81 static TCGv_i32 cpu_R[16]; 82 static TCGv_i32 cpu_FR[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 91 static GHashTable *xtensa_regfile_table; 92 93 #include "exec/gen-icount.h" 94 95 typedef struct XtensaReg { 96 const char *name; 97 uint64_t opt_bits; 98 enum { 99 SR_R = 1, 100 SR_W = 2, 101 SR_X = 4, 102 SR_RW = 3, 103 SR_RWX = 7, 104 } access; 105 } XtensaReg; 106 107 #define XTENSA_REG_ACCESS(regname, opt, acc) { \ 108 .name = (regname), \ 109 .opt_bits = XTENSA_OPTION_BIT(opt), \ 110 .access = (acc), \ 111 } 112 113 #define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX) 114 115 #define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \ 116 .name = (regname), \ 117 .opt_bits = (opt), \ 118 .access = (acc), \ 119 } 120 121 #define XTENSA_REG_BITS(regname, opt) \ 122 XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX) 123 124 static const XtensaReg sregnames[256] = { 125 [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP), 126 [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP), 127 [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP), 128 [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL), 129 [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN), 130 [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R), 131 [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE), 132 [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16), 133 [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16), 134 [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16), 135 [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16), 136 [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16), 137 [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16), 138 [PREFCTL] = XTENSA_REG_BITS("PREFCTL", XTENSA_OPTION_ALL), 139 [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER), 140 [WINDOW_START] = XTENSA_REG("WINDOW_START", 141 XTENSA_OPTION_WINDOWED_REGISTER), 142 [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU), 143 [MMID] = XTENSA_REG_BITS("MMID", XTENSA_OPTION_ALL), 144 [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU), 145 [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU), 146 [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU), 147 [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG), 148 [MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL), 149 [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR), 150 [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL), 151 [DDR] = XTENSA_REG("DDR", XTENSA_OPTION_DEBUG), 152 [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG), 153 [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG), 154 [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG), 155 [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG), 156 [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG), 157 [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG), 158 [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R), 159 [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION), 160 [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 161 [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 162 [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 163 [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 164 [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 165 [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 166 [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION), 167 [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 168 [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 169 [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 170 [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 171 [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 172 [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 173 [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R), 174 [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION), 175 [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2", 176 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 177 [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3", 178 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 179 [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4", 180 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 181 [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5", 182 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 183 [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6", 184 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 185 [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7", 186 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 187 [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR), 188 [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW), 189 [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W), 190 [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT), 191 [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL), 192 [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR), 193 [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION), 194 [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R), 195 [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT), 196 [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R), 197 [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG), 198 [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG), 199 [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION), 200 [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT), 201 [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1", 202 XTENSA_OPTION_TIMER_INTERRUPT), 203 [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2", 204 XTENSA_OPTION_TIMER_INTERRUPT), 205 [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR), 206 [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR), 207 [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR), 208 [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR), 209 }; 210 211 static const XtensaReg uregnames[256] = { 212 [EXPSTATE] = XTENSA_REG_BITS("EXPSTATE", XTENSA_OPTION_ALL), 213 [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER), 214 [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR), 215 [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR), 216 }; 217 218 void xtensa_translate_init(void) 219 { 220 static const char * const regnames[] = { 221 "ar0", "ar1", "ar2", "ar3", 222 "ar4", "ar5", "ar6", "ar7", 223 "ar8", "ar9", "ar10", "ar11", 224 "ar12", "ar13", "ar14", "ar15", 225 }; 226 static const char * const fregnames[] = { 227 "f0", "f1", "f2", "f3", 228 "f4", "f5", "f6", "f7", 229 "f8", "f9", "f10", "f11", 230 "f12", "f13", "f14", "f15", 231 }; 232 static const char * const mregnames[] = { 233 "m0", "m1", "m2", "m3", 234 }; 235 static const char * const bregnames[] = { 236 "b0", "b1", "b2", "b3", 237 "b4", "b5", "b6", "b7", 238 "b8", "b9", "b10", "b11", 239 "b12", "b13", "b14", "b15", 240 }; 241 int i; 242 243 cpu_pc = tcg_global_mem_new_i32(cpu_env, 244 offsetof(CPUXtensaState, pc), "pc"); 245 246 for (i = 0; i < 16; i++) { 247 cpu_R[i] = tcg_global_mem_new_i32(cpu_env, 248 offsetof(CPUXtensaState, regs[i]), 249 regnames[i]); 250 } 251 252 for (i = 0; i < 16; i++) { 253 cpu_FR[i] = tcg_global_mem_new_i32(cpu_env, 254 offsetof(CPUXtensaState, 255 fregs[i].f32[FP_F32_LOW]), 256 fregnames[i]); 257 } 258 259 for (i = 0; i < 4; i++) { 260 cpu_MR[i] = tcg_global_mem_new_i32(cpu_env, 261 offsetof(CPUXtensaState, 262 sregs[MR + i]), 263 mregnames[i]); 264 } 265 266 for (i = 0; i < 16; i++) { 267 cpu_BR[i] = tcg_global_mem_new_i32(cpu_env, 268 offsetof(CPUXtensaState, 269 sregs[BR]), 270 bregnames[i]); 271 if (i % 4 == 0) { 272 cpu_BR4[i / 4] = tcg_global_mem_new_i32(cpu_env, 273 offsetof(CPUXtensaState, 274 sregs[BR]), 275 bregnames[i]); 276 } 277 if (i % 8 == 0) { 278 cpu_BR8[i / 8] = tcg_global_mem_new_i32(cpu_env, 279 offsetof(CPUXtensaState, 280 sregs[BR]), 281 bregnames[i]); 282 } 283 } 284 285 for (i = 0; i < 256; ++i) { 286 if (sregnames[i].name) { 287 cpu_SR[i] = tcg_global_mem_new_i32(cpu_env, 288 offsetof(CPUXtensaState, sregs[i]), 289 sregnames[i].name); 290 } 291 } 292 293 for (i = 0; i < 256; ++i) { 294 if (uregnames[i].name) { 295 cpu_UR[i] = tcg_global_mem_new_i32(cpu_env, 296 offsetof(CPUXtensaState, uregs[i]), 297 uregnames[i].name); 298 } 299 } 300 301 cpu_windowbase_next = 302 tcg_global_mem_new_i32(cpu_env, 303 offsetof(CPUXtensaState, windowbase_next), 304 "windowbase_next"); 305 } 306 307 void **xtensa_get_regfile_by_name(const char *name) 308 { 309 if (xtensa_regfile_table == NULL) { 310 xtensa_regfile_table = g_hash_table_new(g_str_hash, g_str_equal); 311 g_hash_table_insert(xtensa_regfile_table, 312 (void *)"AR", (void *)cpu_R); 313 g_hash_table_insert(xtensa_regfile_table, 314 (void *)"MR", (void *)cpu_MR); 315 g_hash_table_insert(xtensa_regfile_table, 316 (void *)"FR", (void *)cpu_FR); 317 g_hash_table_insert(xtensa_regfile_table, 318 (void *)"BR", (void *)cpu_BR); 319 g_hash_table_insert(xtensa_regfile_table, 320 (void *)"BR4", (void *)cpu_BR4); 321 g_hash_table_insert(xtensa_regfile_table, 322 (void *)"BR8", (void *)cpu_BR8); 323 } 324 return (void **)g_hash_table_lookup(xtensa_regfile_table, (void *)name); 325 } 326 327 static inline bool option_enabled(DisasContext *dc, int opt) 328 { 329 return xtensa_option_enabled(dc->config, opt); 330 } 331 332 static void init_sar_tracker(DisasContext *dc) 333 { 334 dc->sar_5bit = false; 335 dc->sar_m32_5bit = false; 336 dc->sar_m32_allocated = false; 337 } 338 339 static void reset_sar_tracker(DisasContext *dc) 340 { 341 if (dc->sar_m32_allocated) { 342 tcg_temp_free(dc->sar_m32); 343 } 344 } 345 346 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa) 347 { 348 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f); 349 if (dc->sar_m32_5bit) { 350 tcg_gen_discard_i32(dc->sar_m32); 351 } 352 dc->sar_5bit = true; 353 dc->sar_m32_5bit = false; 354 } 355 356 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa) 357 { 358 TCGv_i32 tmp = tcg_const_i32(32); 359 if (!dc->sar_m32_allocated) { 360 dc->sar_m32 = tcg_temp_local_new_i32(); 361 dc->sar_m32_allocated = true; 362 } 363 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f); 364 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32); 365 dc->sar_5bit = false; 366 dc->sar_m32_5bit = true; 367 tcg_temp_free(tmp); 368 } 369 370 static void gen_exception(DisasContext *dc, int excp) 371 { 372 TCGv_i32 tmp = tcg_const_i32(excp); 373 gen_helper_exception(cpu_env, tmp); 374 tcg_temp_free(tmp); 375 } 376 377 static void gen_exception_cause(DisasContext *dc, uint32_t cause) 378 { 379 TCGv_i32 tpc = tcg_const_i32(dc->pc); 380 TCGv_i32 tcause = tcg_const_i32(cause); 381 gen_helper_exception_cause(cpu_env, tpc, tcause); 382 tcg_temp_free(tpc); 383 tcg_temp_free(tcause); 384 if (cause == ILLEGAL_INSTRUCTION_CAUSE || 385 cause == SYSCALL_CAUSE) { 386 dc->base.is_jmp = DISAS_NORETURN; 387 } 388 } 389 390 static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause, 391 TCGv_i32 vaddr) 392 { 393 TCGv_i32 tpc = tcg_const_i32(dc->pc); 394 TCGv_i32 tcause = tcg_const_i32(cause); 395 gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr); 396 tcg_temp_free(tpc); 397 tcg_temp_free(tcause); 398 } 399 400 static void gen_debug_exception(DisasContext *dc, uint32_t cause) 401 { 402 TCGv_i32 tpc = tcg_const_i32(dc->pc); 403 TCGv_i32 tcause = tcg_const_i32(cause); 404 gen_helper_debug_exception(cpu_env, tpc, tcause); 405 tcg_temp_free(tpc); 406 tcg_temp_free(tcause); 407 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) { 408 dc->base.is_jmp = DISAS_NORETURN; 409 } 410 } 411 412 static bool gen_check_privilege(DisasContext *dc) 413 { 414 #ifndef CONFIG_USER_ONLY 415 if (!dc->cring) { 416 return true; 417 } 418 #endif 419 gen_exception_cause(dc, PRIVILEGED_CAUSE); 420 dc->base.is_jmp = DISAS_NORETURN; 421 return false; 422 } 423 424 static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask) 425 { 426 cp_mask &= ~dc->cpenable; 427 428 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) && cp_mask) { 429 gen_exception_cause(dc, COPROCESSOR0_DISABLED + ctz32(cp_mask)); 430 dc->base.is_jmp = DISAS_NORETURN; 431 return false; 432 } 433 return true; 434 } 435 436 static int gen_postprocess(DisasContext *dc, int slot); 437 438 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) 439 { 440 tcg_gen_mov_i32(cpu_pc, dest); 441 if (dc->icount) { 442 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); 443 } 444 if (dc->base.singlestep_enabled) { 445 gen_exception(dc, EXCP_DEBUG); 446 } else { 447 if (dc->op_flags & XTENSA_OP_POSTPROCESS) { 448 slot = gen_postprocess(dc, slot); 449 } 450 if (slot >= 0) { 451 tcg_gen_goto_tb(slot); 452 tcg_gen_exit_tb(dc->base.tb, slot); 453 } else { 454 tcg_gen_exit_tb(NULL, 0); 455 } 456 } 457 dc->base.is_jmp = DISAS_NORETURN; 458 } 459 460 static void gen_jump(DisasContext *dc, TCGv dest) 461 { 462 gen_jump_slot(dc, dest, -1); 463 } 464 465 static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot) 466 { 467 if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) { 468 return -1; 469 } else { 470 return slot; 471 } 472 } 473 474 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot) 475 { 476 TCGv_i32 tmp = tcg_const_i32(dest); 477 gen_jump_slot(dc, tmp, adjust_jump_slot(dc, dest, slot)); 478 tcg_temp_free(tmp); 479 } 480 481 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest, 482 int slot) 483 { 484 TCGv_i32 tcallinc = tcg_const_i32(callinc); 485 486 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS], 487 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN); 488 tcg_temp_free(tcallinc); 489 tcg_gen_movi_i32(cpu_R[callinc << 2], 490 (callinc << 30) | (dc->base.pc_next & 0x3fffffff)); 491 gen_jump_slot(dc, dest, slot); 492 } 493 494 static bool gen_check_loop_end(DisasContext *dc, int slot) 495 { 496 if (dc->base.pc_next == dc->lend) { 497 TCGLabel *label = gen_new_label(); 498 499 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); 500 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); 501 if (dc->lbeg_off) { 502 gen_jumpi(dc, dc->base.pc_next - dc->lbeg_off, slot); 503 } else { 504 gen_jump(dc, cpu_SR[LBEG]); 505 } 506 gen_set_label(label); 507 gen_jumpi(dc, dc->base.pc_next, -1); 508 return true; 509 } 510 return false; 511 } 512 513 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot) 514 { 515 if (!gen_check_loop_end(dc, slot)) { 516 gen_jumpi(dc, dc->base.pc_next, slot); 517 } 518 } 519 520 static void gen_brcond(DisasContext *dc, TCGCond cond, 521 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr) 522 { 523 TCGLabel *label = gen_new_label(); 524 525 tcg_gen_brcond_i32(cond, t0, t1, label); 526 gen_jumpi_check_loop_end(dc, 0); 527 gen_set_label(label); 528 gen_jumpi(dc, addr, 1); 529 } 530 531 static void gen_brcondi(DisasContext *dc, TCGCond cond, 532 TCGv_i32 t0, uint32_t t1, uint32_t addr) 533 { 534 TCGv_i32 tmp = tcg_const_i32(t1); 535 gen_brcond(dc, cond, t0, tmp, addr); 536 tcg_temp_free(tmp); 537 } 538 539 static bool check_sr(DisasContext *dc, uint32_t sr, unsigned access) 540 { 541 if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) { 542 if (sregnames[sr].name) { 543 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name); 544 } else { 545 qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr); 546 } 547 return false; 548 } else if (!(sregnames[sr].access & access)) { 549 static const char * const access_text[] = { 550 [SR_R] = "rsr", 551 [SR_W] = "wsr", 552 [SR_X] = "xsr", 553 }; 554 assert(access < ARRAY_SIZE(access_text) && access_text[access]); 555 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name, 556 access_text[access]); 557 return false; 558 } 559 return true; 560 } 561 562 #ifndef CONFIG_USER_ONLY 563 static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr) 564 { 565 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 566 gen_io_start(); 567 } 568 gen_helper_update_ccount(cpu_env); 569 tcg_gen_mov_i32(d, cpu_SR[sr]); 570 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 571 gen_io_end(); 572 } 573 } 574 575 static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr) 576 { 577 tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10); 578 tcg_gen_or_i32(d, d, cpu_SR[sr]); 579 tcg_gen_andi_i32(d, d, 0xfffffffc); 580 } 581 #endif 582 583 static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr) 584 { 585 static void (* const rsr_handler[256])(DisasContext *dc, 586 TCGv_i32 d, uint32_t sr) = { 587 #ifndef CONFIG_USER_ONLY 588 [CCOUNT] = gen_rsr_ccount, 589 [INTSET] = gen_rsr_ccount, 590 [PTEVADDR] = gen_rsr_ptevaddr, 591 #endif 592 }; 593 594 if (rsr_handler[sr]) { 595 rsr_handler[sr](dc, d, sr); 596 } else { 597 tcg_gen_mov_i32(d, cpu_SR[sr]); 598 } 599 } 600 601 static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s) 602 { 603 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f); 604 if (dc->sar_m32_5bit) { 605 tcg_gen_discard_i32(dc->sar_m32); 606 } 607 dc->sar_5bit = false; 608 dc->sar_m32_5bit = false; 609 } 610 611 static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s) 612 { 613 tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff); 614 } 615 616 static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s) 617 { 618 tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001); 619 } 620 621 static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s) 622 { 623 tcg_gen_ext8s_i32(cpu_SR[sr], s); 624 } 625 626 #ifndef CONFIG_USER_ONLY 627 static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) 628 { 629 tcg_gen_mov_i32(cpu_windowbase_next, v); 630 } 631 632 static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v) 633 { 634 tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1); 635 } 636 637 static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v) 638 { 639 tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000); 640 } 641 642 static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v) 643 { 644 gen_helper_wsr_rasid(cpu_env, v); 645 } 646 647 static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v) 648 { 649 tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000); 650 } 651 652 static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) 653 { 654 gen_helper_wsr_ibreakenable(cpu_env, v); 655 } 656 657 static void gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v) 658 { 659 gen_helper_wsr_memctl(cpu_env, v); 660 } 661 662 static void gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v) 663 { 664 tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f); 665 } 666 667 static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) 668 { 669 unsigned id = sr - IBREAKA; 670 TCGv_i32 tmp = tcg_const_i32(id); 671 672 assert(id < dc->config->nibreak); 673 gen_helper_wsr_ibreaka(cpu_env, tmp, v); 674 tcg_temp_free(tmp); 675 } 676 677 static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) 678 { 679 unsigned id = sr - DBREAKA; 680 TCGv_i32 tmp = tcg_const_i32(id); 681 682 assert(id < dc->config->ndbreak); 683 gen_helper_wsr_dbreaka(cpu_env, tmp, v); 684 tcg_temp_free(tmp); 685 } 686 687 static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v) 688 { 689 unsigned id = sr - DBREAKC; 690 TCGv_i32 tmp = tcg_const_i32(id); 691 692 assert(id < dc->config->ndbreak); 693 gen_helper_wsr_dbreakc(cpu_env, tmp, v); 694 tcg_temp_free(tmp); 695 } 696 697 static void gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) 698 { 699 tcg_gen_andi_i32(cpu_SR[sr], v, 0xff); 700 } 701 702 static void gen_check_interrupts(DisasContext *dc) 703 { 704 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 705 gen_io_start(); 706 } 707 gen_helper_check_interrupts(cpu_env); 708 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 709 gen_io_end(); 710 } 711 } 712 713 static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v) 714 { 715 gen_helper_intset(cpu_env, v); 716 } 717 718 static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v) 719 { 720 gen_helper_intclear(cpu_env, v); 721 } 722 723 static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) 724 { 725 tcg_gen_mov_i32(cpu_SR[sr], v); 726 } 727 728 static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) 729 { 730 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB | 731 PS_UM | PS_EXCM | PS_INTLEVEL; 732 733 if (option_enabled(dc, XTENSA_OPTION_MMU)) { 734 mask |= PS_RING; 735 } 736 tcg_gen_andi_i32(cpu_SR[sr], v, mask); 737 } 738 739 static void gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v) 740 { 741 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 742 gen_io_start(); 743 } 744 gen_helper_wsr_ccount(cpu_env, v); 745 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 746 gen_io_end(); 747 } 748 } 749 750 static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v) 751 { 752 if (dc->icount) { 753 tcg_gen_mov_i32(dc->next_icount, v); 754 } else { 755 tcg_gen_mov_i32(cpu_SR[sr], v); 756 } 757 } 758 759 static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v) 760 { 761 tcg_gen_andi_i32(cpu_SR[sr], v, 0xf); 762 } 763 764 static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v) 765 { 766 uint32_t id = sr - CCOMPARE; 767 TCGv_i32 tmp = tcg_const_i32(id); 768 769 assert(id < dc->config->nccompare); 770 tcg_gen_mov_i32(cpu_SR[sr], v); 771 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 772 gen_io_start(); 773 } 774 gen_helper_update_ccompare(cpu_env, tmp); 775 tcg_temp_free(tmp); 776 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 777 gen_io_end(); 778 } 779 } 780 #else 781 static void gen_check_interrupts(DisasContext *dc) 782 { 783 } 784 #endif 785 786 static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) 787 { 788 static void (* const wsr_handler[256])(DisasContext *dc, 789 uint32_t sr, TCGv_i32 v) = { 790 [SAR] = gen_wsr_sar, 791 [BR] = gen_wsr_br, 792 [LITBASE] = gen_wsr_litbase, 793 [ACCHI] = gen_wsr_acchi, 794 #ifndef CONFIG_USER_ONLY 795 [WINDOW_BASE] = gen_wsr_windowbase, 796 [WINDOW_START] = gen_wsr_windowstart, 797 [PTEVADDR] = gen_wsr_ptevaddr, 798 [RASID] = gen_wsr_rasid, 799 [ITLBCFG] = gen_wsr_tlbcfg, 800 [DTLBCFG] = gen_wsr_tlbcfg, 801 [IBREAKENABLE] = gen_wsr_ibreakenable, 802 [MEMCTL] = gen_wsr_memctl, 803 [ATOMCTL] = gen_wsr_atomctl, 804 [IBREAKA] = gen_wsr_ibreaka, 805 [IBREAKA + 1] = gen_wsr_ibreaka, 806 [DBREAKA] = gen_wsr_dbreaka, 807 [DBREAKA + 1] = gen_wsr_dbreaka, 808 [DBREAKC] = gen_wsr_dbreakc, 809 [DBREAKC + 1] = gen_wsr_dbreakc, 810 [CPENABLE] = gen_wsr_cpenable, 811 [INTSET] = gen_wsr_intset, 812 [INTCLEAR] = gen_wsr_intclear, 813 [INTENABLE] = gen_wsr_intenable, 814 [PS] = gen_wsr_ps, 815 [CCOUNT] = gen_wsr_ccount, 816 [ICOUNT] = gen_wsr_icount, 817 [ICOUNTLEVEL] = gen_wsr_icountlevel, 818 [CCOMPARE] = gen_wsr_ccompare, 819 [CCOMPARE + 1] = gen_wsr_ccompare, 820 [CCOMPARE + 2] = gen_wsr_ccompare, 821 #endif 822 }; 823 824 if (wsr_handler[sr]) { 825 wsr_handler[sr](dc, sr, s); 826 } else { 827 tcg_gen_mov_i32(cpu_SR[sr], s); 828 } 829 } 830 831 static void gen_wur(uint32_t ur, TCGv_i32 s) 832 { 833 switch (ur) { 834 case FCR: 835 gen_helper_wur_fcr(cpu_env, s); 836 break; 837 838 case FSR: 839 tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80); 840 break; 841 842 default: 843 tcg_gen_mov_i32(cpu_UR[ur], s); 844 break; 845 } 846 } 847 848 static void gen_load_store_alignment(DisasContext *dc, int shift, 849 TCGv_i32 addr, bool no_hw_alignment) 850 { 851 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) { 852 tcg_gen_andi_i32(addr, addr, ~0 << shift); 853 } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) && 854 no_hw_alignment) { 855 TCGLabel *label = gen_new_label(); 856 TCGv_i32 tmp = tcg_temp_new_i32(); 857 tcg_gen_andi_i32(tmp, addr, ~(~0 << shift)); 858 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 859 gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr); 860 gen_set_label(label); 861 tcg_temp_free(tmp); 862 } 863 } 864 865 #ifndef CONFIG_USER_ONLY 866 static void gen_waiti(DisasContext *dc, uint32_t imm4) 867 { 868 TCGv_i32 pc = tcg_const_i32(dc->base.pc_next); 869 TCGv_i32 intlevel = tcg_const_i32(imm4); 870 871 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 872 gen_io_start(); 873 } 874 gen_helper_waiti(cpu_env, pc, intlevel); 875 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { 876 gen_io_end(); 877 } 878 tcg_temp_free(pc); 879 tcg_temp_free(intlevel); 880 } 881 #endif 882 883 static bool gen_window_check(DisasContext *dc, uint32_t mask) 884 { 885 unsigned r = 31 - clz32(mask); 886 887 if (r / 4 > dc->window) { 888 TCGv_i32 pc = tcg_const_i32(dc->pc); 889 TCGv_i32 w = tcg_const_i32(r / 4); 890 891 gen_helper_window_check(cpu_env, pc, w); 892 dc->base.is_jmp = DISAS_NORETURN; 893 return false; 894 } 895 return true; 896 } 897 898 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned) 899 { 900 TCGv_i32 m = tcg_temp_new_i32(); 901 902 if (hi) { 903 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16); 904 } else { 905 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v); 906 } 907 return m; 908 } 909 910 static void gen_zero_check(DisasContext *dc, const OpcodeArg arg[]) 911 { 912 TCGLabel *label = gen_new_label(); 913 914 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0, label); 915 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE); 916 gen_set_label(label); 917 } 918 919 static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0) 920 { 921 return xtensa_isa_length_from_chars(dc->config->isa, &op0); 922 } 923 924 static int gen_postprocess(DisasContext *dc, int slot) 925 { 926 uint32_t op_flags = dc->op_flags; 927 928 if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { 929 gen_check_interrupts(dc); 930 } 931 if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) { 932 gen_helper_sync_windowbase(cpu_env); 933 } 934 if (op_flags & XTENSA_OP_EXIT_TB_M1) { 935 slot = -1; 936 } 937 return slot; 938 } 939 940 struct opcode_arg_copy { 941 uint32_t resource; 942 void *temp; 943 OpcodeArg *arg; 944 }; 945 946 struct opcode_arg_info { 947 uint32_t resource; 948 int index; 949 }; 950 951 struct slot_prop { 952 XtensaOpcodeOps *ops; 953 OpcodeArg arg[MAX_OPCODE_ARGS]; 954 struct opcode_arg_info in[MAX_OPCODE_ARGS]; 955 struct opcode_arg_info out[MAX_OPCODE_ARGS]; 956 unsigned n_in; 957 unsigned n_out; 958 uint32_t op_flags; 959 }; 960 961 enum resource_type { 962 RES_REGFILE, 963 RES_STATE, 964 RES_MAX, 965 }; 966 967 static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n) 968 { 969 assert(r < RES_MAX && g < 256 && n < 65536); 970 return (r << 24) | (g << 16) | n; 971 } 972 973 static enum resource_type get_resource_type(uint32_t resource) 974 { 975 return resource >> 24; 976 } 977 978 /* 979 * a depends on b if b must be executed before a, 980 * because a's side effects will destroy b's inputs. 981 */ 982 static bool op_depends_on(const struct slot_prop *a, 983 const struct slot_prop *b) 984 { 985 unsigned i = 0; 986 unsigned j = 0; 987 988 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) { 989 return true; 990 } 991 if ((a->op_flags & XTENSA_OP_LOAD_STORE) < 992 (b->op_flags & XTENSA_OP_LOAD_STORE)) { 993 return true; 994 } 995 while (i < a->n_out && j < b->n_in) { 996 if (a->out[i].resource < b->in[j].resource) { 997 ++i; 998 } else if (a->out[i].resource > b->in[j].resource) { 999 ++j; 1000 } else { 1001 return true; 1002 } 1003 } 1004 return false; 1005 } 1006 1007 /* 1008 * Try to break a dependency on b, append temporary register copy records 1009 * to the end of copy and update n_copy in case of success. 1010 * This is not always possible: e.g. control flow must always be the last, 1011 * load/store must be first and state dependencies are not supported yet. 1012 */ 1013 static bool break_dependency(struct slot_prop *a, 1014 struct slot_prop *b, 1015 struct opcode_arg_copy *copy, 1016 unsigned *n_copy) 1017 { 1018 unsigned i = 0; 1019 unsigned j = 0; 1020 unsigned n = *n_copy; 1021 bool rv = false; 1022 1023 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) { 1024 return false; 1025 } 1026 if ((a->op_flags & XTENSA_OP_LOAD_STORE) < 1027 (b->op_flags & XTENSA_OP_LOAD_STORE)) { 1028 return false; 1029 } 1030 while (i < a->n_out && j < b->n_in) { 1031 if (a->out[i].resource < b->in[j].resource) { 1032 ++i; 1033 } else if (a->out[i].resource > b->in[j].resource) { 1034 ++j; 1035 } else { 1036 int index = b->in[j].index; 1037 1038 if (get_resource_type(a->out[i].resource) != RES_REGFILE || 1039 index < 0) { 1040 return false; 1041 } 1042 copy[n].resource = b->in[j].resource; 1043 copy[n].arg = b->arg + index; 1044 ++n; 1045 ++j; 1046 rv = true; 1047 } 1048 } 1049 *n_copy = n; 1050 return rv; 1051 } 1052 1053 /* 1054 * Calculate evaluation order for slot opcodes. 1055 * Build opcode order graph and output its nodes in topological sort order. 1056 * An edge a -> b in the graph means that opcode a must be followed by 1057 * opcode b. 1058 */ 1059 static bool tsort(struct slot_prop *slot, 1060 struct slot_prop *sorted[], 1061 unsigned n, 1062 struct opcode_arg_copy *copy, 1063 unsigned *n_copy) 1064 { 1065 struct tsnode { 1066 unsigned n_in_edge; 1067 unsigned n_out_edge; 1068 unsigned out_edge[MAX_INSN_SLOTS]; 1069 } node[MAX_INSN_SLOTS]; 1070 1071 unsigned in[MAX_INSN_SLOTS]; 1072 unsigned i, j; 1073 unsigned n_in = 0; 1074 unsigned n_out = 0; 1075 unsigned n_edge = 0; 1076 unsigned in_idx = 0; 1077 unsigned node_idx = 0; 1078 1079 for (i = 0; i < n; ++i) { 1080 node[i].n_in_edge = 0; 1081 node[i].n_out_edge = 0; 1082 } 1083 1084 for (i = 0; i < n; ++i) { 1085 unsigned n_out_edge = 0; 1086 1087 for (j = 0; j < n; ++j) { 1088 if (i != j && op_depends_on(slot + j, slot + i)) { 1089 node[i].out_edge[n_out_edge] = j; 1090 ++node[j].n_in_edge; 1091 ++n_out_edge; 1092 ++n_edge; 1093 } 1094 } 1095 node[i].n_out_edge = n_out_edge; 1096 } 1097 1098 for (i = 0; i < n; ++i) { 1099 if (!node[i].n_in_edge) { 1100 in[n_in] = i; 1101 ++n_in; 1102 } 1103 } 1104 1105 again: 1106 for (; in_idx < n_in; ++in_idx) { 1107 i = in[in_idx]; 1108 sorted[n_out] = slot + i; 1109 ++n_out; 1110 for (j = 0; j < node[i].n_out_edge; ++j) { 1111 --n_edge; 1112 if (--node[node[i].out_edge[j]].n_in_edge == 0) { 1113 in[n_in] = node[i].out_edge[j]; 1114 ++n_in; 1115 } 1116 } 1117 } 1118 if (n_edge) { 1119 for (; node_idx < n; ++node_idx) { 1120 struct tsnode *cnode = node + node_idx; 1121 1122 if (cnode->n_in_edge) { 1123 for (j = 0; j < cnode->n_out_edge; ++j) { 1124 unsigned k = cnode->out_edge[j]; 1125 1126 if (break_dependency(slot + k, slot + node_idx, 1127 copy, n_copy) && 1128 --node[k].n_in_edge == 0) { 1129 in[n_in] = k; 1130 ++n_in; 1131 --n_edge; 1132 cnode->out_edge[j] = 1133 cnode->out_edge[cnode->n_out_edge - 1]; 1134 --cnode->n_out_edge; 1135 goto again; 1136 } 1137 } 1138 } 1139 } 1140 } 1141 return n_edge == 0; 1142 } 1143 1144 static void opcode_add_resource(struct slot_prop *op, 1145 uint32_t resource, char direction, 1146 int index) 1147 { 1148 switch (direction) { 1149 case 'm': 1150 case 'i': 1151 assert(op->n_in < ARRAY_SIZE(op->in)); 1152 op->in[op->n_in].resource = resource; 1153 op->in[op->n_in].index = index; 1154 ++op->n_in; 1155 /* fall through */ 1156 case 'o': 1157 if (direction == 'm' || direction == 'o') { 1158 assert(op->n_out < ARRAY_SIZE(op->out)); 1159 op->out[op->n_out].resource = resource; 1160 op->out[op->n_out].index = index; 1161 ++op->n_out; 1162 } 1163 break; 1164 default: 1165 g_assert_not_reached(); 1166 } 1167 } 1168 1169 static int resource_compare(const void *a, const void *b) 1170 { 1171 const struct opcode_arg_info *pa = a; 1172 const struct opcode_arg_info *pb = b; 1173 1174 return pa->resource < pb->resource ? 1175 -1 : (pa->resource > pb->resource ? 1 : 0); 1176 } 1177 1178 static int arg_copy_compare(const void *a, const void *b) 1179 { 1180 const struct opcode_arg_copy *pa = a; 1181 const struct opcode_arg_copy *pb = b; 1182 1183 return pa->resource < pb->resource ? 1184 -1 : (pa->resource > pb->resource ? 1 : 0); 1185 } 1186 1187 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) 1188 { 1189 xtensa_isa isa = dc->config->isa; 1190 unsigned char b[MAX_INSN_LENGTH] = {cpu_ldub_code(env, dc->pc)}; 1191 unsigned len = xtensa_op0_insn_len(dc, b[0]); 1192 xtensa_format fmt; 1193 int slot, slots; 1194 unsigned i; 1195 uint32_t op_flags = 0; 1196 struct slot_prop slot_prop[MAX_INSN_SLOTS]; 1197 struct slot_prop *ordered[MAX_INSN_SLOTS]; 1198 struct opcode_arg_copy arg_copy[MAX_INSN_SLOTS * MAX_OPCODE_ARGS]; 1199 unsigned n_arg_copy = 0; 1200 uint32_t debug_cause = 0; 1201 uint32_t windowed_register = 0; 1202 uint32_t coprocessor = 0; 1203 1204 if (len == XTENSA_UNDEFINED) { 1205 qemu_log_mask(LOG_GUEST_ERROR, 1206 "unknown instruction length (pc = %08x)\n", 1207 dc->pc); 1208 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1209 return; 1210 } 1211 1212 dc->base.pc_next = dc->pc + len; 1213 for (i = 1; i < len; ++i) { 1214 b[i] = cpu_ldub_code(env, dc->pc + i); 1215 } 1216 xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len); 1217 fmt = xtensa_format_decode(isa, dc->insnbuf); 1218 if (fmt == XTENSA_UNDEFINED) { 1219 qemu_log_mask(LOG_GUEST_ERROR, 1220 "unrecognized instruction format (pc = %08x)\n", 1221 dc->pc); 1222 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1223 return; 1224 } 1225 slots = xtensa_format_num_slots(isa, fmt); 1226 for (slot = 0; slot < slots; ++slot) { 1227 xtensa_opcode opc; 1228 int opnd, vopnd, opnds; 1229 OpcodeArg *arg = slot_prop[slot].arg; 1230 XtensaOpcodeOps *ops; 1231 1232 xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf); 1233 opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf); 1234 if (opc == XTENSA_UNDEFINED) { 1235 qemu_log_mask(LOG_GUEST_ERROR, 1236 "unrecognized opcode in slot %d (pc = %08x)\n", 1237 slot, dc->pc); 1238 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1239 return; 1240 } 1241 opnds = xtensa_opcode_num_operands(isa, opc); 1242 1243 for (opnd = vopnd = 0; opnd < opnds; ++opnd) { 1244 void **register_file = NULL; 1245 1246 if (xtensa_operand_is_register(isa, opc, opnd)) { 1247 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); 1248 1249 register_file = dc->config->regfile[rf]; 1250 1251 if (rf == dc->config->a_regfile) { 1252 uint32_t v; 1253 1254 xtensa_operand_get_field(isa, opc, opnd, fmt, slot, 1255 dc->slotbuf, &v); 1256 xtensa_operand_decode(isa, opc, opnd, &v); 1257 windowed_register |= 1u << v; 1258 } 1259 } 1260 if (xtensa_operand_is_visible(isa, opc, opnd)) { 1261 uint32_t v; 1262 1263 xtensa_operand_get_field(isa, opc, opnd, fmt, slot, 1264 dc->slotbuf, &v); 1265 xtensa_operand_decode(isa, opc, opnd, &v); 1266 arg[vopnd].raw_imm = v; 1267 if (xtensa_operand_is_PCrelative(isa, opc, opnd)) { 1268 xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc); 1269 } 1270 arg[vopnd].imm = v; 1271 if (register_file) { 1272 arg[vopnd].in = register_file[v]; 1273 arg[vopnd].out = register_file[v]; 1274 } 1275 ++vopnd; 1276 } 1277 } 1278 ops = dc->config->opcode_ops[opc]; 1279 slot_prop[slot].ops = ops; 1280 1281 if (ops) { 1282 op_flags |= ops->op_flags; 1283 } else { 1284 qemu_log_mask(LOG_UNIMP, 1285 "unimplemented opcode '%s' in slot %d (pc = %08x)\n", 1286 xtensa_opcode_name(isa, opc), slot, dc->pc); 1287 op_flags |= XTENSA_OP_ILL; 1288 } 1289 if ((op_flags & XTENSA_OP_ILL) || 1290 (ops && ops->test_ill && ops->test_ill(dc, arg, ops->par))) { 1291 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1292 return; 1293 } 1294 if (ops->op_flags & XTENSA_OP_DEBUG_BREAK) { 1295 debug_cause |= ops->par[0]; 1296 } 1297 if (ops->test_overflow) { 1298 windowed_register |= ops->test_overflow(dc, arg, ops->par); 1299 } 1300 coprocessor |= ops->coprocessor; 1301 1302 if (slots > 1) { 1303 slot_prop[slot].n_in = 0; 1304 slot_prop[slot].n_out = 0; 1305 slot_prop[slot].op_flags = ops->op_flags & XTENSA_OP_LOAD_STORE; 1306 1307 opnds = xtensa_opcode_num_operands(isa, opc); 1308 1309 for (opnd = vopnd = 0; opnd < opnds; ++opnd) { 1310 bool visible = xtensa_operand_is_visible(isa, opc, opnd); 1311 1312 if (xtensa_operand_is_register(isa, opc, opnd)) { 1313 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); 1314 uint32_t v = 0; 1315 1316 xtensa_operand_get_field(isa, opc, opnd, fmt, slot, 1317 dc->slotbuf, &v); 1318 xtensa_operand_decode(isa, opc, opnd, &v); 1319 opcode_add_resource(slot_prop + slot, 1320 encode_resource(RES_REGFILE, rf, v), 1321 xtensa_operand_inout(isa, opc, opnd), 1322 visible ? vopnd : -1); 1323 } 1324 if (visible) { 1325 ++vopnd; 1326 } 1327 } 1328 1329 opnds = xtensa_opcode_num_stateOperands(isa, opc); 1330 1331 for (opnd = 0; opnd < opnds; ++opnd) { 1332 xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd); 1333 1334 opcode_add_resource(slot_prop + slot, 1335 encode_resource(RES_STATE, 0, state), 1336 xtensa_stateOperand_inout(isa, opc, opnd), 1337 -1); 1338 } 1339 if (xtensa_opcode_is_branch(isa, opc) || 1340 xtensa_opcode_is_jump(isa, opc) || 1341 xtensa_opcode_is_loop(isa, opc) || 1342 xtensa_opcode_is_call(isa, opc)) { 1343 slot_prop[slot].op_flags |= XTENSA_OP_CONTROL_FLOW; 1344 } 1345 1346 qsort(slot_prop[slot].in, slot_prop[slot].n_in, 1347 sizeof(slot_prop[slot].in[0]), resource_compare); 1348 qsort(slot_prop[slot].out, slot_prop[slot].n_out, 1349 sizeof(slot_prop[slot].out[0]), resource_compare); 1350 } 1351 } 1352 1353 if (slots > 1) { 1354 if (!tsort(slot_prop, ordered, slots, arg_copy, &n_arg_copy)) { 1355 qemu_log_mask(LOG_UNIMP, 1356 "Circular resource dependencies (pc = %08x)\n", 1357 dc->pc); 1358 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1359 return; 1360 } 1361 } else { 1362 ordered[0] = slot_prop + 0; 1363 } 1364 1365 if ((op_flags & XTENSA_OP_PRIVILEGED) && 1366 !gen_check_privilege(dc)) { 1367 return; 1368 } 1369 1370 if (op_flags & XTENSA_OP_SYSCALL) { 1371 gen_exception_cause(dc, SYSCALL_CAUSE); 1372 return; 1373 } 1374 1375 if ((op_flags & XTENSA_OP_DEBUG_BREAK) && dc->debug) { 1376 gen_debug_exception(dc, debug_cause); 1377 return; 1378 } 1379 1380 if (windowed_register && !gen_window_check(dc, windowed_register)) { 1381 return; 1382 } 1383 1384 if (op_flags & XTENSA_OP_UNDERFLOW) { 1385 TCGv_i32 tmp = tcg_const_i32(dc->pc); 1386 1387 gen_helper_test_underflow_retw(cpu_env, tmp); 1388 tcg_temp_free(tmp); 1389 } 1390 1391 if (op_flags & XTENSA_OP_ALLOCA) { 1392 TCGv_i32 tmp = tcg_const_i32(dc->pc); 1393 1394 gen_helper_movsp(cpu_env, tmp); 1395 tcg_temp_free(tmp); 1396 } 1397 1398 if (coprocessor && !gen_check_cpenable(dc, coprocessor)) { 1399 return; 1400 } 1401 1402 if (n_arg_copy) { 1403 uint32_t resource; 1404 void *temp; 1405 unsigned j; 1406 1407 qsort(arg_copy, n_arg_copy, sizeof(*arg_copy), arg_copy_compare); 1408 for (i = j = 0; i < n_arg_copy; ++i) { 1409 if (i == 0 || arg_copy[i].resource != resource) { 1410 resource = arg_copy[i].resource; 1411 temp = tcg_temp_local_new(); 1412 tcg_gen_mov_i32(temp, arg_copy[i].arg->in); 1413 arg_copy[i].temp = temp; 1414 1415 if (i != j) { 1416 arg_copy[j] = arg_copy[i]; 1417 } 1418 ++j; 1419 } 1420 arg_copy[i].arg->in = temp; 1421 } 1422 n_arg_copy = j; 1423 } 1424 1425 if (op_flags & XTENSA_OP_DIVIDE_BY_ZERO) { 1426 for (slot = 0; slot < slots; ++slot) { 1427 if (slot_prop[slot].ops->op_flags & XTENSA_OP_DIVIDE_BY_ZERO) { 1428 gen_zero_check(dc, slot_prop[slot].arg); 1429 } 1430 } 1431 } 1432 1433 dc->op_flags = op_flags; 1434 1435 for (slot = 0; slot < slots; ++slot) { 1436 struct slot_prop *pslot = ordered[slot]; 1437 XtensaOpcodeOps *ops = pslot->ops; 1438 1439 ops->translate(dc, pslot->arg, ops->par); 1440 } 1441 1442 for (i = 0; i < n_arg_copy; ++i) { 1443 tcg_temp_free(arg_copy[i].temp); 1444 } 1445 1446 if (dc->base.is_jmp == DISAS_NEXT) { 1447 gen_postprocess(dc, 0); 1448 dc->op_flags = 0; 1449 if (op_flags & XTENSA_OP_EXIT_TB_M1) { 1450 /* Change in mmu index, memory mapping or tb->flags; exit tb */ 1451 gen_jumpi_check_loop_end(dc, -1); 1452 } else if (op_flags & XTENSA_OP_EXIT_TB_0) { 1453 gen_jumpi_check_loop_end(dc, 0); 1454 } else { 1455 gen_check_loop_end(dc, 0); 1456 } 1457 } 1458 dc->pc = dc->base.pc_next; 1459 } 1460 1461 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc) 1462 { 1463 uint8_t b0 = cpu_ldub_code(env, dc->pc); 1464 return xtensa_op0_insn_len(dc, b0); 1465 } 1466 1467 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc) 1468 { 1469 unsigned i; 1470 1471 for (i = 0; i < dc->config->nibreak; ++i) { 1472 if ((env->sregs[IBREAKENABLE] & (1 << i)) && 1473 env->sregs[IBREAKA + i] == dc->pc) { 1474 gen_debug_exception(dc, DEBUGCAUSE_IB); 1475 break; 1476 } 1477 } 1478 } 1479 1480 static void xtensa_tr_init_disas_context(DisasContextBase *dcbase, 1481 CPUState *cpu) 1482 { 1483 DisasContext *dc = container_of(dcbase, DisasContext, base); 1484 CPUXtensaState *env = cpu->env_ptr; 1485 uint32_t tb_flags = dc->base.tb->flags; 1486 1487 dc->config = env->config; 1488 dc->pc = dc->base.pc_first; 1489 dc->ring = tb_flags & XTENSA_TBFLAG_RING_MASK; 1490 dc->cring = (tb_flags & XTENSA_TBFLAG_EXCM) ? 0 : dc->ring; 1491 dc->lbeg_off = (dc->base.tb->cs_base & XTENSA_CSBASE_LBEG_OFF_MASK) >> 1492 XTENSA_CSBASE_LBEG_OFF_SHIFT; 1493 dc->lend = (dc->base.tb->cs_base & XTENSA_CSBASE_LEND_MASK) + 1494 (dc->base.pc_first & TARGET_PAGE_MASK); 1495 dc->debug = tb_flags & XTENSA_TBFLAG_DEBUG; 1496 dc->icount = tb_flags & XTENSA_TBFLAG_ICOUNT; 1497 dc->cpenable = (tb_flags & XTENSA_TBFLAG_CPENABLE_MASK) >> 1498 XTENSA_TBFLAG_CPENABLE_SHIFT; 1499 dc->window = ((tb_flags & XTENSA_TBFLAG_WINDOW_MASK) >> 1500 XTENSA_TBFLAG_WINDOW_SHIFT); 1501 dc->cwoe = tb_flags & XTENSA_TBFLAG_CWOE; 1502 dc->callinc = ((tb_flags & XTENSA_TBFLAG_CALLINC_MASK) >> 1503 XTENSA_TBFLAG_CALLINC_SHIFT); 1504 1505 if (dc->config->isa) { 1506 dc->insnbuf = xtensa_insnbuf_alloc(dc->config->isa); 1507 dc->slotbuf = xtensa_insnbuf_alloc(dc->config->isa); 1508 } 1509 init_sar_tracker(dc); 1510 } 1511 1512 static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu) 1513 { 1514 DisasContext *dc = container_of(dcbase, DisasContext, base); 1515 1516 if (dc->icount) { 1517 dc->next_icount = tcg_temp_local_new_i32(); 1518 } 1519 } 1520 1521 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 1522 { 1523 tcg_gen_insn_start(dcbase->pc_next); 1524 } 1525 1526 static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, 1527 const CPUBreakpoint *bp) 1528 { 1529 DisasContext *dc = container_of(dcbase, DisasContext, base); 1530 1531 tcg_gen_movi_i32(cpu_pc, dc->base.pc_next); 1532 gen_exception(dc, EXCP_DEBUG); 1533 dc->base.is_jmp = DISAS_NORETURN; 1534 /* The address covered by the breakpoint must be included in 1535 [tb->pc, tb->pc + tb->size) in order to for it to be 1536 properly cleared -- thus we increment the PC here so that 1537 the logic setting tb->size below does the right thing. */ 1538 dc->base.pc_next += 2; 1539 return true; 1540 } 1541 1542 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 1543 { 1544 DisasContext *dc = container_of(dcbase, DisasContext, base); 1545 CPUXtensaState *env = cpu->env_ptr; 1546 target_ulong page_start; 1547 1548 /* These two conditions only apply to the first insn in the TB, 1549 but this is the first TranslateOps hook that allows exiting. */ 1550 if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT) 1551 && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) { 1552 gen_exception(dc, EXCP_YIELD); 1553 dc->base.is_jmp = DISAS_NORETURN; 1554 return; 1555 } 1556 if (dc->base.tb->flags & XTENSA_TBFLAG_EXCEPTION) { 1557 gen_exception(dc, EXCP_DEBUG); 1558 dc->base.is_jmp = DISAS_NORETURN; 1559 return; 1560 } 1561 1562 if (dc->icount) { 1563 TCGLabel *label = gen_new_label(); 1564 1565 tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1); 1566 tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label); 1567 tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]); 1568 if (dc->debug) { 1569 gen_debug_exception(dc, DEBUGCAUSE_IC); 1570 } 1571 gen_set_label(label); 1572 } 1573 1574 if (dc->debug) { 1575 gen_ibreak_check(env, dc); 1576 } 1577 1578 disas_xtensa_insn(env, dc); 1579 1580 if (dc->icount) { 1581 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); 1582 } 1583 1584 /* End the TB if the next insn will cross into the next page. */ 1585 page_start = dc->base.pc_first & TARGET_PAGE_MASK; 1586 if (dc->base.is_jmp == DISAS_NEXT && 1587 (dc->pc - page_start >= TARGET_PAGE_SIZE || 1588 dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) { 1589 dc->base.is_jmp = DISAS_TOO_MANY; 1590 } 1591 } 1592 1593 static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 1594 { 1595 DisasContext *dc = container_of(dcbase, DisasContext, base); 1596 1597 reset_sar_tracker(dc); 1598 if (dc->config->isa) { 1599 xtensa_insnbuf_free(dc->config->isa, dc->insnbuf); 1600 xtensa_insnbuf_free(dc->config->isa, dc->slotbuf); 1601 } 1602 if (dc->icount) { 1603 tcg_temp_free(dc->next_icount); 1604 } 1605 1606 switch (dc->base.is_jmp) { 1607 case DISAS_NORETURN: 1608 break; 1609 case DISAS_TOO_MANY: 1610 if (dc->base.singlestep_enabled) { 1611 tcg_gen_movi_i32(cpu_pc, dc->pc); 1612 gen_exception(dc, EXCP_DEBUG); 1613 } else { 1614 gen_jumpi(dc, dc->pc, 0); 1615 } 1616 break; 1617 default: 1618 g_assert_not_reached(); 1619 } 1620 } 1621 1622 static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) 1623 { 1624 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 1625 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); 1626 } 1627 1628 static const TranslatorOps xtensa_translator_ops = { 1629 .init_disas_context = xtensa_tr_init_disas_context, 1630 .tb_start = xtensa_tr_tb_start, 1631 .insn_start = xtensa_tr_insn_start, 1632 .breakpoint_check = xtensa_tr_breakpoint_check, 1633 .translate_insn = xtensa_tr_translate_insn, 1634 .tb_stop = xtensa_tr_tb_stop, 1635 .disas_log = xtensa_tr_disas_log, 1636 }; 1637 1638 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) 1639 { 1640 DisasContext dc = {}; 1641 translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns); 1642 } 1643 1644 void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags) 1645 { 1646 XtensaCPU *cpu = XTENSA_CPU(cs); 1647 CPUXtensaState *env = &cpu->env; 1648 int i, j; 1649 1650 qemu_fprintf(f, "PC=%08x\n\n", env->pc); 1651 1652 for (i = j = 0; i < 256; ++i) { 1653 if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) { 1654 qemu_fprintf(f, "%12s=%08x%c", 1655 sregnames[i].name, env->sregs[i], 1656 (j++ % 4) == 3 ? '\n' : ' '); 1657 } 1658 } 1659 1660 qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); 1661 1662 for (i = j = 0; i < 256; ++i) { 1663 if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) { 1664 qemu_fprintf(f, "%s=%08x%c", 1665 uregnames[i].name, env->uregs[i], 1666 (j++ % 4) == 3 ? '\n' : ' '); 1667 } 1668 } 1669 1670 qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); 1671 1672 for (i = 0; i < 16; ++i) { 1673 qemu_fprintf(f, " A%02d=%08x%c", 1674 i, env->regs[i], (i % 4) == 3 ? '\n' : ' '); 1675 } 1676 1677 xtensa_sync_phys_from_window(env); 1678 qemu_fprintf(f, "\n"); 1679 1680 for (i = 0; i < env->config->nareg; ++i) { 1681 qemu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]); 1682 if (i % 4 == 3) { 1683 bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0; 1684 bool cw = env->sregs[WINDOW_BASE] == i / 4; 1685 1686 qemu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' '); 1687 } 1688 } 1689 1690 if ((flags & CPU_DUMP_FPU) && 1691 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) { 1692 qemu_fprintf(f, "\n"); 1693 1694 for (i = 0; i < 16; ++i) { 1695 qemu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i, 1696 float32_val(env->fregs[i].f32[FP_F32_LOW]), 1697 *(float *)(env->fregs[i].f32 + FP_F32_LOW), 1698 (i % 2) == 1 ? '\n' : ' '); 1699 } 1700 } 1701 } 1702 1703 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, 1704 target_ulong *data) 1705 { 1706 env->pc = data[0]; 1707 } 1708 1709 static void translate_abs(DisasContext *dc, const OpcodeArg arg[], 1710 const uint32_t par[]) 1711 { 1712 TCGv_i32 zero = tcg_const_i32(0); 1713 TCGv_i32 neg = tcg_temp_new_i32(); 1714 1715 tcg_gen_neg_i32(neg, arg[1].in); 1716 tcg_gen_movcond_i32(TCG_COND_GE, arg[0].out, 1717 arg[1].in, zero, arg[1].in, neg); 1718 tcg_temp_free(neg); 1719 tcg_temp_free(zero); 1720 } 1721 1722 static void translate_add(DisasContext *dc, const OpcodeArg arg[], 1723 const uint32_t par[]) 1724 { 1725 tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in); 1726 } 1727 1728 static void translate_addi(DisasContext *dc, const OpcodeArg arg[], 1729 const uint32_t par[]) 1730 { 1731 tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm); 1732 } 1733 1734 static void translate_addx(DisasContext *dc, const OpcodeArg arg[], 1735 const uint32_t par[]) 1736 { 1737 TCGv_i32 tmp = tcg_temp_new_i32(); 1738 tcg_gen_shli_i32(tmp, arg[1].in, par[0]); 1739 tcg_gen_add_i32(arg[0].out, tmp, arg[2].in); 1740 tcg_temp_free(tmp); 1741 } 1742 1743 static void translate_all(DisasContext *dc, const OpcodeArg arg[], 1744 const uint32_t par[]) 1745 { 1746 uint32_t shift = par[1]; 1747 TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1].imm); 1748 TCGv_i32 tmp = tcg_temp_new_i32(); 1749 1750 tcg_gen_and_i32(tmp, arg[1].in, mask); 1751 if (par[0]) { 1752 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1].imm); 1753 } else { 1754 tcg_gen_add_i32(tmp, tmp, mask); 1755 } 1756 tcg_gen_shri_i32(tmp, tmp, arg[1].imm + shift); 1757 tcg_gen_deposit_i32(arg[0].out, arg[0].out, 1758 tmp, arg[0].imm, 1); 1759 tcg_temp_free(mask); 1760 tcg_temp_free(tmp); 1761 } 1762 1763 static void translate_and(DisasContext *dc, const OpcodeArg arg[], 1764 const uint32_t par[]) 1765 { 1766 tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in); 1767 } 1768 1769 static void translate_ball(DisasContext *dc, const OpcodeArg arg[], 1770 const uint32_t par[]) 1771 { 1772 TCGv_i32 tmp = tcg_temp_new_i32(); 1773 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in); 1774 gen_brcond(dc, par[0], tmp, arg[1].in, arg[2].imm); 1775 tcg_temp_free(tmp); 1776 } 1777 1778 static void translate_bany(DisasContext *dc, const OpcodeArg arg[], 1779 const uint32_t par[]) 1780 { 1781 TCGv_i32 tmp = tcg_temp_new_i32(); 1782 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in); 1783 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); 1784 tcg_temp_free(tmp); 1785 } 1786 1787 static void translate_b(DisasContext *dc, const OpcodeArg arg[], 1788 const uint32_t par[]) 1789 { 1790 gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm); 1791 } 1792 1793 static void translate_bb(DisasContext *dc, const OpcodeArg arg[], 1794 const uint32_t par[]) 1795 { 1796 #ifdef TARGET_WORDS_BIGENDIAN 1797 TCGv_i32 bit = tcg_const_i32(0x80000000u); 1798 #else 1799 TCGv_i32 bit = tcg_const_i32(0x00000001u); 1800 #endif 1801 TCGv_i32 tmp = tcg_temp_new_i32(); 1802 tcg_gen_andi_i32(tmp, arg[1].in, 0x1f); 1803 #ifdef TARGET_WORDS_BIGENDIAN 1804 tcg_gen_shr_i32(bit, bit, tmp); 1805 #else 1806 tcg_gen_shl_i32(bit, bit, tmp); 1807 #endif 1808 tcg_gen_and_i32(tmp, arg[0].in, bit); 1809 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); 1810 tcg_temp_free(tmp); 1811 tcg_temp_free(bit); 1812 } 1813 1814 static void translate_bbi(DisasContext *dc, const OpcodeArg arg[], 1815 const uint32_t par[]) 1816 { 1817 TCGv_i32 tmp = tcg_temp_new_i32(); 1818 #ifdef TARGET_WORDS_BIGENDIAN 1819 tcg_gen_andi_i32(tmp, arg[0].in, 0x80000000u >> arg[1].imm); 1820 #else 1821 tcg_gen_andi_i32(tmp, arg[0].in, 0x00000001u << arg[1].imm); 1822 #endif 1823 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); 1824 tcg_temp_free(tmp); 1825 } 1826 1827 static void translate_bi(DisasContext *dc, const OpcodeArg arg[], 1828 const uint32_t par[]) 1829 { 1830 gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm); 1831 } 1832 1833 static void translate_bz(DisasContext *dc, const OpcodeArg arg[], 1834 const uint32_t par[]) 1835 { 1836 gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm); 1837 } 1838 1839 enum { 1840 BOOLEAN_AND, 1841 BOOLEAN_ANDC, 1842 BOOLEAN_OR, 1843 BOOLEAN_ORC, 1844 BOOLEAN_XOR, 1845 }; 1846 1847 static void translate_boolean(DisasContext *dc, const OpcodeArg arg[], 1848 const uint32_t par[]) 1849 { 1850 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = { 1851 [BOOLEAN_AND] = tcg_gen_and_i32, 1852 [BOOLEAN_ANDC] = tcg_gen_andc_i32, 1853 [BOOLEAN_OR] = tcg_gen_or_i32, 1854 [BOOLEAN_ORC] = tcg_gen_orc_i32, 1855 [BOOLEAN_XOR] = tcg_gen_xor_i32, 1856 }; 1857 1858 TCGv_i32 tmp1 = tcg_temp_new_i32(); 1859 TCGv_i32 tmp2 = tcg_temp_new_i32(); 1860 1861 tcg_gen_shri_i32(tmp1, arg[1].in, arg[1].imm); 1862 tcg_gen_shri_i32(tmp2, arg[2].in, arg[2].imm); 1863 op[par[0]](tmp1, tmp1, tmp2); 1864 tcg_gen_deposit_i32(arg[0].out, arg[0].out, tmp1, arg[0].imm, 1); 1865 tcg_temp_free(tmp1); 1866 tcg_temp_free(tmp2); 1867 } 1868 1869 static void translate_bp(DisasContext *dc, const OpcodeArg arg[], 1870 const uint32_t par[]) 1871 { 1872 TCGv_i32 tmp = tcg_temp_new_i32(); 1873 1874 tcg_gen_andi_i32(tmp, arg[0].in, 1 << arg[0].imm); 1875 gen_brcondi(dc, par[0], tmp, 0, arg[1].imm); 1876 tcg_temp_free(tmp); 1877 } 1878 1879 static void translate_call0(DisasContext *dc, const OpcodeArg arg[], 1880 const uint32_t par[]) 1881 { 1882 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next); 1883 gen_jumpi(dc, arg[0].imm, 0); 1884 } 1885 1886 static void translate_callw(DisasContext *dc, const OpcodeArg arg[], 1887 const uint32_t par[]) 1888 { 1889 TCGv_i32 tmp = tcg_const_i32(arg[0].imm); 1890 gen_callw_slot(dc, par[0], tmp, adjust_jump_slot(dc, arg[0].imm, 0)); 1891 tcg_temp_free(tmp); 1892 } 1893 1894 static void translate_callx0(DisasContext *dc, const OpcodeArg arg[], 1895 const uint32_t par[]) 1896 { 1897 TCGv_i32 tmp = tcg_temp_new_i32(); 1898 tcg_gen_mov_i32(tmp, arg[0].in); 1899 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next); 1900 gen_jump(dc, tmp); 1901 tcg_temp_free(tmp); 1902 } 1903 1904 static void translate_callxw(DisasContext *dc, const OpcodeArg arg[], 1905 const uint32_t par[]) 1906 { 1907 TCGv_i32 tmp = tcg_temp_new_i32(); 1908 1909 tcg_gen_mov_i32(tmp, arg[0].in); 1910 gen_callw_slot(dc, par[0], tmp, -1); 1911 tcg_temp_free(tmp); 1912 } 1913 1914 static void translate_clamps(DisasContext *dc, const OpcodeArg arg[], 1915 const uint32_t par[]) 1916 { 1917 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2].imm); 1918 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2].imm) - 1); 1919 1920 tcg_gen_smax_i32(tmp1, tmp1, arg[1].in); 1921 tcg_gen_smin_i32(arg[0].out, tmp1, tmp2); 1922 tcg_temp_free(tmp1); 1923 tcg_temp_free(tmp2); 1924 } 1925 1926 static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[], 1927 const uint32_t par[]) 1928 { 1929 /* TODO: GPIO32 may be a part of coprocessor */ 1930 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm)); 1931 } 1932 1933 static void translate_const16(DisasContext *dc, const OpcodeArg arg[], 1934 const uint32_t par[]) 1935 { 1936 TCGv_i32 c = tcg_const_i32(arg[1].imm); 1937 1938 tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16); 1939 tcg_temp_free(c); 1940 } 1941 1942 static void translate_dcache(DisasContext *dc, const OpcodeArg arg[], 1943 const uint32_t par[]) 1944 { 1945 TCGv_i32 addr = tcg_temp_new_i32(); 1946 TCGv_i32 res = tcg_temp_new_i32(); 1947 1948 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm); 1949 tcg_gen_qemu_ld8u(res, addr, dc->cring); 1950 tcg_temp_free(addr); 1951 tcg_temp_free(res); 1952 } 1953 1954 static void translate_depbits(DisasContext *dc, const OpcodeArg arg[], 1955 const uint32_t par[]) 1956 { 1957 tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in, 1958 arg[2].imm, arg[3].imm); 1959 } 1960 1961 static bool test_ill_entry(DisasContext *dc, const OpcodeArg arg[], 1962 const uint32_t par[]) 1963 { 1964 if (arg[0].imm > 3 || !dc->cwoe) { 1965 qemu_log_mask(LOG_GUEST_ERROR, 1966 "Illegal entry instruction(pc = %08x)\n", dc->pc); 1967 return true; 1968 } else { 1969 return false; 1970 } 1971 } 1972 1973 static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[], 1974 const uint32_t par[]) 1975 { 1976 return 1 << (dc->callinc * 4); 1977 } 1978 1979 static void translate_entry(DisasContext *dc, const OpcodeArg arg[], 1980 const uint32_t par[]) 1981 { 1982 TCGv_i32 pc = tcg_const_i32(dc->pc); 1983 TCGv_i32 s = tcg_const_i32(arg[0].imm); 1984 TCGv_i32 imm = tcg_const_i32(arg[1].imm); 1985 gen_helper_entry(cpu_env, pc, s, imm); 1986 tcg_temp_free(imm); 1987 tcg_temp_free(s); 1988 tcg_temp_free(pc); 1989 } 1990 1991 static void translate_extui(DisasContext *dc, const OpcodeArg arg[], 1992 const uint32_t par[]) 1993 { 1994 int maskimm = (1 << arg[3].imm) - 1; 1995 1996 TCGv_i32 tmp = tcg_temp_new_i32(); 1997 tcg_gen_shri_i32(tmp, arg[1].in, arg[2].imm); 1998 tcg_gen_andi_i32(arg[0].out, tmp, maskimm); 1999 tcg_temp_free(tmp); 2000 } 2001 2002 static void translate_icache(DisasContext *dc, const OpcodeArg arg[], 2003 const uint32_t par[]) 2004 { 2005 #ifndef CONFIG_USER_ONLY 2006 TCGv_i32 addr = tcg_temp_new_i32(); 2007 2008 tcg_gen_movi_i32(cpu_pc, dc->pc); 2009 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm); 2010 gen_helper_itlb_hit_test(cpu_env, addr); 2011 tcg_temp_free(addr); 2012 #endif 2013 } 2014 2015 static void translate_itlb(DisasContext *dc, const OpcodeArg arg[], 2016 const uint32_t par[]) 2017 { 2018 #ifndef CONFIG_USER_ONLY 2019 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2020 2021 gen_helper_itlb(cpu_env, arg[0].in, dtlb); 2022 tcg_temp_free(dtlb); 2023 #endif 2024 } 2025 2026 static void translate_j(DisasContext *dc, const OpcodeArg arg[], 2027 const uint32_t par[]) 2028 { 2029 gen_jumpi(dc, arg[0].imm, 0); 2030 } 2031 2032 static void translate_jx(DisasContext *dc, const OpcodeArg arg[], 2033 const uint32_t par[]) 2034 { 2035 gen_jump(dc, arg[0].in); 2036 } 2037 2038 static void translate_l32e(DisasContext *dc, const OpcodeArg arg[], 2039 const uint32_t par[]) 2040 { 2041 TCGv_i32 addr = tcg_temp_new_i32(); 2042 2043 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 2044 gen_load_store_alignment(dc, 2, addr, false); 2045 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, MO_TEUL); 2046 tcg_temp_free(addr); 2047 } 2048 2049 static void translate_ldst(DisasContext *dc, const OpcodeArg arg[], 2050 const uint32_t par[]) 2051 { 2052 TCGv_i32 addr = tcg_temp_new_i32(); 2053 2054 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 2055 if (par[0] & MO_SIZE) { 2056 gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]); 2057 } 2058 if (par[2]) { 2059 if (par[1]) { 2060 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL); 2061 } 2062 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, par[0]); 2063 } else { 2064 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, par[0]); 2065 if (par[1]) { 2066 tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL); 2067 } 2068 } 2069 tcg_temp_free(addr); 2070 } 2071 2072 static void translate_l32r(DisasContext *dc, const OpcodeArg arg[], 2073 const uint32_t par[]) 2074 { 2075 TCGv_i32 tmp; 2076 2077 if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) { 2078 tmp = tcg_const_i32(arg[1].raw_imm - 1); 2079 tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp); 2080 } else { 2081 tmp = tcg_const_i32(arg[1].imm); 2082 } 2083 tcg_gen_qemu_ld32u(arg[0].out, tmp, dc->cring); 2084 tcg_temp_free(tmp); 2085 } 2086 2087 static void translate_loop(DisasContext *dc, const OpcodeArg arg[], 2088 const uint32_t par[]) 2089 { 2090 uint32_t lend = arg[1].imm; 2091 2092 tcg_gen_subi_i32(cpu_SR[LCOUNT], arg[0].in, 1); 2093 tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next); 2094 tcg_gen_movi_i32(cpu_SR[LEND], lend); 2095 2096 if (par[0] != TCG_COND_NEVER) { 2097 TCGLabel *label = gen_new_label(); 2098 tcg_gen_brcondi_i32(par[0], arg[0].in, 0, label); 2099 gen_jumpi(dc, lend, 1); 2100 gen_set_label(label); 2101 } 2102 2103 gen_jumpi(dc, dc->base.pc_next, 0); 2104 } 2105 2106 enum { 2107 MAC16_UMUL, 2108 MAC16_MUL, 2109 MAC16_MULA, 2110 MAC16_MULS, 2111 MAC16_NONE, 2112 }; 2113 2114 enum { 2115 MAC16_LL, 2116 MAC16_HL, 2117 MAC16_LH, 2118 MAC16_HH, 2119 2120 MAC16_HX = 0x1, 2121 MAC16_XH = 0x2, 2122 }; 2123 2124 static void translate_mac16(DisasContext *dc, const OpcodeArg arg[], 2125 const uint32_t par[]) 2126 { 2127 int op = par[0]; 2128 unsigned half = par[1]; 2129 uint32_t ld_offset = par[2]; 2130 unsigned off = ld_offset ? 2 : 0; 2131 TCGv_i32 vaddr = tcg_temp_new_i32(); 2132 TCGv_i32 mem32 = tcg_temp_new_i32(); 2133 2134 if (ld_offset) { 2135 tcg_gen_addi_i32(vaddr, arg[1].in, ld_offset); 2136 gen_load_store_alignment(dc, 2, vaddr, false); 2137 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring); 2138 } 2139 if (op != MAC16_NONE) { 2140 TCGv_i32 m1 = gen_mac16_m(arg[off].in, 2141 half & MAC16_HX, op == MAC16_UMUL); 2142 TCGv_i32 m2 = gen_mac16_m(arg[off + 1].in, 2143 half & MAC16_XH, op == MAC16_UMUL); 2144 2145 if (op == MAC16_MUL || op == MAC16_UMUL) { 2146 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2); 2147 if (op == MAC16_UMUL) { 2148 tcg_gen_movi_i32(cpu_SR[ACCHI], 0); 2149 } else { 2150 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31); 2151 } 2152 } else { 2153 TCGv_i32 lo = tcg_temp_new_i32(); 2154 TCGv_i32 hi = tcg_temp_new_i32(); 2155 2156 tcg_gen_mul_i32(lo, m1, m2); 2157 tcg_gen_sari_i32(hi, lo, 31); 2158 if (op == MAC16_MULA) { 2159 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 2160 cpu_SR[ACCLO], cpu_SR[ACCHI], 2161 lo, hi); 2162 } else { 2163 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 2164 cpu_SR[ACCLO], cpu_SR[ACCHI], 2165 lo, hi); 2166 } 2167 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]); 2168 2169 tcg_temp_free_i32(lo); 2170 tcg_temp_free_i32(hi); 2171 } 2172 tcg_temp_free(m1); 2173 tcg_temp_free(m2); 2174 } 2175 if (ld_offset) { 2176 tcg_gen_mov_i32(arg[1].out, vaddr); 2177 tcg_gen_mov_i32(cpu_SR[MR + arg[0].imm], mem32); 2178 } 2179 tcg_temp_free(vaddr); 2180 tcg_temp_free(mem32); 2181 } 2182 2183 static void translate_memw(DisasContext *dc, const OpcodeArg arg[], 2184 const uint32_t par[]) 2185 { 2186 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL); 2187 } 2188 2189 static void translate_smin(DisasContext *dc, const OpcodeArg arg[], 2190 const uint32_t par[]) 2191 { 2192 tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in); 2193 } 2194 2195 static void translate_umin(DisasContext *dc, const OpcodeArg arg[], 2196 const uint32_t par[]) 2197 { 2198 tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in); 2199 } 2200 2201 static void translate_smax(DisasContext *dc, const OpcodeArg arg[], 2202 const uint32_t par[]) 2203 { 2204 tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in); 2205 } 2206 2207 static void translate_umax(DisasContext *dc, const OpcodeArg arg[], 2208 const uint32_t par[]) 2209 { 2210 tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in); 2211 } 2212 2213 static void translate_mov(DisasContext *dc, const OpcodeArg arg[], 2214 const uint32_t par[]) 2215 { 2216 tcg_gen_mov_i32(arg[0].out, arg[1].in); 2217 } 2218 2219 static void translate_movcond(DisasContext *dc, const OpcodeArg arg[], 2220 const uint32_t par[]) 2221 { 2222 TCGv_i32 zero = tcg_const_i32(0); 2223 2224 tcg_gen_movcond_i32(par[0], arg[0].out, 2225 arg[2].in, zero, arg[1].in, arg[0].in); 2226 tcg_temp_free(zero); 2227 } 2228 2229 static void translate_movi(DisasContext *dc, const OpcodeArg arg[], 2230 const uint32_t par[]) 2231 { 2232 tcg_gen_movi_i32(arg[0].out, arg[1].imm); 2233 } 2234 2235 static void translate_movp(DisasContext *dc, const OpcodeArg arg[], 2236 const uint32_t par[]) 2237 { 2238 TCGv_i32 zero = tcg_const_i32(0); 2239 TCGv_i32 tmp = tcg_temp_new_i32(); 2240 2241 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm); 2242 tcg_gen_movcond_i32(par[0], 2243 arg[0].out, tmp, zero, 2244 arg[1].in, arg[0].in); 2245 tcg_temp_free(tmp); 2246 tcg_temp_free(zero); 2247 } 2248 2249 static void translate_movsp(DisasContext *dc, const OpcodeArg arg[], 2250 const uint32_t par[]) 2251 { 2252 tcg_gen_mov_i32(arg[0].out, arg[1].in); 2253 } 2254 2255 static void translate_mul16(DisasContext *dc, const OpcodeArg arg[], 2256 const uint32_t par[]) 2257 { 2258 TCGv_i32 v1 = tcg_temp_new_i32(); 2259 TCGv_i32 v2 = tcg_temp_new_i32(); 2260 2261 if (par[0]) { 2262 tcg_gen_ext16s_i32(v1, arg[1].in); 2263 tcg_gen_ext16s_i32(v2, arg[2].in); 2264 } else { 2265 tcg_gen_ext16u_i32(v1, arg[1].in); 2266 tcg_gen_ext16u_i32(v2, arg[2].in); 2267 } 2268 tcg_gen_mul_i32(arg[0].out, v1, v2); 2269 tcg_temp_free(v2); 2270 tcg_temp_free(v1); 2271 } 2272 2273 static void translate_mull(DisasContext *dc, const OpcodeArg arg[], 2274 const uint32_t par[]) 2275 { 2276 tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in); 2277 } 2278 2279 static void translate_mulh(DisasContext *dc, const OpcodeArg arg[], 2280 const uint32_t par[]) 2281 { 2282 TCGv_i32 lo = tcg_temp_new(); 2283 2284 if (par[0]) { 2285 tcg_gen_muls2_i32(lo, arg[0].out, arg[1].in, arg[2].in); 2286 } else { 2287 tcg_gen_mulu2_i32(lo, arg[0].out, arg[1].in, arg[2].in); 2288 } 2289 tcg_temp_free(lo); 2290 } 2291 2292 static void translate_neg(DisasContext *dc, const OpcodeArg arg[], 2293 const uint32_t par[]) 2294 { 2295 tcg_gen_neg_i32(arg[0].out, arg[1].in); 2296 } 2297 2298 static void translate_nop(DisasContext *dc, const OpcodeArg arg[], 2299 const uint32_t par[]) 2300 { 2301 } 2302 2303 static void translate_nsa(DisasContext *dc, const OpcodeArg arg[], 2304 const uint32_t par[]) 2305 { 2306 tcg_gen_clrsb_i32(arg[0].out, arg[1].in); 2307 } 2308 2309 static void translate_nsau(DisasContext *dc, const OpcodeArg arg[], 2310 const uint32_t par[]) 2311 { 2312 tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32); 2313 } 2314 2315 static void translate_or(DisasContext *dc, const OpcodeArg arg[], 2316 const uint32_t par[]) 2317 { 2318 tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in); 2319 } 2320 2321 static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[], 2322 const uint32_t par[]) 2323 { 2324 #ifndef CONFIG_USER_ONLY 2325 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2326 2327 tcg_gen_movi_i32(cpu_pc, dc->pc); 2328 gen_helper_ptlb(arg[0].out, cpu_env, arg[1].in, dtlb); 2329 tcg_temp_free(dtlb); 2330 #endif 2331 } 2332 2333 static void translate_quos(DisasContext *dc, const OpcodeArg arg[], 2334 const uint32_t par[]) 2335 { 2336 TCGLabel *label1 = gen_new_label(); 2337 TCGLabel *label2 = gen_new_label(); 2338 2339 tcg_gen_brcondi_i32(TCG_COND_NE, arg[1].in, 0x80000000, 2340 label1); 2341 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0xffffffff, 2342 label1); 2343 tcg_gen_movi_i32(arg[0].out, 2344 par[0] ? 0x80000000 : 0); 2345 tcg_gen_br(label2); 2346 gen_set_label(label1); 2347 if (par[0]) { 2348 tcg_gen_div_i32(arg[0].out, 2349 arg[1].in, arg[2].in); 2350 } else { 2351 tcg_gen_rem_i32(arg[0].out, 2352 arg[1].in, arg[2].in); 2353 } 2354 gen_set_label(label2); 2355 } 2356 2357 static void translate_quou(DisasContext *dc, const OpcodeArg arg[], 2358 const uint32_t par[]) 2359 { 2360 tcg_gen_divu_i32(arg[0].out, 2361 arg[1].in, arg[2].in); 2362 } 2363 2364 static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[], 2365 const uint32_t par[]) 2366 { 2367 /* TODO: GPIO32 may be a part of coprocessor */ 2368 tcg_gen_movi_i32(arg[0].out, 0); 2369 } 2370 2371 static void translate_remu(DisasContext *dc, const OpcodeArg arg[], 2372 const uint32_t par[]) 2373 { 2374 tcg_gen_remu_i32(arg[0].out, 2375 arg[1].in, arg[2].in); 2376 } 2377 2378 static void translate_rer(DisasContext *dc, const OpcodeArg arg[], 2379 const uint32_t par[]) 2380 { 2381 gen_helper_rer(arg[0].out, cpu_env, arg[1].in); 2382 } 2383 2384 static void translate_ret(DisasContext *dc, const OpcodeArg arg[], 2385 const uint32_t par[]) 2386 { 2387 gen_jump(dc, cpu_R[0]); 2388 } 2389 2390 static bool test_ill_retw(DisasContext *dc, const OpcodeArg arg[], 2391 const uint32_t par[]) 2392 { 2393 if (!dc->cwoe) { 2394 qemu_log_mask(LOG_GUEST_ERROR, 2395 "Illegal retw instruction(pc = %08x)\n", dc->pc); 2396 return true; 2397 } else { 2398 TCGv_i32 tmp = tcg_const_i32(dc->pc); 2399 2400 gen_helper_test_ill_retw(cpu_env, tmp); 2401 tcg_temp_free(tmp); 2402 return false; 2403 } 2404 } 2405 2406 static void translate_retw(DisasContext *dc, const OpcodeArg arg[], 2407 const uint32_t par[]) 2408 { 2409 TCGv_i32 tmp = tcg_const_i32(1); 2410 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); 2411 tcg_gen_andc_i32(cpu_SR[WINDOW_START], 2412 cpu_SR[WINDOW_START], tmp); 2413 tcg_gen_movi_i32(tmp, dc->pc); 2414 tcg_gen_deposit_i32(tmp, tmp, cpu_R[0], 0, 30); 2415 gen_helper_retw(cpu_env, cpu_R[0]); 2416 gen_jump(dc, tmp); 2417 tcg_temp_free(tmp); 2418 } 2419 2420 static void translate_rfde(DisasContext *dc, const OpcodeArg arg[], 2421 const uint32_t par[]) 2422 { 2423 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]); 2424 } 2425 2426 static void translate_rfe(DisasContext *dc, const OpcodeArg arg[], 2427 const uint32_t par[]) 2428 { 2429 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 2430 gen_jump(dc, cpu_SR[EPC1]); 2431 } 2432 2433 static void translate_rfi(DisasContext *dc, const OpcodeArg arg[], 2434 const uint32_t par[]) 2435 { 2436 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0].imm - 2]); 2437 gen_jump(dc, cpu_SR[EPC1 + arg[0].imm - 1]); 2438 } 2439 2440 static void translate_rfw(DisasContext *dc, const OpcodeArg arg[], 2441 const uint32_t par[]) 2442 { 2443 TCGv_i32 tmp = tcg_const_i32(1); 2444 2445 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 2446 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); 2447 2448 if (par[0]) { 2449 tcg_gen_andc_i32(cpu_SR[WINDOW_START], 2450 cpu_SR[WINDOW_START], tmp); 2451 } else { 2452 tcg_gen_or_i32(cpu_SR[WINDOW_START], 2453 cpu_SR[WINDOW_START], tmp); 2454 } 2455 2456 tcg_temp_free(tmp); 2457 gen_helper_restore_owb(cpu_env); 2458 gen_jump(dc, cpu_SR[EPC1]); 2459 } 2460 2461 static void translate_rotw(DisasContext *dc, const OpcodeArg arg[], 2462 const uint32_t par[]) 2463 { 2464 tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm); 2465 } 2466 2467 static void translate_rsil(DisasContext *dc, const OpcodeArg arg[], 2468 const uint32_t par[]) 2469 { 2470 tcg_gen_mov_i32(arg[0].out, cpu_SR[PS]); 2471 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL); 2472 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm); 2473 } 2474 2475 static bool test_ill_rsr(DisasContext *dc, const OpcodeArg arg[], 2476 const uint32_t par[]) 2477 { 2478 return !check_sr(dc, par[0], SR_R); 2479 } 2480 2481 static void translate_rsr(DisasContext *dc, const OpcodeArg arg[], 2482 const uint32_t par[]) 2483 { 2484 gen_rsr(dc, arg[0].out, par[0]); 2485 } 2486 2487 static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[], 2488 const uint32_t par[]) 2489 { 2490 #ifndef CONFIG_USER_ONLY 2491 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1, 2492 TCGv_i32 a2) = { 2493 gen_helper_rtlb0, 2494 gen_helper_rtlb1, 2495 }; 2496 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2497 2498 helper[par[1]](arg[0].out, cpu_env, arg[1].in, dtlb); 2499 tcg_temp_free(dtlb); 2500 #endif 2501 } 2502 2503 static void translate_rur(DisasContext *dc, const OpcodeArg arg[], 2504 const uint32_t par[]) 2505 { 2506 if (uregnames[par[0]].name) { 2507 tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]); 2508 } else { 2509 qemu_log_mask(LOG_UNIMP, "RUR %d not implemented\n", par[0]); 2510 } 2511 } 2512 2513 static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[], 2514 const uint32_t par[]) 2515 { 2516 /* TODO: GPIO32 may be a part of coprocessor */ 2517 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm); 2518 } 2519 2520 #ifdef CONFIG_USER_ONLY 2521 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr) 2522 { 2523 } 2524 #else 2525 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr) 2526 { 2527 TCGv_i32 tpc = tcg_const_i32(dc->pc); 2528 2529 gen_helper_check_atomctl(cpu_env, tpc, addr); 2530 tcg_temp_free(tpc); 2531 } 2532 #endif 2533 2534 static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[], 2535 const uint32_t par[]) 2536 { 2537 TCGv_i32 tmp = tcg_temp_local_new_i32(); 2538 TCGv_i32 addr = tcg_temp_local_new_i32(); 2539 2540 tcg_gen_mov_i32(tmp, arg[0].in); 2541 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 2542 gen_load_store_alignment(dc, 2, addr, true); 2543 gen_check_atomctl(dc, addr); 2544 tcg_gen_atomic_cmpxchg_i32(arg[0].out, addr, cpu_SR[SCOMPARE1], 2545 tmp, dc->cring, MO_TEUL); 2546 tcg_temp_free(addr); 2547 tcg_temp_free(tmp); 2548 } 2549 2550 static void translate_s32e(DisasContext *dc, const OpcodeArg arg[], 2551 const uint32_t par[]) 2552 { 2553 TCGv_i32 addr = tcg_temp_new_i32(); 2554 2555 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 2556 gen_load_store_alignment(dc, 2, addr, false); 2557 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->ring, MO_TEUL); 2558 tcg_temp_free(addr); 2559 } 2560 2561 static void translate_salt(DisasContext *dc, const OpcodeArg arg[], 2562 const uint32_t par[]) 2563 { 2564 tcg_gen_setcond_i32(par[0], 2565 arg[0].out, 2566 arg[1].in, arg[2].in); 2567 } 2568 2569 static void translate_sext(DisasContext *dc, const OpcodeArg arg[], 2570 const uint32_t par[]) 2571 { 2572 int shift = 31 - arg[2].imm; 2573 2574 if (shift == 24) { 2575 tcg_gen_ext8s_i32(arg[0].out, arg[1].in); 2576 } else if (shift == 16) { 2577 tcg_gen_ext16s_i32(arg[0].out, arg[1].in); 2578 } else { 2579 TCGv_i32 tmp = tcg_temp_new_i32(); 2580 tcg_gen_shli_i32(tmp, arg[1].in, shift); 2581 tcg_gen_sari_i32(arg[0].out, tmp, shift); 2582 tcg_temp_free(tmp); 2583 } 2584 } 2585 2586 static bool test_ill_simcall(DisasContext *dc, const OpcodeArg arg[], 2587 const uint32_t par[]) 2588 { 2589 #ifdef CONFIG_USER_ONLY 2590 bool ill = true; 2591 #else 2592 bool ill = !semihosting_enabled(); 2593 #endif 2594 if (ill) { 2595 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n"); 2596 } 2597 return ill; 2598 } 2599 2600 static void translate_simcall(DisasContext *dc, const OpcodeArg arg[], 2601 const uint32_t par[]) 2602 { 2603 #ifndef CONFIG_USER_ONLY 2604 gen_helper_simcall(cpu_env); 2605 #endif 2606 } 2607 2608 /* 2609 * Note: 64 bit ops are used here solely because SAR values 2610 * have range 0..63 2611 */ 2612 #define gen_shift_reg(cmd, reg) do { \ 2613 TCGv_i64 tmp = tcg_temp_new_i64(); \ 2614 tcg_gen_extu_i32_i64(tmp, reg); \ 2615 tcg_gen_##cmd##_i64(v, v, tmp); \ 2616 tcg_gen_extrl_i64_i32(arg[0].out, v); \ 2617 tcg_temp_free_i64(v); \ 2618 tcg_temp_free_i64(tmp); \ 2619 } while (0) 2620 2621 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR]) 2622 2623 static void translate_sll(DisasContext *dc, const OpcodeArg arg[], 2624 const uint32_t par[]) 2625 { 2626 if (dc->sar_m32_5bit) { 2627 tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32); 2628 } else { 2629 TCGv_i64 v = tcg_temp_new_i64(); 2630 TCGv_i32 s = tcg_const_i32(32); 2631 tcg_gen_sub_i32(s, s, cpu_SR[SAR]); 2632 tcg_gen_andi_i32(s, s, 0x3f); 2633 tcg_gen_extu_i32_i64(v, arg[1].in); 2634 gen_shift_reg(shl, s); 2635 tcg_temp_free(s); 2636 } 2637 } 2638 2639 static void translate_slli(DisasContext *dc, const OpcodeArg arg[], 2640 const uint32_t par[]) 2641 { 2642 if (arg[2].imm == 32) { 2643 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n", 2644 arg[0].imm, arg[1].imm); 2645 } 2646 tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f); 2647 } 2648 2649 static void translate_sra(DisasContext *dc, const OpcodeArg arg[], 2650 const uint32_t par[]) 2651 { 2652 if (dc->sar_m32_5bit) { 2653 tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]); 2654 } else { 2655 TCGv_i64 v = tcg_temp_new_i64(); 2656 tcg_gen_ext_i32_i64(v, arg[1].in); 2657 gen_shift(sar); 2658 } 2659 } 2660 2661 static void translate_srai(DisasContext *dc, const OpcodeArg arg[], 2662 const uint32_t par[]) 2663 { 2664 tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm); 2665 } 2666 2667 static void translate_src(DisasContext *dc, const OpcodeArg arg[], 2668 const uint32_t par[]) 2669 { 2670 TCGv_i64 v = tcg_temp_new_i64(); 2671 tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in); 2672 gen_shift(shr); 2673 } 2674 2675 static void translate_srl(DisasContext *dc, const OpcodeArg arg[], 2676 const uint32_t par[]) 2677 { 2678 if (dc->sar_m32_5bit) { 2679 tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]); 2680 } else { 2681 TCGv_i64 v = tcg_temp_new_i64(); 2682 tcg_gen_extu_i32_i64(v, arg[1].in); 2683 gen_shift(shr); 2684 } 2685 } 2686 2687 #undef gen_shift 2688 #undef gen_shift_reg 2689 2690 static void translate_srli(DisasContext *dc, const OpcodeArg arg[], 2691 const uint32_t par[]) 2692 { 2693 tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm); 2694 } 2695 2696 static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[], 2697 const uint32_t par[]) 2698 { 2699 TCGv_i32 tmp = tcg_temp_new_i32(); 2700 tcg_gen_shli_i32(tmp, arg[0].in, 3); 2701 gen_left_shift_sar(dc, tmp); 2702 tcg_temp_free(tmp); 2703 } 2704 2705 static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[], 2706 const uint32_t par[]) 2707 { 2708 TCGv_i32 tmp = tcg_temp_new_i32(); 2709 tcg_gen_shli_i32(tmp, arg[0].in, 3); 2710 gen_right_shift_sar(dc, tmp); 2711 tcg_temp_free(tmp); 2712 } 2713 2714 static void translate_ssai(DisasContext *dc, const OpcodeArg arg[], 2715 const uint32_t par[]) 2716 { 2717 TCGv_i32 tmp = tcg_const_i32(arg[0].imm); 2718 gen_right_shift_sar(dc, tmp); 2719 tcg_temp_free(tmp); 2720 } 2721 2722 static void translate_ssl(DisasContext *dc, const OpcodeArg arg[], 2723 const uint32_t par[]) 2724 { 2725 gen_left_shift_sar(dc, arg[0].in); 2726 } 2727 2728 static void translate_ssr(DisasContext *dc, const OpcodeArg arg[], 2729 const uint32_t par[]) 2730 { 2731 gen_right_shift_sar(dc, arg[0].in); 2732 } 2733 2734 static void translate_sub(DisasContext *dc, const OpcodeArg arg[], 2735 const uint32_t par[]) 2736 { 2737 tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in); 2738 } 2739 2740 static void translate_subx(DisasContext *dc, const OpcodeArg arg[], 2741 const uint32_t par[]) 2742 { 2743 TCGv_i32 tmp = tcg_temp_new_i32(); 2744 tcg_gen_shli_i32(tmp, arg[1].in, par[0]); 2745 tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in); 2746 tcg_temp_free(tmp); 2747 } 2748 2749 static void translate_waiti(DisasContext *dc, const OpcodeArg arg[], 2750 const uint32_t par[]) 2751 { 2752 #ifndef CONFIG_USER_ONLY 2753 gen_waiti(dc, arg[0].imm); 2754 #endif 2755 } 2756 2757 static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[], 2758 const uint32_t par[]) 2759 { 2760 #ifndef CONFIG_USER_ONLY 2761 TCGv_i32 dtlb = tcg_const_i32(par[0]); 2762 2763 gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb); 2764 tcg_temp_free(dtlb); 2765 #endif 2766 } 2767 2768 static void translate_wer(DisasContext *dc, const OpcodeArg arg[], 2769 const uint32_t par[]) 2770 { 2771 gen_helper_wer(cpu_env, arg[0].in, arg[1].in); 2772 } 2773 2774 static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[], 2775 const uint32_t par[]) 2776 { 2777 /* TODO: GPIO32 may be a part of coprocessor */ 2778 tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in); 2779 } 2780 2781 static bool test_ill_wsr(DisasContext *dc, const OpcodeArg arg[], 2782 const uint32_t par[]) 2783 { 2784 return !check_sr(dc, par[0], SR_W); 2785 } 2786 2787 static void translate_wsr(DisasContext *dc, const OpcodeArg arg[], 2788 const uint32_t par[]) 2789 { 2790 gen_wsr(dc, par[0], arg[0].in); 2791 } 2792 2793 static void translate_wur(DisasContext *dc, const OpcodeArg arg[], 2794 const uint32_t par[]) 2795 { 2796 if (uregnames[par[0]].name) { 2797 gen_wur(par[0], arg[0].in); 2798 } else { 2799 qemu_log_mask(LOG_UNIMP, "WUR %d not implemented\n", par[0]); 2800 } 2801 } 2802 2803 static void translate_xor(DisasContext *dc, const OpcodeArg arg[], 2804 const uint32_t par[]) 2805 { 2806 tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in); 2807 } 2808 2809 static bool test_ill_xsr(DisasContext *dc, const OpcodeArg arg[], 2810 const uint32_t par[]) 2811 { 2812 return !check_sr(dc, par[0], SR_X); 2813 } 2814 2815 static void translate_xsr(DisasContext *dc, const OpcodeArg arg[], 2816 const uint32_t par[]) 2817 { 2818 TCGv_i32 tmp = tcg_temp_new_i32(); 2819 2820 tcg_gen_mov_i32(tmp, arg[0].in); 2821 gen_rsr(dc, arg[0].out, par[0]); 2822 gen_wsr(dc, par[0], tmp); 2823 tcg_temp_free(tmp); 2824 } 2825 2826 static const XtensaOpcodeOps core_ops[] = { 2827 { 2828 .name = "abs", 2829 .translate = translate_abs, 2830 }, { 2831 .name = (const char * const[]) { 2832 "add", "add.n", NULL, 2833 }, 2834 .translate = translate_add, 2835 .op_flags = XTENSA_OP_NAME_ARRAY, 2836 }, { 2837 .name = (const char * const[]) { 2838 "addi", "addi.n", NULL, 2839 }, 2840 .translate = translate_addi, 2841 .op_flags = XTENSA_OP_NAME_ARRAY, 2842 }, { 2843 .name = "addmi", 2844 .translate = translate_addi, 2845 }, { 2846 .name = "addx2", 2847 .translate = translate_addx, 2848 .par = (const uint32_t[]){1}, 2849 }, { 2850 .name = "addx4", 2851 .translate = translate_addx, 2852 .par = (const uint32_t[]){2}, 2853 }, { 2854 .name = "addx8", 2855 .translate = translate_addx, 2856 .par = (const uint32_t[]){3}, 2857 }, { 2858 .name = "all4", 2859 .translate = translate_all, 2860 .par = (const uint32_t[]){true, 4}, 2861 }, { 2862 .name = "all8", 2863 .translate = translate_all, 2864 .par = (const uint32_t[]){true, 8}, 2865 }, { 2866 .name = "and", 2867 .translate = translate_and, 2868 }, { 2869 .name = "andb", 2870 .translate = translate_boolean, 2871 .par = (const uint32_t[]){BOOLEAN_AND}, 2872 }, { 2873 .name = "andbc", 2874 .translate = translate_boolean, 2875 .par = (const uint32_t[]){BOOLEAN_ANDC}, 2876 }, { 2877 .name = "any4", 2878 .translate = translate_all, 2879 .par = (const uint32_t[]){false, 4}, 2880 }, { 2881 .name = "any8", 2882 .translate = translate_all, 2883 .par = (const uint32_t[]){false, 8}, 2884 }, { 2885 .name = (const char * const[]) { 2886 "ball", "ball.w15", "ball.w18", NULL, 2887 }, 2888 .translate = translate_ball, 2889 .par = (const uint32_t[]){TCG_COND_EQ}, 2890 .op_flags = XTENSA_OP_NAME_ARRAY, 2891 }, { 2892 .name = (const char * const[]) { 2893 "bany", "bany.w15", "bany.w18", NULL, 2894 }, 2895 .translate = translate_bany, 2896 .par = (const uint32_t[]){TCG_COND_NE}, 2897 .op_flags = XTENSA_OP_NAME_ARRAY, 2898 }, { 2899 .name = (const char * const[]) { 2900 "bbc", "bbc.w15", "bbc.w18", NULL, 2901 }, 2902 .translate = translate_bb, 2903 .par = (const uint32_t[]){TCG_COND_EQ}, 2904 .op_flags = XTENSA_OP_NAME_ARRAY, 2905 }, { 2906 .name = (const char * const[]) { 2907 "bbci", "bbci.w15", "bbci.w18", NULL, 2908 }, 2909 .translate = translate_bbi, 2910 .par = (const uint32_t[]){TCG_COND_EQ}, 2911 .op_flags = XTENSA_OP_NAME_ARRAY, 2912 }, { 2913 .name = (const char * const[]) { 2914 "bbs", "bbs.w15", "bbs.w18", NULL, 2915 }, 2916 .translate = translate_bb, 2917 .par = (const uint32_t[]){TCG_COND_NE}, 2918 .op_flags = XTENSA_OP_NAME_ARRAY, 2919 }, { 2920 .name = (const char * const[]) { 2921 "bbsi", "bbsi.w15", "bbsi.w18", NULL, 2922 }, 2923 .translate = translate_bbi, 2924 .par = (const uint32_t[]){TCG_COND_NE}, 2925 .op_flags = XTENSA_OP_NAME_ARRAY, 2926 }, { 2927 .name = (const char * const[]) { 2928 "beq", "beq.w15", "beq.w18", NULL, 2929 }, 2930 .translate = translate_b, 2931 .par = (const uint32_t[]){TCG_COND_EQ}, 2932 .op_flags = XTENSA_OP_NAME_ARRAY, 2933 }, { 2934 .name = (const char * const[]) { 2935 "beqi", "beqi.w15", "beqi.w18", NULL, 2936 }, 2937 .translate = translate_bi, 2938 .par = (const uint32_t[]){TCG_COND_EQ}, 2939 .op_flags = XTENSA_OP_NAME_ARRAY, 2940 }, { 2941 .name = (const char * const[]) { 2942 "beqz", "beqz.n", "beqz.w15", "beqz.w18", NULL, 2943 }, 2944 .translate = translate_bz, 2945 .par = (const uint32_t[]){TCG_COND_EQ}, 2946 .op_flags = XTENSA_OP_NAME_ARRAY, 2947 }, { 2948 .name = "bf", 2949 .translate = translate_bp, 2950 .par = (const uint32_t[]){TCG_COND_EQ}, 2951 }, { 2952 .name = (const char * const[]) { 2953 "bge", "bge.w15", "bge.w18", NULL, 2954 }, 2955 .translate = translate_b, 2956 .par = (const uint32_t[]){TCG_COND_GE}, 2957 .op_flags = XTENSA_OP_NAME_ARRAY, 2958 }, { 2959 .name = (const char * const[]) { 2960 "bgei", "bgei.w15", "bgei.w18", NULL, 2961 }, 2962 .translate = translate_bi, 2963 .par = (const uint32_t[]){TCG_COND_GE}, 2964 .op_flags = XTENSA_OP_NAME_ARRAY, 2965 }, { 2966 .name = (const char * const[]) { 2967 "bgeu", "bgeu.w15", "bgeu.w18", NULL, 2968 }, 2969 .translate = translate_b, 2970 .par = (const uint32_t[]){TCG_COND_GEU}, 2971 .op_flags = XTENSA_OP_NAME_ARRAY, 2972 }, { 2973 .name = (const char * const[]) { 2974 "bgeui", "bgeui.w15", "bgeui.w18", NULL, 2975 }, 2976 .translate = translate_bi, 2977 .par = (const uint32_t[]){TCG_COND_GEU}, 2978 .op_flags = XTENSA_OP_NAME_ARRAY, 2979 }, { 2980 .name = (const char * const[]) { 2981 "bgez", "bgez.w15", "bgez.w18", NULL, 2982 }, 2983 .translate = translate_bz, 2984 .par = (const uint32_t[]){TCG_COND_GE}, 2985 .op_flags = XTENSA_OP_NAME_ARRAY, 2986 }, { 2987 .name = (const char * const[]) { 2988 "blt", "blt.w15", "blt.w18", NULL, 2989 }, 2990 .translate = translate_b, 2991 .par = (const uint32_t[]){TCG_COND_LT}, 2992 .op_flags = XTENSA_OP_NAME_ARRAY, 2993 }, { 2994 .name = (const char * const[]) { 2995 "blti", "blti.w15", "blti.w18", NULL, 2996 }, 2997 .translate = translate_bi, 2998 .par = (const uint32_t[]){TCG_COND_LT}, 2999 .op_flags = XTENSA_OP_NAME_ARRAY, 3000 }, { 3001 .name = (const char * const[]) { 3002 "bltu", "bltu.w15", "bltu.w18", NULL, 3003 }, 3004 .translate = translate_b, 3005 .par = (const uint32_t[]){TCG_COND_LTU}, 3006 .op_flags = XTENSA_OP_NAME_ARRAY, 3007 }, { 3008 .name = (const char * const[]) { 3009 "bltui", "bltui.w15", "bltui.w18", NULL, 3010 }, 3011 .translate = translate_bi, 3012 .par = (const uint32_t[]){TCG_COND_LTU}, 3013 .op_flags = XTENSA_OP_NAME_ARRAY, 3014 }, { 3015 .name = (const char * const[]) { 3016 "bltz", "bltz.w15", "bltz.w18", NULL, 3017 }, 3018 .translate = translate_bz, 3019 .par = (const uint32_t[]){TCG_COND_LT}, 3020 .op_flags = XTENSA_OP_NAME_ARRAY, 3021 }, { 3022 .name = (const char * const[]) { 3023 "bnall", "bnall.w15", "bnall.w18", NULL, 3024 }, 3025 .translate = translate_ball, 3026 .par = (const uint32_t[]){TCG_COND_NE}, 3027 .op_flags = XTENSA_OP_NAME_ARRAY, 3028 }, { 3029 .name = (const char * const[]) { 3030 "bne", "bne.w15", "bne.w18", NULL, 3031 }, 3032 .translate = translate_b, 3033 .par = (const uint32_t[]){TCG_COND_NE}, 3034 .op_flags = XTENSA_OP_NAME_ARRAY, 3035 }, { 3036 .name = (const char * const[]) { 3037 "bnei", "bnei.w15", "bnei.w18", NULL, 3038 }, 3039 .translate = translate_bi, 3040 .par = (const uint32_t[]){TCG_COND_NE}, 3041 .op_flags = XTENSA_OP_NAME_ARRAY, 3042 }, { 3043 .name = (const char * const[]) { 3044 "bnez", "bnez.n", "bnez.w15", "bnez.w18", NULL, 3045 }, 3046 .translate = translate_bz, 3047 .par = (const uint32_t[]){TCG_COND_NE}, 3048 .op_flags = XTENSA_OP_NAME_ARRAY, 3049 }, { 3050 .name = (const char * const[]) { 3051 "bnone", "bnone.w15", "bnone.w18", NULL, 3052 }, 3053 .translate = translate_bany, 3054 .par = (const uint32_t[]){TCG_COND_EQ}, 3055 .op_flags = XTENSA_OP_NAME_ARRAY, 3056 }, { 3057 .name = "break", 3058 .translate = translate_nop, 3059 .par = (const uint32_t[]){DEBUGCAUSE_BI}, 3060 .op_flags = XTENSA_OP_DEBUG_BREAK, 3061 }, { 3062 .name = "break.n", 3063 .translate = translate_nop, 3064 .par = (const uint32_t[]){DEBUGCAUSE_BN}, 3065 .op_flags = XTENSA_OP_DEBUG_BREAK, 3066 }, { 3067 .name = "bt", 3068 .translate = translate_bp, 3069 .par = (const uint32_t[]){TCG_COND_NE}, 3070 }, { 3071 .name = "call0", 3072 .translate = translate_call0, 3073 }, { 3074 .name = "call12", 3075 .translate = translate_callw, 3076 .par = (const uint32_t[]){3}, 3077 }, { 3078 .name = "call4", 3079 .translate = translate_callw, 3080 .par = (const uint32_t[]){1}, 3081 }, { 3082 .name = "call8", 3083 .translate = translate_callw, 3084 .par = (const uint32_t[]){2}, 3085 }, { 3086 .name = "callx0", 3087 .translate = translate_callx0, 3088 }, { 3089 .name = "callx12", 3090 .translate = translate_callxw, 3091 .par = (const uint32_t[]){3}, 3092 }, { 3093 .name = "callx4", 3094 .translate = translate_callxw, 3095 .par = (const uint32_t[]){1}, 3096 }, { 3097 .name = "callx8", 3098 .translate = translate_callxw, 3099 .par = (const uint32_t[]){2}, 3100 }, { 3101 .name = "clamps", 3102 .translate = translate_clamps, 3103 }, { 3104 .name = "clrb_expstate", 3105 .translate = translate_clrb_expstate, 3106 }, { 3107 .name = "const16", 3108 .translate = translate_const16, 3109 }, { 3110 .name = "depbits", 3111 .translate = translate_depbits, 3112 }, { 3113 .name = "dhi", 3114 .translate = translate_dcache, 3115 .op_flags = XTENSA_OP_PRIVILEGED, 3116 }, { 3117 .name = "dhu", 3118 .translate = translate_dcache, 3119 .op_flags = XTENSA_OP_PRIVILEGED, 3120 }, { 3121 .name = "dhwb", 3122 .translate = translate_dcache, 3123 }, { 3124 .name = "dhwbi", 3125 .translate = translate_dcache, 3126 }, { 3127 .name = "dii", 3128 .translate = translate_nop, 3129 .op_flags = XTENSA_OP_PRIVILEGED, 3130 }, { 3131 .name = "diu", 3132 .translate = translate_nop, 3133 .op_flags = XTENSA_OP_PRIVILEGED, 3134 }, { 3135 .name = "diwb", 3136 .translate = translate_nop, 3137 .op_flags = XTENSA_OP_PRIVILEGED, 3138 }, { 3139 .name = "diwbi", 3140 .translate = translate_nop, 3141 .op_flags = XTENSA_OP_PRIVILEGED, 3142 }, { 3143 .name = "dpfl", 3144 .translate = translate_dcache, 3145 .op_flags = XTENSA_OP_PRIVILEGED, 3146 }, { 3147 .name = "dpfr", 3148 .translate = translate_nop, 3149 }, { 3150 .name = "dpfro", 3151 .translate = translate_nop, 3152 }, { 3153 .name = "dpfw", 3154 .translate = translate_nop, 3155 }, { 3156 .name = "dpfwo", 3157 .translate = translate_nop, 3158 }, { 3159 .name = "dsync", 3160 .translate = translate_nop, 3161 }, { 3162 .name = "entry", 3163 .translate = translate_entry, 3164 .test_ill = test_ill_entry, 3165 .test_overflow = test_overflow_entry, 3166 .op_flags = XTENSA_OP_EXIT_TB_M1 | 3167 XTENSA_OP_SYNC_REGISTER_WINDOW, 3168 }, { 3169 .name = "esync", 3170 .translate = translate_nop, 3171 }, { 3172 .name = "excw", 3173 .translate = translate_nop, 3174 }, { 3175 .name = "extui", 3176 .translate = translate_extui, 3177 }, { 3178 .name = "extw", 3179 .translate = translate_memw, 3180 }, { 3181 .name = "hwwdtlba", 3182 .op_flags = XTENSA_OP_ILL, 3183 }, { 3184 .name = "hwwitlba", 3185 .op_flags = XTENSA_OP_ILL, 3186 }, { 3187 .name = "idtlb", 3188 .translate = translate_itlb, 3189 .par = (const uint32_t[]){true}, 3190 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 3191 }, { 3192 .name = "ihi", 3193 .translate = translate_icache, 3194 }, { 3195 .name = "ihu", 3196 .translate = translate_icache, 3197 .op_flags = XTENSA_OP_PRIVILEGED, 3198 }, { 3199 .name = "iii", 3200 .translate = translate_nop, 3201 .op_flags = XTENSA_OP_PRIVILEGED, 3202 }, { 3203 .name = "iitlb", 3204 .translate = translate_itlb, 3205 .par = (const uint32_t[]){false}, 3206 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 3207 }, { 3208 .name = "iiu", 3209 .translate = translate_nop, 3210 .op_flags = XTENSA_OP_PRIVILEGED, 3211 }, { 3212 .name = (const char * const[]) { 3213 "ill", "ill.n", NULL, 3214 }, 3215 .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY, 3216 }, { 3217 .name = "ipf", 3218 .translate = translate_nop, 3219 }, { 3220 .name = "ipfl", 3221 .translate = translate_icache, 3222 .op_flags = XTENSA_OP_PRIVILEGED, 3223 }, { 3224 .name = "isync", 3225 .translate = translate_nop, 3226 }, { 3227 .name = "j", 3228 .translate = translate_j, 3229 }, { 3230 .name = "jx", 3231 .translate = translate_jx, 3232 }, { 3233 .name = "l16si", 3234 .translate = translate_ldst, 3235 .par = (const uint32_t[]){MO_TESW, false, false}, 3236 .op_flags = XTENSA_OP_LOAD, 3237 }, { 3238 .name = "l16ui", 3239 .translate = translate_ldst, 3240 .par = (const uint32_t[]){MO_TEUW, false, false}, 3241 .op_flags = XTENSA_OP_LOAD, 3242 }, { 3243 .name = "l32ai", 3244 .translate = translate_ldst, 3245 .par = (const uint32_t[]){MO_TEUL, true, false}, 3246 .op_flags = XTENSA_OP_LOAD, 3247 }, { 3248 .name = "l32e", 3249 .translate = translate_l32e, 3250 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD, 3251 }, { 3252 .name = (const char * const[]) { 3253 "l32i", "l32i.n", NULL, 3254 }, 3255 .translate = translate_ldst, 3256 .par = (const uint32_t[]){MO_TEUL, false, false}, 3257 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD, 3258 }, { 3259 .name = "l32r", 3260 .translate = translate_l32r, 3261 .op_flags = XTENSA_OP_LOAD, 3262 }, { 3263 .name = "l8ui", 3264 .translate = translate_ldst, 3265 .par = (const uint32_t[]){MO_UB, false, false}, 3266 .op_flags = XTENSA_OP_LOAD, 3267 }, { 3268 .name = "lddec", 3269 .translate = translate_mac16, 3270 .par = (const uint32_t[]){MAC16_NONE, 0, -4}, 3271 .op_flags = XTENSA_OP_LOAD, 3272 }, { 3273 .name = "ldinc", 3274 .translate = translate_mac16, 3275 .par = (const uint32_t[]){MAC16_NONE, 0, 4}, 3276 .op_flags = XTENSA_OP_LOAD, 3277 }, { 3278 .name = "ldpte", 3279 .op_flags = XTENSA_OP_ILL, 3280 }, { 3281 .name = (const char * const[]) { 3282 "loop", "loop.w15", NULL, 3283 }, 3284 .translate = translate_loop, 3285 .par = (const uint32_t[]){TCG_COND_NEVER}, 3286 .op_flags = XTENSA_OP_NAME_ARRAY, 3287 }, { 3288 .name = (const char * const[]) { 3289 "loopgtz", "loopgtz.w15", NULL, 3290 }, 3291 .translate = translate_loop, 3292 .par = (const uint32_t[]){TCG_COND_GT}, 3293 .op_flags = XTENSA_OP_NAME_ARRAY, 3294 }, { 3295 .name = (const char * const[]) { 3296 "loopnez", "loopnez.w15", NULL, 3297 }, 3298 .translate = translate_loop, 3299 .par = (const uint32_t[]){TCG_COND_NE}, 3300 .op_flags = XTENSA_OP_NAME_ARRAY, 3301 }, { 3302 .name = "max", 3303 .translate = translate_smax, 3304 }, { 3305 .name = "maxu", 3306 .translate = translate_umax, 3307 }, { 3308 .name = "memw", 3309 .translate = translate_memw, 3310 }, { 3311 .name = "min", 3312 .translate = translate_smin, 3313 }, { 3314 .name = "minu", 3315 .translate = translate_umin, 3316 }, { 3317 .name = (const char * const[]) { 3318 "mov", "mov.n", NULL, 3319 }, 3320 .translate = translate_mov, 3321 .op_flags = XTENSA_OP_NAME_ARRAY, 3322 }, { 3323 .name = "moveqz", 3324 .translate = translate_movcond, 3325 .par = (const uint32_t[]){TCG_COND_EQ}, 3326 }, { 3327 .name = "movf", 3328 .translate = translate_movp, 3329 .par = (const uint32_t[]){TCG_COND_EQ}, 3330 }, { 3331 .name = "movgez", 3332 .translate = translate_movcond, 3333 .par = (const uint32_t[]){TCG_COND_GE}, 3334 }, { 3335 .name = "movi", 3336 .translate = translate_movi, 3337 }, { 3338 .name = "movi.n", 3339 .translate = translate_movi, 3340 }, { 3341 .name = "movltz", 3342 .translate = translate_movcond, 3343 .par = (const uint32_t[]){TCG_COND_LT}, 3344 }, { 3345 .name = "movnez", 3346 .translate = translate_movcond, 3347 .par = (const uint32_t[]){TCG_COND_NE}, 3348 }, { 3349 .name = "movsp", 3350 .translate = translate_movsp, 3351 .op_flags = XTENSA_OP_ALLOCA, 3352 }, { 3353 .name = "movt", 3354 .translate = translate_movp, 3355 .par = (const uint32_t[]){TCG_COND_NE}, 3356 }, { 3357 .name = "mul.aa.hh", 3358 .translate = translate_mac16, 3359 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3360 }, { 3361 .name = "mul.aa.hl", 3362 .translate = translate_mac16, 3363 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3364 }, { 3365 .name = "mul.aa.lh", 3366 .translate = translate_mac16, 3367 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3368 }, { 3369 .name = "mul.aa.ll", 3370 .translate = translate_mac16, 3371 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3372 }, { 3373 .name = "mul.ad.hh", 3374 .translate = translate_mac16, 3375 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3376 }, { 3377 .name = "mul.ad.hl", 3378 .translate = translate_mac16, 3379 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3380 }, { 3381 .name = "mul.ad.lh", 3382 .translate = translate_mac16, 3383 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3384 }, { 3385 .name = "mul.ad.ll", 3386 .translate = translate_mac16, 3387 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3388 }, { 3389 .name = "mul.da.hh", 3390 .translate = translate_mac16, 3391 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3392 }, { 3393 .name = "mul.da.hl", 3394 .translate = translate_mac16, 3395 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3396 }, { 3397 .name = "mul.da.lh", 3398 .translate = translate_mac16, 3399 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3400 }, { 3401 .name = "mul.da.ll", 3402 .translate = translate_mac16, 3403 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3404 }, { 3405 .name = "mul.dd.hh", 3406 .translate = translate_mac16, 3407 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, 3408 }, { 3409 .name = "mul.dd.hl", 3410 .translate = translate_mac16, 3411 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, 3412 }, { 3413 .name = "mul.dd.lh", 3414 .translate = translate_mac16, 3415 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, 3416 }, { 3417 .name = "mul.dd.ll", 3418 .translate = translate_mac16, 3419 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, 3420 }, { 3421 .name = "mul16s", 3422 .translate = translate_mul16, 3423 .par = (const uint32_t[]){true}, 3424 }, { 3425 .name = "mul16u", 3426 .translate = translate_mul16, 3427 .par = (const uint32_t[]){false}, 3428 }, { 3429 .name = "mula.aa.hh", 3430 .translate = translate_mac16, 3431 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3432 }, { 3433 .name = "mula.aa.hl", 3434 .translate = translate_mac16, 3435 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3436 }, { 3437 .name = "mula.aa.lh", 3438 .translate = translate_mac16, 3439 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3440 }, { 3441 .name = "mula.aa.ll", 3442 .translate = translate_mac16, 3443 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3444 }, { 3445 .name = "mula.ad.hh", 3446 .translate = translate_mac16, 3447 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3448 }, { 3449 .name = "mula.ad.hl", 3450 .translate = translate_mac16, 3451 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3452 }, { 3453 .name = "mula.ad.lh", 3454 .translate = translate_mac16, 3455 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3456 }, { 3457 .name = "mula.ad.ll", 3458 .translate = translate_mac16, 3459 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3460 }, { 3461 .name = "mula.da.hh", 3462 .translate = translate_mac16, 3463 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3464 }, { 3465 .name = "mula.da.hh.lddec", 3466 .translate = translate_mac16, 3467 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4}, 3468 }, { 3469 .name = "mula.da.hh.ldinc", 3470 .translate = translate_mac16, 3471 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4}, 3472 }, { 3473 .name = "mula.da.hl", 3474 .translate = translate_mac16, 3475 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3476 }, { 3477 .name = "mula.da.hl.lddec", 3478 .translate = translate_mac16, 3479 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4}, 3480 }, { 3481 .name = "mula.da.hl.ldinc", 3482 .translate = translate_mac16, 3483 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4}, 3484 }, { 3485 .name = "mula.da.lh", 3486 .translate = translate_mac16, 3487 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3488 }, { 3489 .name = "mula.da.lh.lddec", 3490 .translate = translate_mac16, 3491 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4}, 3492 }, { 3493 .name = "mula.da.lh.ldinc", 3494 .translate = translate_mac16, 3495 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4}, 3496 }, { 3497 .name = "mula.da.ll", 3498 .translate = translate_mac16, 3499 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3500 }, { 3501 .name = "mula.da.ll.lddec", 3502 .translate = translate_mac16, 3503 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4}, 3504 }, { 3505 .name = "mula.da.ll.ldinc", 3506 .translate = translate_mac16, 3507 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4}, 3508 }, { 3509 .name = "mula.dd.hh", 3510 .translate = translate_mac16, 3511 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, 3512 }, { 3513 .name = "mula.dd.hh.lddec", 3514 .translate = translate_mac16, 3515 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4}, 3516 }, { 3517 .name = "mula.dd.hh.ldinc", 3518 .translate = translate_mac16, 3519 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4}, 3520 }, { 3521 .name = "mula.dd.hl", 3522 .translate = translate_mac16, 3523 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, 3524 }, { 3525 .name = "mula.dd.hl.lddec", 3526 .translate = translate_mac16, 3527 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4}, 3528 }, { 3529 .name = "mula.dd.hl.ldinc", 3530 .translate = translate_mac16, 3531 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4}, 3532 }, { 3533 .name = "mula.dd.lh", 3534 .translate = translate_mac16, 3535 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, 3536 }, { 3537 .name = "mula.dd.lh.lddec", 3538 .translate = translate_mac16, 3539 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4}, 3540 }, { 3541 .name = "mula.dd.lh.ldinc", 3542 .translate = translate_mac16, 3543 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4}, 3544 }, { 3545 .name = "mula.dd.ll", 3546 .translate = translate_mac16, 3547 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, 3548 }, { 3549 .name = "mula.dd.ll.lddec", 3550 .translate = translate_mac16, 3551 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4}, 3552 }, { 3553 .name = "mula.dd.ll.ldinc", 3554 .translate = translate_mac16, 3555 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4}, 3556 }, { 3557 .name = "mull", 3558 .translate = translate_mull, 3559 }, { 3560 .name = "muls.aa.hh", 3561 .translate = translate_mac16, 3562 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3563 }, { 3564 .name = "muls.aa.hl", 3565 .translate = translate_mac16, 3566 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3567 }, { 3568 .name = "muls.aa.lh", 3569 .translate = translate_mac16, 3570 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3571 }, { 3572 .name = "muls.aa.ll", 3573 .translate = translate_mac16, 3574 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3575 }, { 3576 .name = "muls.ad.hh", 3577 .translate = translate_mac16, 3578 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3579 }, { 3580 .name = "muls.ad.hl", 3581 .translate = translate_mac16, 3582 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3583 }, { 3584 .name = "muls.ad.lh", 3585 .translate = translate_mac16, 3586 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3587 }, { 3588 .name = "muls.ad.ll", 3589 .translate = translate_mac16, 3590 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3591 }, { 3592 .name = "muls.da.hh", 3593 .translate = translate_mac16, 3594 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3595 }, { 3596 .name = "muls.da.hl", 3597 .translate = translate_mac16, 3598 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3599 }, { 3600 .name = "muls.da.lh", 3601 .translate = translate_mac16, 3602 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3603 }, { 3604 .name = "muls.da.ll", 3605 .translate = translate_mac16, 3606 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3607 }, { 3608 .name = "muls.dd.hh", 3609 .translate = translate_mac16, 3610 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, 3611 }, { 3612 .name = "muls.dd.hl", 3613 .translate = translate_mac16, 3614 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, 3615 }, { 3616 .name = "muls.dd.lh", 3617 .translate = translate_mac16, 3618 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, 3619 }, { 3620 .name = "muls.dd.ll", 3621 .translate = translate_mac16, 3622 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, 3623 }, { 3624 .name = "mulsh", 3625 .translate = translate_mulh, 3626 .par = (const uint32_t[]){true}, 3627 }, { 3628 .name = "muluh", 3629 .translate = translate_mulh, 3630 .par = (const uint32_t[]){false}, 3631 }, { 3632 .name = "neg", 3633 .translate = translate_neg, 3634 }, { 3635 .name = (const char * const[]) { 3636 "nop", "nop.n", NULL, 3637 }, 3638 .translate = translate_nop, 3639 .op_flags = XTENSA_OP_NAME_ARRAY, 3640 }, { 3641 .name = "nsa", 3642 .translate = translate_nsa, 3643 }, { 3644 .name = "nsau", 3645 .translate = translate_nsau, 3646 }, { 3647 .name = "or", 3648 .translate = translate_or, 3649 }, { 3650 .name = "orb", 3651 .translate = translate_boolean, 3652 .par = (const uint32_t[]){BOOLEAN_OR}, 3653 }, { 3654 .name = "orbc", 3655 .translate = translate_boolean, 3656 .par = (const uint32_t[]){BOOLEAN_ORC}, 3657 }, { 3658 .name = "pdtlb", 3659 .translate = translate_ptlb, 3660 .par = (const uint32_t[]){true}, 3661 .op_flags = XTENSA_OP_PRIVILEGED, 3662 }, { 3663 .name = "pitlb", 3664 .translate = translate_ptlb, 3665 .par = (const uint32_t[]){false}, 3666 .op_flags = XTENSA_OP_PRIVILEGED, 3667 }, { 3668 .name = "quos", 3669 .translate = translate_quos, 3670 .par = (const uint32_t[]){true}, 3671 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3672 }, { 3673 .name = "quou", 3674 .translate = translate_quou, 3675 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3676 }, { 3677 .name = "rdtlb0", 3678 .translate = translate_rtlb, 3679 .par = (const uint32_t[]){true, 0}, 3680 .op_flags = XTENSA_OP_PRIVILEGED, 3681 }, { 3682 .name = "rdtlb1", 3683 .translate = translate_rtlb, 3684 .par = (const uint32_t[]){true, 1}, 3685 .op_flags = XTENSA_OP_PRIVILEGED, 3686 }, { 3687 .name = "read_impwire", 3688 .translate = translate_read_impwire, 3689 }, { 3690 .name = "rems", 3691 .translate = translate_quos, 3692 .par = (const uint32_t[]){false}, 3693 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3694 }, { 3695 .name = "remu", 3696 .translate = translate_remu, 3697 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, 3698 }, { 3699 .name = "rer", 3700 .translate = translate_rer, 3701 .op_flags = XTENSA_OP_PRIVILEGED, 3702 }, { 3703 .name = (const char * const[]) { 3704 "ret", "ret.n", NULL, 3705 }, 3706 .translate = translate_ret, 3707 .op_flags = XTENSA_OP_NAME_ARRAY, 3708 }, { 3709 .name = (const char * const[]) { 3710 "retw", "retw.n", NULL, 3711 }, 3712 .translate = translate_retw, 3713 .test_ill = test_ill_retw, 3714 .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY, 3715 }, { 3716 .name = "rfdd", 3717 .op_flags = XTENSA_OP_ILL, 3718 }, { 3719 .name = "rfde", 3720 .translate = translate_rfde, 3721 .op_flags = XTENSA_OP_PRIVILEGED, 3722 }, { 3723 .name = "rfdo", 3724 .op_flags = XTENSA_OP_ILL, 3725 }, { 3726 .name = "rfe", 3727 .translate = translate_rfe, 3728 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3729 }, { 3730 .name = "rfi", 3731 .translate = translate_rfi, 3732 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3733 }, { 3734 .name = "rfwo", 3735 .translate = translate_rfw, 3736 .par = (const uint32_t[]){true}, 3737 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3738 }, { 3739 .name = "rfwu", 3740 .translate = translate_rfw, 3741 .par = (const uint32_t[]){false}, 3742 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, 3743 }, { 3744 .name = "ritlb0", 3745 .translate = translate_rtlb, 3746 .par = (const uint32_t[]){false, 0}, 3747 .op_flags = XTENSA_OP_PRIVILEGED, 3748 }, { 3749 .name = "ritlb1", 3750 .translate = translate_rtlb, 3751 .par = (const uint32_t[]){false, 1}, 3752 .op_flags = XTENSA_OP_PRIVILEGED, 3753 }, { 3754 .name = "rotw", 3755 .translate = translate_rotw, 3756 .op_flags = XTENSA_OP_PRIVILEGED | 3757 XTENSA_OP_EXIT_TB_M1 | 3758 XTENSA_OP_SYNC_REGISTER_WINDOW, 3759 }, { 3760 .name = "rsil", 3761 .translate = translate_rsil, 3762 .op_flags = 3763 XTENSA_OP_PRIVILEGED | 3764 XTENSA_OP_EXIT_TB_0 | 3765 XTENSA_OP_CHECK_INTERRUPTS, 3766 }, { 3767 .name = "rsr.176", 3768 .translate = translate_rsr, 3769 .test_ill = test_ill_rsr, 3770 .par = (const uint32_t[]){176}, 3771 .op_flags = XTENSA_OP_PRIVILEGED, 3772 }, { 3773 .name = "rsr.208", 3774 .translate = translate_rsr, 3775 .test_ill = test_ill_rsr, 3776 .par = (const uint32_t[]){208}, 3777 .op_flags = XTENSA_OP_PRIVILEGED, 3778 }, { 3779 .name = "rsr.acchi", 3780 .translate = translate_rsr, 3781 .test_ill = test_ill_rsr, 3782 .par = (const uint32_t[]){ACCHI}, 3783 }, { 3784 .name = "rsr.acclo", 3785 .translate = translate_rsr, 3786 .test_ill = test_ill_rsr, 3787 .par = (const uint32_t[]){ACCLO}, 3788 }, { 3789 .name = "rsr.atomctl", 3790 .translate = translate_rsr, 3791 .test_ill = test_ill_rsr, 3792 .par = (const uint32_t[]){ATOMCTL}, 3793 .op_flags = XTENSA_OP_PRIVILEGED, 3794 }, { 3795 .name = "rsr.br", 3796 .translate = translate_rsr, 3797 .test_ill = test_ill_rsr, 3798 .par = (const uint32_t[]){BR}, 3799 }, { 3800 .name = "rsr.cacheattr", 3801 .translate = translate_rsr, 3802 .test_ill = test_ill_rsr, 3803 .par = (const uint32_t[]){CACHEATTR}, 3804 .op_flags = XTENSA_OP_PRIVILEGED, 3805 }, { 3806 .name = "rsr.ccompare0", 3807 .translate = translate_rsr, 3808 .test_ill = test_ill_rsr, 3809 .par = (const uint32_t[]){CCOMPARE}, 3810 .op_flags = XTENSA_OP_PRIVILEGED, 3811 }, { 3812 .name = "rsr.ccompare1", 3813 .translate = translate_rsr, 3814 .test_ill = test_ill_rsr, 3815 .par = (const uint32_t[]){CCOMPARE + 1}, 3816 .op_flags = XTENSA_OP_PRIVILEGED, 3817 }, { 3818 .name = "rsr.ccompare2", 3819 .translate = translate_rsr, 3820 .test_ill = test_ill_rsr, 3821 .par = (const uint32_t[]){CCOMPARE + 2}, 3822 .op_flags = XTENSA_OP_PRIVILEGED, 3823 }, { 3824 .name = "rsr.ccount", 3825 .translate = translate_rsr, 3826 .test_ill = test_ill_rsr, 3827 .par = (const uint32_t[]){CCOUNT}, 3828 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 3829 }, { 3830 .name = "rsr.configid0", 3831 .translate = translate_rsr, 3832 .test_ill = test_ill_rsr, 3833 .par = (const uint32_t[]){CONFIGID0}, 3834 .op_flags = XTENSA_OP_PRIVILEGED, 3835 }, { 3836 .name = "rsr.configid1", 3837 .translate = translate_rsr, 3838 .test_ill = test_ill_rsr, 3839 .par = (const uint32_t[]){CONFIGID1}, 3840 .op_flags = XTENSA_OP_PRIVILEGED, 3841 }, { 3842 .name = "rsr.cpenable", 3843 .translate = translate_rsr, 3844 .test_ill = test_ill_rsr, 3845 .par = (const uint32_t[]){CPENABLE}, 3846 .op_flags = XTENSA_OP_PRIVILEGED, 3847 }, { 3848 .name = "rsr.dbreaka0", 3849 .translate = translate_rsr, 3850 .test_ill = test_ill_rsr, 3851 .par = (const uint32_t[]){DBREAKA}, 3852 .op_flags = XTENSA_OP_PRIVILEGED, 3853 }, { 3854 .name = "rsr.dbreaka1", 3855 .translate = translate_rsr, 3856 .test_ill = test_ill_rsr, 3857 .par = (const uint32_t[]){DBREAKA + 1}, 3858 .op_flags = XTENSA_OP_PRIVILEGED, 3859 }, { 3860 .name = "rsr.dbreakc0", 3861 .translate = translate_rsr, 3862 .test_ill = test_ill_rsr, 3863 .par = (const uint32_t[]){DBREAKC}, 3864 .op_flags = XTENSA_OP_PRIVILEGED, 3865 }, { 3866 .name = "rsr.dbreakc1", 3867 .translate = translate_rsr, 3868 .test_ill = test_ill_rsr, 3869 .par = (const uint32_t[]){DBREAKC + 1}, 3870 .op_flags = XTENSA_OP_PRIVILEGED, 3871 }, { 3872 .name = "rsr.ddr", 3873 .translate = translate_rsr, 3874 .test_ill = test_ill_rsr, 3875 .par = (const uint32_t[]){DDR}, 3876 .op_flags = XTENSA_OP_PRIVILEGED, 3877 }, { 3878 .name = "rsr.debugcause", 3879 .translate = translate_rsr, 3880 .test_ill = test_ill_rsr, 3881 .par = (const uint32_t[]){DEBUGCAUSE}, 3882 .op_flags = XTENSA_OP_PRIVILEGED, 3883 }, { 3884 .name = "rsr.depc", 3885 .translate = translate_rsr, 3886 .test_ill = test_ill_rsr, 3887 .par = (const uint32_t[]){DEPC}, 3888 .op_flags = XTENSA_OP_PRIVILEGED, 3889 }, { 3890 .name = "rsr.dtlbcfg", 3891 .translate = translate_rsr, 3892 .test_ill = test_ill_rsr, 3893 .par = (const uint32_t[]){DTLBCFG}, 3894 .op_flags = XTENSA_OP_PRIVILEGED, 3895 }, { 3896 .name = "rsr.epc1", 3897 .translate = translate_rsr, 3898 .test_ill = test_ill_rsr, 3899 .par = (const uint32_t[]){EPC1}, 3900 .op_flags = XTENSA_OP_PRIVILEGED, 3901 }, { 3902 .name = "rsr.epc2", 3903 .translate = translate_rsr, 3904 .test_ill = test_ill_rsr, 3905 .par = (const uint32_t[]){EPC1 + 1}, 3906 .op_flags = XTENSA_OP_PRIVILEGED, 3907 }, { 3908 .name = "rsr.epc3", 3909 .translate = translate_rsr, 3910 .test_ill = test_ill_rsr, 3911 .par = (const uint32_t[]){EPC1 + 2}, 3912 .op_flags = XTENSA_OP_PRIVILEGED, 3913 }, { 3914 .name = "rsr.epc4", 3915 .translate = translate_rsr, 3916 .test_ill = test_ill_rsr, 3917 .par = (const uint32_t[]){EPC1 + 3}, 3918 .op_flags = XTENSA_OP_PRIVILEGED, 3919 }, { 3920 .name = "rsr.epc5", 3921 .translate = translate_rsr, 3922 .test_ill = test_ill_rsr, 3923 .par = (const uint32_t[]){EPC1 + 4}, 3924 .op_flags = XTENSA_OP_PRIVILEGED, 3925 }, { 3926 .name = "rsr.epc6", 3927 .translate = translate_rsr, 3928 .test_ill = test_ill_rsr, 3929 .par = (const uint32_t[]){EPC1 + 5}, 3930 .op_flags = XTENSA_OP_PRIVILEGED, 3931 }, { 3932 .name = "rsr.epc7", 3933 .translate = translate_rsr, 3934 .test_ill = test_ill_rsr, 3935 .par = (const uint32_t[]){EPC1 + 6}, 3936 .op_flags = XTENSA_OP_PRIVILEGED, 3937 }, { 3938 .name = "rsr.eps2", 3939 .translate = translate_rsr, 3940 .test_ill = test_ill_rsr, 3941 .par = (const uint32_t[]){EPS2}, 3942 .op_flags = XTENSA_OP_PRIVILEGED, 3943 }, { 3944 .name = "rsr.eps3", 3945 .translate = translate_rsr, 3946 .test_ill = test_ill_rsr, 3947 .par = (const uint32_t[]){EPS2 + 1}, 3948 .op_flags = XTENSA_OP_PRIVILEGED, 3949 }, { 3950 .name = "rsr.eps4", 3951 .translate = translate_rsr, 3952 .test_ill = test_ill_rsr, 3953 .par = (const uint32_t[]){EPS2 + 2}, 3954 .op_flags = XTENSA_OP_PRIVILEGED, 3955 }, { 3956 .name = "rsr.eps5", 3957 .translate = translate_rsr, 3958 .test_ill = test_ill_rsr, 3959 .par = (const uint32_t[]){EPS2 + 3}, 3960 .op_flags = XTENSA_OP_PRIVILEGED, 3961 }, { 3962 .name = "rsr.eps6", 3963 .translate = translate_rsr, 3964 .test_ill = test_ill_rsr, 3965 .par = (const uint32_t[]){EPS2 + 4}, 3966 .op_flags = XTENSA_OP_PRIVILEGED, 3967 }, { 3968 .name = "rsr.eps7", 3969 .translate = translate_rsr, 3970 .test_ill = test_ill_rsr, 3971 .par = (const uint32_t[]){EPS2 + 5}, 3972 .op_flags = XTENSA_OP_PRIVILEGED, 3973 }, { 3974 .name = "rsr.exccause", 3975 .translate = translate_rsr, 3976 .test_ill = test_ill_rsr, 3977 .par = (const uint32_t[]){EXCCAUSE}, 3978 .op_flags = XTENSA_OP_PRIVILEGED, 3979 }, { 3980 .name = "rsr.excsave1", 3981 .translate = translate_rsr, 3982 .test_ill = test_ill_rsr, 3983 .par = (const uint32_t[]){EXCSAVE1}, 3984 .op_flags = XTENSA_OP_PRIVILEGED, 3985 }, { 3986 .name = "rsr.excsave2", 3987 .translate = translate_rsr, 3988 .test_ill = test_ill_rsr, 3989 .par = (const uint32_t[]){EXCSAVE1 + 1}, 3990 .op_flags = XTENSA_OP_PRIVILEGED, 3991 }, { 3992 .name = "rsr.excsave3", 3993 .translate = translate_rsr, 3994 .test_ill = test_ill_rsr, 3995 .par = (const uint32_t[]){EXCSAVE1 + 2}, 3996 .op_flags = XTENSA_OP_PRIVILEGED, 3997 }, { 3998 .name = "rsr.excsave4", 3999 .translate = translate_rsr, 4000 .test_ill = test_ill_rsr, 4001 .par = (const uint32_t[]){EXCSAVE1 + 3}, 4002 .op_flags = XTENSA_OP_PRIVILEGED, 4003 }, { 4004 .name = "rsr.excsave5", 4005 .translate = translate_rsr, 4006 .test_ill = test_ill_rsr, 4007 .par = (const uint32_t[]){EXCSAVE1 + 4}, 4008 .op_flags = XTENSA_OP_PRIVILEGED, 4009 }, { 4010 .name = "rsr.excsave6", 4011 .translate = translate_rsr, 4012 .test_ill = test_ill_rsr, 4013 .par = (const uint32_t[]){EXCSAVE1 + 5}, 4014 .op_flags = XTENSA_OP_PRIVILEGED, 4015 }, { 4016 .name = "rsr.excsave7", 4017 .translate = translate_rsr, 4018 .test_ill = test_ill_rsr, 4019 .par = (const uint32_t[]){EXCSAVE1 + 6}, 4020 .op_flags = XTENSA_OP_PRIVILEGED, 4021 }, { 4022 .name = "rsr.excvaddr", 4023 .translate = translate_rsr, 4024 .test_ill = test_ill_rsr, 4025 .par = (const uint32_t[]){EXCVADDR}, 4026 .op_flags = XTENSA_OP_PRIVILEGED, 4027 }, { 4028 .name = "rsr.ibreaka0", 4029 .translate = translate_rsr, 4030 .test_ill = test_ill_rsr, 4031 .par = (const uint32_t[]){IBREAKA}, 4032 .op_flags = XTENSA_OP_PRIVILEGED, 4033 }, { 4034 .name = "rsr.ibreaka1", 4035 .translate = translate_rsr, 4036 .test_ill = test_ill_rsr, 4037 .par = (const uint32_t[]){IBREAKA + 1}, 4038 .op_flags = XTENSA_OP_PRIVILEGED, 4039 }, { 4040 .name = "rsr.ibreakenable", 4041 .translate = translate_rsr, 4042 .test_ill = test_ill_rsr, 4043 .par = (const uint32_t[]){IBREAKENABLE}, 4044 .op_flags = XTENSA_OP_PRIVILEGED, 4045 }, { 4046 .name = "rsr.icount", 4047 .translate = translate_rsr, 4048 .test_ill = test_ill_rsr, 4049 .par = (const uint32_t[]){ICOUNT}, 4050 .op_flags = XTENSA_OP_PRIVILEGED, 4051 }, { 4052 .name = "rsr.icountlevel", 4053 .translate = translate_rsr, 4054 .test_ill = test_ill_rsr, 4055 .par = (const uint32_t[]){ICOUNTLEVEL}, 4056 .op_flags = XTENSA_OP_PRIVILEGED, 4057 }, { 4058 .name = "rsr.intclear", 4059 .translate = translate_rsr, 4060 .test_ill = test_ill_rsr, 4061 .par = (const uint32_t[]){INTCLEAR}, 4062 .op_flags = XTENSA_OP_PRIVILEGED, 4063 }, { 4064 .name = "rsr.intenable", 4065 .translate = translate_rsr, 4066 .test_ill = test_ill_rsr, 4067 .par = (const uint32_t[]){INTENABLE}, 4068 .op_flags = XTENSA_OP_PRIVILEGED, 4069 }, { 4070 .name = "rsr.interrupt", 4071 .translate = translate_rsr, 4072 .test_ill = test_ill_rsr, 4073 .par = (const uint32_t[]){INTSET}, 4074 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4075 }, { 4076 .name = "rsr.intset", 4077 .translate = translate_rsr, 4078 .test_ill = test_ill_rsr, 4079 .par = (const uint32_t[]){INTSET}, 4080 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4081 }, { 4082 .name = "rsr.itlbcfg", 4083 .translate = translate_rsr, 4084 .test_ill = test_ill_rsr, 4085 .par = (const uint32_t[]){ITLBCFG}, 4086 .op_flags = XTENSA_OP_PRIVILEGED, 4087 }, { 4088 .name = "rsr.lbeg", 4089 .translate = translate_rsr, 4090 .test_ill = test_ill_rsr, 4091 .par = (const uint32_t[]){LBEG}, 4092 }, { 4093 .name = "rsr.lcount", 4094 .translate = translate_rsr, 4095 .test_ill = test_ill_rsr, 4096 .par = (const uint32_t[]){LCOUNT}, 4097 }, { 4098 .name = "rsr.lend", 4099 .translate = translate_rsr, 4100 .test_ill = test_ill_rsr, 4101 .par = (const uint32_t[]){LEND}, 4102 }, { 4103 .name = "rsr.litbase", 4104 .translate = translate_rsr, 4105 .test_ill = test_ill_rsr, 4106 .par = (const uint32_t[]){LITBASE}, 4107 }, { 4108 .name = "rsr.m0", 4109 .translate = translate_rsr, 4110 .test_ill = test_ill_rsr, 4111 .par = (const uint32_t[]){MR}, 4112 }, { 4113 .name = "rsr.m1", 4114 .translate = translate_rsr, 4115 .test_ill = test_ill_rsr, 4116 .par = (const uint32_t[]){MR + 1}, 4117 }, { 4118 .name = "rsr.m2", 4119 .translate = translate_rsr, 4120 .test_ill = test_ill_rsr, 4121 .par = (const uint32_t[]){MR + 2}, 4122 }, { 4123 .name = "rsr.m3", 4124 .translate = translate_rsr, 4125 .test_ill = test_ill_rsr, 4126 .par = (const uint32_t[]){MR + 3}, 4127 }, { 4128 .name = "rsr.memctl", 4129 .translate = translate_rsr, 4130 .test_ill = test_ill_rsr, 4131 .par = (const uint32_t[]){MEMCTL}, 4132 .op_flags = XTENSA_OP_PRIVILEGED, 4133 }, { 4134 .name = "rsr.misc0", 4135 .translate = translate_rsr, 4136 .test_ill = test_ill_rsr, 4137 .par = (const uint32_t[]){MISC}, 4138 .op_flags = XTENSA_OP_PRIVILEGED, 4139 }, { 4140 .name = "rsr.misc1", 4141 .translate = translate_rsr, 4142 .test_ill = test_ill_rsr, 4143 .par = (const uint32_t[]){MISC + 1}, 4144 .op_flags = XTENSA_OP_PRIVILEGED, 4145 }, { 4146 .name = "rsr.misc2", 4147 .translate = translate_rsr, 4148 .test_ill = test_ill_rsr, 4149 .par = (const uint32_t[]){MISC + 2}, 4150 .op_flags = XTENSA_OP_PRIVILEGED, 4151 }, { 4152 .name = "rsr.misc3", 4153 .translate = translate_rsr, 4154 .test_ill = test_ill_rsr, 4155 .par = (const uint32_t[]){MISC + 3}, 4156 .op_flags = XTENSA_OP_PRIVILEGED, 4157 }, { 4158 .name = "rsr.prefctl", 4159 .translate = translate_rsr, 4160 .test_ill = test_ill_rsr, 4161 .par = (const uint32_t[]){PREFCTL}, 4162 }, { 4163 .name = "rsr.prid", 4164 .translate = translate_rsr, 4165 .test_ill = test_ill_rsr, 4166 .par = (const uint32_t[]){PRID}, 4167 .op_flags = XTENSA_OP_PRIVILEGED, 4168 }, { 4169 .name = "rsr.ps", 4170 .translate = translate_rsr, 4171 .test_ill = test_ill_rsr, 4172 .par = (const uint32_t[]){PS}, 4173 .op_flags = XTENSA_OP_PRIVILEGED, 4174 }, { 4175 .name = "rsr.ptevaddr", 4176 .translate = translate_rsr, 4177 .test_ill = test_ill_rsr, 4178 .par = (const uint32_t[]){PTEVADDR}, 4179 .op_flags = XTENSA_OP_PRIVILEGED, 4180 }, { 4181 .name = "rsr.rasid", 4182 .translate = translate_rsr, 4183 .test_ill = test_ill_rsr, 4184 .par = (const uint32_t[]){RASID}, 4185 .op_flags = XTENSA_OP_PRIVILEGED, 4186 }, { 4187 .name = "rsr.sar", 4188 .translate = translate_rsr, 4189 .test_ill = test_ill_rsr, 4190 .par = (const uint32_t[]){SAR}, 4191 }, { 4192 .name = "rsr.scompare1", 4193 .translate = translate_rsr, 4194 .test_ill = test_ill_rsr, 4195 .par = (const uint32_t[]){SCOMPARE1}, 4196 }, { 4197 .name = "rsr.vecbase", 4198 .translate = translate_rsr, 4199 .test_ill = test_ill_rsr, 4200 .par = (const uint32_t[]){VECBASE}, 4201 .op_flags = XTENSA_OP_PRIVILEGED, 4202 }, { 4203 .name = "rsr.windowbase", 4204 .translate = translate_rsr, 4205 .test_ill = test_ill_rsr, 4206 .par = (const uint32_t[]){WINDOW_BASE}, 4207 .op_flags = XTENSA_OP_PRIVILEGED, 4208 }, { 4209 .name = "rsr.windowstart", 4210 .translate = translate_rsr, 4211 .test_ill = test_ill_rsr, 4212 .par = (const uint32_t[]){WINDOW_START}, 4213 .op_flags = XTENSA_OP_PRIVILEGED, 4214 }, { 4215 .name = "rsync", 4216 .translate = translate_nop, 4217 }, { 4218 .name = "rur.expstate", 4219 .translate = translate_rur, 4220 .par = (const uint32_t[]){EXPSTATE}, 4221 }, { 4222 .name = "rur.fcr", 4223 .translate = translate_rur, 4224 .par = (const uint32_t[]){FCR}, 4225 .coprocessor = 0x1, 4226 }, { 4227 .name = "rur.fsr", 4228 .translate = translate_rur, 4229 .par = (const uint32_t[]){FSR}, 4230 .coprocessor = 0x1, 4231 }, { 4232 .name = "rur.threadptr", 4233 .translate = translate_rur, 4234 .par = (const uint32_t[]){THREADPTR}, 4235 }, { 4236 .name = "s16i", 4237 .translate = translate_ldst, 4238 .par = (const uint32_t[]){MO_TEUW, false, true}, 4239 .op_flags = XTENSA_OP_STORE, 4240 }, { 4241 .name = "s32c1i", 4242 .translate = translate_s32c1i, 4243 .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE, 4244 }, { 4245 .name = "s32e", 4246 .translate = translate_s32e, 4247 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE, 4248 }, { 4249 .name = (const char * const[]) { 4250 "s32i", "s32i.n", "s32nb", NULL, 4251 }, 4252 .translate = translate_ldst, 4253 .par = (const uint32_t[]){MO_TEUL, false, true}, 4254 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE, 4255 }, { 4256 .name = "s32ri", 4257 .translate = translate_ldst, 4258 .par = (const uint32_t[]){MO_TEUL, true, true}, 4259 .op_flags = XTENSA_OP_STORE, 4260 }, { 4261 .name = "s8i", 4262 .translate = translate_ldst, 4263 .par = (const uint32_t[]){MO_UB, false, true}, 4264 .op_flags = XTENSA_OP_STORE, 4265 }, { 4266 .name = "salt", 4267 .translate = translate_salt, 4268 .par = (const uint32_t[]){TCG_COND_LT}, 4269 }, { 4270 .name = "saltu", 4271 .translate = translate_salt, 4272 .par = (const uint32_t[]){TCG_COND_LTU}, 4273 }, { 4274 .name = "setb_expstate", 4275 .translate = translate_setb_expstate, 4276 }, { 4277 .name = "sext", 4278 .translate = translate_sext, 4279 }, { 4280 .name = "simcall", 4281 .translate = translate_simcall, 4282 .test_ill = test_ill_simcall, 4283 .op_flags = XTENSA_OP_PRIVILEGED, 4284 }, { 4285 .name = "sll", 4286 .translate = translate_sll, 4287 }, { 4288 .name = "slli", 4289 .translate = translate_slli, 4290 }, { 4291 .name = "sra", 4292 .translate = translate_sra, 4293 }, { 4294 .name = "srai", 4295 .translate = translate_srai, 4296 }, { 4297 .name = "src", 4298 .translate = translate_src, 4299 }, { 4300 .name = "srl", 4301 .translate = translate_srl, 4302 }, { 4303 .name = "srli", 4304 .translate = translate_srli, 4305 }, { 4306 .name = "ssa8b", 4307 .translate = translate_ssa8b, 4308 }, { 4309 .name = "ssa8l", 4310 .translate = translate_ssa8l, 4311 }, { 4312 .name = "ssai", 4313 .translate = translate_ssai, 4314 }, { 4315 .name = "ssl", 4316 .translate = translate_ssl, 4317 }, { 4318 .name = "ssr", 4319 .translate = translate_ssr, 4320 }, { 4321 .name = "sub", 4322 .translate = translate_sub, 4323 }, { 4324 .name = "subx2", 4325 .translate = translate_subx, 4326 .par = (const uint32_t[]){1}, 4327 }, { 4328 .name = "subx4", 4329 .translate = translate_subx, 4330 .par = (const uint32_t[]){2}, 4331 }, { 4332 .name = "subx8", 4333 .translate = translate_subx, 4334 .par = (const uint32_t[]){3}, 4335 }, { 4336 .name = "syscall", 4337 .op_flags = XTENSA_OP_SYSCALL, 4338 }, { 4339 .name = "umul.aa.hh", 4340 .translate = translate_mac16, 4341 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0}, 4342 }, { 4343 .name = "umul.aa.hl", 4344 .translate = translate_mac16, 4345 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0}, 4346 }, { 4347 .name = "umul.aa.lh", 4348 .translate = translate_mac16, 4349 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0}, 4350 }, { 4351 .name = "umul.aa.ll", 4352 .translate = translate_mac16, 4353 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0}, 4354 }, { 4355 .name = "waiti", 4356 .translate = translate_waiti, 4357 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4358 }, { 4359 .name = "wdtlb", 4360 .translate = translate_wtlb, 4361 .par = (const uint32_t[]){true}, 4362 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4363 }, { 4364 .name = "wer", 4365 .translate = translate_wer, 4366 .op_flags = XTENSA_OP_PRIVILEGED, 4367 }, { 4368 .name = "witlb", 4369 .translate = translate_wtlb, 4370 .par = (const uint32_t[]){false}, 4371 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4372 }, { 4373 .name = "wrmsk_expstate", 4374 .translate = translate_wrmsk_expstate, 4375 }, { 4376 .name = "wsr.176", 4377 .translate = translate_wsr, 4378 .test_ill = test_ill_wsr, 4379 .par = (const uint32_t[]){176}, 4380 .op_flags = XTENSA_OP_PRIVILEGED, 4381 }, { 4382 .name = "wsr.208", 4383 .translate = translate_wsr, 4384 .test_ill = test_ill_wsr, 4385 .par = (const uint32_t[]){208}, 4386 .op_flags = XTENSA_OP_PRIVILEGED, 4387 }, { 4388 .name = "wsr.acchi", 4389 .translate = translate_wsr, 4390 .test_ill = test_ill_wsr, 4391 .par = (const uint32_t[]){ACCHI}, 4392 }, { 4393 .name = "wsr.acclo", 4394 .translate = translate_wsr, 4395 .test_ill = test_ill_wsr, 4396 .par = (const uint32_t[]){ACCLO}, 4397 }, { 4398 .name = "wsr.atomctl", 4399 .translate = translate_wsr, 4400 .test_ill = test_ill_wsr, 4401 .par = (const uint32_t[]){ATOMCTL}, 4402 .op_flags = XTENSA_OP_PRIVILEGED, 4403 }, { 4404 .name = "wsr.br", 4405 .translate = translate_wsr, 4406 .test_ill = test_ill_wsr, 4407 .par = (const uint32_t[]){BR}, 4408 }, { 4409 .name = "wsr.cacheattr", 4410 .translate = translate_wsr, 4411 .test_ill = test_ill_wsr, 4412 .par = (const uint32_t[]){CACHEATTR}, 4413 .op_flags = XTENSA_OP_PRIVILEGED, 4414 }, { 4415 .name = "wsr.ccompare0", 4416 .translate = translate_wsr, 4417 .test_ill = test_ill_wsr, 4418 .par = (const uint32_t[]){CCOMPARE}, 4419 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4420 }, { 4421 .name = "wsr.ccompare1", 4422 .translate = translate_wsr, 4423 .test_ill = test_ill_wsr, 4424 .par = (const uint32_t[]){CCOMPARE + 1}, 4425 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4426 }, { 4427 .name = "wsr.ccompare2", 4428 .translate = translate_wsr, 4429 .test_ill = test_ill_wsr, 4430 .par = (const uint32_t[]){CCOMPARE + 2}, 4431 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4432 }, { 4433 .name = "wsr.ccount", 4434 .translate = translate_wsr, 4435 .test_ill = test_ill_wsr, 4436 .par = (const uint32_t[]){CCOUNT}, 4437 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4438 }, { 4439 .name = "wsr.configid0", 4440 .translate = translate_wsr, 4441 .test_ill = test_ill_wsr, 4442 .par = (const uint32_t[]){CONFIGID0}, 4443 .op_flags = XTENSA_OP_PRIVILEGED, 4444 }, { 4445 .name = "wsr.configid1", 4446 .translate = translate_wsr, 4447 .test_ill = test_ill_wsr, 4448 .par = (const uint32_t[]){CONFIGID1}, 4449 .op_flags = XTENSA_OP_PRIVILEGED, 4450 }, { 4451 .name = "wsr.cpenable", 4452 .translate = translate_wsr, 4453 .test_ill = test_ill_wsr, 4454 .par = (const uint32_t[]){CPENABLE}, 4455 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4456 }, { 4457 .name = "wsr.dbreaka0", 4458 .translate = translate_wsr, 4459 .test_ill = test_ill_wsr, 4460 .par = (const uint32_t[]){DBREAKA}, 4461 .op_flags = XTENSA_OP_PRIVILEGED, 4462 }, { 4463 .name = "wsr.dbreaka1", 4464 .translate = translate_wsr, 4465 .test_ill = test_ill_wsr, 4466 .par = (const uint32_t[]){DBREAKA + 1}, 4467 .op_flags = XTENSA_OP_PRIVILEGED, 4468 }, { 4469 .name = "wsr.dbreakc0", 4470 .translate = translate_wsr, 4471 .test_ill = test_ill_wsr, 4472 .par = (const uint32_t[]){DBREAKC}, 4473 .op_flags = XTENSA_OP_PRIVILEGED, 4474 }, { 4475 .name = "wsr.dbreakc1", 4476 .translate = translate_wsr, 4477 .test_ill = test_ill_wsr, 4478 .par = (const uint32_t[]){DBREAKC + 1}, 4479 .op_flags = XTENSA_OP_PRIVILEGED, 4480 }, { 4481 .name = "wsr.ddr", 4482 .translate = translate_wsr, 4483 .test_ill = test_ill_wsr, 4484 .par = (const uint32_t[]){DDR}, 4485 .op_flags = XTENSA_OP_PRIVILEGED, 4486 }, { 4487 .name = "wsr.debugcause", 4488 .translate = translate_wsr, 4489 .test_ill = test_ill_wsr, 4490 .par = (const uint32_t[]){DEBUGCAUSE}, 4491 .op_flags = XTENSA_OP_PRIVILEGED, 4492 }, { 4493 .name = "wsr.depc", 4494 .translate = translate_wsr, 4495 .test_ill = test_ill_wsr, 4496 .par = (const uint32_t[]){DEPC}, 4497 .op_flags = XTENSA_OP_PRIVILEGED, 4498 }, { 4499 .name = "wsr.dtlbcfg", 4500 .translate = translate_wsr, 4501 .test_ill = test_ill_wsr, 4502 .par = (const uint32_t[]){DTLBCFG}, 4503 .op_flags = XTENSA_OP_PRIVILEGED, 4504 }, { 4505 .name = "wsr.epc1", 4506 .translate = translate_wsr, 4507 .test_ill = test_ill_wsr, 4508 .par = (const uint32_t[]){EPC1}, 4509 .op_flags = XTENSA_OP_PRIVILEGED, 4510 }, { 4511 .name = "wsr.epc2", 4512 .translate = translate_wsr, 4513 .test_ill = test_ill_wsr, 4514 .par = (const uint32_t[]){EPC1 + 1}, 4515 .op_flags = XTENSA_OP_PRIVILEGED, 4516 }, { 4517 .name = "wsr.epc3", 4518 .translate = translate_wsr, 4519 .test_ill = test_ill_wsr, 4520 .par = (const uint32_t[]){EPC1 + 2}, 4521 .op_flags = XTENSA_OP_PRIVILEGED, 4522 }, { 4523 .name = "wsr.epc4", 4524 .translate = translate_wsr, 4525 .test_ill = test_ill_wsr, 4526 .par = (const uint32_t[]){EPC1 + 3}, 4527 .op_flags = XTENSA_OP_PRIVILEGED, 4528 }, { 4529 .name = "wsr.epc5", 4530 .translate = translate_wsr, 4531 .test_ill = test_ill_wsr, 4532 .par = (const uint32_t[]){EPC1 + 4}, 4533 .op_flags = XTENSA_OP_PRIVILEGED, 4534 }, { 4535 .name = "wsr.epc6", 4536 .translate = translate_wsr, 4537 .test_ill = test_ill_wsr, 4538 .par = (const uint32_t[]){EPC1 + 5}, 4539 .op_flags = XTENSA_OP_PRIVILEGED, 4540 }, { 4541 .name = "wsr.epc7", 4542 .translate = translate_wsr, 4543 .test_ill = test_ill_wsr, 4544 .par = (const uint32_t[]){EPC1 + 6}, 4545 .op_flags = XTENSA_OP_PRIVILEGED, 4546 }, { 4547 .name = "wsr.eps2", 4548 .translate = translate_wsr, 4549 .test_ill = test_ill_wsr, 4550 .par = (const uint32_t[]){EPS2}, 4551 .op_flags = XTENSA_OP_PRIVILEGED, 4552 }, { 4553 .name = "wsr.eps3", 4554 .translate = translate_wsr, 4555 .test_ill = test_ill_wsr, 4556 .par = (const uint32_t[]){EPS2 + 1}, 4557 .op_flags = XTENSA_OP_PRIVILEGED, 4558 }, { 4559 .name = "wsr.eps4", 4560 .translate = translate_wsr, 4561 .test_ill = test_ill_wsr, 4562 .par = (const uint32_t[]){EPS2 + 2}, 4563 .op_flags = XTENSA_OP_PRIVILEGED, 4564 }, { 4565 .name = "wsr.eps5", 4566 .translate = translate_wsr, 4567 .test_ill = test_ill_wsr, 4568 .par = (const uint32_t[]){EPS2 + 3}, 4569 .op_flags = XTENSA_OP_PRIVILEGED, 4570 }, { 4571 .name = "wsr.eps6", 4572 .translate = translate_wsr, 4573 .test_ill = test_ill_wsr, 4574 .par = (const uint32_t[]){EPS2 + 4}, 4575 .op_flags = XTENSA_OP_PRIVILEGED, 4576 }, { 4577 .name = "wsr.eps7", 4578 .translate = translate_wsr, 4579 .test_ill = test_ill_wsr, 4580 .par = (const uint32_t[]){EPS2 + 5}, 4581 .op_flags = XTENSA_OP_PRIVILEGED, 4582 }, { 4583 .name = "wsr.exccause", 4584 .translate = translate_wsr, 4585 .test_ill = test_ill_wsr, 4586 .par = (const uint32_t[]){EXCCAUSE}, 4587 .op_flags = XTENSA_OP_PRIVILEGED, 4588 }, { 4589 .name = "wsr.excsave1", 4590 .translate = translate_wsr, 4591 .test_ill = test_ill_wsr, 4592 .par = (const uint32_t[]){EXCSAVE1}, 4593 .op_flags = XTENSA_OP_PRIVILEGED, 4594 }, { 4595 .name = "wsr.excsave2", 4596 .translate = translate_wsr, 4597 .test_ill = test_ill_wsr, 4598 .par = (const uint32_t[]){EXCSAVE1 + 1}, 4599 .op_flags = XTENSA_OP_PRIVILEGED, 4600 }, { 4601 .name = "wsr.excsave3", 4602 .translate = translate_wsr, 4603 .test_ill = test_ill_wsr, 4604 .par = (const uint32_t[]){EXCSAVE1 + 2}, 4605 .op_flags = XTENSA_OP_PRIVILEGED, 4606 }, { 4607 .name = "wsr.excsave4", 4608 .translate = translate_wsr, 4609 .test_ill = test_ill_wsr, 4610 .par = (const uint32_t[]){EXCSAVE1 + 3}, 4611 .op_flags = XTENSA_OP_PRIVILEGED, 4612 }, { 4613 .name = "wsr.excsave5", 4614 .translate = translate_wsr, 4615 .test_ill = test_ill_wsr, 4616 .par = (const uint32_t[]){EXCSAVE1 + 4}, 4617 .op_flags = XTENSA_OP_PRIVILEGED, 4618 }, { 4619 .name = "wsr.excsave6", 4620 .translate = translate_wsr, 4621 .test_ill = test_ill_wsr, 4622 .par = (const uint32_t[]){EXCSAVE1 + 5}, 4623 .op_flags = XTENSA_OP_PRIVILEGED, 4624 }, { 4625 .name = "wsr.excsave7", 4626 .translate = translate_wsr, 4627 .test_ill = test_ill_wsr, 4628 .par = (const uint32_t[]){EXCSAVE1 + 6}, 4629 .op_flags = XTENSA_OP_PRIVILEGED, 4630 }, { 4631 .name = "wsr.excvaddr", 4632 .translate = translate_wsr, 4633 .test_ill = test_ill_wsr, 4634 .par = (const uint32_t[]){EXCVADDR}, 4635 .op_flags = XTENSA_OP_PRIVILEGED, 4636 }, { 4637 .name = "wsr.ibreaka0", 4638 .translate = translate_wsr, 4639 .test_ill = test_ill_wsr, 4640 .par = (const uint32_t[]){IBREAKA}, 4641 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4642 }, { 4643 .name = "wsr.ibreaka1", 4644 .translate = translate_wsr, 4645 .test_ill = test_ill_wsr, 4646 .par = (const uint32_t[]){IBREAKA + 1}, 4647 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4648 }, { 4649 .name = "wsr.ibreakenable", 4650 .translate = translate_wsr, 4651 .test_ill = test_ill_wsr, 4652 .par = (const uint32_t[]){IBREAKENABLE}, 4653 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4654 }, { 4655 .name = "wsr.icount", 4656 .translate = translate_wsr, 4657 .test_ill = test_ill_wsr, 4658 .par = (const uint32_t[]){ICOUNT}, 4659 .op_flags = XTENSA_OP_PRIVILEGED, 4660 }, { 4661 .name = "wsr.icountlevel", 4662 .translate = translate_wsr, 4663 .test_ill = test_ill_wsr, 4664 .par = (const uint32_t[]){ICOUNTLEVEL}, 4665 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4666 }, { 4667 .name = "wsr.intclear", 4668 .translate = translate_wsr, 4669 .test_ill = test_ill_wsr, 4670 .par = (const uint32_t[]){INTCLEAR}, 4671 .op_flags = 4672 XTENSA_OP_PRIVILEGED | 4673 XTENSA_OP_EXIT_TB_0 | 4674 XTENSA_OP_CHECK_INTERRUPTS, 4675 }, { 4676 .name = "wsr.intenable", 4677 .translate = translate_wsr, 4678 .test_ill = test_ill_wsr, 4679 .par = (const uint32_t[]){INTENABLE}, 4680 .op_flags = 4681 XTENSA_OP_PRIVILEGED | 4682 XTENSA_OP_EXIT_TB_0 | 4683 XTENSA_OP_CHECK_INTERRUPTS, 4684 }, { 4685 .name = "wsr.interrupt", 4686 .translate = translate_wsr, 4687 .test_ill = test_ill_wsr, 4688 .par = (const uint32_t[]){INTSET}, 4689 .op_flags = 4690 XTENSA_OP_PRIVILEGED | 4691 XTENSA_OP_EXIT_TB_0 | 4692 XTENSA_OP_CHECK_INTERRUPTS, 4693 }, { 4694 .name = "wsr.intset", 4695 .translate = translate_wsr, 4696 .test_ill = test_ill_wsr, 4697 .par = (const uint32_t[]){INTSET}, 4698 .op_flags = 4699 XTENSA_OP_PRIVILEGED | 4700 XTENSA_OP_EXIT_TB_0 | 4701 XTENSA_OP_CHECK_INTERRUPTS, 4702 }, { 4703 .name = "wsr.itlbcfg", 4704 .translate = translate_wsr, 4705 .test_ill = test_ill_wsr, 4706 .par = (const uint32_t[]){ITLBCFG}, 4707 .op_flags = XTENSA_OP_PRIVILEGED, 4708 }, { 4709 .name = "wsr.lbeg", 4710 .translate = translate_wsr, 4711 .test_ill = test_ill_wsr, 4712 .par = (const uint32_t[]){LBEG}, 4713 .op_flags = XTENSA_OP_EXIT_TB_M1, 4714 }, { 4715 .name = "wsr.lcount", 4716 .translate = translate_wsr, 4717 .test_ill = test_ill_wsr, 4718 .par = (const uint32_t[]){LCOUNT}, 4719 }, { 4720 .name = "wsr.lend", 4721 .translate = translate_wsr, 4722 .test_ill = test_ill_wsr, 4723 .par = (const uint32_t[]){LEND}, 4724 .op_flags = XTENSA_OP_EXIT_TB_M1, 4725 }, { 4726 .name = "wsr.litbase", 4727 .translate = translate_wsr, 4728 .test_ill = test_ill_wsr, 4729 .par = (const uint32_t[]){LITBASE}, 4730 .op_flags = XTENSA_OP_EXIT_TB_M1, 4731 }, { 4732 .name = "wsr.m0", 4733 .translate = translate_wsr, 4734 .test_ill = test_ill_wsr, 4735 .par = (const uint32_t[]){MR}, 4736 }, { 4737 .name = "wsr.m1", 4738 .translate = translate_wsr, 4739 .test_ill = test_ill_wsr, 4740 .par = (const uint32_t[]){MR + 1}, 4741 }, { 4742 .name = "wsr.m2", 4743 .translate = translate_wsr, 4744 .test_ill = test_ill_wsr, 4745 .par = (const uint32_t[]){MR + 2}, 4746 }, { 4747 .name = "wsr.m3", 4748 .translate = translate_wsr, 4749 .test_ill = test_ill_wsr, 4750 .par = (const uint32_t[]){MR + 3}, 4751 }, { 4752 .name = "wsr.memctl", 4753 .translate = translate_wsr, 4754 .test_ill = test_ill_wsr, 4755 .par = (const uint32_t[]){MEMCTL}, 4756 .op_flags = XTENSA_OP_PRIVILEGED, 4757 }, { 4758 .name = "wsr.misc0", 4759 .translate = translate_wsr, 4760 .test_ill = test_ill_wsr, 4761 .par = (const uint32_t[]){MISC}, 4762 .op_flags = XTENSA_OP_PRIVILEGED, 4763 }, { 4764 .name = "wsr.misc1", 4765 .translate = translate_wsr, 4766 .test_ill = test_ill_wsr, 4767 .par = (const uint32_t[]){MISC + 1}, 4768 .op_flags = XTENSA_OP_PRIVILEGED, 4769 }, { 4770 .name = "wsr.misc2", 4771 .translate = translate_wsr, 4772 .test_ill = test_ill_wsr, 4773 .par = (const uint32_t[]){MISC + 2}, 4774 .op_flags = XTENSA_OP_PRIVILEGED, 4775 }, { 4776 .name = "wsr.misc3", 4777 .translate = translate_wsr, 4778 .test_ill = test_ill_wsr, 4779 .par = (const uint32_t[]){MISC + 3}, 4780 .op_flags = XTENSA_OP_PRIVILEGED, 4781 }, { 4782 .name = "wsr.mmid", 4783 .translate = translate_wsr, 4784 .test_ill = test_ill_wsr, 4785 .par = (const uint32_t[]){MMID}, 4786 .op_flags = XTENSA_OP_PRIVILEGED, 4787 }, { 4788 .name = "wsr.prefctl", 4789 .translate = translate_wsr, 4790 .test_ill = test_ill_wsr, 4791 .par = (const uint32_t[]){PREFCTL}, 4792 }, { 4793 .name = "wsr.prid", 4794 .translate = translate_wsr, 4795 .test_ill = test_ill_wsr, 4796 .par = (const uint32_t[]){PRID}, 4797 .op_flags = XTENSA_OP_PRIVILEGED, 4798 }, { 4799 .name = "wsr.ps", 4800 .translate = translate_wsr, 4801 .test_ill = test_ill_wsr, 4802 .par = (const uint32_t[]){PS}, 4803 .op_flags = 4804 XTENSA_OP_PRIVILEGED | 4805 XTENSA_OP_EXIT_TB_M1 | 4806 XTENSA_OP_CHECK_INTERRUPTS, 4807 }, { 4808 .name = "wsr.ptevaddr", 4809 .translate = translate_wsr, 4810 .test_ill = test_ill_wsr, 4811 .par = (const uint32_t[]){PTEVADDR}, 4812 .op_flags = XTENSA_OP_PRIVILEGED, 4813 }, { 4814 .name = "wsr.rasid", 4815 .translate = translate_wsr, 4816 .test_ill = test_ill_wsr, 4817 .par = (const uint32_t[]){RASID}, 4818 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4819 }, { 4820 .name = "wsr.sar", 4821 .translate = translate_wsr, 4822 .test_ill = test_ill_wsr, 4823 .par = (const uint32_t[]){SAR}, 4824 }, { 4825 .name = "wsr.scompare1", 4826 .translate = translate_wsr, 4827 .test_ill = test_ill_wsr, 4828 .par = (const uint32_t[]){SCOMPARE1}, 4829 }, { 4830 .name = "wsr.vecbase", 4831 .translate = translate_wsr, 4832 .test_ill = test_ill_wsr, 4833 .par = (const uint32_t[]){VECBASE}, 4834 .op_flags = XTENSA_OP_PRIVILEGED, 4835 }, { 4836 .name = "wsr.windowbase", 4837 .translate = translate_wsr, 4838 .test_ill = test_ill_wsr, 4839 .par = (const uint32_t[]){WINDOW_BASE}, 4840 .op_flags = XTENSA_OP_PRIVILEGED | 4841 XTENSA_OP_EXIT_TB_M1 | 4842 XTENSA_OP_SYNC_REGISTER_WINDOW, 4843 }, { 4844 .name = "wsr.windowstart", 4845 .translate = translate_wsr, 4846 .test_ill = test_ill_wsr, 4847 .par = (const uint32_t[]){WINDOW_START}, 4848 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4849 }, { 4850 .name = "wur.expstate", 4851 .translate = translate_wur, 4852 .par = (const uint32_t[]){EXPSTATE}, 4853 }, { 4854 .name = "wur.fcr", 4855 .translate = translate_wur, 4856 .par = (const uint32_t[]){FCR}, 4857 .coprocessor = 0x1, 4858 }, { 4859 .name = "wur.fsr", 4860 .translate = translate_wur, 4861 .par = (const uint32_t[]){FSR}, 4862 .coprocessor = 0x1, 4863 }, { 4864 .name = "wur.threadptr", 4865 .translate = translate_wur, 4866 .par = (const uint32_t[]){THREADPTR}, 4867 }, { 4868 .name = "xor", 4869 .translate = translate_xor, 4870 }, { 4871 .name = "xorb", 4872 .translate = translate_boolean, 4873 .par = (const uint32_t[]){BOOLEAN_XOR}, 4874 }, { 4875 .name = "xsr.176", 4876 .translate = translate_xsr, 4877 .test_ill = test_ill_xsr, 4878 .par = (const uint32_t[]){176}, 4879 .op_flags = XTENSA_OP_PRIVILEGED, 4880 }, { 4881 .name = "xsr.208", 4882 .translate = translate_xsr, 4883 .test_ill = test_ill_xsr, 4884 .par = (const uint32_t[]){208}, 4885 .op_flags = XTENSA_OP_PRIVILEGED, 4886 }, { 4887 .name = "xsr.acchi", 4888 .translate = translate_xsr, 4889 .test_ill = test_ill_xsr, 4890 .par = (const uint32_t[]){ACCHI}, 4891 }, { 4892 .name = "xsr.acclo", 4893 .translate = translate_xsr, 4894 .test_ill = test_ill_xsr, 4895 .par = (const uint32_t[]){ACCLO}, 4896 }, { 4897 .name = "xsr.atomctl", 4898 .translate = translate_xsr, 4899 .test_ill = test_ill_xsr, 4900 .par = (const uint32_t[]){ATOMCTL}, 4901 .op_flags = XTENSA_OP_PRIVILEGED, 4902 }, { 4903 .name = "xsr.br", 4904 .translate = translate_xsr, 4905 .test_ill = test_ill_xsr, 4906 .par = (const uint32_t[]){BR}, 4907 }, { 4908 .name = "xsr.cacheattr", 4909 .translate = translate_xsr, 4910 .test_ill = test_ill_xsr, 4911 .par = (const uint32_t[]){CACHEATTR}, 4912 .op_flags = XTENSA_OP_PRIVILEGED, 4913 }, { 4914 .name = "xsr.ccompare0", 4915 .translate = translate_xsr, 4916 .test_ill = test_ill_xsr, 4917 .par = (const uint32_t[]){CCOMPARE}, 4918 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4919 }, { 4920 .name = "xsr.ccompare1", 4921 .translate = translate_xsr, 4922 .test_ill = test_ill_xsr, 4923 .par = (const uint32_t[]){CCOMPARE + 1}, 4924 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4925 }, { 4926 .name = "xsr.ccompare2", 4927 .translate = translate_xsr, 4928 .test_ill = test_ill_xsr, 4929 .par = (const uint32_t[]){CCOMPARE + 2}, 4930 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4931 }, { 4932 .name = "xsr.ccount", 4933 .translate = translate_xsr, 4934 .test_ill = test_ill_xsr, 4935 .par = (const uint32_t[]){CCOUNT}, 4936 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 4937 }, { 4938 .name = "xsr.configid0", 4939 .translate = translate_xsr, 4940 .test_ill = test_ill_xsr, 4941 .par = (const uint32_t[]){CONFIGID0}, 4942 .op_flags = XTENSA_OP_PRIVILEGED, 4943 }, { 4944 .name = "xsr.configid1", 4945 .translate = translate_xsr, 4946 .test_ill = test_ill_xsr, 4947 .par = (const uint32_t[]){CONFIGID1}, 4948 .op_flags = XTENSA_OP_PRIVILEGED, 4949 }, { 4950 .name = "xsr.cpenable", 4951 .translate = translate_xsr, 4952 .test_ill = test_ill_xsr, 4953 .par = (const uint32_t[]){CPENABLE}, 4954 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 4955 }, { 4956 .name = "xsr.dbreaka0", 4957 .translate = translate_xsr, 4958 .test_ill = test_ill_xsr, 4959 .par = (const uint32_t[]){DBREAKA}, 4960 .op_flags = XTENSA_OP_PRIVILEGED, 4961 }, { 4962 .name = "xsr.dbreaka1", 4963 .translate = translate_xsr, 4964 .test_ill = test_ill_xsr, 4965 .par = (const uint32_t[]){DBREAKA + 1}, 4966 .op_flags = XTENSA_OP_PRIVILEGED, 4967 }, { 4968 .name = "xsr.dbreakc0", 4969 .translate = translate_xsr, 4970 .test_ill = test_ill_xsr, 4971 .par = (const uint32_t[]){DBREAKC}, 4972 .op_flags = XTENSA_OP_PRIVILEGED, 4973 }, { 4974 .name = "xsr.dbreakc1", 4975 .translate = translate_xsr, 4976 .test_ill = test_ill_xsr, 4977 .par = (const uint32_t[]){DBREAKC + 1}, 4978 .op_flags = XTENSA_OP_PRIVILEGED, 4979 }, { 4980 .name = "xsr.ddr", 4981 .translate = translate_xsr, 4982 .test_ill = test_ill_xsr, 4983 .par = (const uint32_t[]){DDR}, 4984 .op_flags = XTENSA_OP_PRIVILEGED, 4985 }, { 4986 .name = "xsr.debugcause", 4987 .translate = translate_xsr, 4988 .test_ill = test_ill_xsr, 4989 .par = (const uint32_t[]){DEBUGCAUSE}, 4990 .op_flags = XTENSA_OP_PRIVILEGED, 4991 }, { 4992 .name = "xsr.depc", 4993 .translate = translate_xsr, 4994 .test_ill = test_ill_xsr, 4995 .par = (const uint32_t[]){DEPC}, 4996 .op_flags = XTENSA_OP_PRIVILEGED, 4997 }, { 4998 .name = "xsr.dtlbcfg", 4999 .translate = translate_xsr, 5000 .test_ill = test_ill_xsr, 5001 .par = (const uint32_t[]){DTLBCFG}, 5002 .op_flags = XTENSA_OP_PRIVILEGED, 5003 }, { 5004 .name = "xsr.epc1", 5005 .translate = translate_xsr, 5006 .test_ill = test_ill_xsr, 5007 .par = (const uint32_t[]){EPC1}, 5008 .op_flags = XTENSA_OP_PRIVILEGED, 5009 }, { 5010 .name = "xsr.epc2", 5011 .translate = translate_xsr, 5012 .test_ill = test_ill_xsr, 5013 .par = (const uint32_t[]){EPC1 + 1}, 5014 .op_flags = XTENSA_OP_PRIVILEGED, 5015 }, { 5016 .name = "xsr.epc3", 5017 .translate = translate_xsr, 5018 .test_ill = test_ill_xsr, 5019 .par = (const uint32_t[]){EPC1 + 2}, 5020 .op_flags = XTENSA_OP_PRIVILEGED, 5021 }, { 5022 .name = "xsr.epc4", 5023 .translate = translate_xsr, 5024 .test_ill = test_ill_xsr, 5025 .par = (const uint32_t[]){EPC1 + 3}, 5026 .op_flags = XTENSA_OP_PRIVILEGED, 5027 }, { 5028 .name = "xsr.epc5", 5029 .translate = translate_xsr, 5030 .test_ill = test_ill_xsr, 5031 .par = (const uint32_t[]){EPC1 + 4}, 5032 .op_flags = XTENSA_OP_PRIVILEGED, 5033 }, { 5034 .name = "xsr.epc6", 5035 .translate = translate_xsr, 5036 .test_ill = test_ill_xsr, 5037 .par = (const uint32_t[]){EPC1 + 5}, 5038 .op_flags = XTENSA_OP_PRIVILEGED, 5039 }, { 5040 .name = "xsr.epc7", 5041 .translate = translate_xsr, 5042 .test_ill = test_ill_xsr, 5043 .par = (const uint32_t[]){EPC1 + 6}, 5044 .op_flags = XTENSA_OP_PRIVILEGED, 5045 }, { 5046 .name = "xsr.eps2", 5047 .translate = translate_xsr, 5048 .test_ill = test_ill_xsr, 5049 .par = (const uint32_t[]){EPS2}, 5050 .op_flags = XTENSA_OP_PRIVILEGED, 5051 }, { 5052 .name = "xsr.eps3", 5053 .translate = translate_xsr, 5054 .test_ill = test_ill_xsr, 5055 .par = (const uint32_t[]){EPS2 + 1}, 5056 .op_flags = XTENSA_OP_PRIVILEGED, 5057 }, { 5058 .name = "xsr.eps4", 5059 .translate = translate_xsr, 5060 .test_ill = test_ill_xsr, 5061 .par = (const uint32_t[]){EPS2 + 2}, 5062 .op_flags = XTENSA_OP_PRIVILEGED, 5063 }, { 5064 .name = "xsr.eps5", 5065 .translate = translate_xsr, 5066 .test_ill = test_ill_xsr, 5067 .par = (const uint32_t[]){EPS2 + 3}, 5068 .op_flags = XTENSA_OP_PRIVILEGED, 5069 }, { 5070 .name = "xsr.eps6", 5071 .translate = translate_xsr, 5072 .test_ill = test_ill_xsr, 5073 .par = (const uint32_t[]){EPS2 + 4}, 5074 .op_flags = XTENSA_OP_PRIVILEGED, 5075 }, { 5076 .name = "xsr.eps7", 5077 .translate = translate_xsr, 5078 .test_ill = test_ill_xsr, 5079 .par = (const uint32_t[]){EPS2 + 5}, 5080 .op_flags = XTENSA_OP_PRIVILEGED, 5081 }, { 5082 .name = "xsr.exccause", 5083 .translate = translate_xsr, 5084 .test_ill = test_ill_xsr, 5085 .par = (const uint32_t[]){EXCCAUSE}, 5086 .op_flags = XTENSA_OP_PRIVILEGED, 5087 }, { 5088 .name = "xsr.excsave1", 5089 .translate = translate_xsr, 5090 .test_ill = test_ill_xsr, 5091 .par = (const uint32_t[]){EXCSAVE1}, 5092 .op_flags = XTENSA_OP_PRIVILEGED, 5093 }, { 5094 .name = "xsr.excsave2", 5095 .translate = translate_xsr, 5096 .test_ill = test_ill_xsr, 5097 .par = (const uint32_t[]){EXCSAVE1 + 1}, 5098 .op_flags = XTENSA_OP_PRIVILEGED, 5099 }, { 5100 .name = "xsr.excsave3", 5101 .translate = translate_xsr, 5102 .test_ill = test_ill_xsr, 5103 .par = (const uint32_t[]){EXCSAVE1 + 2}, 5104 .op_flags = XTENSA_OP_PRIVILEGED, 5105 }, { 5106 .name = "xsr.excsave4", 5107 .translate = translate_xsr, 5108 .test_ill = test_ill_xsr, 5109 .par = (const uint32_t[]){EXCSAVE1 + 3}, 5110 .op_flags = XTENSA_OP_PRIVILEGED, 5111 }, { 5112 .name = "xsr.excsave5", 5113 .translate = translate_xsr, 5114 .test_ill = test_ill_xsr, 5115 .par = (const uint32_t[]){EXCSAVE1 + 4}, 5116 .op_flags = XTENSA_OP_PRIVILEGED, 5117 }, { 5118 .name = "xsr.excsave6", 5119 .translate = translate_xsr, 5120 .test_ill = test_ill_xsr, 5121 .par = (const uint32_t[]){EXCSAVE1 + 5}, 5122 .op_flags = XTENSA_OP_PRIVILEGED, 5123 }, { 5124 .name = "xsr.excsave7", 5125 .translate = translate_xsr, 5126 .test_ill = test_ill_xsr, 5127 .par = (const uint32_t[]){EXCSAVE1 + 6}, 5128 .op_flags = XTENSA_OP_PRIVILEGED, 5129 }, { 5130 .name = "xsr.excvaddr", 5131 .translate = translate_xsr, 5132 .test_ill = test_ill_xsr, 5133 .par = (const uint32_t[]){EXCVADDR}, 5134 .op_flags = XTENSA_OP_PRIVILEGED, 5135 }, { 5136 .name = "xsr.ibreaka0", 5137 .translate = translate_xsr, 5138 .test_ill = test_ill_xsr, 5139 .par = (const uint32_t[]){IBREAKA}, 5140 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5141 }, { 5142 .name = "xsr.ibreaka1", 5143 .translate = translate_xsr, 5144 .test_ill = test_ill_xsr, 5145 .par = (const uint32_t[]){IBREAKA + 1}, 5146 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5147 }, { 5148 .name = "xsr.ibreakenable", 5149 .translate = translate_xsr, 5150 .test_ill = test_ill_xsr, 5151 .par = (const uint32_t[]){IBREAKENABLE}, 5152 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, 5153 }, { 5154 .name = "xsr.icount", 5155 .translate = translate_xsr, 5156 .test_ill = test_ill_xsr, 5157 .par = (const uint32_t[]){ICOUNT}, 5158 .op_flags = XTENSA_OP_PRIVILEGED, 5159 }, { 5160 .name = "xsr.icountlevel", 5161 .translate = translate_xsr, 5162 .test_ill = test_ill_xsr, 5163 .par = (const uint32_t[]){ICOUNTLEVEL}, 5164 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5165 }, { 5166 .name = "xsr.intclear", 5167 .translate = translate_xsr, 5168 .test_ill = test_ill_xsr, 5169 .par = (const uint32_t[]){INTCLEAR}, 5170 .op_flags = 5171 XTENSA_OP_PRIVILEGED | 5172 XTENSA_OP_EXIT_TB_0 | 5173 XTENSA_OP_CHECK_INTERRUPTS, 5174 }, { 5175 .name = "xsr.intenable", 5176 .translate = translate_xsr, 5177 .test_ill = test_ill_xsr, 5178 .par = (const uint32_t[]){INTENABLE}, 5179 .op_flags = 5180 XTENSA_OP_PRIVILEGED | 5181 XTENSA_OP_EXIT_TB_0 | 5182 XTENSA_OP_CHECK_INTERRUPTS, 5183 }, { 5184 .name = "xsr.interrupt", 5185 .translate = translate_xsr, 5186 .test_ill = test_ill_xsr, 5187 .par = (const uint32_t[]){INTSET}, 5188 .op_flags = 5189 XTENSA_OP_PRIVILEGED | 5190 XTENSA_OP_EXIT_TB_0 | 5191 XTENSA_OP_CHECK_INTERRUPTS, 5192 }, { 5193 .name = "xsr.intset", 5194 .translate = translate_xsr, 5195 .test_ill = test_ill_xsr, 5196 .par = (const uint32_t[]){INTSET}, 5197 .op_flags = 5198 XTENSA_OP_PRIVILEGED | 5199 XTENSA_OP_EXIT_TB_0 | 5200 XTENSA_OP_CHECK_INTERRUPTS, 5201 }, { 5202 .name = "xsr.itlbcfg", 5203 .translate = translate_xsr, 5204 .test_ill = test_ill_xsr, 5205 .par = (const uint32_t[]){ITLBCFG}, 5206 .op_flags = XTENSA_OP_PRIVILEGED, 5207 }, { 5208 .name = "xsr.lbeg", 5209 .translate = translate_xsr, 5210 .test_ill = test_ill_xsr, 5211 .par = (const uint32_t[]){LBEG}, 5212 .op_flags = XTENSA_OP_EXIT_TB_M1, 5213 }, { 5214 .name = "xsr.lcount", 5215 .translate = translate_xsr, 5216 .test_ill = test_ill_xsr, 5217 .par = (const uint32_t[]){LCOUNT}, 5218 }, { 5219 .name = "xsr.lend", 5220 .translate = translate_xsr, 5221 .test_ill = test_ill_xsr, 5222 .par = (const uint32_t[]){LEND}, 5223 .op_flags = XTENSA_OP_EXIT_TB_M1, 5224 }, { 5225 .name = "xsr.litbase", 5226 .translate = translate_xsr, 5227 .test_ill = test_ill_xsr, 5228 .par = (const uint32_t[]){LITBASE}, 5229 .op_flags = XTENSA_OP_EXIT_TB_M1, 5230 }, { 5231 .name = "xsr.m0", 5232 .translate = translate_xsr, 5233 .test_ill = test_ill_xsr, 5234 .par = (const uint32_t[]){MR}, 5235 }, { 5236 .name = "xsr.m1", 5237 .translate = translate_xsr, 5238 .test_ill = test_ill_xsr, 5239 .par = (const uint32_t[]){MR + 1}, 5240 }, { 5241 .name = "xsr.m2", 5242 .translate = translate_xsr, 5243 .test_ill = test_ill_xsr, 5244 .par = (const uint32_t[]){MR + 2}, 5245 }, { 5246 .name = "xsr.m3", 5247 .translate = translate_xsr, 5248 .test_ill = test_ill_xsr, 5249 .par = (const uint32_t[]){MR + 3}, 5250 }, { 5251 .name = "xsr.memctl", 5252 .translate = translate_xsr, 5253 .test_ill = test_ill_xsr, 5254 .par = (const uint32_t[]){MEMCTL}, 5255 .op_flags = XTENSA_OP_PRIVILEGED, 5256 }, { 5257 .name = "xsr.misc0", 5258 .translate = translate_xsr, 5259 .test_ill = test_ill_xsr, 5260 .par = (const uint32_t[]){MISC}, 5261 .op_flags = XTENSA_OP_PRIVILEGED, 5262 }, { 5263 .name = "xsr.misc1", 5264 .translate = translate_xsr, 5265 .test_ill = test_ill_xsr, 5266 .par = (const uint32_t[]){MISC + 1}, 5267 .op_flags = XTENSA_OP_PRIVILEGED, 5268 }, { 5269 .name = "xsr.misc2", 5270 .translate = translate_xsr, 5271 .test_ill = test_ill_xsr, 5272 .par = (const uint32_t[]){MISC + 2}, 5273 .op_flags = XTENSA_OP_PRIVILEGED, 5274 }, { 5275 .name = "xsr.misc3", 5276 .translate = translate_xsr, 5277 .test_ill = test_ill_xsr, 5278 .par = (const uint32_t[]){MISC + 3}, 5279 .op_flags = XTENSA_OP_PRIVILEGED, 5280 }, { 5281 .name = "xsr.prefctl", 5282 .translate = translate_xsr, 5283 .test_ill = test_ill_xsr, 5284 .par = (const uint32_t[]){PREFCTL}, 5285 }, { 5286 .name = "xsr.prid", 5287 .translate = translate_xsr, 5288 .test_ill = test_ill_xsr, 5289 .par = (const uint32_t[]){PRID}, 5290 .op_flags = XTENSA_OP_PRIVILEGED, 5291 }, { 5292 .name = "xsr.ps", 5293 .translate = translate_xsr, 5294 .test_ill = test_ill_xsr, 5295 .par = (const uint32_t[]){PS}, 5296 .op_flags = 5297 XTENSA_OP_PRIVILEGED | 5298 XTENSA_OP_EXIT_TB_M1 | 5299 XTENSA_OP_CHECK_INTERRUPTS, 5300 }, { 5301 .name = "xsr.ptevaddr", 5302 .translate = translate_xsr, 5303 .test_ill = test_ill_xsr, 5304 .par = (const uint32_t[]){PTEVADDR}, 5305 .op_flags = XTENSA_OP_PRIVILEGED, 5306 }, { 5307 .name = "xsr.rasid", 5308 .translate = translate_xsr, 5309 .test_ill = test_ill_xsr, 5310 .par = (const uint32_t[]){RASID}, 5311 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5312 }, { 5313 .name = "xsr.sar", 5314 .translate = translate_xsr, 5315 .test_ill = test_ill_xsr, 5316 .par = (const uint32_t[]){SAR}, 5317 }, { 5318 .name = "xsr.scompare1", 5319 .translate = translate_xsr, 5320 .test_ill = test_ill_xsr, 5321 .par = (const uint32_t[]){SCOMPARE1}, 5322 }, { 5323 .name = "xsr.vecbase", 5324 .translate = translate_xsr, 5325 .test_ill = test_ill_xsr, 5326 .par = (const uint32_t[]){VECBASE}, 5327 .op_flags = XTENSA_OP_PRIVILEGED, 5328 }, { 5329 .name = "xsr.windowbase", 5330 .translate = translate_xsr, 5331 .test_ill = test_ill_xsr, 5332 .par = (const uint32_t[]){WINDOW_BASE}, 5333 .op_flags = XTENSA_OP_PRIVILEGED | 5334 XTENSA_OP_EXIT_TB_M1 | 5335 XTENSA_OP_SYNC_REGISTER_WINDOW, 5336 }, { 5337 .name = "xsr.windowstart", 5338 .translate = translate_xsr, 5339 .test_ill = test_ill_xsr, 5340 .par = (const uint32_t[]){WINDOW_START}, 5341 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, 5342 }, 5343 }; 5344 5345 const XtensaOpcodeTranslators xtensa_core_opcodes = { 5346 .num_opcodes = ARRAY_SIZE(core_ops), 5347 .opcode = core_ops, 5348 }; 5349 5350 5351 static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[], 5352 const uint32_t par[]) 5353 { 5354 gen_helper_abs_s(arg[0].out, arg[1].in); 5355 } 5356 5357 static void translate_add_s(DisasContext *dc, const OpcodeArg arg[], 5358 const uint32_t par[]) 5359 { 5360 gen_helper_add_s(arg[0].out, cpu_env, 5361 arg[1].in, arg[2].in); 5362 } 5363 5364 enum { 5365 COMPARE_UN, 5366 COMPARE_OEQ, 5367 COMPARE_UEQ, 5368 COMPARE_OLT, 5369 COMPARE_ULT, 5370 COMPARE_OLE, 5371 COMPARE_ULE, 5372 }; 5373 5374 static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[], 5375 const uint32_t par[]) 5376 { 5377 static void (* const helper[])(TCGv_env env, TCGv_i32 bit, 5378 TCGv_i32 s, TCGv_i32 t) = { 5379 [COMPARE_UN] = gen_helper_un_s, 5380 [COMPARE_OEQ] = gen_helper_oeq_s, 5381 [COMPARE_UEQ] = gen_helper_ueq_s, 5382 [COMPARE_OLT] = gen_helper_olt_s, 5383 [COMPARE_ULT] = gen_helper_ult_s, 5384 [COMPARE_OLE] = gen_helper_ole_s, 5385 [COMPARE_ULE] = gen_helper_ule_s, 5386 }; 5387 TCGv_i32 bit = tcg_const_i32(1 << arg[0].imm); 5388 5389 helper[par[0]](cpu_env, bit, arg[1].in, arg[2].in); 5390 tcg_temp_free(bit); 5391 } 5392 5393 static void translate_float_s(DisasContext *dc, const OpcodeArg arg[], 5394 const uint32_t par[]) 5395 { 5396 TCGv_i32 scale = tcg_const_i32(-arg[2].imm); 5397 5398 if (par[0]) { 5399 gen_helper_uitof(arg[0].out, cpu_env, arg[1].in, scale); 5400 } else { 5401 gen_helper_itof(arg[0].out, cpu_env, arg[1].in, scale); 5402 } 5403 tcg_temp_free(scale); 5404 } 5405 5406 static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[], 5407 const uint32_t par[]) 5408 { 5409 TCGv_i32 rounding_mode = tcg_const_i32(par[0]); 5410 TCGv_i32 scale = tcg_const_i32(arg[2].imm); 5411 5412 if (par[1]) { 5413 gen_helper_ftoui(arg[0].out, arg[1].in, 5414 rounding_mode, scale); 5415 } else { 5416 gen_helper_ftoi(arg[0].out, arg[1].in, 5417 rounding_mode, scale); 5418 } 5419 tcg_temp_free(rounding_mode); 5420 tcg_temp_free(scale); 5421 } 5422 5423 static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[], 5424 const uint32_t par[]) 5425 { 5426 TCGv_i32 addr = tcg_temp_new_i32(); 5427 5428 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); 5429 gen_load_store_alignment(dc, 2, addr, false); 5430 if (par[0]) { 5431 tcg_gen_qemu_st32(arg[0].in, addr, dc->cring); 5432 } else { 5433 tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring); 5434 } 5435 if (par[1]) { 5436 tcg_gen_mov_i32(arg[1].out, addr); 5437 } 5438 tcg_temp_free(addr); 5439 } 5440 5441 static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[], 5442 const uint32_t par[]) 5443 { 5444 TCGv_i32 addr = tcg_temp_new_i32(); 5445 5446 tcg_gen_add_i32(addr, arg[1].in, arg[2].in); 5447 gen_load_store_alignment(dc, 2, addr, false); 5448 if (par[0]) { 5449 tcg_gen_qemu_st32(arg[0].in, addr, dc->cring); 5450 } else { 5451 tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring); 5452 } 5453 if (par[1]) { 5454 tcg_gen_mov_i32(arg[1].out, addr); 5455 } 5456 tcg_temp_free(addr); 5457 } 5458 5459 static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[], 5460 const uint32_t par[]) 5461 { 5462 gen_helper_madd_s(arg[0].out, cpu_env, 5463 arg[0].in, arg[1].in, arg[2].in); 5464 } 5465 5466 static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[], 5467 const uint32_t par[]) 5468 { 5469 tcg_gen_mov_i32(arg[0].out, arg[1].in); 5470 } 5471 5472 static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[], 5473 const uint32_t par[]) 5474 { 5475 TCGv_i32 zero = tcg_const_i32(0); 5476 5477 tcg_gen_movcond_i32(par[0], arg[0].out, 5478 arg[2].in, zero, 5479 arg[1].in, arg[0].in); 5480 tcg_temp_free(zero); 5481 } 5482 5483 static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[], 5484 const uint32_t par[]) 5485 { 5486 TCGv_i32 zero = tcg_const_i32(0); 5487 TCGv_i32 tmp = tcg_temp_new_i32(); 5488 5489 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm); 5490 tcg_gen_movcond_i32(par[0], 5491 arg[0].out, tmp, zero, 5492 arg[1].in, arg[0].in); 5493 tcg_temp_free(tmp); 5494 tcg_temp_free(zero); 5495 } 5496 5497 static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[], 5498 const uint32_t par[]) 5499 { 5500 gen_helper_mul_s(arg[0].out, cpu_env, 5501 arg[1].in, arg[2].in); 5502 } 5503 5504 static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[], 5505 const uint32_t par[]) 5506 { 5507 gen_helper_msub_s(arg[0].out, cpu_env, 5508 arg[0].in, arg[1].in, arg[2].in); 5509 } 5510 5511 static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[], 5512 const uint32_t par[]) 5513 { 5514 gen_helper_neg_s(arg[0].out, arg[1].in); 5515 } 5516 5517 static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[], 5518 const uint32_t par[]) 5519 { 5520 tcg_gen_mov_i32(arg[0].out, arg[1].in); 5521 } 5522 5523 static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[], 5524 const uint32_t par[]) 5525 { 5526 gen_helper_sub_s(arg[0].out, cpu_env, 5527 arg[1].in, arg[2].in); 5528 } 5529 5530 static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[], 5531 const uint32_t par[]) 5532 { 5533 tcg_gen_mov_i32(arg[0].out, arg[1].in); 5534 } 5535 5536 static const XtensaOpcodeOps fpu2000_ops[] = { 5537 { 5538 .name = "abs.s", 5539 .translate = translate_abs_s, 5540 .coprocessor = 0x1, 5541 }, { 5542 .name = "add.s", 5543 .translate = translate_add_s, 5544 .coprocessor = 0x1, 5545 }, { 5546 .name = "ceil.s", 5547 .translate = translate_ftoi_s, 5548 .par = (const uint32_t[]){float_round_up, false}, 5549 .coprocessor = 0x1, 5550 }, { 5551 .name = "float.s", 5552 .translate = translate_float_s, 5553 .par = (const uint32_t[]){false}, 5554 .coprocessor = 0x1, 5555 }, { 5556 .name = "floor.s", 5557 .translate = translate_ftoi_s, 5558 .par = (const uint32_t[]){float_round_down, false}, 5559 .coprocessor = 0x1, 5560 }, { 5561 .name = "lsi", 5562 .translate = translate_ldsti, 5563 .par = (const uint32_t[]){false, false}, 5564 .op_flags = XTENSA_OP_LOAD, 5565 .coprocessor = 0x1, 5566 }, { 5567 .name = "lsiu", 5568 .translate = translate_ldsti, 5569 .par = (const uint32_t[]){false, true}, 5570 .op_flags = XTENSA_OP_LOAD, 5571 .coprocessor = 0x1, 5572 }, { 5573 .name = "lsx", 5574 .translate = translate_ldstx, 5575 .par = (const uint32_t[]){false, false}, 5576 .op_flags = XTENSA_OP_LOAD, 5577 .coprocessor = 0x1, 5578 }, { 5579 .name = "lsxu", 5580 .translate = translate_ldstx, 5581 .par = (const uint32_t[]){false, true}, 5582 .op_flags = XTENSA_OP_LOAD, 5583 .coprocessor = 0x1, 5584 }, { 5585 .name = "madd.s", 5586 .translate = translate_madd_s, 5587 .coprocessor = 0x1, 5588 }, { 5589 .name = "mov.s", 5590 .translate = translate_mov_s, 5591 .coprocessor = 0x1, 5592 }, { 5593 .name = "moveqz.s", 5594 .translate = translate_movcond_s, 5595 .par = (const uint32_t[]){TCG_COND_EQ}, 5596 .coprocessor = 0x1, 5597 }, { 5598 .name = "movf.s", 5599 .translate = translate_movp_s, 5600 .par = (const uint32_t[]){TCG_COND_EQ}, 5601 .coprocessor = 0x1, 5602 }, { 5603 .name = "movgez.s", 5604 .translate = translate_movcond_s, 5605 .par = (const uint32_t[]){TCG_COND_GE}, 5606 .coprocessor = 0x1, 5607 }, { 5608 .name = "movltz.s", 5609 .translate = translate_movcond_s, 5610 .par = (const uint32_t[]){TCG_COND_LT}, 5611 .coprocessor = 0x1, 5612 }, { 5613 .name = "movnez.s", 5614 .translate = translate_movcond_s, 5615 .par = (const uint32_t[]){TCG_COND_NE}, 5616 .coprocessor = 0x1, 5617 }, { 5618 .name = "movt.s", 5619 .translate = translate_movp_s, 5620 .par = (const uint32_t[]){TCG_COND_NE}, 5621 .coprocessor = 0x1, 5622 }, { 5623 .name = "msub.s", 5624 .translate = translate_msub_s, 5625 .coprocessor = 0x1, 5626 }, { 5627 .name = "mul.s", 5628 .translate = translate_mul_s, 5629 .coprocessor = 0x1, 5630 }, { 5631 .name = "neg.s", 5632 .translate = translate_neg_s, 5633 .coprocessor = 0x1, 5634 }, { 5635 .name = "oeq.s", 5636 .translate = translate_compare_s, 5637 .par = (const uint32_t[]){COMPARE_OEQ}, 5638 .coprocessor = 0x1, 5639 }, { 5640 .name = "ole.s", 5641 .translate = translate_compare_s, 5642 .par = (const uint32_t[]){COMPARE_OLE}, 5643 .coprocessor = 0x1, 5644 }, { 5645 .name = "olt.s", 5646 .translate = translate_compare_s, 5647 .par = (const uint32_t[]){COMPARE_OLT}, 5648 .coprocessor = 0x1, 5649 }, { 5650 .name = "rfr", 5651 .translate = translate_rfr_s, 5652 .coprocessor = 0x1, 5653 }, { 5654 .name = "round.s", 5655 .translate = translate_ftoi_s, 5656 .par = (const uint32_t[]){float_round_nearest_even, false}, 5657 .coprocessor = 0x1, 5658 }, { 5659 .name = "ssi", 5660 .translate = translate_ldsti, 5661 .par = (const uint32_t[]){true, false}, 5662 .op_flags = XTENSA_OP_STORE, 5663 .coprocessor = 0x1, 5664 }, { 5665 .name = "ssiu", 5666 .translate = translate_ldsti, 5667 .par = (const uint32_t[]){true, true}, 5668 .op_flags = XTENSA_OP_STORE, 5669 .coprocessor = 0x1, 5670 }, { 5671 .name = "ssx", 5672 .translate = translate_ldstx, 5673 .par = (const uint32_t[]){true, false}, 5674 .op_flags = XTENSA_OP_STORE, 5675 .coprocessor = 0x1, 5676 }, { 5677 .name = "ssxu", 5678 .translate = translate_ldstx, 5679 .par = (const uint32_t[]){true, true}, 5680 .op_flags = XTENSA_OP_STORE, 5681 .coprocessor = 0x1, 5682 }, { 5683 .name = "sub.s", 5684 .translate = translate_sub_s, 5685 .coprocessor = 0x1, 5686 }, { 5687 .name = "trunc.s", 5688 .translate = translate_ftoi_s, 5689 .par = (const uint32_t[]){float_round_to_zero, false}, 5690 .coprocessor = 0x1, 5691 }, { 5692 .name = "ueq.s", 5693 .translate = translate_compare_s, 5694 .par = (const uint32_t[]){COMPARE_UEQ}, 5695 .coprocessor = 0x1, 5696 }, { 5697 .name = "ufloat.s", 5698 .translate = translate_float_s, 5699 .par = (const uint32_t[]){true}, 5700 .coprocessor = 0x1, 5701 }, { 5702 .name = "ule.s", 5703 .translate = translate_compare_s, 5704 .par = (const uint32_t[]){COMPARE_ULE}, 5705 .coprocessor = 0x1, 5706 }, { 5707 .name = "ult.s", 5708 .translate = translate_compare_s, 5709 .par = (const uint32_t[]){COMPARE_ULT}, 5710 .coprocessor = 0x1, 5711 }, { 5712 .name = "un.s", 5713 .translate = translate_compare_s, 5714 .par = (const uint32_t[]){COMPARE_UN}, 5715 .coprocessor = 0x1, 5716 }, { 5717 .name = "utrunc.s", 5718 .translate = translate_ftoi_s, 5719 .par = (const uint32_t[]){float_round_to_zero, true}, 5720 .coprocessor = 0x1, 5721 }, { 5722 .name = "wfr", 5723 .translate = translate_wfr_s, 5724 .coprocessor = 0x1, 5725 }, 5726 }; 5727 5728 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = { 5729 .num_opcodes = ARRAY_SIZE(fpu2000_ops), 5730 .opcode = fpu2000_ops, 5731 }; 5732