--- 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);
+
+ }
}