#define VFP_SREG(insn, bigbit, smallbit) \
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
- if (arm_feature(env, ARM_FEATURE_VFP3)) { \
+ if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
reg = (((insn) >> (bigbit)) & 0x0f) \
| (((insn) >> ((smallbit) - 4)) & 0x10); \
} else { \
{
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
- if (!arm_feature(env, ARM_FEATURE_V8)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
return 1;
}
TCGv_i32 tmp;
TCGv_i32 tmp2;
- if (!arm_feature(env, ARM_FEATURE_VFP))
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
return 1;
+ }
/* FIXME: this access check should not take precedence over UNDEF
* for invalid encodings; we will generate incorrect syndrome information
if (insn & 0xf)
return 1;
if (insn & 0x00c00060
- && !arm_feature(env, ARM_FEATURE_NEON))
+ && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
return 1;
+ }
pass = (insn >> 21) & 1;
if (insn & (1 << 22)) {
VFP3 restricts all id registers to privileged
accesses. */
if (IS_USER(s)
- && arm_feature(env, ARM_FEATURE_VFP3))
+ && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
return 1;
+ }
tmp = load_cpu_field(vfp.xregs[rn]);
break;
case ARM_VFP_FPEXC:
case ARM_VFP_FPINST2:
/* Not present in VFP3. */
if (IS_USER(s)
- || arm_feature(env, ARM_FEATURE_VFP3))
+ || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
return 1;
+ }
tmp = load_cpu_field(vfp.xregs[rn]);
break;
case ARM_VFP_FPSCR:
}
break;
case ARM_VFP_MVFR2:
- if (!arm_feature(env, ARM_FEATURE_V8)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
return 1;
}
/* fall through */
case ARM_VFP_MVFR0:
case ARM_VFP_MVFR1:
if (IS_USER(s)
- || !arm_feature(env, ARM_FEATURE_MVFR))
+ || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
return 1;
+ }
tmp = load_cpu_field(vfp.xregs[rn]);
break;
default:
* UNPREDICTABLE if bit 8 is set prior to ARMv8
* (we choose to UNDEF)
*/
- if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
- !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
+ if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
+ !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
return 1;
}
if (!extract32(rn, 1, 1)) {
* correct : an input NaN should come out with its sign bit
* flipped if it is a negated-input.
*/
- if (!arm_feature(env, ARM_FEATURE_VFP4)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
return 1;
}
if (dp) {
}
break;
case 14: /* fconst */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
n = (insn << 12) & 0x80000000;
i = ((insn >> 12) & 0x70) | (insn & 0xf);
gen_vfp_sito(dp, 0);
break;
case 20: /* fshto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_shto(dp, 16 - rm, 0);
break;
case 21: /* fslto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_slto(dp, 32 - rm, 0);
break;
case 22: /* fuhto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_uhto(dp, 16 - rm, 0);
break;
case 23: /* fulto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_ulto(dp, 32 - rm, 0);
break;
case 24: /* ftoui */
gen_vfp_tosiz(dp, 0);
break;
case 28: /* ftosh */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_tosh(dp, 16 - rm, 0);
break;
case 29: /* ftosl */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_tosl(dp, 32 - rm, 0);
break;
case 30: /* ftouh */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_touh(dp, 16 - rm, 0);
break;
case 31: /* ftoul */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return 1;
+ }
gen_vfp_toul(dp, 32 - rm, 0);
break;
default: /* undefined */
/* Mask out undefined bits. */
mask &= ~CPSR_RESERVED;
- if (!arm_feature(env, ARM_FEATURE_V4T))
+ if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
mask &= ~CPSR_T;
- if (!arm_feature(env, ARM_FEATURE_V5))
+ }
+ if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
mask &= ~CPSR_Q; /* V5TE in reality*/
- if (!arm_feature(env, ARM_FEATURE_V6))
+ }
+ if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
mask &= ~(CPSR_E | CPSR_GE);
- if (!arm_feature(env, ARM_FEATURE_THUMB2))
+ }
+ if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
mask &= ~CPSR_IT;
+ }
/* Mask out execution state and reserved bits. */
if (!spsr) {
mask &= ~(CPSR_EXEC | CPSR_RESERVED);
return 1;
}
if (!u) { /* SHA-1 */
- if (!arm_feature(env, ARM_FEATURE_V8_SHA1)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
return 1;
}
tmp = tcg_const_i32(rd);
gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
tcg_temp_free_i32(tmp4);
} else { /* SHA-256 */
- if (!arm_feature(env, ARM_FEATURE_V8_SHA256) || size == 3) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
return 1;
}
tmp = tcg_const_i32(rd);
break;
case NEON_3R_FLOAT_MISC:
/* VMAXNM/VMINNM in ARMv8 */
- if (u && !arm_feature(env, ARM_FEATURE_V8)) {
+ if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
return 1;
}
break;
}
break;
case NEON_3R_VFM:
- if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
return 1;
}
break;
if (op == 14 && size == 2) {
TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
- if (!arm_feature(env, ARM_FEATURE_V8_PMULL)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
return 1;
}
tcg_rn = tcg_temp_new_i64();
}
break;
case NEON_2RM_VCVT_F16_F32:
- if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
q || (rm & 1)) {
return 1;
}
tcg_temp_free_i32(tmp);
break;
case NEON_2RM_VCVT_F32_F16:
- if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
q || (rd & 1)) {
return 1;
}
tcg_temp_free_i32(tmp3);
break;
case NEON_2RM_AESE: case NEON_2RM_AESMC:
- if (!arm_feature(env, ARM_FEATURE_V8_AES)
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
|| ((rm | rd) & 1)) {
return 1;
}
tcg_temp_free_i32(tmp3);
break;
case NEON_2RM_SHA1H:
- if (!arm_feature(env, ARM_FEATURE_V8_SHA1)
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
|| ((rm | rd) & 1)) {
return 1;
}
}
/* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
if (q) {
- if (!arm_feature(env, ARM_FEATURE_V8_SHA256)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
return 1;
}
- } else if (!arm_feature(env, ARM_FEATURE_V8_SHA1)) {
+ } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
return 1;
}
tmp = tcg_const_i32(rd);
cpnum = (insn >> 8) & 0xf;
/* First check for coprocessor space used for XScale/iwMMXt insns */
- if (arm_feature(env, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
+ if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
if (extract32(s->c15_cpar, cpnum, 1) == 0) {
return 1;
}
- if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
+ if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
return disas_iwmmxt_insn(env, s, insn);
- } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
+ } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
return disas_dsp_insn(env, s, insn);
}
return 1;
}
if (ri->accessfn ||
- (arm_feature(env, ARM_FEATURE_XSCALE) && cpnum < 14)) {
+ (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
/* Emit code to perform further access permissions checks at
* runtime; this may result in an exception.
* Note that on XScale all cp0..c13 registers do an access check
* in which case the syndrome information won't actually be
* guest visible.
*/
- assert(!arm_feature(env, ARM_FEATURE_V8));
+ assert(!arm_dc_feature(s, ARM_FEATURE_V8));
syndrome = syn_uncategorized();
break;
}
/* Unconditional instructions. */
if (((insn >> 25) & 7) == 1) {
/* NEON Data processing. */
- if (!arm_feature(env, ARM_FEATURE_NEON))
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
goto illegal_op;
+ }
if (disas_neon_data_insn(env, s, insn))
goto illegal_op;
}
if ((insn & 0x0f100000) == 0x04000000) {
/* NEON load/store. */
- if (!arm_feature(env, ARM_FEATURE_NEON))
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
goto illegal_op;
+ }
if (disas_neon_ls_insn(env, s, insn))
goto illegal_op;
((insn & 0x0f30f010) == 0x0710f000)) {
if ((insn & (1 << 22)) == 0) {
/* PLDW; v7MP */
- if (!arm_feature(env, ARM_FEATURE_V7MP)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
goto illegal_op;
}
}
}
if (((insn & 0x0f700000) == 0x04100000) ||
((insn & 0x0f700010) == 0x06100000)) {
- if (!arm_feature(env, ARM_FEATURE_V7MP)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
goto illegal_op;
}
return; /* v7MP: Unallocated memory hint: must NOP */
gen_bx_im(s, val);
return;
} else if ((insn & 0x0e000f00) == 0x0c000100) {
- if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
+ if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
/* iWMMXt register transfer. */
if (extract32(s->c15_cpar, 1, 1)) {
if (!disas_iwmmxt_insn(env, s, insn)) {
* op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
* Bits 8, 10 and 11 should be zero.
*/
- if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
+ if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
(c & 0xd) != 0) {
goto illegal_op;
}
case 1:
case 3:
/* SDIV, UDIV */
- if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
goto illegal_op;
}
if (((insn >> 5) & 7) || (rd != 15)) {
int conds;
int logic_cc;
- if (!(arm_feature(env, ARM_FEATURE_THUMB2)
- || arm_feature (env, ARM_FEATURE_M))) {
+ if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
+ || arm_dc_feature(s, ARM_FEATURE_M))) {
/* Thumb-1 cores may need to treat bl and blx as a pair of
16-bit instructions to get correct prefetch abort behavior. */
insn = insn_hw1;
uint32_t sz = op & 0x3;
uint32_t c = op & 0x8;
- if (!arm_feature(env, ARM_FEATURE_CRC)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
goto illegal_op;
}
tmp2 = load_reg(s, rm);
if ((op & 0x50) == 0x10) {
/* sdiv, udiv */
- if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
goto illegal_op;
}
if (op & 0x20)