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