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