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