Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1671)

Unified Diff: x86asm/ext_test.go

Issue 95300044: code review 95300044: x86asm: basic 64-bit mode decoding (Closed)
Patch Set: diff -r 27604273fc7c https://code.google.com/p/rsc.x86/ Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « x86asm/decode.go ('k') | x86asm/gnu.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: x86asm/ext_test.go
===================================================================
--- a/x86asm/ext_test.go
+++ b/x86asm/ext_test.go
@@ -27,6 +27,7 @@
var (
printTests = flag.Bool("printtests", false, "print test cases that exercise new code paths")
dumpTest = flag.Bool("dump", false, "dump all encodings")
+ mismatch = flag.Bool("mismatch", false, "log allowed mismatches")
longTest = flag.Bool("long", false, "long test")
keep = flag.Bool("keep", false, "keep object files around")
debug = false
@@ -125,7 +126,7 @@
totalSkips = 0
totalErrors = 0
- errors = make([]string, 0, 256) // sampled errors, at most cap
+ errors = make([]string, 0, 100) // sampled errors, at most cap
)
go func() {
errc <- extdis(ext)
@@ -142,9 +143,13 @@
fmt.Printf("%x -> %s [%d]\n", enc[:len(enc)], dec.text, dec.nenc)
}
if text != dec.text || size != dec.nenc {
+ suffix := ""
if allowedMismatch(text, size, &inst, dec) {
totalSkips++
- return
+ if !*mismatch {
+ return
+ }
+ suffix += " (allowed mismatch)"
}
totalErrors++
if len(errors) >= cap(errors) {
@@ -154,14 +159,19 @@
}
errors = append(errors[:j], errors[j+1:]...)
}
- errors = append(errors, fmt.Sprintf("decode(%x) = %q, %d, want %q, %d", enc, text, size, dec.text, dec.nenc))
+ errors = append(errors, fmt.Sprintf("decode(%x) = %q, %d, want %q, %d%s", enc, text, size, dec.text, dec.nenc, suffix))
}
})
+ if *mismatch {
+ totalErrors -= totalSkips
+ }
+
+ for _, b := range errors {
+ t.Log(b)
+ }
+
if totalErrors > 0 {
- for _, b := range errors {
- t.Log(b)
- }
t.Fail()
}
t.Logf("%d test cases, %d expected mismatches, %d failures; %.0f cases/second", totalTests, totalSkips, totalErrors, float64(totalTests)/time.Since(start).Seconds())
@@ -238,10 +248,10 @@
text = "error: " + err.Error()
} else {
switch syntax {
+ case "gnu":
+ text = GNUSyntax(inst)
case "intel":
text = IntelSyntax(inst)
- case "gnu":
- text = GNUSyntax(inst)
default:
text = "error: unknown syntax " + syntax
}
@@ -479,7 +489,7 @@
// pcrel and pcrelw match instructions using relative addressing mode.
var (
- pcrel = regexp.MustCompile(`^((?:.* )?(?:j[a-z]+|call|ljmp|loopn?e?w?|xbegin)(?:,p[nt])?) 0x([0-9a-f]+)$`)
+ pcrel = regexp.MustCompile(`^((?:.* )?(?:j[a-z]+|call|ljmp|loopn?e?w?|xbegin)q?(?:,p[nt])?) 0x([0-9a-f]+)$`)
pcrelw = regexp.MustCompile(`^((?:.* )?(?:callw|jmpw|xbeginw|ljmpw)(?:,p[nt])?) 0x([0-9a-f]+)$`)
)
@@ -569,6 +579,13 @@
}
}
+func rexPrefixes(try func([]byte)) {
+ try(nil)
+ for _, b := range []byte{0x40, 0x48, 0x43, 0x4C} {
+ try([]byte{b})
+ }
+}
+
// concat takes two generators and returns a generator for the
// cross product of the two, concatenating the results from each.
func concat(gen1, gen2 func(func([]byte))) func(func([]byte)) {
@@ -595,6 +612,33 @@
}
}
+// concat4 takes four generators and returns a generator for the
+// cross product of the four, concatenating the results from each.
+func concat4(gen1, gen2, gen3, gen4 func(func([]byte))) func(func([]byte)) {
+ return func(try func([]byte)) {
+ gen1(func(enc1 []byte) {
+ gen2(func(enc2 []byte) {
+ gen3(func(enc3 []byte) {
+ gen4(func(enc4 []byte) {
+ try(append(append(append(enc1[:len(enc1):len(enc1)], enc2...), enc3...), enc4...))
+ })
+ })
+ })
+ })
+ }
+}
+
+// filter generates the sequences from gen that satisfy ok.
+func filter(gen func(func([]byte)), ok func([]byte) bool) func(func([]byte)) {
+ return func(try func([]byte)) {
+ gen(func(enc []byte) {
+ if ok(enc) {
+ try(enc)
+ }
+ })
+ }
+}
+
// enum8bit generates all possible 1-byte sequences, followed by distinctive padding.
func enum8bit(try func([]byte)) {
for i := 0; i < 1<<8; i++ {
@@ -674,6 +718,28 @@
}
}
+func testBasicREX(t *testing.T, testfn func(*testing.T, func(func([]byte))), opcode ...byte) {
+ testfn(t, filter(concat4(basicPrefixes, rexPrefixes, fixed(opcode...), enum8bit), isValidREX))
+ if testing.Short() {
+ return
+ }
+
+ t.Parallel()
+ testfn(t, filter(concat4(basicPrefixes, rexPrefixes, fixed(opcode...), enum16bit), isValidREX))
+ if !*longTest {
+ return
+ }
+
+ name := caller(2)
+ op1 := make([]byte, len(opcode)+1)
+ copy(op1, opcode)
+ for i := 0; i < 256; i++ {
+ log.Printf("%s 24-bit: %d/256\n", name, i)
+ op1[len(opcode)] = byte(i)
+ testfn(t, filter(concat3(rexPrefixes, fixed(op1...), enum16bit), isValidREX))
+ }
+}
+
// testPrefix runs the given test function for all many prefix possibilities
// followed by all possible 1-byte sequences.
//
@@ -693,6 +759,20 @@
}
}
+func testPrefixREX(t *testing.T, testfn func(*testing.T, func(func([]byte)))) {
+ t.Parallel()
+ testfn(t, filter(concat3(manyPrefixes, rexPrefixes, enum8bit), isValidREX))
+ if testing.Short() || !*longTest {
+ return
+ }
+
+ name := caller(2)
+ for i := 0; i < 256; i++ {
+ log.Printf("%s 16-bit: %d/256\n", name, i)
+ testfn(t, filter(concat4(manyPrefixes, rexPrefixes, fixed(byte(i)), enum8bit), isValidREX))
+ }
+}
+
func caller(skip int) string {
pc, _, _, _ := runtime.Caller(skip)
f := runtime.FuncForPC(pc)
@@ -705,3 +785,25 @@
}
return name
}
+
+func isValidREX(x []byte) bool {
+ i := 0
+ for i < len(x) && isPrefixByte(x[i]) {
+ i++
+ }
+ if i < len(x) && Prefix(x[i]).IsREX() {
+ i++
+ if i < len(x) {
+ return !isPrefixByte(x[i]) && !Prefix(x[i]).IsREX()
+ }
+ }
+ return true
+}
+
+func isPrefixByte(b byte) bool {
+ switch b {
+ case 0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65, 0x66, 0x67, 0xF0, 0xF2, 0xF3:
+ return true
+ }
+ return false
+}
« no previous file with comments | « x86asm/decode.go ('k') | x86asm/gnu.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b