ppc: Handle unconditional (always/never) traps at translation time
We don't need to call a helper for trap always and trap never which are used by Linux under some circumstances. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> -- v2. Don't generate the helper call when trapping always Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
		
							parent
							
								
									3433b732a4
								
							
						
					
					
						commit
						22b56ee568
					
				| 
						 | 
					@ -3575,10 +3575,30 @@ static void gen_sc(DisasContext *ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***                                Trap                                   ***/
 | 
					/***                                Trap                                   ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Check for unconditional traps (always or never) */
 | 
				
			||||||
 | 
					static bool check_unconditional_trap(DisasContext *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Trap never */
 | 
				
			||||||
 | 
					    if (TO(ctx->opcode) == 0) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* Trap always */
 | 
				
			||||||
 | 
					    if (TO(ctx->opcode) == 31) {
 | 
				
			||||||
 | 
					        gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tw */
 | 
					/* tw */
 | 
				
			||||||
static void gen_tw(DisasContext *ctx)
 | 
					static void gen_tw(DisasContext *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
 | 
					    TCGv_i32 t0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (check_unconditional_trap(ctx)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    t0 = tcg_const_i32(TO(ctx->opcode));
 | 
				
			||||||
    gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 | 
					    gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 | 
				
			||||||
                  t0);
 | 
					                  t0);
 | 
				
			||||||
    tcg_temp_free_i32(t0);
 | 
					    tcg_temp_free_i32(t0);
 | 
				
			||||||
| 
						 | 
					@ -3587,8 +3607,14 @@ static void gen_tw(DisasContext *ctx)
 | 
				
			||||||
/* twi */
 | 
					/* twi */
 | 
				
			||||||
static void gen_twi(DisasContext *ctx)
 | 
					static void gen_twi(DisasContext *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
 | 
					    TCGv t0;
 | 
				
			||||||
    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
 | 
					    TCGv_i32 t1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (check_unconditional_trap(ctx)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    t0 = tcg_const_tl(SIMM(ctx->opcode));
 | 
				
			||||||
 | 
					    t1 = tcg_const_i32(TO(ctx->opcode));
 | 
				
			||||||
    gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
 | 
					    gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
 | 
				
			||||||
    tcg_temp_free(t0);
 | 
					    tcg_temp_free(t0);
 | 
				
			||||||
    tcg_temp_free_i32(t1);
 | 
					    tcg_temp_free_i32(t1);
 | 
				
			||||||
| 
						 | 
					@ -3598,7 +3624,12 @@ static void gen_twi(DisasContext *ctx)
 | 
				
			||||||
/* td */
 | 
					/* td */
 | 
				
			||||||
static void gen_td(DisasContext *ctx)
 | 
					static void gen_td(DisasContext *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
 | 
					    TCGv_i32 t0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (check_unconditional_trap(ctx)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    t0 = tcg_const_i32(TO(ctx->opcode));
 | 
				
			||||||
    gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 | 
					    gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 | 
				
			||||||
                  t0);
 | 
					                  t0);
 | 
				
			||||||
    tcg_temp_free_i32(t0);
 | 
					    tcg_temp_free_i32(t0);
 | 
				
			||||||
| 
						 | 
					@ -3607,8 +3638,14 @@ static void gen_td(DisasContext *ctx)
 | 
				
			||||||
/* tdi */
 | 
					/* tdi */
 | 
				
			||||||
static void gen_tdi(DisasContext *ctx)
 | 
					static void gen_tdi(DisasContext *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
 | 
					    TCGv t0;
 | 
				
			||||||
    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
 | 
					    TCGv_i32 t1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (check_unconditional_trap(ctx)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    t0 = tcg_const_tl(SIMM(ctx->opcode));
 | 
				
			||||||
 | 
					    t1 = tcg_const_i32(TO(ctx->opcode));
 | 
				
			||||||
    gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
 | 
					    gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
 | 
				
			||||||
    tcg_temp_free(t0);
 | 
					    tcg_temp_free(t0);
 | 
				
			||||||
    tcg_temp_free_i32(t1);
 | 
					    tcg_temp_free_i32(t1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue