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 }