Example #1
0
func main() {
	log.SetFlags(0)
	log.SetPrefix("armspec: ")

	if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, "usage: armspec file.pdf\n")
		os.Exit(2)
	}

	f, err := pdf.Open(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}

	// Find instruction set reference in outline, to build instruction list.
	instList := instHeadings(f.Outline())
	if len(instList) < 200 {
		log.Fatalf("only found %d instructions in table of contents", len(instList))
	}

	stdout = bufio.NewWriter(os.Stdout)
	fmt.Fprintf(stdout, "[")
	numTable := 0
	defer stdout.Flush()

	// Scan document looking for instructions.
	// Must find exactly the ones in the outline.
	n := f.NumPage()
PageLoop:
	for pageNum := 1; pageNum <= n; pageNum++ {
		if debugPage > 0 && pageNum != debugPage {
			continue
		}
		if pageNum > 1127 {
			break
		}
		p := f.Page(pageNum)
		name, table := parsePage(pageNum, p)
		if name == "" {
			continue
		}
		if len(table) < 1 {
			if false {
				fmt.Fprintf(os.Stderr, "no encodings for instruction %q (page %d)\n", name, pageNum)
			}
			continue
		}
		for _, inst := range table {
			if numTable > 0 {
				fmt.Fprintf(stdout, ",")
			}
			numTable++
			js, _ := json.Marshal(inst)
			fmt.Fprintf(stdout, "\n%s", jsFix.Replace(string(js)))
		}
		for j, headline := range instList {
			if name == headline {
				instList[j] = ""
				continue PageLoop
			}
		}
		fmt.Fprintf(os.Stderr, "unexpected instruction %q (page %d)\n", name, pageNum)
	}

	fmt.Fprintf(stdout, "\n]\n")
	stdout.Flush()

	if debugPage == 0 {
		for _, headline := range instList {
			if headline != "" {
				switch headline {
				default:
					fmt.Fprintf(os.Stderr, "missing instruction %q\n", headline)
				case "CHKA": // ThumbEE
				case "CPS": // system instruction
				case "CPY": // synonym for MOV
				case "ENTERX": // ThumbEE
				case "F* (former VFP instruction mnemonics)": // synonyms
				case "HB, HBL, HBLP, HBP": // ThumbEE
				case "LEAVEX": // ThumbEE
				case "MOV (shifted register)": // pseudo instruction for ASR, LSL, LSR, ROR, and RRX
				case "NEG": // synonym for RSB
				case "RFE": // system instruction
				case "SMC (previously SMI)": // system instruction
				case "SRS": // system instruction
				case "SUBS PC, LR and related instructions": // system instruction
				case "VAND (immediate)": // pseudo instruction
				case "VCLE (register)": // pseudo instruction
				case "VCLT (register)": // pseudo instruction
				case "VORN (immediate)": // pseudo instruction
				}
			}
		}
	}
}
Example #2
0
File: spec.go Project: golang/arch
func main() {
	log.SetFlags(0)
	log.SetPrefix("armspec: ")

	if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, "usage: armspec file.pdf\n")
		os.Exit(2)
	}

	f, err := pdf.Open(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}

	// Find instruction set reference in outline, to build instruction list.
	instList := instHeadings(f.Outline())
	if len(instList) < 200 {
		log.Fatalf("only found %d instructions in table of contents", len(instList))
	}

	var all = []Inst{
		// Split across multiple columns and pages!
		{"Count Leading Zeros Word X-form", "cntlzw RA, RS (Rc=0)\ncntlzw. RA, RS (Rc=1)", "31@0|RS@6|RA@11|///@16|26@21|Rc@31|"},
	}

	for j, headline := range instList {
		for _, inst := range all {
			if headline == inst.Name {
				instList[j] = ""
				break
			}
		}
	}

	// Scan document looking for instructions.
	// Must find exactly the ones in the outline.
	n := f.NumPage()
	for pageNum := 1; pageNum <= n; pageNum++ {
		if debugPage > 0 && pageNum != debugPage {
			continue
		}
		p := f.Page(pageNum)
		table := parsePage(pageNum, p)
		if len(table) == 0 {
			continue
		}
	InstLoop:
		for _, inst := range table {
			for j, headline := range instList {
				if inst.Name == headline {
					instList[j] = ""
					continue InstLoop
				}
			}
			fmt.Fprintf(os.Stderr, "page %d: unexpected instruction %q\n", pageNum, inst.Name)
		}
		all = append(all, table...)
	}

	if debugPage == 0 {
		for _, headline := range instList {
			if headline != "" {
				switch headline {
				default:
					fmt.Fprintf(os.Stderr, "missing instruction %q\n", headline)
				case "CHKA": // ThumbEE
				case "CPS": // system instruction
				case "CPY": // synonym for MOV
				case "ENTERX": // ThumbEE
				case "F* (former VFP instruction mnemonics)": // synonyms
				case "HB, HBL, HBLP, HBP": // ThumbEE
				case "LEAVEX": // ThumbEE
				case "MOV (shifted register)": // pseudo instruction for ASR, LSL, LSR, ROR, and RRX
				case "NEG": // synonym for RSB
				case "RFE": // system instruction
				case "SMC (previously SMI)": // system instruction
				case "SRS": // system instruction
				case "SUBS PC, LR and related instructions": // system instruction
				case "VAND (immediate)": // pseudo instruction
				case "VCLE (register)": // pseudo instruction
				case "VCLT (register)": // pseudo instruction
				case "VORN (immediate)": // pseudo instruction
				}
			}
		}
	}

	stdout = bufio.NewWriter(os.Stdout)
	for _, inst := range all {
		fmt.Fprintf(stdout, "%q,%q,%q,%q\n", inst.Name, strings.Replace(inst.Text, "\n", "|", -1), inst.Enc, "")
	}
	stdout.Flush()

}