summaryrefslogtreecommitdiff
path: root/src/arch/x86
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
commit2c9ee52c3726b43fda9f68dbbcad069b3c2e874c (patch)
tree9bdaea719da7f9d6d0faf6d3b7c22978ef1b811f /src/arch/x86
parent7d4db7266ea950bb1af6f74f407cc1e9e11faff6 (diff)
downloadgem5-2c9ee52c3726b43fda9f68dbbcad069b3c2e874c.tar.xz
X86: Implement a microop that compares fp values and writes to rflags.
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/isa/microops/mediaop.isa55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa
index 1bd99db3a..75a4c9468 100644
--- a/src/arch/x86/isa/microops/mediaop.isa
+++ b/src/arch/x86/isa/microops/mediaop.isa
@@ -1342,4 +1342,59 @@ let {{
}
FpDestReg.uqw = result;
'''
+
+ class Mcmpf2rf(MediaOp):
+ def __init__(self, src1, src2,\
+ size = None, destSize = None, srcSize = None, ext = None):
+ super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\
+ src2, size, destSize, srcSize, ext)
+ code = '''
+ union floatInt
+ {
+ float f;
+ uint32_t i;
+ };
+ union doubleInt
+ {
+ double d;
+ uint64_t i;
+ };
+
+ assert(srcSize == destSize);
+ assert(srcSize == 4 || srcSize == 8);
+ int size = srcSize;
+ int sizeBits = size * 8;
+
+ double arg1, arg2;
+ uint64_t arg1Bits = bits(FpSrcReg1.uqw, sizeBits - 1, 0);
+ uint64_t arg2Bits = bits(FpSrcReg2.uqw, sizeBits - 1, 0);
+ 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;
+ }
+
+ // ZF PF CF
+ // Unordered 1 1 1
+ // Greater than 0 0 0
+ // Less than 0 0 1
+ // Equal 1 0 0
+ // OF = SF = AF = 0
+ ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
+ ZFBit | PFBit | CFBit);
+ if (isnan(arg1) || isnan(arg2))
+ ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
+ else if(arg1 < arg2)
+ ccFlagBits = ccFlagBits | CFBit;
+ else if(arg1 == arg2)
+ ccFlagBits = ccFlagBits | ZFBit;
+ '''
}};