diff --git a/arch/amd64_ext.go b/arch/amd64_ext.go index 6b68e02..b0b3bb2 100644 --- a/arch/amd64_ext.go +++ b/arch/amd64_ext.go @@ -364,6 +364,12 @@ var amd64Extensions = []ExtInstr{ {Name: "VSQRTSH", Summary: "Compute the square root of a scalar FP16 value", Bytes: []byte{0x62, 0x05, 0x06, 0x00, 0x51, 0xC0}, Form: ExtFormAmdVec3, Feature: ExtFeatureFP16, Ref: "Intel SDM Vol. 2C, VSQRTSH (EVEX.NDS.LIG.F3.MAP5.W0 51 /r)"}, + {Name: "VSCALEFSH", Summary: "Scale a scalar FP16 value by the ratio of two others", + Bytes: []byte{0x62, 0x06, 0x05, 0x00, 0x2D, 0xC0}, Form: ExtFormAmdVec3, Feature: ExtFeatureFP16, + Ref: "Intel SDM Vol. 2C, VSCALEFSH (EVEX.NDS.LIG.66.MAP6.W0 2D /r)"}, + {Name: "VGETEXPSH", Summary: "Convert the exponent of a scalar FP16 value to an FP16 value", + Bytes: []byte{0x62, 0x06, 0x05, 0x00, 0x43, 0xC0}, Form: ExtFormAmdVec3, Feature: ExtFeatureFP16, + Ref: "Intel SDM Vol. 2C, VGETEXPSH (EVEX.NDS.LIG.66.MAP6.W0 43 /r)"}, {Name: "VCOMISH", Summary: "Compare a scalar FP16 value and set EFLAGS", Bytes: []byte{0x62, 0x05, 0x04, 0x00, 0x2F, 0xC0}, Form: ExtFormAmdVec2, Feature: ExtFeatureFP16, Ref: "Intel SDM Vol. 2C, VCOMISH (EVEX.LIG.MAP5.W0 2F /r)"}, diff --git a/arch/amd64_ext_test.go b/arch/amd64_ext_test.go index ec542df..3994915 100644 --- a/arch/amd64_ext_test.go +++ b/arch/amd64_ext_test.go @@ -108,6 +108,14 @@ var amd64GoldenRows = []amd64GoldenRow{ []ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)}, "6205160051f4", "62 05 16 00 51 f4 vsqrtsh %xmm28,%xmm29,%xmm30"}, + // The scalar scale and exponent extracts, EVEX.NDS.LIG.66.MAP6.W0. + {"vscalefsh", "VSCALEFSH", + []ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)}, + "620615002df4", "62 06 15 00 2d f4 vscalefsh %xmm28,%xmm29,%xmm30"}, + {"vgetexpsh", "VGETEXPSH", + []ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)}, + "6206150043f4", "62 06 15 00 43 f4 vgetexpsh %xmm28,%xmm29,%xmm30"}, + // The scalar compares take two operands, EVEX.LIG.MAP5.W0. {"vcomish", "VCOMISH", []ExtOperand{ExtXmm(29), ExtXmm(30)}, @@ -416,7 +424,7 @@ func TestAmd64ExtArchBinding(t *testing.T) { t.Errorf("Extensions(%s) carries %d instructions, want none", a, len(got)) } } - if got := Extensions(AMD64); len(got) != 46 { - t.Errorf("the amd64 layer registers %d instructions, want 46", len(got)) + if got := Extensions(AMD64); len(got) != 48 { + t.Errorf("the amd64 layer registers %d instructions, want 48", len(got)) } } diff --git a/asm/extension_amd64_test.go b/asm/extension_amd64_test.go index f15ba1e..92c579f 100644 --- a/asm/extension_amd64_test.go +++ b/asm/extension_amd64_test.go @@ -35,6 +35,8 @@ func TestAmd64ExtensionRegistry(t *testing.T) { {"VCVTSH2SI", 2}, {"VADDPH", 1}, {"VSQRTPH", 1}, + {"VSCALEFSH", 1}, + {"VGETEXPSH", 1}, } { cands, ok := LookupExtension(arch.AMD64, tt.mnem) if !ok { @@ -48,8 +50,8 @@ func TestAmd64ExtensionRegistry(t *testing.T) { t.Errorf("the %s lookup is not case-insensitive", tt.mnem) } } - if got := arch.Extensions(arch.AMD64); len(got) != 46 { - t.Errorf("the amd64 layer registers %d instructions, want 46", len(got)) + if got := arch.Extensions(arch.AMD64); len(got) != 48 { + t.Errorf("the amd64 layer registers %d instructions, want 48", len(got)) } if _, ok := LookupExtension(arch.AMD64, "NOSUCHINSTR"); ok { t.Error("a non-extended mnemonic resolved")