home *** CD-ROM | disk | FTP | other *** search
- /*
- * register.c
- * Manage register file.
- *
- * Copyright (c) 1996 Systems Architecture Research Centre,
- * City University, London, UK.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
- */
-
- #include <stdio.h>
- #include <assert.h>
- #include "register.h"
- #include "constants.h"
- #include "classMethod.h"
-
- static int stackPtr;
-
- /*
- * Assign registers to block of instructions.
- */
- void
- allocateRegisters(methods* m)
- {
- int i;
- int nrop;
- instn* ipc;
- int nr;
-
- stackPtr = MAXSTACK / 2;
- initRegisters();
-
- for (nr = m->codelen, ipc = m->insn; nr > 0; nr--, ipc++) {
-
- /* For soft instructions or those which use the stack directly
- (sync), we dont bother with register allocation */
- if (instnTable[ipc->op].coding != i_hard) {
- syncRegisters();
- }
- else {
- nrop = instnTable[ipc->op].in;
- for (i = 0; i < nrop; i++) {
- ipc->in[i].valid = false;
- stackPtr--;
- assert(stackPtr >= 0);
- readRegister(&ipc->in[i]);
- }
- nrop = instnTable[ipc->op].out;
- for (i = nrop - 1; i >= 0; i--) {
- ipc->out[i].valid = false;
- writeRegister(&ipc->out[i]);
- stackPtr++;
- assert(stackPtr < MAXSTACK);
- }
- /* At the end of a block it is necessary to make sure that
- eveything is back on the stack */
- if (ipc->type == i_endblock) {
- syncRegisters();
- }
- }
- }
- }
-
- /*
- * Initialise register to all be unused.
- */
- void
- initRegisters(void)
- {
- int i;
- nativeReg* r;
-
- for (i = 0; i < NRREG; i++) {
- r = ®isterFile[i];
- r->stack = MAXSTACK;
- r->lastWrite = 0;
- }
- }
-
- /*
- * Allocate the register which corresponds to the current stack
- * location.
- */
- void
- readRegister(operand* op)
- {
- nativeReg* r;
-
- #if 0
- r = ®isterFile[stackPtr & (NRREG-1)];
- #endif
- r = ®isterFile[stackPtr % NRREG];
- /*
- * If r->stack == stackPtr then a register is already
- * available - just reuse it. If not we will need to
- * reload.
- */
- if (r->stack > stackPtr) {
- op->valid = true;
- }
- r->stack = stackPtr;
- op->reg = r;
- }
-
- /*
- * Allocate a register to correspond to the current stack
- * location.
- */
- void
- writeRegister(operand* op)
- {
- nativeReg* r;
-
- #if 0
- r = ®isterFile[stackPtr & (NRREG-1)];
- #endif
- r = ®isterFile[stackPtr % NRREG];
- /*
- * If r->stack == stackPtr then a register is already
- * available - just reuse it. If not we will need to
- * spill.
- */
- if (r->stack < stackPtr) {
- assert(r->lastWrite != 0);
- assert(r->lastWrite->reg == r);
- r->lastWrite->valid = true;
- }
- r->stack = stackPtr;
- r->lastWrite = op;
- op->reg = r;
- }
-
- /*
- * Put back any live registers to the stack.
- */
- void
- syncRegisters(void)
- {
- int i;
- nativeReg* r;
-
- for (i = 0; i < NRREG; i++) {
- r = ®isterFile[i];
- if (r->stack < stackPtr) {
- assert(r->lastWrite != 0);
- assert(r->lastWrite->reg == r);
- r->lastWrite->valid = true;
- r->stack = MAXSTACK;
- }
- }
- }
-