target-tilegx: Support iret instruction and related special registers
EX_CONTEXT_0_0 is used for jumping address, and EX_CONTEXT_0_1 is for INTERRUPT_CRITICAL_SECTION, which should only be 0 or 1 in user mode, or it will cause target SIGILL (and the patch doesn't support system mode). Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
		
							parent
							
								
									77b3adc001
								
							
						
					
					
						commit
						fec7daab3d
					
				@ -53,6 +53,8 @@ enum {
 | 
				
			|||||||
    TILEGX_SPR_CMPEXCH = 0,
 | 
					    TILEGX_SPR_CMPEXCH = 0,
 | 
				
			||||||
    TILEGX_SPR_CRITICAL_SEC = 1,
 | 
					    TILEGX_SPR_CRITICAL_SEC = 1,
 | 
				
			||||||
    TILEGX_SPR_SIM_CONTROL = 2,
 | 
					    TILEGX_SPR_SIM_CONTROL = 2,
 | 
				
			||||||
 | 
					    TILEGX_SPR_EX_CONTEXT_0_0 = 3,
 | 
				
			||||||
 | 
					    TILEGX_SPR_EX_CONTEXT_0_1 = 4,
 | 
				
			||||||
    TILEGX_SPR_COUNT
 | 
					    TILEGX_SPR_COUNT
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,6 +22,7 @@
 | 
				
			|||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "exec/helper-proto.h"
 | 
					#include "exec/helper-proto.h"
 | 
				
			||||||
#include <zlib.h> /* For crc32 */
 | 
					#include <zlib.h> /* For crc32 */
 | 
				
			||||||
 | 
					#include "syscall_defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_exception(CPUTLGState *env, uint32_t excp)
 | 
					void helper_exception(CPUTLGState *env, uint32_t excp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -31,6 +32,27 @@ void helper_exception(CPUTLGState *env, uint32_t excp)
 | 
				
			|||||||
    cpu_loop_exit(cs);
 | 
					    cpu_loop_exit(cs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void helper_ext01_ics(CPUTLGState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint64_t val = env->spregs[TILEGX_SPR_EX_CONTEXT_0_1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (val) {
 | 
				
			||||||
 | 
					    case 0:
 | 
				
			||||||
 | 
					    case 1:
 | 
				
			||||||
 | 
					        env->spregs[TILEGX_SPR_CRITICAL_SEC] = val;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					#if defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					        env->signo = TARGET_SIGILL;
 | 
				
			||||||
 | 
					        env->sigcode = TARGET_ILL_ILLOPC;
 | 
				
			||||||
 | 
					        helper_exception(env, TILEGX_EXCP_SIGNAL);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint64_t helper_cntlz(uint64_t arg)
 | 
					uint64_t helper_cntlz(uint64_t arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return clz64(arg);
 | 
					    return clz64(arg);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
DEF_HELPER_2(exception, noreturn, env, i32)
 | 
					DEF_HELPER_2(exception, noreturn, env, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_1(ext01_ics, void, env)
 | 
				
			||||||
DEF_HELPER_FLAGS_1(cntlz, TCG_CALL_NO_RWG_SE, i64, i64)
 | 
					DEF_HELPER_FLAGS_1(cntlz, TCG_CALL_NO_RWG_SE, i64, i64)
 | 
				
			||||||
DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64)
 | 
					DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64)
 | 
				
			||||||
DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64)
 | 
					DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64)
 | 
				
			||||||
 | 
				
			|||||||
@ -529,6 +529,15 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
 | 
				
			|||||||
        /* ??? This should yield, especially in system mode.  */
 | 
					        /* ??? This should yield, especially in system mode.  */
 | 
				
			||||||
        mnemonic = "nap";
 | 
					        mnemonic = "nap";
 | 
				
			||||||
        goto done0;
 | 
					        goto done0;
 | 
				
			||||||
 | 
					    case OE_RR_X1(IRET):
 | 
				
			||||||
 | 
					        gen_helper_ext01_ics(cpu_env);
 | 
				
			||||||
 | 
					        dc->jmp.cond = TCG_COND_ALWAYS;
 | 
				
			||||||
 | 
					        dc->jmp.dest = tcg_temp_new();
 | 
				
			||||||
 | 
					        tcg_gen_ld_tl(dc->jmp.dest, cpu_env,
 | 
				
			||||||
 | 
					                      offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_0]));
 | 
				
			||||||
 | 
					        tcg_gen_andi_tl(dc->jmp.dest, dc->jmp.dest, ~7);
 | 
				
			||||||
 | 
					        mnemonic = "iret";
 | 
				
			||||||
 | 
					        goto done0;
 | 
				
			||||||
    case OE_RR_X1(SWINT0):
 | 
					    case OE_RR_X1(SWINT0):
 | 
				
			||||||
    case OE_RR_X1(SWINT2):
 | 
					    case OE_RR_X1(SWINT2):
 | 
				
			||||||
    case OE_RR_X1(SWINT3):
 | 
					    case OE_RR_X1(SWINT3):
 | 
				
			||||||
@ -606,7 +615,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case OE_RR_X0(FSINGLE_PACK1):
 | 
					    case OE_RR_X0(FSINGLE_PACK1):
 | 
				
			||||||
    case OE_RR_Y0(FSINGLE_PACK1):
 | 
					    case OE_RR_Y0(FSINGLE_PACK1):
 | 
				
			||||||
    case OE_RR_X1(IRET):
 | 
					 | 
				
			||||||
        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 | 
					        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
 | 
				
			||||||
    case OE_RR_X1(LD1S):
 | 
					    case OE_RR_X1(LD1S):
 | 
				
			||||||
        memop = MO_SB;
 | 
					        memop = MO_SB;
 | 
				
			||||||
@ -1947,6 +1955,10 @@ static const TileSPR *find_spr(unsigned spr)
 | 
				
			|||||||
      offsetof(CPUTLGState, spregs[TILEGX_SPR_CRITICAL_SEC]), 0, 0)
 | 
					      offsetof(CPUTLGState, spregs[TILEGX_SPR_CRITICAL_SEC]), 0, 0)
 | 
				
			||||||
    D(SIM_CONTROL,
 | 
					    D(SIM_CONTROL,
 | 
				
			||||||
      offsetof(CPUTLGState, spregs[TILEGX_SPR_SIM_CONTROL]), 0, 0)
 | 
					      offsetof(CPUTLGState, spregs[TILEGX_SPR_SIM_CONTROL]), 0, 0)
 | 
				
			||||||
 | 
					    D(EX_CONTEXT_0_0,
 | 
				
			||||||
 | 
					      offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_0]), 0, 0)
 | 
				
			||||||
 | 
					    D(EX_CONTEXT_0_1,
 | 
				
			||||||
 | 
					      offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_1]), 0, 0)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef D
 | 
					#undef D
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user