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