comparison jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java @ 22672:1bbd4a7c274b

Rename jdk.internal.jvmci to jdk.vm.ci
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 08 Oct 2015 17:28:41 -0700
parents jvmci/jdk.internal.jvmci.hotspot.sparc/src/jdk/internal/jvmci/hotspot/sparc/SPARCHotSpotRegisterConfig.java@a215c16882e0
children 4688478ecb7b
comparison
equal deleted inserted replaced
22671:97f30e4d0e95 22672:1bbd4a7c274b
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.hotspot.sparc;
24
25 import static jdk.vm.ci.sparc.SPARC.FPUd;
26 import static jdk.vm.ci.sparc.SPARC.FPUs;
27 import static jdk.vm.ci.sparc.SPARC.d0;
28 import static jdk.vm.ci.sparc.SPARC.d2;
29 import static jdk.vm.ci.sparc.SPARC.d32;
30 import static jdk.vm.ci.sparc.SPARC.d34;
31 import static jdk.vm.ci.sparc.SPARC.d36;
32 import static jdk.vm.ci.sparc.SPARC.d38;
33 import static jdk.vm.ci.sparc.SPARC.d4;
34 import static jdk.vm.ci.sparc.SPARC.d40;
35 import static jdk.vm.ci.sparc.SPARC.d42;
36 import static jdk.vm.ci.sparc.SPARC.d44;
37 import static jdk.vm.ci.sparc.SPARC.d46;
38 import static jdk.vm.ci.sparc.SPARC.d48;
39 import static jdk.vm.ci.sparc.SPARC.d50;
40 import static jdk.vm.ci.sparc.SPARC.d52;
41 import static jdk.vm.ci.sparc.SPARC.d54;
42 import static jdk.vm.ci.sparc.SPARC.d56;
43 import static jdk.vm.ci.sparc.SPARC.d58;
44 import static jdk.vm.ci.sparc.SPARC.d6;
45 import static jdk.vm.ci.sparc.SPARC.d60;
46 import static jdk.vm.ci.sparc.SPARC.d62;
47 import static jdk.vm.ci.sparc.SPARC.f0;
48 import static jdk.vm.ci.sparc.SPARC.f1;
49 import static jdk.vm.ci.sparc.SPARC.f10;
50 import static jdk.vm.ci.sparc.SPARC.f11;
51 import static jdk.vm.ci.sparc.SPARC.f12;
52 import static jdk.vm.ci.sparc.SPARC.f13;
53 import static jdk.vm.ci.sparc.SPARC.f14;
54 import static jdk.vm.ci.sparc.SPARC.f15;
55 import static jdk.vm.ci.sparc.SPARC.f16;
56 import static jdk.vm.ci.sparc.SPARC.f17;
57 import static jdk.vm.ci.sparc.SPARC.f18;
58 import static jdk.vm.ci.sparc.SPARC.f19;
59 import static jdk.vm.ci.sparc.SPARC.f2;
60 import static jdk.vm.ci.sparc.SPARC.f20;
61 import static jdk.vm.ci.sparc.SPARC.f21;
62 import static jdk.vm.ci.sparc.SPARC.f22;
63 import static jdk.vm.ci.sparc.SPARC.f23;
64 import static jdk.vm.ci.sparc.SPARC.f24;
65 import static jdk.vm.ci.sparc.SPARC.f25;
66 import static jdk.vm.ci.sparc.SPARC.f26;
67 import static jdk.vm.ci.sparc.SPARC.f27;
68 import static jdk.vm.ci.sparc.SPARC.f28;
69 import static jdk.vm.ci.sparc.SPARC.f29;
70 import static jdk.vm.ci.sparc.SPARC.f3;
71 import static jdk.vm.ci.sparc.SPARC.f30;
72 import static jdk.vm.ci.sparc.SPARC.f31;
73 import static jdk.vm.ci.sparc.SPARC.f4;
74 import static jdk.vm.ci.sparc.SPARC.f5;
75 import static jdk.vm.ci.sparc.SPARC.f6;
76 import static jdk.vm.ci.sparc.SPARC.f7;
77 import static jdk.vm.ci.sparc.SPARC.f8;
78 import static jdk.vm.ci.sparc.SPARC.f9;
79 import static jdk.vm.ci.sparc.SPARC.g1;
80 import static jdk.vm.ci.sparc.SPARC.g2;
81 import static jdk.vm.ci.sparc.SPARC.g3;
82 import static jdk.vm.ci.sparc.SPARC.g4;
83 import static jdk.vm.ci.sparc.SPARC.g5;
84 import static jdk.vm.ci.sparc.SPARC.g6;
85 import static jdk.vm.ci.sparc.SPARC.g7;
86 import static jdk.vm.ci.sparc.SPARC.i0;
87 import static jdk.vm.ci.sparc.SPARC.i1;
88 import static jdk.vm.ci.sparc.SPARC.i2;
89 import static jdk.vm.ci.sparc.SPARC.i3;
90 import static jdk.vm.ci.sparc.SPARC.i4;
91 import static jdk.vm.ci.sparc.SPARC.i5;
92 import static jdk.vm.ci.sparc.SPARC.i6;
93 import static jdk.vm.ci.sparc.SPARC.i7;
94 import static jdk.vm.ci.sparc.SPARC.l0;
95 import static jdk.vm.ci.sparc.SPARC.l1;
96 import static jdk.vm.ci.sparc.SPARC.l2;
97 import static jdk.vm.ci.sparc.SPARC.l3;
98 import static jdk.vm.ci.sparc.SPARC.l4;
99 import static jdk.vm.ci.sparc.SPARC.l5;
100 import static jdk.vm.ci.sparc.SPARC.l6;
101 import static jdk.vm.ci.sparc.SPARC.l7;
102 import static jdk.vm.ci.sparc.SPARC.o0;
103 import static jdk.vm.ci.sparc.SPARC.o1;
104 import static jdk.vm.ci.sparc.SPARC.o2;
105 import static jdk.vm.ci.sparc.SPARC.o3;
106 import static jdk.vm.ci.sparc.SPARC.o4;
107 import static jdk.vm.ci.sparc.SPARC.o5;
108 import static jdk.vm.ci.sparc.SPARC.o7;
109 import static jdk.vm.ci.sparc.SPARC.sp;
110
111 import java.util.ArrayList;
112 import java.util.Arrays;
113
114 import jdk.vm.ci.code.Architecture;
115 import jdk.vm.ci.code.CallingConvention;
116 import jdk.vm.ci.code.CallingConvention.Type;
117 import jdk.vm.ci.code.Register;
118 import jdk.vm.ci.code.RegisterAttributes;
119 import jdk.vm.ci.code.RegisterConfig;
120 import jdk.vm.ci.code.StackSlot;
121 import jdk.vm.ci.code.TargetDescription;
122 import jdk.vm.ci.common.JVMCIError;
123 import jdk.vm.ci.hotspot.HotSpotVMConfig;
124 import jdk.vm.ci.meta.AllocatableValue;
125 import jdk.vm.ci.meta.JavaKind;
126 import jdk.vm.ci.meta.JavaType;
127 import jdk.vm.ci.meta.LIRKind;
128 import jdk.vm.ci.meta.PlatformKind;
129 import jdk.vm.ci.meta.Value;
130 import jdk.vm.ci.sparc.SPARC;
131 import jdk.vm.ci.sparc.SPARCKind;
132
133 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
134
135 private final Architecture architecture;
136
137 private final Register[] allocatable;
138
139 private final RegisterAttributes[] attributesMap;
140
141 @Override
142 public Register[] getAllocatableRegisters() {
143 return allocatable.clone();
144 }
145
146 public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
147 ArrayList<Register> list = new ArrayList<>();
148 for (Register reg : registers) {
149 if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
150 // Special treatment for double precision
151 // TODO: This is wasteful it uses only half of the registers as float.
152 if (kind == SPARCKind.DOUBLE) {
153 if (reg.getRegisterCategory().equals(FPUd)) {
154 list.add(reg);
155 }
156 } else if (kind == SPARCKind.SINGLE) {
157 if (reg.getRegisterCategory().equals(FPUs)) {
158 list.add(reg);
159 }
160 } else {
161 list.add(reg);
162 }
163 }
164 }
165
166 Register[] ret = list.toArray(new Register[list.size()]);
167 return ret;
168 }
169
170 @Override
171 public RegisterAttributes[] getAttributesMap() {
172 return attributesMap.clone();
173 }
174
175 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
176 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
177
178 private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
179 private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
180 // @formatter:off
181 private final Register[] callerSaveRegisters =
182 {g1, g2, g3, g4, g5, g6, g7,
183 o0, o1, o2, o3, o4, o5, o7,
184 f0, f1, f2, f3, f4, f5, f6, f7,
185 f8, f9, f10, f11, f12, f13, f14, f15,
186 f16, f17, f18, f19, f20, f21, f22, f23,
187 f24, f25, f26, f27, f28, f29, f30, f31,
188 d32, d34, d36, d38, d40, d42, d44, d46,
189 d48, d50, d52, d54, d56, d58, d60, d62};
190 // @formatter:on
191
192 /**
193 * Registers saved by the callee. This lists all L and I registers which are saved in the
194 * register window.
195 */
196 private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7};
197
198 private static Register[] initAllocatable(boolean reserveForHeapBase) {
199 Register[] registers = null;
200 if (reserveForHeapBase) {
201 // @formatter:off
202 registers = new Register[]{
203 // TODO this is not complete
204 // o7 cannot be used as register because it is always overwritten on call
205 // and the current register handler would ignore this fact if the called
206 // method still does not modify registers, in fact o7 is modified by the Call instruction
207 // There would be some extra handlin necessary to be able to handle the o7 properly for local usage
208 g1, g4, g5,
209 o0, o1, o2, o3, o4, o5, /*o6,o7,*/
210 l0, l1, l2, l3, l4, l5, l6, l7,
211 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
212 //f0, f1, f2, f3, f4, f5, f6, f7,
213 f8, f9, f10, f11, f12, f13, f14, f15,
214 f16, f17, f18, f19, f20, f21, f22, f23,
215 f24, f25, f26, f27, f28, f29, f30, f31,
216 d32, d34, d36, d38, d40, d42, d44, d46,
217 d48, d50, d52, d54, d56, d58, d60, d62
218 };
219 // @formatter:on
220 } else {
221 // @formatter:off
222 registers = new Register[]{
223 // TODO this is not complete
224 g1, g4, g5,
225 o0, o1, o2, o3, o4, o5, /*o6, o7,*/
226 l0, l1, l2, l3, l4, l5, l6, l7,
227 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
228 // f0, f1, f2, f3, f4, f5, f6, f7
229 f8, f9, f10, f11, f12, f13, f14, f15,
230 f16, f17, f18, f19, f20, f21, f22, f23,
231 f24, f25, f26, f27, f28, f29, f30, f31,
232 d32, d34, d36, d38, d40, d42, d44, d46,
233 d48, d50, d52, d54, d56, d58, d60, d62
234 };
235 // @formatter:on
236 }
237
238 return registers;
239 }
240
241 public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
242 this(target, initAllocatable(config.useCompressedOops));
243 }
244
245 public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
246 this.architecture = target.arch;
247 this.allocatable = allocatable.clone();
248 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
249 }
250
251 @Override
252 public Register[] getCallerSaveRegisters() {
253 return callerSaveRegisters;
254 }
255
256 public Register[] getCalleeSaveRegisters() {
257 return calleeSaveRegisters;
258 }
259
260 @Override
261 public boolean areAllAllocatableRegistersCallerSaved() {
262 return false;
263 }
264
265 @Override
266 public Register getRegisterForRole(int index) {
267 throw new UnsupportedOperationException();
268 }
269
270 @Override
271 public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
272 if (type == Type.JavaCall || type == Type.NativeCall) {
273 return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
274 }
275 if (type == Type.JavaCallee) {
276 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
277 }
278 throw JVMCIError.shouldNotReachHere();
279 }
280
281 public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
282 switch (kind) {
283 case Boolean:
284 case Byte:
285 case Short:
286 case Char:
287 case Int:
288 case Long:
289 case Object:
290 return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
291 case Double:
292 case Float:
293 return fpuParameterRegisters;
294 default:
295 throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
296 }
297 }
298
299 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
300 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
301
302 int currentGeneral = 0;
303 int currentFloating = 0;
304 int currentStackOffset = 0;
305
306 for (int i = 0; i < parameterTypes.length; i++) {
307 final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
308
309 switch (kind) {
310 case Byte:
311 case Boolean:
312 case Short:
313 case Char:
314 case Int:
315 case Long:
316 case Object:
317 if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
318 Register register = generalParameterRegisters[currentGeneral++];
319 locations[i] = register.asValue(target.getLIRKind(kind));
320 }
321 break;
322 case Double:
323 if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
324 if (currentFloating % 2 != 0) {
325 // Make register number even to be a double reg
326 currentFloating++;
327 }
328 Register register = fpuDoubleParameterRegisters[currentFloating];
329 currentFloating += 2; // Only every second is a double register
330 locations[i] = register.asValue(target.getLIRKind(kind));
331 }
332 break;
333 case Float:
334 if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
335 Register register = fpuParameterRegisters[currentFloating++];
336 locations[i] = register.asValue(target.getLIRKind(kind));
337 }
338 break;
339 default:
340 throw JVMCIError.shouldNotReachHere();
341 }
342
343 if (locations[i] == null) {
344 LIRKind lirKind = target.getLIRKind(kind);
345 // Stack slot is always aligned to its size in bytes but minimum wordsize
346 int typeSize = lirKind.getPlatformKind().getSizeInBytes();
347 currentStackOffset = roundUp(currentStackOffset, typeSize);
348 int slotOffset = currentStackOffset + SPARC.REGISTER_SAFE_AREA_SIZE;
349 locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
350 currentStackOffset += typeSize;
351 }
352 }
353
354 JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
355 AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
356 // Space where callee may spill outgoing parameters o0...o5
357 int lowerOutgoingSpace = Math.min(locations.length, 6) * target.wordSize;
358 return new CallingConvention(currentStackOffset + lowerOutgoingSpace, returnLocation, locations);
359 }
360
361 private static int roundUp(int number, int mod) {
362 return ((number + mod - 1) / mod) * mod;
363 }
364
365 @Override
366 public Register getReturnRegister(JavaKind kind) {
367 return getReturnRegister(kind, Type.JavaCallee);
368 }
369
370 private static Register getReturnRegister(JavaKind kind, Type type) {
371 switch (kind) {
372 case Boolean:
373 case Byte:
374 case Char:
375 case Short:
376 case Int:
377 case Long:
378 case Object:
379 return type == Type.JavaCallee ? i0 : o0;
380 case Float:
381 return f0;
382 case Double:
383 return d0;
384 case Void:
385 case Illegal:
386 return null;
387 default:
388 throw new UnsupportedOperationException("no return register for type " + kind);
389 }
390 }
391
392 @Override
393 public Register getFrameRegister() {
394 return sp;
395 }
396
397 @Override
398 public String toString() {
399 return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n");
400 }
401 }