[dev.cc] cmd/asm: fix a few minor issues

Fix one place where semicolons were not recognized and fix the
pattern match for the syntax of some pseudo ops.
Also clean up a couple of unreachable code pieces.

There is still an undiagnosed bit difference betwen old and new .6
files. TBD.

With these fixes, asm can successfully compile and test the entire tree.
(Verified by
	turn off verifyAsm in cmd/go
	make.bash
	cp $GOROOT/bin/asm $GOROOT/pkg/tool/darwin_amd64/6a
	go test -short std
)

Change-Id: I91ea892098f76ef4f129fd2530e0c63ffd8745a9
Reviewed-on: https://go-review.googlesource.com/3688
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Rob Pike 2015-02-02 10:56:41 -08:00
parent 5beec6a699
commit 68475da68d
6 changed files with 20 additions and 21 deletions

View file

@ -71,7 +71,7 @@ func (a *Addr) Has(mask int) bool {
return false return false
} }
// Is reports whether the address has exactly the specified elements. // Is reports whether the address has all the specified elements.
// Indirect and immediate are checked. // Indirect and immediate are checked.
func (a *Addr) Is(mask int) bool { func (a *Addr) Is(mask int) bool {
if (mask&ImmediateConstant == 0) != !a.IsImmediateConstant { if (mask&ImmediateConstant == 0) != !a.IsImmediateConstant {

View file

@ -302,7 +302,8 @@ func (p *Parser) asmGlobl(word string, operands [][]lex.Token) {
// Operand 0 has the general form foo<>+0x04(SB). // Operand 0 has the general form foo<>+0x04(SB).
nameAddr := p.address(operands[0]) nameAddr := p.address(operands[0])
if !nameAddr.Is(addr.Symbol|addr.Register|addr.Indirect) || nameAddr.Register != arch.RSB { ok := nameAddr.Is(addr.Symbol|addr.Register|addr.Indirect) || nameAddr.Is(addr.Symbol|addr.Register|addr.Indirect|addr.Offset)
if !ok || nameAddr.Register != arch.RSB {
p.errorf("GLOBL symbol %q must be an offset from SB", nameAddr.Symbol) p.errorf("GLOBL symbol %q must be an offset from SB", nameAddr.Symbol)
} }
name := strings.Replace(nameAddr.Symbol, "·", ".", 1) name := strings.Replace(nameAddr.Symbol, "·", ".", 1)
@ -399,17 +400,19 @@ func (p *Parser) asmFuncData(word string, operands [][]lex.Token) {
if !valueAddr.Is(addr.ImmediateConstant | addr.Offset) { if !valueAddr.Is(addr.ImmediateConstant | addr.Offset) {
p.errorf("FUNCDATA value must be an immediate constant") p.errorf("FUNCDATA value must be an immediate constant")
} }
value := valueAddr.Offset value0 := valueAddr.Offset
// Operand 1 is a symbol name in the form foo(SB). // Operand 1 is a symbol name in the form foo(SB).
// That means symbol plus indirect on SB and no offset. // That means symbol plus indirect on SB and no offset.
nameAddr := p.address(operands[1]) nameAddr := p.address(operands[1])
if !nameAddr.Is(addr.Symbol|addr.Register|addr.Indirect) || nameAddr.Register != arch.RSB { ok := nameAddr.Is(addr.Symbol|addr.Register|addr.Indirect) || nameAddr.Is(addr.Symbol|addr.Register|addr.Indirect|addr.Offset)
if !ok || nameAddr.Register != arch.RSB {
p.errorf("FUNCDATA symbol %q must be an offset from SB", nameAddr.Symbol) p.errorf("FUNCDATA symbol %q must be an offset from SB", nameAddr.Symbol)
} }
name := strings.Replace(nameAddr.Symbol, "·", ".", 1) name := strings.Replace(nameAddr.Symbol, "·", ".", 1)
value1 := nameAddr.Offset
// log.Printf("FUNCDATA %s, $%d", name, value) // log.Printf("FUNCDATA $%d, %d", value0, value1)
prog := &obj.Prog{ prog := &obj.Prog{
Ctxt: p.linkCtxt, Ctxt: p.linkCtxt,
As: int16(p.arch.AFUNCDATA), As: int16(p.arch.AFUNCDATA),
@ -417,12 +420,13 @@ func (p *Parser) asmFuncData(word string, operands [][]lex.Token) {
From: obj.Addr{ From: obj.Addr{
Type: int16(p.arch.D_CONST), Type: int16(p.arch.D_CONST),
Index: uint8(p.arch.D_NONE), Index: uint8(p.arch.D_NONE),
Offset: value, Offset: value0,
}, },
To: obj.Addr{ To: obj.Addr{
Type: int16(p.symbolType(&nameAddr)), Type: int16(p.symbolType(&nameAddr)),
Index: uint8(p.arch.D_NONE), Index: uint8(p.arch.D_NONE),
Sym: obj.Linklookup(p.linkCtxt, name, 0), Sym: obj.Linklookup(p.linkCtxt, name, 0),
Offset: value1,
}, },
} }
p.append(prog, true) p.append(prog, true)

View file

@ -92,7 +92,7 @@ func (p *Parser) line() bool {
p.lineNum = p.lex.Line() p.lineNum = p.lex.Line()
p.histLineNum = lex.HistLine() p.histLineNum = lex.HistLine()
switch tok { switch tok {
case '\n': case '\n', ';':
continue continue
case scanner.EOF: case scanner.EOF:
return false return false
@ -438,8 +438,6 @@ func (p *Parser) term() uint64 {
return value return value
} }
} }
p.errorf("unexpected %s evaluating expression", p.peek())
return 0
} }
// factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')' // factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')'

View file

@ -49,7 +49,7 @@ func Usage() {
os.Exit(2) os.Exit(2)
} }
func Parse(goroot, goos, goarch string, theChar int) { // TODO: see below func Parse(theChar int) {
flag.Usage = Usage flag.Usage = Usage
flag.Parse() flag.Parse()
if flag.NArg() != 1 { if flag.NArg() != 1 {
@ -64,8 +64,4 @@ func Parse(goroot, goos, goarch string, theChar int) { // TODO: see below
} }
*OutputFile = fmt.Sprintf("%s.%c", input, theChar) *OutputFile = fmt.Sprintf("%s.%c", input, theChar)
} }
// Initialize to include $GOROOT/pkg/$GOOS_GOARCH/ so we find textflag.h
// TODO: Delete last line once asm is installed because the go command takes care of this.
// The arguments to Parse can be simplified then too.
I = append(I, filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch)))
} }

View file

@ -93,7 +93,9 @@ func (in *Input) Next() ScanToken {
in.text = in.peekText in.text = in.peekText
return tok return tok
} }
for { // If we cannot generate a token after 100 tries, we're in trouble.
// The usual case is caught by Push, below, but be safe.
for i := 0; i < 100; i++ {
tok := in.Stack.Next() tok := in.Stack.Next()
switch tok { switch tok {
case '#': case '#':

View file

@ -7,7 +7,6 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"go/build"
"log" "log"
"os" "os"
@ -23,14 +22,14 @@ func main() {
log.SetFlags(0) log.SetFlags(0)
log.SetPrefix("asm: ") log.SetPrefix("asm: ")
GOARCH := build.Default.GOARCH GOARCH := obj.Getgoarch()
architecture := arch.Set(GOARCH) architecture := arch.Set(GOARCH)
if architecture == nil { if architecture == nil {
log.Fatalf("asm: unrecognized architecture %s", GOARCH) log.Fatalf("asm: unrecognized architecture %s", GOARCH)
} }
flags.Parse(obj.Getgoroot(), obj.Getgoos(), obj.Getgoarch(), architecture.Thechar) flags.Parse(architecture.Thechar)
// Create object file, write header. // Create object file, write header.
fd, err := os.Create(*flags.OutputFile) fd, err := os.Create(*flags.OutputFile)