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;
 | 
					    target_long ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_log("%s: palcode %02x\n", __func__, palcode);
 | 
					 | 
				
			||||||
    switch (palcode) {
 | 
					    switch (palcode) {
 | 
				
			||||||
    case 0x83:
 | 
					    case 0x83:
 | 
				
			||||||
        /* CALLSYS */
 | 
					        /* CALLSYS */
 | 
				
			||||||
@ -1078,14 +1077,14 @@ void call_pal (CPUState *env, int palcode)
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 0x9E:
 | 
					    case 0x9E:
 | 
				
			||||||
        /* RDUNIQUE */
 | 
					        /* RDUNIQUE */
 | 
				
			||||||
        env->ir[IR_V0] = env->unique;
 | 
					 | 
				
			||||||
        qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
 | 
					        qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
 | 
				
			||||||
        break;
 | 
					        /* Handled in the translator for usermode.  */
 | 
				
			||||||
 | 
					        abort();
 | 
				
			||||||
    case 0x9F:
 | 
					    case 0x9F:
 | 
				
			||||||
        /* WRUNIQUE */
 | 
					        /* WRUNIQUE */
 | 
				
			||||||
        env->unique = env->ir[IR_A0];
 | 
					        qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
 | 
				
			||||||
        qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
 | 
					        /* Handled in the translator for usermode.  */
 | 
				
			||||||
        break;
 | 
					        abort();
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        qemu_log("%s: unhandled palcode %02x\n",
 | 
					        qemu_log("%s: unhandled palcode %02x\n",
 | 
				
			||||||
                    __func__, palcode);
 | 
					                    __func__, palcode);
 | 
				
			||||||
 | 
				
			|||||||
@ -57,6 +57,9 @@ static TCGv cpu_ir[31];
 | 
				
			|||||||
static TCGv cpu_fir[31];
 | 
					static TCGv cpu_fir[31];
 | 
				
			||||||
static TCGv cpu_pc;
 | 
					static TCGv cpu_pc;
 | 
				
			||||||
static TCGv cpu_lock;
 | 
					static TCGv cpu_lock;
 | 
				
			||||||
 | 
					#ifdef CONFIG_USER_ONLY
 | 
				
			||||||
 | 
					static TCGv cpu_uniq;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* register names */
 | 
					/* register names */
 | 
				
			||||||
static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
 | 
					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,
 | 
					    cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
 | 
				
			||||||
                                      offsetof(CPUState, lock), "lock");
 | 
					                                      offsetof(CPUState, lock), "lock");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_USER_ONLY
 | 
				
			||||||
 | 
					    cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
 | 
				
			||||||
 | 
					                                      offsetof(CPUState, unique), "uniq");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* register helpers */
 | 
					    /* register helpers */
 | 
				
			||||||
#define GEN_HELPER 2
 | 
					#define GEN_HELPER 2
 | 
				
			||||||
#include "helper.h"
 | 
					#include "helper.h"
 | 
				
			||||||
@ -751,23 +759,34 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
 | 
				
			|||||||
    switch (opc) {
 | 
					    switch (opc) {
 | 
				
			||||||
    case 0x00:
 | 
					    case 0x00:
 | 
				
			||||||
        /* CALL_PAL */
 | 
					        /* 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) {
 | 
					        if (palcode >= 0x80 && palcode < 0xC0) {
 | 
				
			||||||
            /* Unprivileged PAL call */
 | 
					            /* Unprivileged PAL call */
 | 
				
			||||||
            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
 | 
					            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
 | 
				
			||||||
#if !defined (CONFIG_USER_ONLY)
 | 
					            ret = 3;
 | 
				
			||||||
        } else if (palcode < 0x40) {
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
 | 
					        if (palcode < 0x40) {
 | 
				
			||||||
            /* Privileged PAL code */
 | 
					            /* Privileged PAL code */
 | 
				
			||||||
            if (ctx->mem_idx & 1)
 | 
					            if (ctx->mem_idx & 1)
 | 
				
			||||||
                goto invalid_opc;
 | 
					                goto invalid_opc;
 | 
				
			||||||
            else
 | 
					            gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
 | 
				
			||||||
                gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
 | 
					            ret = 3;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            /* Invalid PAL call */
 | 
					 | 
				
			||||||
            goto invalid_opc;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ret = 3;
 | 
					#endif
 | 
				
			||||||
        break;
 | 
					        /* Invalid PAL call */
 | 
				
			||||||
 | 
					        goto invalid_opc;
 | 
				
			||||||
    case 0x01:
 | 
					    case 0x01:
 | 
				
			||||||
        /* OPC01 */
 | 
					        /* OPC01 */
 | 
				
			||||||
        goto invalid_opc;
 | 
					        goto invalid_opc;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user