golang.org/x/arch@v0.17.0/s390x/s390xutil/util.go (about) 1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build ignore 6 7 // Generate interesting test cases from s390x objdump via 8 // go run util.go 9 // 10 // This requires "/usr/bin/gcc" and "objdump" be in the PATH this command is run. 11 // 12 // These tools can be acquired from the IBM advance toolchain for amd64 hosts too. 13 14 package main 15 16 import ( 17 "bufio" 18 "fmt" 19 "io" 20 "os" 21 "os/exec" 22 "regexp" 23 "strconv" 24 "strings" 25 ) 26 27 // Emit a test file using the generator called name.txt. This requires 28 // a GCC toolchain which supports -march=z16. 29 func genOutput(name, tcPfx string, generator func(io.Writer)) { 30 // Generate object code from gcc 31 cmd := exec.Command(tcPfx+"gcc", "-c", "-march=z16", "-x", "assembler-with-cpp", "-o", name+".o", "-") 32 input, _ := cmd.StdinPipe() 33 cmd.Stderr = os.Stderr 34 go func() { 35 defer input.Close() 36 generator(input.(io.Writer)) 37 }() 38 if cmd.Run() != nil { 39 fmt.Printf("Failed running gcc for: %s\n", name) 40 return 41 } 42 defer os.Remove(name + ".o") 43 cmd = exec.Command(tcPfx+"objdump", "-d", name+".o") 44 45 // Run objdump and parse output into test format 46 output, _ := cmd.StdoutPipe() 47 defer output.Close() 48 scanner := bufio.NewScanner(output) 49 spacere := regexp.MustCompile("[[:space:]]+") 50 outf, _ := os.Create(name + ".txt") 51 defer outf.Close() 52 if cmd.Start() != nil { 53 fmt.Printf("Failed running objdump for: %s\n", name) 54 return 55 } 56 57 for scanner.Scan() { 58 ln := spacere.Split(scanner.Text(), -1) 59 var cnt int16 60 if len(ln) >= 5 { 61 v, _ := strconv.ParseInt(ln[2], 16, 16) 62 if (v >> 6 & 0x3) == 0 { 63 cnt = 2 64 } else if v>>6&0x3 == 1 || v>>6&0x3 == 2 { 65 cnt = 4 66 } else { 67 cnt = 6 68 } 69 opc := strings.Join(ln[2:cnt+2], "") 70 dec := strings.Join(ln[cnt+2:], " ") 71 fmt.Fprintf(outf, "%12s|\tgnu\t%-18s\n", opc, dec) 72 } 73 } 74 cmd.Wait() 75 } 76 77 // Generate representative instructions for all[1] instructions in s390x.csv. 78 // 79 // [1] See hack.h for a few minor, exceptional workarounds. 80 func emitGenerated(out io.Writer) { 81 cmd := exec.Command("go", "run", "../s390xmap/map.go", "-fmt=asm", "../s390x.csv") 82 cmdout, _ := cmd.Output() 83 out.Write(cmdout) 84 } 85 86 // Produce generated test outputs. This should be run every so often with 87 // new versions of objdump to ensure we stay up to date. 88 func main() { 89 genOutput("decode_generated", "/usr/bin/", emitGenerated) 90 }