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