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