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 <sandipan@linux.ibm.com>
uint32_t maskBeg;
uint32_t maskEnd;
uint32_t maskBeg;
uint32_t maskEnd;
maskBeg(machInst.mb),
maskEnd(machInst.me)
{
maskBeg(machInst.mb),
maskEnd(machInst.me)
{
- if (maskEnd >= maskBeg) {
- fullMask = mask(31 - maskBeg, 31 - maskEnd);
- } else {
- fullMask = ~mask(31 - (maskEnd + 1), 31 - (maskBeg - 1));
- }
rotate(uint32_t rs, uint32_t sh) const
{
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(
}
std::string generateDisassembly(
- 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
}
// There are a large number of instructions that have the same primary