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:
Oh, I thought the title was saying that the instruction doesn't work properly! (The article actually just explains how it works.)
show comments
Lerc
My teenage self did not write "CRAP!" on that page of the hardware manual, but I stared at it for so long trying to figure it out.
In the end I did what pretty much everyone else did, Found the BLTCON0 for Bobs and straight copies and then pretended I newer saw the thing.
I did however get an A+ in computational logic at university years later, so maybe some of the trauma turned out to be beneficial.
show comments
pjmlp
> The Amiga blitter user manual didn’t help much either. The “Amiga Hardware Reference Manual” from 1989 tried to explain minterm calculation using confusing symbols, which frustrated many young demo makers at the time.
That is super normal logical calculus that any worthwhile CS degree teaches about.
Granted, probably not what a teenager without access to a BBS, or Aminet, would be able to figure out.
cubefox
About the title: "Ternary logic" usually means "logic with three truth values". But this piece covers a compiler instruction which handles all binary logic gates with three inputs.
show comments
pwrrr
Holy cow. I remember reading that page in the Amiga reference manual, thinking it was utter crap and made up my own way of calculating the value (which worked, lol).
kens
I'll point out that this is the same way that FPGAs implement arbitrary logic functions, as lookup tables (LUTs).
show comments
abecedarius
Re the choice of function "E2" for the example in the docs: it's sort of the most basic, canonical boolean function on 3 inputs, named mux: A if B else C. It's universal -- you don't need to be an Amiga fan to pick it (though for all I know they might've been).
As someone who fits the description rather too well (although neither my teenage or current self would ever use a marker in the Hardware Reference, omg) this was really nice and satisfying to read.
In a weird sense it kind of helped me feel that, yes, I would probably understand stuff better if I tried re-learning the Amiga hardware today and also like I got a bit of it for free already! Is there such a thing as being protected from a nerd snipe? "This article was my nerd trench" ... or something. Thanks! :)
worstspotgain
It's nice that they're finally starting to "compress" the instruction space.
To take a related concept further, it would be nice if there were totally unportable, chip-superspecific ways of feeding uops directly, particularly with raw access to the unrenamed register file.
Say you have an inner loop, and a chip is popular. Let your compiler take a swing at it. If it's way faster than the ISA translation, add a special case to the fat binary for a single function.
Alas, it will probably never happen due to security, integrity, and testing costs.
Nvidia SASS has a similar instruction too (LOP3.LUT)
Findecanor
I didn't have the official Amiga hardware manual, but instead the book "Mapping the Amiga". It said the same thing in a slight more verbose way. I don't remember which minterms I used back then but I think I managed to work things out from this book to do shadebobs, bobs, XOR 3D line drawing and other things.
This is an instruction I would like to implement in RISC-V if it isn't already, (which yeah, I know, isn't very RISC like)
movei (%r1),(%r2),(%r3),value
Move the contents of memory pointed to by r1, to the contents of memory pointed to by r2, applying the boolean operator <value>, with the memory pointed to by r3. Then increment all three registers by 4 to point to the next word. There was something similar to this in the Intel 82786 graphics chip which had a sort of minimal cpu part that could run simple "programs".
And yeah, I really enjoyed the blitter on the Amiga. It was a really cool bit of hardware.
show comments
stevefan1999
If you want to calculate the minterms why don't you just get a K-Map?
show comments
ggerules
It looks like someone paid attention in their undergraduate Discrete Math class.
londons_explore
Do compilers actually output this instruction?
So many super-clever instructions are next to impossible for compilers to automatically use.
show comments
notfed
Couldn't every Boolean operation be "busted" as a lookup table?
show comments
486sx33
it’s fundamentally just a lookup table
hvenev
> an obscure instruction
Come on, vpternlog* is not obscure. It subsumes _all_ bitwise instructions, even loading the constant (-1) into a register.
There is a simple way to get that immediate from expression you want to calculate. For example, if you want to calculate following expression:
then you simply write 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: For MSVC you define them yourself.Oh, I thought the title was saying that the instruction doesn't work properly! (The article actually just explains how it works.)
My teenage self did not write "CRAP!" on that page of the hardware manual, but I stared at it for so long trying to figure it out.
In the end I did what pretty much everyone else did, Found the BLTCON0 for Bobs and straight copies and then pretended I newer saw the thing.
I did however get an A+ in computational logic at university years later, so maybe some of the trauma turned out to be beneficial.
> The Amiga blitter user manual didn’t help much either. The “Amiga Hardware Reference Manual” from 1989 tried to explain minterm calculation using confusing symbols, which frustrated many young demo makers at the time.
That is super normal logical calculus that any worthwhile CS degree teaches about.
Granted, probably not what a teenager without access to a BBS, or Aminet, would be able to figure out.
About the title: "Ternary logic" usually means "logic with three truth values". But this piece covers a compiler instruction which handles all binary logic gates with three inputs.
Holy cow. I remember reading that page in the Amiga reference manual, thinking it was utter crap and made up my own way of calculating the value (which worked, lol).
I'll point out that this is the same way that FPGAs implement arbitrary logic functions, as lookup tables (LUTs).
Re the choice of function "E2" for the example in the docs: it's sort of the most basic, canonical boolean function on 3 inputs, named mux: A if B else C. It's universal -- you don't need to be an Amiga fan to pick it (though for all I know they might've been).
In fact that means that there is a dedicated AVX instruction for Elementary cellular automaton (https://en.wikipedia.org/wiki/Elementary_cellular_automaton).
Another example of packing bitwise ops into an integer is win32's GDI ROP codes: https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-...
As someone who fits the description rather too well (although neither my teenage or current self would ever use a marker in the Hardware Reference, omg) this was really nice and satisfying to read.
In a weird sense it kind of helped me feel that, yes, I would probably understand stuff better if I tried re-learning the Amiga hardware today and also like I got a bit of it for free already! Is there such a thing as being protected from a nerd snipe? "This article was my nerd trench" ... or something. Thanks! :)
It's nice that they're finally starting to "compress" the instruction space.
To take a related concept further, it would be nice if there were totally unportable, chip-superspecific ways of feeding uops directly, particularly with raw access to the unrenamed register file.
Say you have an inner loop, and a chip is popular. Let your compiler take a swing at it. If it's way faster than the ISA translation, add a special case to the fat binary for a single function.
Alas, it will probably never happen due to security, integrity, and testing costs.
Head over to https://www.sandpile.org, and find VPTERNLOG on the 3-byte opcode page https://www.sandpile.org/x86/opc_3.htm and you will not only see Intel's apparent past plan for the variants with byte and word masking (AVX512BITALG2), but also the links from the Ib operand to the ternary logic table page https://www.sandpile.org/x86/ternlog.htm with all 256 cases.
Nvidia SASS has a similar instruction too (LOP3.LUT)
I didn't have the official Amiga hardware manual, but instead the book "Mapping the Amiga". It said the same thing in a slight more verbose way. I don't remember which minterms I used back then but I think I managed to work things out from this book to do shadebobs, bobs, XOR 3D line drawing and other things.
The page in Mapping the Amiga: https://archive.org/details/1993-thomson-randy-rhett-anderso...
This is an instruction I would like to implement in RISC-V if it isn't already, (which yeah, I know, isn't very RISC like)
Move the contents of memory pointed to by r1, to the contents of memory pointed to by r2, applying the boolean operator <value>, with the memory pointed to by r3. Then increment all three registers by 4 to point to the next word. There was something similar to this in the Intel 82786 graphics chip which had a sort of minimal cpu part that could run simple "programs".And yeah, I really enjoyed the blitter on the Amiga. It was a really cool bit of hardware.
If you want to calculate the minterms why don't you just get a K-Map?
It looks like someone paid attention in their undergraduate Discrete Math class.
Do compilers actually output this instruction?
So many super-clever instructions are next to impossible for compilers to automatically use.
Couldn't every Boolean operation be "busted" as a lookup table?
it’s fundamentally just a lookup table
> an obscure instruction
Come on, vpternlog* is not obscure. It subsumes _all_ bitwise instructions, even loading the constant (-1) into a register.
Great little article! Thank you.