OSDN Git Service

Manually convert unsigned integer to floating-point.
authorNicolas Capens <capn@google.com>
Thu, 15 Dec 2016 19:45:13 +0000 (14:45 -0500)
committerNicolas Capens <capn@google.com>
Mon, 16 Jan 2017 18:54:27 +0000 (18:54 +0000)
Subzero uses a helper function to convert uint to float. It's faster to
just emit a sequence of operations to perform the cast manually.
This implementation converts the lower 31 bits as a signed integer, and
adds 0x80000000 as a floating-point value when the upper bit is set.
This approach does not produce the correct rounding in rare cases, but
should still be adequate. For consistency, we're also using this method
with the LLVM back-end.

Change-Id: Ic5d7b73cd2a9e154056365cdbe9af0962bdbe1cb
Reviewed-on: https://swiftshader-review.googlesource.com/8312
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/Reactor/LLVMReactor.cpp
src/Reactor/Nucleus.hpp
src/Reactor/SubzeroReactor.cpp

index 2b7da2c..d319445 100644 (file)
@@ -482,11 +482,6 @@ namespace sw
                return V(::builder->CreateFPToSI(v, destType));
        }
 
-       Value *Nucleus::createUIToFP(Value *v, Type *destType)
-       {
-               return V(::builder->CreateUIToFP(v, destType));
-       }
-
        Value *Nucleus::createSIToFP(Value *v, Type *destType)
        {
                return V(::builder->CreateSIToFP(v, destType));
@@ -952,7 +947,7 @@ namespace sw
                return rhs;
        }
 
-       RValue<Byte> Byte::operator=(const Byte &rhs) 
+       RValue<Byte> Byte::operator=(const Byte &rhs)
        {
                Value *value = rhs.loadValue();
                storeValue(value);
@@ -6101,9 +6096,10 @@ namespace sw
        {
                xyzw.parent = this;
 
-               Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
+               RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
+                                       As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
 
-               storeValue(xyzw);
+               storeValue(result.value);
        }
 
        Float4::Float4()
index 8307800..196ca76 100644 (file)
@@ -106,7 +106,6 @@ namespace sw
                static Value *createZExt(Value *V, Type *destType);
                static Value *createSExt(Value *V, Type *destType);
                static Value *createFPToSI(Value *V, Type *destType);
-               static Value *createUIToFP(Value *V, Type *destType);
                static Value *createSIToFP(Value *V, Type *destType);
                static Value *createFPTrunc(Value *V, Type *destType);
                static Value *createFPExt(Value *V, Type *destType);
index ab4c109..c8d7e1c 100644 (file)
@@ -853,11 +853,6 @@ namespace sw
                return createCast(Ice::InstCast::Fptosi, v, destType);
        }
 
-       Value *Nucleus::createUIToFP(Value *v, Type *destType)
-       {
-               return createCast(Ice::InstCast::Uitofp, v, destType);
-       }
-
        Value *Nucleus::createSIToFP(Value *v, Type *destType)
        {
                return createCast(Ice::InstCast::Sitofp, v, destType);
@@ -5996,9 +5991,10 @@ namespace sw
        {
                xyzw.parent = this;
 
-               Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
+               RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
+                                       As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
 
-               storeValue(xyzw);
+               storeValue(result.value);
        }
 
        Float4::Float4()