/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.architecture;
import org.jikesrvm.VM;
import org.jikesrvm.mm.mminterface.MemoryManager;
import org.jikesrvm.runtime.ArchEntrypoints;
import org.jikesrvm.runtime.Magic;
import org.vmmagic.pragma.Untraced;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.Offset;
import org.vmmagic.unboxed.Word;
import org.vmmagic.unboxed.WordArray;
import org.vmmagic.pragma.Entrypoint;
import org.vmmagic.pragma.NonMoving;
import org.vmmagic.pragma.Uninterruptible;
/**
* The machine state comprising a thread's execution context, used both for
* thread context switching and for software/hardware exception
* reporting/delivery.
*/
@Uninterruptible
@NonMoving
public abstract class AbstractRegisters {
/** General purpose registers */
@Untraced
@Entrypoint(fieldMayBeFinal = true)
private final WordArray gprs;
@Entrypoint(fieldMayBeFinal = true)
private final WordArray gprsShadow;
/** Floating point registers */
@Untraced
@Entrypoint(fieldMayBeFinal = true)
private final double[] fprs;
@Entrypoint(fieldMayBeFinal = true)
private final double[] fprsShadow;
/** Instruction address register */
@Entrypoint
protected Address ip;
/**
* Do exception registers currently contain live values? Set by C hardware
* exception handler and RuntimeEntrypoints.athrow and reset by each
* implementation of ExceptionDeliverer.deliverException
*/
@Entrypoint
private boolean inuse;
protected AbstractRegisters() {
gprs = gprsShadow = MemoryManager.newNonMovingWordArray(ArchConstants.getNumberOfGPRs());
fprs = fprsShadow = MemoryManager.newNonMovingDoubleArray(ArchConstants.getNumberOfFPRs());
}
public final boolean getInUse() {
return inuse;
}
public final void setInUse(boolean b) {
inuse = b;
}
public final WordArray getGPRs() {
return gprs;
}
public final double[] getFPRs() {
return fprs;
}
/** @return Instruction address register */
public final Address getIP() {
return ip;
}
/**
* Sets instruction address register.
* @param ip the new value for the instruction address register
*/
public final void setIP(Address ip) {
this.ip = ip;
}
/** @return memory location of IP register in this data structure */
public final Address getIPLocation() {
Offset ipOffset = ArchEntrypoints.registersIPField.getOffset();
return Magic.objectAsAddress(this).plus(ipOffset);
}
/** Zeroes all registers */
public void clear() {
for (int i = 0; i < gprs.length(); ++i) {
gprs.set(i, Word.zero());
}
for (int i = 0; i < fprs.length; ++i) {
fprs[i] = 0.;
}
ip = Address.zero();
}
protected void dump() {
for (int i = 0; i < gprs.length(); ++i) {
VM.sysWriteln("gprs[", i, "] = ", gprs.get(i));
}
for (int i = 0; i < fprs.length; ++i) {
VM.sysWriteln("fprs[", i, "] = ", fprs[i]);
}
VM.sysWriteln("ip = ", ip);
}
/**
* The following method initializes a thread stack as if
* "startoff" method had been called by an empty baseline-compiled
* "sentinel" frame with one local variable
*
* @param ip The instruction pointer for the "startoff" method
* @param sp The base of the stack
*/
public abstract void initializeStack(Address ip, Address sp);
/**
* A thread's stack has been moved or resized.
* Adjust the ESP register to reflect new position.
*
* @param delta The displacement to be applied
* @param traceAdjustments Log all adjustments to stderr if true
*/
public abstract void adjustESP(Offset delta, boolean traceAdjustments);
/**
* Set ip & fp. used to control the stack frame at which a scan of
* the stack during GC will start, for ex., the top java frame for
* a thread that is blocked in native code during GC.
*
* @param returnAddress the new return address (i.e. ip)
* @param callerFramePointer the new frame pointer (i.e. fp)
*/
public abstract void setInnermost(Address returnAddress, Address callerFramePointer);
public abstract Address getInnermostFramePointer();
public abstract void unwindStackFrame();
public abstract Address getInnermostInstructionAddress();
}