SPU assembler rdch/wrch fixes and MFC commands

This commit is contained in:
Alexandro Sánchez Bach 2016-05-27 01:35:48 +02:00
parent bcc58db504
commit 0d6b48739e
8 changed files with 108 additions and 4 deletions

View file

@ -5,6 +5,7 @@
#pragma once
// Architecture detection
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(_X86_)
#define NUCLEUS_ARCH_X86_32BITS
#endif

View file

@ -205,7 +205,7 @@ void SPUAssembler::orhi(RegGPR rt, RegGPR ra, U32 i10) { emitFormRI10(0x05000000
void SPUAssembler::ori(RegGPR rt, RegGPR ra, U32 i10) { emitFormRI10(0x04000000, rt, ra, i10); }
void SPUAssembler::orx(RegGPR rt, RegGPR ra) { emitFormRR(0x3E000000, rt, ra, 0); }
void SPUAssembler::rchcnt(RegGPR rt, RegGPR ra) { emitFormRR(0x01E00000, rt, ra, 0); }
void SPUAssembler::rdch(RegGPR rt, RegGPR ra) { emitFormRR(0x01A00000, rt, ra, 0); }
void SPUAssembler::rdch(RegGPR rt, U32 ca) { emitFormRR(0x01A00000, rt, ca, 0); }
void SPUAssembler::rot(RegGPR rt, RegGPR ra, RegGPR rb) { emitFormRR(0x0B000000, rt, ra, rb); }
void SPUAssembler::roth(RegGPR rt, RegGPR ra, RegGPR rb) { emitFormRR(0x0B800000, rt, ra, rb); }
void SPUAssembler::rothi(RegGPR rt, RegGPR ra, U32 i7) { emitFormRI7(0x0F800000, rt, ra, i7); }
@ -252,7 +252,7 @@ void SPUAssembler::stqr(RegGPR rt, U32 i16) { emitFormRI16(0x23800000, rt, i16);
void SPUAssembler::stqx(RegGPR rt, RegGPR ra, RegGPR rb) { emitFormRR(0x28800000, rt, ra, rb); }
void SPUAssembler::sumb(RegGPR rt, RegGPR ra, RegGPR rb) { emitFormRR(0x4A600000, rt, ra, rb); }
void SPUAssembler::sync() { } // TODO: 0x00400000
void SPUAssembler::wrch(RegGPR rt, RegGPR ra) { emitFormRR(0x21A00000, rt, ra, 0); }
void SPUAssembler::wrch(U32 ca, RegGPR rt) { emitFormRR(0x21A00000, rt, ca, 0); }
void SPUAssembler::xor_(RegGPR rt, RegGPR ra, RegGPR rb) { emitFormRR(0x48200000, rt, ra, rb); }
void SPUAssembler::xorbi(RegGPR rt, RegGPR ra, U32 i10) { emitFormRI10(0x46000000, rt, ra, i10); }
void SPUAssembler::xorhi(RegGPR rt, RegGPR ra, U32 i10) { emitFormRI10(0x45000000, rt, ra, i10); }

View file

@ -217,7 +217,7 @@ public:
void ori(RegGPR rt, RegGPR ra, U32 i10);
void orx(RegGPR rt, RegGPR ra);
void rchcnt(RegGPR rt, RegGPR ra);
void rdch(RegGPR rt, RegGPR ra);
void rdch(RegGPR rt, U32 ca);
void rot(RegGPR rt, RegGPR ra, RegGPR rb);
void roth(RegGPR rt, RegGPR ra, RegGPR rb);
void rothi(RegGPR rt, RegGPR ra, U32 i7);
@ -264,7 +264,7 @@ public:
void stqx(RegGPR rt, RegGPR ra, RegGPR rb);
void sumb(RegGPR rt, RegGPR ra, RegGPR rb);
void sync();
void wrch(RegGPR rt, RegGPR ra);
void wrch(U32 ca, RegGPR rt);
void xor_(RegGPR rt, RegGPR ra, RegGPR rb);
void xorbi(RegGPR rt, RegGPR ra, U32 i10);
void xorhi(RegGPR rt, RegGPR ra, U32 i10);

View file

@ -45,12 +45,85 @@ enum Channel {
MFC_RdAtomicStat = 0x1B, // MFC Read Atomic Command Status
};
enum MFCCommand {
// MFC DMA Command flags
MFC_BARRIER_ENABLE = 0x0001,
MFC_FENCE_ENABLE = 0x0002,
MFC_LIST_ENABLE = 0x0004, // SPU Only
MFC_START_ENABLE = 0x0008, // PU Only
MFC_RESULT_ENABLE = 0x0010,
// MFC DMA Put Commands
MFC_PUT_CMD = 0x0020,
MFC_PUTS_CMD = 0x0028, // PU Only
MFC_PUTR_CMD = 0x0030,
MFC_PUTF_CMD = 0x0022,
MFC_PUTB_CMD = 0x0021,
MFC_PUTFS_CMD = 0x002A, // PU Only
MFC_PUTBS_CMD = 0x0029, // PU Only
MFC_PUTRF_CMD = 0x0032,
MFC_PUTRB_CMD = 0x0031,
MFC_PUTL_CMD = 0x0024, // SPU Only
MFC_PUTRL_CMD = 0x0034, // SPU Only
MFC_PUTLF_CMD = 0x0026, // SPU Only
MFC_PUTLB_CMD = 0x0025, // SPU Only
MFC_PUTRLF_CMD = 0x0036, // SPU Only
MFC_PUTRLB_CMD = 0x0035, // SPU Only
// MFC DMA Get Commands
MFC_GET_CMD = 0x0040,
MFC_GETS_CMD = 0x0048, // PU Only
MFC_GETF_CMD = 0x0042,
MFC_GETB_CMD = 0x0041,
MFC_GETFS_CMD = 0x004A, // PU Only
MFC_GETBS_CMD = 0x0049, // PU Only
MFC_GETL_CMD = 0x0044, // SPU Only
MFC_GETLF_CMD = 0x0046, // SPU Only
MFC_GETLB_CMD = 0x0045, // SPU Only
// MFC Synchronization Commands
MFC_SNDSIG_CMD = 0x00A0,
MFC_SNDSIGB_CMD = 0x00A1,
MFC_SNDSIGF_CMD = 0x00A2,
MFC_BARRIER_CMD = 0x00C0,
MFC_EIEIO_CMD = 0x00C8,
MFC_SYNC_CMD = 0x00CC,
// MFC Atomic Commands
MFC_GETLLAR_CMD = 0x00D0, // SPU Only
MFC_PUTLLC_CMD = 0x00B4, // SPU Only
MFC_PUTLLUC_CMD = 0x00B0, // SPU Only
MFC_PUTQLLUC_CMD = 0x00B8, // SPU Only
};
class MFC {
public:
// Registers
union {
U64 ea;
struct {
U32 eah;
U32 eal;
};
};
union {
U32 size_tag;
struct {
U16 tag;
U16 size;
};
};
U32 lsa;
};
class alignas(16) SPUState {
public:
V128 r[128]; // General-Purpose Registers
V128 s[128]; // Special-Purpose Registers
U32 pc; // Program Counter
MFC mfc; // Memory Flow Controller
};
} // namespace spu

View file

@ -8,6 +8,7 @@
#include "nucleus/cpu/cell.h"
#include "nucleus/cpu/frontend/spu/spu_state.h"
#include "nucleus/cpu/frontend/spu/spu_decoder.h"
#include "nucleus/assert.h"
namespace cpu {
namespace frontend {
@ -58,6 +59,30 @@ void SPUThread::stop() {
m_event = NUCLEUS_EVENT_STOP;
}
/*void SPUThread::dmaTransfer(U32 cmd, U32 eal, U32 lsa, U32 size) {
if (cmd & (MFC_BARRIER_ENABLE | MFC_FENCE_ENABLE)) {
#ifdef NUCLEUS_ARCH_X86
_mm_mfence();
#endif
}
const auto& memory = parent->memory;
switch (cmd & ~(MFC_BARRIER_ENABLE | MFC_FENCE_ENABLE)) {
case MFC_PUT_CMD:
case MFC_PUTR_CMD:
memcpy(memory->ptr(eal), memory->ptr(lsa), size);
break;
case MFC_GET_CMD:
memcpy(memory->ptr(lsa), memory->ptr(eal), size);
break;
default:
assert_true("Unexpected");
}
}
void dmaTransferList() {
}*/
} // namespace spu
} // namespace frontend
} // namespace cpu

View file

@ -29,6 +29,9 @@ public:
virtual void run() override;
virtual void pause() override;
virtual void stop() override;
/*void dmaTransfer(U32 cmd);
void dmaTransferList(U32 cmd, U32 eal, U32 lsa, U32 size);*/
};
} // namespace ppu

View file

@ -8,6 +8,7 @@
#include "nucleus/compiler.h"
#include "nucleus/types.h"
// Swap endianness macros
#ifdef NUCLEUS_COMPILER_MSVC
#define SE16(val) _byteswap_ushort(val)
#define SE32(val) _byteswap_ulong(val)

View file

@ -5,6 +5,7 @@
#pragma once
// Target detection
#if defined(__ANDROID__)
#define NUCLEUS_TARGET_ANDROID
#endif