/****************************************************************************** ** FILE: sparc_v9_reg.fs ** Facile description file for the SPARC v.9 registers. */ #define NWINDOWS 8 val PC = 0?cvt(stream); // program counter val nPC = 0?cvt(stream); // next program counter val nPC2 = 0?cvt(stream); // next next program counter val CCR = 0?cvt(cc); // integer condition codes val fcc = array(4) { 0?cvt(cc) }; // FP condition codes val Y : ulong = 0; // Y register for multiply & divide // Floating status register (implemented externally) 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(NWINDOWS) { array(16) { 0?ext(64) } }; type cwp_t = unsigned[5]; val CWP = 0?bits(5); // current window pointer val CANSAVE = (NWINDOWS-2)?bits(5); val CANRESTORE = 0?bits(5); val OTHERWIN = 0?bits(5); val CLEANWIN = (NWINDOWS-1)?bits(5); fun Rx(i0) { // get 64-bit register value val ii = i0?ext(32); if(ii == 0) return 0?ext(64); else if(ii < 8) return global_registers[ii-1]; else { val win = (CWP?cvt(ulong) - (ii / 16) + NWINDOWS) % NWINDOWS; ii = ii & 0xf?ext(32); return register_windows[win][ii]; } } fun Rx(i0,vv) { // set 64-bit register value val ii = i0?ext(32); if(ii >= 8) { val win = (CWP?cvt(ulong) - (ii / 16) + NWINDOWS) % NWINDOWS; ii = ii & 0xf?ext(32); register_windows[win][ii] = vv; } else if(ii > 0) { global_registers[ii-1] = vv; } } fun R4(ii) { return Rx(ii)?bits(32); } // get 32-bit register value fun R4(ii,vv) { Rx(ii, vv?sext(64)); } // set 32-bit register value fun R8(i0) { // make a 64-bit value from two 32-bit register val ii = i0?ext(32); val xx = (Rx(ii) & 0xffffffff?ext(64)) << 32; return xx | (Rx(ii+1) & 0xffffffff?ext(64)); } fun R8(i0,vv) { // set two 32-bit registers from a 64 bit value val ii = i0?ext(32); Rx(ii, vv >> 32); Rx(ii+1, vv & 0xffffffff?ext(64)); } // // floating-point registers: val fregs = array(64) { 0?ext(32) }; fun F4(ii) { return fregs[ii]?cast(float); } fun F4(ii,vv) { fregs[ii] = vv?cast(unsigned[_])?cvt(ulong); } fun F8(i0) { // get concatination of two 32-bit fp-registers val ii = i0?ext(32)&(~1) | (i0?bit(0)?ext(32)<<5); val xx = fregs[ii]?ext(64) << 32; return (xx | fregs[ii+1]?ext(64))?cast(double); } fun F8(i0,vv) { // set two 32-bit fp-registers val ii = i0?ext(32)&(~1) | (i0?bit(0)?ext(32)<<5); fregs[ii] = vv?cast(unsigned[64])?bits(32,63); fregs[ii+1] = vv?cast(unsigned[64])?bits(32); } // // 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[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[win][ii] = vv?sext(64); } else if(ii > 0) { global_registers[ii-1] = vv?sext(64); } }