OSDN Git Service

Emulate sub-vector load/store intrinsics.
authorNicolas Capens <capn@google.com>
Wed, 26 Apr 2017 17:36:33 +0000 (13:36 -0400)
committerNicolas Capens <nicolascapens@google.com>
Wed, 26 Jul 2017 19:28:17 +0000 (19:28 +0000)
Bug b/37496321

Change-Id: I173b458a0d1d477ad75deaa33508ae1766c182c0
Reviewed-on: https://swiftshader-review.googlesource.com/9491
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/Reactor/SubzeroReactor.cpp

index 6fbd7a5..1a0ac08 100644 (file)
@@ -849,12 +849,43 @@ namespace sw
 
                if(valueType & EmulatedBits)
                {
-                       const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
-                       auto target = ::context->getConstantUndef(Ice::IceType_i32);
-                       auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
-                       load->addArg(ptr);
-                       load->addArg(::context->getConstantInt32(typeSize(type)));
-                       ::basicBlock->appendInst(load);
+                       if(emulateIntrinsics)
+                       {
+                               if(typeSize(type) == 4)
+                               {
+                                       auto pointer = RValue<Pointer<Byte>>(ptr);
+                                       Int x = *Pointer<Int>(pointer +1-1);
+
+                                       Int4 vector;
+                                       vector = Insert(vector, x, 0);
+
+                                       auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
+                                       ::basicBlock->appendInst(bitcast);
+                               }
+                               else if(typeSize(type) == 8)
+                               {
+                                       auto pointer = RValue<Pointer<Byte>>(ptr);
+                                       Int x = *Pointer<Int>(pointer +1-1);
+                                       Int y = *Pointer<Int>(pointer + 4);
+
+                                       Int4 vector;
+                                       vector = Insert(vector, x, 0);
+                                       vector = Insert(vector, y, 1);
+
+                                       auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
+                                       ::basicBlock->appendInst(bitcast);
+                               }
+                               else assert(false);
+                       }
+                       else
+                       {
+                               const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
+                               auto target = ::context->getConstantUndef(Ice::IceType_i32);
+                               auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
+                               load->addArg(ptr);
+                               load->addArg(::context->getConstantInt32(typeSize(type)));
+                               ::basicBlock->appendInst(load);
+                       }
                }
                else
                {
@@ -871,13 +902,46 @@ namespace sw
 
                if(valueType & EmulatedBits)
                {
-                       const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
-                       auto target = ::context->getConstantUndef(Ice::IceType_i32);
-                       auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
-                       store->addArg(value);
-                       store->addArg(ptr);
-                       store->addArg(::context->getConstantInt32(typeSize(type)));
-                       ::basicBlock->appendInst(store);
+                       if(emulateIntrinsics)
+                       {
+                               if(typeSize(type) == 4)
+                               {
+                                       Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
+                                       auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
+                                       ::basicBlock->appendInst(bitcast);
+
+                                       RValue<Int4> v(V(vector));
+
+                                       auto pointer = RValue<Pointer<Byte>>(ptr);
+                                       Int x = Extract(v, 0);
+                                       *Pointer<Int>(pointer) = x;
+                               }
+                               else if(typeSize(type) == 8)
+                               {
+                                       Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
+                                       auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
+                                       ::basicBlock->appendInst(bitcast);
+
+                                       RValue<Int4> v(V(vector));
+
+                                       auto pointer = RValue<Pointer<Byte>>(ptr);
+                                       Int x = Extract(v, 0);
+                                       *Pointer<Int>(pointer) = x;
+                                       Int y = Extract(v, 1);
+                                       *Pointer<Int>(pointer + 4) = y;
+                               }
+                               else assert(false);
+                       }
+                       else
+                       {
+                               const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
+                               auto target = ::context->getConstantUndef(Ice::IceType_i32);
+                               auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
+                               store->addArg(value);
+                               store->addArg(ptr);
+                               store->addArg(::context->getConstantInt32(typeSize(type)));
+                               ::basicBlock->appendInst(store);
+                       }
                }
                else
                {