fun execute(var inst : InstOp, inum)
{
val ftime = inst.ftime;
if(ftime <= 0?cvt(uchar)) {
inst.ftype = 6 ?cvt(uchar);
return false;
}
if(inst.trap) { if(inum > 0) return false; }
if(!srcs_ready(inst.srcq,inum)) return false;
val ftype = inst.ftype;
if(!fu_alloc(ftype)) return false;
ftime = ftime - 1?cvt(uchar);
inst.ftime = ftime;
if(ftime > 0?cvt(uchar)) return false;
if(!fu_finish(ftype,inst,inum))
return false;
fun i1_src(ii) { return rmap_read(inst.srcq[+ii],inum)?cvt(uchar); }
fun i2_src(ii) { return rmap_read(inst.srcq[+ii],inum)?cvt(ushort); }
fun i4_src(ii) { return rmap_read(inst.srcq[+ii],inum)?cvt(ulong); }
fun x8_src(ii) { return rmap_read(inst.srcq[+ii],inum)?cvt(ullong); }
fun i8_src(ii) {
return ((rmap_read(inst.srcq[+ii],inum)<<32) |
(rmap_read(inst.srcq[+(ii+1)],inum)&0xffffffff?ext(64)));
}
fun f4_src(ii) {
return rmap_read(inst.srcq[+ii],inum)?bits(32)?cast(float);
}
fun f8_src(ii) {
return ((rmap_read(inst.srcq[+(ii+1)],inum)&0xffffffff?ext(64)) |
(rmap_read(inst.srcq[+ii],inum)<<32))?cast(double);
}
fun cc_src(ii) { return rmap_read(inst.srcq[+ii],inum)?cvt(cc); }
fun dest(outnum,value) { rmap_write(outnum,value,inum); }
fun ddest(outnum,value) {
rmap_write(outnum,value?cast(unsigned[64])?bits(32,63),inum);
rmap_write(outnum+1,value?cast(unsigned[64])?bits(32),inum);
}
fun trap(tnum) {
if(tnum == 3) {
flush_windows(CWP,CANRESTORE);
CANSAVE = (8 - 2)?cvt(cwp_t);
CANRESTORE = 0?cvt(cwp_t);
} else {
trap_sparc(tnum+256,CWP,CANRESTORE);
}
is_trap = false;
}
val ccr;
switch(inst.op?cvt(ulong)) {
case 0 : ;
case 1 : if(_z(x8_src(0)) != inst.taken) rollback = true;
case 2 : if(_lez(x8_src(0)) != inst.taken) rollback = true;
case 3 : if(_lz(x8_src(0)) != inst.taken) rollback = true;
case 4 : if(_nz(x8_src(0)) != inst.taken) rollback = true;
case 5 : if(_gz(x8_src(0)) != inst.taken) rollback = true;
case 6 : if(_gez(x8_src(0)) != inst.taken) rollback = true;
case 7 : if(f_u(cc_src(0)) != inst.taken) rollback = true;
case 8 : if(f_g(cc_src(0)) != inst.taken) rollback = true;
case 9 : if(f_ug(cc_src(0)) != inst.taken) rollback = true;
case 10 : if(f_l(cc_src(0)) != inst.taken) rollback = true;
case 11 : if(f_ul(cc_src(0)) != inst.taken) rollback = true;
case 12 : if(f_lg(cc_src(0)) != inst.taken) rollback = true;
case 13 : if(f_ne(cc_src(0)) != inst.taken) rollback = true;
case 14 : if(f_e(cc_src(0)) != inst.taken) rollback = true;
case 15 : if(f_ue(cc_src(0)) != inst.taken) rollback = true;
case 16 : if(f_ge(cc_src(0)) != inst.taken) rollback = true;
case 17 : if(f_uge(cc_src(0)) != inst.taken) rollback = true;
case 18 : if(f_le(cc_src(0)) != inst.taken) rollback = true;
case 19 : if(f_ule(cc_src(0)) != inst.taken) rollback = true;
case 20 : if(f_o(cc_src(0)) != inst.taken) rollback = true;
case 21 : if(i_ne(cc_src(0)) != inst.taken) rollback = true;
case 22 : if(i_e(cc_src(0)) != inst.taken) rollback = true;
case 23 : if(i_g(cc_src(0)) != inst.taken) rollback = true;
case 24 : if(i_le(cc_src(0)) != inst.taken) rollback = true;
case 25 : if(i_ge(cc_src(0)) != inst.taken) rollback = true;
case 26 : if(i_l(cc_src(0)) != inst.taken) rollback = true;
case 27 : if(i_gu(cc_src(0)) != inst.taken) rollback = true;
case 28 : if(i_leu(cc_src(0)) != inst.taken) rollback = true;
case 29 : if(i_cc(cc_src(0)) != inst.taken) rollback = true;
case 30 : if(i_cs(cc_src(0)) != inst.taken) rollback = true;
case 31 : if(i_pos(cc_src(0)) != inst.taken) rollback = true;
case 32 : if(i_neg(cc_src(0)) != inst.taken) rollback = true;
case 33 : if(i_vc(cc_src(0)) != inst.taken) rollback = true;
case 34 : if(i_vs(cc_src(0)) != inst.taken) rollback = true;
case 35 : dest(0,x8_src(0));
case 36 : if(i_ne(cc_src(0))) dest(0,x8_src(1));
case 37 : if(i_e(cc_src(0))) dest(0,x8_src(1));
case 38 : if(i_g(cc_src(0))) dest(0,x8_src(1));
case 39 : if(i_le(cc_src(0))) dest(0,x8_src(1));
case 40 : if(i_ge(cc_src(0))) dest(0,x8_src(1));
case 41 : if(i_l(cc_src(0))) dest(0,x8_src(1));
case 42 : if(i_gu(cc_src(0))) dest(0,x8_src(1));
case 43 : if(i_leu(cc_src(0))) dest(0,x8_src(1));
case 44 : if(i_cc(cc_src(0))) dest(0,x8_src(1));
case 45 : if(i_cs(cc_src(0))) dest(0,x8_src(1));
case 46 : if(i_pos(cc_src(0))) dest(0,x8_src(1));
case 47 : if(i_neg(cc_src(0))) dest(0,x8_src(1));
case 48 : if(i_vc(cc_src(0))) dest(0,x8_src(1));
case 49 : if(i_vs(cc_src(0))) dest(0,x8_src(1));
case 50 : if(f_u(cc_src(0))) dest(0,x8_src(1));
case 51 : if(f_g(cc_src(0))) dest(0,x8_src(1));
case 52 : if(f_ug(cc_src(0))) dest(0,x8_src(1));
case 53 : if(f_l(cc_src(0))) dest(0,x8_src(1));
case 54 : if(f_ul(cc_src(0))) dest(0,x8_src(1));
case 55 : if(f_lg(cc_src(0))) dest(0,x8_src(1));
case 56 : if(f_ne(cc_src(0))) dest(0,x8_src(1));
case 57 : if(f_e(cc_src(0))) dest(0,x8_src(1));
case 58 : if(f_ue(cc_src(0))) dest(0,x8_src(1));
case 59 : if(f_ge(cc_src(0))) dest(0,x8_src(1));
case 60 : if(f_uge(cc_src(0))) dest(0,x8_src(1));
case 61 : if(f_le(cc_src(0))) dest(0,x8_src(1));
case 62 : if(f_ule(cc_src(0))) dest(0,x8_src(1));
case 63 : if(f_o(cc_src(0))) dest(0,x8_src(1));
case 64 : if(_z(x8_src(0))) dest(0,x8_src(1));
case 65 : if(_lez(x8_src(0))) dest(0,x8_src(1));
case 66 : if(_lz(x8_src(0))) dest(0,x8_src(1));
case 67 : if(_nz(x8_src(0))) dest(0,x8_src(1));
case 68 : if(_gz(x8_src(0))) dest(0,x8_src(1));
case 69 : if(_gez(x8_src(0))) dest(0,x8_src(1));
case 70 : trap(i4_src(0));
case 71 : if(i_ne(cc_src(0))) trap(i4_src(1));
case 72 : if(i_e(cc_src(0))) trap(i4_src(1));
case 73 : if(i_g(cc_src(0))) trap(i4_src(1));
case 74 : if(i_le(cc_src(0))) trap(i4_src(1));
case 75 : if(i_ge(cc_src(0))) trap(i4_src(1));
case 76 : if(i_l(cc_src(0))) trap(i4_src(1));
case 77 : if(i_gu(cc_src(0))) trap(i4_src(1));
case 78 : if(i_leu(cc_src(0))) trap(i4_src(1));
case 79 : if(i_cc(cc_src(0))) trap(i4_src(1));
case 80 : if(i_cs(cc_src(0))) trap(i4_src(1));
case 81 : if(i_pos(cc_src(0))) trap(i4_src(1));
case 82 : if(i_neg(cc_src(0))) trap(i4_src(1));
case 83 : if(i_vc(cc_src(0))) trap(i4_src(1));
case 84 : if(i_vs(cc_src(0))) trap(i4_src(1));
case 85 : dest(0, x8_src(0) + x8_src(1));
case 89 : dest(0, x8_src(0) - x8_src(1));
case 93 : dest(0, x8_src(0) & x8_src(1));
case 95 : dest(0, x8_src(0) & ~x8_src(1));
case 97 : dest(0, x8_src(0) | x8_src(1));
case 99 : dest(0, x8_src(0) | ~x8_src(1));
case 101 : dest(0, x8_src(0) ^ x8_src(1));
case 103 : dest(0, x8_src(0) ^ ~x8_src(1));
case 86 : dest(0, (x8_src(0) + x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 90 : dest(0, (x8_src(0) - x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 94 : dest(0, (x8_src(0) & x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 96 : dest(0, (x8_src(0) & ~x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 98 : dest(0, (x8_src(0) | x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 100 : dest(0, (x8_src(0) | ~x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 102 : dest(0, (x8_src(0) ^ x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 104 : dest(0, (x8_src(0) ^ ~x8_src(1))?cc(ccr));
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 87 :
dest(0, x8_src(0) + x8_src(1) + cc_src(2)?bit(0)?ext(64));
case 91 :
dest(0, x8_src(0) - x8_src(1) - cc_src(2)?bit(0)?ext(64));
case 88 :
val ccr2 = 0x00?cvt(cc);
val x1 = x8_src(0); val x2 = x8_src(1);
val xx = ((x1 + x2)?cc(ccr2) + cc_src(2)?bit(0)?ext(64))?cc(ccr);
dest(0, xx);
dest(1, ((ccr?bits(8) & 0b11011101) | (ccr2?bits(8) & 0x11) |
(((x1?bit(31)==x2?bit(31)) &&
(xx?bit(31)!=x1?bit(31)))?ext(8)<<1) |
(((x1?bit(63)==x2?bit(63)) &&
(xx?bit(63)!=x1?bit(63)))?ext(8)<<5))
? cvt(unsigned[64]));
case 92 :
val ccr2 = 0x00?cvt(cc);
val x1 = x8_src(0); val x2 = x8_src(1);
val xx = ((x1 - x2)?cc(ccr2) - cc_src(2)?bit(0)?ext(64))?cc(ccr);
dest(0, xx);
dest(1, ((ccr?bits(8) & 0b11011101) | (ccr2?bits(8) & 0x11) |
(((x1?bit(31)!=x2?bit(31)) &&
(xx?bit(31)!=x1?bit(31)))?ext(8)<<1) |
(((x1?bit(63)!=x2?bit(63)) &&
(xx?bit(63)!=x1?bit(63)))?ext(8)<<5))
? cvt(unsigned[64]));
case 105 : dest(0, x8_src(0) * x8_src(1));
case 107 : dest(0, x8_src(0) / x8_src(1));
case 106 : dest(0, (+x8_src(0) / +x8_src(1))
? cast(unsigned[64]));
case 108 : dest(0, x8_src(0) << x8_src(1)?bits(5));
case 109 : dest(0, i4_src(0) >> x8_src(1)?bits(5));
case 110 : dest(0, (+i4_src(0) >> x8_src(1)?bits(5))
? sext(64));
case 111 : dest(0, x8_src(0) << x8_src(1)?bits(6));
case 112 : dest(0, x8_src(0) >> x8_src(1)?bits(6));
case 113 : dest(0, (+x8_src(0) >> x8_src(1)?bits(6))
? cast(unsigned[64]));
case 114 :
val x1 = x8_src(0); val x2 = x8_src(1);
dest(0, (x1 + x2)?cc(ccr));
if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
ccr = (ccr?bits(8) | 0x02)?cvt(cc);
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 115 :
val x1 = x8_src(0); val x2 = x8_src(1);
dest(0, (x1 + x2)?cc(ccr));
if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
ccr = (ccr?bits(8) | 0x02)?cvt(cc);
dest(1, ccr?bits(8)?cvt(unsigned[64]));
if(ccr?bit(1)) trap(0x23?ext(32) );
case 116 :
val x1 = x8_src(0); val x2 = x8_src(1);
dest(0, (x1 - x2)?cc(ccr));
if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
ccr = (ccr?bits(8) | 0x02)?cvt(cc);
dest(1, ccr?bits(8)?cvt(unsigned[64]));
case 117 :
val x1 = x8_src(0); val x2 = x8_src(1);
dest(0, (x1 - x2)?cc(ccr));
if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
ccr = (ccr?bits(8) | 0x02)?cvt(cc);
dest(1, ccr?bits(8)?cvt(unsigned[64]));
if(ccr?bit(1)) trap(0x23?ext(32) );
case 118 :
val xx = (x8_src(0)<<32) | (x8_src(1)&((-1)?ext(64)));
dest(0, u_div32(xx,x8_src(2),ccr));
case 119 :
val xx = (x8_src(0)<<32) | (x8_src(1)&((-1)?ext(64)));
dest(0, s_div32(xx,x8_src(2),ccr));
case 120 :
val xx = (x8_src(0)&((-1)?ext(64))) * (x8_src(1)&((-1)?ext(64)));
dest(0, xx >> 32); dest(1, xx?bits(32)?sext(64));
case 121 :
val xx = +x8_src(0)?bits(32)?sext(64) * +x8_src(1)?bits(32)?sext(64);
dest(0, xx >> 32); dest(1, xx?bits(32)?sext(64));
case 122 :
val xx = (x8_src(0)<<32) | (x8_src(1)&((-1)?ext(64)));
xx = u_div32(xx,x8_src(2),ccr); dest(0, xx);
dest(1, get_div_mul_cc(xx,ccr));
case 123 :
val xx = (x8_src(0)<<32) | (x8_src(1)&((-1)?ext(64)));
xx = s_div32(xx,x8_src(2),ccr); dest(0, xx);
dest(1, get_div_mul_cc(xx,ccr));
case 126 :
val y0 = x8_src(0)?bit(0); ccr = cc_src(3);
dest(0, (x8_src(0)>>1) | ((x8_src(1)&1?ext(64))<<31));
val xx = (i4_src(1)>>1) | ((ccr?bit(3)^ccr?bit(1))?ext(32)<<31);
if(y0) dest(1, (xx + i4_src(2)?bits(32))?cc(ccr));
else dest(1, (xx + 0)?cc(ccr));
dest(2, ccr?bits(8));
case 127 :
val xx = x8_src(0);
val ii=0; val count=0?ext(64);
while(ii < 64) {
count = count + ((xx >> ii) & 0x1?ext(64));
ii = ii + 1;
}
dest(0, count);
case 128 : cache_flush();
case 129 : trap(3);
case 130 : dest(0, x8_src(0));
case 131 : dest(0, x8_src(0) ^ x8_src(1));
case 133 : dest(0, f4_src(0) + f4_src(1));
case 134 : ddest(0, f8_src(0) + f8_src(2));
case 135 : dest(0, f4_src(0) - f4_src(1));
case 136 : ddest(0, f8_src(0) - f8_src(2));
case 137 : (f4_src(0) - f4_src(1))?cc(ccr); dest(0, ccr?bits(8));
case 138 : (f8_src(0) - f8_src(2))?cc(ccr); dest(0, ccr?bits(8));
case 139 : (f4_src(0) - f4_src(1))?cc(ccr); dest(0, ccr?bits(8));
if(f_u(ccr)) trap(0x21?ext(32) );
case 140 : (f8_src(0) - f8_src(2))?cc(ccr); dest(0, ccr?bits(8));
if(f_u(ccr)) trap(0x21?ext(32) );
case 141 : ddest(0, f4_src(0)?cvt(signed[64]));
case 142 : ddest(0, f8_src(0)?cvt(signed[64]));
case 143 : dest(0, f4_src(0)?cvt(signed[32]));
case 144 : dest(0, f8_src(0)?cvt(signed[32]));
case 145 : ddest(0, f4_src(0)?cvt(double));
case 146 : dest(0, i8_src(0)?cast(signed[_])?cvt(float));
case 147 : ddest(0, i8_src(0)?cast(signed[_])?cvt(double));
case 148 : dest(0, i4_src(0)?cast(signed[_])?cvt(float));
case 149 : ddest(0, i4_src(0)?cast(signed[_])?cvt(double));
case 150 : dest(0, f8_src(0)?cvt(float));
case 151 : dest(0, f4_src(0));
case 152 : ddest(0, f8_src(0));
case 153 : dest(0, -f4_src(0));
case 154 : ddest(0, -f8_src(0));
case 155 : if(f4_src(0) < 0?cvt(float)) dest(0, -f4_src(0));
else dest(0, f4_src(0));
case 156 : if(f8_src(0) < 0?cvt(double)) ddest(0, -f8_src(0));
else ddest(0, f8_src(0));
case 157 : dest(0, f4_src(0) * f4_src(1));
case 158 : ddest(0, f8_src(0) * f8_src(2));
case 159 : dest(0, f4_src(0) / f4_src(1));
case 160 : ddest(0, f8_src(0) / f8_src(2));
case 161 : ddest(0, f4_src(0)?cvt(double)
* f4_src(1)?cvt(double));
case 162 : dest(0, sqrt(f4_src(0)));
case 163 : ddest(0, sqrt(f8_src(0)));
case 164 : dest(0, M1s(x8_src(0) + x8_src(1)));
case 165 : dest(0, M2s(x8_src(0) + x8_src(1)));
case 166 : dest(0, M4s(x8_src(0) + x8_src(1)));
case 167 : dest(0, M1(x8_src(0) + x8_src(1)));
case 168 : dest(0, M2(x8_src(0) + x8_src(1)));
case 169 : dest(0, M4(x8_src(0) + x8_src(1)));
case 170 : dest(0, M8(x8_src(0) + x8_src(1)));
case 171 :
val xx = M8(x8_src(0) + x8_src(1));
dest(0, xx >> 32); dest(1, xx & (-1)?ext(64));
case 174 : M1(x8_src(0) + x8_src(1), i1_src(2));
case 175 : M2(x8_src(0) + x8_src(1), i2_src(2));
case 176 : M4(x8_src(0) + x8_src(1), i4_src(2));
case 177 : M8(x8_src(0) + x8_src(1), x8_src(2));
case 178 : M8(x8_src(0) + x8_src(1), i8_src(2));
case 181 :
val aa = x8_src(0); val xx = M4(aa);
if((x8_src(1)&(-1)?ext(64)) == xx) M4(aa,i4_src(2));
dest(0, xx);
case 182 :
val aa = x8_src(0); val xx = M8(aa);
if(x8_src(1) == xx) M8(aa,x8_src(2));
dest(0, xx);
case 183 :
val aa = x8_src(0) + x8_src(1);
dest(0, M1(aa)); M1(aa,0xff);
case 184 :
val aa = x8_src(0) + x8_src(1); val xx = M4(aa);
M4(aa,i4_src(2)); dest(0, xx);
case 172 : set_FSR4(M4(x8_src(0)+x8_src(1))?bits(32));
is_trap = false;
case 173 : set_FSR8(M8(x8_src(0)+x8_src(1))); is_trap = false;
case 179 : M4(x8_src(0)+x8_src(1),get_FSR4()); is_trap = false;
case 180 : M8(x8_src(0)+x8_src(1),get_FSR8()); is_trap = false;
case 185 :
dest(0, x8_src(0) + x8_src(1));
if(inst.trap) {
save_regs(CWP0,CANRESTORE);
CANSAVE = (CANRESTORE?cvt(ulong) - 1)?cvt(cwp_t);
CANRESTORE = 1?cvt(cwp_t);
is_trap = false;
}
case 186 :
dest(0, x8_src(0) + x8_src(1));
if(inst.trap) {
restore_regs(CWP0);
if(CANSAVE?cvt(ulong) < 8 -2)
CANSAVE = (CANSAVE?cvt(ulong) + 1)?cvt(cwp_t);
is_trap = false;
}
case 187 :
val npc = (x8_src(0) + x8_src(1))?cvt(stream)?static;
if(inst.trap) {
restore_regs(CWP0);
if(CANSAVE?cvt(ulong) < 8 -2)
CANSAVE = (CANSAVE?cvt(ulong) + 1)?cvt(cwp_t);
is_trap = false;
}
if(instq?length() == inum+1) nPC = npc;
else {
assert(instq?length() == inum+2);
instq[-1].npc = npc; PC = npc;
if(!instq[-1].taken) nPC = PC + 4;
}
case 188 :
val npc = (x8_src(0) + x8_src(1))?cvt(stream)?static;
if(instq?length() == inum+1) nPC = npc;
else {
assert(instq?length() == inum+2);
instq[-1].npc = npc; PC = npc;
if(!instq[-1].taken) nPC = PC + 4;
}
case 189 : no_instruction(); is_trap = false;
}
return true;
}