translate.c revision 26d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9
1/* 2 * ARM translation 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * Copyright (c) 2005-2007 CodeSourcery 6 * Copyright (c) 2007 OpenedHand, Ltd. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 20 */ 21#include <stdarg.h> 22#include <stdlib.h> 23#include <stdio.h> 24#include <string.h> 25#include <inttypes.h> 26 27#include "cpu.h" 28#include "exec/exec-all.h" 29#include "disas/disas.h" 30#include "tcg-op.h" 31#include "qemu/log.h" 32 33#include "helper.h" 34#define GEN_HELPER 1 35#include "helper.h" 36 37#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T) 38#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5) 39/* currently all emulated v5 cores are also v5TE, so don't bother */ 40#define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5) 41#define ENABLE_ARCH_5J 0 42#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6) 43#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K) 44#define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2) 45#define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7) 46 47#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0) 48 49/* internal defines */ 50typedef struct DisasContext { 51 target_ulong pc; 52 int is_jmp; 53 /* Nonzero if this instruction has been conditionally skipped. */ 54 int condjmp; 55 /* The label that will be jumped to when the instruction is skipped. */ 56 int condlabel; 57 /* Thumb-2 condtional execution bits. */ 58 int condexec_mask; 59 int condexec_cond; 60 struct TranslationBlock *tb; 61 int singlestep_enabled; 62 int thumb; 63#if !defined(CONFIG_USER_ONLY) 64 int user; 65#endif 66 int vfp_enabled; 67 int vec_len; 68 int vec_stride; 69#ifdef CONFIG_ANDROID_MEMCHECK 70 int search_pc; 71#endif 72} DisasContext; 73 74#include "translate-android.h" 75 76#if defined(CONFIG_USER_ONLY) 77#define IS_USER(s) 1 78#else 79#define IS_USER(s) (s->user) 80#endif 81 82/* These instructions trap after executing, so defer them until after the 83 conditional executions state has been updated. */ 84#define DISAS_WFI 4 85#define DISAS_SWI 5 86#define DISAS_SMC 6 87 88static TCGv_ptr cpu_env; 89/* We reuse the same 64-bit temporaries for efficiency. */ 90static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; 91static TCGv_i32 cpu_R[16]; 92static TCGv_i32 cpu_exclusive_addr; 93static TCGv_i32 cpu_exclusive_val; 94static TCGv_i32 cpu_exclusive_high; 95#ifdef CONFIG_USER_ONLY 96static TCGv_i32 cpu_exclusive_test; 97static TCGv_i32 cpu_exclusive_info; 98#endif 99 100/* FIXME: These should be removed. */ 101static TCGv cpu_F0s, cpu_F1s; 102static TCGv_i64 cpu_F0d, cpu_F1d; 103 104#include "exec/gen-icount.h" 105 106static const char *regnames[] = 107 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 108 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" }; 109 110/* initialize TCG globals. */ 111void arm_translate_init(void) 112{ 113 int i; 114 115 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 116 117 for (i = 0; i < 16; i++) { 118 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0, 119 offsetof(CPUARMState, regs[i]), 120 regnames[i]); 121 } 122 cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0, 123 offsetof(CPUARMState, exclusive_addr), "exclusive_addr"); 124 cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0, 125 offsetof(CPUARMState, exclusive_val), "exclusive_val"); 126 cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0, 127 offsetof(CPUARMState, exclusive_high), "exclusive_high"); 128#ifdef CONFIG_USER_ONLY 129 cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0, 130 offsetof(CPUARMState, exclusive_test), "exclusive_test"); 131 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0, 132 offsetof(CPUARMState, exclusive_info), "exclusive_info"); 133#endif 134} 135 136static inline TCGv load_cpu_offset(int offset) 137{ 138 TCGv tmp = tcg_temp_new_i32(); 139 tcg_gen_ld_i32(tmp, cpu_env, offset); 140 return tmp; 141} 142 143#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name)) 144 145static inline void store_cpu_offset(TCGv var, int offset) 146{ 147 tcg_gen_st_i32(var, cpu_env, offset); 148 tcg_temp_free_i32(var); 149} 150 151#define store_cpu_field(var, name) \ 152 store_cpu_offset(var, offsetof(CPUARMState, name)) 153 154/* Set a variable to the value of a CPU register. */ 155static void load_reg_var(DisasContext *s, TCGv var, int reg) 156{ 157 if (reg == 15) { 158 uint32_t addr; 159 /* normaly, since we updated PC, we need only to add one insn */ 160 if (s->thumb) 161 addr = (long)s->pc + 2; 162 else 163 addr = (long)s->pc + 4; 164 tcg_gen_movi_i32(var, addr); 165 } else { 166 tcg_gen_mov_i32(var, cpu_R[reg]); 167 } 168} 169 170/* Create a new temporary and set it to the value of a CPU register. */ 171static inline TCGv load_reg(DisasContext *s, int reg) 172{ 173 TCGv tmp = tcg_temp_new_i32(); 174 load_reg_var(s, tmp, reg); 175 return tmp; 176} 177 178/* Set a CPU register. The source must be a temporary and will be 179 marked as dead. */ 180static void store_reg(DisasContext *s, int reg, TCGv var) 181{ 182 if (reg == 15) { 183 tcg_gen_andi_i32(var, var, ~1); 184 s->is_jmp = DISAS_JUMP; 185 } 186 tcg_gen_mov_i32(cpu_R[reg], var); 187 tcg_temp_free_i32(var); 188} 189 190/* Value extensions. */ 191#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var) 192#define gen_uxth(var) tcg_gen_ext16u_i32(var, var) 193#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) 194#define gen_sxth(var) tcg_gen_ext16s_i32(var, var) 195 196#define gen_sxtb16(var) gen_helper_sxtb16(var, var) 197#define gen_uxtb16(var) gen_helper_uxtb16(var, var) 198 199 200static inline void gen_set_cpsr(TCGv var, uint32_t mask) 201{ 202 TCGv tmp_mask = tcg_const_i32(mask); 203 gen_helper_cpsr_write(var, tmp_mask); 204 tcg_temp_free_i32(tmp_mask); 205} 206/* Set NZCV flags from the high 4 bits of var. */ 207#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV) 208 209static void gen_exception(int excp) 210{ 211 TCGv tmp = tcg_temp_new_i32(); 212 tcg_gen_movi_i32(tmp, excp); 213 gen_helper_exception(tmp); 214 tcg_temp_free_i32(tmp); 215} 216 217static void gen_smul_dual(TCGv a, TCGv b) 218{ 219 TCGv tmp1 = tcg_temp_new_i32(); 220 TCGv tmp2 = tcg_temp_new_i32(); 221 tcg_gen_ext16s_i32(tmp1, a); 222 tcg_gen_ext16s_i32(tmp2, b); 223 tcg_gen_mul_i32(tmp1, tmp1, tmp2); 224 tcg_temp_free_i32(tmp2); 225 tcg_gen_sari_i32(a, a, 16); 226 tcg_gen_sari_i32(b, b, 16); 227 tcg_gen_mul_i32(b, b, a); 228 tcg_gen_mov_i32(a, tmp1); 229 tcg_temp_free_i32(tmp1); 230} 231 232/* Byteswap each halfword. */ 233static void gen_rev16(TCGv var) 234{ 235 TCGv tmp = tcg_temp_new_i32(); 236 tcg_gen_shri_i32(tmp, var, 8); 237 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff); 238 tcg_gen_shli_i32(var, var, 8); 239 tcg_gen_andi_i32(var, var, 0xff00ff00); 240 tcg_gen_or_i32(var, var, tmp); 241 tcg_temp_free_i32(tmp); 242} 243 244/* Byteswap low halfword and sign extend. */ 245static void gen_revsh(TCGv var) 246{ 247 tcg_gen_ext16u_i32(var, var); 248 tcg_gen_bswap16_i32(var, var); 249 tcg_gen_ext16s_i32(var, var); 250} 251 252/* Unsigned bitfield extract. */ 253static void gen_ubfx(TCGv var, int shift, uint32_t mask) 254{ 255 if (shift) 256 tcg_gen_shri_i32(var, var, shift); 257 tcg_gen_andi_i32(var, var, mask); 258} 259 260/* Signed bitfield extract. */ 261static void gen_sbfx(TCGv var, int shift, int width) 262{ 263 uint32_t signbit; 264 265 if (shift) 266 tcg_gen_sari_i32(var, var, shift); 267 if (shift + width < 32) { 268 signbit = 1u << (width - 1); 269 tcg_gen_andi_i32(var, var, (1u << width) - 1); 270 tcg_gen_xori_i32(var, var, signbit); 271 tcg_gen_subi_i32(var, var, signbit); 272 } 273} 274 275/* Bitfield insertion. Insert val into base. Clobbers base and val. */ 276static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask) 277{ 278 tcg_gen_andi_i32(val, val, mask); 279 tcg_gen_shli_i32(val, val, shift); 280 tcg_gen_andi_i32(base, base, ~(mask << shift)); 281 tcg_gen_or_i32(dest, base, val); 282} 283 284/* Return (b << 32) + a. Mark inputs as dead */ 285static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b) 286{ 287 TCGv_i64 tmp64 = tcg_temp_new_i64(); 288 289 tcg_gen_extu_i32_i64(tmp64, b); 290 tcg_temp_free_i32(b); 291 tcg_gen_shli_i64(tmp64, tmp64, 32); 292 tcg_gen_add_i64(a, tmp64, a); 293 294 tcg_temp_free_i64(tmp64); 295 return a; 296} 297 298/* Return (b << 32) - a. Mark inputs as dead. */ 299static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b) 300{ 301 TCGv_i64 tmp64 = tcg_temp_new_i64(); 302 303 tcg_gen_extu_i32_i64(tmp64, b); 304 tcg_temp_free_i32(b); 305 tcg_gen_shli_i64(tmp64, tmp64, 32); 306 tcg_gen_sub_i64(a, tmp64, a); 307 308 tcg_temp_free_i64(tmp64); 309 return a; 310} 311 312/* FIXME: Most targets have native widening multiplication. 313 It would be good to use that instead of a full wide multiply. */ 314/* 32x32->64 multiply. Marks inputs as dead. */ 315static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b) 316{ 317 TCGv_i64 tmp1 = tcg_temp_new_i64(); 318 TCGv_i64 tmp2 = tcg_temp_new_i64(); 319 320 tcg_gen_extu_i32_i64(tmp1, a); 321 tcg_temp_free_i32(a); 322 tcg_gen_extu_i32_i64(tmp2, b); 323 tcg_temp_free_i32(b); 324 tcg_gen_mul_i64(tmp1, tmp1, tmp2); 325 tcg_temp_free_i64(tmp2); 326 return tmp1; 327} 328 329static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b) 330{ 331 TCGv_i64 tmp1 = tcg_temp_new_i64(); 332 TCGv_i64 tmp2 = tcg_temp_new_i64(); 333 334 tcg_gen_ext_i32_i64(tmp1, a); 335 tcg_temp_free_i32(a); 336 tcg_gen_ext_i32_i64(tmp2, b); 337 tcg_temp_free_i32(b); 338 tcg_gen_mul_i64(tmp1, tmp1, tmp2); 339 tcg_temp_free_i64(tmp2); 340 return tmp1; 341} 342 343/* Swap low and high halfwords. */ 344static void gen_swap_half(TCGv var) 345{ 346 TCGv tmp = tcg_temp_new_i32(); 347 tcg_gen_shri_i32(tmp, var, 16); 348 tcg_gen_shli_i32(var, var, 16); 349 tcg_gen_or_i32(var, var, tmp); 350 tcg_temp_free_i32(tmp); 351} 352 353/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. 354 tmp = (t0 ^ t1) & 0x8000; 355 t0 &= ~0x8000; 356 t1 &= ~0x8000; 357 t0 = (t0 + t1) ^ tmp; 358 */ 359 360static void gen_add16(TCGv t0, TCGv t1) 361{ 362 TCGv tmp = tcg_temp_new_i32(); 363 tcg_gen_xor_i32(tmp, t0, t1); 364 tcg_gen_andi_i32(tmp, tmp, 0x8000); 365 tcg_gen_andi_i32(t0, t0, ~0x8000); 366 tcg_gen_andi_i32(t1, t1, ~0x8000); 367 tcg_gen_add_i32(t0, t0, t1); 368 tcg_gen_xor_i32(t0, t0, tmp); 369 tcg_temp_free_i32(tmp); 370 tcg_temp_free_i32(t1); 371} 372 373#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, CF)) 374 375/* Set CF to the top bit of var. */ 376static void gen_set_CF_bit31(TCGv var) 377{ 378 TCGv tmp = tcg_temp_new_i32(); 379 tcg_gen_shri_i32(tmp, var, 31); 380 gen_set_CF(tmp); 381 tcg_temp_free_i32(tmp); 382} 383 384/* Set N and Z flags from var. */ 385static inline void gen_logic_CC(TCGv var) 386{ 387 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, NF)); 388 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, ZF)); 389} 390 391/* T0 += T1 + CF. */ 392static void gen_adc(TCGv t0, TCGv t1) 393{ 394 TCGv tmp; 395 tcg_gen_add_i32(t0, t0, t1); 396 tmp = load_cpu_field(CF); 397 tcg_gen_add_i32(t0, t0, tmp); 398 tcg_temp_free_i32(tmp); 399} 400 401/* dest = T0 + T1 + CF. */ 402static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) 403{ 404 TCGv tmp; 405 tcg_gen_add_i32(dest, t0, t1); 406 tmp = load_cpu_field(CF); 407 tcg_gen_add_i32(dest, dest, tmp); 408 tcg_temp_free_i32(tmp); 409} 410 411/* dest = T0 - T1 + CF - 1. */ 412static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) 413{ 414 TCGv tmp; 415 tcg_gen_sub_i32(dest, t0, t1); 416 tmp = load_cpu_field(CF); 417 tcg_gen_add_i32(dest, dest, tmp); 418 tcg_gen_subi_i32(dest, dest, 1); 419 tcg_temp_free_i32(tmp); 420} 421 422/* FIXME: Implement this natively. */ 423#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1) 424 425static void shifter_out_im(TCGv var, int shift) 426{ 427 TCGv tmp = tcg_temp_new_i32(); 428 if (shift == 0) { 429 tcg_gen_andi_i32(tmp, var, 1); 430 } else { 431 tcg_gen_shri_i32(tmp, var, shift); 432 if (shift != 31) 433 tcg_gen_andi_i32(tmp, tmp, 1); 434 } 435 gen_set_CF(tmp); 436 tcg_temp_free_i32(tmp); 437} 438 439/* Shift by immediate. Includes special handling for shift == 0. */ 440static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) 441{ 442 switch (shiftop) { 443 case 0: /* LSL */ 444 if (shift != 0) { 445 if (flags) 446 shifter_out_im(var, 32 - shift); 447 tcg_gen_shli_i32(var, var, shift); 448 } 449 break; 450 case 1: /* LSR */ 451 if (shift == 0) { 452 if (flags) { 453 tcg_gen_shri_i32(var, var, 31); 454 gen_set_CF(var); 455 } 456 tcg_gen_movi_i32(var, 0); 457 } else { 458 if (flags) 459 shifter_out_im(var, shift - 1); 460 tcg_gen_shri_i32(var, var, shift); 461 } 462 break; 463 case 2: /* ASR */ 464 if (shift == 0) 465 shift = 32; 466 if (flags) 467 shifter_out_im(var, shift - 1); 468 if (shift == 32) 469 shift = 31; 470 tcg_gen_sari_i32(var, var, shift); 471 break; 472 case 3: /* ROR/RRX */ 473 if (shift != 0) { 474 if (flags) 475 shifter_out_im(var, shift - 1); 476 tcg_gen_rotri_i32(var, var, shift); break; 477 } else { 478 TCGv tmp = load_cpu_field(CF); 479 if (flags) 480 shifter_out_im(var, 0); 481 tcg_gen_shri_i32(var, var, 1); 482 tcg_gen_shli_i32(tmp, tmp, 31); 483 tcg_gen_or_i32(var, var, tmp); 484 tcg_temp_free_i32(tmp); 485 } 486 } 487}; 488 489static inline void gen_arm_shift_reg(TCGv var, int shiftop, 490 TCGv shift, int flags) 491{ 492 if (flags) { 493 switch (shiftop) { 494 case 0: gen_helper_shl_cc(var, var, shift); break; 495 case 1: gen_helper_shr_cc(var, var, shift); break; 496 case 2: gen_helper_sar_cc(var, var, shift); break; 497 case 3: gen_helper_ror_cc(var, var, shift); break; 498 } 499 } else { 500 switch (shiftop) { 501 case 0: gen_helper_shl(var, var, shift); break; 502 case 1: gen_helper_shr(var, var, shift); break; 503 case 2: gen_helper_sar(var, var, shift); break; 504 case 3: tcg_gen_andi_i32(shift, shift, 0x1f); 505 tcg_gen_rotr_i32(var, var, shift); break; 506 } 507 } 508 tcg_temp_free_i32(shift); 509} 510 511#define PAS_OP(pfx) \ 512 switch (op2) { \ 513 case 0: gen_pas_helper(glue(pfx,add16)); break; \ 514 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \ 515 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \ 516 case 3: gen_pas_helper(glue(pfx,sub16)); break; \ 517 case 4: gen_pas_helper(glue(pfx,add8)); break; \ 518 case 7: gen_pas_helper(glue(pfx,sub8)); break; \ 519 } 520static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b) 521{ 522 TCGv_ptr tmp; 523 524 switch (op1) { 525#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) 526 case 1: 527 tmp = tcg_temp_new_ptr(); 528 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); 529 PAS_OP(s) 530 tcg_temp_free_ptr(tmp); 531 break; 532 case 5: 533 tmp = tcg_temp_new_ptr(); 534 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); 535 PAS_OP(u) 536 tcg_temp_free_ptr(tmp); 537 break; 538#undef gen_pas_helper 539#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) 540 case 2: 541 PAS_OP(q); 542 break; 543 case 3: 544 PAS_OP(sh); 545 break; 546 case 6: 547 PAS_OP(uq); 548 break; 549 case 7: 550 PAS_OP(uh); 551 break; 552#undef gen_pas_helper 553 } 554} 555#undef PAS_OP 556 557/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */ 558#define PAS_OP(pfx) \ 559 switch (op1) { \ 560 case 0: gen_pas_helper(glue(pfx,add8)); break; \ 561 case 1: gen_pas_helper(glue(pfx,add16)); break; \ 562 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \ 563 case 4: gen_pas_helper(glue(pfx,sub8)); break; \ 564 case 5: gen_pas_helper(glue(pfx,sub16)); break; \ 565 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \ 566 } 567static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) 568{ 569 TCGv_ptr tmp; 570 571 switch (op2) { 572#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) 573 case 0: 574 tmp = tcg_temp_new_ptr(); 575 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); 576 PAS_OP(s) 577 tcg_temp_free_ptr(tmp); 578 break; 579 case 4: 580 tmp = tcg_temp_new_ptr(); 581 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); 582 PAS_OP(u) 583 tcg_temp_free_ptr(tmp); 584 break; 585#undef gen_pas_helper 586#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) 587 case 1: 588 PAS_OP(q); 589 break; 590 case 2: 591 PAS_OP(sh); 592 break; 593 case 5: 594 PAS_OP(uq); 595 break; 596 case 6: 597 PAS_OP(uh); 598 break; 599#undef gen_pas_helper 600 } 601} 602#undef PAS_OP 603 604static void gen_test_cc(int cc, int label) 605{ 606 TCGv tmp; 607 TCGv tmp2; 608 int inv; 609 610 switch (cc) { 611 case 0: /* eq: Z */ 612 tmp = load_cpu_field(ZF); 613 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 614 break; 615 case 1: /* ne: !Z */ 616 tmp = load_cpu_field(ZF); 617 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); 618 break; 619 case 2: /* cs: C */ 620 tmp = load_cpu_field(CF); 621 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); 622 break; 623 case 3: /* cc: !C */ 624 tmp = load_cpu_field(CF); 625 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 626 break; 627 case 4: /* mi: N */ 628 tmp = load_cpu_field(NF); 629 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); 630 break; 631 case 5: /* pl: !N */ 632 tmp = load_cpu_field(NF); 633 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); 634 break; 635 case 6: /* vs: V */ 636 tmp = load_cpu_field(VF); 637 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); 638 break; 639 case 7: /* vc: !V */ 640 tmp = load_cpu_field(VF); 641 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); 642 break; 643 case 8: /* hi: C && !Z */ 644 inv = gen_new_label(); 645 tmp = load_cpu_field(CF); 646 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); 647 tcg_temp_free_i32(tmp); 648 tmp = load_cpu_field(ZF); 649 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); 650 gen_set_label(inv); 651 break; 652 case 9: /* ls: !C || Z */ 653 tmp = load_cpu_field(CF); 654 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 655 tcg_temp_free_i32(tmp); 656 tmp = load_cpu_field(ZF); 657 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 658 break; 659 case 10: /* ge: N == V -> N ^ V == 0 */ 660 tmp = load_cpu_field(VF); 661 tmp2 = load_cpu_field(NF); 662 tcg_gen_xor_i32(tmp, tmp, tmp2); 663 tcg_temp_free_i32(tmp2); 664 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); 665 break; 666 case 11: /* lt: N != V -> N ^ V != 0 */ 667 tmp = load_cpu_field(VF); 668 tmp2 = load_cpu_field(NF); 669 tcg_gen_xor_i32(tmp, tmp, tmp2); 670 tcg_temp_free_i32(tmp2); 671 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); 672 break; 673 case 12: /* gt: !Z && N == V */ 674 inv = gen_new_label(); 675 tmp = load_cpu_field(ZF); 676 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); 677 tcg_temp_free_i32(tmp); 678 tmp = load_cpu_field(VF); 679 tmp2 = load_cpu_field(NF); 680 tcg_gen_xor_i32(tmp, tmp, tmp2); 681 tcg_temp_free_i32(tmp2); 682 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); 683 gen_set_label(inv); 684 break; 685 case 13: /* le: Z || N != V */ 686 tmp = load_cpu_field(ZF); 687 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); 688 tcg_temp_free_i32(tmp); 689 tmp = load_cpu_field(VF); 690 tmp2 = load_cpu_field(NF); 691 tcg_gen_xor_i32(tmp, tmp, tmp2); 692 tcg_temp_free_i32(tmp2); 693 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); 694 break; 695 default: 696 fprintf(stderr, "Bad condition code 0x%x\n", cc); 697 abort(); 698 } 699 tcg_temp_free_i32(tmp); 700} 701 702static const uint8_t table_logic_cc[16] = { 703 1, /* and */ 704 1, /* xor */ 705 0, /* sub */ 706 0, /* rsb */ 707 0, /* add */ 708 0, /* adc */ 709 0, /* sbc */ 710 0, /* rsc */ 711 1, /* andl */ 712 1, /* xorl */ 713 0, /* cmp */ 714 0, /* cmn */ 715 1, /* orr */ 716 1, /* mov */ 717 1, /* bic */ 718 1, /* mvn */ 719}; 720 721/* Set PC and Thumb state from an immediate address. */ 722static inline void gen_bx_im(DisasContext *s, uint32_t addr) 723{ 724 TCGv tmp; 725 726 s->is_jmp = DISAS_UPDATE; 727 if (s->thumb != (addr & 1)) { 728 tmp = tcg_temp_new_i32(); 729 tcg_gen_movi_i32(tmp, addr & 1); 730 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb)); 731 tcg_temp_free_i32(tmp); 732 } 733 tcg_gen_movi_i32(cpu_R[15], addr & ~1); 734} 735 736/* Set PC and Thumb state from var. var is marked as dead. */ 737static inline void gen_bx(DisasContext *s, TCGv var) 738{ 739 s->is_jmp = DISAS_UPDATE; 740 tcg_gen_andi_i32(cpu_R[15], var, ~1); 741 tcg_gen_andi_i32(var, var, 1); 742 store_cpu_field(var, thumb); 743} 744 745/* Variant of store_reg which uses branch&exchange logic when storing 746 to r15 in ARM architecture v7 and above. The source must be a temporary 747 and will be marked as dead. */ 748static inline void store_reg_bx(CPUARMState *env, DisasContext *s, 749 int reg, TCGv var) 750{ 751 if (reg == 15 && ENABLE_ARCH_7) { 752 gen_bx(s, var); 753 } else { 754 store_reg(s, reg, var); 755 } 756} 757 758/* Variant of store_reg which uses branch&exchange logic when storing 759 * to r15 in ARM architecture v5T and above. This is used for storing 760 * the results of a LDR/LDM/POP into r15, and corresponds to the cases 761 * in the ARM ARM which use the LoadWritePC() pseudocode function. */ 762static inline void store_reg_from_load(CPUARMState *env, DisasContext *s, 763 int reg, TCGv var) 764{ 765 if (reg == 15 && ENABLE_ARCH_5) { 766 gen_bx(s, var); 767 } else { 768 store_reg(s, reg, var); 769 } 770} 771 772static inline void gen_smc(CPUARMState *env, DisasContext *s) 773{ 774 tcg_gen_movi_i32(cpu_R[15], s->pc); 775 s->is_jmp = DISAS_SMC; 776} 777 778static inline TCGv gen_ld8s(TCGv addr, int index) 779{ 780 TCGv tmp = tcg_temp_new_i32(); 781 tcg_gen_qemu_ld8s(tmp, addr, index); 782 return tmp; 783} 784static inline TCGv gen_ld8u(TCGv addr, int index) 785{ 786 TCGv tmp = tcg_temp_new_i32(); 787 tcg_gen_qemu_ld8u(tmp, addr, index); 788 return tmp; 789} 790static inline TCGv gen_ld16s(TCGv addr, int index) 791{ 792 TCGv tmp = tcg_temp_new_i32(); 793 tcg_gen_qemu_ld16s(tmp, addr, index); 794 return tmp; 795} 796static inline TCGv gen_ld16u(TCGv addr, int index) 797{ 798 TCGv tmp = tcg_temp_new_i32(); 799 tcg_gen_qemu_ld16u(tmp, addr, index); 800 return tmp; 801} 802static inline TCGv gen_ld32(TCGv addr, int index) 803{ 804 TCGv tmp = tcg_temp_new_i32(); 805 tcg_gen_qemu_ld32u(tmp, addr, index); 806 return tmp; 807} 808static inline TCGv_i64 gen_ld64(TCGv addr, int index) 809{ 810 TCGv_i64 tmp = tcg_temp_new_i64(); 811 tcg_gen_qemu_ld64(tmp, addr, index); 812 return tmp; 813} 814static inline void gen_st8(TCGv val, TCGv addr, int index) 815{ 816 tcg_gen_qemu_st8(val, addr, index); 817 tcg_temp_free_i32(val); 818} 819static inline void gen_st16(TCGv val, TCGv addr, int index) 820{ 821 tcg_gen_qemu_st16(val, addr, index); 822 tcg_temp_free_i32(val); 823} 824static inline void gen_st32(TCGv val, TCGv addr, int index) 825{ 826 tcg_gen_qemu_st32(val, addr, index); 827 tcg_temp_free_i32(val); 828} 829static inline void gen_st64(TCGv_i64 val, TCGv addr, int index) 830{ 831 tcg_gen_qemu_st64(val, addr, index); 832 tcg_temp_free_i64(val); 833} 834 835static inline void gen_set_pc_im(uint32_t val) 836{ 837 tcg_gen_movi_i32(cpu_R[15], val); 838} 839 840/* Force a TB lookup after an instruction that changes the CPU state. */ 841static inline void gen_lookup_tb(DisasContext *s) 842{ 843 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1); 844 s->is_jmp = DISAS_UPDATE; 845} 846 847static inline void gen_add_data_offset(DisasContext *s, unsigned int insn, 848 TCGv var) 849{ 850 int val, rm, shift, shiftop; 851 TCGv offset; 852 853 if (!(insn & (1 << 25))) { 854 /* immediate */ 855 val = insn & 0xfff; 856 if (!(insn & (1 << 23))) 857 val = -val; 858 if (val != 0) 859 tcg_gen_addi_i32(var, var, val); 860 } else { 861 /* shift/register */ 862 rm = (insn) & 0xf; 863 shift = (insn >> 7) & 0x1f; 864 shiftop = (insn >> 5) & 3; 865 offset = load_reg(s, rm); 866 gen_arm_shift_im(offset, shiftop, shift, 0); 867 if (!(insn & (1 << 23))) 868 tcg_gen_sub_i32(var, var, offset); 869 else 870 tcg_gen_add_i32(var, var, offset); 871 tcg_temp_free_i32(offset); 872 } 873} 874 875static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, 876 int extra, TCGv var) 877{ 878 int val, rm; 879 TCGv offset; 880 881 if (insn & (1 << 22)) { 882 /* immediate */ 883 val = (insn & 0xf) | ((insn >> 4) & 0xf0); 884 if (!(insn & (1 << 23))) 885 val = -val; 886 val += extra; 887 if (val != 0) 888 tcg_gen_addi_i32(var, var, val); 889 } else { 890 /* register */ 891 if (extra) 892 tcg_gen_addi_i32(var, var, extra); 893 rm = (insn) & 0xf; 894 offset = load_reg(s, rm); 895 if (!(insn & (1 << 23))) 896 tcg_gen_sub_i32(var, var, offset); 897 else 898 tcg_gen_add_i32(var, var, offset); 899 tcg_temp_free_i32(offset); 900 } 901} 902 903#define VFP_OP2(name) \ 904static inline void gen_vfp_##name(int dp) \ 905{ \ 906 if (dp) \ 907 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \ 908 else \ 909 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \ 910} 911 912VFP_OP2(add) 913VFP_OP2(sub) 914VFP_OP2(mul) 915VFP_OP2(div) 916 917#undef VFP_OP2 918 919static inline void gen_vfp_F1_mul(int dp) 920{ 921 /* Like gen_vfp_mul() but put result in F1 */ 922 if (dp) { 923 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, cpu_env); 924 } else { 925 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, cpu_env); 926 } 927} 928 929static inline void gen_vfp_F1_neg(int dp) 930{ 931 /* Like gen_vfp_neg() but put result in F1 */ 932 if (dp) { 933 gen_helper_vfp_negd(cpu_F1d, cpu_F0d); 934 } else { 935 gen_helper_vfp_negs(cpu_F1s, cpu_F0s); 936 } 937} 938 939static inline void gen_vfp_abs(int dp) 940{ 941 if (dp) 942 gen_helper_vfp_absd(cpu_F0d, cpu_F0d); 943 else 944 gen_helper_vfp_abss(cpu_F0s, cpu_F0s); 945} 946 947static inline void gen_vfp_neg(int dp) 948{ 949 if (dp) 950 gen_helper_vfp_negd(cpu_F0d, cpu_F0d); 951 else 952 gen_helper_vfp_negs(cpu_F0s, cpu_F0s); 953} 954 955static inline void gen_vfp_sqrt(int dp) 956{ 957 if (dp) 958 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env); 959 else 960 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env); 961} 962 963static inline void gen_vfp_cmp(int dp) 964{ 965 if (dp) 966 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env); 967 else 968 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env); 969} 970 971static inline void gen_vfp_cmpe(int dp) 972{ 973 if (dp) 974 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env); 975 else 976 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env); 977} 978 979static inline void gen_vfp_F1_ld0(int dp) 980{ 981 if (dp) 982 tcg_gen_movi_i64(cpu_F1d, 0); 983 else 984 tcg_gen_movi_i32(cpu_F1s, 0); 985} 986 987#define VFP_GEN_ITOF(name) \ 988static inline void gen_vfp_##name(int dp, int neon) \ 989{ \ 990 TCGv_ptr statusptr = tcg_temp_new_ptr(); \ 991 int offset; \ 992 if (neon) { \ 993 offset = offsetof(CPUARMState, vfp.standard_fp_status); \ 994 } else { \ 995 offset = offsetof(CPUARMState, vfp.fp_status); \ 996 } \ 997 tcg_gen_addi_ptr(statusptr, cpu_env, offset); \ 998 if (dp) { \ 999 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \ 1000 } else { \ 1001 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ 1002 } \ 1003 tcg_temp_free_ptr(statusptr); \ 1004} 1005 1006VFP_GEN_ITOF(uito) 1007VFP_GEN_ITOF(sito) 1008#undef VFP_GEN_ITOF 1009 1010#define VFP_GEN_FTOI(name) \ 1011static inline void gen_vfp_##name(int dp, int neon) \ 1012{ \ 1013 TCGv_ptr statusptr = tcg_temp_new_ptr(); \ 1014 int offset; \ 1015 if (neon) { \ 1016 offset = offsetof(CPUARMState, vfp.standard_fp_status); \ 1017 } else { \ 1018 offset = offsetof(CPUARMState, vfp.fp_status); \ 1019 } \ 1020 tcg_gen_addi_ptr(statusptr, cpu_env, offset); \ 1021 if (dp) { \ 1022 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \ 1023 } else { \ 1024 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ 1025 } \ 1026 tcg_temp_free_ptr(statusptr); \ 1027} 1028 1029VFP_GEN_FTOI(toui) 1030VFP_GEN_FTOI(touiz) 1031VFP_GEN_FTOI(tosi) 1032VFP_GEN_FTOI(tosiz) 1033#undef VFP_GEN_FTOI 1034 1035#define VFP_GEN_FIX(name) \ 1036static inline void gen_vfp_##name(int dp, int shift, int neon) \ 1037{ \ 1038 TCGv tmp_shift = tcg_const_i32(shift); \ 1039 TCGv_ptr statusptr = tcg_temp_new_ptr(); \ 1040 int offset; \ 1041 if (neon) { \ 1042 offset = offsetof(CPUARMState, vfp.standard_fp_status); \ 1043 } else { \ 1044 offset = offsetof(CPUARMState, vfp.fp_status); \ 1045 } \ 1046 tcg_gen_addi_ptr(statusptr, cpu_env, offset); \ 1047 if (dp) { \ 1048 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \ 1049 } else { \ 1050 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \ 1051 } \ 1052 tcg_temp_free_i32(tmp_shift); \ 1053 tcg_temp_free_ptr(statusptr); \ 1054} 1055VFP_GEN_FIX(tosh) 1056VFP_GEN_FIX(tosl) 1057VFP_GEN_FIX(touh) 1058VFP_GEN_FIX(toul) 1059VFP_GEN_FIX(shto) 1060VFP_GEN_FIX(slto) 1061VFP_GEN_FIX(uhto) 1062VFP_GEN_FIX(ulto) 1063#undef VFP_GEN_FIX 1064 1065static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr) 1066{ 1067 if (dp) 1068 tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s)); 1069 else 1070 tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s)); 1071} 1072 1073static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr) 1074{ 1075 if (dp) 1076 tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s)); 1077 else 1078 tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s)); 1079} 1080 1081static inline long 1082vfp_reg_offset (int dp, int reg) 1083{ 1084 if (dp) 1085 return offsetof(CPUARMState, vfp.regs[reg]); 1086 else if (reg & 1) { 1087 return offsetof(CPUARMState, vfp.regs[reg >> 1]) 1088 + offsetof(CPU_DoubleU, l.upper); 1089 } else { 1090 return offsetof(CPUARMState, vfp.regs[reg >> 1]) 1091 + offsetof(CPU_DoubleU, l.lower); 1092 } 1093} 1094 1095/* Return the offset of a 32-bit piece of a NEON register. 1096 zero is the least significant end of the register. */ 1097static inline long 1098neon_reg_offset (int reg, int n) 1099{ 1100 int sreg; 1101 sreg = reg * 2 + n; 1102 return vfp_reg_offset(0, sreg); 1103} 1104 1105static TCGv neon_load_reg(int reg, int pass) 1106{ 1107 TCGv tmp = tcg_temp_new_i32(); 1108 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass)); 1109 return tmp; 1110} 1111 1112static void neon_store_reg(int reg, int pass, TCGv var) 1113{ 1114 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass)); 1115 tcg_temp_free_i32(var); 1116} 1117 1118static inline void neon_load_reg64(TCGv_i64 var, int reg) 1119{ 1120 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg)); 1121} 1122 1123static inline void neon_store_reg64(TCGv_i64 var, int reg) 1124{ 1125 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg)); 1126} 1127 1128#define tcg_gen_ld_f32 tcg_gen_ld_i32 1129#define tcg_gen_ld_f64 tcg_gen_ld_i64 1130#define tcg_gen_st_f32 tcg_gen_st_i32 1131#define tcg_gen_st_f64 tcg_gen_st_i64 1132 1133static inline void gen_mov_F0_vreg(int dp, int reg) 1134{ 1135 if (dp) 1136 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg)); 1137 else 1138 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg)); 1139} 1140 1141static inline void gen_mov_F1_vreg(int dp, int reg) 1142{ 1143 if (dp) 1144 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg)); 1145 else 1146 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg)); 1147} 1148 1149static inline void gen_mov_vreg_F0(int dp, int reg) 1150{ 1151 if (dp) 1152 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg)); 1153 else 1154 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg)); 1155} 1156 1157#define ARM_CP_RW_BIT (1 << 20) 1158 1159static inline void iwmmxt_load_reg(TCGv_i64 var, int reg) 1160{ 1161 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg])); 1162} 1163 1164static inline void iwmmxt_store_reg(TCGv_i64 var, int reg) 1165{ 1166 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg])); 1167} 1168 1169static inline TCGv iwmmxt_load_creg(int reg) 1170{ 1171 TCGv var = tcg_temp_new_i32(); 1172 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg])); 1173 return var; 1174} 1175 1176static inline void iwmmxt_store_creg(int reg, TCGv var) 1177{ 1178 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg])); 1179 tcg_temp_free_i32(var); 1180} 1181 1182static inline void gen_op_iwmmxt_movq_wRn_M0(int rn) 1183{ 1184 iwmmxt_store_reg(cpu_M0, rn); 1185} 1186 1187static inline void gen_op_iwmmxt_movq_M0_wRn(int rn) 1188{ 1189 iwmmxt_load_reg(cpu_M0, rn); 1190} 1191 1192static inline void gen_op_iwmmxt_orq_M0_wRn(int rn) 1193{ 1194 iwmmxt_load_reg(cpu_V1, rn); 1195 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1); 1196} 1197 1198static inline void gen_op_iwmmxt_andq_M0_wRn(int rn) 1199{ 1200 iwmmxt_load_reg(cpu_V1, rn); 1201 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1); 1202} 1203 1204static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn) 1205{ 1206 iwmmxt_load_reg(cpu_V1, rn); 1207 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1); 1208} 1209 1210#define IWMMXT_OP(name) \ 1211static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \ 1212{ \ 1213 iwmmxt_load_reg(cpu_V1, rn); \ 1214 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \ 1215} 1216 1217#define IWMMXT_OP_SIZE(name) \ 1218IWMMXT_OP(name##b) \ 1219IWMMXT_OP(name##w) \ 1220IWMMXT_OP(name##l) 1221 1222#define IWMMXT_OP_1(name) \ 1223static inline void gen_op_iwmmxt_##name##_M0(void) \ 1224{ \ 1225 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0); \ 1226} 1227 1228IWMMXT_OP(maddsq) 1229IWMMXT_OP(madduq) 1230IWMMXT_OP(sadb) 1231IWMMXT_OP(sadw) 1232IWMMXT_OP(mulslw) 1233IWMMXT_OP(mulshw) 1234IWMMXT_OP(mululw) 1235IWMMXT_OP(muluhw) 1236IWMMXT_OP(macsw) 1237IWMMXT_OP(macuw) 1238 1239IWMMXT_OP_SIZE(unpackl) 1240IWMMXT_OP_SIZE(unpackh) 1241 1242IWMMXT_OP_1(unpacklub) 1243IWMMXT_OP_1(unpackluw) 1244IWMMXT_OP_1(unpacklul) 1245IWMMXT_OP_1(unpackhub) 1246IWMMXT_OP_1(unpackhuw) 1247IWMMXT_OP_1(unpackhul) 1248IWMMXT_OP_1(unpacklsb) 1249IWMMXT_OP_1(unpacklsw) 1250IWMMXT_OP_1(unpacklsl) 1251IWMMXT_OP_1(unpackhsb) 1252IWMMXT_OP_1(unpackhsw) 1253IWMMXT_OP_1(unpackhsl) 1254 1255IWMMXT_OP_SIZE(cmpeq) 1256IWMMXT_OP_SIZE(cmpgtu) 1257IWMMXT_OP_SIZE(cmpgts) 1258 1259IWMMXT_OP_SIZE(mins) 1260IWMMXT_OP_SIZE(minu) 1261IWMMXT_OP_SIZE(maxs) 1262IWMMXT_OP_SIZE(maxu) 1263 1264IWMMXT_OP_SIZE(subn) 1265IWMMXT_OP_SIZE(addn) 1266IWMMXT_OP_SIZE(subu) 1267IWMMXT_OP_SIZE(addu) 1268IWMMXT_OP_SIZE(subs) 1269IWMMXT_OP_SIZE(adds) 1270 1271IWMMXT_OP(avgb0) 1272IWMMXT_OP(avgb1) 1273IWMMXT_OP(avgw0) 1274IWMMXT_OP(avgw1) 1275 1276IWMMXT_OP(msadb) 1277 1278IWMMXT_OP(packuw) 1279IWMMXT_OP(packul) 1280IWMMXT_OP(packuq) 1281IWMMXT_OP(packsw) 1282IWMMXT_OP(packsl) 1283IWMMXT_OP(packsq) 1284 1285static void gen_op_iwmmxt_set_mup(void) 1286{ 1287 TCGv tmp; 1288 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]); 1289 tcg_gen_ori_i32(tmp, tmp, 2); 1290 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]); 1291} 1292 1293static void gen_op_iwmmxt_set_cup(void) 1294{ 1295 TCGv tmp; 1296 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]); 1297 tcg_gen_ori_i32(tmp, tmp, 1); 1298 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]); 1299} 1300 1301static void gen_op_iwmmxt_setpsr_nz(void) 1302{ 1303 TCGv tmp = tcg_temp_new_i32(); 1304 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0); 1305 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]); 1306} 1307 1308static inline void gen_op_iwmmxt_addl_M0_wRn(int rn) 1309{ 1310 iwmmxt_load_reg(cpu_V1, rn); 1311 tcg_gen_ext32u_i64(cpu_V1, cpu_V1); 1312 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); 1313} 1314 1315static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest) 1316{ 1317 int rd; 1318 uint32_t offset; 1319 TCGv tmp; 1320 1321 rd = (insn >> 16) & 0xf; 1322 tmp = load_reg(s, rd); 1323 1324 offset = (insn & 0xff) << ((insn >> 7) & 2); 1325 if (insn & (1 << 24)) { 1326 /* Pre indexed */ 1327 if (insn & (1 << 23)) 1328 tcg_gen_addi_i32(tmp, tmp, offset); 1329 else 1330 tcg_gen_addi_i32(tmp, tmp, -offset); 1331 tcg_gen_mov_i32(dest, tmp); 1332 if (insn & (1 << 21)) 1333 store_reg(s, rd, tmp); 1334 else 1335 tcg_temp_free_i32(tmp); 1336 } else if (insn & (1 << 21)) { 1337 /* Post indexed */ 1338 tcg_gen_mov_i32(dest, tmp); 1339 if (insn & (1 << 23)) 1340 tcg_gen_addi_i32(tmp, tmp, offset); 1341 else 1342 tcg_gen_addi_i32(tmp, tmp, -offset); 1343 store_reg(s, rd, tmp); 1344 } else if (!(insn & (1 << 23))) 1345 return 1; 1346 return 0; 1347} 1348 1349static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest) 1350{ 1351 int rd = (insn >> 0) & 0xf; 1352 TCGv tmp; 1353 1354 if (insn & (1 << 8)) { 1355 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) { 1356 return 1; 1357 } else { 1358 tmp = iwmmxt_load_creg(rd); 1359 } 1360 } else { 1361 tmp = tcg_temp_new_i32(); 1362 iwmmxt_load_reg(cpu_V0, rd); 1363 tcg_gen_trunc_i64_i32(tmp, cpu_V0); 1364 } 1365 tcg_gen_andi_i32(tmp, tmp, mask); 1366 tcg_gen_mov_i32(dest, tmp); 1367 tcg_temp_free_i32(tmp); 1368 return 0; 1369} 1370 1371/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred 1372 (ie. an undefined instruction). */ 1373static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn) 1374{ 1375 int rd, wrd; 1376 int rdhi, rdlo, rd0, rd1, i; 1377 TCGv addr; 1378 TCGv tmp, tmp2, tmp3; 1379 1380 if ((insn & 0x0e000e00) == 0x0c000000) { 1381 if ((insn & 0x0fe00ff0) == 0x0c400000) { 1382 wrd = insn & 0xf; 1383 rdlo = (insn >> 12) & 0xf; 1384 rdhi = (insn >> 16) & 0xf; 1385 if (insn & ARM_CP_RW_BIT) { /* TMRRC */ 1386 iwmmxt_load_reg(cpu_V0, wrd); 1387 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0); 1388 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); 1389 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0); 1390 } else { /* TMCRR */ 1391 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); 1392 iwmmxt_store_reg(cpu_V0, wrd); 1393 gen_op_iwmmxt_set_mup(); 1394 } 1395 return 0; 1396 } 1397 1398 wrd = (insn >> 12) & 0xf; 1399 addr = tcg_temp_new_i32(); 1400 if (gen_iwmmxt_address(s, insn, addr)) { 1401 tcg_temp_free_i32(addr); 1402 return 1; 1403 } 1404 if (insn & ARM_CP_RW_BIT) { 1405 if ((insn >> 28) == 0xf) { /* WLDRW wCx */ 1406 tmp = tcg_temp_new_i32(); 1407 tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); 1408 iwmmxt_store_creg(wrd, tmp); 1409 } else { 1410 i = 1; 1411 if (insn & (1 << 8)) { 1412 if (insn & (1 << 22)) { /* WLDRD */ 1413 tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s)); 1414 i = 0; 1415 } else { /* WLDRW wRd */ 1416 tmp = gen_ld32(addr, IS_USER(s)); 1417 } 1418 } else { 1419 if (insn & (1 << 22)) { /* WLDRH */ 1420 tmp = gen_ld16u(addr, IS_USER(s)); 1421 } else { /* WLDRB */ 1422 tmp = gen_ld8u(addr, IS_USER(s)); 1423 } 1424 } 1425 if (i) { 1426 tcg_gen_extu_i32_i64(cpu_M0, tmp); 1427 tcg_temp_free_i32(tmp); 1428 } 1429 gen_op_iwmmxt_movq_wRn_M0(wrd); 1430 } 1431 } else { 1432 if ((insn >> 28) == 0xf) { /* WSTRW wCx */ 1433 tmp = iwmmxt_load_creg(wrd); 1434 gen_st32(tmp, addr, IS_USER(s)); 1435 } else { 1436 gen_op_iwmmxt_movq_M0_wRn(wrd); 1437 tmp = tcg_temp_new_i32(); 1438 if (insn & (1 << 8)) { 1439 if (insn & (1 << 22)) { /* WSTRD */ 1440 tcg_temp_free_i32(tmp); 1441 tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s)); 1442 } else { /* WSTRW wRd */ 1443 tcg_gen_trunc_i64_i32(tmp, cpu_M0); 1444 gen_st32(tmp, addr, IS_USER(s)); 1445 } 1446 } else { 1447 if (insn & (1 << 22)) { /* WSTRH */ 1448 tcg_gen_trunc_i64_i32(tmp, cpu_M0); 1449 gen_st16(tmp, addr, IS_USER(s)); 1450 } else { /* WSTRB */ 1451 tcg_gen_trunc_i64_i32(tmp, cpu_M0); 1452 gen_st8(tmp, addr, IS_USER(s)); 1453 } 1454 } 1455 } 1456 } 1457 tcg_temp_free_i32(addr); 1458 return 0; 1459 } 1460 1461 if ((insn & 0x0f000000) != 0x0e000000) 1462 return 1; 1463 1464 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) { 1465 case 0x000: /* WOR */ 1466 wrd = (insn >> 12) & 0xf; 1467 rd0 = (insn >> 0) & 0xf; 1468 rd1 = (insn >> 16) & 0xf; 1469 gen_op_iwmmxt_movq_M0_wRn(rd0); 1470 gen_op_iwmmxt_orq_M0_wRn(rd1); 1471 gen_op_iwmmxt_setpsr_nz(); 1472 gen_op_iwmmxt_movq_wRn_M0(wrd); 1473 gen_op_iwmmxt_set_mup(); 1474 gen_op_iwmmxt_set_cup(); 1475 break; 1476 case 0x011: /* TMCR */ 1477 if (insn & 0xf) 1478 return 1; 1479 rd = (insn >> 12) & 0xf; 1480 wrd = (insn >> 16) & 0xf; 1481 switch (wrd) { 1482 case ARM_IWMMXT_wCID: 1483 case ARM_IWMMXT_wCASF: 1484 break; 1485 case ARM_IWMMXT_wCon: 1486 gen_op_iwmmxt_set_cup(); 1487 /* Fall through. */ 1488 case ARM_IWMMXT_wCSSF: 1489 tmp = iwmmxt_load_creg(wrd); 1490 tmp2 = load_reg(s, rd); 1491 tcg_gen_andc_i32(tmp, tmp, tmp2); 1492 tcg_temp_free_i32(tmp2); 1493 iwmmxt_store_creg(wrd, tmp); 1494 break; 1495 case ARM_IWMMXT_wCGR0: 1496 case ARM_IWMMXT_wCGR1: 1497 case ARM_IWMMXT_wCGR2: 1498 case ARM_IWMMXT_wCGR3: 1499 gen_op_iwmmxt_set_cup(); 1500 tmp = load_reg(s, rd); 1501 iwmmxt_store_creg(wrd, tmp); 1502 break; 1503 default: 1504 return 1; 1505 } 1506 break; 1507 case 0x100: /* WXOR */ 1508 wrd = (insn >> 12) & 0xf; 1509 rd0 = (insn >> 0) & 0xf; 1510 rd1 = (insn >> 16) & 0xf; 1511 gen_op_iwmmxt_movq_M0_wRn(rd0); 1512 gen_op_iwmmxt_xorq_M0_wRn(rd1); 1513 gen_op_iwmmxt_setpsr_nz(); 1514 gen_op_iwmmxt_movq_wRn_M0(wrd); 1515 gen_op_iwmmxt_set_mup(); 1516 gen_op_iwmmxt_set_cup(); 1517 break; 1518 case 0x111: /* TMRC */ 1519 if (insn & 0xf) 1520 return 1; 1521 rd = (insn >> 12) & 0xf; 1522 wrd = (insn >> 16) & 0xf; 1523 tmp = iwmmxt_load_creg(wrd); 1524 store_reg(s, rd, tmp); 1525 break; 1526 case 0x300: /* WANDN */ 1527 wrd = (insn >> 12) & 0xf; 1528 rd0 = (insn >> 0) & 0xf; 1529 rd1 = (insn >> 16) & 0xf; 1530 gen_op_iwmmxt_movq_M0_wRn(rd0); 1531 tcg_gen_neg_i64(cpu_M0, cpu_M0); 1532 gen_op_iwmmxt_andq_M0_wRn(rd1); 1533 gen_op_iwmmxt_setpsr_nz(); 1534 gen_op_iwmmxt_movq_wRn_M0(wrd); 1535 gen_op_iwmmxt_set_mup(); 1536 gen_op_iwmmxt_set_cup(); 1537 break; 1538 case 0x200: /* WAND */ 1539 wrd = (insn >> 12) & 0xf; 1540 rd0 = (insn >> 0) & 0xf; 1541 rd1 = (insn >> 16) & 0xf; 1542 gen_op_iwmmxt_movq_M0_wRn(rd0); 1543 gen_op_iwmmxt_andq_M0_wRn(rd1); 1544 gen_op_iwmmxt_setpsr_nz(); 1545 gen_op_iwmmxt_movq_wRn_M0(wrd); 1546 gen_op_iwmmxt_set_mup(); 1547 gen_op_iwmmxt_set_cup(); 1548 break; 1549 case 0x810: case 0xa10: /* WMADD */ 1550 wrd = (insn >> 12) & 0xf; 1551 rd0 = (insn >> 0) & 0xf; 1552 rd1 = (insn >> 16) & 0xf; 1553 gen_op_iwmmxt_movq_M0_wRn(rd0); 1554 if (insn & (1 << 21)) 1555 gen_op_iwmmxt_maddsq_M0_wRn(rd1); 1556 else 1557 gen_op_iwmmxt_madduq_M0_wRn(rd1); 1558 gen_op_iwmmxt_movq_wRn_M0(wrd); 1559 gen_op_iwmmxt_set_mup(); 1560 break; 1561 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */ 1562 wrd = (insn >> 12) & 0xf; 1563 rd0 = (insn >> 16) & 0xf; 1564 rd1 = (insn >> 0) & 0xf; 1565 gen_op_iwmmxt_movq_M0_wRn(rd0); 1566 switch ((insn >> 22) & 3) { 1567 case 0: 1568 gen_op_iwmmxt_unpacklb_M0_wRn(rd1); 1569 break; 1570 case 1: 1571 gen_op_iwmmxt_unpacklw_M0_wRn(rd1); 1572 break; 1573 case 2: 1574 gen_op_iwmmxt_unpackll_M0_wRn(rd1); 1575 break; 1576 case 3: 1577 return 1; 1578 } 1579 gen_op_iwmmxt_movq_wRn_M0(wrd); 1580 gen_op_iwmmxt_set_mup(); 1581 gen_op_iwmmxt_set_cup(); 1582 break; 1583 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */ 1584 wrd = (insn >> 12) & 0xf; 1585 rd0 = (insn >> 16) & 0xf; 1586 rd1 = (insn >> 0) & 0xf; 1587 gen_op_iwmmxt_movq_M0_wRn(rd0); 1588 switch ((insn >> 22) & 3) { 1589 case 0: 1590 gen_op_iwmmxt_unpackhb_M0_wRn(rd1); 1591 break; 1592 case 1: 1593 gen_op_iwmmxt_unpackhw_M0_wRn(rd1); 1594 break; 1595 case 2: 1596 gen_op_iwmmxt_unpackhl_M0_wRn(rd1); 1597 break; 1598 case 3: 1599 return 1; 1600 } 1601 gen_op_iwmmxt_movq_wRn_M0(wrd); 1602 gen_op_iwmmxt_set_mup(); 1603 gen_op_iwmmxt_set_cup(); 1604 break; 1605 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */ 1606 wrd = (insn >> 12) & 0xf; 1607 rd0 = (insn >> 16) & 0xf; 1608 rd1 = (insn >> 0) & 0xf; 1609 gen_op_iwmmxt_movq_M0_wRn(rd0); 1610 if (insn & (1 << 22)) 1611 gen_op_iwmmxt_sadw_M0_wRn(rd1); 1612 else 1613 gen_op_iwmmxt_sadb_M0_wRn(rd1); 1614 if (!(insn & (1 << 20))) 1615 gen_op_iwmmxt_addl_M0_wRn(wrd); 1616 gen_op_iwmmxt_movq_wRn_M0(wrd); 1617 gen_op_iwmmxt_set_mup(); 1618 break; 1619 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */ 1620 wrd = (insn >> 12) & 0xf; 1621 rd0 = (insn >> 16) & 0xf; 1622 rd1 = (insn >> 0) & 0xf; 1623 gen_op_iwmmxt_movq_M0_wRn(rd0); 1624 if (insn & (1 << 21)) { 1625 if (insn & (1 << 20)) 1626 gen_op_iwmmxt_mulshw_M0_wRn(rd1); 1627 else 1628 gen_op_iwmmxt_mulslw_M0_wRn(rd1); 1629 } else { 1630 if (insn & (1 << 20)) 1631 gen_op_iwmmxt_muluhw_M0_wRn(rd1); 1632 else 1633 gen_op_iwmmxt_mululw_M0_wRn(rd1); 1634 } 1635 gen_op_iwmmxt_movq_wRn_M0(wrd); 1636 gen_op_iwmmxt_set_mup(); 1637 break; 1638 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */ 1639 wrd = (insn >> 12) & 0xf; 1640 rd0 = (insn >> 16) & 0xf; 1641 rd1 = (insn >> 0) & 0xf; 1642 gen_op_iwmmxt_movq_M0_wRn(rd0); 1643 if (insn & (1 << 21)) 1644 gen_op_iwmmxt_macsw_M0_wRn(rd1); 1645 else 1646 gen_op_iwmmxt_macuw_M0_wRn(rd1); 1647 if (!(insn & (1 << 20))) { 1648 iwmmxt_load_reg(cpu_V1, wrd); 1649 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); 1650 } 1651 gen_op_iwmmxt_movq_wRn_M0(wrd); 1652 gen_op_iwmmxt_set_mup(); 1653 break; 1654 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */ 1655 wrd = (insn >> 12) & 0xf; 1656 rd0 = (insn >> 16) & 0xf; 1657 rd1 = (insn >> 0) & 0xf; 1658 gen_op_iwmmxt_movq_M0_wRn(rd0); 1659 switch ((insn >> 22) & 3) { 1660 case 0: 1661 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1); 1662 break; 1663 case 1: 1664 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1); 1665 break; 1666 case 2: 1667 gen_op_iwmmxt_cmpeql_M0_wRn(rd1); 1668 break; 1669 case 3: 1670 return 1; 1671 } 1672 gen_op_iwmmxt_movq_wRn_M0(wrd); 1673 gen_op_iwmmxt_set_mup(); 1674 gen_op_iwmmxt_set_cup(); 1675 break; 1676 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */ 1677 wrd = (insn >> 12) & 0xf; 1678 rd0 = (insn >> 16) & 0xf; 1679 rd1 = (insn >> 0) & 0xf; 1680 gen_op_iwmmxt_movq_M0_wRn(rd0); 1681 if (insn & (1 << 22)) { 1682 if (insn & (1 << 20)) 1683 gen_op_iwmmxt_avgw1_M0_wRn(rd1); 1684 else 1685 gen_op_iwmmxt_avgw0_M0_wRn(rd1); 1686 } else { 1687 if (insn & (1 << 20)) 1688 gen_op_iwmmxt_avgb1_M0_wRn(rd1); 1689 else 1690 gen_op_iwmmxt_avgb0_M0_wRn(rd1); 1691 } 1692 gen_op_iwmmxt_movq_wRn_M0(wrd); 1693 gen_op_iwmmxt_set_mup(); 1694 gen_op_iwmmxt_set_cup(); 1695 break; 1696 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */ 1697 wrd = (insn >> 12) & 0xf; 1698 rd0 = (insn >> 16) & 0xf; 1699 rd1 = (insn >> 0) & 0xf; 1700 gen_op_iwmmxt_movq_M0_wRn(rd0); 1701 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3)); 1702 tcg_gen_andi_i32(tmp, tmp, 7); 1703 iwmmxt_load_reg(cpu_V1, rd1); 1704 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); 1705 tcg_temp_free_i32(tmp); 1706 gen_op_iwmmxt_movq_wRn_M0(wrd); 1707 gen_op_iwmmxt_set_mup(); 1708 break; 1709 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */ 1710 if (((insn >> 6) & 3) == 3) 1711 return 1; 1712 rd = (insn >> 12) & 0xf; 1713 wrd = (insn >> 16) & 0xf; 1714 tmp = load_reg(s, rd); 1715 gen_op_iwmmxt_movq_M0_wRn(wrd); 1716 switch ((insn >> 6) & 3) { 1717 case 0: 1718 tmp2 = tcg_const_i32(0xff); 1719 tmp3 = tcg_const_i32((insn & 7) << 3); 1720 break; 1721 case 1: 1722 tmp2 = tcg_const_i32(0xffff); 1723 tmp3 = tcg_const_i32((insn & 3) << 4); 1724 break; 1725 case 2: 1726 tmp2 = tcg_const_i32(0xffffffff); 1727 tmp3 = tcg_const_i32((insn & 1) << 5); 1728 break; 1729 default: 1730 TCGV_UNUSED(tmp2); 1731 TCGV_UNUSED(tmp3); 1732 } 1733 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3); 1734 tcg_temp_free(tmp3); 1735 tcg_temp_free(tmp2); 1736 tcg_temp_free_i32(tmp); 1737 gen_op_iwmmxt_movq_wRn_M0(wrd); 1738 gen_op_iwmmxt_set_mup(); 1739 break; 1740 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */ 1741 rd = (insn >> 12) & 0xf; 1742 wrd = (insn >> 16) & 0xf; 1743 if (rd == 15 || ((insn >> 22) & 3) == 3) 1744 return 1; 1745 gen_op_iwmmxt_movq_M0_wRn(wrd); 1746 tmp = tcg_temp_new_i32(); 1747 switch ((insn >> 22) & 3) { 1748 case 0: 1749 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3); 1750 tcg_gen_trunc_i64_i32(tmp, cpu_M0); 1751 if (insn & 8) { 1752 tcg_gen_ext8s_i32(tmp, tmp); 1753 } else { 1754 tcg_gen_andi_i32(tmp, tmp, 0xff); 1755 } 1756 break; 1757 case 1: 1758 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4); 1759 tcg_gen_trunc_i64_i32(tmp, cpu_M0); 1760 if (insn & 8) { 1761 tcg_gen_ext16s_i32(tmp, tmp); 1762 } else { 1763 tcg_gen_andi_i32(tmp, tmp, 0xffff); 1764 } 1765 break; 1766 case 2: 1767 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5); 1768 tcg_gen_trunc_i64_i32(tmp, cpu_M0); 1769 break; 1770 } 1771 store_reg(s, rd, tmp); 1772 break; 1773 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */ 1774 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3) 1775 return 1; 1776 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); 1777 switch ((insn >> 22) & 3) { 1778 case 0: 1779 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0); 1780 break; 1781 case 1: 1782 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4); 1783 break; 1784 case 2: 1785 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12); 1786 break; 1787 } 1788 tcg_gen_shli_i32(tmp, tmp, 28); 1789 gen_set_nzcv(tmp); 1790 tcg_temp_free_i32(tmp); 1791 break; 1792 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */ 1793 if (((insn >> 6) & 3) == 3) 1794 return 1; 1795 rd = (insn >> 12) & 0xf; 1796 wrd = (insn >> 16) & 0xf; 1797 tmp = load_reg(s, rd); 1798 switch ((insn >> 6) & 3) { 1799 case 0: 1800 gen_helper_iwmmxt_bcstb(cpu_M0, tmp); 1801 break; 1802 case 1: 1803 gen_helper_iwmmxt_bcstw(cpu_M0, tmp); 1804 break; 1805 case 2: 1806 gen_helper_iwmmxt_bcstl(cpu_M0, tmp); 1807 break; 1808 } 1809 tcg_temp_free_i32(tmp); 1810 gen_op_iwmmxt_movq_wRn_M0(wrd); 1811 gen_op_iwmmxt_set_mup(); 1812 break; 1813 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */ 1814 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) 1815 return 1; 1816 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); 1817 tmp2 = tcg_temp_new_i32(); 1818 tcg_gen_mov_i32(tmp2, tmp); 1819 switch ((insn >> 22) & 3) { 1820 case 0: 1821 for (i = 0; i < 7; i ++) { 1822 tcg_gen_shli_i32(tmp2, tmp2, 4); 1823 tcg_gen_and_i32(tmp, tmp, tmp2); 1824 } 1825 break; 1826 case 1: 1827 for (i = 0; i < 3; i ++) { 1828 tcg_gen_shli_i32(tmp2, tmp2, 8); 1829 tcg_gen_and_i32(tmp, tmp, tmp2); 1830 } 1831 break; 1832 case 2: 1833 tcg_gen_shli_i32(tmp2, tmp2, 16); 1834 tcg_gen_and_i32(tmp, tmp, tmp2); 1835 break; 1836 } 1837 gen_set_nzcv(tmp); 1838 tcg_temp_free_i32(tmp2); 1839 tcg_temp_free_i32(tmp); 1840 break; 1841 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */ 1842 wrd = (insn >> 12) & 0xf; 1843 rd0 = (insn >> 16) & 0xf; 1844 gen_op_iwmmxt_movq_M0_wRn(rd0); 1845 switch ((insn >> 22) & 3) { 1846 case 0: 1847 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0); 1848 break; 1849 case 1: 1850 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0); 1851 break; 1852 case 2: 1853 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0); 1854 break; 1855 case 3: 1856 return 1; 1857 } 1858 gen_op_iwmmxt_movq_wRn_M0(wrd); 1859 gen_op_iwmmxt_set_mup(); 1860 break; 1861 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */ 1862 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) 1863 return 1; 1864 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); 1865 tmp2 = tcg_temp_new_i32(); 1866 tcg_gen_mov_i32(tmp2, tmp); 1867 switch ((insn >> 22) & 3) { 1868 case 0: 1869 for (i = 0; i < 7; i ++) { 1870 tcg_gen_shli_i32(tmp2, tmp2, 4); 1871 tcg_gen_or_i32(tmp, tmp, tmp2); 1872 } 1873 break; 1874 case 1: 1875 for (i = 0; i < 3; i ++) { 1876 tcg_gen_shli_i32(tmp2, tmp2, 8); 1877 tcg_gen_or_i32(tmp, tmp, tmp2); 1878 } 1879 break; 1880 case 2: 1881 tcg_gen_shli_i32(tmp2, tmp2, 16); 1882 tcg_gen_or_i32(tmp, tmp, tmp2); 1883 break; 1884 } 1885 gen_set_nzcv(tmp); 1886 tcg_temp_free_i32(tmp2); 1887 tcg_temp_free_i32(tmp); 1888 break; 1889 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */ 1890 rd = (insn >> 12) & 0xf; 1891 rd0 = (insn >> 16) & 0xf; 1892 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3) 1893 return 1; 1894 gen_op_iwmmxt_movq_M0_wRn(rd0); 1895 tmp = tcg_temp_new_i32(); 1896 switch ((insn >> 22) & 3) { 1897 case 0: 1898 gen_helper_iwmmxt_msbb(tmp, cpu_M0); 1899 break; 1900 case 1: 1901 gen_helper_iwmmxt_msbw(tmp, cpu_M0); 1902 break; 1903 case 2: 1904 gen_helper_iwmmxt_msbl(tmp, cpu_M0); 1905 break; 1906 } 1907 store_reg(s, rd, tmp); 1908 break; 1909 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */ 1910 case 0x906: case 0xb06: case 0xd06: case 0xf06: 1911 wrd = (insn >> 12) & 0xf; 1912 rd0 = (insn >> 16) & 0xf; 1913 rd1 = (insn >> 0) & 0xf; 1914 gen_op_iwmmxt_movq_M0_wRn(rd0); 1915 switch ((insn >> 22) & 3) { 1916 case 0: 1917 if (insn & (1 << 21)) 1918 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1); 1919 else 1920 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1); 1921 break; 1922 case 1: 1923 if (insn & (1 << 21)) 1924 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1); 1925 else 1926 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1); 1927 break; 1928 case 2: 1929 if (insn & (1 << 21)) 1930 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1); 1931 else 1932 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1); 1933 break; 1934 case 3: 1935 return 1; 1936 } 1937 gen_op_iwmmxt_movq_wRn_M0(wrd); 1938 gen_op_iwmmxt_set_mup(); 1939 gen_op_iwmmxt_set_cup(); 1940 break; 1941 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */ 1942 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e: 1943 wrd = (insn >> 12) & 0xf; 1944 rd0 = (insn >> 16) & 0xf; 1945 gen_op_iwmmxt_movq_M0_wRn(rd0); 1946 switch ((insn >> 22) & 3) { 1947 case 0: 1948 if (insn & (1 << 21)) 1949 gen_op_iwmmxt_unpacklsb_M0(); 1950 else 1951 gen_op_iwmmxt_unpacklub_M0(); 1952 break; 1953 case 1: 1954 if (insn & (1 << 21)) 1955 gen_op_iwmmxt_unpacklsw_M0(); 1956 else 1957 gen_op_iwmmxt_unpackluw_M0(); 1958 break; 1959 case 2: 1960 if (insn & (1 << 21)) 1961 gen_op_iwmmxt_unpacklsl_M0(); 1962 else 1963 gen_op_iwmmxt_unpacklul_M0(); 1964 break; 1965 case 3: 1966 return 1; 1967 } 1968 gen_op_iwmmxt_movq_wRn_M0(wrd); 1969 gen_op_iwmmxt_set_mup(); 1970 gen_op_iwmmxt_set_cup(); 1971 break; 1972 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */ 1973 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c: 1974 wrd = (insn >> 12) & 0xf; 1975 rd0 = (insn >> 16) & 0xf; 1976 gen_op_iwmmxt_movq_M0_wRn(rd0); 1977 switch ((insn >> 22) & 3) { 1978 case 0: 1979 if (insn & (1 << 21)) 1980 gen_op_iwmmxt_unpackhsb_M0(); 1981 else 1982 gen_op_iwmmxt_unpackhub_M0(); 1983 break; 1984 case 1: 1985 if (insn & (1 << 21)) 1986 gen_op_iwmmxt_unpackhsw_M0(); 1987 else 1988 gen_op_iwmmxt_unpackhuw_M0(); 1989 break; 1990 case 2: 1991 if (insn & (1 << 21)) 1992 gen_op_iwmmxt_unpackhsl_M0(); 1993 else 1994 gen_op_iwmmxt_unpackhul_M0(); 1995 break; 1996 case 3: 1997 return 1; 1998 } 1999 gen_op_iwmmxt_movq_wRn_M0(wrd); 2000 gen_op_iwmmxt_set_mup(); 2001 gen_op_iwmmxt_set_cup(); 2002 break; 2003 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */ 2004 case 0x214: case 0x614: case 0xa14: case 0xe14: 2005 if (((insn >> 22) & 3) == 0) 2006 return 1; 2007 wrd = (insn >> 12) & 0xf; 2008 rd0 = (insn >> 16) & 0xf; 2009 gen_op_iwmmxt_movq_M0_wRn(rd0); 2010 tmp = tcg_temp_new_i32(); 2011 if (gen_iwmmxt_shift(insn, 0xff, tmp)) { 2012 tcg_temp_free_i32(tmp); 2013 return 1; 2014 } 2015 switch ((insn >> 22) & 3) { 2016 case 1: 2017 gen_helper_iwmmxt_srlw(cpu_M0, cpu_M0, tmp); 2018 break; 2019 case 2: 2020 gen_helper_iwmmxt_srll(cpu_M0, cpu_M0, tmp); 2021 break; 2022 case 3: 2023 gen_helper_iwmmxt_srlq(cpu_M0, cpu_M0, tmp); 2024 break; 2025 } 2026 tcg_temp_free_i32(tmp); 2027 gen_op_iwmmxt_movq_wRn_M0(wrd); 2028 gen_op_iwmmxt_set_mup(); 2029 gen_op_iwmmxt_set_cup(); 2030 break; 2031 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */ 2032 case 0x014: case 0x414: case 0x814: case 0xc14: 2033 if (((insn >> 22) & 3) == 0) 2034 return 1; 2035 wrd = (insn >> 12) & 0xf; 2036 rd0 = (insn >> 16) & 0xf; 2037 gen_op_iwmmxt_movq_M0_wRn(rd0); 2038 tmp = tcg_temp_new_i32(); 2039 if (gen_iwmmxt_shift(insn, 0xff, tmp)) { 2040 tcg_temp_free_i32(tmp); 2041 return 1; 2042 } 2043 switch ((insn >> 22) & 3) { 2044 case 1: 2045 gen_helper_iwmmxt_sraw(cpu_M0, cpu_M0, tmp); 2046 break; 2047 case 2: 2048 gen_helper_iwmmxt_sral(cpu_M0, cpu_M0, tmp); 2049 break; 2050 case 3: 2051 gen_helper_iwmmxt_sraq(cpu_M0, cpu_M0, tmp); 2052 break; 2053 } 2054 tcg_temp_free_i32(tmp); 2055 gen_op_iwmmxt_movq_wRn_M0(wrd); 2056 gen_op_iwmmxt_set_mup(); 2057 gen_op_iwmmxt_set_cup(); 2058 break; 2059 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */ 2060 case 0x114: case 0x514: case 0x914: case 0xd14: 2061 if (((insn >> 22) & 3) == 0) 2062 return 1; 2063 wrd = (insn >> 12) & 0xf; 2064 rd0 = (insn >> 16) & 0xf; 2065 gen_op_iwmmxt_movq_M0_wRn(rd0); 2066 tmp = tcg_temp_new_i32(); 2067 if (gen_iwmmxt_shift(insn, 0xff, tmp)) { 2068 tcg_temp_free_i32(tmp); 2069 return 1; 2070 } 2071 switch ((insn >> 22) & 3) { 2072 case 1: 2073 gen_helper_iwmmxt_sllw(cpu_M0, cpu_M0, tmp); 2074 break; 2075 case 2: 2076 gen_helper_iwmmxt_slll(cpu_M0, cpu_M0, tmp); 2077 break; 2078 case 3: 2079 gen_helper_iwmmxt_sllq(cpu_M0, cpu_M0, tmp); 2080 break; 2081 } 2082 tcg_temp_free_i32(tmp); 2083 gen_op_iwmmxt_movq_wRn_M0(wrd); 2084 gen_op_iwmmxt_set_mup(); 2085 gen_op_iwmmxt_set_cup(); 2086 break; 2087 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */ 2088 case 0x314: case 0x714: case 0xb14: case 0xf14: 2089 if (((insn >> 22) & 3) == 0) 2090 return 1; 2091 wrd = (insn >> 12) & 0xf; 2092 rd0 = (insn >> 16) & 0xf; 2093 gen_op_iwmmxt_movq_M0_wRn(rd0); 2094 tmp = tcg_temp_new_i32(); 2095 switch ((insn >> 22) & 3) { 2096 case 1: 2097 if (gen_iwmmxt_shift(insn, 0xf, tmp)) { 2098 tcg_temp_free_i32(tmp); 2099 return 1; 2100 } 2101 gen_helper_iwmmxt_rorw(cpu_M0, cpu_M0, tmp); 2102 break; 2103 case 2: 2104 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) { 2105 tcg_temp_free_i32(tmp); 2106 return 1; 2107 } 2108 gen_helper_iwmmxt_rorl(cpu_M0, cpu_M0, tmp); 2109 break; 2110 case 3: 2111 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) { 2112 tcg_temp_free_i32(tmp); 2113 return 1; 2114 } 2115 gen_helper_iwmmxt_rorq(cpu_M0, cpu_M0, tmp); 2116 break; 2117 } 2118 tcg_temp_free_i32(tmp); 2119 gen_op_iwmmxt_movq_wRn_M0(wrd); 2120 gen_op_iwmmxt_set_mup(); 2121 gen_op_iwmmxt_set_cup(); 2122 break; 2123 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */ 2124 case 0x916: case 0xb16: case 0xd16: case 0xf16: 2125 wrd = (insn >> 12) & 0xf; 2126 rd0 = (insn >> 16) & 0xf; 2127 rd1 = (insn >> 0) & 0xf; 2128 gen_op_iwmmxt_movq_M0_wRn(rd0); 2129 switch ((insn >> 22) & 3) { 2130 case 0: 2131 if (insn & (1 << 21)) 2132 gen_op_iwmmxt_minsb_M0_wRn(rd1); 2133 else 2134 gen_op_iwmmxt_minub_M0_wRn(rd1); 2135 break; 2136 case 1: 2137 if (insn & (1 << 21)) 2138 gen_op_iwmmxt_minsw_M0_wRn(rd1); 2139 else 2140 gen_op_iwmmxt_minuw_M0_wRn(rd1); 2141 break; 2142 case 2: 2143 if (insn & (1 << 21)) 2144 gen_op_iwmmxt_minsl_M0_wRn(rd1); 2145 else 2146 gen_op_iwmmxt_minul_M0_wRn(rd1); 2147 break; 2148 case 3: 2149 return 1; 2150 } 2151 gen_op_iwmmxt_movq_wRn_M0(wrd); 2152 gen_op_iwmmxt_set_mup(); 2153 break; 2154 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */ 2155 case 0x816: case 0xa16: case 0xc16: case 0xe16: 2156 wrd = (insn >> 12) & 0xf; 2157 rd0 = (insn >> 16) & 0xf; 2158 rd1 = (insn >> 0) & 0xf; 2159 gen_op_iwmmxt_movq_M0_wRn(rd0); 2160 switch ((insn >> 22) & 3) { 2161 case 0: 2162 if (insn & (1 << 21)) 2163 gen_op_iwmmxt_maxsb_M0_wRn(rd1); 2164 else 2165 gen_op_iwmmxt_maxub_M0_wRn(rd1); 2166 break; 2167 case 1: 2168 if (insn & (1 << 21)) 2169 gen_op_iwmmxt_maxsw_M0_wRn(rd1); 2170 else 2171 gen_op_iwmmxt_maxuw_M0_wRn(rd1); 2172 break; 2173 case 2: 2174 if (insn & (1 << 21)) 2175 gen_op_iwmmxt_maxsl_M0_wRn(rd1); 2176 else 2177 gen_op_iwmmxt_maxul_M0_wRn(rd1); 2178 break; 2179 case 3: 2180 return 1; 2181 } 2182 gen_op_iwmmxt_movq_wRn_M0(wrd); 2183 gen_op_iwmmxt_set_mup(); 2184 break; 2185 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */ 2186 case 0x402: case 0x502: case 0x602: case 0x702: 2187 wrd = (insn >> 12) & 0xf; 2188 rd0 = (insn >> 16) & 0xf; 2189 rd1 = (insn >> 0) & 0xf; 2190 gen_op_iwmmxt_movq_M0_wRn(rd0); 2191 tmp = tcg_const_i32((insn >> 20) & 3); 2192 iwmmxt_load_reg(cpu_V1, rd1); 2193 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); 2194 tcg_temp_free(tmp); 2195 gen_op_iwmmxt_movq_wRn_M0(wrd); 2196 gen_op_iwmmxt_set_mup(); 2197 break; 2198 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */ 2199 case 0x41a: case 0x51a: case 0x61a: case 0x71a: 2200 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a: 2201 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a: 2202 wrd = (insn >> 12) & 0xf; 2203 rd0 = (insn >> 16) & 0xf; 2204 rd1 = (insn >> 0) & 0xf; 2205 gen_op_iwmmxt_movq_M0_wRn(rd0); 2206 switch ((insn >> 20) & 0xf) { 2207 case 0x0: 2208 gen_op_iwmmxt_subnb_M0_wRn(rd1); 2209 break; 2210 case 0x1: 2211 gen_op_iwmmxt_subub_M0_wRn(rd1); 2212 break; 2213 case 0x3: 2214 gen_op_iwmmxt_subsb_M0_wRn(rd1); 2215 break; 2216 case 0x4: 2217 gen_op_iwmmxt_subnw_M0_wRn(rd1); 2218 break; 2219 case 0x5: 2220 gen_op_iwmmxt_subuw_M0_wRn(rd1); 2221 break; 2222 case 0x7: 2223 gen_op_iwmmxt_subsw_M0_wRn(rd1); 2224 break; 2225 case 0x8: 2226 gen_op_iwmmxt_subnl_M0_wRn(rd1); 2227 break; 2228 case 0x9: 2229 gen_op_iwmmxt_subul_M0_wRn(rd1); 2230 break; 2231 case 0xb: 2232 gen_op_iwmmxt_subsl_M0_wRn(rd1); 2233 break; 2234 default: 2235 return 1; 2236 } 2237 gen_op_iwmmxt_movq_wRn_M0(wrd); 2238 gen_op_iwmmxt_set_mup(); 2239 gen_op_iwmmxt_set_cup(); 2240 break; 2241 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */ 2242 case 0x41e: case 0x51e: case 0x61e: case 0x71e: 2243 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e: 2244 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e: 2245 wrd = (insn >> 12) & 0xf; 2246 rd0 = (insn >> 16) & 0xf; 2247 gen_op_iwmmxt_movq_M0_wRn(rd0); 2248 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f)); 2249 gen_helper_iwmmxt_shufh(cpu_M0, cpu_M0, tmp); 2250 tcg_temp_free(tmp); 2251 gen_op_iwmmxt_movq_wRn_M0(wrd); 2252 gen_op_iwmmxt_set_mup(); 2253 gen_op_iwmmxt_set_cup(); 2254 break; 2255 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */ 2256 case 0x418: case 0x518: case 0x618: case 0x718: 2257 case 0x818: case 0x918: case 0xa18: case 0xb18: 2258 case 0xc18: case 0xd18: case 0xe18: case 0xf18: 2259 wrd = (insn >> 12) & 0xf; 2260 rd0 = (insn >> 16) & 0xf; 2261 rd1 = (insn >> 0) & 0xf; 2262 gen_op_iwmmxt_movq_M0_wRn(rd0); 2263 switch ((insn >> 20) & 0xf) { 2264 case 0x0: 2265 gen_op_iwmmxt_addnb_M0_wRn(rd1); 2266 break; 2267 case 0x1: 2268 gen_op_iwmmxt_addub_M0_wRn(rd1); 2269 break; 2270 case 0x3: 2271 gen_op_iwmmxt_addsb_M0_wRn(rd1); 2272 break; 2273 case 0x4: 2274 gen_op_iwmmxt_addnw_M0_wRn(rd1); 2275 break; 2276 case 0x5: 2277 gen_op_iwmmxt_adduw_M0_wRn(rd1); 2278 break; 2279 case 0x7: 2280 gen_op_iwmmxt_addsw_M0_wRn(rd1); 2281 break; 2282 case 0x8: 2283 gen_op_iwmmxt_addnl_M0_wRn(rd1); 2284 break; 2285 case 0x9: 2286 gen_op_iwmmxt_addul_M0_wRn(rd1); 2287 break; 2288 case 0xb: 2289 gen_op_iwmmxt_addsl_M0_wRn(rd1); 2290 break; 2291 default: 2292 return 1; 2293 } 2294 gen_op_iwmmxt_movq_wRn_M0(wrd); 2295 gen_op_iwmmxt_set_mup(); 2296 gen_op_iwmmxt_set_cup(); 2297 break; 2298 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */ 2299 case 0x408: case 0x508: case 0x608: case 0x708: 2300 case 0x808: case 0x908: case 0xa08: case 0xb08: 2301 case 0xc08: case 0xd08: case 0xe08: case 0xf08: 2302 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0) 2303 return 1; 2304 wrd = (insn >> 12) & 0xf; 2305 rd0 = (insn >> 16) & 0xf; 2306 rd1 = (insn >> 0) & 0xf; 2307 gen_op_iwmmxt_movq_M0_wRn(rd0); 2308 switch ((insn >> 22) & 3) { 2309 case 1: 2310 if (insn & (1 << 21)) 2311 gen_op_iwmmxt_packsw_M0_wRn(rd1); 2312 else 2313 gen_op_iwmmxt_packuw_M0_wRn(rd1); 2314 break; 2315 case 2: 2316 if (insn & (1 << 21)) 2317 gen_op_iwmmxt_packsl_M0_wRn(rd1); 2318 else 2319 gen_op_iwmmxt_packul_M0_wRn(rd1); 2320 break; 2321 case 3: 2322 if (insn & (1 << 21)) 2323 gen_op_iwmmxt_packsq_M0_wRn(rd1); 2324 else 2325 gen_op_iwmmxt_packuq_M0_wRn(rd1); 2326 break; 2327 } 2328 gen_op_iwmmxt_movq_wRn_M0(wrd); 2329 gen_op_iwmmxt_set_mup(); 2330 gen_op_iwmmxt_set_cup(); 2331 break; 2332 case 0x201: case 0x203: case 0x205: case 0x207: 2333 case 0x209: case 0x20b: case 0x20d: case 0x20f: 2334 case 0x211: case 0x213: case 0x215: case 0x217: 2335 case 0x219: case 0x21b: case 0x21d: case 0x21f: 2336 wrd = (insn >> 5) & 0xf; 2337 rd0 = (insn >> 12) & 0xf; 2338 rd1 = (insn >> 0) & 0xf; 2339 if (rd0 == 0xf || rd1 == 0xf) 2340 return 1; 2341 gen_op_iwmmxt_movq_M0_wRn(wrd); 2342 tmp = load_reg(s, rd0); 2343 tmp2 = load_reg(s, rd1); 2344 switch ((insn >> 16) & 0xf) { 2345 case 0x0: /* TMIA */ 2346 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); 2347 break; 2348 case 0x8: /* TMIAPH */ 2349 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); 2350 break; 2351 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */ 2352 if (insn & (1 << 16)) 2353 tcg_gen_shri_i32(tmp, tmp, 16); 2354 if (insn & (1 << 17)) 2355 tcg_gen_shri_i32(tmp2, tmp2, 16); 2356 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); 2357 break; 2358 default: 2359 tcg_temp_free_i32(tmp2); 2360 tcg_temp_free_i32(tmp); 2361 return 1; 2362 } 2363 tcg_temp_free_i32(tmp2); 2364 tcg_temp_free_i32(tmp); 2365 gen_op_iwmmxt_movq_wRn_M0(wrd); 2366 gen_op_iwmmxt_set_mup(); 2367 break; 2368 default: 2369 return 1; 2370 } 2371 2372 return 0; 2373} 2374 2375/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred 2376 (ie. an undefined instruction). */ 2377static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn) 2378{ 2379 int acc, rd0, rd1, rdhi, rdlo; 2380 TCGv tmp, tmp2; 2381 2382 if ((insn & 0x0ff00f10) == 0x0e200010) { 2383 /* Multiply with Internal Accumulate Format */ 2384 rd0 = (insn >> 12) & 0xf; 2385 rd1 = insn & 0xf; 2386 acc = (insn >> 5) & 7; 2387 2388 if (acc != 0) 2389 return 1; 2390 2391 tmp = load_reg(s, rd0); 2392 tmp2 = load_reg(s, rd1); 2393 switch ((insn >> 16) & 0xf) { 2394 case 0x0: /* MIA */ 2395 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); 2396 break; 2397 case 0x8: /* MIAPH */ 2398 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); 2399 break; 2400 case 0xc: /* MIABB */ 2401 case 0xd: /* MIABT */ 2402 case 0xe: /* MIATB */ 2403 case 0xf: /* MIATT */ 2404 if (insn & (1 << 16)) 2405 tcg_gen_shri_i32(tmp, tmp, 16); 2406 if (insn & (1 << 17)) 2407 tcg_gen_shri_i32(tmp2, tmp2, 16); 2408 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); 2409 break; 2410 default: 2411 return 1; 2412 } 2413 tcg_temp_free_i32(tmp2); 2414 tcg_temp_free_i32(tmp); 2415 2416 gen_op_iwmmxt_movq_wRn_M0(acc); 2417 return 0; 2418 } 2419 2420 if ((insn & 0x0fe00ff8) == 0x0c400000) { 2421 /* Internal Accumulator Access Format */ 2422 rdhi = (insn >> 16) & 0xf; 2423 rdlo = (insn >> 12) & 0xf; 2424 acc = insn & 7; 2425 2426 if (acc != 0) 2427 return 1; 2428 2429 if (insn & ARM_CP_RW_BIT) { /* MRA */ 2430 iwmmxt_load_reg(cpu_V0, acc); 2431 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0); 2432 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); 2433 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0); 2434 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1); 2435 } else { /* MAR */ 2436 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); 2437 iwmmxt_store_reg(cpu_V0, acc); 2438 } 2439 return 0; 2440 } 2441 2442 return 1; 2443} 2444 2445/* Disassemble system coprocessor instruction. Return nonzero if 2446 instruction is not defined. */ 2447static int disas_cp_insn(CPUARMState *env, DisasContext *s, uint32_t insn) 2448{ 2449 TCGv tmp, tmp2; 2450 uint32_t rd = (insn >> 12) & 0xf; 2451 uint32_t cp = (insn >> 8) & 0xf; 2452 2453 if (insn & ARM_CP_RW_BIT) { 2454 if (!env->cp[cp].cp_read) 2455 return 1; 2456 gen_set_pc_im(s->pc); 2457 tmp = tcg_temp_new_i32(); 2458 tmp2 = tcg_const_i32(insn); 2459 gen_helper_get_cp(tmp, cpu_env, tmp2); 2460 tcg_temp_free(tmp2); 2461 store_reg(s, rd, tmp); 2462 } else { 2463 if (!env->cp[cp].cp_write) 2464 return 1; 2465 gen_set_pc_im(s->pc); 2466 tmp = load_reg(s, rd); 2467 tmp2 = tcg_const_i32(insn); 2468 gen_helper_set_cp(cpu_env, tmp2, tmp); 2469 tcg_temp_free(tmp2); 2470 tcg_temp_free_i32(tmp); 2471 } 2472 return 0; 2473} 2474 2475static int cp15_user_ok(uint32_t insn) 2476{ 2477 int cpn = (insn >> 16) & 0xf; 2478 int cpm = insn & 0xf; 2479 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38); 2480 2481 if (cpn == 13 && cpm == 0) { 2482 /* TLS register. */ 2483 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT))) 2484 return 1; 2485 } 2486 if (cpn == 7) { 2487 /* ISB, DSB, DMB. */ 2488 if ((cpm == 5 && op == 4) 2489 || (cpm == 10 && (op == 4 || op == 5))) 2490 return 1; 2491 } 2492 return 0; 2493} 2494 2495static int cp15_tls_load_store(CPUARMState *env, DisasContext *s, uint32_t insn, uint32_t rd) 2496{ 2497 TCGv tmp; 2498 int cpn = (insn >> 16) & 0xf; 2499 int cpm = insn & 0xf; 2500 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38); 2501 2502 if (!arm_feature(env, ARM_FEATURE_V6K)) 2503 return 0; 2504 2505 if (!(cpn == 13 && cpm == 0)) 2506 return 0; 2507 2508 if (insn & ARM_CP_RW_BIT) { 2509 switch (op) { 2510 case 2: 2511 tmp = load_cpu_field(cp15.c13_tls1); 2512 break; 2513 case 3: 2514 tmp = load_cpu_field(cp15.c13_tls2); 2515 break; 2516 case 4: 2517 tmp = load_cpu_field(cp15.c13_tls3); 2518 break; 2519 default: 2520 return 0; 2521 } 2522 store_reg(s, rd, tmp); 2523 2524 } else { 2525 tmp = load_reg(s, rd); 2526 switch (op) { 2527 case 2: 2528 store_cpu_field(tmp, cp15.c13_tls1); 2529 break; 2530 case 3: 2531 store_cpu_field(tmp, cp15.c13_tls2); 2532 break; 2533 case 4: 2534 store_cpu_field(tmp, cp15.c13_tls3); 2535 break; 2536 default: 2537 tcg_temp_free_i32(tmp); 2538 return 0; 2539 } 2540 } 2541 return 1; 2542} 2543 2544/* Disassemble system coprocessor (cp15) instruction. Return nonzero if 2545 instruction is not defined. */ 2546static int disas_cp15_insn(CPUARMState *env, DisasContext *s, uint32_t insn) 2547{ 2548 uint32_t rd; 2549 TCGv tmp, tmp2; 2550 2551 /* M profile cores use memory mapped registers instead of cp15. */ 2552 if (arm_feature(env, ARM_FEATURE_M)) 2553 return 1; 2554 2555 if ((insn & (1 << 25)) == 0) { 2556 if (insn & (1 << 20)) { 2557 /* mrrc */ 2558 return 1; 2559 } 2560 /* mcrr. Used for block cache operations, so implement as no-op. */ 2561 return 0; 2562 } 2563 if ((insn & (1 << 4)) == 0) { 2564 /* cdp */ 2565 return 1; 2566 } 2567 if (IS_USER(s) && !cp15_user_ok(insn)) { 2568 return 1; 2569 } 2570 2571 /* Pre-v7 versions of the architecture implemented WFI via coprocessor 2572 * instructions rather than a separate instruction. 2573 */ 2574 if ((insn & 0x0fff0fff) == 0x0e070f90) { 2575 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores). 2576 * In v7, this must NOP. 2577 */ 2578 if (!arm_feature(env, ARM_FEATURE_V7)) { 2579 /* Wait for interrupt. */ 2580 gen_set_pc_im(s->pc); 2581 s->is_jmp = DISAS_WFI; 2582 } 2583 return 0; 2584 } 2585 2586 if ((insn & 0x0fff0fff) == 0x0e070f58) { 2587 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI, 2588 * so this is slightly over-broad. 2589 */ 2590 if (!arm_feature(env, ARM_FEATURE_V6)) { 2591 /* Wait for interrupt. */ 2592 gen_set_pc_im(s->pc); 2593 s->is_jmp = DISAS_WFI; 2594 return 0; 2595 } 2596 /* Otherwise fall through to handle via helper function. 2597 * In particular, on v7 and some v6 cores this is one of 2598 * the VA-PA registers. 2599 */ 2600 } 2601 2602 rd = (insn >> 12) & 0xf; 2603 2604 if (cp15_tls_load_store(env, s, insn, rd)) 2605 return 0; 2606 2607 tmp2 = tcg_const_i32(insn); 2608 if (insn & ARM_CP_RW_BIT) { 2609 tmp = tcg_temp_new_i32(); 2610 gen_helper_get_cp15(tmp, cpu_env, tmp2); 2611 /* If the destination register is r15 then sets condition codes. */ 2612 if (rd != 15) 2613 store_reg(s, rd, tmp); 2614 else 2615 tcg_temp_free_i32(tmp); 2616 } else { 2617 tmp = load_reg(s, rd); 2618 gen_helper_set_cp15(cpu_env, tmp2, tmp); 2619 tcg_temp_free_i32(tmp); 2620 /* Normally we would always end the TB here, but Linux 2621 * arch/arm/mach-pxa/sleep.S expects two instructions following 2622 * an MMU enable to execute from cache. Imitate this behaviour. */ 2623 if (!arm_feature(env, ARM_FEATURE_XSCALE) || 2624 (insn & 0x0fff0fff) != 0x0e010f10) 2625 gen_lookup_tb(s); 2626 } 2627 tcg_temp_free_i32(tmp2); 2628 return 0; 2629} 2630 2631#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n)) 2632#define VFP_SREG(insn, bigbit, smallbit) \ 2633 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1)) 2634#define VFP_DREG(reg, insn, bigbit, smallbit) do { \ 2635 if (arm_feature(env, ARM_FEATURE_VFP3)) { \ 2636 reg = (((insn) >> (bigbit)) & 0x0f) \ 2637 | (((insn) >> ((smallbit) - 4)) & 0x10); \ 2638 } else { \ 2639 if (insn & (1 << (smallbit))) \ 2640 return 1; \ 2641 reg = ((insn) >> (bigbit)) & 0x0f; \ 2642 }} while (0) 2643 2644#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22) 2645#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22) 2646#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7) 2647#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7) 2648#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5) 2649#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5) 2650 2651/* Move between integer and VFP cores. */ 2652static TCGv gen_vfp_mrs(void) 2653{ 2654 TCGv tmp = tcg_temp_new_i32(); 2655 tcg_gen_mov_i32(tmp, cpu_F0s); 2656 return tmp; 2657} 2658 2659static void gen_vfp_msr(TCGv tmp) 2660{ 2661 tcg_gen_mov_i32(cpu_F0s, tmp); 2662 tcg_temp_free_i32(tmp); 2663} 2664 2665static void gen_neon_dup_u8(TCGv var, int shift) 2666{ 2667 TCGv tmp = tcg_temp_new_i32(); 2668 if (shift) 2669 tcg_gen_shri_i32(var, var, shift); 2670 tcg_gen_ext8u_i32(var, var); 2671 tcg_gen_shli_i32(tmp, var, 8); 2672 tcg_gen_or_i32(var, var, tmp); 2673 tcg_gen_shli_i32(tmp, var, 16); 2674 tcg_gen_or_i32(var, var, tmp); 2675 tcg_temp_free_i32(tmp); 2676} 2677 2678static void gen_neon_dup_low16(TCGv var) 2679{ 2680 TCGv tmp = tcg_temp_new_i32(); 2681 tcg_gen_ext16u_i32(var, var); 2682 tcg_gen_shli_i32(tmp, var, 16); 2683 tcg_gen_or_i32(var, var, tmp); 2684 tcg_temp_free_i32(tmp); 2685} 2686 2687static void gen_neon_dup_high16(TCGv var) 2688{ 2689 TCGv tmp = tcg_temp_new_i32(); 2690 tcg_gen_andi_i32(var, var, 0xffff0000); 2691 tcg_gen_shri_i32(tmp, var, 16); 2692 tcg_gen_or_i32(var, var, tmp); 2693 tcg_temp_free_i32(tmp); 2694} 2695 2696static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size) 2697{ 2698 /* Load a single Neon element and replicate into a 32 bit TCG reg */ 2699 TCGv tmp; 2700 switch (size) { 2701 case 0: 2702 tmp = gen_ld8u(addr, IS_USER(s)); 2703 gen_neon_dup_u8(tmp, 0); 2704 break; 2705 case 1: 2706 tmp = gen_ld16u(addr, IS_USER(s)); 2707 gen_neon_dup_low16(tmp); 2708 break; 2709 case 2: 2710 tmp = gen_ld32(addr, IS_USER(s)); 2711 break; 2712 default: /* Avoid compiler warnings. */ 2713 abort(); 2714 } 2715 return tmp; 2716} 2717 2718/* Disassemble a VFP instruction. Returns nonzero if an error occurred 2719 (ie. an undefined instruction). */ 2720static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) 2721{ 2722 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; 2723 int dp, veclen; 2724 TCGv addr; 2725 TCGv tmp; 2726 TCGv tmp2; 2727 2728 if (!arm_feature(env, ARM_FEATURE_VFP)) 2729 return 1; 2730 2731 if (!s->vfp_enabled) { 2732 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ 2733 if ((insn & 0x0fe00fff) != 0x0ee00a10) 2734 return 1; 2735 rn = (insn >> 16) & 0xf; 2736 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC 2737 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) 2738 return 1; 2739 } 2740 dp = ((insn & 0xf00) == 0xb00); 2741 switch ((insn >> 24) & 0xf) { 2742 case 0xe: 2743 if (insn & (1 << 4)) { 2744 /* single register transfer */ 2745 rd = (insn >> 12) & 0xf; 2746 if (dp) { 2747 int size; 2748 int pass; 2749 2750 VFP_DREG_N(rn, insn); 2751 if (insn & 0xf) 2752 return 1; 2753 if (insn & 0x00c00060 2754 && !arm_feature(env, ARM_FEATURE_NEON)) 2755 return 1; 2756 2757 pass = (insn >> 21) & 1; 2758 if (insn & (1 << 22)) { 2759 size = 0; 2760 offset = ((insn >> 5) & 3) * 8; 2761 } else if (insn & (1 << 5)) { 2762 size = 1; 2763 offset = (insn & (1 << 6)) ? 16 : 0; 2764 } else { 2765 size = 2; 2766 offset = 0; 2767 } 2768 if (insn & ARM_CP_RW_BIT) { 2769 /* vfp->arm */ 2770 tmp = neon_load_reg(rn, pass); 2771 switch (size) { 2772 case 0: 2773 if (offset) 2774 tcg_gen_shri_i32(tmp, tmp, offset); 2775 if (insn & (1 << 23)) 2776 gen_uxtb(tmp); 2777 else 2778 gen_sxtb(tmp); 2779 break; 2780 case 1: 2781 if (insn & (1 << 23)) { 2782 if (offset) { 2783 tcg_gen_shri_i32(tmp, tmp, 16); 2784 } else { 2785 gen_uxth(tmp); 2786 } 2787 } else { 2788 if (offset) { 2789 tcg_gen_sari_i32(tmp, tmp, 16); 2790 } else { 2791 gen_sxth(tmp); 2792 } 2793 } 2794 break; 2795 case 2: 2796 break; 2797 } 2798 store_reg(s, rd, tmp); 2799 } else { 2800 /* arm->vfp */ 2801 tmp = load_reg(s, rd); 2802 if (insn & (1 << 23)) { 2803 /* VDUP */ 2804 if (size == 0) { 2805 gen_neon_dup_u8(tmp, 0); 2806 } else if (size == 1) { 2807 gen_neon_dup_low16(tmp); 2808 } 2809 for (n = 0; n <= pass * 2; n++) { 2810 tmp2 = tcg_temp_new_i32(); 2811 tcg_gen_mov_i32(tmp2, tmp); 2812 neon_store_reg(rn, n, tmp2); 2813 } 2814 neon_store_reg(rn, n, tmp); 2815 } else { 2816 /* VMOV */ 2817 switch (size) { 2818 case 0: 2819 tmp2 = neon_load_reg(rn, pass); 2820 gen_bfi(tmp, tmp2, tmp, offset, 0xff); 2821 tcg_temp_free_i32(tmp2); 2822 break; 2823 case 1: 2824 tmp2 = neon_load_reg(rn, pass); 2825 gen_bfi(tmp, tmp2, tmp, offset, 0xffff); 2826 tcg_temp_free_i32(tmp2); 2827 break; 2828 case 2: 2829 break; 2830 } 2831 neon_store_reg(rn, pass, tmp); 2832 } 2833 } 2834 } else { /* !dp */ 2835 if ((insn & 0x6f) != 0x00) 2836 return 1; 2837 rn = VFP_SREG_N(insn); 2838 if (insn & ARM_CP_RW_BIT) { 2839 /* vfp->arm */ 2840 if (insn & (1 << 21)) { 2841 /* system register */ 2842 rn >>= 1; 2843 2844 switch (rn) { 2845 case ARM_VFP_FPSID: 2846 /* VFP2 allows access to FSID from userspace. 2847 VFP3 restricts all id registers to privileged 2848 accesses. */ 2849 if (IS_USER(s) 2850 && arm_feature(env, ARM_FEATURE_VFP3)) 2851 return 1; 2852 tmp = load_cpu_field(vfp.xregs[rn]); 2853 break; 2854 case ARM_VFP_FPEXC: 2855 if (IS_USER(s)) 2856 return 1; 2857 tmp = load_cpu_field(vfp.xregs[rn]); 2858 break; 2859 case ARM_VFP_FPINST: 2860 case ARM_VFP_FPINST2: 2861 /* Not present in VFP3. */ 2862 if (IS_USER(s) 2863 || arm_feature(env, ARM_FEATURE_VFP3)) 2864 return 1; 2865 tmp = load_cpu_field(vfp.xregs[rn]); 2866 break; 2867 case ARM_VFP_FPSCR: 2868 if (rd == 15) { 2869 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); 2870 tcg_gen_andi_i32(tmp, tmp, 0xf0000000); 2871 } else { 2872 tmp = tcg_temp_new_i32(); 2873 gen_helper_vfp_get_fpscr(tmp, cpu_env); 2874 } 2875 break; 2876 case ARM_VFP_MVFR0: 2877 case ARM_VFP_MVFR1: 2878 if (IS_USER(s) 2879 || !arm_feature(env, ARM_FEATURE_VFP3)) 2880 return 1; 2881 tmp = load_cpu_field(vfp.xregs[rn]); 2882 break; 2883 default: 2884 return 1; 2885 } 2886 } else { 2887 gen_mov_F0_vreg(0, rn); 2888 tmp = gen_vfp_mrs(); 2889 } 2890 if (rd == 15) { 2891 /* Set the 4 flag bits in the CPSR. */ 2892 gen_set_nzcv(tmp); 2893 tcg_temp_free_i32(tmp); 2894 } else { 2895 store_reg(s, rd, tmp); 2896 } 2897 } else { 2898 /* arm->vfp */ 2899 tmp = load_reg(s, rd); 2900 if (insn & (1 << 21)) { 2901 rn >>= 1; 2902 /* system register */ 2903 switch (rn) { 2904 case ARM_VFP_FPSID: 2905 case ARM_VFP_MVFR0: 2906 case ARM_VFP_MVFR1: 2907 /* Writes are ignored. */ 2908 break; 2909 case ARM_VFP_FPSCR: 2910 gen_helper_vfp_set_fpscr(cpu_env, tmp); 2911 tcg_temp_free_i32(tmp); 2912 gen_lookup_tb(s); 2913 break; 2914 case ARM_VFP_FPEXC: 2915 if (IS_USER(s)) 2916 return 1; 2917 /* TODO: VFP subarchitecture support. 2918 * For now, keep the EN bit only */ 2919 tcg_gen_andi_i32(tmp, tmp, 1 << 30); 2920 store_cpu_field(tmp, vfp.xregs[rn]); 2921 gen_lookup_tb(s); 2922 break; 2923 case ARM_VFP_FPINST: 2924 case ARM_VFP_FPINST2: 2925 store_cpu_field(tmp, vfp.xregs[rn]); 2926 break; 2927 default: 2928 return 1; 2929 } 2930 } else { 2931 gen_vfp_msr(tmp); 2932 gen_mov_vreg_F0(0, rn); 2933 } 2934 } 2935 } 2936 } else { 2937 /* data processing */ 2938 /* The opcode is in bits 23, 21, 20 and 6. */ 2939 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1); 2940 if (dp) { 2941 if (op == 15) { 2942 /* rn is opcode */ 2943 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1); 2944 } else { 2945 /* rn is register number */ 2946 VFP_DREG_N(rn, insn); 2947 } 2948 2949 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) { 2950 /* Integer or single precision destination. */ 2951 rd = VFP_SREG_D(insn); 2952 } else { 2953 VFP_DREG_D(rd, insn); 2954 } 2955 if (op == 15 && 2956 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) { 2957 /* VCVT from int is always from S reg regardless of dp bit. 2958 * VCVT with immediate frac_bits has same format as SREG_M 2959 */ 2960 rm = VFP_SREG_M(insn); 2961 } else { 2962 VFP_DREG_M(rm, insn); 2963 } 2964 } else { 2965 rn = VFP_SREG_N(insn); 2966 if (op == 15 && rn == 15) { 2967 /* Double precision destination. */ 2968 VFP_DREG_D(rd, insn); 2969 } else { 2970 rd = VFP_SREG_D(insn); 2971 } 2972 /* NB that we implicitly rely on the encoding for the frac_bits 2973 * in VCVT of fixed to float being the same as that of an SREG_M 2974 */ 2975 rm = VFP_SREG_M(insn); 2976 } 2977 2978 veclen = s->vec_len; 2979 if (op == 15 && rn > 3) 2980 veclen = 0; 2981 2982 /* Shut up compiler warnings. */ 2983 delta_m = 0; 2984 delta_d = 0; 2985 bank_mask = 0; 2986 2987 if (veclen > 0) { 2988 if (dp) 2989 bank_mask = 0xc; 2990 else 2991 bank_mask = 0x18; 2992 2993 /* Figure out what type of vector operation this is. */ 2994 if ((rd & bank_mask) == 0) { 2995 /* scalar */ 2996 veclen = 0; 2997 } else { 2998 if (dp) 2999 delta_d = (s->vec_stride >> 1) + 1; 3000 else 3001 delta_d = s->vec_stride + 1; 3002 3003 if ((rm & bank_mask) == 0) { 3004 /* mixed scalar/vector */ 3005 delta_m = 0; 3006 } else { 3007 /* vector */ 3008 delta_m = delta_d; 3009 } 3010 } 3011 } 3012 3013 /* Load the initial operands. */ 3014 if (op == 15) { 3015 switch (rn) { 3016 case 16: 3017 case 17: 3018 /* Integer source */ 3019 gen_mov_F0_vreg(0, rm); 3020 break; 3021 case 8: 3022 case 9: 3023 /* Compare */ 3024 gen_mov_F0_vreg(dp, rd); 3025 gen_mov_F1_vreg(dp, rm); 3026 break; 3027 case 10: 3028 case 11: 3029 /* Compare with zero */ 3030 gen_mov_F0_vreg(dp, rd); 3031 gen_vfp_F1_ld0(dp); 3032 break; 3033 case 20: 3034 case 21: 3035 case 22: 3036 case 23: 3037 case 28: 3038 case 29: 3039 case 30: 3040 case 31: 3041 /* Source and destination the same. */ 3042 gen_mov_F0_vreg(dp, rd); 3043 break; 3044 default: 3045 /* One source operand. */ 3046 gen_mov_F0_vreg(dp, rm); 3047 break; 3048 } 3049 } else { 3050 /* Two source operands. */ 3051 gen_mov_F0_vreg(dp, rn); 3052 gen_mov_F1_vreg(dp, rm); 3053 } 3054 3055 for (;;) { 3056 /* Perform the calculation. */ 3057 switch (op) { 3058 case 0: /* VMLA: fd + (fn * fm) */ 3059 /* Note that order of inputs to the add matters for NaNs */ 3060 gen_vfp_F1_mul(dp); 3061 gen_mov_F0_vreg(dp, rd); 3062 gen_vfp_add(dp); 3063 break; 3064 case 1: /* VMLS: fd + -(fn * fm) */ 3065 gen_vfp_mul(dp); 3066 gen_vfp_F1_neg(dp); 3067 gen_mov_F0_vreg(dp, rd); 3068 gen_vfp_add(dp); 3069 break; 3070 case 2: /* VNMLS: -fd + (fn * fm) */ 3071 /* Note that it isn't valid to replace (-A + B) with (B - A) 3072 * or similar plausible looking simplifications 3073 * because this will give wrong results for NaNs. 3074 */ 3075 gen_vfp_F1_mul(dp); 3076 gen_mov_F0_vreg(dp, rd); 3077 gen_vfp_neg(dp); 3078 gen_vfp_add(dp); 3079 break; 3080 case 3: /* VNMLA: -fd + -(fn * fm) */ 3081 gen_vfp_mul(dp); 3082 gen_vfp_F1_neg(dp); 3083 gen_mov_F0_vreg(dp, rd); 3084 gen_vfp_neg(dp); 3085 gen_vfp_add(dp); 3086 break; 3087 case 4: /* mul: fn * fm */ 3088 gen_vfp_mul(dp); 3089 break; 3090 case 5: /* nmul: -(fn * fm) */ 3091 gen_vfp_mul(dp); 3092 gen_vfp_neg(dp); 3093 break; 3094 case 6: /* add: fn + fm */ 3095 gen_vfp_add(dp); 3096 break; 3097 case 7: /* sub: fn - fm */ 3098 gen_vfp_sub(dp); 3099 break; 3100 case 8: /* div: fn / fm */ 3101 gen_vfp_div(dp); 3102 break; 3103 case 14: /* fconst */ 3104 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3105 return 1; 3106 3107 n = (insn << 12) & 0x80000000; 3108 i = ((insn >> 12) & 0x70) | (insn & 0xf); 3109 if (dp) { 3110 if (i & 0x40) 3111 i |= 0x3f80; 3112 else 3113 i |= 0x4000; 3114 n |= i << 16; 3115 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32); 3116 } else { 3117 if (i & 0x40) 3118 i |= 0x780; 3119 else 3120 i |= 0x800; 3121 n |= i << 19; 3122 tcg_gen_movi_i32(cpu_F0s, n); 3123 } 3124 break; 3125 case 15: /* extension space */ 3126 switch (rn) { 3127 case 0: /* cpy */ 3128 /* no-op */ 3129 break; 3130 case 1: /* abs */ 3131 gen_vfp_abs(dp); 3132 break; 3133 case 2: /* neg */ 3134 gen_vfp_neg(dp); 3135 break; 3136 case 3: /* sqrt */ 3137 gen_vfp_sqrt(dp); 3138 break; 3139 case 4: /* vcvtb.f32.f16 */ 3140 if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) 3141 return 1; 3142 tmp = gen_vfp_mrs(); 3143 tcg_gen_ext16u_i32(tmp, tmp); 3144 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); 3145 tcg_temp_free_i32(tmp); 3146 break; 3147 case 5: /* vcvtt.f32.f16 */ 3148 if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) 3149 return 1; 3150 tmp = gen_vfp_mrs(); 3151 tcg_gen_shri_i32(tmp, tmp, 16); 3152 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); 3153 tcg_temp_free_i32(tmp); 3154 break; 3155 case 6: /* vcvtb.f16.f32 */ 3156 if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) 3157 return 1; 3158 tmp = tcg_temp_new_i32(); 3159 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); 3160 gen_mov_F0_vreg(0, rd); 3161 tmp2 = gen_vfp_mrs(); 3162 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); 3163 tcg_gen_or_i32(tmp, tmp, tmp2); 3164 tcg_temp_free_i32(tmp2); 3165 gen_vfp_msr(tmp); 3166 break; 3167 case 7: /* vcvtt.f16.f32 */ 3168 if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) 3169 return 1; 3170 tmp = tcg_temp_new_i32(); 3171 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); 3172 tcg_gen_shli_i32(tmp, tmp, 16); 3173 gen_mov_F0_vreg(0, rd); 3174 tmp2 = gen_vfp_mrs(); 3175 tcg_gen_ext16u_i32(tmp2, tmp2); 3176 tcg_gen_or_i32(tmp, tmp, tmp2); 3177 tcg_temp_free_i32(tmp2); 3178 gen_vfp_msr(tmp); 3179 break; 3180 case 8: /* cmp */ 3181 gen_vfp_cmp(dp); 3182 break; 3183 case 9: /* cmpe */ 3184 gen_vfp_cmpe(dp); 3185 break; 3186 case 10: /* cmpz */ 3187 gen_vfp_cmp(dp); 3188 break; 3189 case 11: /* cmpez */ 3190 gen_vfp_F1_ld0(dp); 3191 gen_vfp_cmpe(dp); 3192 break; 3193 case 15: /* single<->double conversion */ 3194 if (dp) 3195 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); 3196 else 3197 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); 3198 break; 3199 case 16: /* fuito */ 3200 gen_vfp_uito(dp, 0); 3201 break; 3202 case 17: /* fsito */ 3203 gen_vfp_sito(dp, 0); 3204 break; 3205 case 20: /* fshto */ 3206 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3207 return 1; 3208 gen_vfp_shto(dp, 16 - rm, 0); 3209 break; 3210 case 21: /* fslto */ 3211 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3212 return 1; 3213 gen_vfp_slto(dp, 32 - rm, 0); 3214 break; 3215 case 22: /* fuhto */ 3216 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3217 return 1; 3218 gen_vfp_uhto(dp, 16 - rm, 0); 3219 break; 3220 case 23: /* fulto */ 3221 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3222 return 1; 3223 gen_vfp_ulto(dp, 32 - rm, 0); 3224 break; 3225 case 24: /* ftoui */ 3226 gen_vfp_toui(dp, 0); 3227 break; 3228 case 25: /* ftouiz */ 3229 gen_vfp_touiz(dp, 0); 3230 break; 3231 case 26: /* ftosi */ 3232 gen_vfp_tosi(dp, 0); 3233 break; 3234 case 27: /* ftosiz */ 3235 gen_vfp_tosiz(dp, 0); 3236 break; 3237 case 28: /* ftosh */ 3238 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3239 return 1; 3240 gen_vfp_tosh(dp, 16 - rm, 0); 3241 break; 3242 case 29: /* ftosl */ 3243 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3244 return 1; 3245 gen_vfp_tosl(dp, 32 - rm, 0); 3246 break; 3247 case 30: /* ftouh */ 3248 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3249 return 1; 3250 gen_vfp_touh(dp, 16 - rm, 0); 3251 break; 3252 case 31: /* ftoul */ 3253 if (!arm_feature(env, ARM_FEATURE_VFP3)) 3254 return 1; 3255 gen_vfp_toul(dp, 32 - rm, 0); 3256 break; 3257 default: /* undefined */ 3258 printf ("rn:%d\n", rn); 3259 return 1; 3260 } 3261 break; 3262 default: /* undefined */ 3263 printf ("op:%d\n", op); 3264 return 1; 3265 } 3266 3267 /* Write back the result. */ 3268 if (op == 15 && (rn >= 8 && rn <= 11)) 3269 ; /* Comparison, do nothing. */ 3270 else if (op == 15 && dp && ((rn & 0x1c) == 0x18)) 3271 /* VCVT double to int: always integer result. */ 3272 gen_mov_vreg_F0(0, rd); 3273 else if (op == 15 && rn == 15) 3274 /* conversion */ 3275 gen_mov_vreg_F0(!dp, rd); 3276 else 3277 gen_mov_vreg_F0(dp, rd); 3278 3279 /* break out of the loop if we have finished */ 3280 if (veclen == 0) 3281 break; 3282 3283 if (op == 15 && delta_m == 0) { 3284 /* single source one-many */ 3285 while (veclen--) { 3286 rd = ((rd + delta_d) & (bank_mask - 1)) 3287 | (rd & bank_mask); 3288 gen_mov_vreg_F0(dp, rd); 3289 } 3290 break; 3291 } 3292 /* Setup the next operands. */ 3293 veclen--; 3294 rd = ((rd + delta_d) & (bank_mask - 1)) 3295 | (rd & bank_mask); 3296 3297 if (op == 15) { 3298 /* One source operand. */ 3299 rm = ((rm + delta_m) & (bank_mask - 1)) 3300 | (rm & bank_mask); 3301 gen_mov_F0_vreg(dp, rm); 3302 } else { 3303 /* Two source operands. */ 3304 rn = ((rn + delta_d) & (bank_mask - 1)) 3305 | (rn & bank_mask); 3306 gen_mov_F0_vreg(dp, rn); 3307 if (delta_m) { 3308 rm = ((rm + delta_m) & (bank_mask - 1)) 3309 | (rm & bank_mask); 3310 gen_mov_F1_vreg(dp, rm); 3311 } 3312 } 3313 } 3314 } 3315 break; 3316 case 0xc: 3317 case 0xd: 3318 if ((insn & 0x03e00000) == 0x00400000) { 3319 /* two-register transfer */ 3320 rn = (insn >> 16) & 0xf; 3321 rd = (insn >> 12) & 0xf; 3322 if (dp) { 3323 VFP_DREG_M(rm, insn); 3324 } else { 3325 rm = VFP_SREG_M(insn); 3326 } 3327 3328 if (insn & ARM_CP_RW_BIT) { 3329 /* vfp->arm */ 3330 if (dp) { 3331 gen_mov_F0_vreg(0, rm * 2); 3332 tmp = gen_vfp_mrs(); 3333 store_reg(s, rd, tmp); 3334 gen_mov_F0_vreg(0, rm * 2 + 1); 3335 tmp = gen_vfp_mrs(); 3336 store_reg(s, rn, tmp); 3337 } else { 3338 gen_mov_F0_vreg(0, rm); 3339 tmp = gen_vfp_mrs(); 3340 store_reg(s, rd, tmp); 3341 gen_mov_F0_vreg(0, rm + 1); 3342 tmp = gen_vfp_mrs(); 3343 store_reg(s, rn, tmp); 3344 } 3345 } else { 3346 /* arm->vfp */ 3347 if (dp) { 3348 tmp = load_reg(s, rd); 3349 gen_vfp_msr(tmp); 3350 gen_mov_vreg_F0(0, rm * 2); 3351 tmp = load_reg(s, rn); 3352 gen_vfp_msr(tmp); 3353 gen_mov_vreg_F0(0, rm * 2 + 1); 3354 } else { 3355 tmp = load_reg(s, rd); 3356 gen_vfp_msr(tmp); 3357 gen_mov_vreg_F0(0, rm); 3358 tmp = load_reg(s, rn); 3359 gen_vfp_msr(tmp); 3360 gen_mov_vreg_F0(0, rm + 1); 3361 } 3362 } 3363 } else { 3364 /* Load/store */ 3365 rn = (insn >> 16) & 0xf; 3366 if (dp) 3367 VFP_DREG_D(rd, insn); 3368 else 3369 rd = VFP_SREG_D(insn); 3370 if (s->thumb && rn == 15) { 3371 addr = tcg_temp_new_i32(); 3372 tcg_gen_movi_i32(addr, s->pc & ~2); 3373 } else { 3374 addr = load_reg(s, rn); 3375 } 3376 if ((insn & 0x01200000) == 0x01000000) { 3377 /* Single load/store */ 3378 offset = (insn & 0xff) << 2; 3379 if ((insn & (1 << 23)) == 0) 3380 offset = -offset; 3381 tcg_gen_addi_i32(addr, addr, offset); 3382 if (insn & (1 << 20)) { 3383 gen_vfp_ld(s, dp, addr); 3384 gen_mov_vreg_F0(dp, rd); 3385 } else { 3386 gen_mov_F0_vreg(dp, rd); 3387 gen_vfp_st(s, dp, addr); 3388 } 3389 tcg_temp_free_i32(addr); 3390 } else { 3391 /* load/store multiple */ 3392 if (dp) 3393 n = (insn >> 1) & 0x7f; 3394 else 3395 n = insn & 0xff; 3396 3397 if (insn & (1 << 24)) /* pre-decrement */ 3398 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); 3399 3400 if (dp) 3401 offset = 8; 3402 else 3403 offset = 4; 3404 tmp = tcg_const_i32(offset); 3405 for (i = 0; i < n; i++) { 3406 if (insn & ARM_CP_RW_BIT) { 3407 /* load */ 3408 gen_vfp_ld(s, dp, addr); 3409 gen_mov_vreg_F0(dp, rd + i); 3410 } else { 3411 /* store */ 3412 gen_mov_F0_vreg(dp, rd + i); 3413 gen_vfp_st(s, dp, addr); 3414 } 3415 tcg_gen_add_i32(addr, addr, tmp); 3416 } 3417 tcg_temp_free_i32(tmp); 3418 if (insn & (1 << 21)) { 3419 /* writeback */ 3420 if (insn & (1 << 24)) 3421 offset = -offset * n; 3422 else if (dp && (insn & 1)) 3423 offset = 4; 3424 else 3425 offset = 0; 3426 3427 if (offset != 0) 3428 tcg_gen_addi_i32(addr, addr, offset); 3429 store_reg(s, rn, addr); 3430 } else { 3431 tcg_temp_free_i32(addr); 3432 } 3433 } 3434 } 3435 break; 3436 default: 3437 /* Should never happen. */ 3438 return 1; 3439 } 3440 return 0; 3441} 3442 3443static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest) 3444{ 3445 TranslationBlock *tb; 3446 3447 tb = s->tb; 3448 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { 3449 tcg_gen_goto_tb(n); 3450 gen_set_pc_im(dest); 3451 tcg_gen_exit_tb((tcg_target_long)tb + n); 3452 } else { 3453 gen_set_pc_im(dest); 3454 tcg_gen_exit_tb(0); 3455 } 3456} 3457 3458static inline void gen_jmp (DisasContext *s, uint32_t dest) 3459{ 3460 if (unlikely(s->singlestep_enabled)) { 3461 /* An indirect jump so that we still trigger the debug exception. */ 3462 if (s->thumb) 3463 dest |= 1; 3464 gen_bx_im(s, dest); 3465 } else { 3466 gen_goto_tb(s, 0, dest); 3467 s->is_jmp = DISAS_TB_JUMP; 3468 } 3469} 3470 3471static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y) 3472{ 3473 if (x) 3474 tcg_gen_sari_i32(t0, t0, 16); 3475 else 3476 gen_sxth(t0); 3477 if (y) 3478 tcg_gen_sari_i32(t1, t1, 16); 3479 else 3480 gen_sxth(t1); 3481 tcg_gen_mul_i32(t0, t0, t1); 3482} 3483 3484/* Return the mask of PSR bits set by a MSR instruction. */ 3485static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) { 3486 uint32_t mask; 3487 3488 mask = 0; 3489 if (flags & (1 << 0)) 3490 mask |= 0xff; 3491 if (flags & (1 << 1)) 3492 mask |= 0xff00; 3493 if (flags & (1 << 2)) 3494 mask |= 0xff0000; 3495 if (flags & (1 << 3)) 3496 mask |= 0xff000000; 3497 3498 /* Mask out undefined bits. */ 3499 mask &= ~CPSR_RESERVED; 3500 if (!arm_feature(env, ARM_FEATURE_V4T)) 3501 mask &= ~CPSR_T; 3502 if (!arm_feature(env, ARM_FEATURE_V5)) 3503 mask &= ~CPSR_Q; /* V5TE in reality*/ 3504 if (!arm_feature(env, ARM_FEATURE_V6)) 3505 mask &= ~(CPSR_E | CPSR_GE); 3506 if (!arm_feature(env, ARM_FEATURE_THUMB2)) 3507 mask &= ~CPSR_IT; 3508 /* Mask out execution state bits. */ 3509 if (!spsr) 3510 mask &= ~CPSR_EXEC; 3511 /* Mask out privileged bits. */ 3512 if (IS_USER(s)) 3513 mask &= CPSR_USER; 3514 return mask; 3515} 3516 3517/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */ 3518static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0) 3519{ 3520 TCGv tmp; 3521 if (spsr) { 3522 /* ??? This is also undefined in system mode. */ 3523 if (IS_USER(s)) 3524 return 1; 3525 3526 tmp = load_cpu_field(spsr); 3527 tcg_gen_andi_i32(tmp, tmp, ~mask); 3528 tcg_gen_andi_i32(t0, t0, mask); 3529 tcg_gen_or_i32(tmp, tmp, t0); 3530 store_cpu_field(tmp, spsr); 3531 } else { 3532 gen_set_cpsr(t0, mask); 3533 } 3534 tcg_temp_free_i32(t0); 3535 gen_lookup_tb(s); 3536 return 0; 3537} 3538 3539/* Returns nonzero if access to the PSR is not permitted. */ 3540static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val) 3541{ 3542 TCGv tmp; 3543 tmp = tcg_temp_new_i32(); 3544 tcg_gen_movi_i32(tmp, val); 3545 return gen_set_psr(s, mask, spsr, tmp); 3546} 3547 3548/* Generate an old-style exception return. Marks pc as dead. */ 3549static void gen_exception_return(DisasContext *s, TCGv pc) 3550{ 3551 TCGv tmp; 3552 store_reg(s, 15, pc); 3553 tmp = load_cpu_field(spsr); 3554 gen_set_cpsr(tmp, 0xffffffff); 3555 tcg_temp_free_i32(tmp); 3556 s->is_jmp = DISAS_UPDATE; 3557} 3558 3559/* Generate a v6 exception return. Marks both values as dead. */ 3560static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr) 3561{ 3562 gen_set_cpsr(cpsr, 0xffffffff); 3563 tcg_temp_free_i32(cpsr); 3564 store_reg(s, 15, pc); 3565 s->is_jmp = DISAS_UPDATE; 3566} 3567 3568static inline void 3569gen_set_condexec (DisasContext *s) 3570{ 3571 if (s->condexec_mask) { 3572 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); 3573 TCGv tmp = tcg_temp_new_i32(); 3574 tcg_gen_movi_i32(tmp, val); 3575 store_cpu_field(tmp, condexec_bits); 3576 } 3577} 3578 3579static void gen_exception_insn(DisasContext *s, int offset, int excp) 3580{ 3581 gen_set_condexec(s); 3582 gen_set_pc_im(s->pc - offset); 3583 gen_exception(excp); 3584 s->is_jmp = DISAS_JUMP; 3585} 3586 3587static void gen_nop_hint(DisasContext *s, int val) 3588{ 3589 switch (val) { 3590 case 3: /* wfi */ 3591 gen_set_pc_im(s->pc); 3592 s->is_jmp = DISAS_WFI; 3593 break; 3594 case 2: /* wfe */ 3595 case 4: /* sev */ 3596 /* TODO: Implement SEV and WFE. May help SMP performance. */ 3597 default: /* nop */ 3598 break; 3599 } 3600} 3601 3602#define CPU_V001 cpu_V0, cpu_V0, cpu_V1 3603 3604static inline void gen_neon_add(int size, TCGv t0, TCGv t1) 3605{ 3606 switch (size) { 3607 case 0: gen_helper_neon_add_u8(t0, t0, t1); break; 3608 case 1: gen_helper_neon_add_u16(t0, t0, t1); break; 3609 case 2: tcg_gen_add_i32(t0, t0, t1); break; 3610 default: abort(); 3611 } 3612} 3613 3614static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1) 3615{ 3616 switch (size) { 3617 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break; 3618 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break; 3619 case 2: tcg_gen_sub_i32(t0, t1, t0); break; 3620 default: return; 3621 } 3622} 3623 3624/* 32-bit pairwise ops end up the same as the elementwise versions. */ 3625#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32 3626#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32 3627#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32 3628#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32 3629 3630#define GEN_NEON_INTEGER_OP(name) do { \ 3631 switch ((size << 1) | u) { \ 3632 case 0: \ 3633 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \ 3634 break; \ 3635 case 1: \ 3636 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \ 3637 break; \ 3638 case 2: \ 3639 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \ 3640 break; \ 3641 case 3: \ 3642 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \ 3643 break; \ 3644 case 4: \ 3645 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \ 3646 break; \ 3647 case 5: \ 3648 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \ 3649 break; \ 3650 default: return 1; \ 3651 }} while (0) 3652 3653static TCGv neon_load_scratch(int scratch) 3654{ 3655 TCGv tmp = tcg_temp_new_i32(); 3656 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); 3657 return tmp; 3658} 3659 3660static void neon_store_scratch(int scratch, TCGv var) 3661{ 3662 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); 3663 tcg_temp_free_i32(var); 3664} 3665 3666static inline TCGv neon_get_scalar(int size, int reg) 3667{ 3668 TCGv tmp; 3669 if (size == 1) { 3670 tmp = neon_load_reg(reg & 7, reg >> 4); 3671 if (reg & 8) { 3672 gen_neon_dup_high16(tmp); 3673 } else { 3674 gen_neon_dup_low16(tmp); 3675 } 3676 } else { 3677 tmp = neon_load_reg(reg & 15, reg >> 4); 3678 } 3679 return tmp; 3680} 3681 3682static int gen_neon_unzip(int rd, int rm, int size, int q) 3683{ 3684 TCGv tmp, tmp2; 3685 if (!q && size == 2) { 3686 return 1; 3687 } 3688 tmp = tcg_const_i32(rd); 3689 tmp2 = tcg_const_i32(rm); 3690 if (q) { 3691 switch (size) { 3692 case 0: 3693 gen_helper_neon_qunzip8(tmp, tmp2); 3694 break; 3695 case 1: 3696 gen_helper_neon_qunzip16(tmp, tmp2); 3697 break; 3698 case 2: 3699 gen_helper_neon_qunzip32(tmp, tmp2); 3700 break; 3701 default: 3702 abort(); 3703 } 3704 } else { 3705 switch (size) { 3706 case 0: 3707 gen_helper_neon_unzip8(tmp, tmp2); 3708 break; 3709 case 1: 3710 gen_helper_neon_unzip16(tmp, tmp2); 3711 break; 3712 default: 3713 abort(); 3714 } 3715 } 3716 tcg_temp_free_i32(tmp); 3717 tcg_temp_free_i32(tmp2); 3718 return 0; 3719} 3720 3721static int gen_neon_zip(int rd, int rm, int size, int q) 3722{ 3723 TCGv tmp, tmp2; 3724 if (!q && size == 2) { 3725 return 1; 3726 } 3727 tmp = tcg_const_i32(rd); 3728 tmp2 = tcg_const_i32(rm); 3729 if (q) { 3730 switch (size) { 3731 case 0: 3732 gen_helper_neon_qzip8(tmp, tmp2); 3733 break; 3734 case 1: 3735 gen_helper_neon_qzip16(tmp, tmp2); 3736 break; 3737 case 2: 3738 gen_helper_neon_qzip32(tmp, tmp2); 3739 break; 3740 default: 3741 abort(); 3742 } 3743 } else { 3744 switch (size) { 3745 case 0: 3746 gen_helper_neon_zip8(tmp, tmp2); 3747 break; 3748 case 1: 3749 gen_helper_neon_zip16(tmp, tmp2); 3750 break; 3751 default: 3752 abort(); 3753 } 3754 } 3755 tcg_temp_free_i32(tmp); 3756 tcg_temp_free_i32(tmp2); 3757 return 0; 3758} 3759 3760static void gen_neon_trn_u8(TCGv t0, TCGv t1) 3761{ 3762 TCGv rd, tmp; 3763 3764 rd = tcg_temp_new_i32(); 3765 tmp = tcg_temp_new_i32(); 3766 3767 tcg_gen_shli_i32(rd, t0, 8); 3768 tcg_gen_andi_i32(rd, rd, 0xff00ff00); 3769 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); 3770 tcg_gen_or_i32(rd, rd, tmp); 3771 3772 tcg_gen_shri_i32(t1, t1, 8); 3773 tcg_gen_andi_i32(t1, t1, 0x00ff00ff); 3774 tcg_gen_andi_i32(tmp, t0, 0xff00ff00); 3775 tcg_gen_or_i32(t1, t1, tmp); 3776 tcg_gen_mov_i32(t0, rd); 3777 3778 tcg_temp_free_i32(tmp); 3779 tcg_temp_free_i32(rd); 3780} 3781 3782static void gen_neon_trn_u16(TCGv t0, TCGv t1) 3783{ 3784 TCGv rd, tmp; 3785 3786 rd = tcg_temp_new_i32(); 3787 tmp = tcg_temp_new_i32(); 3788 3789 tcg_gen_shli_i32(rd, t0, 16); 3790 tcg_gen_andi_i32(tmp, t1, 0xffff); 3791 tcg_gen_or_i32(rd, rd, tmp); 3792 tcg_gen_shri_i32(t1, t1, 16); 3793 tcg_gen_andi_i32(tmp, t0, 0xffff0000); 3794 tcg_gen_or_i32(t1, t1, tmp); 3795 tcg_gen_mov_i32(t0, rd); 3796 3797 tcg_temp_free_i32(tmp); 3798 tcg_temp_free_i32(rd); 3799} 3800 3801 3802static struct { 3803 int nregs; 3804 int interleave; 3805 int spacing; 3806} neon_ls_element_type[11] = { 3807 {4, 4, 1}, 3808 {4, 4, 2}, 3809 {4, 1, 1}, 3810 {4, 2, 1}, 3811 {3, 3, 1}, 3812 {3, 3, 2}, 3813 {3, 1, 1}, 3814 {1, 1, 1}, 3815 {2, 2, 1}, 3816 {2, 2, 2}, 3817 {2, 1, 1} 3818}; 3819 3820/* Translate a NEON load/store element instruction. Return nonzero if the 3821 instruction is invalid. */ 3822static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn) 3823{ 3824 int rd, rn, rm; 3825 int op; 3826 int nregs; 3827 int interleave; 3828 int spacing; 3829 int stride; 3830 int size; 3831 int reg; 3832 int pass; 3833 int load; 3834 int shift; 3835 TCGv addr; 3836 TCGv tmp; 3837 TCGv tmp2; 3838 3839 if (!s->vfp_enabled) 3840 return 1; 3841 VFP_DREG_D(rd, insn); 3842 rn = (insn >> 16) & 0xf; 3843 rm = insn & 0xf; 3844 load = (insn & (1 << 21)) != 0; 3845 if ((insn & (1 << 23)) == 0) { 3846 /* Load store all elements. */ 3847 op = (insn >> 8) & 0xf; 3848 size = (insn >> 6) & 3; 3849 if (op > 10) 3850 return 1; 3851 /* Catch UNDEF cases for bad values of align field */ 3852 switch (op & 0xc) { 3853 case 4: 3854 if (((insn >> 5) & 1) == 1) { 3855 return 1; 3856 } 3857 break; 3858 case 8: 3859 if (((insn >> 4) & 3) == 3) { 3860 return 1; 3861 } 3862 break; 3863 default: 3864 break; 3865 } 3866 nregs = neon_ls_element_type[op].nregs; 3867 interleave = neon_ls_element_type[op].interleave; 3868 spacing = neon_ls_element_type[op].spacing; 3869 if (size == 3 && (interleave | spacing) != 1) { 3870 return 1; 3871 } 3872 addr = tcg_const_i32(insn); 3873 gen_helper_neon_vldst_all(addr); 3874 tcg_temp_free_i32(addr); 3875 stride = nregs * 8; 3876 } else { 3877 size = (insn >> 10) & 3; 3878 if (size == 3) { 3879 /* Load single element to all lanes. */ 3880 int a = (insn >> 4) & 1; 3881 if (!load) { 3882 return 1; 3883 } 3884 size = (insn >> 6) & 3; 3885 nregs = ((insn >> 8) & 3) + 1; 3886 3887 if (size == 3) { 3888 if (nregs != 4 || a == 0) { 3889 return 1; 3890 } 3891 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */ 3892 size = 2; 3893 } 3894 if (nregs == 1 && a == 1 && size == 0) { 3895 return 1; 3896 } 3897 if (nregs == 3 && a == 1) { 3898 return 1; 3899 } 3900 addr = tcg_temp_new_i32(); 3901 load_reg_var(s, addr, rn); 3902 if (nregs == 1) { 3903 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */ 3904 tmp = gen_load_and_replicate(s, addr, size); 3905 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); 3906 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); 3907 if (insn & (1 << 5)) { 3908 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0)); 3909 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1)); 3910 } 3911 tcg_temp_free_i32(tmp); 3912 } else { 3913 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */ 3914 stride = (insn & (1 << 5)) ? 2 : 1; 3915 for (reg = 0; reg < nregs; reg++) { 3916 tmp = gen_load_and_replicate(s, addr, size); 3917 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); 3918 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); 3919 tcg_temp_free_i32(tmp); 3920 tcg_gen_addi_i32(addr, addr, 1 << size); 3921 rd += stride; 3922 } 3923 } 3924 tcg_temp_free_i32(addr); 3925 stride = (1 << size) * nregs; 3926 } else { 3927 /* Single element. */ 3928 int idx = (insn >> 4) & 0xf; 3929 pass = (insn >> 7) & 1; 3930 switch (size) { 3931 case 0: 3932 shift = ((insn >> 5) & 3) * 8; 3933 stride = 1; 3934 break; 3935 case 1: 3936 shift = ((insn >> 6) & 1) * 16; 3937 stride = (insn & (1 << 5)) ? 2 : 1; 3938 break; 3939 case 2: 3940 shift = 0; 3941 stride = (insn & (1 << 6)) ? 2 : 1; 3942 break; 3943 default: 3944 abort(); 3945 } 3946 nregs = ((insn >> 8) & 3) + 1; 3947 /* Catch the UNDEF cases. This is unavoidably a bit messy. */ 3948 switch (nregs) { 3949 case 1: 3950 if (((idx & (1 << size)) != 0) || 3951 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) { 3952 return 1; 3953 } 3954 break; 3955 case 3: 3956 if ((idx & 1) != 0) { 3957 return 1; 3958 } 3959 /* fall through */ 3960 case 2: 3961 if (size == 2 && (idx & 2) != 0) { 3962 return 1; 3963 } 3964 break; 3965 case 4: 3966 if ((size == 2) && ((idx & 3) == 3)) { 3967 return 1; 3968 } 3969 break; 3970 default: 3971 abort(); 3972 } 3973 if ((rd + stride * (nregs - 1)) > 31) { 3974 /* Attempts to write off the end of the register file 3975 * are UNPREDICTABLE; we choose to UNDEF because otherwise 3976 * the neon_load_reg() would write off the end of the array. 3977 */ 3978 return 1; 3979 } 3980 addr = tcg_temp_new_i32(); 3981 load_reg_var(s, addr, rn); 3982 for (reg = 0; reg < nregs; reg++) { 3983 if (load) { 3984 switch (size) { 3985 case 0: 3986 tmp = gen_ld8u(addr, IS_USER(s)); 3987 break; 3988 case 1: 3989 tmp = gen_ld16u(addr, IS_USER(s)); 3990 break; 3991 case 2: 3992 tmp = gen_ld32(addr, IS_USER(s)); 3993 break; 3994 default: /* Avoid compiler warnings. */ 3995 abort(); 3996 } 3997 if (size != 2) { 3998 tmp2 = neon_load_reg(rd, pass); 3999 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff); 4000 tcg_temp_free_i32(tmp2); 4001 } 4002 neon_store_reg(rd, pass, tmp); 4003 } else { /* Store */ 4004 tmp = neon_load_reg(rd, pass); 4005 if (shift) 4006 tcg_gen_shri_i32(tmp, tmp, shift); 4007 switch (size) { 4008 case 0: 4009 gen_st8(tmp, addr, IS_USER(s)); 4010 break; 4011 case 1: 4012 gen_st16(tmp, addr, IS_USER(s)); 4013 break; 4014 case 2: 4015 gen_st32(tmp, addr, IS_USER(s)); 4016 break; 4017 } 4018 } 4019 rd += stride; 4020 tcg_gen_addi_i32(addr, addr, 1 << size); 4021 } 4022 tcg_temp_free_i32(addr); 4023 stride = nregs * (1 << size); 4024 } 4025 } 4026 if (rm != 15) { 4027 TCGv base; 4028 4029 base = load_reg(s, rn); 4030 if (rm == 13) { 4031 tcg_gen_addi_i32(base, base, stride); 4032 } else { 4033 TCGv index; 4034 index = load_reg(s, rm); 4035 tcg_gen_add_i32(base, base, index); 4036 tcg_temp_free_i32(index); 4037 } 4038 store_reg(s, rn, base); 4039 } 4040 return 0; 4041} 4042 4043/* Bitwise select. dest = c ? t : f. Clobbers T and F. */ 4044static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c) 4045{ 4046 tcg_gen_and_i32(t, t, c); 4047 tcg_gen_andc_i32(f, f, c); 4048 tcg_gen_or_i32(dest, t, f); 4049} 4050 4051static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src) 4052{ 4053 switch (size) { 4054 case 0: gen_helper_neon_narrow_u8(dest, src); break; 4055 case 1: gen_helper_neon_narrow_u16(dest, src); break; 4056 case 2: tcg_gen_trunc_i64_i32(dest, src); break; 4057 default: abort(); 4058 } 4059} 4060 4061static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src) 4062{ 4063 switch (size) { 4064 case 0: gen_helper_neon_narrow_sat_s8(dest, src); break; 4065 case 1: gen_helper_neon_narrow_sat_s16(dest, src); break; 4066 case 2: gen_helper_neon_narrow_sat_s32(dest, src); break; 4067 default: abort(); 4068 } 4069} 4070 4071static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src) 4072{ 4073 switch (size) { 4074 case 0: gen_helper_neon_narrow_sat_u8(dest, src); break; 4075 case 1: gen_helper_neon_narrow_sat_u16(dest, src); break; 4076 case 2: gen_helper_neon_narrow_sat_u32(dest, src); break; 4077 default: abort(); 4078 } 4079} 4080 4081static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src) 4082{ 4083 switch (size) { 4084 case 0: gen_helper_neon_unarrow_sat8(dest, src); break; 4085 case 1: gen_helper_neon_unarrow_sat16(dest, src); break; 4086 case 2: gen_helper_neon_unarrow_sat32(dest, src); break; 4087 default: abort(); 4088 } 4089} 4090 4091static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift, 4092 int q, int u) 4093{ 4094 if (q) { 4095 if (u) { 4096 switch (size) { 4097 case 1: gen_helper_neon_rshl_u16(var, var, shift); break; 4098 case 2: gen_helper_neon_rshl_u32(var, var, shift); break; 4099 default: abort(); 4100 } 4101 } else { 4102 switch (size) { 4103 case 1: gen_helper_neon_rshl_s16(var, var, shift); break; 4104 case 2: gen_helper_neon_rshl_s32(var, var, shift); break; 4105 default: abort(); 4106 } 4107 } 4108 } else { 4109 if (u) { 4110 switch (size) { 4111 case 1: gen_helper_neon_shl_u16(var, var, shift); break; 4112 case 2: gen_helper_neon_shl_u32(var, var, shift); break; 4113 default: abort(); 4114 } 4115 } else { 4116 switch (size) { 4117 case 1: gen_helper_neon_shl_s16(var, var, shift); break; 4118 case 2: gen_helper_neon_shl_s32(var, var, shift); break; 4119 default: abort(); 4120 } 4121 } 4122 } 4123} 4124 4125static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u) 4126{ 4127 if (u) { 4128 switch (size) { 4129 case 0: gen_helper_neon_widen_u8(dest, src); break; 4130 case 1: gen_helper_neon_widen_u16(dest, src); break; 4131 case 2: tcg_gen_extu_i32_i64(dest, src); break; 4132 default: abort(); 4133 } 4134 } else { 4135 switch (size) { 4136 case 0: gen_helper_neon_widen_s8(dest, src); break; 4137 case 1: gen_helper_neon_widen_s16(dest, src); break; 4138 case 2: tcg_gen_ext_i32_i64(dest, src); break; 4139 default: abort(); 4140 } 4141 } 4142 tcg_temp_free_i32(src); 4143} 4144 4145static inline void gen_neon_addl(int size) 4146{ 4147 switch (size) { 4148 case 0: gen_helper_neon_addl_u16(CPU_V001); break; 4149 case 1: gen_helper_neon_addl_u32(CPU_V001); break; 4150 case 2: tcg_gen_add_i64(CPU_V001); break; 4151 default: abort(); 4152 } 4153} 4154 4155static inline void gen_neon_subl(int size) 4156{ 4157 switch (size) { 4158 case 0: gen_helper_neon_subl_u16(CPU_V001); break; 4159 case 1: gen_helper_neon_subl_u32(CPU_V001); break; 4160 case 2: tcg_gen_sub_i64(CPU_V001); break; 4161 default: abort(); 4162 } 4163} 4164 4165static inline void gen_neon_negl(TCGv_i64 var, int size) 4166{ 4167 switch (size) { 4168 case 0: gen_helper_neon_negl_u16(var, var); break; 4169 case 1: gen_helper_neon_negl_u32(var, var); break; 4170 case 2: gen_helper_neon_negl_u64(var, var); break; 4171 default: abort(); 4172 } 4173} 4174 4175static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size) 4176{ 4177 switch (size) { 4178 case 1: gen_helper_neon_addl_saturate_s32(op0, op0, op1); break; 4179 case 2: gen_helper_neon_addl_saturate_s64(op0, op0, op1); break; 4180 default: abort(); 4181 } 4182} 4183 4184static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u) 4185{ 4186 TCGv_i64 tmp; 4187 4188 switch ((size << 1) | u) { 4189 case 0: gen_helper_neon_mull_s8(dest, a, b); break; 4190 case 1: gen_helper_neon_mull_u8(dest, a, b); break; 4191 case 2: gen_helper_neon_mull_s16(dest, a, b); break; 4192 case 3: gen_helper_neon_mull_u16(dest, a, b); break; 4193 case 4: 4194 tmp = gen_muls_i64_i32(a, b); 4195 tcg_gen_mov_i64(dest, tmp); 4196 tcg_temp_free_i64(tmp); 4197 break; 4198 case 5: 4199 tmp = gen_mulu_i64_i32(a, b); 4200 tcg_gen_mov_i64(dest, tmp); 4201 tcg_temp_free_i64(tmp); 4202 break; 4203 default: abort(); 4204 } 4205 4206 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters. 4207 Don't forget to clean them now. */ 4208 if (size < 2) { 4209 tcg_temp_free_i32(a); 4210 tcg_temp_free_i32(b); 4211 } 4212} 4213 4214static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src) 4215{ 4216 if (op) { 4217 if (u) { 4218 gen_neon_unarrow_sats(size, dest, src); 4219 } else { 4220 gen_neon_narrow(size, dest, src); 4221 } 4222 } else { 4223 if (u) { 4224 gen_neon_narrow_satu(size, dest, src); 4225 } else { 4226 gen_neon_narrow_sats(size, dest, src); 4227 } 4228 } 4229} 4230 4231/* Symbolic constants for op fields for Neon 3-register same-length. 4232 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B 4233 * table A7-9. 4234 */ 4235#define NEON_3R_VHADD 0 4236#define NEON_3R_VQADD 1 4237#define NEON_3R_VRHADD 2 4238#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */ 4239#define NEON_3R_VHSUB 4 4240#define NEON_3R_VQSUB 5 4241#define NEON_3R_VCGT 6 4242#define NEON_3R_VCGE 7 4243#define NEON_3R_VSHL 8 4244#define NEON_3R_VQSHL 9 4245#define NEON_3R_VRSHL 10 4246#define NEON_3R_VQRSHL 11 4247#define NEON_3R_VMAX 12 4248#define NEON_3R_VMIN 13 4249#define NEON_3R_VABD 14 4250#define NEON_3R_VABA 15 4251#define NEON_3R_VADD_VSUB 16 4252#define NEON_3R_VTST_VCEQ 17 4253#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */ 4254#define NEON_3R_VMUL 19 4255#define NEON_3R_VPMAX 20 4256#define NEON_3R_VPMIN 21 4257#define NEON_3R_VQDMULH_VQRDMULH 22 4258#define NEON_3R_VPADD 23 4259#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */ 4260#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */ 4261#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */ 4262#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */ 4263#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */ 4264#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */ 4265 4266static const uint8_t neon_3r_sizes[] = { 4267 [NEON_3R_VHADD] = 0x7, 4268 [NEON_3R_VQADD] = 0xf, 4269 [NEON_3R_VRHADD] = 0x7, 4270 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */ 4271 [NEON_3R_VHSUB] = 0x7, 4272 [NEON_3R_VQSUB] = 0xf, 4273 [NEON_3R_VCGT] = 0x7, 4274 [NEON_3R_VCGE] = 0x7, 4275 [NEON_3R_VSHL] = 0xf, 4276 [NEON_3R_VQSHL] = 0xf, 4277 [NEON_3R_VRSHL] = 0xf, 4278 [NEON_3R_VQRSHL] = 0xf, 4279 [NEON_3R_VMAX] = 0x7, 4280 [NEON_3R_VMIN] = 0x7, 4281 [NEON_3R_VABD] = 0x7, 4282 [NEON_3R_VABA] = 0x7, 4283 [NEON_3R_VADD_VSUB] = 0xf, 4284 [NEON_3R_VTST_VCEQ] = 0x7, 4285 [NEON_3R_VML] = 0x7, 4286 [NEON_3R_VMUL] = 0x7, 4287 [NEON_3R_VPMAX] = 0x7, 4288 [NEON_3R_VPMIN] = 0x7, 4289 [NEON_3R_VQDMULH_VQRDMULH] = 0x6, 4290 [NEON_3R_VPADD] = 0x7, 4291 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */ 4292 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */ 4293 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */ 4294 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */ 4295 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */ 4296 [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */ 4297}; 4298 4299/* Symbolic constants for op fields for Neon 2-register miscellaneous. 4300 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B 4301 * table A7-13. 4302 */ 4303#define NEON_2RM_VREV64 0 4304#define NEON_2RM_VREV32 1 4305#define NEON_2RM_VREV16 2 4306#define NEON_2RM_VPADDL 4 4307#define NEON_2RM_VPADDL_U 5 4308#define NEON_2RM_VCLS 8 4309#define NEON_2RM_VCLZ 9 4310#define NEON_2RM_VCNT 10 4311#define NEON_2RM_VMVN 11 4312#define NEON_2RM_VPADAL 12 4313#define NEON_2RM_VPADAL_U 13 4314#define NEON_2RM_VQABS 14 4315#define NEON_2RM_VQNEG 15 4316#define NEON_2RM_VCGT0 16 4317#define NEON_2RM_VCGE0 17 4318#define NEON_2RM_VCEQ0 18 4319#define NEON_2RM_VCLE0 19 4320#define NEON_2RM_VCLT0 20 4321#define NEON_2RM_VABS 22 4322#define NEON_2RM_VNEG 23 4323#define NEON_2RM_VCGT0_F 24 4324#define NEON_2RM_VCGE0_F 25 4325#define NEON_2RM_VCEQ0_F 26 4326#define NEON_2RM_VCLE0_F 27 4327#define NEON_2RM_VCLT0_F 28 4328#define NEON_2RM_VABS_F 30 4329#define NEON_2RM_VNEG_F 31 4330#define NEON_2RM_VSWP 32 4331#define NEON_2RM_VTRN 33 4332#define NEON_2RM_VUZP 34 4333#define NEON_2RM_VZIP 35 4334#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ 4335#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ 4336#define NEON_2RM_VSHLL 38 4337#define NEON_2RM_VCVT_F16_F32 44 4338#define NEON_2RM_VCVT_F32_F16 46 4339#define NEON_2RM_VRECPE 56 4340#define NEON_2RM_VRSQRTE 57 4341#define NEON_2RM_VRECPE_F 58 4342#define NEON_2RM_VRSQRTE_F 59 4343#define NEON_2RM_VCVT_FS 60 4344#define NEON_2RM_VCVT_FU 61 4345#define NEON_2RM_VCVT_SF 62 4346#define NEON_2RM_VCVT_UF 63 4347 4348static int neon_2rm_is_float_op(int op) 4349{ 4350 /* Return true if this neon 2reg-misc op is float-to-float */ 4351 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || 4352 op >= NEON_2RM_VRECPE_F); 4353} 4354 4355/* Each entry in this array has bit n set if the insn allows 4356 * size value n (otherwise it will UNDEF). Since unallocated 4357 * op values will have no bits set they always UNDEF. 4358 */ 4359static const uint8_t neon_2rm_sizes[] = { 4360 [NEON_2RM_VREV64] = 0x7, 4361 [NEON_2RM_VREV32] = 0x3, 4362 [NEON_2RM_VREV16] = 0x1, 4363 [NEON_2RM_VPADDL] = 0x7, 4364 [NEON_2RM_VPADDL_U] = 0x7, 4365 [NEON_2RM_VCLS] = 0x7, 4366 [NEON_2RM_VCLZ] = 0x7, 4367 [NEON_2RM_VCNT] = 0x1, 4368 [NEON_2RM_VMVN] = 0x1, 4369 [NEON_2RM_VPADAL] = 0x7, 4370 [NEON_2RM_VPADAL_U] = 0x7, 4371 [NEON_2RM_VQABS] = 0x7, 4372 [NEON_2RM_VQNEG] = 0x7, 4373 [NEON_2RM_VCGT0] = 0x7, 4374 [NEON_2RM_VCGE0] = 0x7, 4375 [NEON_2RM_VCEQ0] = 0x7, 4376 [NEON_2RM_VCLE0] = 0x7, 4377 [NEON_2RM_VCLT0] = 0x7, 4378 [NEON_2RM_VABS] = 0x7, 4379 [NEON_2RM_VNEG] = 0x7, 4380 [NEON_2RM_VCGT0_F] = 0x4, 4381 [NEON_2RM_VCGE0_F] = 0x4, 4382 [NEON_2RM_VCEQ0_F] = 0x4, 4383 [NEON_2RM_VCLE0_F] = 0x4, 4384 [NEON_2RM_VCLT0_F] = 0x4, 4385 [NEON_2RM_VABS_F] = 0x4, 4386 [NEON_2RM_VNEG_F] = 0x4, 4387 [NEON_2RM_VSWP] = 0x1, 4388 [NEON_2RM_VTRN] = 0x7, 4389 [NEON_2RM_VUZP] = 0x7, 4390 [NEON_2RM_VZIP] = 0x7, 4391 [NEON_2RM_VMOVN] = 0x7, 4392 [NEON_2RM_VQMOVN] = 0x7, 4393 [NEON_2RM_VSHLL] = 0x7, 4394 [NEON_2RM_VCVT_F16_F32] = 0x2, 4395 [NEON_2RM_VCVT_F32_F16] = 0x2, 4396 [NEON_2RM_VRECPE] = 0x4, 4397 [NEON_2RM_VRSQRTE] = 0x4, 4398 [NEON_2RM_VRECPE_F] = 0x4, 4399 [NEON_2RM_VRSQRTE_F] = 0x4, 4400 [NEON_2RM_VCVT_FS] = 0x4, 4401 [NEON_2RM_VCVT_FU] = 0x4, 4402 [NEON_2RM_VCVT_SF] = 0x4, 4403 [NEON_2RM_VCVT_UF] = 0x4, 4404}; 4405 4406/* Translate a NEON data processing instruction. Return nonzero if the 4407 instruction is invalid. 4408 We process data in a mixture of 32-bit and 64-bit chunks. 4409 Mostly we use 32-bit chunks so we can use normal scalar instructions. */ 4410 4411static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn) 4412{ 4413 int op; 4414 int q; 4415 int rd, rn, rm; 4416 int size; 4417 int shift; 4418 int pass; 4419 int count; 4420 int pairwise; 4421 int u; 4422 uint32_t imm, mask; 4423 TCGv tmp, tmp2, tmp3, tmp4, tmp5; 4424 TCGv_i64 tmp64; 4425 4426 if (!s->vfp_enabled) 4427 return 1; 4428 q = (insn & (1 << 6)) != 0; 4429 u = (insn >> 24) & 1; 4430 VFP_DREG_D(rd, insn); 4431 VFP_DREG_N(rn, insn); 4432 VFP_DREG_M(rm, insn); 4433 size = (insn >> 20) & 3; 4434 if ((insn & (1 << 23)) == 0) { 4435 /* Three register same length. */ 4436 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1); 4437 /* Catch invalid op and bad size combinations: UNDEF */ 4438 if ((neon_3r_sizes[op] & (1 << size)) == 0) { 4439 return 1; 4440 } 4441 /* All insns of this form UNDEF for either this condition or the 4442 * superset of cases "Q==1"; we catch the latter later. 4443 */ 4444 if (q && ((rd | rn | rm) & 1)) { 4445 return 1; 4446 } 4447 if (size == 3 && op != NEON_3R_LOGIC) { 4448 /* 64-bit element instructions. */ 4449 for (pass = 0; pass < (q ? 2 : 1); pass++) { 4450 neon_load_reg64(cpu_V0, rn + pass); 4451 neon_load_reg64(cpu_V1, rm + pass); 4452 switch (op) { 4453 case NEON_3R_VQADD: 4454 if (u) { 4455 gen_helper_neon_qadd_u64(cpu_V0, cpu_V0, cpu_V1); 4456 } else { 4457 gen_helper_neon_qadd_s64(cpu_V0, cpu_V0, cpu_V1); 4458 } 4459 break; 4460 case NEON_3R_VQSUB: 4461 if (u) { 4462 gen_helper_neon_qsub_u64(cpu_V0, cpu_V0, cpu_V1); 4463 } else { 4464 gen_helper_neon_qsub_s64(cpu_V0, cpu_V0, cpu_V1); 4465 } 4466 break; 4467 case NEON_3R_VSHL: 4468 if (u) { 4469 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0); 4470 } else { 4471 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0); 4472 } 4473 break; 4474 case NEON_3R_VQSHL: 4475 if (u) { 4476 gen_helper_neon_qshl_u64(cpu_V0, cpu_V1, cpu_V0); 4477 } else { 4478 gen_helper_neon_qshl_s64(cpu_V0, cpu_V1, cpu_V0); 4479 } 4480 break; 4481 case NEON_3R_VRSHL: 4482 if (u) { 4483 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0); 4484 } else { 4485 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0); 4486 } 4487 break; 4488 case NEON_3R_VQRSHL: 4489 if (u) { 4490 gen_helper_neon_qrshl_u64(cpu_V0, cpu_V1, cpu_V0); 4491 } else { 4492 gen_helper_neon_qrshl_s64(cpu_V0, cpu_V1, cpu_V0); 4493 } 4494 break; 4495 case NEON_3R_VADD_VSUB: 4496 if (u) { 4497 tcg_gen_sub_i64(CPU_V001); 4498 } else { 4499 tcg_gen_add_i64(CPU_V001); 4500 } 4501 break; 4502 default: 4503 abort(); 4504 } 4505 neon_store_reg64(cpu_V0, rd + pass); 4506 } 4507 return 0; 4508 } 4509 pairwise = 0; 4510 switch (op) { 4511 case NEON_3R_VSHL: 4512 case NEON_3R_VQSHL: 4513 case NEON_3R_VRSHL: 4514 case NEON_3R_VQRSHL: 4515 { 4516 int rtmp; 4517 /* Shift instruction operands are reversed. */ 4518 rtmp = rn; 4519 rn = rm; 4520 rm = rtmp; 4521 } 4522 break; 4523 case NEON_3R_VPADD: 4524 if (u) { 4525 return 1; 4526 } 4527 /* Fall through */ 4528 case NEON_3R_VPMAX: 4529 case NEON_3R_VPMIN: 4530 pairwise = 1; 4531 break; 4532 case NEON_3R_FLOAT_ARITH: 4533 pairwise = (u && size < 2); /* if VPADD (float) */ 4534 break; 4535 case NEON_3R_FLOAT_MINMAX: 4536 pairwise = u; /* if VPMIN/VPMAX (float) */ 4537 break; 4538 case NEON_3R_FLOAT_CMP: 4539 if (!u && size) { 4540 /* no encoding for U=0 C=1x */ 4541 return 1; 4542 } 4543 break; 4544 case NEON_3R_FLOAT_ACMP: 4545 if (!u) { 4546 return 1; 4547 } 4548 break; 4549 case NEON_3R_VRECPS_VRSQRTS: 4550 if (u) { 4551 return 1; 4552 } 4553 break; 4554 case NEON_3R_VMUL: 4555 if (u && (size != 0)) { 4556 /* UNDEF on invalid size for polynomial subcase */ 4557 return 1; 4558 } 4559 break; 4560 default: 4561 break; 4562 } 4563 4564 if (pairwise && q) { 4565 /* All the pairwise insns UNDEF if Q is set */ 4566 return 1; 4567 } 4568 4569 for (pass = 0; pass < (q ? 4 : 2); pass++) { 4570 4571 if (pairwise) { 4572 /* Pairwise. */ 4573 if (pass < 1) { 4574 tmp = neon_load_reg(rn, 0); 4575 tmp2 = neon_load_reg(rn, 1); 4576 } else { 4577 tmp = neon_load_reg(rm, 0); 4578 tmp2 = neon_load_reg(rm, 1); 4579 } 4580 } else { 4581 /* Elementwise. */ 4582 tmp = neon_load_reg(rn, pass); 4583 tmp2 = neon_load_reg(rm, pass); 4584 } 4585 switch (op) { 4586 case NEON_3R_VHADD: 4587 GEN_NEON_INTEGER_OP(hadd); 4588 break; 4589 case NEON_3R_VQADD: 4590 GEN_NEON_INTEGER_OP(qadd); 4591 break; 4592 case NEON_3R_VRHADD: 4593 GEN_NEON_INTEGER_OP(rhadd); 4594 break; 4595 case NEON_3R_LOGIC: /* Logic ops. */ 4596 switch ((u << 2) | size) { 4597 case 0: /* VAND */ 4598 tcg_gen_and_i32(tmp, tmp, tmp2); 4599 break; 4600 case 1: /* BIC */ 4601 tcg_gen_andc_i32(tmp, tmp, tmp2); 4602 break; 4603 case 2: /* VORR */ 4604 tcg_gen_or_i32(tmp, tmp, tmp2); 4605 break; 4606 case 3: /* VORN */ 4607 tcg_gen_orc_i32(tmp, tmp, tmp2); 4608 break; 4609 case 4: /* VEOR */ 4610 tcg_gen_xor_i32(tmp, tmp, tmp2); 4611 break; 4612 case 5: /* VBSL */ 4613 tmp3 = neon_load_reg(rd, pass); 4614 gen_neon_bsl(tmp, tmp, tmp2, tmp3); 4615 tcg_temp_free_i32(tmp3); 4616 break; 4617 case 6: /* VBIT */ 4618 tmp3 = neon_load_reg(rd, pass); 4619 gen_neon_bsl(tmp, tmp, tmp3, tmp2); 4620 tcg_temp_free_i32(tmp3); 4621 break; 4622 case 7: /* VBIF */ 4623 tmp3 = neon_load_reg(rd, pass); 4624 gen_neon_bsl(tmp, tmp3, tmp, tmp2); 4625 tcg_temp_free_i32(tmp3); 4626 break; 4627 } 4628 break; 4629 case NEON_3R_VHSUB: 4630 GEN_NEON_INTEGER_OP(hsub); 4631 break; 4632 case NEON_3R_VQSUB: 4633 GEN_NEON_INTEGER_OP(qsub); 4634 break; 4635 case NEON_3R_VCGT: 4636 GEN_NEON_INTEGER_OP(cgt); 4637 break; 4638 case NEON_3R_VCGE: 4639 GEN_NEON_INTEGER_OP(cge); 4640 break; 4641 case NEON_3R_VSHL: 4642 GEN_NEON_INTEGER_OP(shl); 4643 break; 4644 case NEON_3R_VQSHL: 4645 GEN_NEON_INTEGER_OP(qshl); 4646 break; 4647 case NEON_3R_VRSHL: 4648 GEN_NEON_INTEGER_OP(rshl); 4649 break; 4650 case NEON_3R_VQRSHL: 4651 GEN_NEON_INTEGER_OP(qrshl); 4652 break; 4653 case NEON_3R_VMAX: 4654 GEN_NEON_INTEGER_OP(max); 4655 break; 4656 case NEON_3R_VMIN: 4657 GEN_NEON_INTEGER_OP(min); 4658 break; 4659 case NEON_3R_VABD: 4660 GEN_NEON_INTEGER_OP(abd); 4661 break; 4662 case NEON_3R_VABA: 4663 GEN_NEON_INTEGER_OP(abd); 4664 tcg_temp_free_i32(tmp2); 4665 tmp2 = neon_load_reg(rd, pass); 4666 gen_neon_add(size, tmp, tmp2); 4667 break; 4668 case NEON_3R_VADD_VSUB: 4669 if (!u) { /* VADD */ 4670 gen_neon_add(size, tmp, tmp2); 4671 } else { /* VSUB */ 4672 switch (size) { 4673 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break; 4674 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break; 4675 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break; 4676 default: abort(); 4677 } 4678 } 4679 break; 4680 case NEON_3R_VTST_VCEQ: 4681 if (!u) { /* VTST */ 4682 switch (size) { 4683 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break; 4684 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break; 4685 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break; 4686 default: abort(); 4687 } 4688 } else { /* VCEQ */ 4689 switch (size) { 4690 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; 4691 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; 4692 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; 4693 default: abort(); 4694 } 4695 } 4696 break; 4697 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */ 4698 switch (size) { 4699 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; 4700 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; 4701 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; 4702 default: abort(); 4703 } 4704 tcg_temp_free_i32(tmp2); 4705 tmp2 = neon_load_reg(rd, pass); 4706 if (u) { /* VMLS */ 4707 gen_neon_rsb(size, tmp, tmp2); 4708 } else { /* VMLA */ 4709 gen_neon_add(size, tmp, tmp2); 4710 } 4711 break; 4712 case NEON_3R_VMUL: 4713 if (u) { /* polynomial */ 4714 gen_helper_neon_mul_p8(tmp, tmp, tmp2); 4715 } else { /* Integer */ 4716 switch (size) { 4717 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; 4718 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; 4719 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; 4720 default: abort(); 4721 } 4722 } 4723 break; 4724 case NEON_3R_VPMAX: 4725 GEN_NEON_INTEGER_OP(pmax); 4726 break; 4727 case NEON_3R_VPMIN: 4728 GEN_NEON_INTEGER_OP(pmin); 4729 break; 4730 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */ 4731 if (!u) { /* VQDMULH */ 4732 switch (size) { 4733 case 1: gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2); break; 4734 case 2: gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2); break; 4735 default: abort(); 4736 } 4737 } else { /* VQRDMULH */ 4738 switch (size) { 4739 case 1: gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2); break; 4740 case 2: gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2); break; 4741 default: abort(); 4742 } 4743 } 4744 break; 4745 case NEON_3R_VPADD: 4746 switch (size) { 4747 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; 4748 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; 4749 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break; 4750 default: abort(); 4751 } 4752 break; 4753 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */ 4754 switch ((u << 2) | size) { 4755 case 0: /* VADD */ 4756 gen_helper_neon_add_f32(tmp, tmp, tmp2); 4757 break; 4758 case 2: /* VSUB */ 4759 gen_helper_neon_sub_f32(tmp, tmp, tmp2); 4760 break; 4761 case 4: /* VPADD */ 4762 gen_helper_neon_add_f32(tmp, tmp, tmp2); 4763 break; 4764 case 6: /* VABD */ 4765 gen_helper_neon_abd_f32(tmp, tmp, tmp2); 4766 break; 4767 default: 4768 abort(); 4769 } 4770 break; 4771 case NEON_3R_FLOAT_MULTIPLY: 4772 gen_helper_neon_mul_f32(tmp, tmp, tmp2); 4773 if (!u) { 4774 tcg_temp_free_i32(tmp2); 4775 tmp2 = neon_load_reg(rd, pass); 4776 if (size == 0) { 4777 gen_helper_neon_add_f32(tmp, tmp, tmp2); 4778 } else { 4779 gen_helper_neon_sub_f32(tmp, tmp2, tmp); 4780 } 4781 } 4782 break; 4783 case NEON_3R_FLOAT_CMP: 4784 if (!u) { 4785 gen_helper_neon_ceq_f32(tmp, tmp, tmp2); 4786 } else { 4787 if (size == 0) 4788 gen_helper_neon_cge_f32(tmp, tmp, tmp2); 4789 else 4790 gen_helper_neon_cgt_f32(tmp, tmp, tmp2); 4791 } 4792 break; 4793 case NEON_3R_FLOAT_ACMP: 4794 if (size == 0) 4795 gen_helper_neon_acge_f32(tmp, tmp, tmp2); 4796 else 4797 gen_helper_neon_acgt_f32(tmp, tmp, tmp2); 4798 break; 4799 case NEON_3R_FLOAT_MINMAX: 4800 if (size == 0) 4801 gen_helper_neon_max_f32(tmp, tmp, tmp2); 4802 else 4803 gen_helper_neon_min_f32(tmp, tmp, tmp2); 4804 break; 4805 case NEON_3R_VRECPS_VRSQRTS: 4806 if (size == 0) 4807 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env); 4808 else 4809 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env); 4810 break; 4811 default: 4812 abort(); 4813 } 4814 tcg_temp_free_i32(tmp2); 4815 4816 /* Save the result. For elementwise operations we can put it 4817 straight into the destination register. For pairwise operations 4818 we have to be careful to avoid clobbering the source operands. */ 4819 if (pairwise && rd == rm) { 4820 neon_store_scratch(pass, tmp); 4821 } else { 4822 neon_store_reg(rd, pass, tmp); 4823 } 4824 4825 } /* for pass */ 4826 if (pairwise && rd == rm) { 4827 for (pass = 0; pass < (q ? 4 : 2); pass++) { 4828 tmp = neon_load_scratch(pass); 4829 neon_store_reg(rd, pass, tmp); 4830 } 4831 } 4832 /* End of 3 register same size operations. */ 4833 } else if (insn & (1 << 4)) { 4834 if ((insn & 0x00380080) != 0) { 4835 /* Two registers and shift. */ 4836 op = (insn >> 8) & 0xf; 4837 if (insn & (1 << 7)) { 4838 /* 64-bit shift. */ 4839 if (op > 7) { 4840 return 1; 4841 } 4842 size = 3; 4843 } else { 4844 size = 2; 4845 while ((insn & (1 << (size + 19))) == 0) 4846 size--; 4847 } 4848 shift = (insn >> 16) & ((1 << (3 + size)) - 1); 4849 /* To avoid excessive dumplication of ops we implement shift 4850 by immediate using the variable shift operations. */ 4851 if (op < 8) { 4852 /* Shift by immediate: 4853 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ 4854 if (q && ((rd | rm) & 1)) { 4855 return 1; 4856 } 4857 if (!u && (op == 4 || op == 6)) { 4858 return 1; 4859 } 4860 /* Right shifts are encoded as N - shift, where N is the 4861 element size in bits. */ 4862 if (op <= 4) 4863 shift = shift - (1 << (size + 3)); 4864 if (size == 3) { 4865 count = q + 1; 4866 } else { 4867 count = q ? 4: 2; 4868 } 4869 switch (size) { 4870 case 0: 4871 imm = (uint8_t) shift; 4872 imm |= imm << 8; 4873 imm |= imm << 16; 4874 break; 4875 case 1: 4876 imm = (uint16_t) shift; 4877 imm |= imm << 16; 4878 break; 4879 case 2: 4880 case 3: 4881 imm = shift; 4882 break; 4883 default: 4884 abort(); 4885 } 4886 4887 for (pass = 0; pass < count; pass++) { 4888 if (size == 3) { 4889 neon_load_reg64(cpu_V0, rm + pass); 4890 tcg_gen_movi_i64(cpu_V1, imm); 4891 switch (op) { 4892 case 0: /* VSHR */ 4893 case 1: /* VSRA */ 4894 if (u) 4895 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); 4896 else 4897 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1); 4898 break; 4899 case 2: /* VRSHR */ 4900 case 3: /* VRSRA */ 4901 if (u) 4902 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1); 4903 else 4904 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1); 4905 break; 4906 case 4: /* VSRI */ 4907 case 5: /* VSHL, VSLI */ 4908 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); 4909 break; 4910 case 6: /* VQSHLU */ 4911 gen_helper_neon_qshlu_s64(cpu_V0, cpu_V0, cpu_V1); 4912 break; 4913 case 7: /* VQSHL */ 4914 if (u) { 4915 gen_helper_neon_qshl_u64(cpu_V0, 4916 cpu_V0, cpu_V1); 4917 } else { 4918 gen_helper_neon_qshl_s64(cpu_V0, 4919 cpu_V0, cpu_V1); 4920 } 4921 break; 4922 } 4923 if (op == 1 || op == 3) { 4924 /* Accumulate. */ 4925 neon_load_reg64(cpu_V1, rd + pass); 4926 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1); 4927 } else if (op == 4 || (op == 5 && u)) { 4928 /* Insert */ 4929 neon_load_reg64(cpu_V1, rd + pass); 4930 uint64_t mask; 4931 if (shift < -63 || shift > 63) { 4932 mask = 0; 4933 } else { 4934 if (op == 4) { 4935 mask = 0xffffffffffffffffull >> -shift; 4936 } else { 4937 mask = 0xffffffffffffffffull << shift; 4938 } 4939 } 4940 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask); 4941 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); 4942 } 4943 neon_store_reg64(cpu_V0, rd + pass); 4944 } else { /* size < 3 */ 4945 /* Operands in T0 and T1. */ 4946 tmp = neon_load_reg(rm, pass); 4947 tmp2 = tcg_const_i32(imm); 4948 switch (op) { 4949 case 0: /* VSHR */ 4950 case 1: /* VSRA */ 4951 GEN_NEON_INTEGER_OP(shl); 4952 break; 4953 case 2: /* VRSHR */ 4954 case 3: /* VRSRA */ 4955 GEN_NEON_INTEGER_OP(rshl); 4956 break; 4957 case 4: /* VSRI */ 4958 case 5: /* VSHL, VSLI */ 4959 switch (size) { 4960 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break; 4961 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break; 4962 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break; 4963 default: abort(); 4964 } 4965 break; 4966 case 6: /* VQSHLU */ 4967 switch (size) { 4968 case 0: 4969 gen_helper_neon_qshlu_s8(tmp, tmp, tmp2); 4970 break; 4971 case 1: 4972 gen_helper_neon_qshlu_s16(tmp, tmp, tmp2); 4973 break; 4974 case 2: 4975 gen_helper_neon_qshlu_s32(tmp, tmp, tmp2); 4976 break; 4977 default: 4978 abort(); 4979 } 4980 break; 4981 case 7: /* VQSHL */ 4982 GEN_NEON_INTEGER_OP(qshl); 4983 break; 4984 } 4985 tcg_temp_free_i32(tmp2); 4986 4987 if (op == 1 || op == 3) { 4988 /* Accumulate. */ 4989 tmp2 = neon_load_reg(rd, pass); 4990 gen_neon_add(size, tmp, tmp2); 4991 tcg_temp_free_i32(tmp2); 4992 } else if (op == 4 || (op == 5 && u)) { 4993 /* Insert */ 4994 switch (size) { 4995 case 0: 4996 if (op == 4) 4997 mask = 0xff >> -shift; 4998 else 4999 mask = (uint8_t)(0xff << shift); 5000 mask |= mask << 8; 5001 mask |= mask << 16; 5002 break; 5003 case 1: 5004 if (op == 4) 5005 mask = 0xffff >> -shift; 5006 else 5007 mask = (uint16_t)(0xffff << shift); 5008 mask |= mask << 16; 5009 break; 5010 case 2: 5011 if (shift < -31 || shift > 31) { 5012 mask = 0; 5013 } else { 5014 if (op == 4) 5015 mask = 0xffffffffu >> -shift; 5016 else 5017 mask = 0xffffffffu << shift; 5018 } 5019 break; 5020 default: 5021 abort(); 5022 } 5023 tmp2 = neon_load_reg(rd, pass); 5024 tcg_gen_andi_i32(tmp, tmp, mask); 5025 tcg_gen_andi_i32(tmp2, tmp2, ~mask); 5026 tcg_gen_or_i32(tmp, tmp, tmp2); 5027 tcg_temp_free_i32(tmp2); 5028 } 5029 neon_store_reg(rd, pass, tmp); 5030 } 5031 } /* for pass */ 5032 } else if (op < 10) { 5033 /* Shift by immediate and narrow: 5034 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ 5035 int input_unsigned = (op == 8) ? !u : u; 5036 if (rm & 1) { 5037 return 1; 5038 } 5039 shift = shift - (1 << (size + 3)); 5040 size++; 5041 if (size == 3) { 5042 tmp64 = tcg_const_i64(shift); 5043 neon_load_reg64(cpu_V0, rm); 5044 neon_load_reg64(cpu_V1, rm + 1); 5045 for (pass = 0; pass < 2; pass++) { 5046 TCGv_i64 in; 5047 if (pass == 0) { 5048 in = cpu_V0; 5049 } else { 5050 in = cpu_V1; 5051 } 5052 if (q) { 5053 if (input_unsigned) { 5054 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64); 5055 } else { 5056 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64); 5057 } 5058 } else { 5059 if (input_unsigned) { 5060 gen_helper_neon_shl_u64(cpu_V0, in, tmp64); 5061 } else { 5062 gen_helper_neon_shl_s64(cpu_V0, in, tmp64); 5063 } 5064 } 5065 tmp = tcg_temp_new_i32(); 5066 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); 5067 neon_store_reg(rd, pass, tmp); 5068 } /* for pass */ 5069 tcg_temp_free_i64(tmp64); 5070 } else { 5071 if (size == 1) { 5072 imm = (uint16_t)shift; 5073 imm |= imm << 16; 5074 } else { 5075 /* size == 2 */ 5076 imm = (uint32_t)shift; 5077 } 5078 tmp2 = tcg_const_i32(imm); 5079 tmp4 = neon_load_reg(rm + 1, 0); 5080 tmp5 = neon_load_reg(rm + 1, 1); 5081 for (pass = 0; pass < 2; pass++) { 5082 if (pass == 0) { 5083 tmp = neon_load_reg(rm, 0); 5084 } else { 5085 tmp = tmp4; 5086 } 5087 gen_neon_shift_narrow(size, tmp, tmp2, q, 5088 input_unsigned); 5089 if (pass == 0) { 5090 tmp3 = neon_load_reg(rm, 1); 5091 } else { 5092 tmp3 = tmp5; 5093 } 5094 gen_neon_shift_narrow(size, tmp3, tmp2, q, 5095 input_unsigned); 5096 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); 5097 tcg_temp_free_i32(tmp); 5098 tcg_temp_free_i32(tmp3); 5099 tmp = tcg_temp_new_i32(); 5100 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); 5101 neon_store_reg(rd, pass, tmp); 5102 } /* for pass */ 5103 tcg_temp_free_i32(tmp2); 5104 } 5105 } else if (op == 10) { 5106 /* VSHLL, VMOVL */ 5107 if (q || (rd & 1)) { 5108 return 1; 5109 } 5110 tmp = neon_load_reg(rm, 0); 5111 tmp2 = neon_load_reg(rm, 1); 5112 for (pass = 0; pass < 2; pass++) { 5113 if (pass == 1) 5114 tmp = tmp2; 5115 5116 gen_neon_widen(cpu_V0, tmp, size, u); 5117 5118 if (shift != 0) { 5119 /* The shift is less than the width of the source 5120 type, so we can just shift the whole register. */ 5121 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift); 5122 /* Widen the result of shift: we need to clear 5123 * the potential overflow bits resulting from 5124 * left bits of the narrow input appearing as 5125 * right bits of left the neighbour narrow 5126 * input. */ 5127 if (size < 2 || !u) { 5128 uint64_t imm64; 5129 if (size == 0) { 5130 imm = (0xffu >> (8 - shift)); 5131 imm |= imm << 16; 5132 } else if (size == 1) { 5133 imm = 0xffff >> (16 - shift); 5134 } else { 5135 /* size == 2 */ 5136 imm = 0xffffffff >> (32 - shift); 5137 } 5138 if (size < 2) { 5139 imm64 = imm | (((uint64_t)imm) << 32); 5140 } else { 5141 imm64 = imm; 5142 } 5143 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64); 5144 } 5145 } 5146 neon_store_reg64(cpu_V0, rd + pass); 5147 } 5148 } else if (op >= 14) { 5149 /* VCVT fixed-point. */ 5150 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { 5151 return 1; 5152 } 5153 /* We have already masked out the must-be-1 top bit of imm6, 5154 * hence this 32-shift where the ARM ARM has 64-imm6. 5155 */ 5156 shift = 32 - shift; 5157 for (pass = 0; pass < (q ? 4 : 2); pass++) { 5158 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); 5159 if (!(op & 1)) { 5160 if (u) 5161 gen_vfp_ulto(0, shift, 1); 5162 else 5163 gen_vfp_slto(0, shift, 1); 5164 } else { 5165 if (u) 5166 gen_vfp_toul(0, shift, 1); 5167 else 5168 gen_vfp_tosl(0, shift, 1); 5169 } 5170 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); 5171 } 5172 } else { 5173 return 1; 5174 } 5175 } else { /* (insn & 0x00380080) == 0 */ 5176 int invert; 5177 if (q && (rd & 1)) { 5178 return 1; 5179 } 5180 5181 op = (insn >> 8) & 0xf; 5182 /* One register and immediate. */ 5183 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf); 5184 invert = (insn & (1 << 5)) != 0; 5185 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. 5186 * We choose to not special-case this and will behave as if a 5187 * valid constant encoding of 0 had been given. 5188 */ 5189 switch (op) { 5190 case 0: case 1: 5191 /* no-op */ 5192 break; 5193 case 2: case 3: 5194 imm <<= 8; 5195 break; 5196 case 4: case 5: 5197 imm <<= 16; 5198 break; 5199 case 6: case 7: 5200 imm <<= 24; 5201 break; 5202 case 8: case 9: 5203 imm |= imm << 16; 5204 break; 5205 case 10: case 11: 5206 imm = (imm << 8) | (imm << 24); 5207 break; 5208 case 12: 5209 imm = (imm << 8) | 0xff; 5210 break; 5211 case 13: 5212 imm = (imm << 16) | 0xffff; 5213 break; 5214 case 14: 5215 imm |= (imm << 8) | (imm << 16) | (imm << 24); 5216 if (invert) 5217 imm = ~imm; 5218 break; 5219 case 15: 5220 if (invert) { 5221 return 1; 5222 } 5223 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) 5224 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); 5225 break; 5226 } 5227 if (invert) 5228 imm = ~imm; 5229 5230 for (pass = 0; pass < (q ? 4 : 2); pass++) { 5231 if (op & 1 && op < 12) { 5232 tmp = neon_load_reg(rd, pass); 5233 if (invert) { 5234 /* The immediate value has already been inverted, so 5235 BIC becomes AND. */ 5236 tcg_gen_andi_i32(tmp, tmp, imm); 5237 } else { 5238 tcg_gen_ori_i32(tmp, tmp, imm); 5239 } 5240 } else { 5241 /* VMOV, VMVN. */ 5242 tmp = tcg_temp_new_i32(); 5243 if (op == 14 && invert) { 5244 int n; 5245 uint32_t val; 5246 val = 0; 5247 for (n = 0; n < 4; n++) { 5248 if (imm & (1 << (n + (pass & 1) * 4))) 5249 val |= 0xff << (n * 8); 5250 } 5251 tcg_gen_movi_i32(tmp, val); 5252 } else { 5253 tcg_gen_movi_i32(tmp, imm); 5254 } 5255 } 5256 neon_store_reg(rd, pass, tmp); 5257 } 5258 } 5259 } else { /* (insn & 0x00800010 == 0x00800000) */ 5260 if (size != 3) { 5261 op = (insn >> 8) & 0xf; 5262 if ((insn & (1 << 6)) == 0) { 5263 /* Three registers of different lengths. */ 5264 int src1_wide; 5265 int src2_wide; 5266 int prewiden; 5267 /* undefreq: bit 0 : UNDEF if size != 0 5268 * bit 1 : UNDEF if size == 0 5269 * bit 2 : UNDEF if U == 1 5270 * Note that [1:0] set implies 'always UNDEF' 5271 */ 5272 int undefreq; 5273 /* prewiden, src1_wide, src2_wide, undefreq */ 5274 static const int neon_3reg_wide[16][4] = { 5275 {1, 0, 0, 0}, /* VADDL */ 5276 {1, 1, 0, 0}, /* VADDW */ 5277 {1, 0, 0, 0}, /* VSUBL */ 5278 {1, 1, 0, 0}, /* VSUBW */ 5279 {0, 1, 1, 0}, /* VADDHN */ 5280 {0, 0, 0, 0}, /* VABAL */ 5281 {0, 1, 1, 0}, /* VSUBHN */ 5282 {0, 0, 0, 0}, /* VABDL */ 5283 {0, 0, 0, 0}, /* VMLAL */ 5284 {0, 0, 0, 6}, /* VQDMLAL */ 5285 {0, 0, 0, 0}, /* VMLSL */ 5286 {0, 0, 0, 6}, /* VQDMLSL */ 5287 {0, 0, 0, 0}, /* Integer VMULL */ 5288 {0, 0, 0, 2}, /* VQDMULL */ 5289 {0, 0, 0, 5}, /* Polynomial VMULL */ 5290 {0, 0, 0, 3}, /* Reserved: always UNDEF */ 5291 }; 5292 5293 prewiden = neon_3reg_wide[op][0]; 5294 src1_wide = neon_3reg_wide[op][1]; 5295 src2_wide = neon_3reg_wide[op][2]; 5296 undefreq = neon_3reg_wide[op][3]; 5297 5298 if (((undefreq & 1) && (size != 0)) || 5299 ((undefreq & 2) && (size == 0)) || 5300 ((undefreq & 4) && u)) { 5301 return 1; 5302 } 5303 if ((src1_wide && (rn & 1)) || 5304 (src2_wide && (rm & 1)) || 5305 (!src2_wide && (rd & 1))) { 5306 return 1; 5307 } 5308 5309 /* Avoid overlapping operands. Wide source operands are 5310 always aligned so will never overlap with wide 5311 destinations in problematic ways. */ 5312 if (rd == rm && !src2_wide) { 5313 tmp = neon_load_reg(rm, 1); 5314 neon_store_scratch(2, tmp); 5315 } else if (rd == rn && !src1_wide) { 5316 tmp = neon_load_reg(rn, 1); 5317 neon_store_scratch(2, tmp); 5318 } 5319 TCGV_UNUSED(tmp3); 5320 for (pass = 0; pass < 2; pass++) { 5321 if (src1_wide) { 5322 neon_load_reg64(cpu_V0, rn + pass); 5323 TCGV_UNUSED(tmp); 5324 } else { 5325 if (pass == 1 && rd == rn) { 5326 tmp = neon_load_scratch(2); 5327 } else { 5328 tmp = neon_load_reg(rn, pass); 5329 } 5330 if (prewiden) { 5331 gen_neon_widen(cpu_V0, tmp, size, u); 5332 } 5333 } 5334 if (src2_wide) { 5335 neon_load_reg64(cpu_V1, rm + pass); 5336 TCGV_UNUSED(tmp2); 5337 } else { 5338 if (pass == 1 && rd == rm) { 5339 tmp2 = neon_load_scratch(2); 5340 } else { 5341 tmp2 = neon_load_reg(rm, pass); 5342 } 5343 if (prewiden) { 5344 gen_neon_widen(cpu_V1, tmp2, size, u); 5345 } 5346 } 5347 switch (op) { 5348 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */ 5349 gen_neon_addl(size); 5350 break; 5351 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */ 5352 gen_neon_subl(size); 5353 break; 5354 case 5: case 7: /* VABAL, VABDL */ 5355 switch ((size << 1) | u) { 5356 case 0: 5357 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2); 5358 break; 5359 case 1: 5360 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2); 5361 break; 5362 case 2: 5363 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2); 5364 break; 5365 case 3: 5366 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2); 5367 break; 5368 case 4: 5369 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2); 5370 break; 5371 case 5: 5372 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2); 5373 break; 5374 default: abort(); 5375 } 5376 tcg_temp_free_i32(tmp2); 5377 tcg_temp_free_i32(tmp); 5378 break; 5379 case 8: case 9: case 10: case 11: case 12: case 13: 5380 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */ 5381 gen_neon_mull(cpu_V0, tmp, tmp2, size, u); 5382 break; 5383 case 14: /* Polynomial VMULL */ 5384 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2); 5385 tcg_temp_free_i32(tmp2); 5386 tcg_temp_free_i32(tmp); 5387 break; 5388 default: /* 15 is RESERVED: caught earlier */ 5389 abort(); 5390 } 5391 if (op == 13) { 5392 /* VQDMULL */ 5393 gen_neon_addl_saturate(cpu_V0, cpu_V0, size); 5394 neon_store_reg64(cpu_V0, rd + pass); 5395 } else if (op == 5 || (op >= 8 && op <= 11)) { 5396 /* Accumulate. */ 5397 neon_load_reg64(cpu_V1, rd + pass); 5398 switch (op) { 5399 case 10: /* VMLSL */ 5400 gen_neon_negl(cpu_V0, size); 5401 /* Fall through */ 5402 case 5: case 8: /* VABAL, VMLAL */ 5403 gen_neon_addl(size); 5404 break; 5405 case 9: case 11: /* VQDMLAL, VQDMLSL */ 5406 gen_neon_addl_saturate(cpu_V0, cpu_V0, size); 5407 if (op == 11) { 5408 gen_neon_negl(cpu_V0, size); 5409 } 5410 gen_neon_addl_saturate(cpu_V0, cpu_V1, size); 5411 break; 5412 default: 5413 abort(); 5414 } 5415 neon_store_reg64(cpu_V0, rd + pass); 5416 } else if (op == 4 || op == 6) { 5417 /* Narrowing operation. */ 5418 tmp = tcg_temp_new_i32(); 5419 if (!u) { 5420 switch (size) { 5421 case 0: 5422 gen_helper_neon_narrow_high_u8(tmp, cpu_V0); 5423 break; 5424 case 1: 5425 gen_helper_neon_narrow_high_u16(tmp, cpu_V0); 5426 break; 5427 case 2: 5428 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); 5429 tcg_gen_trunc_i64_i32(tmp, cpu_V0); 5430 break; 5431 default: abort(); 5432 } 5433 } else { 5434 switch (size) { 5435 case 0: 5436 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0); 5437 break; 5438 case 1: 5439 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0); 5440 break; 5441 case 2: 5442 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31); 5443 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); 5444 tcg_gen_trunc_i64_i32(tmp, cpu_V0); 5445 break; 5446 default: abort(); 5447 } 5448 } 5449 if (pass == 0) { 5450 tmp3 = tmp; 5451 } else { 5452 neon_store_reg(rd, 0, tmp3); 5453 neon_store_reg(rd, 1, tmp); 5454 } 5455 } else { 5456 /* Write back the result. */ 5457 neon_store_reg64(cpu_V0, rd + pass); 5458 } 5459 } 5460 } else { 5461 /* Two registers and a scalar. NB that for ops of this form 5462 * the ARM ARM labels bit 24 as Q, but it is in our variable 5463 * 'u', not 'q'. 5464 */ 5465 if (size == 0) { 5466 return 1; 5467 } 5468 switch (op) { 5469 case 1: /* Float VMLA scalar */ 5470 case 5: /* Floating point VMLS scalar */ 5471 case 9: /* Floating point VMUL scalar */ 5472 if (size == 1) { 5473 return 1; 5474 } 5475 /* fall through */ 5476 case 0: /* Integer VMLA scalar */ 5477 case 4: /* Integer VMLS scalar */ 5478 case 8: /* Integer VMUL scalar */ 5479 case 12: /* VQDMULH scalar */ 5480 case 13: /* VQRDMULH scalar */ 5481 if (u && ((rd | rn) & 1)) { 5482 return 1; 5483 } 5484 tmp = neon_get_scalar(size, rm); 5485 neon_store_scratch(0, tmp); 5486 for (pass = 0; pass < (u ? 4 : 2); pass++) { 5487 tmp = neon_load_scratch(0); 5488 tmp2 = neon_load_reg(rn, pass); 5489 if (op == 12) { 5490 if (size == 1) { 5491 gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2); 5492 } else { 5493 gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2); 5494 } 5495 } else if (op == 13) { 5496 if (size == 1) { 5497 gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2); 5498 } else { 5499 gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2); 5500 } 5501 } else if (op & 1) { 5502 gen_helper_neon_mul_f32(tmp, tmp, tmp2); 5503 } else { 5504 switch (size) { 5505 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; 5506 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; 5507 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; 5508 default: abort(); 5509 } 5510 } 5511 tcg_temp_free_i32(tmp2); 5512 if (op < 8) { 5513 /* Accumulate. */ 5514 tmp2 = neon_load_reg(rd, pass); 5515 switch (op) { 5516 case 0: 5517 gen_neon_add(size, tmp, tmp2); 5518 break; 5519 case 1: 5520 gen_helper_neon_add_f32(tmp, tmp, tmp2); 5521 break; 5522 case 4: 5523 gen_neon_rsb(size, tmp, tmp2); 5524 break; 5525 case 5: 5526 gen_helper_neon_sub_f32(tmp, tmp2, tmp); 5527 break; 5528 default: 5529 abort(); 5530 } 5531 tcg_temp_free_i32(tmp2); 5532 } 5533 neon_store_reg(rd, pass, tmp); 5534 } 5535 break; 5536 case 3: /* VQDMLAL scalar */ 5537 case 7: /* VQDMLSL scalar */ 5538 case 11: /* VQDMULL scalar */ 5539 if (u == 1) { 5540 return 1; 5541 } 5542 /* fall through */ 5543 case 2: /* VMLAL sclar */ 5544 case 6: /* VMLSL scalar */ 5545 case 10: /* VMULL scalar */ 5546 if (rd & 1) { 5547 return 1; 5548 } 5549 tmp2 = neon_get_scalar(size, rm); 5550 /* We need a copy of tmp2 because gen_neon_mull 5551 * deletes it during pass 0. */ 5552 tmp4 = tcg_temp_new_i32(); 5553 tcg_gen_mov_i32(tmp4, tmp2); 5554 tmp3 = neon_load_reg(rn, 1); 5555 5556 for (pass = 0; pass < 2; pass++) { 5557 if (pass == 0) { 5558 tmp = neon_load_reg(rn, 0); 5559 } else { 5560 tmp = tmp3; 5561 tmp2 = tmp4; 5562 } 5563 gen_neon_mull(cpu_V0, tmp, tmp2, size, u); 5564 if (op != 11) { 5565 neon_load_reg64(cpu_V1, rd + pass); 5566 } 5567 switch (op) { 5568 case 6: 5569 gen_neon_negl(cpu_V0, size); 5570 /* Fall through */ 5571 case 2: 5572 gen_neon_addl(size); 5573 break; 5574 case 3: case 7: 5575 gen_neon_addl_saturate(cpu_V0, cpu_V0, size); 5576 if (op == 7) { 5577 gen_neon_negl(cpu_V0, size); 5578 } 5579 gen_neon_addl_saturate(cpu_V0, cpu_V1, size); 5580 break; 5581 case 10: 5582 /* no-op */ 5583 break; 5584 case 11: 5585 gen_neon_addl_saturate(cpu_V0, cpu_V0, size); 5586 break; 5587 default: 5588 abort(); 5589 } 5590 neon_store_reg64(cpu_V0, rd + pass); 5591 } 5592 5593 5594 break; 5595 default: /* 14 and 15 are RESERVED */ 5596 return 1; 5597 } 5598 } 5599 } else { /* size == 3 */ 5600 if (!u) { 5601 /* Extract. */ 5602 imm = (insn >> 8) & 0xf; 5603 5604 if (imm > 7 && !q) 5605 return 1; 5606 5607 if (q && ((rd | rn | rm) & 1)) { 5608 return 1; 5609 } 5610 5611 if (imm == 0) { 5612 neon_load_reg64(cpu_V0, rn); 5613 if (q) { 5614 neon_load_reg64(cpu_V1, rn + 1); 5615 } 5616 } else if (imm == 8) { 5617 neon_load_reg64(cpu_V0, rn + 1); 5618 if (q) { 5619 neon_load_reg64(cpu_V1, rm); 5620 } 5621 } else if (q) { 5622 tmp64 = tcg_temp_new_i64(); 5623 if (imm < 8) { 5624 neon_load_reg64(cpu_V0, rn); 5625 neon_load_reg64(tmp64, rn + 1); 5626 } else { 5627 neon_load_reg64(cpu_V0, rn + 1); 5628 neon_load_reg64(tmp64, rm); 5629 } 5630 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8); 5631 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8)); 5632 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); 5633 if (imm < 8) { 5634 neon_load_reg64(cpu_V1, rm); 5635 } else { 5636 neon_load_reg64(cpu_V1, rm + 1); 5637 imm -= 8; 5638 } 5639 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); 5640 tcg_gen_shri_i64(tmp64, tmp64, imm * 8); 5641 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64); 5642 tcg_temp_free_i64(tmp64); 5643 } else { 5644 /* BUGFIX */ 5645 neon_load_reg64(cpu_V0, rn); 5646 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8); 5647 neon_load_reg64(cpu_V1, rm); 5648 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); 5649 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); 5650 } 5651 neon_store_reg64(cpu_V0, rd); 5652 if (q) { 5653 neon_store_reg64(cpu_V1, rd + 1); 5654 } 5655 } else if ((insn & (1 << 11)) == 0) { 5656 /* Two register misc. */ 5657 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf); 5658 size = (insn >> 18) & 3; 5659 /* UNDEF for unknown op values and bad op-size combinations */ 5660 if ((neon_2rm_sizes[op] & (1 << size)) == 0) { 5661 return 1; 5662 } 5663 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) && 5664 q && ((rm | rd) & 1)) { 5665 return 1; 5666 } 5667 switch (op) { 5668 case NEON_2RM_VREV64: 5669 for (pass = 0; pass < (q ? 2 : 1); pass++) { 5670 tmp = neon_load_reg(rm, pass * 2); 5671 tmp2 = neon_load_reg(rm, pass * 2 + 1); 5672 switch (size) { 5673 case 0: tcg_gen_bswap32_i32(tmp, tmp); break; 5674 case 1: gen_swap_half(tmp); break; 5675 case 2: /* no-op */ break; 5676 default: abort(); 5677 } 5678 neon_store_reg(rd, pass * 2 + 1, tmp); 5679 if (size == 2) { 5680 neon_store_reg(rd, pass * 2, tmp2); 5681 } else { 5682 switch (size) { 5683 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break; 5684 case 1: gen_swap_half(tmp2); break; 5685 default: abort(); 5686 } 5687 neon_store_reg(rd, pass * 2, tmp2); 5688 } 5689 } 5690 break; 5691 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U: 5692 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U: 5693 for (pass = 0; pass < q + 1; pass++) { 5694 tmp = neon_load_reg(rm, pass * 2); 5695 gen_neon_widen(cpu_V0, tmp, size, op & 1); 5696 tmp = neon_load_reg(rm, pass * 2 + 1); 5697 gen_neon_widen(cpu_V1, tmp, size, op & 1); 5698 switch (size) { 5699 case 0: gen_helper_neon_paddl_u16(CPU_V001); break; 5700 case 1: gen_helper_neon_paddl_u32(CPU_V001); break; 5701 case 2: tcg_gen_add_i64(CPU_V001); break; 5702 default: abort(); 5703 } 5704 if (op >= NEON_2RM_VPADAL) { 5705 /* Accumulate. */ 5706 neon_load_reg64(cpu_V1, rd + pass); 5707 gen_neon_addl(size); 5708 } 5709 neon_store_reg64(cpu_V0, rd + pass); 5710 } 5711 break; 5712 case NEON_2RM_VTRN: 5713 if (size == 2) { 5714 int n; 5715 for (n = 0; n < (q ? 4 : 2); n += 2) { 5716 tmp = neon_load_reg(rm, n); 5717 tmp2 = neon_load_reg(rd, n + 1); 5718 neon_store_reg(rm, n, tmp2); 5719 neon_store_reg(rd, n + 1, tmp); 5720 } 5721 } else { 5722 goto elementwise; 5723 } 5724 break; 5725 case NEON_2RM_VUZP: 5726 if (gen_neon_unzip(rd, rm, size, q)) { 5727 return 1; 5728 } 5729 break; 5730 case NEON_2RM_VZIP: 5731 if (gen_neon_zip(rd, rm, size, q)) { 5732 return 1; 5733 } 5734 break; 5735 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN: 5736 /* also VQMOVUN; op field and mnemonics don't line up */ 5737 if (rm & 1) { 5738 return 1; 5739 } 5740 TCGV_UNUSED(tmp2); 5741 for (pass = 0; pass < 2; pass++) { 5742 neon_load_reg64(cpu_V0, rm + pass); 5743 tmp = tcg_temp_new_i32(); 5744 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size, 5745 tmp, cpu_V0); 5746 if (pass == 0) { 5747 tmp2 = tmp; 5748 } else { 5749 neon_store_reg(rd, 0, tmp2); 5750 neon_store_reg(rd, 1, tmp); 5751 } 5752 } 5753 break; 5754 case NEON_2RM_VSHLL: 5755 if (q || (rd & 1)) { 5756 return 1; 5757 } 5758 tmp = neon_load_reg(rm, 0); 5759 tmp2 = neon_load_reg(rm, 1); 5760 for (pass = 0; pass < 2; pass++) { 5761 if (pass == 1) 5762 tmp = tmp2; 5763 gen_neon_widen(cpu_V0, tmp, size, 1); 5764 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size); 5765 neon_store_reg64(cpu_V0, rd + pass); 5766 } 5767 break; 5768 case NEON_2RM_VCVT_F16_F32: 5769 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) || 5770 q || (rm & 1)) { 5771 return 1; 5772 } 5773 tmp = tcg_temp_new_i32(); 5774 tmp2 = tcg_temp_new_i32(); 5775 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0)); 5776 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); 5777 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1)); 5778 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); 5779 tcg_gen_shli_i32(tmp2, tmp2, 16); 5780 tcg_gen_or_i32(tmp2, tmp2, tmp); 5781 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2)); 5782 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); 5783 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3)); 5784 neon_store_reg(rd, 0, tmp2); 5785 tmp2 = tcg_temp_new_i32(); 5786 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); 5787 tcg_gen_shli_i32(tmp2, tmp2, 16); 5788 tcg_gen_or_i32(tmp2, tmp2, tmp); 5789 neon_store_reg(rd, 1, tmp2); 5790 tcg_temp_free_i32(tmp); 5791 break; 5792 case NEON_2RM_VCVT_F32_F16: 5793 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) || 5794 q || (rd & 1)) { 5795 return 1; 5796 } 5797 tmp3 = tcg_temp_new_i32(); 5798 tmp = neon_load_reg(rm, 0); 5799 tmp2 = neon_load_reg(rm, 1); 5800 tcg_gen_ext16u_i32(tmp3, tmp); 5801 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); 5802 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0)); 5803 tcg_gen_shri_i32(tmp3, tmp, 16); 5804 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); 5805 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1)); 5806 tcg_temp_free_i32(tmp); 5807 tcg_gen_ext16u_i32(tmp3, tmp2); 5808 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); 5809 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2)); 5810 tcg_gen_shri_i32(tmp3, tmp2, 16); 5811 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); 5812 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3)); 5813 tcg_temp_free_i32(tmp2); 5814 tcg_temp_free_i32(tmp3); 5815 break; 5816 default: 5817 elementwise: 5818 for (pass = 0; pass < (q ? 4 : 2); pass++) { 5819 if (neon_2rm_is_float_op(op)) { 5820 tcg_gen_ld_f32(cpu_F0s, cpu_env, 5821 neon_reg_offset(rm, pass)); 5822 TCGV_UNUSED(tmp); 5823 } else { 5824 tmp = neon_load_reg(rm, pass); 5825 } 5826 switch (op) { 5827 case NEON_2RM_VREV32: 5828 switch (size) { 5829 case 0: tcg_gen_bswap32_i32(tmp, tmp); break; 5830 case 1: gen_swap_half(tmp); break; 5831 default: abort(); 5832 } 5833 break; 5834 case NEON_2RM_VREV16: 5835 gen_rev16(tmp); 5836 break; 5837 case NEON_2RM_VCLS: 5838 switch (size) { 5839 case 0: gen_helper_neon_cls_s8(tmp, tmp); break; 5840 case 1: gen_helper_neon_cls_s16(tmp, tmp); break; 5841 case 2: gen_helper_neon_cls_s32(tmp, tmp); break; 5842 default: abort(); 5843 } 5844 break; 5845 case NEON_2RM_VCLZ: 5846 switch (size) { 5847 case 0: gen_helper_neon_clz_u8(tmp, tmp); break; 5848 case 1: gen_helper_neon_clz_u16(tmp, tmp); break; 5849 case 2: gen_helper_clz(tmp, tmp); break; 5850 default: abort(); 5851 } 5852 break; 5853 case NEON_2RM_VCNT: 5854 gen_helper_neon_cnt_u8(tmp, tmp); 5855 break; 5856 case NEON_2RM_VMVN: 5857 tcg_gen_not_i32(tmp, tmp); 5858 break; 5859 case NEON_2RM_VQABS: 5860 switch (size) { 5861 case 0: gen_helper_neon_qabs_s8(tmp, tmp); break; 5862 case 1: gen_helper_neon_qabs_s16(tmp, tmp); break; 5863 case 2: gen_helper_neon_qabs_s32(tmp, tmp); break; 5864 default: abort(); 5865 } 5866 break; 5867 case NEON_2RM_VQNEG: 5868 switch (size) { 5869 case 0: gen_helper_neon_qneg_s8(tmp, tmp); break; 5870 case 1: gen_helper_neon_qneg_s16(tmp, tmp); break; 5871 case 2: gen_helper_neon_qneg_s32(tmp, tmp); break; 5872 default: abort(); 5873 } 5874 break; 5875 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0: 5876 tmp2 = tcg_const_i32(0); 5877 switch(size) { 5878 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break; 5879 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break; 5880 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break; 5881 default: abort(); 5882 } 5883 tcg_temp_free(tmp2); 5884 if (op == NEON_2RM_VCLE0) { 5885 tcg_gen_not_i32(tmp, tmp); 5886 } 5887 break; 5888 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0: 5889 tmp2 = tcg_const_i32(0); 5890 switch(size) { 5891 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break; 5892 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break; 5893 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break; 5894 default: abort(); 5895 } 5896 tcg_temp_free(tmp2); 5897 if (op == NEON_2RM_VCLT0) { 5898 tcg_gen_not_i32(tmp, tmp); 5899 } 5900 break; 5901 case NEON_2RM_VCEQ0: 5902 tmp2 = tcg_const_i32(0); 5903 switch(size) { 5904 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; 5905 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; 5906 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; 5907 default: abort(); 5908 } 5909 tcg_temp_free(tmp2); 5910 break; 5911 case NEON_2RM_VABS: 5912 switch(size) { 5913 case 0: gen_helper_neon_abs_s8(tmp, tmp); break; 5914 case 1: gen_helper_neon_abs_s16(tmp, tmp); break; 5915 case 2: tcg_gen_abs_i32(tmp, tmp); break; 5916 default: abort(); 5917 } 5918 break; 5919 case NEON_2RM_VNEG: 5920 tmp2 = tcg_const_i32(0); 5921 gen_neon_rsb(size, tmp, tmp2); 5922 tcg_temp_free(tmp2); 5923 break; 5924 case NEON_2RM_VCGT0_F: 5925 tmp2 = tcg_const_i32(0); 5926 gen_helper_neon_cgt_f32(tmp, tmp, tmp2); 5927 tcg_temp_free(tmp2); 5928 break; 5929 case NEON_2RM_VCGE0_F: 5930 tmp2 = tcg_const_i32(0); 5931 gen_helper_neon_cge_f32(tmp, tmp, tmp2); 5932 tcg_temp_free(tmp2); 5933 break; 5934 case NEON_2RM_VCEQ0_F: 5935 tmp2 = tcg_const_i32(0); 5936 gen_helper_neon_ceq_f32(tmp, tmp, tmp2); 5937 tcg_temp_free(tmp2); 5938 break; 5939 case NEON_2RM_VCLE0_F: 5940 tmp2 = tcg_const_i32(0); 5941 gen_helper_neon_cge_f32(tmp, tmp2, tmp); 5942 tcg_temp_free(tmp2); 5943 break; 5944 case NEON_2RM_VCLT0_F: 5945 tmp2 = tcg_const_i32(0); 5946 gen_helper_neon_cgt_f32(tmp, tmp2, tmp); 5947 tcg_temp_free(tmp2); 5948 break; 5949 case NEON_2RM_VABS_F: 5950 gen_vfp_abs(0); 5951 break; 5952 case NEON_2RM_VNEG_F: 5953 gen_vfp_neg(0); 5954 break; 5955 case NEON_2RM_VSWP: 5956 tmp2 = neon_load_reg(rd, pass); 5957 neon_store_reg(rm, pass, tmp2); 5958 break; 5959 case NEON_2RM_VTRN: 5960 tmp2 = neon_load_reg(rd, pass); 5961 switch (size) { 5962 case 0: gen_neon_trn_u8(tmp, tmp2); break; 5963 case 1: gen_neon_trn_u16(tmp, tmp2); break; 5964 default: abort(); 5965 } 5966 neon_store_reg(rm, pass, tmp2); 5967 break; 5968 case NEON_2RM_VRECPE: 5969 gen_helper_recpe_u32(tmp, tmp, cpu_env); 5970 break; 5971 case NEON_2RM_VRSQRTE: 5972 gen_helper_rsqrte_u32(tmp, tmp, cpu_env); 5973 break; 5974 case NEON_2RM_VRECPE_F: 5975 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env); 5976 break; 5977 case NEON_2RM_VRSQRTE_F: 5978 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env); 5979 break; 5980 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */ 5981 gen_vfp_sito(0, 1); 5982 break; 5983 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */ 5984 gen_vfp_uito(0, 1); 5985 break; 5986 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */ 5987 gen_vfp_tosiz(0, 1); 5988 break; 5989 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */ 5990 gen_vfp_touiz(0, 1); 5991 break; 5992 default: 5993 /* Reserved op values were caught by the 5994 * neon_2rm_sizes[] check earlier. 5995 */ 5996 abort(); 5997 } 5998 if (neon_2rm_is_float_op(op)) { 5999 tcg_gen_st_f32(cpu_F0s, cpu_env, 6000 neon_reg_offset(rd, pass)); 6001 } else { 6002 neon_store_reg(rd, pass, tmp); 6003 } 6004 } 6005 break; 6006 } 6007 } else if ((insn & (1 << 10)) == 0) { 6008 /* VTBL, VTBX. */ 6009 int n = ((insn >> 8) & 3) + 1; 6010 if ((rn + n) > 32) { 6011 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the 6012 * helper function running off the end of the register file. 6013 */ 6014 return 1; 6015 } 6016 n <<= 3; 6017 if (insn & (1 << 6)) { 6018 tmp = neon_load_reg(rd, 0); 6019 } else { 6020 tmp = tcg_temp_new_i32(); 6021 tcg_gen_movi_i32(tmp, 0); 6022 } 6023 tmp2 = neon_load_reg(rm, 0); 6024 tmp4 = tcg_const_i32(rn); 6025 tmp5 = tcg_const_i32(n); 6026 gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5); 6027 tcg_temp_free_i32(tmp); 6028 if (insn & (1 << 6)) { 6029 tmp = neon_load_reg(rd, 1); 6030 } else { 6031 tmp = tcg_temp_new_i32(); 6032 tcg_gen_movi_i32(tmp, 0); 6033 } 6034 tmp3 = neon_load_reg(rm, 1); 6035 gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5); 6036 tcg_temp_free_i32(tmp5); 6037 tcg_temp_free_i32(tmp4); 6038 neon_store_reg(rd, 0, tmp2); 6039 neon_store_reg(rd, 1, tmp3); 6040 tcg_temp_free_i32(tmp); 6041 } else if ((insn & 0x380) == 0) { 6042 /* VDUP */ 6043 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) { 6044 return 1; 6045 } 6046 if (insn & (1 << 19)) { 6047 tmp = neon_load_reg(rm, 1); 6048 } else { 6049 tmp = neon_load_reg(rm, 0); 6050 } 6051 if (insn & (1 << 16)) { 6052 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8); 6053 } else if (insn & (1 << 17)) { 6054 if ((insn >> 18) & 1) 6055 gen_neon_dup_high16(tmp); 6056 else 6057 gen_neon_dup_low16(tmp); 6058 } 6059 for (pass = 0; pass < (q ? 4 : 2); pass++) { 6060 tmp2 = tcg_temp_new_i32(); 6061 tcg_gen_mov_i32(tmp2, tmp); 6062 neon_store_reg(rd, pass, tmp2); 6063 } 6064 tcg_temp_free_i32(tmp); 6065 } else { 6066 return 1; 6067 } 6068 } 6069 } 6070 return 0; 6071} 6072 6073static int disas_cp14_read(CPUARMState * env, DisasContext *s, uint32_t insn) 6074{ 6075 int crn = (insn >> 16) & 0xf; 6076 int crm = insn & 0xf; 6077 int op1 = (insn >> 21) & 7; 6078 int op2 = (insn >> 5) & 7; 6079 int rt = (insn >> 12) & 0xf; 6080 TCGv tmp; 6081 6082 /* Minimal set of debug registers, since we don't support debug */ 6083 if (op1 == 0 && crn == 0 && op2 == 0) { 6084 switch (crm) { 6085 case 0: 6086 /* DBGDIDR: just RAZ. In particular this means the 6087 * "debug architecture version" bits will read as 6088 * a reserved value, which should cause Linux to 6089 * not try to use the debug hardware. 6090 */ 6091 tmp = tcg_const_i32(0); 6092 store_reg(s, rt, tmp); 6093 return 0; 6094 case 1: 6095 case 2: 6096 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we 6097 * don't implement memory mapped debug components 6098 */ 6099 if (ENABLE_ARCH_7) { 6100 tmp = tcg_const_i32(0); 6101 store_reg(s, rt, tmp); 6102 return 0; 6103 } 6104 break; 6105 default: 6106 break; 6107 } 6108 } 6109 6110 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { 6111 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) { 6112 /* TEECR */ 6113 if (IS_USER(s)) 6114 return 1; 6115 tmp = load_cpu_field(teecr); 6116 store_reg(s, rt, tmp); 6117 return 0; 6118 } 6119 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) { 6120 /* TEEHBR */ 6121 if (IS_USER(s) && (env->teecr & 1)) 6122 return 1; 6123 tmp = load_cpu_field(teehbr); 6124 store_reg(s, rt, tmp); 6125 return 0; 6126 } 6127 } 6128 fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n", 6129 op1, crn, crm, op2); 6130 return 1; 6131} 6132 6133static int disas_cp14_write(CPUARMState * env, DisasContext *s, uint32_t insn) 6134{ 6135 int crn = (insn >> 16) & 0xf; 6136 int crm = insn & 0xf; 6137 int op1 = (insn >> 21) & 7; 6138 int op2 = (insn >> 5) & 7; 6139 int rt = (insn >> 12) & 0xf; 6140 TCGv tmp; 6141 6142 /* Minimal set of debug registers, since we don't support debug */ 6143 if (op1 == 0 && crn == 0 && op2 == 0) { 6144 switch (crm) { 6145 case 0: 6146 /* DBGDIDR */ 6147 tmp = load_cpu_field(cp14_dbgdidr); 6148 store_reg(s, rt, tmp); 6149 return 0; 6150 case 1: 6151 case 2: 6152 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we 6153 * don't implement memory mapped debug components 6154 */ 6155 if (ENABLE_ARCH_7) { 6156 tmp = tcg_const_i32(0); 6157 store_reg(s, rt, tmp); 6158 return 0; 6159 } 6160 break; 6161 default: 6162 break; 6163 } 6164 } 6165 6166 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { 6167 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) { 6168 /* TEECR */ 6169 if (IS_USER(s)) 6170 return 1; 6171 tmp = load_reg(s, rt); 6172 gen_helper_set_teecr(cpu_env, tmp); 6173 tcg_temp_free_i32(tmp); 6174 return 0; 6175 } 6176 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) { 6177 /* TEEHBR */ 6178 if (IS_USER(s) && (env->teecr & 1)) 6179 return 1; 6180 tmp = load_reg(s, rt); 6181 store_cpu_field(tmp, teehbr); 6182 return 0; 6183 } 6184 } 6185 fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n", 6186 op1, crn, crm, op2); 6187 return 1; 6188} 6189 6190static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) 6191{ 6192 int cpnum; 6193 6194 cpnum = (insn >> 8) & 0xf; 6195 if (arm_feature(env, ARM_FEATURE_XSCALE) 6196 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum))) 6197 return 1; 6198 6199 switch (cpnum) { 6200 case 0: 6201 case 1: 6202 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 6203 return disas_iwmmxt_insn(env, s, insn); 6204 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { 6205 return disas_dsp_insn(env, s, insn); 6206 } 6207 goto board; 6208 case 10: 6209 case 11: 6210 return disas_vfp_insn (env, s, insn); 6211 case 14: 6212 /* Coprocessors 7-15 are architecturally reserved by ARM. 6213 Unfortunately Intel decided to ignore this. */ 6214 if (arm_feature(env, ARM_FEATURE_XSCALE)) 6215 goto board; 6216 if (insn & (1 << 20)) 6217 return disas_cp14_read(env, s, insn); 6218 else 6219 return disas_cp14_write(env, s, insn); 6220 case 15: 6221 return disas_cp15_insn (env, s, insn); 6222 default: 6223 board: 6224 /* Unknown coprocessor. See if the board has hooked it. */ 6225 return disas_cp_insn (env, s, insn); 6226 } 6227} 6228 6229 6230/* Store a 64-bit value to a register pair. Clobbers val. */ 6231static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val) 6232{ 6233 TCGv tmp; 6234 tmp = tcg_temp_new_i32(); 6235 tcg_gen_trunc_i64_i32(tmp, val); 6236 store_reg(s, rlow, tmp); 6237 tmp = tcg_temp_new_i32(); 6238 tcg_gen_shri_i64(val, val, 32); 6239 tcg_gen_trunc_i64_i32(tmp, val); 6240 store_reg(s, rhigh, tmp); 6241} 6242 6243/* load a 32-bit value from a register and perform a 64-bit accumulate. */ 6244static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow) 6245{ 6246 TCGv_i64 tmp; 6247 TCGv tmp2; 6248 6249 /* Load value and extend to 64 bits. */ 6250 tmp = tcg_temp_new_i64(); 6251 tmp2 = load_reg(s, rlow); 6252 tcg_gen_extu_i32_i64(tmp, tmp2); 6253 tcg_temp_free_i32(tmp2); 6254 tcg_gen_add_i64(val, val, tmp); 6255 tcg_temp_free_i64(tmp); 6256} 6257 6258/* load and add a 64-bit value from a register pair. */ 6259static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh) 6260{ 6261 TCGv_i64 tmp; 6262 TCGv tmpl; 6263 TCGv tmph; 6264 6265 /* Load 64-bit value rd:rn. */ 6266 tmpl = load_reg(s, rlow); 6267 tmph = load_reg(s, rhigh); 6268 tmp = tcg_temp_new_i64(); 6269 tcg_gen_concat_i32_i64(tmp, tmpl, tmph); 6270 tcg_temp_free_i32(tmpl); 6271 tcg_temp_free_i32(tmph); 6272 tcg_gen_add_i64(val, val, tmp); 6273 tcg_temp_free_i64(tmp); 6274} 6275 6276/* Set N and Z flags from a 64-bit value. */ 6277static void gen_logicq_cc(TCGv_i64 val) 6278{ 6279 TCGv tmp = tcg_temp_new_i32(); 6280 gen_helper_logicq_cc(tmp, val); 6281 gen_logic_CC(tmp); 6282 tcg_temp_free_i32(tmp); 6283} 6284 6285/* Load/Store exclusive instructions are implemented by remembering 6286 the value/address loaded, and seeing if these are the same 6287 when the store is performed. This should be is sufficient to implement 6288 the architecturally mandated semantics, and avoids having to monitor 6289 regular stores. 6290 6291 In system emulation mode only one CPU will be running at once, so 6292 this sequence is effectively atomic. In user emulation mode we 6293 throw an exception and handle the atomic operation elsewhere. */ 6294static void gen_load_exclusive(DisasContext *s, int rt, int rt2, 6295 TCGv addr, int size) 6296{ 6297 TCGv tmp; 6298 6299 switch (size) { 6300 case 0: 6301 tmp = gen_ld8u(addr, IS_USER(s)); 6302 break; 6303 case 1: 6304 tmp = gen_ld16u(addr, IS_USER(s)); 6305 break; 6306 case 2: 6307 case 3: 6308 tmp = gen_ld32(addr, IS_USER(s)); 6309 break; 6310 default: 6311 abort(); 6312 } 6313 tcg_gen_mov_i32(cpu_exclusive_val, tmp); 6314 store_reg(s, rt, tmp); 6315 if (size == 3) { 6316 TCGv tmp2 = tcg_temp_new_i32(); 6317 tcg_gen_addi_i32(tmp2, addr, 4); 6318 tmp = gen_ld32(tmp2, IS_USER(s)); 6319 tcg_temp_free_i32(tmp2); 6320 tcg_gen_mov_i32(cpu_exclusive_high, tmp); 6321 store_reg(s, rt2, tmp); 6322 } 6323 tcg_gen_mov_i32(cpu_exclusive_addr, addr); 6324} 6325 6326static void gen_clrex(DisasContext *s) 6327{ 6328 tcg_gen_movi_i32(cpu_exclusive_addr, -1); 6329} 6330 6331#ifdef CONFIG_USER_ONLY 6332static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, 6333 TCGv addr, int size) 6334{ 6335 tcg_gen_mov_i32(cpu_exclusive_test, addr); 6336 tcg_gen_movi_i32(cpu_exclusive_info, 6337 size | (rd << 4) | (rt << 8) | (rt2 << 12)); 6338 gen_exception_insn(s, 4, EXCP_STREX); 6339} 6340#else 6341static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, 6342 TCGv addr, int size) 6343{ 6344 TCGv tmp; 6345 int done_label; 6346 int fail_label; 6347 6348 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) { 6349 [addr] = {Rt}; 6350 {Rd} = 0; 6351 } else { 6352 {Rd} = 1; 6353 } */ 6354 fail_label = gen_new_label(); 6355 done_label = gen_new_label(); 6356 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label); 6357 switch (size) { 6358 case 0: 6359 tmp = gen_ld8u(addr, IS_USER(s)); 6360 break; 6361 case 1: 6362 tmp = gen_ld16u(addr, IS_USER(s)); 6363 break; 6364 case 2: 6365 case 3: 6366 tmp = gen_ld32(addr, IS_USER(s)); 6367 break; 6368 default: 6369 abort(); 6370 } 6371 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label); 6372 tcg_temp_free_i32(tmp); 6373 if (size == 3) { 6374 TCGv tmp2 = tcg_temp_new_i32(); 6375 tcg_gen_addi_i32(tmp2, addr, 4); 6376 tmp = gen_ld32(tmp2, IS_USER(s)); 6377 tcg_temp_free_i32(tmp2); 6378 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label); 6379 tcg_temp_free_i32(tmp); 6380 } 6381 tmp = load_reg(s, rt); 6382 switch (size) { 6383 case 0: 6384 gen_st8(tmp, addr, IS_USER(s)); 6385 break; 6386 case 1: 6387 gen_st16(tmp, addr, IS_USER(s)); 6388 break; 6389 case 2: 6390 case 3: 6391 gen_st32(tmp, addr, IS_USER(s)); 6392 break; 6393 default: 6394 abort(); 6395 } 6396 if (size == 3) { 6397 tcg_gen_addi_i32(addr, addr, 4); 6398 tmp = load_reg(s, rt2); 6399 gen_st32(tmp, addr, IS_USER(s)); 6400 } 6401 tcg_gen_movi_i32(cpu_R[rd], 0); 6402 tcg_gen_br(done_label); 6403 gen_set_label(fail_label); 6404 tcg_gen_movi_i32(cpu_R[rd], 1); 6405 gen_set_label(done_label); 6406 tcg_gen_movi_i32(cpu_exclusive_addr, -1); 6407} 6408#endif 6409 6410static void disas_arm_insn(CPUARMState * env, DisasContext *s) 6411{ 6412 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; 6413 TCGv tmp; 6414 TCGv tmp2; 6415 TCGv tmp3; 6416 TCGv addr; 6417 TCGv_i64 tmp64; 6418 6419 insn = cpu_ldl_code(env, s->pc); 6420 6421 ANDROID_WATCH_CALLSTACK_ARM(s); 6422 6423 s->pc += 4; 6424 6425 /* M variants do not implement ARM mode. */ 6426 if (IS_M(env)) 6427 goto illegal_op; 6428 cond = insn >> 28; 6429 if (cond == 0xf){ 6430 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we 6431 * choose to UNDEF. In ARMv5 and above the space is used 6432 * for miscellaneous unconditional instructions. 6433 */ 6434 ARCH(5); 6435 6436 /* Unconditional instructions. */ 6437 if (((insn >> 25) & 7) == 1) { 6438 /* NEON Data processing. */ 6439 if (!arm_feature(env, ARM_FEATURE_NEON)) 6440 goto illegal_op; 6441 6442 if (disas_neon_data_insn(env, s, insn)) 6443 goto illegal_op; 6444 return; 6445 } 6446 if ((insn & 0x0f100000) == 0x04000000) { 6447 /* NEON load/store. */ 6448 if (!arm_feature(env, ARM_FEATURE_NEON)) 6449 goto illegal_op; 6450 6451 if (disas_neon_ls_insn(env, s, insn)) 6452 goto illegal_op; 6453 return; 6454 } 6455 if (((insn & 0x0f30f000) == 0x0510f000) || 6456 ((insn & 0x0f30f010) == 0x0710f000)) { 6457 if ((insn & (1 << 22)) == 0) { 6458 /* PLDW; v7MP */ 6459 if (!arm_feature(env, ARM_FEATURE_V7MP)) { 6460 goto illegal_op; 6461 } 6462 } 6463 /* Otherwise PLD; v5TE+ */ 6464 ARCH(5TE); 6465 return; 6466 } 6467 if (((insn & 0x0f70f000) == 0x0450f000) || 6468 ((insn & 0x0f70f010) == 0x0650f000)) { 6469 ARCH(7); 6470 return; /* PLI; V7 */ 6471 } 6472 if (((insn & 0x0f700000) == 0x04100000) || 6473 ((insn & 0x0f700010) == 0x06100000)) { 6474 if (!arm_feature(env, ARM_FEATURE_V7MP)) { 6475 goto illegal_op; 6476 } 6477 return; /* v7MP: Unallocated memory hint: must NOP */ 6478 } 6479 6480 if ((insn & 0x0ffffdff) == 0x01010000) { 6481 ARCH(6); 6482 /* setend */ 6483 if (insn & (1 << 9)) { 6484 /* BE8 mode not implemented. */ 6485 goto illegal_op; 6486 } 6487 return; 6488 } else if ((insn & 0x0fffff00) == 0x057ff000) { 6489 switch ((insn >> 4) & 0xf) { 6490 case 1: /* clrex */ 6491 ARCH(6K); 6492 gen_clrex(s); 6493 return; 6494 case 4: /* dsb */ 6495 case 5: /* dmb */ 6496 case 6: /* isb */ 6497 ARCH(7); 6498 /* We don't emulate caches so these are a no-op. */ 6499 return; 6500 default: 6501 goto illegal_op; 6502 } 6503 } else if ((insn & 0x0e5fffe0) == 0x084d0500) { 6504 /* srs */ 6505 int32_t offset; 6506 if (IS_USER(s)) 6507 goto illegal_op; 6508 ARCH(6); 6509 op1 = (insn & 0x1f); 6510 addr = tcg_temp_new_i32(); 6511 tmp = tcg_const_i32(op1); 6512 gen_helper_get_r13_banked(addr, cpu_env, tmp); 6513 tcg_temp_free_i32(tmp); 6514 i = (insn >> 23) & 3; 6515 switch (i) { 6516 case 0: offset = -4; break; /* DA */ 6517 case 1: offset = 0; break; /* IA */ 6518 case 2: offset = -8; break; /* DB */ 6519 case 3: offset = 4; break; /* IB */ 6520 default: abort(); 6521 } 6522 if (offset) 6523 tcg_gen_addi_i32(addr, addr, offset); 6524 tmp = load_reg(s, 14); 6525 gen_st32(tmp, addr, 0); 6526 tmp = load_cpu_field(spsr); 6527 tcg_gen_addi_i32(addr, addr, 4); 6528 gen_st32(tmp, addr, 0); 6529 if (insn & (1 << 21)) { 6530 /* Base writeback. */ 6531 switch (i) { 6532 case 0: offset = -8; break; 6533 case 1: offset = 4; break; 6534 case 2: offset = -4; break; 6535 case 3: offset = 0; break; 6536 default: abort(); 6537 } 6538 if (offset) 6539 tcg_gen_addi_i32(addr, addr, offset); 6540 tmp = tcg_const_i32(op1); 6541 gen_helper_set_r13_banked(cpu_env, tmp, addr); 6542 tcg_temp_free_i32(tmp); 6543 tcg_temp_free_i32(addr); 6544 } else { 6545 tcg_temp_free_i32(addr); 6546 } 6547 return; 6548 } else if ((insn & 0x0e50ffe0) == 0x08100a00) { 6549 /* rfe */ 6550 int32_t offset; 6551 if (IS_USER(s)) 6552 goto illegal_op; 6553 ARCH(6); 6554 rn = (insn >> 16) & 0xf; 6555 addr = load_reg(s, rn); 6556 i = (insn >> 23) & 3; 6557 switch (i) { 6558 case 0: offset = -4; break; /* DA */ 6559 case 1: offset = 0; break; /* IA */ 6560 case 2: offset = -8; break; /* DB */ 6561 case 3: offset = 4; break; /* IB */ 6562 default: abort(); 6563 } 6564 if (offset) 6565 tcg_gen_addi_i32(addr, addr, offset); 6566 /* Load PC into tmp and CPSR into tmp2. */ 6567 tmp = gen_ld32(addr, 0); 6568 tcg_gen_addi_i32(addr, addr, 4); 6569 tmp2 = gen_ld32(addr, 0); 6570 if (insn & (1 << 21)) { 6571 /* Base writeback. */ 6572 switch (i) { 6573 case 0: offset = -8; break; 6574 case 1: offset = 4; break; 6575 case 2: offset = -4; break; 6576 case 3: offset = 0; break; 6577 default: abort(); 6578 } 6579 if (offset) 6580 tcg_gen_addi_i32(addr, addr, offset); 6581 store_reg(s, rn, addr); 6582 } else { 6583 tcg_temp_free_i32(addr); 6584 } 6585 gen_rfe(s, tmp, tmp2); 6586 return; 6587 } else if ((insn & 0x0e000000) == 0x0a000000) { 6588 /* branch link and change to thumb (blx <offset>) */ 6589 int32_t offset; 6590 6591 val = (uint32_t)s->pc; 6592 tmp = tcg_temp_new_i32(); 6593 tcg_gen_movi_i32(tmp, val); 6594 store_reg(s, 14, tmp); 6595 /* Sign-extend the 24-bit offset */ 6596 offset = (((int32_t)insn) << 8) >> 8; 6597 /* offset * 4 + bit24 * 2 + (thumb bit) */ 6598 val += (offset << 2) | ((insn >> 23) & 2) | 1; 6599 /* pipeline offset */ 6600 val += 4; 6601 /* protected by ARCH(5); above, near the start of uncond block */ 6602 gen_bx_im(s, val); 6603 return; 6604 } else if ((insn & 0x0e000f00) == 0x0c000100) { 6605 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 6606 /* iWMMXt register transfer. */ 6607 if (env->cp15.c15_cpar & (1 << 1)) 6608 if (!disas_iwmmxt_insn(env, s, insn)) 6609 return; 6610 } 6611 } else if ((insn & 0x0fe00000) == 0x0c400000) { 6612 /* Coprocessor double register transfer. */ 6613 ARCH(5TE); 6614 } else if ((insn & 0x0f000010) == 0x0e000010) { 6615 /* Additional coprocessor register transfer. */ 6616 if (!disas_coproc_insn(env, s, insn)) { 6617 return; 6618 } 6619 } else if ((insn & 0x0ff10020) == 0x01000000) { 6620 uint32_t mask; 6621 uint32_t val; 6622 /* cps (privileged) */ 6623 if (IS_USER(s)) 6624 return; 6625 mask = val = 0; 6626 if (insn & (1 << 19)) { 6627 if (insn & (1 << 8)) 6628 mask |= CPSR_A; 6629 if (insn & (1 << 7)) 6630 mask |= CPSR_I; 6631 if (insn & (1 << 6)) 6632 mask |= CPSR_F; 6633 if (insn & (1 << 18)) 6634 val |= mask; 6635 } 6636 if (insn & (1 << 17)) { 6637 mask |= CPSR_M; 6638 val |= (insn & 0x1f); 6639 } 6640 if (mask) { 6641 gen_set_psr_im(s, mask, 0, val); 6642 } 6643 return; 6644 } 6645 goto illegal_op; 6646 } 6647 if (cond != 0xe) { 6648 /* if not always execute, we generate a conditional jump to 6649 next instruction */ 6650 s->condlabel = gen_new_label(); 6651 gen_test_cc(cond ^ 1, s->condlabel); 6652 s->condjmp = 1; 6653 } 6654 if ((insn & 0x0f900000) == 0x03000000) { 6655 if ((insn & (1 << 21)) == 0) { 6656 ARCH(6T2); 6657 rd = (insn >> 12) & 0xf; 6658 val = ((insn >> 4) & 0xf000) | (insn & 0xfff); 6659 if ((insn & (1 << 22)) == 0) { 6660 /* MOVW */ 6661 tmp = tcg_temp_new_i32(); 6662 tcg_gen_movi_i32(tmp, val); 6663 } else { 6664 /* MOVT */ 6665 tmp = load_reg(s, rd); 6666 tcg_gen_ext16u_i32(tmp, tmp); 6667 tcg_gen_ori_i32(tmp, tmp, val << 16); 6668 } 6669 store_reg(s, rd, tmp); 6670 } else { 6671 if (((insn >> 12) & 0xf) != 0xf) 6672 goto illegal_op; 6673 if (((insn >> 16) & 0xf) == 0) { 6674 gen_nop_hint(s, insn & 0xff); 6675 } else { 6676 /* CPSR = immediate */ 6677 val = insn & 0xff; 6678 shift = ((insn >> 8) & 0xf) * 2; 6679 if (shift) 6680 val = (val >> shift) | (val << (32 - shift)); 6681 i = ((insn & (1 << 22)) != 0); 6682 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val)) 6683 goto illegal_op; 6684 } 6685 } 6686 } else if ((insn & 0x0f900000) == 0x01000000 6687 && (insn & 0x00000090) != 0x00000090) { 6688 /* miscellaneous instructions */ 6689 op1 = (insn >> 21) & 3; 6690 sh = (insn >> 4) & 0xf; 6691 rm = insn & 0xf; 6692 switch (sh) { 6693 case 0x0: /* move program status register */ 6694 if (op1 & 1) { 6695 /* PSR = reg */ 6696 tmp = load_reg(s, rm); 6697 i = ((op1 & 2) != 0); 6698 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp)) 6699 goto illegal_op; 6700 } else { 6701 /* reg = PSR */ 6702 rd = (insn >> 12) & 0xf; 6703 if (op1 & 2) { 6704 if (IS_USER(s)) 6705 goto illegal_op; 6706 tmp = load_cpu_field(spsr); 6707 } else { 6708 tmp = tcg_temp_new_i32(); 6709 gen_helper_cpsr_read(tmp); 6710 } 6711 store_reg(s, rd, tmp); 6712 } 6713 break; 6714 case 0x1: 6715 if (op1 == 1) { 6716 /* branch/exchange thumb (bx). */ 6717 ARCH(4T); 6718 tmp = load_reg(s, rm); 6719 gen_bx(s, tmp); 6720 } else if (op1 == 3) { 6721 /* clz */ 6722 ARCH(5); 6723 rd = (insn >> 12) & 0xf; 6724 tmp = load_reg(s, rm); 6725 gen_helper_clz(tmp, tmp); 6726 store_reg(s, rd, tmp); 6727 } else { 6728 goto illegal_op; 6729 } 6730 break; 6731 case 0x2: 6732 if (op1 == 1) { 6733 ARCH(5J); /* bxj */ 6734 /* Trivial implementation equivalent to bx. */ 6735 tmp = load_reg(s, rm); 6736 gen_bx(s, tmp); 6737 } else { 6738 goto illegal_op; 6739 } 6740 break; 6741 case 0x3: 6742 if (op1 != 1) 6743 goto illegal_op; 6744 6745 ARCH(5); 6746 /* branch link/exchange thumb (blx) */ 6747 tmp = load_reg(s, rm); 6748 tmp2 = tcg_temp_new_i32(); 6749 tcg_gen_movi_i32(tmp2, s->pc); 6750 store_reg(s, 14, tmp2); 6751 gen_bx(s, tmp); 6752 break; 6753 case 0x5: /* saturating add/subtract */ 6754 ARCH(5TE); 6755 rd = (insn >> 12) & 0xf; 6756 rn = (insn >> 16) & 0xf; 6757 tmp = load_reg(s, rm); 6758 tmp2 = load_reg(s, rn); 6759 if (op1 & 2) 6760 gen_helper_double_saturate(tmp2, tmp2); 6761 if (op1 & 1) 6762 gen_helper_sub_saturate(tmp, tmp, tmp2); 6763 else 6764 gen_helper_add_saturate(tmp, tmp, tmp2); 6765 tcg_temp_free_i32(tmp2); 6766 store_reg(s, rd, tmp); 6767 break; 6768 case 7: 6769 if (op1 == 1) { 6770 /* bkpt */ 6771 ARCH(5); 6772 gen_exception_insn(s, 4, EXCP_BKPT); 6773 } else if (op1 == 3) { 6774 /* smi/smc */ 6775 if (!(env->cp15.c0_c2[4] & 0xf000) || IS_USER(s)) { 6776 goto illegal_op; 6777 } 6778 gen_smc(env, s); 6779 } else { 6780 goto illegal_op; 6781 } 6782 break; 6783 case 0x8: /* signed multiply */ 6784 case 0xa: 6785 case 0xc: 6786 case 0xe: 6787 ARCH(5TE); 6788 rs = (insn >> 8) & 0xf; 6789 rn = (insn >> 12) & 0xf; 6790 rd = (insn >> 16) & 0xf; 6791 if (op1 == 1) { 6792 /* (32 * 16) >> 16 */ 6793 tmp = load_reg(s, rm); 6794 tmp2 = load_reg(s, rs); 6795 if (sh & 4) 6796 tcg_gen_sari_i32(tmp2, tmp2, 16); 6797 else 6798 gen_sxth(tmp2); 6799 tmp64 = gen_muls_i64_i32(tmp, tmp2); 6800 tcg_gen_shri_i64(tmp64, tmp64, 16); 6801 tmp = tcg_temp_new_i32(); 6802 tcg_gen_trunc_i64_i32(tmp, tmp64); 6803 tcg_temp_free_i64(tmp64); 6804 if ((sh & 2) == 0) { 6805 tmp2 = load_reg(s, rn); 6806 gen_helper_add_setq(tmp, tmp, tmp2); 6807 tcg_temp_free_i32(tmp2); 6808 } 6809 store_reg(s, rd, tmp); 6810 } else { 6811 /* 16 * 16 */ 6812 tmp = load_reg(s, rm); 6813 tmp2 = load_reg(s, rs); 6814 gen_mulxy(tmp, tmp2, sh & 2, sh & 4); 6815 tcg_temp_free_i32(tmp2); 6816 if (op1 == 2) { 6817 tmp64 = tcg_temp_new_i64(); 6818 tcg_gen_ext_i32_i64(tmp64, tmp); 6819 tcg_temp_free_i32(tmp); 6820 gen_addq(s, tmp64, rn, rd); 6821 gen_storeq_reg(s, rn, rd, tmp64); 6822 tcg_temp_free_i64(tmp64); 6823 } else { 6824 if (op1 == 0) { 6825 tmp2 = load_reg(s, rn); 6826 gen_helper_add_setq(tmp, tmp, tmp2); 6827 tcg_temp_free_i32(tmp2); 6828 } 6829 store_reg(s, rd, tmp); 6830 } 6831 } 6832 break; 6833 default: 6834 goto illegal_op; 6835 } 6836 } else if (((insn & 0x0e000000) == 0 && 6837 (insn & 0x00000090) != 0x90) || 6838 ((insn & 0x0e000000) == (1 << 25))) { 6839 int set_cc, logic_cc, shiftop; 6840 6841 op1 = (insn >> 21) & 0xf; 6842 set_cc = (insn >> 20) & 1; 6843 logic_cc = table_logic_cc[op1] & set_cc; 6844 6845 /* data processing instruction */ 6846 if (insn & (1 << 25)) { 6847 /* immediate operand */ 6848 val = insn & 0xff; 6849 shift = ((insn >> 8) & 0xf) * 2; 6850 if (shift) { 6851 val = (val >> shift) | (val << (32 - shift)); 6852 } 6853 tmp2 = tcg_temp_new_i32(); 6854 tcg_gen_movi_i32(tmp2, val); 6855 if (logic_cc && shift) { 6856 gen_set_CF_bit31(tmp2); 6857 } 6858 } else { 6859 /* register */ 6860 rm = (insn) & 0xf; 6861 tmp2 = load_reg(s, rm); 6862 shiftop = (insn >> 5) & 3; 6863 if (!(insn & (1 << 4))) { 6864 shift = (insn >> 7) & 0x1f; 6865 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); 6866 } else { 6867 rs = (insn >> 8) & 0xf; 6868 tmp = load_reg(s, rs); 6869 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); 6870 } 6871 } 6872 if (op1 != 0x0f && op1 != 0x0d) { 6873 rn = (insn >> 16) & 0xf; 6874 tmp = load_reg(s, rn); 6875 } else { 6876 TCGV_UNUSED(tmp); 6877 } 6878 rd = (insn >> 12) & 0xf; 6879 switch(op1) { 6880 case 0x00: 6881 tcg_gen_and_i32(tmp, tmp, tmp2); 6882 if (logic_cc) { 6883 gen_logic_CC(tmp); 6884 } 6885 store_reg_bx(env, s, rd, tmp); 6886 break; 6887 case 0x01: 6888 tcg_gen_xor_i32(tmp, tmp, tmp2); 6889 if (logic_cc) { 6890 gen_logic_CC(tmp); 6891 } 6892 store_reg_bx(env, s, rd, tmp); 6893 break; 6894 case 0x02: 6895 if (set_cc && rd == 15) { 6896 /* SUBS r15, ... is used for exception return. */ 6897 if (IS_USER(s)) { 6898 goto illegal_op; 6899 } 6900 gen_helper_sub_cc(tmp, tmp, tmp2); 6901 gen_exception_return(s, tmp); 6902 } else { 6903 if (set_cc) { 6904 gen_helper_sub_cc(tmp, tmp, tmp2); 6905 } else { 6906 tcg_gen_sub_i32(tmp, tmp, tmp2); 6907 } 6908 store_reg_bx(env, s, rd, tmp); 6909 } 6910 break; 6911 case 0x03: 6912 if (set_cc) { 6913 gen_helper_sub_cc(tmp, tmp2, tmp); 6914 } else { 6915 tcg_gen_sub_i32(tmp, tmp2, tmp); 6916 } 6917 store_reg_bx(env, s, rd, tmp); 6918 break; 6919 case 0x04: 6920 if (set_cc) { 6921 gen_helper_add_cc(tmp, tmp, tmp2); 6922 } else { 6923 tcg_gen_add_i32(tmp, tmp, tmp2); 6924 } 6925 store_reg_bx(env, s, rd, tmp); 6926 break; 6927 case 0x05: 6928 if (set_cc) { 6929 gen_helper_adc_cc(tmp, tmp, tmp2); 6930 } else { 6931 gen_add_carry(tmp, tmp, tmp2); 6932 } 6933 store_reg_bx(env, s, rd, tmp); 6934 break; 6935 case 0x06: 6936 if (set_cc) { 6937 gen_helper_sbc_cc(tmp, tmp, tmp2); 6938 } else { 6939 gen_sub_carry(tmp, tmp, tmp2); 6940 } 6941 store_reg_bx(env, s, rd, tmp); 6942 break; 6943 case 0x07: 6944 if (set_cc) { 6945 gen_helper_sbc_cc(tmp, tmp2, tmp); 6946 } else { 6947 gen_sub_carry(tmp, tmp2, tmp); 6948 } 6949 store_reg_bx(env, s, rd, tmp); 6950 break; 6951 case 0x08: 6952 if (set_cc) { 6953 tcg_gen_and_i32(tmp, tmp, tmp2); 6954 gen_logic_CC(tmp); 6955 } 6956 tcg_temp_free_i32(tmp); 6957 break; 6958 case 0x09: 6959 if (set_cc) { 6960 tcg_gen_xor_i32(tmp, tmp, tmp2); 6961 gen_logic_CC(tmp); 6962 } 6963 tcg_temp_free_i32(tmp); 6964 break; 6965 case 0x0a: 6966 if (set_cc) { 6967 gen_helper_sub_cc(tmp, tmp, tmp2); 6968 } 6969 tcg_temp_free_i32(tmp); 6970 break; 6971 case 0x0b: 6972 if (set_cc) { 6973 gen_helper_add_cc(tmp, tmp, tmp2); 6974 } 6975 tcg_temp_free_i32(tmp); 6976 break; 6977 case 0x0c: 6978 tcg_gen_or_i32(tmp, tmp, tmp2); 6979 if (logic_cc) { 6980 gen_logic_CC(tmp); 6981 } 6982 store_reg_bx(env, s, rd, tmp); 6983 break; 6984 case 0x0d: 6985 if (logic_cc && rd == 15) { 6986 /* MOVS r15, ... is used for exception return. */ 6987 if (IS_USER(s)) { 6988 goto illegal_op; 6989 } 6990 gen_exception_return(s, tmp2); 6991 } else { 6992 if (logic_cc) { 6993 gen_logic_CC(tmp2); 6994 } 6995 store_reg_bx(env, s, rd, tmp2); 6996 } 6997 break; 6998 case 0x0e: 6999 tcg_gen_andc_i32(tmp, tmp, tmp2); 7000 if (logic_cc) { 7001 gen_logic_CC(tmp); 7002 } 7003 store_reg_bx(env, s, rd, tmp); 7004 break; 7005 default: 7006 case 0x0f: 7007 tcg_gen_not_i32(tmp2, tmp2); 7008 if (logic_cc) { 7009 gen_logic_CC(tmp2); 7010 } 7011 store_reg_bx(env, s, rd, tmp2); 7012 break; 7013 } 7014 if (op1 != 0x0f && op1 != 0x0d) { 7015 tcg_temp_free_i32(tmp2); 7016 } 7017 } else { 7018 /* other instructions */ 7019 op1 = (insn >> 24) & 0xf; 7020 switch(op1) { 7021 case 0x0: 7022 case 0x1: 7023 /* multiplies, extra load/stores */ 7024 sh = (insn >> 5) & 3; 7025 if (sh == 0) { 7026 if (op1 == 0x0) { 7027 rd = (insn >> 16) & 0xf; 7028 rn = (insn >> 12) & 0xf; 7029 rs = (insn >> 8) & 0xf; 7030 rm = (insn) & 0xf; 7031 op1 = (insn >> 20) & 0xf; 7032 switch (op1) { 7033 case 0: case 1: case 2: case 3: case 6: 7034 /* 32 bit mul */ 7035 tmp = load_reg(s, rs); 7036 tmp2 = load_reg(s, rm); 7037 tcg_gen_mul_i32(tmp, tmp, tmp2); 7038 tcg_temp_free_i32(tmp2); 7039 if (insn & (1 << 22)) { 7040 /* Subtract (mls) */ 7041 ARCH(6T2); 7042 tmp2 = load_reg(s, rn); 7043 tcg_gen_sub_i32(tmp, tmp2, tmp); 7044 tcg_temp_free_i32(tmp2); 7045 } else if (insn & (1 << 21)) { 7046 /* Add */ 7047 tmp2 = load_reg(s, rn); 7048 tcg_gen_add_i32(tmp, tmp, tmp2); 7049 tcg_temp_free_i32(tmp2); 7050 } 7051 if (insn & (1 << 20)) 7052 gen_logic_CC(tmp); 7053 store_reg(s, rd, tmp); 7054 break; 7055 case 4: 7056 /* 64 bit mul double accumulate (UMAAL) */ 7057 ARCH(6); 7058 tmp = load_reg(s, rs); 7059 tmp2 = load_reg(s, rm); 7060 tmp64 = gen_mulu_i64_i32(tmp, tmp2); 7061 gen_addq_lo(s, tmp64, rn); 7062 gen_addq_lo(s, tmp64, rd); 7063 gen_storeq_reg(s, rn, rd, tmp64); 7064 tcg_temp_free_i64(tmp64); 7065 break; 7066 case 8: case 9: case 10: case 11: 7067 case 12: case 13: case 14: case 15: 7068 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */ 7069 tmp = load_reg(s, rs); 7070 tmp2 = load_reg(s, rm); 7071 if (insn & (1 << 22)) { 7072 tmp64 = gen_muls_i64_i32(tmp, tmp2); 7073 } else { 7074 tmp64 = gen_mulu_i64_i32(tmp, tmp2); 7075 } 7076 if (insn & (1 << 21)) { /* mult accumulate */ 7077 gen_addq(s, tmp64, rn, rd); 7078 } 7079 if (insn & (1 << 20)) { 7080 gen_logicq_cc(tmp64); 7081 } 7082 gen_storeq_reg(s, rn, rd, tmp64); 7083 tcg_temp_free_i64(tmp64); 7084 break; 7085 default: 7086 goto illegal_op; 7087 } 7088 } else { 7089 rn = (insn >> 16) & 0xf; 7090 rd = (insn >> 12) & 0xf; 7091 if (insn & (1 << 23)) { 7092 /* load/store exclusive */ 7093 op1 = (insn >> 21) & 0x3; 7094 if (op1) 7095 ARCH(6K); 7096 else 7097 ARCH(6); 7098 addr = tcg_temp_local_new_i32(); 7099 load_reg_var(s, addr, rn); 7100 if (insn & (1 << 20)) { 7101 switch (op1) { 7102 case 0: /* ldrex */ 7103 gen_load_exclusive(s, rd, 15, addr, 2); 7104 break; 7105 case 1: /* ldrexd */ 7106 gen_load_exclusive(s, rd, rd + 1, addr, 3); 7107 break; 7108 case 2: /* ldrexb */ 7109 gen_load_exclusive(s, rd, 15, addr, 0); 7110 break; 7111 case 3: /* ldrexh */ 7112 gen_load_exclusive(s, rd, 15, addr, 1); 7113 break; 7114 default: 7115 abort(); 7116 } 7117 } else { 7118 rm = insn & 0xf; 7119 switch (op1) { 7120 case 0: /* strex */ 7121 gen_store_exclusive(s, rd, rm, 15, addr, 2); 7122 break; 7123 case 1: /* strexd */ 7124 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3); 7125 break; 7126 case 2: /* strexb */ 7127 gen_store_exclusive(s, rd, rm, 15, addr, 0); 7128 break; 7129 case 3: /* strexh */ 7130 gen_store_exclusive(s, rd, rm, 15, addr, 1); 7131 break; 7132 default: 7133 abort(); 7134 } 7135 } 7136 tcg_temp_free(addr); 7137 } else { 7138 /* SWP instruction */ 7139 rm = (insn) & 0xf; 7140 7141 /* ??? This is not really atomic. However we know 7142 we never have multiple CPUs running in parallel, 7143 so it is good enough. */ 7144 addr = load_reg(s, rn); 7145 tmp = load_reg(s, rm); 7146 if (insn & (1 << 22)) { 7147 tmp2 = gen_ld8u(addr, IS_USER(s)); 7148 gen_st8(tmp, addr, IS_USER(s)); 7149 } else { 7150 tmp2 = gen_ld32(addr, IS_USER(s)); 7151 gen_st32(tmp, addr, IS_USER(s)); 7152 } 7153 tcg_temp_free_i32(addr); 7154 store_reg(s, rd, tmp2); 7155 } 7156 } 7157 } else { 7158 int address_offset; 7159 int load; 7160 /* Misc load/store */ 7161 rn = (insn >> 16) & 0xf; 7162 rd = (insn >> 12) & 0xf; 7163 addr = load_reg(s, rn); 7164 if (insn & (1 << 24)) 7165 gen_add_datah_offset(s, insn, 0, addr); 7166 address_offset = 0; 7167 if (insn & (1 << 20)) { 7168 /* load */ 7169 switch(sh) { 7170 case 1: 7171 tmp = gen_ld16u(addr, IS_USER(s)); 7172 break; 7173 case 2: 7174 tmp = gen_ld8s(addr, IS_USER(s)); 7175 break; 7176 default: 7177 case 3: 7178 tmp = gen_ld16s(addr, IS_USER(s)); 7179 break; 7180 } 7181 load = 1; 7182 } else if (sh & 2) { 7183 ARCH(5TE); 7184 /* doubleword */ 7185 if (sh & 1) { 7186 /* store */ 7187 tmp = load_reg(s, rd); 7188 gen_st32(tmp, addr, IS_USER(s)); 7189 tcg_gen_addi_i32(addr, addr, 4); 7190 tmp = load_reg(s, rd + 1); 7191 gen_st32(tmp, addr, IS_USER(s)); 7192 load = 0; 7193 } else { 7194 /* load */ 7195 tmp = gen_ld32(addr, IS_USER(s)); 7196 store_reg(s, rd, tmp); 7197 tcg_gen_addi_i32(addr, addr, 4); 7198 tmp = gen_ld32(addr, IS_USER(s)); 7199 rd++; 7200 load = 1; 7201 } 7202 address_offset = -4; 7203 } else { 7204 /* store */ 7205 tmp = load_reg(s, rd); 7206 gen_st16(tmp, addr, IS_USER(s)); 7207 load = 0; 7208 } 7209 /* Perform base writeback before the loaded value to 7210 ensure correct behavior with overlapping index registers. 7211 ldrd with base writeback is is undefined if the 7212 destination and index registers overlap. */ 7213 if (!(insn & (1 << 24))) { 7214 gen_add_datah_offset(s, insn, address_offset, addr); 7215 store_reg(s, rn, addr); 7216 } else if (insn & (1 << 21)) { 7217 if (address_offset) 7218 tcg_gen_addi_i32(addr, addr, address_offset); 7219 store_reg(s, rn, addr); 7220 } else { 7221 tcg_temp_free_i32(addr); 7222 } 7223 if (load) { 7224 /* Complete the load. */ 7225 store_reg(s, rd, tmp); 7226 } 7227 } 7228 break; 7229 case 0x4: 7230 case 0x5: 7231 goto do_ldst; 7232 case 0x6: 7233 case 0x7: 7234 if (insn & (1 << 4)) { 7235 ARCH(6); 7236 /* Armv6 Media instructions. */ 7237 rm = insn & 0xf; 7238 rn = (insn >> 16) & 0xf; 7239 rd = (insn >> 12) & 0xf; 7240 rs = (insn >> 8) & 0xf; 7241 switch ((insn >> 23) & 3) { 7242 case 0: /* Parallel add/subtract. */ 7243 op1 = (insn >> 20) & 7; 7244 tmp = load_reg(s, rn); 7245 tmp2 = load_reg(s, rm); 7246 sh = (insn >> 5) & 7; 7247 if ((op1 & 3) == 0 || sh == 5 || sh == 6) 7248 goto illegal_op; 7249 gen_arm_parallel_addsub(op1, sh, tmp, tmp2); 7250 tcg_temp_free_i32(tmp2); 7251 store_reg(s, rd, tmp); 7252 break; 7253 case 1: 7254 if ((insn & 0x00700020) == 0) { 7255 /* Halfword pack. */ 7256 tmp = load_reg(s, rn); 7257 tmp2 = load_reg(s, rm); 7258 shift = (insn >> 7) & 0x1f; 7259 if (insn & (1 << 6)) { 7260 /* pkhtb */ 7261 if (shift == 0) 7262 shift = 31; 7263 tcg_gen_sari_i32(tmp2, tmp2, shift); 7264 tcg_gen_andi_i32(tmp, tmp, 0xffff0000); 7265 tcg_gen_ext16u_i32(tmp2, tmp2); 7266 } else { 7267 /* pkhbt */ 7268 if (shift) 7269 tcg_gen_shli_i32(tmp2, tmp2, shift); 7270 tcg_gen_ext16u_i32(tmp, tmp); 7271 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); 7272 } 7273 tcg_gen_or_i32(tmp, tmp, tmp2); 7274 tcg_temp_free_i32(tmp2); 7275 store_reg(s, rd, tmp); 7276 } else if ((insn & 0x00200020) == 0x00200000) { 7277 /* [us]sat */ 7278 tmp = load_reg(s, rm); 7279 shift = (insn >> 7) & 0x1f; 7280 if (insn & (1 << 6)) { 7281 if (shift == 0) 7282 shift = 31; 7283 tcg_gen_sari_i32(tmp, tmp, shift); 7284 } else { 7285 tcg_gen_shli_i32(tmp, tmp, shift); 7286 } 7287 sh = (insn >> 16) & 0x1f; 7288 tmp2 = tcg_const_i32(sh); 7289 if (insn & (1 << 22)) 7290 gen_helper_usat(tmp, tmp, tmp2); 7291 else 7292 gen_helper_ssat(tmp, tmp, tmp2); 7293 tcg_temp_free_i32(tmp2); 7294 store_reg(s, rd, tmp); 7295 } else if ((insn & 0x00300fe0) == 0x00200f20) { 7296 /* [us]sat16 */ 7297 tmp = load_reg(s, rm); 7298 sh = (insn >> 16) & 0x1f; 7299 tmp2 = tcg_const_i32(sh); 7300 if (insn & (1 << 22)) 7301 gen_helper_usat16(tmp, tmp, tmp2); 7302 else 7303 gen_helper_ssat16(tmp, tmp, tmp2); 7304 tcg_temp_free_i32(tmp2); 7305 store_reg(s, rd, tmp); 7306 } else if ((insn & 0x00700fe0) == 0x00000fa0) { 7307 /* Select bytes. */ 7308 tmp = load_reg(s, rn); 7309 tmp2 = load_reg(s, rm); 7310 tmp3 = tcg_temp_new_i32(); 7311 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); 7312 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); 7313 tcg_temp_free_i32(tmp3); 7314 tcg_temp_free_i32(tmp2); 7315 store_reg(s, rd, tmp); 7316 } else if ((insn & 0x000003e0) == 0x00000060) { 7317 tmp = load_reg(s, rm); 7318 shift = (insn >> 10) & 3; 7319 /* ??? In many cases it's not necessary to do a 7320 rotate, a shift is sufficient. */ 7321 if (shift != 0) 7322 tcg_gen_rotri_i32(tmp, tmp, shift * 8); 7323 op1 = (insn >> 20) & 7; 7324 switch (op1) { 7325 case 0: gen_sxtb16(tmp); break; 7326 case 2: gen_sxtb(tmp); break; 7327 case 3: gen_sxth(tmp); break; 7328 case 4: gen_uxtb16(tmp); break; 7329 case 6: gen_uxtb(tmp); break; 7330 case 7: gen_uxth(tmp); break; 7331 default: tcg_temp_free_i32(tmp); goto illegal_op; 7332 } 7333 if (rn != 15) { 7334 tmp2 = load_reg(s, rn); 7335 if ((op1 & 3) == 0) { 7336 gen_add16(tmp, tmp2); 7337 } else { 7338 tcg_gen_add_i32(tmp, tmp, tmp2); 7339 tcg_temp_free_i32(tmp2); 7340 } 7341 } 7342 store_reg(s, rd, tmp); 7343 } else if ((insn & 0x003f0f60) == 0x003f0f20) { 7344 /* rev */ 7345 tmp = load_reg(s, rm); 7346 if (insn & (1 << 22)) { 7347 if (insn & (1 << 7)) { 7348 gen_revsh(tmp); 7349 } else { 7350 ARCH(6T2); 7351 gen_helper_rbit(tmp, tmp); 7352 } 7353 } else { 7354 if (insn & (1 << 7)) 7355 gen_rev16(tmp); 7356 else 7357 tcg_gen_bswap32_i32(tmp, tmp); 7358 } 7359 store_reg(s, rd, tmp); 7360 } else { 7361 goto illegal_op; 7362 } 7363 break; 7364 case 2: /* Multiplies (Type 3). */ 7365 tmp = load_reg(s, rm); 7366 tmp2 = load_reg(s, rs); 7367 if (insn & (1 << 20)) { 7368 /* Signed multiply most significant [accumulate]. 7369 (SMMUL, SMMLA, SMMLS) */ 7370 tmp64 = gen_muls_i64_i32(tmp, tmp2); 7371 7372 if (rd != 15) { 7373 tmp = load_reg(s, rd); 7374 if (insn & (1 << 6)) { 7375 tmp64 = gen_subq_msw(tmp64, tmp); 7376 } else { 7377 tmp64 = gen_addq_msw(tmp64, tmp); 7378 } 7379 } 7380 if (insn & (1 << 5)) { 7381 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); 7382 } 7383 tcg_gen_shri_i64(tmp64, tmp64, 32); 7384 tmp = tcg_temp_new_i32(); 7385 tcg_gen_trunc_i64_i32(tmp, tmp64); 7386 tcg_temp_free_i64(tmp64); 7387 store_reg(s, rn, tmp); 7388 } else { 7389 if (insn & (1 << 5)) 7390 gen_swap_half(tmp2); 7391 gen_smul_dual(tmp, tmp2); 7392 if (insn & (1 << 6)) { 7393 /* This subtraction cannot overflow. */ 7394 tcg_gen_sub_i32(tmp, tmp, tmp2); 7395 } else { 7396 /* This addition cannot overflow 32 bits; 7397 * however it may overflow considered as a signed 7398 * operation, in which case we must set the Q flag. 7399 */ 7400 gen_helper_add_setq(tmp, tmp, tmp2); 7401 } 7402 tcg_temp_free_i32(tmp2); 7403 if (insn & (1 << 22)) { 7404 /* smlald, smlsld */ 7405 tmp64 = tcg_temp_new_i64(); 7406 tcg_gen_ext_i32_i64(tmp64, tmp); 7407 tcg_temp_free_i32(tmp); 7408 gen_addq(s, tmp64, rd, rn); 7409 gen_storeq_reg(s, rd, rn, tmp64); 7410 tcg_temp_free_i64(tmp64); 7411 } else { 7412 /* smuad, smusd, smlad, smlsd */ 7413 if (rd != 15) 7414 { 7415 tmp2 = load_reg(s, rd); 7416 gen_helper_add_setq(tmp, tmp, tmp2); 7417 tcg_temp_free_i32(tmp2); 7418 } 7419 store_reg(s, rn, tmp); 7420 } 7421 } 7422 break; 7423 case 3: 7424 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7); 7425 switch (op1) { 7426 case 0: /* Unsigned sum of absolute differences. */ 7427 ARCH(6); 7428 tmp = load_reg(s, rm); 7429 tmp2 = load_reg(s, rs); 7430 gen_helper_usad8(tmp, tmp, tmp2); 7431 tcg_temp_free_i32(tmp2); 7432 if (rd != 15) { 7433 tmp2 = load_reg(s, rd); 7434 tcg_gen_add_i32(tmp, tmp, tmp2); 7435 tcg_temp_free_i32(tmp2); 7436 } 7437 store_reg(s, rn, tmp); 7438 break; 7439 case 0x20: case 0x24: case 0x28: case 0x2c: 7440 /* Bitfield insert/clear. */ 7441 ARCH(6T2); 7442 shift = (insn >> 7) & 0x1f; 7443 i = (insn >> 16) & 0x1f; 7444 i = i + 1 - shift; 7445 if (rm == 15) { 7446 tmp = tcg_temp_new_i32(); 7447 tcg_gen_movi_i32(tmp, 0); 7448 } else { 7449 tmp = load_reg(s, rm); 7450 } 7451 if (i != 32) { 7452 tmp2 = load_reg(s, rd); 7453 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1); 7454 tcg_temp_free_i32(tmp2); 7455 } 7456 store_reg(s, rd, tmp); 7457 break; 7458 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ 7459 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ 7460 ARCH(6T2); 7461 tmp = load_reg(s, rm); 7462 shift = (insn >> 7) & 0x1f; 7463 i = ((insn >> 16) & 0x1f) + 1; 7464 if (shift + i > 32) 7465 goto illegal_op; 7466 if (i < 32) { 7467 if (op1 & 0x20) { 7468 gen_ubfx(tmp, shift, (1u << i) - 1); 7469 } else { 7470 gen_sbfx(tmp, shift, i); 7471 } 7472 } 7473 store_reg(s, rd, tmp); 7474 break; 7475 default: 7476 goto illegal_op; 7477 } 7478 break; 7479 } 7480 break; 7481 } 7482 do_ldst: 7483 /* Check for undefined extension instructions 7484 * per the ARM Bible IE: 7485 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx 7486 */ 7487 sh = (0xf << 20) | (0xf << 4); 7488 if (op1 == 0x7 && ((insn & sh) == sh)) 7489 { 7490 goto illegal_op; 7491 } 7492 /* load/store byte/word */ 7493 rn = (insn >> 16) & 0xf; 7494 rd = (insn >> 12) & 0xf; 7495 tmp2 = load_reg(s, rn); 7496 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000); 7497 if (insn & (1 << 24)) 7498 gen_add_data_offset(s, insn, tmp2); 7499 if (insn & (1 << 20)) { 7500 /* load */ 7501 if (insn & (1 << 22)) { 7502 tmp = gen_ld8u(tmp2, i); 7503 } else { 7504 tmp = gen_ld32(tmp2, i); 7505 } 7506 } else { 7507 /* store */ 7508 tmp = load_reg(s, rd); 7509 if (insn & (1 << 22)) 7510 gen_st8(tmp, tmp2, i); 7511 else 7512 gen_st32(tmp, tmp2, i); 7513 } 7514 if (!(insn & (1 << 24))) { 7515 gen_add_data_offset(s, insn, tmp2); 7516 store_reg(s, rn, tmp2); 7517 } else if (insn & (1 << 21)) { 7518 store_reg(s, rn, tmp2); 7519 } else { 7520 tcg_temp_free_i32(tmp2); 7521 } 7522 if (insn & (1 << 20)) { 7523 /* Complete the load. */ 7524 store_reg_from_load(env, s, rd, tmp); 7525 } 7526 break; 7527 case 0x08: 7528 case 0x09: 7529 { 7530 int j, n, user, loaded_base; 7531 TCGv loaded_var; 7532 /* load/store multiple words */ 7533 /* XXX: store correct base if write back */ 7534 user = 0; 7535 if (insn & (1 << 22)) { 7536 if (IS_USER(s)) 7537 goto illegal_op; /* only usable in supervisor mode */ 7538 7539 if ((insn & (1 << 15)) == 0) 7540 user = 1; 7541 } 7542 rn = (insn >> 16) & 0xf; 7543 addr = load_reg(s, rn); 7544 tmp3 = tcg_const_i32(4); 7545 7546 /* compute total size */ 7547 loaded_base = 0; 7548 TCGV_UNUSED(loaded_var); 7549 n = 0; 7550 for(i=0;i<16;i++) { 7551 if (insn & (1 << i)) 7552 n++; 7553 } 7554 /* XXX: test invalid n == 0 case ? */ 7555 if (insn & (1 << 23)) { 7556 if (insn & (1 << 24)) { 7557 /* pre increment */ 7558 tcg_gen_add_i32(addr, addr, tmp3); 7559 } else { 7560 /* post increment */ 7561 } 7562 } else { 7563 if (insn & (1 << 24)) { 7564 /* pre decrement */ 7565 tcg_gen_addi_i32(addr, addr, -(n * 4)); 7566 } else { 7567 /* post decrement */ 7568 if (n != 1) 7569 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); 7570 } 7571 } 7572 j = 0; 7573 for(i=0;i<16;i++) { 7574 if (insn & (1 << i)) { 7575 if (insn & (1 << 20)) { 7576 /* load */ 7577 tmp = gen_ld32(addr, IS_USER(s)); 7578 if (user) { 7579 tmp2 = tcg_const_i32(i); 7580 gen_helper_set_user_reg(tmp2, tmp); 7581 tcg_temp_free_i32(tmp2); 7582 tcg_temp_free_i32(tmp); 7583 } else if (i == rn) { 7584 loaded_var = tmp; 7585 loaded_base = 1; 7586 } else { 7587 store_reg_from_load(env, s, i, tmp); 7588 } 7589 } else { 7590 /* store */ 7591 if (i == 15) { 7592 /* special case: r15 = PC + 8 */ 7593 val = (long)s->pc + 4; 7594 tmp = tcg_temp_new_i32(); 7595 tcg_gen_movi_i32(tmp, val); 7596 } else if (user) { 7597 tmp = tcg_temp_new_i32(); 7598 tmp2 = tcg_const_i32(i); 7599 gen_helper_get_user_reg(tmp, tmp2); 7600 tcg_temp_free_i32(tmp2); 7601 } else { 7602 tmp = load_reg(s, i); 7603 } 7604 gen_st32(tmp, addr, IS_USER(s)); 7605 } 7606 j++; 7607 /* no need to add after the last transfer */ 7608 if (j != n) 7609 tcg_gen_add_i32(addr, addr, tmp3); 7610 } 7611 } 7612 if (insn & (1 << 21)) { 7613 /* write back */ 7614 if (insn & (1 << 23)) { 7615 if (insn & (1 << 24)) { 7616 /* pre increment */ 7617 } else { 7618 /* post increment */ 7619 tcg_gen_add_i32(addr, addr, tmp3); 7620 } 7621 } else { 7622 if (insn & (1 << 24)) { 7623 /* pre decrement */ 7624 if (n != 1) 7625 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); 7626 } else { 7627 /* post decrement */ 7628 tcg_gen_addi_i32(addr, addr, -(n * 4)); 7629 } 7630 } 7631 store_reg(s, rn, addr); 7632 } else { 7633 tcg_temp_free_i32(addr); 7634 } 7635 tcg_temp_free_i32(tmp3); 7636 if (loaded_base) { 7637 store_reg(s, rn, loaded_var); 7638 } 7639 if ((insn & (1 << 22)) && !user) { 7640 /* Restore CPSR from SPSR. */ 7641 tmp = load_cpu_field(spsr); 7642 gen_set_cpsr(tmp, 0xffffffff); 7643 tcg_temp_free_i32(tmp); 7644 s->is_jmp = DISAS_UPDATE; 7645 } 7646 } 7647 break; 7648 case 0xa: 7649 case 0xb: 7650 { 7651 int32_t offset; 7652 7653 /* branch (and link) */ 7654 val = (int32_t)s->pc; 7655 if (insn & (1 << 24)) { 7656 tmp = tcg_temp_new_i32(); 7657 tcg_gen_movi_i32(tmp, val); 7658 store_reg(s, 14, tmp); 7659 } 7660 offset = (((int32_t)insn << 8) >> 8); 7661 val += (offset << 2) + 4; 7662 gen_jmp(s, val); 7663 } 7664 break; 7665 case 0xc: 7666 case 0xd: 7667 case 0xe: 7668 /* Coprocessor. */ 7669 if (disas_coproc_insn(env, s, insn)) 7670 goto illegal_op; 7671 break; 7672 case 0xf: 7673 /* swi */ 7674 gen_set_pc_im(s->pc); 7675 s->is_jmp = DISAS_SWI; 7676 break; 7677 default: 7678 illegal_op: 7679 gen_exception_insn(s, 4, EXCP_UDEF); 7680 break; 7681 } 7682 } 7683} 7684 7685/* Return true if this is a Thumb-2 logical op. */ 7686static int 7687thumb2_logic_op(int op) 7688{ 7689 return (op < 8); 7690} 7691 7692/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero 7693 then set condition code flags based on the result of the operation. 7694 If SHIFTER_OUT is nonzero then set the carry flag for logical operations 7695 to the high bit of T1. 7696 Returns zero if the opcode is valid. */ 7697 7698static int 7699gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1) 7700{ 7701 int logic_cc; 7702 7703 logic_cc = 0; 7704 switch (op) { 7705 case 0: /* and */ 7706 tcg_gen_and_i32(t0, t0, t1); 7707 logic_cc = conds; 7708 break; 7709 case 1: /* bic */ 7710 tcg_gen_andc_i32(t0, t0, t1); 7711 logic_cc = conds; 7712 break; 7713 case 2: /* orr */ 7714 tcg_gen_or_i32(t0, t0, t1); 7715 logic_cc = conds; 7716 break; 7717 case 3: /* orn */ 7718 tcg_gen_orc_i32(t0, t0, t1); 7719 logic_cc = conds; 7720 break; 7721 case 4: /* eor */ 7722 tcg_gen_xor_i32(t0, t0, t1); 7723 logic_cc = conds; 7724 break; 7725 case 8: /* add */ 7726 if (conds) 7727 gen_helper_add_cc(t0, t0, t1); 7728 else 7729 tcg_gen_add_i32(t0, t0, t1); 7730 break; 7731 case 10: /* adc */ 7732 if (conds) 7733 gen_helper_adc_cc(t0, t0, t1); 7734 else 7735 gen_adc(t0, t1); 7736 break; 7737 case 11: /* sbc */ 7738 if (conds) 7739 gen_helper_sbc_cc(t0, t0, t1); 7740 else 7741 gen_sub_carry(t0, t0, t1); 7742 break; 7743 case 13: /* sub */ 7744 if (conds) 7745 gen_helper_sub_cc(t0, t0, t1); 7746 else 7747 tcg_gen_sub_i32(t0, t0, t1); 7748 break; 7749 case 14: /* rsb */ 7750 if (conds) 7751 gen_helper_sub_cc(t0, t1, t0); 7752 else 7753 tcg_gen_sub_i32(t0, t1, t0); 7754 break; 7755 default: /* 5, 6, 7, 9, 12, 15. */ 7756 return 1; 7757 } 7758 if (logic_cc) { 7759 gen_logic_CC(t0); 7760 if (shifter_out) 7761 gen_set_CF_bit31(t1); 7762 } 7763 return 0; 7764} 7765 7766/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction 7767 is not legal. */ 7768static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1) 7769{ 7770 uint32_t insn, imm, shift, offset; 7771 uint32_t rd, rn, rm, rs; 7772 TCGv tmp; 7773 TCGv tmp2; 7774 TCGv tmp3; 7775 TCGv addr; 7776 TCGv_i64 tmp64; 7777 int op; 7778 int shiftop; 7779 int conds; 7780 int logic_cc; 7781 7782 if (!(arm_feature(env, ARM_FEATURE_THUMB2) 7783 || arm_feature (env, ARM_FEATURE_M))) { 7784 /* Thumb-1 cores may need to treat bl and blx as a pair of 7785 16-bit instructions to get correct prefetch abort behavior. */ 7786 insn = insn_hw1; 7787 if ((insn & (1 << 12)) == 0) { 7788 ARCH(5); 7789 /* Second half of blx. */ 7790 offset = ((insn & 0x7ff) << 1); 7791 tmp = load_reg(s, 14); 7792 tcg_gen_addi_i32(tmp, tmp, offset); 7793 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); 7794 7795 tmp2 = tcg_temp_new_i32(); 7796 tcg_gen_movi_i32(tmp2, s->pc | 1); 7797 store_reg(s, 14, tmp2); 7798 gen_bx(s, tmp); 7799 return 0; 7800 } 7801 if (insn & (1 << 11)) { 7802 /* Second half of bl. */ 7803 offset = ((insn & 0x7ff) << 1) | 1; 7804 tmp = load_reg(s, 14); 7805 tcg_gen_addi_i32(tmp, tmp, offset); 7806 7807 tmp2 = tcg_temp_new_i32(); 7808 tcg_gen_movi_i32(tmp2, s->pc | 1); 7809 store_reg(s, 14, tmp2); 7810 gen_bx(s, tmp); 7811 return 0; 7812 } 7813 if ((s->pc & ~TARGET_PAGE_MASK) == 0) { 7814 /* Instruction spans a page boundary. Implement it as two 7815 16-bit instructions in case the second half causes an 7816 prefetch abort. */ 7817 offset = ((int32_t)insn << 21) >> 9; 7818 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset); 7819 return 0; 7820 } 7821 /* Fall through to 32-bit decode. */ 7822 } 7823 7824 insn = cpu_lduw_code(env, s->pc); 7825 s->pc += 2; 7826 insn |= (uint32_t)insn_hw1 << 16; 7827 7828 if ((insn & 0xf800e800) != 0xf000e800) { 7829 ARCH(6T2); 7830 } 7831 7832 rn = (insn >> 16) & 0xf; 7833 rs = (insn >> 12) & 0xf; 7834 rd = (insn >> 8) & 0xf; 7835 rm = insn & 0xf; 7836 switch ((insn >> 25) & 0xf) { 7837 case 0: case 1: case 2: case 3: 7838 /* 16-bit instructions. Should never happen. */ 7839 abort(); 7840 case 4: 7841 if (insn & (1 << 22)) { 7842 /* Other load/store, table branch. */ 7843 if (insn & 0x01200000) { 7844 /* Load/store doubleword. */ 7845 if (rn == 15) { 7846 addr = tcg_temp_new_i32(); 7847 tcg_gen_movi_i32(addr, s->pc & ~3); 7848 } else { 7849 addr = load_reg(s, rn); 7850 } 7851 offset = (insn & 0xff) * 4; 7852 if ((insn & (1 << 23)) == 0) 7853 offset = -offset; 7854 if (insn & (1 << 24)) { 7855 tcg_gen_addi_i32(addr, addr, offset); 7856 offset = 0; 7857 } 7858 if (insn & (1 << 20)) { 7859 /* ldrd */ 7860 tmp = gen_ld32(addr, IS_USER(s)); 7861 store_reg(s, rs, tmp); 7862 tcg_gen_addi_i32(addr, addr, 4); 7863 tmp = gen_ld32(addr, IS_USER(s)); 7864 store_reg(s, rd, tmp); 7865 } else { 7866 /* strd */ 7867 tmp = load_reg(s, rs); 7868 gen_st32(tmp, addr, IS_USER(s)); 7869 tcg_gen_addi_i32(addr, addr, 4); 7870 tmp = load_reg(s, rd); 7871 gen_st32(tmp, addr, IS_USER(s)); 7872 } 7873 if (insn & (1 << 21)) { 7874 /* Base writeback. */ 7875 if (rn == 15) 7876 goto illegal_op; 7877 tcg_gen_addi_i32(addr, addr, offset - 4); 7878 store_reg(s, rn, addr); 7879 } else { 7880 tcg_temp_free_i32(addr); 7881 } 7882 } else if ((insn & (1 << 23)) == 0) { 7883 /* Load/store exclusive word. */ 7884 addr = tcg_temp_local_new(); 7885 load_reg_var(s, addr, rn); 7886 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); 7887 if (insn & (1 << 20)) { 7888 gen_load_exclusive(s, rs, 15, addr, 2); 7889 } else { 7890 gen_store_exclusive(s, rd, rs, 15, addr, 2); 7891 } 7892 tcg_temp_free(addr); 7893 } else if ((insn & (1 << 6)) == 0) { 7894 /* Table Branch. */ 7895 if (rn == 15) { 7896 addr = tcg_temp_new_i32(); 7897 tcg_gen_movi_i32(addr, s->pc); 7898 } else { 7899 addr = load_reg(s, rn); 7900 } 7901 tmp = load_reg(s, rm); 7902 tcg_gen_add_i32(addr, addr, tmp); 7903 if (insn & (1 << 4)) { 7904 /* tbh */ 7905 tcg_gen_add_i32(addr, addr, tmp); 7906 tcg_temp_free_i32(tmp); 7907 tmp = gen_ld16u(addr, IS_USER(s)); 7908 } else { /* tbb */ 7909 tcg_temp_free_i32(tmp); 7910 tmp = gen_ld8u(addr, IS_USER(s)); 7911 } 7912 tcg_temp_free_i32(addr); 7913 tcg_gen_shli_i32(tmp, tmp, 1); 7914 tcg_gen_addi_i32(tmp, tmp, s->pc); 7915 store_reg(s, 15, tmp); 7916 } else { 7917 /* Load/store exclusive byte/halfword/doubleword. */ 7918 ARCH(7); 7919 op = (insn >> 4) & 0x3; 7920 if (op == 2) { 7921 goto illegal_op; 7922 } 7923 addr = tcg_temp_local_new(); 7924 load_reg_var(s, addr, rn); 7925 if (insn & (1 << 20)) { 7926 gen_load_exclusive(s, rs, rd, addr, op); 7927 } else { 7928 gen_store_exclusive(s, rm, rs, rd, addr, op); 7929 } 7930 tcg_temp_free(addr); 7931 } 7932 } else { 7933 /* Load/store multiple, RFE, SRS. */ 7934 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { 7935 /* Not available in user mode. */ 7936 if (IS_USER(s)) 7937 goto illegal_op; 7938 if (insn & (1 << 20)) { 7939 /* rfe */ 7940 addr = load_reg(s, rn); 7941 if ((insn & (1 << 24)) == 0) 7942 tcg_gen_addi_i32(addr, addr, -8); 7943 /* Load PC into tmp and CPSR into tmp2. */ 7944 tmp = gen_ld32(addr, 0); 7945 tcg_gen_addi_i32(addr, addr, 4); 7946 tmp2 = gen_ld32(addr, 0); 7947 if (insn & (1 << 21)) { 7948 /* Base writeback. */ 7949 if (insn & (1 << 24)) { 7950 tcg_gen_addi_i32(addr, addr, 4); 7951 } else { 7952 tcg_gen_addi_i32(addr, addr, -4); 7953 } 7954 store_reg(s, rn, addr); 7955 } else { 7956 tcg_temp_free_i32(addr); 7957 } 7958 gen_rfe(s, tmp, tmp2); 7959 } else { 7960 /* srs */ 7961 op = (insn & 0x1f); 7962 addr = tcg_temp_new_i32(); 7963 tmp = tcg_const_i32(op); 7964 gen_helper_get_r13_banked(addr, cpu_env, tmp); 7965 tcg_temp_free_i32(tmp); 7966 if ((insn & (1 << 24)) == 0) { 7967 tcg_gen_addi_i32(addr, addr, -8); 7968 } 7969 tmp = load_reg(s, 14); 7970 gen_st32(tmp, addr, 0); 7971 tcg_gen_addi_i32(addr, addr, 4); 7972 tmp = tcg_temp_new_i32(); 7973 gen_helper_cpsr_read(tmp); 7974 gen_st32(tmp, addr, 0); 7975 if (insn & (1 << 21)) { 7976 if ((insn & (1 << 24)) == 0) { 7977 tcg_gen_addi_i32(addr, addr, -4); 7978 } else { 7979 tcg_gen_addi_i32(addr, addr, 4); 7980 } 7981 tmp = tcg_const_i32(op); 7982 gen_helper_set_r13_banked(cpu_env, tmp, addr); 7983 tcg_temp_free_i32(tmp); 7984 } else { 7985 tcg_temp_free_i32(addr); 7986 } 7987 } 7988 } else { 7989 int i, loaded_base = 0; 7990 TCGv loaded_var; 7991 /* Load/store multiple. */ 7992 addr = load_reg(s, rn); 7993 offset = 0; 7994 for (i = 0; i < 16; i++) { 7995 if (insn & (1 << i)) 7996 offset += 4; 7997 } 7998 if (insn & (1 << 24)) { 7999 tcg_gen_addi_i32(addr, addr, -offset); 8000 } 8001 8002 TCGV_UNUSED(loaded_var); 8003 tmp2 = tcg_const_i32(4); 8004 for (i = 0; i < 16; i++) { 8005 if ((insn & (1 << i)) == 0) 8006 continue; 8007 if (insn & (1 << 20)) { 8008 /* Load. */ 8009 tmp = gen_ld32(addr, IS_USER(s)); 8010 if (i == 15) { 8011 gen_bx(s, tmp); 8012 } else if (i == rn) { 8013 loaded_var = tmp; 8014 loaded_base = 1; 8015 } else { 8016 store_reg(s, i, tmp); 8017 } 8018 } else { 8019 /* Store. */ 8020 tmp = load_reg(s, i); 8021 gen_st32(tmp, addr, IS_USER(s)); 8022 } 8023 tcg_gen_add_i32(addr, addr, tmp2); 8024 } 8025 if (loaded_base) { 8026 store_reg(s, rn, loaded_var); 8027 } 8028 tcg_temp_free_i32(tmp2); 8029 if (insn & (1 << 21)) { 8030 /* Base register writeback. */ 8031 if (insn & (1 << 24)) { 8032 tcg_gen_addi_i32(addr, addr, -offset); 8033 } 8034 /* Fault if writeback register is in register list. */ 8035 if (insn & (1 << rn)) 8036 goto illegal_op; 8037 store_reg(s, rn, addr); 8038 } else { 8039 tcg_temp_free_i32(addr); 8040 } 8041 } 8042 } 8043 break; 8044 case 5: 8045 8046 op = (insn >> 21) & 0xf; 8047 if (op == 6) { 8048 /* Halfword pack. */ 8049 tmp = load_reg(s, rn); 8050 tmp2 = load_reg(s, rm); 8051 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3); 8052 if (insn & (1 << 5)) { 8053 /* pkhtb */ 8054 if (shift == 0) 8055 shift = 31; 8056 tcg_gen_sari_i32(tmp2, tmp2, shift); 8057 tcg_gen_andi_i32(tmp, tmp, 0xffff0000); 8058 tcg_gen_ext16u_i32(tmp2, tmp2); 8059 } else { 8060 /* pkhbt */ 8061 if (shift) 8062 tcg_gen_shli_i32(tmp2, tmp2, shift); 8063 tcg_gen_ext16u_i32(tmp, tmp); 8064 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); 8065 } 8066 tcg_gen_or_i32(tmp, tmp, tmp2); 8067 tcg_temp_free_i32(tmp2); 8068 store_reg(s, rd, tmp); 8069 } else { 8070 /* Data processing register constant shift. */ 8071 if (rn == 15) { 8072 tmp = tcg_temp_new_i32(); 8073 tcg_gen_movi_i32(tmp, 0); 8074 } else { 8075 tmp = load_reg(s, rn); 8076 } 8077 tmp2 = load_reg(s, rm); 8078 8079 shiftop = (insn >> 4) & 3; 8080 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); 8081 conds = (insn & (1 << 20)) != 0; 8082 logic_cc = (conds && thumb2_logic_op(op)); 8083 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); 8084 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) 8085 goto illegal_op; 8086 tcg_temp_free_i32(tmp2); 8087 if (rd != 15) { 8088 store_reg(s, rd, tmp); 8089 } else { 8090 tcg_temp_free_i32(tmp); 8091 } 8092 } 8093 break; 8094 case 13: /* Misc data processing. */ 8095 op = ((insn >> 22) & 6) | ((insn >> 7) & 1); 8096 if (op < 4 && (insn & 0xf000) != 0xf000) 8097 goto illegal_op; 8098 switch (op) { 8099 case 0: /* Register controlled shift. */ 8100 tmp = load_reg(s, rn); 8101 tmp2 = load_reg(s, rm); 8102 if ((insn & 0x70) != 0) 8103 goto illegal_op; 8104 op = (insn >> 21) & 3; 8105 logic_cc = (insn & (1 << 20)) != 0; 8106 gen_arm_shift_reg(tmp, op, tmp2, logic_cc); 8107 if (logic_cc) 8108 gen_logic_CC(tmp); 8109 store_reg_bx(env, s, rd, tmp); 8110 break; 8111 case 1: /* Sign/zero extend. */ 8112 tmp = load_reg(s, rm); 8113 shift = (insn >> 4) & 3; 8114 /* ??? In many cases it's not necessary to do a 8115 rotate, a shift is sufficient. */ 8116 if (shift != 0) 8117 tcg_gen_rotri_i32(tmp, tmp, shift * 8); 8118 op = (insn >> 20) & 7; 8119 switch (op) { 8120 case 0: gen_sxth(tmp); break; 8121 case 1: gen_uxth(tmp); break; 8122 case 2: gen_sxtb16(tmp); break; 8123 case 3: gen_uxtb16(tmp); break; 8124 case 4: gen_sxtb(tmp); break; 8125 case 5: gen_uxtb(tmp); break; 8126 default: goto illegal_op; 8127 } 8128 if (rn != 15) { 8129 tmp2 = load_reg(s, rn); 8130 if ((op >> 1) == 1) { 8131 gen_add16(tmp, tmp2); 8132 } else { 8133 tcg_gen_add_i32(tmp, tmp, tmp2); 8134 tcg_temp_free_i32(tmp2); 8135 } 8136 } 8137 store_reg(s, rd, tmp); 8138 break; 8139 case 2: /* SIMD add/subtract. */ 8140 op = (insn >> 20) & 7; 8141 shift = (insn >> 4) & 7; 8142 if ((op & 3) == 3 || (shift & 3) == 3) 8143 goto illegal_op; 8144 tmp = load_reg(s, rn); 8145 tmp2 = load_reg(s, rm); 8146 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); 8147 tcg_temp_free_i32(tmp2); 8148 store_reg(s, rd, tmp); 8149 break; 8150 case 3: /* Other data processing. */ 8151 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); 8152 if (op < 4) { 8153 /* Saturating add/subtract. */ 8154 tmp = load_reg(s, rn); 8155 tmp2 = load_reg(s, rm); 8156 if (op & 1) 8157 gen_helper_double_saturate(tmp, tmp); 8158 if (op & 2) 8159 gen_helper_sub_saturate(tmp, tmp2, tmp); 8160 else 8161 gen_helper_add_saturate(tmp, tmp, tmp2); 8162 tcg_temp_free_i32(tmp2); 8163 } else { 8164 tmp = load_reg(s, rn); 8165 switch (op) { 8166 case 0x0a: /* rbit */ 8167 gen_helper_rbit(tmp, tmp); 8168 break; 8169 case 0x08: /* rev */ 8170 tcg_gen_bswap32_i32(tmp, tmp); 8171 break; 8172 case 0x09: /* rev16 */ 8173 gen_rev16(tmp); 8174 break; 8175 case 0x0b: /* revsh */ 8176 gen_revsh(tmp); 8177 break; 8178 case 0x10: /* sel */ 8179 tmp2 = load_reg(s, rm); 8180 tmp3 = tcg_temp_new_i32(); 8181 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); 8182 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); 8183 tcg_temp_free_i32(tmp3); 8184 tcg_temp_free_i32(tmp2); 8185 break; 8186 case 0x18: /* clz */ 8187 gen_helper_clz(tmp, tmp); 8188 break; 8189 default: 8190 goto illegal_op; 8191 } 8192 } 8193 store_reg(s, rd, tmp); 8194 break; 8195 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ 8196 op = (insn >> 4) & 0xf; 8197 tmp = load_reg(s, rn); 8198 tmp2 = load_reg(s, rm); 8199 switch ((insn >> 20) & 7) { 8200 case 0: /* 32 x 32 -> 32 */ 8201 tcg_gen_mul_i32(tmp, tmp, tmp2); 8202 tcg_temp_free_i32(tmp2); 8203 if (rs != 15) { 8204 tmp2 = load_reg(s, rs); 8205 if (op) 8206 tcg_gen_sub_i32(tmp, tmp2, tmp); 8207 else 8208 tcg_gen_add_i32(tmp, tmp, tmp2); 8209 tcg_temp_free_i32(tmp2); 8210 } 8211 break; 8212 case 1: /* 16 x 16 -> 32 */ 8213 gen_mulxy(tmp, tmp2, op & 2, op & 1); 8214 tcg_temp_free_i32(tmp2); 8215 if (rs != 15) { 8216 tmp2 = load_reg(s, rs); 8217 gen_helper_add_setq(tmp, tmp, tmp2); 8218 tcg_temp_free_i32(tmp2); 8219 } 8220 break; 8221 case 2: /* Dual multiply add. */ 8222 case 4: /* Dual multiply subtract. */ 8223 if (op) 8224 gen_swap_half(tmp2); 8225 gen_smul_dual(tmp, tmp2); 8226 if (insn & (1 << 22)) { 8227 /* This subtraction cannot overflow. */ 8228 tcg_gen_sub_i32(tmp, tmp, tmp2); 8229 } else { 8230 /* This addition cannot overflow 32 bits; 8231 * however it may overflow considered as a signed 8232 * operation, in which case we must set the Q flag. 8233 */ 8234 gen_helper_add_setq(tmp, tmp, tmp2); 8235 } 8236 tcg_temp_free_i32(tmp2); 8237 if (rs != 15) 8238 { 8239 tmp2 = load_reg(s, rs); 8240 gen_helper_add_setq(tmp, tmp, tmp2); 8241 tcg_temp_free_i32(tmp2); 8242 } 8243 break; 8244 case 3: /* 32 * 16 -> 32msb */ 8245 if (op) 8246 tcg_gen_sari_i32(tmp2, tmp2, 16); 8247 else 8248 gen_sxth(tmp2); 8249 tmp64 = gen_muls_i64_i32(tmp, tmp2); 8250 tcg_gen_shri_i64(tmp64, tmp64, 16); 8251 tmp = tcg_temp_new_i32(); 8252 tcg_gen_trunc_i64_i32(tmp, tmp64); 8253 tcg_temp_free_i64(tmp64); 8254 if (rs != 15) 8255 { 8256 tmp2 = load_reg(s, rs); 8257 gen_helper_add_setq(tmp, tmp, tmp2); 8258 tcg_temp_free_i32(tmp2); 8259 } 8260 break; 8261 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ 8262 tmp64 = gen_muls_i64_i32(tmp, tmp2); 8263 if (rs != 15) { 8264 tmp = load_reg(s, rs); 8265 if (insn & (1 << 20)) { 8266 tmp64 = gen_addq_msw(tmp64, tmp); 8267 } else { 8268 tmp64 = gen_subq_msw(tmp64, tmp); 8269 } 8270 } 8271 if (insn & (1 << 4)) { 8272 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); 8273 } 8274 tcg_gen_shri_i64(tmp64, tmp64, 32); 8275 tmp = tcg_temp_new_i32(); 8276 tcg_gen_trunc_i64_i32(tmp, tmp64); 8277 tcg_temp_free_i64(tmp64); 8278 break; 8279 case 7: /* Unsigned sum of absolute differences. */ 8280 gen_helper_usad8(tmp, tmp, tmp2); 8281 tcg_temp_free_i32(tmp2); 8282 if (rs != 15) { 8283 tmp2 = load_reg(s, rs); 8284 tcg_gen_add_i32(tmp, tmp, tmp2); 8285 tcg_temp_free_i32(tmp2); 8286 } 8287 break; 8288 } 8289 store_reg(s, rd, tmp); 8290 break; 8291 case 6: case 7: /* 64-bit multiply, Divide. */ 8292 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); 8293 tmp = load_reg(s, rn); 8294 tmp2 = load_reg(s, rm); 8295 if ((op & 0x50) == 0x10) { 8296 /* sdiv, udiv */ 8297 if (!arm_feature(env, ARM_FEATURE_DIV)) 8298 goto illegal_op; 8299 if (op & 0x20) 8300 gen_helper_udiv(tmp, tmp, tmp2); 8301 else 8302 gen_helper_sdiv(tmp, tmp, tmp2); 8303 tcg_temp_free_i32(tmp2); 8304 store_reg(s, rd, tmp); 8305 } else if ((op & 0xe) == 0xc) { 8306 /* Dual multiply accumulate long. */ 8307 if (op & 1) 8308 gen_swap_half(tmp2); 8309 gen_smul_dual(tmp, tmp2); 8310 if (op & 0x10) { 8311 tcg_gen_sub_i32(tmp, tmp, tmp2); 8312 } else { 8313 tcg_gen_add_i32(tmp, tmp, tmp2); 8314 } 8315 tcg_temp_free_i32(tmp2); 8316 /* BUGFIX */ 8317 tmp64 = tcg_temp_new_i64(); 8318 tcg_gen_ext_i32_i64(tmp64, tmp); 8319 tcg_temp_free_i32(tmp); 8320 gen_addq(s, tmp64, rs, rd); 8321 gen_storeq_reg(s, rs, rd, tmp64); 8322 tcg_temp_free_i64(tmp64); 8323 } else { 8324 if (op & 0x20) { 8325 /* Unsigned 64-bit multiply */ 8326 tmp64 = gen_mulu_i64_i32(tmp, tmp2); 8327 } else { 8328 if (op & 8) { 8329 /* smlalxy */ 8330 gen_mulxy(tmp, tmp2, op & 2, op & 1); 8331 tcg_temp_free_i32(tmp2); 8332 tmp64 = tcg_temp_new_i64(); 8333 tcg_gen_ext_i32_i64(tmp64, tmp); 8334 tcg_temp_free_i32(tmp); 8335 } else { 8336 /* Signed 64-bit multiply */ 8337 tmp64 = gen_muls_i64_i32(tmp, tmp2); 8338 } 8339 } 8340 if (op & 4) { 8341 /* umaal */ 8342 gen_addq_lo(s, tmp64, rs); 8343 gen_addq_lo(s, tmp64, rd); 8344 } else if (op & 0x40) { 8345 /* 64-bit accumulate. */ 8346 gen_addq(s, tmp64, rs, rd); 8347 } 8348 gen_storeq_reg(s, rs, rd, tmp64); 8349 tcg_temp_free_i64(tmp64); 8350 } 8351 break; 8352 } 8353 break; 8354 case 6: case 7: case 14: case 15: 8355 /* Coprocessor. */ 8356 if (((insn >> 24) & 3) == 3) { 8357 /* Translate into the equivalent ARM encoding. */ 8358 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); 8359 if (disas_neon_data_insn(env, s, insn)) 8360 goto illegal_op; 8361 } else { 8362 if (insn & (1 << 28)) 8363 goto illegal_op; 8364 if (disas_coproc_insn (env, s, insn)) 8365 goto illegal_op; 8366 } 8367 break; 8368 case 8: case 9: case 10: case 11: 8369 if (insn & (1 << 15)) { 8370 /* Branches, misc control. */ 8371 if (insn & 0x5000) { 8372 /* Unconditional branch. */ 8373 /* signextend(hw1[10:0]) -> offset[:12]. */ 8374 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff; 8375 /* hw1[10:0] -> offset[11:1]. */ 8376 offset |= (insn & 0x7ff) << 1; 8377 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22] 8378 offset[24:22] already have the same value because of the 8379 sign extension above. */ 8380 offset ^= ((~insn) & (1 << 13)) << 10; 8381 offset ^= ((~insn) & (1 << 11)) << 11; 8382 8383 if (insn & (1 << 14)) { 8384 /* Branch and link. */ 8385 tcg_gen_movi_i32(cpu_R[14], s->pc | 1); 8386 } 8387 8388 offset += s->pc; 8389 if (insn & (1 << 12)) { 8390 /* b/bl */ 8391 gen_jmp(s, offset); 8392 } else { 8393 /* blx */ 8394 offset &= ~(uint32_t)2; 8395 /* thumb2 bx, no need to check */ 8396 gen_bx_im(s, offset); 8397 } 8398 } else if (((insn >> 23) & 7) == 7) { 8399 /* Misc control */ 8400 if (insn & (1 << 13)) 8401 goto illegal_op; 8402 8403 if (insn & (1 << 26)) { 8404 /* Secure monitor call / smc (v6Z) */ 8405 if (!(env->cp15.c0_c2[4] & 0xf000) || IS_USER(s)) { 8406 goto illegal_op; 8407 } 8408 gen_smc(env, s); 8409 } else { 8410 op = (insn >> 20) & 7; 8411 switch (op) { 8412 case 0: /* msr cpsr. */ 8413 if (IS_M(env)) { 8414 tmp = load_reg(s, rn); 8415 addr = tcg_const_i32(insn & 0xff); 8416 gen_helper_v7m_msr(cpu_env, addr, tmp); 8417 tcg_temp_free_i32(addr); 8418 tcg_temp_free_i32(tmp); 8419 gen_lookup_tb(s); 8420 break; 8421 } 8422 /* fall through */ 8423 case 1: /* msr spsr. */ 8424 if (IS_M(env)) 8425 goto illegal_op; 8426 tmp = load_reg(s, rn); 8427 if (gen_set_psr(s, 8428 msr_mask(env, s, (insn >> 8) & 0xf, op == 1), 8429 op == 1, tmp)) 8430 goto illegal_op; 8431 break; 8432 case 2: /* cps, nop-hint. */ 8433 if (((insn >> 8) & 7) == 0) { 8434 gen_nop_hint(s, insn & 0xff); 8435 } 8436 /* Implemented as NOP in user mode. */ 8437 if (IS_USER(s)) 8438 break; 8439 offset = 0; 8440 imm = 0; 8441 if (insn & (1 << 10)) { 8442 if (insn & (1 << 7)) 8443 offset |= CPSR_A; 8444 if (insn & (1 << 6)) 8445 offset |= CPSR_I; 8446 if (insn & (1 << 5)) 8447 offset |= CPSR_F; 8448 if (insn & (1 << 9)) 8449 imm = CPSR_A | CPSR_I | CPSR_F; 8450 } 8451 if (insn & (1 << 8)) { 8452 offset |= 0x1f; 8453 imm |= (insn & 0x1f); 8454 } 8455 if (offset) { 8456 gen_set_psr_im(s, offset, 0, imm); 8457 } 8458 break; 8459 case 3: /* Special control operations. */ 8460 ARCH(7); 8461 op = (insn >> 4) & 0xf; 8462 switch (op) { 8463 case 2: /* clrex */ 8464 gen_clrex(s); 8465 break; 8466 case 4: /* dsb */ 8467 case 5: /* dmb */ 8468 case 6: /* isb */ 8469 /* These execute as NOPs. */ 8470 break; 8471 default: 8472 goto illegal_op; 8473 } 8474 break; 8475 case 4: /* bxj */ 8476 /* Trivial implementation equivalent to bx. */ 8477 tmp = load_reg(s, rn); 8478 gen_bx(s, tmp); 8479 break; 8480 case 5: /* Exception return. */ 8481 if (IS_USER(s)) { 8482 goto illegal_op; 8483 } 8484 if (rn != 14 || rd != 15) { 8485 goto illegal_op; 8486 } 8487 tmp = load_reg(s, rn); 8488 tcg_gen_subi_i32(tmp, tmp, insn & 0xff); 8489 gen_exception_return(s, tmp); 8490 break; 8491 case 6: /* mrs cpsr. */ 8492 tmp = tcg_temp_new_i32(); 8493 if (IS_M(env)) { 8494 addr = tcg_const_i32(insn & 0xff); 8495 gen_helper_v7m_mrs(tmp, cpu_env, addr); 8496 tcg_temp_free_i32(addr); 8497 } else { 8498 gen_helper_cpsr_read(tmp); 8499 } 8500 store_reg(s, rd, tmp); 8501 break; 8502 case 7: /* mrs spsr. */ 8503 /* Not accessible in user mode. */ 8504 if (IS_USER(s) || IS_M(env)) 8505 goto illegal_op; 8506 tmp = load_cpu_field(spsr); 8507 store_reg(s, rd, tmp); 8508 break; 8509 } 8510 } 8511 } else { 8512 /* Conditional branch. */ 8513 op = (insn >> 22) & 0xf; 8514 /* Generate a conditional jump to next instruction. */ 8515 s->condlabel = gen_new_label(); 8516 gen_test_cc(op ^ 1, s->condlabel); 8517 s->condjmp = 1; 8518 8519 /* offset[11:1] = insn[10:0] */ 8520 offset = (insn & 0x7ff) << 1; 8521 /* offset[17:12] = insn[21:16]. */ 8522 offset |= (insn & 0x003f0000) >> 4; 8523 /* offset[31:20] = insn[26]. */ 8524 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11; 8525 /* offset[18] = insn[13]. */ 8526 offset |= (insn & (1 << 13)) << 5; 8527 /* offset[19] = insn[11]. */ 8528 offset |= (insn & (1 << 11)) << 8; 8529 8530 /* jump to the offset */ 8531 gen_jmp(s, s->pc + offset); 8532 } 8533 } else { 8534 /* Data processing immediate. */ 8535 if (insn & (1 << 25)) { 8536 if (insn & (1 << 24)) { 8537 if (insn & (1 << 20)) 8538 goto illegal_op; 8539 /* Bitfield/Saturate. */ 8540 op = (insn >> 21) & 7; 8541 imm = insn & 0x1f; 8542 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); 8543 if (rn == 15) { 8544 tmp = tcg_temp_new_i32(); 8545 tcg_gen_movi_i32(tmp, 0); 8546 } else { 8547 tmp = load_reg(s, rn); 8548 } 8549 switch (op) { 8550 case 2: /* Signed bitfield extract. */ 8551 imm++; 8552 if (shift + imm > 32) 8553 goto illegal_op; 8554 if (imm < 32) 8555 gen_sbfx(tmp, shift, imm); 8556 break; 8557 case 6: /* Unsigned bitfield extract. */ 8558 imm++; 8559 if (shift + imm > 32) 8560 goto illegal_op; 8561 if (imm < 32) 8562 gen_ubfx(tmp, shift, (1u << imm) - 1); 8563 break; 8564 case 3: /* Bitfield insert/clear. */ 8565 if (imm < shift) 8566 goto illegal_op; 8567 imm = imm + 1 - shift; 8568 if (imm != 32) { 8569 tmp2 = load_reg(s, rd); 8570 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1); 8571 tcg_temp_free_i32(tmp2); 8572 } 8573 break; 8574 case 7: 8575 goto illegal_op; 8576 default: /* Saturate. */ 8577 if (shift) { 8578 if (op & 1) 8579 tcg_gen_sari_i32(tmp, tmp, shift); 8580 else 8581 tcg_gen_shli_i32(tmp, tmp, shift); 8582 } 8583 tmp2 = tcg_const_i32(imm); 8584 if (op & 4) { 8585 /* Unsigned. */ 8586 if ((op & 1) && shift == 0) 8587 gen_helper_usat16(tmp, tmp, tmp2); 8588 else 8589 gen_helper_usat(tmp, tmp, tmp2); 8590 } else { 8591 /* Signed. */ 8592 if ((op & 1) && shift == 0) 8593 gen_helper_ssat16(tmp, tmp, tmp2); 8594 else 8595 gen_helper_ssat(tmp, tmp, tmp2); 8596 } 8597 tcg_temp_free_i32(tmp2); 8598 break; 8599 } 8600 store_reg(s, rd, tmp); 8601 } else { 8602 imm = ((insn & 0x04000000) >> 15) 8603 | ((insn & 0x7000) >> 4) | (insn & 0xff); 8604 if (insn & (1 << 22)) { 8605 /* 16-bit immediate. */ 8606 imm |= (insn >> 4) & 0xf000; 8607 if (insn & (1 << 23)) { 8608 /* movt */ 8609 tmp = load_reg(s, rd); 8610 tcg_gen_ext16u_i32(tmp, tmp); 8611 tcg_gen_ori_i32(tmp, tmp, imm << 16); 8612 } else { 8613 /* movw */ 8614 tmp = tcg_temp_new_i32(); 8615 tcg_gen_movi_i32(tmp, imm); 8616 } 8617 } else { 8618 /* Add/sub 12-bit immediate. */ 8619 if (rn == 15) { 8620 offset = s->pc & ~(uint32_t)3; 8621 if (insn & (1 << 23)) 8622 offset -= imm; 8623 else 8624 offset += imm; 8625 tmp = tcg_temp_new_i32(); 8626 tcg_gen_movi_i32(tmp, offset); 8627 } else { 8628 tmp = load_reg(s, rn); 8629 if (insn & (1 << 23)) 8630 tcg_gen_subi_i32(tmp, tmp, imm); 8631 else 8632 tcg_gen_addi_i32(tmp, tmp, imm); 8633 } 8634 } 8635 store_reg(s, rd, tmp); 8636 } 8637 } else { 8638 int shifter_out = 0; 8639 /* modified 12-bit immediate. */ 8640 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); 8641 imm = (insn & 0xff); 8642 switch (shift) { 8643 case 0: /* XY */ 8644 /* Nothing to do. */ 8645 break; 8646 case 1: /* 00XY00XY */ 8647 imm |= imm << 16; 8648 break; 8649 case 2: /* XY00XY00 */ 8650 imm |= imm << 16; 8651 imm <<= 8; 8652 break; 8653 case 3: /* XYXYXYXY */ 8654 imm |= imm << 16; 8655 imm |= imm << 8; 8656 break; 8657 default: /* Rotated constant. */ 8658 shift = (shift << 1) | (imm >> 7); 8659 imm |= 0x80; 8660 imm = imm << (32 - shift); 8661 shifter_out = 1; 8662 break; 8663 } 8664 tmp2 = tcg_temp_new_i32(); 8665 tcg_gen_movi_i32(tmp2, imm); 8666 rn = (insn >> 16) & 0xf; 8667 if (rn == 15) { 8668 tmp = tcg_temp_new_i32(); 8669 tcg_gen_movi_i32(tmp, 0); 8670 } else { 8671 tmp = load_reg(s, rn); 8672 } 8673 op = (insn >> 21) & 0xf; 8674 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, 8675 shifter_out, tmp, tmp2)) 8676 goto illegal_op; 8677 tcg_temp_free_i32(tmp2); 8678 rd = (insn >> 8) & 0xf; 8679 if (rd != 15) { 8680 store_reg(s, rd, tmp); 8681 } else { 8682 tcg_temp_free_i32(tmp); 8683 } 8684 } 8685 } 8686 break; 8687 case 12: /* Load/store single data item. */ 8688 { 8689 int postinc = 0; 8690 int writeback = 0; 8691 int user; 8692 if ((insn & 0x01100000) == 0x01000000) { 8693 if (disas_neon_ls_insn(env, s, insn)) 8694 goto illegal_op; 8695 break; 8696 } 8697 op = ((insn >> 21) & 3) | ((insn >> 22) & 4); 8698 if (rs == 15) { 8699 if (!(insn & (1 << 20))) { 8700 goto illegal_op; 8701 } 8702 if (op != 2) { 8703 /* Byte or halfword load space with dest == r15 : memory hints. 8704 * Catch them early so we don't emit pointless addressing code. 8705 * This space is a mix of: 8706 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike 8707 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP 8708 * cores) 8709 * unallocated hints, which must be treated as NOPs 8710 * UNPREDICTABLE space, which we NOP or UNDEF depending on 8711 * which is easiest for the decoding logic 8712 * Some space which must UNDEF 8713 */ 8714 int op1 = (insn >> 23) & 3; 8715 int op2 = (insn >> 6) & 0x3f; 8716 if (op & 2) { 8717 goto illegal_op; 8718 } 8719 if (rn == 15) { 8720 /* UNPREDICTABLE or unallocated hint */ 8721 return 0; 8722 } 8723 if (op1 & 1) { 8724 return 0; /* PLD* or unallocated hint */ 8725 } 8726 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { 8727 return 0; /* PLD* or unallocated hint */ 8728 } 8729 /* UNDEF space, or an UNPREDICTABLE */ 8730 return 1; 8731 } 8732 } 8733 user = IS_USER(s); 8734 if (rn == 15) { 8735 addr = tcg_temp_new_i32(); 8736 /* PC relative. */ 8737 /* s->pc has already been incremented by 4. */ 8738 imm = s->pc & 0xfffffffc; 8739 if (insn & (1 << 23)) 8740 imm += insn & 0xfff; 8741 else 8742 imm -= insn & 0xfff; 8743 tcg_gen_movi_i32(addr, imm); 8744 } else { 8745 addr = load_reg(s, rn); 8746 if (insn & (1 << 23)) { 8747 /* Positive offset. */ 8748 imm = insn & 0xfff; 8749 tcg_gen_addi_i32(addr, addr, imm); 8750 } else { 8751 imm = insn & 0xff; 8752 switch ((insn >> 8) & 0xf) { 8753 case 0x0: /* Shifted Register. */ 8754 shift = (insn >> 4) & 0xf; 8755 if (shift > 3) { 8756 tcg_temp_free_i32(addr); 8757 goto illegal_op; 8758 } 8759 tmp = load_reg(s, rm); 8760 if (shift) 8761 tcg_gen_shli_i32(tmp, tmp, shift); 8762 tcg_gen_add_i32(addr, addr, tmp); 8763 tcg_temp_free_i32(tmp); 8764 break; 8765 case 0xc: /* Negative offset. */ 8766 tcg_gen_addi_i32(addr, addr, -imm); 8767 break; 8768 case 0xe: /* User privilege. */ 8769 tcg_gen_addi_i32(addr, addr, imm); 8770 user = 1; 8771 break; 8772 case 0x9: /* Post-decrement. */ 8773 imm = -imm; 8774 /* Fall through. */ 8775 case 0xb: /* Post-increment. */ 8776 postinc = 1; 8777 writeback = 1; 8778 break; 8779 case 0xd: /* Pre-decrement. */ 8780 imm = -imm; 8781 /* Fall through. */ 8782 case 0xf: /* Pre-increment. */ 8783 tcg_gen_addi_i32(addr, addr, imm); 8784 writeback = 1; 8785 break; 8786 default: 8787 tcg_temp_free_i32(addr); 8788 goto illegal_op; 8789 } 8790 } 8791 } 8792 if (insn & (1 << 20)) { 8793 /* Load. */ 8794 switch (op) { 8795 case 0: tmp = gen_ld8u(addr, user); break; 8796 case 4: tmp = gen_ld8s(addr, user); break; 8797 case 1: tmp = gen_ld16u(addr, user); break; 8798 case 5: tmp = gen_ld16s(addr, user); break; 8799 case 2: tmp = gen_ld32(addr, user); break; 8800 default: 8801 tcg_temp_free_i32(addr); 8802 goto illegal_op; 8803 } 8804 if (rs == 15) { 8805 gen_bx(s, tmp); 8806 } else { 8807 store_reg(s, rs, tmp); 8808 } 8809 } else { 8810 /* Store. */ 8811 tmp = load_reg(s, rs); 8812 switch (op) { 8813 case 0: gen_st8(tmp, addr, user); break; 8814 case 1: gen_st16(tmp, addr, user); break; 8815 case 2: gen_st32(tmp, addr, user); break; 8816 default: 8817 tcg_temp_free_i32(addr); 8818 goto illegal_op; 8819 } 8820 } 8821 if (postinc) 8822 tcg_gen_addi_i32(addr, addr, imm); 8823 if (writeback) { 8824 store_reg(s, rn, addr); 8825 } else { 8826 tcg_temp_free_i32(addr); 8827 } 8828 } 8829 break; 8830 default: 8831 goto illegal_op; 8832 } 8833 return 0; 8834illegal_op: 8835 return 1; 8836} 8837 8838static void disas_thumb_insn(CPUARMState *env, DisasContext *s) 8839{ 8840 uint32_t val, insn, op, rm, rn, rd, shift, cond; 8841 int32_t offset; 8842 int i; 8843 TCGv tmp; 8844 TCGv tmp2; 8845 TCGv addr; 8846 8847 if (s->condexec_mask) { 8848 cond = s->condexec_cond; 8849 if (cond != 0x0e) { /* Skip conditional when condition is AL. */ 8850 s->condlabel = gen_new_label(); 8851 gen_test_cc(cond ^ 1, s->condlabel); 8852 s->condjmp = 1; 8853 } 8854 } 8855 8856 insn = cpu_lduw_code(env, s->pc); 8857 8858 ANDROID_WATCH_CALLSTACK_THUMB(s); 8859 8860 s->pc += 2; 8861 8862 switch (insn >> 12) { 8863 case 0: case 1: 8864 8865 rd = insn & 7; 8866 op = (insn >> 11) & 3; 8867 if (op == 3) { 8868 /* add/subtract */ 8869 rn = (insn >> 3) & 7; 8870 tmp = load_reg(s, rn); 8871 if (insn & (1 << 10)) { 8872 /* immediate */ 8873 tmp2 = tcg_temp_new_i32(); 8874 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7); 8875 } else { 8876 /* reg */ 8877 rm = (insn >> 6) & 7; 8878 tmp2 = load_reg(s, rm); 8879 } 8880 if (insn & (1 << 9)) { 8881 if (s->condexec_mask) 8882 tcg_gen_sub_i32(tmp, tmp, tmp2); 8883 else 8884 gen_helper_sub_cc(tmp, tmp, tmp2); 8885 } else { 8886 if (s->condexec_mask) 8887 tcg_gen_add_i32(tmp, tmp, tmp2); 8888 else 8889 gen_helper_add_cc(tmp, tmp, tmp2); 8890 } 8891 tcg_temp_free_i32(tmp2); 8892 store_reg(s, rd, tmp); 8893 } else { 8894 /* shift immediate */ 8895 rm = (insn >> 3) & 7; 8896 shift = (insn >> 6) & 0x1f; 8897 tmp = load_reg(s, rm); 8898 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0); 8899 if (!s->condexec_mask) 8900 gen_logic_CC(tmp); 8901 store_reg(s, rd, tmp); 8902 } 8903 break; 8904 case 2: case 3: 8905 /* arithmetic large immediate */ 8906 op = (insn >> 11) & 3; 8907 rd = (insn >> 8) & 0x7; 8908 if (op == 0) { /* mov */ 8909 tmp = tcg_temp_new_i32(); 8910 tcg_gen_movi_i32(tmp, insn & 0xff); 8911 if (!s->condexec_mask) 8912 gen_logic_CC(tmp); 8913 store_reg(s, rd, tmp); 8914 } else { 8915 tmp = load_reg(s, rd); 8916 tmp2 = tcg_temp_new_i32(); 8917 tcg_gen_movi_i32(tmp2, insn & 0xff); 8918 switch (op) { 8919 case 1: /* cmp */ 8920 gen_helper_sub_cc(tmp, tmp, tmp2); 8921 tcg_temp_free_i32(tmp); 8922 tcg_temp_free_i32(tmp2); 8923 break; 8924 case 2: /* add */ 8925 if (s->condexec_mask) 8926 tcg_gen_add_i32(tmp, tmp, tmp2); 8927 else 8928 gen_helper_add_cc(tmp, tmp, tmp2); 8929 tcg_temp_free_i32(tmp2); 8930 store_reg(s, rd, tmp); 8931 break; 8932 case 3: /* sub */ 8933 if (s->condexec_mask) 8934 tcg_gen_sub_i32(tmp, tmp, tmp2); 8935 else 8936 gen_helper_sub_cc(tmp, tmp, tmp2); 8937 tcg_temp_free_i32(tmp2); 8938 store_reg(s, rd, tmp); 8939 break; 8940 } 8941 } 8942 break; 8943 case 4: 8944 if (insn & (1 << 11)) { 8945 rd = (insn >> 8) & 7; 8946 /* load pc-relative. Bit 1 of PC is ignored. */ 8947 val = s->pc + 2 + ((insn & 0xff) * 4); 8948 val &= ~(uint32_t)2; 8949 addr = tcg_temp_new_i32(); 8950 tcg_gen_movi_i32(addr, val); 8951 tmp = gen_ld32(addr, IS_USER(s)); 8952 tcg_temp_free_i32(addr); 8953 store_reg(s, rd, tmp); 8954 break; 8955 } 8956 if (insn & (1 << 10)) { 8957 /* data processing extended or blx */ 8958 rd = (insn & 7) | ((insn >> 4) & 8); 8959 rm = (insn >> 3) & 0xf; 8960 op = (insn >> 8) & 3; 8961 switch (op) { 8962 case 0: /* add */ 8963 tmp = load_reg(s, rd); 8964 tmp2 = load_reg(s, rm); 8965 tcg_gen_add_i32(tmp, tmp, tmp2); 8966 tcg_temp_free_i32(tmp2); 8967 store_reg(s, rd, tmp); 8968 break; 8969 case 1: /* cmp */ 8970 tmp = load_reg(s, rd); 8971 tmp2 = load_reg(s, rm); 8972 gen_helper_sub_cc(tmp, tmp, tmp2); 8973 tcg_temp_free_i32(tmp2); 8974 tcg_temp_free_i32(tmp); 8975 break; 8976 case 2: /* mov/cpy */ 8977 tmp = load_reg(s, rm); 8978 store_reg(s, rd, tmp); 8979 break; 8980 case 3:/* branch [and link] exchange thumb register */ 8981 tmp = load_reg(s, rm); 8982 if (insn & (1 << 7)) { 8983 ARCH(5); 8984 val = (uint32_t)s->pc | 1; 8985 tmp2 = tcg_temp_new_i32(); 8986 tcg_gen_movi_i32(tmp2, val); 8987 store_reg(s, 14, tmp2); 8988 } 8989 /* already thumb, no need to check */ 8990 gen_bx(s, tmp); 8991 break; 8992 } 8993 break; 8994 } 8995 8996 /* data processing register */ 8997 rd = insn & 7; 8998 rm = (insn >> 3) & 7; 8999 op = (insn >> 6) & 0xf; 9000 if (op == 2 || op == 3 || op == 4 || op == 7) { 9001 /* the shift/rotate ops want the operands backwards */ 9002 val = rm; 9003 rm = rd; 9004 rd = val; 9005 val = 1; 9006 } else { 9007 val = 0; 9008 } 9009 9010 if (op == 9) { /* neg */ 9011 tmp = tcg_temp_new_i32(); 9012 tcg_gen_movi_i32(tmp, 0); 9013 } else if (op != 0xf) { /* mvn doesn't read its first operand */ 9014 tmp = load_reg(s, rd); 9015 } else { 9016 TCGV_UNUSED(tmp); 9017 } 9018 9019 tmp2 = load_reg(s, rm); 9020 switch (op) { 9021 case 0x0: /* and */ 9022 tcg_gen_and_i32(tmp, tmp, tmp2); 9023 if (!s->condexec_mask) 9024 gen_logic_CC(tmp); 9025 break; 9026 case 0x1: /* eor */ 9027 tcg_gen_xor_i32(tmp, tmp, tmp2); 9028 if (!s->condexec_mask) 9029 gen_logic_CC(tmp); 9030 break; 9031 case 0x2: /* lsl */ 9032 if (s->condexec_mask) { 9033 gen_helper_shl(tmp2, tmp2, tmp); 9034 } else { 9035 gen_helper_shl_cc(tmp2, tmp2, tmp); 9036 gen_logic_CC(tmp2); 9037 } 9038 break; 9039 case 0x3: /* lsr */ 9040 if (s->condexec_mask) { 9041 gen_helper_shr(tmp2, tmp2, tmp); 9042 } else { 9043 gen_helper_shr_cc(tmp2, tmp2, tmp); 9044 gen_logic_CC(tmp2); 9045 } 9046 break; 9047 case 0x4: /* asr */ 9048 if (s->condexec_mask) { 9049 gen_helper_sar(tmp2, tmp2, tmp); 9050 } else { 9051 gen_helper_sar_cc(tmp2, tmp2, tmp); 9052 gen_logic_CC(tmp2); 9053 } 9054 break; 9055 case 0x5: /* adc */ 9056 if (s->condexec_mask) 9057 gen_adc(tmp, tmp2); 9058 else 9059 gen_helper_adc_cc(tmp, tmp, tmp2); 9060 break; 9061 case 0x6: /* sbc */ 9062 if (s->condexec_mask) 9063 gen_sub_carry(tmp, tmp, tmp2); 9064 else 9065 gen_helper_sbc_cc(tmp, tmp, tmp2); 9066 break; 9067 case 0x7: /* ror */ 9068 if (s->condexec_mask) { 9069 tcg_gen_andi_i32(tmp, tmp, 0x1f); 9070 tcg_gen_rotr_i32(tmp2, tmp2, tmp); 9071 } else { 9072 gen_helper_ror_cc(tmp2, tmp2, tmp); 9073 gen_logic_CC(tmp2); 9074 } 9075 break; 9076 case 0x8: /* tst */ 9077 tcg_gen_and_i32(tmp, tmp, tmp2); 9078 gen_logic_CC(tmp); 9079 rd = 16; 9080 break; 9081 case 0x9: /* neg */ 9082 if (s->condexec_mask) 9083 tcg_gen_neg_i32(tmp, tmp2); 9084 else 9085 gen_helper_sub_cc(tmp, tmp, tmp2); 9086 break; 9087 case 0xa: /* cmp */ 9088 gen_helper_sub_cc(tmp, tmp, tmp2); 9089 rd = 16; 9090 break; 9091 case 0xb: /* cmn */ 9092 gen_helper_add_cc(tmp, tmp, tmp2); 9093 rd = 16; 9094 break; 9095 case 0xc: /* orr */ 9096 tcg_gen_or_i32(tmp, tmp, tmp2); 9097 if (!s->condexec_mask) 9098 gen_logic_CC(tmp); 9099 break; 9100 case 0xd: /* mul */ 9101 tcg_gen_mul_i32(tmp, tmp, tmp2); 9102 if (!s->condexec_mask) 9103 gen_logic_CC(tmp); 9104 break; 9105 case 0xe: /* bic */ 9106 tcg_gen_andc_i32(tmp, tmp, tmp2); 9107 if (!s->condexec_mask) 9108 gen_logic_CC(tmp); 9109 break; 9110 case 0xf: /* mvn */ 9111 tcg_gen_not_i32(tmp2, tmp2); 9112 if (!s->condexec_mask) 9113 gen_logic_CC(tmp2); 9114 val = 1; 9115 rm = rd; 9116 break; 9117 } 9118 if (rd != 16) { 9119 if (val) { 9120 store_reg(s, rm, tmp2); 9121 if (op != 0xf) 9122 tcg_temp_free_i32(tmp); 9123 } else { 9124 store_reg(s, rd, tmp); 9125 tcg_temp_free_i32(tmp2); 9126 } 9127 } else { 9128 tcg_temp_free_i32(tmp); 9129 tcg_temp_free_i32(tmp2); 9130 } 9131 break; 9132 9133 case 5: 9134 /* load/store register offset. */ 9135 rd = insn & 7; 9136 rn = (insn >> 3) & 7; 9137 rm = (insn >> 6) & 7; 9138 op = (insn >> 9) & 7; 9139 addr = load_reg(s, rn); 9140 tmp = load_reg(s, rm); 9141 tcg_gen_add_i32(addr, addr, tmp); 9142 tcg_temp_free_i32(tmp); 9143 9144 if (op < 3) /* store */ 9145 tmp = load_reg(s, rd); 9146 9147 switch (op) { 9148 case 0: /* str */ 9149 gen_st32(tmp, addr, IS_USER(s)); 9150 break; 9151 case 1: /* strh */ 9152 gen_st16(tmp, addr, IS_USER(s)); 9153 break; 9154 case 2: /* strb */ 9155 gen_st8(tmp, addr, IS_USER(s)); 9156 break; 9157 case 3: /* ldrsb */ 9158 tmp = gen_ld8s(addr, IS_USER(s)); 9159 break; 9160 case 4: /* ldr */ 9161 tmp = gen_ld32(addr, IS_USER(s)); 9162 break; 9163 case 5: /* ldrh */ 9164 tmp = gen_ld16u(addr, IS_USER(s)); 9165 break; 9166 case 6: /* ldrb */ 9167 tmp = gen_ld8u(addr, IS_USER(s)); 9168 break; 9169 case 7: /* ldrsh */ 9170 tmp = gen_ld16s(addr, IS_USER(s)); 9171 break; 9172 } 9173 if (op >= 3) /* load */ 9174 store_reg(s, rd, tmp); 9175 tcg_temp_free_i32(addr); 9176 break; 9177 9178 case 6: 9179 /* load/store word immediate offset */ 9180 rd = insn & 7; 9181 rn = (insn >> 3) & 7; 9182 addr = load_reg(s, rn); 9183 val = (insn >> 4) & 0x7c; 9184 tcg_gen_addi_i32(addr, addr, val); 9185 9186 if (insn & (1 << 11)) { 9187 /* load */ 9188 tmp = gen_ld32(addr, IS_USER(s)); 9189 store_reg(s, rd, tmp); 9190 } else { 9191 /* store */ 9192 tmp = load_reg(s, rd); 9193 gen_st32(tmp, addr, IS_USER(s)); 9194 } 9195 tcg_temp_free_i32(addr); 9196 break; 9197 9198 case 7: 9199 /* load/store byte immediate offset */ 9200 rd = insn & 7; 9201 rn = (insn >> 3) & 7; 9202 addr = load_reg(s, rn); 9203 val = (insn >> 6) & 0x1f; 9204 tcg_gen_addi_i32(addr, addr, val); 9205 9206 if (insn & (1 << 11)) { 9207 /* load */ 9208 tmp = gen_ld8u(addr, IS_USER(s)); 9209 store_reg(s, rd, tmp); 9210 } else { 9211 /* store */ 9212 tmp = load_reg(s, rd); 9213 gen_st8(tmp, addr, IS_USER(s)); 9214 } 9215 tcg_temp_free_i32(addr); 9216 break; 9217 9218 case 8: 9219 /* load/store halfword immediate offset */ 9220 rd = insn & 7; 9221 rn = (insn >> 3) & 7; 9222 addr = load_reg(s, rn); 9223 val = (insn >> 5) & 0x3e; 9224 tcg_gen_addi_i32(addr, addr, val); 9225 9226 if (insn & (1 << 11)) { 9227 /* load */ 9228 tmp = gen_ld16u(addr, IS_USER(s)); 9229 store_reg(s, rd, tmp); 9230 } else { 9231 /* store */ 9232 tmp = load_reg(s, rd); 9233 gen_st16(tmp, addr, IS_USER(s)); 9234 } 9235 tcg_temp_free_i32(addr); 9236 break; 9237 9238 case 9: 9239 /* load/store from stack */ 9240 rd = (insn >> 8) & 7; 9241 addr = load_reg(s, 13); 9242 val = (insn & 0xff) * 4; 9243 tcg_gen_addi_i32(addr, addr, val); 9244 9245 if (insn & (1 << 11)) { 9246 /* load */ 9247 tmp = gen_ld32(addr, IS_USER(s)); 9248 store_reg(s, rd, tmp); 9249 } else { 9250 /* store */ 9251 tmp = load_reg(s, rd); 9252 gen_st32(tmp, addr, IS_USER(s)); 9253 } 9254 tcg_temp_free_i32(addr); 9255 break; 9256 9257 case 10: 9258 /* add to high reg */ 9259 rd = (insn >> 8) & 7; 9260 if (insn & (1 << 11)) { 9261 /* SP */ 9262 tmp = load_reg(s, 13); 9263 } else { 9264 /* PC. bit 1 is ignored. */ 9265 tmp = tcg_temp_new_i32(); 9266 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2); 9267 } 9268 val = (insn & 0xff) * 4; 9269 tcg_gen_addi_i32(tmp, tmp, val); 9270 store_reg(s, rd, tmp); 9271 break; 9272 9273 case 11: 9274 /* misc */ 9275 op = (insn >> 8) & 0xf; 9276 switch (op) { 9277 case 0: 9278 /* adjust stack pointer */ 9279 tmp = load_reg(s, 13); 9280 val = (insn & 0x7f) * 4; 9281 if (insn & (1 << 7)) 9282 val = -(int32_t)val; 9283 tcg_gen_addi_i32(tmp, tmp, val); 9284 store_reg(s, 13, tmp); 9285 break; 9286 9287 case 2: /* sign/zero extend. */ 9288 ARCH(6); 9289 rd = insn & 7; 9290 rm = (insn >> 3) & 7; 9291 tmp = load_reg(s, rm); 9292 switch ((insn >> 6) & 3) { 9293 case 0: gen_sxth(tmp); break; 9294 case 1: gen_sxtb(tmp); break; 9295 case 2: gen_uxth(tmp); break; 9296 case 3: gen_uxtb(tmp); break; 9297 } 9298 store_reg(s, rd, tmp); 9299 break; 9300 case 4: case 5: case 0xc: case 0xd: 9301 /* push/pop */ 9302 addr = load_reg(s, 13); 9303 if (insn & (1 << 8)) 9304 offset = 4; 9305 else 9306 offset = 0; 9307 for (i = 0; i < 8; i++) { 9308 if (insn & (1 << i)) 9309 offset += 4; 9310 } 9311 if ((insn & (1 << 11)) == 0) { 9312 tcg_gen_addi_i32(addr, addr, -offset); 9313 } 9314 tmp2 = tcg_const_i32(4); 9315 for (i = 0; i < 8; i++) { 9316 if (insn & (1 << i)) { 9317 if (insn & (1 << 11)) { 9318 /* pop */ 9319 tmp = gen_ld32(addr, IS_USER(s)); 9320 store_reg(s, i, tmp); 9321 } else { 9322 /* push */ 9323 tmp = load_reg(s, i); 9324 gen_st32(tmp, addr, IS_USER(s)); 9325 } 9326 /* advance to the next address. */ 9327 tcg_gen_add_i32(addr, addr, tmp2); 9328 } 9329 } 9330 TCGV_UNUSED(tmp); 9331 if (insn & (1 << 8)) { 9332 if (insn & (1 << 11)) { 9333 /* pop pc */ 9334 tmp = gen_ld32(addr, IS_USER(s)); 9335 /* don't set the pc until the rest of the instruction 9336 has completed */ 9337 } else { 9338 /* push lr */ 9339 tmp = load_reg(s, 14); 9340 gen_st32(tmp, addr, IS_USER(s)); 9341 } 9342 tcg_gen_add_i32(addr, addr, tmp2); 9343 } 9344 tcg_temp_free_i32(tmp2); 9345 if ((insn & (1 << 11)) == 0) { 9346 tcg_gen_addi_i32(addr, addr, -offset); 9347 } 9348 /* write back the new stack pointer */ 9349 store_reg(s, 13, addr); 9350 /* set the new PC value */ 9351 if ((insn & 0x0900) == 0x0900) { 9352 store_reg_from_load(env, s, 15, tmp); 9353 } 9354 break; 9355 9356 case 1: case 3: case 9: case 11: /* czb */ 9357 rm = insn & 7; 9358 tmp = load_reg(s, rm); 9359 s->condlabel = gen_new_label(); 9360 s->condjmp = 1; 9361 if (insn & (1 << 11)) 9362 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel); 9363 else 9364 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel); 9365 tcg_temp_free_i32(tmp); 9366 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; 9367 val = (uint32_t)s->pc + 2; 9368 val += offset; 9369 gen_jmp(s, val); 9370 break; 9371 9372 case 15: /* IT, nop-hint. */ 9373 if ((insn & 0xf) == 0) { 9374 gen_nop_hint(s, (insn >> 4) & 0xf); 9375 break; 9376 } 9377 /* If Then. */ 9378 s->condexec_cond = (insn >> 4) & 0xe; 9379 s->condexec_mask = insn & 0x1f; 9380 /* No actual code generated for this insn, just setup state. */ 9381 break; 9382 9383 case 0xe: /* bkpt */ 9384 ARCH(5); 9385 gen_exception_insn(s, 2, EXCP_BKPT); 9386 break; 9387 9388 case 0xa: /* rev */ 9389 ARCH(6); 9390 rn = (insn >> 3) & 0x7; 9391 rd = insn & 0x7; 9392 tmp = load_reg(s, rn); 9393 switch ((insn >> 6) & 3) { 9394 case 0: tcg_gen_bswap32_i32(tmp, tmp); break; 9395 case 1: gen_rev16(tmp); break; 9396 case 3: gen_revsh(tmp); break; 9397 default: goto illegal_op; 9398 } 9399 store_reg(s, rd, tmp); 9400 break; 9401 9402 case 6: /* cps */ 9403 ARCH(6); 9404 if (IS_USER(s)) 9405 break; 9406 if (IS_M(env)) { 9407 tmp = tcg_const_i32((insn & (1 << 4)) != 0); 9408 /* PRIMASK */ 9409 if (insn & 1) { 9410 addr = tcg_const_i32(16); 9411 gen_helper_v7m_msr(cpu_env, addr, tmp); 9412 tcg_temp_free_i32(addr); 9413 } 9414 /* FAULTMASK */ 9415 if (insn & 2) { 9416 addr = tcg_const_i32(17); 9417 gen_helper_v7m_msr(cpu_env, addr, tmp); 9418 tcg_temp_free_i32(addr); 9419 } 9420 tcg_temp_free_i32(tmp); 9421 gen_lookup_tb(s); 9422 } else { 9423 if (insn & (1 << 4)) 9424 shift = CPSR_A | CPSR_I | CPSR_F; 9425 else 9426 shift = 0; 9427 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift); 9428 } 9429 break; 9430 9431 default: 9432 goto undef; 9433 } 9434 break; 9435 9436 case 12: 9437 { 9438 /* load/store multiple */ 9439 TCGv loaded_var; 9440 TCGV_UNUSED(loaded_var); 9441 rn = (insn >> 8) & 0x7; 9442 addr = load_reg(s, rn); 9443 for (i = 0; i < 8; i++) { 9444 if (insn & (1 << i)) { 9445 if (insn & (1 << 11)) { 9446 /* load */ 9447 tmp = gen_ld32(addr, IS_USER(s)); 9448 if (i == rn) { 9449 loaded_var = tmp; 9450 } else { 9451 store_reg(s, i, tmp); 9452 } 9453 } else { 9454 /* store */ 9455 tmp = load_reg(s, i); 9456 gen_st32(tmp, addr, IS_USER(s)); 9457 } 9458 /* advance to the next address */ 9459 tcg_gen_addi_i32(addr, addr, 4); 9460 } 9461 } 9462 if ((insn & (1 << rn)) == 0) { 9463 /* base reg not in list: base register writeback */ 9464 store_reg(s, rn, addr); 9465 } else { 9466 /* base reg in list: if load, complete it now */ 9467 if (insn & (1 << 11)) { 9468 store_reg(s, rn, loaded_var); 9469 } 9470 tcg_temp_free_i32(addr); 9471 } 9472 break; 9473 } 9474 case 13: 9475 /* conditional branch or swi */ 9476 cond = (insn >> 8) & 0xf; 9477 if (cond == 0xe) 9478 goto undef; 9479 9480 if (cond == 0xf) { 9481 /* swi */ 9482 gen_set_pc_im(s->pc); 9483 s->is_jmp = DISAS_SWI; 9484 break; 9485 } 9486 /* generate a conditional jump to next instruction */ 9487 s->condlabel = gen_new_label(); 9488 gen_test_cc(cond ^ 1, s->condlabel); 9489 s->condjmp = 1; 9490 9491 /* jump to the offset */ 9492 val = (uint32_t)s->pc + 2; 9493 offset = ((int32_t)insn << 24) >> 24; 9494 val += offset << 1; 9495 gen_jmp(s, val); 9496 break; 9497 9498 case 14: 9499 if (insn & (1 << 11)) { 9500 if (disas_thumb2_insn(env, s, insn)) 9501 goto undef32; 9502 break; 9503 } 9504 /* unconditional branch */ 9505 val = (uint32_t)s->pc; 9506 offset = ((int32_t)insn << 21) >> 21; 9507 val += (offset << 1) + 2; 9508 gen_jmp(s, val); 9509 break; 9510 9511 case 15: 9512 if (disas_thumb2_insn(env, s, insn)) 9513 goto undef32; 9514 break; 9515 } 9516 return; 9517undef32: 9518 gen_exception_insn(s, 4, EXCP_UDEF); 9519 return; 9520illegal_op: 9521undef: 9522 gen_exception_insn(s, 2, EXCP_UDEF); 9523} 9524 9525/* generate intermediate code in gen_opc_buf and gen_opparam_buf for 9526 basic block 'tb'. If search_pc is TRUE, also generate PC 9527 information for each intermediate instruction. */ 9528static inline void gen_intermediate_code_internal(CPUARMState *env, 9529 TranslationBlock *tb, 9530 int search_pc) 9531{ 9532 DisasContext dc1, *dc = &dc1; 9533 CPUBreakpoint *bp; 9534 uint16_t *gen_opc_end; 9535 int j, lj; 9536 target_ulong pc_start; 9537 uint32_t next_page_start; 9538 int num_insns; 9539 int max_insns; 9540 9541 /* generate intermediate code */ 9542 pc_start = tb->pc; 9543 9544 dc->tb = tb; 9545 9546 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; 9547 9548 dc->is_jmp = DISAS_NEXT; 9549 dc->pc = pc_start; 9550 dc->singlestep_enabled = env->singlestep_enabled; 9551 dc->condjmp = 0; 9552 dc->thumb = ARM_TBFLAG_THUMB(tb->flags); 9553 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1; 9554 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4; 9555#if !defined(CONFIG_USER_ONLY) 9556 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0); 9557#endif 9558 ANDROID_START_CODEGEN(search_pc); 9559 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags); 9560 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); 9561 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags); 9562 cpu_F0s = tcg_temp_new_i32(); 9563 cpu_F1s = tcg_temp_new_i32(); 9564 cpu_F0d = tcg_temp_new_i64(); 9565 cpu_F1d = tcg_temp_new_i64(); 9566 cpu_V0 = cpu_F0d; 9567 cpu_V1 = cpu_F1d; 9568 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */ 9569 cpu_M0 = tcg_temp_new_i64(); 9570 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 9571 lj = -1; 9572 num_insns = 0; 9573 max_insns = tb->cflags & CF_COUNT_MASK; 9574 if (max_insns == 0) 9575 max_insns = CF_COUNT_MASK; 9576 9577 gen_icount_start(); 9578 9579 tcg_clear_temp_count(); 9580 9581 /* A note on handling of the condexec (IT) bits: 9582 * 9583 * We want to avoid the overhead of having to write the updated condexec 9584 * bits back to the CPUARMState for every instruction in an IT block. So: 9585 * (1) if the condexec bits are not already zero then we write 9586 * zero back into the CPUARMState now. This avoids complications trying 9587 * to do it at the end of the block. (For example if we don't do this 9588 * it's hard to identify whether we can safely skip writing condexec 9589 * at the end of the TB, which we definitely want to do for the case 9590 * where a TB doesn't do anything with the IT state at all.) 9591 * (2) if we are going to leave the TB then we call gen_set_condexec() 9592 * which will write the correct value into CPUARMState if zero is wrong. 9593 * This is done both for leaving the TB at the end, and for leaving 9594 * it because of an exception we know will happen, which is done in 9595 * gen_exception_insn(). The latter is necessary because we need to 9596 * leave the TB with the PC/IT state just prior to execution of the 9597 * instruction which caused the exception. 9598 * (3) if we leave the TB unexpectedly (eg a data abort on a load) 9599 * then the CPUARMState will be wrong and we need to reset it. 9600 * This is handled in the same way as restoration of the 9601 * PC in these situations: we will be called again with search_pc=1 9602 * and generate a mapping of the condexec bits for each PC in 9603 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses 9604 * this to restore the condexec bits. 9605 * 9606 * Note that there are no instructions which can read the condexec 9607 * bits, and none which can write non-static values to them, so 9608 * we don't need to care about whether CPUARMState is correct in the 9609 * middle of a TB. 9610 */ 9611 9612 /* Reset the conditional execution bits immediately. This avoids 9613 complications trying to do it at the end of the block. */ 9614 if (dc->condexec_mask || dc->condexec_cond) 9615 { 9616 TCGv tmp = tcg_temp_new_i32(); 9617 tcg_gen_movi_i32(tmp, 0); 9618 store_cpu_field(tmp, condexec_bits); 9619 } 9620 do { 9621#ifdef CONFIG_USER_ONLY 9622 /* Intercept jump to the magic kernel page. */ 9623 if (dc->pc >= 0xffff0000) { 9624 /* We always get here via a jump, so know we are not in a 9625 conditional execution block. */ 9626 gen_exception(EXCP_KERNEL_TRAP); 9627 dc->is_jmp = DISAS_UPDATE; 9628 break; 9629 } 9630#else 9631 if (dc->pc >= 0xfffffff0 && IS_M(env)) { 9632 /* We always get here via a jump, so know we are not in a 9633 conditional execution block. */ 9634 gen_exception(EXCP_EXCEPTION_EXIT); 9635 dc->is_jmp = DISAS_UPDATE; 9636 break; 9637 } 9638#endif 9639 9640 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { 9641 QTAILQ_FOREACH(bp, &env->breakpoints, entry) { 9642 if (bp->pc == dc->pc) { 9643 gen_exception_insn(dc, 0, EXCP_DEBUG); 9644 /* Advance PC so that clearing the breakpoint will 9645 invalidate this TB. */ 9646 dc->pc += 2; 9647 goto done_generating; 9648 break; 9649 } 9650 } 9651 } 9652 9653 if (ANDROID_CHECK_CODEGEN_PC(search_pc)) { 9654 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 9655 if (lj < j) { 9656 lj++; 9657 while (lj < j) 9658 tcg_ctx.gen_opc_instr_start[lj++] = 0; 9659 } 9660 tcg_ctx.gen_opc_pc[lj] = dc->pc; 9661 tcg_ctx.gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1); 9662 tcg_ctx.gen_opc_instr_start[lj] = 1; 9663 tcg_ctx.gen_opc_icount[lj] = num_insns; 9664 } 9665 9666 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) 9667 gen_io_start(); 9668 9669 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { 9670 tcg_gen_debug_insn_start(dc->pc); 9671 } 9672 9673 if (dc->thumb) { 9674 disas_thumb_insn(env, dc); 9675 if (dc->condexec_mask) { 9676 dc->condexec_cond = (dc->condexec_cond & 0xe) 9677 | ((dc->condexec_mask >> 4) & 1); 9678 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f; 9679 if (dc->condexec_mask == 0) { 9680 dc->condexec_cond = 0; 9681 } 9682 } 9683 } else { 9684 disas_arm_insn(env, dc); 9685 } 9686 9687 if (dc->condjmp && !dc->is_jmp) { 9688 gen_set_label(dc->condlabel); 9689 dc->condjmp = 0; 9690 } 9691 9692 if (tcg_check_temp_count()) { 9693 fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc); 9694 } 9695 9696 /* Translation stops when a conditional branch is encountered. 9697 * Otherwise the subsequent code could get translated several times. 9698 * Also stop translation when a page boundary is reached. This 9699 * ensures prefetch aborts occur at the right place. */ 9700 num_insns ++; 9701 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && 9702 !env->singlestep_enabled && 9703 !singlestep && 9704 dc->pc < next_page_start && 9705 num_insns < max_insns); 9706 9707 if (tb->cflags & CF_LAST_IO) { 9708 if (dc->condjmp) { 9709 /* FIXME: This can theoretically happen with self-modifying 9710 code. */ 9711 cpu_abort(env, "IO on conditional branch instruction"); 9712 } 9713 gen_io_end(); 9714 } 9715 9716 /* At this stage dc->condjmp will only be set when the skipped 9717 instruction was a conditional branch or trap, and the PC has 9718 already been written. */ 9719 if (unlikely(env->singlestep_enabled)) { 9720 /* Make sure the pc is updated, and raise a debug exception. */ 9721 if (dc->condjmp) { 9722 gen_set_condexec(dc); 9723 if (dc->is_jmp == DISAS_SWI) { 9724 gen_exception(EXCP_SWI); 9725 } else if (dc->is_jmp == DISAS_SMC) { 9726 gen_exception(EXCP_SMC); 9727 } else { 9728 gen_exception(EXCP_DEBUG); 9729 } 9730 gen_set_label(dc->condlabel); 9731 } 9732 if (dc->condjmp || !dc->is_jmp) { 9733 gen_set_pc_im(dc->pc); 9734 dc->condjmp = 0; 9735 } 9736 gen_set_condexec(dc); 9737 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) { 9738 gen_exception(EXCP_SWI); 9739 } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) { 9740 gen_exception(EXCP_SMC); 9741 } else { 9742 /* FIXME: Single stepping a WFI insn will not halt 9743 the CPU. */ 9744 gen_exception(EXCP_DEBUG); 9745 } 9746 } else { 9747 /* While branches must always occur at the end of an IT block, 9748 there are a few other things that can cause us to terminate 9749 the TB in the middel of an IT block: 9750 - Exception generating instructions (bkpt, swi, undefined). 9751 - Page boundaries. 9752 - Hardware watchpoints. 9753 Hardware breakpoints have already been handled and skip this code. 9754 */ 9755 gen_set_condexec(dc); 9756 switch(dc->is_jmp) { 9757 case DISAS_NEXT: 9758 gen_goto_tb(dc, 1, dc->pc); 9759 break; 9760 default: 9761 case DISAS_JUMP: 9762 case DISAS_UPDATE: 9763 /* indicate that the hash table must be used to find the next TB */ 9764 tcg_gen_exit_tb(0); 9765 break; 9766 case DISAS_TB_JUMP: 9767 /* nothing more to generate */ 9768 break; 9769 case DISAS_WFI: 9770 gen_helper_wfi(); 9771 break; 9772 case DISAS_SWI: 9773 gen_exception(EXCP_SWI); 9774 break; 9775 case DISAS_SMC: 9776 gen_exception(EXCP_SMC); 9777 break; 9778 } 9779 if (dc->condjmp) { 9780 gen_set_label(dc->condlabel); 9781 gen_set_condexec(dc); 9782 gen_goto_tb(dc, 1, dc->pc); 9783 dc->condjmp = 0; 9784 } 9785 } 9786 9787done_generating: 9788 gen_icount_end(tb, num_insns); 9789 *tcg_ctx.gen_opc_ptr = INDEX_op_end; 9790 9791#ifdef DEBUG_DISAS 9792 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { 9793 qemu_log("----------------\n"); 9794 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 9795 log_target_disas(env, pc_start, dc->pc - pc_start, dc->thumb); 9796 qemu_log("\n"); 9797 } 9798#endif 9799 if (search_pc) { 9800 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 9801 lj++; 9802 while (lj <= j) 9803 tcg_ctx.gen_opc_instr_start[lj++] = 0; 9804 } else { 9805 ANDROID_END_CODEGEN(); 9806 tb->size = dc->pc - pc_start; 9807 tb->icount = num_insns; 9808 } 9809} 9810 9811void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) 9812{ 9813 gen_intermediate_code_internal(env, tb, 0); 9814} 9815 9816void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb) 9817{ 9818 gen_intermediate_code_internal(env, tb, 1); 9819} 9820 9821static const char *cpu_mode_names[16] = { 9822 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt", 9823 "???", "???", "???", "und", "???", "???", "???", "sys" 9824}; 9825 9826void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf, 9827 int flags) 9828{ 9829 int i; 9830#if 0 9831 union { 9832 uint32_t i; 9833 float s; 9834 } s0, s1; 9835 CPU_DoubleU d; 9836 /* ??? This assumes float64 and double have the same layout. 9837 Oh well, it's only debug dumps. */ 9838 union { 9839 float64 f64; 9840 double d; 9841 } d0; 9842#endif 9843 uint32_t psr; 9844 9845 for(i=0;i<16;i++) { 9846 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]); 9847 if ((i % 4) == 3) 9848 cpu_fprintf(f, "\n"); 9849 else 9850 cpu_fprintf(f, " "); 9851 } 9852 psr = cpsr_read(env); 9853 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n", 9854 psr, 9855 psr & (1 << 31) ? 'N' : '-', 9856 psr & (1 << 30) ? 'Z' : '-', 9857 psr & (1 << 29) ? 'C' : '-', 9858 psr & (1 << 28) ? 'V' : '-', 9859 psr & CPSR_T ? 'T' : 'A', 9860 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26); 9861 9862#if 0 9863 for (i = 0; i < 16; i++) { 9864 d.d = env->vfp.regs[i]; 9865 s0.i = d.l.lower; 9866 s1.i = d.l.upper; 9867 d0.f64 = d.d; 9868 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n", 9869 i * 2, (int)s0.i, s0.s, 9870 i * 2 + 1, (int)s1.i, s1.s, 9871 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower, 9872 d0.d); 9873 } 9874 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); 9875#endif 9876} 9877 9878void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos) 9879{ 9880 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos]; 9881 env->condexec_bits = tcg_ctx.gen_opc_condexec_bits[pc_pos]; 9882} 9883