1
+ //
2
+ // Created by Shae Bolt on 8/11/2017.
3
+ //
4
+
5
+ #include " ternary_operators.h"
6
+
7
+ namespace tvm {
8
+
9
+
10
+ std::uint64_t native_to_10_encoded_ternary (std::uint64_t ternary_bits) {
11
+ return ((ternary_bits & ALT_101010) >> 1 ) ^ ternary_bits;
12
+ }
13
+
14
+ std::uint64_t ternary_coded_bin_to_bin (std::uint64_t bits) {
15
+ std::uint64_t acc = native_to_10_encoded_ternary (bits);
16
+ acc = acc - (((acc >> 2 ) & 0x3333333333333333 ) * (4 - 3 ));
17
+ acc = acc - (((acc >> 4 ) & 0x0F0F0F0F0F0F0F0F ) * (16 - 9 ));
18
+ acc = acc - (((acc >> 8 ) & 0x00FF00FF00FF00FF ) * (256 - 81 ));
19
+ acc = acc - (((acc >> 16 ) & 0x0000FFFF0000FFFF ) * (65536 - 6561 ));
20
+ acc = acc - (((acc >> 32 ) & 0x00000000FFFFFFFF ) * (4294967296ULL - 43046721 ));
21
+ return acc;
22
+ }
23
+
24
+ std::uint64_t isolate_uknown_op (std::uint64_t bits_110100) {
25
+ std::uint64_t conv_bits = native_to_10_encoded_ternary (bits_110100);
26
+ return conv_bits & ALT_010101;
27
+ }
28
+
29
+ std::uint64_t not_op (std::uint64_t bits_110100) {
30
+ std::uint64_t inv_bits_001011 = ~bits_110100;
31
+ std::uint64_t isolated_01 = isolate_uknown_op (bits_110100);
32
+ std::uint64_t isolated_shr_10 = isolated_01 << 1 ;
33
+ std::uint64_t removed_u = inv_bits_001011 ^isolated_shr_10;
34
+ return removed_u ^ isolated_01;
35
+ }
36
+
37
+ // alternate way, but slower
38
+ // std::uint64_t xor_op(std::uint64_t lhs, std::uint64_t rhs){
39
+ // return (lhs & not_op(rhs)) | (not_op(lhs) & rhs);
40
+ // }
41
+ std::uint64_t xor_op (std::uint64_t lhs_110100, std::uint64_t rhs_001101) {
42
+ std::uint64_t lhs_010100 = lhs_110100 & ALT_010101;
43
+ std::uint64_t rhs_000101 = rhs_001101 & ALT_010101;
44
+ std::uint64_t lrs_000100 = lhs_010100 & rhs_000101;
45
+ std::uint64_t lrs_001100 = lrs_000100 | (lrs_000100 << 1 );
46
+ std::uint64_t lrs_110011 = ~lrs_001100;
47
+ std::uint64_t xor_111001 = lhs_110100 ^rhs_001101;
48
+ std::uint64_t xor_110001 = xor_111001 & lrs_110011;
49
+ return xor_110001 | lrs_000100;
50
+ }
51
+
52
+ std::uint64_t shl_op (std::uint64_t bits, std::uint64_t shl_amount) {
53
+
54
+ std::uint64_t bin_shl_amount = ternary_coded_bin_to_bin (shl_amount);
55
+ return bits << (bin_shl_amount * 2 );
56
+ }
57
+
58
+ std::uint64_t shr_op (std::uint64_t bits, std::uint64_t shr_amount, std::uint64_t mask) {
59
+ std::uint64_t masked_bits = bits & mask;
60
+ std::uint64_t bin_shr_amount = ternary_coded_bin_to_bin (shr_amount);
61
+ return masked_bits >> (bin_shr_amount * 2 );
62
+ }
63
+
64
+ std::uint64_t not_false_op (std::uint64_t bits_110100) {
65
+ std::uint64_t bits_010100 = bits_110100 & ALT_010101;
66
+ return bits_010100 | (bits_010100 << 1 );
67
+ }
68
+
69
+ std::uint64_t not_true_op (std::uint64_t bits_110100) {
70
+ std::uint64_t bits_001010 = ~bits_110100 & ALT_101010;
71
+ return bits_001010 | (bits_001010 >> 1 );
72
+ }
73
+
74
+ std::uint64_t is_unknown_op (std::uint64_t bits) {
75
+ std::uint64_t isolated_unknown = isolate_uknown_op (bits);
76
+ return isolated_unknown | (isolated_unknown << 1 );
77
+ }
78
+
79
+ std::uint64_t not_unknown_op (std::uint64_t bits_110100) {
80
+ return ~is_unknown_op (bits_110100);
81
+ }
82
+
83
+ std::uint64_t is_true_op (std::uint64_t bits_110100) {
84
+ std::uint64_t bits_100000 = bits_110100 & ALT_101010;
85
+ return bits_100000 | (bits_100000 >> 1 );
86
+ }
87
+
88
+ std::uint64_t unknown_only_true_op (std::uint64_t bits_110100) {
89
+ std::uint64_t bits_100000 = bits_110100 & ALT_101010;
90
+ return (bits_100000 >> 1 );
91
+ }
92
+
93
+ std::uint64_t unknown_only_false_op (std::uint64_t bits_110100) {
94
+ std::uint64_t bits_000001 = ~bits_110100 & ALT_010101;
95
+ return bits_000001;
96
+ }
97
+
98
+ std::uint64_t is_false_op (std::uint64_t bits_110100) {
99
+ std::uint64_t bits_000001 = ~bits_110100 & ALT_010101;
100
+ return bits_000001 | (bits_000001 << 1 );
101
+ }
102
+
103
+ std::uint64_t sharkfin_op (std::uint64_t lhs, std::uint64_t rhs) {
104
+ std::uint64_t isolate_TT = is_true_op (lhs & rhs);
105
+ std::uint64_t isolate_TT_U = unknown_only_true_op (isolate_TT);
106
+ std::uint64_t isolate_UOR = isolate_uknown_op (lhs | rhs);
107
+
108
+
109
+ std::uint64_t alt_true_false_lhs = (lhs ^ ALT_010101);
110
+ std::uint64_t alt_true_false_rhs = (rhs ^ ALT_010101);
111
+ std::uint64_t is_unk_lhs = is_unknown_op (lhs);
112
+ std::uint64_t is_unk_rhs = is_unknown_op (rhs);
113
+ std::uint64_t is_unk = is_unk_lhs | is_unk_rhs;
114
+
115
+ std::uint64_t tf_11 = (alt_true_false_lhs ^ alt_true_false_rhs) & ~(is_unk);
116
+ std::uint64_t uu_11 = is_unk_lhs & is_unk_rhs;
117
+ std::uint64_t all_11 = tf_11 | uu_11;
118
+ // std::uint64_t lhs_010100 = lhs & ALT_010101;
119
+ // std::uint64_t rhs_010100 = ~rhs & ALT_101010;
120
+ // std::uint64_t lrs = lhs_010100 & (rhs_010100 >> 1);
121
+ // std::uint64_t lrs_11 = lrs | (lrs << 1);
122
+ return isolate_TT_U | isolate_UOR | all_11;
123
+ }
124
+
125
+ std::uint64_t find_carry_op (std::uint64_t lhs, std::uint64_t rhs) {
126
+ std::uint64_t notf_and = not_false_op (lhs & rhs);
127
+ std::uint64_t true_or = is_true_op (lhs | rhs);
128
+ return (notf_and & true_or) & ALT_010101;
129
+ }
130
+
131
+ std::uint64_t add_op (std::uint64_t x, std::uint64_t y){
132
+ while (y != 0 ){
133
+ std::uint64_t carry = find_carry_op (x, y);
134
+
135
+ x = sharkfin_op (x,y);
136
+
137
+ y = shl_op (carry, 1 );
138
+ }
139
+ return x;
140
+ }
141
+
142
+ std::uint64_t sub_op (std::uint64_t x, std::uint64_t y){
143
+ std::uint64_t y_comp = add_op (not_op (y), 1 );
144
+ return add_op (x, y_comp);
145
+ }
146
+
147
+ std::uint64_t comp_op (std::uint64_t lhs, std::uint64_t rhs){
148
+ std::uint64_t ret = 1 ;
149
+ if (lhs < rhs){
150
+ ret = 0 ;
151
+ }
152
+ else if (lhs > rhs){
153
+ ret = 3 ;
154
+ }
155
+ return ret;
156
+ }
157
+ std::uint64_t rotl_op (std::uint64_t bits, std::uint64_t rotate_amount, std::uint64_t mask, std::uint64_t max_bits){
158
+ std::uint64_t lower_bits = shr_op (bits, max_bits - rotate_amount, mask);
159
+ std::uint64_t upper_bits = shl_op (bits, rotate_amount);
160
+ return lower_bits | upper_bits;
161
+ }
162
+
163
+ std::uint64_t rotr_op (std::uint64_t bits, std::uint64_t rotate_amount, std::uint64_t mask, std::uint64_t max_bits){
164
+ std::uint64_t lower_bits = shr_op (bits, rotate_amount, mask);
165
+ std::uint64_t upper_bits = shl_op (bits, max_bits - rotate_amount);
166
+ return lower_bits | upper_bits;
167
+ }
168
+ }
0 commit comments