x86: Simplify thumb instructions and remove last function calls
This commit is contained in:
parent
8dda395c54
commit
e0708b1dcf
224
x86/x86_emit.h
224
x86/x86_emit.h
|
@ -614,6 +614,7 @@ typedef enum
|
||||||
#define generate_shift_reg(ireg, name, flags_op) \
|
#define generate_shift_reg(ireg, name, flags_op) \
|
||||||
generate_load_reg_pc(ireg, rm, 12); \
|
generate_load_reg_pc(ireg, rm, 12); \
|
||||||
generate_load_reg(a1, ((opcode >> 8) & 0x0F)); \
|
generate_load_reg(a1, ((opcode >> 8) & 0x0F)); \
|
||||||
|
generate_and_imm(a1, 0xFF); \
|
||||||
generate_##name##_##flags_op##_reg(ireg); \
|
generate_##name##_##flags_op##_reg(ireg); \
|
||||||
|
|
||||||
#ifdef TRACE_INSTRUCTIONS
|
#ifdef TRACE_INSTRUCTIONS
|
||||||
|
@ -812,59 +813,43 @@ typedef enum
|
||||||
generate_load_reg_pc(ireg, rm, 8); \
|
generate_load_reg_pc(ireg, rm, 8); \
|
||||||
if(shift != 0) \
|
if(shift != 0) \
|
||||||
{ \
|
{ \
|
||||||
generate_mov(a1, ireg); \
|
|
||||||
generate_shift_right(a1, (32 - shift)); \
|
|
||||||
generate_and_imm(a1, 1); \
|
|
||||||
generate_store_reg(a1, REG_C_FLAG); \
|
|
||||||
generate_shift_left(ireg, shift); \
|
generate_shift_left(ireg, shift); \
|
||||||
|
generate_update_flag(c, REG_C_FLAG); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define generate_shift_imm_lsr_flags(ireg) \
|
#define generate_shift_imm_lsr_flags(ireg) \
|
||||||
|
generate_load_reg_pc(ireg, rm, 8); \
|
||||||
if(shift != 0) \
|
if(shift != 0) \
|
||||||
{ \
|
{ \
|
||||||
generate_load_reg_pc(ireg, rm, 8); \
|
|
||||||
generate_mov(a1, ireg); \
|
|
||||||
generate_shift_right(a1, shift - 1); \
|
|
||||||
generate_and_imm(a1, 1); \
|
|
||||||
generate_store_reg(a1, REG_C_FLAG); \
|
|
||||||
generate_shift_right(ireg, shift); \
|
generate_shift_right(ireg, shift); \
|
||||||
|
generate_update_flag(c, REG_C_FLAG); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
generate_load_reg_pc(a1, rm, 8); \
|
generate_shift_right(ireg, 31); \
|
||||||
generate_shift_right(a1, 31); \
|
generate_store_reg(ireg, REG_C_FLAG); \
|
||||||
generate_store_reg(a1, REG_C_FLAG); \
|
|
||||||
generate_load_imm(ireg, 0); \
|
generate_load_imm(ireg, 0); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define generate_shift_imm_asr_flags(ireg) \
|
#define generate_shift_imm_asr_flags(ireg) \
|
||||||
|
generate_load_reg_pc(ireg, rm, 8); \
|
||||||
if(shift != 0) \
|
if(shift != 0) \
|
||||||
{ \
|
{ \
|
||||||
generate_load_reg_pc(ireg, rm, 8); \
|
|
||||||
generate_mov(a1, ireg); \
|
|
||||||
generate_shift_right_arithmetic(a1, shift - 1); \
|
|
||||||
generate_and_imm(a1, 1); \
|
|
||||||
generate_store_reg(a1, REG_C_FLAG); \
|
|
||||||
generate_shift_right_arithmetic(ireg, shift); \
|
generate_shift_right_arithmetic(ireg, shift); \
|
||||||
|
generate_update_flag(c, REG_C_FLAG); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
generate_load_reg_pc(a0, rm, 8); \
|
|
||||||
generate_shift_right_arithmetic(ireg, 31); \
|
generate_shift_right_arithmetic(ireg, 31); \
|
||||||
generate_mov(a1, ireg); \
|
generate_update_flag(nz, REG_C_FLAG); \
|
||||||
generate_and_imm(a1, 1); \
|
|
||||||
generate_store_reg(a1, REG_C_FLAG); \
|
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define generate_shift_imm_ror_flags(ireg) \
|
#define generate_shift_imm_ror_flags(ireg) \
|
||||||
generate_load_reg_pc(ireg, rm, 8); \
|
generate_load_reg_pc(ireg, rm, 8); \
|
||||||
if(shift != 0) \
|
if(shift != 0) \
|
||||||
{ \
|
{ \
|
||||||
generate_mov(a1, ireg); \
|
|
||||||
generate_shift_right(a1, shift - 1); \
|
|
||||||
generate_and_imm(a1, 1); \
|
|
||||||
generate_store_reg(a1, REG_C_FLAG); \
|
|
||||||
generate_rotate_right(ireg, shift); \
|
generate_rotate_right(ireg, shift); \
|
||||||
|
generate_update_flag(c, REG_C_FLAG) \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
|
@ -1790,149 +1775,49 @@ u32 function_cc execute_aligned_load32(u32 address)
|
||||||
// Operation types: lsl, lsr, asr, ror
|
// Operation types: lsl, lsr, asr, ror
|
||||||
// Affects N/Z/C flags
|
// Affects N/Z/C flags
|
||||||
|
|
||||||
u32 function_cc execute_lsl_reg_op(u32 value, u32 shift)
|
#define thumb_lsl_imm_op() \
|
||||||
{
|
if (imm) { \
|
||||||
if(shift != 0)
|
generate_shift_left(a0, imm); \
|
||||||
{
|
generate_update_flag(c, REG_C_FLAG) \
|
||||||
if(shift > 31)
|
} else { \
|
||||||
{
|
generate_or(a0, a0); \
|
||||||
if(shift == 32)
|
} \
|
||||||
reg[REG_C_FLAG] = value & 0x01;
|
generate_update_flag(z, REG_Z_FLAG) \
|
||||||
else
|
generate_update_flag(s, REG_N_FLAG) \
|
||||||
reg[REG_C_FLAG] = 0;
|
|
||||||
|
|
||||||
value = 0;
|
#define thumb_lsr_imm_op() \
|
||||||
}
|
if (imm) { \
|
||||||
else
|
generate_shift_right(a0, imm); \
|
||||||
{
|
generate_update_flag(c, REG_C_FLAG) \
|
||||||
reg[REG_C_FLAG] = (value >> (32 - shift)) & 0x01;
|
} else { \
|
||||||
value <<= shift;
|
generate_shift_right(a0, 31); \
|
||||||
}
|
generate_update_flag(nz, REG_C_FLAG) \
|
||||||
}
|
generate_xor(a0, a0); \
|
||||||
|
} \
|
||||||
|
generate_update_flag(z, REG_Z_FLAG) \
|
||||||
|
generate_update_flag(s, REG_N_FLAG) \
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
#define thumb_asr_imm_op() \
|
||||||
return value;
|
if (imm) { \
|
||||||
}
|
generate_shift_right_arithmetic(a0, imm); \
|
||||||
|
generate_update_flag(c, REG_C_FLAG) \
|
||||||
|
} else { \
|
||||||
|
generate_shift_right_arithmetic(a0, 31); \
|
||||||
|
generate_update_flag(s, REG_C_FLAG) \
|
||||||
|
} \
|
||||||
|
generate_update_flag(z, REG_Z_FLAG) \
|
||||||
|
generate_update_flag(s, REG_N_FLAG) \
|
||||||
|
|
||||||
u32 function_cc execute_lsr_reg_op(u32 value, u32 shift)
|
#define thumb_ror_imm_op() \
|
||||||
{
|
if (imm) { \
|
||||||
if(shift != 0)
|
generate_rotate_right(a0, imm); \
|
||||||
{
|
generate_update_flag(c, REG_C_FLAG) \
|
||||||
if(shift > 31)
|
} else { \
|
||||||
{
|
generate_rrx_flags(a0); \
|
||||||
if(shift == 32)
|
} \
|
||||||
reg[REG_C_FLAG] = (value >> 31) & 0x01;
|
generate_update_flag(z, REG_Z_FLAG) \
|
||||||
else
|
generate_update_flag(s, REG_N_FLAG) \
|
||||||
reg[REG_C_FLAG] = 0;
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (shift - 1)) & 0x01;
|
|
||||||
value >>= shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 function_cc execute_asr_reg_op(u32 value, u32 shift)
|
|
||||||
{
|
|
||||||
if(shift != 0)
|
|
||||||
{
|
|
||||||
if(shift > 31)
|
|
||||||
{
|
|
||||||
value = (s32)value >> 31;
|
|
||||||
reg[REG_C_FLAG] = value & 0x01;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (shift - 1)) & 0x01;
|
|
||||||
value = (s32)value >> shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 function_cc execute_ror_reg_op(u32 value, u32 shift)
|
|
||||||
{
|
|
||||||
if(shift != 0)
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (shift - 1)) & 0x01;
|
|
||||||
ror(value, value, shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 function_cc execute_lsl_imm_op(u32 value, u32 shift)
|
|
||||||
{
|
|
||||||
if(shift != 0)
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (32 - shift)) & 0x01;
|
|
||||||
value <<= shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 function_cc execute_lsr_imm_op(u32 value, u32 shift)
|
|
||||||
{
|
|
||||||
if(shift != 0)
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (shift - 1)) & 0x01;
|
|
||||||
value >>= shift;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = value >> 31;
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 function_cc execute_asr_imm_op(u32 value, u32 shift)
|
|
||||||
{
|
|
||||||
if(shift != 0)
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (shift - 1)) & 0x01;
|
|
||||||
value = (s32)value >> shift;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = (s32)value >> 31;
|
|
||||||
reg[REG_C_FLAG] = value & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 function_cc execute_ror_imm_op(u32 value, u32 shift)
|
|
||||||
{
|
|
||||||
if(shift != 0)
|
|
||||||
{
|
|
||||||
reg[REG_C_FLAG] = (value >> (shift - 1)) & 0x01;
|
|
||||||
ror(value, value, shift);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u32 c_flag = reg[REG_C_FLAG];
|
|
||||||
reg[REG_C_FLAG] = value & 0x01;
|
|
||||||
value = (value >> 1) | (c_flag << 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate_flags_logic(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define generate_shift_load_operands_reg() \
|
#define generate_shift_load_operands_reg() \
|
||||||
generate_load_reg(a0, rd); \
|
generate_load_reg(a0, rd); \
|
||||||
|
@ -1942,11 +1827,20 @@ u32 function_cc execute_ror_imm_op(u32 value, u32 shift)
|
||||||
generate_load_reg(a0, rs); \
|
generate_load_reg(a0, rs); \
|
||||||
generate_load_imm(a1, imm) \
|
generate_load_imm(a1, imm) \
|
||||||
|
|
||||||
|
#define thumb_shift_operation_imm(op_type) \
|
||||||
|
thumb_##op_type##_imm_op()
|
||||||
|
|
||||||
|
#define thumb_shift_operation_reg(op_type) \
|
||||||
|
generate_##op_type##_flags_reg(a0); \
|
||||||
|
generate_or(a0, a0); \
|
||||||
|
generate_update_flag(z, REG_Z_FLAG) \
|
||||||
|
generate_update_flag(s, REG_N_FLAG) \
|
||||||
|
|
||||||
#define thumb_shift(decode_type, op_type, value_type) \
|
#define thumb_shift(decode_type, op_type, value_type) \
|
||||||
{ \
|
{ \
|
||||||
thumb_decode_##decode_type(); \
|
thumb_decode_##decode_type(); \
|
||||||
generate_shift_load_operands_##value_type(); \
|
generate_shift_load_operands_##value_type(); \
|
||||||
generate_function_call(execute_##op_type##_##value_type##_op); \
|
thumb_shift_operation_##value_type(op_type); \
|
||||||
generate_store_reg(rv, rd); \
|
generate_store_reg(rv, rd); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue