backend/a64: Port a32_emit_a64

This commit is contained in:
SachinVin 2019-08-03 10:32:47 +05:30
parent 4b48391fd3
commit cb56c74d19
3 changed files with 2170 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* This software may be used and distributed according to the terms of the GNU
* General Public License version 2 or any later version.
*/
#pragma once
#include <array>
#include <optional>
#include "backend/A64/a32_jitstate.h"
#include "backend/A64/block_range_information.h"
#include "backend/A64/emit_a64.h"
#include "dynarmic/A32/a32.h"
#include "dynarmic/A32/config.h"
#include "frontend/A32/location_descriptor.h"
#include "frontend/ir/terminal.h"
namespace Dynarmic::BackendA64 {
class RegAlloc;
struct A32EmitContext final : public EmitContext {
A32EmitContext(RegAlloc& reg_alloc, IR::Block& block);
A32::LocationDescriptor Location() const;
FP::RoundingMode FPSCR_RMode() const override;
u32 FPCR() const override;
bool FPSCR_FTZ() const override;
bool FPSCR_DN() const override;
};
class A32EmitA64 final : public EmitA64 {
public:
A32EmitA64(BlockOfCode& code, A32::UserConfig config, A32::Jit* jit_interface);
~A32EmitA64() override;
/**
* Emit host machine code for a basic block with intermediate representation `ir`.
* @note ir is modified.
*/
BlockDescriptor Emit(IR::Block& ir);
void ClearCache() override;
void InvalidateCacheRanges(const boost::icl::interval_set<u32>& ranges);
protected:
const A32::UserConfig config;
A32::Jit* jit_interface;
BlockRangeInformation<u32> block_ranges;
struct FastDispatchEntry {
u64 location_descriptor;
const void* code_ptr;
};
static_assert(sizeof(FastDispatchEntry) == 0x10);
static constexpr u64 fast_dispatch_table_mask = 0xFFFF0;
static constexpr size_t fast_dispatch_table_size = 0x10000;
std::array<FastDispatchEntry, fast_dispatch_table_size> fast_dispatch_table;
void ClearFastDispatchTable();
const void* read_memory_8;
const void* read_memory_16;
const void* read_memory_32;
const void* read_memory_64;
const void* write_memory_8;
const void* write_memory_16;
const void* write_memory_32;
const void* write_memory_64;
void GenMemoryAccessors();
const void* terminal_handler_pop_rsb_hint;
const void* terminal_handler_fast_dispatch_hint = nullptr;
void GenTerminalHandlers();
// Microinstruction emitters
#define OPCODE(...)
#define A32OPC(name, type, ...) void EmitA32##name(A32EmitContext& ctx, IR::Inst* inst);
#define A64OPC(...)
#include "frontend/ir/opcodes.inc"
#undef OPCODE
#undef A32OPC
#undef A64OPC
// Helpers
std::string LocationDescriptorToFriendlyName(const IR::LocationDescriptor&) const override;
// Terminal instruction emitters
void EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::ReturnToDispatch terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::PopRSBHint terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::FastDispatchHint terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::If terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::CheckBit terminal, IR::LocationDescriptor initial_location) override;
void EmitTerminalImpl(IR::Term::CheckHalt terminal, IR::LocationDescriptor initial_location) override;
// Patching
void EmitPatchJg(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr) override;
void EmitPatchJmp(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr) override;
void EmitPatchMovX0(CodePtr target_code_ptr = nullptr) override;
};
} // namespace Dynarmic::BackendA64

649
src/backend/A64/opcodes.inc Normal file
View File

@ -0,0 +1,649 @@
// opcode name, return type, arg1 type, arg2 type, arg3 type, arg4 type, ...
OPCODE(Void, Void, )
OPCODE(Identity, Opaque, Opaque )
OPCODE(Breakpoint, Void, )
// A32 Context getters/setters
A32OPC(GetRegister, U32, A32Reg )
//A32OPC(GetExtendedRegister32, U32, A32ExtReg )
//A32OPC(GetExtendedRegister64, U64, A32ExtReg )
A32OPC(SetRegister, Void, A32Reg, U32 )
//A32OPC(SetExtendedRegister32, Void, A32ExtReg, U32 )
//A32OPC(SetExtendedRegister64, Void, A32ExtReg, U64 )
A32OPC(GetCpsr, U32, )
A32OPC(SetCpsr, Void, U32 )
A32OPC(SetCpsrNZCV, Void, U32 )
A32OPC(SetCpsrNZCVQ, Void, U32 )
A32OPC(GetNFlag, U1, )
A32OPC(SetNFlag, Void, U1 )
A32OPC(GetZFlag, U1, )
A32OPC(SetZFlag, Void, U1 )
A32OPC(GetCFlag, U1, )
A32OPC(SetCFlag, Void, U1 )
A32OPC(GetVFlag, U1, )
A32OPC(SetVFlag, Void, U1 )
A32OPC(OrQFlag, Void, U1 )
//A32OPC(GetGEFlags, U32, )
//A32OPC(SetGEFlags, Void, U32 )
A32OPC(SetGEFlagsCompressed, Void, U32 )
A32OPC(BXWritePC, Void, U32 )
A32OPC(CallSupervisor, Void, U32 )
A32OPC(ExceptionRaised, Void, U32, U64 )
//A32OPC(GetFpscr, U32, )
//A32OPC(SetFpscr, Void, U32, )
//A32OPC(GetFpscrNZCV, U32, )
//A32OPC(SetFpscrNZCV, Void, NZCV )
// A64 Context getters/setters
//A64OPC(SetCheckBit, Void, U1 )
//A64OPC(GetCFlag, U1, )
//A64OPC(GetNZCVRaw, U32, )
//A64OPC(SetNZCVRaw, Void, U32 )
//A64OPC(SetNZCV, Void, NZCV )
//A64OPC(GetW, U32, A64Reg )
//A64OPC(GetX, U64, A64Reg )
//A64OPC(GetS, U128, A64Vec )
//A64OPC(GetD, U128, A64Vec )
//A64OPC(GetQ, U128, A64Vec )
//A64OPC(GetSP, U64, )
//A64OPC(GetFPCR, U32, )
//A64OPC(GetFPSR, U32, )
//A64OPC(SetW, Void, A64Reg, U32 )
//A64OPC(SetX, Void, A64Reg, U64 )
//A64OPC(SetS, Void, A64Vec, U128 )
//A64OPC(SetD, Void, A64Vec, U128 )
//A64OPC(SetQ, Void, A64Vec, U128 )
//A64OPC(SetSP, Void, U64 )
//A64OPC(SetFPCR, Void, U32 )
//A64OPC(SetFPSR, Void, U32 )
//A64OPC(OrQC, Void, U1 )
//A64OPC(SetPC, Void, U64 )
//A64OPC(CallSupervisor, Void, U32 )
//A64OPC(ExceptionRaised, Void, U64, U64 )
//A64OPC(DataCacheOperationRaised, Void, U64, U64 )
//A64OPC(DataSynchronizationBarrier, Void, )
//A64OPC(DataMemoryBarrier, Void, )
//A64OPC(InstructionSynchronizationBarrier, Void, )
//A64OPC(GetCNTFRQ, U32, )
//A64OPC(GetCNTPCT, U64, )
//A64OPC(GetCTR, U32, )
//A64OPC(GetDCZID, U32, )
//A64OPC(GetTPIDR, U64, )
//A64OPC(GetTPIDRRO, U64, )
//A64OPC(SetTPIDR, Void, U64 )
// Hints
OPCODE(PushRSB, Void, U64 )
// Pseudo-operation, handled specially at final emit
OPCODE(GetCarryFromOp, U1, Opaque )
OPCODE(GetOverflowFromOp, U1, Opaque )
OPCODE(GetGEFromOp, U32, Opaque )
OPCODE(GetNZCVFromOp, NZCV, Opaque )
OPCODE(GetUpperFromOp, U128, Opaque )
OPCODE(GetLowerFromOp, U128, Opaque )
OPCODE(NZCVFromPackedFlags, NZCV, U32 )
// Calculations
//OPCODE(Pack2x32To1x64, U64, U32, U32 )
//OPCODE(Pack2x64To1x128, U128, U64, U64 )
//OPCODE(LeastSignificantWord, U32, U64 )
//OPCODE(MostSignificantWord, U32, U64 )
//OPCODE(LeastSignificantHalf, U16, U32 )
//OPCODE(LeastSignificantByte, U8, U32 )
//OPCODE(MostSignificantBit, U1, U32 )
//OPCODE(IsZero32, U1, U32 )
//OPCODE(IsZero64, U1, U64 )
//OPCODE(TestBit, U1, U64, U8 )
//OPCODE(ConditionalSelect32, U32, Cond, U32, U32 )
//OPCODE(ConditionalSelect64, U64, Cond, U64, U64 )
//OPCODE(ConditionalSelectNZCV, NZCV, Cond, NZCV, NZCV )
//OPCODE(LogicalShiftLeft32, U32, U32, U8, U1 )
//OPCODE(LogicalShiftLeft64, U64, U64, U8 )
//OPCODE(LogicalShiftRight32, U32, U32, U8, U1 )
//OPCODE(LogicalShiftRight64, U64, U64, U8 )
//OPCODE(ArithmeticShiftRight32, U32, U32, U8, U1 )
//OPCODE(ArithmeticShiftRight64, U64, U64, U8 )
//OPCODE(RotateRight32, U32, U32, U8, U1 )
//OPCODE(RotateRight64, U64, U64, U8 )
//OPCODE(RotateRightExtended, U32, U32, U1 )
//OPCODE(Add32, U32, U32, U32, U1 )
//OPCODE(Add64, U64, U64, U64, U1 )
//OPCODE(Sub32, U32, U32, U32, U1 )
//OPCODE(Sub64, U64, U64, U64, U1 )
//OPCODE(Mul32, U32, U32, U32 )
//OPCODE(Mul64, U64, U64, U64 )
//OPCODE(SignedMultiplyHigh64, U64, U64, U64 )
//OPCODE(UnsignedMultiplyHigh64, U64, U64, U64 )
//OPCODE(UnsignedDiv32, U32, U32, U32 )
//OPCODE(UnsignedDiv64, U64, U64, U64 )
//OPCODE(SignedDiv32, U32, U32, U32 )
//OPCODE(SignedDiv64, U64, U64, U64 )
//OPCODE(And32, U32, U32, U32 )
//OPCODE(And64, U64, U64, U64 )
//OPCODE(Eor32, U32, U32, U32 )
//OPCODE(Eor64, U64, U64, U64 )
//OPCODE(Or32, U32, U32, U32 )
//OPCODE(Or64, U64, U64, U64 )
//OPCODE(Not32, U32, U32 )
//OPCODE(Not64, U64, U64 )
//OPCODE(SignExtendByteToWord, U32, U8 )
//OPCODE(SignExtendHalfToWord, U32, U16 )
//OPCODE(SignExtendByteToLong, U64, U8 )
//OPCODE(SignExtendHalfToLong, U64, U16 )
//OPCODE(SignExtendWordToLong, U64, U32 )
//OPCODE(ZeroExtendByteToWord, U32, U8 )
//OPCODE(ZeroExtendHalfToWord, U32, U16 )
//OPCODE(ZeroExtendByteToLong, U64, U8 )
//OPCODE(ZeroExtendHalfToLong, U64, U16 )
//OPCODE(ZeroExtendWordToLong, U64, U32 )
//OPCODE(ZeroExtendLongToQuad, U128, U64 )
//OPCODE(ByteReverseWord, U32, U32 )
//OPCODE(ByteReverseHalf, U16, U16 )
////OPCODE(ByteReverseDual, U64, U64 )
//OPCODE(CountLeadingZeros32, U32, U32 )
//OPCODE(CountLeadingZeros64, U64, U64 )
//OPCODE(ExtractRegister32, U32, U32, U32, U8 )
//OPCODE(ExtractRegister64, U64, U64, U64, U8 )
//OPCODE(MaxSigned32, U32, U32, U32 )
//OPCODE(MaxSigned64, U64, U64, U64 )
//OPCODE(MaxUnsigned32, U32, U32, U32 )
//OPCODE(MaxUnsigned64, U64, U64, U64 )
//OPCODE(MinSigned32, U32, U32, U32 )
//OPCODE(MinSigned64, U64, U64, U64 )
//OPCODE(MinUnsigned32, U32, U32, U32 )
//OPCODE(MinUnsigned64, U64, U64, U64 )
// Saturated instructions
//OPCODE(SignedSaturatedAdd8, U8, U8, U8 )
//OPCODE(SignedSaturatedAdd16, U16, U16, U16 )
//OPCODE(SignedSaturatedAdd32, U32, U32, U32 )
//OPCODE(SignedSaturatedAdd64, U64, U64, U64 )
//OPCODE(SignedSaturatedDoublingMultiplyReturnHigh16, U16, U16, U16 )
//OPCODE(SignedSaturatedDoublingMultiplyReturnHigh32, U32, U32, U32 )
//OPCODE(SignedSaturatedSub8, U8, U8, U8 )
//OPCODE(SignedSaturatedSub16, U16, U16, U16 )
//OPCODE(SignedSaturatedSub32, U32, U32, U32 )
//OPCODE(SignedSaturatedSub64, U64, U64, U64 )
//OPCODE(SignedSaturation, U32, U32, U8 )
//OPCODE(UnsignedSaturatedAdd8, U8, U8, U8 )
//OPCODE(UnsignedSaturatedAdd16, U16, U16, U16 )
//OPCODE(UnsignedSaturatedAdd32, U32, U32, U32 )
//OPCODE(UnsignedSaturatedAdd64, U64, U64, U64 )
//OPCODE(UnsignedSaturatedSub8, U8, U8, U8 )
//OPCODE(UnsignedSaturatedSub16, U16, U16, U16 )
//OPCODE(UnsignedSaturatedSub32, U32, U32, U32 )
//OPCODE(UnsignedSaturatedSub64, U64, U64, U64 )
//OPCODE(UnsignedSaturation, U32, U32, U8 )
// Packed instructions
//OPCODE(PackedAddU8, U32, U32, U32 )
//OPCODE(PackedAddS8, U32, U32, U32 )
//OPCODE(PackedSubU8, U32, U32, U32 )
//OPCODE(PackedSubS8, U32, U32, U32 )
//OPCODE(PackedAddU16, U32, U32, U32 )
//OPCODE(PackedAddS16, U32, U32, U32 )
//OPCODE(PackedSubU16, U32, U32, U32 )
//OPCODE(PackedSubS16, U32, U32, U32 )
//OPCODE(PackedAddSubU16, U32, U32, U32 )
//OPCODE(PackedAddSubS16, U32, U32, U32 )
//OPCODE(PackedSubAddU16, U32, U32, U32 )
//OPCODE(PackedSubAddS16, U32, U32, U32 )
//OPCODE(PackedHalvingAddU8, U32, U32, U32 )
//OPCODE(PackedHalvingAddS8, U32, U32, U32 )
//OPCODE(PackedHalvingSubU8, U32, U32, U32 )
//OPCODE(PackedHalvingSubS8, U32, U32, U32 )
//OPCODE(PackedHalvingAddU16, U32, U32, U32 )
//OPCODE(PackedHalvingAddS16, U32, U32, U32 )
//OPCODE(PackedHalvingSubU16, U32, U32, U32 )
//OPCODE(PackedHalvingSubS16, U32, U32, U32 )
//OPCODE(PackedHalvingAddSubU16, U32, U32, U32 )
//OPCODE(PackedHalvingAddSubS16, U32, U32, U32 )
//OPCODE(PackedHalvingSubAddU16, U32, U32, U32 )
//OPCODE(PackedHalvingSubAddS16, U32, U32, U32 )
//OPCODE(PackedSaturatedAddU8, U32, U32, U32 )
//OPCODE(PackedSaturatedAddS8, U32, U32, U32 )
//OPCODE(PackedSaturatedSubU8, U32, U32, U32 )
//OPCODE(PackedSaturatedSubS8, U32, U32, U32 )
//OPCODE(PackedSaturatedAddU16, U32, U32, U32 )
//OPCODE(PackedSaturatedAddS16, U32, U32, U32 )
//OPCODE(PackedSaturatedSubU16, U32, U32, U32 )
//OPCODE(PackedSaturatedSubS16, U32, U32, U32 )
//OPCODE(PackedAbsDiffSumS8, U32, U32, U32 )
//OPCODE(PackedSelect, U32, U32, U32, U32 )
// CRC instructions
//OPCODE(CRC32Castagnoli8, U32, U32, U32 )
//OPCODE(CRC32Castagnoli16, U32, U32, U32 )
//OPCODE(CRC32Castagnoli32, U32, U32, U32 )
//OPCODE(CRC32Castagnoli64, U32, U32, U64 )
//OPCODE(CRC32ISO8, U32, U32, U32 )
//OPCODE(CRC32ISO16, U32, U32, U32 )
//OPCODE(CRC32ISO32, U32, U32, U32 )
//OPCODE(CRC32ISO64, U32, U32, U64 )
// AES instructions
//OPCODE(AESDecryptSingleRound, U128, U128 )
//OPCODE(AESEncryptSingleRound, U128, U128 )
//OPCODE(AESInverseMixColumns, U128, U128 )
//OPCODE(AESMixColumns, U128, U128 )
// SM4 instructions
//OPCODE(SM4AccessSubstitutionBox, U8, U8 )
// Vector instructions
//OPCODE(VectorGetElement8, U8, U128, U8 )
//OPCODE(VectorGetElement16, U16, U128, U8 )
//OPCODE(VectorGetElement32, U32, U128, U8 )
//OPCODE(VectorGetElement64, U64, U128, U8 )
//OPCODE(VectorSetElement8, U128, U128, U8, U8 )
//OPCODE(VectorSetElement16, U128, U128, U8, U16 )
//OPCODE(VectorSetElement32, U128, U128, U8, U32 )
//OPCODE(VectorSetElement64, U128, U128, U8, U64 )
//OPCODE(VectorAbs8, U128, U128 )
//OPCODE(VectorAbs16, U128, U128 )
//OPCODE(VectorAbs32, U128, U128 )
//OPCODE(VectorAbs64, U128, U128 )
//OPCODE(VectorAdd8, U128, U128, U128 )
//OPCODE(VectorAdd16, U128, U128, U128 )
//OPCODE(VectorAdd32, U128, U128, U128 )
//OPCODE(VectorAdd64, U128, U128, U128 )
//OPCODE(VectorAnd, U128, U128, U128 )
//OPCODE(VectorArithmeticShiftRight8, U128, U128, U8 )
//OPCODE(VectorArithmeticShiftRight16, U128, U128, U8 )
//OPCODE(VectorArithmeticShiftRight32, U128, U128, U8 )
//OPCODE(VectorArithmeticShiftRight64, U128, U128, U8 )
//OPCODE(VectorArithmeticVShift8, U128, U128, U128 )
//OPCODE(VectorArithmeticVShift16, U128, U128, U128 )
//OPCODE(VectorArithmeticVShift32, U128, U128, U128 )
//OPCODE(VectorArithmeticVShift64, U128, U128, U128 )
//OPCODE(VectorBroadcastLower8, U128, U8 )
//OPCODE(VectorBroadcastLower16, U128, U16 )
//OPCODE(VectorBroadcastLower32, U128, U32 )
//OPCODE(VectorBroadcast8, U128, U8 )
//OPCODE(VectorBroadcast16, U128, U16 )
//OPCODE(VectorBroadcast32, U128, U32 )
//OPCODE(VectorBroadcast64, U128, U64 )
//OPCODE(VectorCountLeadingZeros8, U128, U128 )
//OPCODE(VectorCountLeadingZeros16, U128, U128 )
//OPCODE(VectorCountLeadingZeros32, U128, U128 )
//OPCODE(VectorDeinterleaveEven8, U128, U128, U128 )
//OPCODE(VectorDeinterleaveEven16, U128, U128, U128 )
//OPCODE(VectorDeinterleaveEven32, U128, U128, U128 )
//OPCODE(VectorDeinterleaveEven64, U128, U128, U128 )
//OPCODE(VectorDeinterleaveOdd8, U128, U128, U128 )
//OPCODE(VectorDeinterleaveOdd16, U128, U128, U128 )
//OPCODE(VectorDeinterleaveOdd32, U128, U128, U128 )
//OPCODE(VectorDeinterleaveOdd64, U128, U128, U128 )
//OPCODE(VectorEor, U128, U128, U128 )
//OPCODE(VectorEqual8, U128, U128, U128 )
//OPCODE(VectorEqual16, U128, U128, U128 )
//OPCODE(VectorEqual32, U128, U128, U128 )
//OPCODE(VectorEqual64, U128, U128, U128 )
//OPCODE(VectorEqual128, U128, U128, U128 )
//OPCODE(VectorExtract, U128, U128, U128, U8 )
//OPCODE(VectorExtractLower, U128, U128, U128, U8 )
//OPCODE(VectorGreaterS8, U128, U128, U128 )
//OPCODE(VectorGreaterS16, U128, U128, U128 )
//OPCODE(VectorGreaterS32, U128, U128, U128 )
//OPCODE(VectorGreaterS64, U128, U128, U128 )
//OPCODE(VectorHalvingAddS8, U128, U128, U128 )
//OPCODE(VectorHalvingAddS16, U128, U128, U128 )
//OPCODE(VectorHalvingAddS32, U128, U128, U128 )
//OPCODE(VectorHalvingAddU8, U128, U128, U128 )
//OPCODE(VectorHalvingAddU16, U128, U128, U128 )
//OPCODE(VectorHalvingAddU32, U128, U128, U128 )
//OPCODE(VectorHalvingSubS8, U128, U128, U128 )
//OPCODE(VectorHalvingSubS16, U128, U128, U128 )
//OPCODE(VectorHalvingSubS32, U128, U128, U128 )
//OPCODE(VectorHalvingSubU8, U128, U128, U128 )
//OPCODE(VectorHalvingSubU16, U128, U128, U128 )
//OPCODE(VectorHalvingSubU32, U128, U128, U128 )
//OPCODE(VectorInterleaveLower8, U128, U128, U128 )
//OPCODE(VectorInterleaveLower16, U128, U128, U128 )
//OPCODE(VectorInterleaveLower32, U128, U128, U128 )
//OPCODE(VectorInterleaveLower64, U128, U128, U128 )
//OPCODE(VectorInterleaveUpper8, U128, U128, U128 )
//OPCODE(VectorInterleaveUpper16, U128, U128, U128 )
//OPCODE(VectorInterleaveUpper32, U128, U128, U128 )
//OPCODE(VectorInterleaveUpper64, U128, U128, U128 )
//OPCODE(VectorLogicalShiftLeft8, U128, U128, U8 )
//OPCODE(VectorLogicalShiftLeft16, U128, U128, U8 )
//OPCODE(VectorLogicalShiftLeft32, U128, U128, U8 )
//OPCODE(VectorLogicalShiftLeft64, U128, U128, U8 )
//OPCODE(VectorLogicalShiftRight8, U128, U128, U8 )
//OPCODE(VectorLogicalShiftRight16, U128, U128, U8 )
//OPCODE(VectorLogicalShiftRight32, U128, U128, U8 )
//OPCODE(VectorLogicalShiftRight64, U128, U128, U8 )
//OPCODE(VectorLogicalVShift8, U128, U128, U128 )
//OPCODE(VectorLogicalVShift16, U128, U128, U128 )
//OPCODE(VectorLogicalVShift32, U128, U128, U128 )
//OPCODE(VectorLogicalVShift64, U128, U128, U128 )
//OPCODE(VectorMaxS8, U128, U128, U128 )
//OPCODE(VectorMaxS16, U128, U128, U128 )
//OPCODE(VectorMaxS32, U128, U128, U128 )
//OPCODE(VectorMaxS64, U128, U128, U128 )
//OPCODE(VectorMaxU8, U128, U128, U128 )
//OPCODE(VectorMaxU16, U128, U128, U128 )
//OPCODE(VectorMaxU32, U128, U128, U128 )
//OPCODE(VectorMaxU64, U128, U128, U128 )
//OPCODE(VectorMinS8, U128, U128, U128 )
//OPCODE(VectorMinS16, U128, U128, U128 )
//OPCODE(VectorMinS32, U128, U128, U128 )
//OPCODE(VectorMinS64, U128, U128, U128 )
//OPCODE(VectorMinU8, U128, U128, U128 )
//OPCODE(VectorMinU16, U128, U128, U128 )
//OPCODE(VectorMinU32, U128, U128, U128 )
//OPCODE(VectorMinU64, U128, U128, U128 )
//OPCODE(VectorMultiply8, U128, U128, U128 )
//OPCODE(VectorMultiply16, U128, U128, U128 )
//OPCODE(VectorMultiply32, U128, U128, U128 )
//OPCODE(VectorMultiply64, U128, U128, U128 )
//OPCODE(VectorNarrow16, U128, U128 )
//OPCODE(VectorNarrow32, U128, U128 )
//OPCODE(VectorNarrow64, U128, U128 )
//OPCODE(VectorNot, U128, U128 )
//OPCODE(VectorOr, U128, U128, U128 )
//OPCODE(VectorPairedAddLower8, U128, U128, U128 )
//OPCODE(VectorPairedAddLower16, U128, U128, U128 )
//OPCODE(VectorPairedAddLower32, U128, U128, U128 )
//OPCODE(VectorPairedAddSignedWiden8, U128, U128 )
//OPCODE(VectorPairedAddSignedWiden16, U128, U128 )
//OPCODE(VectorPairedAddSignedWiden32, U128, U128 )
//OPCODE(VectorPairedAddUnsignedWiden8, U128, U128 )
//OPCODE(VectorPairedAddUnsignedWiden16, U128, U128 )
//OPCODE(VectorPairedAddUnsignedWiden32, U128, U128 )
//OPCODE(VectorPairedAdd8, U128, U128, U128 )
//OPCODE(VectorPairedAdd16, U128, U128, U128 )
//OPCODE(VectorPairedAdd32, U128, U128, U128 )
//OPCODE(VectorPairedAdd64, U128, U128, U128 )
//OPCODE(VectorPairedMaxS8, U128, U128, U128 )
//OPCODE(VectorPairedMaxS16, U128, U128, U128 )
//OPCODE(VectorPairedMaxS32, U128, U128, U128 )
//OPCODE(VectorPairedMaxU8, U128, U128, U128 )
//OPCODE(VectorPairedMaxU16, U128, U128, U128 )
//OPCODE(VectorPairedMaxU32, U128, U128, U128 )
//OPCODE(VectorPairedMinS8, U128, U128, U128 )
//OPCODE(VectorPairedMinS16, U128, U128, U128 )
//OPCODE(VectorPairedMinS32, U128, U128, U128 )
//OPCODE(VectorPairedMinU8, U128, U128, U128 )
//OPCODE(VectorPairedMinU16, U128, U128, U128 )
//OPCODE(VectorPairedMinU32, U128, U128, U128 )
//OPCODE(VectorPolynomialMultiply8, U128, U128, U128 )
//OPCODE(VectorPolynomialMultiplyLong8, U128, U128, U128 )
//OPCODE(VectorPolynomialMultiplyLong64, U128, U128, U128 )
//OPCODE(VectorPopulationCount, U128, U128 )
//OPCODE(VectorReverseBits, U128, U128 )
//OPCODE(VectorRoundingHalvingAddS8, U128, U128, U128 )
//OPCODE(VectorRoundingHalvingAddS16, U128, U128, U128 )
//OPCODE(VectorRoundingHalvingAddS32, U128, U128, U128 )
//OPCODE(VectorRoundingHalvingAddU8, U128, U128, U128 )
//OPCODE(VectorRoundingHalvingAddU16, U128, U128, U128 )
//OPCODE(VectorRoundingHalvingAddU32, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftS8, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftS16, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftS32, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftS64, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftU8, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftU16, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftU32, U128, U128, U128 )
//OPCODE(VectorRoundingShiftLeftU64, U128, U128, U128 )
//OPCODE(VectorShuffleHighHalfwords, U128, U128, U8 )
//OPCODE(VectorShuffleLowHalfwords, U128, U128, U8 )
//OPCODE(VectorShuffleWords, U128, U128, U8 )
//OPCODE(VectorSignExtend8, U128, U128 )
//OPCODE(VectorSignExtend16, U128, U128 )
//OPCODE(VectorSignExtend32, U128, U128 )
//OPCODE(VectorSignExtend64, U128, U128 )
//OPCODE(VectorSignedAbsoluteDifference8, U128, U128, U128 )
//OPCODE(VectorSignedAbsoluteDifference16, U128, U128, U128 )
//OPCODE(VectorSignedAbsoluteDifference32, U128, U128, U128 )
//OPCODE(VectorSignedMultiply16, Void, U128, U128 )
//OPCODE(VectorSignedMultiply32, Void, U128, U128 )
//OPCODE(VectorSignedSaturatedAbs8, U128, U128 )
//OPCODE(VectorSignedSaturatedAbs16, U128, U128 )
//OPCODE(VectorSignedSaturatedAbs32, U128, U128 )
//OPCODE(VectorSignedSaturatedAbs64, U128, U128 )
//OPCODE(VectorSignedSaturatedAccumulateUnsigned8, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedAccumulateUnsigned16, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedAccumulateUnsigned32, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedAccumulateUnsigned64, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedDoublingMultiply16, Void, U128, U128 )
//OPCODE(VectorSignedSaturatedDoublingMultiply32, Void, U128, U128 )
//OPCODE(VectorSignedSaturatedDoublingMultiplyLong16, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedDoublingMultiplyLong32, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedNarrowToSigned16, U128, U128 )
//OPCODE(VectorSignedSaturatedNarrowToSigned32, U128, U128 )
//OPCODE(VectorSignedSaturatedNarrowToSigned64, U128, U128 )
//OPCODE(VectorSignedSaturatedNarrowToUnsigned16, U128, U128 )
//OPCODE(VectorSignedSaturatedNarrowToUnsigned32, U128, U128 )
//OPCODE(VectorSignedSaturatedNarrowToUnsigned64, U128, U128 )
//OPCODE(VectorSignedSaturatedNeg8, U128, U128 )
//OPCODE(VectorSignedSaturatedNeg16, U128, U128 )
//OPCODE(VectorSignedSaturatedNeg32, U128, U128 )
//OPCODE(VectorSignedSaturatedNeg64, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeft8, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeft16, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeft32, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeft64, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeftUnsigned8, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeftUnsigned16, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeftUnsigned32, U128, U128, U128 )
//OPCODE(VectorSignedSaturatedShiftLeftUnsigned64, U128, U128, U128 )
//OPCODE(VectorSub8, U128, U128, U128 )
//OPCODE(VectorSub16, U128, U128, U128 )
//OPCODE(VectorSub32, U128, U128, U128 )
//OPCODE(VectorSub64, U128, U128, U128 )
//OPCODE(VectorTable, Table, U128, Opaque, Opaque, Opaque )
//OPCODE(VectorTableLookup, U128, U128, Table, U128 )
//OPCODE(VectorUnsignedAbsoluteDifference8, U128, U128, U128 )
//OPCODE(VectorUnsignedAbsoluteDifference16, U128, U128, U128 )
//OPCODE(VectorUnsignedAbsoluteDifference32, U128, U128, U128 )
//OPCODE(VectorUnsignedMultiply16, Void, U128, U128 )
//OPCODE(VectorUnsignedMultiply32, Void, U128, U128 )
//OPCODE(VectorUnsignedRecipEstimate, U128, U128 )
//OPCODE(VectorUnsignedRecipSqrtEstimate, U128, U128 )
//OPCODE(VectorUnsignedSaturatedAccumulateSigned8, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedAccumulateSigned16, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedAccumulateSigned32, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedAccumulateSigned64, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedNarrow16, U128, U128 )
//OPCODE(VectorUnsignedSaturatedNarrow32, U128, U128 )
//OPCODE(VectorUnsignedSaturatedNarrow64, U128, U128 )
//OPCODE(VectorUnsignedSaturatedShiftLeft8, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedShiftLeft16, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedShiftLeft32, U128, U128, U128 )
//OPCODE(VectorUnsignedSaturatedShiftLeft64, U128, U128, U128 )
//OPCODE(VectorZeroExtend8, U128, U128 )
//OPCODE(VectorZeroExtend16, U128, U128 )
//OPCODE(VectorZeroExtend32, U128, U128 )
//OPCODE(VectorZeroExtend64, U128, U128 )
//OPCODE(VectorZeroUpper, U128, U128 )
//OPCODE(ZeroVector, U128, )
// Floating-point operations
//OPCODE(FPAbs16, U16, U16 )
//OPCODE(FPAbs32, U32, U32 )
//OPCODE(FPAbs64, U64, U64 )
//OPCODE(FPAdd32, U32, U32, U32 )
//OPCODE(FPAdd64, U64, U64, U64 )
//OPCODE(FPCompare32, NZCV, U32, U32, U1 )
//OPCODE(FPCompare64, NZCV, U64, U64, U1 )
//OPCODE(FPDiv32, U32, U32, U32 )
//OPCODE(FPDiv64, U64, U64, U64 )
//OPCODE(FPMax32, U32, U32, U32 )
//OPCODE(FPMax64, U64, U64, U64 )
//OPCODE(FPMaxNumeric32, U32, U32, U32 )
//OPCODE(FPMaxNumeric64, U64, U64, U64 )
//OPCODE(FPMin32, U32, U32, U32 )
//OPCODE(FPMin64, U64, U64, U64 )
//OPCODE(FPMinNumeric32, U32, U32, U32 )
//OPCODE(FPMinNumeric64, U64, U64, U64 )
//OPCODE(FPMul32, U32, U32, U32 )
//OPCODE(FPMul64, U64, U64, U64 )
//OPCODE(FPMulAdd16, U16, U16, U16, U16 )
//OPCODE(FPMulAdd32, U32, U32, U32, U32 )
//OPCODE(FPMulAdd64, U64, U64, U64, U64 )
//OPCODE(FPMulX32, U32, U32, U32 )
//OPCODE(FPMulX64, U64, U64, U64 )
//OPCODE(FPNeg16, U16, U16 )
//OPCODE(FPNeg32, U32, U32 )
//OPCODE(FPNeg64, U64, U64 )
//OPCODE(FPRecipEstimate16, U16, U16 )
//OPCODE(FPRecipEstimate32, U32, U32 )
//OPCODE(FPRecipEstimate64, U64, U64 )
//OPCODE(FPRecipExponent16, U16, U16 )
//OPCODE(FPRecipExponent32, U32, U32 )
//OPCODE(FPRecipExponent64, U64, U64 )
//OPCODE(FPRecipStepFused16, U16, U16, U16 )
//OPCODE(FPRecipStepFused32, U32, U32, U32 )
//OPCODE(FPRecipStepFused64, U64, U64, U64 )
//OPCODE(FPRoundInt16, U16, U16, U8, U1 )
//OPCODE(FPRoundInt32, U32, U32, U8, U1 )
//OPCODE(FPRoundInt64, U64, U64, U8, U1 )
//OPCODE(FPRSqrtEstimate16, U16, U16 )
//OPCODE(FPRSqrtEstimate32, U32, U32 )
//OPCODE(FPRSqrtEstimate64, U64, U64 )
//OPCODE(FPRSqrtStepFused16, U16, U16, U16 )
//OPCODE(FPRSqrtStepFused32, U32, U32, U32 )
//OPCODE(FPRSqrtStepFused64, U64, U64, U64 )
//OPCODE(FPSqrt32, U32, U32 )
//OPCODE(FPSqrt64, U64, U64 )
//OPCODE(FPSub32, U32, U32, U32 )
//OPCODE(FPSub64, U64, U64, U64 )
// Floating-point conversions
//OPCODE(FPHalfToDouble, U64, U16, U8 )
//OPCODE(FPHalfToSingle, U32, U16, U8 )
//OPCODE(FPSingleToDouble, U64, U32, U8 )
//OPCODE(FPSingleToHalf, U16, U32, U8 )
//OPCODE(FPDoubleToHalf, U16, U64, U8 )
//OPCODE(FPDoubleToSingle, U32, U64, U8 )
//OPCODE(FPDoubleToFixedS32, U32, U64, U8, U8 )
//OPCODE(FPDoubleToFixedS64, U64, U64, U8, U8 )
//OPCODE(FPDoubleToFixedU32, U32, U64, U8, U8 )
//OPCODE(FPDoubleToFixedU64, U64, U64, U8, U8 )
//OPCODE(FPHalfToFixedS32, U32, U16, U8, U8 )
//OPCODE(FPHalfToFixedS64, U64, U16, U8, U8 )
//OPCODE(FPHalfToFixedU32, U32, U16, U8, U8 )
//OPCODE(FPHalfToFixedU64, U64, U16, U8, U8 )
//OPCODE(FPSingleToFixedS32, U32, U32, U8, U8 )
//OPCODE(FPSingleToFixedS64, U64, U32, U8, U8 )
//OPCODE(FPSingleToFixedU32, U32, U32, U8, U8 )
//OPCODE(FPSingleToFixedU64, U64, U32, U8, U8 )
//OPCODE(FPFixedU32ToSingle, U32, U32, U8, U8 )
//OPCODE(FPFixedS32ToSingle, U32, U32, U8, U8 )
//OPCODE(FPFixedU32ToDouble, U64, U32, U8, U8 )
//OPCODE(FPFixedU64ToDouble, U64, U64, U8, U8 )
//OPCODE(FPFixedU64ToSingle, U32, U64, U8, U8 )
//OPCODE(FPFixedS32ToDouble, U64, U32, U8, U8 )
//OPCODE(FPFixedS64ToDouble, U64, U64, U8, U8 )
//OPCODE(FPFixedS64ToSingle, U32, U64, U8, U8 )
// Floating-point vector instructions
//OPCODE(FPVectorAbs16, U128, U128 )
//OPCODE(FPVectorAbs32, U128, U128 )
//OPCODE(FPVectorAbs64, U128, U128 )
//OPCODE(FPVectorAdd32, U128, U128, U128 )
//OPCODE(FPVectorAdd64, U128, U128, U128 )
//OPCODE(FPVectorDiv32, U128, U128, U128 )
//OPCODE(FPVectorDiv64, U128, U128, U128 )
//OPCODE(FPVectorEqual32, U128, U128, U128 )
//OPCODE(FPVectorEqual64, U128, U128, U128 )
//OPCODE(FPVectorFromSignedFixed32, U128, U128, U8, U8 )
//OPCODE(FPVectorFromSignedFixed64, U128, U128, U8, U8 )
//OPCODE(FPVectorFromUnsignedFixed32, U128, U128, U8, U8 )
//OPCODE(FPVectorFromUnsignedFixed64, U128, U128, U8, U8 )
//OPCODE(FPVectorGreater32, U128, U128, U128 )
//OPCODE(FPVectorGreater64, U128, U128, U128 )
//OPCODE(FPVectorGreaterEqual32, U128, U128, U128 )
//OPCODE(FPVectorGreaterEqual64, U128, U128, U128 )
//OPCODE(FPVectorMax32, U128, U128, U128 )
//OPCODE(FPVectorMax64, U128, U128, U128 )
//OPCODE(FPVectorMin32, U128, U128, U128 )
//OPCODE(FPVectorMin64, U128, U128, U128 )
//OPCODE(FPVectorMul32, U128, U128, U128 )
//OPCODE(FPVectorMul64, U128, U128, U128 )
//OPCODE(FPVectorMulAdd16, U128, U128, U128, U128 )
//OPCODE(FPVectorMulAdd32, U128, U128, U128, U128 )
//OPCODE(FPVectorMulAdd64, U128, U128, U128, U128 )
//OPCODE(FPVectorMulX32, U128, U128, U128 )
//OPCODE(FPVectorMulX64, U128, U128, U128 )
//OPCODE(FPVectorNeg16, U128, U128 )
//OPCODE(FPVectorNeg32, U128, U128 )
//OPCODE(FPVectorNeg64, U128, U128 )
//OPCODE(FPVectorPairedAdd32, U128, U128, U128 )
//OPCODE(FPVectorPairedAdd64, U128, U128, U128 )
//OPCODE(FPVectorPairedAddLower32, U128, U128, U128 )
//OPCODE(FPVectorPairedAddLower64, U128, U128, U128 )
//OPCODE(FPVectorRecipEstimate16, U128, U128 )
//OPCODE(FPVectorRecipEstimate32, U128, U128 )
//OPCODE(FPVectorRecipEstimate64, U128, U128 )
//OPCODE(FPVectorRecipStepFused16, U128, U128, U128 )
//OPCODE(FPVectorRecipStepFused32, U128, U128, U128 )
//OPCODE(FPVectorRecipStepFused64, U128, U128, U128 )
//OPCODE(FPVectorRoundInt16, U128, U128, U8, U1 )
//OPCODE(FPVectorRoundInt32, U128, U128, U8, U1 )
//OPCODE(FPVectorRoundInt64, U128, U128, U8, U1 )
//OPCODE(FPVectorRSqrtEstimate16, U128, U128 )
//OPCODE(FPVectorRSqrtEstimate32, U128, U128 )
//OPCODE(FPVectorRSqrtEstimate64, U128, U128 )
//OPCODE(FPVectorRSqrtStepFused16, U128, U128, U128 )
//OPCODE(FPVectorRSqrtStepFused32, U128, U128, U128 )
//OPCODE(FPVectorRSqrtStepFused64, U128, U128, U128 )
//OPCODE(FPVectorSqrt32, U128, U128 )
//OPCODE(FPVectorSqrt64, U128, U128 )
//OPCODE(FPVectorSub32, U128, U128, U128 )
//OPCODE(FPVectorSub64, U128, U128, U128 )
//OPCODE(FPVectorToSignedFixed16, U128, U128, U8, U8 )
//OPCODE(FPVectorToSignedFixed32, U128, U128, U8, U8 )
//OPCODE(FPVectorToSignedFixed64, U128, U128, U8, U8 )
//OPCODE(FPVectorToUnsignedFixed16, U128, U128, U8, U8 )
//OPCODE(FPVectorToUnsignedFixed32, U128, U128, U8, U8 )
//OPCODE(FPVectorToUnsignedFixed64, U128, U128, U8, U8 )
// A32 Memory access
A32OPC(ClearExclusive, Void, )
A32OPC(SetExclusive, Void, U32, U8 )
A32OPC(ReadMemory8, U8, U32 )
A32OPC(ReadMemory16, U16, U32 )
A32OPC(ReadMemory32, U32, U32 )
A32OPC(ReadMemory64, U64, U32 )
A32OPC(WriteMemory8, Void, U32, U8 )
A32OPC(WriteMemory16, Void, U32, U16 )
A32OPC(WriteMemory32, Void, U32, U32 )
A32OPC(WriteMemory64, Void, U32, U64 )
A32OPC(ExclusiveWriteMemory8, U32, U32, U8 )
A32OPC(ExclusiveWriteMemory16, U32, U32, U16 )
A32OPC(ExclusiveWriteMemory32, U32, U32, U32 )
A32OPC(ExclusiveWriteMemory64, U32, U32, U32, U32 )
// A64 Memory access
//A64OPC(ClearExclusive, Void, )
//A64OPC(SetExclusive, Void, U64, U8 )
//A64OPC(ReadMemory8, U8, U64 )
//A64OPC(ReadMemory16, U16, U64 )
//A64OPC(ReadMemory32, U32, U64 )
//A64OPC(ReadMemory64, U64, U64 )
//A64OPC(ReadMemory128, U128, U64 )
//A64OPC(WriteMemory8, Void, U64, U8 )
//A64OPC(WriteMemory16, Void, U64, U16 )
//A64OPC(WriteMemory32, Void, U64, U32 )
//A64OPC(WriteMemory64, Void, U64, U64 )
//A64OPC(WriteMemory128, Void, U64, U128 )
//A64OPC(ExclusiveWriteMemory8, U32, U64, U8 )
//A64OPC(ExclusiveWriteMemory16, U32, U64, U16 )
//A64OPC(ExclusiveWriteMemory32, U32, U64, U32 )
//A64OPC(ExclusiveWriteMemory64, U32, U64, U64 )
//A64OPC(ExclusiveWriteMemory128, U32, U64, U128 )
// Coprocessor
//A32OPC(CoprocInternalOperation, Void, CoprocInfo )
//A32OPC(CoprocSendOneWord, Void, CoprocInfo, U32 )
//A32OPC(CoprocSendTwoWords, Void, CoprocInfo, U32, U32 )
//A32OPC(CoprocGetOneWord, U32, CoprocInfo )
//A32OPC(CoprocGetTwoWords, U64, CoprocInfo )
//A32OPC(CoprocLoadWords, Void, CoprocInfo, U32 )
//A32OPC(CoprocStoreWords, Void, CoprocInfo, U32 )