1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package asm implements the parser and instruction generator for the assembler.
6// TODO: Split apart?
7package asm
8
9import (
10	"fmt"
11	"io"
12	"log"
13	"os"
14	"strconv"
15	"text/scanner"
16	"unicode/utf8"
17
18	"cmd/asm/internal/arch"
19	"cmd/asm/internal/flags"
20	"cmd/asm/internal/lex"
21	"cmd/internal/obj"
22	"cmd/internal/src"
23	"cmd/internal/sys"
24)
25
26type Parser struct {
27	lex           lex.TokenReader
28	lineNum       int   // Line number in source file.
29	errorLine     int   // Line number of last error.
30	errorCount    int   // Number of errors.
31	pc            int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA.
32	input         []lex.Token
33	inputPos      int
34	pendingLabels []string // Labels to attach to next instruction.
35	labels        map[string]*obj.Prog
36	toPatch       []Patch
37	addr          []obj.Addr
38	arch          *arch.Arch
39	ctxt          *obj.Link
40	firstProg     *obj.Prog
41	lastProg      *obj.Prog
42	dataAddr      map[string]int64 // Most recent address for DATA for this symbol.
43	isJump        bool             // Instruction being assembled is a jump.
44	errorWriter   io.Writer
45}
46
47type Patch struct {
48	prog  *obj.Prog
49	label string
50}
51
52func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser {
53	return &Parser{
54		ctxt:        ctxt,
55		arch:        ar,
56		lex:         lexer,
57		labels:      make(map[string]*obj.Prog),
58		dataAddr:    make(map[string]int64),
59		errorWriter: os.Stderr,
60	}
61}
62
63// panicOnError is enabled when testing to abort execution on the first error
64// and turn it into a recoverable panic.
65var panicOnError bool
66
67func (p *Parser) errorf(format string, args ...interface{}) {
68	if panicOnError {
69		panic(fmt.Errorf(format, args...))
70	}
71	if p.lineNum == p.errorLine {
72		// Only one error per line.
73		return
74	}
75	p.errorLine = p.lineNum
76	if p.lex != nil {
77		// Put file and line information on head of message.
78		format = "%s:%d: " + format + "\n"
79		args = append([]interface{}{p.lex.File(), p.lineNum}, args...)
80	}
81	fmt.Fprintf(p.errorWriter, format, args...)
82	p.errorCount++
83	if p.errorCount > 10 && !*flags.AllErrors {
84		log.Fatal("too many errors")
85	}
86}
87
88func (p *Parser) pos() src.XPos {
89	return p.ctxt.PosTable.XPos(src.MakePos(p.lex.Base(), uint(p.lineNum), 0))
90}
91
92func (p *Parser) Parse() (*obj.Prog, bool) {
93	for p.line() {
94	}
95	if p.errorCount > 0 {
96		return nil, false
97	}
98	p.patch()
99	return p.firstProg, true
100}
101
102// WORD [ arg {, arg} ] (';' | '\n')
103func (p *Parser) line() bool {
104	// Skip newlines.
105	var tok lex.ScanToken
106	for {
107		tok = p.lex.Next()
108		// We save the line number here so error messages from this instruction
109		// are labeled with this line. Otherwise we complain after we've absorbed
110		// the terminating newline and the line numbers are off by one in errors.
111		p.lineNum = p.lex.Line()
112		switch tok {
113		case '\n', ';':
114			continue
115		case scanner.EOF:
116			return false
117		}
118		break
119	}
120	// First item must be an identifier.
121	if tok != scanner.Ident {
122		p.errorf("expected identifier, found %q", p.lex.Text())
123		return false // Might as well stop now.
124	}
125	word := p.lex.Text()
126	var cond string
127	operands := make([][]lex.Token, 0, 3)
128	// Zero or more comma-separated operands, one per loop.
129	nesting := 0
130	colon := -1
131	for tok != '\n' && tok != ';' {
132		// Process one operand.
133		items := make([]lex.Token, 0, 3)
134		for {
135			tok = p.lex.Next()
136			if len(operands) == 0 && len(items) == 0 {
137				if p.arch.InFamily(sys.ARM, sys.ARM64) && tok == '.' {
138					// ARM conditionals.
139					tok = p.lex.Next()
140					str := p.lex.Text()
141					if tok != scanner.Ident {
142						p.errorf("ARM condition expected identifier, found %s", str)
143					}
144					cond = cond + "." + str
145					continue
146				}
147				if tok == ':' {
148					// Labels.
149					p.pendingLabels = append(p.pendingLabels, word)
150					return true
151				}
152			}
153			if tok == scanner.EOF {
154				p.errorf("unexpected EOF")
155				return false
156			}
157			// Split operands on comma. Also, the old syntax on x86 for a "register pair"
158			// was AX:DX, for which the new syntax is DX, AX. Note the reordering.
159			if tok == '\n' || tok == ';' || (nesting == 0 && (tok == ',' || tok == ':')) {
160				if tok == ':' {
161					// Remember this location so we can swap the operands below.
162					if colon >= 0 {
163						p.errorf("invalid ':' in operand")
164						return true
165					}
166					colon = len(operands)
167				}
168				break
169			}
170			if tok == '(' || tok == '[' {
171				nesting++
172			}
173			if tok == ')' || tok == ']' {
174				nesting--
175			}
176			items = append(items, lex.Make(tok, p.lex.Text()))
177		}
178		if len(items) > 0 {
179			operands = append(operands, items)
180			if colon >= 0 && len(operands) == colon+2 {
181				// AX:DX becomes DX, AX.
182				operands[colon], operands[colon+1] = operands[colon+1], operands[colon]
183				colon = -1
184			}
185		} else if len(operands) > 0 || tok == ',' || colon >= 0 {
186			// Had a separator with nothing after.
187			p.errorf("missing operand")
188		}
189	}
190	if p.pseudo(word, operands) {
191		return true
192	}
193	i, present := p.arch.Instructions[word]
194	if present {
195		p.instruction(i, word, cond, operands)
196		return true
197	}
198	p.errorf("unrecognized instruction %q", word)
199	return true
200}
201
202func (p *Parser) instruction(op obj.As, word, cond string, operands [][]lex.Token) {
203	p.addr = p.addr[0:0]
204	p.isJump = p.arch.IsJump(word)
205	for _, op := range operands {
206		addr := p.address(op)
207		if !p.isJump && addr.Reg < 0 { // Jumps refer to PC, a pseudo.
208			p.errorf("illegal use of pseudo-register in %s", word)
209		}
210		p.addr = append(p.addr, addr)
211	}
212	if p.isJump {
213		p.asmJump(op, cond, p.addr)
214		return
215	}
216	p.asmInstruction(op, cond, p.addr)
217}
218
219func (p *Parser) pseudo(word string, operands [][]lex.Token) bool {
220	switch word {
221	case "DATA":
222		p.asmData(word, operands)
223	case "FUNCDATA":
224		p.asmFuncData(word, operands)
225	case "GLOBL":
226		p.asmGlobl(word, operands)
227	case "PCDATA":
228		p.asmPCData(word, operands)
229	case "TEXT":
230		p.asmText(word, operands)
231	default:
232		return false
233	}
234	return true
235}
236
237func (p *Parser) start(operand []lex.Token) {
238	p.input = operand
239	p.inputPos = 0
240}
241
242// address parses the operand into a link address structure.
243func (p *Parser) address(operand []lex.Token) obj.Addr {
244	p.start(operand)
245	addr := obj.Addr{}
246	p.operand(&addr)
247	return addr
248}
249
250// parseScale converts a decimal string into a valid scale factor.
251func (p *Parser) parseScale(s string) int8 {
252	switch s {
253	case "1", "2", "4", "8":
254		return int8(s[0] - '0')
255	}
256	p.errorf("bad scale: %s", s)
257	return 0
258}
259
260// operand parses a general operand and stores the result in *a.
261func (p *Parser) operand(a *obj.Addr) bool {
262	//fmt.Printf("Operand: %v\n", p.input)
263	if len(p.input) == 0 {
264		p.errorf("empty operand: cannot happen")
265		return false
266	}
267	// General address (with a few exceptions) looks like
268	//	$sym±offset(SB)(reg)(index*scale)
269	// Exceptions are:
270	//
271	//	R1
272	//	offset
273	//	$offset
274	// Every piece is optional, so we scan left to right and what
275	// we discover tells us where we are.
276
277	// Prefix: $.
278	var prefix rune
279	switch tok := p.peek(); tok {
280	case '$', '*':
281		prefix = rune(tok)
282		p.next()
283	}
284
285	// Symbol: sym±offset(SB)
286	tok := p.next()
287	name := tok.String()
288	if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) {
289		// We have a symbol. Parse $sym±offset(symkind)
290		p.symbolReference(a, name, prefix)
291		// fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, a))
292		if p.peek() == scanner.EOF {
293			return true
294		}
295	}
296
297	// Special register list syntax for arm: [R1,R3-R7]
298	if tok.ScanToken == '[' {
299		if prefix != 0 {
300			p.errorf("illegal use of register list")
301		}
302		p.registerList(a)
303		p.expectOperandEnd()
304		return true
305	}
306
307	// Register: R1
308	if tok.ScanToken == scanner.Ident && p.atStartOfRegister(name) {
309		if p.atRegisterShift() {
310			// ARM shifted register such as R1<<R2 or R1>>2.
311			a.Type = obj.TYPE_SHIFT
312			a.Offset = p.registerShift(tok.String(), prefix)
313			if p.peek() == '(' {
314				// Can only be a literal register here.
315				p.next()
316				tok := p.next()
317				name := tok.String()
318				if !p.atStartOfRegister(name) {
319					p.errorf("expected register; found %s", name)
320				}
321				a.Reg, _ = p.registerReference(name)
322				p.get(')')
323			}
324		} else if r1, r2, scale, ok := p.register(tok.String(), prefix); ok {
325			if scale != 0 {
326				p.errorf("expected simple register reference")
327			}
328			a.Type = obj.TYPE_REG
329			a.Reg = r1
330			if r2 != 0 {
331				// Form is R1:R2. It is on RHS and the second register
332				// needs to go into the LHS.
333				panic("cannot happen (Addr.Reg2)")
334			}
335		}
336		// fmt.Printf("REG %s\n", obj.Dconv(&emptyProg, 0, a))
337		p.expectOperandEnd()
338		return true
339	}
340
341	// Constant.
342	haveConstant := false
343	switch tok.ScanToken {
344	case scanner.Int, scanner.Float, scanner.String, scanner.Char, '+', '-', '~':
345		haveConstant = true
346	case '(':
347		// Could be parenthesized expression or (R). Must be something, though.
348		tok := p.next()
349		if tok.ScanToken == scanner.EOF {
350			p.errorf("missing right parenthesis")
351			return false
352		}
353		rname := tok.String()
354		p.back()
355		haveConstant = !p.atStartOfRegister(rname)
356		if !haveConstant {
357			p.back() // Put back the '('.
358		}
359	}
360	if haveConstant {
361		p.back()
362		if p.have(scanner.Float) {
363			if prefix != '$' {
364				p.errorf("floating-point constant must be an immediate")
365			}
366			a.Type = obj.TYPE_FCONST
367			a.Val = p.floatExpr()
368			// fmt.Printf("FCONST %s\n", obj.Dconv(&emptyProg, 0, a))
369			p.expectOperandEnd()
370			return true
371		}
372		if p.have(scanner.String) {
373			if prefix != '$' {
374				p.errorf("string constant must be an immediate")
375				return false
376			}
377			str, err := strconv.Unquote(p.get(scanner.String).String())
378			if err != nil {
379				p.errorf("string parse error: %s", err)
380			}
381			a.Type = obj.TYPE_SCONST
382			a.Val = str
383			// fmt.Printf("SCONST %s\n", obj.Dconv(&emptyProg, 0, a))
384			p.expectOperandEnd()
385			return true
386		}
387		a.Offset = int64(p.expr())
388		if p.peek() != '(' {
389			switch prefix {
390			case '$':
391				a.Type = obj.TYPE_CONST
392			case '*':
393				a.Type = obj.TYPE_INDIR // Can appear but is illegal, will be rejected by the linker.
394			default:
395				a.Type = obj.TYPE_MEM
396			}
397			// fmt.Printf("CONST %d %s\n", a.Offset, obj.Dconv(&emptyProg, 0, a))
398			p.expectOperandEnd()
399			return true
400		}
401		// fmt.Printf("offset %d \n", a.Offset)
402	}
403
404	// Register indirection: (reg) or (index*scale). We are on the opening paren.
405	p.registerIndirect(a, prefix)
406	// fmt.Printf("DONE %s\n", p.arch.Dconv(&emptyProg, 0, a))
407
408	p.expectOperandEnd()
409	return true
410}
411
412// atStartOfRegister reports whether the parser is at the start of a register definition.
413func (p *Parser) atStartOfRegister(name string) bool {
414	// Simple register: R10.
415	_, present := p.arch.Register[name]
416	if present {
417		return true
418	}
419	// Parenthesized register: R(10).
420	return p.arch.RegisterPrefix[name] && p.peek() == '('
421}
422
423// atRegisterShift reports whether we are at the start of an ARM shifted register.
424// We have consumed the register or R prefix.
425func (p *Parser) atRegisterShift() bool {
426	// ARM only.
427	if !p.arch.InFamily(sys.ARM, sys.ARM64) {
428		return false
429	}
430	// R1<<...
431	if lex.IsRegisterShift(p.peek()) {
432		return true
433	}
434	// R(1)<<...   Ugly check. TODO: Rethink how we handle ARM register shifts to be
435	// less special.
436	if p.peek() != '(' || len(p.input)-p.inputPos < 4 {
437		return false
438	}
439	return p.at('(', scanner.Int, ')') && lex.IsRegisterShift(p.input[p.inputPos+3].ScanToken)
440}
441
442// registerReference parses a register given either the name, R10, or a parenthesized form, SPR(10).
443func (p *Parser) registerReference(name string) (int16, bool) {
444	r, present := p.arch.Register[name]
445	if present {
446		return r, true
447	}
448	if !p.arch.RegisterPrefix[name] {
449		p.errorf("expected register; found %s", name)
450		return 0, false
451	}
452	p.get('(')
453	tok := p.get(scanner.Int)
454	num, err := strconv.ParseInt(tok.String(), 10, 16)
455	p.get(')')
456	if err != nil {
457		p.errorf("parsing register list: %s", err)
458		return 0, false
459	}
460	r, ok := p.arch.RegisterNumber(name, int16(num))
461	if !ok {
462		p.errorf("illegal register %s(%d)", name, r)
463		return 0, false
464	}
465	return r, true
466}
467
468// register parses a full register reference where there is no symbol present (as in 4(R0) or R(10) but not sym(SB))
469// including forms involving multiple registers such as R1:R2.
470func (p *Parser) register(name string, prefix rune) (r1, r2 int16, scale int8, ok bool) {
471	// R1 or R(1) R1:R2 R1,R2 R1+R2, or R1*scale.
472	r1, ok = p.registerReference(name)
473	if !ok {
474		return
475	}
476	if prefix != 0 && prefix != '*' { // *AX is OK.
477		p.errorf("prefix %c not allowed for register: %c%s", prefix, prefix, name)
478	}
479	c := p.peek()
480	if c == ':' || c == ',' || c == '+' {
481		// 2nd register; syntax (R1+R2) etc. No two architectures agree.
482		// Check the architectures match the syntax.
483		switch p.next().ScanToken {
484		case ',':
485			if !p.arch.InFamily(sys.ARM, sys.ARM64) {
486				p.errorf("(register,register) not supported on this architecture")
487				return
488			}
489		case '+':
490			if p.arch.Family != sys.PPC64 {
491				p.errorf("(register+register) not supported on this architecture")
492				return
493			}
494		}
495		name := p.next().String()
496		r2, ok = p.registerReference(name)
497		if !ok {
498			return
499		}
500	}
501	if p.peek() == '*' {
502		// Scale
503		p.next()
504		scale = p.parseScale(p.next().String())
505	}
506	return r1, r2, scale, true
507}
508
509// registerShift parses an ARM/ARM64 shifted register reference and returns the encoded representation.
510// There is known to be a register (current token) and a shift operator (peeked token).
511func (p *Parser) registerShift(name string, prefix rune) int64 {
512	if prefix != 0 {
513		p.errorf("prefix %c not allowed for shifted register: $%s", prefix, name)
514	}
515	// R1 op R2 or r1 op constant.
516	// op is:
517	//	"<<" == 0
518	//	">>" == 1
519	//	"->" == 2
520	//	"@>" == 3
521	r1, ok := p.registerReference(name)
522	if !ok {
523		return 0
524	}
525	var op int16
526	switch p.next().ScanToken {
527	case lex.LSH:
528		op = 0
529	case lex.RSH:
530		op = 1
531	case lex.ARR:
532		op = 2
533	case lex.ROT:
534		// following instructions on ARM64 support rotate right
535		// AND, ANDS, TST, BIC, BICS, EON, EOR, ORR, MVN, ORN
536		op = 3
537	}
538	tok := p.next()
539	str := tok.String()
540	var count int16
541	switch tok.ScanToken {
542	case scanner.Ident:
543		if p.arch.Family == sys.ARM64 {
544			p.errorf("rhs of shift must be integer: %s", str)
545		} else {
546			r2, ok := p.registerReference(str)
547			if !ok {
548				p.errorf("rhs of shift must be register or integer: %s", str)
549			}
550			count = (r2&15)<<8 | 1<<4
551		}
552	case scanner.Int, '(':
553		p.back()
554		x := int64(p.expr())
555		if p.arch.Family == sys.ARM64 {
556			if x >= 64 {
557				p.errorf("register shift count too large: %s", str)
558			}
559			count = int16((x & 63) << 10)
560		} else {
561			if x >= 32 {
562				p.errorf("register shift count too large: %s", str)
563			}
564			count = int16((x & 31) << 7)
565		}
566	default:
567		p.errorf("unexpected %s in register shift", tok.String())
568	}
569	if p.arch.Family == sys.ARM64 {
570		return int64(int64(r1&31)<<16 | int64(op)<<22 | int64(uint16(count)))
571	} else {
572		return int64((r1 & 15) | op<<5 | count)
573	}
574}
575
576// symbolReference parses a symbol that is known not to be a register.
577func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) {
578	// Identifier is a name.
579	switch prefix {
580	case 0:
581		a.Type = obj.TYPE_MEM
582	case '$':
583		a.Type = obj.TYPE_ADDR
584	case '*':
585		a.Type = obj.TYPE_INDIR
586	}
587	// Weirdness with statics: Might now have "<>".
588	isStatic := false
589	if p.peek() == '<' {
590		isStatic = true
591		p.next()
592		p.get('>')
593	}
594	if p.peek() == '+' || p.peek() == '-' {
595		a.Offset = int64(p.expr())
596	}
597	if isStatic {
598		a.Sym = p.ctxt.LookupStatic(name)
599	} else {
600		a.Sym = p.ctxt.Lookup(name)
601	}
602	if p.peek() == scanner.EOF {
603		if prefix == 0 && p.isJump {
604			// Symbols without prefix or suffix are jump labels.
605			return
606		}
607		p.errorf("illegal or missing addressing mode for symbol %s", name)
608		return
609	}
610	// Expect (SB), (FP), (PC), or (SP)
611	p.get('(')
612	reg := p.get(scanner.Ident).String()
613	p.get(')')
614	p.setPseudoRegister(a, reg, isStatic, prefix)
615}
616
617// setPseudoRegister sets the NAME field of addr for a pseudo-register reference such as (SB).
618func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, prefix rune) {
619	if addr.Reg != 0 {
620		p.errorf("internal error: reg %s already set in pseudo", reg)
621	}
622	switch reg {
623	case "FP":
624		addr.Name = obj.NAME_PARAM
625	case "PC":
626		if prefix != 0 {
627			p.errorf("illegal addressing mode for PC")
628		}
629		addr.Type = obj.TYPE_BRANCH // We set the type and leave NAME untouched. See asmJump.
630	case "SB":
631		addr.Name = obj.NAME_EXTERN
632		if isStatic {
633			addr.Name = obj.NAME_STATIC
634		}
635	case "SP":
636		addr.Name = obj.NAME_AUTO // The pseudo-stack.
637	default:
638		p.errorf("expected pseudo-register; found %s", reg)
639	}
640	if prefix == '$' {
641		addr.Type = obj.TYPE_ADDR
642	}
643}
644
645// registerIndirect parses the general form of a register indirection.
646// It is can be (R1), (R2*scale), or (R1)(R2*scale) where R1 may be a simple
647// register or register pair R:R or (R, R) or (R+R).
648// Or it might be a pseudo-indirection like (FP).
649// We are sitting on the opening parenthesis.
650func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
651	p.get('(')
652	tok := p.next()
653	name := tok.String()
654	r1, r2, scale, ok := p.register(name, 0)
655	if !ok {
656		p.errorf("indirect through non-register %s", tok)
657	}
658	p.get(')')
659	a.Type = obj.TYPE_MEM
660	if r1 < 0 {
661		// Pseudo-register reference.
662		if r2 != 0 {
663			p.errorf("cannot use pseudo-register in pair")
664			return
665		}
666		// For SB, SP, and FP, there must be a name here. 0(FP) is not legal.
667		if name != "PC" && a.Name == obj.NAME_NONE {
668			p.errorf("cannot reference %s without a symbol", name)
669		}
670		p.setPseudoRegister(a, name, false, prefix)
671		return
672	}
673	a.Reg = r1
674	if r2 != 0 {
675		// TODO: Consistency in the encoding would be nice here.
676		if p.arch.InFamily(sys.ARM, sys.ARM64) {
677			// Special form
678			// ARM: destination register pair (R1, R2).
679			// ARM64: register pair (R1, R2) for LDP/STP.
680			if prefix != 0 || scale != 0 {
681				p.errorf("illegal address mode for register pair")
682				return
683			}
684			a.Type = obj.TYPE_REGREG
685			a.Offset = int64(r2)
686			// Nothing may follow
687			return
688		}
689		if p.arch.Family == sys.PPC64 {
690			// Special form for PPC64: (R1+R2); alias for (R1)(R2*1).
691			if prefix != 0 || scale != 0 {
692				p.errorf("illegal address mode for register+register")
693				return
694			}
695			a.Type = obj.TYPE_MEM
696			a.Scale = 1
697			a.Index = r2
698			// Nothing may follow.
699			return
700		}
701	}
702	if r2 != 0 {
703		p.errorf("indirect through register pair")
704	}
705	if prefix == '$' {
706		a.Type = obj.TYPE_ADDR
707	}
708	if r1 == arch.RPC && prefix != 0 {
709		p.errorf("illegal addressing mode for PC")
710	}
711	if scale == 0 && p.peek() == '(' {
712		// General form (R)(R*scale).
713		p.next()
714		tok := p.next()
715		r1, r2, scale, ok = p.register(tok.String(), 0)
716		if !ok {
717			p.errorf("indirect through non-register %s", tok)
718		}
719		if r2 != 0 {
720			p.errorf("unimplemented two-register form")
721		}
722		a.Index = r1
723		a.Scale = int16(scale)
724		p.get(')')
725	} else if scale != 0 {
726		// First (R) was missing, all we have is (R*scale).
727		a.Reg = 0
728		a.Index = r1
729		a.Scale = int16(scale)
730	}
731}
732
733// registerList parses an ARM register list expression, a list of registers in [].
734// There may be comma-separated ranges or individual registers, as in
735// [R1,R3-R5]. Only R0 through R15 may appear.
736// The opening bracket has been consumed.
737func (p *Parser) registerList(a *obj.Addr) {
738	// One range per loop.
739	const maxReg = 16
740	var bits uint16
741ListLoop:
742	for {
743		tok := p.next()
744		switch tok.ScanToken {
745		case ']':
746			break ListLoop
747		case scanner.EOF:
748			p.errorf("missing ']' in register list")
749			return
750		}
751		// Parse the upper and lower bounds.
752		lo := p.registerNumber(tok.String())
753		hi := lo
754		if p.peek() == '-' {
755			p.next()
756			hi = p.registerNumber(p.next().String())
757		}
758		if hi < lo {
759			lo, hi = hi, lo
760		}
761		// Check there are no duplicates in the register list.
762		for i := 0; lo <= hi && i < maxReg; i++ {
763			if bits&(1<<lo) != 0 {
764				p.errorf("register R%d already in list", lo)
765			}
766			bits |= 1 << lo
767			lo++
768		}
769		if p.peek() != ']' {
770			p.get(',')
771		}
772	}
773	a.Type = obj.TYPE_REGLIST
774	a.Offset = int64(bits)
775}
776
777// register number is ARM-specific. It returns the number of the specified register.
778func (p *Parser) registerNumber(name string) uint16 {
779	if p.arch.Family == sys.ARM && name == "g" {
780		return 10
781	}
782	if name[0] != 'R' {
783		p.errorf("expected g or R0 through R15; found %s", name)
784		return 0
785	}
786	r, ok := p.registerReference(name)
787	if !ok {
788		return 0
789	}
790	reg := r - p.arch.Register["R0"]
791	if reg < 0 {
792		// Could happen for an architecture having other registers prefixed by R
793		p.errorf("expected g or R0 through R15; found %s", name)
794		return 0
795	}
796	return uint16(reg)
797}
798
799// Note: There are two changes in the expression handling here
800// compared to the old yacc/C implementations. Neither has
801// much practical consequence because the expressions we
802// see in assembly code are simple, but for the record:
803//
804// 1) Evaluation uses uint64; the old one used int64.
805// 2) Precedence uses Go rules not C rules.
806
807// expr = term | term ('+' | '-' | '|' | '^') term.
808func (p *Parser) expr() uint64 {
809	value := p.term()
810	for {
811		switch p.peek() {
812		case '+':
813			p.next()
814			value += p.term()
815		case '-':
816			p.next()
817			value -= p.term()
818		case '|':
819			p.next()
820			value |= p.term()
821		case '^':
822			p.next()
823			value ^= p.term()
824		default:
825			return value
826		}
827	}
828}
829
830// floatExpr = fconst | '-' floatExpr | '+' floatExpr | '(' floatExpr ')'
831func (p *Parser) floatExpr() float64 {
832	tok := p.next()
833	switch tok.ScanToken {
834	case '(':
835		v := p.floatExpr()
836		if p.next().ScanToken != ')' {
837			p.errorf("missing closing paren")
838		}
839		return v
840	case '+':
841		return +p.floatExpr()
842	case '-':
843		return -p.floatExpr()
844	case scanner.Float:
845		return p.atof(tok.String())
846	}
847	p.errorf("unexpected %s evaluating float expression", tok)
848	return 0
849}
850
851// term = factor | factor ('*' | '/' | '%' | '>>' | '<<' | '&') factor
852func (p *Parser) term() uint64 {
853	value := p.factor()
854	for {
855		switch p.peek() {
856		case '*':
857			p.next()
858			value *= p.factor()
859		case '/':
860			p.next()
861			if int64(value) < 0 {
862				p.errorf("divide of value with high bit set")
863			}
864			divisor := p.factor()
865			if divisor == 0 {
866				p.errorf("division by zero")
867			} else {
868				value /= divisor
869			}
870		case '%':
871			p.next()
872			divisor := p.factor()
873			if int64(value) < 0 {
874				p.errorf("modulo of value with high bit set")
875			}
876			if divisor == 0 {
877				p.errorf("modulo by zero")
878			} else {
879				value %= divisor
880			}
881		case lex.LSH:
882			p.next()
883			shift := p.factor()
884			if int64(shift) < 0 {
885				p.errorf("negative left shift count")
886			}
887			return value << shift
888		case lex.RSH:
889			p.next()
890			shift := p.term()
891			if int64(shift) < 0 {
892				p.errorf("negative right shift count")
893			}
894			if int64(value) < 0 {
895				p.errorf("right shift of value with high bit set")
896			}
897			value >>= shift
898		case '&':
899			p.next()
900			value &= p.factor()
901		default:
902			return value
903		}
904	}
905}
906
907// factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')'
908func (p *Parser) factor() uint64 {
909	tok := p.next()
910	switch tok.ScanToken {
911	case scanner.Int:
912		return p.atoi(tok.String())
913	case scanner.Char:
914		str, err := strconv.Unquote(tok.String())
915		if err != nil {
916			p.errorf("%s", err)
917		}
918		r, w := utf8.DecodeRuneInString(str)
919		if w == 1 && r == utf8.RuneError {
920			p.errorf("illegal UTF-8 encoding for character constant")
921		}
922		return uint64(r)
923	case '+':
924		return +p.factor()
925	case '-':
926		return -p.factor()
927	case '~':
928		return ^p.factor()
929	case '(':
930		v := p.expr()
931		if p.next().ScanToken != ')' {
932			p.errorf("missing closing paren")
933		}
934		return v
935	}
936	p.errorf("unexpected %s evaluating expression", tok)
937	return 0
938}
939
940// positiveAtoi returns an int64 that must be >= 0.
941func (p *Parser) positiveAtoi(str string) int64 {
942	value, err := strconv.ParseInt(str, 0, 64)
943	if err != nil {
944		p.errorf("%s", err)
945	}
946	if value < 0 {
947		p.errorf("%s overflows int64", str)
948	}
949	return value
950}
951
952func (p *Parser) atoi(str string) uint64 {
953	value, err := strconv.ParseUint(str, 0, 64)
954	if err != nil {
955		p.errorf("%s", err)
956	}
957	return value
958}
959
960func (p *Parser) atof(str string) float64 {
961	value, err := strconv.ParseFloat(str, 64)
962	if err != nil {
963		p.errorf("%s", err)
964	}
965	return value
966}
967
968// EOF represents the end of input.
969var EOF = lex.Make(scanner.EOF, "EOF")
970
971func (p *Parser) next() lex.Token {
972	if !p.more() {
973		return EOF
974	}
975	tok := p.input[p.inputPos]
976	p.inputPos++
977	return tok
978}
979
980func (p *Parser) back() {
981	if p.inputPos == 0 {
982		p.errorf("internal error: backing up before BOL")
983	} else {
984		p.inputPos--
985	}
986}
987
988func (p *Parser) peek() lex.ScanToken {
989	if p.more() {
990		return p.input[p.inputPos].ScanToken
991	}
992	return scanner.EOF
993}
994
995func (p *Parser) more() bool {
996	return p.inputPos < len(p.input)
997}
998
999// get verifies that the next item has the expected type and returns it.
1000func (p *Parser) get(expected lex.ScanToken) lex.Token {
1001	p.expect(expected, expected.String())
1002	return p.next()
1003}
1004
1005// expectOperandEnd verifies that the parsing state is properly at the end of an operand.
1006func (p *Parser) expectOperandEnd() {
1007	p.expect(scanner.EOF, "end of operand")
1008}
1009
1010// expect verifies that the next item has the expected type. It does not consume it.
1011func (p *Parser) expect(expectedToken lex.ScanToken, expectedMessage string) {
1012	if p.peek() != expectedToken {
1013		p.errorf("expected %s, found %s", expectedMessage, p.next())
1014	}
1015}
1016
1017// have reports whether the remaining tokens (including the current one) contain the specified token.
1018func (p *Parser) have(token lex.ScanToken) bool {
1019	for i := p.inputPos; i < len(p.input); i++ {
1020		if p.input[i].ScanToken == token {
1021			return true
1022		}
1023	}
1024	return false
1025}
1026
1027// at reports whether the next tokens are as requested.
1028func (p *Parser) at(next ...lex.ScanToken) bool {
1029	if len(p.input)-p.inputPos < len(next) {
1030		return false
1031	}
1032	for i, r := range next {
1033		if p.input[p.inputPos+i].ScanToken != r {
1034			return false
1035		}
1036	}
1037	return true
1038}
1039