- vpternlogd di AVX-512 adalah instruksi SIMD yang mengeksekusi logika Boolean bitwise arbitrer dari tiga input sekaligus dengan memilihnya melalui nilai immediate 8-bit
- Kuncinya bukan menghafal ekspresi logika yang rumit, melainkan melihat
#imm8 sebagai tabel lookup untuk 8 kemungkinan kasus dari tiga input A/B/C
- Blitter Amiga pada 1985 juga menentukan kombinasi logika yang sama untuk tiga sumber bitmap dan minterm 8-bit, dan
0xE2 sering dipakai untuk masked sprite
- Jika 8 bit pada kolom hasil dibaca dari bawah ke atas, itulah nilai immediate, sehingga kondisi seperti “tepat dua dari tiga input bernilai 1” juga bisa dibuat langsung sebagai
0x68
- Contoh
vpternlogd di dokumentasi Intel dan 0xE2 yang umum di demoscene Amiga saling terhubung, menunjukkan bahwa instruksi SIMD modern dan perangkat keras grafis retro berbagi selera desain yang sama
vpternlogd di AVX-512
- vpternlogd adalah instruksi logika ternary bitwise yang mencolok dalam materi presentasi desain ISA AVX-512
- Instruksi ini menerima tiga input A, B, dan C, lalu dapat mengekspresikan logika Boolean arbitrer apa pun dalam satu instruksi
- Contoh:
(NOT A) OR ((NOT B) XOR (C AND A))
- Inputnya bisa berupa register 512-bit, sehingga logika yang kompleks dapat diterapkan ke seluruh 512 bit secara bersamaan
- Alih-alih terus menambahkan instruksi khusus seperti
foo_and_a_or_not_b, pendekatan ini menangani berbagai logika dengan satu instruksi fleksibel dan nilai immediate 8-bit
VPTERNLOGD r0, r1, r3, #imm8
#imm8 menentukan fungsi logika bitwise mana yang akan dijalankan
- Banyak dokumen hanya menjelaskan bahwa nilai immediate ini “menentukan fungsi biner tertentu”, sehingga sulit memahami cara menghitungnya secara intuitif
Blitter Amiga dan minterm
- Pada komputer era 1980-an, penggunaan chip kustom untuk pemrosesan grafis adalah hal yang umum
- Blitter pada Commodore Amiga 500 menerapkan operasi logika sambil memindahkan grafis bitmap dari satu lokasi ke lokasi lain
- Ia dapat menangani hingga tiga sumber bitmap, dan operasi logika di antaranya ditentukan dengan minterm berupa nilai 8-bit
- Dalam hal memilih kombinasi logika dengan tiga sumber dan nilai 8-bit, strukturnya sama seperti vpternlogd
- Banyak programmer Amiga lebih sering memakai ulang nilai yang umum dipakai daripada benar-benar memahami cara menghitung minterm
- Untuk mengosongkan buffer:
0x00
- Untuk menggambar masked sprite:
0xE2
- “Amiga Hardware Reference Manual” tahun 1989 menjelaskan perhitungan minterm dengan notasi yang membingungkan, sehingga tidak terlalu membantu para pembuat demo saat itu
Menghitung nilai 8-bit sebagai tabel lookup
#imm8 atau minterm sebaiknya dipandang bukan sebagai gabungan operator logika, melainkan sebagai tabel lookup berisi 8 entri
- Karena tiga input A, B, dan C masing-masing bisa 0 atau 1, ada 8 kombinasi yang mungkin
- Anda cukup mengisi hasil yang diinginkan langsung pada kolom keempat
| A |
B |
C |
Hasil yang diinginkan |
| 0 |
0 |
0 |
? |
| 0 |
0 |
1 |
? |
| 0 |
1 |
0 |
? |
| 0 |
1 |
1 |
? |
| 1 |
0 |
0 |
? |
| 1 |
0 |
1 |
? |
| 1 |
1 |
0 |
? |
| 1 |
1 |
1 |
? |
- Misalnya, jika Anda ingin hasil bernilai 1 hanya saat tepat dua dari tiga input bernilai 1, isi kolom keempat dengan nilai yang sesuai kondisi itu
- Jika 8 bit pada kolom hasil dibaca dari bawah ke atas, hasilnya adalah
01101000, yaitu 0x68
- Jadi fungsi
0x68 akan menetapkan hasil ke 1 saat tepat dua input dari tiga input bernilai 1
- Dengan cara yang sama, Anda bisa mendapatkan nilai
#imm8 yang diperlukan untuk fungsi logika arbitrer apa pun di antara tiga sumber
0xE2 untuk masked sprite
- Salah satu nilai minterm yang sangat umum di Amiga adalah
0xE2
- Nilai ini sering digunakan saat merender masked 2D sprite
- A: bitmap sprite
- B: mask sprite
- C: background
- Kondisinya bisa dinyatakan dengan logika program sederhana
- Jika piksel mask B diset, hasilnya adalah sprite A
- Jika piksel mask B tidak diset, hasilnya adalah background C
| A |
B |
C |
Hasil yang diinginkan |
| 0 |
0 |
0 |
0 |
| 0 |
0 |
1 |
1 |
| 0 |
1 |
0 |
0 |
| 0 |
1 |
1 |
0 |
| 1 |
0 |
0 |
0 |
| 1 |
0 |
1 |
1 |
| 1 |
1 |
0 |
1 |
| 1 |
1 |
1 |
1 |
- Jika kolom hasil dibaca dari bawah ke atas, hasilnya
11100010, yaitu 0xE2
0xE2 adalah nilai minterm yang sangat umum dalam budaya demoscene Amiga
Keterhubungan tak terduga dengan dokumentasi Intel
1 komentar
Komentar Hacker News
Ada cara sederhana untuk mendapatkan nilai immediate dari ekspresi yang ingin dihitung. Misalnya, jika ingin menghitung
(NOT A) OR ((NOT B) XOR (C AND A)), cukup tulis seperti~_MM_TERNLOG_A | (~_MM_TERNLOG_B ^ (_MM_TERNLOG_C & _MM_TERNLOG_A))Itu persis ekspresi yang ingin dihitung, dan akan dievaluasi menjadi nilai immediate dari konstanta
_MM_TERNLOG_A/B/Cyang didefinisikan di header intrinsic gcc dan clang:typedef enum { _MM_TERNLOG_A = 0xF0, _MM_TERNLOG_B = 0xCC, _MM_TERNLOG_C = 0xAA } _MM_TERNLOG_ENUM;Di MSVC, bisa didefinisikan sendiri
A = 0b11110000,B = 0b11001100,C = 0b10101010Dari judulnya saja, saya kira maksudnya instruksi ini tidak bekerja dengan benar. Ternyata artikelnya hanya menjelaskan cara kerjanya
Saya saat remaja memang tidak menulis “CRAP!” di halaman manual hardware itu, tetapi saya benar-benar memelototinya lama sekali untuk mencoba memahaminya
Pada akhirnya, seperti hampir semua orang, saya mencari dan memakai Bobs serta BLTCON0 untuk copy sederhana, lalu pura-pura tidak melihat bagian itu
Namun beberapa tahun kemudian saya mendapat A+ di logika komputasional di universitas, jadi mungkin trauma itu sedikit banyak membantu
Soal judulnya, “ternary logic” biasanya berarti logika dengan tiga nilai kebenaran. Namun artikel ini membahas instruksi compiler yang menangani semua gerbang logika biner dengan tiga input
ternlogdan intrinsic-nya jugaternarylogic, jadi meski agak disayangkan, judulnya tetap tepatSelain itu,
bitwisesudah cukup berperan membedakannya dari “logika tiga nilai”, danternaryjuga sangat sering dipakai dengan arti tiga input.a ? b : cjuga umum disebut operator ternary, dan sebenarnyaternlogbisa meniru operasi ternary ini; artikel tersebut juga membahas hal itutrinary, bukanternaryDari sudut pandang C++, JavaScript, dan Python, penggunaan yang paling umum tampaknya adalah ekspresi ternary seperti
(a < b) ? 5 : 2. https://www.programiz.com/cpp-programming/ternary-operatorBagaimanapun, asumsi apa pun tidak terlalu menjadi masalah. Kata atau frasa memang bisa punya beberapa makna, dan
ternaryberarti terdiri dari tiga bagian, jadi cocok juga di siniternarydi sini bukan dalam arti ituDi C,
+adalah operator biner karena menerima dua input, dan?:adalah operator ternary karena menerima tiga input. Karena itu satu-satunya di C, biasanya disebut “the ternary operator”, tetapi pada dasarnya tidak ada yang istimewavpternlogdmengimplementasikan semua operator ternary bitwise yang menerima tiga inputSaya sempat berpikir ini mirip dengan fungsi
BitBltdi Windows. Sepertinya sudah ada setidaknya sejak Windows 3.1, dan parameteropmenentukan bagaimana source, destination, dan mask digabungkanSaya ingat ada nama kode seperti
BLACKNESS, yang membuat hitam terlepas dari input, danCOPY, yang menyalin source ke destination.BLACKNESSdanWHITENESSentah mengapa terdengar puitisDari yang saya ingat di Petzold, implementasinya berbasis software, tetapi saat dipanggil, opcode diterjemahkan menjadi assembly khusus di dalam fungsi, jadi tampaknya merupakan contoh self-modifying code yang langka di sistem operasi Windows
BitBltawalnya memakai “operation codes” 16-bit yang rumit, yang menyimpan operasi biner dalam notasi Polandia terbalikKemudian, seperti Amiga, ditambahkan “operation index” yang memuat informasi yang sama dalam 1 byte, lebih pendek dan elegan. Sekarang setiap raster operation code memuat baik operation index maupun operation code, sehingga encoding-nya redundan. https://devblogs.microsoft.com/oldnewthing/20180528-00/?p=98...
Ini sama seperti cara FPGA mengimplementasikan fungsi logika arbitrer sebagai lookup table
Hanya saja, selain untuk tujuan khusus seperti FPGA atau instruksi dalam artikel ini, biasanya tidak dilakukan seperti itu. Register berkecepatan tinggi dan RAM statis kadang dibuat dengan logika, tetapi lebih umum dibuat langsung dari transistor daripada dari gerbang
74181juga melakukan ituJika membuka https://www.sandpile.org lalu mencari
VPTERNLOGdi halaman opcode 3 byte https://www.sandpile.org/x86/opc_3.htm, Anda juga bisa melihat AVX512BITALG2, varian masking byte/word yang tampaknya pernah direncanakan IntelHalaman itu juga menaut ke halaman tabel logika ternary yang memuat semua 256 kemungkinan pada operand
Ib: https://www.sandpile.org/x86/ternlog.htmMungkin fungsi
E2dipilih sebagai contoh dokumentasi karena itu adalah mux yang hampir paling mendasar dan standar di antara fungsi boolean tiga input: jikaBmakaA, jika tidak makaCKarena ini fungsi universal, seseorang tidak harus menjadi penggemar Amiga untuk memilihnya. Tentu saja, bisa saja memang penggemar
Contoh lain operasi bitwise yang dimasukkan ke dalam integer adalah kode ROP GDI Win32: https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-...
Saya tidak punya manual hardware Amiga resmi, melainkan membaca buku “Mapping the Amiga”. Buku itu menjelaskan hal yang sama dengan sedikit lebih bertele-tele
Saya tidak ingat minterm mana yang saya pakai waktu itu, tetapi sepertinya dari buku ini saya entah bagaimana berhasil mengimplementasikan hal-hal seperti shadebobs, bobs, dan penggambaran garis 3D XOR
Halaman terkait dari Mapping the Amiga: https://archive.org/details/1993-thomson-randy-rhett-anderso...