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 typedef 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 TCGv_i32 litbase; 63 int is_jmp; 64 int singlestep_enabled; 65 66 bool sar_5bit; 67 bool sar_m32_5bit; 68 bool sar_m32_allocated; 69 TCGv_i32 sar_m32; 70 71 unsigned window; 72 73 bool debug; 74 bool icount; 75 TCGv_i32 next_icount; 76 77 unsigned cpenable; 78 79 uint32_t *raw_arg; 80 } DisasContext; 81 82 static TCGv_i32 cpu_pc; 83 static TCGv_i32 cpu_R[16]; 84 static TCGv_i32 cpu_FR[16]; 85 static TCGv_i32 cpu_SR[256]; 86 static TCGv_i32 cpu_UR[256]; 87 88 #include "exec/gen-icount.h" 89 90 typedef struct XtensaReg { 91 const char *name; 92 uint64_t opt_bits; 93 enum { 94 SR_R = 1, 95 SR_W = 2, 96 SR_X = 4, 97 SR_RW = 3, 98 SR_RWX = 7, 99 } access; 100 } XtensaReg; 101 102 #define XTENSA_REG_ACCESS(regname, opt, acc) { \ 103 .name = (regname), \ 104 .opt_bits = XTENSA_OPTION_BIT(opt), \ 105 .access = (acc), \ 106 } 107 108 #define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX) 109 110 #define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \ 111 .name = (regname), \ 112 .opt_bits = (opt), \ 113 .access = (acc), \ 114 } 115 116 #define XTENSA_REG_BITS(regname, opt) \ 117 XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX) 118 119 static const XtensaReg sregnames[256] = { 120 [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP), 121 [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP), 122 [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP), 123 [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL), 124 [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN), 125 [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R), 126 [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE), 127 [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16), 128 [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16), 129 [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16), 130 [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16), 131 [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16), 132 [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16), 133 [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER), 134 [WINDOW_START] = XTENSA_REG("WINDOW_START", 135 XTENSA_OPTION_WINDOWED_REGISTER), 136 [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU), 137 [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU), 138 [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU), 139 [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU), 140 [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG), 141 [MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL), 142 [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR), 143 [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL), 144 [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG), 145 [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG), 146 [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG), 147 [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG), 148 [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG), 149 [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG), 150 [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R), 151 [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION), 152 [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 153 [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 154 [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 155 [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 156 [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 157 [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 158 [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION), 159 [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 160 [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 161 [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 162 [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 163 [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 164 [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 165 [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R), 166 [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION), 167 [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2", 168 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 169 [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3", 170 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 171 [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4", 172 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 173 [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5", 174 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 175 [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6", 176 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 177 [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7", 178 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT), 179 [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR), 180 [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW), 181 [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W), 182 [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT), 183 [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL), 184 [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR), 185 [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION), 186 [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R), 187 [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT), 188 [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R), 189 [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG), 190 [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG), 191 [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION), 192 [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT), 193 [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1", 194 XTENSA_OPTION_TIMER_INTERRUPT), 195 [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2", 196 XTENSA_OPTION_TIMER_INTERRUPT), 197 [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR), 198 [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR), 199 [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR), 200 [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR), 201 }; 202 203 static const XtensaReg uregnames[256] = { 204 [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER), 205 [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR), 206 [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR), 207 }; 208 209 void xtensa_translate_init(void) 210 { 211 static const char * const regnames[] = { 212 "ar0", "ar1", "ar2", "ar3", 213 "ar4", "ar5", "ar6", "ar7", 214 "ar8", "ar9", "ar10", "ar11", 215 "ar12", "ar13", "ar14", "ar15", 216 }; 217 static const char * const fregnames[] = { 218 "f0", "f1", "f2", "f3", 219 "f4", "f5", "f6", "f7", 220 "f8", "f9", "f10", "f11", 221 "f12", "f13", "f14", "f15", 222 }; 223 int i; 224 225 cpu_pc = tcg_global_mem_new_i32(cpu_env, 226 offsetof(CPUXtensaState, pc), "pc"); 227 228 for (i = 0; i < 16; i++) { 229 cpu_R[i] = tcg_global_mem_new_i32(cpu_env, 230 offsetof(CPUXtensaState, regs[i]), 231 regnames[i]); 232 } 233 234 for (i = 0; i < 16; i++) { 235 cpu_FR[i] = tcg_global_mem_new_i32(cpu_env, 236 offsetof(CPUXtensaState, fregs[i].f32[FP_F32_LOW]), 237 fregnames[i]); 238 } 239 240 for (i = 0; i < 256; ++i) { 241 if (sregnames[i].name) { 242 cpu_SR[i] = tcg_global_mem_new_i32(cpu_env, 243 offsetof(CPUXtensaState, sregs[i]), 244 sregnames[i].name); 245 } 246 } 247 248 for (i = 0; i < 256; ++i) { 249 if (uregnames[i].name) { 250 cpu_UR[i] = tcg_global_mem_new_i32(cpu_env, 251 offsetof(CPUXtensaState, uregs[i]), 252 uregnames[i].name); 253 } 254 } 255 } 256 257 static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt) 258 { 259 return xtensa_option_bits_enabled(dc->config, opt); 260 } 261 262 static inline bool option_enabled(DisasContext *dc, int opt) 263 { 264 return xtensa_option_enabled(dc->config, opt); 265 } 266 267 static void init_litbase(DisasContext *dc) 268 { 269 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) { 270 dc->litbase = tcg_temp_local_new_i32(); 271 tcg_gen_andi_i32(dc->litbase, cpu_SR[LITBASE], 0xfffff000); 272 } 273 } 274 275 static void reset_litbase(DisasContext *dc) 276 { 277 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) { 278 tcg_temp_free(dc->litbase); 279 } 280 } 281 282 static void init_sar_tracker(DisasContext *dc) 283 { 284 dc->sar_5bit = false; 285 dc->sar_m32_5bit = false; 286 dc->sar_m32_allocated = false; 287 } 288 289 static void reset_sar_tracker(DisasContext *dc) 290 { 291 if (dc->sar_m32_allocated) { 292 tcg_temp_free(dc->sar_m32); 293 } 294 } 295 296 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa) 297 { 298 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f); 299 if (dc->sar_m32_5bit) { 300 tcg_gen_discard_i32(dc->sar_m32); 301 } 302 dc->sar_5bit = true; 303 dc->sar_m32_5bit = false; 304 } 305 306 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa) 307 { 308 TCGv_i32 tmp = tcg_const_i32(32); 309 if (!dc->sar_m32_allocated) { 310 dc->sar_m32 = tcg_temp_local_new_i32(); 311 dc->sar_m32_allocated = true; 312 } 313 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f); 314 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32); 315 dc->sar_5bit = false; 316 dc->sar_m32_5bit = true; 317 tcg_temp_free(tmp); 318 } 319 320 static void gen_exception(DisasContext *dc, int excp) 321 { 322 TCGv_i32 tmp = tcg_const_i32(excp); 323 gen_helper_exception(cpu_env, tmp); 324 tcg_temp_free(tmp); 325 } 326 327 static void gen_exception_cause(DisasContext *dc, uint32_t cause) 328 { 329 TCGv_i32 tpc = tcg_const_i32(dc->pc); 330 TCGv_i32 tcause = tcg_const_i32(cause); 331 gen_helper_exception_cause(cpu_env, tpc, tcause); 332 tcg_temp_free(tpc); 333 tcg_temp_free(tcause); 334 if (cause == ILLEGAL_INSTRUCTION_CAUSE || 335 cause == SYSCALL_CAUSE) { 336 dc->is_jmp = DISAS_UPDATE; 337 } 338 } 339 340 static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause, 341 TCGv_i32 vaddr) 342 { 343 TCGv_i32 tpc = tcg_const_i32(dc->pc); 344 TCGv_i32 tcause = tcg_const_i32(cause); 345 gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr); 346 tcg_temp_free(tpc); 347 tcg_temp_free(tcause); 348 } 349 350 static void gen_debug_exception(DisasContext *dc, uint32_t cause) 351 { 352 TCGv_i32 tpc = tcg_const_i32(dc->pc); 353 TCGv_i32 tcause = tcg_const_i32(cause); 354 gen_helper_debug_exception(cpu_env, tpc, tcause); 355 tcg_temp_free(tpc); 356 tcg_temp_free(tcause); 357 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) { 358 dc->is_jmp = DISAS_UPDATE; 359 } 360 } 361 362 static bool gen_check_privilege(DisasContext *dc) 363 { 364 if (dc->cring) { 365 gen_exception_cause(dc, PRIVILEGED_CAUSE); 366 dc->is_jmp = DISAS_UPDATE; 367 return false; 368 } 369 return true; 370 } 371 372 static bool gen_check_cpenable(DisasContext *dc, unsigned cp) 373 { 374 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) && 375 !(dc->cpenable & (1 << cp))) { 376 gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp); 377 dc->is_jmp = DISAS_UPDATE; 378 return false; 379 } 380 return true; 381 } 382 383 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) 384 { 385 tcg_gen_mov_i32(cpu_pc, dest); 386 if (dc->icount) { 387 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); 388 } 389 if (dc->singlestep_enabled) { 390 gen_exception(dc, EXCP_DEBUG); 391 } else { 392 if (slot >= 0) { 393 tcg_gen_goto_tb(slot); 394 tcg_gen_exit_tb((uintptr_t)dc->tb + slot); 395 } else { 396 tcg_gen_exit_tb(0); 397 } 398 } 399 dc->is_jmp = DISAS_UPDATE; 400 } 401 402 static void gen_jump(DisasContext *dc, TCGv dest) 403 { 404 gen_jump_slot(dc, dest, -1); 405 } 406 407 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot) 408 { 409 TCGv_i32 tmp = tcg_const_i32(dest); 410 #ifndef CONFIG_USER_ONLY 411 if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) { 412 slot = -1; 413 } 414 #endif 415 gen_jump_slot(dc, tmp, slot); 416 tcg_temp_free(tmp); 417 } 418 419 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest, 420 int slot) 421 { 422 TCGv_i32 tcallinc = tcg_const_i32(callinc); 423 424 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS], 425 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN); 426 tcg_temp_free(tcallinc); 427 tcg_gen_movi_i32(cpu_R[callinc << 2], 428 (callinc << 30) | (dc->next_pc & 0x3fffffff)); 429 gen_jump_slot(dc, dest, slot); 430 } 431 432 static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest) 433 { 434 gen_callw_slot(dc, callinc, dest, -1); 435 } 436 437 static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot) 438 { 439 TCGv_i32 tmp = tcg_const_i32(dest); 440 #ifndef CONFIG_USER_ONLY 441 if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) { 442 slot = -1; 443 } 444 #endif 445 gen_callw_slot(dc, callinc, tmp, slot); 446 tcg_temp_free(tmp); 447 } 448 449 static bool gen_check_loop_end(DisasContext *dc, int slot) 450 { 451 if (option_enabled(dc, XTENSA_OPTION_LOOP) && 452 !(dc->tb->flags & XTENSA_TBFLAG_EXCM) && 453 dc->next_pc == dc->lend) { 454 TCGLabel *label = gen_new_label(); 455 456 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); 457 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); 458 gen_jumpi(dc, dc->lbeg, slot); 459 gen_set_label(label); 460 gen_jumpi(dc, dc->next_pc, -1); 461 return true; 462 } 463 return false; 464 } 465 466 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot) 467 { 468 if (!gen_check_loop_end(dc, slot)) { 469 gen_jumpi(dc, dc->next_pc, slot); 470 } 471 } 472 473 static void gen_brcond(DisasContext *dc, TCGCond cond, 474 TCGv_i32 t0, TCGv_i32 t1, uint32_t offset) 475 { 476 TCGLabel *label = gen_new_label(); 477 478 tcg_gen_brcond_i32(cond, t0, t1, label); 479 gen_jumpi_check_loop_end(dc, 0); 480 gen_set_label(label); 481 gen_jumpi(dc, dc->pc + offset, 1); 482 } 483 484 static void gen_brcondi(DisasContext *dc, TCGCond cond, 485 TCGv_i32 t0, uint32_t t1, uint32_t offset) 486 { 487 TCGv_i32 tmp = tcg_const_i32(t1); 488 gen_brcond(dc, cond, t0, tmp, offset); 489 tcg_temp_free(tmp); 490 } 491 492 static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) 493 { 494 if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) { 495 if (sregnames[sr].name) { 496 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name); 497 } else { 498 qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr); 499 } 500 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 501 return false; 502 } else if (!(sregnames[sr].access & access)) { 503 static const char * const access_text[] = { 504 [SR_R] = "rsr", 505 [SR_W] = "wsr", 506 [SR_X] = "xsr", 507 }; 508 assert(access < ARRAY_SIZE(access_text) && access_text[access]); 509 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name, 510 access_text[access]); 511 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 512 return false; 513 } 514 return true; 515 } 516 517 static bool gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr) 518 { 519 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 520 gen_io_start(); 521 } 522 gen_helper_update_ccount(cpu_env); 523 tcg_gen_mov_i32(d, cpu_SR[sr]); 524 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 525 gen_io_end(); 526 return true; 527 } 528 return false; 529 } 530 531 static bool gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr) 532 { 533 tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10); 534 tcg_gen_or_i32(d, d, cpu_SR[sr]); 535 tcg_gen_andi_i32(d, d, 0xfffffffc); 536 return false; 537 } 538 539 static bool gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr) 540 { 541 static bool (* const rsr_handler[256])(DisasContext *dc, 542 TCGv_i32 d, uint32_t sr) = { 543 [CCOUNT] = gen_rsr_ccount, 544 [INTSET] = gen_rsr_ccount, 545 [PTEVADDR] = gen_rsr_ptevaddr, 546 }; 547 548 if (rsr_handler[sr]) { 549 return rsr_handler[sr](dc, d, sr); 550 } else { 551 tcg_gen_mov_i32(d, cpu_SR[sr]); 552 return false; 553 } 554 } 555 556 static bool gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s) 557 { 558 gen_helper_wsr_lbeg(cpu_env, s); 559 gen_jumpi_check_loop_end(dc, 0); 560 return false; 561 } 562 563 static bool gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s) 564 { 565 gen_helper_wsr_lend(cpu_env, s); 566 gen_jumpi_check_loop_end(dc, 0); 567 return false; 568 } 569 570 static bool gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s) 571 { 572 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f); 573 if (dc->sar_m32_5bit) { 574 tcg_gen_discard_i32(dc->sar_m32); 575 } 576 dc->sar_5bit = false; 577 dc->sar_m32_5bit = false; 578 return false; 579 } 580 581 static bool gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s) 582 { 583 tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff); 584 return false; 585 } 586 587 static bool gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s) 588 { 589 tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001); 590 /* This can change tb->flags, so exit tb */ 591 gen_jumpi_check_loop_end(dc, -1); 592 return true; 593 } 594 595 static bool gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s) 596 { 597 tcg_gen_ext8s_i32(cpu_SR[sr], s); 598 return false; 599 } 600 601 static bool gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) 602 { 603 gen_helper_wsr_windowbase(cpu_env, v); 604 /* This can change tb->flags, so exit tb */ 605 gen_jumpi_check_loop_end(dc, -1); 606 return true; 607 } 608 609 static bool gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v) 610 { 611 tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1); 612 /* This can change tb->flags, so exit tb */ 613 gen_jumpi_check_loop_end(dc, -1); 614 return true; 615 } 616 617 static bool gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v) 618 { 619 tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000); 620 return false; 621 } 622 623 static bool gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v) 624 { 625 gen_helper_wsr_rasid(cpu_env, v); 626 /* This can change tb->flags, so exit tb */ 627 gen_jumpi_check_loop_end(dc, -1); 628 return true; 629 } 630 631 static bool gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v) 632 { 633 tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000); 634 return false; 635 } 636 637 static bool gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) 638 { 639 gen_helper_wsr_ibreakenable(cpu_env, v); 640 gen_jumpi_check_loop_end(dc, 0); 641 return true; 642 } 643 644 static bool gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v) 645 { 646 gen_helper_wsr_memctl(cpu_env, v); 647 return false; 648 } 649 650 static bool gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v) 651 { 652 tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f); 653 return false; 654 } 655 656 static bool gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) 657 { 658 unsigned id = sr - IBREAKA; 659 660 if (id < dc->config->nibreak) { 661 TCGv_i32 tmp = tcg_const_i32(id); 662 gen_helper_wsr_ibreaka(cpu_env, tmp, v); 663 tcg_temp_free(tmp); 664 gen_jumpi_check_loop_end(dc, 0); 665 return true; 666 } 667 return false; 668 } 669 670 static bool gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v) 671 { 672 unsigned id = sr - DBREAKA; 673 674 if (id < dc->config->ndbreak) { 675 TCGv_i32 tmp = tcg_const_i32(id); 676 gen_helper_wsr_dbreaka(cpu_env, tmp, v); 677 tcg_temp_free(tmp); 678 } 679 return false; 680 } 681 682 static bool gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v) 683 { 684 unsigned id = sr - DBREAKC; 685 686 if (id < dc->config->ndbreak) { 687 TCGv_i32 tmp = tcg_const_i32(id); 688 gen_helper_wsr_dbreakc(cpu_env, tmp, v); 689 tcg_temp_free(tmp); 690 } 691 return false; 692 } 693 694 static bool gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) 695 { 696 tcg_gen_andi_i32(cpu_SR[sr], v, 0xff); 697 /* This can change tb->flags, so exit tb */ 698 gen_jumpi_check_loop_end(dc, -1); 699 return true; 700 } 701 702 static void gen_check_interrupts(DisasContext *dc) 703 { 704 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 705 gen_io_start(); 706 } 707 gen_helper_check_interrupts(cpu_env); 708 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 709 gen_io_end(); 710 } 711 } 712 713 static bool gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v) 714 { 715 tcg_gen_andi_i32(cpu_SR[sr], v, 716 dc->config->inttype_mask[INTTYPE_SOFTWARE]); 717 gen_check_interrupts(dc); 718 gen_jumpi_check_loop_end(dc, 0); 719 return true; 720 } 721 722 static bool gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v) 723 { 724 TCGv_i32 tmp = tcg_temp_new_i32(); 725 726 tcg_gen_andi_i32(tmp, v, 727 dc->config->inttype_mask[INTTYPE_EDGE] | 728 dc->config->inttype_mask[INTTYPE_NMI] | 729 dc->config->inttype_mask[INTTYPE_SOFTWARE]); 730 tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp); 731 tcg_temp_free(tmp); 732 gen_check_interrupts(dc); 733 gen_jumpi_check_loop_end(dc, 0); 734 return true; 735 } 736 737 static bool gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v) 738 { 739 tcg_gen_mov_i32(cpu_SR[sr], v); 740 gen_check_interrupts(dc); 741 gen_jumpi_check_loop_end(dc, 0); 742 return true; 743 } 744 745 static bool gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) 746 { 747 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB | 748 PS_UM | PS_EXCM | PS_INTLEVEL; 749 750 if (option_enabled(dc, XTENSA_OPTION_MMU)) { 751 mask |= PS_RING; 752 } 753 tcg_gen_andi_i32(cpu_SR[sr], v, mask); 754 gen_check_interrupts(dc); 755 /* This can change mmu index and tb->flags, so exit tb */ 756 gen_jumpi_check_loop_end(dc, -1); 757 return true; 758 } 759 760 static bool gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v) 761 { 762 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 763 gen_io_start(); 764 } 765 gen_helper_wsr_ccount(cpu_env, v); 766 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 767 gen_io_end(); 768 gen_jumpi_check_loop_end(dc, 0); 769 return true; 770 } 771 return false; 772 } 773 774 static bool gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v) 775 { 776 if (dc->icount) { 777 tcg_gen_mov_i32(dc->next_icount, v); 778 } else { 779 tcg_gen_mov_i32(cpu_SR[sr], v); 780 } 781 return false; 782 } 783 784 static bool gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v) 785 { 786 tcg_gen_andi_i32(cpu_SR[sr], v, 0xf); 787 /* This can change tb->flags, so exit tb */ 788 gen_jumpi_check_loop_end(dc, -1); 789 return true; 790 } 791 792 static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v) 793 { 794 uint32_t id = sr - CCOMPARE; 795 bool ret = false; 796 797 if (id < dc->config->nccompare) { 798 uint32_t int_bit = 1 << dc->config->timerint[id]; 799 TCGv_i32 tmp = tcg_const_i32(id); 800 801 tcg_gen_mov_i32(cpu_SR[sr], v); 802 tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit); 803 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 804 gen_io_start(); 805 } 806 gen_helper_update_ccompare(cpu_env, tmp); 807 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 808 gen_io_end(); 809 gen_jumpi_check_loop_end(dc, 0); 810 ret = true; 811 } 812 tcg_temp_free(tmp); 813 } 814 return ret; 815 } 816 817 static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) 818 { 819 static bool (* const wsr_handler[256])(DisasContext *dc, 820 uint32_t sr, TCGv_i32 v) = { 821 [LBEG] = gen_wsr_lbeg, 822 [LEND] = gen_wsr_lend, 823 [SAR] = gen_wsr_sar, 824 [BR] = gen_wsr_br, 825 [LITBASE] = gen_wsr_litbase, 826 [ACCHI] = gen_wsr_acchi, 827 [WINDOW_BASE] = gen_wsr_windowbase, 828 [WINDOW_START] = gen_wsr_windowstart, 829 [PTEVADDR] = gen_wsr_ptevaddr, 830 [RASID] = gen_wsr_rasid, 831 [ITLBCFG] = gen_wsr_tlbcfg, 832 [DTLBCFG] = gen_wsr_tlbcfg, 833 [IBREAKENABLE] = gen_wsr_ibreakenable, 834 [MEMCTL] = gen_wsr_memctl, 835 [ATOMCTL] = gen_wsr_atomctl, 836 [IBREAKA] = gen_wsr_ibreaka, 837 [IBREAKA + 1] = gen_wsr_ibreaka, 838 [DBREAKA] = gen_wsr_dbreaka, 839 [DBREAKA + 1] = gen_wsr_dbreaka, 840 [DBREAKC] = gen_wsr_dbreakc, 841 [DBREAKC + 1] = gen_wsr_dbreakc, 842 [CPENABLE] = gen_wsr_cpenable, 843 [INTSET] = gen_wsr_intset, 844 [INTCLEAR] = gen_wsr_intclear, 845 [INTENABLE] = gen_wsr_intenable, 846 [PS] = gen_wsr_ps, 847 [CCOUNT] = gen_wsr_ccount, 848 [ICOUNT] = gen_wsr_icount, 849 [ICOUNTLEVEL] = gen_wsr_icountlevel, 850 [CCOMPARE] = gen_wsr_ccompare, 851 [CCOMPARE + 1] = gen_wsr_ccompare, 852 [CCOMPARE + 2] = gen_wsr_ccompare, 853 }; 854 855 if (wsr_handler[sr]) { 856 return wsr_handler[sr](dc, sr, s); 857 } else { 858 tcg_gen_mov_i32(cpu_SR[sr], s); 859 return false; 860 } 861 } 862 863 static void gen_wur(uint32_t ur, TCGv_i32 s) 864 { 865 switch (ur) { 866 case FCR: 867 gen_helper_wur_fcr(cpu_env, s); 868 break; 869 870 case FSR: 871 tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80); 872 break; 873 874 default: 875 tcg_gen_mov_i32(cpu_UR[ur], s); 876 break; 877 } 878 } 879 880 static void gen_load_store_alignment(DisasContext *dc, int shift, 881 TCGv_i32 addr, bool no_hw_alignment) 882 { 883 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) { 884 tcg_gen_andi_i32(addr, addr, ~0 << shift); 885 } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) && 886 no_hw_alignment) { 887 TCGLabel *label = gen_new_label(); 888 TCGv_i32 tmp = tcg_temp_new_i32(); 889 tcg_gen_andi_i32(tmp, addr, ~(~0 << shift)); 890 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 891 gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr); 892 gen_set_label(label); 893 tcg_temp_free(tmp); 894 } 895 } 896 897 static void gen_waiti(DisasContext *dc, uint32_t imm4) 898 { 899 TCGv_i32 pc = tcg_const_i32(dc->next_pc); 900 TCGv_i32 intlevel = tcg_const_i32(imm4); 901 902 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 903 gen_io_start(); 904 } 905 gen_helper_waiti(cpu_env, pc, intlevel); 906 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { 907 gen_io_end(); 908 } 909 tcg_temp_free(pc); 910 tcg_temp_free(intlevel); 911 gen_jumpi_check_loop_end(dc, 0); 912 } 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(unsigned op0) 951 { 952 return op0 >= 8 ? 2 : 3; 953 } 954 955 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) 956 { 957 #define HAS_OPTION_BITS(opt) do { \ 958 if (!option_bits_enabled(dc, opt)) { \ 959 qemu_log_mask(LOG_GUEST_ERROR, "Option is not enabled %s:%d\n", \ 960 __FILE__, __LINE__); \ 961 goto invalid_opcode; \ 962 } \ 963 } while (0) 964 965 #define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt)) 966 967 #define TBD() qemu_log_mask(LOG_UNIMP, "TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__) 968 #define RESERVED() do { \ 969 qemu_log_mask(LOG_GUEST_ERROR, "RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \ 970 dc->pc, b0, b1, b2, __FILE__, __LINE__); \ 971 goto invalid_opcode; \ 972 } while (0) 973 974 975 #ifdef TARGET_WORDS_BIGENDIAN 976 #define OP0 (((b0) & 0xf0) >> 4) 977 #define OP1 (((b2) & 0xf0) >> 4) 978 #define OP2 ((b2) & 0xf) 979 #define RRR_R ((b1) & 0xf) 980 #define RRR_S (((b1) & 0xf0) >> 4) 981 #define RRR_T ((b0) & 0xf) 982 #else 983 #define OP0 (((b0) & 0xf)) 984 #define OP1 (((b2) & 0xf)) 985 #define OP2 (((b2) & 0xf0) >> 4) 986 #define RRR_R (((b1) & 0xf0) >> 4) 987 #define RRR_S (((b1) & 0xf)) 988 #define RRR_T (((b0) & 0xf0) >> 4) 989 #endif 990 #define RRR_X ((RRR_R & 0x4) >> 2) 991 #define RRR_Y ((RRR_T & 0x4) >> 2) 992 #define RRR_W (RRR_R & 0x3) 993 994 #define RRRN_R RRR_R 995 #define RRRN_S RRR_S 996 #define RRRN_T RRR_T 997 998 #define RRI4_R RRR_R 999 #define RRI4_S RRR_S 1000 #define RRI4_T RRR_T 1001 #ifdef TARGET_WORDS_BIGENDIAN 1002 #define RRI4_IMM4 ((b2) & 0xf) 1003 #else 1004 #define RRI4_IMM4 (((b2) & 0xf0) >> 4) 1005 #endif 1006 1007 #define RRI8_R RRR_R 1008 #define RRI8_S RRR_S 1009 #define RRI8_T RRR_T 1010 #define RRI8_IMM8 (b2) 1011 #define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8) 1012 1013 #ifdef TARGET_WORDS_BIGENDIAN 1014 #define RI16_IMM16 (((b1) << 8) | (b2)) 1015 #else 1016 #define RI16_IMM16 (((b2) << 8) | (b1)) 1017 #endif 1018 1019 #ifdef TARGET_WORDS_BIGENDIAN 1020 #define CALL_N (((b0) & 0xc) >> 2) 1021 #define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2)) 1022 #else 1023 #define CALL_N (((b0) & 0x30) >> 4) 1024 #define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10)) 1025 #endif 1026 #define CALL_OFFSET_SE \ 1027 (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET) 1028 1029 #define CALLX_N CALL_N 1030 #ifdef TARGET_WORDS_BIGENDIAN 1031 #define CALLX_M ((b0) & 0x3) 1032 #else 1033 #define CALLX_M (((b0) & 0xc0) >> 6) 1034 #endif 1035 #define CALLX_S RRR_S 1036 1037 #define BRI12_M CALLX_M 1038 #define BRI12_S RRR_S 1039 #ifdef TARGET_WORDS_BIGENDIAN 1040 #define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2)) 1041 #else 1042 #define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4)) 1043 #endif 1044 #define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12) 1045 1046 #define BRI8_M BRI12_M 1047 #define BRI8_R RRI8_R 1048 #define BRI8_S RRI8_S 1049 #define BRI8_IMM8 RRI8_IMM8 1050 #define BRI8_IMM8_SE RRI8_IMM8_SE 1051 1052 #define RSR_SR (b1) 1053 1054 uint8_t b0 = cpu_ldub_code(env, dc->pc); 1055 uint8_t b1 = cpu_ldub_code(env, dc->pc + 1); 1056 uint8_t b2 = 0; 1057 unsigned len = xtensa_op0_insn_len(OP0); 1058 1059 static const uint32_t B4CONST[] = { 1060 0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256 1061 }; 1062 1063 static const uint32_t B4CONSTU[] = { 1064 32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256 1065 }; 1066 1067 switch (len) { 1068 case 2: 1069 HAS_OPTION(XTENSA_OPTION_CODE_DENSITY); 1070 break; 1071 1072 case 3: 1073 b2 = cpu_ldub_code(env, dc->pc + 2); 1074 break; 1075 1076 default: 1077 RESERVED(); 1078 } 1079 dc->next_pc = dc->pc + len; 1080 1081 switch (OP0) { 1082 case 0: /*QRST*/ 1083 switch (OP1) { 1084 case 0: /*RST0*/ 1085 switch (OP2) { 1086 case 0: /*ST0*/ 1087 if ((RRR_R & 0xc) == 0x8) { 1088 HAS_OPTION(XTENSA_OPTION_BOOLEAN); 1089 } 1090 1091 switch (RRR_R) { 1092 case 0: /*SNM0*/ 1093 switch (CALLX_M) { 1094 case 0: /*ILL*/ 1095 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1096 break; 1097 1098 case 1: /*reserved*/ 1099 RESERVED(); 1100 break; 1101 1102 case 2: /*JR*/ 1103 switch (CALLX_N) { 1104 case 0: /*RET*/ 1105 case 2: /*JX*/ 1106 if (gen_window_check1(dc, CALLX_S)) { 1107 gen_jump(dc, cpu_R[CALLX_S]); 1108 } 1109 break; 1110 1111 case 1: /*RETWw*/ 1112 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 1113 { 1114 TCGv_i32 tmp = tcg_const_i32(dc->pc); 1115 gen_helper_retw(tmp, cpu_env, tmp); 1116 gen_jump(dc, tmp); 1117 tcg_temp_free(tmp); 1118 } 1119 break; 1120 1121 case 3: /*reserved*/ 1122 RESERVED(); 1123 break; 1124 } 1125 break; 1126 1127 case 3: /*CALLX*/ 1128 if (!gen_window_check2(dc, CALLX_S, CALLX_N << 2)) { 1129 break; 1130 } 1131 switch (CALLX_N) { 1132 case 0: /*CALLX0*/ 1133 { 1134 TCGv_i32 tmp = tcg_temp_new_i32(); 1135 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]); 1136 tcg_gen_movi_i32(cpu_R[0], dc->next_pc); 1137 gen_jump(dc, tmp); 1138 tcg_temp_free(tmp); 1139 } 1140 break; 1141 1142 case 1: /*CALLX4w*/ 1143 case 2: /*CALLX8w*/ 1144 case 3: /*CALLX12w*/ 1145 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 1146 { 1147 TCGv_i32 tmp = tcg_temp_new_i32(); 1148 1149 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]); 1150 gen_callw(dc, CALLX_N, tmp); 1151 tcg_temp_free(tmp); 1152 } 1153 break; 1154 } 1155 break; 1156 } 1157 break; 1158 1159 case 1: /*MOVSPw*/ 1160 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 1161 if (gen_window_check2(dc, RRR_T, RRR_S)) { 1162 TCGv_i32 pc = tcg_const_i32(dc->pc); 1163 gen_helper_movsp(cpu_env, pc); 1164 tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]); 1165 tcg_temp_free(pc); 1166 } 1167 break; 1168 1169 case 2: /*SYNC*/ 1170 switch (RRR_T) { 1171 case 0: /*ISYNC*/ 1172 break; 1173 1174 case 1: /*RSYNC*/ 1175 break; 1176 1177 case 2: /*ESYNC*/ 1178 break; 1179 1180 case 3: /*DSYNC*/ 1181 break; 1182 1183 case 8: /*EXCW*/ 1184 HAS_OPTION(XTENSA_OPTION_EXCEPTION); 1185 break; 1186 1187 case 12: /*MEMW*/ 1188 break; 1189 1190 case 13: /*EXTW*/ 1191 break; 1192 1193 case 15: /*NOP*/ 1194 break; 1195 1196 default: /*reserved*/ 1197 RESERVED(); 1198 break; 1199 } 1200 break; 1201 1202 case 3: /*RFEIx*/ 1203 switch (RRR_T) { 1204 case 0: /*RFETx*/ 1205 HAS_OPTION(XTENSA_OPTION_EXCEPTION); 1206 switch (RRR_S) { 1207 case 0: /*RFEx*/ 1208 if (gen_check_privilege(dc)) { 1209 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 1210 gen_check_interrupts(dc); 1211 gen_jump(dc, cpu_SR[EPC1]); 1212 } 1213 break; 1214 1215 case 1: /*RFUEx*/ 1216 RESERVED(); 1217 break; 1218 1219 case 2: /*RFDEx*/ 1220 if (gen_check_privilege(dc)) { 1221 gen_jump(dc, cpu_SR[ 1222 dc->config->ndepc ? DEPC : EPC1]); 1223 } 1224 break; 1225 1226 case 4: /*RFWOw*/ 1227 case 5: /*RFWUw*/ 1228 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 1229 if (gen_check_privilege(dc)) { 1230 TCGv_i32 tmp = tcg_const_i32(1); 1231 1232 tcg_gen_andi_i32( 1233 cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 1234 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); 1235 1236 if (RRR_S == 4) { 1237 tcg_gen_andc_i32(cpu_SR[WINDOW_START], 1238 cpu_SR[WINDOW_START], tmp); 1239 } else { 1240 tcg_gen_or_i32(cpu_SR[WINDOW_START], 1241 cpu_SR[WINDOW_START], tmp); 1242 } 1243 1244 gen_helper_restore_owb(cpu_env); 1245 gen_check_interrupts(dc); 1246 gen_jump(dc, cpu_SR[EPC1]); 1247 1248 tcg_temp_free(tmp); 1249 } 1250 break; 1251 1252 default: /*reserved*/ 1253 RESERVED(); 1254 break; 1255 } 1256 break; 1257 1258 case 1: /*RFIx*/ 1259 HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT); 1260 if (RRR_S >= 2 && RRR_S <= dc->config->nlevel) { 1261 if (gen_check_privilege(dc)) { 1262 tcg_gen_mov_i32(cpu_SR[PS], 1263 cpu_SR[EPS2 + RRR_S - 2]); 1264 gen_check_interrupts(dc); 1265 gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]); 1266 } 1267 } else { 1268 qemu_log_mask(LOG_GUEST_ERROR, "RFI %d is illegal\n", RRR_S); 1269 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1270 } 1271 break; 1272 1273 case 2: /*RFME*/ 1274 TBD(); 1275 break; 1276 1277 default: /*reserved*/ 1278 RESERVED(); 1279 break; 1280 1281 } 1282 break; 1283 1284 case 4: /*BREAKx*/ 1285 HAS_OPTION(XTENSA_OPTION_DEBUG); 1286 if (dc->debug) { 1287 gen_debug_exception(dc, DEBUGCAUSE_BI); 1288 } 1289 break; 1290 1291 case 5: /*SYSCALLx*/ 1292 HAS_OPTION(XTENSA_OPTION_EXCEPTION); 1293 switch (RRR_S) { 1294 case 0: /*SYSCALLx*/ 1295 gen_exception_cause(dc, SYSCALL_CAUSE); 1296 break; 1297 1298 case 1: /*SIMCALL*/ 1299 if (semihosting_enabled()) { 1300 if (gen_check_privilege(dc)) { 1301 gen_helper_simcall(cpu_env); 1302 } 1303 } else { 1304 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n"); 1305 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 1306 } 1307 break; 1308 1309 default: 1310 RESERVED(); 1311 break; 1312 } 1313 break; 1314 1315 case 6: /*RSILx*/ 1316 HAS_OPTION(XTENSA_OPTION_INTERRUPT); 1317 if (gen_check_privilege(dc) && 1318 gen_window_check1(dc, RRR_T)) { 1319 tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]); 1320 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL); 1321 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S); 1322 gen_check_interrupts(dc); 1323 gen_jumpi_check_loop_end(dc, 0); 1324 } 1325 break; 1326 1327 case 7: /*WAITIx*/ 1328 HAS_OPTION(XTENSA_OPTION_INTERRUPT); 1329 if (gen_check_privilege(dc)) { 1330 gen_waiti(dc, RRR_S); 1331 } 1332 break; 1333 1334 case 8: /*ANY4p*/ 1335 case 9: /*ALL4p*/ 1336 case 10: /*ANY8p*/ 1337 case 11: /*ALL8p*/ 1338 HAS_OPTION(XTENSA_OPTION_BOOLEAN); 1339 { 1340 const unsigned shift = (RRR_R & 2) ? 8 : 4; 1341 TCGv_i32 mask = tcg_const_i32( 1342 ((1 << shift) - 1) << RRR_S); 1343 TCGv_i32 tmp = tcg_temp_new_i32(); 1344 1345 tcg_gen_and_i32(tmp, cpu_SR[BR], mask); 1346 if (RRR_R & 1) { /*ALL*/ 1347 tcg_gen_addi_i32(tmp, tmp, 1 << RRR_S); 1348 } else { /*ANY*/ 1349 tcg_gen_add_i32(tmp, tmp, mask); 1350 } 1351 tcg_gen_shri_i32(tmp, tmp, RRR_S + shift); 1352 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], 1353 tmp, RRR_T, 1); 1354 tcg_temp_free(mask); 1355 tcg_temp_free(tmp); 1356 } 1357 break; 1358 1359 default: /*reserved*/ 1360 RESERVED(); 1361 break; 1362 1363 } 1364 break; 1365 1366 case 1: /*AND*/ 1367 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1368 tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1369 } 1370 break; 1371 1372 case 2: /*OR*/ 1373 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1374 tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1375 } 1376 break; 1377 1378 case 3: /*XOR*/ 1379 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1380 tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1381 } 1382 break; 1383 1384 case 4: /*ST1*/ 1385 switch (RRR_R) { 1386 case 0: /*SSR*/ 1387 if (gen_window_check1(dc, RRR_S)) { 1388 gen_right_shift_sar(dc, cpu_R[RRR_S]); 1389 } 1390 break; 1391 1392 case 1: /*SSL*/ 1393 if (gen_window_check1(dc, RRR_S)) { 1394 gen_left_shift_sar(dc, cpu_R[RRR_S]); 1395 } 1396 break; 1397 1398 case 2: /*SSA8L*/ 1399 if (gen_window_check1(dc, RRR_S)) { 1400 TCGv_i32 tmp = tcg_temp_new_i32(); 1401 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3); 1402 gen_right_shift_sar(dc, tmp); 1403 tcg_temp_free(tmp); 1404 } 1405 break; 1406 1407 case 3: /*SSA8B*/ 1408 if (gen_window_check1(dc, RRR_S)) { 1409 TCGv_i32 tmp = tcg_temp_new_i32(); 1410 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3); 1411 gen_left_shift_sar(dc, tmp); 1412 tcg_temp_free(tmp); 1413 } 1414 break; 1415 1416 case 4: /*SSAI*/ 1417 { 1418 TCGv_i32 tmp = tcg_const_i32( 1419 RRR_S | ((RRR_T & 1) << 4)); 1420 gen_right_shift_sar(dc, tmp); 1421 tcg_temp_free(tmp); 1422 } 1423 break; 1424 1425 case 6: /*RER*/ 1426 HAS_OPTION(XTENSA_OPTION_EXTERN_REGS); 1427 if (gen_check_privilege(dc) && 1428 gen_window_check2(dc, RRR_S, RRR_T)) { 1429 gen_helper_rer(cpu_R[RRR_T], cpu_env, cpu_R[RRR_S]); 1430 } 1431 break; 1432 1433 case 7: /*WER*/ 1434 HAS_OPTION(XTENSA_OPTION_EXTERN_REGS); 1435 if (gen_check_privilege(dc) && 1436 gen_window_check2(dc, RRR_S, RRR_T)) { 1437 gen_helper_wer(cpu_env, cpu_R[RRR_T], cpu_R[RRR_S]); 1438 } 1439 break; 1440 1441 case 8: /*ROTWw*/ 1442 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 1443 if (gen_check_privilege(dc)) { 1444 TCGv_i32 tmp = tcg_const_i32( 1445 RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0)); 1446 gen_helper_rotw(cpu_env, tmp); 1447 tcg_temp_free(tmp); 1448 /* This can change tb->flags, so exit tb */ 1449 gen_jumpi_check_loop_end(dc, -1); 1450 } 1451 break; 1452 1453 case 14: /*NSAu*/ 1454 HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA); 1455 if (gen_window_check2(dc, RRR_S, RRR_T)) { 1456 tcg_gen_clrsb_i32(cpu_R[RRR_T], cpu_R[RRR_S]); 1457 } 1458 break; 1459 1460 case 15: /*NSAUu*/ 1461 HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA); 1462 if (gen_window_check2(dc, RRR_S, RRR_T)) { 1463 tcg_gen_clzi_i32(cpu_R[RRR_T], cpu_R[RRR_S], 32); 1464 } 1465 break; 1466 1467 default: /*reserved*/ 1468 RESERVED(); 1469 break; 1470 } 1471 break; 1472 1473 case 5: /*TLB*/ 1474 HAS_OPTION_BITS( 1475 XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) | 1476 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) | 1477 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION)); 1478 if (gen_check_privilege(dc) && 1479 gen_window_check2(dc, RRR_S, RRR_T)) { 1480 TCGv_i32 dtlb = tcg_const_i32((RRR_R & 8) != 0); 1481 1482 switch (RRR_R & 7) { 1483 case 3: /*RITLB0*/ /*RDTLB0*/ 1484 gen_helper_rtlb0(cpu_R[RRR_T], 1485 cpu_env, cpu_R[RRR_S], dtlb); 1486 break; 1487 1488 case 4: /*IITLB*/ /*IDTLB*/ 1489 gen_helper_itlb(cpu_env, cpu_R[RRR_S], dtlb); 1490 /* This could change memory mapping, so exit tb */ 1491 gen_jumpi_check_loop_end(dc, -1); 1492 break; 1493 1494 case 5: /*PITLB*/ /*PDTLB*/ 1495 tcg_gen_movi_i32(cpu_pc, dc->pc); 1496 gen_helper_ptlb(cpu_R[RRR_T], 1497 cpu_env, cpu_R[RRR_S], dtlb); 1498 break; 1499 1500 case 6: /*WITLB*/ /*WDTLB*/ 1501 gen_helper_wtlb( 1502 cpu_env, cpu_R[RRR_T], cpu_R[RRR_S], dtlb); 1503 /* This could change memory mapping, so exit tb */ 1504 gen_jumpi_check_loop_end(dc, -1); 1505 break; 1506 1507 case 7: /*RITLB1*/ /*RDTLB1*/ 1508 gen_helper_rtlb1(cpu_R[RRR_T], 1509 cpu_env, cpu_R[RRR_S], dtlb); 1510 break; 1511 1512 default: 1513 tcg_temp_free(dtlb); 1514 RESERVED(); 1515 break; 1516 } 1517 tcg_temp_free(dtlb); 1518 } 1519 break; 1520 1521 case 6: /*RT0*/ 1522 if (!gen_window_check2(dc, RRR_R, RRR_T)) { 1523 break; 1524 } 1525 switch (RRR_S) { 1526 case 0: /*NEG*/ 1527 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]); 1528 break; 1529 1530 case 1: /*ABS*/ 1531 { 1532 TCGv_i32 zero = tcg_const_i32(0); 1533 TCGv_i32 neg = tcg_temp_new_i32(); 1534 1535 tcg_gen_neg_i32(neg, cpu_R[RRR_T]); 1536 tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[RRR_R], 1537 cpu_R[RRR_T], zero, cpu_R[RRR_T], neg); 1538 tcg_temp_free(neg); 1539 tcg_temp_free(zero); 1540 } 1541 break; 1542 1543 default: /*reserved*/ 1544 RESERVED(); 1545 break; 1546 } 1547 break; 1548 1549 case 7: /*reserved*/ 1550 RESERVED(); 1551 break; 1552 1553 case 8: /*ADD*/ 1554 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1555 tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1556 } 1557 break; 1558 1559 case 9: /*ADD**/ 1560 case 10: 1561 case 11: 1562 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1563 TCGv_i32 tmp = tcg_temp_new_i32(); 1564 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8); 1565 tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]); 1566 tcg_temp_free(tmp); 1567 } 1568 break; 1569 1570 case 12: /*SUB*/ 1571 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1572 tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1573 } 1574 break; 1575 1576 case 13: /*SUB**/ 1577 case 14: 1578 case 15: 1579 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1580 TCGv_i32 tmp = tcg_temp_new_i32(); 1581 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12); 1582 tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]); 1583 tcg_temp_free(tmp); 1584 } 1585 break; 1586 } 1587 break; 1588 1589 case 1: /*RST1*/ 1590 switch (OP2) { 1591 case 0: /*SLLI*/ 1592 case 1: 1593 if (gen_window_check2(dc, RRR_R, RRR_S)) { 1594 tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S], 1595 32 - (RRR_T | ((OP2 & 1) << 4))); 1596 } 1597 break; 1598 1599 case 2: /*SRAI*/ 1600 case 3: 1601 if (gen_window_check2(dc, RRR_R, RRR_T)) { 1602 tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T], 1603 RRR_S | ((OP2 & 1) << 4)); 1604 } 1605 break; 1606 1607 case 4: /*SRLI*/ 1608 if (gen_window_check2(dc, RRR_R, RRR_T)) { 1609 tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S); 1610 } 1611 break; 1612 1613 case 6: /*XSR*/ 1614 if (gen_check_sr(dc, RSR_SR, SR_X) && 1615 (RSR_SR < 64 || gen_check_privilege(dc)) && 1616 gen_window_check1(dc, RRR_T)) { 1617 TCGv_i32 tmp = tcg_temp_new_i32(); 1618 bool rsr_end, wsr_end; 1619 1620 tcg_gen_mov_i32(tmp, cpu_R[RRR_T]); 1621 rsr_end = gen_rsr(dc, cpu_R[RRR_T], RSR_SR); 1622 wsr_end = gen_wsr(dc, RSR_SR, tmp); 1623 tcg_temp_free(tmp); 1624 if (rsr_end && !wsr_end) { 1625 gen_jumpi_check_loop_end(dc, 0); 1626 } 1627 } 1628 break; 1629 1630 /* 1631 * Note: 64 bit ops are used here solely because SAR values 1632 * have range 0..63 1633 */ 1634 #define gen_shift_reg(cmd, reg) do { \ 1635 TCGv_i64 tmp = tcg_temp_new_i64(); \ 1636 tcg_gen_extu_i32_i64(tmp, reg); \ 1637 tcg_gen_##cmd##_i64(v, v, tmp); \ 1638 tcg_gen_extrl_i64_i32(cpu_R[RRR_R], v); \ 1639 tcg_temp_free_i64(v); \ 1640 tcg_temp_free_i64(tmp); \ 1641 } while (0) 1642 1643 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR]) 1644 1645 case 8: /*SRC*/ 1646 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1647 TCGv_i64 v = tcg_temp_new_i64(); 1648 tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]); 1649 gen_shift(shr); 1650 } 1651 break; 1652 1653 case 9: /*SRL*/ 1654 if (!gen_window_check2(dc, RRR_R, RRR_T)) { 1655 break; 1656 } 1657 if (dc->sar_5bit) { 1658 tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]); 1659 } else { 1660 TCGv_i64 v = tcg_temp_new_i64(); 1661 tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]); 1662 gen_shift(shr); 1663 } 1664 break; 1665 1666 case 10: /*SLL*/ 1667 if (!gen_window_check2(dc, RRR_R, RRR_S)) { 1668 break; 1669 } 1670 if (dc->sar_m32_5bit) { 1671 tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32); 1672 } else { 1673 TCGv_i64 v = tcg_temp_new_i64(); 1674 TCGv_i32 s = tcg_const_i32(32); 1675 tcg_gen_sub_i32(s, s, cpu_SR[SAR]); 1676 tcg_gen_andi_i32(s, s, 0x3f); 1677 tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]); 1678 gen_shift_reg(shl, s); 1679 tcg_temp_free(s); 1680 } 1681 break; 1682 1683 case 11: /*SRA*/ 1684 if (!gen_window_check2(dc, RRR_R, RRR_T)) { 1685 break; 1686 } 1687 if (dc->sar_5bit) { 1688 tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]); 1689 } else { 1690 TCGv_i64 v = tcg_temp_new_i64(); 1691 tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]); 1692 gen_shift(sar); 1693 } 1694 break; 1695 #undef gen_shift 1696 #undef gen_shift_reg 1697 1698 case 12: /*MUL16U*/ 1699 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL); 1700 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1701 TCGv_i32 v1 = tcg_temp_new_i32(); 1702 TCGv_i32 v2 = tcg_temp_new_i32(); 1703 tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]); 1704 tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]); 1705 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2); 1706 tcg_temp_free(v2); 1707 tcg_temp_free(v1); 1708 } 1709 break; 1710 1711 case 13: /*MUL16S*/ 1712 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL); 1713 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1714 TCGv_i32 v1 = tcg_temp_new_i32(); 1715 TCGv_i32 v2 = tcg_temp_new_i32(); 1716 tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]); 1717 tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]); 1718 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2); 1719 tcg_temp_free(v2); 1720 tcg_temp_free(v1); 1721 } 1722 break; 1723 1724 default: /*reserved*/ 1725 RESERVED(); 1726 break; 1727 } 1728 break; 1729 1730 case 2: /*RST2*/ 1731 if (OP2 >= 8 && !gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1732 break; 1733 } 1734 1735 if (OP2 >= 12) { 1736 HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV); 1737 TCGLabel *label = gen_new_label(); 1738 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label); 1739 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE); 1740 gen_set_label(label); 1741 } 1742 1743 switch (OP2) { 1744 #define BOOLEAN_LOGIC(fn, r, s, t) \ 1745 do { \ 1746 HAS_OPTION(XTENSA_OPTION_BOOLEAN); \ 1747 TCGv_i32 tmp1 = tcg_temp_new_i32(); \ 1748 TCGv_i32 tmp2 = tcg_temp_new_i32(); \ 1749 \ 1750 tcg_gen_shri_i32(tmp1, cpu_SR[BR], s); \ 1751 tcg_gen_shri_i32(tmp2, cpu_SR[BR], t); \ 1752 tcg_gen_##fn##_i32(tmp1, tmp1, tmp2); \ 1753 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, r, 1); \ 1754 tcg_temp_free(tmp1); \ 1755 tcg_temp_free(tmp2); \ 1756 } while (0) 1757 1758 case 0: /*ANDBp*/ 1759 BOOLEAN_LOGIC(and, RRR_R, RRR_S, RRR_T); 1760 break; 1761 1762 case 1: /*ANDBCp*/ 1763 BOOLEAN_LOGIC(andc, RRR_R, RRR_S, RRR_T); 1764 break; 1765 1766 case 2: /*ORBp*/ 1767 BOOLEAN_LOGIC(or, RRR_R, RRR_S, RRR_T); 1768 break; 1769 1770 case 3: /*ORBCp*/ 1771 BOOLEAN_LOGIC(orc, RRR_R, RRR_S, RRR_T); 1772 break; 1773 1774 case 4: /*XORBp*/ 1775 BOOLEAN_LOGIC(xor, RRR_R, RRR_S, RRR_T); 1776 break; 1777 1778 #undef BOOLEAN_LOGIC 1779 1780 case 8: /*MULLi*/ 1781 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL); 1782 tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1783 break; 1784 1785 case 10: /*MULUHi*/ 1786 case 11: /*MULSHi*/ 1787 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL_HIGH); 1788 { 1789 TCGv lo = tcg_temp_new(); 1790 1791 if (OP2 == 10) { 1792 tcg_gen_mulu2_i32(lo, cpu_R[RRR_R], 1793 cpu_R[RRR_S], cpu_R[RRR_T]); 1794 } else { 1795 tcg_gen_muls2_i32(lo, cpu_R[RRR_R], 1796 cpu_R[RRR_S], cpu_R[RRR_T]); 1797 } 1798 tcg_temp_free(lo); 1799 } 1800 break; 1801 1802 case 12: /*QUOUi*/ 1803 tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1804 break; 1805 1806 case 13: /*QUOSi*/ 1807 case 15: /*REMSi*/ 1808 { 1809 TCGLabel *label1 = gen_new_label(); 1810 TCGLabel *label2 = gen_new_label(); 1811 1812 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000, 1813 label1); 1814 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff, 1815 label1); 1816 tcg_gen_movi_i32(cpu_R[RRR_R], 1817 OP2 == 13 ? 0x80000000 : 0); 1818 tcg_gen_br(label2); 1819 gen_set_label(label1); 1820 if (OP2 == 13) { 1821 tcg_gen_div_i32(cpu_R[RRR_R], 1822 cpu_R[RRR_S], cpu_R[RRR_T]); 1823 } else { 1824 tcg_gen_rem_i32(cpu_R[RRR_R], 1825 cpu_R[RRR_S], cpu_R[RRR_T]); 1826 } 1827 gen_set_label(label2); 1828 } 1829 break; 1830 1831 case 14: /*REMUi*/ 1832 tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); 1833 break; 1834 1835 default: /*reserved*/ 1836 RESERVED(); 1837 break; 1838 } 1839 break; 1840 1841 case 3: /*RST3*/ 1842 switch (OP2) { 1843 case 0: /*RSR*/ 1844 if (gen_check_sr(dc, RSR_SR, SR_R) && 1845 (RSR_SR < 64 || gen_check_privilege(dc)) && 1846 gen_window_check1(dc, RRR_T)) { 1847 if (gen_rsr(dc, cpu_R[RRR_T], RSR_SR)) { 1848 gen_jumpi_check_loop_end(dc, 0); 1849 } 1850 } 1851 break; 1852 1853 case 1: /*WSR*/ 1854 if (gen_check_sr(dc, RSR_SR, SR_W) && 1855 (RSR_SR < 64 || gen_check_privilege(dc)) && 1856 gen_window_check1(dc, RRR_T)) { 1857 gen_wsr(dc, RSR_SR, cpu_R[RRR_T]); 1858 } 1859 break; 1860 1861 case 2: /*SEXTu*/ 1862 HAS_OPTION(XTENSA_OPTION_MISC_OP_SEXT); 1863 if (gen_window_check2(dc, RRR_R, RRR_S)) { 1864 int shift = 24 - RRR_T; 1865 1866 if (shift == 24) { 1867 tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]); 1868 } else if (shift == 16) { 1869 tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]); 1870 } else { 1871 TCGv_i32 tmp = tcg_temp_new_i32(); 1872 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift); 1873 tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift); 1874 tcg_temp_free(tmp); 1875 } 1876 } 1877 break; 1878 1879 case 3: /*CLAMPSu*/ 1880 HAS_OPTION(XTENSA_OPTION_MISC_OP_CLAMPS); 1881 if (gen_window_check2(dc, RRR_R, RRR_S)) { 1882 TCGv_i32 tmp1 = tcg_temp_new_i32(); 1883 TCGv_i32 tmp2 = tcg_temp_new_i32(); 1884 TCGv_i32 zero = tcg_const_i32(0); 1885 1886 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T); 1887 tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]); 1888 tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7)); 1889 1890 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31); 1891 tcg_gen_xori_i32(tmp1, tmp1, 0xffffffff >> (25 - RRR_T)); 1892 1893 tcg_gen_movcond_i32(TCG_COND_EQ, cpu_R[RRR_R], tmp2, zero, 1894 cpu_R[RRR_S], tmp1); 1895 tcg_temp_free(tmp1); 1896 tcg_temp_free(tmp2); 1897 tcg_temp_free(zero); 1898 } 1899 break; 1900 1901 case 4: /*MINu*/ 1902 case 5: /*MAXu*/ 1903 case 6: /*MINUu*/ 1904 case 7: /*MAXUu*/ 1905 HAS_OPTION(XTENSA_OPTION_MISC_OP_MINMAX); 1906 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1907 static const TCGCond cond[] = { 1908 TCG_COND_LE, 1909 TCG_COND_GE, 1910 TCG_COND_LEU, 1911 TCG_COND_GEU 1912 }; 1913 tcg_gen_movcond_i32(cond[OP2 - 4], cpu_R[RRR_R], 1914 cpu_R[RRR_S], cpu_R[RRR_T], 1915 cpu_R[RRR_S], cpu_R[RRR_T]); 1916 } 1917 break; 1918 1919 case 8: /*MOVEQZ*/ 1920 case 9: /*MOVNEZ*/ 1921 case 10: /*MOVLTZ*/ 1922 case 11: /*MOVGEZ*/ 1923 if (gen_window_check3(dc, RRR_R, RRR_S, RRR_T)) { 1924 static const TCGCond cond[] = { 1925 TCG_COND_EQ, 1926 TCG_COND_NE, 1927 TCG_COND_LT, 1928 TCG_COND_GE, 1929 }; 1930 TCGv_i32 zero = tcg_const_i32(0); 1931 1932 tcg_gen_movcond_i32(cond[OP2 - 8], cpu_R[RRR_R], 1933 cpu_R[RRR_T], zero, cpu_R[RRR_S], cpu_R[RRR_R]); 1934 tcg_temp_free(zero); 1935 } 1936 break; 1937 1938 case 12: /*MOVFp*/ 1939 case 13: /*MOVTp*/ 1940 HAS_OPTION(XTENSA_OPTION_BOOLEAN); 1941 if (gen_window_check2(dc, RRR_R, RRR_S)) { 1942 TCGv_i32 zero = tcg_const_i32(0); 1943 TCGv_i32 tmp = tcg_temp_new_i32(); 1944 1945 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T); 1946 tcg_gen_movcond_i32(OP2 & 1 ? TCG_COND_NE : TCG_COND_EQ, 1947 cpu_R[RRR_R], tmp, zero, 1948 cpu_R[RRR_S], cpu_R[RRR_R]); 1949 1950 tcg_temp_free(tmp); 1951 tcg_temp_free(zero); 1952 } 1953 break; 1954 1955 case 14: /*RUR*/ 1956 if (gen_window_check1(dc, RRR_R)) { 1957 int st = (RRR_S << 4) + RRR_T; 1958 if (uregnames[st].name) { 1959 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]); 1960 } else { 1961 qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", st); 1962 TBD(); 1963 } 1964 } 1965 break; 1966 1967 case 15: /*WUR*/ 1968 if (gen_window_check1(dc, RRR_T)) { 1969 if (uregnames[RSR_SR].name) { 1970 gen_wur(RSR_SR, cpu_R[RRR_T]); 1971 } else { 1972 qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", RSR_SR); 1973 TBD(); 1974 } 1975 } 1976 break; 1977 1978 } 1979 break; 1980 1981 case 4: /*EXTUI*/ 1982 case 5: 1983 if (gen_window_check2(dc, RRR_R, RRR_T)) { 1984 int shiftimm = RRR_S | ((OP1 & 1) << 4); 1985 int maskimm = (1 << (OP2 + 1)) - 1; 1986 1987 TCGv_i32 tmp = tcg_temp_new_i32(); 1988 tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm); 1989 tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm); 1990 tcg_temp_free(tmp); 1991 } 1992 break; 1993 1994 case 6: /*CUST0*/ 1995 RESERVED(); 1996 break; 1997 1998 case 7: /*CUST1*/ 1999 RESERVED(); 2000 break; 2001 2002 case 8: /*LSCXp*/ 2003 switch (OP2) { 2004 case 0: /*LSXf*/ 2005 case 1: /*LSXUf*/ 2006 case 4: /*SSXf*/ 2007 case 5: /*SSXUf*/ 2008 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR); 2009 if (gen_window_check2(dc, RRR_S, RRR_T) && 2010 gen_check_cpenable(dc, 0)) { 2011 TCGv_i32 addr = tcg_temp_new_i32(); 2012 tcg_gen_add_i32(addr, cpu_R[RRR_S], cpu_R[RRR_T]); 2013 gen_load_store_alignment(dc, 2, addr, false); 2014 if (OP2 & 0x4) { 2015 tcg_gen_qemu_st32(cpu_FR[RRR_R], addr, dc->cring); 2016 } else { 2017 tcg_gen_qemu_ld32u(cpu_FR[RRR_R], addr, dc->cring); 2018 } 2019 if (OP2 & 0x1) { 2020 tcg_gen_mov_i32(cpu_R[RRR_S], addr); 2021 } 2022 tcg_temp_free(addr); 2023 } 2024 break; 2025 2026 default: /*reserved*/ 2027 RESERVED(); 2028 break; 2029 } 2030 break; 2031 2032 case 9: /*LSC4*/ 2033 if (!gen_window_check2(dc, RRR_S, RRR_T)) { 2034 break; 2035 } 2036 switch (OP2) { 2037 case 0: /*L32E*/ 2038 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 2039 if (gen_check_privilege(dc) && 2040 gen_window_check2(dc, RRR_S, RRR_T)) { 2041 TCGv_i32 addr = tcg_temp_new_i32(); 2042 tcg_gen_addi_i32(addr, cpu_R[RRR_S], 2043 (0xffffffc0 | (RRR_R << 2))); 2044 tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring); 2045 tcg_temp_free(addr); 2046 } 2047 break; 2048 2049 case 4: /*S32E*/ 2050 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 2051 if (gen_check_privilege(dc) && 2052 gen_window_check2(dc, RRR_S, RRR_T)) { 2053 TCGv_i32 addr = tcg_temp_new_i32(); 2054 tcg_gen_addi_i32(addr, cpu_R[RRR_S], 2055 (0xffffffc0 | (RRR_R << 2))); 2056 tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring); 2057 tcg_temp_free(addr); 2058 } 2059 break; 2060 2061 case 5: /*S32N*/ 2062 if (gen_window_check2(dc, RRI4_S, RRI4_T)) { 2063 TCGv_i32 addr = tcg_temp_new_i32(); 2064 2065 tcg_gen_addi_i32(addr, cpu_R[RRI4_S], RRI4_IMM4 << 2); 2066 gen_load_store_alignment(dc, 2, addr, false); 2067 tcg_gen_qemu_st32(cpu_R[RRI4_T], addr, dc->cring); 2068 tcg_temp_free(addr); 2069 } 2070 break; 2071 2072 default: 2073 RESERVED(); 2074 break; 2075 } 2076 break; 2077 2078 case 10: /*FP0*/ 2079 /*DEPBITS*/ 2080 if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) { 2081 if (!gen_window_check2(dc, RRR_S, RRR_T)) { 2082 break; 2083 } 2084 tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S], 2085 OP2, RRR_R + 1); 2086 break; 2087 } 2088 2089 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR); 2090 switch (OP2) { 2091 case 0: /*ADD.Sf*/ 2092 if (gen_check_cpenable(dc, 0)) { 2093 gen_helper_add_s(cpu_FR[RRR_R], cpu_env, 2094 cpu_FR[RRR_S], cpu_FR[RRR_T]); 2095 } 2096 break; 2097 2098 case 1: /*SUB.Sf*/ 2099 if (gen_check_cpenable(dc, 0)) { 2100 gen_helper_sub_s(cpu_FR[RRR_R], cpu_env, 2101 cpu_FR[RRR_S], cpu_FR[RRR_T]); 2102 } 2103 break; 2104 2105 case 2: /*MUL.Sf*/ 2106 if (gen_check_cpenable(dc, 0)) { 2107 gen_helper_mul_s(cpu_FR[RRR_R], cpu_env, 2108 cpu_FR[RRR_S], cpu_FR[RRR_T]); 2109 } 2110 break; 2111 2112 case 4: /*MADD.Sf*/ 2113 if (gen_check_cpenable(dc, 0)) { 2114 gen_helper_madd_s(cpu_FR[RRR_R], cpu_env, 2115 cpu_FR[RRR_R], cpu_FR[RRR_S], 2116 cpu_FR[RRR_T]); 2117 } 2118 break; 2119 2120 case 5: /*MSUB.Sf*/ 2121 if (gen_check_cpenable(dc, 0)) { 2122 gen_helper_msub_s(cpu_FR[RRR_R], cpu_env, 2123 cpu_FR[RRR_R], cpu_FR[RRR_S], 2124 cpu_FR[RRR_T]); 2125 } 2126 break; 2127 2128 case 8: /*ROUND.Sf*/ 2129 case 9: /*TRUNC.Sf*/ 2130 case 10: /*FLOOR.Sf*/ 2131 case 11: /*CEIL.Sf*/ 2132 case 14: /*UTRUNC.Sf*/ 2133 if (gen_window_check1(dc, RRR_R) && 2134 gen_check_cpenable(dc, 0)) { 2135 static const unsigned rounding_mode_const[] = { 2136 float_round_nearest_even, 2137 float_round_to_zero, 2138 float_round_down, 2139 float_round_up, 2140 [6] = float_round_to_zero, 2141 }; 2142 TCGv_i32 rounding_mode = tcg_const_i32( 2143 rounding_mode_const[OP2 & 7]); 2144 TCGv_i32 scale = tcg_const_i32(RRR_T); 2145 2146 if (OP2 == 14) { 2147 gen_helper_ftoui(cpu_R[RRR_R], cpu_FR[RRR_S], 2148 rounding_mode, scale); 2149 } else { 2150 gen_helper_ftoi(cpu_R[RRR_R], cpu_FR[RRR_S], 2151 rounding_mode, scale); 2152 } 2153 2154 tcg_temp_free(rounding_mode); 2155 tcg_temp_free(scale); 2156 } 2157 break; 2158 2159 case 12: /*FLOAT.Sf*/ 2160 case 13: /*UFLOAT.Sf*/ 2161 if (gen_window_check1(dc, RRR_S) && 2162 gen_check_cpenable(dc, 0)) { 2163 TCGv_i32 scale = tcg_const_i32(-RRR_T); 2164 2165 if (OP2 == 13) { 2166 gen_helper_uitof(cpu_FR[RRR_R], cpu_env, 2167 cpu_R[RRR_S], scale); 2168 } else { 2169 gen_helper_itof(cpu_FR[RRR_R], cpu_env, 2170 cpu_R[RRR_S], scale); 2171 } 2172 tcg_temp_free(scale); 2173 } 2174 break; 2175 2176 case 15: /*FP1OP*/ 2177 switch (RRR_T) { 2178 case 0: /*MOV.Sf*/ 2179 if (gen_check_cpenable(dc, 0)) { 2180 tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]); 2181 } 2182 break; 2183 2184 case 1: /*ABS.Sf*/ 2185 if (gen_check_cpenable(dc, 0)) { 2186 gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]); 2187 } 2188 break; 2189 2190 case 4: /*RFRf*/ 2191 if (gen_window_check1(dc, RRR_R) && 2192 gen_check_cpenable(dc, 0)) { 2193 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]); 2194 } 2195 break; 2196 2197 case 5: /*WFRf*/ 2198 if (gen_window_check1(dc, RRR_S) && 2199 gen_check_cpenable(dc, 0)) { 2200 tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]); 2201 } 2202 break; 2203 2204 case 6: /*NEG.Sf*/ 2205 if (gen_check_cpenable(dc, 0)) { 2206 gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]); 2207 } 2208 break; 2209 2210 default: /*reserved*/ 2211 RESERVED(); 2212 break; 2213 } 2214 break; 2215 2216 default: /*reserved*/ 2217 RESERVED(); 2218 break; 2219 } 2220 break; 2221 2222 case 11: /*FP1*/ 2223 /*DEPBITS*/ 2224 if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) { 2225 if (!gen_window_check2(dc, RRR_S, RRR_T)) { 2226 break; 2227 } 2228 tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S], 2229 OP2 + 16, RRR_R + 1); 2230 break; 2231 } 2232 2233 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR); 2234 2235 #define gen_compare(rel, br, a, b) \ 2236 do { \ 2237 if (gen_check_cpenable(dc, 0)) { \ 2238 TCGv_i32 bit = tcg_const_i32(1 << br); \ 2239 \ 2240 gen_helper_##rel(cpu_env, bit, cpu_FR[a], cpu_FR[b]); \ 2241 tcg_temp_free(bit); \ 2242 } \ 2243 } while (0) 2244 2245 switch (OP2) { 2246 case 1: /*UN.Sf*/ 2247 gen_compare(un_s, RRR_R, RRR_S, RRR_T); 2248 break; 2249 2250 case 2: /*OEQ.Sf*/ 2251 gen_compare(oeq_s, RRR_R, RRR_S, RRR_T); 2252 break; 2253 2254 case 3: /*UEQ.Sf*/ 2255 gen_compare(ueq_s, RRR_R, RRR_S, RRR_T); 2256 break; 2257 2258 case 4: /*OLT.Sf*/ 2259 gen_compare(olt_s, RRR_R, RRR_S, RRR_T); 2260 break; 2261 2262 case 5: /*ULT.Sf*/ 2263 gen_compare(ult_s, RRR_R, RRR_S, RRR_T); 2264 break; 2265 2266 case 6: /*OLE.Sf*/ 2267 gen_compare(ole_s, RRR_R, RRR_S, RRR_T); 2268 break; 2269 2270 case 7: /*ULE.Sf*/ 2271 gen_compare(ule_s, RRR_R, RRR_S, RRR_T); 2272 break; 2273 2274 #undef gen_compare 2275 2276 case 8: /*MOVEQZ.Sf*/ 2277 case 9: /*MOVNEZ.Sf*/ 2278 case 10: /*MOVLTZ.Sf*/ 2279 case 11: /*MOVGEZ.Sf*/ 2280 if (gen_window_check1(dc, RRR_T) && 2281 gen_check_cpenable(dc, 0)) { 2282 static const TCGCond cond[] = { 2283 TCG_COND_EQ, 2284 TCG_COND_NE, 2285 TCG_COND_LT, 2286 TCG_COND_GE, 2287 }; 2288 TCGv_i32 zero = tcg_const_i32(0); 2289 2290 tcg_gen_movcond_i32(cond[OP2 - 8], cpu_FR[RRR_R], 2291 cpu_R[RRR_T], zero, cpu_FR[RRR_S], cpu_FR[RRR_R]); 2292 tcg_temp_free(zero); 2293 } 2294 break; 2295 2296 case 12: /*MOVF.Sf*/ 2297 case 13: /*MOVT.Sf*/ 2298 HAS_OPTION(XTENSA_OPTION_BOOLEAN); 2299 if (gen_check_cpenable(dc, 0)) { 2300 TCGv_i32 zero = tcg_const_i32(0); 2301 TCGv_i32 tmp = tcg_temp_new_i32(); 2302 2303 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T); 2304 tcg_gen_movcond_i32(OP2 & 1 ? TCG_COND_NE : TCG_COND_EQ, 2305 cpu_FR[RRR_R], tmp, zero, 2306 cpu_FR[RRR_S], cpu_FR[RRR_R]); 2307 2308 tcg_temp_free(tmp); 2309 tcg_temp_free(zero); 2310 } 2311 break; 2312 2313 default: /*reserved*/ 2314 RESERVED(); 2315 break; 2316 } 2317 break; 2318 2319 default: /*reserved*/ 2320 RESERVED(); 2321 break; 2322 } 2323 break; 2324 2325 case 1: /*L32R*/ 2326 if (gen_window_check1(dc, RRR_T)) { 2327 TCGv_i32 tmp = tcg_const_i32( 2328 ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ? 2329 0 : ((dc->pc + 3) & ~3)) + 2330 (0xfffc0000 | (RI16_IMM16 << 2))); 2331 2332 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) { 2333 tcg_gen_add_i32(tmp, tmp, dc->litbase); 2334 } 2335 tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring); 2336 tcg_temp_free(tmp); 2337 } 2338 break; 2339 2340 case 2: /*LSAI*/ 2341 #define gen_load_store(type, shift) do { \ 2342 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { \ 2343 TCGv_i32 addr = tcg_temp_new_i32(); \ 2344 \ 2345 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \ 2346 if (shift) { \ 2347 gen_load_store_alignment(dc, shift, addr, false); \ 2348 } \ 2349 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \ 2350 tcg_temp_free(addr); \ 2351 } \ 2352 } while (0) 2353 2354 switch (RRI8_R) { 2355 case 0: /*L8UI*/ 2356 gen_load_store(ld8u, 0); 2357 break; 2358 2359 case 1: /*L16UI*/ 2360 gen_load_store(ld16u, 1); 2361 break; 2362 2363 case 2: /*L32I*/ 2364 gen_load_store(ld32u, 2); 2365 break; 2366 2367 case 4: /*S8I*/ 2368 gen_load_store(st8, 0); 2369 break; 2370 2371 case 5: /*S16I*/ 2372 gen_load_store(st16, 1); 2373 break; 2374 2375 case 6: /*S32I*/ 2376 gen_load_store(st32, 2); 2377 break; 2378 2379 #define gen_dcache_hit_test(w, shift) do { \ 2380 if (gen_window_check1(dc, RRI##w##_S)) { \ 2381 TCGv_i32 addr = tcg_temp_new_i32(); \ 2382 TCGv_i32 res = tcg_temp_new_i32(); \ 2383 tcg_gen_addi_i32(addr, cpu_R[RRI##w##_S], \ 2384 RRI##w##_IMM##w << shift); \ 2385 tcg_gen_qemu_ld8u(res, addr, dc->cring); \ 2386 tcg_temp_free(addr); \ 2387 tcg_temp_free(res); \ 2388 } \ 2389 } while (0) 2390 2391 #define gen_dcache_hit_test4() gen_dcache_hit_test(4, 4) 2392 #define gen_dcache_hit_test8() gen_dcache_hit_test(8, 2) 2393 2394 case 7: /*CACHEc*/ 2395 if (RRI8_T < 8) { 2396 HAS_OPTION(XTENSA_OPTION_DCACHE); 2397 } 2398 2399 switch (RRI8_T) { 2400 case 0: /*DPFRc*/ 2401 gen_window_check1(dc, RRI8_S); 2402 break; 2403 2404 case 1: /*DPFWc*/ 2405 gen_window_check1(dc, RRI8_S); 2406 break; 2407 2408 case 2: /*DPFROc*/ 2409 gen_window_check1(dc, RRI8_S); 2410 break; 2411 2412 case 3: /*DPFWOc*/ 2413 gen_window_check1(dc, RRI8_S); 2414 break; 2415 2416 case 4: /*DHWBc*/ 2417 gen_dcache_hit_test8(); 2418 break; 2419 2420 case 5: /*DHWBIc*/ 2421 gen_dcache_hit_test8(); 2422 break; 2423 2424 case 6: /*DHIc*/ 2425 if (gen_check_privilege(dc)) { 2426 gen_dcache_hit_test8(); 2427 } 2428 break; 2429 2430 case 7: /*DIIc*/ 2431 if (gen_check_privilege(dc)) { 2432 gen_window_check1(dc, RRI8_S); 2433 } 2434 break; 2435 2436 case 8: /*DCEc*/ 2437 switch (OP1) { 2438 case 0: /*DPFLl*/ 2439 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK); 2440 if (gen_check_privilege(dc)) { 2441 gen_dcache_hit_test4(); 2442 } 2443 break; 2444 2445 case 2: /*DHUl*/ 2446 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK); 2447 if (gen_check_privilege(dc)) { 2448 gen_dcache_hit_test4(); 2449 } 2450 break; 2451 2452 case 3: /*DIUl*/ 2453 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK); 2454 if (gen_check_privilege(dc)) { 2455 gen_window_check1(dc, RRI4_S); 2456 } 2457 break; 2458 2459 case 4: /*DIWBc*/ 2460 HAS_OPTION(XTENSA_OPTION_DCACHE); 2461 if (gen_check_privilege(dc)) { 2462 gen_window_check1(dc, RRI4_S); 2463 } 2464 break; 2465 2466 case 5: /*DIWBIc*/ 2467 HAS_OPTION(XTENSA_OPTION_DCACHE); 2468 if (gen_check_privilege(dc)) { 2469 gen_window_check1(dc, RRI4_S); 2470 } 2471 break; 2472 2473 default: /*reserved*/ 2474 RESERVED(); 2475 break; 2476 2477 } 2478 break; 2479 2480 #undef gen_dcache_hit_test 2481 #undef gen_dcache_hit_test4 2482 #undef gen_dcache_hit_test8 2483 2484 #define gen_icache_hit_test(w, shift) do { \ 2485 if (gen_window_check1(dc, RRI##w##_S)) { \ 2486 TCGv_i32 addr = tcg_temp_new_i32(); \ 2487 tcg_gen_movi_i32(cpu_pc, dc->pc); \ 2488 tcg_gen_addi_i32(addr, cpu_R[RRI##w##_S], \ 2489 RRI##w##_IMM##w << shift); \ 2490 gen_helper_itlb_hit_test(cpu_env, addr); \ 2491 tcg_temp_free(addr); \ 2492 }\ 2493 } while (0) 2494 2495 #define gen_icache_hit_test4() gen_icache_hit_test(4, 4) 2496 #define gen_icache_hit_test8() gen_icache_hit_test(8, 2) 2497 2498 case 12: /*IPFc*/ 2499 HAS_OPTION(XTENSA_OPTION_ICACHE); 2500 gen_window_check1(dc, RRI8_S); 2501 break; 2502 2503 case 13: /*ICEc*/ 2504 switch (OP1) { 2505 case 0: /*IPFLl*/ 2506 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK); 2507 if (gen_check_privilege(dc)) { 2508 gen_icache_hit_test4(); 2509 } 2510 break; 2511 2512 case 2: /*IHUl*/ 2513 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK); 2514 if (gen_check_privilege(dc)) { 2515 gen_icache_hit_test4(); 2516 } 2517 break; 2518 2519 case 3: /*IIUl*/ 2520 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK); 2521 if (gen_check_privilege(dc)) { 2522 gen_window_check1(dc, RRI4_S); 2523 } 2524 break; 2525 2526 default: /*reserved*/ 2527 RESERVED(); 2528 break; 2529 } 2530 break; 2531 2532 case 14: /*IHIc*/ 2533 HAS_OPTION(XTENSA_OPTION_ICACHE); 2534 gen_icache_hit_test8(); 2535 break; 2536 2537 case 15: /*IIIc*/ 2538 HAS_OPTION(XTENSA_OPTION_ICACHE); 2539 if (gen_check_privilege(dc)) { 2540 gen_window_check1(dc, RRI8_S); 2541 } 2542 break; 2543 2544 default: /*reserved*/ 2545 RESERVED(); 2546 break; 2547 } 2548 break; 2549 2550 #undef gen_icache_hit_test 2551 #undef gen_icache_hit_test4 2552 #undef gen_icache_hit_test8 2553 2554 case 9: /*L16SI*/ 2555 gen_load_store(ld16s, 1); 2556 break; 2557 #undef gen_load_store 2558 2559 case 10: /*MOVI*/ 2560 if (gen_window_check1(dc, RRI8_T)) { 2561 tcg_gen_movi_i32(cpu_R[RRI8_T], 2562 RRI8_IMM8 | (RRI8_S << 8) | 2563 ((RRI8_S & 0x8) ? 0xfffff000 : 0)); 2564 } 2565 break; 2566 2567 #define gen_load_store_no_hw_align(type) do { \ 2568 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { \ 2569 TCGv_i32 addr = tcg_temp_local_new_i32(); \ 2570 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \ 2571 gen_load_store_alignment(dc, 2, addr, true); \ 2572 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \ 2573 tcg_temp_free(addr); \ 2574 } \ 2575 } while (0) 2576 2577 case 11: /*L32AIy*/ 2578 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO); 2579 gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/ 2580 break; 2581 2582 case 12: /*ADDI*/ 2583 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2584 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE); 2585 } 2586 break; 2587 2588 case 13: /*ADDMI*/ 2589 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2590 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], 2591 RRI8_IMM8_SE << 8); 2592 } 2593 break; 2594 2595 case 14: /*S32C1Iy*/ 2596 HAS_OPTION(XTENSA_OPTION_CONDITIONAL_STORE); 2597 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2598 TCGLabel *label = gen_new_label(); 2599 TCGv_i32 tmp = tcg_temp_local_new_i32(); 2600 TCGv_i32 addr = tcg_temp_local_new_i32(); 2601 TCGv_i32 tpc; 2602 2603 tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]); 2604 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); 2605 gen_load_store_alignment(dc, 2, addr, true); 2606 2607 tpc = tcg_const_i32(dc->pc); 2608 gen_helper_check_atomctl(cpu_env, tpc, addr); 2609 tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring); 2610 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T], 2611 cpu_SR[SCOMPARE1], label); 2612 2613 tcg_gen_qemu_st32(tmp, addr, dc->cring); 2614 2615 gen_set_label(label); 2616 tcg_temp_free(tpc); 2617 tcg_temp_free(addr); 2618 tcg_temp_free(tmp); 2619 } 2620 break; 2621 2622 case 15: /*S32RIy*/ 2623 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO); 2624 gen_load_store_no_hw_align(st32); /*TODO release?*/ 2625 break; 2626 #undef gen_load_store_no_hw_align 2627 2628 default: /*reserved*/ 2629 RESERVED(); 2630 break; 2631 } 2632 break; 2633 2634 case 3: /*LSCIp*/ 2635 switch (RRI8_R) { 2636 case 0: /*LSIf*/ 2637 case 4: /*SSIf*/ 2638 case 8: /*LSIUf*/ 2639 case 12: /*SSIUf*/ 2640 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR); 2641 if (gen_window_check1(dc, RRI8_S) && 2642 gen_check_cpenable(dc, 0)) { 2643 TCGv_i32 addr = tcg_temp_new_i32(); 2644 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); 2645 gen_load_store_alignment(dc, 2, addr, false); 2646 if (RRI8_R & 0x4) { 2647 tcg_gen_qemu_st32(cpu_FR[RRI8_T], addr, dc->cring); 2648 } else { 2649 tcg_gen_qemu_ld32u(cpu_FR[RRI8_T], addr, dc->cring); 2650 } 2651 if (RRI8_R & 0x8) { 2652 tcg_gen_mov_i32(cpu_R[RRI8_S], addr); 2653 } 2654 tcg_temp_free(addr); 2655 } 2656 break; 2657 2658 default: /*reserved*/ 2659 RESERVED(); 2660 break; 2661 } 2662 break; 2663 2664 case 4: /*MAC16d*/ 2665 HAS_OPTION(XTENSA_OPTION_MAC16); 2666 { 2667 enum { 2668 MAC16_UMUL = 0x0, 2669 MAC16_MUL = 0x4, 2670 MAC16_MULA = 0x8, 2671 MAC16_MULS = 0xc, 2672 MAC16_NONE = 0xf, 2673 } op = OP1 & 0xc; 2674 bool is_m1_sr = (OP2 & 0x3) == 2; 2675 bool is_m2_sr = (OP2 & 0xc) == 0; 2676 uint32_t ld_offset = 0; 2677 2678 if (OP2 > 9) { 2679 RESERVED(); 2680 } 2681 2682 switch (OP2 & 2) { 2683 case 0: /*MACI?/MACC?*/ 2684 is_m1_sr = true; 2685 ld_offset = (OP2 & 1) ? -4 : 4; 2686 2687 if (OP2 >= 8) { /*MACI/MACC*/ 2688 if (OP1 == 0) { /*LDINC/LDDEC*/ 2689 op = MAC16_NONE; 2690 } else { 2691 RESERVED(); 2692 } 2693 } else if (op != MAC16_MULA) { /*MULA.*.*.LDINC/LDDEC*/ 2694 RESERVED(); 2695 } 2696 break; 2697 2698 case 2: /*MACD?/MACA?*/ 2699 if (op == MAC16_UMUL && OP2 != 7) { /*UMUL only in MACAA*/ 2700 RESERVED(); 2701 } 2702 break; 2703 } 2704 2705 if (op != MAC16_NONE) { 2706 if (!is_m1_sr && !gen_window_check1(dc, RRR_S)) { 2707 break; 2708 } 2709 if (!is_m2_sr && !gen_window_check1(dc, RRR_T)) { 2710 break; 2711 } 2712 } 2713 2714 if (ld_offset && !gen_window_check1(dc, RRR_S)) { 2715 break; 2716 } 2717 2718 { 2719 TCGv_i32 vaddr = tcg_temp_new_i32(); 2720 TCGv_i32 mem32 = tcg_temp_new_i32(); 2721 2722 if (ld_offset) { 2723 tcg_gen_addi_i32(vaddr, cpu_R[RRR_S], ld_offset); 2724 gen_load_store_alignment(dc, 2, vaddr, false); 2725 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring); 2726 } 2727 if (op != MAC16_NONE) { 2728 TCGv_i32 m1 = gen_mac16_m( 2729 is_m1_sr ? cpu_SR[MR + RRR_X] : cpu_R[RRR_S], 2730 OP1 & 1, op == MAC16_UMUL); 2731 TCGv_i32 m2 = gen_mac16_m( 2732 is_m2_sr ? cpu_SR[MR + 2 + RRR_Y] : cpu_R[RRR_T], 2733 OP1 & 2, op == MAC16_UMUL); 2734 2735 if (op == MAC16_MUL || op == MAC16_UMUL) { 2736 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2); 2737 if (op == MAC16_UMUL) { 2738 tcg_gen_movi_i32(cpu_SR[ACCHI], 0); 2739 } else { 2740 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31); 2741 } 2742 } else { 2743 TCGv_i32 lo = tcg_temp_new_i32(); 2744 TCGv_i32 hi = tcg_temp_new_i32(); 2745 2746 tcg_gen_mul_i32(lo, m1, m2); 2747 tcg_gen_sari_i32(hi, lo, 31); 2748 if (op == MAC16_MULA) { 2749 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 2750 cpu_SR[ACCLO], cpu_SR[ACCHI], 2751 lo, hi); 2752 } else { 2753 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 2754 cpu_SR[ACCLO], cpu_SR[ACCHI], 2755 lo, hi); 2756 } 2757 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]); 2758 2759 tcg_temp_free_i32(lo); 2760 tcg_temp_free_i32(hi); 2761 } 2762 tcg_temp_free(m1); 2763 tcg_temp_free(m2); 2764 } 2765 if (ld_offset) { 2766 tcg_gen_mov_i32(cpu_R[RRR_S], vaddr); 2767 tcg_gen_mov_i32(cpu_SR[MR + RRR_W], mem32); 2768 } 2769 tcg_temp_free(vaddr); 2770 tcg_temp_free(mem32); 2771 } 2772 } 2773 break; 2774 2775 case 5: /*CALLN*/ 2776 switch (CALL_N) { 2777 case 0: /*CALL0*/ 2778 tcg_gen_movi_i32(cpu_R[0], dc->next_pc); 2779 gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0); 2780 break; 2781 2782 case 1: /*CALL4w*/ 2783 case 2: /*CALL8w*/ 2784 case 3: /*CALL12w*/ 2785 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 2786 if (gen_window_check1(dc, CALL_N << 2)) { 2787 gen_callwi(dc, CALL_N, 2788 (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0); 2789 } 2790 break; 2791 } 2792 break; 2793 2794 case 6: /*SI*/ 2795 switch (CALL_N) { 2796 case 0: /*J*/ 2797 gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0); 2798 break; 2799 2800 case 1: /*BZ*/ 2801 if (gen_window_check1(dc, BRI12_S)) { 2802 static const TCGCond cond[] = { 2803 TCG_COND_EQ, /*BEQZ*/ 2804 TCG_COND_NE, /*BNEZ*/ 2805 TCG_COND_LT, /*BLTZ*/ 2806 TCG_COND_GE, /*BGEZ*/ 2807 }; 2808 2809 gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0, 2810 4 + BRI12_IMM12_SE); 2811 } 2812 break; 2813 2814 case 2: /*BI0*/ 2815 if (gen_window_check1(dc, BRI8_S)) { 2816 static const TCGCond cond[] = { 2817 TCG_COND_EQ, /*BEQI*/ 2818 TCG_COND_NE, /*BNEI*/ 2819 TCG_COND_LT, /*BLTI*/ 2820 TCG_COND_GE, /*BGEI*/ 2821 }; 2822 2823 gen_brcondi(dc, cond[BRI8_M & 3], 2824 cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE); 2825 } 2826 break; 2827 2828 case 3: /*BI1*/ 2829 switch (BRI8_M) { 2830 case 0: /*ENTRYw*/ 2831 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 2832 { 2833 TCGv_i32 pc = tcg_const_i32(dc->pc); 2834 TCGv_i32 s = tcg_const_i32(BRI12_S); 2835 TCGv_i32 imm = tcg_const_i32(BRI12_IMM12 << 3); 2836 gen_helper_entry(cpu_env, pc, s, imm); 2837 tcg_temp_free(imm); 2838 tcg_temp_free(s); 2839 tcg_temp_free(pc); 2840 /* This can change tb->flags, so exit tb */ 2841 gen_jumpi_check_loop_end(dc, -1); 2842 } 2843 break; 2844 2845 case 1: /*B1*/ 2846 switch (BRI8_R) { 2847 case 0: /*BFp*/ 2848 case 1: /*BTp*/ 2849 HAS_OPTION(XTENSA_OPTION_BOOLEAN); 2850 { 2851 TCGv_i32 tmp = tcg_temp_new_i32(); 2852 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRI8_S); 2853 gen_brcondi(dc, 2854 BRI8_R == 1 ? TCG_COND_NE : TCG_COND_EQ, 2855 tmp, 0, 4 + RRI8_IMM8_SE); 2856 tcg_temp_free(tmp); 2857 } 2858 break; 2859 2860 case 8: /*LOOP*/ 2861 case 9: /*LOOPNEZ*/ 2862 case 10: /*LOOPGTZ*/ 2863 HAS_OPTION(XTENSA_OPTION_LOOP); 2864 if (gen_window_check1(dc, RRI8_S)) { 2865 uint32_t lend = dc->pc + RRI8_IMM8 + 4; 2866 TCGv_i32 tmp = tcg_const_i32(lend); 2867 2868 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1); 2869 tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc); 2870 gen_helper_wsr_lend(cpu_env, tmp); 2871 tcg_temp_free(tmp); 2872 2873 if (BRI8_R > 8) { 2874 TCGLabel *label = gen_new_label(); 2875 tcg_gen_brcondi_i32( 2876 BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT, 2877 cpu_R[RRI8_S], 0, label); 2878 gen_jumpi(dc, lend, 1); 2879 gen_set_label(label); 2880 } 2881 2882 gen_jumpi(dc, dc->next_pc, 0); 2883 } 2884 break; 2885 2886 default: /*reserved*/ 2887 RESERVED(); 2888 break; 2889 2890 } 2891 break; 2892 2893 case 2: /*BLTUI*/ 2894 case 3: /*BGEUI*/ 2895 if (gen_window_check1(dc, BRI8_S)) { 2896 gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU, 2897 cpu_R[BRI8_S], B4CONSTU[BRI8_R], 2898 4 + BRI8_IMM8_SE); 2899 } 2900 break; 2901 } 2902 break; 2903 2904 } 2905 break; 2906 2907 case 7: /*B*/ 2908 { 2909 TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ; 2910 2911 switch (RRI8_R & 7) { 2912 case 0: /*BNONE*/ /*BANY*/ 2913 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2914 TCGv_i32 tmp = tcg_temp_new_i32(); 2915 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]); 2916 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE); 2917 tcg_temp_free(tmp); 2918 } 2919 break; 2920 2921 case 1: /*BEQ*/ /*BNE*/ 2922 case 2: /*BLT*/ /*BGE*/ 2923 case 3: /*BLTU*/ /*BGEU*/ 2924 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2925 static const TCGCond cond[] = { 2926 [1] = TCG_COND_EQ, 2927 [2] = TCG_COND_LT, 2928 [3] = TCG_COND_LTU, 2929 [9] = TCG_COND_NE, 2930 [10] = TCG_COND_GE, 2931 [11] = TCG_COND_GEU, 2932 }; 2933 gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T], 2934 4 + RRI8_IMM8_SE); 2935 } 2936 break; 2937 2938 case 4: /*BALL*/ /*BNALL*/ 2939 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2940 TCGv_i32 tmp = tcg_temp_new_i32(); 2941 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]); 2942 gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T], 2943 4 + RRI8_IMM8_SE); 2944 tcg_temp_free(tmp); 2945 } 2946 break; 2947 2948 case 5: /*BBC*/ /*BBS*/ 2949 if (gen_window_check2(dc, RRI8_S, RRI8_T)) { 2950 #ifdef TARGET_WORDS_BIGENDIAN 2951 TCGv_i32 bit = tcg_const_i32(0x80000000); 2952 #else 2953 TCGv_i32 bit = tcg_const_i32(0x00000001); 2954 #endif 2955 TCGv_i32 tmp = tcg_temp_new_i32(); 2956 tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f); 2957 #ifdef TARGET_WORDS_BIGENDIAN 2958 tcg_gen_shr_i32(bit, bit, tmp); 2959 #else 2960 tcg_gen_shl_i32(bit, bit, tmp); 2961 #endif 2962 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit); 2963 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE); 2964 tcg_temp_free(tmp); 2965 tcg_temp_free(bit); 2966 } 2967 break; 2968 2969 case 6: /*BBCI*/ /*BBSI*/ 2970 case 7: 2971 if (gen_window_check1(dc, RRI8_S)) { 2972 TCGv_i32 tmp = tcg_temp_new_i32(); 2973 tcg_gen_andi_i32(tmp, cpu_R[RRI8_S], 2974 #ifdef TARGET_WORDS_BIGENDIAN 2975 0x80000000 >> (((RRI8_R & 1) << 4) | RRI8_T)); 2976 #else 2977 0x00000001 << (((RRI8_R & 1) << 4) | RRI8_T)); 2978 #endif 2979 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE); 2980 tcg_temp_free(tmp); 2981 } 2982 break; 2983 2984 } 2985 } 2986 break; 2987 2988 #define gen_narrow_load_store(type) do { \ 2989 if (gen_window_check2(dc, RRRN_S, RRRN_T)) { \ 2990 TCGv_i32 addr = tcg_temp_new_i32(); \ 2991 tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \ 2992 gen_load_store_alignment(dc, 2, addr, false); \ 2993 tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \ 2994 tcg_temp_free(addr); \ 2995 } \ 2996 } while (0) 2997 2998 case 8: /*L32I.Nn*/ 2999 gen_narrow_load_store(ld32u); 3000 break; 3001 3002 case 9: /*S32I.Nn*/ 3003 gen_narrow_load_store(st32); 3004 break; 3005 #undef gen_narrow_load_store 3006 3007 case 10: /*ADD.Nn*/ 3008 if (gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T)) { 3009 tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]); 3010 } 3011 break; 3012 3013 case 11: /*ADDI.Nn*/ 3014 if (gen_window_check2(dc, RRRN_R, RRRN_S)) { 3015 tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], 3016 RRRN_T ? RRRN_T : -1); 3017 } 3018 break; 3019 3020 case 12: /*ST2n*/ 3021 if (!gen_window_check1(dc, RRRN_S)) { 3022 break; 3023 } 3024 if (RRRN_T < 8) { /*MOVI.Nn*/ 3025 tcg_gen_movi_i32(cpu_R[RRRN_S], 3026 RRRN_R | (RRRN_T << 4) | 3027 ((RRRN_T & 6) == 6 ? 0xffffff80 : 0)); 3028 } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/ 3029 TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ; 3030 3031 gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0, 3032 4 + (RRRN_R | ((RRRN_T & 3) << 4))); 3033 } 3034 break; 3035 3036 case 13: /*ST3n*/ 3037 switch (RRRN_R) { 3038 case 0: /*MOV.Nn*/ 3039 if (gen_window_check2(dc, RRRN_S, RRRN_T)) { 3040 tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]); 3041 } 3042 break; 3043 3044 case 15: /*S3*/ 3045 switch (RRRN_T) { 3046 case 0: /*RET.Nn*/ 3047 gen_jump(dc, cpu_R[0]); 3048 break; 3049 3050 case 1: /*RETW.Nn*/ 3051 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 3052 { 3053 TCGv_i32 tmp = tcg_const_i32(dc->pc); 3054 gen_helper_retw(tmp, cpu_env, tmp); 3055 gen_jump(dc, tmp); 3056 tcg_temp_free(tmp); 3057 } 3058 break; 3059 3060 case 2: /*BREAK.Nn*/ 3061 HAS_OPTION(XTENSA_OPTION_DEBUG); 3062 if (dc->debug) { 3063 gen_debug_exception(dc, DEBUGCAUSE_BN); 3064 } 3065 break; 3066 3067 case 3: /*NOP.Nn*/ 3068 break; 3069 3070 case 6: /*ILL.Nn*/ 3071 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 3072 break; 3073 3074 default: /*reserved*/ 3075 RESERVED(); 3076 break; 3077 } 3078 break; 3079 3080 default: /*reserved*/ 3081 RESERVED(); 3082 break; 3083 } 3084 break; 3085 3086 default: /*reserved*/ 3087 RESERVED(); 3088 break; 3089 } 3090 3091 if (dc->is_jmp == DISAS_NEXT) { 3092 gen_check_loop_end(dc, 0); 3093 } 3094 dc->pc = dc->next_pc; 3095 3096 return; 3097 3098 invalid_opcode: 3099 qemu_log_mask(LOG_GUEST_ERROR, "INVALID(pc = %08x)\n", dc->pc); 3100 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 3101 #undef HAS_OPTION 3102 } 3103 3104 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc) 3105 { 3106 uint8_t b0 = cpu_ldub_code(env, dc->pc); 3107 return xtensa_op0_insn_len(OP0); 3108 } 3109 3110 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc) 3111 { 3112 unsigned i; 3113 3114 for (i = 0; i < dc->config->nibreak; ++i) { 3115 if ((env->sregs[IBREAKENABLE] & (1 << i)) && 3116 env->sregs[IBREAKA + i] == dc->pc) { 3117 gen_debug_exception(dc, DEBUGCAUSE_IB); 3118 break; 3119 } 3120 } 3121 } 3122 3123 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) 3124 { 3125 CPUXtensaState *env = cs->env_ptr; 3126 DisasContext dc; 3127 int insn_count = 0; 3128 int max_insns = tb_cflags(tb) & CF_COUNT_MASK; 3129 uint32_t pc_start = tb->pc; 3130 uint32_t next_page_start = 3131 (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 3132 3133 if (max_insns == 0) { 3134 max_insns = CF_COUNT_MASK; 3135 } 3136 if (max_insns > TCG_MAX_INSNS) { 3137 max_insns = TCG_MAX_INSNS; 3138 } 3139 3140 dc.config = env->config; 3141 dc.singlestep_enabled = cs->singlestep_enabled; 3142 dc.tb = tb; 3143 dc.pc = pc_start; 3144 dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK; 3145 dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring; 3146 dc.lbeg = env->sregs[LBEG]; 3147 dc.lend = env->sregs[LEND]; 3148 dc.is_jmp = DISAS_NEXT; 3149 dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG; 3150 dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT; 3151 dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >> 3152 XTENSA_TBFLAG_CPENABLE_SHIFT; 3153 dc.window = ((tb->flags & XTENSA_TBFLAG_WINDOW_MASK) >> 3154 XTENSA_TBFLAG_WINDOW_SHIFT); 3155 3156 init_litbase(&dc); 3157 init_sar_tracker(&dc); 3158 if (dc.icount) { 3159 dc.next_icount = tcg_temp_local_new_i32(); 3160 } 3161 3162 gen_tb_start(tb); 3163 3164 if ((tb_cflags(tb) & CF_USE_ICOUNT) && 3165 (tb->flags & XTENSA_TBFLAG_YIELD)) { 3166 tcg_gen_insn_start(dc.pc); 3167 ++insn_count; 3168 gen_exception(&dc, EXCP_YIELD); 3169 dc.is_jmp = DISAS_UPDATE; 3170 goto done; 3171 } 3172 if (tb->flags & XTENSA_TBFLAG_EXCEPTION) { 3173 tcg_gen_insn_start(dc.pc); 3174 ++insn_count; 3175 gen_exception(&dc, EXCP_DEBUG); 3176 dc.is_jmp = DISAS_UPDATE; 3177 goto done; 3178 } 3179 3180 do { 3181 tcg_gen_insn_start(dc.pc); 3182 ++insn_count; 3183 3184 if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) { 3185 tcg_gen_movi_i32(cpu_pc, dc.pc); 3186 gen_exception(&dc, EXCP_DEBUG); 3187 dc.is_jmp = DISAS_UPDATE; 3188 /* The address covered by the breakpoint must be included in 3189 [tb->pc, tb->pc + tb->size) in order to for it to be 3190 properly cleared -- thus we increment the PC here so that 3191 the logic setting tb->size below does the right thing. */ 3192 dc.pc += 2; 3193 break; 3194 } 3195 3196 if (insn_count == max_insns && (tb_cflags(tb) & CF_LAST_IO)) { 3197 gen_io_start(); 3198 } 3199 3200 if (dc.icount) { 3201 TCGLabel *label = gen_new_label(); 3202 3203 tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1); 3204 tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label); 3205 tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]); 3206 if (dc.debug) { 3207 gen_debug_exception(&dc, DEBUGCAUSE_IC); 3208 } 3209 gen_set_label(label); 3210 } 3211 3212 if (dc.debug) { 3213 gen_ibreak_check(env, &dc); 3214 } 3215 3216 disas_xtensa_insn(env, &dc); 3217 if (dc.icount) { 3218 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount); 3219 } 3220 if (cs->singlestep_enabled) { 3221 tcg_gen_movi_i32(cpu_pc, dc.pc); 3222 gen_exception(&dc, EXCP_DEBUG); 3223 break; 3224 } 3225 } while (dc.is_jmp == DISAS_NEXT && 3226 insn_count < max_insns && 3227 dc.pc < next_page_start && 3228 dc.pc + xtensa_insn_len(env, &dc) <= next_page_start && 3229 !tcg_op_buf_full()); 3230 done: 3231 reset_litbase(&dc); 3232 reset_sar_tracker(&dc); 3233 if (dc.icount) { 3234 tcg_temp_free(dc.next_icount); 3235 } 3236 3237 if (tb_cflags(tb) & CF_LAST_IO) { 3238 gen_io_end(); 3239 } 3240 3241 if (dc.is_jmp == DISAS_NEXT) { 3242 gen_jumpi(&dc, dc.pc, 0); 3243 } 3244 gen_tb_end(tb, insn_count); 3245 3246 #ifdef DEBUG_DISAS 3247 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 3248 && qemu_log_in_addr_range(pc_start)) { 3249 qemu_log_lock(); 3250 qemu_log("----------------\n"); 3251 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 3252 log_target_disas(cs, pc_start, dc.pc - pc_start); 3253 qemu_log("\n"); 3254 qemu_log_unlock(); 3255 } 3256 #endif 3257 tb->size = dc.pc - pc_start; 3258 tb->icount = insn_count; 3259 } 3260 3261 void xtensa_cpu_dump_state(CPUState *cs, FILE *f, 3262 fprintf_function cpu_fprintf, int flags) 3263 { 3264 XtensaCPU *cpu = XTENSA_CPU(cs); 3265 CPUXtensaState *env = &cpu->env; 3266 int i, j; 3267 3268 cpu_fprintf(f, "PC=%08x\n\n", env->pc); 3269 3270 for (i = j = 0; i < 256; ++i) { 3271 if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) { 3272 cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i], 3273 (j++ % 4) == 3 ? '\n' : ' '); 3274 } 3275 } 3276 3277 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); 3278 3279 for (i = j = 0; i < 256; ++i) { 3280 if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) { 3281 cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i], 3282 (j++ % 4) == 3 ? '\n' : ' '); 3283 } 3284 } 3285 3286 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); 3287 3288 for (i = 0; i < 16; ++i) { 3289 cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i], 3290 (i % 4) == 3 ? '\n' : ' '); 3291 } 3292 3293 cpu_fprintf(f, "\n"); 3294 3295 for (i = 0; i < env->config->nareg; ++i) { 3296 cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i], 3297 (i % 4) == 3 ? '\n' : ' '); 3298 } 3299 3300 if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) { 3301 cpu_fprintf(f, "\n"); 3302 3303 for (i = 0; i < 16; ++i) { 3304 cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i, 3305 float32_val(env->fregs[i].f32[FP_F32_LOW]), 3306 *(float *)(env->fregs[i].f32 + FP_F32_LOW), 3307 (i % 2) == 1 ? '\n' : ' '); 3308 } 3309 } 3310 } 3311 3312 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, 3313 target_ulong *data) 3314 { 3315 env->pc = data[0]; 3316 } 3317 3318 static int compare_opcode_ops(const void *a, const void *b) 3319 { 3320 return strcmp((const char *)a, 3321 ((const XtensaOpcodeOps *)b)->name); 3322 } 3323 3324 XtensaOpcodeOps * 3325 xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t, 3326 const char *name) 3327 { 3328 XtensaOpcodeOps *ops; 3329 3330 ops = bsearch(name, t->opcode, t->num_opcodes, 3331 sizeof(XtensaOpcodeOps), compare_opcode_ops); 3332 return ops; 3333 } 3334 3335 static void translate_abs(DisasContext *dc, const uint32_t arg[], 3336 const uint32_t par[]) 3337 { 3338 if (gen_window_check2(dc, arg[0], arg[1])) { 3339 TCGv_i32 zero = tcg_const_i32(0); 3340 TCGv_i32 neg = tcg_temp_new_i32(); 3341 3342 tcg_gen_neg_i32(neg, cpu_R[arg[1]]); 3343 tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[arg[0]], 3344 cpu_R[arg[1]], zero, cpu_R[arg[1]], neg); 3345 tcg_temp_free(neg); 3346 tcg_temp_free(zero); 3347 } 3348 } 3349 3350 static void translate_add(DisasContext *dc, const uint32_t arg[], 3351 const uint32_t par[]) 3352 { 3353 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3354 tcg_gen_add_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 3355 } 3356 } 3357 3358 static void translate_addi(DisasContext *dc, const uint32_t arg[], 3359 const uint32_t par[]) 3360 { 3361 if (gen_window_check2(dc, arg[0], arg[1])) { 3362 tcg_gen_addi_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]); 3363 } 3364 } 3365 3366 static void translate_addx(DisasContext *dc, const uint32_t arg[], 3367 const uint32_t par[]) 3368 { 3369 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3370 TCGv_i32 tmp = tcg_temp_new_i32(); 3371 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]); 3372 tcg_gen_add_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]); 3373 tcg_temp_free(tmp); 3374 } 3375 } 3376 3377 static void translate_all(DisasContext *dc, const uint32_t arg[], 3378 const uint32_t par[]) 3379 { 3380 uint32_t shift = par[1]; 3381 TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1]); 3382 TCGv_i32 tmp = tcg_temp_new_i32(); 3383 3384 tcg_gen_and_i32(tmp, cpu_SR[BR], mask); 3385 if (par[0]) { 3386 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1]); 3387 } else { 3388 tcg_gen_add_i32(tmp, tmp, mask); 3389 } 3390 tcg_gen_shri_i32(tmp, tmp, arg[1] + shift); 3391 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], 3392 tmp, arg[0], 1); 3393 tcg_temp_free(mask); 3394 tcg_temp_free(tmp); 3395 } 3396 3397 static void translate_and(DisasContext *dc, const uint32_t arg[], 3398 const uint32_t par[]) 3399 { 3400 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3401 tcg_gen_and_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 3402 } 3403 } 3404 3405 static void translate_ball(DisasContext *dc, const uint32_t arg[], 3406 const uint32_t par[]) 3407 { 3408 if (gen_window_check2(dc, arg[0], arg[1])) { 3409 TCGv_i32 tmp = tcg_temp_new_i32(); 3410 tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]); 3411 gen_brcond(dc, par[0], tmp, cpu_R[arg[1]], arg[2]); 3412 tcg_temp_free(tmp); 3413 } 3414 } 3415 3416 static void translate_bany(DisasContext *dc, const uint32_t arg[], 3417 const uint32_t par[]) 3418 { 3419 if (gen_window_check2(dc, arg[0], arg[1])) { 3420 TCGv_i32 tmp = tcg_temp_new_i32(); 3421 tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]); 3422 gen_brcondi(dc, par[0], tmp, 0, arg[2]); 3423 tcg_temp_free(tmp); 3424 } 3425 } 3426 3427 static void translate_b(DisasContext *dc, const uint32_t arg[], 3428 const uint32_t par[]) 3429 { 3430 if (gen_window_check2(dc, arg[0], arg[1])) { 3431 gen_brcond(dc, par[0], cpu_R[arg[0]], cpu_R[arg[1]], arg[2]); 3432 } 3433 } 3434 3435 static void translate_bb(DisasContext *dc, const uint32_t arg[], 3436 const uint32_t par[]) 3437 { 3438 if (gen_window_check2(dc, arg[0], arg[1])) { 3439 #ifdef TARGET_WORDS_BIGENDIAN 3440 TCGv_i32 bit = tcg_const_i32(0x80000000u); 3441 #else 3442 TCGv_i32 bit = tcg_const_i32(0x00000001u); 3443 #endif 3444 TCGv_i32 tmp = tcg_temp_new_i32(); 3445 tcg_gen_andi_i32(tmp, cpu_R[arg[1]], 0x1f); 3446 #ifdef TARGET_WORDS_BIGENDIAN 3447 tcg_gen_shr_i32(bit, bit, tmp); 3448 #else 3449 tcg_gen_shl_i32(bit, bit, tmp); 3450 #endif 3451 tcg_gen_and_i32(tmp, cpu_R[arg[0]], bit); 3452 gen_brcondi(dc, par[0], tmp, 0, arg[2]); 3453 tcg_temp_free(tmp); 3454 tcg_temp_free(bit); 3455 } 3456 } 3457 3458 static void translate_bbi(DisasContext *dc, const uint32_t arg[], 3459 const uint32_t par[]) 3460 { 3461 if (gen_window_check1(dc, arg[0])) { 3462 TCGv_i32 tmp = tcg_temp_new_i32(); 3463 #ifdef TARGET_WORDS_BIGENDIAN 3464 tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x80000000u >> arg[1]); 3465 #else 3466 tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x00000001u << arg[1]); 3467 #endif 3468 gen_brcondi(dc, par[0], tmp, 0, arg[2]); 3469 tcg_temp_free(tmp); 3470 } 3471 } 3472 3473 static void translate_bi(DisasContext *dc, const uint32_t arg[], 3474 const uint32_t par[]) 3475 { 3476 if (gen_window_check1(dc, arg[0])) { 3477 gen_brcondi(dc, par[0], cpu_R[arg[0]], arg[1], arg[2]); 3478 } 3479 } 3480 3481 static void translate_bz(DisasContext *dc, const uint32_t arg[], 3482 const uint32_t par[]) 3483 { 3484 if (gen_window_check1(dc, arg[0])) { 3485 gen_brcondi(dc, par[0], cpu_R[arg[0]], 0, arg[1]); 3486 } 3487 } 3488 3489 enum { 3490 BOOLEAN_AND, 3491 BOOLEAN_ANDC, 3492 BOOLEAN_OR, 3493 BOOLEAN_ORC, 3494 BOOLEAN_XOR, 3495 }; 3496 3497 static void translate_boolean(DisasContext *dc, const uint32_t arg[], 3498 const uint32_t par[]) 3499 { 3500 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = { 3501 [BOOLEAN_AND] = tcg_gen_and_i32, 3502 [BOOLEAN_ANDC] = tcg_gen_andc_i32, 3503 [BOOLEAN_OR] = tcg_gen_or_i32, 3504 [BOOLEAN_ORC] = tcg_gen_orc_i32, 3505 [BOOLEAN_XOR] = tcg_gen_xor_i32, 3506 }; 3507 3508 TCGv_i32 tmp1 = tcg_temp_new_i32(); 3509 TCGv_i32 tmp2 = tcg_temp_new_i32(); 3510 3511 tcg_gen_shri_i32(tmp1, cpu_SR[BR], arg[1]); 3512 tcg_gen_shri_i32(tmp2, cpu_SR[BR], arg[2]); 3513 op[par[0]](tmp1, tmp1, tmp2); 3514 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, arg[0], 1); 3515 tcg_temp_free(tmp1); 3516 tcg_temp_free(tmp2); 3517 } 3518 3519 static void translate_bp(DisasContext *dc, const uint32_t arg[], 3520 const uint32_t par[]) 3521 { 3522 TCGv_i32 tmp = tcg_temp_new_i32(); 3523 3524 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[0]); 3525 gen_brcondi(dc, par[0], tmp, 0, arg[1]); 3526 tcg_temp_free(tmp); 3527 } 3528 3529 static void translate_break(DisasContext *dc, const uint32_t arg[], 3530 const uint32_t par[]) 3531 { 3532 if (dc->debug) { 3533 gen_debug_exception(dc, par[0]); 3534 } 3535 } 3536 3537 static void translate_call0(DisasContext *dc, const uint32_t arg[], 3538 const uint32_t par[]) 3539 { 3540 tcg_gen_movi_i32(cpu_R[0], dc->next_pc); 3541 gen_jumpi(dc, arg[0], 0); 3542 } 3543 3544 static void translate_callw(DisasContext *dc, const uint32_t arg[], 3545 const uint32_t par[]) 3546 { 3547 if (gen_window_check1(dc, par[0] << 2)) { 3548 gen_callwi(dc, par[0], arg[0], 0); 3549 } 3550 } 3551 3552 static void translate_callx0(DisasContext *dc, const uint32_t arg[], 3553 const uint32_t par[]) 3554 { 3555 if (gen_window_check1(dc, arg[0])) { 3556 TCGv_i32 tmp = tcg_temp_new_i32(); 3557 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]); 3558 tcg_gen_movi_i32(cpu_R[0], dc->next_pc); 3559 gen_jump(dc, tmp); 3560 tcg_temp_free(tmp); 3561 } 3562 } 3563 3564 static void translate_callxw(DisasContext *dc, const uint32_t arg[], 3565 const uint32_t par[]) 3566 { 3567 if (gen_window_check2(dc, arg[0], par[0] << 2)) { 3568 TCGv_i32 tmp = tcg_temp_new_i32(); 3569 3570 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]); 3571 gen_callw(dc, par[0], tmp); 3572 tcg_temp_free(tmp); 3573 } 3574 } 3575 3576 static void translate_clamps(DisasContext *dc, const uint32_t arg[], 3577 const uint32_t par[]) 3578 { 3579 if (gen_window_check2(dc, arg[0], arg[1])) { 3580 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]); 3581 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1); 3582 3583 tcg_gen_movcond_i32(TCG_COND_GT, tmp1, 3584 cpu_R[arg[1]], tmp1, cpu_R[arg[1]], tmp1); 3585 tcg_gen_movcond_i32(TCG_COND_LT, cpu_R[arg[0]], 3586 tmp1, tmp2, tmp1, tmp2); 3587 tcg_temp_free(tmp1); 3588 tcg_temp_free(tmp2); 3589 } 3590 } 3591 3592 /* par[0]: privileged, par[1]: check memory access */ 3593 static void translate_dcache(DisasContext *dc, const uint32_t arg[], 3594 const uint32_t par[]) 3595 { 3596 if ((!par[0] || gen_check_privilege(dc)) && 3597 gen_window_check1(dc, arg[0]) && par[1]) { 3598 TCGv_i32 addr = tcg_temp_new_i32(); 3599 TCGv_i32 res = tcg_temp_new_i32(); 3600 3601 tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]); 3602 tcg_gen_qemu_ld8u(res, addr, dc->cring); 3603 tcg_temp_free(addr); 3604 tcg_temp_free(res); 3605 } 3606 } 3607 3608 static void translate_depbits(DisasContext *dc, const uint32_t arg[], 3609 const uint32_t par[]) 3610 { 3611 if (gen_window_check2(dc, arg[0], arg[1])) { 3612 tcg_gen_deposit_i32(cpu_R[arg[1]], cpu_R[arg[1]], cpu_R[arg[0]], 3613 arg[2], arg[3]); 3614 } 3615 } 3616 3617 static void translate_entry(DisasContext *dc, const uint32_t arg[], 3618 const uint32_t par[]) 3619 { 3620 TCGv_i32 pc = tcg_const_i32(dc->pc); 3621 TCGv_i32 s = tcg_const_i32(arg[0]); 3622 TCGv_i32 imm = tcg_const_i32(arg[1]); 3623 gen_helper_entry(cpu_env, pc, s, imm); 3624 tcg_temp_free(imm); 3625 tcg_temp_free(s); 3626 tcg_temp_free(pc); 3627 /* This can change tb->flags, so exit tb */ 3628 gen_jumpi_check_loop_end(dc, -1); 3629 } 3630 3631 static void translate_extui(DisasContext *dc, const uint32_t arg[], 3632 const uint32_t par[]) 3633 { 3634 if (gen_window_check2(dc, arg[0], arg[1])) { 3635 int maskimm = (1 << arg[3]) - 1; 3636 3637 TCGv_i32 tmp = tcg_temp_new_i32(); 3638 tcg_gen_shri_i32(tmp, cpu_R[arg[1]], arg[2]); 3639 tcg_gen_andi_i32(cpu_R[arg[0]], tmp, maskimm); 3640 tcg_temp_free(tmp); 3641 } 3642 } 3643 3644 /* par[0]: privileged, par[1]: check memory access */ 3645 static void translate_icache(DisasContext *dc, const uint32_t arg[], 3646 const uint32_t par[]) 3647 { 3648 if ((!par[0] || gen_check_privilege(dc)) && 3649 gen_window_check1(dc, arg[0]) && par[1]) { 3650 TCGv_i32 addr = tcg_temp_new_i32(); 3651 3652 tcg_gen_movi_i32(cpu_pc, dc->pc); 3653 tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]); 3654 gen_helper_itlb_hit_test(cpu_env, addr); 3655 tcg_temp_free(addr); 3656 } 3657 } 3658 3659 static void translate_itlb(DisasContext *dc, const uint32_t arg[], 3660 const uint32_t par[]) 3661 { 3662 if (gen_check_privilege(dc) && 3663 gen_window_check1(dc, arg[0])) { 3664 TCGv_i32 dtlb = tcg_const_i32(par[0]); 3665 3666 gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb); 3667 /* This could change memory mapping, so exit tb */ 3668 gen_jumpi_check_loop_end(dc, -1); 3669 tcg_temp_free(dtlb); 3670 } 3671 } 3672 3673 static void translate_ill(DisasContext *dc, const uint32_t arg[], 3674 const uint32_t par[]) 3675 { 3676 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 3677 } 3678 3679 static void translate_j(DisasContext *dc, const uint32_t arg[], 3680 const uint32_t par[]) 3681 { 3682 gen_jumpi(dc, arg[0], 0); 3683 } 3684 3685 static void translate_jx(DisasContext *dc, const uint32_t arg[], 3686 const uint32_t par[]) 3687 { 3688 if (gen_window_check1(dc, arg[0])) { 3689 gen_jump(dc, cpu_R[arg[0]]); 3690 } 3691 } 3692 3693 static void translate_l32e(DisasContext *dc, const uint32_t arg[], 3694 const uint32_t par[]) 3695 { 3696 if (gen_check_privilege(dc) && 3697 gen_window_check2(dc, arg[0], arg[1])) { 3698 TCGv_i32 addr = tcg_temp_new_i32(); 3699 3700 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]); 3701 gen_load_store_alignment(dc, 2, addr, false); 3702 tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL); 3703 tcg_temp_free(addr); 3704 } 3705 } 3706 3707 static void translate_ldst(DisasContext *dc, const uint32_t arg[], 3708 const uint32_t par[]) 3709 { 3710 if (gen_window_check2(dc, arg[0], arg[1])) { 3711 TCGv_i32 addr = tcg_temp_new_i32(); 3712 3713 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]); 3714 if (par[0] & MO_SIZE) { 3715 gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]); 3716 } 3717 if (par[2]) { 3718 tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->cring, par[0]); 3719 } else { 3720 tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->cring, par[0]); 3721 } 3722 tcg_temp_free(addr); 3723 } 3724 } 3725 3726 static void translate_l32r(DisasContext *dc, const uint32_t arg[], 3727 const uint32_t par[]) 3728 { 3729 if (gen_window_check1(dc, arg[0])) { 3730 TCGv_i32 tmp = (dc->tb->flags & XTENSA_TBFLAG_LITBASE) ? 3731 tcg_const_i32(dc->raw_arg[1] - 1) : 3732 tcg_const_i32(arg[1]); 3733 3734 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) { 3735 tcg_gen_add_i32(tmp, tmp, dc->litbase); 3736 } 3737 tcg_gen_qemu_ld32u(cpu_R[arg[0]], tmp, dc->cring); 3738 tcg_temp_free(tmp); 3739 } 3740 } 3741 3742 static void translate_loop(DisasContext *dc, const uint32_t arg[], 3743 const uint32_t par[]) 3744 { 3745 if (gen_window_check1(dc, arg[0])) { 3746 uint32_t lend = arg[1]; 3747 TCGv_i32 tmp = tcg_const_i32(lend); 3748 3749 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[arg[0]], 1); 3750 tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc); 3751 gen_helper_wsr_lend(cpu_env, tmp); 3752 tcg_temp_free(tmp); 3753 3754 if (par[0] != TCG_COND_NEVER) { 3755 TCGLabel *label = gen_new_label(); 3756 tcg_gen_brcondi_i32(par[0], cpu_R[arg[0]], 0, label); 3757 gen_jumpi(dc, lend, 1); 3758 gen_set_label(label); 3759 } 3760 3761 gen_jumpi(dc, dc->next_pc, 0); 3762 } 3763 } 3764 3765 enum { 3766 MAC16_UMUL, 3767 MAC16_MUL, 3768 MAC16_MULA, 3769 MAC16_MULS, 3770 MAC16_NONE, 3771 }; 3772 3773 enum { 3774 MAC16_LL, 3775 MAC16_HL, 3776 MAC16_LH, 3777 MAC16_HH, 3778 3779 MAC16_HX = 0x1, 3780 MAC16_XH = 0x2, 3781 }; 3782 3783 enum { 3784 MAC16_AA, 3785 MAC16_AD, 3786 MAC16_DA, 3787 MAC16_DD, 3788 3789 MAC16_XD = 0x1, 3790 MAC16_DX = 0x2, 3791 }; 3792 3793 static void translate_mac16(DisasContext *dc, const uint32_t arg[], 3794 const uint32_t par[]) 3795 { 3796 int op = par[0]; 3797 bool is_m1_sr = par[1] & MAC16_DX; 3798 bool is_m2_sr = par[1] & MAC16_XD; 3799 unsigned half = par[2]; 3800 uint32_t ld_offset = par[3]; 3801 unsigned off = ld_offset ? 2 : 0; 3802 uint32_t ar[3] = {0}; 3803 unsigned n_ar = 0; 3804 3805 if (op != MAC16_NONE) { 3806 if (!is_m1_sr) { 3807 ar[n_ar++] = arg[off]; 3808 } 3809 if (!is_m2_sr) { 3810 ar[n_ar++] = arg[off + 1]; 3811 } 3812 } 3813 3814 if (ld_offset) { 3815 ar[n_ar++] = arg[1]; 3816 } 3817 3818 if (gen_window_check3(dc, ar[0], ar[1], ar[2])) { 3819 TCGv_i32 vaddr = tcg_temp_new_i32(); 3820 TCGv_i32 mem32 = tcg_temp_new_i32(); 3821 3822 if (ld_offset) { 3823 tcg_gen_addi_i32(vaddr, cpu_R[arg[1]], ld_offset); 3824 gen_load_store_alignment(dc, 2, vaddr, false); 3825 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring); 3826 } 3827 if (op != MAC16_NONE) { 3828 TCGv_i32 m1 = gen_mac16_m(is_m1_sr ? 3829 cpu_SR[MR + arg[off]] : 3830 cpu_R[arg[off]], 3831 half & MAC16_HX, op == MAC16_UMUL); 3832 TCGv_i32 m2 = gen_mac16_m(is_m2_sr ? 3833 cpu_SR[MR + arg[off + 1]] : 3834 cpu_R[arg[off + 1]], 3835 half & MAC16_XH, op == MAC16_UMUL); 3836 3837 if (op == MAC16_MUL || op == MAC16_UMUL) { 3838 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2); 3839 if (op == MAC16_UMUL) { 3840 tcg_gen_movi_i32(cpu_SR[ACCHI], 0); 3841 } else { 3842 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31); 3843 } 3844 } else { 3845 TCGv_i32 lo = tcg_temp_new_i32(); 3846 TCGv_i32 hi = tcg_temp_new_i32(); 3847 3848 tcg_gen_mul_i32(lo, m1, m2); 3849 tcg_gen_sari_i32(hi, lo, 31); 3850 if (op == MAC16_MULA) { 3851 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 3852 cpu_SR[ACCLO], cpu_SR[ACCHI], 3853 lo, hi); 3854 } else { 3855 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], 3856 cpu_SR[ACCLO], cpu_SR[ACCHI], 3857 lo, hi); 3858 } 3859 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]); 3860 3861 tcg_temp_free_i32(lo); 3862 tcg_temp_free_i32(hi); 3863 } 3864 tcg_temp_free(m1); 3865 tcg_temp_free(m2); 3866 } 3867 if (ld_offset) { 3868 tcg_gen_mov_i32(cpu_R[arg[1]], vaddr); 3869 tcg_gen_mov_i32(cpu_SR[MR + arg[0]], mem32); 3870 } 3871 tcg_temp_free(vaddr); 3872 tcg_temp_free(mem32); 3873 } 3874 } 3875 3876 static void translate_minmax(DisasContext *dc, const uint32_t arg[], 3877 const uint32_t par[]) 3878 { 3879 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3880 tcg_gen_movcond_i32(par[0], cpu_R[arg[0]], 3881 cpu_R[arg[1]], cpu_R[arg[2]], 3882 cpu_R[arg[1]], cpu_R[arg[2]]); 3883 } 3884 } 3885 3886 static void translate_mov(DisasContext *dc, const uint32_t arg[], 3887 const uint32_t par[]) 3888 { 3889 if (gen_window_check2(dc, arg[0], arg[1])) { 3890 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]); 3891 } 3892 } 3893 3894 static void translate_movcond(DisasContext *dc, const uint32_t arg[], 3895 const uint32_t par[]) 3896 { 3897 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3898 TCGv_i32 zero = tcg_const_i32(0); 3899 3900 tcg_gen_movcond_i32(par[0], cpu_R[arg[0]], 3901 cpu_R[arg[2]], zero, cpu_R[arg[1]], cpu_R[arg[0]]); 3902 tcg_temp_free(zero); 3903 } 3904 } 3905 3906 static void translate_movi(DisasContext *dc, const uint32_t arg[], 3907 const uint32_t par[]) 3908 { 3909 if (gen_window_check1(dc, arg[0])) { 3910 tcg_gen_movi_i32(cpu_R[arg[0]], arg[1]); 3911 } 3912 } 3913 3914 static void translate_movp(DisasContext *dc, const uint32_t arg[], 3915 const uint32_t par[]) 3916 { 3917 if (gen_window_check2(dc, arg[0], arg[1])) { 3918 TCGv_i32 zero = tcg_const_i32(0); 3919 TCGv_i32 tmp = tcg_temp_new_i32(); 3920 3921 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]); 3922 tcg_gen_movcond_i32(par[0], 3923 cpu_R[arg[0]], tmp, zero, 3924 cpu_R[arg[1]], cpu_R[arg[0]]); 3925 tcg_temp_free(tmp); 3926 tcg_temp_free(zero); 3927 } 3928 } 3929 3930 static void translate_movsp(DisasContext *dc, const uint32_t arg[], 3931 const uint32_t par[]) 3932 { 3933 if (gen_window_check2(dc, arg[0], arg[1])) { 3934 TCGv_i32 pc = tcg_const_i32(dc->pc); 3935 gen_helper_movsp(cpu_env, pc); 3936 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]); 3937 tcg_temp_free(pc); 3938 } 3939 } 3940 3941 static void translate_mul16(DisasContext *dc, const uint32_t arg[], 3942 const uint32_t par[]) 3943 { 3944 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3945 TCGv_i32 v1 = tcg_temp_new_i32(); 3946 TCGv_i32 v2 = tcg_temp_new_i32(); 3947 3948 if (par[0]) { 3949 tcg_gen_ext16s_i32(v1, cpu_R[arg[1]]); 3950 tcg_gen_ext16s_i32(v2, cpu_R[arg[2]]); 3951 } else { 3952 tcg_gen_ext16u_i32(v1, cpu_R[arg[1]]); 3953 tcg_gen_ext16u_i32(v2, cpu_R[arg[2]]); 3954 } 3955 tcg_gen_mul_i32(cpu_R[arg[0]], v1, v2); 3956 tcg_temp_free(v2); 3957 tcg_temp_free(v1); 3958 } 3959 } 3960 3961 static void translate_mull(DisasContext *dc, const uint32_t arg[], 3962 const uint32_t par[]) 3963 { 3964 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3965 tcg_gen_mul_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 3966 } 3967 } 3968 3969 static void translate_mulh(DisasContext *dc, const uint32_t arg[], 3970 const uint32_t par[]) 3971 { 3972 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 3973 TCGv_i32 lo = tcg_temp_new(); 3974 3975 if (par[0]) { 3976 tcg_gen_muls2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 3977 } else { 3978 tcg_gen_mulu2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 3979 } 3980 tcg_temp_free(lo); 3981 } 3982 } 3983 3984 static void translate_neg(DisasContext *dc, const uint32_t arg[], 3985 const uint32_t par[]) 3986 { 3987 if (gen_window_check2(dc, arg[0], arg[1])) { 3988 tcg_gen_neg_i32(cpu_R[arg[0]], cpu_R[arg[1]]); 3989 } 3990 } 3991 3992 static void translate_nop(DisasContext *dc, const uint32_t arg[], 3993 const uint32_t par[]) 3994 { 3995 } 3996 3997 static void translate_nsa(DisasContext *dc, const uint32_t arg[], 3998 const uint32_t par[]) 3999 { 4000 if (gen_window_check2(dc, arg[0], arg[1])) { 4001 tcg_gen_clrsb_i32(cpu_R[arg[0]], cpu_R[arg[1]]); 4002 } 4003 } 4004 4005 static void translate_nsau(DisasContext *dc, const uint32_t arg[], 4006 const uint32_t par[]) 4007 { 4008 if (gen_window_check2(dc, arg[0], arg[1])) { 4009 tcg_gen_clzi_i32(cpu_R[arg[0]], cpu_R[arg[1]], 32); 4010 } 4011 } 4012 4013 static void translate_or(DisasContext *dc, const uint32_t arg[], 4014 const uint32_t par[]) 4015 { 4016 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4017 tcg_gen_or_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 4018 } 4019 } 4020 4021 static void translate_ptlb(DisasContext *dc, const uint32_t arg[], 4022 const uint32_t par[]) 4023 { 4024 if (gen_check_privilege(dc) && 4025 gen_window_check2(dc, arg[0], arg[1])) { 4026 TCGv_i32 dtlb = tcg_const_i32(par[0]); 4027 4028 tcg_gen_movi_i32(cpu_pc, dc->pc); 4029 gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb); 4030 tcg_temp_free(dtlb); 4031 } 4032 } 4033 4034 static void gen_zero_check(DisasContext *dc, const uint32_t arg[]) 4035 { 4036 TCGLabel *label = gen_new_label(); 4037 4038 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0, label); 4039 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE); 4040 gen_set_label(label); 4041 } 4042 4043 static void translate_quos(DisasContext *dc, const uint32_t arg[], 4044 const uint32_t par[]) 4045 { 4046 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4047 TCGLabel *label1 = gen_new_label(); 4048 TCGLabel *label2 = gen_new_label(); 4049 4050 gen_zero_check(dc, arg); 4051 4052 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[1]], 0x80000000, 4053 label1); 4054 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0xffffffff, 4055 label1); 4056 tcg_gen_movi_i32(cpu_R[arg[0]], 4057 par[0] ? 0x80000000 : 0); 4058 tcg_gen_br(label2); 4059 gen_set_label(label1); 4060 if (par[0]) { 4061 tcg_gen_div_i32(cpu_R[arg[0]], 4062 cpu_R[arg[1]], cpu_R[arg[2]]); 4063 } else { 4064 tcg_gen_rem_i32(cpu_R[arg[0]], 4065 cpu_R[arg[1]], cpu_R[arg[2]]); 4066 } 4067 gen_set_label(label2); 4068 } 4069 } 4070 4071 static void translate_quou(DisasContext *dc, const uint32_t arg[], 4072 const uint32_t par[]) 4073 { 4074 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4075 gen_zero_check(dc, arg); 4076 if (par[0]) { 4077 tcg_gen_divu_i32(cpu_R[arg[0]], 4078 cpu_R[arg[1]], cpu_R[arg[2]]); 4079 } else { 4080 tcg_gen_remu_i32(cpu_R[arg[0]], 4081 cpu_R[arg[1]], cpu_R[arg[2]]); 4082 } 4083 } 4084 } 4085 4086 static void translate_rer(DisasContext *dc, const uint32_t arg[], 4087 const uint32_t par[]) 4088 { 4089 if (gen_check_privilege(dc) && 4090 gen_window_check2(dc, arg[0], arg[1])) { 4091 gen_helper_rer(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]]); 4092 } 4093 } 4094 4095 static void translate_ret(DisasContext *dc, const uint32_t arg[], 4096 const uint32_t par[]) 4097 { 4098 gen_jump(dc, cpu_R[0]); 4099 } 4100 4101 static void translate_retw(DisasContext *dc, const uint32_t arg[], 4102 const uint32_t par[]) 4103 { 4104 TCGv_i32 tmp = tcg_const_i32(dc->pc); 4105 gen_helper_retw(tmp, cpu_env, tmp); 4106 gen_jump(dc, tmp); 4107 tcg_temp_free(tmp); 4108 } 4109 4110 static void translate_rfde(DisasContext *dc, const uint32_t arg[], 4111 const uint32_t par[]) 4112 { 4113 if (gen_check_privilege(dc)) { 4114 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]); 4115 } 4116 } 4117 4118 static void translate_rfe(DisasContext *dc, const uint32_t arg[], 4119 const uint32_t par[]) 4120 { 4121 if (gen_check_privilege(dc)) { 4122 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 4123 gen_check_interrupts(dc); 4124 gen_jump(dc, cpu_SR[EPC1]); 4125 } 4126 } 4127 4128 static void translate_rfi(DisasContext *dc, const uint32_t arg[], 4129 const uint32_t par[]) 4130 { 4131 if (gen_check_privilege(dc)) { 4132 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0] - 2]); 4133 gen_check_interrupts(dc); 4134 gen_jump(dc, cpu_SR[EPC1 + arg[0] - 1]); 4135 } 4136 } 4137 4138 static void translate_rfw(DisasContext *dc, const uint32_t arg[], 4139 const uint32_t par[]) 4140 { 4141 if (gen_check_privilege(dc)) { 4142 TCGv_i32 tmp = tcg_const_i32(1); 4143 4144 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); 4145 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); 4146 4147 if (par[0]) { 4148 tcg_gen_andc_i32(cpu_SR[WINDOW_START], 4149 cpu_SR[WINDOW_START], tmp); 4150 } else { 4151 tcg_gen_or_i32(cpu_SR[WINDOW_START], 4152 cpu_SR[WINDOW_START], tmp); 4153 } 4154 4155 gen_helper_restore_owb(cpu_env); 4156 gen_check_interrupts(dc); 4157 gen_jump(dc, cpu_SR[EPC1]); 4158 4159 tcg_temp_free(tmp); 4160 } 4161 } 4162 4163 static void translate_rotw(DisasContext *dc, const uint32_t arg[], 4164 const uint32_t par[]) 4165 { 4166 if (gen_check_privilege(dc)) { 4167 TCGv_i32 tmp = tcg_const_i32(arg[0]); 4168 gen_helper_rotw(cpu_env, tmp); 4169 tcg_temp_free(tmp); 4170 /* This can change tb->flags, so exit tb */ 4171 gen_jumpi_check_loop_end(dc, -1); 4172 } 4173 } 4174 4175 static void translate_rsil(DisasContext *dc, const uint32_t arg[], 4176 const uint32_t par[]) 4177 { 4178 if (gen_check_privilege(dc) && 4179 gen_window_check1(dc, arg[0])) { 4180 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_SR[PS]); 4181 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL); 4182 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1]); 4183 gen_check_interrupts(dc); 4184 gen_jumpi_check_loop_end(dc, 0); 4185 } 4186 } 4187 4188 static void translate_rsr(DisasContext *dc, const uint32_t arg[], 4189 const uint32_t par[]) 4190 { 4191 if (gen_check_sr(dc, par[0], SR_R) && 4192 (par[0] < 64 || gen_check_privilege(dc)) && 4193 gen_window_check1(dc, arg[0])) { 4194 if (gen_rsr(dc, cpu_R[arg[0]], par[0])) { 4195 gen_jumpi_check_loop_end(dc, 0); 4196 } 4197 } 4198 } 4199 4200 static void translate_rtlb(DisasContext *dc, const uint32_t arg[], 4201 const uint32_t par[]) 4202 { 4203 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1, 4204 TCGv_i32 a2) = { 4205 gen_helper_rtlb0, 4206 gen_helper_rtlb1, 4207 }; 4208 4209 if (gen_check_privilege(dc) && 4210 gen_window_check2(dc, arg[0], arg[1])) { 4211 TCGv_i32 dtlb = tcg_const_i32(par[0]); 4212 4213 helper[par[1]](cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb); 4214 tcg_temp_free(dtlb); 4215 } 4216 } 4217 4218 static void translate_rur(DisasContext *dc, const uint32_t arg[], 4219 const uint32_t par[]) 4220 { 4221 if (gen_window_check1(dc, arg[0])) { 4222 if (uregnames[par[0]].name) { 4223 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]); 4224 } else { 4225 qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", par[0]); 4226 } 4227 } 4228 } 4229 4230 static void translate_s32c1i(DisasContext *dc, const uint32_t arg[], 4231 const uint32_t par[]) 4232 { 4233 if (gen_window_check2(dc, arg[0], arg[1])) { 4234 TCGLabel *label = gen_new_label(); 4235 TCGv_i32 tmp = tcg_temp_local_new_i32(); 4236 TCGv_i32 addr = tcg_temp_local_new_i32(); 4237 TCGv_i32 tpc; 4238 4239 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]); 4240 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]); 4241 gen_load_store_alignment(dc, 2, addr, true); 4242 4243 tpc = tcg_const_i32(dc->pc); 4244 gen_helper_check_atomctl(cpu_env, tpc, addr); 4245 tcg_gen_qemu_ld32u(cpu_R[arg[0]], addr, dc->cring); 4246 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[arg[0]], 4247 cpu_SR[SCOMPARE1], label); 4248 4249 tcg_gen_qemu_st32(tmp, addr, dc->cring); 4250 4251 gen_set_label(label); 4252 tcg_temp_free(tpc); 4253 tcg_temp_free(addr); 4254 tcg_temp_free(tmp); 4255 } 4256 } 4257 4258 static void translate_s32e(DisasContext *dc, const uint32_t arg[], 4259 const uint32_t par[]) 4260 { 4261 if (gen_check_privilege(dc) && 4262 gen_window_check2(dc, arg[0], arg[1])) { 4263 TCGv_i32 addr = tcg_temp_new_i32(); 4264 4265 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]); 4266 gen_load_store_alignment(dc, 2, addr, false); 4267 tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL); 4268 tcg_temp_free(addr); 4269 } 4270 } 4271 4272 static void translate_sext(DisasContext *dc, const uint32_t arg[], 4273 const uint32_t par[]) 4274 { 4275 if (gen_window_check2(dc, arg[0], arg[1])) { 4276 int shift = 31 - arg[2]; 4277 4278 if (shift == 24) { 4279 tcg_gen_ext8s_i32(cpu_R[arg[0]], cpu_R[arg[1]]); 4280 } else if (shift == 16) { 4281 tcg_gen_ext16s_i32(cpu_R[arg[0]], cpu_R[arg[1]]); 4282 } else { 4283 TCGv_i32 tmp = tcg_temp_new_i32(); 4284 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], shift); 4285 tcg_gen_sari_i32(cpu_R[arg[0]], tmp, shift); 4286 tcg_temp_free(tmp); 4287 } 4288 } 4289 } 4290 4291 static void translate_simcall(DisasContext *dc, const uint32_t arg[], 4292 const uint32_t par[]) 4293 { 4294 if (semihosting_enabled()) { 4295 if (gen_check_privilege(dc)) { 4296 gen_helper_simcall(cpu_env); 4297 } 4298 } else { 4299 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n"); 4300 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); 4301 } 4302 } 4303 4304 /* 4305 * Note: 64 bit ops are used here solely because SAR values 4306 * have range 0..63 4307 */ 4308 #define gen_shift_reg(cmd, reg) do { \ 4309 TCGv_i64 tmp = tcg_temp_new_i64(); \ 4310 tcg_gen_extu_i32_i64(tmp, reg); \ 4311 tcg_gen_##cmd##_i64(v, v, tmp); \ 4312 tcg_gen_extrl_i64_i32(cpu_R[arg[0]], v); \ 4313 tcg_temp_free_i64(v); \ 4314 tcg_temp_free_i64(tmp); \ 4315 } while (0) 4316 4317 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR]) 4318 4319 static void translate_sll(DisasContext *dc, const uint32_t arg[], 4320 const uint32_t par[]) 4321 { 4322 if (gen_window_check2(dc, arg[0], arg[1])) { 4323 if (dc->sar_m32_5bit) { 4324 tcg_gen_shl_i32(cpu_R[arg[0]], cpu_R[arg[1]], dc->sar_m32); 4325 } else { 4326 TCGv_i64 v = tcg_temp_new_i64(); 4327 TCGv_i32 s = tcg_const_i32(32); 4328 tcg_gen_sub_i32(s, s, cpu_SR[SAR]); 4329 tcg_gen_andi_i32(s, s, 0x3f); 4330 tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]); 4331 gen_shift_reg(shl, s); 4332 tcg_temp_free(s); 4333 } 4334 } 4335 } 4336 4337 static void translate_slli(DisasContext *dc, const uint32_t arg[], 4338 const uint32_t par[]) 4339 { 4340 if (gen_window_check2(dc, arg[0], arg[1])) { 4341 if (arg[2] == 32) { 4342 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined", 4343 arg[0], arg[1]); 4344 } 4345 tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f); 4346 } 4347 } 4348 4349 static void translate_sra(DisasContext *dc, const uint32_t arg[], 4350 const uint32_t par[]) 4351 { 4352 if (gen_window_check2(dc, arg[0], arg[1])) { 4353 if (dc->sar_m32_5bit) { 4354 tcg_gen_sar_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]); 4355 } else { 4356 TCGv_i64 v = tcg_temp_new_i64(); 4357 tcg_gen_ext_i32_i64(v, cpu_R[arg[1]]); 4358 gen_shift(sar); 4359 } 4360 } 4361 } 4362 4363 static void translate_srai(DisasContext *dc, const uint32_t arg[], 4364 const uint32_t par[]) 4365 { 4366 if (gen_window_check2(dc, arg[0], arg[1])) { 4367 tcg_gen_sari_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]); 4368 } 4369 } 4370 4371 static void translate_src(DisasContext *dc, const uint32_t arg[], 4372 const uint32_t par[]) 4373 { 4374 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4375 TCGv_i64 v = tcg_temp_new_i64(); 4376 tcg_gen_concat_i32_i64(v, cpu_R[arg[2]], cpu_R[arg[1]]); 4377 gen_shift(shr); 4378 } 4379 } 4380 4381 static void translate_srl(DisasContext *dc, const uint32_t arg[], 4382 const uint32_t par[]) 4383 { 4384 if (gen_window_check2(dc, arg[0], arg[1])) { 4385 if (dc->sar_m32_5bit) { 4386 tcg_gen_shr_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]); 4387 } else { 4388 TCGv_i64 v = tcg_temp_new_i64(); 4389 tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]); 4390 gen_shift(shr); 4391 } 4392 } 4393 } 4394 4395 #undef gen_shift 4396 #undef gen_shift_reg 4397 4398 static void translate_srli(DisasContext *dc, const uint32_t arg[], 4399 const uint32_t par[]) 4400 { 4401 if (gen_window_check2(dc, arg[0], arg[1])) { 4402 tcg_gen_shri_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]); 4403 } 4404 } 4405 4406 static void translate_ssa8b(DisasContext *dc, const uint32_t arg[], 4407 const uint32_t par[]) 4408 { 4409 if (gen_window_check1(dc, arg[0])) { 4410 TCGv_i32 tmp = tcg_temp_new_i32(); 4411 tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3); 4412 gen_left_shift_sar(dc, tmp); 4413 tcg_temp_free(tmp); 4414 } 4415 } 4416 4417 static void translate_ssa8l(DisasContext *dc, const uint32_t arg[], 4418 const uint32_t par[]) 4419 { 4420 if (gen_window_check1(dc, arg[0])) { 4421 TCGv_i32 tmp = tcg_temp_new_i32(); 4422 tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3); 4423 gen_right_shift_sar(dc, tmp); 4424 tcg_temp_free(tmp); 4425 } 4426 } 4427 4428 static void translate_ssai(DisasContext *dc, const uint32_t arg[], 4429 const uint32_t par[]) 4430 { 4431 TCGv_i32 tmp = tcg_const_i32(arg[0]); 4432 gen_right_shift_sar(dc, tmp); 4433 tcg_temp_free(tmp); 4434 } 4435 4436 static void translate_ssl(DisasContext *dc, const uint32_t arg[], 4437 const uint32_t par[]) 4438 { 4439 if (gen_window_check1(dc, arg[0])) { 4440 gen_left_shift_sar(dc, cpu_R[arg[0]]); 4441 } 4442 } 4443 4444 static void translate_ssr(DisasContext *dc, const uint32_t arg[], 4445 const uint32_t par[]) 4446 { 4447 if (gen_window_check1(dc, arg[0])) { 4448 gen_right_shift_sar(dc, cpu_R[arg[0]]); 4449 } 4450 } 4451 4452 static void translate_sub(DisasContext *dc, const uint32_t arg[], 4453 const uint32_t par[]) 4454 { 4455 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4456 tcg_gen_sub_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 4457 } 4458 } 4459 4460 static void translate_subx(DisasContext *dc, const uint32_t arg[], 4461 const uint32_t par[]) 4462 { 4463 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4464 TCGv_i32 tmp = tcg_temp_new_i32(); 4465 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]); 4466 tcg_gen_sub_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]); 4467 tcg_temp_free(tmp); 4468 } 4469 } 4470 4471 static void translate_syscall(DisasContext *dc, const uint32_t arg[], 4472 const uint32_t par[]) 4473 { 4474 gen_exception_cause(dc, SYSCALL_CAUSE); 4475 } 4476 4477 static void translate_waiti(DisasContext *dc, const uint32_t arg[], 4478 const uint32_t par[]) 4479 { 4480 if (gen_check_privilege(dc)) { 4481 gen_waiti(dc, arg[0]); 4482 } 4483 } 4484 4485 static void translate_wtlb(DisasContext *dc, const uint32_t arg[], 4486 const uint32_t par[]) 4487 { 4488 if (gen_check_privilege(dc) && 4489 gen_window_check2(dc, arg[0], arg[1])) { 4490 TCGv_i32 dtlb = tcg_const_i32(par[0]); 4491 4492 gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb); 4493 /* This could change memory mapping, so exit tb */ 4494 gen_jumpi_check_loop_end(dc, -1); 4495 tcg_temp_free(dtlb); 4496 } 4497 } 4498 4499 static void translate_wer(DisasContext *dc, const uint32_t arg[], 4500 const uint32_t par[]) 4501 { 4502 if (gen_check_privilege(dc) && 4503 gen_window_check2(dc, arg[0], arg[1])) { 4504 gen_helper_wer(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]]); 4505 } 4506 } 4507 4508 static void translate_wsr(DisasContext *dc, const uint32_t arg[], 4509 const uint32_t par[]) 4510 { 4511 if (gen_check_sr(dc, par[0], SR_W) && 4512 (par[0] < 64 || gen_check_privilege(dc)) && 4513 gen_window_check1(dc, arg[0])) { 4514 gen_wsr(dc, par[0], cpu_R[arg[0]]); 4515 } 4516 } 4517 4518 static void translate_wur(DisasContext *dc, const uint32_t arg[], 4519 const uint32_t par[]) 4520 { 4521 if (gen_window_check1(dc, arg[0])) { 4522 if (uregnames[par[0]].name) { 4523 gen_wur(par[0], cpu_R[arg[0]]); 4524 } else { 4525 qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", par[0]); 4526 } 4527 } 4528 } 4529 4530 static void translate_xor(DisasContext *dc, const uint32_t arg[], 4531 const uint32_t par[]) 4532 { 4533 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) { 4534 tcg_gen_xor_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]); 4535 } 4536 } 4537 4538 static void translate_xsr(DisasContext *dc, const uint32_t arg[], 4539 const uint32_t par[]) 4540 { 4541 if (gen_check_sr(dc, par[0], SR_X) && 4542 (par[0] < 64 || gen_check_privilege(dc)) && 4543 gen_window_check1(dc, arg[0])) { 4544 TCGv_i32 tmp = tcg_temp_new_i32(); 4545 bool rsr_end, wsr_end; 4546 4547 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]); 4548 rsr_end = gen_rsr(dc, cpu_R[arg[0]], par[0]); 4549 wsr_end = gen_wsr(dc, par[0], tmp); 4550 tcg_temp_free(tmp); 4551 if (rsr_end && !wsr_end) { 4552 gen_jumpi_check_loop_end(dc, 0); 4553 } 4554 } 4555 } 4556 4557 static const XtensaOpcodeOps core_ops[] = { 4558 { 4559 .name = "abs", 4560 .translate = translate_abs, 4561 }, { 4562 .name = "add", 4563 .translate = translate_add, 4564 }, { 4565 .name = "add.n", 4566 .translate = translate_add, 4567 }, { 4568 .name = "addi", 4569 .translate = translate_addi, 4570 }, { 4571 .name = "addi.n", 4572 .translate = translate_addi, 4573 }, { 4574 .name = "addmi", 4575 .translate = translate_addi, 4576 }, { 4577 .name = "addx2", 4578 .translate = translate_addx, 4579 .par = (const uint32_t[]){1}, 4580 }, { 4581 .name = "addx4", 4582 .translate = translate_addx, 4583 .par = (const uint32_t[]){2}, 4584 }, { 4585 .name = "addx8", 4586 .translate = translate_addx, 4587 .par = (const uint32_t[]){3}, 4588 }, { 4589 .name = "all4", 4590 .translate = translate_all, 4591 .par = (const uint32_t[]){true, 4}, 4592 }, { 4593 .name = "all8", 4594 .translate = translate_all, 4595 .par = (const uint32_t[]){true, 8}, 4596 }, { 4597 .name = "and", 4598 .translate = translate_and, 4599 }, { 4600 .name = "andb", 4601 .translate = translate_boolean, 4602 .par = (const uint32_t[]){BOOLEAN_AND}, 4603 }, { 4604 .name = "andbc", 4605 .translate = translate_boolean, 4606 .par = (const uint32_t[]){BOOLEAN_ANDC}, 4607 }, { 4608 .name = "any4", 4609 .translate = translate_all, 4610 .par = (const uint32_t[]){false, 4}, 4611 }, { 4612 .name = "any8", 4613 .translate = translate_all, 4614 .par = (const uint32_t[]){false, 8}, 4615 }, { 4616 .name = "ball", 4617 .translate = translate_ball, 4618 .par = (const uint32_t[]){TCG_COND_EQ}, 4619 }, { 4620 .name = "bany", 4621 .translate = translate_bany, 4622 .par = (const uint32_t[]){TCG_COND_NE}, 4623 }, { 4624 .name = "bbc", 4625 .translate = translate_bb, 4626 .par = (const uint32_t[]){TCG_COND_EQ}, 4627 }, { 4628 .name = "bbci", 4629 .translate = translate_bbi, 4630 .par = (const uint32_t[]){TCG_COND_EQ}, 4631 }, { 4632 .name = "bbs", 4633 .translate = translate_bb, 4634 .par = (const uint32_t[]){TCG_COND_NE}, 4635 }, { 4636 .name = "bbsi", 4637 .translate = translate_bbi, 4638 .par = (const uint32_t[]){TCG_COND_NE}, 4639 }, { 4640 .name = "beq", 4641 .translate = translate_b, 4642 .par = (const uint32_t[]){TCG_COND_EQ}, 4643 }, { 4644 .name = "beqi", 4645 .translate = translate_bi, 4646 .par = (const uint32_t[]){TCG_COND_EQ}, 4647 }, { 4648 .name = "beqz", 4649 .translate = translate_bz, 4650 .par = (const uint32_t[]){TCG_COND_EQ}, 4651 }, { 4652 .name = "beqz.n", 4653 .translate = translate_bz, 4654 .par = (const uint32_t[]){TCG_COND_EQ}, 4655 }, { 4656 .name = "bf", 4657 .translate = translate_bp, 4658 .par = (const uint32_t[]){TCG_COND_EQ}, 4659 }, { 4660 .name = "bge", 4661 .translate = translate_b, 4662 .par = (const uint32_t[]){TCG_COND_GE}, 4663 }, { 4664 .name = "bgei", 4665 .translate = translate_bi, 4666 .par = (const uint32_t[]){TCG_COND_GE}, 4667 }, { 4668 .name = "bgeu", 4669 .translate = translate_b, 4670 .par = (const uint32_t[]){TCG_COND_GEU}, 4671 }, { 4672 .name = "bgeui", 4673 .translate = translate_bi, 4674 .par = (const uint32_t[]){TCG_COND_GEU}, 4675 }, { 4676 .name = "bgez", 4677 .translate = translate_bz, 4678 .par = (const uint32_t[]){TCG_COND_GE}, 4679 }, { 4680 .name = "blt", 4681 .translate = translate_b, 4682 .par = (const uint32_t[]){TCG_COND_LT}, 4683 }, { 4684 .name = "blti", 4685 .translate = translate_bi, 4686 .par = (const uint32_t[]){TCG_COND_LT}, 4687 }, { 4688 .name = "bltu", 4689 .translate = translate_b, 4690 .par = (const uint32_t[]){TCG_COND_LTU}, 4691 }, { 4692 .name = "bltui", 4693 .translate = translate_bi, 4694 .par = (const uint32_t[]){TCG_COND_LTU}, 4695 }, { 4696 .name = "bltz", 4697 .translate = translate_bz, 4698 .par = (const uint32_t[]){TCG_COND_LT}, 4699 }, { 4700 .name = "bnall", 4701 .translate = translate_ball, 4702 .par = (const uint32_t[]){TCG_COND_NE}, 4703 }, { 4704 .name = "bne", 4705 .translate = translate_b, 4706 .par = (const uint32_t[]){TCG_COND_NE}, 4707 }, { 4708 .name = "bnei", 4709 .translate = translate_bi, 4710 .par = (const uint32_t[]){TCG_COND_NE}, 4711 }, { 4712 .name = "bnez", 4713 .translate = translate_bz, 4714 .par = (const uint32_t[]){TCG_COND_NE}, 4715 }, { 4716 .name = "bnez.n", 4717 .translate = translate_bz, 4718 .par = (const uint32_t[]){TCG_COND_NE}, 4719 }, { 4720 .name = "bnone", 4721 .translate = translate_bany, 4722 .par = (const uint32_t[]){TCG_COND_EQ}, 4723 }, { 4724 .name = "break", 4725 .translate = translate_break, 4726 .par = (const uint32_t[]){DEBUGCAUSE_BI}, 4727 }, { 4728 .name = "break.n", 4729 .translate = translate_break, 4730 .par = (const uint32_t[]){DEBUGCAUSE_BN}, 4731 }, { 4732 .name = "bt", 4733 .translate = translate_bp, 4734 .par = (const uint32_t[]){TCG_COND_NE}, 4735 }, { 4736 .name = "call0", 4737 .translate = translate_call0, 4738 }, { 4739 .name = "call12", 4740 .translate = translate_callw, 4741 .par = (const uint32_t[]){3}, 4742 }, { 4743 .name = "call4", 4744 .translate = translate_callw, 4745 .par = (const uint32_t[]){1}, 4746 }, { 4747 .name = "call8", 4748 .translate = translate_callw, 4749 .par = (const uint32_t[]){2}, 4750 }, { 4751 .name = "callx0", 4752 .translate = translate_callx0, 4753 }, { 4754 .name = "callx12", 4755 .translate = translate_callxw, 4756 .par = (const uint32_t[]){3}, 4757 }, { 4758 .name = "callx4", 4759 .translate = translate_callxw, 4760 .par = (const uint32_t[]){1}, 4761 }, { 4762 .name = "callx8", 4763 .translate = translate_callxw, 4764 .par = (const uint32_t[]){2}, 4765 }, { 4766 .name = "clamps", 4767 .translate = translate_clamps, 4768 }, { 4769 .name = "depbits", 4770 .translate = translate_depbits, 4771 }, { 4772 .name = "dhi", 4773 .translate = translate_dcache, 4774 .par = (const uint32_t[]){true, true}, 4775 }, { 4776 .name = "dhu", 4777 .translate = translate_dcache, 4778 .par = (const uint32_t[]){true, true}, 4779 }, { 4780 .name = "dhwb", 4781 .translate = translate_dcache, 4782 .par = (const uint32_t[]){false, true}, 4783 }, { 4784 .name = "dhwbi", 4785 .translate = translate_dcache, 4786 .par = (const uint32_t[]){false, true}, 4787 }, { 4788 .name = "dii", 4789 .translate = translate_dcache, 4790 .par = (const uint32_t[]){true, false}, 4791 }, { 4792 .name = "diu", 4793 .translate = translate_dcache, 4794 .par = (const uint32_t[]){true, false}, 4795 }, { 4796 .name = "diwb", 4797 .translate = translate_dcache, 4798 .par = (const uint32_t[]){true, false}, 4799 }, { 4800 .name = "diwbi", 4801 .translate = translate_dcache, 4802 .par = (const uint32_t[]){true, false}, 4803 }, { 4804 .name = "dpfl", 4805 .translate = translate_dcache, 4806 .par = (const uint32_t[]){true, true}, 4807 }, { 4808 .name = "dpfr", 4809 .translate = translate_dcache, 4810 .par = (const uint32_t[]){false, false}, 4811 }, { 4812 .name = "dpfro", 4813 .translate = translate_dcache, 4814 .par = (const uint32_t[]){false, false}, 4815 }, { 4816 .name = "dpfw", 4817 .translate = translate_dcache, 4818 .par = (const uint32_t[]){false, false}, 4819 }, { 4820 .name = "dpfwo", 4821 .translate = translate_dcache, 4822 .par = (const uint32_t[]){false, false}, 4823 }, { 4824 .name = "dsync", 4825 .translate = translate_nop, 4826 }, { 4827 .name = "entry", 4828 .translate = translate_entry, 4829 }, { 4830 .name = "esync", 4831 .translate = translate_nop, 4832 }, { 4833 .name = "excw", 4834 .translate = translate_nop, 4835 }, { 4836 .name = "extui", 4837 .translate = translate_extui, 4838 }, { 4839 .name = "extw", 4840 .translate = translate_nop, 4841 }, { 4842 .name = "idtlb", 4843 .translate = translate_itlb, 4844 .par = (const uint32_t[]){true}, 4845 }, { 4846 .name = "ihi", 4847 .translate = translate_icache, 4848 .par = (const uint32_t[]){false, true}, 4849 }, { 4850 .name = "ihu", 4851 .translate = translate_icache, 4852 .par = (const uint32_t[]){true, true}, 4853 }, { 4854 .name = "iii", 4855 .translate = translate_icache, 4856 .par = (const uint32_t[]){true, false}, 4857 }, { 4858 .name = "iitlb", 4859 .translate = translate_itlb, 4860 .par = (const uint32_t[]){false}, 4861 }, { 4862 .name = "iiu", 4863 .translate = translate_icache, 4864 .par = (const uint32_t[]){true, false}, 4865 }, { 4866 .name = "ill", 4867 .translate = translate_ill, 4868 }, { 4869 .name = "ill.n", 4870 .translate = translate_ill, 4871 }, { 4872 .name = "ipf", 4873 .translate = translate_icache, 4874 .par = (const uint32_t[]){false, false}, 4875 }, { 4876 .name = "ipfl", 4877 .translate = translate_icache, 4878 .par = (const uint32_t[]){true, true}, 4879 }, { 4880 .name = "isync", 4881 .translate = translate_nop, 4882 }, { 4883 .name = "j", 4884 .translate = translate_j, 4885 }, { 4886 .name = "jx", 4887 .translate = translate_jx, 4888 }, { 4889 .name = "l16si", 4890 .translate = translate_ldst, 4891 .par = (const uint32_t[]){MO_TESW, false, false}, 4892 }, { 4893 .name = "l16ui", 4894 .translate = translate_ldst, 4895 .par = (const uint32_t[]){MO_TEUW, false, false}, 4896 }, { 4897 .name = "l32ai", 4898 .translate = translate_ldst, 4899 .par = (const uint32_t[]){MO_TEUL, true, false}, 4900 }, { 4901 .name = "l32e", 4902 .translate = translate_l32e, 4903 }, { 4904 .name = "l32i", 4905 .translate = translate_ldst, 4906 .par = (const uint32_t[]){MO_TEUL, false, false}, 4907 }, { 4908 .name = "l32i.n", 4909 .translate = translate_ldst, 4910 .par = (const uint32_t[]){MO_TEUL, false, false}, 4911 }, { 4912 .name = "l32r", 4913 .translate = translate_l32r, 4914 }, { 4915 .name = "l8ui", 4916 .translate = translate_ldst, 4917 .par = (const uint32_t[]){MO_UB, false, false}, 4918 }, { 4919 .name = "lddec", 4920 .translate = translate_mac16, 4921 .par = (const uint32_t[]){MAC16_NONE, 0, 0, -4}, 4922 }, { 4923 .name = "ldinc", 4924 .translate = translate_mac16, 4925 .par = (const uint32_t[]){MAC16_NONE, 0, 0, 4}, 4926 }, { 4927 .name = "loop", 4928 .translate = translate_loop, 4929 .par = (const uint32_t[]){TCG_COND_NEVER}, 4930 }, { 4931 .name = "loopgtz", 4932 .translate = translate_loop, 4933 .par = (const uint32_t[]){TCG_COND_GT}, 4934 }, { 4935 .name = "loopnez", 4936 .translate = translate_loop, 4937 .par = (const uint32_t[]){TCG_COND_NE}, 4938 }, { 4939 .name = "max", 4940 .translate = translate_minmax, 4941 .par = (const uint32_t[]){TCG_COND_GE}, 4942 }, { 4943 .name = "maxu", 4944 .translate = translate_minmax, 4945 .par = (const uint32_t[]){TCG_COND_GEU}, 4946 }, { 4947 .name = "memw", 4948 .translate = translate_nop, 4949 }, { 4950 .name = "min", 4951 .translate = translate_minmax, 4952 .par = (const uint32_t[]){TCG_COND_LT}, 4953 }, { 4954 .name = "minu", 4955 .translate = translate_minmax, 4956 .par = (const uint32_t[]){TCG_COND_LTU}, 4957 }, { 4958 .name = "mov", 4959 .translate = translate_mov, 4960 }, { 4961 .name = "mov.n", 4962 .translate = translate_mov, 4963 }, { 4964 .name = "moveqz", 4965 .translate = translate_movcond, 4966 .par = (const uint32_t[]){TCG_COND_EQ}, 4967 }, { 4968 .name = "movf", 4969 .translate = translate_movp, 4970 .par = (const uint32_t[]){TCG_COND_EQ}, 4971 }, { 4972 .name = "movgez", 4973 .translate = translate_movcond, 4974 .par = (const uint32_t[]){TCG_COND_GE}, 4975 }, { 4976 .name = "movi", 4977 .translate = translate_movi, 4978 }, { 4979 .name = "movi.n", 4980 .translate = translate_movi, 4981 }, { 4982 .name = "movltz", 4983 .translate = translate_movcond, 4984 .par = (const uint32_t[]){TCG_COND_LT}, 4985 }, { 4986 .name = "movnez", 4987 .translate = translate_movcond, 4988 .par = (const uint32_t[]){TCG_COND_NE}, 4989 }, { 4990 .name = "movsp", 4991 .translate = translate_movsp, 4992 }, { 4993 .name = "movt", 4994 .translate = translate_movp, 4995 .par = (const uint32_t[]){TCG_COND_NE}, 4996 }, { 4997 .name = "mul.aa.hh", 4998 .translate = translate_mac16, 4999 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HH, 0}, 5000 }, { 5001 .name = "mul.aa.hl", 5002 .translate = translate_mac16, 5003 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HL, 0}, 5004 }, { 5005 .name = "mul.aa.lh", 5006 .translate = translate_mac16, 5007 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LH, 0}, 5008 }, { 5009 .name = "mul.aa.ll", 5010 .translate = translate_mac16, 5011 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LL, 0}, 5012 }, { 5013 .name = "mul.ad.hh", 5014 .translate = translate_mac16, 5015 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HH, 0}, 5016 }, { 5017 .name = "mul.ad.hl", 5018 .translate = translate_mac16, 5019 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HL, 0}, 5020 }, { 5021 .name = "mul.ad.lh", 5022 .translate = translate_mac16, 5023 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LH, 0}, 5024 }, { 5025 .name = "mul.ad.ll", 5026 .translate = translate_mac16, 5027 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LL, 0}, 5028 }, { 5029 .name = "mul.da.hh", 5030 .translate = translate_mac16, 5031 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HH, 0}, 5032 }, { 5033 .name = "mul.da.hl", 5034 .translate = translate_mac16, 5035 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HL, 0}, 5036 }, { 5037 .name = "mul.da.lh", 5038 .translate = translate_mac16, 5039 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LH, 0}, 5040 }, { 5041 .name = "mul.da.ll", 5042 .translate = translate_mac16, 5043 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LL, 0}, 5044 }, { 5045 .name = "mul.dd.hh", 5046 .translate = translate_mac16, 5047 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HH, 0}, 5048 }, { 5049 .name = "mul.dd.hl", 5050 .translate = translate_mac16, 5051 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HL, 0}, 5052 }, { 5053 .name = "mul.dd.lh", 5054 .translate = translate_mac16, 5055 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LH, 0}, 5056 }, { 5057 .name = "mul.dd.ll", 5058 .translate = translate_mac16, 5059 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LL, 0}, 5060 }, { 5061 .name = "mul16s", 5062 .translate = translate_mul16, 5063 .par = (const uint32_t[]){true}, 5064 }, { 5065 .name = "mul16u", 5066 .translate = translate_mul16, 5067 .par = (const uint32_t[]){false}, 5068 }, { 5069 .name = "mula.aa.hh", 5070 .translate = translate_mac16, 5071 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HH, 0}, 5072 }, { 5073 .name = "mula.aa.hl", 5074 .translate = translate_mac16, 5075 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HL, 0}, 5076 }, { 5077 .name = "mula.aa.lh", 5078 .translate = translate_mac16, 5079 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LH, 0}, 5080 }, { 5081 .name = "mula.aa.ll", 5082 .translate = translate_mac16, 5083 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LL, 0}, 5084 }, { 5085 .name = "mula.ad.hh", 5086 .translate = translate_mac16, 5087 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HH, 0}, 5088 }, { 5089 .name = "mula.ad.hl", 5090 .translate = translate_mac16, 5091 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HL, 0}, 5092 }, { 5093 .name = "mula.ad.lh", 5094 .translate = translate_mac16, 5095 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LH, 0}, 5096 }, { 5097 .name = "mula.ad.ll", 5098 .translate = translate_mac16, 5099 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LL, 0}, 5100 }, { 5101 .name = "mula.da.hh", 5102 .translate = translate_mac16, 5103 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 0}, 5104 }, { 5105 .name = "mula.da.hh.lddec", 5106 .translate = translate_mac16, 5107 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, -4}, 5108 }, { 5109 .name = "mula.da.hh.ldinc", 5110 .translate = translate_mac16, 5111 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 4}, 5112 }, { 5113 .name = "mula.da.hl", 5114 .translate = translate_mac16, 5115 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 0}, 5116 }, { 5117 .name = "mula.da.hl.lddec", 5118 .translate = translate_mac16, 5119 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, -4}, 5120 }, { 5121 .name = "mula.da.hl.ldinc", 5122 .translate = translate_mac16, 5123 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 4}, 5124 }, { 5125 .name = "mula.da.lh", 5126 .translate = translate_mac16, 5127 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 0}, 5128 }, { 5129 .name = "mula.da.lh.lddec", 5130 .translate = translate_mac16, 5131 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, -4}, 5132 }, { 5133 .name = "mula.da.lh.ldinc", 5134 .translate = translate_mac16, 5135 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 4}, 5136 }, { 5137 .name = "mula.da.ll", 5138 .translate = translate_mac16, 5139 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 0}, 5140 }, { 5141 .name = "mula.da.ll.lddec", 5142 .translate = translate_mac16, 5143 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, -4}, 5144 }, { 5145 .name = "mula.da.ll.ldinc", 5146 .translate = translate_mac16, 5147 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 4}, 5148 }, { 5149 .name = "mula.dd.hh", 5150 .translate = translate_mac16, 5151 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 0}, 5152 }, { 5153 .name = "mula.dd.hh.lddec", 5154 .translate = translate_mac16, 5155 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, -4}, 5156 }, { 5157 .name = "mula.dd.hh.ldinc", 5158 .translate = translate_mac16, 5159 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 4}, 5160 }, { 5161 .name = "mula.dd.hl", 5162 .translate = translate_mac16, 5163 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 0}, 5164 }, { 5165 .name = "mula.dd.hl.lddec", 5166 .translate = translate_mac16, 5167 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, -4}, 5168 }, { 5169 .name = "mula.dd.hl.ldinc", 5170 .translate = translate_mac16, 5171 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 4}, 5172 }, { 5173 .name = "mula.dd.lh", 5174 .translate = translate_mac16, 5175 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 0}, 5176 }, { 5177 .name = "mula.dd.lh.lddec", 5178 .translate = translate_mac16, 5179 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, -4}, 5180 }, { 5181 .name = "mula.dd.lh.ldinc", 5182 .translate = translate_mac16, 5183 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 4}, 5184 }, { 5185 .name = "mula.dd.ll", 5186 .translate = translate_mac16, 5187 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 0}, 5188 }, { 5189 .name = "mula.dd.ll.lddec", 5190 .translate = translate_mac16, 5191 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, -4}, 5192 }, { 5193 .name = "mula.dd.ll.ldinc", 5194 .translate = translate_mac16, 5195 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 4}, 5196 }, { 5197 .name = "mull", 5198 .translate = translate_mull, 5199 }, { 5200 .name = "muls.aa.hh", 5201 .translate = translate_mac16, 5202 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HH, 0}, 5203 }, { 5204 .name = "muls.aa.hl", 5205 .translate = translate_mac16, 5206 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HL, 0}, 5207 }, { 5208 .name = "muls.aa.lh", 5209 .translate = translate_mac16, 5210 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LH, 0}, 5211 }, { 5212 .name = "muls.aa.ll", 5213 .translate = translate_mac16, 5214 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LL, 0}, 5215 }, { 5216 .name = "muls.ad.hh", 5217 .translate = translate_mac16, 5218 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HH, 0}, 5219 }, { 5220 .name = "muls.ad.hl", 5221 .translate = translate_mac16, 5222 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HL, 0}, 5223 }, { 5224 .name = "muls.ad.lh", 5225 .translate = translate_mac16, 5226 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LH, 0}, 5227 }, { 5228 .name = "muls.ad.ll", 5229 .translate = translate_mac16, 5230 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LL, 0}, 5231 }, { 5232 .name = "muls.da.hh", 5233 .translate = translate_mac16, 5234 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HH, 0}, 5235 }, { 5236 .name = "muls.da.hl", 5237 .translate = translate_mac16, 5238 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HL, 0}, 5239 }, { 5240 .name = "muls.da.lh", 5241 .translate = translate_mac16, 5242 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LH, 0}, 5243 }, { 5244 .name = "muls.da.ll", 5245 .translate = translate_mac16, 5246 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LL, 0}, 5247 }, { 5248 .name = "muls.dd.hh", 5249 .translate = translate_mac16, 5250 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HH, 0}, 5251 }, { 5252 .name = "muls.dd.hl", 5253 .translate = translate_mac16, 5254 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HL, 0}, 5255 }, { 5256 .name = "muls.dd.lh", 5257 .translate = translate_mac16, 5258 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LH, 0}, 5259 }, { 5260 .name = "muls.dd.ll", 5261 .translate = translate_mac16, 5262 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LL, 0}, 5263 }, { 5264 .name = "mulsh", 5265 .translate = translate_mulh, 5266 .par = (const uint32_t[]){true}, 5267 }, { 5268 .name = "muluh", 5269 .translate = translate_mulh, 5270 .par = (const uint32_t[]){false}, 5271 }, { 5272 .name = "neg", 5273 .translate = translate_neg, 5274 }, { 5275 .name = "nop", 5276 .translate = translate_nop, 5277 }, { 5278 .name = "nop.n", 5279 .translate = translate_nop, 5280 }, { 5281 .name = "nsa", 5282 .translate = translate_nsa, 5283 }, { 5284 .name = "nsau", 5285 .translate = translate_nsau, 5286 }, { 5287 .name = "or", 5288 .translate = translate_or, 5289 }, { 5290 .name = "orb", 5291 .translate = translate_boolean, 5292 .par = (const uint32_t[]){BOOLEAN_OR}, 5293 }, { 5294 .name = "orbc", 5295 .translate = translate_boolean, 5296 .par = (const uint32_t[]){BOOLEAN_ORC}, 5297 }, { 5298 .name = "pdtlb", 5299 .translate = translate_ptlb, 5300 .par = (const uint32_t[]){true}, 5301 }, { 5302 .name = "pitlb", 5303 .translate = translate_ptlb, 5304 .par = (const uint32_t[]){false}, 5305 }, { 5306 .name = "quos", 5307 .translate = translate_quos, 5308 .par = (const uint32_t[]){true}, 5309 }, { 5310 .name = "quou", 5311 .translate = translate_quou, 5312 .par = (const uint32_t[]){true}, 5313 }, { 5314 .name = "rdtlb0", 5315 .translate = translate_rtlb, 5316 .par = (const uint32_t[]){true, 0}, 5317 }, { 5318 .name = "rdtlb1", 5319 .translate = translate_rtlb, 5320 .par = (const uint32_t[]){true, 1}, 5321 }, { 5322 .name = "rems", 5323 .translate = translate_quos, 5324 .par = (const uint32_t[]){false}, 5325 }, { 5326 .name = "remu", 5327 .translate = translate_quou, 5328 .par = (const uint32_t[]){false}, 5329 }, { 5330 .name = "rer", 5331 .translate = translate_rer, 5332 }, { 5333 .name = "ret", 5334 .translate = translate_ret, 5335 }, { 5336 .name = "ret.n", 5337 .translate = translate_ret, 5338 }, { 5339 .name = "retw", 5340 .translate = translate_retw, 5341 }, { 5342 .name = "retw.n", 5343 .translate = translate_retw, 5344 }, { 5345 .name = "rfde", 5346 .translate = translate_rfde, 5347 }, { 5348 .name = "rfe", 5349 .translate = translate_rfe, 5350 }, { 5351 .name = "rfi", 5352 .translate = translate_rfi, 5353 }, { 5354 .name = "rfwo", 5355 .translate = translate_rfw, 5356 .par = (const uint32_t[]){true}, 5357 }, { 5358 .name = "rfwu", 5359 .translate = translate_rfw, 5360 .par = (const uint32_t[]){false}, 5361 }, { 5362 .name = "ritlb0", 5363 .translate = translate_rtlb, 5364 .par = (const uint32_t[]){false, 0}, 5365 }, { 5366 .name = "ritlb1", 5367 .translate = translate_rtlb, 5368 .par = (const uint32_t[]){false, 1}, 5369 }, { 5370 .name = "rotw", 5371 .translate = translate_rotw, 5372 }, { 5373 .name = "rsil", 5374 .translate = translate_rsil, 5375 }, { 5376 .name = "rsr.176", 5377 .translate = translate_rsr, 5378 .par = (const uint32_t[]){176}, 5379 }, { 5380 .name = "rsr.208", 5381 .translate = translate_rsr, 5382 .par = (const uint32_t[]){208}, 5383 }, { 5384 .name = "rsr.acchi", 5385 .translate = translate_rsr, 5386 .par = (const uint32_t[]){ACCHI}, 5387 }, { 5388 .name = "rsr.acclo", 5389 .translate = translate_rsr, 5390 .par = (const uint32_t[]){ACCLO}, 5391 }, { 5392 .name = "rsr.atomctl", 5393 .translate = translate_rsr, 5394 .par = (const uint32_t[]){ATOMCTL}, 5395 }, { 5396 .name = "rsr.br", 5397 .translate = translate_rsr, 5398 .par = (const uint32_t[]){BR}, 5399 }, { 5400 .name = "rsr.cacheattr", 5401 .translate = translate_rsr, 5402 .par = (const uint32_t[]){CACHEATTR}, 5403 }, { 5404 .name = "rsr.ccompare0", 5405 .translate = translate_rsr, 5406 .par = (const uint32_t[]){CCOMPARE}, 5407 }, { 5408 .name = "rsr.ccompare1", 5409 .translate = translate_rsr, 5410 .par = (const uint32_t[]){CCOMPARE + 1}, 5411 }, { 5412 .name = "rsr.ccompare2", 5413 .translate = translate_rsr, 5414 .par = (const uint32_t[]){CCOMPARE + 2}, 5415 }, { 5416 .name = "rsr.ccount", 5417 .translate = translate_rsr, 5418 .par = (const uint32_t[]){CCOUNT}, 5419 }, { 5420 .name = "rsr.configid0", 5421 .translate = translate_rsr, 5422 .par = (const uint32_t[]){CONFIGID0}, 5423 }, { 5424 .name = "rsr.configid1", 5425 .translate = translate_rsr, 5426 .par = (const uint32_t[]){CONFIGID1}, 5427 }, { 5428 .name = "rsr.cpenable", 5429 .translate = translate_rsr, 5430 .par = (const uint32_t[]){CPENABLE}, 5431 }, { 5432 .name = "rsr.dbreaka0", 5433 .translate = translate_rsr, 5434 .par = (const uint32_t[]){DBREAKA}, 5435 }, { 5436 .name = "rsr.dbreaka1", 5437 .translate = translate_rsr, 5438 .par = (const uint32_t[]){DBREAKA + 1}, 5439 }, { 5440 .name = "rsr.dbreakc0", 5441 .translate = translate_rsr, 5442 .par = (const uint32_t[]){DBREAKC}, 5443 }, { 5444 .name = "rsr.dbreakc1", 5445 .translate = translate_rsr, 5446 .par = (const uint32_t[]){DBREAKC + 1}, 5447 }, { 5448 .name = "rsr.debugcause", 5449 .translate = translate_rsr, 5450 .par = (const uint32_t[]){DEBUGCAUSE}, 5451 }, { 5452 .name = "rsr.depc", 5453 .translate = translate_rsr, 5454 .par = (const uint32_t[]){DEPC}, 5455 }, { 5456 .name = "rsr.dtlbcfg", 5457 .translate = translate_rsr, 5458 .par = (const uint32_t[]){DTLBCFG}, 5459 }, { 5460 .name = "rsr.epc1", 5461 .translate = translate_rsr, 5462 .par = (const uint32_t[]){EPC1}, 5463 }, { 5464 .name = "rsr.epc2", 5465 .translate = translate_rsr, 5466 .par = (const uint32_t[]){EPC1 + 1}, 5467 }, { 5468 .name = "rsr.epc3", 5469 .translate = translate_rsr, 5470 .par = (const uint32_t[]){EPC1 + 2}, 5471 }, { 5472 .name = "rsr.epc4", 5473 .translate = translate_rsr, 5474 .par = (const uint32_t[]){EPC1 + 3}, 5475 }, { 5476 .name = "rsr.epc5", 5477 .translate = translate_rsr, 5478 .par = (const uint32_t[]){EPC1 + 4}, 5479 }, { 5480 .name = "rsr.epc6", 5481 .translate = translate_rsr, 5482 .par = (const uint32_t[]){EPC1 + 5}, 5483 }, { 5484 .name = "rsr.epc7", 5485 .translate = translate_rsr, 5486 .par = (const uint32_t[]){EPC1 + 6}, 5487 }, { 5488 .name = "rsr.eps2", 5489 .translate = translate_rsr, 5490 .par = (const uint32_t[]){EPS2}, 5491 }, { 5492 .name = "rsr.eps3", 5493 .translate = translate_rsr, 5494 .par = (const uint32_t[]){EPS2 + 1}, 5495 }, { 5496 .name = "rsr.eps4", 5497 .translate = translate_rsr, 5498 .par = (const uint32_t[]){EPS2 + 2}, 5499 }, { 5500 .name = "rsr.eps5", 5501 .translate = translate_rsr, 5502 .par = (const uint32_t[]){EPS2 + 3}, 5503 }, { 5504 .name = "rsr.eps6", 5505 .translate = translate_rsr, 5506 .par = (const uint32_t[]){EPS2 + 4}, 5507 }, { 5508 .name = "rsr.eps7", 5509 .translate = translate_rsr, 5510 .par = (const uint32_t[]){EPS2 + 5}, 5511 }, { 5512 .name = "rsr.exccause", 5513 .translate = translate_rsr, 5514 .par = (const uint32_t[]){EXCCAUSE}, 5515 }, { 5516 .name = "rsr.excsave1", 5517 .translate = translate_rsr, 5518 .par = (const uint32_t[]){EXCSAVE1}, 5519 }, { 5520 .name = "rsr.excsave2", 5521 .translate = translate_rsr, 5522 .par = (const uint32_t[]){EXCSAVE1 + 1}, 5523 }, { 5524 .name = "rsr.excsave3", 5525 .translate = translate_rsr, 5526 .par = (const uint32_t[]){EXCSAVE1 + 2}, 5527 }, { 5528 .name = "rsr.excsave4", 5529 .translate = translate_rsr, 5530 .par = (const uint32_t[]){EXCSAVE1 + 3}, 5531 }, { 5532 .name = "rsr.excsave5", 5533 .translate = translate_rsr, 5534 .par = (const uint32_t[]){EXCSAVE1 + 4}, 5535 }, { 5536 .name = "rsr.excsave6", 5537 .translate = translate_rsr, 5538 .par = (const uint32_t[]){EXCSAVE1 + 5}, 5539 }, { 5540 .name = "rsr.excsave7", 5541 .translate = translate_rsr, 5542 .par = (const uint32_t[]){EXCSAVE1 + 6}, 5543 }, { 5544 .name = "rsr.excvaddr", 5545 .translate = translate_rsr, 5546 .par = (const uint32_t[]){EXCVADDR}, 5547 }, { 5548 .name = "rsr.ibreaka0", 5549 .translate = translate_rsr, 5550 .par = (const uint32_t[]){IBREAKA}, 5551 }, { 5552 .name = "rsr.ibreaka1", 5553 .translate = translate_rsr, 5554 .par = (const uint32_t[]){IBREAKA + 1}, 5555 }, { 5556 .name = "rsr.ibreakenable", 5557 .translate = translate_rsr, 5558 .par = (const uint32_t[]){IBREAKENABLE}, 5559 }, { 5560 .name = "rsr.icount", 5561 .translate = translate_rsr, 5562 .par = (const uint32_t[]){ICOUNT}, 5563 }, { 5564 .name = "rsr.icountlevel", 5565 .translate = translate_rsr, 5566 .par = (const uint32_t[]){ICOUNTLEVEL}, 5567 }, { 5568 .name = "rsr.intclear", 5569 .translate = translate_rsr, 5570 .par = (const uint32_t[]){INTCLEAR}, 5571 }, { 5572 .name = "rsr.intenable", 5573 .translate = translate_rsr, 5574 .par = (const uint32_t[]){INTENABLE}, 5575 }, { 5576 .name = "rsr.interrupt", 5577 .translate = translate_rsr, 5578 .par = (const uint32_t[]){INTSET}, 5579 }, { 5580 .name = "rsr.intset", 5581 .translate = translate_rsr, 5582 .par = (const uint32_t[]){INTSET}, 5583 }, { 5584 .name = "rsr.itlbcfg", 5585 .translate = translate_rsr, 5586 .par = (const uint32_t[]){ITLBCFG}, 5587 }, { 5588 .name = "rsr.lbeg", 5589 .translate = translate_rsr, 5590 .par = (const uint32_t[]){LBEG}, 5591 }, { 5592 .name = "rsr.lcount", 5593 .translate = translate_rsr, 5594 .par = (const uint32_t[]){LCOUNT}, 5595 }, { 5596 .name = "rsr.lend", 5597 .translate = translate_rsr, 5598 .par = (const uint32_t[]){LEND}, 5599 }, { 5600 .name = "rsr.litbase", 5601 .translate = translate_rsr, 5602 .par = (const uint32_t[]){LITBASE}, 5603 }, { 5604 .name = "rsr.m0", 5605 .translate = translate_rsr, 5606 .par = (const uint32_t[]){MR}, 5607 }, { 5608 .name = "rsr.m1", 5609 .translate = translate_rsr, 5610 .par = (const uint32_t[]){MR + 1}, 5611 }, { 5612 .name = "rsr.m2", 5613 .translate = translate_rsr, 5614 .par = (const uint32_t[]){MR + 2}, 5615 }, { 5616 .name = "rsr.m3", 5617 .translate = translate_rsr, 5618 .par = (const uint32_t[]){MR + 3}, 5619 }, { 5620 .name = "rsr.memctl", 5621 .translate = translate_rsr, 5622 .par = (const uint32_t[]){MEMCTL}, 5623 }, { 5624 .name = "rsr.misc0", 5625 .translate = translate_rsr, 5626 .par = (const uint32_t[]){MISC}, 5627 }, { 5628 .name = "rsr.misc1", 5629 .translate = translate_rsr, 5630 .par = (const uint32_t[]){MISC + 1}, 5631 }, { 5632 .name = "rsr.misc2", 5633 .translate = translate_rsr, 5634 .par = (const uint32_t[]){MISC + 2}, 5635 }, { 5636 .name = "rsr.misc3", 5637 .translate = translate_rsr, 5638 .par = (const uint32_t[]){MISC + 3}, 5639 }, { 5640 .name = "rsr.prid", 5641 .translate = translate_rsr, 5642 .par = (const uint32_t[]){PRID}, 5643 }, { 5644 .name = "rsr.ps", 5645 .translate = translate_rsr, 5646 .par = (const uint32_t[]){PS}, 5647 }, { 5648 .name = "rsr.ptevaddr", 5649 .translate = translate_rsr, 5650 .par = (const uint32_t[]){PTEVADDR}, 5651 }, { 5652 .name = "rsr.rasid", 5653 .translate = translate_rsr, 5654 .par = (const uint32_t[]){RASID}, 5655 }, { 5656 .name = "rsr.sar", 5657 .translate = translate_rsr, 5658 .par = (const uint32_t[]){SAR}, 5659 }, { 5660 .name = "rsr.scompare1", 5661 .translate = translate_rsr, 5662 .par = (const uint32_t[]){SCOMPARE1}, 5663 }, { 5664 .name = "rsr.vecbase", 5665 .translate = translate_rsr, 5666 .par = (const uint32_t[]){VECBASE}, 5667 }, { 5668 .name = "rsr.windowbase", 5669 .translate = translate_rsr, 5670 .par = (const uint32_t[]){WINDOW_BASE}, 5671 }, { 5672 .name = "rsr.windowstart", 5673 .translate = translate_rsr, 5674 .par = (const uint32_t[]){WINDOW_START}, 5675 }, { 5676 .name = "rsync", 5677 .translate = translate_nop, 5678 }, { 5679 .name = "rur.fcr", 5680 .translate = translate_rur, 5681 .par = (const uint32_t[]){FCR}, 5682 }, { 5683 .name = "rur.fsr", 5684 .translate = translate_rur, 5685 .par = (const uint32_t[]){FSR}, 5686 }, { 5687 .name = "rur.threadptr", 5688 .translate = translate_rur, 5689 .par = (const uint32_t[]){THREADPTR}, 5690 }, { 5691 .name = "s16i", 5692 .translate = translate_ldst, 5693 .par = (const uint32_t[]){MO_TEUW, false, true}, 5694 }, { 5695 .name = "s32c1i", 5696 .translate = translate_s32c1i, 5697 }, { 5698 .name = "s32e", 5699 .translate = translate_s32e, 5700 }, { 5701 .name = "s32i", 5702 .translate = translate_ldst, 5703 .par = (const uint32_t[]){MO_TEUL, false, true}, 5704 }, { 5705 .name = "s32i.n", 5706 .translate = translate_ldst, 5707 .par = (const uint32_t[]){MO_TEUL, false, true}, 5708 }, { 5709 .name = "s32nb", 5710 .translate = translate_ldst, 5711 .par = (const uint32_t[]){MO_TEUL, false, true}, 5712 }, { 5713 .name = "s32ri", 5714 .translate = translate_ldst, 5715 .par = (const uint32_t[]){MO_TEUL, true, true}, 5716 }, { 5717 .name = "s8i", 5718 .translate = translate_ldst, 5719 .par = (const uint32_t[]){MO_UB, false, true}, 5720 }, { 5721 .name = "sext", 5722 .translate = translate_sext, 5723 }, { 5724 .name = "simcall", 5725 .translate = translate_simcall, 5726 }, { 5727 .name = "sll", 5728 .translate = translate_sll, 5729 }, { 5730 .name = "slli", 5731 .translate = translate_slli, 5732 }, { 5733 .name = "sra", 5734 .translate = translate_sra, 5735 }, { 5736 .name = "srai", 5737 .translate = translate_srai, 5738 }, { 5739 .name = "src", 5740 .translate = translate_src, 5741 }, { 5742 .name = "srl", 5743 .translate = translate_srl, 5744 }, { 5745 .name = "srli", 5746 .translate = translate_srli, 5747 }, { 5748 .name = "ssa8b", 5749 .translate = translate_ssa8b, 5750 }, { 5751 .name = "ssa8l", 5752 .translate = translate_ssa8l, 5753 }, { 5754 .name = "ssai", 5755 .translate = translate_ssai, 5756 }, { 5757 .name = "ssl", 5758 .translate = translate_ssl, 5759 }, { 5760 .name = "ssr", 5761 .translate = translate_ssr, 5762 }, { 5763 .name = "sub", 5764 .translate = translate_sub, 5765 }, { 5766 .name = "subx2", 5767 .translate = translate_subx, 5768 .par = (const uint32_t[]){1}, 5769 }, { 5770 .name = "subx4", 5771 .translate = translate_subx, 5772 .par = (const uint32_t[]){2}, 5773 }, { 5774 .name = "subx8", 5775 .translate = translate_subx, 5776 .par = (const uint32_t[]){3}, 5777 }, { 5778 .name = "syscall", 5779 .translate = translate_syscall, 5780 }, { 5781 .name = "umul.aa.hh", 5782 .translate = translate_mac16, 5783 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HH, 0}, 5784 }, { 5785 .name = "umul.aa.hl", 5786 .translate = translate_mac16, 5787 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HL, 0}, 5788 }, { 5789 .name = "umul.aa.lh", 5790 .translate = translate_mac16, 5791 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LH, 0}, 5792 }, { 5793 .name = "umul.aa.ll", 5794 .translate = translate_mac16, 5795 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LL, 0}, 5796 }, { 5797 .name = "waiti", 5798 .translate = translate_waiti, 5799 }, { 5800 .name = "wdtlb", 5801 .translate = translate_wtlb, 5802 .par = (const uint32_t[]){true}, 5803 }, { 5804 .name = "wer", 5805 .translate = translate_wer, 5806 }, { 5807 .name = "witlb", 5808 .translate = translate_wtlb, 5809 .par = (const uint32_t[]){false}, 5810 }, { 5811 .name = "wsr.176", 5812 .translate = translate_wsr, 5813 .par = (const uint32_t[]){176}, 5814 }, { 5815 .name = "wsr.208", 5816 .translate = translate_wsr, 5817 .par = (const uint32_t[]){208}, 5818 }, { 5819 .name = "wsr.acchi", 5820 .translate = translate_wsr, 5821 .par = (const uint32_t[]){ACCHI}, 5822 }, { 5823 .name = "wsr.acclo", 5824 .translate = translate_wsr, 5825 .par = (const uint32_t[]){ACCLO}, 5826 }, { 5827 .name = "wsr.atomctl", 5828 .translate = translate_wsr, 5829 .par = (const uint32_t[]){ATOMCTL}, 5830 }, { 5831 .name = "wsr.br", 5832 .translate = translate_wsr, 5833 .par = (const uint32_t[]){BR}, 5834 }, { 5835 .name = "wsr.cacheattr", 5836 .translate = translate_wsr, 5837 .par = (const uint32_t[]){CACHEATTR}, 5838 }, { 5839 .name = "wsr.ccompare0", 5840 .translate = translate_wsr, 5841 .par = (const uint32_t[]){CCOMPARE}, 5842 }, { 5843 .name = "wsr.ccompare1", 5844 .translate = translate_wsr, 5845 .par = (const uint32_t[]){CCOMPARE + 1}, 5846 }, { 5847 .name = "wsr.ccompare2", 5848 .translate = translate_wsr, 5849 .par = (const uint32_t[]){CCOMPARE + 2}, 5850 }, { 5851 .name = "wsr.ccount", 5852 .translate = translate_wsr, 5853 .par = (const uint32_t[]){CCOUNT}, 5854 }, { 5855 .name = "wsr.configid0", 5856 .translate = translate_wsr, 5857 .par = (const uint32_t[]){CONFIGID0}, 5858 }, { 5859 .name = "wsr.configid1", 5860 .translate = translate_wsr, 5861 .par = (const uint32_t[]){CONFIGID1}, 5862 }, { 5863 .name = "wsr.cpenable", 5864 .translate = translate_wsr, 5865 .par = (const uint32_t[]){CPENABLE}, 5866 }, { 5867 .name = "wsr.dbreaka0", 5868 .translate = translate_wsr, 5869 .par = (const uint32_t[]){DBREAKA}, 5870 }, { 5871 .name = "wsr.dbreaka1", 5872 .translate = translate_wsr, 5873 .par = (const uint32_t[]){DBREAKA + 1}, 5874 }, { 5875 .name = "wsr.dbreakc0", 5876 .translate = translate_wsr, 5877 .par = (const uint32_t[]){DBREAKC}, 5878 }, { 5879 .name = "wsr.dbreakc1", 5880 .translate = translate_wsr, 5881 .par = (const uint32_t[]){DBREAKC + 1}, 5882 }, { 5883 .name = "wsr.debugcause", 5884 .translate = translate_wsr, 5885 .par = (const uint32_t[]){DEBUGCAUSE}, 5886 }, { 5887 .name = "wsr.depc", 5888 .translate = translate_wsr, 5889 .par = (const uint32_t[]){DEPC}, 5890 }, { 5891 .name = "wsr.dtlbcfg", 5892 .translate = translate_wsr, 5893 .par = (const uint32_t[]){DTLBCFG}, 5894 }, { 5895 .name = "wsr.epc1", 5896 .translate = translate_wsr, 5897 .par = (const uint32_t[]){EPC1}, 5898 }, { 5899 .name = "wsr.epc2", 5900 .translate = translate_wsr, 5901 .par = (const uint32_t[]){EPC1 + 1}, 5902 }, { 5903 .name = "wsr.epc3", 5904 .translate = translate_wsr, 5905 .par = (const uint32_t[]){EPC1 + 2}, 5906 }, { 5907 .name = "wsr.epc4", 5908 .translate = translate_wsr, 5909 .par = (const uint32_t[]){EPC1 + 3}, 5910 }, { 5911 .name = "wsr.epc5", 5912 .translate = translate_wsr, 5913 .par = (const uint32_t[]){EPC1 + 4}, 5914 }, { 5915 .name = "wsr.epc6", 5916 .translate = translate_wsr, 5917 .par = (const uint32_t[]){EPC1 + 5}, 5918 }, { 5919 .name = "wsr.epc7", 5920 .translate = translate_wsr, 5921 .par = (const uint32_t[]){EPC1 + 6}, 5922 }, { 5923 .name = "wsr.eps2", 5924 .translate = translate_wsr, 5925 .par = (const uint32_t[]){EPS2}, 5926 }, { 5927 .name = "wsr.eps3", 5928 .translate = translate_wsr, 5929 .par = (const uint32_t[]){EPS2 + 1}, 5930 }, { 5931 .name = "wsr.eps4", 5932 .translate = translate_wsr, 5933 .par = (const uint32_t[]){EPS2 + 2}, 5934 }, { 5935 .name = "wsr.eps5", 5936 .translate = translate_wsr, 5937 .par = (const uint32_t[]){EPS2 + 3}, 5938 }, { 5939 .name = "wsr.eps6", 5940 .translate = translate_wsr, 5941 .par = (const uint32_t[]){EPS2 + 4}, 5942 }, { 5943 .name = "wsr.eps7", 5944 .translate = translate_wsr, 5945 .par = (const uint32_t[]){EPS2 + 5}, 5946 }, { 5947 .name = "wsr.exccause", 5948 .translate = translate_wsr, 5949 .par = (const uint32_t[]){EXCCAUSE}, 5950 }, { 5951 .name = "wsr.excsave1", 5952 .translate = translate_wsr, 5953 .par = (const uint32_t[]){EXCSAVE1}, 5954 }, { 5955 .name = "wsr.excsave2", 5956 .translate = translate_wsr, 5957 .par = (const uint32_t[]){EXCSAVE1 + 1}, 5958 }, { 5959 .name = "wsr.excsave3", 5960 .translate = translate_wsr, 5961 .par = (const uint32_t[]){EXCSAVE1 + 2}, 5962 }, { 5963 .name = "wsr.excsave4", 5964 .translate = translate_wsr, 5965 .par = (const uint32_t[]){EXCSAVE1 + 3}, 5966 }, { 5967 .name = "wsr.excsave5", 5968 .translate = translate_wsr, 5969 .par = (const uint32_t[]){EXCSAVE1 + 4}, 5970 }, { 5971 .name = "wsr.excsave6", 5972 .translate = translate_wsr, 5973 .par = (const uint32_t[]){EXCSAVE1 + 5}, 5974 }, { 5975 .name = "wsr.excsave7", 5976 .translate = translate_wsr, 5977 .par = (const uint32_t[]){EXCSAVE1 + 6}, 5978 }, { 5979 .name = "wsr.excvaddr", 5980 .translate = translate_wsr, 5981 .par = (const uint32_t[]){EXCVADDR}, 5982 }, { 5983 .name = "wsr.ibreaka0", 5984 .translate = translate_wsr, 5985 .par = (const uint32_t[]){IBREAKA}, 5986 }, { 5987 .name = "wsr.ibreaka1", 5988 .translate = translate_wsr, 5989 .par = (const uint32_t[]){IBREAKA + 1}, 5990 }, { 5991 .name = "wsr.ibreakenable", 5992 .translate = translate_wsr, 5993 .par = (const uint32_t[]){IBREAKENABLE}, 5994 }, { 5995 .name = "wsr.icount", 5996 .translate = translate_wsr, 5997 .par = (const uint32_t[]){ICOUNT}, 5998 }, { 5999 .name = "wsr.icountlevel", 6000 .translate = translate_wsr, 6001 .par = (const uint32_t[]){ICOUNTLEVEL}, 6002 }, { 6003 .name = "wsr.intclear", 6004 .translate = translate_wsr, 6005 .par = (const uint32_t[]){INTCLEAR}, 6006 }, { 6007 .name = "wsr.intenable", 6008 .translate = translate_wsr, 6009 .par = (const uint32_t[]){INTENABLE}, 6010 }, { 6011 .name = "wsr.interrupt", 6012 .translate = translate_wsr, 6013 .par = (const uint32_t[]){INTSET}, 6014 }, { 6015 .name = "wsr.intset", 6016 .translate = translate_wsr, 6017 .par = (const uint32_t[]){INTSET}, 6018 }, { 6019 .name = "wsr.itlbcfg", 6020 .translate = translate_wsr, 6021 .par = (const uint32_t[]){ITLBCFG}, 6022 }, { 6023 .name = "wsr.lbeg", 6024 .translate = translate_wsr, 6025 .par = (const uint32_t[]){LBEG}, 6026 }, { 6027 .name = "wsr.lcount", 6028 .translate = translate_wsr, 6029 .par = (const uint32_t[]){LCOUNT}, 6030 }, { 6031 .name = "wsr.lend", 6032 .translate = translate_wsr, 6033 .par = (const uint32_t[]){LEND}, 6034 }, { 6035 .name = "wsr.litbase", 6036 .translate = translate_wsr, 6037 .par = (const uint32_t[]){LITBASE}, 6038 }, { 6039 .name = "wsr.m0", 6040 .translate = translate_wsr, 6041 .par = (const uint32_t[]){MR}, 6042 }, { 6043 .name = "wsr.m1", 6044 .translate = translate_wsr, 6045 .par = (const uint32_t[]){MR + 1}, 6046 }, { 6047 .name = "wsr.m2", 6048 .translate = translate_wsr, 6049 .par = (const uint32_t[]){MR + 2}, 6050 }, { 6051 .name = "wsr.m3", 6052 .translate = translate_wsr, 6053 .par = (const uint32_t[]){MR + 3}, 6054 }, { 6055 .name = "wsr.memctl", 6056 .translate = translate_wsr, 6057 .par = (const uint32_t[]){MEMCTL}, 6058 }, { 6059 .name = "wsr.misc0", 6060 .translate = translate_wsr, 6061 .par = (const uint32_t[]){MISC}, 6062 }, { 6063 .name = "wsr.misc1", 6064 .translate = translate_wsr, 6065 .par = (const uint32_t[]){MISC + 1}, 6066 }, { 6067 .name = "wsr.misc2", 6068 .translate = translate_wsr, 6069 .par = (const uint32_t[]){MISC + 2}, 6070 }, { 6071 .name = "wsr.misc3", 6072 .translate = translate_wsr, 6073 .par = (const uint32_t[]){MISC + 3}, 6074 }, { 6075 .name = "wsr.prid", 6076 .translate = translate_wsr, 6077 .par = (const uint32_t[]){PRID}, 6078 }, { 6079 .name = "wsr.ps", 6080 .translate = translate_wsr, 6081 .par = (const uint32_t[]){PS}, 6082 }, { 6083 .name = "wsr.ptevaddr", 6084 .translate = translate_wsr, 6085 .par = (const uint32_t[]){PTEVADDR}, 6086 }, { 6087 .name = "wsr.rasid", 6088 .translate = translate_wsr, 6089 .par = (const uint32_t[]){RASID}, 6090 }, { 6091 .name = "wsr.sar", 6092 .translate = translate_wsr, 6093 .par = (const uint32_t[]){SAR}, 6094 }, { 6095 .name = "wsr.scompare1", 6096 .translate = translate_wsr, 6097 .par = (const uint32_t[]){SCOMPARE1}, 6098 }, { 6099 .name = "wsr.vecbase", 6100 .translate = translate_wsr, 6101 .par = (const uint32_t[]){VECBASE}, 6102 }, { 6103 .name = "wsr.windowbase", 6104 .translate = translate_wsr, 6105 .par = (const uint32_t[]){WINDOW_BASE}, 6106 }, { 6107 .name = "wsr.windowstart", 6108 .translate = translate_wsr, 6109 .par = (const uint32_t[]){WINDOW_START}, 6110 }, { 6111 .name = "wur.fcr", 6112 .translate = translate_wur, 6113 .par = (const uint32_t[]){FCR}, 6114 }, { 6115 .name = "wur.fsr", 6116 .translate = translate_wur, 6117 .par = (const uint32_t[]){FSR}, 6118 }, { 6119 .name = "wur.threadptr", 6120 .translate = translate_wur, 6121 .par = (const uint32_t[]){THREADPTR}, 6122 }, { 6123 .name = "xor", 6124 .translate = translate_xor, 6125 }, { 6126 .name = "xorb", 6127 .translate = translate_boolean, 6128 .par = (const uint32_t[]){BOOLEAN_XOR}, 6129 }, { 6130 .name = "xsr.176", 6131 .translate = translate_xsr, 6132 .par = (const uint32_t[]){176}, 6133 }, { 6134 .name = "xsr.208", 6135 .translate = translate_xsr, 6136 .par = (const uint32_t[]){208}, 6137 }, { 6138 .name = "xsr.acchi", 6139 .translate = translate_xsr, 6140 .par = (const uint32_t[]){ACCHI}, 6141 }, { 6142 .name = "xsr.acclo", 6143 .translate = translate_xsr, 6144 .par = (const uint32_t[]){ACCLO}, 6145 }, { 6146 .name = "xsr.atomctl", 6147 .translate = translate_xsr, 6148 .par = (const uint32_t[]){ATOMCTL}, 6149 }, { 6150 .name = "xsr.br", 6151 .translate = translate_xsr, 6152 .par = (const uint32_t[]){BR}, 6153 }, { 6154 .name = "xsr.cacheattr", 6155 .translate = translate_xsr, 6156 .par = (const uint32_t[]){CACHEATTR}, 6157 }, { 6158 .name = "xsr.ccompare0", 6159 .translate = translate_xsr, 6160 .par = (const uint32_t[]){CCOMPARE}, 6161 }, { 6162 .name = "xsr.ccompare1", 6163 .translate = translate_xsr, 6164 .par = (const uint32_t[]){CCOMPARE + 1}, 6165 }, { 6166 .name = "xsr.ccompare2", 6167 .translate = translate_xsr, 6168 .par = (const uint32_t[]){CCOMPARE + 2}, 6169 }, { 6170 .name = "xsr.ccount", 6171 .translate = translate_xsr, 6172 .par = (const uint32_t[]){CCOUNT}, 6173 }, { 6174 .name = "xsr.configid0", 6175 .translate = translate_xsr, 6176 .par = (const uint32_t[]){CONFIGID0}, 6177 }, { 6178 .name = "xsr.configid1", 6179 .translate = translate_xsr, 6180 .par = (const uint32_t[]){CONFIGID1}, 6181 }, { 6182 .name = "xsr.cpenable", 6183 .translate = translate_xsr, 6184 .par = (const uint32_t[]){CPENABLE}, 6185 }, { 6186 .name = "xsr.dbreaka0", 6187 .translate = translate_xsr, 6188 .par = (const uint32_t[]){DBREAKA}, 6189 }, { 6190 .name = "xsr.dbreaka1", 6191 .translate = translate_xsr, 6192 .par = (const uint32_t[]){DBREAKA + 1}, 6193 }, { 6194 .name = "xsr.dbreakc0", 6195 .translate = translate_xsr, 6196 .par = (const uint32_t[]){DBREAKC}, 6197 }, { 6198 .name = "xsr.dbreakc1", 6199 .translate = translate_xsr, 6200 .par = (const uint32_t[]){DBREAKC + 1}, 6201 }, { 6202 .name = "xsr.debugcause", 6203 .translate = translate_xsr, 6204 .par = (const uint32_t[]){DEBUGCAUSE}, 6205 }, { 6206 .name = "xsr.depc", 6207 .translate = translate_xsr, 6208 .par = (const uint32_t[]){DEPC}, 6209 }, { 6210 .name = "xsr.dtlbcfg", 6211 .translate = translate_xsr, 6212 .par = (const uint32_t[]){DTLBCFG}, 6213 }, { 6214 .name = "xsr.epc1", 6215 .translate = translate_xsr, 6216 .par = (const uint32_t[]){EPC1}, 6217 }, { 6218 .name = "xsr.epc2", 6219 .translate = translate_xsr, 6220 .par = (const uint32_t[]){EPC1 + 1}, 6221 }, { 6222 .name = "xsr.epc3", 6223 .translate = translate_xsr, 6224 .par = (const uint32_t[]){EPC1 + 2}, 6225 }, { 6226 .name = "xsr.epc4", 6227 .translate = translate_xsr, 6228 .par = (const uint32_t[]){EPC1 + 3}, 6229 }, { 6230 .name = "xsr.epc5", 6231 .translate = translate_xsr, 6232 .par = (const uint32_t[]){EPC1 + 4}, 6233 }, { 6234 .name = "xsr.epc6", 6235 .translate = translate_xsr, 6236 .par = (const uint32_t[]){EPC1 + 5}, 6237 }, { 6238 .name = "xsr.epc7", 6239 .translate = translate_xsr, 6240 .par = (const uint32_t[]){EPC1 + 6}, 6241 }, { 6242 .name = "xsr.eps2", 6243 .translate = translate_xsr, 6244 .par = (const uint32_t[]){EPS2}, 6245 }, { 6246 .name = "xsr.eps3", 6247 .translate = translate_xsr, 6248 .par = (const uint32_t[]){EPS2 + 1}, 6249 }, { 6250 .name = "xsr.eps4", 6251 .translate = translate_xsr, 6252 .par = (const uint32_t[]){EPS2 + 2}, 6253 }, { 6254 .name = "xsr.eps5", 6255 .translate = translate_xsr, 6256 .par = (const uint32_t[]){EPS2 + 3}, 6257 }, { 6258 .name = "xsr.eps6", 6259 .translate = translate_xsr, 6260 .par = (const uint32_t[]){EPS2 + 4}, 6261 }, { 6262 .name = "xsr.eps7", 6263 .translate = translate_xsr, 6264 .par = (const uint32_t[]){EPS2 + 5}, 6265 }, { 6266 .name = "xsr.exccause", 6267 .translate = translate_xsr, 6268 .par = (const uint32_t[]){EXCCAUSE}, 6269 }, { 6270 .name = "xsr.excsave1", 6271 .translate = translate_xsr, 6272 .par = (const uint32_t[]){EXCSAVE1}, 6273 }, { 6274 .name = "xsr.excsave2", 6275 .translate = translate_xsr, 6276 .par = (const uint32_t[]){EXCSAVE1 + 1}, 6277 }, { 6278 .name = "xsr.excsave3", 6279 .translate = translate_xsr, 6280 .par = (const uint32_t[]){EXCSAVE1 + 2}, 6281 }, { 6282 .name = "xsr.excsave4", 6283 .translate = translate_xsr, 6284 .par = (const uint32_t[]){EXCSAVE1 + 3}, 6285 }, { 6286 .name = "xsr.excsave5", 6287 .translate = translate_xsr, 6288 .par = (const uint32_t[]){EXCSAVE1 + 4}, 6289 }, { 6290 .name = "xsr.excsave6", 6291 .translate = translate_xsr, 6292 .par = (const uint32_t[]){EXCSAVE1 + 5}, 6293 }, { 6294 .name = "xsr.excsave7", 6295 .translate = translate_xsr, 6296 .par = (const uint32_t[]){EXCSAVE1 + 6}, 6297 }, { 6298 .name = "xsr.excvaddr", 6299 .translate = translate_xsr, 6300 .par = (const uint32_t[]){EXCVADDR}, 6301 }, { 6302 .name = "xsr.ibreaka0", 6303 .translate = translate_xsr, 6304 .par = (const uint32_t[]){IBREAKA}, 6305 }, { 6306 .name = "xsr.ibreaka1", 6307 .translate = translate_xsr, 6308 .par = (const uint32_t[]){IBREAKA + 1}, 6309 }, { 6310 .name = "xsr.ibreakenable", 6311 .translate = translate_xsr, 6312 .par = (const uint32_t[]){IBREAKENABLE}, 6313 }, { 6314 .name = "xsr.icount", 6315 .translate = translate_xsr, 6316 .par = (const uint32_t[]){ICOUNT}, 6317 }, { 6318 .name = "xsr.icountlevel", 6319 .translate = translate_xsr, 6320 .par = (const uint32_t[]){ICOUNTLEVEL}, 6321 }, { 6322 .name = "xsr.intclear", 6323 .translate = translate_xsr, 6324 .par = (const uint32_t[]){INTCLEAR}, 6325 }, { 6326 .name = "xsr.intenable", 6327 .translate = translate_xsr, 6328 .par = (const uint32_t[]){INTENABLE}, 6329 }, { 6330 .name = "xsr.interrupt", 6331 .translate = translate_xsr, 6332 .par = (const uint32_t[]){INTSET}, 6333 }, { 6334 .name = "xsr.intset", 6335 .translate = translate_xsr, 6336 .par = (const uint32_t[]){INTSET}, 6337 }, { 6338 .name = "xsr.itlbcfg", 6339 .translate = translate_xsr, 6340 .par = (const uint32_t[]){ITLBCFG}, 6341 }, { 6342 .name = "xsr.lbeg", 6343 .translate = translate_xsr, 6344 .par = (const uint32_t[]){LBEG}, 6345 }, { 6346 .name = "xsr.lcount", 6347 .translate = translate_xsr, 6348 .par = (const uint32_t[]){LCOUNT}, 6349 }, { 6350 .name = "xsr.lend", 6351 .translate = translate_xsr, 6352 .par = (const uint32_t[]){LEND}, 6353 }, { 6354 .name = "xsr.litbase", 6355 .translate = translate_xsr, 6356 .par = (const uint32_t[]){LITBASE}, 6357 }, { 6358 .name = "xsr.m0", 6359 .translate = translate_xsr, 6360 .par = (const uint32_t[]){MR}, 6361 }, { 6362 .name = "xsr.m1", 6363 .translate = translate_xsr, 6364 .par = (const uint32_t[]){MR + 1}, 6365 }, { 6366 .name = "xsr.m2", 6367 .translate = translate_xsr, 6368 .par = (const uint32_t[]){MR + 2}, 6369 }, { 6370 .name = "xsr.m3", 6371 .translate = translate_xsr, 6372 .par = (const uint32_t[]){MR + 3}, 6373 }, { 6374 .name = "xsr.memctl", 6375 .translate = translate_xsr, 6376 .par = (const uint32_t[]){MEMCTL}, 6377 }, { 6378 .name = "xsr.misc0", 6379 .translate = translate_xsr, 6380 .par = (const uint32_t[]){MISC}, 6381 }, { 6382 .name = "xsr.misc1", 6383 .translate = translate_xsr, 6384 .par = (const uint32_t[]){MISC + 1}, 6385 }, { 6386 .name = "xsr.misc2", 6387 .translate = translate_xsr, 6388 .par = (const uint32_t[]){MISC + 2}, 6389 }, { 6390 .name = "xsr.misc3", 6391 .translate = translate_xsr, 6392 .par = (const uint32_t[]){MISC + 3}, 6393 }, { 6394 .name = "xsr.prid", 6395 .translate = translate_xsr, 6396 .par = (const uint32_t[]){PRID}, 6397 }, { 6398 .name = "xsr.ps", 6399 .translate = translate_xsr, 6400 .par = (const uint32_t[]){PS}, 6401 }, { 6402 .name = "xsr.ptevaddr", 6403 .translate = translate_xsr, 6404 .par = (const uint32_t[]){PTEVADDR}, 6405 }, { 6406 .name = "xsr.rasid", 6407 .translate = translate_xsr, 6408 .par = (const uint32_t[]){RASID}, 6409 }, { 6410 .name = "xsr.sar", 6411 .translate = translate_xsr, 6412 .par = (const uint32_t[]){SAR}, 6413 }, { 6414 .name = "xsr.scompare1", 6415 .translate = translate_xsr, 6416 .par = (const uint32_t[]){SCOMPARE1}, 6417 }, { 6418 .name = "xsr.vecbase", 6419 .translate = translate_xsr, 6420 .par = (const uint32_t[]){VECBASE}, 6421 }, { 6422 .name = "xsr.windowbase", 6423 .translate = translate_xsr, 6424 .par = (const uint32_t[]){WINDOW_BASE}, 6425 }, { 6426 .name = "xsr.windowstart", 6427 .translate = translate_xsr, 6428 .par = (const uint32_t[]){WINDOW_START}, 6429 }, 6430 }; 6431 6432 const XtensaOpcodeTranslators xtensa_core_opcodes = { 6433 .num_opcodes = ARRAY_SIZE(core_ops), 6434 .opcode = core_ops, 6435 }; 6436 6437 6438 static void translate_abs_s(DisasContext *dc, const uint32_t arg[], 6439 const uint32_t par[]) 6440 { 6441 if (gen_check_cpenable(dc, 0)) { 6442 gen_helper_abs_s(cpu_FR[arg[0]], cpu_FR[arg[1]]); 6443 } 6444 } 6445 6446 static void translate_add_s(DisasContext *dc, const uint32_t arg[], 6447 const uint32_t par[]) 6448 { 6449 if (gen_check_cpenable(dc, 0)) { 6450 gen_helper_add_s(cpu_FR[arg[0]], cpu_env, 6451 cpu_FR[arg[1]], cpu_FR[arg[2]]); 6452 } 6453 } 6454 6455 enum { 6456 COMPARE_UN, 6457 COMPARE_OEQ, 6458 COMPARE_UEQ, 6459 COMPARE_OLT, 6460 COMPARE_ULT, 6461 COMPARE_OLE, 6462 COMPARE_ULE, 6463 }; 6464 6465 static void translate_compare_s(DisasContext *dc, const uint32_t arg[], 6466 const uint32_t par[]) 6467 { 6468 static void (* const helper[])(TCGv_env env, TCGv_i32 bit, 6469 TCGv_i32 s, TCGv_i32 t) = { 6470 [COMPARE_UN] = gen_helper_un_s, 6471 [COMPARE_OEQ] = gen_helper_oeq_s, 6472 [COMPARE_UEQ] = gen_helper_ueq_s, 6473 [COMPARE_OLT] = gen_helper_olt_s, 6474 [COMPARE_ULT] = gen_helper_ult_s, 6475 [COMPARE_OLE] = gen_helper_ole_s, 6476 [COMPARE_ULE] = gen_helper_ule_s, 6477 }; 6478 6479 if (gen_check_cpenable(dc, 0)) { 6480 TCGv_i32 bit = tcg_const_i32(1 << arg[0]); 6481 6482 helper[par[0]](cpu_env, bit, cpu_FR[arg[1]], cpu_FR[arg[2]]); 6483 tcg_temp_free(bit); 6484 } 6485 } 6486 6487 static void translate_float_s(DisasContext *dc, const uint32_t arg[], 6488 const uint32_t par[]) 6489 { 6490 if (gen_window_check1(dc, arg[1]) && gen_check_cpenable(dc, 0)) { 6491 TCGv_i32 scale = tcg_const_i32(-arg[2]); 6492 6493 if (par[0]) { 6494 gen_helper_uitof(cpu_FR[arg[0]], cpu_env, cpu_R[arg[1]], scale); 6495 } else { 6496 gen_helper_itof(cpu_FR[arg[0]], cpu_env, cpu_R[arg[1]], scale); 6497 } 6498 tcg_temp_free(scale); 6499 } 6500 } 6501 6502 static void translate_ftoi_s(DisasContext *dc, const uint32_t arg[], 6503 const uint32_t par[]) 6504 { 6505 if (gen_window_check1(dc, arg[0]) && gen_check_cpenable(dc, 0)) { 6506 TCGv_i32 rounding_mode = tcg_const_i32(par[0]); 6507 TCGv_i32 scale = tcg_const_i32(arg[2]); 6508 6509 if (par[1]) { 6510 gen_helper_ftoui(cpu_R[arg[0]], cpu_FR[arg[1]], 6511 rounding_mode, scale); 6512 } else { 6513 gen_helper_ftoi(cpu_R[arg[0]], cpu_FR[arg[1]], 6514 rounding_mode, scale); 6515 } 6516 tcg_temp_free(rounding_mode); 6517 tcg_temp_free(scale); 6518 } 6519 } 6520 6521 static void translate_ldsti(DisasContext *dc, const uint32_t arg[], 6522 const uint32_t par[]) 6523 { 6524 if (gen_window_check1(dc, arg[1]) && gen_check_cpenable(dc, 0)) { 6525 TCGv_i32 addr = tcg_temp_new_i32(); 6526 6527 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]); 6528 gen_load_store_alignment(dc, 2, addr, false); 6529 if (par[0]) { 6530 tcg_gen_qemu_st32(cpu_FR[arg[0]], addr, dc->cring); 6531 } else { 6532 tcg_gen_qemu_ld32u(cpu_FR[arg[0]], addr, dc->cring); 6533 } 6534 if (par[1]) { 6535 tcg_gen_mov_i32(cpu_R[arg[1]], addr); 6536 } 6537 tcg_temp_free(addr); 6538 } 6539 } 6540 6541 static void translate_ldstx(DisasContext *dc, const uint32_t arg[], 6542 const uint32_t par[]) 6543 { 6544 if (gen_window_check2(dc, arg[1], arg[2]) && gen_check_cpenable(dc, 0)) { 6545 TCGv_i32 addr = tcg_temp_new_i32(); 6546 6547 tcg_gen_add_i32(addr, cpu_R[arg[1]], cpu_R[arg[2]]); 6548 gen_load_store_alignment(dc, 2, addr, false); 6549 if (par[0]) { 6550 tcg_gen_qemu_st32(cpu_FR[arg[0]], addr, dc->cring); 6551 } else { 6552 tcg_gen_qemu_ld32u(cpu_FR[arg[0]], addr, dc->cring); 6553 } 6554 if (par[1]) { 6555 tcg_gen_mov_i32(cpu_R[arg[1]], addr); 6556 } 6557 tcg_temp_free(addr); 6558 } 6559 } 6560 6561 static void translate_madd_s(DisasContext *dc, const uint32_t arg[], 6562 const uint32_t par[]) 6563 { 6564 if (gen_check_cpenable(dc, 0)) { 6565 gen_helper_madd_s(cpu_FR[arg[0]], cpu_env, 6566 cpu_FR[arg[0]], cpu_FR[arg[1]], cpu_FR[arg[2]]); 6567 } 6568 } 6569 6570 static void translate_mov_s(DisasContext *dc, const uint32_t arg[], 6571 const uint32_t par[]) 6572 { 6573 if (gen_check_cpenable(dc, 0)) { 6574 tcg_gen_mov_i32(cpu_FR[arg[0]], cpu_FR[arg[1]]); 6575 } 6576 } 6577 6578 static void translate_movcond_s(DisasContext *dc, const uint32_t arg[], 6579 const uint32_t par[]) 6580 { 6581 if (gen_window_check1(dc, arg[2]) && gen_check_cpenable(dc, 0)) { 6582 TCGv_i32 zero = tcg_const_i32(0); 6583 6584 tcg_gen_movcond_i32(par[0], cpu_FR[arg[0]], 6585 cpu_R[arg[2]], zero, 6586 cpu_FR[arg[1]], cpu_FR[arg[2]]); 6587 tcg_temp_free(zero); 6588 } 6589 } 6590 6591 static void translate_movp_s(DisasContext *dc, const uint32_t arg[], 6592 const uint32_t par[]) 6593 { 6594 if (gen_check_cpenable(dc, 0)) { 6595 TCGv_i32 zero = tcg_const_i32(0); 6596 TCGv_i32 tmp = tcg_temp_new_i32(); 6597 6598 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]); 6599 tcg_gen_movcond_i32(par[0], 6600 cpu_FR[arg[0]], tmp, zero, 6601 cpu_FR[arg[1]], cpu_FR[arg[0]]); 6602 tcg_temp_free(tmp); 6603 tcg_temp_free(zero); 6604 } 6605 } 6606 6607 static void translate_mul_s(DisasContext *dc, const uint32_t arg[], 6608 const uint32_t par[]) 6609 { 6610 if (gen_check_cpenable(dc, 0)) { 6611 gen_helper_mul_s(cpu_FR[arg[0]], cpu_env, 6612 cpu_FR[arg[1]], cpu_FR[arg[2]]); 6613 } 6614 } 6615 6616 static void translate_msub_s(DisasContext *dc, const uint32_t arg[], 6617 const uint32_t par[]) 6618 { 6619 if (gen_check_cpenable(dc, 0)) { 6620 gen_helper_msub_s(cpu_FR[arg[0]], cpu_env, 6621 cpu_FR[arg[0]], cpu_FR[arg[1]], cpu_FR[arg[2]]); 6622 } 6623 } 6624 6625 static void translate_neg_s(DisasContext *dc, const uint32_t arg[], 6626 const uint32_t par[]) 6627 { 6628 if (gen_check_cpenable(dc, 0)) { 6629 gen_helper_neg_s(cpu_FR[arg[0]], cpu_FR[arg[1]]); 6630 } 6631 } 6632 6633 static void translate_rfr_s(DisasContext *dc, const uint32_t arg[], 6634 const uint32_t par[]) 6635 { 6636 if (gen_window_check1(dc, arg[0]) && 6637 gen_check_cpenable(dc, 0)) { 6638 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_FR[arg[1]]); 6639 } 6640 } 6641 6642 static void translate_sub_s(DisasContext *dc, const uint32_t arg[], 6643 const uint32_t par[]) 6644 { 6645 if (gen_check_cpenable(dc, 0)) { 6646 gen_helper_sub_s(cpu_FR[arg[0]], cpu_env, 6647 cpu_FR[arg[1]], cpu_FR[arg[2]]); 6648 } 6649 } 6650 6651 static void translate_wfr_s(DisasContext *dc, const uint32_t arg[], 6652 const uint32_t par[]) 6653 { 6654 if (gen_window_check1(dc, arg[1]) && 6655 gen_check_cpenable(dc, 0)) { 6656 tcg_gen_mov_i32(cpu_FR[arg[0]], cpu_R[arg[1]]); 6657 } 6658 } 6659 6660 static const XtensaOpcodeOps fpu2000_ops[] = { 6661 { 6662 .name = "abs.s", 6663 .translate = translate_abs_s, 6664 }, { 6665 .name = "add.s", 6666 .translate = translate_add_s, 6667 }, { 6668 .name = "ceil.s", 6669 .translate = translate_ftoi_s, 6670 .par = (const uint32_t[]){float_round_up, false}, 6671 }, { 6672 .name = "float.s", 6673 .translate = translate_float_s, 6674 .par = (const uint32_t[]){false}, 6675 }, { 6676 .name = "floor.s", 6677 .translate = translate_ftoi_s, 6678 .par = (const uint32_t[]){float_round_down, false}, 6679 }, { 6680 .name = "lsi", 6681 .translate = translate_ldsti, 6682 .par = (const uint32_t[]){false, false}, 6683 }, { 6684 .name = "lsiu", 6685 .translate = translate_ldsti, 6686 .par = (const uint32_t[]){false, true}, 6687 }, { 6688 .name = "lsx", 6689 .translate = translate_ldstx, 6690 .par = (const uint32_t[]){false, false}, 6691 }, { 6692 .name = "lsxu", 6693 .translate = translate_ldstx, 6694 .par = (const uint32_t[]){false, true}, 6695 }, { 6696 .name = "madd.s", 6697 .translate = translate_madd_s, 6698 }, { 6699 .name = "mov.s", 6700 .translate = translate_mov_s, 6701 }, { 6702 .name = "moveqz.s", 6703 .translate = translate_movcond_s, 6704 .par = (const uint32_t[]){TCG_COND_EQ}, 6705 }, { 6706 .name = "movf.s", 6707 .translate = translate_movp_s, 6708 .par = (const uint32_t[]){TCG_COND_EQ}, 6709 }, { 6710 .name = "movgez.s", 6711 .translate = translate_movcond_s, 6712 .par = (const uint32_t[]){TCG_COND_GE}, 6713 }, { 6714 .name = "movltz.s", 6715 .translate = translate_movcond_s, 6716 .par = (const uint32_t[]){TCG_COND_LT}, 6717 }, { 6718 .name = "movnez.s", 6719 .translate = translate_movcond_s, 6720 .par = (const uint32_t[]){TCG_COND_NE}, 6721 }, { 6722 .name = "movt.s", 6723 .translate = translate_movp_s, 6724 .par = (const uint32_t[]){TCG_COND_NE}, 6725 }, { 6726 .name = "msub.s", 6727 .translate = translate_msub_s, 6728 }, { 6729 .name = "mul.s", 6730 .translate = translate_mul_s, 6731 }, { 6732 .name = "neg.s", 6733 .translate = translate_neg_s, 6734 }, { 6735 .name = "oeq.s", 6736 .translate = translate_compare_s, 6737 .par = (const uint32_t[]){COMPARE_OEQ}, 6738 }, { 6739 .name = "ole.s", 6740 .translate = translate_compare_s, 6741 .par = (const uint32_t[]){COMPARE_OLE}, 6742 }, { 6743 .name = "olt.s", 6744 .translate = translate_compare_s, 6745 .par = (const uint32_t[]){COMPARE_OLT}, 6746 }, { 6747 .name = "rfr.s", 6748 .translate = translate_rfr_s, 6749 }, { 6750 .name = "round.s", 6751 .translate = translate_ftoi_s, 6752 .par = (const uint32_t[]){float_round_nearest_even, false}, 6753 }, { 6754 .name = "ssi", 6755 .translate = translate_ldsti, 6756 .par = (const uint32_t[]){true, false}, 6757 }, { 6758 .name = "ssiu", 6759 .translate = translate_ldsti, 6760 .par = (const uint32_t[]){true, true}, 6761 }, { 6762 .name = "ssx", 6763 .translate = translate_ldstx, 6764 .par = (const uint32_t[]){true, false}, 6765 }, { 6766 .name = "ssxu", 6767 .translate = translate_ldstx, 6768 .par = (const uint32_t[]){true, true}, 6769 }, { 6770 .name = "sub.s", 6771 .translate = translate_sub_s, 6772 }, { 6773 .name = "trunc.s", 6774 .translate = translate_ftoi_s, 6775 .par = (const uint32_t[]){float_round_to_zero, false}, 6776 }, { 6777 .name = "ueq.s", 6778 .translate = translate_compare_s, 6779 .par = (const uint32_t[]){COMPARE_UEQ}, 6780 }, { 6781 .name = "ufloat.s", 6782 .translate = translate_float_s, 6783 .par = (const uint32_t[]){true}, 6784 }, { 6785 .name = "ule.s", 6786 .translate = translate_compare_s, 6787 .par = (const uint32_t[]){COMPARE_ULE}, 6788 }, { 6789 .name = "ult.s", 6790 .translate = translate_compare_s, 6791 .par = (const uint32_t[]){COMPARE_ULT}, 6792 }, { 6793 .name = "un.s", 6794 .translate = translate_compare_s, 6795 .par = (const uint32_t[]){COMPARE_UN}, 6796 }, { 6797 .name = "utrunc.s", 6798 .translate = translate_ftoi_s, 6799 .par = (const uint32_t[]){float_round_to_zero, true}, 6800 }, { 6801 .name = "wfr.s", 6802 .translate = translate_wfr_s, 6803 }, 6804 }; 6805 6806 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = { 6807 .num_opcodes = ARRAY_SIZE(fpu2000_ops), 6808 .opcode = fpu2000_ops, 6809 }; 6810