From: Sandipan Das Date: Sat, 6 Feb 2021 11:52:00 +0000 (+0530) Subject: arch-power: Fix rotate instructions X-Git-Tag: develop-gem5-snapshot~21 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=70067883b00b7932378caeb73584fe511a550f77;p=gem5.git arch-power: Fix rotate instructions Now that 64-bit registers are being used, the rotation operation changes for words. Instead of just rotating the lower word of the operand, the lower word is first duplicated in the upper word and then rotated. This fixes the following instructions. * Rotate Left Word Immediate then And with Mask (rlwinm[.]) * Rotate Left Word then And with Mask (rlwnm[.]) * Rotate Left Word Immediate then Mask Insert (rlwimi[.]) Change-Id: Ic743bceb8bafff461276984ecc999dedc1f94e9f Signed-off-by: Sandipan Das --- diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index d96936291..6d39a5fed 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -651,7 +651,6 @@ class IntRotateOp : public IntShiftOp { protected: - uint32_t fullMask; uint32_t maskBeg; uint32_t maskEnd; @@ -661,18 +660,29 @@ class IntRotateOp : public IntShiftOp maskBeg(machInst.mb), maskEnd(machInst.me) { - if (maskEnd >= maskBeg) { - fullMask = mask(31 - maskBeg, 31 - maskEnd); - } else { - fullMask = ~mask(31 - (maskEnd + 1), 31 - (maskBeg - 1)); - } } - inline uint32_t + inline uint64_t rotate(uint32_t rs, uint32_t sh) const { - uint32_t n = shift & 31; - return (rs << n) | (rs >> (32 - n)); + uint64_t res; + sh = sh & 0x1f; + res = rs; + res = (res << 32) | res; + res = (res << sh) | (res >> (32 - sh)); + return res; + } + + inline uint64_t + bitmask(uint32_t mb, uint32_t me) const + { + mb = mb & 0x1f; + me = me & 0x1f; + if (mb <= me) { + return mask(31 - mb, 31 - me); + } else { + return ~mask(31 - (me + 1), 31 - (mb - 1)); + } } std::string generateDisassembly( diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index ef66ac95d..1c67d3aaa 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -266,10 +266,27 @@ decode PO default Unknown::unknown() { } format IntRotateOp { - 21: rlwinm({{ Ra = rotate(Rs, sh) & fullMask; }}); - 23: rlwnm({{ Ra = rotate(Rs, Rb) & fullMask; }}); - 20: rlwimi({{ Ra = (rotate(Rs, sh) & fullMask) | - (Ra & ~fullMask); }}); + 21: rlwinm({{ + uint64_t res; + res = rotate(Rs, shift); + res = res & bitmask(maskBeg, maskEnd); + Ra = res; + }}); + + 23: rlwnm({{ + uint64_t res; + res = rotate(Rs, Rb); + res = res & bitmask(maskBeg, maskEnd); + Ra = res; + }}); + + 20: rlwimi({{ + uint64_t res, mask; + mask = bitmask(maskBeg, maskEnd); + res = rotate(Rs, shift); + res = (res & mask) | (Ra & ~mask); + Ra = res; + }}); } // There are a large number of instructions that have the same primary