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