Commit aa55bd44 authored by Rob Pike's avatar Rob Pike

[dev.cc] cmd/asm: clean up jumps

Set TYPE_BRANCH for x(PC) in the parser and the assembler has less work to do.
This also makes the operand test handle -4(PC) correctly.

Also add a special test case for AX:DX, which should be fixed in obj really.

Change-Id: If195e3a8cf3454a73508633e9b317d66030da826
Reviewed-on: https://go-review.googlesource.com/5071Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent e190e271
......@@ -304,6 +304,12 @@ func (p *Parser) asmJump(op int, cond string, a []obj.Addr) {
As: int16(op),
}
switch {
case target.Type == obj.TYPE_BRANCH:
// JMP 4(PC)
prog.To = obj.Addr{
Type: obj.TYPE_BRANCH,
Offset: p.pc + 1 + target.Offset, // +1 because p.pc is incremented in link, below.
}
case target.Type == obj.TYPE_REG:
// JMP R1
prog.To = *target
......@@ -324,14 +330,7 @@ func (p *Parser) asmJump(op int, cond string, a []obj.Addr) {
}
case target.Type == obj.TYPE_MEM && target.Name == obj.NAME_NONE:
// JMP 4(PC)
if target.Reg == arch.RPC {
prog.To = obj.Addr{
Type: obj.TYPE_BRANCH,
Offset: p.pc + 1 + target.Offset, // +1 because p.pc is incremented in link, below.
}
} else {
prog.To = *target
}
prog.To = *target
default:
p.errorf("cannot assemble jump %+v", target)
}
......
......@@ -27,6 +27,21 @@ func TestAMD64OperandParser(t *testing.T) {
t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output)
}
}
// Special case for AX:DX, which is really two operands so isn't print correcctly
// by Aconv, but is OK by the -S output.
parser.start(lex.Tokenize("AX:BX)"))
addr := obj.Addr{}
parser.operand(&addr)
want := obj.Addr{
Type: obj.TYPE_REG,
Reg: int16(architecture.Registers["AX"]),
Class: int8(architecture.Registers["BX"]),
}
if want != addr {
t.Errorf("AX:DX: expected %+v got %+v", want, addr)
}
}
type operandTest struct {
......@@ -86,13 +101,14 @@ var amd64operandTests = []operandTest{
{"(SP)", "(SP)"},
{"(6+8)(AX)", "14(AX)"},
{"(8*4)(BP)", "32(BP)"},
// {"+3(PC)", "+3(PC)"}, TODO: Need to parse this knowing it's a branch.
{"+3(PC)", "3(PC)"},
{"-3(PC)", "-3(PC)"},
{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},
{"-64(SI)(BX*1)", "-64(SI)(BX*1)"},
{"-96(SI)(BX*1)", "-96(SI)(BX*1)"},
{"AL", "AL"},
{"AX", "AX"},
// {"AX:DX", "AX:DX"}, TODO: prints as AX although -S output is correct.
// {"AX:DX", "AX:DX"}, Handled in TestAMD64OperandParser directly.
{"BP", "BP"},
{"BX", "BX"},
{"CX", "CX"},
......
......@@ -126,7 +126,7 @@ func (p *Parser) line() bool {
continue
}
if tok == ':' {
// LABELS
// Labels.
p.pendingLabels = append(p.pendingLabels, word)
return true
}
......@@ -506,11 +506,10 @@ func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, pr
case "FP":
addr.Name = obj.NAME_PARAM
case "PC":
// Fine as is.
if prefix != 0 {
p.errorf("illegal addressing mode for PC")
}
addr.Reg = arch.RPC // Tells asmJump how to interpret this address.
addr.Type = obj.TYPE_BRANCH // We set the type and leave NAME untouched. See asmJump.
case "SB":
addr.Name = obj.NAME_EXTERN
if isStatic {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment