1
0
mirror of https://github.com/golang/go synced 2024-11-19 02:14:43 -07:00

cmd/asm: add a couple of operand parses discovered by end-to-end test

Missing cases for JMP $4 and foo+4(SB):AX. Both are odd but 8a accepts them
and they seem valid.

Change-Id: Ic739f626fcc79ace1eaf646c5dfdd96da59df165
Reviewed-on: https://go-review.googlesource.com/5693
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Rob Pike 2015-02-23 15:45:40 -08:00
parent 07b73ce146
commit 4241b758af
3 changed files with 33 additions and 4 deletions

View File

@ -369,6 +369,9 @@ func (p *Parser) asmJump(op int, cond string, a []obj.Addr) {
if p.arch.Thechar == '9' && target.Offset == 0 {
prog.To.Type = obj.TYPE_REG
}
case target.Type == obj.TYPE_CONST:
// JMP $4
prog.To = a[0]
default:
p.errorf("cannot assemble jump %+v", target)
}

View File

@ -55,6 +55,21 @@ func testX86RegisterPair(t *testing.T, parser *Parser) {
if want != addr {
t.Errorf("AX:DX: expected %+v got %+v", want, addr)
}
// Special case for foo(SB):DX, which is really two operands so isn't printed correctly
// by Aconv, but is OK by the -S output.
parser.start(lex.Tokenize("foo+4(SB):AX"))
addr = obj.Addr{}
parser.operand(&addr)
want = obj.Addr{
Type: obj.TYPE_MEM,
Name: obj.NAME_EXTERN,
Offset: 4,
Sym: obj.Linklookup(parser.linkCtxt, "foo", 0),
Class: int8(parser.arch.Register["AX"]), // TODO: clean up how this is encoded in parse.go
}
if want != addr {
t.Errorf("foo+4(SB):AX: expected %+v got %+v", want, addr)
}
}
func TestAMD64OperandParser(t *testing.T) {
@ -229,6 +244,7 @@ var x86OperandTests = []operandTest{
{"(BP*8)", "(NONE)(BP*8)"}, // TODO: odd printout.
{"(BX)", "(BX)"},
{"(SP)", "(SP)"},
{"*AX", "AX"}, // TODO: Should make * illegal here; a simple alias for JMP AX.
{"*runtime·_GetStdHandle(SB)", "type=16"}, // TODO: bizarre
{"-(4+12)(DI)", "-16(DI)"},
{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},

View File

@ -362,8 +362,18 @@ func (p *Parser) operand(a *obj.Addr) bool {
// fmt.Printf("offset %d \n", a.Offset)
}
// Register indirection: (reg) or (index*scale). We are on the opening paren.
p.registerIndirect(a, prefix)
// Odd x86 case: sym+4(SB):AX. Have name, colon, register.
if p.peek() == ':' && a.Name != obj.NAME_NONE && a.Class == 0 && (p.arch.Thechar == '6' || p.arch.Thechar == '8') {
p.get(':')
r2, ok := p.registerReference(p.next().String())
if !ok {
return false
}
a.Class = int8(r2) // TODO: See comment about Class above.
} else {
// Register indirection: (reg) or (index*scale). We are on the opening paren.
p.registerIndirect(a, prefix)
}
// fmt.Printf("DONE %s\n", p.arch.Dconv(&emptyProg, 0, a))
p.expect(scanner.EOF)
@ -434,8 +444,8 @@ func (p *Parser) register(name string, prefix rune) (r1, r2 int16, scale int8, o
if !ok {
return
}
if prefix != 0 {
p.errorf("prefix %c not allowed for register: $%s", prefix, name)
if prefix != 0 && prefix != '*' { // *AX is OK.
p.errorf("prefix %c not allowed for register: %c%s", prefix, prefix, name)
}
c := p.peek()
if c == ':' || c == ',' || c == '+' {