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