target-alpha: Implement RD/WRUNIQUE in the translator
When emulating user-mode only, there's no reason to exit the translation block to effect a call_pal. We can generate a move to/from the unique slot directly. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
		
							parent
							
								
									73651cce62
								
							
						
					
					
						commit
						ab471ade02
					
				@ -1060,7 +1060,6 @@ void call_pal (CPUState *env, int palcode)
 | 
			
		||||
{
 | 
			
		||||
    target_long ret;
 | 
			
		||||
 | 
			
		||||
    qemu_log("%s: palcode %02x\n", __func__, palcode);
 | 
			
		||||
    switch (palcode) {
 | 
			
		||||
    case 0x83:
 | 
			
		||||
        /* CALLSYS */
 | 
			
		||||
@ -1078,14 +1077,14 @@ void call_pal (CPUState *env, int palcode)
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x9E:
 | 
			
		||||
        /* RDUNIQUE */
 | 
			
		||||
        env->ir[IR_V0] = env->unique;
 | 
			
		||||
        qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
 | 
			
		||||
        break;
 | 
			
		||||
        /* Handled in the translator for usermode.  */
 | 
			
		||||
        abort();
 | 
			
		||||
    case 0x9F:
 | 
			
		||||
        /* WRUNIQUE */
 | 
			
		||||
        env->unique = env->ir[IR_A0];
 | 
			
		||||
        qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
 | 
			
		||||
        break;
 | 
			
		||||
        qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
 | 
			
		||||
        /* Handled in the translator for usermode.  */
 | 
			
		||||
        abort();
 | 
			
		||||
    default:
 | 
			
		||||
        qemu_log("%s: unhandled palcode %02x\n",
 | 
			
		||||
                    __func__, palcode);
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,9 @@ static TCGv cpu_ir[31];
 | 
			
		||||
static TCGv cpu_fir[31];
 | 
			
		||||
static TCGv cpu_pc;
 | 
			
		||||
static TCGv cpu_lock;
 | 
			
		||||
#ifdef CONFIG_USER_ONLY
 | 
			
		||||
static TCGv cpu_uniq;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* register names */
 | 
			
		||||
static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
 | 
			
		||||
@ -93,6 +96,11 @@ static void alpha_translate_init(void)
 | 
			
		||||
    cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
 | 
			
		||||
                                      offsetof(CPUState, lock), "lock");
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_USER_ONLY
 | 
			
		||||
    cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
 | 
			
		||||
                                      offsetof(CPUState, unique), "uniq");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* register helpers */
 | 
			
		||||
#define GEN_HELPER 2
 | 
			
		||||
#include "helper.h"
 | 
			
		||||
@ -751,23 +759,34 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
 | 
			
		||||
    switch (opc) {
 | 
			
		||||
    case 0x00:
 | 
			
		||||
        /* CALL_PAL */
 | 
			
		||||
#ifdef CONFIG_USER_ONLY
 | 
			
		||||
        if (palcode == 0x9E) {
 | 
			
		||||
            /* RDUNIQUE */
 | 
			
		||||
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq);
 | 
			
		||||
            break;
 | 
			
		||||
        } else if (palcode == 0x9F) {
 | 
			
		||||
            /* WRUNIQUE */
 | 
			
		||||
            tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        if (palcode >= 0x80 && palcode < 0xC0) {
 | 
			
		||||
            /* Unprivileged PAL call */
 | 
			
		||||
            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
 | 
			
		||||
#if !defined (CONFIG_USER_ONLY)
 | 
			
		||||
        } else if (palcode < 0x40) {
 | 
			
		||||
            ret = 3;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
        if (palcode < 0x40) {
 | 
			
		||||
            /* Privileged PAL code */
 | 
			
		||||
            if (ctx->mem_idx & 1)
 | 
			
		||||
                goto invalid_opc;
 | 
			
		||||
            else
 | 
			
		||||
            gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
 | 
			
		||||
            ret = 3;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        } else {
 | 
			
		||||
        /* Invalid PAL call */
 | 
			
		||||
        goto invalid_opc;
 | 
			
		||||
        }
 | 
			
		||||
        ret = 3;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x01:
 | 
			
		||||
        /* OPC01 */
 | 
			
		||||
        goto invalid_opc;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user