type Parser … type Patch … func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser { … } var panicOnError … func (p *Parser) errorf(format string, args ...interface{ … } func (p *Parser) pos() src.XPos { … } func (p *Parser) Parse() (*obj.Prog, bool) { … } // 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 { … } // 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 { … } // 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, cond string, operands [][]lex.Token, ok bool) { … } func (p *Parser) instruction(op obj.As, word, cond string, operands [][]lex.Token) { … } func (p *Parser) pseudo(word string, operands [][]lex.Token) bool { … } // 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) { … } func (p *Parser) start(operand []lex.Token) { … } // address parses the operand into a link address structure. func (p *Parser) address(operand []lex.Token) obj.Addr { … } // parseScale converts a decimal string into a valid scale factor. func (p *Parser) parseScale(s string) int8 { … } // operand parses a general operand and stores the result in *a. func (p *Parser) operand(a *obj.Addr) { … } // atStartOfRegister reports whether the parser is at the start of a register definition. func (p *Parser) atStartOfRegister(name string) bool { … } // 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 { … } // 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 { … } // registerReference parses a register given either the name, R10, or a parenthesized form, SPR(10). func (p *Parser) registerReference(name string) (int16, bool) { … } // 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, r2 int16, scale int8, ok bool) { … } // 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 { … } // 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) { … } // 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 { … } // symbolReference parses a symbol that is known not to be a register. func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) { … } // 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) { … } // 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) // "<ABI0>" yielding (false, obj.ABI0) // "<ABIInternal>" 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) { … } // 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[<abi>][+Int](SB) func (p *Parser) funcAddress() (string, obj.ABI, bool) { … } // 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 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) { … } func (p *Parser) registerListARM(a *obj.Addr) { … } func (p *Parser) registerListX86(a *obj.Addr) { … } // registerNumber is ARM-specific. It returns the number of the specified register. func (p *Parser) registerNumber(name string) uint16 { … } // expr = term | term ('+' | '-' | '|' | '^') term. func (p *Parser) expr() uint64 { … } // floatExpr = fconst | '-' floatExpr | '+' floatExpr | '(' floatExpr ')' func (p *Parser) floatExpr() float64 { … } // term = factor | factor ('*' | '/' | '%' | '>>' | '<<' | '&') factor func (p *Parser) term() uint64 { … } // factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')' func (p *Parser) factor() uint64 { … } // positiveAtoi returns an int64 that must be >= 0. func (p *Parser) positiveAtoi(str string) int64 { … } func (p *Parser) atoi(str string) uint64 { … } func (p *Parser) atof(str string) float64 { … } var EOF … func (p *Parser) next() lex.Token { … } func (p *Parser) back() { … } func (p *Parser) peek() lex.ScanToken { … } func (p *Parser) more() bool { … } // get verifies that the next item has the expected type and returns it. func (p *Parser) get(expected lex.ScanToken) lex.Token { … } // expectOperandEnd verifies that the parsing state is properly at the end of an operand. func (p *Parser) expectOperandEnd() { … } // expect verifies that the next item has the expected type. It does not consume it. func (p *Parser) expect(expectedToken lex.ScanToken, expectedMessage string) { … } // have reports whether the remaining tokens (including the current one) contain the specified token. func (p *Parser) have(token lex.ScanToken) bool { … } // at reports whether the next tokens are as requested. func (p *Parser) at(next ...lex.ScanToken) bool { … }