< prev index next >

src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java

Print this page




   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 jdk.vm.ci.amd64;
  24 
  25 import static jdk.vm.ci.code.MemoryBarriers.*;
  26 import static jdk.vm.ci.code.Register.*;

  27 
  28 import java.nio.*;
  29 import java.util.*;
  30 
  31 import jdk.vm.ci.code.*;

  32 import jdk.vm.ci.code.Register.RegisterCategory;
  33 import jdk.vm.ci.meta.*;

  34 
  35 /**
  36  * Represents the AMD64 architecture.
  37  */
  38 public class AMD64 extends Architecture {
  39 
  40     public static final RegisterCategory CPU = new RegisterCategory("CPU");
  41 
  42     // @formatter:off
  43 
  44     // General purpose CPU registers
  45     public static final Register rax = new Register(0, 0, "rax", CPU);
  46     public static final Register rcx = new Register(1, 1, "rcx", CPU);
  47     public static final Register rdx = new Register(2, 2, "rdx", CPU);
  48     public static final Register rbx = new Register(3, 3, "rbx", CPU);
  49     public static final Register rsp = new Register(4, 4, "rsp", CPU);
  50     public static final Register rbp = new Register(5, 5, "rbp", CPU);
  51     public static final Register rsi = new Register(6, 6, "rsi", CPU);
  52     public static final Register rdi = new Register(7, 7, "rdi", CPU);
  53 
  54     public static final Register r8  = new Register(8,  8,  "r8", CPU);
  55     public static final Register r9  = new Register(9,  9,  "r9", CPU);
  56     public static final Register r10 = new Register(10, 10, "r10", CPU);
  57     public static final Register r11 = new Register(11, 11, "r11", CPU);
  58     public static final Register r12 = new Register(12, 12, "r12", CPU);
  59     public static final Register r13 = new Register(13, 13, "r13", CPU);
  60     public static final Register r14 = new Register(14, 14, "r14", CPU);
  61     public static final Register r15 = new Register(15, 15, "r15", CPU);
  62 
  63     public static final Register[] cpuRegisters = {
  64         rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
  65         r8, r9, r10, r11, r12, r13, r14, r15
  66     };
  67 
  68     private static final int XMM_REFERENCE_MAP_SHIFT = 2;
  69 
  70     public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT);
  71 
  72     // XMM registers
  73     public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
  74     public static final Register xmm1 = new Register(17, 1, "xmm1", XMM);
  75     public static final Register xmm2 = new Register(18, 2, "xmm2", XMM);
  76     public static final Register xmm3 = new Register(19, 3, "xmm3", XMM);
  77     public static final Register xmm4 = new Register(20, 4, "xmm4", XMM);
  78     public static final Register xmm5 = new Register(21, 5, "xmm5", XMM);
  79     public static final Register xmm6 = new Register(22, 6, "xmm6", XMM);
  80     public static final Register xmm7 = new Register(23, 7, "xmm7", XMM);
  81 
  82     public static final Register xmm8 =  new Register(24,  8, "xmm8",  XMM);
  83     public static final Register xmm9 =  new Register(25,  9, "xmm9",  XMM);
  84     public static final Register xmm10 = new Register(26, 10, "xmm10", XMM);
  85     public static final Register xmm11 = new Register(27, 11, "xmm11", XMM);
  86     public static final Register xmm12 = new Register(28, 12, "xmm12", XMM);
  87     public static final Register xmm13 = new Register(29, 13, "xmm13", XMM);
  88     public static final Register xmm14 = new Register(30, 14, "xmm14", XMM);
  89     public static final Register xmm15 = new Register(31, 15, "xmm15", XMM);
  90 
  91     public static final Register[] xmmRegisters = {


















  92         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
  93         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
  94     };
  95 
  96     public static final Register[] cpuxmmRegisters = {


















  97         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
  98         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
  99         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 100         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
 101     };
 102 










 103     /**
 104      * Register used to construct an instruction-relative address.
 105      */
 106     public static final Register rip = new Register(32, -1, "rip", SPECIAL);
 107 
 108     public static final Register[] allRegisters = {
 109         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
 110         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
 111         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 112         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,



 113         rip
 114     };
 115 
 116     // @formatter:on
 117 
 118     /**
 119      * Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
 120      * {@code VM_Version::cpuFeatureFlags}.
 121      */
 122     public static enum CPUFeature {
 123         CX8,
 124         CMOV,
 125         FXSR,
 126         HT,
 127         MMX,
 128         AMD_3DNOW_PREFETCH,
 129         SSE,
 130         SSE2,
 131         SSE3,
 132         SSSE3,


 134         SSE4_1,
 135         SSE4_2,
 136         POPCNT,
 137         LZCNT,
 138         TSC,
 139         TSCINV,
 140         AVX,
 141         AVX2,
 142         AES,
 143         ERMS,
 144         CLMUL,
 145         BMI1,
 146         BMI2,
 147         RTM,
 148         ADX,
 149         AVX512F,
 150         AVX512DQ,
 151         AVX512PF,
 152         AVX512ER,
 153         AVX512CD,
 154         AVX512BW

 155     }
 156 
 157     private final EnumSet<CPUFeature> features;
 158 
 159     /**
 160      * Set of flags to control code emission.
 161      */
 162     public static enum Flag {
 163         UseCountLeadingZerosInstruction,
 164         UseCountTrailingZerosInstruction
 165     }
 166 
 167     private final EnumSet<Flag> flags;
 168 


 169     public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
 170         super("AMD64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + (xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT), 8);
 171         this.features = features;
 172         this.flags = flags;
 173         assert features.contains(CPUFeature.SSE2) : "minimum config for x64";








 174     }
 175 
 176     public EnumSet<CPUFeature> getFeatures() {
 177         return features;
 178     }
 179 
 180     public EnumSet<Flag> getFlags() {
 181         return flags;
 182     }
 183 
 184     @Override
 185     public PlatformKind getPlatformKind(JavaKind javaKind) {
 186         if (javaKind.isObject()) {
 187             return getWordKind();
 188         } else {
 189             return javaKind;
 190         }
 191     }
 192 
 193     @Override
 194     public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
 195         if (!(platformKind instanceof JavaKind)) {
 196             return false;
 197         }
 198 
 199         JavaKind kind = (JavaKind) platformKind;
 200         if (category.equals(CPU)) {
 201             switch (kind) {
 202                 case Boolean:
 203                 case Byte:
 204                 case Char:
 205                 case Short:


 206                 case Int:

 207                 case Long:
 208                     return true;
 209             }
 210         } else if (category.equals(XMM)) {
 211             switch (kind) {
 212                 case Float:

 213                 case Double:
 214                     return true;


 215             }
 216         }
 217 
 218         return false;










 219     }
 220 
 221     @Override
 222     public PlatformKind getLargestStorableKind(RegisterCategory category) {
 223         if (category.equals(CPU)) {
 224             return JavaKind.Long;
 225         } else if (category.equals(XMM)) {
 226             return JavaKind.Double;


 227         } else {
 228             return JavaKind.Illegal;
 229         }
 230     }
 231 }


   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 jdk.vm.ci.amd64;
  24 
  25 import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
  26 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
  27 import static jdk.vm.ci.code.Register.SPECIAL;
  28 
  29 import java.nio.ByteOrder;
  30 import java.util.EnumSet;
  31 
  32 import jdk.vm.ci.code.Architecture;
  33 import jdk.vm.ci.code.Register;
  34 import jdk.vm.ci.code.Register.RegisterCategory;
  35 import jdk.vm.ci.meta.JavaKind;
  36 import jdk.vm.ci.meta.PlatformKind;
  37 
  38 /**
  39  * Represents the AMD64 architecture.
  40  */
  41 public class AMD64 extends Architecture {
  42 
  43     public static final RegisterCategory CPU = new RegisterCategory("CPU");
  44 
  45     // @formatter:off
  46 
  47     // General purpose CPU registers
  48     public static final Register rax = new Register(0, 0, "rax", CPU);
  49     public static final Register rcx = new Register(1, 1, "rcx", CPU);
  50     public static final Register rdx = new Register(2, 2, "rdx", CPU);
  51     public static final Register rbx = new Register(3, 3, "rbx", CPU);
  52     public static final Register rsp = new Register(4, 4, "rsp", CPU);
  53     public static final Register rbp = new Register(5, 5, "rbp", CPU);
  54     public static final Register rsi = new Register(6, 6, "rsi", CPU);
  55     public static final Register rdi = new Register(7, 7, "rdi", CPU);
  56 
  57     public static final Register r8  = new Register(8,  8,  "r8", CPU);
  58     public static final Register r9  = new Register(9,  9,  "r9", CPU);
  59     public static final Register r10 = new Register(10, 10, "r10", CPU);
  60     public static final Register r11 = new Register(11, 11, "r11", CPU);
  61     public static final Register r12 = new Register(12, 12, "r12", CPU);
  62     public static final Register r13 = new Register(13, 13, "r13", CPU);
  63     public static final Register r14 = new Register(14, 14, "r14", CPU);
  64     public static final Register r15 = new Register(15, 15, "r15", CPU);
  65 
  66     public static final Register[] cpuRegisters = {
  67         rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
  68         r8, r9, r10, r11, r12, r13, r14, r15
  69     };
  70 
  71     public static final RegisterCategory XMM = new RegisterCategory("XMM");


  72 
  73     // XMM registers
  74     public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
  75     public static final Register xmm1 = new Register(17, 1, "xmm1", XMM);
  76     public static final Register xmm2 = new Register(18, 2, "xmm2", XMM);
  77     public static final Register xmm3 = new Register(19, 3, "xmm3", XMM);
  78     public static final Register xmm4 = new Register(20, 4, "xmm4", XMM);
  79     public static final Register xmm5 = new Register(21, 5, "xmm5", XMM);
  80     public static final Register xmm6 = new Register(22, 6, "xmm6", XMM);
  81     public static final Register xmm7 = new Register(23, 7, "xmm7", XMM);
  82 
  83     public static final Register xmm8  = new Register(24,  8, "xmm8",  XMM);
  84     public static final Register xmm9  = new Register(25,  9, "xmm9",  XMM);
  85     public static final Register xmm10 = new Register(26, 10, "xmm10", XMM);
  86     public static final Register xmm11 = new Register(27, 11, "xmm11", XMM);
  87     public static final Register xmm12 = new Register(28, 12, "xmm12", XMM);
  88     public static final Register xmm13 = new Register(29, 13, "xmm13", XMM);
  89     public static final Register xmm14 = new Register(30, 14, "xmm14", XMM);
  90     public static final Register xmm15 = new Register(31, 15, "xmm15", XMM);
  91 
  92     public static final Register xmm16 = new Register(32, 16, "xmm16", XMM);
  93     public static final Register xmm17 = new Register(33, 17, "xmm17", XMM);
  94     public static final Register xmm18 = new Register(34, 18, "xmm18", XMM);
  95     public static final Register xmm19 = new Register(35, 19, "xmm19", XMM);
  96     public static final Register xmm20 = new Register(36, 20, "xmm20", XMM);
  97     public static final Register xmm21 = new Register(37, 21, "xmm21", XMM);
  98     public static final Register xmm22 = new Register(38, 22, "xmm22", XMM);
  99     public static final Register xmm23 = new Register(39, 23, "xmm23", XMM);
 100 
 101     public static final Register xmm24 = new Register(40, 24, "xmm24", XMM);
 102     public static final Register xmm25 = new Register(41, 25, "xmm25", XMM);
 103     public static final Register xmm26 = new Register(42, 26, "xmm26", XMM);
 104     public static final Register xmm27 = new Register(43, 27, "xmm27", XMM);
 105     public static final Register xmm28 = new Register(44, 28, "xmm28", XMM);
 106     public static final Register xmm29 = new Register(45, 29, "xmm29", XMM);
 107     public static final Register xmm30 = new Register(46, 30, "xmm30", XMM);
 108     public static final Register xmm31 = new Register(47, 31, "xmm31", XMM);
 109 
 110     public static final Register[] xmmRegistersSSE = {
 111         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 112         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
 113     };
 114 
 115     public static final Register[] xmmRegistersAVX512 = {
 116         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 117         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
 118         xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
 119         xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31
 120     };
 121 
 122     public static final RegisterCategory MASK = new RegisterCategory("MASK", false);
 123 
 124     public static final Register k0 = new Register(48, 0, "k0", MASK);
 125     public static final Register k1 = new Register(49, 1, "k1", MASK);
 126     public static final Register k2 = new Register(50, 2, "k2", MASK);
 127     public static final Register k3 = new Register(51, 3, "k3", MASK);
 128     public static final Register k4 = new Register(52, 4, "k4", MASK);
 129     public static final Register k5 = new Register(53, 5, "k5", MASK);
 130     public static final Register k6 = new Register(54, 6, "k6", MASK);
 131     public static final Register k7 = new Register(55, 7, "k7", MASK);
 132 
 133     public static final Register[] valueRegistersSSE = {
 134         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
 135         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
 136         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 137         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
 138     };
 139 
 140     public static final Register[] valueRegistersAVX512 = {
 141         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
 142         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
 143         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 144         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
 145         xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
 146         xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
 147         k0, k1, k2, k3, k4, k5, k6, k7
 148     };
 149 
 150     /**
 151      * Register used to construct an instruction-relative address.
 152      */
 153     public static final Register rip = new Register(56, -1, "rip", SPECIAL);
 154 
 155     public static final Register[] allRegisters = {
 156         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
 157         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
 158         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
 159         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
 160         xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
 161         xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
 162         k0, k1, k2, k3, k4, k5, k6, k7,
 163         rip
 164     };
 165 
 166     // @formatter:on
 167 
 168     /**
 169      * Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
 170      * {@code VM_Version::cpuFeatureFlags}.
 171      */
 172     public static enum CPUFeature {
 173         CX8,
 174         CMOV,
 175         FXSR,
 176         HT,
 177         MMX,
 178         AMD_3DNOW_PREFETCH,
 179         SSE,
 180         SSE2,
 181         SSE3,
 182         SSSE3,


 184         SSE4_1,
 185         SSE4_2,
 186         POPCNT,
 187         LZCNT,
 188         TSC,
 189         TSCINV,
 190         AVX,
 191         AVX2,
 192         AES,
 193         ERMS,
 194         CLMUL,
 195         BMI1,
 196         BMI2,
 197         RTM,
 198         ADX,
 199         AVX512F,
 200         AVX512DQ,
 201         AVX512PF,
 202         AVX512ER,
 203         AVX512CD,
 204         AVX512BW,
 205         AVX512VL
 206     }
 207 
 208     private final EnumSet<CPUFeature> features;
 209 
 210     /**
 211      * Set of flags to control code emission.
 212      */
 213     public static enum Flag {
 214         UseCountLeadingZerosInstruction,
 215         UseCountTrailingZerosInstruction
 216     }
 217 
 218     private final EnumSet<Flag> flags;
 219 
 220     private final AMD64Kind largestKind;
 221 
 222     public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
 223         super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, 8);
 224         this.features = features;
 225         this.flags = flags;
 226         assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
 227 
 228         if (features.contains(CPUFeature.AVX512F)) {
 229             largestKind = AMD64Kind.V512_QWORD;
 230         } else if (features.contains(CPUFeature.AVX)) {
 231             largestKind = AMD64Kind.V256_QWORD;
 232         } else {
 233             largestKind = AMD64Kind.V128_QWORD;
 234         }
 235     }
 236 
 237     public EnumSet<CPUFeature> getFeatures() {
 238         return features;
 239     }
 240 
 241     public EnumSet<Flag> getFlags() {
 242         return flags;
 243     }
 244 
 245     @Override
 246     public Register[] getAvailableValueRegisters() {
 247         if (features.contains(CPUFeature.AVX512F)) {
 248             return valueRegistersAVX512;
 249         } else {
 250             return valueRegistersSSE;
 251         }
 252     }
 253 
 254     @Override
 255     public PlatformKind getPlatformKind(JavaKind javaKind) {
 256         switch (javaKind) {






 257             case Boolean:
 258             case Byte:
 259                 return AMD64Kind.BYTE;
 260             case Short:
 261             case Char:
 262                 return AMD64Kind.WORD;
 263             case Int:
 264                 return AMD64Kind.DWORD;
 265             case Long:
 266             case Object:
 267                 return AMD64Kind.QWORD;


 268             case Float:
 269                 return AMD64Kind.SINGLE;
 270             case Double:
 271                 return AMD64Kind.DOUBLE;
 272             default:
 273                 return null;
 274         }
 275     }
 276 
 277     @Override
 278     public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
 279         AMD64Kind kind = (AMD64Kind) platformKind;
 280         if (kind.isInteger()) {
 281             return category.equals(CPU);
 282         } else if (kind.isXMM()) {
 283             return category.equals(XMM);
 284         } else {
 285             assert kind.isMask();
 286             return category.equals(MASK);
 287         }
 288     }
 289 
 290     @Override
 291     public AMD64Kind getLargestStorableKind(RegisterCategory category) {
 292         if (category.equals(CPU)) {
 293             return AMD64Kind.QWORD;
 294         } else if (category.equals(XMM)) {
 295             return largestKind;
 296         } else if (category.equals(MASK)) {
 297             return AMD64Kind.MASK64;
 298         } else {
 299             return null;
 300         }
 301     }
 302 }
< prev index next >