#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