1
2
3
4
5
6
7 package asm
8
9 import (
10 "fmt"
11 "io"
12 "log"
13 "os"
14 "strconv"
15 "strings"
16 "text/scanner"
17 "unicode/utf8"
18
19 "cmd/asm/internal/arch"
20 "cmd/asm/internal/flags"
21 "cmd/asm/internal/lex"
22 "cmd/internal/obj"
23 "cmd/internal/obj/arm64"
24 "cmd/internal/obj/x86"
25 "cmd/internal/objabi"
26 "cmd/internal/src"
27 "cmd/internal/sys"
28 )
29
30 type Parser struct {
31 lex lex.TokenReader
32 lineNum int
33 errorLine int
34 errorCount int
35 sawCode bool
36 pc int64
37 input []lex.Token
38 inputPos int
39 pendingLabels []string
40 labels map[string]*obj.Prog
41 toPatch []Patch
42 addr []obj.Addr
43 arch *arch.Arch
44 ctxt *obj.Link
45 firstProg *obj.Prog
46 lastProg *obj.Prog
47 dataAddr map[string]int64
48 isJump bool
49 allowABI bool
50 pkgPrefix string
51 errorWriter io.Writer
52 }
53
54 type Patch struct {
55 addr *obj.Addr
56 label string
57 }
58
59 func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser {
60 pkgPrefix := obj.UnlinkablePkg
61 if ctxt != nil {
62 pkgPrefix = objabi.PathToPrefix(ctxt.Pkgpath)
63 }
64 return &Parser{
65 ctxt: ctxt,
66 arch: ar,
67 lex: lexer,
68 labels: make(map[string]*obj.Prog),
69 dataAddr: make(map[string]int64),
70 errorWriter: os.Stderr,
71 allowABI: ctxt != nil && objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI,
72 pkgPrefix: pkgPrefix,
73 }
74 }
75
76
77
78 var panicOnError bool
79
80 func (p *Parser) errorf(format string, args ...interface{}) {
81 if panicOnError {
82 panic(fmt.Errorf(format, args...))
83 }
84 if p.lineNum == p.errorLine {
85
86 return
87 }
88 p.errorLine = p.lineNum
89 if p.lex != nil {
90
91 format = "%s:%d: " + format + "\n"
92 args = append([]interface{}{p.lex.File(), p.lineNum}, args...)
93 }
94 fmt.Fprintf(p.errorWriter, format, args...)
95 p.errorCount++
96 if p.errorCount > 10 && !*flags.AllErrors {
97 log.Fatal("too many errors")
98 }
99 }
100
101 func (p *Parser) pos() src.XPos {
102 return p.ctxt.PosTable.XPos(src.MakePos(p.lex.Base(), uint(p.lineNum), 0))
103 }
104
105 func (p *Parser) Parse() (*obj.Prog, bool) {
106 scratch := make([][]lex.Token, 0, 3)
107 for {
108 word, cond, operands, ok := p.line(scratch)
109 if !ok {
110 break
111 }
112 scratch = operands
113
114 if p.pseudo(word, operands) {
115 continue
116 }
117 i, present := p.arch.Instructions[word]
118 if present {
119 p.instruction(i, word, cond, operands)
120 continue
121 }
122 p.errorf("unrecognized instruction %q", word)
123 }
124 if p.errorCount > 0 {
125 return nil, false
126 }
127 p.patch()
128 return p.firstProg, true
129 }
130
131
132
133 func (p *Parser) ParseSymABIs(w io.Writer) bool {
134 operands := make([][]lex.Token, 0, 3)
135 for {
136 word, _, operands1, ok := p.line(operands)
137 if !ok {
138 break
139 }
140 operands = operands1
141
142 p.symDefRef(w, word, operands)
143 }
144 return p.errorCount == 0
145 }
146
147
148
149 func (p *Parser) nextToken() lex.ScanToken {
150 for {
151 tok := p.lex.Next()
152 if tok == lex.BuildComment {
153 if p.sawCode {
154 p.errorf("misplaced //go:build comment")
155 }
156 continue
157 }
158 if tok != '\n' {
159 p.sawCode = true
160 }
161 if tok == '#' {
162
163
164
165 continue
166 }
167 return tok
168 }
169 }
170
171
172
173
174
175
176
177
178
179
180 func (p *Parser) line(scratch [][]lex.Token) (word, cond string, operands [][]lex.Token, ok bool) {
181 next:
182
183 var tok lex.ScanToken
184 for {
185 tok = p.nextToken()
186
187
188
189 p.lineNum = p.lex.Line()
190 switch tok {
191 case '\n', ';':
192 continue
193 case scanner.EOF:
194 return "", "", nil, false
195 }
196 break
197 }
198
199 if tok != scanner.Ident {
200 p.errorf("expected identifier, found %q", p.lex.Text())
201 return "", "", nil, false
202 }
203 word, cond = p.lex.Text(), ""
204 operands = scratch[:0]
205
206 nesting := 0
207 colon := -1
208 for tok != '\n' && tok != ';' {
209
210 var items []lex.Token
211 if cap(operands) > len(operands) {
212
213 items = operands[:cap(operands)][len(operands)][:0]
214 } else {
215 items = make([]lex.Token, 0, 3)
216 }
217 for {
218 tok = p.nextToken()
219 if len(operands) == 0 && len(items) == 0 {
220 if p.arch.InFamily(sys.ARM, sys.ARM64, sys.AMD64, sys.I386, sys.RISCV64) && tok == '.' {
221
222 tok = p.nextToken()
223 str := p.lex.Text()
224 if tok != scanner.Ident {
225 p.errorf("instruction suffix expected identifier, found %s", str)
226 }
227 cond = cond + "." + str
228 continue
229 }
230 if tok == ':' {
231
232 p.pendingLabels = append(p.pendingLabels, word)
233 goto next
234 }
235 }
236 if tok == scanner.EOF {
237 p.errorf("unexpected EOF")
238 return "", "", nil, false
239 }
240
241
242 if tok == '\n' || tok == ';' || (nesting == 0 && (tok == ',' || tok == ':')) {
243 if tok == ':' {
244
245 if colon >= 0 {
246 p.errorf("invalid ':' in operand")
247 return word, cond, operands, true
248 }
249 colon = len(operands)
250 }
251 break
252 }
253 if tok == '(' || tok == '[' {
254 nesting++
255 }
256 if tok == ')' || tok == ']' {
257 nesting--
258 }
259 items = append(items, lex.Make(tok, p.lex.Text()))
260 }
261 if len(items) > 0 {
262 operands = append(operands, items)
263 if colon >= 0 && len(operands) == colon+2 {
264
265 operands[colon], operands[colon+1] = operands[colon+1], operands[colon]
266 colon = -1
267 }
268 } else if len(operands) > 0 || tok == ',' || colon >= 0 {
269
270 p.errorf("missing operand")
271 }
272 }
273 return word, cond, operands, true
274 }
275
276 func (p *Parser) instruction(op obj.As, word, cond string, operands [][]lex.Token) {
277 p.addr = p.addr[0:0]
278 p.isJump = p.arch.IsJump(word)
279 for _, op := range operands {
280 addr := p.address(op)
281 if !p.isJump && addr.Reg < 0 {
282 p.errorf("illegal use of pseudo-register in %s", word)
283 }
284 p.addr = append(p.addr, addr)
285 }
286 if p.isJump {
287 p.asmJump(op, cond, p.addr)
288 return
289 }
290 p.asmInstruction(op, cond, p.addr)
291 }
292
293 func (p *Parser) pseudo(word string, operands [][]lex.Token) bool {
294 switch word {
295 case "DATA":
296 p.asmData(operands)
297 case "FUNCDATA":
298 p.asmFuncData(operands)
299 case "GLOBL":
300 p.asmGlobl(operands)
301 case "PCDATA":
302 p.asmPCData(operands)
303 case "PCALIGN":
304 p.asmPCAlign(operands)
305 case "TEXT":
306 p.asmText(operands)
307 default:
308 return false
309 }
310 return true
311 }
312
313
314
315
316
317
318 func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) {
319 switch word {
320 case "TEXT":
321
322 if len(operands) > 0 {
323 p.start(operands[0])
324 if name, abi, ok := p.funcAddress(); ok {
325 fmt.Fprintf(w, "def %s %s\n", name, abi)
326 }
327 }
328 return
329 case "GLOBL", "PCDATA":
330
331 case "DATA", "FUNCDATA":
332
333
334
335 if len(operands) < 2 {
336 return
337 }
338 operands = operands[1:]
339 }
340
341 for _, op := range operands {
342 p.start(op)
343 if name, abi, ok := p.funcAddress(); ok {
344 fmt.Fprintf(w, "ref %s %s\n", name, abi)
345 }
346 }
347 }
348
349 func (p *Parser) start(operand []lex.Token) {
350 p.input = operand
351 p.inputPos = 0
352 }
353
354
355 func (p *Parser) address(operand []lex.Token) obj.Addr {
356 p.start(operand)
357 addr := obj.Addr{}
358 p.operand(&addr)
359 return addr
360 }
361
362
363 func (p *Parser) parseScale(s string) int8 {
364 switch s {
365 case "1", "2", "4", "8":
366 return int8(s[0] - '0')
367 }
368 p.errorf("bad scale: %s", s)
369 return 0
370 }
371
372
373 func (p *Parser) operand(a *obj.Addr) {
374
375 if len(p.input) == 0 {
376 p.errorf("empty operand: cannot happen")
377 return
378 }
379
380
381
382
383
384
385
386
387
388
389
390 var prefix rune
391 switch tok := p.peek(); tok {
392 case '$', '*':
393 prefix = rune(tok)
394 p.next()
395 }
396
397
398 tok := p.next()
399 name := tok.String()
400 if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) {
401 switch p.arch.Family {
402 case sys.ARM64:
403
404 if opd := arch.GetARM64SpecialOperand(name); opd != arm64.SPOP_END {
405 a.Type = obj.TYPE_SPECIAL
406 a.Offset = int64(opd)
407 break
408 }
409 fallthrough
410 default:
411
412 p.symbolReference(a, p.qualifySymbol(name), prefix)
413 }
414
415 if p.peek() == scanner.EOF {
416 return
417 }
418 }
419
420
421 if tok.ScanToken == '[' {
422 if prefix != 0 {
423 p.errorf("illegal use of register list")
424 }
425 p.registerList(a)
426 p.expectOperandEnd()
427 return
428 }
429
430
431 if tok.ScanToken == scanner.Ident && p.atStartOfRegister(name) {
432 if p.atRegisterShift() {
433
434 a.Type = obj.TYPE_SHIFT
435 a.Offset = p.registerShift(tok.String(), prefix)
436 if p.peek() == '(' {
437
438 p.next()
439 tok := p.next()
440 name := tok.String()
441 if !p.atStartOfRegister(name) {
442 p.errorf("expected register; found %s", name)
443 }
444 a.Reg, _ = p.registerReference(name)
445 p.get(')')
446 }
447 } else if p.atRegisterExtension() {
448 a.Type = obj.TYPE_REG
449 p.registerExtension(a, tok.String(), prefix)
450 p.expectOperandEnd()
451 return
452 } else if r1, r2, scale, ok := p.register(tok.String(), prefix); ok {
453 if scale != 0 {
454 p.errorf("expected simple register reference")
455 }
456 a.Type = obj.TYPE_REG
457 a.Reg = r1
458 if r2 != 0 {
459
460
461 panic("cannot happen (Addr.Reg2)")
462 }
463 }
464
465 p.expectOperandEnd()
466 return
467 }
468
469
470 haveConstant := false
471 switch tok.ScanToken {
472 case scanner.Int, scanner.Float, scanner.String, scanner.Char, '+', '-', '~':
473 haveConstant = true
474 case '(':
475
476 tok := p.next()
477 if tok.ScanToken == scanner.EOF {
478 p.errorf("missing right parenthesis")
479 return
480 }
481 rname := tok.String()
482 p.back()
483 haveConstant = !p.atStartOfRegister(rname)
484 if !haveConstant {
485 p.back()
486 }
487 }
488 if haveConstant {
489 p.back()
490 if p.have(scanner.Float) {
491 if prefix != '$' {
492 p.errorf("floating-point constant must be an immediate")
493 }
494 a.Type = obj.TYPE_FCONST
495 a.Val = p.floatExpr()
496
497 p.expectOperandEnd()
498 return
499 }
500 if p.have(scanner.String) {
501 if prefix != '$' {
502 p.errorf("string constant must be an immediate")
503 return
504 }
505 str, err := strconv.Unquote(p.get(scanner.String).String())
506 if err != nil {
507 p.errorf("string parse error: %s", err)
508 }
509 a.Type = obj.TYPE_SCONST
510 a.Val = str
511
512 p.expectOperandEnd()
513 return
514 }
515 a.Offset = int64(p.expr())
516 if p.peek() != '(' {
517 switch prefix {
518 case '$':
519 a.Type = obj.TYPE_CONST
520 case '*':
521 a.Type = obj.TYPE_INDIR
522 default:
523 a.Type = obj.TYPE_MEM
524 }
525
526 p.expectOperandEnd()
527 return
528 }
529
530 }
531
532
533 p.registerIndirect(a, prefix)
534
535
536 p.expectOperandEnd()
537 return
538 }
539
540
541 func (p *Parser) atStartOfRegister(name string) bool {
542
543 _, present := p.arch.Register[name]
544 if present {
545 return true
546 }
547
548 return p.arch.RegisterPrefix[name] && p.peek() == '('
549 }
550
551
552
553 func (p *Parser) atRegisterShift() bool {
554
555 if !p.arch.InFamily(sys.ARM, sys.ARM64) {
556 return false
557 }
558
559 if lex.IsRegisterShift(p.peek()) {
560 return true
561 }
562
563
564 if p.peek() != '(' || len(p.input)-p.inputPos < 4 {
565 return false
566 }
567 return p.at('(', scanner.Int, ')') && lex.IsRegisterShift(p.input[p.inputPos+3].ScanToken)
568 }
569
570
571
572 func (p *Parser) atRegisterExtension() bool {
573
574 if p.arch.Family != sys.ARM64 {
575 return false
576 }
577
578 return p.peek() == '.'
579 }
580
581
582 func (p *Parser) registerReference(name string) (int16, bool) {
583 r, present := p.arch.Register[name]
584 if present {
585 return r, true
586 }
587 if !p.arch.RegisterPrefix[name] {
588 p.errorf("expected register; found %s", name)
589 return 0, false
590 }
591 p.get('(')
592 tok := p.get(scanner.Int)
593 num, err := strconv.ParseInt(tok.String(), 10, 16)
594 p.get(')')
595 if err != nil {
596 p.errorf("parsing register list: %s", err)
597 return 0, false
598 }
599 r, ok := p.arch.RegisterNumber(name, int16(num))
600 if !ok {
601 p.errorf("illegal register %s(%d)", name, r)
602 return 0, false
603 }
604 return r, true
605 }
606
607
608
609 func (p *Parser) register(name string, prefix rune) (r1, r2 int16, scale int8, ok bool) {
610
611 r1, ok = p.registerReference(name)
612 if !ok {
613 return
614 }
615 if prefix != 0 && prefix != '*' {
616 p.errorf("prefix %c not allowed for register: %c%s", prefix, prefix, name)
617 }
618 c := p.peek()
619 if c == ':' || c == ',' || c == '+' {
620
621
622 switch p.next().ScanToken {
623 case ',':
624 if !p.arch.InFamily(sys.ARM, sys.ARM64) {
625 p.errorf("(register,register) not supported on this architecture")
626 return
627 }
628 case '+':
629 if p.arch.Family != sys.PPC64 {
630 p.errorf("(register+register) not supported on this architecture")
631 return
632 }
633 }
634 name := p.next().String()
635 r2, ok = p.registerReference(name)
636 if !ok {
637 return
638 }
639 }
640 if p.peek() == '*' {
641
642 p.next()
643 scale = p.parseScale(p.next().String())
644 }
645 return r1, r2, scale, true
646 }
647
648
649
650 func (p *Parser) registerShift(name string, prefix rune) int64 {
651 if prefix != 0 {
652 p.errorf("prefix %c not allowed for shifted register: $%s", prefix, name)
653 }
654
655
656
657
658
659
660 r1, ok := p.registerReference(name)
661 if !ok {
662 return 0
663 }
664 var op int16
665 switch p.next().ScanToken {
666 case lex.LSH:
667 op = 0
668 case lex.RSH:
669 op = 1
670 case lex.ARR:
671 op = 2
672 case lex.ROT:
673
674
675 op = 3
676 }
677 tok := p.next()
678 str := tok.String()
679 var count int16
680 switch tok.ScanToken {
681 case scanner.Ident:
682 if p.arch.Family == sys.ARM64 {
683 p.errorf("rhs of shift must be integer: %s", str)
684 } else {
685 r2, ok := p.registerReference(str)
686 if !ok {
687 p.errorf("rhs of shift must be register or integer: %s", str)
688 }
689 count = (r2&15)<<8 | 1<<4
690 }
691 case scanner.Int, '(':
692 p.back()
693 x := int64(p.expr())
694 if p.arch.Family == sys.ARM64 {
695 if x >= 64 {
696 p.errorf("register shift count too large: %s", str)
697 }
698 count = int16((x & 63) << 10)
699 } else {
700 if x >= 32 {
701 p.errorf("register shift count too large: %s", str)
702 }
703 count = int16((x & 31) << 7)
704 }
705 default:
706 p.errorf("unexpected %s in register shift", tok.String())
707 }
708 if p.arch.Family == sys.ARM64 {
709 off, err := arch.ARM64RegisterShift(r1, op, count)
710 if err != nil {
711 p.errorf(err.Error())
712 }
713 return off
714 } else {
715 return int64((r1 & 15) | op<<5 | count)
716 }
717 }
718
719
720
721 func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune) {
722 if prefix != 0 {
723 p.errorf("prefix %c not allowed for shifted register: $%s", prefix, name)
724 }
725
726 reg, ok := p.registerReference(name)
727 if !ok {
728 p.errorf("unexpected %s in register extension", name)
729 return
730 }
731
732 isIndex := false
733 num := int16(0)
734 isAmount := true
735 ext := ""
736 if p.peek() == lex.LSH {
737
738 ext = "LSL"
739 } else {
740
741
742 p.get('.')
743 tok := p.next()
744 ext = tok.String()
745 }
746 if p.peek() == lex.LSH {
747
748 p.get(lex.LSH)
749 tok := p.get(scanner.Int)
750 amount, err := strconv.ParseInt(tok.String(), 10, 16)
751 if err != nil {
752 p.errorf("parsing left shift amount: %s", err)
753 }
754 num = int16(amount)
755 } else if p.peek() == '[' {
756
757 p.get('[')
758 tok := p.get(scanner.Int)
759 index, err := strconv.ParseInt(tok.String(), 10, 16)
760 p.get(']')
761 if err != nil {
762 p.errorf("parsing element index: %s", err)
763 }
764 isIndex = true
765 isAmount = false
766 num = int16(index)
767 }
768
769 switch p.arch.Family {
770 case sys.ARM64:
771 err := arch.ARM64RegisterExtension(a, ext, reg, num, isAmount, isIndex)
772 if err != nil {
773 p.errorf(err.Error())
774 }
775 default:
776 p.errorf("register extension not supported on this architecture")
777 }
778 }
779
780
781
782
783 func (p *Parser) qualifySymbol(name string) string {
784 if strings.HasPrefix(name, ".") {
785 name = p.pkgPrefix + name
786 }
787 return name
788 }
789
790
791 func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) {
792
793 switch prefix {
794 case 0:
795 a.Type = obj.TYPE_MEM
796 case '$':
797 a.Type = obj.TYPE_ADDR
798 case '*':
799 a.Type = obj.TYPE_INDIR
800 }
801
802
803
804 doIssueError := true
805 isStatic, abi := p.symRefAttrs(name, doIssueError)
806
807 if p.peek() == '+' || p.peek() == '-' {
808 a.Offset = int64(p.expr())
809 }
810 if isStatic {
811 a.Sym = p.ctxt.LookupStatic(name)
812 } else {
813 a.Sym = p.ctxt.LookupABI(name, abi)
814 }
815 if p.peek() == scanner.EOF {
816 if prefix == 0 && p.isJump {
817
818 return
819 }
820 p.errorf("illegal or missing addressing mode for symbol %s", name)
821 return
822 }
823
824 p.get('(')
825 reg := p.get(scanner.Ident).String()
826 p.get(')')
827 p.setPseudoRegister(a, reg, isStatic, prefix)
828 }
829
830
831 func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, prefix rune) {
832 if addr.Reg != 0 {
833 p.errorf("internal error: reg %s already set in pseudo", reg)
834 }
835 switch reg {
836 case "FP":
837 addr.Name = obj.NAME_PARAM
838 case "PC":
839 if prefix != 0 {
840 p.errorf("illegal addressing mode for PC")
841 }
842 addr.Type = obj.TYPE_BRANCH
843 case "SB":
844 addr.Name = obj.NAME_EXTERN
845 if isStatic {
846 addr.Name = obj.NAME_STATIC
847 }
848 case "SP":
849 addr.Name = obj.NAME_AUTO
850 default:
851 p.errorf("expected pseudo-register; found %s", reg)
852 }
853 if prefix == '$' {
854 addr.Type = obj.TYPE_ADDR
855 }
856 }
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873 func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI) {
874 abi := obj.ABI0
875 isStatic := false
876 if p.peek() != '<' {
877 return isStatic, abi
878 }
879 p.next()
880 tok := p.peek()
881 if tok == '>' {
882 isStatic = true
883 } else if tok == scanner.Ident {
884 abistr := p.get(scanner.Ident).String()
885 if !p.allowABI {
886 if issueError {
887 p.errorf("ABI selector only permitted when compiling runtime, reference was to %q", name)
888 }
889 } else {
890 theabi, valid := obj.ParseABI(abistr)
891 if !valid {
892 if issueError {
893 p.errorf("malformed ABI selector %q in reference to %q",
894 abistr, name)
895 }
896 } else {
897 abi = theabi
898 }
899 }
900 }
901 p.get('>')
902 return isStatic, abi
903 }
904
905
906
907
908
909
910 func (p *Parser) funcAddress() (string, obj.ABI, bool) {
911 switch p.peek() {
912 case '$', '*':
913
914 p.next()
915 }
916
917 tok := p.next()
918 name := tok.String()
919 if tok.ScanToken != scanner.Ident || p.atStartOfRegister(name) {
920 return "", obj.ABI0, false
921 }
922 name = p.qualifySymbol(name)
923
924
925 noErrMsg := false
926 isStatic, abi := p.symRefAttrs(name, noErrMsg)
927 if isStatic {
928 return "", obj.ABI0, false
929 }
930 tok = p.next()
931 if tok.ScanToken == '+' {
932 if p.next().ScanToken != scanner.Int {
933 return "", obj.ABI0, false
934 }
935 tok = p.next()
936 }
937 if tok.ScanToken != '(' {
938 return "", obj.ABI0, false
939 }
940 if reg := p.next(); reg.ScanToken != scanner.Ident || reg.String() != "SB" {
941 return "", obj.ABI0, false
942 }
943 if p.next().ScanToken != ')' || p.peek() != scanner.EOF {
944 return "", obj.ABI0, false
945 }
946 return name, abi, true
947 }
948
949
950
951
952
953
954 func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
955 p.get('(')
956 tok := p.next()
957 name := tok.String()
958 r1, r2, scale, ok := p.register(name, 0)
959 if !ok {
960 p.errorf("indirect through non-register %s", tok)
961 }
962 p.get(')')
963 a.Type = obj.TYPE_MEM
964 if r1 < 0 {
965
966 if r2 != 0 {
967 p.errorf("cannot use pseudo-register in pair")
968 return
969 }
970
971 if name != "PC" && a.Name == obj.NAME_NONE {
972 p.errorf("cannot reference %s without a symbol", name)
973 }
974 p.setPseudoRegister(a, name, false, prefix)
975 return
976 }
977 a.Reg = r1
978 if r2 != 0 {
979
980 if p.arch.InFamily(sys.ARM, sys.ARM64) {
981
982
983
984 if prefix != 0 || scale != 0 {
985 p.errorf("illegal address mode for register pair")
986 return
987 }
988 a.Type = obj.TYPE_REGREG
989 a.Offset = int64(r2)
990
991 return
992 }
993 if p.arch.Family == sys.PPC64 {
994
995 if prefix != 0 || scale != 0 {
996 p.errorf("illegal address mode for register+register")
997 return
998 }
999 a.Type = obj.TYPE_MEM
1000 a.Scale = 0
1001 a.Index = r2
1002
1003 return
1004 }
1005 }
1006 if r2 != 0 {
1007 p.errorf("indirect through register pair")
1008 }
1009 if prefix == '$' {
1010 a.Type = obj.TYPE_ADDR
1011 }
1012 if r1 == arch.RPC && prefix != 0 {
1013 p.errorf("illegal addressing mode for PC")
1014 }
1015 if scale == 0 && p.peek() == '(' {
1016
1017 p.next()
1018 tok := p.next()
1019 if p.atRegisterExtension() {
1020 p.registerExtension(a, tok.String(), prefix)
1021 } else if p.atRegisterShift() {
1022
1023 p.registerExtension(a, tok.String(), prefix)
1024 } else {
1025 r1, r2, scale, ok = p.register(tok.String(), 0)
1026 if !ok {
1027 p.errorf("indirect through non-register %s", tok)
1028 }
1029 if r2 != 0 {
1030 p.errorf("unimplemented two-register form")
1031 }
1032 a.Index = r1
1033 if scale != 0 && scale != 1 && (p.arch.Family == sys.ARM64 ||
1034 p.arch.Family == sys.PPC64) {
1035
1036 p.errorf("%s doesn't support scaled register format", p.arch.Name)
1037 } else {
1038 a.Scale = int16(scale)
1039 }
1040 }
1041 p.get(')')
1042 } else if scale != 0 {
1043 if p.arch.Family == sys.ARM64 {
1044 p.errorf("arm64 doesn't support scaled register format")
1045 }
1046
1047 a.Reg = 0
1048 a.Index = r1
1049 a.Scale = int16(scale)
1050 }
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 func (p *Parser) registerList(a *obj.Addr) {
1073 if p.arch.InFamily(sys.I386, sys.AMD64) {
1074 p.registerListX86(a)
1075 } else {
1076 p.registerListARM(a)
1077 }
1078 }
1079
1080 func (p *Parser) registerListARM(a *obj.Addr) {
1081
1082 var maxReg int
1083 var bits uint16
1084 var arrangement int64
1085 switch p.arch.Family {
1086 case sys.ARM:
1087 maxReg = 16
1088 case sys.ARM64:
1089 maxReg = 32
1090 default:
1091 p.errorf("unexpected register list")
1092 }
1093 firstReg := -1
1094 nextReg := -1
1095 regCnt := 0
1096 ListLoop:
1097 for {
1098 tok := p.next()
1099 switch tok.ScanToken {
1100 case ']':
1101 break ListLoop
1102 case scanner.EOF:
1103 p.errorf("missing ']' in register list")
1104 return
1105 }
1106 switch p.arch.Family {
1107 case sys.ARM64:
1108
1109 name := tok.String()
1110 r, ok := p.registerReference(name)
1111 if !ok {
1112 p.errorf("invalid register: %s", name)
1113 }
1114 reg := r - p.arch.Register["V0"]
1115 p.get('.')
1116 tok := p.next()
1117 ext := tok.String()
1118 curArrangement, err := arch.ARM64RegisterArrangement(reg, name, ext)
1119 if err != nil {
1120 p.errorf(err.Error())
1121 }
1122 if firstReg == -1 {
1123
1124 firstReg = int(reg)
1125 nextReg = firstReg
1126 arrangement = curArrangement
1127 } else if curArrangement != arrangement {
1128 p.errorf("inconsistent arrangement in ARM64 register list")
1129 } else if nextReg != int(reg) {
1130 p.errorf("incontiguous register in ARM64 register list: %s", name)
1131 }
1132 regCnt++
1133 nextReg = (nextReg + 1) % 32
1134 case sys.ARM:
1135
1136 lo := p.registerNumber(tok.String())
1137 hi := lo
1138 if p.peek() == '-' {
1139 p.next()
1140 hi = p.registerNumber(p.next().String())
1141 }
1142 if hi < lo {
1143 lo, hi = hi, lo
1144 }
1145
1146 for i := 0; lo <= hi && i < maxReg; i++ {
1147 if bits&(1<<lo) != 0 {
1148 p.errorf("register R%d already in list", lo)
1149 }
1150 bits |= 1 << lo
1151 lo++
1152 }
1153 default:
1154 p.errorf("unexpected register list")
1155 }
1156 if p.peek() != ']' {
1157 p.get(',')
1158 }
1159 }
1160 a.Type = obj.TYPE_REGLIST
1161 switch p.arch.Family {
1162 case sys.ARM:
1163 a.Offset = int64(bits)
1164 case sys.ARM64:
1165 offset, err := arch.ARM64RegisterListOffset(firstReg, regCnt, arrangement)
1166 if err != nil {
1167 p.errorf(err.Error())
1168 }
1169 a.Offset = offset
1170 default:
1171 p.errorf("register list not supported on this architecture")
1172 }
1173 }
1174
1175 func (p *Parser) registerListX86(a *obj.Addr) {
1176
1177
1178
1179 loName := p.next().String()
1180 lo, ok := p.arch.Register[loName]
1181 if !ok {
1182 if loName == "EOF" {
1183 p.errorf("register list: expected ']', found EOF")
1184 } else {
1185 p.errorf("register list: bad low register in `[%s`", loName)
1186 }
1187 return
1188 }
1189 if tok := p.next().ScanToken; tok != '-' {
1190 p.errorf("register list: expected '-' after `[%s`, found %s", loName, tok)
1191 return
1192 }
1193 hiName := p.next().String()
1194 hi, ok := p.arch.Register[hiName]
1195 if !ok {
1196 p.errorf("register list: bad high register in `[%s-%s`", loName, hiName)
1197 return
1198 }
1199 if tok := p.next().ScanToken; tok != ']' {
1200 p.errorf("register list: expected ']' after `[%s-%s`, found %s", loName, hiName, tok)
1201 }
1202
1203 a.Type = obj.TYPE_REGLIST
1204 a.Reg = lo
1205 a.Offset = x86.EncodeRegisterRange(lo, hi)
1206 }
1207
1208
1209 func (p *Parser) registerNumber(name string) uint16 {
1210 if p.arch.Family == sys.ARM && name == "g" {
1211 return 10
1212 }
1213 if name[0] != 'R' {
1214 p.errorf("expected g or R0 through R15; found %s", name)
1215 return 0
1216 }
1217 r, ok := p.registerReference(name)
1218 if !ok {
1219 return 0
1220 }
1221 reg := r - p.arch.Register["R0"]
1222 if reg < 0 {
1223
1224 p.errorf("expected g or R0 through R15; found %s", name)
1225 return 0
1226 }
1227 return uint16(reg)
1228 }
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239 func (p *Parser) expr() uint64 {
1240 value := p.term()
1241 for {
1242 switch p.peek() {
1243 case '+':
1244 p.next()
1245 value += p.term()
1246 case '-':
1247 p.next()
1248 value -= p.term()
1249 case '|':
1250 p.next()
1251 value |= p.term()
1252 case '^':
1253 p.next()
1254 value ^= p.term()
1255 default:
1256 return value
1257 }
1258 }
1259 }
1260
1261
1262 func (p *Parser) floatExpr() float64 {
1263 tok := p.next()
1264 switch tok.ScanToken {
1265 case '(':
1266 v := p.floatExpr()
1267 if p.next().ScanToken != ')' {
1268 p.errorf("missing closing paren")
1269 }
1270 return v
1271 case '+':
1272 return +p.floatExpr()
1273 case '-':
1274 return -p.floatExpr()
1275 case scanner.Float:
1276 return p.atof(tok.String())
1277 }
1278 p.errorf("unexpected %s evaluating float expression", tok)
1279 return 0
1280 }
1281
1282
1283 func (p *Parser) term() uint64 {
1284 value := p.factor()
1285 for {
1286 switch p.peek() {
1287 case '*':
1288 p.next()
1289 value *= p.factor()
1290 case '/':
1291 p.next()
1292 if int64(value) < 0 {
1293 p.errorf("divide of value with high bit set")
1294 }
1295 divisor := p.factor()
1296 if divisor == 0 {
1297 p.errorf("division by zero")
1298 } else {
1299 value /= divisor
1300 }
1301 case '%':
1302 p.next()
1303 divisor := p.factor()
1304 if int64(value) < 0 {
1305 p.errorf("modulo of value with high bit set")
1306 }
1307 if divisor == 0 {
1308 p.errorf("modulo by zero")
1309 } else {
1310 value %= divisor
1311 }
1312 case lex.LSH:
1313 p.next()
1314 shift := p.factor()
1315 if int64(shift) < 0 {
1316 p.errorf("negative left shift count")
1317 }
1318 return value << shift
1319 case lex.RSH:
1320 p.next()
1321 shift := p.term()
1322 if int64(shift) < 0 {
1323 p.errorf("negative right shift count")
1324 }
1325 if int64(value) < 0 {
1326 p.errorf("right shift of value with high bit set")
1327 }
1328 value >>= shift
1329 case '&':
1330 p.next()
1331 value &= p.factor()
1332 default:
1333 return value
1334 }
1335 }
1336 }
1337
1338
1339 func (p *Parser) factor() uint64 {
1340 tok := p.next()
1341 switch tok.ScanToken {
1342 case scanner.Int:
1343 return p.atoi(tok.String())
1344 case scanner.Char:
1345 str, err := strconv.Unquote(tok.String())
1346 if err != nil {
1347 p.errorf("%s", err)
1348 }
1349 r, w := utf8.DecodeRuneInString(str)
1350 if w == 1 && r == utf8.RuneError {
1351 p.errorf("illegal UTF-8 encoding for character constant")
1352 }
1353 return uint64(r)
1354 case '+':
1355 return +p.factor()
1356 case '-':
1357 return -p.factor()
1358 case '~':
1359 return ^p.factor()
1360 case '(':
1361 v := p.expr()
1362 if p.next().ScanToken != ')' {
1363 p.errorf("missing closing paren")
1364 }
1365 return v
1366 }
1367 p.errorf("unexpected %s evaluating expression", tok)
1368 return 0
1369 }
1370
1371
1372 func (p *Parser) positiveAtoi(str string) int64 {
1373 value, err := strconv.ParseInt(str, 0, 64)
1374 if err != nil {
1375 p.errorf("%s", err)
1376 }
1377 if value < 0 {
1378 p.errorf("%s overflows int64", str)
1379 }
1380 return value
1381 }
1382
1383 func (p *Parser) atoi(str string) uint64 {
1384 value, err := strconv.ParseUint(str, 0, 64)
1385 if err != nil {
1386 p.errorf("%s", err)
1387 }
1388 return value
1389 }
1390
1391 func (p *Parser) atof(str string) float64 {
1392 value, err := strconv.ParseFloat(str, 64)
1393 if err != nil {
1394 p.errorf("%s", err)
1395 }
1396 return value
1397 }
1398
1399
1400 var EOF = lex.Make(scanner.EOF, "EOF")
1401
1402 func (p *Parser) next() lex.Token {
1403 if !p.more() {
1404 return EOF
1405 }
1406 tok := p.input[p.inputPos]
1407 p.inputPos++
1408 return tok
1409 }
1410
1411 func (p *Parser) back() {
1412 if p.inputPos == 0 {
1413 p.errorf("internal error: backing up before BOL")
1414 } else {
1415 p.inputPos--
1416 }
1417 }
1418
1419 func (p *Parser) peek() lex.ScanToken {
1420 if p.more() {
1421 return p.input[p.inputPos].ScanToken
1422 }
1423 return scanner.EOF
1424 }
1425
1426 func (p *Parser) more() bool {
1427 return p.inputPos < len(p.input)
1428 }
1429
1430
1431 func (p *Parser) get(expected lex.ScanToken) lex.Token {
1432 p.expect(expected, expected.String())
1433 return p.next()
1434 }
1435
1436
1437 func (p *Parser) expectOperandEnd() {
1438 p.expect(scanner.EOF, "end of operand")
1439 }
1440
1441
1442 func (p *Parser) expect(expectedToken lex.ScanToken, expectedMessage string) {
1443 if p.peek() != expectedToken {
1444 p.errorf("expected %s, found %s", expectedMessage, p.next())
1445 }
1446 }
1447
1448
1449 func (p *Parser) have(token lex.ScanToken) bool {
1450 for i := p.inputPos; i < len(p.input); i++ {
1451 if p.input[i].ScanToken == token {
1452 return true
1453 }
1454 }
1455 return false
1456 }
1457
1458
1459 func (p *Parser) at(next ...lex.ScanToken) bool {
1460 if len(p.input)-p.inputPos < len(next) {
1461 return false
1462 }
1463 for i, r := range next {
1464 if p.input[p.inputPos+i].ScanToken != r {
1465 return false
1466 }
1467 }
1468 return true
1469 }
1470
View as plain text