IPSDK  4_1_0_2
IPSDK : Image Processing Software Development Kit
SignedUnsignedOpReg.h
Go to the documentation of this file.
1 // SignedUnsignedOpReg.h:
3 // -------------------
4 //
14 
15 #ifndef __IPSDKUTIL_INSTRUCTIONSET_ARITHMETIC_DETAIL_STD_SIGNEDUNSIGNEDOPREG_H__
16 #define __IPSDKUTIL_INSTRUCTIONSET_ARITHMETIC_DETAIL_STD_SIGNEDUNSIGNEDOPREG_H__
17 
19 #include <IPSDKUtil/InstructionSet/Arithmetic/detail/SignedUnsignedOpReg.h>
21 
22 #include <boost/type_traits/make_unsigned.hpp>
23 
24 namespace ipsdk {
25 namespace simd {
26 namespace detail {
27 
30 
31 /*
32  * Copied from boost_1_53_0/include/boost/random/detail/signed_unsigned_tools.hpp
33  * Compute x - y, we know that x >= y, return an unsigned value.
34  */
35 
38 template<typename T>
40  T, /* signed */ false>
41 {
42  typedef T result_type;
43 
44  static IPSDK_FORCEINLINE result_type act(T x, T y)
45  {
46  return x - y;
47  }
48 
49  static IPSDK_FORCEINLINE result_type act(T x, T y, result_type& out)
50  {
51  out = x - y;
52  }
53 };
54 
57 template<typename T>
59  T, /* signed */ true>
60 {
61  typedef typename boost::make_unsigned<T>::type result_type;
62 
63  static IPSDK_FORCEINLINE result_type act(T x, T y)
64  {
65  if (y >= 0) // because x >= y, it follows that x >= 0, too
66  return result_type(x) - result_type(y);
67  if (x >= 0) // y < 0
68  // avoid the nasty two's complement case for y == min()
69  return result_type(x) + result_type(-(y+1)) + 1;
70  // both x and y are negative: no signed overflow
71  return result_type(x - y);
72  }
73 
74  static IPSDK_FORCEINLINE void act(T x, T y, result_type& out)
75  {
76  if (y >= 0) // because x >= y, it follows that x >= 0, too
77  out =result_type(x) - result_type(y);
78  else if (x >= 0) // y < 0
79  // avoid the nasty two's complement case for y == min()
80  out = result_type(x) + result_type(-(y+1)) + 1;
81  else
82  // both x and y are negative: no signed overflow
83  out = result_type(x - y);
84  }
85 };
86 
87 /*
88  * Copied from boost_1_53_0/include/boost/random/detail/signed_unsigned_tools.hpp
89  * Compute x + y, x is unsigned, result fits in type of "y".
90  */
91 
94 template<typename T1, typename T2>
96  T1, T2, /* signed */ false>
97 {
98  typedef T2 result_type;
99  static IPSDK_FORCEINLINE result_type act(T1 x, T2 y)
100  {
101  return T2(x) + y;
102  }
103 
104  static IPSDK_FORCEINLINE void act(T1 x, T2 y, result_type& out)
105  {
106  out = T2(x) + y;
107  }
108 };
109 
112 template<typename T1, typename T2>
114  T1, T2, /* signed */ true>
115 {
116  typedef T2 result_type;
117  static IPSDK_FORCEINLINE result_type act(T1 x, T2 y)
118  {
119  if (y >= 0)
120  return T2(x) + y;
121  // y < 0
122  if (x > T1(-(y+1))) // result >= 0 after subtraction
123  // avoid the nasty two's complement edge case for y == min()
124  return T2(x - T1(-(y+1)) - 1);
125  // abs(x) < abs(y), thus T2 able to represent x
126  return T2(x) + y;
127  }
128 
129  static IPSDK_FORCEINLINE void act(T1 x, T2 y, result_type& out)
130  {
131  if (y >= 0)
132  out = T2(x) + y;
133  // y < 0
134  else if (x > T1(-(y+1))) // result >= 0 after subtraction
135  // avoid the nasty two's complement edge case for y == min()
136  out = T2(x - T1(-(y+1)) - 1);
137  else
138  // abs(x) < abs(y), thus T2 able to represent x
139  out = T2(x) + y;
140  }
141 };
142 
145 
146 } // end of namespace detail
147 } // end of namespace simd
148 } // end of namespace ipsdk
149 
150 #endif // __IPSDKUTIL_INSTRUCTIONSET_ARITHMETIC_DETAIL_STD_ADDREG_H__
Defines the IPSDK_FORCEINLINE.
Main namespace for IPSDK library.
Definition: AlgorithmFunctionEfficiency.h:22
Definition: SignedUnsignedOpReg.h:69
eInstructionSet
Enumerate for processor instruction set description.
Definition: InstructionSetTypes.h:31
Definition of import/export macro for library.
compiler optimisations only
Definition: InstructionSetTypes.h:34
Definition: SignedUnsignedOpReg.h:51