diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-08-05 03:01:49 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-08-05 03:01:49 -0700 |
commit | d265f7683e761207a60d9187324846aedf674c84 (patch) | |
tree | 6af4d0c31018863baec8ff63f82f2488d1d34af1 | |
parent | 77dc6b33ee836e030a2e9c230b8ce67e0e39c322 (diff) | |
download | gem5-d265f7683e761207a60d9187324846aedf674c84.tar.xz |
X86: Handle rotate right with carry instructions that go all the way around or more.
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 0bf3420b8..477034224 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -762,13 +762,14 @@ let {{ code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); - if(shiftAmt) + uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1); + if(realShiftAmt) { CCFlagBits flags = ccFlagBits; - uint64_t top = flags.cf << (dataSize * 8 - shiftAmt); - if(shiftAmt > 1) - top |= psrc1 << (dataSize * 8 - shiftAmt + 1); - uint64_t bottom = bits(psrc1, dataSize * 8 - 1, shiftAmt); + uint64_t top = flags.cf << (dataSize * 8 - realShiftAmt); + if (realShiftAmt > 1) + top |= psrc1 << (dataSize * 8 - realShiftAmt + 1); + uint64_t bottom = bits(psrc1, dataSize * 8 - 1, realShiftAmt); DestReg = merge(DestReg, top | bottom, dataSize); } else @@ -787,8 +788,11 @@ let {{ ccFlagBits = ccFlagBits | OFBit; } //If some combination of the CF bits need to be set, set them. - if ((ext & (CFBit | ECFBit)) && bits(SrcReg1, shiftAmt - 1)) + if ((ext & (CFBit | ECFBit)) && + (realShiftAmt == 0) ? origCFBit : + bits(SrcReg1, realShiftAmt - 1)) { ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + } //Use the regular mechanisms to calculate the other flags. ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); |