mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-30 19:15:42 +00:00 
			
		
		
		
	target/s390x: Implement SRSTU
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
		
							parent
							
								
									7591db780d
								
							
						
					
					
						commit
						be7acb5839
					
				| @ -13,6 +13,7 @@ DEF_HELPER_FLAGS_3(divu32, TCG_CALL_NO_WG, i64, env, i64, i64) | ||||
| DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64) | ||||
| DEF_HELPER_FLAGS_4(divu64, TCG_CALL_NO_WG, i64, env, i64, i64, i64) | ||||
| DEF_HELPER_3(srst, void, env, i32, i32) | ||||
| DEF_HELPER_3(srstu, void, env, i32, i32) | ||||
| DEF_HELPER_4(clst, i64, env, i64, i64, i64) | ||||
| DEF_HELPER_FLAGS_4(mvn, TCG_CALL_NO_WG, void, env, i32, i64, i64) | ||||
| DEF_HELPER_FLAGS_4(mvo, TCG_CALL_NO_WG, void, env, i32, i64, i64) | ||||
|  | ||||
| @ -737,6 +737,8 @@ | ||||
| 
 | ||||
| /* SEARCH STRING */ | ||||
|     C(0xb25e, SRST,    RRE,   Z,   0, 0, 0, 0, srst, 0) | ||||
| /* SEARCH STRING UNICODE */ | ||||
|     C(0xb9be, SRSTU,   RRE,   ETF3, 0, 0, 0, 0, srstu, 0) | ||||
| 
 | ||||
| /* SET ACCESS */ | ||||
|     C(0xb24e, SAR,     RRE,   Z,   0, r2_o, 0, 0, sar, 0) | ||||
|  | ||||
| @ -576,6 +576,47 @@ void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2) | ||||
|     set_address(env, r2, str + len); | ||||
| } | ||||
| 
 | ||||
| void HELPER(srstu)(CPUS390XState *env, uint32_t r1, uint32_t r2) | ||||
| { | ||||
|     uintptr_t ra = GETPC(); | ||||
|     uint32_t len; | ||||
|     uint16_t v, c = env->regs[0]; | ||||
|     uint64_t end, str, adj_end; | ||||
| 
 | ||||
|     /* Bits 32-47 of R0 must be zero.  */ | ||||
|     if (env->regs[0] & 0xffff0000u) { | ||||
|         cpu_restore_state(ENV_GET_CPU(env), ra); | ||||
|         program_interrupt(env, PGM_SPECIFICATION, 6); | ||||
|     } | ||||
| 
 | ||||
|     str = get_address(env, r2); | ||||
|     end = get_address(env, r1); | ||||
| 
 | ||||
|     /* If the LSB of the two addresses differ, use one extra byte.  */ | ||||
|     adj_end = end + ((str ^ end) & 1); | ||||
| 
 | ||||
|     /* Lest we fail to service interrupts in a timely manner, limit the
 | ||||
|        amount of work we're willing to do.  For now, let's cap at 8k.  */ | ||||
|     for (len = 0; len < 0x2000; len += 2) { | ||||
|         if (str + len == adj_end) { | ||||
|             /* End of input found.  */ | ||||
|             env->cc_op = 2; | ||||
|             return; | ||||
|         } | ||||
|         v = cpu_lduw_data_ra(env, str + len, ra); | ||||
|         if (v == c) { | ||||
|             /* Character found.  Set R1 to the location; R2 is unmodified.  */ | ||||
|             env->cc_op = 1; | ||||
|             set_address(env, r1, str + len); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /* CPU-determined bytes processed.  Advance R2 to next byte to process.  */ | ||||
|     env->cc_op = 3; | ||||
|     set_address(env, r2, str + len); | ||||
| } | ||||
| 
 | ||||
| /* unsigned string compare (c is string terminator) */ | ||||
| uint64_t HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2) | ||||
| { | ||||
|  | ||||
| @ -4298,6 +4298,19 @@ static ExitStatus op_srst(DisasContext *s, DisasOps *o) | ||||
|     return NO_EXIT; | ||||
| } | ||||
| 
 | ||||
| static ExitStatus op_srstu(DisasContext *s, DisasOps *o) | ||||
| { | ||||
|     TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1)); | ||||
|     TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2)); | ||||
| 
 | ||||
|     gen_helper_srstu(cpu_env, r1, r2); | ||||
| 
 | ||||
|     tcg_temp_free_i32(r1); | ||||
|     tcg_temp_free_i32(r2); | ||||
|     set_cc_static(s); | ||||
|     return NO_EXIT; | ||||
| } | ||||
| 
 | ||||
| static ExitStatus op_sub(DisasContext *s, DisasOps *o) | ||||
| { | ||||
|     tcg_gen_sub_i64(o->out, o->in1, o->in2); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Richard Henderson
						Richard Henderson