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  */
  23 package org.graalvm.compiler.asm.amd64;
  24 
  25 import jdk.vm.ci.amd64.AMD64;
  26 import jdk.vm.ci.amd64.AMD64.CPUFeature;
  27 import jdk.vm.ci.code.TargetDescription;
  28 
  29 /**
  30  * Attributes for instructions for SSE through EVEX, also including address components.
  31  */
  32 public 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 }