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