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