Take into account of `output_unsigned` in rescale operation

Set QMin and QMax based on the value of attribute `output_unsigned`.

Change-Id: I7f21f3edd7311295285fb3988b3c800de114777a
Signed-off-by: TatWai Chong <tatwai.chong@arm.com>
diff --git a/reference_model/src/arith_util.h b/reference_model/src/arith_util.h
index f0d184c..fee9fef 100644
--- a/reference_model/src/arith_util.h
+++ b/reference_model/src/arith_util.h
@@ -22,6 +22,7 @@
  *      fix point arithmetic
  *      fp16 type conversion(in binary translation)
  *      fp16 arithmetic (disguised with fp32 now)
+ *    and include the arithmetic helpers listed in Section 4.3.1. of the spec
  */
 
 #ifndef ARITH_UTIL_H
@@ -35,6 +36,7 @@
 #include "func_debug.h"
 #include "half.hpp"
 #include "inttypes.h"
+#include "ops/template_types.h"
 #include <bitset>
 #include <cassert>
 #include <limits>
@@ -247,4 +249,72 @@
     return f_in;
 }
 
+// return the maximum value when interpreting type T as a signed value.
+template <TOSA_REF_TYPE Dtype>
+int32_t getSignedMaximum()
+{
+    if (Dtype == TOSA_REF_TYPE_INT8 || Dtype == TOSA_REF_TYPE_UINT8)
+        return GetQMax<TOSA_REF_TYPE_INT8>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT16 || Dtype == TOSA_REF_TYPE_UINT16)
+        return GetQMax<TOSA_REF_TYPE_INT16>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT32)
+        return GetQMax<TOSA_REF_TYPE_INT32>::value;
+
+    FATAL_ERROR("Get maximum_s for the dtype input is not supported");
+    return 0;
+}
+
+// return the minimum value when interpreting type T as a signed value.
+template <TOSA_REF_TYPE Dtype>
+int32_t getSignedMinimum()
+{
+    if (Dtype == TOSA_REF_TYPE_INT8 || Dtype == TOSA_REF_TYPE_UINT8)
+        return GetQMin<TOSA_REF_TYPE_INT8>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT16 || Dtype == TOSA_REF_TYPE_UINT16)
+        return GetQMin<TOSA_REF_TYPE_INT16>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT32)
+        return GetQMin<TOSA_REF_TYPE_INT32>::value;
+
+    FATAL_ERROR("Get minimum_s for the dtype input is not supported");
+    return 0;
+}
+
+// return the maximum value when interpreting type T as an unsigned value.
+template <TOSA_REF_TYPE Dtype>
+int32_t getUnsignedMaximum()
+{
+    if (Dtype == TOSA_REF_TYPE_INT8 || Dtype == TOSA_REF_TYPE_UINT8)
+        return GetQMax<TOSA_REF_TYPE_UINT8>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT16 || Dtype == TOSA_REF_TYPE_UINT16)
+        return GetQMax<TOSA_REF_TYPE_UINT16>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT32)
+        return std::numeric_limits<uint32_t>::max();
+
+    FATAL_ERROR("Get maximum_u for the dtype input is not supported");
+    return 0;
+}
+
+// return the minimum value when interpreting type T as an unsigned value.
+template <TOSA_REF_TYPE Dtype>
+int32_t getUnsignedMinimum()
+{
+    if (Dtype == TOSA_REF_TYPE_INT8 || Dtype == TOSA_REF_TYPE_UINT8)
+        return GetQMin<TOSA_REF_TYPE_UINT8>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT16 || Dtype == TOSA_REF_TYPE_UINT16)
+        return GetQMin<TOSA_REF_TYPE_UINT16>::value;
+
+    if (Dtype == TOSA_REF_TYPE_INT32)
+        return std::numeric_limits<uint32_t>::min();
+
+    FATAL_ERROR("Get minimum_u for the dtype input is not supported");
+    return 0;
+}
+
 #endif /* _ARITH_UTIL_H */