mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-27 00:29:18 +00:00
Refactor the interpreter, part 1: loads and stores.
This commit is contained in:
parent
7bdad7703c
commit
0d5817042e
61
cpu/ppc/ppcdefs.h
Normal file
61
cpu/ppc/ppcdefs.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-21 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PPC_DEFS_H
|
||||
#define PPC_DEFS_H
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#define GET_rD_rA_OFFS(opcode) \
|
||||
uint32_t reg_d = ((opcode) >> 21) & 31; \
|
||||
uint32_t reg_a = ((opcode) >> 16) & 31; \
|
||||
int32_t offs = (int32_t)((int16_t)((opcode) & 0xFFFF));
|
||||
|
||||
#define GET_GPR(reg) ppc_state.gpr[(reg)]
|
||||
#define SET_GPR(reg, val) ppc_state.gpr[(reg)] = (val)
|
||||
|
||||
#define GET_rD_iA_iB(opcode) \
|
||||
uint32_t reg_d = ((opcode) >> 21) & 31; \
|
||||
uint32_t imm_a = ppc_state.gpr[((opcode) >> 16) & 31]; \
|
||||
uint32_t imm_b = ppc_state.gpr[((opcode) >> 11) & 31];
|
||||
|
||||
#define GET_rD_rA_iA_iB(opcode) \
|
||||
uint32_t reg_d = ((opcode) >> 21) & 31; \
|
||||
uint32_t reg_a = ((opcode) >> 16) & 31; \
|
||||
uint32_t imm_a = ppc_state.gpr[reg_a]; \
|
||||
uint32_t imm_b = ppc_state.gpr[((opcode) >> 11) & 31];
|
||||
|
||||
#define GET_rA_iS(opcode) \
|
||||
uint32_t reg_a = ((opcode) >> 16) & 31; \
|
||||
uint32_t imm_d = ppc_state.gpr[((opcode) >> 21) & 31];
|
||||
|
||||
#define GET_rS_rA_OFFS(opcode) \
|
||||
uint32_t reg_s = ((opcode) >> 21) & 31; \
|
||||
uint32_t reg_a = ((opcode) >> 16) & 31; \
|
||||
int32_t offs = (int32_t)((int16_t)((opcode) & 0xFFFF));
|
||||
|
||||
#define GET_rS_rA_iA_iB(opcode) \
|
||||
uint32_t reg_s = ((opcode) >> 21) & 31; \
|
||||
uint32_t reg_a = ((opcode) >> 16) & 31; \
|
||||
uint32_t imm_a = ppc_state.gpr[reg_a]; \
|
||||
uint32_t imm_b = ppc_state.gpr[((opcode) >> 11) & 31];
|
||||
|
||||
#endif // PPC_DEFS_H
|
@ -505,14 +505,16 @@ extern void ppc_bcl();
|
||||
extern void ppc_bcla();
|
||||
extern void ppc_cmpi();
|
||||
extern void ppc_cmpli();
|
||||
extern void ppc_lbz();
|
||||
extern void ppc_lbzu();
|
||||
extern void ppc_lha();
|
||||
extern void ppc_lhau();
|
||||
extern void ppc_lhz();
|
||||
extern void ppc_lhzu();
|
||||
extern void ppc_lwz();
|
||||
extern void ppc_lwzu();
|
||||
template <class T> void ppc_lz(void);
|
||||
template <class T> void ppc_lzu(void);
|
||||
template <class T> void ppc_lzux(void);
|
||||
template <class T> void ppc_lzx(void);
|
||||
template <class T> void ppc_st(void);
|
||||
template <class T> void ppc_stu(void);
|
||||
template <class T> void ppc_stux(void);
|
||||
template <class T> void ppc_stx(void);
|
||||
extern void ppc_lmw();
|
||||
extern void ppc_mulli();
|
||||
extern void ppc_ori();
|
||||
@ -522,12 +524,6 @@ extern void ppc_rlwimi();
|
||||
extern void ppc_rlwinm();
|
||||
extern void ppc_rlwnm();
|
||||
extern void ppc_sc();
|
||||
extern void ppc_stb();
|
||||
extern void ppc_stbu();
|
||||
extern void ppc_sth();
|
||||
extern void ppc_sthu();
|
||||
extern void ppc_stw();
|
||||
extern void ppc_stwu();
|
||||
extern void ppc_stmw();
|
||||
extern void ppc_subfic();
|
||||
extern void ppc_twi();
|
||||
|
@ -136,9 +136,9 @@ static PPCOpcode OpcodeGrabber[] = {
|
||||
ppc_addic, ppc_addicdot, ppc_addi, ppc_addis, ppc_opcode16, ppc_sc,
|
||||
ppc_opcode18, ppc_opcode19, ppc_rlwimi, ppc_rlwinm, power_rlmi, ppc_rlwnm,
|
||||
ppc_ori, ppc_oris, ppc_xori, ppc_xoris, ppc_andidot, ppc_andisdot,
|
||||
ppc_illegalop, ppc_opcode31, ppc_lwz, ppc_lwzu, ppc_lbz, ppc_lbzu,
|
||||
ppc_stw, ppc_stwu, ppc_stb, ppc_stbu, ppc_lhz, ppc_lhzu,
|
||||
ppc_lha, ppc_lhau, ppc_sth, ppc_sthu, ppc_lmw, ppc_stmw,
|
||||
ppc_illegalop, ppc_opcode31, ppc_lz<uint32_t>, ppc_lzu<uint32_t>, ppc_lz<uint8_t>, ppc_lzu<uint8_t>,
|
||||
ppc_st<uint32_t>, ppc_stu<uint32_t>, ppc_st<uint8_t>, ppc_stu<uint8_t>, ppc_lz<uint16_t>, ppc_lzu<uint16_t>,
|
||||
ppc_lha, ppc_lhau, ppc_st<uint16_t>, ppc_stu<uint16_t>, ppc_lmw, ppc_stmw,
|
||||
ppc_lfs, ppc_lfsu, ppc_lfd, ppc_lfdu, ppc_stfs, ppc_stfsu,
|
||||
ppc_stfd, ppc_stfdu, ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode59,
|
||||
ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode63};
|
||||
@ -818,12 +818,12 @@ void initialize_ppc_opcode_tables() {
|
||||
SubOpcode31Grabber[491] = SubOpcode31Grabber[1003] = ppc_divw;
|
||||
|
||||
SubOpcode31Grabber[20] = ppc_lwarx;
|
||||
SubOpcode31Grabber[23] = ppc_lwzx;
|
||||
SubOpcode31Grabber[55] = ppc_lwzux;
|
||||
SubOpcode31Grabber[87] = ppc_lbzx;
|
||||
SubOpcode31Grabber[119] = ppc_lbzux;
|
||||
SubOpcode31Grabber[279] = ppc_lhzx;
|
||||
SubOpcode31Grabber[311] = ppc_lhzux;
|
||||
SubOpcode31Grabber[23] = ppc_lzx<uint32_t>;
|
||||
SubOpcode31Grabber[55] = ppc_lzux<uint32_t>;
|
||||
SubOpcode31Grabber[87] = ppc_lzx<uint8_t>;
|
||||
SubOpcode31Grabber[119] = ppc_lzux<uint8_t>;
|
||||
SubOpcode31Grabber[279] = ppc_lzx<uint16_t>;
|
||||
SubOpcode31Grabber[311] = ppc_lzux<uint16_t>;
|
||||
SubOpcode31Grabber[343] = ppc_lhax;
|
||||
SubOpcode31Grabber[375] = ppc_lhaux;
|
||||
SubOpcode31Grabber[533] = ppc_lswx;
|
||||
@ -836,12 +836,12 @@ void initialize_ppc_opcode_tables() {
|
||||
SubOpcode31Grabber[790] = ppc_lhbrx;
|
||||
|
||||
SubOpcode31Grabber[150] = ppc_stwcx;
|
||||
SubOpcode31Grabber[151] = ppc_stwx;
|
||||
SubOpcode31Grabber[183] = ppc_stwux;
|
||||
SubOpcode31Grabber[215] = ppc_stbx;
|
||||
SubOpcode31Grabber[247] = ppc_stbux;
|
||||
SubOpcode31Grabber[407] = ppc_sthx;
|
||||
SubOpcode31Grabber[439] = ppc_sthux;
|
||||
SubOpcode31Grabber[151] = ppc_stx<uint32_t>;
|
||||
SubOpcode31Grabber[183] = ppc_stux<uint32_t>;
|
||||
SubOpcode31Grabber[215] = ppc_stx<uint8_t>;
|
||||
SubOpcode31Grabber[247] = ppc_stux<uint8_t>;
|
||||
SubOpcode31Grabber[407] = ppc_stx<uint16_t>;
|
||||
SubOpcode31Grabber[439] = ppc_stux<uint16_t>;
|
||||
SubOpcode31Grabber[661] = ppc_stswx;
|
||||
SubOpcode31Grabber[662] = ppc_stwbrx;
|
||||
SubOpcode31Grabber[663] = ppc_stfsx;
|
||||
|
@ -21,6 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// General opcodes for the processor - ppcopcodes.cpp
|
||||
|
||||
#include "ppcdefs.h"
|
||||
#include "ppcemu.h"
|
||||
#include "ppcmmu.h"
|
||||
#include <array>
|
||||
@ -1415,203 +1416,112 @@ void dppc_interpreter::ppc_dcbz() {
|
||||
|
||||
// Integer Load and Store Functions
|
||||
|
||||
void dppc_interpreter::ppc_stb() {
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_st() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssa();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += reg_a ? ppc_result_a : 0;
|
||||
mmu_write_vmem<uint8_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_byte(ppc_effective_address, ppc_result_d);
|
||||
GET_rS_rA_OFFS(ppc_cur_instruction);
|
||||
uint32_t ea = offs + (reg_a ? GET_GPR(reg_a) : 0);
|
||||
mmu_write_vmem<T>(ea, GET_GPR(reg_s));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stbx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
mmu_write_vmem<uint8_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_byte(ppc_effective_address, ppc_result_d);
|
||||
}
|
||||
// explicitely instantiate all required ppc_st variants
|
||||
template void dppc_interpreter::ppc_st<uint8_t>(void); // stb
|
||||
template void dppc_interpreter::ppc_st<uint16_t>(void); // sth
|
||||
template void dppc_interpreter::ppc_st<uint32_t>(void); // stw
|
||||
|
||||
void dppc_interpreter::ppc_stbu() {
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_stu() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssa();
|
||||
if (reg_a != 0) {
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += ppc_result_a;
|
||||
mmu_write_vmem<uint8_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_byte(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.gpr[reg_a] = ppc_effective_address;
|
||||
} else {
|
||||
GET_rS_rA_OFFS(ppc_cur_instruction);
|
||||
if (!reg_a) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
uint32_t ea = offs + GET_GPR(reg_a);
|
||||
mmu_write_vmem<T>(ea, GET_GPR(reg_s));
|
||||
SET_GPR(reg_a, ea);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stbux() {
|
||||
// explicitely instantiate all required ppc_stu variants
|
||||
template void dppc_interpreter::ppc_stu<uint8_t>(void); // stbu
|
||||
template void dppc_interpreter::ppc_stu<uint16_t>(void); // sthu
|
||||
template void dppc_interpreter::ppc_stu<uint32_t>(void); // stwu
|
||||
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_stx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
if (reg_a != 0) {
|
||||
ppc_effective_address = ppc_result_a + ppc_result_b;
|
||||
mmu_write_vmem<uint8_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_byte(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.gpr[reg_a] = ppc_effective_address;
|
||||
} else {
|
||||
GET_rS_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
mmu_write_vmem<T>(ea, GET_GPR(reg_s));
|
||||
}
|
||||
|
||||
// explicitely instantiate all required ppc_stx variants
|
||||
template void dppc_interpreter::ppc_stx<uint8_t>(void); // stbx
|
||||
template void dppc_interpreter::ppc_stx<uint16_t>(void); // sthx
|
||||
template void dppc_interpreter::ppc_stx<uint32_t>(void); // stwx
|
||||
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_stux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
GET_rS_rA_iA_iB(ppc_cur_instruction);
|
||||
if (!reg_a) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
uint32_t ea = imm_a + imm_b;
|
||||
mmu_write_vmem<T>(ea, GET_GPR(reg_s));
|
||||
SET_GPR(reg_a, ea);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_sth() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssa();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0;
|
||||
mmu_write_vmem<uint16_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_word(ppc_effective_address, ppc_result_d);
|
||||
}
|
||||
// explicitely instantiate all required ppc_stux variants
|
||||
template void dppc_interpreter::ppc_stux<uint8_t>(void); // stbux
|
||||
template void dppc_interpreter::ppc_stux<uint16_t>(void); // sthux
|
||||
template void dppc_interpreter::ppc_stux<uint32_t>(void); // stwux
|
||||
|
||||
void dppc_interpreter::ppc_sthu() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssa();
|
||||
if (reg_a != 0) {
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += ppc_result_a;
|
||||
mmu_write_vmem<uint16_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_word(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.gpr[reg_a] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_sthux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
if (reg_a != 0) {
|
||||
ppc_effective_address = ppc_result_a + ppc_result_b;
|
||||
mmu_write_vmem<uint16_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_word(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.gpr[reg_a] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_sthx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
mmu_write_vmem<uint16_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_word(ppc_effective_address, ppc_result_d);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_sthbrx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b);
|
||||
ppc_result_d = (uint32_t)(BYTESWAP_16((uint16_t)ppc_result_d));
|
||||
mmu_write_vmem<uint16_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_word(ppc_effective_address, ppc_result_d);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stw() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssa();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += reg_a ? ppc_result_a : 0;
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_dword(ppc_effective_address, ppc_result_d);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stwx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_dword(ppc_effective_address, ppc_result_d);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stwcx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
// PLACEHOLDER CODE FOR STWCX - We need to check for reserve memory
|
||||
if (rc_flag == 0) {
|
||||
ppc_illegalop();
|
||||
} else {
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b);
|
||||
if (ppc_state.reserve) {
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_dword(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x30000000 : 0x20000000;
|
||||
ppc_state.reserve = false;
|
||||
} else {
|
||||
ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x10000000 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stwu() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssa();
|
||||
if (reg_a != 0) {
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += ppc_result_a;
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_dword(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.gpr[reg_a] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stwux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
if (reg_a != 0) {
|
||||
ppc_effective_address = ppc_result_a + ppc_result_b;
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_dword(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.gpr[reg_a] = ppc_effective_address;
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
GET_rS_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
mmu_write_vmem<uint16_t>(ea, BYTESWAP_16((uint16_t)(GET_GPR(reg_s))));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stwbrx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
ppc_result_d = BYTESWAP_32(ppc_result_d);
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
//mem_write_dword(ppc_effective_address, ppc_result_d);
|
||||
GET_rS_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
mmu_write_vmem<uint32_t>(ea, BYTESWAP_32(GET_GPR(reg_s)));
|
||||
}
|
||||
|
||||
|
||||
void dppc_interpreter::ppc_stwcx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_stores++;
|
||||
#endif
|
||||
if (rc_flag == 0) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
} else {
|
||||
// TODO: We need to check for memory reservation
|
||||
ppc_grab_regssab();
|
||||
ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b);
|
||||
if (ppc_state.reserve) {
|
||||
mmu_write_vmem<uint32_t>(ppc_effective_address, ppc_result_d);
|
||||
ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x30000000 : 0x20000000;
|
||||
ppc_state.reserve = false;
|
||||
} else {
|
||||
ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x10000000 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_stmw() {
|
||||
@ -1634,277 +1544,136 @@ void dppc_interpreter::ppc_stmw() {
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lbz() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0;
|
||||
//ppc_result_d = mem_grab_byte(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint8_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lbzu() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address += ppc_result_a;
|
||||
//ppc_result_d = mem_grab_byte(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint8_t>(ppc_effective_address);
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_regd();
|
||||
ppc_store_result_rega();
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lbzx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//ppc_result_d = mem_grab_byte(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint8_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lbzux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address = ppc_result_a + ppc_result_b;
|
||||
//ppc_result_d = mem_grab_byte(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint8_t>(ppc_effective_address);
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_regd();
|
||||
ppc_store_result_rega();
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dppc_interpreter::ppc_lhz() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += reg_a ? ppc_result_a : 0;
|
||||
//ppc_result_d = mem_grab_word(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhzu() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += ppc_result_a;
|
||||
//ppc_result_d = mem_grab_word(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_regd();
|
||||
ppc_store_result_rega();
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhzx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//ppc_result_d = mem_grab_word(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhzux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address = ppc_result_a + ppc_result_b;
|
||||
//ppc_result_d = mem_grab_word(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_regd();
|
||||
ppc_store_result_rega();
|
||||
} else {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lha() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0;
|
||||
//uint16_t val = mem_grab_word(ppc_effective_address);
|
||||
uint16_t val = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
if (val & 0x8000) {
|
||||
ppc_result_d = 0xFFFF0000UL | (uint32_t)val;
|
||||
} else {
|
||||
ppc_result_d = (uint32_t)val;
|
||||
}
|
||||
ppc_store_result_regd();
|
||||
GET_rD_rA_OFFS(ppc_cur_instruction);
|
||||
uint32_t ea = offs + ((reg_a) ? ppc_state.gpr[reg_a] : 0);
|
||||
SET_GPR(reg_d, (int32_t)((int16_t)mmu_read_vmem<uint16_t>(ea)));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhau() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += ppc_result_a;
|
||||
//uint16_t val = mem_grab_word(ppc_effective_address);
|
||||
uint16_t val = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
if (val & 0x8000) {
|
||||
ppc_result_d = 0xFFFF0000UL | (uint32_t)val;
|
||||
} else {
|
||||
ppc_result_d = (uint32_t)val;
|
||||
}
|
||||
ppc_store_result_regd();
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_rega();
|
||||
} else {
|
||||
GET_rD_rA_OFFS(ppc_cur_instruction);
|
||||
if ((reg_a == reg_d) || reg_a == 0) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
uint32_t ea = offs + ppc_state.gpr[reg_a];
|
||||
SET_GPR(reg_d, (int32_t)((int16_t)mmu_read_vmem<uint16_t>(ea)));
|
||||
SET_GPR(reg_a, ea);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhaux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//uint16_t val = mem_grab_word(ppc_effective_address);
|
||||
uint16_t val = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
if (val & 0x8000) {
|
||||
ppc_result_d = 0xFFFF0000UL | (uint32_t)val;
|
||||
} else {
|
||||
ppc_result_d = (uint32_t)val;
|
||||
GET_rD_rA_iA_iB(ppc_cur_instruction);
|
||||
if ((reg_a == reg_d) || reg_a == 0) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
ppc_store_result_regd();
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_rega();
|
||||
uint32_t ea = imm_a + imm_b;
|
||||
SET_GPR(reg_d, (int32_t)((int16_t)mmu_read_vmem<uint16_t>(ea)));
|
||||
SET_GPR(reg_a, ea);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhax() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//uint16_t val = mem_grab_word(ppc_effective_address);
|
||||
uint16_t val = mmu_read_vmem<uint16_t>(ppc_effective_address);
|
||||
if (val & 0x8000) {
|
||||
ppc_result_d = 0xFFFF0000UL | (uint32_t)val;
|
||||
} else {
|
||||
ppc_result_d = (uint32_t)val;
|
||||
}
|
||||
ppc_store_result_regd();
|
||||
GET_rD_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
SET_GPR(reg_d, (int32_t)((int16_t)mmu_read_vmem<uint16_t>(ea)));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lhbrx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//ppc_result_d = (uint32_t)(BYTESWAP_16(mem_grab_word(ppc_effective_address)));
|
||||
ppc_result_d = (uint32_t)(BYTESWAP_16(mmu_read_vmem<uint16_t>(ppc_effective_address)));
|
||||
ppc_store_result_regd();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lwz() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
ppc_effective_address += (reg_a > 0) ? ppc_result_a : 0;
|
||||
//ppc_result_d = mem_grab_dword(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint32_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
GET_rD_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
SET_GPR(reg_d, BYTESWAP_16(mmu_read_vmem<uint16_t>(ea)));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lwbrx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//ppc_result_d = BYTESWAP_32(mem_grab_dword(ppc_effective_address));
|
||||
ppc_result_d = BYTESWAP_32(mmu_read_vmem<uint32_t>(ppc_effective_address));
|
||||
ppc_store_result_regd();
|
||||
GET_rD_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
SET_GPR(reg_d, BYTESWAP_32(mmu_read_vmem<uint32_t>(ea)));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lwzu() {
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_lz() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsda();
|
||||
ppc_effective_address = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address += ppc_result_a;
|
||||
//ppc_result_d = mem_grab_dword(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint32_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_rega();
|
||||
} else {
|
||||
GET_rD_rA_OFFS(ppc_cur_instruction);
|
||||
uint32_t ea = offs + ((reg_a) ? ppc_state.gpr[reg_a] : 0);
|
||||
SET_GPR(reg_d, mmu_read_vmem<T>(ea));
|
||||
}
|
||||
|
||||
// explicitely instantiate all required ppc_lz variants
|
||||
template void dppc_interpreter::ppc_lz<uint8_t>(void); // lbz
|
||||
template void dppc_interpreter::ppc_lz<uint16_t>(void); // lhz
|
||||
template void dppc_interpreter::ppc_lz<uint32_t>(void); // lwz
|
||||
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_lzu() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
GET_rD_rA_OFFS(ppc_cur_instruction);
|
||||
if ((reg_a == reg_d) || reg_a == 0) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
uint32_t ea = offs + ppc_state.gpr[reg_a];
|
||||
SET_GPR(reg_d, mmu_read_vmem<T>(ea));
|
||||
SET_GPR(reg_a, ea);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lwzx() {
|
||||
// explicitely instantiate all required ppc_lzu variants
|
||||
template void dppc_interpreter::ppc_lzu<uint8_t>(void); // lbzu
|
||||
template void dppc_interpreter::ppc_lzu<uint16_t>(void); // lhzu
|
||||
template void dppc_interpreter::ppc_lzu<uint32_t>(void); // lwzu
|
||||
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_lzx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
ppc_effective_address = reg_a ? (ppc_result_a + ppc_result_b) : ppc_result_b;
|
||||
//ppc_result_d = mem_grab_dword(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint32_t>(ppc_effective_address);
|
||||
ppc_store_result_regd();
|
||||
GET_rD_rA_iA_iB(ppc_cur_instruction);
|
||||
uint32_t ea = imm_b + ((reg_a) ? imm_a : 0);
|
||||
SET_GPR(reg_d, mmu_read_vmem<T>(ea));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_lwzux() {
|
||||
// explicitely instantiate all required ppc_lzx variants
|
||||
template void dppc_interpreter::ppc_lzx<uint8_t>(void); // lbzx
|
||||
template void dppc_interpreter::ppc_lzx<uint16_t>(void); // lhzx
|
||||
template void dppc_interpreter::ppc_lzx<uint32_t>(void); // lwzx
|
||||
|
||||
template <class T>
|
||||
void dppc_interpreter::ppc_lzux() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
#endif
|
||||
ppc_grab_regsdab();
|
||||
if ((reg_a != reg_d) || reg_a != 0) {
|
||||
ppc_effective_address = ppc_result_a + ppc_result_b;
|
||||
} else {
|
||||
GET_rD_rA_iA_iB(ppc_cur_instruction);
|
||||
if ((reg_a == reg_d) || reg_a == 0) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||
}
|
||||
//ppc_result_d = mem_grab_dword(ppc_effective_address);
|
||||
ppc_result_d = mmu_read_vmem<uint32_t>(ppc_effective_address);
|
||||
ppc_result_a = ppc_effective_address;
|
||||
ppc_store_result_regd();
|
||||
ppc_store_result_rega();
|
||||
uint32_t ea = imm_a + imm_b;
|
||||
SET_GPR(reg_d, mmu_read_vmem<T>(ea));
|
||||
SET_GPR(reg_a, ea);
|
||||
}
|
||||
|
||||
// explicitely instantiate all required ppc_lzux variants
|
||||
template void dppc_interpreter::ppc_lzux<uint8_t>(void); // lbzux
|
||||
template void dppc_interpreter::ppc_lzux<uint16_t>(void); // lhzux
|
||||
template void dppc_interpreter::ppc_lzux<uint32_t>(void); // lwzux
|
||||
|
||||
void dppc_interpreter::ppc_lwarx() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_int_loads++;
|
||||
|
Loading…
Reference in New Issue
Block a user