Mercurial > hg > truffle
annotate graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java @ 14614:abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Mar 2014 12:42:43 +0100 |
parents | 883fbd3e06e0 |
children | 64dcb92ee75a |
rev | line source |
---|---|
10459 | 1 /* |
2 * Copyright (c) 2013, 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 com.oracle.graal.hotspot.sparc; | |
24 | |
25 import static com.oracle.graal.sparc.SPARC.*; | |
26 import static com.oracle.graal.phases.GraalOptions.*; | |
27 | |
28 import java.util.*; | |
29 | |
30 import com.oracle.graal.sparc.*; | |
31 import com.oracle.graal.api.code.*; | |
32 import com.oracle.graal.api.code.CallingConvention.Type; | |
33 import com.oracle.graal.api.meta.*; | |
34 import com.oracle.graal.graph.*; | |
35 import com.oracle.graal.hotspot.*; | |
11233 | 36 import com.oracle.graal.lir.*; |
10459 | 37 |
38 public class SPARCHotSpotRegisterConfig implements RegisterConfig { | |
39 | |
40 private final Architecture architecture; | |
41 | |
42 private final Register[] allocatable; | |
43 | |
44 private final HashMap<PlatformKind, Register[]> categorized = new HashMap<>(); | |
45 | |
46 private final RegisterAttributes[] attributesMap; | |
47 | |
48 @Override | |
49 public Register[] getAllocatableRegisters() { | |
50 return allocatable.clone(); | |
51 } | |
52 | |
53 public Register[] getAllocatableRegisters(PlatformKind kind) { | |
54 if (categorized.containsKey(kind)) { | |
55 return categorized.get(kind); | |
56 } | |
57 | |
58 ArrayList<Register> list = new ArrayList<>(); | |
59 for (Register reg : getAllocatableRegisters()) { | |
60 if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { | |
61 list.add(reg); | |
62 } | |
63 } | |
64 | |
65 Register[] ret = list.toArray(new Register[0]); | |
66 categorized.put(kind, ret); | |
67 return ret; | |
68 } | |
69 | |
70 @Override | |
71 public RegisterAttributes[] getAttributesMap() { | |
72 return attributesMap.clone(); | |
73 } | |
74 | |
10792 | 75 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; |
76 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; | |
77 | |
10459 | 78 private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; |
79 | |
10686
73122b5edf6a
SPARC: Can compile simple methods and do static calls.
twisti
parents:
10459
diff
changeset
|
80 private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7}; |
11233 | 81 |
82 /** | |
83 * Registers saved by the callee. This lists all L and I registers which are saved in the | |
84 * register window. {@link FrameMap} uses this array to calculate the spill area size. | |
85 */ | |
86 private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7}; | |
10686
73122b5edf6a
SPARC: Can compile simple methods and do static calls.
twisti
parents:
10459
diff
changeset
|
87 |
10459 | 88 private final CalleeSaveLayout csl; |
89 | |
90 private static Register findRegister(String name, Register[] all) { | |
91 for (Register reg : all) { | |
92 if (reg.name.equals(name)) { | |
93 return reg; | |
94 } | |
95 } | |
96 throw new IllegalArgumentException("register " + name + " is not allocatable"); | |
97 } | |
98 | |
99 private static Register[] initAllocatable(boolean reserveForHeapBase) { | |
100 Register[] registers = null; | |
101 // @formatter:off | |
102 if (reserveForHeapBase) { | |
103 registers = new Register[] { | |
10854
e1fcdda22831
SPARC: can compile some stubs now but they don't work yet
twisti
parents:
10792
diff
changeset
|
104 // TODO this is not complete |
e1fcdda22831
SPARC: can compile some stubs now but they don't work yet
twisti
parents:
10792
diff
changeset
|
105 o0, o1, o2, o3, o4, o5, /*o6,*/ o7, |
10459 | 106 l0, l1, l2, l3, l4, l5, l6, l7, |
11233 | 107 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ |
10459 | 108 f0, f1, f2, f3, f4, f5, f6, f7 |
109 }; | |
110 } else { | |
111 registers = new Register[] { | |
10854
e1fcdda22831
SPARC: can compile some stubs now but they don't work yet
twisti
parents:
10792
diff
changeset
|
112 // TODO this is not complete |
e1fcdda22831
SPARC: can compile some stubs now but they don't work yet
twisti
parents:
10792
diff
changeset
|
113 o0, o1, o2, o3, o4, o5, /*o6,*/ o7, |
10459 | 114 l0, l1, l2, l3, l4, l5, l6, l7, |
11233 | 115 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ |
10459 | 116 f0, f1, f2, f3, f4, f5, f6, f7 |
117 }; | |
118 } | |
119 // @formatter:on | |
120 | |
121 if (RegisterPressure.getValue() != null) { | |
122 String[] names = RegisterPressure.getValue().split(","); | |
123 Register[] regs = new Register[names.length]; | |
124 for (int i = 0; i < names.length; i++) { | |
125 regs[i] = findRegister(names[i], registers); | |
126 } | |
127 return regs; | |
128 } | |
129 | |
130 return registers; | |
131 } | |
132 | |
14559
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
133 public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) { |
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
134 this.architecture = target.arch; |
10459 | 135 |
14559
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
136 csl = new CalleeSaveLayout(target, -1, -1, target.arch.getWordSize(), calleeSaveRegisters); |
10459 | 137 allocatable = initAllocatable(config.useCompressedOops); |
138 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); | |
139 } | |
140 | |
141 @Override | |
142 public Register[] getCallerSaveRegisters() { | |
10686
73122b5edf6a
SPARC: Can compile simple methods and do static calls.
twisti
parents:
10459
diff
changeset
|
143 return callerSaveRegisters; |
10459 | 144 } |
145 | |
146 @Override | |
14614
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
147 public boolean areAllAllocatableRegistersCallerSaved() { |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
148 return false; |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
149 } |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
150 |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
151 @Override |
10459 | 152 public Register getRegisterForRole(int index) { |
153 throw new UnsupportedOperationException(); | |
154 } | |
155 | |
156 @Override | |
157 public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { | |
10792 | 158 if (type == Type.JavaCall || type == Type.NativeCall) { |
159 return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly); | |
10459 | 160 } |
10792 | 161 if (type == Type.JavaCallee) { |
162 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly); | |
163 } | |
164 throw GraalInternalError.shouldNotReachHere(); | |
10459 | 165 } |
166 | |
167 public Register[] getCallingConventionRegisters(Type type, Kind kind) { | |
168 if (architecture.canStoreValue(FPU, kind)) { | |
169 return fpuParameterRegisters; | |
170 } | |
171 assert architecture.canStoreValue(CPU, kind); | |
10792 | 172 return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; |
10459 | 173 } |
174 | |
175 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { | |
176 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; | |
177 | |
178 int currentGeneral = 0; | |
179 int currentFloating = 0; | |
180 int currentStackOffset = 0; | |
181 | |
182 for (int i = 0; i < parameterTypes.length; i++) { | |
183 final Kind kind = parameterTypes[i].getKind(); | |
184 | |
185 switch (kind) { | |
186 case Byte: | |
187 case Boolean: | |
188 case Short: | |
189 case Char: | |
190 case Int: | |
191 case Long: | |
192 case Object: | |
193 if (!stackOnly && currentGeneral < generalParameterRegisters.length) { | |
194 Register register = generalParameterRegisters[currentGeneral++]; | |
195 locations[i] = register.asValue(kind); | |
196 } | |
197 break; | |
198 case Float: | |
199 case Double: | |
200 if (!stackOnly && currentFloating < fpuParameterRegisters.length) { | |
201 Register register = fpuParameterRegisters[currentFloating++]; | |
202 locations[i] = register.asValue(kind); | |
203 } | |
204 break; | |
205 default: | |
206 throw GraalInternalError.shouldNotReachHere(); | |
207 } | |
208 | |
209 if (locations[i] == null) { | |
210 locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); | |
14559
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
211 currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); |
10459 | 212 } |
213 } | |
214 | |
215 Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); | |
14003
0c38906450a0
Make conversion from Stamp to PlatformKind extensible by backend.
Roland Schatz <roland.schatz@oracle.com>
parents:
11233
diff
changeset
|
216 AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(returnKind.getStackKind()); |
10459 | 217 return new CallingConvention(currentStackOffset, returnLocation, locations); |
218 } | |
219 | |
220 @Override | |
221 public Register getReturnRegister(Kind kind) { | |
10871
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
222 return getReturnRegister(kind, Type.JavaCallee); |
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
223 } |
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
224 |
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
225 private static Register getReturnRegister(Kind kind, Type type) { |
10459 | 226 switch (kind) { |
227 case Boolean: | |
228 case Byte: | |
229 case Char: | |
230 case Short: | |
231 case Int: | |
232 case Long: | |
233 case Object: | |
10871
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
234 return type == Type.JavaCallee ? i0 : o0; |
10459 | 235 case Float: |
236 case Double: | |
237 return f0; | |
238 case Void: | |
239 case Illegal: | |
240 return null; | |
241 default: | |
242 throw new UnsupportedOperationException("no return register for type " + kind); | |
243 } | |
244 } | |
245 | |
246 @Override | |
247 public Register getFrameRegister() { | |
248 return sp; | |
249 } | |
250 | |
251 public CalleeSaveLayout getCalleeSaveLayout() { | |
252 return csl; | |
253 } | |
254 | |
255 @Override | |
256 public String toString() { | |
257 return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); | |
258 } | |
259 } |