1/*
2 * Copyright (c) 2012, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.asm.amd64;
24
25import jdk.vm.ci.amd64.AMD64;
26import jdk.vm.ci.amd64.AMD64.CPUFeature;
27import jdk.vm.ci.code.TargetDescription;
28
29/**
30 * Attributes for instructions for SSE through EVEX, also including address components.
31 */
32public class AMD64InstructionAttr {
33    AMD64InstructionAttr(
34                    int inVectorLen,
35                    boolean inRexVexW,
36                    boolean inLegacyMode,
37                    boolean inNoRegMask,
38                    boolean inUsesVl,
39                    TargetDescription target) {
40        avxVectorLen = inVectorLen;
41        rexVexW = inRexVexW;
42        this.target = target;
43        legacyMode = (!supports(CPUFeature.AVX512F)) ? true : inLegacyMode;
44        noRegMask = inNoRegMask;
45        usesVl = inUsesVl;
46        rexVexWReverted = false;
47        tupleType = 0;
48        inputSizeInBits = 0;
49        isEvexInstruction = false;
50        evexEncoding = 0;
51        isClearContext = false;
52        isExtendedContext = false;
53    }
54
55    private TargetDescription target;
56    private int avxVectorLen;
57    private boolean rexVexW;
58    private boolean rexVexWReverted;
59    private boolean legacyMode;
60    private boolean noRegMask;
61    private boolean usesVl;
62    private int tupleType;
63    private int inputSizeInBits;
64    private boolean isEvexInstruction;
65    private int evexEncoding;
66    private boolean isClearContext;
67    private boolean isExtendedContext;
68
69    public int getVectorLen() {
70        return avxVectorLen;
71    }
72
73    public boolean isRexVexW() {
74        return rexVexW;
75    }
76
77    public boolean isRexVexWReverted() {
78        return rexVexWReverted;
79    }
80
81    public boolean isLegacyMode() {
82        return legacyMode;
83    }
84
85    public boolean isNoRegMask() {
86        return noRegMask;
87    }
88
89    public boolean usesVl() {
90        return usesVl;
91    }
92
93    public int getTupleType() {
94        return tupleType;
95    }
96
97    public int getInputSize() {
98        return inputSizeInBits;
99    }
100
101    public boolean isEvexInstruction() {
102        return isEvexInstruction;
103    }
104
105    public int getEvexEncoding() {
106        return evexEncoding;
107    }
108
109    public boolean isClearContext() {
110        return isClearContext;
111    }
112
113    public boolean isExtendedContext() {
114        return isExtendedContext;
115    }
116
117    /**
118     * Set the vector length of a given instruction.
119     *
120     * @param vectorLen
121     */
122    public void setVectorLen(int vectorLen) {
123        avxVectorLen = vectorLen;
124    }
125
126    /**
127     * In EVEX it is possible in blended code generation to revert the encoding width for AVX.
128     */
129    public void setRexVexWReverted() {
130        rexVexWReverted = true;
131    }
132
133    /**
134     * Alter the current encoding width.
135     *
136     * @param state
137     */
138    public void setRexVexW(boolean state) {
139        rexVexW = state;
140    }
141
142    /**
143     * Alter the current instructions legacy mode. Blended code generation will use this.
144     */
145    public void setLegacyMode() {
146        legacyMode = true;
147    }
148
149    /**
150     * During emit or during definition of an instruction, mark if it is EVEX.
151     */
152    public void setIsEvexInstruction() {
153        isEvexInstruction = true;
154    }
155
156    /**
157     * Set the current encoding attributes to be used in address calculations for EVEX.
158     *
159     * @param value
160     */
161    public void setEvexEncoding(int value) {
162        evexEncoding = value;
163    }
164
165    /**
166     * Use clear context for this instruction in EVEX, defaults is merge(false).
167     */
168    public void setIsClearContext() {
169        isClearContext = true;
170    }
171
172    /**
173     * Set the address attributes for configuring displacement calculations in EVEX.
174     */
175    public void setAddressAttributes(int inTupleType, int inInputSizeInBits) {
176        if (supports(CPUFeature.AVX512F)) {
177            tupleType = inTupleType;
178            inputSizeInBits = inInputSizeInBits;
179        }
180    }
181
182    private boolean supports(CPUFeature feature) {
183        return ((AMD64) target.arch).getFeatures().contains(feature);
184    }
185}
186