Commit 2baed385 authored by Cherry Zhang's avatar Cherry Zhang

cmd/asm: fix assembling return jump

In RET instruction, the operand is the return jump's target,
which should be put in Prog.To.

Add an action "buildrundir" to the test driver, which builds
(compile+assemble+link) the code in a directory and runs the
resulting binary.

Fixes #23838.

Change-Id: I7ebe7eda49024b40a69a24857322c5ca9c67babb
Reviewed-on: https://go-review.googlesource.com/94175
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarAustin Clements <austin@google.com>
parent 213a7517
......@@ -486,7 +486,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
case 0:
// Nothing to do.
case 1:
if p.arch.UnaryDst[op] {
if p.arch.UnaryDst[op] || op == obj.ARET {
// prog.From is no address.
prog.To = a[0]
} else {
......
......@@ -91,3 +91,4 @@ loop:
// LTYPE0 nonnon { outcode(int($1), &$2); }
RET
RET foo(SB)
......@@ -145,3 +145,4 @@ loop:
// LTYPE0 nonnon { outcode($1, &$2); }
RET // c3
RET foo(SB)
......@@ -1579,6 +1579,8 @@ jmp_label_3:
MOVHU R5@>16, R1 // 7518ffe6
MOVHU R5@>24, R1 // 751cffe6
RET foo(SB)
//
// END
//
......
......@@ -426,6 +426,7 @@ again:
// }
BEQ 2(PC)
RET
RET foo(SB)
// More B/BL cases, and canonical names JMP, CALL.
......
......@@ -422,6 +422,7 @@ label4:
BEQ R1, 2(PC)
JMP foo(SB)
CALL foo(SB)
RET foo(SB)
NEGW R1, R2 // 00011023
......
......@@ -402,6 +402,7 @@ label4:
BEQ R1, 2(PC)
JMP foo(SB)
CALL foo(SB)
RET foo(SB)
NEGW R1, R2 // 00011023
NEGV R1, R2 // 0001102f
......
......@@ -1197,6 +1197,7 @@ label1:
BEQ 2(PC)
JMP foo(SB)
CALL foo(SB)
RET foo(SB)
// END
//
......
......@@ -365,6 +365,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
VSTEB $15, V29, 4094(R12) // e7d0cffef808
RET
RET foo(SB)
TEXT main·init(SB),DUPOK|NOSPLIT,$0 // TEXT main.init(SB), DUPOK|NOSPLIT, $0
RET
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
TEXT ·f(SB), 4, $8-0
CALL ·f1(SB)
RET ·f2(SB)
CALL ·unreachable(SB)
TEXT ·leaf(SB), 4, $0-0
RET ·f3(SB)
JMP ·unreachable(SB)
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
func f()
func leaf()
var f1called, f2called, f3called bool
func main() {
f()
if !f1called {
panic("f1 not called")
}
if !f2called {
panic("f2 not called")
}
leaf()
if !f3called {
panic("f3 not called")
}
}
func f1() { f1called = true }
func f2() { f2called = true }
func f3() { f3called = true }
func unreachable() {
panic("unreachable function called")
}
// buildrundir
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test that return jump works correctly in assembly code.
package ignored
......@@ -488,7 +488,7 @@ func (t *test) run() {
action = "rundir"
case "cmpout":
action = "run" // the run case already looks for <dir>/<test>.out files
case "compile", "compiledir", "build", "builddir", "run", "buildrun", "runoutput", "rundir", "asmcheck":
case "compile", "compiledir", "build", "builddir", "buildrundir", "run", "buildrun", "runoutput", "rundir", "asmcheck":
// nothing to do
case "errorcheckandrundir":
wantError = false // should be no error if also will run
......@@ -735,7 +735,7 @@ func (t *test) run() {
t.err = err
}
case "builddir":
case "builddir", "buildrundir":
// Build an executable from all the .go and .s files in a subdirectory.
useTmp = true
longdir := filepath.Join(cwd, t.goDirName())
......@@ -788,12 +788,23 @@ func (t *test) run() {
t.err = err
break
}
cmd = []string{"go", "tool", "link", "all.a"}
cmd = []string{"go", "tool", "link", "-o", "a.exe", "all.a"}
_, err = runcmd(cmd...)
if err != nil {
t.err = err
break
}
if action == "buildrundir" {
cmd = append(findExecCmd(), filepath.Join(t.tempDir, "a.exe"))
out, err := runcmd(cmd...)
if err != nil {
t.err = err
break
}
if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
}
}
case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop.
// TODO: not supported on NaCl
......
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