X86: Implement a media microop for converting integer values to floating point.
authorGabe Black <gblack@eecs.umich.edu>
Tue, 18 Aug 2009 01:41:25 +0000 (18:41 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Tue, 18 Aug 2009 01:41:25 +0000 (18:41 -0700)
src/arch/x86/isa/microops/mediaop.isa

index edfc27908bb6e59660471472af002e1d49ce4278..641f378653013494460785ef5dd6378cb9228603 100644 (file)
@@ -758,4 +758,64 @@ let {{
             }
             FpDestReg.uqw = result;
         '''
+
+    class Cvti2f(MediaOp):
+        def __init__(self, dest, src, \
+                size = None, destSize = None, srcSize = None, ext = None):
+            super(Cvti2f, self).__init__(dest, src,\
+                    "InstRegIndex(0)", size, destSize, srcSize, ext)
+        code = '''
+            union floatInt
+            {
+                float f;
+                uint32_t i;
+            };
+            union doubleInt
+            {
+                double d;
+                uint64_t i;
+            };
+
+            assert(destSize == 4 || destSize == 8);
+            assert(srcSize == 4 || srcSize == 8);
+            int srcSizeBits = srcSize * 8;
+            int destSizeBits = destSize * 8;
+            int items;
+            int srcStart = 0;
+            int destStart = 0;
+            if (srcSize == 2 * destSize) {
+                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
+                if (ext & 0x2)
+                    destStart = destSizeBits * items;
+            } else if (destSize == 2 * srcSize) {
+                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
+                if (ext & 0x2)
+                    srcStart = srcSizeBits * items;
+            } else {
+                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
+            }
+            uint64_t result = FpDestReg.uqw;
+
+            for (int i = 0; i < items; i++) {
+                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
+                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
+                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
+                int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex)));
+                double arg = sArg;
+
+                if (destSize == 4) {
+                    floatInt fi;
+                    fi.f = arg;
+                    argBits = fi.i;
+                } else {
+                    doubleInt di;
+                    di.d = arg;
+                    argBits = di.i;
+                }
+                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
+                int destLoIndex = destStart + (i + 0) * destSizeBits;
+                result = insertBits(result, destHiIndex, destLoIndex, argBits);
+            }
+            FpDestReg.uqw = result;
+        '''
 }};