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.architecture;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.mm.mminterface.MemoryManager;
017import org.jikesrvm.runtime.ArchEntrypoints;
018import org.jikesrvm.runtime.Magic;
019import org.vmmagic.pragma.Untraced;
020import org.vmmagic.unboxed.Address;
021import org.vmmagic.unboxed.Offset;
022import org.vmmagic.unboxed.Word;
023import org.vmmagic.unboxed.WordArray;
024import org.vmmagic.pragma.Entrypoint;
025import org.vmmagic.pragma.NonMoving;
026import org.vmmagic.pragma.Uninterruptible;
027
028/**
029 * The machine state comprising a thread's execution context, used both for
030 * thread context switching and for software/hardware exception
031 * reporting/delivery.
032 */
033@Uninterruptible
034@NonMoving
035public abstract class AbstractRegisters {
036
037  /** General purpose registers */
038  @Untraced
039  @Entrypoint
040  private final WordArray gprs;
041  private final WordArray gprsShadow;
042  /** Floating point registers */
043  @Untraced
044  @Entrypoint
045  private final double[] fprs;
046  private final double[] fprsShadow;
047  /** Instruction address register */
048  @Entrypoint
049  protected Address ip;
050
051  /**
052   * Do exception registers currently contain live values? Set by C hardware
053   * exception handler and RuntimeEntrypoints.athrow and reset by each
054   * implementation of ExceptionDeliverer.deliverException
055   */
056  @Entrypoint
057  private boolean inuse;
058
059  protected AbstractRegisters() {
060    gprs = gprsShadow = MemoryManager.newNonMovingWordArray(ArchConstants.getNumberOfGPRs());
061    fprs = fprsShadow = MemoryManager.newNonMovingDoubleArray(ArchConstants.getNumberOfFPRs());
062  }
063
064  public final boolean getInUse() {
065    return inuse;
066  }
067
068  public final void setInUse(boolean b) {
069    inuse = b;
070  }
071
072  public final WordArray getGPRs() {
073    return gprs;
074  }
075
076  public final double[] getFPRs() {
077    return fprs;
078  }
079
080  /** @return Instruction address register */
081
082  public final Address getIP() {
083    return ip;
084  }
085
086  /**
087   * Sets instruction address register.
088   * @param ip the new value for the instruction address register
089   */
090  public final void setIP(Address ip) {
091    this.ip = ip;
092  }
093
094  /** @return memory location of IP register in this data structure */
095  public final Address getIPLocation() {
096    Offset ipOffset = ArchEntrypoints.registersIPField.getOffset();
097    return Magic.objectAsAddress(this).plus(ipOffset);
098  }
099
100  /** Zeroes all registers */
101  public void clear() {
102    for (int i = 0; i < gprs.length(); ++i) {
103      gprs.set(i, Word.zero());
104    }
105    for (int i = 0; i < fprs.length; ++i) {
106      fprs[i] = 0.;
107    }
108    ip = Address.zero();
109  }
110
111  protected void dump() {
112    for (int i = 0; i < gprs.length(); ++i) {
113      VM.sysWriteln("gprs[", i, "] = ", gprs.get(i));
114    }
115    for (int i = 0; i < fprs.length; ++i) {
116      VM.sysWriteln("fprs[", i, "] = ", fprs[i]);
117    }
118    VM.sysWriteln("ip = ", ip);
119  }
120
121  /**
122   * The following method initializes a thread stack as if
123   * "startoff" method had been called by an empty baseline-compiled
124   * "sentinel" frame with one local variable
125   *
126   * @param ip The instruction pointer for the "startoff" method
127   * @param sp The base of the stack
128   */
129  public abstract void initializeStack(Address ip, Address sp);
130
131  /**
132   * A thread's stack has been moved or resized.
133   * Adjust the ESP register to reflect new position.
134   *
135   * @param delta The displacement to be applied
136   * @param traceAdjustments Log all adjustments to stderr if true
137   */
138  public abstract void adjustESP(Offset delta, boolean traceAdjustments);
139
140  /**
141   * Set ip &amp; fp. used to control the stack frame at which a scan of
142   * the stack during GC will start, for ex., the top java frame for
143   * a thread that is blocked in native code during GC.
144   *
145   * @param returnAddress the new return address (i.e. ip)
146   * @param callerFramePointer the new frame pointer (i.e. fp)
147   */
148  public abstract void setInnermost(Address returnAddress, Address callerFramePointer);
149
150  public abstract Address getInnermostFramePointer();
151
152  public abstract void unwindStackFrame();
153
154  public abstract Address getInnermostInstructionAddress();
155
156}