aboutsummaryrefslogtreecommitdiff
path: root/chapters/pseudocode.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'chapters/pseudocode.adoc')
-rw-r--r--chapters/pseudocode.adoc128
1 files changed, 128 insertions, 0 deletions
diff --git a/chapters/pseudocode.adoc b/chapters/pseudocode.adoc
new file mode 100644
index 0000000..901211a
--- /dev/null
+++ b/chapters/pseudocode.adoc
@@ -0,0 +1,128 @@
+//
+// This confidential and proprietary software may be used only as
+// authorised by a licensing agreement from ARM Limited
+// (C) COPYRIGHT 2021 ARM Limited
+// ALL RIGHTS RESERVED
+// The entire notice above must be reproduced on all authorised
+// copies and copies may only be made to the extent permitted
+// by a licensing agreement from ARM Limited.
+
+== TOSA Pseudocode
+
+The TOSA pseudocode provides precise descriptions of TOSA operations.
+Each operator contains pseudocode describing the operator's functionality.
+This section contains pseudocode functions shared across multiple operators in the specification.
+
+=== Operator Validation Helpers
+
+
+The following functions are used to define the valid conditions for TOSA operators.
+The REQUIRE function defines the conditions required by the TOSA operator.
+When a call to unpredictable() is made, processing defined in the pseudocode for this operator may or may not be executed.
+Once unpredictable is called, the whole TOSA graph is considered unpredictable, even if the unpredictable result does not propagate to the graph output.
+
+[source,c++]
+----
+void unpredictable() {
+ // Behavior of this TOSA operator cannot be relied on if this is called.
+ tosa_graph_result_unpredictable = true;
+}
+
+void REQUIRE(condition) {
+ if (not condition) {
+ unpredictable();
+ }
+}
+----
+
+=== General Pseudocode Helpers
+
+This section contains general pseudocode utility functions used throughout the specification.
+
+The following functions provide basic arithmetic while defining requirements such that values stay in the valid range.
+
+[source,c++]
+----
+acc_t apply_add<acc_t>(acc_t a, acc_t b) {
+ if (acc_t == float_t) return a + b;
+ int64_t c = (int64_t)a + (int64_t)b;
+ REQUIRE(c >= minimum<acc_t> && c <= maximum<acc_t>);
+ return (acc_t)c;
+}
+
+acc_t apply_sub<acc_t>(acc_t a, acc_t b) {
+ if (acc_t == float_t) return a - b;
+ int64_t c = (int64_t)a - (int64_t)b;
+ REQUIRE(c >= minimum<acc_t> && c <= maximum<acc_t>);
+ return (acc_t)c;
+}
+----
+
+The following functions are used in the pseudocode to take maximum,
+minimum, clip values to a range, or count leading zeros.
+[[count_leading_zeros]]
+[source,c++]
+----
+<type> apply_max<type>(<type> a, <type> b) {
+ if (a >= b) return a; else return b;
+}
+
+<type> apply_min<type>(<type> a, <type> b) {
+ if (a < b) return a; else return b;
+}
+
+<type> apply_clip<type>(<type> value, <type> min_val, <type> max_val) {
+ REQUIRE(min_val <= max_val);
+ value = apply_max(value, min_val);
+ value = apply_min(value, max_val);
+ return value;
+}
+
+int32_t count_leading_zeros(int32_t a) {
+ int32_t acc = 32;
+ if (a != 0) {
+ uint32_t mask;
+ mask = 1 << (32 - 1); // width of int32_t - 1
+ acc = 0;
+ while ((mask & a) == 0) {
+ mask = mask >> 1;
+ acc = acc + 1;
+ }
+ }
+ return acc;
+}
+----
+
+The following definitions are used in pseudocode to do numeric conversions.
+
+[source,c++]
+----
+int round_to_nearest_int(float_t f)
+ Converts the floating-point value to f, with rounding to the nearest integer value.
+
+float_t round_to_nearest_float(in_t f)
+ Converts the input value into floating-point, rounding to the nearest representable value.
+ The behavior for ties is implementation dependent.
+
+out_t sign_extend(in_t input)
+ Only valid for twos complement integer values where out_t has more bits than in_t.
+ Output = input
+ Replicate the top bit of input for all bits between the top bit of input and the top bit of output.
+
+out_t truncate(in_t input)
+ output is the sizeof(out_t) least significant bits in input.
+----
+
+The following definition is used to flatten a list of lists into a single list
+
+[source,c++]
+----
+in_t* flatten(in_t lists[]) {
+ in_t output = [];
+ for_each(list in lists) {
+ for_each(element in list) {
+ output.append(element);
+ }
+ }
+}
+----