Commit 879a1ff1 authored by Giovanni Bajo's avatar Giovanni Bajo

test: improve asmcheck syntax

asmcheck comments now support a compact form of specifying
multiple checks for each platform, using the following syntax:

   amd64:"SHL\t[$]4","SHR\t[$]4"

Negative checks are also parsed using the following syntax:

   amd64:-"ROR"

though they are still not working.

Moreover, out-of-line comments have been implemented. This
allows to specify asmchecks on comment-only lines, that will
be matched on the first subsequent non-comment non-empty line.

    // amd64:"XOR"
    // arm:"EOR"

    x ^= 1

Change-Id: I110c7462fc6a5c70fd4af0d42f516016ae7f2760
Reviewed-on: https://go-review.googlesource.com/97816Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 9372e3f5
...@@ -21,5 +21,7 @@ func rot64(x uint64) uint64 { ...@@ -21,5 +21,7 @@ func rot64(x uint64) uint64 {
} }
func copysign(a, b float64) float64 { func copysign(a, b float64) float64 {
// amd64:"SHLQ\t[$]1","SHRQ\t[$]1","SHRQ\t[$]63","SHLQ\t[$]63","ORQ"
// ppc64le:"FCPSGN" s390x:"CPSDR",-"MOVD"
return math.Copysign(a, b) return math.Copysign(a, b)
} }
...@@ -1247,8 +1247,23 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) { ...@@ -1247,8 +1247,23 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
return return
} }
const (
// Regexp to match a single opcode check: optionally begin with "-" (to indicate
// a negative check), followed by a string literal enclosed in "" or ``. For "",
// backslashes must be handled.
reMatchCheck = `-?(?:\x60[^\x60]*\x60|"(?:[^"\\]|\\.)*")`
)
var ( var (
rxAsmCheck = regexp.MustCompile(`//(?:\s+(\w+):((?:"(?:.+?)")|(?:` + "`" + `(?:.+?)` + "`" + `)))+`) // Regexp to split a line in code and comment, trimming spaces
rxAsmComment = regexp.MustCompile(`^\s*(.*?)\s*(?:\/\/\s*(.+)\s*)?$`)
// Regexp to extract an architecture check: architecture name, followed by semi-colon,
// followed by a comma-separated list of opcode checks.
rxAsmPlatform = regexp.MustCompile(`(\w+):(` + reMatchCheck + `(?:,` + reMatchCheck + `)*)`)
// Regexp to extract a single opcoded check
rxAsmCheck = regexp.MustCompile(reMatchCheck)
) )
type wantedAsmOpcode struct { type wantedAsmOpcode struct {
...@@ -1262,33 +1277,52 @@ func (t *test) wantedAsmOpcodes(fn string) (map[string]map[string][]wantedAsmOpc ...@@ -1262,33 +1277,52 @@ func (t *test) wantedAsmOpcodes(fn string) (map[string]map[string][]wantedAsmOpc
ops := make(map[string]map[string][]wantedAsmOpcode) ops := make(map[string]map[string][]wantedAsmOpcode)
archs := make(map[string]bool) archs := make(map[string]bool)
comment := ""
src, _ := ioutil.ReadFile(fn) src, _ := ioutil.ReadFile(fn)
for i, line := range strings.Split(string(src), "\n") { for i, line := range strings.Split(string(src), "\n") {
matches := rxAsmCheck.FindStringSubmatch(line) matches := rxAsmComment.FindStringSubmatch(line)
if len(matches) == 0 { code, cmt := matches[1], matches[2]
// Keep comments pending in the comment variable until
// we find a line that contains some code.
comment += " " + cmt
if code == "" {
continue continue
} }
// Parse and extract any architecture check from comments,
// made by one architecture name and multiple checks.
lnum := fn + ":" + strconv.Itoa(i+1) lnum := fn + ":" + strconv.Itoa(i+1)
for j := 1; j < len(matches); j += 2 { for _, ac := range rxAsmPlatform.FindAllStringSubmatch(comment, -1) {
rxsrc, err := strconv.Unquote(matches[j+1]) arch, allchecks := ac[1], ac[2]
if err != nil {
log.Fatalf("%s:%d: error unquoting string: %v", t.goFileName(), i+1, err) for _, m := range rxAsmCheck.FindAllString(allchecks, -1) {
} negative := false
oprx, err := regexp.Compile(rxsrc) if m[0] == '-' {
if err != nil { negative = true
log.Fatalf("%s:%d: %v", t.goFileName(), i+1, err) m = m[1:]
} }
arch := matches[j]
if ops[arch] == nil { rxsrc, err := strconv.Unquote(m)
ops[arch] = make(map[string][]wantedAsmOpcode) if err != nil {
log.Fatalf("%s:%d: error unquoting string: %v", t.goFileName(), i+1, err)
}
oprx, err := regexp.Compile(rxsrc)
if err != nil {
log.Fatalf("%s:%d: %v", t.goFileName(), i+1, err)
}
if ops[arch] == nil {
ops[arch] = make(map[string][]wantedAsmOpcode)
}
archs[arch] = true
ops[arch][lnum] = append(ops[arch][lnum], wantedAsmOpcode{
negative: negative,
line: i + 1,
opcode: oprx,
})
} }
archs[arch] = true
ops[arch][lnum] = append(ops[arch][lnum], wantedAsmOpcode{
line: i + 1,
opcode: oprx,
})
} }
comment = ""
} }
var sarchs []string var sarchs []string
......
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