1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
package main
import (
"bytes"
"flag"
"fmt"
"go/format"
"math/bits"
"os"
)
// pextByte handles single-byte PEXT operation
func pextByte(b, m uint8) uint8 {
var result, bitPos uint8
for i := uint8(0); i < 8; i++ {
if m&(1<<i) != 0 {
if b&(1<<i) != 0 {
result |= 1 << bitPos
}
bitPos++
}
}
return result
}
// pdepByte handles single-byte PDEP operation
func pdepByte(b, m uint8) uint8 {
var result, bitPos uint8
for i := uint8(0); i < 8; i++ {
if m&(1<<i) != 0 {
if b&(1<<bitPos) != 0 {
result |= 1 << i
}
bitPos++
}
}
return result
}
func generateTable(name string, data interface{}, comment string) string {
var buf bytes.Buffer
if comment != "" {
fmt.Fprintf(&buf, "// %s\n", comment)
}
fmt.Fprintf(&buf, "var %s = ", name)
switch v := data.(type) {
case [256]uint8:
buf.WriteString("[256]uint8{")
for i, val := range v {
if i%16 == 0 {
buf.WriteString("\n\t")
}
fmt.Fprintf(&buf, "%d,", val)
}
buf.WriteString("\n}")
case [256][256]uint8:
buf.WriteString("[256][256]uint8{")
for i, row := range v {
if i%4 == 0 {
buf.WriteString("\n\t")
}
buf.WriteString("{")
for j, val := range row {
if j%16 == 0 {
buf.WriteString("\n\t\t")
}
fmt.Fprintf(&buf, "%d,", val)
}
buf.WriteString("\n\t},")
}
buf.WriteString("\n}")
}
return buf.String()
}
func main() {
packageName := flag.String("pkg", "", "package name for generated code")
flag.Parse()
if *packageName == "" {
fmt.Fprintln(os.Stderr, "package name is required")
return
}
// Initialize lookup tables
var pextLUT [256][256]uint8
var pdepLUT [256][256]uint8
var popLUT [256]uint8
for b := 0; b < 256; b++ {
popLUT[b] = uint8(bits.OnesCount8(uint8(b)))
for m := 0; m < 256; m++ {
pextLUT[b][m] = pextByte(uint8(b), uint8(m))
pdepLUT[b][m] = pdepByte(uint8(b), uint8(m))
}
}
// Generate code
var buf bytes.Buffer
buf.WriteString("// Code generated by cmd/pextgen/main.go; DO NOT EDIT.\n")
buf.WriteString("//\n")
buf.WriteString("// To regenerate this file:\n")
buf.WriteString("// go run cmd/pextgen/main.go\n")
buf.WriteString("\n")
fmt.Fprintf(&buf, "package %s\n\n", *packageName)
tables := []struct {
name string
data interface{}
comment string
}{
{"pextLUT", pextLUT, "pextLUT contains pre-computed parallel bit extraction results"},
{"pdepLUT", pdepLUT, "pdepLUT contains pre-computed parallel bit deposit results"},
{"popLUT", popLUT, "popLUT contains pre-computed population counts"},
}
for _, table := range tables {
buf.WriteString(generateTable(table.name, table.data, table.comment))
buf.WriteString("\n\n")
}
// Format the generated code
formatted, err := format.Source(buf.Bytes())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to format code: %v\n", err)
os.Exit(1)
}
// Write to tables.go
err = os.WriteFile("pext.gen.go", formatted, 0644)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to write file: %v\n", err)
os.Exit(1)
}
}
|