Skip to content

Commit 756791b

Browse files
Automatic merge of master into galahad
2 parents 97e9eed + 45f3ed3 commit 756791b

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.lir.amd64.vector;
26+
27+
import jdk.graal.compiler.asm.amd64.AMD64Address;
28+
import jdk.graal.compiler.asm.amd64.AMD64Assembler;
29+
import jdk.graal.compiler.asm.amd64.AMD64Assembler.VexFloatCompareOp;
30+
import jdk.graal.compiler.asm.amd64.AMD64Assembler.VexIntegerCompareOp;
31+
import jdk.graal.compiler.asm.amd64.AMD64Assembler.VexOp;
32+
import jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRMOp;
33+
import jdk.graal.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
34+
import jdk.graal.compiler.asm.amd64.AMD64MacroAssembler;
35+
import jdk.graal.compiler.asm.amd64.AVXKind;
36+
import jdk.graal.compiler.debug.GraalError;
37+
import jdk.graal.compiler.lir.LIRInstructionClass;
38+
import jdk.graal.compiler.lir.Opcode;
39+
import jdk.graal.compiler.lir.asm.CompilationResultBuilder;
40+
import jdk.vm.ci.meta.AllocatableValue;
41+
42+
import static jdk.graal.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B0;
43+
import static jdk.graal.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z0;
44+
import static jdk.graal.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z1;
45+
import static jdk.vm.ci.code.ValueUtil.asRegister;
46+
import static jdk.vm.ci.code.ValueUtil.isRegister;
47+
48+
/**
49+
* Masked operations from AVX512, they are in the form {@code op dst{mask}, src...}. E.g.
50+
* {@code vpaddd zmm0{k1}, zmm1, zmm2} adds dword elements from {@code zmm1} and {@code zmm2}. The
51+
* results are put into {@code zmm0} for each element at which the corresponding element in
52+
* {@code k1} is set. The elements at which the corresponding element in {@code k1} is unset are
53+
* unchanged by the operation; if {@code {z}} is additionally specified, those elements will be
54+
* cleared.
55+
*/
56+
public class AVX512MaskedOp {
57+
58+
/**
59+
* Merge-masking operations, the elements not selected by {@code mask} are taken from {@code
60+
* background}.
61+
*/
62+
public static class AVX512MaskedMergeOp extends AMD64VectorInstruction {
63+
public static final LIRInstructionClass<AVX512MaskedMergeOp> TYPE = LIRInstructionClass.create(AVX512MaskedMergeOp.class);
64+
65+
@Opcode private final VexOp op;
66+
@Def protected AllocatableValue result;
67+
@Use({OperandFlag.REG, OperandFlag.HINT}) protected AllocatableValue background;
68+
@Alive(OperandFlag.REG) protected AllocatableValue mask;
69+
@Alive({OperandFlag.REG, OperandFlag.ILLEGAL}) AllocatableValue src1;
70+
@Alive({OperandFlag.REG, OperandFlag.STACK}) AllocatableValue src2;
71+
72+
public AVX512MaskedMergeOp(VexOp op, AVXKind.AVXSize avxSize, AllocatableValue result, AllocatableValue background, AllocatableValue mask, AllocatableValue src1, AllocatableValue src2) {
73+
super(TYPE, avxSize);
74+
this.op = op;
75+
this.result = result;
76+
this.background = background;
77+
this.mask = mask;
78+
this.src1 = src1;
79+
this.src2 = src2;
80+
}
81+
82+
@Override
83+
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
84+
new AMD64VectorMove.MoveToRegOp(result, background, AMD64Assembler.AMD64SIMDInstructionEncoding.EVEX).emitCode(crb, masm);
85+
if (isRegister(src2)) {
86+
switch (op) {
87+
case VexRMOp c -> c.emit(masm, size, asRegister(result), asRegister(src2), asRegister(mask), Z0, B0);
88+
case VexRVMOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(mask), Z0, B0);
89+
default -> throw GraalError.shouldNotReachHereUnexpectedValue(op);
90+
}
91+
} else {
92+
AMD64Address src2Address = (AMD64Address) crb.asAddress(src2);
93+
switch (op) {
94+
case VexRMOp c -> c.emit(masm, size, asRegister(result), src2Address, asRegister(mask), Z0, B0);
95+
case VexRVMOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), src2Address, asRegister(mask), Z0, B0);
96+
default -> throw GraalError.shouldNotReachHereUnexpectedValue(op);
97+
}
98+
}
99+
}
100+
}
101+
102+
/**
103+
* Zero-masking operations, the unset elements in {@code mask} are cleared.
104+
*/
105+
public static class AVX512MaskedZeroOp extends AMD64VectorInstruction {
106+
public static final LIRInstructionClass<AVX512MaskedZeroOp> TYPE = LIRInstructionClass.create(AVX512MaskedZeroOp.class);
107+
108+
@Opcode private final VexOp op;
109+
// Predicate for comparisons
110+
private final Object predicate;
111+
@Def protected AllocatableValue result;
112+
@Use protected AllocatableValue mask;
113+
@Use({OperandFlag.REG, OperandFlag.ILLEGAL}) AllocatableValue src1;
114+
@Use({OperandFlag.REG, OperandFlag.STACK}) AllocatableValue src2;
115+
116+
public AVX512MaskedZeroOp(VexOp op, Object predicate, AVXKind.AVXSize avxSize, AllocatableValue result, AllocatableValue mask, AllocatableValue src1, AllocatableValue src2) {
117+
super(TYPE, avxSize);
118+
this.op = op;
119+
this.predicate = predicate;
120+
this.result = result;
121+
this.mask = mask;
122+
this.src1 = src1;
123+
this.src2 = src2;
124+
}
125+
126+
@Override
127+
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
128+
if (isRegister(src2)) {
129+
switch (op) {
130+
case VexRMOp c -> c.emit(masm, size, asRegister(result), asRegister(src2), asRegister(mask), Z1, B0);
131+
case VexRVMOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(mask), Z1, B0);
132+
case VexIntegerCompareOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(mask), (VexIntegerCompareOp.Predicate) predicate);
133+
case VexFloatCompareOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(mask), (VexFloatCompareOp.Predicate) predicate);
134+
default -> throw GraalError.shouldNotReachHereUnexpectedValue(op);
135+
}
136+
} else {
137+
AMD64Address src2Address = (AMD64Address) crb.asAddress(src2);
138+
switch (op) {
139+
case VexRMOp c -> c.emit(masm, size, asRegister(result), src2Address, asRegister(mask), Z1, B0);
140+
case VexRVMOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), src2Address, asRegister(mask), Z1, B0);
141+
case VexIntegerCompareOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), src2Address, asRegister(mask), (VexIntegerCompareOp.Predicate) predicate, B0);
142+
case VexFloatCompareOp c -> c.emit(masm, size, asRegister(result), asRegister(src1), src2Address, asRegister(mask), (VexFloatCompareOp.Predicate) predicate, B0);
143+
default -> throw GraalError.shouldNotReachHereUnexpectedValue(op);
144+
}
145+
}
146+
}
147+
}
148+
}

0 commit comments

Comments
 (0)