mmozeiko
9 months ago
There is a simple way to get that immediate from expression you want to calculate. For example, if you want to calculate following expression:
(NOT A) OR ((NOT B) XOR (C AND A))
then you simply write ~_MM_TERNLOG_A | (~_MM_TERNLOG_B ^ (_MM_TERNLOG_C & _MM_TERNLOG_A))
Literally the expression you want to calculate. It evaluates to immediate from _MM_TERNLOG_A/B/C constants defined in intrinsic headers, at least for gcc & clang: typedef enum {
_MM_TERNLOG_A = 0xF0,
_MM_TERNLOG_B = 0xCC,
_MM_TERNLOG_C = 0xAA
} _MM_TERNLOG_ENUM;
For MSVC you define them yourself.o11c
9 months ago
To take the magic away, write it in binary:
A = 0b11110000
B = 0b11001100
C = 0b10101010
meow_catrix
9 months ago
The Amiga manual suggests normalizing to a conjunctive normal form.
bcoates
9 months ago
The constant-math method above doesn't require that and works on denormalized expressions, too.
That said, the trick for turning four or more argument bitwise operations into a series of vpternlogd operations has yet to be posted
LegionMammal978
9 months ago
Suppose you have four boolean variables A, B, C, and D. You can calculate X as the result from A, B, C assuming that D is false, and Y as the result assuming that D is true. Then, a third ternary operation can switch between X and Y depending on D. This creates a tree of 3 operations, which I suspect is the best you can do in the worst case.
For five or more arguments, this naturally extends into a tree, though it likely isn't the most efficient encoding.