001/* 002 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.sparc; 024 025import static jdk.internal.jvmci.code.MemoryBarriers.*; 026 027import java.nio.*; 028import java.util.*; 029 030import jdk.internal.jvmci.code.*; 031import jdk.internal.jvmci.code.Register.*; 032import jdk.internal.jvmci.meta.*; 033 034/** 035 * Represents the SPARC architecture. 036 */ 037public class SPARC extends Architecture { 038 039 public static final RegisterCategory CPU = new RegisterCategory("CPU"); 040 041 // General purpose registers 042 public static final Register r0 = new Register(0, 0, "g0", CPU); 043 public static final Register r1 = new Register(1, 1, "g1", CPU); 044 public static final Register r2 = new Register(2, 2, "g2", CPU); 045 public static final Register r3 = new Register(3, 3, "g3", CPU); 046 public static final Register r4 = new Register(4, 4, "g4", CPU); 047 public static final Register r5 = new Register(5, 5, "g5", CPU); 048 public static final Register r6 = new Register(6, 6, "g6", CPU); 049 public static final Register r7 = new Register(7, 7, "g7", CPU); 050 051 public static final Register r8 = new Register(8, 8, "o0", CPU); 052 public static final Register r9 = new Register(9, 9, "o1", CPU); 053 public static final Register r10 = new Register(10, 10, "o2", CPU); 054 public static final Register r11 = new Register(11, 11, "o3", CPU); 055 public static final Register r12 = new Register(12, 12, "o4", CPU); 056 public static final Register r13 = new Register(13, 13, "o5", CPU); 057 public static final Register r14 = new Register(14, 14, "o6", CPU); 058 public static final Register r15 = new Register(15, 15, "o7", CPU); 059 060 public static final Register r16 = new Register(16, 16, "l0", CPU); 061 public static final Register r17 = new Register(17, 17, "l1", CPU); 062 public static final Register r18 = new Register(18, 18, "l2", CPU); 063 public static final Register r19 = new Register(19, 19, "l3", CPU); 064 public static final Register r20 = new Register(20, 20, "l4", CPU); 065 public static final Register r21 = new Register(21, 21, "l5", CPU); 066 public static final Register r22 = new Register(22, 22, "l6", CPU); 067 public static final Register r23 = new Register(23, 23, "l7", CPU); 068 069 public static final Register r24 = new Register(24, 24, "i0", CPU); 070 public static final Register r25 = new Register(25, 25, "i1", CPU); 071 public static final Register r26 = new Register(26, 26, "i2", CPU); 072 public static final Register r27 = new Register(27, 27, "i3", CPU); 073 public static final Register r28 = new Register(28, 28, "i4", CPU); 074 public static final Register r29 = new Register(29, 29, "i5", CPU); 075 public static final Register r30 = new Register(30, 30, "i6", CPU); 076 public static final Register r31 = new Register(31, 31, "i7", CPU); 077 078 public static final Register g0 = r0; 079 public static final Register g1 = r1; 080 public static final Register g2 = r2; 081 public static final Register g3 = r3; 082 public static final Register g4 = r4; 083 public static final Register g5 = r5; 084 public static final Register g6 = r6; 085 public static final Register g7 = r7; 086 087 public static final Register o0 = r8; 088 public static final Register o1 = r9; 089 public static final Register o2 = r10; 090 public static final Register o3 = r11; 091 public static final Register o4 = r12; 092 public static final Register o5 = r13; 093 public static final Register o6 = r14; 094 public static final Register o7 = r15; 095 096 public static final Register l0 = r16; 097 public static final Register l1 = r17; 098 public static final Register l2 = r18; 099 public static final Register l3 = r19; 100 public static final Register l4 = r20; 101 public static final Register l5 = r21; 102 public static final Register l6 = r22; 103 public static final Register l7 = r23; 104 105 public static final Register i0 = r24; 106 public static final Register i1 = r25; 107 public static final Register i2 = r26; 108 public static final Register i3 = r27; 109 public static final Register i4 = r28; 110 public static final Register i5 = r29; 111 public static final Register i6 = r30; 112 public static final Register i7 = r31; 113 114 public static final Register sp = o6; 115 public static final Register fp = i6; 116 117 // @formatter:off 118 public static final Register[] cpuRegisters = { 119 r0, r1, r2, r3, r4, r5, r6, r7, 120 r8, r9, r10, r11, r12, r13, r14, r15, 121 r16, r17, r18, r19, r20, r21, r22, r23, 122 r24, r25, r26, r27, r28, r29, r30, r31 123 }; 124 // @formatter:on 125 126 public static final RegisterCategory FPUs = new RegisterCategory("FPUs", cpuRegisters.length); 127 public static final RegisterCategory FPUd = new RegisterCategory("FPUd", cpuRegisters.length + 32); 128 129 // Floating point registers 130 public static final Register f0 = new Register(32, 0, "f0", FPUs); 131 public static final Register f1 = new Register(33, 1, "f1", FPUs); 132 public static final Register f2 = new Register(34, 2, "f2", FPUs); 133 public static final Register f3 = new Register(35, 3, "f3", FPUs); 134 public static final Register f4 = new Register(36, 4, "f4", FPUs); 135 public static final Register f5 = new Register(37, 5, "f5", FPUs); 136 public static final Register f6 = new Register(38, 6, "f6", FPUs); 137 public static final Register f7 = new Register(39, 7, "f7", FPUs); 138 139 public static final Register f8 = new Register(40, 8, "f8", FPUs); 140 public static final Register f9 = new Register(41, 9, "f9", FPUs); 141 public static final Register f10 = new Register(42, 10, "f10", FPUs); 142 public static final Register f11 = new Register(43, 11, "f11", FPUs); 143 public static final Register f12 = new Register(44, 12, "f12", FPUs); 144 public static final Register f13 = new Register(45, 13, "f13", FPUs); 145 public static final Register f14 = new Register(46, 14, "f14", FPUs); 146 public static final Register f15 = new Register(47, 15, "f15", FPUs); 147 148 public static final Register f16 = new Register(48, 16, "f16", FPUs); 149 public static final Register f17 = new Register(49, 17, "f17", FPUs); 150 public static final Register f18 = new Register(50, 18, "f18", FPUs); 151 public static final Register f19 = new Register(51, 19, "f19", FPUs); 152 public static final Register f20 = new Register(52, 20, "f20", FPUs); 153 public static final Register f21 = new Register(53, 21, "f21", FPUs); 154 public static final Register f22 = new Register(54, 22, "f22", FPUs); 155 public static final Register f23 = new Register(55, 23, "f23", FPUs); 156 157 public static final Register f24 = new Register(56, 24, "f24", FPUs); 158 public static final Register f25 = new Register(57, 25, "f25", FPUs); 159 public static final Register f26 = new Register(58, 26, "f26", FPUs); 160 public static final Register f27 = new Register(59, 27, "f27", FPUs); 161 public static final Register f28 = new Register(60, 28, "f28", FPUs); 162 public static final Register f29 = new Register(61, 29, "f29", FPUs); 163 public static final Register f30 = new Register(62, 30, "f30", FPUs); 164 public static final Register f31 = new Register(63, 31, "f31", FPUs); 165 166 public static final Register d0 = new Register(32, getDoubleEncoding(0), "d0", FPUs); 167 public static final Register d2 = new Register(34, getDoubleEncoding(2), "d2", FPUs); 168 public static final Register d4 = new Register(36, getDoubleEncoding(4), "d4", FPUs); 169 public static final Register d6 = new Register(38, getDoubleEncoding(6), "d6", FPUs); 170 public static final Register d8 = new Register(40, getDoubleEncoding(8), "d8", FPUs); 171 public static final Register d10 = new Register(42, getDoubleEncoding(10), "d10", FPUs); 172 public static final Register d12 = new Register(44, getDoubleEncoding(12), "d12", FPUs); 173 public static final Register d14 = new Register(46, getDoubleEncoding(14), "d14", FPUs); 174 175 public static final Register d16 = new Register(48, getDoubleEncoding(16), "d16", FPUs); 176 public static final Register d18 = new Register(50, getDoubleEncoding(18), "d18", FPUs); 177 public static final Register d20 = new Register(52, getDoubleEncoding(20), "d20", FPUs); 178 public static final Register d22 = new Register(54, getDoubleEncoding(22), "d22", FPUs); 179 public static final Register d24 = new Register(56, getDoubleEncoding(24), "d24", FPUs); 180 public static final Register d26 = new Register(58, getDoubleEncoding(26), "d26", FPUs); 181 public static final Register d28 = new Register(60, getDoubleEncoding(28), "d28", FPUs); 182 public static final Register d30 = new Register(62, getDoubleEncoding(28), "d28", FPUs); 183 184 public static final Register d32 = new Register(64, getDoubleEncoding(32), "d32", FPUd); 185 public static final Register d34 = new Register(65, getDoubleEncoding(34), "d34", FPUd); 186 public static final Register d36 = new Register(66, getDoubleEncoding(36), "d36", FPUd); 187 public static final Register d38 = new Register(67, getDoubleEncoding(38), "d38", FPUd); 188 public static final Register d40 = new Register(68, getDoubleEncoding(40), "d40", FPUd); 189 public static final Register d42 = new Register(69, getDoubleEncoding(42), "d42", FPUd); 190 public static final Register d44 = new Register(70, getDoubleEncoding(44), "d44", FPUd); 191 public static final Register d46 = new Register(71, getDoubleEncoding(46), "d46", FPUd); 192 193 public static final Register d48 = new Register(72, getDoubleEncoding(48), "d48", FPUd); 194 public static final Register d50 = new Register(73, getDoubleEncoding(50), "d50", FPUd); 195 public static final Register d52 = new Register(74, getDoubleEncoding(52), "d52", FPUd); 196 public static final Register d54 = new Register(75, getDoubleEncoding(54), "d54", FPUd); 197 public static final Register d56 = new Register(76, getDoubleEncoding(56), "d56", FPUd); 198 public static final Register d58 = new Register(77, getDoubleEncoding(58), "d58", FPUd); 199 public static final Register d60 = new Register(78, getDoubleEncoding(60), "d60", FPUd); 200 public static final Register d62 = new Register(79, getDoubleEncoding(62), "d62", FPUd); 201 202 // @formatter:off 203 public static final Register[] fpuRegisters = { 204 f0, f1, f2, f3, f4, f5, f6, f7, 205 f8, f9, f10, f11, f12, f13, f14, f15, 206 f16, f17, f18, f19, f20, f21, f22, f23, 207 f24, f25, f26, f27, f28, f29, f30, f31, 208 d32, d34, d36, d38, d40, d42, d44, d46, 209 d48, d50, d52, d54, d56, d58, d60, d62 210 }; 211 // @formatter:on 212 213 // @formatter:off 214 public static final Register[] allRegisters = { 215 // CPU 216 r0, r1, r2, r3, r4, r5, r6, r7, 217 r8, r9, r10, r11, r12, r13, r14, r15, 218 r16, r17, r18, r19, r20, r21, r22, r23, 219 r24, r25, r26, r27, r28, r29, r30, r31, 220 // FPU 221 f0, f1, f2, f3, f4, f5, f6, f7, 222 f8, f9, f10, f11, f12, f13, f14, f15, 223 f16, f17, f18, f19, f20, f21, f22, f23, 224 f24, f25, f26, f27, f28, f29, f30, f31, 225 d32, d34, d36, d38, d40, d42, d44, d46, 226 d48, d50, d52, d54, d56, d58, d60, d62 227 }; 228 // @formatter:on 229 230 /** 231 * Stack bias for stack and frame pointer loads. 232 */ 233 public static final int STACK_BIAS = 0x7ff; 234 /** 235 * In fact there are 64 single floating point registers, 32 of them could be accessed. TODO: 236 * Improve handling of these float registers 237 */ 238 public static final int FLOAT_REGISTER_COUNT = 64; 239 240 /** 241 * Alignment for valid memory access. 242 */ 243 public static final int MEMORY_ACCESS_ALIGN = 4; 244 245 public static final int INSTRUCTION_SIZE = 4; 246 247 /** 248 * Size to keep free for flushing the register-window to stack. 249 */ 250 public static final int REGISTER_SAFE_AREA_SIZE = 128; 251 252 public final Set<CPUFeature> features; 253 254 public SPARC(Set<CPUFeature> features) { 255 super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + FLOAT_REGISTER_COUNT + 1, 8); 256 this.features = features; 257 } 258 259 @Override 260 public boolean canStoreValue(RegisterCategory category, PlatformKind lirKind) { 261 if (!(lirKind instanceof Kind)) { 262 return false; 263 } 264 265 Kind kind = (Kind) lirKind; 266 if (category.equals(CPU)) { 267 switch (kind) { 268 case Boolean: 269 case Byte: 270 case Char: 271 case Short: 272 case Int: 273 case Long: 274 case Object: 275 return true; 276 } 277 } else if (category.equals(FPUs) && kind.equals(Kind.Float)) { 278 return true; 279 } else if (category.equals(FPUd) && kind.equals(Kind.Double)) { 280 return true; 281 } 282 return false; 283 } 284 285 @Override 286 public PlatformKind getLargestStorableKind(RegisterCategory category) { 287 if (category.equals(CPU)) { 288 return Kind.Long; 289 } else if (category.equals(FPUd)) { 290 return Kind.Double; 291 } else if (category.equals(FPUs)) { 292 return Kind.Float; 293 } else { 294 return Kind.Illegal; 295 } 296 } 297 298 public static int spillSlotSize(TargetDescription td, PlatformKind kind) { 299 return Math.max(td.getSizeInBytes(kind), MEMORY_ACCESS_ALIGN); 300 } 301 302 public static int getDoubleEncoding(int reg) { 303 assert reg < 64 && ((reg & 1) == 0); 304 // ignore v8 assertion for now 305 return (reg & 0x1e) | ((reg & 0x20) >> 5); 306 } 307 308 public static boolean isCPURegister(Register r) { 309 return r.getRegisterCategory().equals(CPU); 310 } 311 312 public static boolean isCPURegister(Register... regs) { 313 for (Register reg : regs) { 314 if (!isCPURegister(reg)) { 315 return false; 316 } 317 } 318 return true; 319 } 320 321 public static boolean isGlobalRegister(Register r) { 322 return isCPURegister(r) && g0.number <= r.number && r.number <= g7.number; 323 } 324 325 public static boolean isSingleFloatRegister(Register r) { 326 return r.name.startsWith("f"); 327 } 328 329 public static boolean isDoubleFloatRegister(Register r) { 330 return r.name.startsWith("d"); 331 } 332 333 public Set<CPUFeature> getFeatures() { 334 return features; 335 } 336 337 public boolean hasFeature(CPUFeature feature) { 338 return features.contains(feature); 339 } 340 341 public enum CPUFeature { 342 VIS1, 343 VIS2, 344 VIS3, 345 CBCOND 346 } 347}