ensure all stdlib opcodes are present
This commit is contained in:
@@ -24,6 +24,9 @@ func (g godata) Generate(is []inst.Instruction) ([]byte, error) {
|
||||
p.Printf("{\n")
|
||||
|
||||
p.Printf("Opcode: %#v,\n", i.Opcode)
|
||||
if i.AliasOf != "" {
|
||||
p.Printf("AliasOf: %#v,\n", i.AliasOf)
|
||||
}
|
||||
p.Printf("Summary: %#v,\n", i.Summary)
|
||||
|
||||
p.Printf("Forms: []Form{\n")
|
||||
|
||||
@@ -62,8 +62,6 @@ func TestLookup(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStdLibOpcodes(t *testing.T) {
|
||||
t.Skip("currently does not pass")
|
||||
|
||||
b, err := ioutil.ReadFile("testdata/stdlibopcodes.txt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -2,6 +2,7 @@ package inst
|
||||
|
||||
type Instruction struct {
|
||||
Opcode string
|
||||
AliasOf string
|
||||
Summary string
|
||||
Forms []Form
|
||||
}
|
||||
|
||||
@@ -3842,6 +3842,12 @@ var Instructions = []Instruction{
|
||||
{Type: "r32", Action: 0x2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Opcode: "CVTTSD2SQ",
|
||||
Summary: "Convert with Truncation Scalar Double-Precision FP Value to Signed Integer",
|
||||
Forms: []Form{
|
||||
{
|
||||
ISA: []string{"SSE2"},
|
||||
Operands: []Operand{
|
||||
@@ -4734,6 +4740,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JA",
|
||||
AliasOf: "JHI",
|
||||
Summary: "Jump if above (CF == 0 and ZF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -4760,6 +4767,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JAE",
|
||||
AliasOf: "JCC",
|
||||
Summary: "Jump if above or equal (CF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -4796,6 +4804,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JB",
|
||||
AliasOf: "JCS",
|
||||
Summary: "Jump if below (CF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -4832,6 +4841,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JBE",
|
||||
AliasOf: "JLS",
|
||||
Summary: "Jump if below or equal (CF == 1 or ZF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -4858,6 +4868,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JC",
|
||||
AliasOf: "JCS",
|
||||
Summary: "Jump if below (CF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -4994,6 +5005,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JE",
|
||||
AliasOf: "JEQ",
|
||||
Summary: "Jump if equal (ZF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5046,6 +5058,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JG",
|
||||
AliasOf: "JGT",
|
||||
Summary: "Jump if greater (ZF == 0 and SF == OF)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5150,6 +5163,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JHS",
|
||||
AliasOf: "JCC",
|
||||
Summary: "Jump if above or equal (CF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5186,6 +5200,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JL",
|
||||
AliasOf: "JLT",
|
||||
Summary: "Jump if less (SF != OF)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5238,6 +5253,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JLO",
|
||||
AliasOf: "JCS",
|
||||
Summary: "Jump if below (CF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5368,6 +5384,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNA",
|
||||
AliasOf: "JLS",
|
||||
Summary: "Jump if below or equal (CF == 1 or ZF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5394,6 +5411,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNAE",
|
||||
AliasOf: "JCS",
|
||||
Summary: "Jump if below (CF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5430,6 +5448,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNB",
|
||||
AliasOf: "JCC",
|
||||
Summary: "Jump if above or equal (CF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5466,6 +5485,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNBE",
|
||||
AliasOf: "JHI",
|
||||
Summary: "Jump if above (CF == 0 and ZF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5492,6 +5512,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNC",
|
||||
AliasOf: "JCC",
|
||||
Summary: "Jump if above or equal (CF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5554,6 +5575,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNG",
|
||||
AliasOf: "JLE",
|
||||
Summary: "Jump if less or equal (ZF == 1 or SF != OF)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5580,6 +5602,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNGE",
|
||||
AliasOf: "JLT",
|
||||
Summary: "Jump if less (SF != OF)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5606,6 +5629,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNL",
|
||||
AliasOf: "JGE",
|
||||
Summary: "Jump if greater or equal (SF == OF)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5632,6 +5656,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNLE",
|
||||
AliasOf: "JGT",
|
||||
Summary: "Jump if greater (ZF == 0 and SF == OF)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5658,6 +5683,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNO",
|
||||
AliasOf: "JOC",
|
||||
Summary: "Jump if not overflow (OF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5674,6 +5700,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNP",
|
||||
AliasOf: "JPC",
|
||||
Summary: "Jump if not parity (PF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5700,6 +5727,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNS",
|
||||
AliasOf: "JPL",
|
||||
Summary: "Jump if not sign (SF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5716,6 +5744,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JNZ",
|
||||
AliasOf: "JNE",
|
||||
Summary: "Jump if not equal (ZF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5742,6 +5771,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JO",
|
||||
AliasOf: "JOS",
|
||||
Summary: "Jump if overflow (OF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5790,6 +5820,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JP",
|
||||
AliasOf: "JPS",
|
||||
Summary: "Jump if parity (PF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5842,6 +5873,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JPE",
|
||||
AliasOf: "JPS",
|
||||
Summary: "Jump if parity (PF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5884,6 +5916,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JPO",
|
||||
AliasOf: "JPC",
|
||||
Summary: "Jump if not parity (PF == 0)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5936,6 +5969,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JS",
|
||||
AliasOf: "JMI",
|
||||
Summary: "Jump if sign (SF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -5952,6 +5986,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "JZ",
|
||||
AliasOf: "JEQ",
|
||||
Summary: "Jump if equal (ZF == 1)",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -6109,6 +6144,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "MASKMOVDQU",
|
||||
AliasOf: "MASKMOVOU",
|
||||
Summary: "Store Selected Bytes of Double Quadword",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -6584,6 +6620,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "MOVD",
|
||||
AliasOf: "MOVQ",
|
||||
Summary: "Move",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -6681,6 +6718,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "MOVDQ2Q",
|
||||
AliasOf: "MOVQ",
|
||||
Summary: "Move",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -6916,6 +6954,18 @@ var Instructions = []Instruction{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Opcode: "MOVLQZX",
|
||||
Summary: "Move with Zero-Extend",
|
||||
Forms: []Form{
|
||||
{
|
||||
Operands: []Operand{
|
||||
{Type: "m32", Action: 0x1},
|
||||
{Type: "r64", Action: 0x2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Opcode: "MOVMSKPD",
|
||||
Summary: "Extract Packed Double-Precision Floating-Point Sign Mask",
|
||||
@@ -6944,6 +6994,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "MOVNTDQ",
|
||||
AliasOf: "MOVNTO",
|
||||
Summary: "Store Double Quadword Using Non-Temporal Hint",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -7062,6 +7113,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "MOVOA",
|
||||
AliasOf: "MOVO",
|
||||
Summary: "Move Aligned Double Quadword",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -8258,6 +8310,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "PADDD",
|
||||
AliasOf: "PADDL",
|
||||
Summary: "Add Packed Doubleword Integers",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -10150,6 +10203,29 @@ var Instructions = []Instruction{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Opcode: "PSHUFD",
|
||||
AliasOf: "PSHUFL",
|
||||
Summary: "Shuffle Packed Doublewords",
|
||||
Forms: []Form{
|
||||
{
|
||||
ISA: []string{"SSE2"},
|
||||
Operands: []Operand{
|
||||
{Type: "imm8", Action: 0x0},
|
||||
{Type: "xmm", Action: 0x1},
|
||||
{Type: "xmm", Action: 0x2},
|
||||
},
|
||||
},
|
||||
{
|
||||
ISA: []string{"SSE2"},
|
||||
Operands: []Operand{
|
||||
{Type: "imm8", Action: 0x0},
|
||||
{Type: "m128", Action: 0x1},
|
||||
{Type: "xmm", Action: 0x2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Opcode: "PSHUFHW",
|
||||
Summary: "Shuffle Packed High Words",
|
||||
@@ -10278,6 +10354,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "PSLLDQ",
|
||||
AliasOf: "PSLLO",
|
||||
Summary: "Shift Packed Double Quadword Left Logical",
|
||||
Forms: []Form{
|
||||
{
|
||||
@@ -10439,6 +10516,7 @@ var Instructions = []Instruction{
|
||||
},
|
||||
{
|
||||
Opcode: "PSRLDQ",
|
||||
AliasOf: "PSRLO",
|
||||
Summary: "Shift Packed Double Quadword Right Logical",
|
||||
Forms: []Form{
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -62,10 +62,16 @@ func (l *Loader) Load() ([]inst.Instruction, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply list of "annoying aliases".
|
||||
for from, to := range annoyingaliases {
|
||||
// Add extras to our list.
|
||||
for _, e := range extras {
|
||||
im[e.Opcode] = e
|
||||
}
|
||||
|
||||
// Apply list of aliases.
|
||||
for from, to := range aliases {
|
||||
cpy := *im[to]
|
||||
cpy.Opcode = from
|
||||
cpy.AliasOf = to
|
||||
im[from] = &cpy
|
||||
}
|
||||
|
||||
@@ -184,6 +190,24 @@ func (l Loader) lookupAlias(f opcodesxml.Form) string {
|
||||
}
|
||||
|
||||
func (l Loader) gonames(f opcodesxml.Form) []string {
|
||||
s := datasize(f)
|
||||
|
||||
// Suspect a "bug" in x86 CSV for the CVTTSD2SQ instruction, as CVTTSD2SL appears twice.
|
||||
//
|
||||
// Reference: https://github.com/golang/arch/blob/b19384d3c130858bb31a343ea8fce26be71b5998/x86/x86.v0.2.csv#L345-L346
|
||||
//
|
||||
// "CVTTSD2SI r32, xmm2/m64","CVTTSD2SL xmm2/m64, r32","cvttsd2si xmm2/m64, r32","F2 0F 2C /r","V","V","SSE2","operand16,operand32","w,r","Y","32"
|
||||
// "CVTTSD2SI r64, xmm2/m64","CVTTSD2SL xmm2/m64, r64","cvttsd2siq xmm2/m64, r64","F2 REX.W 0F 2C /r","N.E.","V","SSE2","","w,r","Y","64"
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/cmd/internal/obj/x86/asm6.go#L1073-L1074
|
||||
//
|
||||
// {ACVTTSD2SL, yxcvfl, Pf2, opBytes{0x2c}},
|
||||
// {ACVTTSD2SQ, yxcvfq, Pw, opBytes{Pf2, 0x2c}},
|
||||
//
|
||||
if f.GASName == "cvttsd2si" && s == 64 {
|
||||
return []string{"CVTTSD2SQ"}
|
||||
}
|
||||
|
||||
// Return alias if available.
|
||||
if a := l.lookupAlias(f); a != "" {
|
||||
return []string{a}
|
||||
@@ -221,7 +245,6 @@ func (l Loader) gonames(f opcodesxml.Form) []string {
|
||||
|
||||
// Some need data sizes added to them.
|
||||
// TODO(mbm): is there a better way of determining which ones these are?
|
||||
s := datasize(f)
|
||||
suffix := map[int]string{16: "W", 32: "L", 64: "Q", 128: "X", 256: "Y"}
|
||||
switch n {
|
||||
case "VCVTUSI2SS", "VCVTSD2USI", "VCVTSS2USI", "VCVTUSI2SD", "VCVTTSS2USI", "VCVTTSD2USI":
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
package load
|
||||
|
||||
import (
|
||||
"github.com/mmcloughlin/avo/internal/inst"
|
||||
)
|
||||
|
||||
// aliases defines a list of opcode aliases. Where possible these are extracted
|
||||
// from the code (see note below).
|
||||
var aliases = map[string]string{
|
||||
// The PSHUFD/PSHUFL alias is not recorded in the list of "Annoying aliases" below. However the instructions are identical.
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/cmd/internal/obj/x86/asm6.go#L1365
|
||||
//
|
||||
// {APSHUFL, yxshuf, Pq, opBytes{0x70, 00}},
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/cmd/internal/obj/x86/asm6.go#L1688
|
||||
//
|
||||
// {APSHUFD, yxshuf, Pq, opBytes{0x70, 0}},
|
||||
//
|
||||
"PSHUFD": "PSHUFL",
|
||||
}
|
||||
|
||||
// Go contains a list of self-proclaimed "Annoying aliases", as follows. We use
|
||||
// a script to automatically extract this list from the source code (see the
|
||||
// following go:generate line).
|
||||
// following go:generate line). Then we merge this with the manual list above.
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/cmd/asm/internal/arch/arch.go#L126-L182
|
||||
//
|
||||
@@ -66,3 +86,43 @@ package load
|
||||
//
|
||||
|
||||
//go:generate ./annoyingaliases.sh zannoyingaliases.go
|
||||
|
||||
func init() {
|
||||
for from, to := range annoyingaliases {
|
||||
aliases[from] = to
|
||||
}
|
||||
}
|
||||
|
||||
// extras is simply a list of extra instructions to add to the database.
|
||||
var extras = []*inst.Instruction{
|
||||
// MOVLQZX does not appear in either x86 CSV or Opcodes, but does appear in stdlib assembly.
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/runtime/asm_amd64.s#L451-L453
|
||||
//
|
||||
// TEXT ·reflectcall(SB), NOSPLIT, $0-32
|
||||
// MOVLQZX argsize+24(FP), CX
|
||||
// DISPATCH(runtime·call32, 32)
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/cmd/internal/obj/x86/asm6.go#L1217
|
||||
//
|
||||
// {AMOVLQZX, yml_rl, Px, opBytes{0x8b}},
|
||||
//
|
||||
// Reference: https://github.com/golang/go/blob/048c9164a0c5572df18325e377473e7893dbfb07/src/cmd/internal/obj/x86/asm6.go#L515-L517
|
||||
//
|
||||
// var yml_rl = []ytab{
|
||||
// {Zm_r, 1, argList{Yml, Yrl}},
|
||||
// }
|
||||
//
|
||||
{
|
||||
Opcode: "MOVLQZX",
|
||||
Summary: "Move with Zero-Extend",
|
||||
Forms: []inst.Form{
|
||||
{
|
||||
Operands: []inst.Operand{
|
||||
{Type: "m32", Action: inst.R},
|
||||
{Type: "r64", Action: inst.W},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user