mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 09:15:11 +00:00 
			
		
		
		
	target/arm: Implement v8.1M NOCP handling
From v8.1M, disabled-coprocessor handling changes slightly: * coprocessors 8, 9, 14 and 15 are also governed by the cp10 enable bit, like cp11 * an extra range of instruction patterns is considered to be inside the coprocessor space We previously marked these up with TODO comments; implement the correct behaviour. Unfortunately there is no ID register field which indicates this behaviour. We could in theory test an unrelated ID register which indicates guaranteed-to-be-in-v8.1M behaviour like ID_ISAR0.CmpBranch >= 3 (low-overhead-loops), but it seems better to simply define a new ARM_FEATURE_V8_1M feature flag and use it for this and other new-in-v8.1M behaviour that isn't identifiable from the ID registers. Backports commit 5d2555a1fe7370feeb1efbbf276a653040910017
This commit is contained in:
		
							parent
							
								
									51093daf5f
								
							
						
					
					
						commit
						2dae268fcb
					
				| 
						 | 
					@ -1854,6 +1854,7 @@ enum arm_features {
 | 
				
			||||||
    ARM_FEATURE_VBAR, /* has cp15 VBAR */
 | 
					    ARM_FEATURE_VBAR, /* has cp15 VBAR */
 | 
				
			||||||
    ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
 | 
					    ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
 | 
				
			||||||
    ARM_FEATURE_M_MAIN, /* M profile Main Extension */
 | 
					    ARM_FEATURE_M_MAIN, /* M profile Main Extension */
 | 
				
			||||||
 | 
					    ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int arm_feature(CPUARMState *env, int feature)
 | 
					static inline int arm_feature(CPUARMState *env, int feature)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,14 +29,16 @@
 | 
				
			||||||
# If the coprocessor is not present or disabled then we will generate
 | 
					# If the coprocessor is not present or disabled then we will generate
 | 
				
			||||||
# the NOCP exception; otherwise we let the insn through to the main decode.
 | 
					# the NOCP exception; otherwise we let the insn through to the main decode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&nocp cp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  # Special cases which do not take an early NOCP: VLLDM and VLSTM
 | 
					  # Special cases which do not take an early NOCP: VLLDM and VLSTM
 | 
				
			||||||
  VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 0000 0000
 | 
					  VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 0000 0000
 | 
				
			||||||
  # TODO: VSCCLRM (new in v8.1M) is similar:
 | 
					  # TODO: VSCCLRM (new in v8.1M) is similar:
 | 
				
			||||||
  #VSCCLRM      1110 1100 1-01 1111 ---- 1011 ---- ---0
 | 
					  #VSCCLRM      1110 1100 1-01 1111 ---- 1011 ---- ---0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  NOCP         111- 1110 ---- ---- ---- cp:4 ---- ----
 | 
					  NOCP         111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
 | 
				
			||||||
  NOCP         111- 110- ---- ---- ---- cp:4 ---- ----
 | 
					  NOCP         111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
 | 
				
			||||||
  # TODO: From v8.1M onwards we will also want this range to NOCP
 | 
					  # From v8.1M onwards this range will also NOCP:
 | 
				
			||||||
  #NOCP_8_1     111- 1111 ---- ---- ---- ---- ---- ---- cp=10
 | 
					  NOCP_8_1     111- 1111 ---- ---- ---- ---- ---- ---- &nocp cp=10
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3534,7 +3534,11 @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
 | 
				
			||||||
    if (a->cp == 11) {
 | 
					    if (a->cp == 11) {
 | 
				
			||||||
        a->cp = 10;
 | 
					        a->cp = 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* TODO: in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
 | 
					    if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
 | 
				
			||||||
 | 
					        (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
 | 
				
			||||||
 | 
					        /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
 | 
				
			||||||
 | 
					        a->cp = 10;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (a->cp != 10) {
 | 
					    if (a->cp != 10) {
 | 
				
			||||||
        gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
 | 
					        gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
 | 
				
			||||||
| 
						 | 
					@ -3551,6 +3555,15 @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* This range needs a coprocessor check for v8.1M and later only */
 | 
				
			||||||
 | 
					    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return trans_NOCP(s, a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool trans_VINS(DisasContext *s, arg_VINS *a)
 | 
					static bool trans_VINS(DisasContext *s, arg_VINS *a)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
					    TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue