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