comparison graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java @ 6495:75f130f2b30f

moved AMD64 specific HotSpot code in com.oracle.graal.hotspot.amd64 project
author Doug Simon <doug.simon@oracle.com>
date Wed, 03 Oct 2012 01:18:03 +0200
parents graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRegisterConfig.java@df02fa2bce58
children 2a0c9f20baa1
comparison
equal deleted inserted replaced
6494:df02fa2bce58 6495:75f130f2b30f
1 /*
2 * Copyright (c) 2011, 2012, 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.amd64;
24
25 import static com.oracle.max.asm.amd64.AMD64.*;
26
27 import java.util.*;
28
29 import com.oracle.max.asm.amd64.*;
30 import com.oracle.graal.api.code.*;
31 import com.oracle.graal.api.code.CallingConvention.*;
32 import com.oracle.graal.api.code.Register.*;
33 import com.oracle.graal.api.meta.*;
34 import com.oracle.graal.graph.*;
35 import com.oracle.graal.hotspot.*;
36
37 public class AMD64HotSpotRegisterConfig implements RegisterConfig {
38
39 // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp
40 private final Register[] allocatable = {
41 rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/
42 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
43 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
44 };
45
46 private final EnumMap<RegisterFlag, Register[]> categorized = Register.categorize(allocatable);
47
48 private final RegisterAttributes[] attributesMap;
49
50 @Override
51 public Register[] getAllocatableRegisters() {
52 return allocatable;
53 }
54
55 @Override
56 public EnumMap<RegisterFlag, Register[]> getCategorizedAllocatableRegisters() {
57 return categorized;
58 }
59
60 @Override
61 public RegisterAttributes[] getAttributesMap() {
62 return attributesMap;
63 }
64
65 private final Register[] generalParameterRegisters;
66 private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7};
67 private final Register[] allParameterRegisters;
68
69 private final CalleeSaveLayout csl;
70
71 public AMD64HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
72 if (config.windowsOs) {
73 generalParameterRegisters = new Register[] {rdx, r8, r9, rdi, rsi, rcx};
74 } else {
75 generalParameterRegisters = new Register[] {rsi, rdx, rcx, r8, r9, rdi};
76 }
77
78 if (globalStubConfig) {
79 Register[] regs = {
80 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
81 r8, r9, r10, r11, r12, r13, r14, r15,
82 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
83 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
84 };
85 csl = new CalleeSaveLayout(0, -1, 8, regs);
86 } else {
87 // We reserve space for saving RBP but don't explicitly specify
88 // it as a callee save register since we explicitly do the saving
89 // with push and pop in HotSpotFrameContext
90 final int size = 8;
91 final Register[] regs = {};
92 csl = new CalleeSaveLayout(0, size, 8, regs);
93 }
94
95 attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
96 allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length);
97 System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length);
98 }
99
100 @Override
101 public Register[] getCallerSaveRegisters() {
102 return getAllocatableRegisters();
103 }
104
105 @Override
106 public Register getRegisterForRole(int index) {
107 throw new UnsupportedOperationException();
108 }
109
110 @Override
111 public CallingConvention getCallingConvention(Type type, Kind returnKind, Kind[] parameters, TargetDescription target, boolean stackOnly) {
112 if (type == Type.NativeCall) {
113 throw new UnsupportedOperationException();
114 }
115 return callingConvention(returnKind, parameters, type, target, stackOnly);
116 }
117
118 public Register[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
119 return allParameterRegisters;
120 }
121
122 private CallingConvention callingConvention(Kind returnKind, Kind[] kinds, Type type, TargetDescription target, boolean stackOnly) {
123 Value[] locations = new Value[kinds.length];
124
125 int currentGeneral = 0;
126 int currentXMM = 0;
127 int currentStackOffset = 0;
128
129 for (int i = 0; i < kinds.length; i++) {
130 final Kind kind = kinds[i];
131
132 switch (kind) {
133 case Byte:
134 case Boolean:
135 case Short:
136 case Char:
137 case Int:
138 case Long:
139 case Object:
140 if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
141 Register register = generalParameterRegisters[currentGeneral++];
142 locations[i] = register.asValue(kind);
143 }
144 break;
145 case Float:
146 case Double:
147 if (!stackOnly && currentXMM < xmmParameterRegisters.length) {
148 Register register = xmmParameterRegisters[currentXMM++];
149 locations[i] = register.asValue(kind);
150 }
151 break;
152 default:
153 throw GraalInternalError.shouldNotReachHere();
154 }
155
156 if (locations[i] == null) {
157 locations[i] = StackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
158 currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
159 }
160 }
161
162 Value returnLocation = returnKind.isVoid() ? Value.IllegalValue : getReturnRegister(returnKind).asValue(returnKind);
163 return new CallingConvention(currentStackOffset, returnLocation, locations);
164 }
165
166 @Override
167 public Register getReturnRegister(Kind kind) {
168 switch (kind) {
169 case Boolean:
170 case Byte:
171 case Char:
172 case Short:
173 case Int:
174 case Long:
175 case Object:
176 return rax;
177 case Float:
178 case Double:
179 return xmm0;
180 case Void:
181 case Illegal:
182 return null;
183 default:
184 throw new UnsupportedOperationException("no return register for type " + kind);
185 }
186 }
187
188 @Override
189 public Register getScratchRegister() {
190 return r10;
191 }
192
193 @Override
194 public Register getFrameRegister() {
195 return rsp;
196 }
197
198 public CalleeSaveLayout getCalleeSaveLayout() {
199 return csl;
200 }
201
202 @Override
203 public String toString() {
204 String res = String.format(
205 "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
206 "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
207 "CalleeSave: " + getCalleeSaveLayout() + "%n" +
208 "Scratch: " + getScratchRegister() + "%n");
209 return res;
210 }
211 }