Merge branch 'pontos2024:master' into master

This commit is contained in:
izzy2lost
2025-08-22 04:12:51 -04:00
committed by GitHub
47 changed files with 1208 additions and 740 deletions
+1 -1
View File
@@ -4,6 +4,6 @@
* It is still unfinished because I made it while studying due to my lack of experience with assembler.
* I think it would be good to look at it for reference.
* https://www.youtube.com/watch?v=ACxMJufB1EM
* [https://www.youtube.com/watch?v=ACxMJufB1EM](https://youtu.be/hNc3k3wPyTM)
![Image](https://github.com/user-attachments/assets/534405ee-c622-4726-876b-31f398bbb46d)
+1 -8
View File
@@ -124,8 +124,6 @@ if(_M_X86)
)
else()
target_sources(common PRIVATE
arm64/AsmHelpers.cpp
arm64/AsmHelpers.h
emitter/x86emitter.cpp
emitter/x86emitter.h
emitter/x86types.h
@@ -216,7 +214,6 @@ if(NOT WIN32)
endif()
if(ANDROID)
target_link_libraries(common INTERFACE vixl)
target_link_libraries(common PRIVATE
${LIBC_LIBRARIES}
jpeg
@@ -248,11 +245,7 @@ endif()
fixup_file_properties(common)
target_compile_features(common PUBLIC cxx_std_20)
if(ANDROID)
target_include_directories(common PUBLIC ../3rdparty/include ../3rdparty/vixl/include ../)
else()
target_include_directories(common PUBLIC ../3rdparty/include ../)
endif()
target_include_directories(common PUBLIC ../3rdparty/include ../3rdparty/vixl/include ../)
target_compile_definitions(common PUBLIC "${PCSX2_DEFS}")
target_compile_options(common PRIVATE "${PCSX2_WARNINGS}")
+46 -5
View File
@@ -998,7 +998,16 @@ std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode, Error*
return fp;
#else
std::FILE* fp = std::fopen(filename, mode);
std::FILE* fp;
////
std::string _filename(filename);
if (_filename.rfind("content://", 0) == 0) {
fp = fdopen(FileSystem::OpenFDFileContent(_filename.c_str()), "rb");
} else {
fp = std::fopen(_filename.c_str(), mode);
}
////
if (!fp)
Error::SetErrno(error, errno);
return fp;
@@ -1010,7 +1019,15 @@ std::FILE* FileSystem::OpenCFileTryIgnoreCase(const char* filename, const char*
#if defined(_WIN32) || defined(__APPLE__)
return OpenCFile(filename, mode, error);
#else
std::FILE* fp = std::fopen(filename, mode);
std::FILE* fp;
////
std::string _filename(filename);
if (_filename.rfind("content://", 0) == 0) {
fp = fdopen(FileSystem::OpenFDFileContent(_filename.c_str()), "rb");
} else {
fp = std::fopen(_filename.c_str(), mode);
}
////
const auto cur_errno = errno;
if (!fp)
@@ -1023,7 +1040,13 @@ std::FILE* FileSystem::OpenCFileTryIgnoreCase(const char* filename, const char*
{
if (StringUtil::compareNoCase(file.FileName, filename))
{
fp = std::fopen(file.FileName.c_str(), mode);
////
if (file.FileName.rfind("content://", 0) == 0) {
fp = fdopen(FileSystem::OpenFDFileContent(file.FileName.c_str()), "rb");
} else {
fp = std::fopen(file.FileName.c_str(), mode);
}
////
break;
}
}
@@ -1045,7 +1068,16 @@ int FileSystem::OpenFDFile(const char* filename, int flags, int mode, Error* err
return -1;
#else
const int fd = open(filename, flags, mode);
int fd;
////
std::string _filename(filename);
if (_filename.rfind("content://", 0) == 0) {
fd = FileSystem::OpenFDFileContent(_filename.c_str());
} else {
fd = open(_filename.c_str(), flags, mode);
}
////
if (fd < 0)
Error::SetErrno(error, errno);
return fd;
@@ -1095,7 +1127,16 @@ std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, F
Error::SetErrno(error, errno);
return nullptr;
#else
std::FILE* fp = std::fopen(filename, mode);
std::FILE* fp;
////
std::string _filename(filename);
if (_filename.rfind("content://", 0) == 0) {
fp = fdopen(FileSystem::OpenFDFileContent(_filename.c_str()), "rb");
} else {
fp = std::fopen(_filename.c_str(), mode);
}
////
if (!fp)
Error::SetErrno(error, errno);
return fp;
+2 -2
View File
@@ -28,7 +28,7 @@ static constexpr bool IsDebugBuild = false;
static constexpr unsigned int __pagesize = OVERRIDE_HOST_PAGE_SIZE;
static constexpr unsigned int __pagemask = __pagesize - 1;
static constexpr unsigned int __pageshift = std::bit_width(__pagemask);
#elif defined(_M_ARM64)
#elif defined(_M_ARM64) && !defined(ANDROID)
// Apple Silicon uses 16KB pages and 128 byte cache lines.
static constexpr unsigned int __pagesize = 0x4000;
static constexpr unsigned int __pageshift = 14;
@@ -41,7 +41,7 @@ static constexpr bool IsDebugBuild = false;
#endif
#if defined(OVERRIDE_HOST_CACHE_LINE_SIZE)
static constexpr unsigned int __cachelinesize = OVERRIDE_HOST_CACHE_LINE_SIZE;
#elif defined(_M_ARM64)
#elif defined(_M_ARM64) && !defined(ANDROID)
static constexpr unsigned int __cachelinesize = 128;
#else
static constexpr unsigned int __cachelinesize = 64;
@@ -18,6 +18,7 @@
#if defined(__ANDROID__)
#include "common/emitter/x86types.h"
#else
#include "common/emitter/internal.h"
#endif
+4 -1
View File
@@ -6,7 +6,10 @@
#include "common/Threading.h"
#include "common/Assertions.h"
#include "common/Pcsx2Defs.h"
#include "common/arm64/AsmHelpers.h"
#include "vixl/aarch64/constants-aarch64.h"
#include "vixl/aarch64/macro-assembler-aarch64.h"
namespace a64 = vixl::aarch64;
static const uint iREGCNT_XMM = 16;
#if defined(__ANDROID__)
+4 -4
View File
@@ -1056,13 +1056,13 @@ set(pcsx2x86Headers
set(pcsx2arm64Sources
arm64/Vif_Dynarec.cpp
arm64/Vif_UnpackNEON.cpp
# arm64/AsmHelpers.cpp
arm64/VixlHelpers.cpp
# arm64/RecStubs.cpp
)
#set(pcsx2arm64Headers
# arm64/AsmHelpers.h
#)
set(pcsx2arm64Headers
arm64/VixlHelpers.h
)
# These ones benefit a lot from LTO
set(pcsx2LTOSources
+1
View File
@@ -3,6 +3,7 @@
#pragma once
#include "arm64/VixlHelpers.h"
#include "common/Pcsx2Defs.h"
static const u32 BIAS = 2; // Bus is half of the actual ps2 speed
+1 -1
View File
@@ -9,7 +9,7 @@
#include <thread>
VU_Thread vu1Thread;
//VU_Thread vu1Thread;
#define MTVU_ALWAYS_KICK 0
#define MTVU_SYNC_MODE 0
+1 -1
View File
@@ -120,4 +120,4 @@ private:
u32 Get_vuCycles();
};
extern VU_Thread vu1Thread;
extern VU_Thread& vu1Thread;
+2
View File
@@ -603,6 +603,8 @@ Pcsx2Config::CpuOptions::CpuOptions()
VU0FPCR = DEFAULT_VU_FP_CONTROL_REGISTER;
VU1FPCR = DEFAULT_VU_FP_CONTROL_REGISTER;
ExtraMemory = false;
////
g_cpuRegistersPack.Cpu = *this;
}
void Pcsx2Config::CpuOptions::ApplySanityCheck()
+1 -1
View File
@@ -3,7 +3,7 @@
#pragma once
#include "cpuRegistersPack.h"
#include "arm64/VixlHelpers.h"
#ifndef _PC_
+5 -1
View File
@@ -34,7 +34,7 @@ using namespace R5900; // for R5900 disasm tools
s32 EEsCycle; // used to sync the IOP to the EE
u32 EEoCycle;
alignas(16) cpuRegistersPack g_cpuRegistersPack;
alignas(64) cpuRegistersPack g_cpuRegistersPack;
alignas(16) tlbs tlb[48];
cachedTlbs_t cachedTlbs;
@@ -58,6 +58,10 @@ uptr g_argPtrs[kMaxArgs];
void cpuReset()
{
//// cpuRegistersPack -> VIFregisters
g_cpuRegistersPack.vifRegs[0] = vif0Regs;
g_cpuRegistersPack.vifRegs[1] = vif1Regs;
////
std::memset(&cpuRegs, 0, sizeof(cpuRegs));
std::memset(&fpuRegs, 0, sizeof(fpuRegs));
std::memset(&tlb, 0, sizeof(tlb));
+1 -1
View File
@@ -3,7 +3,7 @@
#pragma once
#include "cpuRegistersPack.h"
#include "arm64/VixlHelpers.h"
#include <array>
// --------------------------------------------------------------------------------------
+124
View File
@@ -170,4 +170,128 @@ struct alignas(16) VURegs
}
};
struct mVU_Globals
{
#define __four(val) { val, val, val, val }
u32 absclip [4] = __four(0x7fffffff);
u32 signbit [4] = __four(0x80000000);
u32 minvals [4] = __four(0xff7fffff);
u32 maxvals [4] = __four(0x7f7fffff);
u32 exponent[4] = __four(0x7f800000);
u32 one [4] = __four(0x3f800000);
u32 Pi4 [4] = __four(0x3f490fdb);
u32 T1 [4] = __four(0x3f7ffff5);
u32 T5 [4] = __four(0xbeaaa61c);
u32 T2 [4] = __four(0x3e4c40a6);
u32 T3 [4] = __four(0xbe0e6c63);
u32 T4 [4] = __four(0x3dc577df);
u32 T6 [4] = __four(0xbd6501c4);
u32 T7 [4] = __four(0x3cb31652);
u32 T8 [4] = __four(0xbb84d7e7);
u32 S2 [4] = __four(0xbe2aaaa4);
u32 S3 [4] = __four(0x3c08873e);
u32 S4 [4] = __four(0xb94fb21f);
u32 S5 [4] = __four(0x362e9c14);
u32 E1 [4] = __four(0x3e7fffa8);
u32 E2 [4] = __four(0x3d0007f4);
u32 E3 [4] = __four(0x3b29d3ff);
u32 E4 [4] = __four(0x3933e553);
u32 E5 [4] = __four(0x36b63510);
u32 E6 [4] = __four(0x353961ac);
u32 I32MAXF [4] = __four(0x4effffff);
float FTOI_4 [4] = __four(16.0);
float FTOI_12 [4] = __four(4096.0);
float FTOI_15 [4] = __four(32768.0);
float ITOF_4 [4] = __four(0.0625f);
float ITOF_12 [4] = __four(0.000244140625);
float ITOF_15 [4] = __four(0.000030517578125);
#undef __four
};
#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant))
#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL))
struct FPUd_Globals
{
u32 neg[4], pos[4];
u32 pos_inf[4], neg_inf[4],
one_exp[4];
u64 dbl_one_exp[2];
u64 dbl_cvt_overflow, // needs special code if above or equal
dbl_ps2_overflow, // overflow & clamp if above or equal
dbl_underflow; // underflow if below
u64 padding;
u64 dbl_s_pos[2];
//u64 dlb_s_neg[2];
};
struct SSEMasks
{
u32 MIN_MAX_1[4], MIN_MAX_2[4], ADD_SS[4];
};
struct mVU_SSE4
{
u32 sse4_minvals[2][4] = {
{0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000
{0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111
};
u32 sse4_maxvals[2][4] = {
{0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000
{0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
};
////
u32 sse4_compvals[2][4] = {
{0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111
};
////
u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff};
u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff};
////
u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff};
u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff};
////
u32 result[4] = { 0x3f490fda };
////
u32 minmax_mask[8] =
{
0xffffffff, 0x80000000, 0, 0,
0, 0x40000000, 0, 0,
};
////
FPUd_Globals s_const =
{
{0x80000000, 0xffffffff, 0xffffffff, 0xffffffff},
{0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff},
{SINGLE(0, 0xff, 0), 0, 0, 0},
{SINGLE(1, 0xff, 0), 0, 0, 0},
{SINGLE(0, 1, 0), 0, 0, 0},
{DOUBLE(0, 1, 0), 0},
DOUBLE(0, 1151, 0), // cvt_overflow
DOUBLE(0, 1152, 0), // ps2_overflow
DOUBLE(0, 897, 0), // underflow
0, // Padding!!
{0x7fffffffffffffffULL, 0},
//{0x8000000000000000ULL, 0},
};
////
SSEMasks sseMasks =
{
{0xffffffff, 0x80000000, 0xffffffff, 0x80000000},
{0x00000000, 0x40000000, 0x00000000, 0x40000000},
{0x80000000, 0xffffffff, 0xffffffff, 0xffffffff},
};
};
#endif //PCSX2_VUDEF_H
+272
View File
@@ -0,0 +1,272 @@
//
// Created by k2154 on 2025-08-20.
//
#ifndef PCSX2_SHUFFLELANES_H
#define PCSX2_SHUFFLELANES_H
#include <cstdint>
struct ShuffleLanes
{
__uint8_t data[256][2][16] = {
{{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}},
{{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}},
{{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}},
{{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}},
{{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}},
{{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}},
{{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}},
{{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}},
{{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}},
{{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}},
{{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}},
{{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}},
{{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}},
{{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}},
{{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}},
{{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}},
{{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}},
{{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}},
{{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}},
{{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}},
{{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}},
{{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}},
{{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}},
{{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}},
{{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}},
{{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}},
{{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}},
{{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}},
{{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}},
{{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}},
{{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}},
{{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}},
{{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}},
{{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}},
{{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}},
{{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}},
{{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}},
{{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}},
{{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}},
{{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}},
{{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}},
{{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}},
{{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}},
{{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}},
{{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}},
{{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}},
{{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}},
{{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}},
{{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}},
{{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}},
{{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}},
{{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}},
{{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}},
{{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}},
{{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}},
{{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}},
{{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}},
{{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}},
{{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}},
{{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}},
{{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}},
{{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}},
{{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}},
{{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}},
{{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}},
{{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}},
{{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}},
{{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}},
{{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}},
{{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}},
{{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}},
{{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}},
{{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}},
{{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}},
{{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}},
{{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}},
{{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}},
{{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}},
{{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}},
{{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}},
{{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}},
{{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}},
{{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}},
{{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}},
{{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}},
{{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}},
{{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}},
{{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}},
{{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}},
{{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}},
{{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}},
{{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}},
{{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}},
{{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}},
{{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}},
{{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}},
{{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}},
{{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}},
{{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}},
{{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}},
{{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}},
{{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}},
{{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}},
{{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}},
{{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}},
{{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}},
{{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}},
{{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}},
{{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}},
{{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}},
{{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}},
{{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}},
{{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}},
{{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}},
{{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}},
{{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}},
{{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}},
{{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}},
{{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}},
{{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}},
{{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}},
{{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}},
{{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}},
{{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}},
{{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}},
{{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}},
{{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}},
{{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}},
{{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}},
{{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}},
{{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}},
{{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}},
{{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}},
{{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}},
{{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}},
{{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}},
{{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}},
{{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}},
{{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}},
{{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}},
{{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}},
{{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}},
{{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}},
{{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}},
{{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}},
{{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}},
{{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}},
{{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}},
{{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}},
{{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}},
{{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}},
{{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}},
{{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}},
{{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}},
{{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}},
{{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}},
{{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}},
{{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}},
{{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}},
{{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}},
{{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}},
{{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}},
{{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}},
{{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}},
{{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}},
{{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}},
{{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}},
{{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}},
{{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}},
{{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}},
{{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}},
{{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}},
{{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}},
{{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}},
{{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}},
{{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}},
{{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}},
{{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}},
{{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}},
{{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}},
{{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}},
{{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}},
{{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}},
{{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}},
{{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}},
{{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}},
{{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}},
{{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}},
{{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}},
{{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}},
{{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}},
{{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}},
{{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}},
{{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}},
{{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}},
{{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}},
{{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}},
{{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}},
{{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}},
{{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}},
{{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}},
{{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}},
{{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}},
{{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}},
{{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}},
{{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}},
{{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}},
{{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}},
{{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}},
{{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}},
{{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}},
{{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}},
{{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}},
{{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}},
{{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}},
{{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}},
{{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}},
{{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}},
{{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}},
{{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}},
{{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}},
{{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}},
{{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}},
{{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}},
{{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}},
{{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}},
{{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}},
{{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}},
{{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}},
{{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}},
{{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}},
{{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}},
{{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}},
{{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}},
{{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}},
{{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}},
{{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}},
{{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}},
{{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}},
{{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}},
{{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}},
{{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}},
{{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}},
{{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}},
{{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}},
{{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}},
{{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}},
{{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}},
{{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}},
{{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}},
{{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}},
{{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}}
};
};
#endif //PCSX2_SHUFFLELANES_H
@@ -6,7 +6,7 @@
#include "Common.h"
#include "Vif_Dma.h"
#include "Vif_Dynarec.h"
#include "common/arm64/AsmHelpers.h"
#include "VixlHelpers.h"
#define xmmCol0 vixl::aarch64::q2
#define xmmCol1 vixl::aarch64::q3
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0
#include "common/arm64/AsmHelpers.h"
#include "VixlHelpers.h"
#include "common/Assertions.h"
#include "common/BitUtils.h"
@@ -160,7 +160,8 @@ void armEmitJmp(const void* ptr, bool force_inline)
if (use_blr)
{
armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast<uintptr_t>(ptr));
armAsm->Mov(RXVIXLSCRATCH, (uptr)ptr);
// armAsm->Ldr(RXVIXLSCRATCH, (uptr)ptr);
armAsm->Br(RXVIXLSCRATCH);
}
else
@@ -185,7 +186,8 @@ void armEmitCall(const void* ptr, bool force_inline)
if (use_blr)
{
armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast<uintptr_t>(ptr));
armAsm->Mov(RXVIXLSCRATCH, (uptr)ptr);
// armAsm->Ldr(RXVIXLSCRATCH, (uptr)ptr);
armAsm->Blr(RXVIXLSCRATCH);
}
else
@@ -275,6 +277,16 @@ void armMoveAddressToReg(const a64::Register& reg, const void* addr)
}
}
void armCbz(const a64::Register& reg, a64::Label* p_label)
{
armAsm->Cbz(reg, p_label);
}
void armCbnz(const a64::Register& reg, a64::Label* p_label)
{
armAsm->Cbnz(reg, p_label);
}
void armLoadPtr(const a64::CPURegister& reg, const void* addr)
{
armMoveAddressToReg(RSCRATCHADDR, addr);
@@ -584,6 +596,12 @@ a64::VRegister armLoadPtrV(const void* addr)
return RQSCRATCH;
}
a64::VRegister armLoadPtrM(const a64::MemOperand offset)
{
armAsm->Ldr(RQSCRATCH, offset);
return RQSCRATCH;
}
a64::VRegister armLoadPtrM(a64::Register regRs, int64_t offset)
{
armAsm->Ldr(RQSCRATCH, a64::MemOperand(regRs, offset));
@@ -997,67 +1015,17 @@ void armPMOVMSKB(const a64::Register& regDst, const a64::VRegister& regSrc)
void armSHUFPS(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex)
{
armShuffle(dstreg, srcreg, pIndex, true);
armAsm->Mov(RQSCRATCH3, armLoadPtrV(PTR_CPU(shuffle.data[pIndex][1])).Q());
////
armAsm->Mov(RQSCRATCH2, srcreg);
armAsm->Mov(RQSCRATCH, dstreg);
armAsm->Tbx(dstreg.V16B(), RQSCRATCH.V16B(), RQSCRATCH2.V16B(), RQSCRATCH3.V16B());
}
void armPSHUFD(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex)
{
armShuffle(dstreg, srcreg, pIndex, false);
}
void armShuffleTblx(const a64::VRegister& p_dst, const a64::VRegister& p_src, int p_a, int p_b, int p_c, int p_d, bool p_is_tbx)
{
uint8_t lanes[16];
int i, s, e, nIndex = 0;
int lanesTbx = 0;
if(p_is_tbx) {
lanesTbx = 16;
}
// 0, 4, 8, 12
// 0 * 4 = 0, 1 * 4 = 4, 2 * 4 = 8, 3 * 4 = 12
// lanes 16 => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
s = p_a << 2; e = s + 4;
for(i=s; i<e; ++i) {
lanes[nIndex++] = i;
}
////
s = p_b << 2; e = s + 4;
for(i=s; i<e; ++i) {
lanes[nIndex++] = i;
}
////
s = p_c << 2; e = s + 4;
for(i=s; i<e; ++i) {
lanes[nIndex++] = i + lanesTbx;
}
////
s = p_d << 2; e = s + 4;
for(i=s; i<e; ++i) {
lanes[nIndex++] = i + lanesTbx;
}
armLoadConstant128(RQSCRATCH3, lanes);
if(p_is_tbx) {
armAsm->Mov(RQSCRATCH, p_dst);
armAsm->Mov(RQSCRATCH2, p_src);
armAsm->Tbx(p_dst.V16B(), RQSCRATCH.V16B(), RQSCRATCH2.V16B(), RQSCRATCH3.V16B());
} else {
armAsm->Tbl(p_dst.V16B(), p_src.V16B(), RQSCRATCH3.V16B());
}
}
void armShuffle(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex, bool p_is_tbx)
{
int shuffle_0 = (pIndex >> 0) & 0x3;
int shuffle_1 = (pIndex >> 2) & 0x3;
int shuffle_2 = (pIndex >> 4) & 0x3;
int shuffle_3 = (pIndex >> 6) & 0x3;
////
armShuffleTblx(dstreg, srcreg, shuffle_0, shuffle_1, shuffle_2, shuffle_3, p_is_tbx);
armAsm->Mov(RQSCRATCH3, armLoadPtrV(PTR_CPU(shuffle.data[pIndex][0])).Q());
armAsm->Tbl(dstreg.V16B(), srcreg.V16B(), RQSCRATCH3.V16B());
}
int find_bit_pos(uint32_t p_hex_value)
@@ -3,14 +3,14 @@
#pragma once
#include <unordered_map>
#include "common/Pcsx2Defs.h"
#include "common/HashCombine.h"
#include "cpuRegistersPack.h"
#include "vixl/aarch64/constants-aarch64.h"
#include "vixl/aarch64/macro-assembler-aarch64.h"
#include <unordered_map>
namespace a64 = vixl::aarch64;
#define RWARG1 a64::w0
@@ -58,6 +58,7 @@ namespace a64 = vixl::aarch64;
// fastmem
#define RFASTMEMBASE a64::x25
// iopMem->Main
#define RSTATE_x26 a64::x26
// CPU(iR5900), PSX(iR3000A), FPU(iFPU, iFPUd)
@@ -69,9 +70,12 @@ namespace a64 = vixl::aarch64;
#define RSTATE_MVU a64::x28
#define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field))
// iopMem->Main
// recLUT, psxRecLUT
#define RSTATE_x29 a64::x29
// eeHw[Ps2MemSize::Hardware]
#define psHu(mem) (mem & 0xffff)
static inline s64 GetPCDisplacement(const void* current, const void* target)
{
return static_cast<s64>((reinterpret_cast<ptrdiff_t>(target) - reinterpret_cast<ptrdiff_t>(current)) >> 2);
@@ -118,6 +122,8 @@ void armEmitCall(const void* ptr, bool force_inline = false);
void armEmitCbnz(const a64::Register& reg, const void* ptr);
void armEmitCondBranch(a64::Condition cond, const void* ptr);
void armMoveAddressToReg(const a64::Register& reg, const void* addr);
void armCbz(const a64::Register& reg, a64::Label* p_label);
void armCbnz(const a64::Register& reg, a64::Label* p_label);
void armLoadPtr(const a64::CPURegister& reg, const void* addr);
void armStorePtr(const a64::CPURegister& reg, const void* addr);
void armBeginStackFrame(bool save_fpr=true);
@@ -191,6 +197,7 @@ void armLoadPtr(const a64::CPURegister& regRt, a64::Register regRs, int64_t offs
void armLoadPtr(uint64_t imm, const void* addr, const a64::Register& reg=EEX);
void armLoadPtr(uint64_t imm, a64::Register regRs, int64_t offset, const a64::Register& regRt=EEX);
a64::VRegister armLoadPtrV(const void* addr);
a64::VRegister armLoadPtrM(const a64::MemOperand offset);
a64::VRegister armLoadPtrM(a64::Register regRs, int64_t offset=0);
void armStorePtr(const a64::CPURegister& reg, const void* addr, int64_t offset);
void armStorePtr(const a64::CPURegister& regRt, a64::Register regRs, int64_t offset);
@@ -252,7 +259,6 @@ void armPMOVMSKB(const a64::Register& regDst, const a64::VRegister& regSrc);
void armSHUFPS(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex);
void armPSHUFD(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex);
void armShuffleTblx(const a64::VRegister& p_dst, const a64::VRegister& p_src, int p_a, int p_b, int p_c, int p_d, bool p_is_tbx);
void armShuffle(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex, bool p_is_tbx);
void armShuffleTblx(const a64::VRegister& p_dst, const a64::VRegister& p_src, int pIndex, bool p_is_tbx);
int find_bit_pos(uint32_t p_hex_value);
@@ -5,18 +5,27 @@
#ifndef PCSX2_CPUREGISTERSPACK_H
#define PCSX2_CPUREGISTERSPACK_H
#include "Config.h"
#include "R5900Def.h"
#include "R3000ADef.h"
#include "VUDef.h"
#include "vtlbDef.h"
#include "ShuffleLanes.h"
struct cpuRegistersPack
{
alignas(16) cpuRegisters cpuRegs{};
alignas(16) fpuRegisters fpuRegs{};
alignas(16) psxRegisters psxRegs{};
alignas(16) VIFregisters vifRegs[2]{};
alignas(16) VURegs vuRegs[2];
alignas(16) ShuffleLanes shuffle;
alignas(16) Pcsx2Config::CpuOptions Cpu;
alignas(16) mVU_SSE4 mVUss4;
alignas(32) mVU_Globals mVUglob;
alignas(64) vtlb_private::MapData vtlbdata;
};
alignas(16) extern cpuRegistersPack g_cpuRegistersPack;
alignas(64) extern cpuRegistersPack g_cpuRegistersPack;
////
static cpuRegisters& cpuRegs = g_cpuRegistersPack.cpuRegs;
static fpuRegisters& fpuRegs = g_cpuRegistersPack.fpuRegs;

Some files were not shown because too many files have changed in this diff Show More