// 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 }