Mercurial > hg > graal-jvmci-8
annotate graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java @ 16321:fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
author | Stefan Anzinger <stefan.anzinger@gmail.com> |
---|---|
date | Thu, 05 Jun 2014 11:28:16 +0200 |
parents | 109d6c7c40b5 |
children | 5f01f7c48d40 |
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 | |
15259
d90e5c22ba55
Move GraalOptions to graal.compiler.common.
Josef Eisl <josef.eisl@jku.at>
parents:
15193
diff
changeset
|
25 import static com.oracle.graal.compiler.common.GraalOptions.*; |
10459 | 26 import static com.oracle.graal.sparc.SPARC.*; |
27 | |
28 import java.util.*; | |
29 | |
30 import com.oracle.graal.api.code.*; | |
31 import com.oracle.graal.api.code.CallingConvention.Type; | |
32 import com.oracle.graal.api.meta.*; | |
15193
96bb07a5d667
Spit up and move GraalInternalError.
Josef Eisl <josef.eisl@jku.at>
parents:
15011
diff
changeset
|
33 import com.oracle.graal.compiler.common.*; |
10459 | 34 import com.oracle.graal.hotspot.*; |
11233 | 35 import com.oracle.graal.lir.*; |
14991
64dcb92ee75a
Truffle: Change signature for Truffle calls from (PackedFrame, Arguments) to (Object[]).
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
14614
diff
changeset
|
36 import com.oracle.graal.sparc.*; |
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)) { | |
16321
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
61 // Special treatment for double precision |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
62 if (kind == Kind.Double) { |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
63 // Only even register numbers are valid double precision regs |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
64 if (reg.number % 2 == 0) { |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
65 list.add(reg); |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
66 } |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
67 } else { |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
68 list.add(reg); |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
69 } |
10459 | 70 } |
71 } | |
72 | |
73 Register[] ret = list.toArray(new Register[0]); | |
74 categorized.put(kind, ret); | |
75 return ret; | |
76 } | |
77 | |
78 @Override | |
79 public RegisterAttributes[] getAttributesMap() { | |
80 return attributesMap.clone(); | |
81 } | |
82 | |
10792 | 83 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; |
84 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; | |
85 | |
10459 | 86 private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; |
87 | |
10686
73122b5edf6a
SPARC: Can compile simple methods and do static calls.
twisti
parents:
10459
diff
changeset
|
88 private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7}; |
11233 | 89 |
90 /** | |
91 * Registers saved by the callee. This lists all L and I registers which are saved in the | |
92 * register window. {@link FrameMap} uses this array to calculate the spill area size. | |
93 */ | |
94 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
|
95 |
10459 | 96 private final CalleeSaveLayout csl; |
97 | |
98 private static Register findRegister(String name, Register[] all) { | |
99 for (Register reg : all) { | |
100 if (reg.name.equals(name)) { | |
101 return reg; | |
102 } | |
103 } | |
104 throw new IllegalArgumentException("register " + name + " is not allocatable"); | |
105 } | |
106 | |
107 private static Register[] initAllocatable(boolean reserveForHeapBase) { | |
108 Register[] registers = null; | |
109 if (reserveForHeapBase) { | |
15345 | 110 // @formatter:off |
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 |
15345 | 117 }; |
118 // @formatter:on | |
10459 | 119 } else { |
15345 | 120 // @formatter:off |
121 registers = new Register[]{ | |
10854
e1fcdda22831
SPARC: can compile some stubs now but they don't work yet
twisti
parents:
10792
diff
changeset
|
122 // TODO this is not complete |
e1fcdda22831
SPARC: can compile some stubs now but they don't work yet
twisti
parents:
10792
diff
changeset
|
123 o0, o1, o2, o3, o4, o5, /*o6,*/ o7, |
10459 | 124 l0, l1, l2, l3, l4, l5, l6, l7, |
11233 | 125 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ |
10459 | 126 f0, f1, f2, f3, f4, f5, f6, f7 |
15345 | 127 }; |
128 // @formatter:on | |
10459 | 129 } |
130 | |
131 if (RegisterPressure.getValue() != null) { | |
132 String[] names = RegisterPressure.getValue().split(","); | |
133 Register[] regs = new Register[names.length]; | |
134 for (int i = 0; i < names.length; i++) { | |
135 regs[i] = findRegister(names[i], registers); | |
136 } | |
137 return regs; | |
138 } | |
139 | |
140 return registers; | |
141 } | |
142 | |
14559
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
143 public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) { |
15011
c8e575742f36
allow compilation with custom RegisterConfig
Lukas Stadler <lukas.stadler@oracle.com>
parents:
14991
diff
changeset
|
144 this(target, initAllocatable(config.useCompressedOops)); |
c8e575742f36
allow compilation with custom RegisterConfig
Lukas Stadler <lukas.stadler@oracle.com>
parents:
14991
diff
changeset
|
145 } |
c8e575742f36
allow compilation with custom RegisterConfig
Lukas Stadler <lukas.stadler@oracle.com>
parents:
14991
diff
changeset
|
146 |
c8e575742f36
allow compilation with custom RegisterConfig
Lukas Stadler <lukas.stadler@oracle.com>
parents:
14991
diff
changeset
|
147 public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) { |
14559
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
148 this.architecture = target.arch; |
10459 | 149 |
14559
883fbd3e06e0
Make size of PlatformKind overridable by VM specific code.
Roland Schatz <roland.schatz@oracle.com>
parents:
14003
diff
changeset
|
150 csl = new CalleeSaveLayout(target, -1, -1, target.arch.getWordSize(), calleeSaveRegisters); |
15011
c8e575742f36
allow compilation with custom RegisterConfig
Lukas Stadler <lukas.stadler@oracle.com>
parents:
14991
diff
changeset
|
151 this.allocatable = allocatable.clone(); |
10459 | 152 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); |
153 } | |
154 | |
155 @Override | |
156 public Register[] getCallerSaveRegisters() { | |
10686
73122b5edf6a
SPARC: Can compile simple methods and do static calls.
twisti
parents:
10459
diff
changeset
|
157 return callerSaveRegisters; |
10459 | 158 } |
159 | |
160 @Override | |
14614
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
161 public boolean areAllAllocatableRegistersCallerSaved() { |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
162 return false; |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
163 } |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
164 |
abf7cf57df5e
added RegisterConfig.areAllAllocatableRegistersCallerSaved()
Doug Simon <doug.simon@oracle.com>
parents:
14559
diff
changeset
|
165 @Override |
10459 | 166 public Register getRegisterForRole(int index) { |
167 throw new UnsupportedOperationException(); | |
168 } | |
169 | |
170 @Override | |
171 public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { | |
10792 | 172 if (type == Type.JavaCall || type == Type.NativeCall) { |
173 return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly); | |
10459 | 174 } |
10792 | 175 if (type == Type.JavaCallee) { |
176 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly); | |
177 } | |
178 throw GraalInternalError.shouldNotReachHere(); | |
10459 | 179 } |
180 | |
181 public Register[] getCallingConventionRegisters(Type type, Kind kind) { | |
182 if (architecture.canStoreValue(FPU, kind)) { | |
183 return fpuParameterRegisters; | |
184 } | |
185 assert architecture.canStoreValue(CPU, kind); | |
10792 | 186 return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; |
10459 | 187 } |
188 | |
189 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { | |
190 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; | |
191 | |
192 int currentGeneral = 0; | |
193 int currentFloating = 0; | |
194 int currentStackOffset = 0; | |
195 | |
196 for (int i = 0; i < parameterTypes.length; i++) { | |
197 final Kind kind = parameterTypes[i].getKind(); | |
198 | |
199 switch (kind) { | |
200 case Byte: | |
201 case Boolean: | |
202 case Short: | |
203 case Char: | |
204 case Int: | |
205 case Long: | |
206 case Object: | |
207 if (!stackOnly && currentGeneral < generalParameterRegisters.length) { | |
208 Register register = generalParameterRegisters[currentGeneral++]; | |
209 locations[i] = register.asValue(kind); | |
210 } | |
211 break; | |
16321
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
212 case Double: |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
213 if (!stackOnly && currentFloating < fpuParameterRegisters.length) { |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
214 if (currentFloating % 2 != 0) { |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
215 // Make register number even to be a double reg |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
216 currentFloating++; |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
217 } |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
218 Register register = fpuParameterRegisters[currentFloating]; |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
219 currentFloating += 2; // Only every second is a double register |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
220 locations[i] = register.asValue(kind); |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
221 } |
fac4af29aeb8
[SPARC] Fixing lots of float and double issues.
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
15345
diff
changeset
|
222 break; |
10459 | 223 case Float: |
224 if (!stackOnly && currentFloating < fpuParameterRegisters.length) { | |
225 Register register = fpuParameterRegisters[currentFloating++]; | |
226 locations[i] = register.asValue(kind); | |
227 } | |
228 break; | |
229 default: | |
230 throw GraalInternalError.shouldNotReachHere(); | |
231 } | |
232 | |
233 if (locations[i] == null) { | |
234 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
|
235 currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); |
10459 | 236 } |
237 } | |
238 | |
239 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
|
240 AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(returnKind.getStackKind()); |
10459 | 241 return new CallingConvention(currentStackOffset, returnLocation, locations); |
242 } | |
243 | |
244 @Override | |
245 public Register getReturnRegister(Kind kind) { | |
10871
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
246 return getReturnRegister(kind, Type.JavaCallee); |
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
247 } |
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
248 |
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
249 private static Register getReturnRegister(Kind kind, Type type) { |
10459 | 250 switch (kind) { |
251 case Boolean: | |
252 case Byte: | |
253 case Char: | |
254 case Short: | |
255 case Int: | |
256 case Long: | |
257 case Object: | |
10871
c3b09d69dfde
SPARC: fixes and more implementation; can now allocate objects
twisti
parents:
10854
diff
changeset
|
258 return type == Type.JavaCallee ? i0 : o0; |
10459 | 259 case Float: |
260 case Double: | |
261 return f0; | |
262 case Void: | |
263 case Illegal: | |
264 return null; | |
265 default: | |
266 throw new UnsupportedOperationException("no return register for type " + kind); | |
267 } | |
268 } | |
269 | |
270 @Override | |
271 public Register getFrameRegister() { | |
272 return sp; | |
273 } | |
274 | |
275 public CalleeSaveLayout getCalleeSaveLayout() { | |
276 return csl; | |
277 } | |
278 | |
279 @Override | |
280 public String toString() { | |
281 return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); | |
282 } | |
283 } |