]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] cmd/asm: clean up jumps
authorRob Pike <r@golang.org>
Tue, 17 Feb 2015 22:49:04 +0000 (14:49 -0800)
committerRob Pike <r@golang.org>
Tue, 17 Feb 2015 23:17:51 +0000 (23:17 +0000)
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/5071
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/asm/internal/asm/asm.go
src/cmd/asm/internal/asm/operand_test.go
src/cmd/asm/internal/asm/parse.go

index e7bfc4fe89cd45880f748f2416ed58f14d5bdafb..bd402ed00171a8a9d9783a632d86bc08387ba357 100644 (file)
@@ -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)
        }
index a7d1d846cf6c7018a4d913254c196c7f4be5668d..1dc15133ddfc35e8425dd16d72b46a53b895ee4d 100644 (file)
@@ -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"},
index 61198736fd772c1d3d2be30d3134816f05611085..16133269066e51fd3bb2ff4c4798040d03826d80 100644 (file)
@@ -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 {