From 70b783384e41f93cbc13d01cfcf2b20dbe67ccfc Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:21:37 +0530 Subject: [PATCH] arch-power: Refactor shift instructions This changes the format for integer shift instructions such that the computation of the carry bit is implicitly handled rather than including it in the definition of an instruction. Change-Id: Ib916597287efd51b2c9e8781209a8019f2fc38e8 Signed-off-by: Sandipan Das --- src/arch/power/insts/integer.hh | 7 ++-- src/arch/power/isa/decoder.isa | 44 ++++++++------------------ src/arch/power/isa/formats/integer.isa | 31 +++++++++++++++--- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index 1e4ce368b..14b6daca5 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -599,18 +599,19 @@ class IntImmLogicOp : public IntLogicOp /** - * Class for integer operations with a shift. + * Class for integer operations with a shift value obtained from + * a register or an instruction field. */ class IntShiftOp : public IntOp { protected: - uint32_t sh; + uint32_t shift; /// Constructor IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass) : IntOp(mnem, _machInst, __opClass), - sh(machInst.sh) + shift(machInst.sh) { } diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 908ba3c26..80886de93 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -583,7 +583,10 @@ decode PO default Unknown::unknown() { } Ra = res; }}); + } + // Integer instructions with a shift value. + format IntShiftOp { 24: slw({{ if (Rb & 0x20) { Ra = 0; @@ -601,65 +604,46 @@ decode PO default Unknown::unknown() { }}); 792: sraw({{ - bool shiftSetCA = false; int32_t s = Rs; if (Rb == 0) { Ra = Rs; - shiftSetCA = true; + setCA = true; } else if (Rb & 0x20) { if (s < 0) { Ra = (uint32_t)-1; if (s & 0x7fffffff) { - shiftSetCA = true; + setCA = true; } else { - shiftSetCA = false; + setCA = false; } } else { Ra = 0; - shiftSetCA = false; + setCA = false; } } else { Ra = s >> (Rb & 0x1f); if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) { - shiftSetCA = true; + setCA = true; } else { - shiftSetCA = false; + setCA = false; } } - Xer xer1 = XER; - if (shiftSetCA) { - xer1.ca = 1; - } else { - xer1.ca = 0; - } - XER = xer1; - }}); - } + }}, true); - // Integer logic instructions with a shift value. - format IntShiftOp { 824: srawi({{ - bool shiftSetCA = false; if (sh == 0) { Ra = Rs; - shiftSetCA = false; + setCA = false; } else { int32_t s = Rs; Ra = s >> sh; if (s < 0 && (s << (32 - sh)) != 0) { - shiftSetCA = true; + setCA = true; } else { - shiftSetCA = false; + setCA = false; } } - Xer xer1 = XER; - if (shiftSetCA) { - xer1.ca = 1; - } else { - xer1.ca = 0; - } - XER = xer1; - }}); + }}, true); } format StoreIndexOp { diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index 286c1cf98..4fa21349d 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -110,6 +110,16 @@ computeOVCode = ''' } ''' +setCACode = ''' + if (setCA) { + xer.ca = 1; + xer.ca32 = 1; + } else { + xer.ca = 0; + xer.ca32 = 0; + } +''' + setOVCode = ''' if (setOV) { xer.ov = 1; @@ -305,13 +315,26 @@ def format IntLogicOp(code, computeCR0 = 0, inst_flags = []) {{ }}; -// Integer instructions with a shift amount. As above, except inheriting -// from the IntShiftOp class. -def format IntShiftOp(code, inst_flags = []) {{ +// Integer instructions that perform shift operations. All of these +// instructions write to Ra and use Rs as a source register. The shift +// value is obtained from an register or an instruction field. If it +// from a register, Rb is also used as a source register. In certain +// situations, the carry bits have to be set and this is dealt with +// using the 'setCA' boolean in decoder.isa. We need two versions for +// each instruction to deal with the Rc bit. +def format IntShiftOp(code, computeCA = 0, inst_flags = []) {{ dict = {'result':'Ra'} + # Add code to setup variables and access XER if necessary + code = 'M5_VAR_USED bool setCA = false;\n' + code + # Code when Rc is set - code_rc1 = code + readXERCode + computeCR0Code % dict + code_rc1 = readXERCode + code + computeCR0Code % dict + + # Add code for calculating the carry, if needed + if computeCA: + code = readXERCode + code + setCACode + setXERCode + code_rc1 += setCACode + setXERCode # Generate the first class (header_output, decoder_output, decode_block, exec_output) = \ -- 2.30.2