summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-08-17 20:25:14 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-08-17 20:25:14 -0700
commit288f4286322f56255d15b13224371ec60b4b2cac (patch)
tree3f74dd71f729c0de1885f2697ba0ebb85fc49fd6
parent87ad6772094170cf92e8de385e1dea47a31924dc (diff)
downloadgem5-288f4286322f56255d15b13224371ec60b4b2cac.tar.xz
X86: Implement a microop that compares fp values and writes a mask as a result.
-rw-r--r--src/arch/x86/isa/microops/mediaop.isa82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa
index 75a4c9468..f268a6b90 100644
--- a/src/arch/x86/isa/microops/mediaop.isa
+++ b/src/arch/x86/isa/microops/mediaop.isa
@@ -1343,6 +1343,88 @@ let {{
FpDestReg.uqw = result;
'''
+ class Mcmpf2r(MediaOp):
+ code = '''
+ union floatInt
+ {
+ float f;
+ uint32_t i;
+ };
+ union doubleInt
+ {
+ double d;
+ uint64_t i;
+ };
+
+ assert(srcSize == destSize);
+ int size = srcSize;
+ int sizeBits = size * 8;
+ int items = (ext & 0x8) ? 1: (sizeof(FloatRegBits) / size);
+ uint64_t result = FpDestReg.uqw;
+
+ for (int i = 0; i < items; i++) {
+ int hiIndex = (i + 1) * sizeBits - 1;
+ int loIndex = (i + 0) * sizeBits;
+ uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
+ uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
+ double arg1, arg2;
+
+ if (size == 4) {
+ floatInt fi;
+ fi.i = arg1Bits;
+ arg1 = fi.f;
+ fi.i = arg2Bits;
+ arg2 = fi.f;
+ } else {
+ doubleInt di;
+ di.i = arg1Bits;
+ arg1 = di.d;
+ di.i = arg2Bits;
+ arg2 = di.d;
+ }
+
+ uint64_t resBits = 0;
+ bool nanop = isnan(arg1) || isnan(arg2);
+ switch (ext & mask(3)) {
+ case 0:
+ if (arg1 == arg2 && !nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 1:
+ if (arg1 < arg2 && !nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 2:
+ if (arg1 <= arg2 && !nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 3:
+ if (nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 4:
+ if (arg1 != arg2 || nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 5:
+ if (!(arg1 < arg2) || nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 6:
+ if (!(arg1 <= arg2) || nanop)
+ resBits = mask(sizeBits);
+ break;
+ case 7:
+ if (!nanop)
+ resBits = mask(sizeBits);
+ break;
+ };
+
+ result = insertBits(result, hiIndex, loIndex, resBits);
+ }
+ FpDestReg.uqw = result;
+ '''
+
class Mcmpf2rf(MediaOp):
def __init__(self, src1, src2,\
size = None, destSize = None, srcSize = None, ext = None):