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