#ifndef _rename_decode_fs
#define _rename_decode_fs
/******************************************************************************
** FILE: rename_decode.fs
** Functions used durring instruction decode to set up register renaming.
*/

#include "param.h"
#include "rename_regs.h"
#include "rename_types.fs"
#include "rename_alloc.fs"
#include "rename_data.fs"
#include "instq.fs"

///////////////////////////////////////////////////////////////////////////////
// Set up mapping for src and dest registers.
// rmap_src() -- lookup mapping for src register
// literal_src() -- set source data as a literal value
// rmap_dest() -- alter mapping to bind a new destination register
//

fun rmap_src(rtype, regnum,	// identify register type & num
	     inum)		// index of instruction
{
    val src : SrcRef;
    src.rtype = rtype?cvt(uchar);
    src.regnum = regnum?cvt(uchar);
    src.literal = 0;

    val ii = +(inum - 1);
    while(ii >= +0) {
	// Search for register in all earlier instructions
	val jj = 0;
	while(jj < instq[ii].destq?length()) {
	    // Search all destinations of an instruction
	    val dest = instq[ii].destq[+jj];
	    if(dest.rtype == rtype?cvt(uchar) &&
	       dest.regnum == regnum?cvt(uchar)) {
		// Value in produced by an earlier instruction
		src.bypass = (+inum - ii)?cvt(uchar);
		src.outnum = jj?cvt(uchar);
		return src;
	    }
	    jj = jj + 1;
	}
	ii = ii - +1;
    }

    // Value is in the architectural register file
    src.bypass = 0?cvt(uchar);
    src.outnum = 0?cvt(uchar);
    return src;
}

fun literal_src(lit)			// literal value
{
    val src : SrcRef;
    src.rtype = REG_LITERAL?cvt(uchar);
    src.regnum = 0?cvt(uchar);
    src.bypass = 0?cvt(uchar);
    src.outnum = 0?cvt(uchar);
    src.literal = lit?cvt(ulong);
    return src;
}

fun rmap_dest(rtype, regnum,		// identify register type & num
	      inum)			// instruction index
{
    val dest : DestRef;
    dest.rtype = rtype?cvt(uchar);
    dest.regnum = regnum?cvt(uchar);
    return dest;
}

fun rmap_src(rtype, regnum)
{ return rmap_src(rtype,regnum,instq?length()); }

fun rmap_dest(rtype, regnum)
{ return rmap_dest(rtype,regnum,instq?length()); }

///////////////////////////////////////////////////////////////////////////////
// Update rmap structures after fetching 1 instruction
//

fun rmap_fetch()
{
    destq?push_back();
}

///////////////////////////////////////////////////////////////////////////////
// Checkpoint the rmap to support speculative execution.
//

fun rmap_checkpoint()
{}

#endif