From fe8eda9c4ee53dec780463b3506c3bba30a57da9 Mon Sep 17 00:00:00 2001 From: Sascha Bischoff Date: Wed, 3 Aug 2022 15:38:46 +0100 Subject: [PATCH] arch, arch-arm, cpu: Add matrix reg support to the ISA Parser The ISA parser now emits the code required to access matrix registers. In the case where a register is both a source and a destination, the ISA parser generates appropriate code to make sure that the contents of the source is copied to the destination. This is required for the O3 CPU which treats these as two different physical registers, and hence data is lost if not explicitly preserved. Jira Issue: https://gem5.atlassian.net/browse/GEM5-1289 Change-Id: I8796bd1ea55b5edf5fb8ab92ef1a6060ccc58fa1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64338 Maintainer: Giacomo Travaglini Tested-by: kokoro Reviewed-by: Giacomo Travaglini --- src/arch/arm/isa/operands.isa | 8 ++++ src/arch/isa_parser/isa_parser.py | 5 ++- src/arch/isa_parser/operand_types.py | 65 +++++++++++++++++++++++++++- src/cpu/FuncUnit.py | 5 ++- src/cpu/minor/BaseMinorCPU.py | 3 ++ src/cpu/op_class.hh | 5 ++- 6 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 2addd10def..5919ae974e 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -53,6 +53,7 @@ def operand_types {{ 'sf' : 'float', 'df' : 'double', 'vc' : 'ArmISA::VecRegContainer', + 'mc' : 'ArmISA::MatRegContainer', # For operations that are implemented as a template 'x' : 'TPElem', 'xs' : 'TPSElem', @@ -99,6 +100,10 @@ let {{ def __init__(self, idx): super().__init__('pc', idx, sort_pri=srtNormal) + class MatrixReg(MatRegOp): + def __init__(self, idx, suffix=''): + super().__init__('mc', idx, 'IsMatrix', srtNormal) + class IntRegNPC(IntRegOp): @overrideInOperand def regId(self): @@ -454,6 +459,9 @@ def operands {{ 'FfrAux': VecPredReg('PREDREG_FFR'), 'PUreg0': VecPredReg('PREDREG_UREG0'), + # SME ZA Register: + 'ZA': MatrixReg('0'), + #Abstracted control reg operands 'MiscDest': CntrlReg('dest'), 'MiscOp1': CntrlReg('op1'), diff --git a/src/arch/isa_parser/isa_parser.py b/src/arch/isa_parser/isa_parser.py index aff3c9f63c..39b50f06b6 100755 --- a/src/arch/isa_parser/isa_parser.py +++ b/src/arch/isa_parser/isa_parser.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014, 2016, 2018-2019 ARM Limited +# Copyright (c) 2014, 2016, 2018-2019, 2022 ARM Limited # All rights reserved # # The license below extends only to copyright in the software and shall @@ -481,6 +481,8 @@ class InstObjParams(object): self.op_class = "FloatAddOp" elif "IsVector" in self.flags: self.op_class = "SimdAddOp" + elif "IsMatrix" in self.flags: + self.op_class = "MatrixOp" else: self.op_class = "IntAluOp" @@ -564,6 +566,7 @@ class ISAParser(Grammar): "VecElemOp": VecElemOperandDesc, "VecRegOp": VecRegOperandDesc, "VecPredRegOp": VecPredRegOperandDesc, + "MatRegOp": MatRegOperandDesc, "ControlRegOp": ControlRegOperandDesc, "MemOp": MemOperandDesc, "PCStateOp": PCStateOperandDesc, diff --git a/src/arch/isa_parser/operand_types.py b/src/arch/isa_parser/operand_types.py index 63ca765a09..4786f88774 100755 --- a/src/arch/isa_parser/operand_types.py +++ b/src/arch/isa_parser/operand_types.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014, 2016, 2018-2019 ARM Limited +# Copyright (c) 2014, 2016, 2018-2019, 2022 ARM Limited # All rights reserved # # The license below extends only to copyright in the software and shall @@ -447,6 +447,69 @@ class VecPredRegOperandDesc(RegOperandDesc): super().__init__("vecPredRegClass", VecPredRegOperand, *args, **kwargs) +class MatRegOperand(RegOperand): + reg_class = "MatRegClass" + + def __init__(self, parser, full_name, ext, is_src, is_dest): + super().__init__(parser, full_name, ext, is_src, is_dest) + + def makeDecl(self): + return "" + + def makeReadW(self): + c_readw = ( + f"\t\tauto &tmp_d{self.dest_reg_idx} = \n" + f"\t\t *({self.parser.namespace}::MatRegContainer *)\n" + f"\t\t xc->getWritableRegOperand(this, \n" + f"\t\t {self.dest_reg_idx});\n" + f"\t\tauto &{self.base_name} = tmp_d{self.dest_reg_idx};\n" + ) + + return c_readw + + def makeRead(self): + name = self.base_name + if self.is_dest and self.is_src: + name += "_merger" + + c_read = ( + f"\t\t{self.parser.namespace}::MatRegContainer " + f"\t\t tmp_s{self.src_reg_idx};\n" + f"\t\txc->getRegOperand(this, {self.src_reg_idx},\n" + f"\t\t &tmp_s{self.src_reg_idx});\n" + f"\t\tauto &{name} = tmp_s{self.src_reg_idx};\n" + ) + + # The following is required due to the way that the O3 CPU + # works. The ZA register is seen as two physical registers; one + # for reading from and one for writing to. We need to make sure + # to copy the data from the read-only copy to the writable + # reference (the destination). Failure to do this results in + # data loss for the O3 CPU. Other CPU models don't appear to + # require this. + if self.is_dest and self.is_src: + c_read += f"{self.base_name} = {name};" + + return c_read + + def makeWrite(self): + return f""" + if (traceData) {{ + traceData->setData({self.reg_class}, &tmp_d{self.dest_reg_idx}); + }} + """ + + def finalize(self): + super().finalize() + if self.is_dest: + self.op_rd = self.makeReadW() + self.op_rd + + +class MatRegOperandDesc(RegOperandDesc): + def __init__(self, *args, **kwargs): + super().__init__("matRegClass", MatRegOperand, *args, **kwargs) + + class ControlRegOperand(Operand): reg_class = "miscRegClass" diff --git a/src/cpu/FuncUnit.py b/src/cpu/FuncUnit.py index c5137ac970..4a2733afc0 100644 --- a/src/cpu/FuncUnit.py +++ b/src/cpu/FuncUnit.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010, 2017-2018 ARM Limited +# Copyright (c) 2010, 2017-2018, 2022 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -89,6 +89,9 @@ class OpClass(Enum): "SimdShaSigma2", "SimdShaSigma3", "SimdPredAlu", + "Matrix", + "MatrixMov", + "MatrixOP", "MemRead", "MemWrite", "FloatMemRead", diff --git a/src/cpu/minor/BaseMinorCPU.py b/src/cpu/minor/BaseMinorCPU.py index bcdab1bad5..6641a39b4e 100644 --- a/src/cpu/minor/BaseMinorCPU.py +++ b/src/cpu/minor/BaseMinorCPU.py @@ -215,6 +215,9 @@ class MinorDefaultFloatSimdFU(MinorFU): "SimdSha256Hash2", "SimdShaSigma2", "SimdShaSigma3", + "Matrix", + "MatrixMov", + "MatrixOP", ] ) diff --git a/src/cpu/op_class.hh b/src/cpu/op_class.hh index 94730f3d5d..4de018f21b 100644 --- a/src/cpu/op_class.hh +++ b/src/cpu/op_class.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2017-2018 ARM Limited + * Copyright (c) 2010, 2017-2018, 2022 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -99,6 +99,9 @@ static const OpClass SimdSha256Hash2Op = enums::SimdSha256Hash2; static const OpClass SimdShaSigma2Op = enums::SimdShaSigma2; static const OpClass SimdShaSigma3Op = enums::SimdShaSigma3; static const OpClass SimdPredAluOp = enums::SimdPredAlu; +static const OpClass MatrixOp = enums::Matrix; +static const OpClass MatrixMovOp = enums::MatrixMov; +static const OpClass MatrixOPOp = enums::MatrixOP; static const OpClass MemReadOp = enums::MemRead; static const OpClass MemWriteOp = enums::MemWrite; static const OpClass FloatMemReadOp = enums::FloatMemRead;