/* * Copyright (c) 2017-2019 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall * not be construed as granting a license to any other intellectual * property including but not limited to intellectual property relating * to a hardware implementation of the functionality of the software * licensed hereunder. You may use the software subject to the license * terms below provided that you ensure that this notice is replicated * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Giacomo Gabrielli */ #ifndef __ARCH_ARM_INSTS_SVE_HH__ #define __ARCH_ARM_INSTS_SVE_HH__ #include "arch/arm/insts/static_inst.hh" namespace ArmISA { enum class SvePredType { NONE, MERGE, ZERO, SELECT }; /// Returns the specifier for the predication type `pt` as a string. const char* svePredTypeToStr(SvePredType pt); /// Index generation instruction, immediate operands class SveIndexIIOp : public ArmStaticInst { protected: IntRegIndex dest; int8_t imm1; int8_t imm2; SveIndexIIOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, int8_t _imm1, int8_t _imm2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), imm1(_imm1), imm2(_imm2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; class SveIndexIROp : public ArmStaticInst { protected: IntRegIndex dest; int8_t imm1; IntRegIndex op2; SveIndexIROp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, int8_t _imm1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), imm1(_imm1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; class SveIndexRIOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; int8_t imm2; SveIndexRIOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, int8_t _imm2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm2(_imm2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; class SveIndexRROp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; IntRegIndex op2; SveIndexRROp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; // Predicate count SVE instruction. class SvePredCountOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex gp; bool srcIs32b; bool destIsVec; SvePredCountOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, bool _srcIs32b = false, bool _destIsVec = false) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), gp(_gp), srcIs32b(_srcIs32b), destIsVec(_destIsVec) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; // Predicate count SVE instruction (predicated). class SvePredCountPredOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; IntRegIndex gp; SvePredCountPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// While predicate generation SVE instruction. class SveWhileOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; bool srcIs32b; SveWhileOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, bool _srcIs32b) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), srcIs32b(_srcIs32b) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Compare and terminate loop SVE instruction. class SveCompTermOp : public ArmStaticInst { protected: IntRegIndex op1, op2; SveCompTermOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _op1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Unary, constructive, predicated (merging) SVE instruction. class SveUnaryPredOp : public ArmStaticInst { protected: IntRegIndex dest, op1, gp; SveUnaryPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Unary, constructive, unpredicated SVE instruction. class SveUnaryUnpredOp : public ArmStaticInst { protected: IntRegIndex dest, op1; SveUnaryUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Unary with wide immediate, constructive, unpredicated SVE instruction. class SveUnaryWideImmUnpredOp : public ArmStaticInst { protected: IntRegIndex dest; uint64_t imm; SveUnaryWideImmUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Unary with wide immediate, constructive, predicated SVE instruction. class SveUnaryWideImmPredOp : public ArmStaticInst { protected: IntRegIndex dest; uint64_t imm; IntRegIndex gp; bool isMerging; SveUnaryWideImmPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm, IntRegIndex _gp, bool _isMerging) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), imm(_imm), gp(_gp), isMerging(_isMerging) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary with immediate, destructive, unpredicated SVE instruction. class SveBinImmUnpredConstrOp : public ArmStaticInst { protected: IntRegIndex dest, op1; uint64_t imm; SveBinImmUnpredConstrOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary with immediate, destructive, predicated (merging) SVE instruction. class SveBinImmPredOp : public ArmStaticInst { protected: IntRegIndex dest, gp; uint64_t imm; SveBinImmPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), gp(_gp), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary with wide immediate, destructive, unpredicated SVE instruction. class SveBinWideImmUnpredOp : public ArmStaticInst { protected: IntRegIndex dest; uint64_t imm; SveBinWideImmUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary, destructive, predicated (merging) SVE instruction. class SveBinDestrPredOp : public ArmStaticInst { protected: IntRegIndex dest, op2, gp; SveBinDestrPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op2, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op2(_op2), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary, constructive, predicated SVE instruction. class SveBinConstrPredOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2, gp; SvePredType predType; SveBinConstrPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp, SvePredType _predType) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), gp(_gp), predType(_predType) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary, unpredicated SVE instruction with indexed operand class SveBinUnpredOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; SveBinUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary, unpredicated SVE instruction class SveBinIdxUnpredOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; uint8_t index; SveBinIdxUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint8_t _index) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), index(_index) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Predicate logical instruction. class SvePredLogicalOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2, gp; bool isSel; SvePredLogicalOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp, bool _isSel = false) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), gp(_gp), isSel(_isSel) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Predicate binary permute instruction. class SvePredBinPermOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; SvePredBinPermOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE compare instructions, predicated (zeroing). class SveCmpOp : public ArmStaticInst { protected: IntRegIndex dest, gp, op1, op2; SveCmpOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), gp(_gp), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE compare-with-immediate instructions, predicated (zeroing). class SveCmpImmOp : public ArmStaticInst { protected: IntRegIndex dest, gp, op1; uint64_t imm; SveCmpImmOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), gp(_gp), op1(_op1), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Ternary, destructive, predicated (merging) SVE instruction. class SveTerPredOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2, gp; SveTerPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Ternary with immediate, destructive, unpredicated SVE instruction. class SveTerImmUnpredOp : public ArmStaticInst { protected: IntRegIndex dest, op2; uint64_t imm; SveTerImmUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op2, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op2(_op2), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE reductions. class SveReducOp : public ArmStaticInst { protected: IntRegIndex dest, op1, gp; SveReducOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE ordered reductions. class SveOrdReducOp : public ArmStaticInst { protected: IntRegIndex dest, op1, gp; SveOrdReducOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// PTRUE, PTRUES. class SvePtrueOp : public ArmStaticInst { protected: IntRegIndex dest; uint8_t imm; SvePtrueOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint8_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Integer compare SVE instruction. class SveIntCmpOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1, op2; IntRegIndex gp; bool op2IsWide; SveIntCmpOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp, bool _op2IsWide = false) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), gp(_gp), op2IsWide(_op2IsWide) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Integer compare with immediate SVE instruction. class SveIntCmpImmOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; int64_t imm; IntRegIndex gp; SveIntCmpImmOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, int64_t _imm, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// ADR. class SveAdrOp : public ArmStaticInst { public: enum SveAdrOffsetFormat { SveAdrOffsetPacked, SveAdrOffsetUnpackedSigned, SveAdrOffsetUnpackedUnsigned }; protected: IntRegIndex dest, op1, op2; uint8_t mult; SveAdrOffsetFormat offsetFormat; SveAdrOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint8_t _mult, SveAdrOffsetFormat _offsetFormat) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), mult(_mult), offsetFormat(_offsetFormat) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Element count SVE instruction. class SveElemCountOp : public ArmStaticInst { protected: IntRegIndex dest; uint8_t pattern; uint8_t imm; bool dstIsVec; bool dstIs32b; uint8_t esize; SveElemCountOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint8_t _pattern, uint8_t _imm, bool _dstIsVec, bool _dstIs32b) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), pattern(_pattern), imm(_imm), dstIsVec(_dstIsVec), dstIs32b(_dstIs32b) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Partition break SVE instruction. class SvePartBrkOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex gp; IntRegIndex op1; bool isMerging; SvePartBrkOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _op1, bool _isMerging) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), gp(_gp), op1(_op1), isMerging(_isMerging) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Partition break with propagation SVE instruction. class SvePartBrkPropOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; IntRegIndex op2; IntRegIndex gp; SvePartBrkPropOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Scalar element select SVE instruction. class SveSelectOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; IntRegIndex gp; bool conditional; bool scalar; bool simdFp; size_t scalar_width; SveSelectOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp, bool _conditional, bool _scalar, bool _simdFp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), gp(_gp), conditional(_conditional), scalar(_scalar), simdFp(_simdFp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE unary operation on predicate (predicated) class SveUnaryPredPredOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; IntRegIndex gp; SveUnaryPredPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE table lookup/permute using vector of element indices (TBL) class SveTblOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; IntRegIndex op2; SveTblOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE unpack and widen predicate class SveUnpackOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; SveUnpackOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE predicate test class SvePredTestOp : public ArmStaticInst { protected: IntRegIndex op1; IntRegIndex gp; SvePredTestOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _op1, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), op1(_op1), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE unary predicate instructions with implicit source operand class SvePredUnaryWImplicitSrcOp : public ArmStaticInst { protected: IntRegIndex dest; SvePredUnaryWImplicitSrcOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE unary predicate instructions, predicated, with implicit source operand class SvePredUnaryWImplicitSrcPredOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex gp; SvePredUnaryWImplicitSrcPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), gp(_gp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE unary predicate instructions with implicit destination operand class SvePredUnaryWImplicitDstOp : public ArmStaticInst { protected: IntRegIndex op1; SvePredUnaryWImplicitDstOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _op1) : ArmStaticInst(mnem, _machInst, __opClass), op1(_op1) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE unary predicate instructions with implicit destination operand class SveWImplicitSrcDstOp : public ArmStaticInst { protected: SveWImplicitSrcDstOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass) : ArmStaticInst(mnem, _machInst, __opClass) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE vector - immediate binary operation class SveBinImmUnpredDestrOp : public ArmStaticInst { protected: IntRegIndex dest; IntRegIndex op1; uint64_t imm; SveBinImmUnpredDestrOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Binary with immediate index, destructive, unpredicated SVE instruction. class SveBinImmIdxUnpredOp : public ArmStaticInst { protected: IntRegIndex dest, op1; uint64_t imm; SveBinImmIdxUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Unary unpredicated scalar to vector instruction class SveUnarySca2VecUnpredOp : public ArmStaticInst { protected: IntRegIndex dest, op1; bool simdFp; SveUnarySca2VecUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, bool _simdFp) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), simdFp(_simdFp) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE dot product instruction (indexed) class SveDotProdIdxOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; uint64_t imm; uint8_t esize; public: SveDotProdIdxOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint64_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE dot product instruction (vectors) class SveDotProdOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; uint8_t esize; public: SveDotProdOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE Complex Instructions (vectors) class SveComplexOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2, gp; uint8_t rot; public: SveComplexOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp, uint8_t _rot) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), gp(_gp), rot(_rot) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// SVE Complex Instructions (indexed) class SveComplexIdxOp : public ArmStaticInst { protected: IntRegIndex dest, op1, op2; uint8_t rot, imm; public: SveComplexIdxOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint8_t _rot, uint8_t _imm) : ArmStaticInst(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2), rot(_rot), imm(_imm) {} std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /// Returns the symbolic name associated with pattern `imm` for PTRUE(S) /// instructions. std::string sveDisasmPredCountImm(uint8_t imm); /// Returns the actual number of elements active for PTRUE(S) instructions. /// @param imm 5-bit immediate encoding the predicate pattern. /// @param num_elems Current number of elements per vector (depending on /// current vector length and element size). unsigned int sveDecodePredCount(uint8_t imm, unsigned int num_elems); /// Expand 1-bit floating-point immediate to 0.5 or 1.0 (FADD, FSUB, FSUBR). /// @param imm 1-bit immediate. /// @param size Encoding of the vector element size. /// @return Encoding of the expanded value. uint64_t sveExpandFpImmAddSub(uint8_t imm, uint8_t size); /// Expand 1-bit floating-point immediate to 0.0 or 1.0 (FMAX, FMAXNM, FMIN, /// FMINNM). /// @param imm 1-bit immediate. /// @param size Encoding of the vector element size. /// @return Encoding of the expanded value. uint64_t sveExpandFpImmMaxMin(uint8_t imm, uint8_t size); /// Expand 1-bit floating-point immediate to 0.5 or 2.0 (FMUL). /// @param imm 1-bit immediate. /// @param size Encoding of the vector element size. /// @return Encoding of the expanded value. uint64_t sveExpandFpImmMul(uint8_t imm, uint8_t size); } // namespace ArmISA #endif // __ARCH_ARM_INSTS_SVE_HH__