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