From 4cff3e5f1ff0983e8884f2fcd74a4dd313c15445 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 7 Oct 2023 14:47:06 -0700 Subject: [PATCH] FEXCore/IR: Changes over to automated IR dispatch generation Suggested by Alyssa. Adding an IR operation can be a little tedious since you need to add the definition to JIT.cpp for the dispatch switch, JITClass.h for the function declared, and then actually defining the implementation in the correct file. Instead support the common case where an IR operation just gets dispatched through to the regular handler. This lets the developer just put the function definition in to the json and the relevent cpp file and it just gets picked up. Some minor things: - Needs to support dynamic dispatch for {Load,Store}Register and {Load,Store}Mem - This is just a bool in the json - It needs to not output JIT dispatch for some IR operations - SSE4.2 string instructions and x87 operations - These go down the "Unhandled" path - Needs to support a Dispatcher function override - This is just for handling NoOp IR operations that get used for other reasons. - Finally removes VSMul and VUMul, consolidating to VMul - Unlike V{U,S}Mull, signed or unsigned doesn't change behaviour here - Fixed a couple random handler names not matching the IR operation name. --- FEXCore/Scripts/json_ir_generator.py | 52 +++- FEXCore/Source/CMakeLists.txt | 5 +- .../Interface/Core/JIT/Arm64/BranchOps.cpp | 2 +- .../Core/JIT/Arm64/EncryptionOps.cpp | 12 +- .../Source/Interface/Core/JIT/Arm64/JIT.cpp | 267 +---------------- .../Interface/Core/JIT/Arm64/JITClass.h | 275 +----------------- .../Interface/Core/JIT/Arm64/VectorOps.cpp | 2 +- .../Interface/Core/OpcodeDispatcher.cpp | 10 +- .../Core/OpcodeDispatcher/Vector.cpp | 14 +- FEXCore/Source/Interface/IR/IR.json | 174 ++++++----- 10 files changed, 192 insertions(+), 621 deletions(-) diff --git a/FEXCore/Scripts/json_ir_generator.py b/FEXCore/Scripts/json_ir_generator.py index a87c68d0b..291eedceb 100755 --- a/FEXCore/Scripts/json_ir_generator.py +++ b/FEXCore/Scripts/json_ir_generator.py @@ -51,6 +51,9 @@ class OpDefinition: ArgPrinter: bool SSAArgNum: int NonSSAArgNum: int + DynamicDispatch: bool + JITDispatch: bool + JITDispatchOverride: str Arguments: list EmitValidation: list Desc: list @@ -69,6 +72,9 @@ class OpDefinition: self.ArgPrinter = True self.SSAArgNum = 0 self.NonSSAArgNum = 0 + self.DynamicDispatch = False + self.JITDispatch = True + self.JITDispatchOverride = None self.Arguments = [] self.EmitValidation = [] self.Desc = [] @@ -228,6 +234,15 @@ def parse_ops(ops): if "Desc" in op_val: OpDef.Desc = op_val["Desc"] + if "DynamicDispatch" in op_val: + OpDef.DynamicDispatch = bool(op_val["DynamicDispatch"]) + + if "JITDispatch" in op_val: + OpDef.JITDispatch = bool(op_val["JITDispatch"]) + + if "JITDispatchOverride" in op_val: + OpDef.JITDispatchOverride = op_val["JITDispatchOverride"] + # Do some fixups of the data here if len(OpDef.EmitValidation) != 0: for i in range(len(OpDef.EmitValidation)): @@ -730,10 +745,38 @@ def print_ir_parser_switch_helper(): output_file.write("#undef IROP_PARSER_SWITCH_HELPERS\n") output_file.write("#endif\n") -if (len(sys.argv) < 3): +def print_ir_dispatcher_defs(): + output_dispatch_file.write("#ifdef IROP_DISPATCH_DEFS\n") + for op in IROps: + if op.Name != "Last" and op.SwitchGen and op.JITDispatch and op.JITDispatchOverride == None: + output_dispatch_file.write("DEF_OP({});\n".format(op.Name)) + + output_dispatch_file.write("#undef IROP_DISPATCH_DEFS\n") + output_dispatch_file.write("#endif\n") + +def print_ir_dispatcher_dispatch(): + output_dispatch_file.write("#ifdef IROP_DISPATCH_DISPATCH\n") + for op in IROps: + if op.Name != "Last" and op.JITDispatch: + DispatchName = op.Name + if op.JITDispatchOverride != None: + DispatchName = op.JITDispatchOverride + + if (op.DynamicDispatch): + output_dispatch_file.write("REGISTER_OP_RT({}, {});\n".format(op.Name.upper(), DispatchName)) + else: + output_dispatch_file.write("REGISTER_OP({}, {});\n".format(op.Name.upper(), DispatchName)) + + output_dispatch_file.write("#undef IROP_DISPATCH_DISPATCH\n") + output_dispatch_file.write("#endif\n") + + +if (len(sys.argv) < 4): ExitError() output_filename = sys.argv[2] +output_dispatcher_filename = sys.argv[3] + json_file = open(sys.argv[1], "r") json_text = json_file.read() json_file.close() @@ -763,3 +806,10 @@ print_ir_allocator_helpers() print_ir_parser_switch_helper() output_file.close() + +output_dispatch_file = open(output_dispatcher_filename, "w") +print_ir_dispatcher_defs() +print_ir_dispatcher_dispatch() + +output_dispatch_file.close() + diff --git a/FEXCore/Source/CMakeLists.txt b/FEXCore/Source/CMakeLists.txt index 602c83090..59b69a6bd 100644 --- a/FEXCore/Source/CMakeLists.txt +++ b/FEXCore/Source/CMakeLists.txt @@ -221,15 +221,16 @@ configure_file( # Generate IR include file set(OUTPUT_IR_FOLDER "${CMAKE_BINARY_DIR}/include/FEXCore/IR") set(OUTPUT_NAME "${OUTPUT_IR_FOLDER}/IRDefines.inc") +set(OUTPUT_DISPATCHER_NAME "${OUTPUT_IR_FOLDER}/IRDefines_Dispatch.inc") set(INPUT_NAME "${CMAKE_CURRENT_SOURCE_DIR}/Interface/IR/IR.json") file(MAKE_DIRECTORY "${OUTPUT_IR_FOLDER}") add_custom_command( - OUTPUT "${OUTPUT_NAME}" + OUTPUT "${OUTPUT_NAME}" "${OUTPUT_DISPATCHER_NAME}" DEPENDS "${INPUT_NAME}" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/../Scripts/json_ir_generator.py" - COMMAND "python3" "${CMAKE_CURRENT_SOURCE_DIR}/../Scripts/json_ir_generator.py" "${INPUT_NAME}" "${OUTPUT_NAME}" + COMMAND "python3" "${CMAKE_CURRENT_SOURCE_DIR}/../Scripts/json_ir_generator.py" "${INPUT_NAME}" "${OUTPUT_NAME}" "${OUTPUT_DISPATCHER_NAME}" ) set_source_files_properties(${OUTPUT_NAME} PROPERTIES diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp index 119e97df7..e1b728c9c 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp @@ -467,7 +467,7 @@ DEF_OP(CPUID) { mov(ARMEmitter::Size::i64Bit, Dst.second, ARMEmitter::Reg::r1); } -DEF_OP(XGETBV) { +DEF_OP(XGetBV) { auto Op = IROp->C(); PushDynamicRegsAndLR(TMP1); diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp index c407947d0..6ee3510de 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp @@ -12,12 +12,12 @@ $end_info$ namespace FEXCore::CPU { #define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header const *IROp, IR::NodeID Node) -DEF_OP(AESImc) { +DEF_OP(VAESImc) { auto Op = IROp->C(); aesimc(GetVReg(Node), GetVReg(Op->Vector.ID())); } -DEF_OP(AESEnc) { +DEF_OP(VAESEnc) { const auto Op = IROp->C(); const auto OpSize = IROp->Size; @@ -44,7 +44,7 @@ DEF_OP(AESEnc) { } } -DEF_OP(AESEncLast) { +DEF_OP(VAESEncLast) { const auto Op = IROp->C(); const auto OpSize = IROp->Size; @@ -69,7 +69,7 @@ DEF_OP(AESEncLast) { } } -DEF_OP(AESDec) { +DEF_OP(VAESDec) { const auto Op = IROp->C(); const auto OpSize = IROp->Size; @@ -96,7 +96,7 @@ DEF_OP(AESDec) { } } -DEF_OP(AESDecLast) { +DEF_OP(VAESDecLast) { const auto Op = IROp->C(); const auto OpSize = IROp->Size; @@ -121,7 +121,7 @@ DEF_OP(AESDecLast) { } } -DEF_OP(AESKeyGenAssist) { +DEF_OP(VAESKeyGenAssist) { auto Op = IROp->C(); const auto Dst = GetVReg(Node); const auto Src = GetVReg(Op->Src.ID()); diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 9b2fb6f6d..27b49c9b6 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -800,272 +800,9 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, switch (IROp->Op) { #define REGISTER_OP_RT(op, x) case FEXCore::IR::IROps::OP_##op: std::invoke(RT_##x, this, IROp, ID); break #define REGISTER_OP(op, x) case FEXCore::IR::IROps::OP_##op: Op_##x(IROp, ID); break - // ALU ops - REGISTER_OP(TRUNCELEMENTPAIR, TruncElementPair); - REGISTER_OP(CONSTANT, Constant); - REGISTER_OP(ENTRYPOINTOFFSET, EntrypointOffset); - REGISTER_OP(INLINECONSTANT, InlineConstant); - REGISTER_OP(INLINEENTRYPOINTOFFSET, InlineEntrypointOffset); - REGISTER_OP(CYCLECOUNTER, CycleCounter); - REGISTER_OP(ADD, Add); - REGISTER_OP(ADDNZCV, AddNZCV); - REGISTER_OP(ADCNZCV, AdcNZCV); - REGISTER_OP(SBBNZCV, SbbNZCV); - REGISTER_OP(TESTNZ, TestNZ); - REGISTER_OP(SUB, Sub); - REGISTER_OP(SUBNZCV, SubNZCV); - REGISTER_OP(NEG, Neg); - REGISTER_OP(ABS, Abs); - REGISTER_OP(MUL, Mul); - REGISTER_OP(UMUL, UMul); - REGISTER_OP(DIV, Div); - REGISTER_OP(UDIV, UDiv); - REGISTER_OP(REM, Rem); - REGISTER_OP(UREM, URem); - REGISTER_OP(MULH, MulH); - REGISTER_OP(UMULH, UMulH); - REGISTER_OP(OR, Or); - REGISTER_OP(ORLSHL, Orlshl); - REGISTER_OP(ORLSHR, Orlshr); - REGISTER_OP(ORNROR, Ornror); - REGISTER_OP(AND, And); - REGISTER_OP(ANDN, Andn); - REGISTER_OP(XOR, Xor); - REGISTER_OP(LSHL, Lshl); - REGISTER_OP(LSHR, Lshr); - REGISTER_OP(ASHR, Ashr); - REGISTER_OP(ROR, Ror); - REGISTER_OP(EXTR, Extr); - REGISTER_OP(PDEP, PDep); - REGISTER_OP(PEXT, PExt); - REGISTER_OP(LDIV, LDiv); - REGISTER_OP(LUDIV, LUDiv); - REGISTER_OP(LREM, LRem); - REGISTER_OP(LUREM, LURem); - REGISTER_OP(NOT, Not); - REGISTER_OP(POPCOUNT, Popcount); - REGISTER_OP(FINDLSB, FindLSB); - REGISTER_OP(FINDMSB, FindMSB); - REGISTER_OP(FINDTRAILINGZEROES, FindTrailingZeroes); - REGISTER_OP(COUNTLEADINGZEROES, CountLeadingZeroes); - REGISTER_OP(REV, Rev); - REGISTER_OP(BFI, Bfi); - REGISTER_OP(BFXIL, Bfxil); - REGISTER_OP(BFE, Bfe); - REGISTER_OP(SBFE, Sbfe); - REGISTER_OP(SELECT, Select); - REGISTER_OP(VEXTRACTTOGPR, VExtractToGPR); - REGISTER_OP(FLOAT_TOGPR_ZS, Float_ToGPR_ZS); - REGISTER_OP(FLOAT_TOGPR_S, Float_ToGPR_S); - REGISTER_OP(FCMP, FCmp); - // Atomic ops - REGISTER_OP(CASPAIR, CASPair); - REGISTER_OP(CAS, CAS); - REGISTER_OP(ATOMICADD, AtomicAdd); - REGISTER_OP(ATOMICSUB, AtomicSub); - REGISTER_OP(ATOMICAND, AtomicAnd); - REGISTER_OP(ATOMICOR, AtomicOr); - REGISTER_OP(ATOMICXOR, AtomicXor); - REGISTER_OP(ATOMICSWAP, AtomicSwap); - REGISTER_OP(ATOMICFETCHADD, AtomicFetchAdd); - REGISTER_OP(ATOMICFETCHSUB, AtomicFetchSub); - REGISTER_OP(ATOMICFETCHAND, AtomicFetchAnd); - REGISTER_OP(ATOMICFETCHCLR, AtomicFetchCLR); - REGISTER_OP(ATOMICFETCHOR, AtomicFetchOr); - REGISTER_OP(ATOMICFETCHXOR, AtomicFetchXor); - REGISTER_OP(ATOMICFETCHNEG, AtomicFetchNeg); - REGISTER_OP(TELEMETRYSETVALUE, TelemetrySetValue); - - // Branch ops - REGISTER_OP(CALLBACKRETURN, CallbackReturn); - REGISTER_OP(EXITFUNCTION, ExitFunction); - REGISTER_OP(JUMP, Jump); - REGISTER_OP(CONDJUMP, CondJump); - REGISTER_OP(SYSCALL, Syscall); - REGISTER_OP(INLINESYSCALL, InlineSyscall); - REGISTER_OP(THUNK, Thunk); - REGISTER_OP(VALIDATECODE, ValidateCode); - REGISTER_OP(THREADREMOVECODEENTRY, ThreadRemoveCodeEntry); - REGISTER_OP(CPUID, CPUID); - REGISTER_OP(XGETBV, XGETBV); - - // Conversion ops - REGISTER_OP(VINSGPR, VInsGPR); - REGISTER_OP(VCASTFROMGPR, VCastFromGPR); - REGISTER_OP(VDUPFROMGPR, VDupFromGPR); - REGISTER_OP(FLOAT_FROMGPR_S, Float_FromGPR_S); - REGISTER_OP(FLOAT_FTOF, Float_FToF); - REGISTER_OP(VECTOR_STOF, Vector_SToF); - REGISTER_OP(VECTOR_FTOZS, Vector_FToZS); - REGISTER_OP(VECTOR_FTOS, Vector_FToS); - REGISTER_OP(VECTOR_FTOF, Vector_FToF); - REGISTER_OP(VECTOR_FTOI, Vector_FToI); - - // Encryption ops - REGISTER_OP(VAESIMC, AESImc); - REGISTER_OP(VAESENC, AESEnc); - REGISTER_OP(VAESENCLAST, AESEncLast); - REGISTER_OP(VAESDEC, AESDec); - REGISTER_OP(VAESDECLAST, AESDecLast); - REGISTER_OP(VAESKEYGENASSIST, AESKeyGenAssist); - REGISTER_OP(CRC32, CRC32); - REGISTER_OP(PCLMUL, PCLMUL); - - // Flag ops - REGISTER_OP(GETHOSTFLAG, GetHostFlag); - - // Memory ops - REGISTER_OP(LOADCONTEXT, LoadContext); - REGISTER_OP(STORECONTEXT, StoreContext); - REGISTER_OP_RT(LOADREGISTER, LoadRegister); - REGISTER_OP_RT(STOREREGISTER, StoreRegister); - REGISTER_OP(LOADCONTEXTINDEXED, LoadContextIndexed); - REGISTER_OP(STORECONTEXTINDEXED, StoreContextIndexed); - REGISTER_OP(SPILLREGISTER, SpillRegister); - REGISTER_OP(FILLREGISTER, FillRegister); - REGISTER_OP(LOADFLAG, LoadFlag); - REGISTER_OP(STOREFLAG, StoreFlag); - REGISTER_OP(LOADMEM, LoadMem); - REGISTER_OP(STOREMEM, StoreMem); - REGISTER_OP_RT(LOADMEMTSO, LoadMemTSO); - REGISTER_OP_RT(STOREMEMTSO, StoreMemTSO); - REGISTER_OP(VLOADVECTORMASKED, VLoadVectorMasked); - REGISTER_OP(VSTOREVECTORMASKED, VStoreVectorMasked); - REGISTER_OP(VLOADVECTORELEMENT, VLoadVectorElement); - REGISTER_OP(VSTOREVECTORELEMENT, VStoreVectorElement); - REGISTER_OP(VBROADCASTFROMMEM, VBroadcastFromMem); - REGISTER_OP(PUSH, Push); - REGISTER_OP(MEMSET, MemSet); - REGISTER_OP(MEMCPY, MemCpy); - REGISTER_OP(CACHELINECLEAR, CacheLineClear); - REGISTER_OP(CACHELINECLEAN, CacheLineClean); - REGISTER_OP(CACHELINEZERO, CacheLineZero); - - // Misc ops - REGISTER_OP(DUMMY, NoOp); - REGISTER_OP(IRHEADER, NoOp); - REGISTER_OP(CODEBLOCK, NoOp); - REGISTER_OP(BEGINBLOCK, NoOp); - REGISTER_OP(ENDBLOCK, NoOp); - REGISTER_OP(GUESTOPCODE, GuestOpcode); - REGISTER_OP(FENCE, Fence); - REGISTER_OP(BREAK, Break); - REGISTER_OP(PRINT, Print); - REGISTER_OP(GETROUNDINGMODE, GetRoundingMode); - REGISTER_OP(SETROUNDINGMODE, SetRoundingMode); - REGISTER_OP(INVALIDATEFLAGS, NoOp); - REGISTER_OP(PROCESSORID, ProcessorID); - REGISTER_OP(RDRAND, RDRAND); - REGISTER_OP(YIELD, Yield); - - // Move ops - REGISTER_OP(EXTRACTELEMENTPAIR, ExtractElementPair); - REGISTER_OP(CREATEELEMENTPAIR, CreateElementPair); - - // Vector ops - REGISTER_OP(VECTORZERO, VectorZero); - REGISTER_OP(VECTORIMM, VectorImm); - REGISTER_OP(LOADNAMEDVECTORCONSTANT, LoadNamedVectorConstant); - REGISTER_OP(LOADNAMEDVECTORINDEXEDCONSTANT, LoadNamedVectorIndexedConstant); - REGISTER_OP(VMOV, VMov); - REGISTER_OP(VAND, VAnd); - REGISTER_OP(VBIC, VBic); - REGISTER_OP(VOR, VOr); - REGISTER_OP(VXOR, VXor); - REGISTER_OP(VADD, VAdd); - REGISTER_OP(VSUB, VSub); - REGISTER_OP(VUQADD, VUQAdd); - REGISTER_OP(VUQSUB, VUQSub); - REGISTER_OP(VSQADD, VSQAdd); - REGISTER_OP(VSQSUB, VSQSub); - REGISTER_OP(VADDP, VAddP); - REGISTER_OP(VADDV, VAddV); - REGISTER_OP(VUMINV, VUMinV); - REGISTER_OP(VURAVG, VURAvg); - REGISTER_OP(VABS, VAbs); - REGISTER_OP(VFABS, VFAbs); - REGISTER_OP(VPOPCOUNT, VPopcount); - REGISTER_OP(VFADD, VFAdd); - REGISTER_OP(VFADDP, VFAddP); - REGISTER_OP(VFSUB, VFSub); - REGISTER_OP(VFMUL, VFMul); - REGISTER_OP(VFDIV, VFDiv); - REGISTER_OP(VFMIN, VFMin); - REGISTER_OP(VFMAX, VFMax); - REGISTER_OP(VFRECP, VFRecp); - REGISTER_OP(VFSQRT, VFSqrt); - REGISTER_OP(VFRSQRT, VFRSqrt); - REGISTER_OP(VNEG, VNeg); - REGISTER_OP(VFNEG, VFNeg); - REGISTER_OP(VNOT, VNot); - REGISTER_OP(VUMIN, VUMin); - REGISTER_OP(VSMIN, VSMin); - REGISTER_OP(VUMAX, VUMax); - REGISTER_OP(VSMAX, VSMax); - REGISTER_OP(VZIP, VZip); - REGISTER_OP(VZIP2, VZip2); - REGISTER_OP(VUNZIP, VUnZip); - REGISTER_OP(VUNZIP2, VUnZip2); - REGISTER_OP(VTRN, VTrn); - REGISTER_OP(VTRN2, VTrn2); - REGISTER_OP(VBSL, VBSL); - REGISTER_OP(VCMPEQ, VCMPEQ); - REGISTER_OP(VCMPEQZ, VCMPEQZ); - REGISTER_OP(VCMPGT, VCMPGT); - REGISTER_OP(VCMPGTZ, VCMPGTZ); - REGISTER_OP(VCMPLTZ, VCMPLTZ); - REGISTER_OP(VFCMPEQ, VFCMPEQ); - REGISTER_OP(VFCMPNEQ, VFCMPNEQ); - REGISTER_OP(VFCMPLT, VFCMPLT); - REGISTER_OP(VFCMPGT, VFCMPGT); - REGISTER_OP(VFCMPLE, VFCMPLE); - REGISTER_OP(VFCMPORD, VFCMPORD); - REGISTER_OP(VFCMPUNO, VFCMPUNO); - REGISTER_OP(VUSHL, VUShl); - REGISTER_OP(VUSHR, VUShr); - REGISTER_OP(VSSHR, VSShr); - REGISTER_OP(VUSHLS, VUShlS); - REGISTER_OP(VUSHRS, VUShrS); - REGISTER_OP(VUSHRSWIDE, VUShrSWide); - REGISTER_OP(VSSHRSWIDE, VSShrSWide); - REGISTER_OP(VUSHLSWIDE, VUShlSWide); - REGISTER_OP(VSSHRS, VSShrS); - REGISTER_OP(VINSELEMENT, VInsElement); - REGISTER_OP(VDUPELEMENT, VDupElement); - REGISTER_OP(VEXTR, VExtr); - REGISTER_OP(VUSHRI, VUShrI); - REGISTER_OP(VSSHRI, VSShrI); - REGISTER_OP(VSHLI, VShlI); - REGISTER_OP(VUSHRNI, VUShrNI); - REGISTER_OP(VUSHRNI2, VUShrNI2); - REGISTER_OP(VSXTL, VSXTL); - REGISTER_OP(VSXTL2, VSXTL2); - REGISTER_OP(VUXTL, VUXTL); - REGISTER_OP(VUXTL2, VUXTL2); - REGISTER_OP(VSQXTN, VSQXTN); - REGISTER_OP(VSQXTN2, VSQXTN2); - REGISTER_OP(VSQXTNPAIR, VSQXTNPair); - REGISTER_OP(VSQXTUN, VSQXTUN); - REGISTER_OP(VSQXTUN2, VSQXTUN2); - REGISTER_OP(VSQXTUNPAIR, VSQXTUNPair); - REGISTER_OP(VSRSHR, VSRSHR); - REGISTER_OP(VSQSHL, VSQSHL); - REGISTER_OP(VUMUL, VMul); - REGISTER_OP(VSMUL, VMul); - REGISTER_OP(VUMULL, VUMull); - REGISTER_OP(VSMULL, VSMull); - REGISTER_OP(VUMULL2, VUMull2); - REGISTER_OP(VSMULL2, VSMull2); - REGISTER_OP(VUMULH, VUMulH); - REGISTER_OP(VSMULH, VSMulH); - REGISTER_OP(VUABDL, VUABDL); - REGISTER_OP(VUABDL2, VUABDL2); - REGISTER_OP(VTBL1, VTBL1); - REGISTER_OP(VTBL2, VTBL2); - REGISTER_OP(VREV32, VRev32); - REGISTER_OP(VREV64, VRev64); - REGISTER_OP(VFCADD, VFCADD); +#define IROP_DISPATCH_DISPATCH +#include #undef REGISTER_OP default: diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index a235e74b8..c464bb59f 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -218,278 +218,21 @@ private: #define DEF_OP(x) void Op_##x(IR::IROp_Header const *IROp, IR::NodeID Node) + // Dynamic Dispatcher supporting operations + DEF_OP(LoadRegisterSRA); + DEF_OP(StoreRegisterSRA); + + DEF_OP(ParanoidLoadMemTSO); + DEF_OP(ParanoidStoreMemTSO); + ///< Unhandled handler DEF_OP(Unhandled); ///< No-op Handler DEF_OP(NoOp); - ///< ALU Ops - DEF_OP(TruncElementPair); - DEF_OP(Constant); - DEF_OP(EntrypointOffset); - DEF_OP(InlineConstant); - DEF_OP(InlineEntrypointOffset); - DEF_OP(CycleCounter); - DEF_OP(Add); - DEF_OP(AddNZCV); - DEF_OP(AdcNZCV); - DEF_OP(SbbNZCV); - DEF_OP(TestNZ); - DEF_OP(Sub); - DEF_OP(SubNZCV); - DEF_OP(Neg); - DEF_OP(Abs); - DEF_OP(Mul); - DEF_OP(UMul); - DEF_OP(Div); - DEF_OP(UDiv); - DEF_OP(Rem); - DEF_OP(URem); - DEF_OP(MulH); - DEF_OP(UMulH); - DEF_OP(Or); - DEF_OP(Orlshl); - DEF_OP(Orlshr); - DEF_OP(Ornror); - DEF_OP(And); - DEF_OP(Andn); - DEF_OP(Xor); - DEF_OP(Lshl); - DEF_OP(Lshr); - DEF_OP(Ashr); - DEF_OP(Rol); - DEF_OP(Ror); - DEF_OP(Extr); - DEF_OP(PDep); - DEF_OP(PExt); - DEF_OP(LDiv); - DEF_OP(LUDiv); - DEF_OP(LRem); - DEF_OP(LURem); - DEF_OP(Zext); - DEF_OP(Not); - DEF_OP(Popcount); - DEF_OP(FindLSB); - DEF_OP(FindMSB); - DEF_OP(FindTrailingZeroes); - DEF_OP(CountLeadingZeroes); - DEF_OP(Rev); - DEF_OP(Bfi); - DEF_OP(Bfxil); - DEF_OP(Bfe); - DEF_OP(Sbfe); - DEF_OP(Select); - DEF_OP(VExtractToGPR); - DEF_OP(Float_ToGPR_ZU); - DEF_OP(Float_ToGPR_ZS); - DEF_OP(Float_ToGPR_S); - DEF_OP(FCmp); - - ///< Atomic ops - DEF_OP(CASPair); - DEF_OP(CAS); - DEF_OP(AtomicAdd); - DEF_OP(AtomicSub); - DEF_OP(AtomicAnd); - DEF_OP(AtomicOr); - DEF_OP(AtomicXor); - DEF_OP(AtomicSwap); - DEF_OP(AtomicFetchAdd); - DEF_OP(AtomicFetchSub); - DEF_OP(AtomicFetchAnd); - DEF_OP(AtomicFetchCLR); - DEF_OP(AtomicFetchOr); - DEF_OP(AtomicFetchXor); - DEF_OP(AtomicFetchNeg); - DEF_OP(TelemetrySetValue); - - ///< Branch ops - DEF_OP(CallbackReturn); - DEF_OP(ExitFunction); - DEF_OP(Jump); - DEF_OP(CondJump); - DEF_OP(Syscall); - DEF_OP(InlineSyscall); - DEF_OP(Thunk); - DEF_OP(ValidateCode); - DEF_OP(ThreadRemoveCodeEntry); - DEF_OP(CPUID); - DEF_OP(XGETBV); - - ///< Conversion ops - DEF_OP(VInsGPR); - DEF_OP(VCastFromGPR); - DEF_OP(VDupFromGPR); - DEF_OP(Float_FromGPR_S); - DEF_OP(Float_FToF); - DEF_OP(Vector_SToF); - DEF_OP(Vector_FToZS); - DEF_OP(Vector_FToS); - DEF_OP(Vector_FToF); - DEF_OP(Vector_FToI); - - ///< Flag ops - DEF_OP(GetHostFlag); - - ///< Memory ops - DEF_OP(LoadContext); - DEF_OP(StoreContext); - DEF_OP(LoadRegister); - DEF_OP(StoreRegister); - DEF_OP(LoadRegisterSRA); - DEF_OP(StoreRegisterSRA); - DEF_OP(LoadContextIndexed); - DEF_OP(StoreContextIndexed); - DEF_OP(SpillRegister); - DEF_OP(FillRegister); - DEF_OP(LoadFlag); - DEF_OP(StoreFlag); - DEF_OP(LoadMem); - DEF_OP(StoreMem); - DEF_OP(LoadMemTSO); - DEF_OP(StoreMemTSO); - DEF_OP(VLoadVectorMasked); - DEF_OP(VStoreVectorMasked); - DEF_OP(VLoadVectorElement); - DEF_OP(VStoreVectorElement); - DEF_OP(VBroadcastFromMem); - DEF_OP(Push); - DEF_OP(MemSet); - DEF_OP(MemCpy); - DEF_OP(ParanoidLoadMemTSO); - DEF_OP(ParanoidStoreMemTSO); - DEF_OP(CacheLineClear); - DEF_OP(CacheLineClean); - DEF_OP(CacheLineZero); - - ///< Misc ops - DEF_OP(GuestOpcode); - DEF_OP(Fence); - DEF_OP(Break); - DEF_OP(Print); - DEF_OP(GetRoundingMode); - DEF_OP(SetRoundingMode); - DEF_OP(ProcessorID); - DEF_OP(RDRAND); - DEF_OP(Yield); - - ///< Move ops - DEF_OP(ExtractElementPair); - DEF_OP(CreateElementPair); - - ///< Vector ops - DEF_OP(VectorZero); - DEF_OP(VectorImm); - DEF_OP(LoadNamedVectorConstant); - DEF_OP(LoadNamedVectorIndexedConstant); - DEF_OP(VMov); - DEF_OP(VAnd); - DEF_OP(VBic); - DEF_OP(VOr); - DEF_OP(VXor); - DEF_OP(VAdd); - DEF_OP(VSub); - DEF_OP(VUQAdd); - DEF_OP(VUQSub); - DEF_OP(VSQAdd); - DEF_OP(VSQSub); - DEF_OP(VAddP); - DEF_OP(VAddV); - DEF_OP(VUMinV); - DEF_OP(VURAvg); - DEF_OP(VAbs); - DEF_OP(VFAbs); - DEF_OP(VPopcount); - DEF_OP(VFAdd); - DEF_OP(VFAddP); - DEF_OP(VFSub); - DEF_OP(VFMul); - DEF_OP(VFDiv); - DEF_OP(VFMin); - DEF_OP(VFMax); - DEF_OP(VFRecp); - DEF_OP(VFSqrt); - DEF_OP(VFRSqrt); - DEF_OP(VNeg); - DEF_OP(VFNeg); - DEF_OP(VNot); - DEF_OP(VUMin); - DEF_OP(VSMin); - DEF_OP(VUMax); - DEF_OP(VSMax); - DEF_OP(VZip); - DEF_OP(VZip2); - DEF_OP(VUnZip); - DEF_OP(VUnZip2); - DEF_OP(VTrn); - DEF_OP(VTrn2); - DEF_OP(VBSL); - DEF_OP(VCMPEQ); - DEF_OP(VCMPEQZ); - DEF_OP(VCMPGT); - DEF_OP(VCMPGTZ); - DEF_OP(VCMPLTZ); - DEF_OP(VFCMPEQ); - DEF_OP(VFCMPNEQ); - DEF_OP(VFCMPLT); - DEF_OP(VFCMPGT); - DEF_OP(VFCMPLE); - DEF_OP(VFCMPORD); - DEF_OP(VFCMPUNO); - DEF_OP(VUShl); - DEF_OP(VUShr); - DEF_OP(VSShr); - DEF_OP(VUShlS); - DEF_OP(VUShrS); - DEF_OP(VSShrS); - DEF_OP(VUShrSWide); - DEF_OP(VSShrSWide); - DEF_OP(VUShlSWide); - DEF_OP(VInsElement); - DEF_OP(VDupElement); - DEF_OP(VExtr); - DEF_OP(VUShrI); - DEF_OP(VSShrI); - DEF_OP(VShlI); - DEF_OP(VUShrNI); - DEF_OP(VUShrNI2); - DEF_OP(VSXTL); - DEF_OP(VSXTL2); - DEF_OP(VUXTL); - DEF_OP(VUXTL2); - DEF_OP(VSQXTN); - DEF_OP(VSQXTN2); - DEF_OP(VSQXTNPair); - DEF_OP(VSQXTUN); - DEF_OP(VSQXTUN2); - DEF_OP(VSQXTUNPair); - DEF_OP(VSRSHR); - DEF_OP(VSQSHL); - DEF_OP(VMul); - DEF_OP(VUMull); - DEF_OP(VSMull); - DEF_OP(VUMull2); - DEF_OP(VSMull2); - DEF_OP(VUMulH); - DEF_OP(VSMulH); - DEF_OP(VUABDL); - DEF_OP(VUABDL2); - DEF_OP(VTBL1); - DEF_OP(VTBL2); - DEF_OP(VRev32); - DEF_OP(VRev64); - DEF_OP(VFCADD); - - ///< Encryption ops - DEF_OP(AESImc); - DEF_OP(AESEnc); - DEF_OP(AESEncLast); - DEF_OP(AESDec); - DEF_OP(AESDecLast); - DEF_OP(AESKeyGenAssist); - DEF_OP(CRC32); - DEF_OP(PCLMUL); +#define IROP_DISPATCH_DEFS +#include #undef DEF_OP }; diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index a5423982a..28d5258fb 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -3613,7 +3613,7 @@ DEF_OP(VSQSHL) { } DEF_OP(VMul) { - const auto Op = IROp->C(); + const auto Op = IROp->C(); const auto OpSize = IROp->Size; const auto Is256Bit = OpSize == Core::CPUState::XMM_AVX_REG_SIZE; diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index c434feeb7..d35d60aa7 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -6048,7 +6048,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(1, 0b01, 0xD2), 1, &OpDispatchBuilder::VPSRLDOp<4>}, {OPD(1, 0b01, 0xD3), 1, &OpDispatchBuilder::VPSRLDOp<8>}, {OPD(1, 0b01, 0xD4), 1, &OpDispatchBuilder::AVXVectorALUOp}, - {OPD(1, 0b01, 0xD5), 1, &OpDispatchBuilder::AVXVectorALUOp}, + {OPD(1, 0b01, 0xD5), 1, &OpDispatchBuilder::AVXVectorALUOp}, {OPD(1, 0b01, 0xD6), 1, &OpDispatchBuilder::MOVQOp}, {OPD(1, 0b01, 0xD7), 1, &OpDispatchBuilder::MOVMSKOpOne}, @@ -6162,7 +6162,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(2, 0b01, 0x3E), 1, &OpDispatchBuilder::AVXVectorALUOp}, {OPD(2, 0b01, 0x3F), 1, &OpDispatchBuilder::AVXVectorALUOp}, - {OPD(2, 0b01, 0x40), 1, &OpDispatchBuilder::AVXVectorALUOp}, + {OPD(2, 0b01, 0x40), 1, &OpDispatchBuilder::AVXVectorALUOp}, {OPD(2, 0b01, 0x41), 1, &OpDispatchBuilder::PHMINPOSUWOp}, {OPD(2, 0b01, 0x45), 1, &OpDispatchBuilder::VPSRLVOp}, {OPD(2, 0b01, 0x46), 1, &OpDispatchBuilder::VPSRAVDOp}, @@ -6488,7 +6488,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xD2, 1, &OpDispatchBuilder::PSRLDOp<4>}, {0xD3, 1, &OpDispatchBuilder::PSRLDOp<8>}, {0xD4, 1, &OpDispatchBuilder::VectorALUOp}, - {0xD5, 1, &OpDispatchBuilder::VectorALUOp}, + {0xD5, 1, &OpDispatchBuilder::VectorALUOp}, {0xD7, 1, &OpDispatchBuilder::MOVMSKOpOne}, // PMOVMSKB {0xD8, 1, &OpDispatchBuilder::VectorALUOp}, {0xD9, 1, &OpDispatchBuilder::VectorALUOp}, @@ -6787,7 +6787,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xD2, 1, &OpDispatchBuilder::PSRLDOp<4>}, {0xD3, 1, &OpDispatchBuilder::PSRLDOp<8>}, {0xD4, 1, &OpDispatchBuilder::VectorALUOp}, - {0xD5, 1, &OpDispatchBuilder::VectorALUOp}, + {0xD5, 1, &OpDispatchBuilder::VectorALUOp}, {0xD6, 1, &OpDispatchBuilder::MOVQOp}, {0xD7, 1, &OpDispatchBuilder::MOVMSKOpOne}, // PMOVMSKB {0xD8, 1, &OpDispatchBuilder::VectorALUOp}, @@ -7475,7 +7475,7 @@ constexpr uint16_t PF_F2 = 3; {OPD(PF_38_66, 0x3D), 1, &OpDispatchBuilder::VectorALUOp}, {OPD(PF_38_66, 0x3E), 1, &OpDispatchBuilder::VectorALUOp}, {OPD(PF_38_66, 0x3F), 1, &OpDispatchBuilder::VectorALUOp}, - {OPD(PF_38_66, 0x40), 1, &OpDispatchBuilder::VectorALUOp}, + {OPD(PF_38_66, 0x40), 1, &OpDispatchBuilder::VectorALUOp}, {OPD(PF_38_66, 0x41), 1, &OpDispatchBuilder::PHMINPOSUWOp}, {OPD(PF_38_NONE, 0xF0), 2, &OpDispatchBuilder::MOVBEOp}, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index acdd1b98a..6716de5d3 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -291,9 +291,9 @@ template void OpDispatchBuilder::VectorALUOp(OpcodeArgs); template -void OpDispatchBuilder::VectorALUOp(OpcodeArgs); +void OpDispatchBuilder::VectorALUOp(OpcodeArgs); template -void OpDispatchBuilder::VectorALUOp(OpcodeArgs); +void OpDispatchBuilder::VectorALUOp(OpcodeArgs); template void OpDispatchBuilder::VectorALUOp(OpcodeArgs); template @@ -472,9 +472,9 @@ template void OpDispatchBuilder::AVXVectorALUOp(OpcodeArgs); template -void OpDispatchBuilder::AVXVectorALUOp(OpcodeArgs); +void OpDispatchBuilder::AVXVectorALUOp(OpcodeArgs); template -void OpDispatchBuilder::AVXVectorALUOp(OpcodeArgs); +void OpDispatchBuilder::AVXVectorALUOp(OpcodeArgs); void OpDispatchBuilder::VectorALUROpImpl(OpcodeArgs, IROps IROp, size_t ElementSize) { const auto Size = GetSrcSize(Op); @@ -1699,7 +1699,7 @@ OrderedNode* OpDispatchBuilder::PSIGNImpl(OpcodeArgs, size_t ElementSize, if (CTX->BackendFeatures.SupportsSaturatingRoundingShifts) { OrderedNode *Control = _VSQSHL(Size, ElementSize, Src2, (ElementSize * 8) - 1); Control = _VSRSHR(Size, ElementSize, Control, (ElementSize * 8) - 1); - return _VSMul(Size, ElementSize, Src1, Control); + return _VMul(Size, ElementSize, Src1, Control); } else { auto NegVec = _VNeg(Size, ElementSize, Src1); @@ -3543,12 +3543,12 @@ OrderedNode* OpDispatchBuilder::PMADDUBSWOpImpl(OpcodeArgs, const X86Tables::Dec // Src1 is unsigned auto Src1_16b_L = _VUXTL(Size, 1, Src1); // [7:0 ], [15:8], [23:16], [31:24], [39:32], [47:40], [55:48], [63:56] auto Src2_16b_L = _VSXTL(Size, 1, Src2); // [7:0 ], [15:8], [23:16], [31:24], [39:32], [47:40], [55:48], [63:56] - auto ResMul_L = _VSMul(Size, 2, Src1_16b_L, Src2_16b_L); + auto ResMul_L = _VMul(Size, 2, Src1_16b_L, Src2_16b_L); // Src2 is signed auto Src1_16b_H = _VUXTL2(Size, 1, Src1); // Offset to +64bits [7:0 ], [15:8], [23:16], [31:24], [39:32], [47:40], [55:48], [63:56] auto Src2_16b_H = _VSXTL2(Size, 1, Src2); // Offset to +64bits [7:0 ], [15:8], [23:16], [31:24], [39:32], [47:40], [55:48], [63:56] - auto ResMul_L_H = _VSMul(Size, 2, Src1_16b_H, Src2_16b_H); + auto ResMul_L_H = _VMul(Size, 2, Src1_16b_H, Src2_16b_H); auto TmpZip1 = _VUnZip(Size, 2, ResMul_L, ResMul_L_H); auto TmpZip2 = _VUnZip2(Size, 2, ResMul_L, ResMul_L_H); diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 563c5e55f..94fe6d844 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -163,28 +163,34 @@ "Misc": { "Dummy": { "HasSideEffects": true, - "SwitchGen": false + "SwitchGen": false, + "JITDispatchOverride": "NoOp" }, "IRHeader SSA:$Blocks, u64:$OriginalRIP, u32:$BlockCount, u32:$NumHostInstructions": { - "SwitchGen": false + "SwitchGen": false, + "JITDispatchOverride": "NoOp" }, "CodeBlock SSA:$Begin, SSA:$Last": { "SwitchGen": false, - "RAOverride": "0" + "RAOverride": "0", + "JITDispatchOverride": "NoOp" }, "BeginBlock SSA:$BlockHeader": { "HasSideEffects": true, "SwitchGen": false, - "RAOverride": "0" + "RAOverride": "0", + "JITDispatchOverride": "NoOp" }, "InvalidateFlags u64:$Flags": { - "HasSideEffects": true + "HasSideEffects": true, + "JITDispatchOverride": "NoOp" }, "EndBlock SSA:$BlockHeader": { "HasSideEffects": true, "SwitchGen": false, - "RAOverride": "0" + "RAOverride": "0", + "JITDispatchOverride": "NoOp" }, "GuestOpcode u32:$GuestEntryOffset": { @@ -337,7 +343,8 @@ "Desc": ["Loads a value from the static-ra context with offset", "Dest = Ctx[Offset]" ], - "DestSize": "Size" + "DestSize": "Size", + "DynamicDispatch": true }, "StoreRegister SSA:$Value, i1:$IsPrewrite, u32:$Offset, RegisterClass:$Class, RegisterClass:$StaticClass, u8:#Size": { @@ -348,6 +355,7 @@ "Truncates if value's type is too large" ], "DestSize": "Size", + "DynamicDispatch": true, "EmitValidation": [ "WalkFindRegClass($Value) == $Class" ] @@ -472,7 +480,8 @@ "SSA = LoadMemTSO RegisterClass:$Class, u8:#Size, GPR:$Addr, GPR:$Offset, u8:$Align, MemOffsetType:$OffsetType, u8:$OffsetScale": { "Desc": ["Does a x86 TSO compatible load from memory. Offset must be Invalid()." ], - "DestSize": "Size" + "DestSize": "Size", + "DynamicDispatch": true }, "StoreMemTSO RegisterClass:$Class, u8:#Size, SSA:$Value, GPR:$Addr, GPR:$Offset, u8:$Align, MemOffsetType:$OffsetType, u8:$OffsetScale": { @@ -480,6 +489,7 @@ ], "HasSideEffects": true, "DestSize": "Size", + "DynamicDispatch": true, "EmitValidation": [ "WalkFindRegClass($Value) == $Class" ] @@ -1621,11 +1631,7 @@ "DestSize": "RegisterSize", "NumElements": "RegisterSize / ElementSize" }, - "FPR = VUMul u8:#RegisterSize, u8:#ElementSize, FPR:$Vector1, FPR:$Vector2": { - "DestSize": "RegisterSize", - "NumElements": "RegisterSize / ElementSize" - }, - "FPR = VSMul u8:#RegisterSize, u8:#ElementSize, FPR:$Vector1, FPR:$Vector2": { + "FPR = VMul u8:#RegisterSize, u8:#ElementSize, FPR:$Vector1, FPR:$Vector2": { "DestSize": "RegisterSize", "NumElements": "RegisterSize / ElementSize" }, @@ -1807,7 +1813,8 @@ "flags into the upper 16-bits of the 32-bit result, as these can also be derived over the", "course of creating the intermediate result" ], - "DestSize": "4" + "DestSize": "4", + "JITDispatch": false }, "GPR = VPCMPISTRX FPR:$LHS, FPR:$RHS, u8:$Control": { "Desc": ["Performs intermediate behavior analogous to the x86 PCMPISTRI/PCMPISTRM instruction", @@ -1818,7 +1825,8 @@ "flags into the upper 16-bits of the 32-bit result, as these can also be derived over the", "course of creating the intermediate result" ], - "DestSize": "4" + "DestSize": "4", + "JITDispatch": false }, "FPR = VFCADD u8:#RegisterSize, u8:#ElementSize, FPR:$Vector1, FPR:$Vector2, u16:$Rotate": { "DestSize": "RegisterSize", @@ -1925,111 +1933,143 @@ } }, "F64": { - "FPR = F64ATAN FPR:$Src1, FPR:$Src2": { - "DestSize": "8" - }, - "FPR = F64FPREM FPR:$Src1, FPR:$Src2": { - "DestSize": "8" - }, - "FPR = F64FPREM1 FPR:$Src1, FPR:$Src2": { - "DestSize": "8" - }, - "FPR = F64SCALE FPR:$Src1, FPR:$Src2": { - "DestSize": "8" - }, - "FPR = F64F2XM1 FPR:$Src": { - "DestSize": "8" - }, - "FPR = F64FYL2X FPR:$Src, FPR:$Src2": { - "DestSize": "8" - }, - "FPR = F64TAN FPR:$Src": { - "DestSize": "8" - }, - "FPR = F64SIN FPR:$Src": { - "DestSize": "8" - }, - "FPR = F64COS FPR:$Src": { - "DestSize": "8" - } + "FPR = F64ATAN FPR:$Src1, FPR:$Src2": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64FPREM FPR:$Src1, FPR:$Src2": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64FPREM1 FPR:$Src1, FPR:$Src2": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64SCALE FPR:$Src1, FPR:$Src2": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64F2XM1 FPR:$Src": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64FYL2X FPR:$Src, FPR:$Src2": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64TAN FPR:$Src": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64SIN FPR:$Src": { + "DestSize": "8", + "JITDispatch": false + }, + "FPR = F64COS FPR:$Src": { + "DestSize": "8", + "JITDispatch": false + } }, "F80": { "FPR = F80Add FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80Sub FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80Mul FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, - "FPR = F80Div FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80ATAN FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80FPREM FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80FPREM1 FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80SCALE FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80CVT u8:#Size, FPR:$X80Src": { - "DestSize": "Size" + "DestSize": "Size", + "JITDispatch": false }, "GPR = F80CVTInt u8:#Size, FPR:$X80Src, i1:$Truncate": { - "DestSize": "Size" + "DestSize": "Size", + "JITDispatch": false }, "FPR = F80CVTTo FPR:$X80Src, u8:$SrcSize": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80CVTToInt GPR:$Src, u8:$SrcSize": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80Round FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80F2XM1 FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80TAN FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80SIN FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80COS FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80SQRT FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80XTRACT_EXP FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80XTRACT_SIG FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "GPR = F80Cmp FPR:$X80Src1, FPR:$X80Src2, u32:$Flags": { "Desc": ["Does a scalar unordered compare and stores the asked for flags in to a GPR", "Ordering flag result is true if either float input is NaN" ], - "DestSize": "4" + "DestSize": "4", + "JITDispatch": false }, "FPR = F80BCDLoad FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80BCDStore FPR:$X80Src": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false }, "FPR = F80FYL2X FPR:$X80Src1, FPR:$X80Src2": { - "DestSize": "16" + "DestSize": "16", + "JITDispatch": false } }, "Backend": {