src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
changeset 49451 e06f9607f370
parent 48861 47f19ff9903c
child 50330 2cbc42a5764b
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Fri Mar 16 11:26:05 2018 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Fri Mar 16 22:59:32 2018 -0700
@@ -195,11 +195,6 @@
         private static final int VEX_W = 0x80;
     }
 
-    private static class AvxVectorLen {
-        private static final int AVX_128bit = 0x0;
-        private static final int AVX_256bit = 0x1;
-    }
-
     private static class VexSimdPrefix {
         private static final int VEX_SIMD_NONE = 0x0;
         private static final int VEX_SIMD_66 = 0x1;
@@ -208,11 +203,44 @@
     }
 
     private static class VexOpcode {
+        private static final int VEX_OPCODE_NONE = 0x0;
         private static final int VEX_OPCODE_0F = 0x1;
         private static final int VEX_OPCODE_0F_38 = 0x2;
         private static final int VEX_OPCODE_0F_3A = 0x3;
     }
 
+    public static class AvxVectorLen {
+        public static final int AVX_128bit = 0x0;
+        public static final int AVX_256bit = 0x1;
+        public static final int AVX_512bit = 0x2;
+        public static final int AVX_NoVec = 0x4;
+    }
+
+    public static class EvexTupleType {
+        public static final int EVEX_FV = 0;
+        public static final int EVEX_HV = 4;
+        public static final int EVEX_FVM = 6;
+        public static final int EVEX_T1S = 7;
+        public static final int EVEX_T1F = 11;
+        public static final int EVEX_T2 = 13;
+        public static final int EVEX_T4 = 15;
+        public static final int EVEX_T8 = 17;
+        public static final int EVEX_HVM = 18;
+        public static final int EVEX_QVM = 19;
+        public static final int EVEX_OVM = 20;
+        public static final int EVEX_M128 = 21;
+        public static final int EVEX_DUP = 22;
+        public static final int EVEX_ETUP = 23;
+    }
+
+    public static class EvexInputSizeInBits {
+        public static final int EVEX_8bit = 0;
+        public static final int EVEX_16bit = 1;
+        public static final int EVEX_32bit = 2;
+        public static final int EVEX_64bit = 3;
+        public static final int EVEX_NObit = 4;
+    }
+
     private AMD64InstructionAttr curAttributes;
 
     AMD64InstructionAttr getCurAttributes() {
@@ -873,6 +901,7 @@
                         opc = VexOpcode.VEX_OPCODE_0F_3A;
                         break;
                     default:
+                        opc = VexOpcode.VEX_OPCODE_NONE;
                         isSimd = false;
                         break;
                 }
@@ -1770,6 +1799,13 @@
         emitOperandHelper(dst, src, 0);
     }
 
+    public final void bsfq(Register dst, Register src) {
+        int encode = prefixqAndEncode(dst.encoding(), src.encoding());
+        emitByte(0x0F);
+        emitByte(0xBC);
+        emitByte(0xC0 | encode);
+    }
+
     public final void bsrl(Register dst, Register src) {
         int encode = prefixAndEncode(dst.encoding(), src.encoding());
         emitByte(0x0F);
@@ -1857,6 +1893,26 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void evmovdquq(Register dst, AMD64Address src, int vectorLen) {
+        assert supports(CPUFeature.AVX512F);
+        AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target);
+        attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+        attributes.setIsEvexInstruction();
+        vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes);
+        emitByte(0x6F);
+        emitOperandHelper(dst, src, 0);
+    }
+
+    public final void evpcmpeqb(Register kdst, Register nds, AMD64Address src, int vectorLen) {
+        assert supports(CPUFeature.AVX512BW);
+        AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+        attributes.setIsEvexInstruction();
+        attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+        vexPrefix(src, nds, kdst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes);
+        emitByte(0x74);
+        emitOperandHelper(kdst, src, 0);
+    }
+
     public final void hlt() {
         emitByte(0xF4);
     }
@@ -1982,6 +2038,32 @@
         }
     }
 
+    // This instruction produces ZF or CF flags
+    public final void kortestql(Register src1, Register src2) {
+        assert supports(CPUFeature.AVX512BW);
+        AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+        int encode = vexPrefixAndEncode(src1, Register.None, src2, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes);
+        emitByte(0x98);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void kmovql(Register dst, Register src) {
+        assert supports(CPUFeature.AVX512BW);
+        if (src.getRegisterCategory().equals(AMD64.MASK)) {
+            // kmovql(KRegister dst, KRegister src)
+            AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+            int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes);
+            emitByte(0x90);
+            emitByte(0xC0 | encode);
+        } else {
+            // kmovql(KRegister dst, Register src)
+            AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+            int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes);
+            emitByte(0x92);
+            emitByte(0xC0 | encode);
+        }
+    }
+
     public final void lead(Register dst, AMD64Address src) {
         prefix(src, dst);
         emitByte(0x8D);
@@ -2050,6 +2132,15 @@
         emitOperandHelper(dst, src, 0);
     }
 
+    /**
+     * @param wide use 4 byte encoding for displacements that would normally fit in a byte
+     */
+    public final void movl(Register dst, AMD64Address src, boolean wide) {
+        prefix(src, dst);
+        emitByte(0x8B);
+        emitOperandHelper(dst, src, wide, 0);
+    }
+
     public final void movl(AMD64Address dst, int imm32) {
         prefix(dst);
         emitByte(0xC7);
@@ -2291,6 +2382,10 @@
         NOT.emit(this, DWORD, dst);
     }
 
+    public final void notq(Register dst) {
+        NOT.emit(this, QWORD, dst);
+    }
+
     @Override
     public final void ensureUniquePC() {
         nop();
@@ -2540,7 +2635,7 @@
         emitByte(0xC0 | encode);
     }
 
-    void pcmpestri(Register dst, AMD64Address src, int imm8) {
+    public final void pcmpestri(Register dst, AMD64Address src, int imm8) {
         assert supports(CPUFeature.SSE4_2);
         AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target);
         simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes);
@@ -2549,7 +2644,7 @@
         emitByte(imm8);
     }
 
-    void pcmpestri(Register dst, Register src, int imm8) {
+    public final void pcmpestri(Register dst, Register src, int imm8) {
         assert supports(CPUFeature.SSE4_2);
         AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target);
         int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes);
@@ -2558,6 +2653,26 @@
         emitByte(imm8);
     }
 
+    public final void pmovzxbw(Register dst, AMD64Address src) {
+        assert supports(CPUFeature.SSE4_2);
+        // XXX legacy_mode should be: _legacy_mode_bw
+        AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+        attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+        simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes);
+        emitByte(0x30);
+        emitOperandHelper(dst, src, 0);
+    }
+
+    public final void vpmovzxbw(Register dst, AMD64Address src, int vectorLen) {
+        assert supports(CPUFeature.AVX);
+        // XXX legacy_mode should be: _legacy_mode_bw
+        AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+        attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+        vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes);
+        emitByte(0x30);
+        emitOperandHelper(dst, src, 0);
+    }
+
     public final void push(Register src) {
         int encode = prefixAndEncode(src.encoding);
         emitByte(0x50 | encode);
@@ -2634,6 +2749,15 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void vpxor(Register dst, Register nds, AMD64Address src) {
+        assert supports(CPUFeature.AVX);
+        AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target);
+        attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FV, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_32bit);
+        vexPrefix(src, nds, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes);
+        emitByte(0xEF);
+        emitOperandHelper(dst, src, 0);
+    }
+
     public final void pslld(Register dst, int imm8) {
         assert isUByte(imm8) : "invalid value";
         assert dst.getRegisterCategory().equals(AMD64.XMM);
@@ -3843,4 +3967,11 @@
         emitByte(0x0f);
         emitByte(0x0b);
     }
+
+    public void lfence() {
+        emitByte(0x0f);
+        emitByte(0xae);
+        emitByte(0xe8);
+
+    }
 }