asm

Imports

Imports #

"fmt"
"internal/abi"
"strconv"
"strings"
"text/scanner"
"cmd/asm/internal/arch"
"cmd/asm/internal/flags"
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/obj/ppc64"
"cmd/internal/obj/riscv"
"cmd/internal/obj/x86"
"cmd/internal/sys"
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
"text/scanner"
"unicode/utf8"
"cmd/asm/internal/arch"
"cmd/asm/internal/flags"
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/obj/arm64"
"cmd/internal/obj/x86"
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"

Constants & Variables

EOF var #

EOF represents the end of input.

var EOF = *ast.CallExpr

emptyProg var #

var emptyProg obj.Prog

panicOnError var #

panicOnError is enabled when testing to abort execution on the first error and turn it into a recoverable panic.

var panicOnError bool

testOut var #

var testOut *strings.Builder

Structs

Parser struct #

type Parser struct {
lex lex.TokenReader
lineNum int
errorLine int
errorCount int
sawCode bool
pc int64
input []lex.Token
inputPos int
pendingLabels []string
labels map[string]*obj.Prog
toPatch []Patch
addr []obj.Addr
arch *arch.Arch
ctxt *obj.Link
firstProg *obj.Prog
lastProg *obj.Prog
dataAddr map[string]int64
isJump bool
allowABI bool
pkgPrefix string
errorWriter io.Writer
}

Patch struct #

type Patch struct {
addr *obj.Addr
label string
}

Functions

NewParser function #

func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser

Parse method #

func (p *Parser) Parse() (*obj.Prog, bool)

ParseSymABIs method #

ParseSymABIs parses p's assembly code to find text symbol definitions and references and writes a symabis file to w.

func (p *Parser) ParseSymABIs(w io.Writer) bool

address method #

address parses the operand into a link address structure.

func (p *Parser) address(operand []lex.Token) obj.Addr

append method #

append adds the Prog to the end of the program-thus-far. If doLabel is set, it also defines the labels collect for this Prog.

func (p *Parser) append(prog *obj.Prog, cond string, doLabel bool)

asmData method #

asmData assembles a DATA pseudo-op. DATA masks<>+0x00(SB)/4, $0x00000000

func (p *Parser) asmData(operands [][]lex.Token)

asmFuncData method #

asmFuncData assembles a FUNCDATA pseudo-op. FUNCDATA $1, funcdata<>+4(SB)

func (p *Parser) asmFuncData(operands [][]lex.Token)

asmGlobl method #

asmGlobl assembles a GLOBL pseudo-op. GLOBL shifts<>(SB),8,$256 GLOBL shifts<>(SB),$256

func (p *Parser) asmGlobl(operands [][]lex.Token)

asmInstruction method #

asmInstruction assembles an instruction. MOVW R9, (R10)

func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr)

asmJump method #

asmJump assembles a jump instruction. JMP R1 JMP exit JMP 3(PC)

func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr)

asmPCAlign method #

asmPCAlign assembles a PCALIGN pseudo-op. PCALIGN $16

func (p *Parser) asmPCAlign(operands [][]lex.Token)

asmPCData method #

asmPCData assembles a PCDATA pseudo-op. PCDATA $2, $705

func (p *Parser) asmPCData(operands [][]lex.Token)

asmText method #

asmText assembles a TEXT pseudo-op. TEXT runtime·sigtramp(SB),4,$0-0

func (p *Parser) asmText(operands [][]lex.Token)

at method #

at reports whether the next tokens are as requested.

func (p *Parser) at(next ...lex.ScanToken) bool

atRegisterExtension method #

atRegisterExtension reports whether we are at the start of an ARM64 extended register. We have consumed the register or R prefix.

func (p *Parser) atRegisterExtension() bool

atRegisterShift method #

atRegisterShift reports whether we are at the start of an ARM shifted register. We have consumed the register or R prefix.

func (p *Parser) atRegisterShift() bool

atStartOfRegister method #

atStartOfRegister reports whether the parser is at the start of a register definition.

func (p *Parser) atStartOfRegister(name string) bool

atof method #

func (p *Parser) atof(str string) float64

atoi method #

func (p *Parser) atoi(str string) uint64

back method #

func (p *Parser) back()

branch method #

func (p *Parser) branch(addr *obj.Addr, target *obj.Prog)

errorf method #

func (p *Parser) errorf(format string, args ...interface{})

evalInteger method #

evalInteger evaluates an integer constant for a pseudo-op.

func (p *Parser) evalInteger(pseudo string, operands []lex.Token) int64

expect method #

expect verifies that the next item has the expected type. It does not consume it.

func (p *Parser) expect(expectedToken lex.ScanToken, expectedMessage string)

expectOperandEnd method #

expectOperandEnd verifies that the parsing state is properly at the end of an operand.

func (p *Parser) expectOperandEnd()

expr method #

expr = term | term ('+' | '-' | '|' | '^') term.

func (p *Parser) expr() uint64

factor method #

factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')'

func (p *Parser) factor() uint64

floatExpr method #

floatExpr = fconst | '-' floatExpr | '+' floatExpr | '(' floatExpr ')'

func (p *Parser) floatExpr() float64

funcAddress method #

funcAddress parses an external function address. This is a constrained form of the operand syntax that's always SB-based, non-static, and has at most a simple integer offset: [$|*]sym[][+Int](SB)

func (p *Parser) funcAddress() (string, obj.ABI, bool)

get method #

get verifies that the next item has the expected type and returns it.

func (p *Parser) get(expected lex.ScanToken) lex.Token

getConstant method #

getConstant checks that addr represents a plain constant and returns its value.

func (p *Parser) getConstant(prog *obj.Prog, op obj.As, addr *obj.Addr) int64

getConstantPseudo method #

getConstantPseudo checks that addr represents a plain constant and returns its value.

func (p *Parser) getConstantPseudo(pseudo string, addr *obj.Addr) int64

getImmediate method #

getImmediate checks that addr represents an immediate constant and returns its value.

func (p *Parser) getImmediate(prog *obj.Prog, op obj.As, addr *obj.Addr) int64

getRegister method #

getRegister checks that addr represents a register and returns its value.

func (p *Parser) getRegister(prog *obj.Prog, op obj.As, addr *obj.Addr) int16

have method #

have reports whether the remaining tokens (including the current one) contain the specified token.

func (p *Parser) have(token lex.ScanToken) bool

instruction method #

func (p *Parser) instruction(op obj.As, word string, cond string, operands [][]lex.Token)

line method #

line consumes a single assembly line from p.lex of the form {label:} WORD[.cond] [ arg {, arg} ] (';' | '\n') It adds any labels to p.pendingLabels and returns the word, cond, operand list, and true. If there is an error or EOF, it returns ok=false. line may reuse the memory from scratch.

func (p *Parser) line(scratch [][]lex.Token) (word string, cond string, operands [][]lex.Token, ok bool)

more method #

func (p *Parser) more() bool

next method #

func (p *Parser) next() lex.Token

nextToken method #

nextToken returns the next non-build-comment token from the lexer. It reports misplaced //go:build comments but otherwise discards them.

func (p *Parser) nextToken() lex.ScanToken

operand method #

operand parses a general operand and stores the result in *a.

func (p *Parser) operand(a *obj.Addr)

parseScale method #

parseScale converts a decimal string into a valid scale factor.

func (p *Parser) parseScale(s string) int8

patch method #

func (p *Parser) patch()

peek method #

func (p *Parser) peek() lex.ScanToken

pos method #

func (p *Parser) pos() src.XPos

positiveAtoi method #

positiveAtoi returns an int64 that must be >= 0.

func (p *Parser) positiveAtoi(str string) int64

pseudo method #

func (p *Parser) pseudo(word string, operands [][]lex.Token) bool

qualifySymbol method #

qualifySymbol returns name as a package-qualified symbol name. If name starts with a period, qualifySymbol prepends the package prefix. Otherwise it returns name unchanged.

func (p *Parser) qualifySymbol(name string) string

register method #

register parses a full register reference where there is no symbol present (as in 4(R0) or R(10) but not sym(SB)) including forms involving multiple registers such as R1:R2.

func (p *Parser) register(name string, prefix rune) (r1 int16, r2 int16, scale int8, ok bool)

registerExtension method #

registerExtension parses a register with extension or arrangement. There is known to be a register (current token) and an extension operator (peeked token).

func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune)

registerIndirect method #

registerIndirect parses the general form of a register indirection. It can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3) where R1 may be a simple register or register pair R:R or (R, R) or (R+R). Or it might be a pseudo-indirection like (FP). We are sitting on the opening parenthesis.

func (p *Parser) registerIndirect(a *obj.Addr, prefix rune)

registerList method #

registerList parses an ARM or ARM64 register list expression, a list of registers in []. There may be comma-separated ranges or individual registers, as in [R1,R3-R5] or [V1.S4, V2.S4, V3.S4, V4.S4]. For ARM, only R0 through R15 may appear. For ARM64, V0 through V31 with arrangement may appear. For 386/AMD64 register list specifies 4VNNIW-style multi-source operand. For range of 4 elements, Intel manual uses "+3" notation, for example: VP4DPWSSDS zmm1{k1}{z}, zmm2+3, m128 Given asm line: VP4DPWSSDS Z5, [Z10-Z13], (AX) zmm2 is Z10, and Z13 is the only valid value for it (Z10+3). Only simple ranges are accepted, like [Z0-Z3]. The opening bracket has been consumed.

func (p *Parser) registerList(a *obj.Addr)

registerListARM method #

func (p *Parser) registerListARM(a *obj.Addr)

registerListX86 method #

func (p *Parser) registerListX86(a *obj.Addr)

registerNumber method #

registerNumber is ARM-specific. It returns the number of the specified register.

func (p *Parser) registerNumber(name string) uint16

registerReference method #

registerReference parses a register given either the name, R10, or a parenthesized form, SPR(10).

func (p *Parser) registerReference(name string) (int16, bool)

registerShift method #

registerShift parses an ARM/ARM64 shifted register reference and returns the encoded representation. There is known to be a register (current token) and a shift operator (peeked token).

func (p *Parser) registerShift(name string, prefix rune) int64

setPseudoRegister method #

setPseudoRegister sets the NAME field of addr for a pseudo-register reference such as (SB).

func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, prefix rune)

start method #

func (p *Parser) start(operand []lex.Token)

symDefRef method #

symDefRef scans a line for potential text symbol definitions and references and writes symabis information to w. The symabis format is documented at cmd/compile/internal/ssagen.ReadSymABIs.

func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token)

symRefAttrs method #

symRefAttrs parses an optional function symbol attribute clause for the function symbol 'name', logging an error for a malformed attribute clause if 'issueError' is true. The return value is a (boolean, ABI) pair indicating that the named symbol is either static or a particular ABI specification. The expected form of the attribute clause is: empty, yielding (false, obj.ABI0) "<>", yielding (true, obj.ABI0) "" yielding (false, obj.ABI0) "" yielding (false, obj.ABIInternal) Anything else beginning with "<" logs an error if issueError is true, otherwise returns (false, obj.ABI0).

func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI)

symbolName function #

symbolName returns the symbol name, or an error string if none is available.

func symbolName(addr *obj.Addr) string

symbolReference method #

symbolReference parses a symbol that is known not to be a register.

func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune)

term method #

term = factor | factor ('*' | '/' | '%' | '>>' | '<<' | '&') factor

func (p *Parser) term() uint64

validImmediate method #

validImmediate checks that addr represents an immediate constant.

func (p *Parser) validImmediate(pseudo string, addr *obj.Addr) bool

validSymbol method #

validSymbol checks that addr represents a valid name for a pseudo-op.

func (p *Parser) validSymbol(pseudo string, addr *obj.Addr, offsetOk bool) bool

Generated with Arrow