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