Mercurial > hg > graal-jvmci-8
comparison jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java @ 22681:c278790fa252
[SPARC] Move allocatable register selection out of the Architecture description
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Tue, 13 Oct 2015 18:22:26 +0200 |
parents | 4688478ecb7b |
children | 5ba5ff0fda9e |
comparison
equal
deleted
inserted
replaced
22680:1179ab4c25fa | 22681:c278790fa252 |
---|---|
20 * or visit www.oracle.com if you need additional information or have any | 20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 package jdk.vm.ci.hotspot.sparc; | 23 package jdk.vm.ci.hotspot.sparc; |
24 | 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; | 25 import static jdk.vm.ci.sparc.SPARC.d0; |
28 import static jdk.vm.ci.sparc.SPARC.d2; | 26 import static jdk.vm.ci.sparc.SPARC.d2; |
29 import static jdk.vm.ci.sparc.SPARC.d32; | 27 import static jdk.vm.ci.sparc.SPARC.d32; |
30 import static jdk.vm.ci.sparc.SPARC.d34; | 28 import static jdk.vm.ci.sparc.SPARC.d34; |
31 import static jdk.vm.ci.sparc.SPARC.d36; | 29 import static jdk.vm.ci.sparc.SPARC.d36; |
74 import static jdk.vm.ci.sparc.SPARC.f5; | 72 import static jdk.vm.ci.sparc.SPARC.f5; |
75 import static jdk.vm.ci.sparc.SPARC.f6; | 73 import static jdk.vm.ci.sparc.SPARC.f6; |
76 import static jdk.vm.ci.sparc.SPARC.f7; | 74 import static jdk.vm.ci.sparc.SPARC.f7; |
77 import static jdk.vm.ci.sparc.SPARC.f8; | 75 import static jdk.vm.ci.sparc.SPARC.f8; |
78 import static jdk.vm.ci.sparc.SPARC.f9; | 76 import static jdk.vm.ci.sparc.SPARC.f9; |
77 import static jdk.vm.ci.sparc.SPARC.g0; | |
79 import static jdk.vm.ci.sparc.SPARC.g1; | 78 import static jdk.vm.ci.sparc.SPARC.g1; |
80 import static jdk.vm.ci.sparc.SPARC.g2; | 79 import static jdk.vm.ci.sparc.SPARC.g2; |
81 import static jdk.vm.ci.sparc.SPARC.g3; | 80 import static jdk.vm.ci.sparc.SPARC.g3; |
82 import static jdk.vm.ci.sparc.SPARC.g4; | 81 import static jdk.vm.ci.sparc.SPARC.g4; |
83 import static jdk.vm.ci.sparc.SPARC.g5; | 82 import static jdk.vm.ci.sparc.SPARC.g5; |
126 import jdk.vm.ci.meta.JavaType; | 125 import jdk.vm.ci.meta.JavaType; |
127 import jdk.vm.ci.meta.LIRKind; | 126 import jdk.vm.ci.meta.LIRKind; |
128 import jdk.vm.ci.meta.PlatformKind; | 127 import jdk.vm.ci.meta.PlatformKind; |
129 import jdk.vm.ci.meta.Value; | 128 import jdk.vm.ci.meta.Value; |
130 import jdk.vm.ci.sparc.SPARC; | 129 import jdk.vm.ci.sparc.SPARC; |
131 import jdk.vm.ci.sparc.SPARCKind; | |
132 | 130 |
133 public class SPARCHotSpotRegisterConfig implements RegisterConfig { | 131 public class SPARCHotSpotRegisterConfig implements RegisterConfig { |
134 | 132 |
135 private final Architecture architecture; | 133 private final Architecture architecture; |
136 | 134 |
150 | 148 |
151 public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) { | 149 public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) { |
152 ArrayList<Register> list = new ArrayList<>(); | 150 ArrayList<Register> list = new ArrayList<>(); |
153 for (Register reg : registers) { | 151 for (Register reg : registers) { |
154 if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { | 152 if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { |
155 // Special treatment for double precision | 153 list.add(reg); |
156 // TODO: This is wasteful it uses only half of the registers as float. | 154 } |
157 if (kind == SPARCKind.DOUBLE) { | 155 } |
158 if (reg.getRegisterCategory().equals(FPUd)) { | |
159 list.add(reg); | |
160 } | |
161 } else if (kind == SPARCKind.SINGLE) { | |
162 if (reg.getRegisterCategory().equals(FPUs)) { | |
163 list.add(reg); | |
164 } | |
165 } else { | |
166 list.add(reg); | |
167 } | |
168 } | |
169 } | |
170 | |
171 Register[] ret = list.toArray(new Register[list.size()]); | 156 Register[] ret = list.toArray(new Register[list.size()]); |
172 return ret; | 157 return ret; |
173 } | 158 } |
174 | 159 |
175 @Override | 160 @Override |
178 } | 163 } |
179 | 164 |
180 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; | 165 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; |
181 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; | 166 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; |
182 | 167 |
183 private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; | 168 private final Register[] fpuFloatParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; |
184 private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null}; | 169 private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null}; |
170 | |
185 // @formatter:off | 171 // @formatter:off |
186 private final Register[] callerSaveRegisters = | 172 private final Register[] callerSaveRegisters = |
187 {g1, g2, g3, g4, g5, g6, g7, | 173 {g1, g2, g3, g4, g5, g6, g7, |
188 o0, o1, o2, o3, o4, o5, o7, | 174 o0, o1, o2, o3, o4, o5, o7, |
189 f0, f1, f2, f3, f4, f5, f6, f7, | 175 f0, f1, f2, f3, f4, f5, f6, f7, |
196 | 182 |
197 /** | 183 /** |
198 * Registers saved by the callee. This lists all L and I registers which are saved in the | 184 * Registers saved by the callee. This lists all L and I registers which are saved in the |
199 * register window. | 185 * register window. |
200 */ | 186 */ |
201 private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7}; | 187 // @formatter:off |
202 | 188 private final Register[] calleeSaveRegisters = { |
203 private static Register[] initAllocatable(boolean reserveForHeapBase) { | 189 l0, l1, l2, l3, l4, l5, l6, l7, |
204 Register[] registers = null; | 190 i0, i1, i2, i3, i4, i5, i6, i7}; |
205 if (reserveForHeapBase) { | 191 // @formatter:on |
206 // @formatter:off | 192 |
207 registers = new Register[]{ | 193 private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) { |
208 // TODO this is not complete | 194 Register[] allRegisters = arch.getAvailableValueRegisters(); |
209 // o7 cannot be used as register because it is always overwritten on call | 195 Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 4 : 3)]; |
210 // and the current register handler would ignore this fact if the called | 196 |
211 // method still does not modify registers, in fact o7 is modified by the Call instruction | 197 int idx = 0; |
212 // There would be some extra handlin necessary to be able to handle the o7 properly for local usage | 198 for (Register reg : allRegisters) { |
213 g1, g4, g5, | 199 if (reg.equals(sp) || reg.equals(g2) || reg.equals(g0)) { |
214 o0, o1, o2, o3, o4, o5, /*o6,o7,*/ | 200 // skip g0, stack pointer and thread register |
215 l0, l1, l2, l3, l4, l5, l6, l7, | 201 continue; |
216 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ | 202 } |
217 //f0, f1, f2, f3, f4, f5, f6, f7, | 203 if (reserveForHeapBase && reg.equals(g6)) { |
218 f8, f9, f10, f11, f12, f13, f14, f15, | 204 // skip heap base register |
219 f16, f17, f18, f19, f20, f21, f22, f23, | 205 continue; |
220 f24, f25, f26, f27, f28, f29, f30, f31, | 206 } |
221 d32, d34, d36, d38, d40, d42, d44, d46, | 207 |
222 d48, d50, d52, d54, d56, d58, d60, d62 | 208 registers[idx++] = reg; |
223 }; | 209 } |
224 // @formatter:on | 210 |
225 } else { | 211 assert idx == registers.length; |
226 // @formatter:off | |
227 registers = new Register[]{ | |
228 // TODO this is not complete | |
229 g1, g4, g5, | |
230 o0, o1, o2, o3, o4, o5, /*o6, o7,*/ | |
231 l0, l1, l2, l3, l4, l5, l6, l7, | |
232 i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ | |
233 // f0, f1, f2, f3, f4, f5, f6, f7 | |
234 f8, f9, f10, f11, f12, f13, f14, f15, | |
235 f16, f17, f18, f19, f20, f21, f22, f23, | |
236 f24, f25, f26, f27, f28, f29, f30, f31, | |
237 d32, d34, d36, d38, d40, d42, d44, d46, | |
238 d48, d50, d52, d54, d56, d58, d60, d62 | |
239 }; | |
240 // @formatter:on | |
241 } | |
242 | |
243 return registers; | 212 return registers; |
244 } | 213 } |
245 | 214 |
246 public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) { | 215 public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) { |
247 this(target, initAllocatable(config.useCompressedOops), config); | 216 this(arch, initAllocatable(arch, config.useCompressedOops), config); |
248 } | 217 } |
249 | 218 |
250 public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable, HotSpotVMConfig config) { | 219 public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) { |
251 this.architecture = target.arch; | 220 this.architecture = arch; |
252 this.allocatable = allocatable.clone(); | 221 this.allocatable = allocatable.clone(); |
253 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); | 222 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); |
254 this.addNativeRegisterArgumentSlots = config.linuxOs; | 223 this.addNativeRegisterArgumentSlots = config.linuxOs; |
255 } | 224 } |
256 | 225 |
294 case Long: | 263 case Long: |
295 case Object: | 264 case Object: |
296 return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; | 265 return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; |
297 case Double: | 266 case Double: |
298 case Float: | 267 case Float: |
299 return fpuParameterRegisters; | 268 return fpuFloatParameterRegisters; |
300 default: | 269 default: |
301 throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind); | 270 throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind); |
302 } | 271 } |
303 } | 272 } |
304 | 273 |
324 Register register = generalParameterRegisters[currentGeneral++]; | 293 Register register = generalParameterRegisters[currentGeneral++]; |
325 locations[i] = register.asValue(target.getLIRKind(kind)); | 294 locations[i] = register.asValue(target.getLIRKind(kind)); |
326 } | 295 } |
327 break; | 296 break; |
328 case Double: | 297 case Double: |
329 if (!stackOnly && currentFloating < fpuParameterRegisters.length) { | 298 if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) { |
330 if (currentFloating % 2 != 0) { | 299 if (currentFloating % 2 != 0) { |
331 // Make register number even to be a double reg | 300 // Make register number even to be a double reg |
332 currentFloating++; | 301 currentFloating++; |
333 } | 302 } |
334 Register register = fpuDoubleParameterRegisters[currentFloating]; | 303 Register register = fpuDoubleParameterRegisters[currentFloating]; |
335 currentFloating += 2; // Only every second is a double register | 304 currentFloating += 2; // Only every second is a double register |
336 locations[i] = register.asValue(target.getLIRKind(kind)); | 305 locations[i] = register.asValue(target.getLIRKind(kind)); |
337 } | 306 } |
338 break; | 307 break; |
339 case Float: | 308 case Float: |
340 if (!stackOnly && currentFloating < fpuParameterRegisters.length) { | 309 if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) { |
341 Register register = fpuParameterRegisters[currentFloating++]; | 310 Register register = fpuFloatParameterRegisters[currentFloating++]; |
342 locations[i] = register.asValue(target.getLIRKind(kind)); | 311 locations[i] = register.asValue(target.getLIRKind(kind)); |
343 } | 312 } |
344 break; | 313 break; |
345 default: | 314 default: |
346 throw JVMCIError.shouldNotReachHere(); | 315 throw JVMCIError.shouldNotReachHere(); |