001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.ia32;
014
015 import org.vmmagic.pragma.Pure;
016 import org.vmmagic.pragma.UninterruptibleNoWarn;
017 import org.jikesrvm.VM;
018
019 public interface RegisterConstants {
020 //---------------------------------------------------------------------------------------//
021 // RVM register usage conventions - Intel version. //
022 //---------------------------------------------------------------------------------------//
023
024 byte LG_INSTRUCTION_WIDTH = 0; // log2 of instruction width in bytes
025 int INSTRUCTION_WIDTH = 1 << LG_INSTRUCTION_WIDTH;
026
027 /**
028 * Common interface implemented by all registers constants
029 */
030 public interface MachineRegister {
031 /** @return encoded value of this register */
032 byte value();
033 /** @return does this register require a REX prefix byte? */
034 boolean needsREXprefix();
035 }
036
037 /**
038 * Super interface for floating point registers
039 */
040 public interface FloatingPointMachineRegister extends MachineRegister {
041 }
042
043 /**
044 * Representation of general purpose registers
045 */
046 public enum GPR implements MachineRegister {
047 EAX(0), ECX(1), EDX(2), EBX(3), ESP(4), EBP(5), ESI(6), EDI(7),
048 R8(8), R9(9), R10(10), R11(11), R12(12), R13(13), R14(14), R15(15),
049 EIP(16);
050
051 /** Local copy of the backing array. Copied here to avoid calls to clone */
052 private static final GPR[] vals = values();
053
054 /** Constructor a register with the given encoding value */
055 private GPR(int v) {
056 if (v != ordinal()) {
057 throw new Error("Invalid register ordinal");
058 }
059 }
060 /** @return encoded value of this register */
061 @UninterruptibleNoWarn("Interruptible code only called during boot image creation")
062 @Pure
063 public byte value() {
064 byte result;
065 if (!org.jikesrvm.VM.runningVM) {
066 result = (byte)ordinal();
067 } else {
068 result = (byte)java.lang.JikesRVMSupport.getEnumOrdinal(this);
069 }
070 if (VM.VerifyAssertions) {
071 if (VM.buildFor32Addr()) {
072 VM._assert(result >=0 && result <= 7);
073 } else {
074 VM._assert(result >=0 && result <= 15);
075 }
076 }
077 return result;
078 }
079 /** @return encoded value of this register to be included in the opcode byte */
080 @Pure
081 public byte valueForOpcode() {
082 byte result;
083 if (!org.jikesrvm.VM.runningVM) {
084 result = (byte)ordinal();
085 } else {
086 result = (byte)java.lang.JikesRVMSupport.getEnumOrdinal(this);
087 }
088 if (!VM.buildFor32Addr()) {
089 result &= 0x7;
090 }
091 if (VM.VerifyAssertions) {
092 VM._assert(result >=0 && result <= 7);
093 }
094 return result;
095 }
096 /** @return does this register require a REX prefix byte? */
097 @Pure
098 public boolean needsREXprefix() {
099 if (VM.buildFor32Addr()) {
100 return false;
101 } else {
102 return (this != EIP) && (value() > 7);
103 }
104 }
105 /**
106 * Convert encoded value into the GPR it represents
107 * @param num encoded value
108 * @return represented GPR
109 */
110 @Pure
111 public static GPR lookup(int num) {
112 return vals[num];
113 }
114 /**
115 * Convert encoded value representing an opcode into the GPR to represent it
116 * @param opcode encoded value
117 * @return represented GPR
118 */
119 public static GPR getForOpcode(int opcode) {
120 if (VM.VerifyAssertions) VM._assert(opcode >=0 && opcode <= 7);
121 return lookup(opcode);
122 }
123 }
124
125 /**
126 * Representation of x87 floating point registers
127 */
128 public enum FPR implements FloatingPointMachineRegister {
129 FP0(0), FP1(1), FP2(2), FP3(3), FP4(4), FP5(5), FP6(6), FP7(7);
130 /** Local copy of the backing array. Copied here to avoid calls to clone */
131 private static final FPR[] vals = values();
132 /** Constructor a register with the given encoding value */
133 FPR(int v) {
134 if (v != ordinal()) {
135 throw new Error("Invalid register ordinal");
136 }
137 }
138 /** @return encoded value of this register */
139 @Pure
140 public byte value() {
141 return (byte)ordinal();
142 }
143 /** @return does this register require a REX prefix byte? */
144 @Pure
145 public boolean needsREXprefix() {
146 return false; // do REX prefixes of floating point operands make sense?
147 }
148 /**
149 * Convert encoded value into the FPR it represents
150 * @param num encoded value
151 * @return represented FPR
152 */
153 @Pure
154 public static FPR lookup(int num) {
155 return vals[num];
156 }
157 }
158 /**
159 * Representation of MMX MM registers
160 * N.B. MM and x87 FPR registers alias
161 */
162 public enum MM implements MachineRegister {
163 MM0(0), MM1(1), MM2(2), MM3(3), MM4(4), MM5(5), MM6(6), MM7(7),
164 MM8(8), MM9(9), MM10(10), MM11(11), MM12(12), MM13(13), MM14(14), MM15(15);
165 /** Local copy of the backing array. Copied here to avoid calls to clone */
166 private static final MM[] vals = values();
167 /** Constructor a register with the given encoding value */
168 MM(int v) {
169 if (v != ordinal()) {
170 throw new Error("Invalid register ordinal");
171 }
172 }
173 /** @return encoded value of this register */
174 @Pure
175 public byte value() {
176 return (byte)ordinal();
177 }
178 /** @return does this register require a REX prefix byte? */
179 @Pure
180 public boolean needsREXprefix() {
181 if (VM.buildFor32Addr()) {
182 return false;
183 } else {
184 return value() > 7;
185 }
186 }
187 /**
188 * Convert encoded value into the MM it represents
189 * @param num encoded value
190 * @return represented MM
191 */
192 @Pure
193 public static MM lookup(int num) {
194 return vals[num];
195 }
196 }
197
198 /**
199 * Representation of SSE XMM registers
200 */
201 public enum XMM implements FloatingPointMachineRegister {
202 XMM0(0), XMM1(1), XMM2(2), XMM3(3), XMM4(4), XMM5(5), XMM6(6), XMM7(7),
203 XMM8(8), XMM9(9), XMM10(10), XMM11(11), XMM12(12), XMM13(13), XMM14(14), XMM15(15);
204 /** Local copy of the backing array. Copied here to avoid calls to clone */
205 private static final XMM[] vals = values();
206 /** Constructor a register with the given encoding value */
207 XMM(int v) {
208 if (v != ordinal()) {
209 throw new Error("Invalid register ordinal");
210 }
211 }
212 /** @return encoded value of this register */
213 @Pure
214 public byte value() {
215 return (byte)ordinal();
216 }
217 /** @return does this register require a REX prefix byte? */
218 @Pure
219 public boolean needsREXprefix() {
220 if (VM.buildFor32Addr()) {
221 return false;
222 } else {
223 return value() > 7;
224 }
225 }
226 /**
227 * Convert encoded value into the XMM it represents
228 * @param num encoded value
229 * @return represented XMM
230 */
231 @Pure
232 public static XMM lookup(int num) {
233 return vals[num];
234 }
235 }
236
237 /*
238 * Symbolic values for general purpose registers.
239 * These values are used to assemble instructions and as indices into:
240 * Registers.gprs[]
241 * Registers.fprs[]
242 * GCMapIterator.registerLocations[]
243 * RegisterConstants.GPR_NAMES[]
244 */
245 GPR EAX = GPR.EAX;
246 GPR ECX = GPR.ECX;
247 GPR EDX = GPR.EDX;
248 GPR EBX = GPR.EBX;
249 GPR ESP = GPR.ESP;
250 GPR EBP = GPR.EBP;
251 GPR ESI = GPR.ESI;
252 GPR EDI = GPR.EDI;
253
254 GPR R0 = GPR.EAX;
255 GPR R1 = GPR.ECX;
256 GPR R2 = GPR.EDX;
257 GPR R3 = GPR.EBX;
258 GPR R4 = GPR.ESP;
259 GPR R5 = GPR.EBP;
260 GPR R6 = GPR.ESI;
261 GPR R7 = GPR.EDI;
262 GPR R8 = GPR.R8;
263 GPR R9 = GPR.R9;
264 GPR R10 = GPR.R10;
265 GPR R11 = GPR.R11;
266 GPR R12 = GPR.R12;
267 GPR R13 = GPR.R13;
268 GPR R14 = GPR.R14;
269 GPR R15 = GPR.R15;
270
271 FPR FP0 = FPR.FP0;
272 FPR FP1 = FPR.FP1;
273 FPR FP2 = FPR.FP2;
274 FPR FP3 = FPR.FP3;
275 FPR FP4 = FPR.FP4;
276 FPR FP5 = FPR.FP5;
277 FPR FP6 = FPR.FP6;
278 FPR FP7 = FPR.FP7;
279
280 MM MM0 = MM.MM0;
281 MM MM1 = MM.MM1;
282 MM MM2 = MM.MM2;
283 MM MM3 = MM.MM3;
284 MM MM4 = MM.MM4;
285 MM MM5 = MM.MM5;
286 MM MM6 = MM.MM6;
287 MM MM7 = MM.MM7;
288 MM MM8 = MM.MM8;
289 MM MM9 = MM.MM9;
290 MM MM10 = MM.MM10;
291 MM MM11 = MM.MM11;
292 MM MM12 = MM.MM12;
293 MM MM13 = MM.MM13;
294 MM MM14 = MM.MM14;
295 MM MM15 = MM.MM15;
296
297 XMM XMM0 = XMM.XMM0;
298 XMM XMM1 = XMM.XMM1;
299 XMM XMM2 = XMM.XMM2;
300 XMM XMM3 = XMM.XMM3;
301 XMM XMM4 = XMM.XMM4;
302 XMM XMM5 = XMM.XMM5;
303 XMM XMM6 = XMM.XMM6;
304 XMM XMM7 = XMM.XMM7;
305 XMM XMM8 = XMM.XMM8;
306 XMM XMM9 = XMM.XMM9;
307 XMM XMM10 = XMM.XMM10;
308 XMM XMM11 = XMM.XMM11;
309 XMM XMM12 = XMM.XMM12;
310 XMM XMM13 = XMM.XMM13;
311 XMM XMM14 = XMM.XMM14;
312 XMM XMM15 = XMM.XMM15;
313
314 /*
315 * Dedicated registers.
316 */
317
318 /** Register current stack pointer. NB the frame pointer is maintained in the processor. */
319 GPR STACK_POINTER = ESP;
320 /** Register holding a reference to thread local information */
321 GPR THREAD_REGISTER = ESI;
322
323 /*
324 * Register sets
325 * (``range'' is a misnomer for the alphabet soup of of intel registers)
326 */
327 // CHECKSTYLE:OFF
328 /** All general purpose registers */
329 GPR[] ALL_GPRS =
330 VM.buildFor32Addr() ? new GPR[]{EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI}
331 : new GPR[]{EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8, R9, R10, R11, R12, R13, R14, R15};
332
333 /** Number of general purpose registers */
334 byte NUM_GPRS = (byte)ALL_GPRS.length;
335
336 /**
337 * All floating point purpose registers
338 * NB with SSE x87 registers must be explicitly managed
339 */
340 FloatingPointMachineRegister[] ALL_FPRS =
341 VM.buildFor32Addr() ? (VM.buildForSSE2() ? new FPR[]{FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7}
342 : new XMM[]{XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7})
343 : new XMM[]{XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
344 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15};
345
346 /** Number of floating point registers */
347 byte NUM_FPRS = (byte)ALL_FPRS.length;
348
349 /**
350 * Volatile general purpose registers.
351 * NB: the order here is important. The opt-compiler allocates
352 * the volatile registers in the order they appear here.
353 */
354 GPR[] VOLATILE_GPRS = VM.buildFor32Addr() ? new GPR[]{R0 /*EAX*/, R2 /*EDX*/, R1 /*ECX*/} : new GPR[]{R0, R2, R1};
355 int NUM_VOLATILE_GPRS = VOLATILE_GPRS.length;
356
357 /**
358 * Volatile floating point registers within the RVM.
359 * TODO: this should include XMMs
360 */
361 FloatingPointMachineRegister[] VOLATILE_FPRS = {FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7};
362 /** Number of volatile FPRs */
363 int NUM_VOLATILE_FPRS = VOLATILE_FPRS.length;
364
365 /**
366 * Non-volatile general purpose registers within the RVM.
367 * Note: the order here is very important. The opt-compiler allocates
368 * the nonvolatile registers in the reverse of order they appear here.
369 * R3 (EBX) must be last, because it is the only non-volatile that can
370 * be used in instructions that are using r8 and we must ensure that
371 * opt doesn't skip over another nonvol while looking for an r8 nonvol.
372 */
373 GPR[] NONVOLATILE_GPRS =
374 VM.buildFor32Addr() ? new GPR[]{R5 /*EBP*/, R7 /*EDI*/, R3 /*EBX*/}
375 : new GPR[]{R5, R7, R3};
376 /** Number of non-volatile GPRs */
377 int NUM_NONVOLATILE_GPRS = NONVOLATILE_GPRS.length;
378
379 /** Non-volatile floating point registers within the RVM. */
380 FloatingPointMachineRegister[] NONVOLATILE_FPRS = {};
381 /** Number of non-volatile FPRs */
382 int NUM_NONVOLATILE_FPRS = NONVOLATILE_FPRS.length;
383
384 /** General purpose registers to pass arguments within the RVM */
385 GPR[] PARAMETER_GPRS = new GPR[]{EAX, EDX};
386 /** Number of parameter GPRs */
387 int NUM_PARAMETER_GPRS = PARAMETER_GPRS.length;
388
389 /** Floating point registers to pass arguments within the RVM */
390 FloatingPointMachineRegister[] PARAMETER_FPRS =
391 VM.buildForSSE2() ? new XMM[]{XMM0, XMM1, XMM2, XMM3}
392 : new FPR[]{FP0, FP1, FP2, FP3};
393 /** Number of parameter FPRs */
394 int NUM_PARAMETER_FPRS = PARAMETER_FPRS.length;
395 /** GPR registers used for returning values */
396 GPR[] RETURN_GPRS = VM.buildFor32Addr() ? new GPR[]{EAX, EDX} : new GPR[]{EAX};
397 /** Number of return GPRs */
398 int NUM_RETURN_GPRS = RETURN_GPRS.length;
399
400 /** FPR registers used for returning values */
401 FloatingPointMachineRegister[] RETURN_FPRS =
402 VM.buildForSSE2() ? new XMM[]{XMM0} : new FPR[]{FP0};
403 /** Number of return FPRs */
404 int NUM_RETURN_FPRS = RETURN_FPRS.length;
405
406 /** Native volatile GPRS */
407 GPR[] NATIVE_VOLATILE_GPRS = VM.buildFor32Addr() ? new GPR[]{EAX, ECX, EDX} : new GPR[]{EAX, ECX, EDX, R8, R9, R10, R11};
408 /** Native non-volatile GPRS */
409 GPR[] NATIVE_NONVOLATILE_GPRS = VM.buildFor32Addr() ? new GPR[]{EBX, EBP, EDI, ESI} : new GPR[]{EBX, EBP, R12, R13, R14, R15};
410
411 /** Native volatile FPRS */
412 FloatingPointMachineRegister[] NATIVE_VOLATILE_FPRS = ALL_FPRS;
413 /** Native non-volatile FPRS */
414 FloatingPointMachineRegister[] NATIVE_NONVOLATILE_FPRS = new FloatingPointMachineRegister[0];
415
416 /** General purpose registers to pass arguments to native code */
417 GPR[] NATIVE_PARAMETER_GPRS =
418 VM.buildFor32Addr() ? new GPR[0]
419 : new GPR[]{EDI /*R7*/, ESI /*R6*/, EDX /*R2*/, ECX /*R1*/, R8, R9};
420
421 /** Floating point registers to pass arguments to native code */
422 FloatingPointMachineRegister[] NATIVE_PARAMETER_FPRS =
423 VM.buildFor32Addr() ? new FloatingPointMachineRegister[0]
424 : new XMM[]{XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7};
425 // CHECKSTYLE:ON
426 }