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