Skip to content

Commit dbcc75e

Browse files
committed
[GR-60769] Prepare assembler supports for masked operations
PullRequest: graal/19718
2 parents 45f3c25 + e9da62d commit dbcc75e

File tree

3 files changed

+96
-19
lines changed

3 files changed

+96
-19
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -2276,10 +2276,10 @@ public static class VexRVMOp extends VexOp {
22762276
public static final VexRVMOp VPACKSSWB = new VexRVMOp("VPACKSSWB", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0x63, VEXOpAssertion.AVX1_AVX2_AVX512BW_VL, EVEXTuple.FVM, VEXPrefixConfig.WIG);
22772277
public static final VexRVMOp VADDSUBPS = new VexRVMOp("VADDSUBPS", VEXPrefixConfig.P_F2, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xD0, VEXOpAssertion.AVX1);
22782278
public static final VexRVMOp VADDSUBPD = new VexRVMOp("VADDSUBPD", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xD0, VEXOpAssertion.AVX1);
2279-
public static final VexRVMOp VPAND = new VexRVMOp("VPAND", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xDB, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1);
2280-
public static final VexRVMOp VPANDN = new VexRVMOp("VPANDN", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xDF, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1);
2281-
public static final VexRVMOp VPOR = new VexRVMOp("VPOR", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xEB, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1);
2282-
public static final VexRVMOp VPXOR = new VexRVMOp("VPXOR", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xEF, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1);
2279+
public static final VexRVMOp VPAND = new VexRVMOp("VPAND", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xDB, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W0);
2280+
public static final VexRVMOp VPANDN = new VexRVMOp("VPANDN", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xDF, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W0);
2281+
public static final VexRVMOp VPOR = new VexRVMOp("VPOR", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xEB, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W0);
2282+
public static final VexRVMOp VPXOR = new VexRVMOp("VPXOR", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xEF, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W0);
22832283
public static final VexRVMOp VPADDB = new VexRVMOp("VPADDB", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xFC, VEXOpAssertion.AVX1_AVX2_AVX512BW_VL, EVEXTuple.FVM, VEXPrefixConfig.WIG);
22842284
public static final VexRVMOp VPADDW = new VexRVMOp("VPADDW", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xFD, VEXOpAssertion.AVX1_AVX2_AVX512BW_VL, EVEXTuple.FVM, VEXPrefixConfig.WIG);
22852285
public static final VexRVMOp VPADDD = new VexRVMOp("VPADDD", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xFE, VEXOpAssertion.AVX1_AVX2_AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W0);
@@ -2375,10 +2375,14 @@ public static class VexRVMOp extends VexOp {
23752375
public static final VexRVMOp EVMAXSD = new VexRVMOp("EVMAXSD", VMAXSD);
23762376
public static final VexRVMOp EVPACKUSDW = new VexRVMOp("EVPACKUSDW", VPACKUSDW);
23772377
public static final VexRVMOp EVPACKUSWB = new VexRVMOp("EVPACKUSWB", VPACKUSWB);
2378-
public static final VexRVMOp EVPAND = new VexRVMOp("EVPAND", VPAND);
2379-
public static final VexRVMOp EVPANDN = new VexRVMOp("EVPANDN", VPANDN);
2380-
public static final VexRVMOp EVPOR = new VexRVMOp("EVPOR", VPOR);
2381-
public static final VexRVMOp EVPXOR = new VexRVMOp("EVPXOR", VPXOR);
2378+
public static final VexRVMOp EVPANDD = new VexRVMOp("EVPANDD", VPAND);
2379+
public static final VexRVMOp EVPANDQ = new VexRVMOp("EVPANDQ", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xDB, VEXOpAssertion.AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1, true);
2380+
public static final VexRVMOp EVPANDND = new VexRVMOp("EVPANDND", VPANDN);
2381+
public static final VexRVMOp EVPANDNQ = new VexRVMOp("EVPANDNQ", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xDF, VEXOpAssertion.AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1, true);
2382+
public static final VexRVMOp EVPORD = new VexRVMOp("EVPORD", VPOR);
2383+
public static final VexRVMOp EVPORQ = new VexRVMOp("EVPORQ", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xEB, VEXOpAssertion.AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1, true);
2384+
public static final VexRVMOp EVPXORD = new VexRVMOp("EVPXORD", VPXOR);
2385+
public static final VexRVMOp EVPXORQ = new VexRVMOp("EVPXORQ", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F, VEXPrefixConfig.WIG, 0xEF, VEXOpAssertion.AVX512F_VL, EVEXTuple.FVM, VEXPrefixConfig.W1, true);
23822386
public static final VexRVMOp EVPADDB = new VexRVMOp("EVPADDB", VPADDB);
23832387
public static final VexRVMOp EVPADDW = new VexRVMOp("EVPADDW", VPADDW);
23842388
public static final VexRVMOp EVPADDD = new VexRVMOp("EVPADDD", VPADDD);
@@ -3145,6 +3149,71 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1,
31453149
}
31463150
}
31473151

3152+
/**
3153+
* VEX-encoded comparison operation with an operand order of RVMI. The immediate operand is a
3154+
* comparison operator.
3155+
*/
3156+
public static final class VexIntegerCompareOp extends VexOp {
3157+
// @formatter:off
3158+
public static final VexIntegerCompareOp EVPCMPB = new VexIntegerCompareOp("EVPCMPB", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W0, 0x3F, VEXOpAssertion.MASK_XMM_XMM_AVX512BW_VL, EVEXTuple.FVM);
3159+
public static final VexIntegerCompareOp EVPCMPW = new VexIntegerCompareOp("EVPCMPW", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W1, 0x3F, VEXOpAssertion.MASK_XMM_XMM_AVX512BW_VL, EVEXTuple.FVM);
3160+
public static final VexIntegerCompareOp EVPCMPD = new VexIntegerCompareOp("EVPCMPD", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W0, 0x1F, VEXOpAssertion.MASK_XMM_XMM_AVX512F_VL, EVEXTuple.FVM);
3161+
public static final VexIntegerCompareOp EVPCMPQ = new VexIntegerCompareOp("EVPCMPQ", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W1, 0x1F, VEXOpAssertion.MASK_XMM_XMM_AVX512F_VL, EVEXTuple.FVM);
3162+
3163+
public static final VexIntegerCompareOp EVPCMPUB = new VexIntegerCompareOp("EVPCMPUB", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W0, 0x3E, VEXOpAssertion.MASK_XMM_XMM_AVX512BW_VL, EVEXTuple.FVM);
3164+
public static final VexIntegerCompareOp EVPCMPUW = new VexIntegerCompareOp("EVPCMPUW", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W1, 0x3E, VEXOpAssertion.MASK_XMM_XMM_AVX512BW_VL, EVEXTuple.FVM);
3165+
public static final VexIntegerCompareOp EVPCMPUD = new VexIntegerCompareOp("EVPCMPUD", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W0, 0x1E, VEXOpAssertion.MASK_XMM_XMM_AVX512F_VL, EVEXTuple.FVM);
3166+
public static final VexIntegerCompareOp EVPCMPUQ = new VexIntegerCompareOp("EVPCMPUQ", VEXPrefixConfig.P_66, VEXPrefixConfig.M_0F3A, VEXPrefixConfig.W1, 0x1E, VEXOpAssertion.MASK_XMM_XMM_AVX512F_VL, EVEXTuple.FVM);
3167+
// @formatter:on
3168+
3169+
public enum Predicate {
3170+
EQ(0),
3171+
LT(1),
3172+
LE(2),
3173+
FALSE(3),
3174+
NEQ(4),
3175+
NLT(5),
3176+
NLE(6),
3177+
TRUE(7);
3178+
3179+
private int imm8;
3180+
3181+
Predicate(int imm8) {
3182+
this.imm8 = imm8;
3183+
}
3184+
3185+
public static Predicate getPredicate(Condition condition) {
3186+
return switch (condition) {
3187+
case EQ -> EQ;
3188+
case NE -> NEQ;
3189+
case LT, BT -> LT;
3190+
case LE, BE -> LE;
3191+
case GT, AT -> NLE;
3192+
case GE, AE -> NLT;
3193+
default -> throw GraalError.shouldNotReachHereUnexpectedValue(condition);
3194+
};
3195+
}
3196+
}
3197+
3198+
private VexIntegerCompareOp(String opcode, int pp, int mmmmm, int wEvex, int op, VEXOpAssertion assertion, EVEXTuple evexTuple) {
3199+
super(opcode, pp, mmmmm, wEvex, op, assertion, evexTuple, wEvex, true);
3200+
}
3201+
3202+
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, Register mask, Predicate p) {
3203+
emitVexOrEvex(asm, dst, src1, src2, mask, size, pp, mmmmm, w, wEvex, Z0, B0);
3204+
asm.emitByte(op);
3205+
asm.emitModRM(dst, src2);
3206+
asm.emitByte(p.imm8);
3207+
}
3208+
3209+
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Register mask, Predicate p, int b) {
3210+
emitVexOrEvex(asm, dst, src1, src2, mask, size, pp, mmmmm, w, wEvex, Z0, b);
3211+
asm.emitByte(op);
3212+
asm.emitOperandHelper(dst, src2, 1, getDisp8Scale(isEvex, size));
3213+
asm.emitByte(p.imm8);
3214+
}
3215+
}
3216+
31483217
/**
31493218
* VEX-encoded comparison operation with an operand order of RVMI. The immediate operand is a
31503219
* comparison operator.
@@ -3262,14 +3331,22 @@ public VexFloatCompareOp encoding(AMD64SIMDInstructionEncoding encoding) {
32623331
}
32633332

32643333
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, Predicate p) {
3265-
emitVexOrEvex(asm, dst, src1, src2, size, pp, mmmmm, w, wEvex);
3334+
emit(asm, size, dst, src1, src2, Register.None, p);
3335+
}
3336+
3337+
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Predicate p) {
3338+
emit(asm, size, dst, src1, src2, Register.None, p, B0);
3339+
}
3340+
3341+
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, Register mask, Predicate p) {
3342+
emitVexOrEvex(asm, dst, src1, src2, mask, size, pp, mmmmm, w, wEvex, Z0, B0);
32663343
asm.emitByte(op);
32673344
asm.emitModRM(dst, src2);
32683345
asm.emitByte(p.imm8);
32693346
}
32703347

3271-
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Predicate p) {
3272-
emitVexOrEvex(asm, dst, src1, src2, size, pp, mmmmm, w, wEvex);
3348+
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Register mask, Predicate p, int b) {
3349+
emitVexOrEvex(asm, dst, src1, src2, mask, size, pp, mmmmm, w, wEvex, Z0, b);
32733350
asm.emitByte(op);
32743351
asm.emitOperandHelper(dst, src2, 1, getDisp8Scale(isEvex, size));
32753352
asm.emitByte(p.imm8);
@@ -6199,6 +6276,6 @@ public final void evpternlogq(Register dst, int imm8, Register src1, Register sr
61996276
}
62006277

62016278
public final void evpxorq(Register dst, Register mask, Register nds, AMD64Address src) {
6202-
VexRVMOp.EVPXOR.emit(this, AVXSize.ZMM, dst, nds, src, mask);
6279+
VexRVMOp.EVPXORQ.emit(this, AVXSize.ZMM, dst, nds, src, mask);
62036280
}
62046281
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/amd64/AMD64CountPositivesOp.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
2626

2727
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRMVOp.SHLX;
2828
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRMOp.VPBROADCASTD;
29-
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.EVPXOR;
29+
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.EVPXORD;
3030
import static jdk.graal.compiler.asm.amd64.AVXKind.AVXSize.QWORD;
3131
import static jdk.graal.compiler.asm.amd64.AVXKind.AVXSize.YMM;
3232
import static jdk.graal.compiler.asm.amd64.AVXKind.AVXSize.ZMM;
@@ -144,7 +144,7 @@ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
144144
Register mask2 = asRegister(maskValue2);
145145

146146
masm.movl(tmp1, len);
147-
masm.emit(EVPXOR, vec2, vec2, vec2, ZMM);
147+
masm.emit(EVPXORD, vec2, vec2, vec2, ZMM);
148148
// tail count (in chars) 0x3
149149
masm.andl(tmp1, 0x0000003f);
150150
// vector count (in chars)

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/amd64/vector/AMD64VectorShuffle.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@
5656
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMIOp.VSHUFPS;
5757
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.EVPERMT2B;
5858
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.EVPSHUFB;
59-
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.EVPXOR;
59+
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.EVPXORD;
6060
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMOVHPD;
6161
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMOVLHPS;
6262
import static jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMOVLPD;
@@ -446,7 +446,7 @@ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
446446
int alignment = crb.dataBuilder.ensureValidDataAlignment(selectorData.length);
447447
AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(selectorData, alignment);
448448
EVMOVDQU64.emit(masm, AVXKind.getRegisterSize(kind), asRegister(selector), address);
449-
EVPXOR.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(result), asRegister(result));
449+
EVPXORD.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(result), asRegister(result));
450450
if (isRegister(source)) {
451451
EVPERMT2B.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(selector), asRegister(source), mask != null ? asRegister(mask) : Register.None,
452452
mask != null ? AMD64BaseAssembler.EVEXPrefixConfig.Z1 : AMD64BaseAssembler.EVEXPrefixConfig.Z0,

0 commit comments

Comments
 (0)