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