📄 x86_emit.h
字号:
else \ { \ generate_load_reg_pc(a0, rm, 8); \ generate_function_call(execute_rrx); \ generate_mov(ireg, rv); \ } \#define generate_shift_imm_lsl_flags(ireg) \ generate_load_reg_pc(ireg, rm, 8); \ 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); \ } \#define generate_shift_imm_lsr_flags(ireg) \ 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); \ } \ else \ { \ generate_load_reg_pc(a1, rm, 8); \ generate_shift_right(a1, 31); \ generate_store_reg(a1, REG_C_FLAG); \ generate_load_imm(ireg, 0); \ } \#define generate_shift_imm_asr_flags(ireg) \ 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); \ } \ else \ { \ generate_load_reg_pc(a0, rm, 8); \ generate_shift_right_arithmetic(ireg, 31); \ generate_mov(a1, ireg); \ generate_and_imm(a1, 1); \ generate_store_reg(a1, REG_C_FLAG); \ } \#define generate_shift_imm_ror_flags(ireg) \ generate_load_reg_pc(ireg, rm, 8); \ if(shift != 0) \ { \ generate_mov(a1, ireg); \ generate_shift_right_arithmetic(a1, shift - 1); \ generate_and_imm(a1, 1); \ generate_store_reg(a1, REG_C_FLAG); \ generate_rotate_right(ireg, shift); \ } \ else \ { \ generate_function_call(execute_rrx_flags); \ generate_mov(ireg, rv); \ } \#define generate_shift_imm(ireg, name, flags_op) \ get_shift_imm(); \ generate_shift_imm_##name##_##flags_op(ireg) \#define generate_load_rm_sh(flags_op) \ switch((opcode >> 4) & 0x07) \ { \ /* LSL imm */ \ case 0x0: \ { \ generate_shift_imm(a0, lsl, flags_op); \ break; \ } \ \ /* LSL reg */ \ case 0x1: \ { \ generate_shift_reg(a0, lsl, flags_op); \ break; \ } \ \ /* LSR imm */ \ case 0x2: \ { \ generate_shift_imm(a0, lsr, flags_op); \ break; \ } \ \ /* LSR reg */ \ case 0x3: \ { \ generate_shift_reg(a0, lsr, flags_op); \ break; \ } \ \ /* ASR imm */ \ case 0x4: \ { \ generate_shift_imm(a0, asr, flags_op); \ break; \ } \ \ /* ASR reg */ \ case 0x5: \ { \ generate_shift_reg(a0, asr, flags_op); \ break; \ } \ \ /* ROR imm */ \ case 0x6: \ { \ generate_shift_imm(a0, ror, flags_op); \ break; \ } \ \ /* ROR reg */ \ case 0x7: \ { \ generate_shift_reg(a0, ror, flags_op); \ break; \ } \ } \#define generate_load_offset_sh() \ switch((opcode >> 5) & 0x03) \ { \ /* LSL imm */ \ case 0x0: \ { \ generate_shift_imm(a1, lsl, no_flags); \ break; \ } \ \ /* LSR imm */ \ case 0x1: \ { \ generate_shift_imm(a1, lsr, no_flags); \ break; \ } \ \ /* ASR imm */ \ case 0x2: \ { \ generate_shift_imm(a1, asr, no_flags); \ break; \ } \ \ /* ROR imm */ \ case 0x3: \ { \ generate_shift_imm(a1, ror, no_flags); \ break; \ } \ } \#define calculate_flags_add(dest, src_a, src_b) \ calculate_z_flag(dest); \ calculate_n_flag(dest); \ calculate_c_flag_add(dest, src_a, src_b); \ calculate_v_flag_add(dest, src_a, src_b) \#define calculate_flags_sub(dest, src_a, src_b) \ calculate_z_flag(dest); \ calculate_n_flag(dest); \ calculate_c_flag_sub(dest, src_a, src_b); \ calculate_v_flag_sub(dest, src_a, src_b) \#define calculate_flags_logic(dest) \ calculate_z_flag(dest); \ calculate_n_flag(dest) \#define extract_flags() \ reg[REG_N_FLAG] = reg[REG_CPSR] >> 31; \ reg[REG_Z_FLAG] = (reg[REG_CPSR] >> 30) & 0x01; \ reg[REG_C_FLAG] = (reg[REG_CPSR] >> 29) & 0x01; \ reg[REG_V_FLAG] = (reg[REG_CPSR] >> 28) & 0x01; \#define collapse_flags() \ reg[REG_CPSR] = (reg[REG_N_FLAG] << 31) | (reg[REG_Z_FLAG] << 30) | \ (reg[REG_C_FLAG] << 29) | (reg[REG_V_FLAG] << 28) | \ reg[REG_CPSR] & 0xFF \// It should be okay to still generate result flags, spsr will overwrite them.// This is pretty infrequent (returning from interrupt handlers, et al) so// probably not worth optimizing for.#define check_for_interrupts() \ if((io_registers[REG_IE] & io_registers[REG_IF]) && \ io_registers[REG_IME] && ((reg[REG_CPSR] & 0x80) == 0)) \ { \ reg_mode[MODE_IRQ][6] = reg[REG_PC] + 4; \ spsr[MODE_IRQ] = reg[REG_CPSR]; \ reg[REG_CPSR] = 0xD2; \ address = 0x00000018; \ set_cpu_mode(MODE_IRQ); \ } \#define generate_load_reg_pc(ireg, reg_index, pc_offset) \ if(reg_index == 15) \ { \ generate_load_pc(ireg, pc + pc_offset); \ } \ else \ { \ generate_load_reg(ireg, reg_index); \ } \#define generate_store_reg_pc_no_flags(ireg, reg_index) \ generate_store_reg(ireg, reg_index); \ if(reg_index == 15) \ { \ generate_mov(a0, ireg); \ generate_indirect_branch_arm(); \ } \u32 function_cc execute_spsr_restore(u32 address){ reg[REG_CPSR] = spsr[reg[CPU_MODE]]; extract_flags(); set_cpu_mode(cpu_modes[reg[REG_CPSR] & 0x1F]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -