arch-arm: Add support for the SVE INSR (scalar) instruction Change-Id: I0e2fb57cf6c0d452722c92bd60f291d9d33c758b Signed-off-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com>
diff --git a/src/arch/arm/insts/sve.cc b/src/arch/arm/insts/sve.cc index e8e6fa9..d16c47e 100644 --- a/src/arch/arm/insts/sve.cc +++ b/src/arch/arm/insts/sve.cc
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited + * Copyright (c) 2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -690,6 +690,18 @@ } std::string +SveUnarySca2VecUnpredOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + printMnemonic(ss, "", false); + printVecReg(ss, dest, true); + ccprintf(ss, ", "); + printIntReg(ss, op1); + return ss.str(); +} + +std::string sveDisasmPredCountImm(uint8_t imm) { switch (imm) {
diff --git a/src/arch/arm/insts/sve.hh b/src/arch/arm/insts/sve.hh index 2417211..3344e8c 100644 --- a/src/arch/arm/insts/sve.hh +++ b/src/arch/arm/insts/sve.hh
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited + * Copyright (c) 2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -729,6 +729,20 @@ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; +/// Unary unpredicated scalar to vector instruction +class SveUnarySca2VecUnpredOp : public ArmStaticInst { + protected: + IntRegIndex dest, op1; + + SveUnarySca2VecUnpredOp(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; +}; + /// Returns the symbolic name associated with pattern `imm` for PTRUE(S) /// instructions. std::string sveDisasmPredCountImm(uint8_t imm);
diff --git a/src/arch/arm/isa/formats/sve_2nd_level.isa b/src/arch/arm/isa/formats/sve_2nd_level.isa index c994f5c..2276cd6 100644 --- a/src/arch/arm/isa/formats/sve_2nd_level.isa +++ b/src/arch/arm/isa/formats/sve_2nd_level.isa
@@ -1003,8 +1003,10 @@ IntRegIndex zd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); return decodeSveUnaryUnpredU<SveDupScalar>(size, machInst, zd, rn); } else if (bits(machInst, 20, 16) == 0x4 && b12_10 == 0x6) { - // INSR (scalar) - return new Unknown64(machInst); + uint8_t size = bits(machInst, 23, 22); + IntRegIndex zdn = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); + IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); + return decodeSveUnaryUnpredU<SveInsr>(size, machInst, zdn, rm); } else if (bits(machInst, 20, 16) == 0x14 && b12_10 == 0x6) { // INSR (SIMD&FP scalar) return new Unknown64(machInst);
diff --git a/src/arch/arm/isa/insts/sve.isa b/src/arch/arm/isa/insts/sve.isa index d71ab23..0182da3 100644 --- a/src/arch/arm/isa/insts/sve.isa +++ b/src/arch/arm/isa/insts/sve.isa
@@ -1,4 +1,4 @@ -// Copyright (c) 2017 ARM Limited +// Copyright (c) 2018 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -2612,6 +2612,33 @@ substDict = {'targs': type, 'class_name': 'Sve' + Name} exec_output += SveOpExecDeclare.subst(substDict) + # Generate definition for shift & insert instructions + def sveShiftAndInsertInst(name, Name, opClass, types, + srcType = SrcRegType.Scalar, decoder = 'Generic'): + assert srcType in (SrcRegType.Vector, SrcRegType.Scalar) + global header_output, exec_output, decoders + code = sveEnabledCheckCode + ''' + unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>( + xc->tcBase());''' + if srcType == SrcRegType.Scalar: + code += ''' + auto& srcElem1 = XOp1;''' + else: + code += ''' + auto& srcElem1 = AA64FpOp1;''' + code += ''' + for (int i = eCount - 1; i > 0; --i) { + AA64FpDest_x[i] = AA64FpDestMerge_x[i-1]; + } + AA64FpDest_x[0] = srcElem1;''' + iop = InstObjParams(name, 'Sve' + Name, 'SveUnarySca2VecUnpredOp', + {'code': code, 'op_class': opClass}, []) + header_output += SveUnaryUnpredOpDeclare.subst(iop) + exec_output += SveOpExecute.subst(iop) + for type in types: + substDict = {'targs': type, 'class_name': 'Sve' + Name} + exec_output += SveOpExecDeclare.subst(substDict) + fpTypes = ('uint16_t', 'uint32_t', 'uint64_t') signedTypes = ('int8_t', 'int16_t', 'int32_t', 'int64_t') unsignedTypes = ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t') @@ -3385,6 +3412,9 @@ sveIndex(IndexFormat.RegImm) # INDEX (scalars) sveIndex(IndexFormat.RegReg) + # INSR (scalar) + sveShiftAndInsertInst('insr', 'Insr', 'SimdAluOp', unsignedTypes, + srcType = SrcRegType.Scalar) # LASTA (scalar) lastaCode = ''' last++;