#ifndef _sparc_v9_regs_fs #define _sparc_v9_regs_fs /****************************************************************************** ** FILE: sparc_v9_regs.fs ** Facile description file for the SPARC v.9 registers. */ #include "instq.fs" #include "rename_decode.fs" #define NWINDOWS 8 // number of architectural register windows #define NUM_WREGS 128 // total number of registers in windows // // Architectural registers val PC : stream; val nPC : stream; val nPC2 : stream; val CCR = 0?cvt(cc); val fcc = array(4) { 0?cvt(cc) }; val Y : ulong = 0; extern get_FSR4() : unsigned[32]; extern get_FSR8() : unsigned[64]; extern set_FSR4(unsigned[32]) : void; extern set_FSR8(unsigned[64]) : void; // // integer registers: val global_registers = array(7) { 0?ext(64) }; val register_windows = array(NUM_WREGS) { 0?ext(64) }; type cwp_t = unsigned[5]; val CWP = 0?bits(5); val CWP0 = 0?bits(5); val CANSAVE = (NWINDOWS-2)?bits(5); val CANRESTORE = 0?bits(5); val OTHERWIN = 0?bits(5); val CLEANWIN = (NWINDOWS-1)?bits(5); fun regs_init(sp) { register_windows[14] = sp?sext(64); } fun Rx_src(var inst : InstOp, i0) { val ii = i0?ext(32); if(ii == 0) inst.srcq?push_back(literal_src(0)); else if(ii < 8) inst.srcq?push_back(rmap_src(REG_GLOBAL,ii-1)); else { val win = (CWP?cvt(ulong) - (ii / 16) + NWINDOWS) % NWINDOWS; ii = ii & 0xf?ext(32); inst.srcq?push_back(rmap_src(REG_WINDOW,16*win+ii)); } } fun Rx_dest(var inst : InstOp, i0) { val ii = i0?ext(32); if(ii >= 8) { val win = (CWP?cvt(ulong) - (ii / 16) + NWINDOWS) % NWINDOWS; ii = ii & 0xf?ext(32); inst.destq?push_back(rmap_dest(REG_WINDOW,16*win+ii)); } else if(ii > 0) { inst.destq?push_back(rmap_dest(REG_GLOBAL,ii-1)); } else { val dest : DestRef; dest.rtype = REG_LITERAL?cvt(uchar); dest.regnum = 0?cvt(uchar); inst.destq?push_back(dest); } } fun R8_src(var inst : InstOp, i0) { val ii = i0?ext(32); Rx_src(inst,ii); Rx_src(inst,ii+1); } fun R8_dest(var inst : InstOp, i0) { val ii = i0?ext(32); Rx_dest(inst,ii); Rx_dest(inst,ii+1); } // // floating-point registers: val fregs = array(64) { 0?ext(32) }; fun F4_src(var inst : InstOp, ii) { inst.srcq?push_back(rmap_src(REG_FP,ii)); } fun F4_dest(var inst : InstOp, ii) { inst.destq?push_back(rmap_dest(REG_FP,ii)); } fun F8_src(var inst : InstOp, i0) { val ii = i0?ext(32)&(~1) | (i0?bit(0)?ext(32)<<5); F4_src(inst,ii); F4_src(inst,ii+1); } fun F8_dest(var inst : InstOp, i0) { val ii = i0?ext(32)&(~1) | (i0?bit(0)?ext(32)<<5); F4_dest(inst,ii); F4_dest(inst,ii+1); } // // Memory access: fun M1(a) { return system?memory(1,a)?ext(64); } fun M1s(a) { return system?memory(1,a)?sext(64); } fun M1(a,vv) { system?memory(1,a) = vv?cast(unsigned[_])?bits(8); } fun M2(a) { return system?memory(2,a)?ext(64); } fun M2s(a) { return system?memory(2,a)?sext(64); } fun M2(a,vv) { system?memory(2,a) = vv?cast(unsigned[_])?bits(16); } fun M4(a) { return system?memory(4,a)?ext(64); } fun M4s(a) { return system?memory(4,a)?sext(64); } fun M4(a,vv) { system?memory(4,a) = vv?cast(unsigned[_])?bits(32); } fun M8(a) { return system?memory(8,a); } fun M8(a,vv) { system?memory(8,a) = vv?cast(unsigned[64]); } /////////////////////////////////////////////////////////////////////////////// // External functions providing access to processor data structures. // extern get_CCR() : cc; extern set_CCR(cc) : void; fun get_CCR() : cc { return CCR; } fun set_CCR(CCR1 : cc) : void { CCR = CCR1; } extern get_fcc(ulong) : cc; extern set_fcc(ulong,cc) : void; fun get_fcc(ii : ulong) : cc { return fcc[ii]; } fun set_fcc(ii : ulong, CC1 : cc) : void { fcc[ii] = CC1; } extern get_R4(cwp_t,ulong) : ulong; extern set_R4(cwp_t,ulong,ulong) : void; fun get_R4(cwp : cwp_t, i0 : ulong) { val ii = i0?ext(32); if(ii == 0) return 0?ext(32); else if(ii < 8) return global_registers[ii-1]?bits(32); else { val win = (cwp?cvt(ulong) - (ii / 16) + NWINDOWS) % NWINDOWS; ii = ii & 0xf?ext(32); return register_windows[16*win+ii]?bits(32); } } fun set_R4(cwp : cwp_t, i0 : ulong, vv : ulong) { val ii = i0?ext(32); if(ii >= 8) { val win = (cwp?cvt(ulong) - (ii / 16) + NWINDOWS) % NWINDOWS; ii = ii & 0xf?ext(32); register_windows[16*win+ii] = vv?sext(64); } else if(ii > 0) { global_registers[ii-1] = vv?sext(64); } } #endif