1 /*
   2  * Copyright (c) 2013, 2019, 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 jdk.vm.ci.sparc;
  24 
  25 import static java.nio.ByteOrder.BIG_ENDIAN;
  26 import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
  27 import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
  28 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
  29 
  30 import java.util.Set;
  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.code.RegisterArray;
  36 import jdk.vm.ci.meta.JavaKind;
  37 import jdk.vm.ci.meta.PlatformKind;
  38 
  39 /**
  40  * Represents the SPARC architecture.
  41  */
  42 public class SPARC extends Architecture {
  43 
  44     public static final RegisterCategory CPU = new RegisterCategory("CPU");
  45     public static final RegisterCategory FPUs = new RegisterCategory("FPUs");
  46     public static final RegisterCategory FPUd = new RegisterCategory("FPUd");
  47     public static final RegisterCategory FPUq = new RegisterCategory("FPUq");
  48 
  49     // General purpose registers
  50     public static final Register g0 = new Register(0, 0, "g0", CPU);
  51     public static final Register g1 = new Register(1, 1, "g1", CPU);
  52     public static final Register g2 = new Register(2, 2, "g2", CPU);
  53     public static final Register g3 = new Register(3, 3, "g3", CPU);
  54     public static final Register g4 = new Register(4, 4, "g4", CPU);
  55     public static final Register g5 = new Register(5, 5, "g5", CPU);
  56     public static final Register g6 = new Register(6, 6, "g6", CPU);
  57     public static final Register g7 = new Register(7, 7, "g7", CPU);
  58 
  59     public static final Register o0 = new Register(8, 8, "o0", CPU);
  60     public static final Register o1 = new Register(9, 9, "o1", CPU);
  61     public static final Register o2 = new Register(10, 10, "o2", CPU);
  62     public static final Register o3 = new Register(11, 11, "o3", CPU);
  63     public static final Register o4 = new Register(12, 12, "o4", CPU);
  64     public static final Register o5 = new Register(13, 13, "o5", CPU);
  65     public static final Register o6 = new Register(14, 14, "o6", CPU);
  66     public static final Register o7 = new Register(15, 15, "o7", CPU);
  67 
  68     public static final Register l0 = new Register(16, 16, "l0", CPU);
  69     public static final Register l1 = new Register(17, 17, "l1", CPU);
  70     public static final Register l2 = new Register(18, 18, "l2", CPU);
  71     public static final Register l3 = new Register(19, 19, "l3", CPU);
  72     public static final Register l4 = new Register(20, 20, "l4", CPU);
  73     public static final Register l5 = new Register(21, 21, "l5", CPU);
  74     public static final Register l6 = new Register(22, 22, "l6", CPU);
  75     public static final Register l7 = new Register(23, 23, "l7", CPU);
  76 
  77     public static final Register i0 = new Register(24, 24, "i0", CPU);
  78     public static final Register i1 = new Register(25, 25, "i1", CPU);
  79     public static final Register i2 = new Register(26, 26, "i2", CPU);
  80     public static final Register i3 = new Register(27, 27, "i3", CPU);
  81     public static final Register i4 = new Register(28, 28, "i4", CPU);
  82     public static final Register i5 = new Register(29, 29, "i5", CPU);
  83     public static final Register i6 = new Register(30, 30, "i6", CPU);
  84     public static final Register i7 = new Register(31, 31, "i7", CPU);
  85 
  86     public static final Register sp = o6;
  87     public static final Register fp = i6;
  88 
  89     // Floating point registers
  90     public static final Register f0 = new Register(32, 0, "f0", FPUs);
  91     public static final Register f1 = new Register(33, 1, "f1", FPUs);
  92     public static final Register f2 = new Register(34, 2, "f2", FPUs);
  93     public static final Register f3 = new Register(35, 3, "f3", FPUs);
  94     public static final Register f4 = new Register(36, 4, "f4", FPUs);
  95     public static final Register f5 = new Register(37, 5, "f5", FPUs);
  96     public static final Register f6 = new Register(38, 6, "f6", FPUs);
  97     public static final Register f7 = new Register(39, 7, "f7", FPUs);
  98 
  99     public static final Register f8 = new Register(40, 8, "f8", FPUs);
 100     public static final Register f9 = new Register(41, 9, "f9", FPUs);
 101     public static final Register f10 = new Register(42, 10, "f10", FPUs);
 102     public static final Register f11 = new Register(43, 11, "f11", FPUs);
 103     public static final Register f12 = new Register(44, 12, "f12", FPUs);
 104     public static final Register f13 = new Register(45, 13, "f13", FPUs);
 105     public static final Register f14 = new Register(46, 14, "f14", FPUs);
 106     public static final Register f15 = new Register(47, 15, "f15", FPUs);
 107 
 108     public static final Register f16 = new Register(48, 16, "f16", FPUs);
 109     public static final Register f17 = new Register(49, 17, "f17", FPUs);
 110     public static final Register f18 = new Register(50, 18, "f18", FPUs);
 111     public static final Register f19 = new Register(51, 19, "f19", FPUs);
 112     public static final Register f20 = new Register(52, 20, "f20", FPUs);
 113     public static final Register f21 = new Register(53, 21, "f21", FPUs);
 114     public static final Register f22 = new Register(54, 22, "f22", FPUs);
 115     public static final Register f23 = new Register(55, 23, "f23", FPUs);
 116 
 117     public static final Register f24 = new Register(56, 24, "f24", FPUs);
 118     public static final Register f25 = new Register(57, 25, "f25", FPUs);
 119     public static final Register f26 = new Register(58, 26, "f26", FPUs);
 120     public static final Register f27 = new Register(59, 27, "f27", FPUs);
 121     public static final Register f28 = new Register(60, 28, "f28", FPUs);
 122     public static final Register f29 = new Register(61, 29, "f29", FPUs);
 123     public static final Register f30 = new Register(62, 30, "f30", FPUs);
 124     public static final Register f31 = new Register(63, 31, "f31", FPUs);
 125 
 126     // Double precision registers
 127     public static final Register d0 = new Register(64, getDoubleEncoding(0), "d0", FPUd);
 128     public static final Register d2 = new Register(65, getDoubleEncoding(2), "d2", FPUd);
 129     public static final Register d4 = new Register(66, getDoubleEncoding(4), "d4", FPUd);
 130     public static final Register d6 = new Register(67, getDoubleEncoding(6), "d6", FPUd);
 131     public static final Register d8 = new Register(68, getDoubleEncoding(8), "d8", FPUd);
 132     public static final Register d10 = new Register(69, getDoubleEncoding(10), "d10", FPUd);
 133     public static final Register d12 = new Register(70, getDoubleEncoding(12), "d12", FPUd);
 134     public static final Register d14 = new Register(71, getDoubleEncoding(14), "d14", FPUd);
 135 
 136     public static final Register d16 = new Register(72, getDoubleEncoding(16), "d16", FPUd);
 137     public static final Register d18 = new Register(73, getDoubleEncoding(18), "d18", FPUd);
 138     public static final Register d20 = new Register(74, getDoubleEncoding(20), "d20", FPUd);
 139     public static final Register d22 = new Register(75, getDoubleEncoding(22), "d22", FPUd);
 140     public static final Register d24 = new Register(76, getDoubleEncoding(24), "d24", FPUd);
 141     public static final Register d26 = new Register(77, getDoubleEncoding(26), "d26", FPUd);
 142     public static final Register d28 = new Register(78, getDoubleEncoding(28), "d28", FPUd);
 143     public static final Register d30 = new Register(79, getDoubleEncoding(28), "d28", FPUd);
 144 
 145     public static final Register d32 = new Register(80, getDoubleEncoding(32), "d32", FPUd);
 146     public static final Register d34 = new Register(81, getDoubleEncoding(34), "d34", FPUd);
 147     public static final Register d36 = new Register(82, getDoubleEncoding(36), "d36", FPUd);
 148     public static final Register d38 = new Register(83, getDoubleEncoding(38), "d38", FPUd);
 149     public static final Register d40 = new Register(84, getDoubleEncoding(40), "d40", FPUd);
 150     public static final Register d42 = new Register(85, getDoubleEncoding(42), "d42", FPUd);
 151     public static final Register d44 = new Register(86, getDoubleEncoding(44), "d44", FPUd);
 152     public static final Register d46 = new Register(87, getDoubleEncoding(46), "d46", FPUd);
 153 
 154     public static final Register d48 = new Register(88, getDoubleEncoding(48), "d48", FPUd);
 155     public static final Register d50 = new Register(89, getDoubleEncoding(50), "d50", FPUd);
 156     public static final Register d52 = new Register(90, getDoubleEncoding(52), "d52", FPUd);
 157     public static final Register d54 = new Register(91, getDoubleEncoding(54), "d54", FPUd);
 158     public static final Register d56 = new Register(92, getDoubleEncoding(56), "d56", FPUd);
 159     public static final Register d58 = new Register(93, getDoubleEncoding(58), "d58", FPUd);
 160     public static final Register d60 = new Register(94, getDoubleEncoding(60), "d60", FPUd);
 161     public static final Register d62 = new Register(95, getDoubleEncoding(62), "d62", FPUd);
 162 
 163     // Quad precision registers
 164     public static final Register q0 = new Register(96, getQuadncoding(0), "q0", FPUq);
 165     public static final Register q4 = new Register(97, getQuadncoding(4), "q4", FPUq);
 166     public static final Register q8 = new Register(98, getQuadncoding(8), "q8", FPUq);
 167     public static final Register q12 = new Register(99, getQuadncoding(12), "q12", FPUq);
 168     public static final Register q16 = new Register(100, getQuadncoding(16), "q16", FPUq);
 169     public static final Register q20 = new Register(101, getQuadncoding(20), "q20", FPUq);
 170     public static final Register q24 = new Register(102, getQuadncoding(24), "q24", FPUq);
 171     public static final Register q28 = new Register(103, getQuadncoding(28), "q28", FPUq);
 172 
 173     public static final Register q32 = new Register(104, getQuadncoding(32), "q32", FPUq);
 174     public static final Register q36 = new Register(105, getQuadncoding(36), "q36", FPUq);
 175     public static final Register q40 = new Register(106, getQuadncoding(40), "q40", FPUq);
 176     public static final Register q44 = new Register(107, getQuadncoding(44), "q44", FPUq);
 177     public static final Register q48 = new Register(108, getQuadncoding(48), "q48", FPUq);
 178     public static final Register q52 = new Register(109, getQuadncoding(52), "q52", FPUq);
 179     public static final Register q56 = new Register(110, getQuadncoding(56), "q56", FPUq);
 180     public static final Register q60 = new Register(111, getQuadncoding(60), "q60", FPUq);
 181 
 182     // @formatter:off
 183     public static final RegisterArray cpuRegisters = new RegisterArray(
 184         g0,  g1,  g2,  g3,  g4,  g5,  g6,  g7,
 185         o0,  o1,  o2,  o3,  o4,  o5,  o6,  o7,
 186         l0,  l1,  l2,  l3,  l4,  l5,  l6,  l7,
 187         i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7
 188     );
 189 
 190     public static final RegisterArray fpusRegisters = new RegisterArray(
 191         f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
 192         f8,  f9,  f10, f11, f12, f13, f14, f15,
 193         f16, f17, f18, f19, f20, f21, f22, f23,
 194         f24, f25, f26, f27, f28, f29, f30, f31
 195     );
 196 
 197     public static final RegisterArray fpudRegisters = new RegisterArray(
 198         d0, d2, d4, d6, d8,  d10, d12, d14,
 199         d16, d18, d20, d22, d24, d26, d28, d30,
 200         d32, d34, d36, d38, d40, d42, d44, d46,
 201         d48, d50, d52, d54, d56, d58, d60, d62
 202     );
 203 
 204     public static final RegisterArray fpuqRegisters = new RegisterArray(
 205         q0, q4, q8, q12,
 206         q16, q20, q24, q28,
 207         q32, q36, q40, q44,
 208         q48, q52, q56, q60
 209     );
 210 
 211     public static final RegisterArray allRegisters = new RegisterArray(
 212         g0,  g1,  g2,  g3,  g4,  g5,  g6,  g7,
 213         o0,  o1,  o2,  o3,  o4,  o5,  o6,  o7,
 214         l0,  l1,  l2,  l3,  l4,  l5,  l6,  l7,
 215         i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7,
 216 
 217         f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
 218         f8,  f9,  f10, f11, f12, f13, f14, f15,
 219         f16, f17, f18, f19, f20, f21, f22, f23,
 220         f24, f25, f26, f27, f28, f29, f30, f31,
 221 
 222         d0, d2, d4, d6, d8,  d10, d12, d14,
 223         d16, d18, d20, d22, d24, d26, d28, d30,
 224         d32, d34, d36, d38, d40, d42, d44, d46,
 225         d48, d50, d52, d54, d56, d58, d60, d62,
 226 
 227         q0, q4, q8, q12,
 228         q16, q20, q24, q28,
 229         q32, q36, q40, q44,
 230         q48, q52, q56, q60
 231     );
 232     // @formatter:on
 233 
 234     /**
 235      * Stack bias for stack and frame pointer loads.
 236      */
 237     public static final int STACK_BIAS = 0x7ff;
 238 
 239     /**
 240      * Size to keep free for flushing the register-window to stack.
 241      */
 242     public static final int REGISTER_SAFE_AREA_SIZE = 128;
 243 
 244     public final Set<CPUFeature> features;
 245 
 246     public SPARC(Set<CPUFeature> features) {
 247         super("SPARC", SPARCKind.XWORD, BIG_ENDIAN, false, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8);
 248         this.features = features;
 249     }
 250 
 251     @Override
 252     public RegisterArray getAvailableValueRegisters() {
 253         return allRegisters;
 254     }
 255 
 256     @Override
 257     public boolean canStoreValue(RegisterCategory category, PlatformKind kind) {
 258         SPARCKind sparcKind = (SPARCKind) kind;
 259         switch (sparcKind) {
 260             case BYTE:
 261             case HWORD:
 262             case WORD:
 263             case XWORD:
 264                 return CPU.equals(category);
 265             case SINGLE:
 266             case V32_BYTE:
 267             case V32_HWORD:
 268                 return FPUs.equals(category);
 269             case DOUBLE:
 270             case V64_BYTE:
 271             case V64_HWORD:
 272             case V64_WORD:
 273             case V64_SINGLE:
 274                 return FPUd.equals(category);
 275             case QUAD:
 276                 return FPUq.equals(category);
 277             default:
 278                 return false;
 279         }
 280     }
 281 
 282     @Override
 283     public PlatformKind getLargestStorableKind(RegisterCategory category) {
 284         if (category.equals(CPU)) {
 285             return SPARCKind.XWORD;
 286         } else if (category.equals(FPUd)) {
 287             return SPARCKind.DOUBLE;
 288         } else if (category.equals(FPUs)) {
 289             return SPARCKind.SINGLE;
 290         } else if (category.equals(FPUq)) {
 291             return SPARCKind.QUAD;
 292         } else {
 293             throw new IllegalArgumentException("Unknown register category: " + category);
 294         }
 295     }
 296 
 297     @Override
 298     public PlatformKind getPlatformKind(JavaKind javaKind) {
 299         switch (javaKind) {
 300             case Boolean:
 301             case Byte:
 302                 return SPARCKind.BYTE;
 303             case Short:
 304             case Char:
 305                 return SPARCKind.HWORD;
 306             case Int:
 307                 return SPARCKind.WORD;
 308             case Long:
 309             case Object:
 310                 return SPARCKind.XWORD;
 311             case Float:
 312                 return SPARCKind.SINGLE;
 313             case Double:
 314                 return SPARCKind.DOUBLE;
 315             default:
 316                 return null;
 317         }
 318     }
 319 
 320     private static int getDoubleEncoding(int reg) {
 321         assert reg < 64 && ((reg & 1) == 0);
 322         return (reg & 0x1e) | ((reg & 0x20) >> 5);
 323     }
 324 
 325     private static int getQuadncoding(int reg) {
 326         assert reg < 64 && ((reg & 1) == 0);
 327         return (reg & 0x1c) | ((reg & 0x20) >> 5);
 328     }
 329 
 330     public Set<CPUFeature> getFeatures() {
 331         return features;
 332     }
 333 
 334     public boolean hasFeature(CPUFeature feature) {
 335         return features.contains(feature);
 336     }
 337 
 338     public enum CPUFeature {
 339         // ISA determined properties:
 340         ADI,
 341         AES,
 342         BLK_INIT,
 343         CAMELLIA,
 344         CBCOND,
 345         CRC32C,
 346         DES,
 347         DICTUNP,
 348         FMAF,
 349         FPCMPSHL,
 350         HPC,
 351         IMA,
 352         KASUMI,
 353         MD5,
 354         MME,
 355         MONT,
 356         MPMUL,
 357         MWAIT,
 358         PAUSE,
 359         PAUSE_NSEC,
 360         POPC,
 361         RLE,
 362         SHA1,
 363         SHA256,
 364         SHA3,
 365         SHA512,
 366         SPARC5,
 367         SPARC5B,
 368         SPARC6,
 369         V9,
 370         VAMASK,
 371         VIS1,
 372         VIS2,
 373         VIS3,
 374         VIS3B,
 375         VIS3C,
 376         XMONT,
 377         XMPMUL,
 378         // Synthesised CPU properties:
 379         BLK_ZEROING,
 380         FAST_BIS,
 381         FAST_CMOVE,
 382         FAST_IDIV,
 383         FAST_IND_BR,
 384         FAST_LD,
 385         FAST_RDPC
 386     }
 387 }