decoder.isa revision 2561
1//////////////////////////////////////////////////////////////////// 2// 3// The actual decoder specification 4// 5 6decode OP default Unknown::unknown() 7{ 8 0x0: decode OP2 9 { 10 //Throw an illegal instruction acception 11 0x0: Trap::illtrap({{fault = new IllegalInstruction;}}); 12 0x1: decode BPCC 13 { 14 format Branch19 15 { 16 0x0: bpcci({{ 17 if(passesCondition(CcrIcc, COND2)) 18 NNPC = xc->readPC() + disp; 19 }}); 20 0x2: bpccx({{ 21 if(passesCondition(CcrXcc, COND2)) 22 NNPC = xc->readPC() + disp; 23 }}); 24 } 25 } 26 0x2: Branch22::bicc({{ 27 if(passesCondition(CcrIcc, COND2)) 28 NNPC = xc->readPC() + disp; 29 }}); 30 0x3: decode RCOND2 31 { 32 format BranchSplit 33 { 34 0x1: bpreq({{ 35 if(Rs1 == 0) 36 NNPC = xc->readPC() + disp; 37 }}); 38 0x2: bprle({{ 39 if(Rs1 <= 0) 40 NNPC = xc->readPC() + disp; 41 }}); 42 0x3: bprl({{ 43 if(Rs1 < 0) 44 NNPC = xc->readPC() + disp; 45 }}); 46 0x5: bprne({{ 47 if(Rs1 != 0) 48 NNPC = xc->readPC() + disp; 49 }}); 50 0x6: bprg({{ 51 if(Rs1 > 0) 52 NNPC = xc->readPC() + disp; 53 }}); 54 0x7: bprge({{ 55 if(Rs1 >= 0) 56 NNPC = xc->readPC() + disp; 57 }}); 58 } 59 } 60 //SETHI (or NOP if rd == 0 and imm == 0) 61 0x4: SetHi::sethi({{Rd = imm;}}); 62 0x5: Trap::fbpfcc({{fault = new FpDisabled;}}); 63 0x6: Trap::fbfcc({{fault = new FpDisabled;}}); 64 } 65 0x1: Branch30::call({{ 66 R15 = xc->readPC(); 67 NNPC = R15 + disp; 68 }}); 69 0x2: decode OP3 { 70 format IntOp { 71 0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}}); 72 0x01: and({{Rd = Rs1.udw & Rs2_or_imm13;}}); 73 0x02: or({{Rd = Rs1.udw | Rs2_or_imm13;}}); 74 0x03: xor({{Rd = Rs1.udw ^ Rs2_or_imm13;}}); 75 0x04: sub({{Rd = Rs1.sdw - Rs2_or_imm13;}}); 76 0x05: andn({{Rd = Rs1.udw & ~Rs2_or_imm13;}}); 77 0x06: orn({{Rd = Rs1.udw | ~Rs2_or_imm13;}}); 78 0x07: xnor({{Rd = ~(Rs1.udw ^ Rs2_or_imm13);}}); 79 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + CcrIccC;}}); 80 0x09: mulx({{Rd = Rs1 * Rs2_or_imm13;}}); 81 0x0A: umul({{ 82 Rd = Rs1.udw<31:0> * Rs2_or_imm13<31:0>; 83 YValue = Rd<63:32>; 84 }}); 85 0x0B: smul({{ 86 Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>; 87 YValue = Rd.sdw; 88 }}); 89 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 + CcrIccC;}}); 90 0x0D: udivx({{ 91 if(Rs2_or_imm13 == 0) fault = new DivisionByZero; 92 else Rd.udw = Rs1.udw / Rs2_or_imm13; 93 }}); 94 0x0E: udiv({{ 95 if(Rs2_or_imm13 == 0) fault = new DivisionByZero; 96 else 97 { 98 Rd.udw = ((YValue << 32) | Rs1.udw<31:0>) / Rs2_or_imm13; 99 if(Rd.udw >> 32 != 0) 100 Rd.udw = 0xFFFFFFFF; 101 } 102 }}); 103 0x0F: sdiv({{ 104 if(Rs2_or_imm13 == 0) 105 fault = new DivisionByZero; 106 else 107 { 108 Rd.udw = ((YValue << 32) | Rs1.sdw<31:0>) / Rs2_or_imm13; 109 if(Rd.udw<63:31> != 0) 110 Rd.udw = 0x7FFFFFFF; 111 else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF) 112 Rd.udw = 0xFFFFFFFF80000000; 113 } 114 }}); 115 } 116 format IntOpCc { 117 0x10: addcc({{ 118 int64_t resTemp, val2 = Rs2_or_imm13; 119 Rd = resTemp = Rs1 + val2;}}, 120 {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, 121 {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, 122 {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, 123 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 124 ); 125 0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}}); 126 0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}}); 127 0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}}); 128 0x14: subcc({{ 129 int64_t resTemp, val2 = Rs2_or_imm13; 130 Rd = resTemp = Rs1 - val2;}}, 131 {{((Rs1 & 0xFFFFFFFF - val2 & 0xFFFFFFFF) >> 31)}}, 132 {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, 133 {{(((Rs1 >> 1) + (~val2) >> 1) + 134 ((Rs1 | ~val2) & 0x1))<63:>}}, 135 {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} 136 ); 137 0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}}); 138 0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}}); 139 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}}); 140 0x18: addccc({{ 141 int64_t resTemp, val2 = Rs2_or_imm13; 142 int64_t carryin = CcrIccC; 143 Rd = resTemp = Rs1 + val2 + carryin;}}, 144 {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 145 + carryin)}}, 146 {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, 147 {{((Rs1 >> 1) + (val2 >> 1) + 148 ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, 149 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 150 ); 151 0x1A: umulcc({{ 152 uint64_t resTemp, val2 = Rs2_or_imm13; 153 Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; 154 YValue = resTemp<63:32>;}}, 155 {{0}},{{0}},{{0}},{{0}}); 156 0x1B: smulcc({{ 157 int64_t resTemp, val2 = Rs2_or_imm13; 158 Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; 159 YValue = resTemp<63:32>;}}, 160 {{0}},{{0}},{{0}},{{0}}); 161 0x1C: subccc({{ 162 int64_t resTemp, val2 = Rs2_or_imm13; 163 int64_t carryin = CcrIccC; 164 Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, 165 {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}}, 166 {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, 167 {{(((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}}, 168 {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} 169 ); 170 0x1D: udivxcc({{ 171 if(Rs2_or_imm13 == 0) fault = new DivisionByZero; 172 else Rd = Rs1.udw / Rs2_or_imm13;}} 173 ,{{0}},{{0}},{{0}},{{0}}); 174 0x1E: udivcc({{ 175 uint32_t resTemp, val2 = Rs2_or_imm13; 176 int32_t overflow; 177 if(val2 == 0) fault = new DivisionByZero; 178 else 179 { 180 resTemp = (uint64_t)((YValue << 32) | Rs1.udw<31:0>) / val2; 181 overflow = (resTemp<63:32> != 0); 182 if(overflow) Rd = resTemp = 0xFFFFFFFF; 183 else Rd = resTemp; 184 } }}, 185 {{0}}, 186 {{overflow}}, 187 {{0}}, 188 {{0}} 189 ); 190 0x1F: sdivcc({{ 191 int32_t resTemp, val2 = Rs2_or_imm13; 192 int32_t overflow, underflow; 193 if(val2 == 0) fault = new DivisionByZero; 194 else 195 { 196 Rd = resTemp = (int64_t)((YValue << 32) | Rs1.sdw<31:0>) / val2; 197 overflow = (resTemp<63:31> != 0); 198 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); 199 if(overflow) Rd = resTemp = 0x7FFFFFFF; 200 else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000; 201 else Rd = resTemp; 202 } }}, 203 {{0}}, 204 {{overflow || underflow}}, 205 {{0}}, 206 {{0}} 207 ); 208 0x20: taddcc({{ 209 int64_t resTemp, val2 = Rs2_or_imm13; 210 Rd = resTemp = Rs1 + val2; 211 int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, 212 {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, 213 {{overflow}}, 214 {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, 215 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 216 ); 217 0x21: tsubcc({{ 218 int64_t resTemp, val2 = Rs2_or_imm13; 219 Rd = resTemp = Rs1 + val2; 220 int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, 221 {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31}}, 222 {{overflow}}, 223 {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, 224 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 225 ); 226 0x22: taddcctv({{ 227 int64_t resTemp, val2 = Rs2_or_imm13; 228 Rd = resTemp = Rs1 + val2; 229 int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); 230 if(overflow) fault = new TagOverflow;}}, 231 {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, 232 {{overflow}}, 233 {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, 234 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 235 ); 236 0x23: tsubcctv({{ 237 int64_t resTemp, val2 = Rs2_or_imm13; 238 Rd = resTemp = Rs1 + val2; 239 int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); 240 if(overflow) fault = new TagOverflow;}}, 241 {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, 242 {{overflow}}, 243 {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, 244 {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} 245 ); 246 0x24: mulscc({{ 247 int64_t resTemp, multiplicand = Rs2_or_imm13; 248 int32_t multiplier = Rs1<31:0>; 249 int32_t savedLSB = Rs1<0:>; 250 multiplier = multiplier<31:1> | 251 ((CcrIccN 252 ^ CcrIccV) << 32); 253 if(!YValue<0:>) 254 multiplicand = 0; 255 Rd = resTemp = multiplicand + multiplier; 256 YValue = YValue<31:1> | (savedLSB << 31);}}, 257 {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}}, 258 {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}}, 259 {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}}, 260 {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}} 261 ); 262 } 263 format IntOp 264 { 265 0x25: decode X { 266 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); 267 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); 268 } 269 0x26: decode X { 270 0x0: srl({{Rd = Rs1.uw >> (I ? SHCNT32 : Rs2<4:0>);}}); 271 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}}); 272 } 273 0x27: decode X { 274 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); 275 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}}); 276 } 277 0x28: decode RS1 { 278 0x0: rdy({{Rd = YValue;}}); 279 0x2: rdccr({{Rd = Ccr;}}); 280 0x3: rdasi({{Rd = Asi;}}); 281 0x4: PrivTick::rdtick({{Rd = Tick;}}); 282 0x5: rdpc({{Rd = xc->readPC();}}); 283 0x6: rdfprs({{Rd = Fprs;}}); 284 0xF: decode I { 285 0x0: Nop::membar({{/*Membar isn't needed yet*/}}); 286 0x1: Nop::stbar({{/*Stbar isn't needed yet*/}}); 287 } 288 } 289 0x2A: decode RS1 { 290 format Priv 291 { 292 0x0: rdprtpc({{ 293 Rd = xc->readMiscReg(MISCREG_TPC_BASE + Tl); 294 }}); 295 0x1: rdprtnpc({{ 296 Rd = xc->readMiscReg(MISCREG_TNPC_BASE + Tl); 297 }}); 298 0x2: rdprtstate({{ 299 Rd = xc->readMiscReg(MISCREG_TSTATE_BASE + Tl); 300 }}); 301 0x3: rdprtt({{ 302 Rd = xc->readMiscReg(MISCREG_TT_BASE + Tl); 303 }}); 304 0x4: rdprtick({{Rd = Tick;}}); 305 0x5: rdprtba({{Rd = Tba;}}); 306 0x6: rdprpstate({{Rd = Pstate;}}); 307 0x7: rdprtl({{Rd = Tl;}}); 308 0x8: rdprpil({{Rd = Pil;}}); 309 0x9: rdprcwp({{Rd = Cwp;}}); 310 0xA: rdprcansave({{Rd = Cansave;}}); 311 0xB: rdprcanrestore({{Rd = Canrestore;}}); 312 0xC: rdprcleanwin({{Rd = Cleanwin;}}); 313 0xD: rdprotherwin({{Rd = Otherwin;}}); 314 0xE: rdprwstate({{Rd = Wstate;}}); 315 } 316 //The floating point queue isn't implemented right now. 317 0xF: Trap::rdprfq({{fault = new IllegalInstruction;}}); 318 0x1F: Priv::rdprver({{Rd = Ver;}}); 319 } 320 0x2B: BasicOperate::flushw({{ 321 if(NWindows - 2 - Cansave == 0) 322 { 323 if(Otherwin) 324 fault = new SpillNOther(WstateOther); 325 else 326 fault = new SpillNNormal(WstateNormal); 327 } 328 }}); 329 0x2C: decode MOVCC3 330 { 331 0x0: Trap::movccfcc({{fault = new FpDisabled;}}); 332 0x1: decode CC 333 { 334 0x0: movcci({{ 335 if(passesCondition(CcrIcc, COND4)) 336 Rd = (I ? SIMM11 : RS2); 337 }}); 338 0x2: movccx({{ 339 if(passesCondition(CcrXcc, COND4)) 340 Rd = (I ? SIMM11 : RS2); 341 }}); 342 } 343 } 344 0x2D: sdivx({{ 345 if(Rs2_or_imm13 == 0) fault = new DivisionByZero; 346 else Rd.sdw = Rs1.sdw / Rs2_or_imm13; 347 }}); 348 0x2E: decode RS1 { 349 0x0: IntOp::popc({{ 350 int64_t count = 0; 351 uint64_t temp = Rs2_or_imm13; 352 //Count the 1s in the front 4bits until none are left 353 uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; 354 while(temp) 355 { 356 count += oneBits[temp & 0xF]; 357 temp = temp >> 4; 358 } 359 }}); 360 } 361 0x2F: decode RCOND3 362 { 363 0x1: movreq({{if(Rs1 == 0) Rd = Rs2_or_imm10;}}); 364 0x2: movrle({{if(Rs1 <= 0) Rd = Rs2_or_imm10;}}); 365 0x3: movrl({{if(Rs1 < 0) Rd = Rs2_or_imm10;}}); 366 0x5: movrne({{if(Rs1 != 0) Rd = Rs2_or_imm10;}}); 367 0x6: movrg({{if(Rs1 > 0) Rd = Rs2_or_imm10;}}); 368 0x7: movrge({{if(Rs1 >= 0) Rd = Rs2_or_imm10;}}); 369 } 370 0x30: decode RD { 371 0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}}); 372 0x2: wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}}); 373 0x3: wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}); 374 0x6: wrfprs({{Asi = Rs1 ^ Rs2_or_imm13;}}); 375 0xF: Trap::sir({{fault = new SoftwareInitiatedReset;}}); 376 } 377 0x31: decode FCN { 378 0x0: BasicOperate::saved({{/*Boogy Boogy*/}}); 379 0x1: BasicOperate::restored({{/*Boogy Boogy*/}}); 380 } 381 0x32: decode RD { 382 format Priv 383 { 384 0x0: wrprtpc({{ 385 xc->setMiscReg(MISCREG_TPC_BASE + Tl, 386 Rs1 ^ Rs2_or_imm13); 387 }}); 388 0x1: wrprtnpc({{ 389 xc->setMiscReg(MISCREG_TNPC_BASE + Tl, 390 Rs1 ^ Rs2_or_imm13); 391 }}); 392 0x2: wrprtstate({{ 393 xc->setMiscReg(MISCREG_TSTATE_BASE + Tl, 394 Rs1 ^ Rs2_or_imm13); 395 }}); 396 0x3: wrprtt({{ 397 xc->setMiscReg(MISCREG_TT_BASE + Tl, 398 Rs1 ^ Rs2_or_imm13); 399 }}); 400 0x4: wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}}); 401 0x5: wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); 402 0x6: wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); 403 0x7: wrprtl({{Tl = Rs1 ^ Rs2_or_imm13;}}); 404 0x8: wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}}); 405 0x9: wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}}); 406 0xA: wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}}); 407 0xB: wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}}); 408 0xC: wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}}); 409 0xD: wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}}); 410 0xE: wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}}); 411 } 412 } 413 0x34: Trap::fpop1({{fault = new FpDisabled;}}); 414 0x35: Trap::fpop2({{fault = new FpDisabled;}}); 415 0x38: Branch::jmpl({{ 416 Addr target = Rs1 + Rs2_or_imm13; 417 if(target & 0x3) 418 fault = new MemAddressNotAligned; 419 else 420 { 421 Rd = xc->readPC(); 422 NNPC = target; 423 } 424 }}); 425 0x39: Branch::return({{ 426 //If both MemAddressNotAligned and 427 //a fill trap happen, it's not clear 428 //which one should be returned. 429 Addr target = Rs1 + Rs2_or_imm13; 430 if(target & 0x3) 431 fault = new MemAddressNotAligned; 432 else 433 NNPC = target; 434 if(fault == NoFault) 435 { 436 //CWP should be set directly so that it always happens 437 //Also, this will allow writing to the new window and 438 //reading from the old one 439 Cwp = (Cwp - 1 + NWindows) % NWindows; 440 if(Canrestore == 0) 441 { 442 if(Otherwin) 443 fault = new FillNOther(WstateOther); 444 else 445 fault = new FillNNormal(WstateNormal); 446 } 447 else 448 { 449 Rd = Rs1 + Rs2_or_imm13; 450 Cansave = Cansave + 1; 451 Canrestore = Canrestore - 1; 452 } 453 //This is here to make sure the CWP is written 454 //no matter what. This ensures that the results 455 //are written in the new window as well. 456 xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); 457 } 458 }}); 459 0x3A: decode CC 460 { 461 0x0: Trap::tcci({{ 462 if(passesCondition(CcrIcc, COND2)) 463 { 464 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); 465 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); 466#if FULL_SYSTEM 467 fault = new TrapInstruction(lTrapNum); 468#else 469 DPRINTF(Sparc, "The syscall number is %d\n", R1); 470 xc->syscall(R1); 471#endif 472 } 473 else 474 { 475 DPRINTF(Sparc, "Didn't fire on %s\n", CondTestAbbrev[machInst<25:28>]); 476 } 477 }}); 478 0x2: Trap::tccx({{ 479 if(passesCondition(CcrXcc, COND2)) 480 { 481 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); 482 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); 483#if FULL_SYSTEM 484 fault = new TrapInstruction(lTrapNum); 485#else 486 DPRINTF(Sparc, "The syscall number is %d\n", R1); 487 xc->syscall(R1); 488#endif 489 } 490 }}); 491 } 492 0x3B: Nop::flush({{/*Instruction memory flush*/}}); 493 0x3C: save({{ 494 //CWP should be set directly so that it always happens 495 //Also, this will allow writing to the new window and 496 //reading from the old one 497 if(Cansave == 0) 498 { 499 if(Otherwin) 500 fault = new SpillNOther(WstateOther); 501 else 502 fault = new SpillNNormal(WstateNormal); 503 Cwp = (Cwp + 2) % NWindows; 504 } 505 else if(Cleanwin - Canrestore == 0) 506 { 507 Cwp = (Cwp + 1) % NWindows; 508 fault = new CleanWindow; 509 } 510 else 511 { 512 Cwp = (Cwp + 1) % NWindows; 513 Rd = Rs1 + Rs2_or_imm13; 514 Cansave = Cansave - 1; 515 Canrestore = Canrestore + 1; 516 } 517 //This is here to make sure the CWP is written 518 //no matter what. This ensures that the results 519 //are written in the new window as well. 520 xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); 521 }}); 522 0x3D: restore({{ 523 //CWP should be set directly so that it always happens 524 //Also, this will allow writing to the new window and 525 //reading from the old one 526 Cwp = (Cwp - 1 + NWindows) % NWindows; 527 if(Canrestore == 0) 528 { 529 if(Otherwin) 530 fault = new FillNOther(WstateOther); 531 else 532 fault = new FillNNormal(WstateNormal); 533 } 534 else 535 { 536 Rd = Rs1 + Rs2_or_imm13; 537 Cansave = Cansave + 1; 538 Canrestore = Canrestore - 1; 539 } 540 //This is here to make sure the CWP is written 541 //no matter what. This ensures that the results 542 //are written in the new window as well. 543 xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); 544 }}); 545 0x3E: decode FCN { 546 0x0: Priv::done({{ 547 if(Tl == 0) 548 return new IllegalInstruction; 549 Cwp = xc->readMiscReg(MISCREG_TSTATE_CWP_BASE + Tl); 550 Asi = xc->readMiscReg(MISCREG_TSTATE_ASI_BASE + Tl); 551 Ccr = xc->readMiscReg(MISCREG_TSTATE_CCR_BASE + Tl); 552 Pstate = xc->readMiscReg(MISCREG_TSTATE_PSTATE_BASE + Tl); 553 NPC = xc->readMiscReg(MISCREG_TNPC_BASE + Tl); 554 NNPC = NPC + 4; 555 Tl = Tl - 1; 556 }}); 557 0x1: BasicOperate::retry({{ 558 if(Tl == 0) 559 return new IllegalInstruction; 560 Cwp = xc->readMiscReg(MISCREG_TSTATE_CWP_BASE + Tl); 561 Asi = xc->readMiscReg(MISCREG_TSTATE_ASI_BASE + Tl); 562 Ccr = xc->readMiscReg(MISCREG_TSTATE_CCR_BASE + Tl); 563 Pstate = xc->readMiscReg(MISCREG_TSTATE_PSTATE_BASE + Tl); 564 NPC = xc->readMiscReg(MISCREG_TPC_BASE + Tl); 565 NNPC = xc->readMiscReg(MISCREG_TNPC_BASE + Tl); 566 Tl = Tl - 1; 567 }}); 568 } 569 } 570 } 571 0x3: decode OP3 { 572 format Load { 573 0x00: lduw({{Rd = Mem;}}, {{32}}); 574 0x01: ldub({{Rd = Mem;}}, {{8}}); 575 0x02: lduh({{Rd = Mem;}}, {{16}}); 576 0x03: ldd({{ 577 uint64_t val = Mem; 578 RdLow = val<31:0>; 579 RdHigh = val<63:32>; 580 }}, {{64}}); 581 } 582 format Store { 583 0x04: stw({{Mem = Rd.sw;}}, {{32}}); 584 0x05: stb({{Mem = Rd.sb;}}, {{8}}); 585 0x06: sth({{Mem = Rd.shw;}}, {{16}}); 586 0x07: std({{Mem = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{64}}); 587 } 588 format Load { 589 0x08: ldsw({{Rd = (int32_t)Mem;}}, {{32}}); 590 0x09: ldsb({{Rd = (int8_t)Mem;}}, {{8}}); 591 0x0A: ldsh({{Rd = (int16_t)Mem;}}, {{16}}); 592 0x0B: ldx({{Rd = (int64_t)Mem;}}, {{64}}); 593 0x0D: ldstub({{ 594 Rd = Mem; 595 Mem = 0xFF; 596 }}, {{8}}); 597 } 598 0x0E: Store::stx({{Mem = Rd}}, {{64}}); 599 0x0F: LoadStore::swap({{ 600 uint32_t temp = Rd; 601 Rd = Mem; 602 Mem = temp; 603 }}, {{32}}); 604 format Load { 605 0x10: lduwa({{Rd = Mem;}}, {{32}}); 606 0x11: lduba({{Rd = Mem;}}, {{8}}); 607 0x12: lduha({{Rd = Mem;}}, {{16}}); 608 0x13: ldda({{ 609 uint64_t val = Mem; 610 RdLow = val<31:0>; 611 RdHigh = val<63:32>; 612 }}, {{64}}); 613 } 614 format Store { 615 0x14: stwa({{Mem = Rd;}}, {{32}}); 616 0x15: stba({{Mem = Rd;}}, {{8}}); 617 0x16: stha({{Mem = Rd;}}, {{16}}); 618 0x17: stda({{Mem = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{64}}); 619 } 620 format Load { 621 0x18: ldswa({{Rd = (int32_t)Mem;}}, {{32}}); 622 0x19: ldsba({{Rd = (int8_t)Mem;}}, {{8}}); 623 0x1A: ldsha({{Rd = (int16_t)Mem;}}, {{16}}); 624 0x1B: ldxa({{Rd = (int64_t)Mem;}}, {{64}}); 625 } 626 0x1D: LoadStore::ldstuba({{ 627 Rd = Mem; 628 Mem = 0xFF; 629 }}, {{8}}); 630 0x1E: Store::stxa({{Mem = Rd}}, {{64}}); 631 0x1F: LoadStore::swapa({{ 632 uint32_t temp = Rd; 633 Rd = Mem; 634 Mem = temp; 635 }}, {{32}}); 636 format Trap { 637 0x20: ldf({{fault = new FpDisabled;}}); 638 0x21: decode X { 639 0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}}); 640 0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}}); 641 } 642 0x22: ldqf({{fault = new FpDisabled;}}); 643 0x23: lddf({{fault = new FpDisabled;}}); 644 0x24: stf({{fault = new FpDisabled;}}); 645 0x25: decode X { 646 0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}}); 647 0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}}); 648 } 649 0x26: stqf({{fault = new FpDisabled;}}); 650 0x27: stdf({{fault = new FpDisabled;}}); 651 0x2D: Nop::prefetch({{ }}); 652 0x30: ldfa({{return new FpDisabled;}}); 653 0x32: ldqfa({{fault = new FpDisabled;}}); 654 0x33: lddfa({{fault = new FpDisabled;}}); 655 0x34: stfa({{fault = new FpDisabled;}}); 656 0x35: stqfa({{fault = new FpDisabled;}}); 657 0x36: stdfa({{fault = new FpDisabled;}}); 658 0x3C: Cas::casa({{ 659 uint64_t val = Mem.uw; 660 if(Rs2.uw == val) 661 Mem.uw = Rd.uw; 662 Rd.uw = val; 663 }}); 664 0x3D: Nop::prefetcha({{ }}); 665 0x3E: Cas::casxa({{ 666 uint64_t val = Mem.udw; 667 if(Rs2 == val) 668 Mem.udw = Rd; 669 Rd = val; 670 }}); 671 } 672 } 673} 674