target/arm: Convert division from feature bits to isar0 tests
Both arm and thumb2 division are controlled by the same ISAR field, which takes care of the arm implies thumb case. Having M imply thumb2 division was wrong for cortex-m0, which is v6m and does not have thumb2 at all, much less thumb2 division. Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20181016223115.24100-5-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									962fcbf2ef
								
							
						
					
					
						commit
						7e0cf8b47f
					
				@ -471,8 +471,8 @@ static uint32_t get_elf_hwcap(void)
 | 
				
			|||||||
    GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
 | 
					    GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
 | 
				
			||||||
    GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
 | 
					    GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
 | 
				
			||||||
    GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
 | 
					    GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
 | 
				
			||||||
    GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
 | 
					    GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
 | 
				
			||||||
    GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
 | 
					    GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
 | 
				
			||||||
    /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
 | 
					    /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
 | 
				
			||||||
     * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
 | 
					     * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
 | 
				
			||||||
     * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
 | 
					     * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
 | 
				
			||||||
 | 
				
			|||||||
@ -829,7 +829,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
				
			|||||||
         * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
 | 
					         * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
 | 
				
			||||||
         * Security Extensions is ARM_FEATURE_EL3.
 | 
					         * Security Extensions is ARM_FEATURE_EL3.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_ARM_DIV);
 | 
					        assert(cpu_isar_feature(arm_div, cpu));
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_LPAE);
 | 
					        set_feature(env, ARM_FEATURE_LPAE);
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_V7);
 | 
					        set_feature(env, ARM_FEATURE_V7);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -862,12 +862,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
				
			|||||||
    if (arm_feature(env, ARM_FEATURE_V5)) {
 | 
					    if (arm_feature(env, ARM_FEATURE_V5)) {
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_V4T);
 | 
					        set_feature(env, ARM_FEATURE_V4T);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (arm_feature(env, ARM_FEATURE_M)) {
 | 
					 | 
				
			||||||
        set_feature(env, ARM_FEATURE_THUMB_DIV);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
 | 
					 | 
				
			||||||
        set_feature(env, ARM_FEATURE_THUMB_DIV);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (arm_feature(env, ARM_FEATURE_VFP4)) {
 | 
					    if (arm_feature(env, ARM_FEATURE_VFP4)) {
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_VFP3);
 | 
					        set_feature(env, ARM_FEATURE_VFP3);
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_VFP_FP16);
 | 
					        set_feature(env, ARM_FEATURE_VFP_FP16);
 | 
				
			||||||
@ -1388,8 +1382,6 @@ static void cortex_r5_initfn(Object *obj)
 | 
				
			|||||||
    ARMCPU *cpu = ARM_CPU(obj);
 | 
					    ARMCPU *cpu = ARM_CPU(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_V7);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_V7);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV);
 | 
					 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
 | 
					 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_V7MP);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_V7MP);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_PMSA);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_PMSA);
 | 
				
			||||||
    cpu->midr = 0x411fc153; /* r1p3 */
 | 
					    cpu->midr = 0x411fc153; /* r1p3 */
 | 
				
			||||||
 | 
				
			|||||||
@ -1563,7 +1563,6 @@ enum arm_features {
 | 
				
			|||||||
    ARM_FEATURE_VFP3,
 | 
					    ARM_FEATURE_VFP3,
 | 
				
			||||||
    ARM_FEATURE_VFP_FP16,
 | 
					    ARM_FEATURE_VFP_FP16,
 | 
				
			||||||
    ARM_FEATURE_NEON,
 | 
					    ARM_FEATURE_NEON,
 | 
				
			||||||
    ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */
 | 
					 | 
				
			||||||
    ARM_FEATURE_M, /* Microcontroller profile.  */
 | 
					    ARM_FEATURE_M, /* Microcontroller profile.  */
 | 
				
			||||||
    ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling.  */
 | 
					    ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling.  */
 | 
				
			||||||
    ARM_FEATURE_THUMB2EE,
 | 
					    ARM_FEATURE_THUMB2EE,
 | 
				
			||||||
@ -1573,7 +1572,6 @@ enum arm_features {
 | 
				
			|||||||
    ARM_FEATURE_V5,
 | 
					    ARM_FEATURE_V5,
 | 
				
			||||||
    ARM_FEATURE_STRONGARM,
 | 
					    ARM_FEATURE_STRONGARM,
 | 
				
			||||||
    ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
 | 
					    ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
 | 
				
			||||||
    ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
 | 
					 | 
				
			||||||
    ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
 | 
					    ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
 | 
				
			||||||
    ARM_FEATURE_GENERIC_TIMER,
 | 
					    ARM_FEATURE_GENERIC_TIMER,
 | 
				
			||||||
    ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
 | 
					    ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
 | 
				
			||||||
@ -3152,6 +3150,16 @@ extern const uint64_t pred_esz_masks[4];
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 32-bit feature tests via id registers.
 | 
					 * 32-bit feature tests via id registers.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool isar_feature_arm_div(const ARMISARegisters *id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
 | 
					static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
 | 
					    return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -9755,7 +9755,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
 | 
				
			|||||||
                    case 1:
 | 
					                    case 1:
 | 
				
			||||||
                    case 3:
 | 
					                    case 3:
 | 
				
			||||||
                        /* SDIV, UDIV */
 | 
					                        /* SDIV, UDIV */
 | 
				
			||||||
                        if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
 | 
					                        if (!dc_isar_feature(arm_div, s)) {
 | 
				
			||||||
                            goto illegal_op;
 | 
					                            goto illegal_op;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        if (((insn >> 5) & 7) || (rd != 15)) {
 | 
					                        if (((insn >> 5) & 7) || (rd != 15)) {
 | 
				
			||||||
@ -10963,7 +10963,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
 | 
				
			|||||||
            tmp2 = load_reg(s, rm);
 | 
					            tmp2 = load_reg(s, rm);
 | 
				
			||||||
            if ((op & 0x50) == 0x10) {
 | 
					            if ((op & 0x50) == 0x10) {
 | 
				
			||||||
                /* sdiv, udiv */
 | 
					                /* sdiv, udiv */
 | 
				
			||||||
                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
 | 
					                if (!dc_isar_feature(thumb_div, s)) {
 | 
				
			||||||
                    goto illegal_op;
 | 
					                    goto illegal_op;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (op & 0x20)
 | 
					                if (op & 0x20)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user