#ifndef _rename_exec_fs
#define _rename_exec_fs
/******************************************************************************
** FILE: rename_exec.fs
** Functions to access register values durring execution,
** and to do necessary cleanup when instructions retire.
*/
#include "param.h"
#include "funits.h"
#include "rename_regs.h"
#include "rename_types.fs"
#include "rename_alloc.fs"
#include "rename_data.fs"
#include "sparc_v9_regs.fs"
///////////////////////////////////////////////////////////////////////////////
// Determine if the data read by an instruction is ready
//
fun srcs_ready(var srcq : SrcRef queue, inum)
{
for(src in srcq) {
if(0?cvt(uchar) < src.bypass && src.bypass <= inum?cvt(uchar))
if(instq[+(inum?cvt(uchar)-src.bypass)].ftype!=FU_DONE?cvt(uchar))
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// Read & write data values from physical registers.
//
fun rmap_read(var src : SrcRef, inum) : unsigned[64]
{
if(src.bypass == 0?cvt(uchar) || src.bypass > inum?cvt(uchar)) {
switch(src.rtype?cvt(ulong)) {
case REG_LITERAL:
return src.literal?sext(64);
case REG_GLOBAL:
return global_registers[src.regnum];
case REG_WINDOW:
return register_windows[src.regnum];
case REG_FP:
return fregs[src.regnum]?ext(64);
case REG_CCR:
if(src.regnum == 0?cvt(uchar))
return CCR?bits(8)?cvt(unsigned[64]);
return CCR?bits(4,7)?cvt(unsigned[64]);
case REG_FCC:
return fcc[src.regnum]?bits(2)?cvt(unsigned[64]);
case REG_Y:
return Y?ext(64);
}
}
return destq[+(inum?cvt(uchar)-src.bypass)][src.outnum];
}
fun rmap_write(outnum, value, inum)
{
destq[+inum][outnum] = value?cast(unsigned[_])?cvt(unsigned[64]);
}
///////////////////////////////////////////////////////////////////////////////
// rmap_retire() -- Retiring instructions. Under the current scheme,
// destination data must be moved to architectural registers here.
//
fun rmap_retire(num)
{
val ii = 0;
while(ii < num) {
val jj = 0;
while(jj < instq[+ii].destq?length()) {
val dest = instq[+ii].destq[+jj];
switch(dest.rtype?cvt(ulong)) {
case REG_LITERAL: ; // throw this data away
case REG_GLOBAL:
global_registers[dest.regnum] = destq[+ii][jj];
case REG_WINDOW:
register_windows[dest.regnum] = destq[+ii][jj];
case REG_FP:
fregs[dest.regnum] = destq[+ii][jj]?bits(32);
case REG_CCR:
assert(dest.regnum == 0?cvt(uchar));
CCR = destq[+ii][jj]?cvt(cc);
case REG_FCC:
fcc[dest.regnum] = destq[+ii][jj]?cvt(cc);
case REG_Y:
Y = destq[+ii][jj]?bits(32);
case REG_FSR: ; // handled in execute()
}
jj = jj + 1;
}
ii = ii + 1;
}
destq?pop_front(num);
}
///////////////////////////////////////////////////////////////////////////////
// Rollback the rmap. (Support for speculative execution.)
//
fun rmap_rollback(inum)
{
destq?pop_back(destq?length() - inum);
}
#endif