📄 mips_emit.h
字号:
#define generate_load_memory_s8(ireg, offset) \ mips_emit_lb(ireg, ireg, offset) \#define generate_load_memory_s16(ireg, offset) \ mips_emit_lh(ireg, ireg, offset) \#define generate_load_memory(type, ireg, address) \{ \ u32 _address = (u32)(address); \ u32 _address_hi = (_address + 0x8000) >> 16; \ generate_load_imm(ireg, address); \ mips_emit_lui(ireg, _address_hi >> 16) \ generate_load_memory_##type(ireg, _address - (_address_hi << 16)); \} \#define generate_known_address_load_builder(type) \ u32 generate_known_address_load_##type(u32 rd, u32 address) \ { \ switch(address >> 24) \ { \ /* Read from the BIOS ROM, can be converted to an immediate load. \ Only really possible to do this from the BIOS but should be okay \ to allow it everywhere */ \ case 0x00: \ u32 imm = read_memory_constant_##type(address); \ generate_load_imm(arm_to_mips_reg[rd], imm); \ return 1; \ \ /* Read from RAM, can be converted to a load */ \ case 0x02: \ generate_load_memory(type, arm_to_mips_reg[rd], (u8 *)ewram + \ (address & 0x7FFF) + ((address & 0x38000) * 2) + 0x8000); \ return 1; \ \ case 0x03: \ generate_load_memory(type, arm_to_mips_reg[rd], (u8 *)iwram + \ (address & 0x7FFF) + 0x8000); \ return 1; \ \ /* Read from gamepak ROM, this has to be an immediate load because \ it might not actually be in memory anymore when we get to it. */ \ case 0x08: \ u32 imm = read_memory_constant_##type(address); \ generate_load_imm(arm_to_mips_reg[rd], imm); \ return 1; \ \ default: \ return 0; \ } \ } \#define generate_block_extra_vars() \ u32 stored_pc = pc; \ u8 *update_trampoline \#define generate_block_extra_vars_arm() \ generate_block_extra_vars(); \ generate_load_rm_sh_builder(flags); \ generate_load_rm_sh_builder(no_flags); \ \/* generate_known_address_load_builder(u8); \ generate_known_address_load_builder(u16); \ generate_known_address_load_builder(u32); \ generate_known_address_load_builder(s8); \ generate_known_address_load_builder(s16); */ \ \ u32 generate_load_offset_sh(u32 rm) \ { \ switch((opcode >> 5) & 0x03) \ { \ /* LSL imm */ \ case 0x0: \ { \ generate_shift_imm(arm_reg_a1, lsl, no_flags); \ break; \ } \ \ /* LSR imm */ \ case 0x1: \ { \ generate_shift_imm(arm_reg_a1, lsr, no_flags); \ break; \ } \ \ /* ASR imm */ \ case 0x2: \ { \ generate_shift_imm(arm_reg_a1, asr, no_flags); \ break; \ } \ \ /* ROR imm */ \ case 0x3: \ { \ generate_shift_imm(arm_reg_a1, ror, no_flags); \ break; \ } \ } \ \ return rm; \ } \ \ void generate_indirect_branch_arm() \ { \ if(condition == 0x0E) \ { \ generate_indirect_branch_cycle_update(arm); \ } \ else \ { \ generate_indirect_branch_no_cycle_update(arm); \ } \ } \ \ void generate_indirect_branch_dual() \ { \ if(condition == 0x0E) \ { \ generate_indirect_branch_cycle_update(dual); \ } \ else \ { \ generate_indirect_branch_no_cycle_update(dual); \ } \ } \#define generate_block_extra_vars_thumb() \ generate_block_extra_vars() \// 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.u32 execute_spsr_restore_body(u32 address){ set_cpu_mode(cpu_modes[reg[REG_CPSR] & 0x1F]); if((io_registers[REG_IE] & io_registers[REG_IF]) && io_registers[REG_IME] && ((reg[REG_CPSR] & 0x80) == 0)) { reg_mode[MODE_IRQ][6] = address + 4; spsr[MODE_IRQ] = reg[REG_CPSR]; reg[REG_CPSR] = 0xD2; address = 0x00000018; set_cpu_mode(MODE_IRQ); } if(reg[REG_CPSR] & 0x20) address |= 0x01; return address;}typedef enum{ CONDITION_TRUE, CONDITION_FALSE, CONDITION_EQUAL, CONDITION_NOT_EQUAL} condition_check_type;#define generate_condition_eq() \ mips_emit_b_filler(beq, reg_z_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_ne() \ mips_emit_b_filler(bne, reg_z_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_cs() \ mips_emit_b_filler(beq, reg_c_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_cc() \ mips_emit_b_filler(bne, reg_c_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_mi() \ mips_emit_b_filler(beq, reg_n_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_pl() \ mips_emit_b_filler(bne, reg_n_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_vs() \ mips_emit_b_filler(beq, reg_v_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_vc() \ mips_emit_b_filler(bne, reg_v_cache, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_hi() \ mips_emit_xori(reg_temp, reg_c_cache, 1); \ mips_emit_or(reg_temp, reg_temp, reg_z_cache); \ mips_emit_b_filler(bne, reg_temp, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_ls() \ mips_emit_xori(reg_temp, reg_c_cache, 1); \ mips_emit_or(reg_temp, reg_temp, reg_z_cache); \ mips_emit_b_filler(beq, reg_temp, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_ge() \ mips_emit_b_filler(bne, reg_n_cache, reg_v_cache, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_lt() \ mips_emit_b_filler(beq, reg_n_cache, reg_v_cache, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_gt() \ mips_emit_xor(reg_temp, reg_n_cache, reg_v_cache); \ mips_emit_or(reg_temp, reg_temp, reg_z_cache); \ mips_emit_b_filler(bne, reg_temp, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition_le() \ mips_emit_xor(reg_temp, reg_n_cache, reg_v_cache); \ mips_emit_or(reg_temp, reg_temp, reg_z_cache); \ mips_emit_b_filler(beq, reg_temp, reg_zero, backpatch_address); \ generate_cycle_update_force() \#define generate_condition() \ switch(condition) \ { \ case 0x0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -