File: x86csv.go

package info (click to toggle)
golang-golang-x-arch 0.13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,932 kB
  • sloc: ansic: 1,975; makefile: 59
file content (111 lines) | stat: -rw-r--r-- 3,258 bytes parent folder | download
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
// Copyright 2017 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package x86csv provides means to work with "x86.csv".
// Only latest version of "x86.csv" format is supported.
//
// Terminology:
// given "OPCODE [ARGS...]" line;
// Opcode - instruction name/mnemonic/class.
// Args   - instruction operands.
// Syntax - Opcode with Args.
package x86csv

import (
	"strings"
)

// An Inst describes single x86 instruction encoding form.
type Inst struct {
	// Intel syntax (example: "SHR r/m32, imm8").
	Intel string

	// Go assembler syntax (example: "SHRL imm8, r/m32").
	Go string

	// GNU binutils syntax (example: "shrl imm8, r/m32").
	GNU string

	// Binary encoding (example: "C1 /4 ib").
	Encoding string

	// Validity in 32bit mode ("V", "I" or "N.E.").
	Mode32 string

	// Validity in 64bit mode ("V", "I", "N.E.", "N.P.", "N.I." or "N.S.").
	Mode64 string

	// CPUID feature flags required (comma-separated).
	CPUID string

	// Hints about instruction (comma-separated).
	// See "x86spec" package to see detailed overview of possible
	// tags and their meaning.
	Tags string

	// Read/write action of the instruction on its arguments, in Intel order.
	// For example, "rw,r" denotes that "SHR r/m32, imm8" reads and writes
	// its first argument but only reads its second argument.
	Action string

	// Whether Intel syntax has encoding forms distinguished only by
	// operand size, like most arithmetic instructions ("" or "Y").
	Multisize string

	// DataSize is the size of the data operation in bits ("8" for MOVB, "16" for MOVW, and so on).
	DataSize string
}

// IntelOpcode returns the opcode in the Intel syntax.
func (inst *Inst) IntelOpcode() string { return instOpcode(inst.Intel) }

// GoOpcode returns the opcode in Go (Plan9) syntax.
func (inst *Inst) GoOpcode() string { return instOpcode(inst.Go) }

// GNUOpcode returns the opcode in GNU binutils (mostly AT&T) syntax.
func (inst *Inst) GNUOpcode() string { return instOpcode(inst.GNU) }

// IntelArgs returns the arguments in the Intel syntax.
func (inst *Inst) IntelArgs() []string { return instArgs(inst.Intel) }

// GoArgs returns the arguments in Go (Plan9) syntax.
func (inst *Inst) GoArgs() []string { return instArgs(inst.Go) }

// GNUArgs returns the arguments in GNU binutils (mostly AT&T) syntax.
func (inst *Inst) GNUArgs() []string { return instArgs(inst.GNU) }

// HasTag reports whether inst tag list contains the specified tag.
func (inst *Inst) HasTag(tag string) bool {
	i := strings.Index(inst.Tags, tag)
	if i == -1 {
		return false
	}
	leftOK := i == 0 ||
		(inst.Tags[i-1] == ',')
	rigthOK := i+len(tag) == len(inst.Tags) ||
		(inst.Tags[i+len(tag)] == ',')
	return leftOK && rigthOK
}

// instOpcode returns the opcode from an instruction syntax.
func instOpcode(syntax string) string {
	i := strings.Index(syntax, " ")
	if i == -1 {
		return syntax
	}
	return syntax[:i]
}

// instArgs returns the arguments from an instruction syntax.
func instArgs(syntax string) []string {
	i := strings.Index(syntax, " ")
	if i < 0 {
		return nil
	}
	args := strings.Split(syntax[i+1:], ",")
	for i := range args {
		args[i] = strings.TrimSpace(args[i])
	}
	return args
}