mirror of
https://github.com/AlexAltea/nucleus.git
synced 2024-06-11 16:57:40 -04:00
SPU assembler rdch/wrch fixes and MFC commands
This commit is contained in:
parent
bcc58db504
commit
0d6b48739e
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Architecture detection
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(_X86_)
|
||||
#define NUCLEUS_ARCH_X86_32BITS
|
||||
#endif
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Target detection
|
||||
#if defined(__ANDROID__)
|
||||
#define NUCLEUS_TARGET_ANDROID
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue