Fix clang-7 and MSVC build

- added missing includes
- fixed ambiguous Bitfield extract_from
- VU branch delay slot cleanup
- removed unused CGif function
- removed reference to removed variables
This commit is contained in:
hch12907 2018-10-18 20:58:16 +08:00
parent 313f59a019
commit 4e62239a94
8 changed files with 31 additions and 125 deletions

View file

@ -76,9 +76,9 @@ struct Bitfield
throw std::logic_error("Cannot extract bitfield over 64 bit boundary from a uqword [not implemented]");
if (start < 64)
return Bitfield(start, length).extract_from<To>(value.lo);
return Bitfield(start, length).extract_from<To, udword>(value.lo);
else
return Bitfield(start - 64, length).extract_from<To>(value.hi);
return Bitfield(start - 64, length).extract_from<To, udword>(value.hi);
}
constexpr bool operator==(const Bitfield& rhs) const

View file

@ -1,8 +1,10 @@
#pragma once
#include <cereal/cereal.hpp>
#include <array>
#include <utility>
#include <cereal/cereal.hpp>
#include "Common/Types/Primitive.hpp"
#include "Common/Types/Register/PcRegisters.hpp"
@ -13,13 +15,13 @@
/// configured branch slots have been run, and then the jump/branch occurs.
/// A default slot size of 1 is used by the EE and IOP cores.
/// slot + 1 is used internally as this is the real amount of instruction cycles.
template <size_t slots = 1>
/// inst_size specifies the instruction size of the unit (4 bytes for EE & IOP, 8 for VU)
template <size_t slots = 1, size_t inst_size = Constants::MIPS::SIZE_MIPS_INSTRUCTION>
class BranchDelaySlot
{
public:
BranchDelaySlot() :
current_slot(0),
branch_pc(0)
pending_branches { std::pair(-1, 0), std::pair(-1, 0) }
{
}
@ -39,6 +41,13 @@ public:
throw std::runtime_error("BDS: More than 2 branches in queue - this should not happen");
}
/// Obtains the PC of a soon-to-happen branching.
/// This is used by the *AL* (link register) branching/jumping instructions.
uptr get_branch_pc()
{
return pending_branches[0].second;
}
/// Sets a pending branch to the direct address given.
void set_branch_direct(const uptr address)
{
@ -49,14 +58,14 @@ public:
/// the offset specified. Used for I-type instructions (imm's).
void set_branch_itype(WordPcRegister& pc, const shword imm)
{
add_branch_queue((pc.read_uword() + Constants::MIPS::SIZE_MIPS_INSTRUCTION) + (imm << 2));
add_branch_queue((pc.read_uword() + inst_size) + (imm * inst_size));
}
/// Sets a pending branch which combines the current PC address with
/// the region address. Used for J-type instructions.
void set_branch_jtype(WordPcRegister& pc, const uptr j_region_addr)
{
add_branch_queue(((pc.read_uword() + Constants::MIPS::SIZE_MIPS_INSTRUCTION) & 0xF0000000) | (j_region_addr << 2));
add_branch_queue(((pc.read_uword() + inst_size) & 0xF0000000) | (j_region_addr * inst_size));
}
/// Advances the PC by either incrementing by 1 instruction,
@ -88,7 +97,7 @@ public:
}
// Increment by 1 instruction.
pc.offset(Constants::MIPS::SIZE_MIPS_INSTRUCTION);
pc.offset(inst_size);
}
/// Stops the current branch in progress (used by exception handler).
@ -110,7 +119,7 @@ public:
protected:
// sword of std::pair = cycles left before branching
// uptr of std::pair = address to branch to
std::array<std::pair<sword, uptr>, 2> pending_branches;
std::array<std::pair<sword, uptr>, slots + 1> pending_branches;
public:
template <class Archive>

View file

@ -33,6 +33,4 @@ public:
int handle_data_reglist(const uqword data);
int handle_data_image(const uqword data);
std::pair<size_t, SizedDwordRegister*> get_register_descriptor() const;
};

View file

@ -282,14 +282,14 @@ bool CVuInterpreter::check_data_hazard(VuUnit_Base* unit, const VuInstructionDec
decoder.lower_src(1).value_or(-1)};
// If the instruction is WAITP, return true if EFU is running
if ((decoder.get_lower_inst().value) & 0x7FF == 0x7BF)
if (((decoder.get_lower_inst().value) & 0x7FF) == 0x7BF)
{
if (unit->efu.is_running())
return true;
}
// If the instruction is WAITQ, return true if FDIV is running
if ((decoder.get_lower_inst().value) & 0x7FF == 0x3BF)
if (((decoder.get_lower_inst().value) & 0x7FF) == 0x3BF)
{
if (unit->fdiv.is_running())
return true;
@ -309,7 +309,7 @@ bool CVuInterpreter::check_data_hazard(VuUnit_Base* unit, const VuInstructionDec
{
if (fmac.is_using_register(upper_read[0], inst.dest()))
return true;
if (fmac.is_using_register(upper_read[1], 1 << (3 - inst.bc())))
if (fmac.is_using_register(upper_read[1], 1U << (3 - inst.bc())))
return true;
}
}
@ -334,7 +334,7 @@ bool CVuInterpreter::check_data_hazard(VuUnit_Base* unit, const VuInstructionDec
return true;
if (fmac.is_using_register(upper_read[1], inst.dest()))
return true;
if (fmac.is_using_register(upper_read[2], 1 << (3 - inst.bc())))
if (fmac.is_using_register(upper_read[2], 1U << (3 - inst.bc())))
return true;
}
}

View file

@ -1,10 +1,7 @@
#include "Resources/Ee/Gif/GifRegisters.hpp"
GifRegister_Ctrl::GifRegister_Ctrl() :
transfer_started(false),
tag(),
transfer_register_count(0),
transfer_loop_count(0),
rgbaq_q(1.0f)
{
}

View file

@ -28,11 +28,8 @@ public:
void serialize(Archive & archive)
{
archive(
cereal::base_class<SizedWordRegister>(this),
CEREAL_NVP(transfer_started),
CEREAL_NVP(tag),
CEREAL_NVP(transfer_register_count),
CEREAL_NVP(transfer_loop_count),
cereal::base_class<SizedWordRegister>(this)
// CEREAL_NVP(tag) // TODO
);
}
};

View file

@ -1,112 +1,17 @@
#pragma once
#include <cereal/cereal.hpp>
#include "Common/Types/Mips/BranchDelaySlot.hpp"
#include "Common/Types/Primitive.hpp"
#include "Common/Types/Register/PcRegisters.hpp"
/// BranchDelaySlot, modified slightly for the VUs.
/// BranchDelaySlot modified slightly for the VUs.
/// See BranchDelaySlot for more documentation.
template <size_t slots = 1>
class VuBranchDelaySlot : public BranchDelaySlot<slots>
class VuBranchDelaySlot : public BranchDelaySlot<1, Constants::EE::VPU::SIZE_VU_INSTRUCTION>
{
public:
VuBranchDelaySlot() :
second_branch_pc(0),
second_branch_pending(false),
BranchDelaySlot<slots>()
{
}
/// is_branch_pending() in VuBranchDelaySlot has the same behaviour as the
/// one in BranchDelaySlot.
using BranchDelaySlot<slots>::is_branch_pending;
/// Obtains the PC of which the VU is branching to.
/// This is used by the *AL* (link register) branching/jumping instructions.
uptr get_branch_pc()
{
return branch_pc;
}
/// Sets the offset of the PC address of the VUs, with a delay slot.
/// See BranchDelaySlot::set_branch_itype for more documentation.
/// The only difference is the size of the instruction - VU instructions are 8 bytes long
/// whereas EE Core instructions are only 4.
void set_branch_itype(WordPcRegister& pc, const shword imm)
{
// If we are branching in the delay slot, the original branch runs for only one cycle
if (is_branch_pending())
{
second_branch_pending = true;
second_branch_pc = (pc.read_uword() + Constants::EE::VPU::SIZE_VU_INSTRUCTION + imm * 8) & 0x3FFF;
}
else
{
current_slot = slots + 1;
// VU can hold 16KB of instructions only (and 4KB in VU0), so AND it with 0x3FFF
branch_pc = (pc.read_uword() + Constants::EE::VPU::SIZE_VU_INSTRUCTION + imm * 8) & 0x3FFF;
}
}
/// Sets the PC address of the VUs, with a delay slot.
/// The VUs' jumping range is much smaller than the EE Core's
/// (just 16KB is sufficient for the VUs), and so this method behaves
/// differently from the original set_branch_jtype.
/// The VUs don't have the concept of virtual address, so just jump
void set_branch_jtype(WordPcRegister& pc, const uptr jump_to)
{
if (is_branch_pending())
{
second_branch_pending = true;
second_branch_pc = (jump_to * 8) & 0x3FFF;
}
else
{
current_slot = slots + 1;
branch_pc = (jump_to * 8) & 0x3FFF;
}
add_branch_queue((jump_to * Constants::EE::VPU::SIZE_VU_INSTRUCTION) & 0x3FFF);
}
void advance_pc(WordPcRegister& pc)
{
if (current_slot)
{
current_slot--;
if (!current_slot)
{
pc.write_uword(branch_pc);
if (second_branch_pending)
{
second_branch_pending = false;
branch_pc = second_branch_pc;
current_slot = 1;
}
return;
}
}
pc.offset(Constants::EE::VPU::SIZE_VU_INSTRUCTION);
}
private:
// introduces the base class variables to this class
using BranchDelaySlot<slots>::branch_pc;
using BranchDelaySlot<slots>::current_slot;
uptr second_branch_pc;
bool second_branch_pending;
// Serialization
public:
template <class Archive>
void serialize(Archive& archive)
{
archive(
CEREAL_NVP(current_slot),
CEREAL_NVP(branch_pc),
CEREAL_NVP(second_branch_pc),
CEREAL_NVP(second_branch_pending));
}
};
};

View file

@ -67,7 +67,7 @@ public:
/// Also known as the TPC (termination PC), treated as the same thing.
/// Made to be 32-bit even though only 16-bits are used (bus maps easier).
WordPcRegister pc;
VuBranchDelaySlot<> bdelay;
VuBranchDelaySlot bdelay;
/// The CMSAR register used for micro subroutine execution.
/// See VU Users Manual page 202.