diff --git a/internal/gen/loadertest.go b/internal/gen/loadertest.go
index b5cb7e1..af8ef9a 100644
--- a/internal/gen/loadertest.go
+++ b/internal/gen/loadertest.go
@@ -1,7 +1,9 @@
package gen
import (
+ "fmt"
"io"
+ "math"
"strings"
"github.com/mmcloughlin/avo/internal/inst"
@@ -16,8 +18,8 @@ func (l LoaderTest) Generate(w io.Writer, is []*inst.Instruction) error {
for _, i := range is {
p.printf("\t// %s %s\n", i.Opcode, i.Summary)
- if strings.HasPrefix(i.Opcode, "RET") {
- p.printf("\t// SKIP: early RET instruction would cause assembler error")
+ if skip, msg := l.skip(i.Opcode); skip {
+ p.printf("\t// SKIP: %s\n", msg)
continue
}
@@ -25,7 +27,7 @@ func (l LoaderTest) Generate(w io.Writer, is []*inst.Instruction) error {
as := args(f.Operands)
p.printf("\t// %#v\n", f.Operands)
if as == nil {
- p.printf("\t// SKIP:\n")
+ p.printf("\t// TODO\n")
continue
}
p.printf("\t%s\t%s\n", i.Opcode, strings.Join(as, ", "))
@@ -38,6 +40,19 @@ func (l LoaderTest) Generate(w io.Writer, is []*inst.Instruction) error {
return p.Err()
}
+func (l LoaderTest) skip(opcode string) (bool, string) {
+ prefixes := map[string]string{
+ "PUSH": "PUSH can produce 'unbalanced PUSH/POP' assembler error",
+ "POP": "POP can produce 'unbalanced PUSH/POP' assembler error",
+ }
+ for p, m := range prefixes {
+ if strings.HasPrefix(opcode, p) {
+ return true, m
+ }
+ }
+ return false, ""
+}
+
func args(ops []inst.Operand) []string {
as := make([]string, len(ops))
for i, op := range ops {
@@ -58,8 +73,8 @@ func arg(t string) string {
//
//
//
- //
- //
+ "imm32": fmt.Sprintf("$%d", math.MaxInt32), //
+ "imm64": fmt.Sprintf("$%d", math.MaxInt64), //
//
//
//
diff --git a/internal/load/load.go b/internal/load/load.go
index 18e903a..1a12ca7 100644
--- a/internal/load/load.go
+++ b/internal/load/load.go
@@ -1,7 +1,6 @@
package load
import (
- "log"
"path/filepath"
"strconv"
"strings"
@@ -20,7 +19,8 @@ type Loader struct {
X86CSVPath string
OpcodesXMLPath string
- alias map[opcodescsv.Alias]string
+ alias map[opcodescsv.Alias]string
+ usesIntelOrder map[string]bool
}
func NewLoaderFromDataDir(dir string) *Loader {
@@ -58,7 +58,7 @@ func (l *Loader) Load() ([]*inst.Instruction, error) {
}
}
- im[opcode].Forms = append(im[opcode].Forms, l.form(f))
+ im[opcode].Forms = append(im[opcode].Forms, l.form(opcode, f))
}
}
@@ -82,9 +82,7 @@ func (l *Loader) init() error {
return err
}
- for a, op := range l.alias {
- log.Printf("alias: %#v -> %s", a, op)
- }
+ l.usesIntelOrder = opcodescsv.BuildIntelOrderSet(icsv)
return nil
}
@@ -156,18 +154,24 @@ func (l Loader) goname(f opcodesxml.Form) string {
return n
}
-func (l Loader) form(f opcodesxml.Form) inst.Form {
+func (l Loader) form(opcode string, f opcodesxml.Form) inst.Form {
+ ops := operands(f.Operands)
+ if !l.usesIntelOrder[opcode] {
+ for l, r := 0, len(ops)-1; l < r; l, r = l+1, r-1 {
+ ops[l], ops[r] = ops[r], ops[l]
+ }
+ }
return inst.Form{
- Operands: operands(f.Operands),
+ Operands: ops,
}
}
-// operands maps Opcodes XML operands to avo format.
+// operands maps Opcodes XML operands to avo format. Returned in Intel order.
func operands(ops []opcodesxml.Operand) []inst.Operand {
n := len(ops)
- r := make([]inst.Operand, len(ops))
+ r := make([]inst.Operand, n)
for i, op := range ops {
- r[n-1-i] = operand(op)
+ r[i] = operand(op)
}
return r
}
diff --git a/internal/opcodescsv/analysis.go b/internal/opcodescsv/analysis.go
index 7f696aa..9cf8908 100644
--- a/internal/opcodescsv/analysis.go
+++ b/internal/opcodescsv/analysis.go
@@ -1,6 +1,7 @@
package opcodescsv
import (
+ "reflect"
"strconv"
"strings"
@@ -17,7 +18,7 @@ type Alias struct {
func BuildAliasMap(is []*x86csv.Inst) (map[Alias]string, error) {
m := map[Alias]string{}
for _, i := range is {
- s, err := datasize(i.DataSize)
+ s, err := strconv.Atoi("0" + i.DataSize)
if err != nil {
return nil, err
}
@@ -40,9 +41,13 @@ func BuildAliasMap(is []*x86csv.Inst) (map[Alias]string, error) {
return m, nil
}
-func datasize(s string) (int, error) {
- if s == "" {
- return 0, nil
+// BuildIntelOrderSet builds the set of instructions that use intel order rather than the usual GNU/AT&T order.
+func BuildIntelOrderSet(is []*x86csv.Inst) map[string]bool {
+ s := map[string]bool{}
+ for _, i := range is {
+ if !reflect.DeepEqual(i.GoArgs(), i.GNUArgs()) {
+ s[i.GoOpcode()] = true
+ }
}
- return strconv.Atoi(s)
+ return s
}