]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] cmd/asm: final fixups for correct assembly of runtime, the last package...
authorRob Pike <r@golang.org>
Wed, 11 Feb 2015 01:11:36 +0000 (17:11 -0800)
committerRob Pike <r@golang.org>
Wed, 11 Feb 2015 03:44:19 +0000 (03:44 +0000)
- obj: add a missing setting of the context for a generated JMP instruction
- asm:  correct the encoding of mode (R)(R*scale)
- asm: fix a silly bug in the test for macro recursion.
- asm: accept address mode sym(R)(R*8); was an oversight

Change-Id: I27112eaaa1faa0d2ba97e414f0571b70733ea087
Reviewed-on: https://go-review.googlesource.com/4502
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/asm/internal/asm/parse.go
src/cmd/asm/internal/lex/input.go
src/cmd/dist/build.go
src/cmd/dist/buildtool.go
src/cmd/internal/obj/x86/obj6.go

index 8ba0973d97ab42f5155a8c2770c85bd8b3bfc6f5..c09221e31ed0ad1bbcc022ede676a3c88fcedb94 100644 (file)
@@ -235,6 +235,9 @@ func (p *Parser) operand(a *obj.Addr) bool {
                        break // Nothing can follow.
                }
                p.symbolReference(a, tok.String(), prefix)
+               if p.peek() == '(' {
+                       p.registerIndirect(a, prefix)
+               }
        case scanner.Int, scanner.Float, scanner.String, '+', '-', '~', '(':
                if p.have(scanner.Float) {
                        if prefix != '$' {
@@ -276,39 +279,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
                        }
                        break // Nothing can follow.
                }
-               p.next()
-               tok := p.next()
-               r1, r2, scale, ok := p.register(tok.String(), 0)
-               if !ok {
-                       p.errorf("indirect through non-register %s", tok)
-               }
-               if r2 != 0 {
-                       p.errorf("indirect through register pair")
-               }
-               a.Type = obj.TYPE_MEM
-               if prefix == '$' {
-                       a.Type = obj.TYPE_ADDR
-               }
-               a.Reg = r1
-               if r1 == arch.RPC && prefix != 0 {
-                       p.errorf("illegal addressing mode for PC")
-               }
-               a.Scale = scale
-               p.get(')')
-               if scale == 0 && p.peek() == '(' {
-                       p.next()
-                       tok := p.next()
-                       r1, r2, scale, ok = p.register(tok.String(), 0)
-                       if !ok {
-                               p.errorf("indirect through non-register %s", tok)
-                       }
-                       if r2 != 0 {
-                               p.errorf("unimplemented two-register form")
-                       }
-                       a.Index = r1
-                       a.Scale = scale
-                       p.get(')')
-               }
+               p.registerIndirect(a, prefix)
        }
        p.expect(scanner.EOF)
        return true
@@ -396,6 +367,51 @@ func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) {
        p.get(')')
 }
 
+// registerIndirect parses the general form of a register indirection.
+// It is can be (R1), (R2*scale), or (R1)(R2*scale) where R1 may be a simple
+// register or register pair R:R.
+// The opening parenthesis is known to be present.
+func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
+       p.next()
+       tok := p.next()
+       r1, r2, scale, ok := p.register(tok.String(), 0)
+       if !ok {
+               p.errorf("indirect through non-register %s", tok)
+       }
+       if r2 != 0 {
+               p.errorf("indirect through register pair")
+       }
+       a.Type = obj.TYPE_MEM
+       if prefix == '$' {
+               a.Type = obj.TYPE_ADDR
+       }
+       a.Reg = r1
+       if r1 == arch.RPC && prefix != 0 {
+               p.errorf("illegal addressing mode for PC")
+       }
+       p.get(')')
+       if scale == 0 && p.peek() == '(' {
+               // General form (R)(R*scale).
+               p.next()
+               tok := p.next()
+               r1, r2, scale, ok = p.register(tok.String(), 0)
+               if !ok {
+                       p.errorf("indirect through non-register %s", tok)
+               }
+               if r2 != 0 {
+                       p.errorf("unimplemented two-register form")
+               }
+               a.Index = r1
+               a.Scale = scale
+               p.get(')')
+       } else if scale != 0 {
+               // First (R) was missing, all we have is (R*scale).
+               a.Reg = 0
+               a.Index = r1
+               a.Scale = scale
+       }
+}
+
 // Note: There are two changes in the expression handling here
 // compared to the old yacc/C implemenatations. Neither has
 // much practical consequence because the expressions we
index 4c8abafc2392d727f3a1a89dc464eea016d4c69c..8768b4f6484033cfbc915a8c0e5c633cde7b7857 100644 (file)
@@ -93,9 +93,9 @@ func (in *Input) Next() ScanToken {
                in.text = in.peekText
                return tok
        }
-       // If we cannot generate a token after 100 tries, we're in trouble.
+       // If we cannot generate a token after 100 macro invocations, we're in trouble.
        // The usual case is caught by Push, below, but be safe.
-       for i := 0; i < 100; i++ {
+       for nesting := 0; nesting < 100; {
                tok := in.Stack.Next()
                switch tok {
                case '#':
@@ -108,6 +108,7 @@ func (in *Input) Next() ScanToken {
                        name := in.Stack.Text()
                        macro := in.macros[name]
                        if macro != nil {
+                               nesting++
                                in.invokeMacro(macro)
                                continue
                        }
index 152655b5086fb51c3eb5219ea43656dbbdef69ba..5cfc47ce84960a6ebfa74b86e8278af6c43047ea 100644 (file)
@@ -629,7 +629,7 @@ func install(dir string) {
        }
 
        isgo := true
-       ispkg := !strings.HasPrefix(dir, "cmd/") || strings.HasPrefix(dir, "cmd/internal/")
+       ispkg := !strings.HasPrefix(dir, "cmd/") || strings.HasPrefix(dir, "cmd/internal/") || strings.HasPrefix(dir, "cmd/asm/internal/")
        islib := false
 
        // Legacy C exceptions.
index 6cfe4c78b5be616c12df110c7cc9f436fff69bec..5b2db27143c3e875c7d0f5aa19cd12551db374ee 100644 (file)
@@ -29,6 +29,11 @@ var bootstrapDirs = []string{
        "internal/obj/i386",
        "internal/obj/ppc64",
        "internal/obj/x86",
+       "asm",
+       "asm/internal/arch",
+       "asm/internal/asm",
+       "asm/internal/flags",
+       "asm/internal/lex",
        "new5a",
        "new6a",
        "new8a",
@@ -119,7 +124,7 @@ func bootstrapFixImports(text, srcFile string) string {
                }
                if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
                        inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
-                       lines[i] = strings.Replace(line, `"cmd/internal/`, `"bootstrap/internal/`, -1)
+                       lines[i] = strings.Replace(line, `"cmd/`, `"bootstrap/`, -1)
                }
        }
 
index b3991e4a272a9c78ffb75486e2f454ecb5ebf4d9..82960d746f155972f7f99c22c704f7883fcea91a 100644 (file)
@@ -1063,6 +1063,7 @@ loop:
                q.To.Type = obj.TYPE_BRANCH
                q.To.Offset = p.Pc
                q.Pcond = p
+               q.Ctxt = p.Ctxt
                p = q
        }