mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 05:45:38 +00:00
Core: Add constexpr MIPS Encoder
From https://raw.githubusercontent.com/grumpycoders/pcsx-redux/main/src/mips/common/util/encoder.hh
This commit is contained in:
parent
71738d12e0
commit
9e09f53566
|
@ -2735,6 +2735,31 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<h3>MIPS Encoder - <a href="https://raw.githubusercontent.com/grumpycoders/pcsx-redux/main/src/mips/common/util/encoder.hh">https://raw.githubusercontent.com/grumpycoders/pcsx-redux/main/src/mips/common/util/encoder.hh</a></h3>
|
||||||
|
<pre>
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 PCSX-Redux authors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
</pre>
|
||||||
|
|
||||||
Some shaders provided with the application are sourced from:
|
Some shaders provided with the application are sourced from:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/Matsilagi/RSRetroArch/">https://github.com/Matsilagi/RSRetroArch/</a></li>
|
<li><a href="https://github.com/Matsilagi/RSRetroArch/">https://github.com/Matsilagi/RSRetroArch/</a></li>
|
||||||
|
|
|
@ -81,6 +81,7 @@ add_library(core
|
||||||
memory_card.h
|
memory_card.h
|
||||||
memory_card_image.cpp
|
memory_card_image.cpp
|
||||||
memory_card_image.h
|
memory_card_image.h
|
||||||
|
mips_encoder.h
|
||||||
multitap.cpp
|
multitap.cpp
|
||||||
multitap.h
|
multitap.h
|
||||||
negcon.cpp
|
negcon.cpp
|
||||||
|
|
227
src/core/mips_encoder.h
Normal file
227
src/core/mips_encoder.h
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 PCSX-Redux authors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
Sourced from https://raw.githubusercontent.com/grumpycoders/pcsx-redux/main/src/mips/common/util/encoder.hh
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace Mips {
|
||||||
|
namespace Encoder {
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
enum class Reg {
|
||||||
|
R0, AT, V0, V1, A0, A1, A2, A3, // 00 to 07
|
||||||
|
T0, T1, T2, T3, T4, T5, T6, T7, // 08 to 0f
|
||||||
|
S0, S1, S2, S3, S4, S5, S6, S7, // 10 to 17
|
||||||
|
T8, T9, K0, K1, GP, SP, S8, RA, // 18 to 1f
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
constexpr uint32_t iclass(uint32_t v) { return v << 26; }
|
||||||
|
constexpr uint32_t dstVal(Reg r) { return uint32_t(r) << 11; }
|
||||||
|
constexpr uint32_t tgtVal(Reg r) { return uint32_t(r) << 16; }
|
||||||
|
constexpr uint32_t srcVal(Reg r) { return uint32_t(r) << 21; }
|
||||||
|
|
||||||
|
// ALU
|
||||||
|
constexpr uint32_t add(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100000; }
|
||||||
|
constexpr uint32_t addu(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100001; }
|
||||||
|
constexpr uint32_t addi(Reg tgt, Reg src, int16_t value) {
|
||||||
|
uint32_t v = value;
|
||||||
|
v &= 0xffff;
|
||||||
|
return iclass(0b001000) | srcVal(src) | tgtVal(tgt) | v;
|
||||||
|
}
|
||||||
|
constexpr uint32_t addiu(Reg tgt, Reg src, int16_t value) {
|
||||||
|
uint32_t v = value;
|
||||||
|
v &= 0xffff;
|
||||||
|
return iclass(0b001001) | srcVal(src) | tgtVal(tgt) | v;
|
||||||
|
}
|
||||||
|
constexpr uint32_t andd(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100100; }
|
||||||
|
constexpr uint32_t andi(Reg tgt, Reg src, uint16_t value) {
|
||||||
|
return iclass(0b001100) | srcVal(src) | tgtVal(tgt) | value;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lui(Reg tgt, uint16_t value) { return iclass(0b001111) | tgtVal(tgt) | value; }
|
||||||
|
constexpr uint32_t nor(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100111; }
|
||||||
|
constexpr uint32_t orr(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100101; }
|
||||||
|
constexpr uint32_t ori(Reg tgt, Reg src, uint16_t value) {
|
||||||
|
return iclass(0b001101) | srcVal(src) | tgtVal(tgt) | value;
|
||||||
|
}
|
||||||
|
constexpr uint32_t slt(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b101010; }
|
||||||
|
constexpr uint32_t sltu(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b101011; }
|
||||||
|
constexpr uint32_t slti(Reg tgt, Reg src, int16_t value) {
|
||||||
|
uint32_t v = value;
|
||||||
|
v &= 0xffff;
|
||||||
|
return iclass(0b001010) | srcVal(src) | tgtVal(tgt) | v;
|
||||||
|
}
|
||||||
|
constexpr uint32_t sltiu(Reg tgt, Reg src, uint16_t value) {
|
||||||
|
return iclass(0b001011) | srcVal(src) | tgtVal(tgt) | value;
|
||||||
|
}
|
||||||
|
constexpr uint32_t sub(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100010; }
|
||||||
|
constexpr uint32_t subu(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100011; }
|
||||||
|
constexpr uint32_t xorr(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100110; }
|
||||||
|
constexpr uint32_t xori(Reg tgt, Reg src, uint16_t value) {
|
||||||
|
return iclass(0b001110) | srcVal(src) | tgtVal(tgt) | value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// shifts
|
||||||
|
constexpr uint32_t sll(Reg dst, Reg tgt, uint16_t sa) { return dstVal(dst) | tgtVal(tgt) | (sa << 6) | 0b000000; }
|
||||||
|
constexpr uint32_t sllv(Reg dst, Reg tgt, Reg src) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b000100; }
|
||||||
|
constexpr uint32_t sra(Reg dst, Reg tgt, uint16_t sa) { return dstVal(dst) | tgtVal(tgt) | (sa << 6) | 0b000011; }
|
||||||
|
constexpr uint32_t srav(Reg dst, Reg tgt, Reg src) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b000111; }
|
||||||
|
constexpr uint32_t srl(Reg dst, Reg tgt, uint16_t sa) { return dstVal(dst) | tgtVal(tgt) | (sa << 6) | 0b000010; }
|
||||||
|
constexpr uint32_t srlv(Reg dst, Reg tgt, Reg src) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b000110; }
|
||||||
|
|
||||||
|
// mults
|
||||||
|
constexpr uint32_t div(Reg src, Reg tgt) { return tgtVal(tgt) | srcVal(src) | 0b011010; }
|
||||||
|
constexpr uint32_t divu(Reg src, Reg tgt) { return tgtVal(tgt) | srcVal(src) | 0b011011; }
|
||||||
|
constexpr uint32_t mfhi(Reg dst) { return dstVal(dst) | 0b010000; }
|
||||||
|
constexpr uint32_t mflo(Reg dst) { return dstVal(dst) | 0b010010; }
|
||||||
|
constexpr uint32_t mthi(Reg dst) { return dstVal(dst) | 0b010001; }
|
||||||
|
constexpr uint32_t mtlo(Reg dst) { return dstVal(dst) | 0b010011; }
|
||||||
|
constexpr uint32_t mult(Reg src, Reg tgt) { return tgtVal(tgt) | srcVal(src) | 0b011000; }
|
||||||
|
constexpr uint32_t multu(Reg src, Reg tgt) { return tgtVal(tgt) | srcVal(src) | 0b011001; }
|
||||||
|
|
||||||
|
// branches
|
||||||
|
constexpr uint32_t beq(Reg src, Reg tgt, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000100) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t bgez(Reg src, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000001) | tgtVal(Reg(0b00001)) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t bgezal(Reg src, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000001) | tgtVal(Reg(0b10001)) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t bgtz(Reg src, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000111) | tgtVal(Reg(0b00000)) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t blez(Reg src, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000110) | tgtVal(Reg(0b00000)) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t bltz(Reg src, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000001) | tgtVal(Reg(0b00000)) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t bltzal(Reg src, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000001) | tgtVal(Reg(0b10000)) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t bne(Reg src, Reg tgt, int16_t offset) {
|
||||||
|
uint32_t o = offset >> 2;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b000101) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t brk(uint32_t code) { return (code << 6) | 0b001101; }
|
||||||
|
constexpr uint32_t j(uint32_t addr) { return iclass(0b000010) | ((addr >> 2) & 0x03ffffff); }
|
||||||
|
constexpr uint32_t jal(uint32_t addr) { return iclass(0b000011) | ((addr >> 2) & 0x03ffffff); }
|
||||||
|
constexpr uint32_t jalr(Reg src, Reg dst = Reg::RA) { return dstVal(dst) | srcVal(src) | 0b001001; }
|
||||||
|
constexpr uint32_t jr(Reg src) { return srcVal(src) | 0b001000; }
|
||||||
|
constexpr uint32_t syscall() { return 0b001100; }
|
||||||
|
|
||||||
|
// memory
|
||||||
|
constexpr uint32_t lb(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100000) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lbu(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100100) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lh(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100001) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lhu(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100101) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lw(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100011) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lwl(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100010) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t lwr(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b100110) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t sb(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b101000) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t sh(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b101001) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t sw(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b101011) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t swl(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b101010) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
constexpr uint32_t swr(Reg tgt, int16_t offset, Reg src) {
|
||||||
|
uint32_t o = offset;
|
||||||
|
o &= 0xffff;
|
||||||
|
return iclass(0b101110) | tgtVal(tgt) | srcVal(src) | o;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cop0
|
||||||
|
constexpr uint32_t mfc0(Reg tgt, uint8_t dst) { return iclass(0b010000) | tgtVal(tgt) | (dst << 11); }
|
||||||
|
constexpr uint32_t mtc0(Reg tgt, uint8_t dst) { return iclass(0b010000) | (4 << 21) | tgtVal(tgt) | (dst << 11); }
|
||||||
|
constexpr uint32_t rfe() { return 0x42000010; }
|
||||||
|
|
||||||
|
// pseudo
|
||||||
|
constexpr uint32_t nop() { return 0; }
|
||||||
|
|
||||||
|
} // namespace Encoder
|
||||||
|
} // namespace Mips
|
Loading…
Reference in a new issue