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();