decoder.isa revision 7720
1// Copyright (c) 2006-2007 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// The actual decoder specification 34// 35 36decode OP default Unknown::unknown() 37{ 38 0x0: decode OP2 39 { 40 //Throw an illegal instruction acception 41 0x0: Trap::illtrap({{fault = new IllegalInstruction;}}); 42 format BranchN 43 { 44 //bpcc 45 0x1: decode COND2 46 { 47 //Branch Always 48 0x8: bpa(19, annul_code={{ 49 SparcISA::PCState pc = PCS; 50 pc.npc(pc.pc() + disp); 51 pc.nnpc(pc.npc() + 4); 52 PCS = pc; 53 }}); 54 //Branch Never 55 0x0: bpn(19, {{;}}, 56 annul_code={{ 57 SparcISA::PCState pc = PCS; 58 pc.nnpc(pc.npc() + 8); 59 pc.npc(pc.npc() + 4); 60 PCS = pc; 61 }}); 62 default: decode BPCC 63 { 64 0x0: bpcci(19, test={{passesCondition(Ccr<3:0>, COND2)}}); 65 0x2: bpccx(19, test={{passesCondition(Ccr<7:4>, COND2)}}); 66 } 67 } 68 //bicc 69 0x2: decode COND2 70 { 71 //Branch Always 72 0x8: ba(22, annul_code={{ 73 SparcISA::PCState pc = PCS; 74 pc.npc(pc.pc() + disp); 75 pc.nnpc(pc.npc() + 4); 76 PCS = pc; 77 }}); 78 //Branch Never 79 0x0: bn(22, {{;}}, 80 annul_code={{ 81 SparcISA::PCState pc = PCS; 82 pc.nnpc(pc.npc() + 8); 83 pc.npc(pc.npc() + 4); 84 PCS = pc; 85 }}); 86 default: bicc(22, test={{passesCondition(Ccr<3:0>, COND2)}}); 87 } 88 } 89 0x3: decode RCOND2 90 { 91 format BranchSplit 92 { 93 0x1: bpreq(test={{Rs1.sdw == 0}}); 94 0x2: bprle(test={{Rs1.sdw <= 0}}); 95 0x3: bprl(test={{Rs1.sdw < 0}}); 96 0x5: bprne(test={{Rs1.sdw != 0}}); 97 0x6: bprg(test={{Rs1.sdw > 0}}); 98 0x7: bprge(test={{Rs1.sdw >= 0}}); 99 } 100 } 101 //SETHI (or NOP if rd == 0 and imm == 0) 102 0x4: SetHi::sethi({{Rd.udw = imm;}}); 103 //fbpfcc 104 0x5: decode COND2 { 105 format BranchN { 106 //Branch Always 107 0x8: fbpa(22, annul_code={{ 108 SparcISA::PCState pc = PCS; 109 pc.npc(pc.pc() + disp); 110 pc.nnpc(pc.npc() + 4); 111 PCS = pc; 112 }}); 113 //Branch Never 114 0x0: fbpn(22, {{;}}, 115 annul_code={{ 116 SparcISA::PCState pc = PCS; 117 pc.nnpc(pc.npc() + 8); 118 pc.npc(pc.npc() + 4); 119 PCS = pc; 120 }}); 121 default: decode BPCC { 122 0x0: fbpfcc0(19, test= 123 {{passesFpCondition(Fsr<11:10>, COND2)}}); 124 0x1: fbpfcc1(19, test= 125 {{passesFpCondition(Fsr<33:32>, COND2)}}); 126 0x2: fbpfcc2(19, test= 127 {{passesFpCondition(Fsr<35:34>, COND2)}}); 128 0x3: fbpfcc3(19, test= 129 {{passesFpCondition(Fsr<37:36>, COND2)}}); 130 } 131 } 132 } 133 //fbfcc 134 0x6: decode COND2 { 135 format BranchN { 136 //Branch Always 137 0x8: fba(22, annul_code={{ 138 SparcISA::PCState pc = PCS; 139 pc.npc(pc.pc() + disp); 140 pc.nnpc(pc.npc() + 4); 141 PCS = pc; 142 }}); 143 //Branch Never 144 0x0: fbn(22, {{;}}, 145 annul_code={{ 146 SparcISA::PCState pc = PCS; 147 pc.nnpc(pc.npc() + 8); 148 pc.npc(pc.npc() + 4); 149 PCS = pc; 150 }}); 151 default: fbfcc(22, test= 152 {{passesFpCondition(Fsr<11:10>, COND2)}}); 153 } 154 } 155 } 156 0x1: BranchN::call(30, {{ 157 SparcISA::PCState pc = PCS; 158 if (Pstate<3:>) 159 R15 = (pc.pc())<31:0>; 160 else 161 R15 = pc.pc(); 162 pc.nnpc(R15 + disp); 163 PCS = pc; 164 }}); 165 0x2: decode OP3 { 166 format IntOp { 167 0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}}); 168 0x01: and({{Rd = Rs1.sdw & Rs2_or_imm13;}}); 169 0x02: or({{Rd = Rs1.sdw | Rs2_or_imm13;}}); 170 0x03: xor({{Rd = Rs1.sdw ^ Rs2_or_imm13;}}); 171 0x04: sub({{Rd = Rs1.sdw - Rs2_or_imm13;}}); 172 0x05: andn({{Rd = Rs1.sdw & ~Rs2_or_imm13;}}); 173 0x06: orn({{Rd = Rs1.sdw | ~Rs2_or_imm13;}}); 174 0x07: xnor({{Rd = ~(Rs1.sdw ^ Rs2_or_imm13);}}); 175 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + Ccr<0:0>;}}); 176 0x09: mulx({{Rd = Rs1.sdw * Rs2_or_imm13;}}); 177 0x0A: umul({{ 178 Rd = Rs1.udw<31:0> * Rs2_or_imm13<31:0>; 179 Y = Rd<63:32>; 180 }}); 181 0x0B: smul({{ 182 Rd.sdw = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>); 183 Y = Rd.sdw<63:32>; 184 }}); 185 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}}); 186 0x0D: udivx({{ 187 if(Rs2_or_imm13 == 0) fault = new DivisionByZero; 188 else Rd.udw = Rs1.udw / Rs2_or_imm13; 189 }}); 190 0x0E: udiv({{ 191 if(Rs2_or_imm13 == 0) fault = new DivisionByZero; 192 else 193 { 194 Rd.udw = ((Y << 32) | Rs1.udw<31:0>) / Rs2_or_imm13; 195 if(Rd.udw >> 32 != 0) 196 Rd.udw = 0xFFFFFFFF; 197 } 198 }}); 199 0x0F: sdiv({{ 200 if(Rs2_or_imm13.sdw == 0) 201 fault = new DivisionByZero; 202 else 203 { 204 Rd.udw = ((int64_t)((Y << 32) | Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw; 205 if((int64_t)Rd.udw >= std::numeric_limits<int32_t>::max()) 206 Rd.udw = 0x7FFFFFFF; 207 else if((int64_t)Rd.udw <= std::numeric_limits<int32_t>::min()) 208 Rd.udw = ULL(0xFFFFFFFF80000000); 209 } 210 }}); 211 } 212 format IntOpCc { 213 0x10: addcc({{ 214 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 215 Rd = res = op1 + op2; 216 }}); 217 0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}}); 218 0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}}); 219 0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}}); 220 0x14: subcc({{ 221 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 222 Rd = res = op1 - op2; 223 }}, sub=True); 224 0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}}); 225 0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}}); 226 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}}); 227 0x18: addccc({{ 228 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 229 Rd = res = op1 + op2 + Ccr<0:>; 230 }}); 231 0x1A: IntOpCcRes::umulcc({{ 232 uint64_t resTemp; 233 Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; 234 Y = resTemp<63:32>;}}); 235 0x1B: IntOpCcRes::smulcc({{ 236 int64_t resTemp; 237 Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>); 238 Y = resTemp<63:32>;}}); 239 0x1C: subccc({{ 240 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 241 Rd = res = op1 - op2 - Ccr<0:>; 242 }}, sub=True); 243 0x1D: IntOpCcRes::udivxcc({{ 244 if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; 245 else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 246 0x1E: IntOpCcRes::udivcc({{ 247 uint64_t resTemp; 248 uint32_t val2 = Rs2_or_imm13.udw; 249 int32_t overflow = 0; 250 if(val2 == 0) fault = new DivisionByZero; 251 else 252 { 253 resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2; 254 overflow = (resTemp<63:32> != 0); 255 if(overflow) Rd = resTemp = 0xFFFFFFFF; 256 else Rd = resTemp; 257 } 258 }}, iv={{overflow}}); 259 0x1F: IntOpCcRes::sdivcc({{ 260 int64_t val2 = Rs2_or_imm13.sdw<31:0>; 261 bool overflow = false, underflow = false; 262 if(val2 == 0) fault = new DivisionByZero; 263 else 264 { 265 Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2; 266 overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max()); 267 underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min()); 268 if(overflow) Rd = 0x7FFFFFFF; 269 else if(underflow) Rd = ULL(0xFFFFFFFF80000000); 270 } 271 }}, iv={{overflow || underflow}}); 272 0x20: taddcc({{ 273 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 274 Rd = res = Rs1 + op2; 275 }}, iv={{ 276 (op1 & mask(2)) || (op2 & mask(2)) || 277 findOverflow(32, res, op1, op2) 278 }}); 279 0x21: tsubcc({{ 280 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 281 Rd = res = Rs1 - op2; 282 }}, iv={{ 283 (op1 & mask(2)) || (op2 & mask(2)) || 284 findOverflow(32, res, op1, ~op2) 285 }}, sub=True); 286 0x22: taddcctv({{ 287 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 288 Rd = res = op1 + op2; 289 bool overflow = (op1 & mask(2)) || (op2 & mask(2)) || 290 findOverflow(32, res, op1, op2); 291 if(overflow) fault = new TagOverflow; 292 }}, iv={{overflow}}); 293 0x23: tsubcctv({{ 294 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; 295 Rd = res = op1 - op2; 296 bool overflow = (op1 & mask(2)) || (op2 & mask(2)) || 297 findOverflow(32, res, op1, ~op2); 298 if(overflow) fault = new TagOverflow; 299 }}, iv={{overflow}}, sub=True); 300 0x24: mulscc({{ 301 int32_t savedLSB = Rs1<0:>; 302 303 //Step 1 304 int64_t multiplicand = Rs2_or_imm13; 305 //Step 2 306 int32_t partialP = Rs1<31:1> | 307 ((Ccr<3:3> ^ Ccr<1:1>) << 31); 308 //Step 3 309 int32_t added = Y<0:> ? multiplicand : 0; 310 int64_t res, op1 = partialP, op2 = added; 311 Rd = res = partialP + added; 312 //Steps 4 & 5 313 Y = Y<31:1> | (savedLSB << 31); 314 }}); 315 } 316 format IntOp 317 { 318 0x25: decode X { 319 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); 320 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); 321 } 322 0x26: decode X { 323 0x0: srl({{Rd = Rs1.uw >> (I ? SHCNT32 : Rs2<4:0>);}}); 324 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}}); 325 } 326 0x27: decode X { 327 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); 328 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}}); 329 } 330 0x28: decode RS1 { 331 0x00: NoPriv::rdy({{Rd = Y<31:0>;}}); 332 //1 should cause an illegal instruction exception 333 0x02: NoPriv::rdccr({{Rd = Ccr;}}); 334 0x03: NoPriv::rdasi({{Rd = Asi;}}); 335 0x04: Priv::rdtick({{Rd = Tick;}}, {{Tick<63:>}}); 336 0x05: NoPriv::rdpc({{ 337 SparcISA::PCState pc = PCS; 338 if(Pstate<3:>) 339 Rd = (pc.pc())<31:0>; 340 else 341 Rd = pc.pc(); 342 }}); 343 0x06: NoPriv::rdfprs({{ 344 //Wait for all fpops to finish. 345 Rd = Fprs; 346 }}); 347 //7-14 should cause an illegal instruction exception 348 0x0F: decode I { 349 0x0: Nop::stbar({{/*stuff*/}}, IsWriteBarrier, MemWriteOp); 350 0x1: Nop::membar({{/*stuff*/}}, IsMemBarrier, MemReadOp); 351 } 352 0x10: Priv::rdpcr({{Rd = Pcr;}}); 353 0x11: Priv::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); 354 //0x12 should cause an illegal instruction exception 355 0x13: NoPriv::rdgsr({{ 356 fault = checkFpEnableFault(xc); 357 if (fault) 358 return fault; 359 Rd = Gsr; 360 }}); 361 //0x14-0x15 should cause an illegal instruction exception 362 0x16: Priv::rdsoftint({{Rd = Softint;}}); 363 0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}}); 364 0x18: Priv::rdstick({{Rd = Stick}}, {{Stick<63:>}}); 365 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}}); 366 0x1A: Priv::rdstrand_sts_reg({{ 367 if(Pstate<2:> && !Hpstate<2:>) 368 Rd = StrandStsReg<0:>; 369 else 370 Rd = StrandStsReg; 371 }}); 372 //0x1A is supposed to be reserved, but it reads the strand 373 //status register. 374 //0x1B-0x1F should cause an illegal instruction exception 375 } 376 0x29: decode RS1 { 377 0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}}); 378 0x01: HPriv::rdhprhtstate({{Rd = Htstate;}}, checkTl=true); 379 //0x02 should cause an illegal instruction exception 380 0x03: HPriv::rdhprhintp({{Rd = Hintp;}}); 381 //0x04 should cause an illegal instruction exception 382 0x05: HPriv::rdhprhtba({{Rd = Htba;}}); 383 0x06: HPriv::rdhprhver({{Rd = Hver;}}); 384 //0x07-0x1E should cause an illegal instruction exception 385 0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}}); 386 } 387 0x2A: decode RS1 { 388 0x00: Priv::rdprtpc({{Rd = Tpc;}}, checkTl=true); 389 0x01: Priv::rdprtnpc({{Rd = Tnpc;}}, checkTl=true); 390 0x02: Priv::rdprtstate({{Rd = Tstate;}}, checkTl=true); 391 0x03: Priv::rdprtt({{Rd = Tt;}}, checkTl=true); 392 0x04: Priv::rdprtick({{Rd = Tick;}}); 393 0x05: Priv::rdprtba({{Rd = Tba;}}); 394 0x06: Priv::rdprpstate({{Rd = Pstate;}}); 395 0x07: Priv::rdprtl({{Rd = Tl;}}); 396 0x08: Priv::rdprpil({{Rd = Pil;}}); 397 0x09: Priv::rdprcwp({{Rd = Cwp;}}); 398 0x0A: Priv::rdprcansave({{Rd = Cansave;}}); 399 0x0B: Priv::rdprcanrestore({{Rd = Canrestore;}}); 400 0x0C: Priv::rdprcleanwin({{Rd = Cleanwin;}}); 401 0x0D: Priv::rdprotherwin({{Rd = Otherwin;}}); 402 0x0E: Priv::rdprwstate({{Rd = Wstate;}}); 403 //0x0F should cause an illegal instruction exception 404 0x10: Priv::rdprgl({{Rd = Gl;}}); 405 //0x11-0x1F should cause an illegal instruction exception 406 } 407 0x2B: BasicOperate::flushw({{ 408 if(NWindows - 2 - Cansave != 0) 409 { 410 if(Otherwin) 411 fault = new SpillNOther(4*Wstate<5:3>); 412 else 413 fault = new SpillNNormal(4*Wstate<2:0>); 414 } 415 }}); 416 0x2C: decode MOVCC3 417 { 418 0x0: decode CC 419 { 420 0x0: movccfcc0({{ 421 if(passesCondition(Fsr<11:10>, COND4)) 422 Rd = Rs2_or_imm11; 423 else 424 Rd = Rd; 425 }}); 426 0x1: movccfcc1({{ 427 if(passesCondition(Fsr<33:32>, COND4)) 428 Rd = Rs2_or_imm11; 429 else 430 Rd = Rd; 431 }}); 432 0x2: movccfcc2({{ 433 if(passesCondition(Fsr<35:34>, COND4)) 434 Rd = Rs2_or_imm11; 435 else 436 Rd = Rd; 437 }}); 438 0x3: movccfcc3({{ 439 if(passesCondition(Fsr<37:36>, COND4)) 440 Rd = Rs2_or_imm11; 441 else 442 Rd = Rd; 443 }}); 444 } 445 0x1: decode CC 446 { 447 0x0: movcci({{ 448 if(passesCondition(Ccr<3:0>, COND4)) 449 Rd = Rs2_or_imm11; 450 else 451 Rd = Rd; 452 }}); 453 0x2: movccx({{ 454 if(passesCondition(Ccr<7:4>, COND4)) 455 Rd = Rs2_or_imm11; 456 else 457 Rd = Rd; 458 }}); 459 } 460 } 461 0x2D: sdivx({{ 462 if(Rs2_or_imm13.sdw == 0) fault = new DivisionByZero; 463 else Rd.sdw = Rs1.sdw / Rs2_or_imm13.sdw; 464 }}); 465 0x2E: Trap::popc({{fault = new IllegalInstruction;}}); 466 0x2F: decode RCOND3 467 { 468 0x1: movreq({{Rd = (Rs1.sdw == 0) ? Rs2_or_imm10 : Rd;}}); 469 0x2: movrle({{Rd = (Rs1.sdw <= 0) ? Rs2_or_imm10 : Rd;}}); 470 0x3: movrl({{Rd = (Rs1.sdw < 0) ? Rs2_or_imm10 : Rd;}}); 471 0x5: movrne({{Rd = (Rs1.sdw != 0) ? Rs2_or_imm10 : Rd;}}); 472 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}}); 473 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}}); 474 } 475 0x30: decode RD { 476 0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}}); 477 //0x01 should cause an illegal instruction exception 478 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}}); 479 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}); 480 //0x04-0x05 should cause an illegal instruction exception 481 0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}}); 482 //0x07-0x0E should cause an illegal instruction exception 483 0x0F: Trap::softreset({{fault = new SoftwareInitiatedReset;}}); 484 0x10: Priv::wrpcr({{Pcr = Rs1 ^ Rs2_or_imm13;}}); 485 0x11: Priv::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}}); 486 //0x12 should cause an illegal instruction exception 487 0x13: NoPriv::wrgsr({{ 488 if(Fprs<2:> == 0 || Pstate<4:> == 0) 489 return new FpDisabled; 490 Gsr = Rs1 ^ Rs2_or_imm13; 491 }}); 492 0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}}); 493 0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}}); 494 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}}); 495 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}}); 496 0x18: NoPriv::wrstick({{ 497 if(!Hpstate<2:>) 498 return new IllegalInstruction; 499 Stick = Rs1 ^ Rs2_or_imm13; 500 }}); 501 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}}); 502 0x1A: Priv::wrstrand_sts_reg({{ 503 StrandStsReg = Rs1 ^ Rs2_or_imm13; 504 }}); 505 //0x1A is supposed to be reserved, but it writes the strand 506 //status register. 507 //0x1B-0x1F should cause an illegal instruction exception 508 } 509 0x31: decode FCN { 510 0x0: Priv::saved({{ 511 assert(Cansave < NWindows - 2); 512 assert(Otherwin || Canrestore); 513 Cansave = Cansave + 1; 514 if(Otherwin == 0) 515 Canrestore = Canrestore - 1; 516 else 517 Otherwin = Otherwin - 1; 518 }}); 519 0x1: Priv::restored({{ 520 assert(Cansave || Otherwin); 521 assert(Canrestore < NWindows - 2); 522 Canrestore = Canrestore + 1; 523 if(Otherwin == 0) 524 Cansave = Cansave - 1; 525 else 526 Otherwin = Otherwin - 1; 527 528 if(Cleanwin < NWindows - 1) 529 Cleanwin = Cleanwin + 1; 530 }}); 531 } 532 0x32: decode RD { 533 0x00: Priv::wrprtpc( 534 {{Tpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); 535 0x01: Priv::wrprtnpc( 536 {{Tnpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); 537 0x02: Priv::wrprtstate( 538 {{Tstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); 539 0x03: Priv::wrprtt( 540 {{Tt = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); 541 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}}); 542 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); 543 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); 544 0x07: Priv::wrprtl({{ 545 if(Pstate<2:> && !Hpstate<2:>) 546 Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPTL); 547 else 548 Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxTL); 549 }}); 550 0x08: Priv::wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}}); 551 0x09: Priv::wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}}); 552 0x0A: Priv::wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}}); 553 0x0B: Priv::wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}}); 554 0x0C: Priv::wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}}); 555 0x0D: Priv::wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}}); 556 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}}); 557 //0x0F should cause an illegal instruction exception 558 0x10: Priv::wrprgl({{ 559 if(Pstate<2:> && !Hpstate<2:>) 560 Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPGL); 561 else 562 Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxGL); 563 }}); 564 //0x11-0x1F should cause an illegal instruction exception 565 } 566 0x33: decode RD { 567 0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}}); 568 0x01: HPriv::wrhprhtstate( 569 {{Htstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); 570 //0x02 should cause an illegal instruction exception 571 0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}}); 572 //0x04 should cause an illegal instruction exception 573 0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}}); 574 //0x06-0x01D should cause an illegal instruction exception 575 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}}); 576 } 577 0x34: decode OPF{ 578 format FpBasic{ 579 0x01: fmovs({{Frds.uw = Frs2s.uw;}}); 580 0x02: fmovd({{Frd.udw = Frs2.udw;}}); 581 0x03: FpUnimpl::fmovq(); 582 0x05: fnegs({{Frds.uw = Frs2s.uw ^ (1UL << 31);}}); 583 0x06: fnegd({{Frd.udw = Frs2.udw ^ (1ULL << 63);}}); 584 0x07: FpUnimpl::fnegq(); 585 0x09: fabss({{Frds.uw = ((1UL << 31) - 1) & Frs2s.uw;}}); 586 0x0A: fabsd({{Frd.udw = ((1ULL << 63) - 1) & Frs2.udw;}}); 587 0x0B: FpUnimpl::fabsq(); 588 0x29: fsqrts({{Frds.sf = std::sqrt(Frs2s.sf);}}); 589 0x2A: fsqrtd({{Frd.df = std::sqrt(Frs2.df);}}); 590 0x2B: FpUnimpl::fsqrtq(); 591 0x41: fadds({{Frds.sf = Frs1s.sf + Frs2s.sf;}}); 592 0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}}); 593 0x43: FpUnimpl::faddq(); 594 0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}}); 595 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df; }}); 596 0x47: FpUnimpl::fsubq(); 597 0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}}); 598 0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}}); 599 0x4B: FpUnimpl::fmulq(); 600 0x4D: fdivs({{Frds.sf = Frs1s.sf / Frs2s.sf;}}); 601 0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}}); 602 0x4F: FpUnimpl::fdivq(); 603 0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}}); 604 0x6E: FpUnimpl::fdmulq(); 605 0x81: fstox({{Frd.sdw = static_cast<int64_t>(Frs2s.sf);}}); 606 0x82: fdtox({{Frd.sdw = static_cast<int64_t>(Frs2.df);}}); 607 0x83: FpUnimpl::fqtox(); 608 0x84: fxtos({{Frds.sf = static_cast<float>(Frs2.sdw);}}); 609 0x88: fxtod({{Frd.df = static_cast<double>(Frs2.sdw);}}); 610 0x8C: FpUnimpl::fxtoq(); 611 0xC4: fitos({{Frds.sf = static_cast<float>(Frs2s.sw);}}); 612 0xC6: fdtos({{Frds.sf = Frs2.df;}}); 613 0xC7: FpUnimpl::fqtos(); 614 0xC8: fitod({{Frd.df = static_cast<double>(Frs2s.sw);}}); 615 0xC9: fstod({{Frd.df = Frs2s.sf;}}); 616 0xCB: FpUnimpl::fqtod(); 617 0xCC: FpUnimpl::fitoq(); 618 0xCD: FpUnimpl::fstoq(); 619 0xCE: FpUnimpl::fdtoq(); 620 0xD1: fstoi({{ 621 Frds.sw = static_cast<int32_t>(Frs2s.sf); 622 float t = Frds.sw; 623 if (t != Frs2s.sf) 624 Fsr = insertBits(Fsr, 4,0, 0x01); 625 }}); 626 0xD2: fdtoi({{ 627 Frds.sw = static_cast<int32_t>(Frs2.df); 628 double t = Frds.sw; 629 if (t != Frs2.df) 630 Fsr = insertBits(Fsr, 4,0, 0x01); 631 }}); 632 0xD3: FpUnimpl::fqtoi(); 633 default: FailUnimpl::fpop1(); 634 } 635 } 636 0x35: decode OPF{ 637 format FpBasic{ 638 0x01: fmovs_fcc0({{ 639 if(passesFpCondition(Fsr<11:10>, COND4)) 640 Frds = Frs2s; 641 else 642 Frds = Frds; 643 }}); 644 0x02: fmovd_fcc0({{ 645 if(passesFpCondition(Fsr<11:10>, COND4)) 646 Frd = Frs2; 647 else 648 Frd = Frd; 649 }}); 650 0x03: FpUnimpl::fmovq_fcc0(); 651 0x25: fmovrsz({{ 652 if(Rs1 == 0) 653 Frds = Frs2s; 654 else 655 Frds = Frds; 656 }}); 657 0x26: fmovrdz({{ 658 if(Rs1 == 0) 659 Frd = Frs2; 660 else 661 Frd = Frd; 662 }}); 663 0x27: FpUnimpl::fmovrqz(); 664 0x41: fmovs_fcc1({{ 665 if(passesFpCondition(Fsr<33:32>, COND4)) 666 Frds = Frs2s; 667 else 668 Frds = Frds; 669 }}); 670 0x42: fmovd_fcc1({{ 671 if(passesFpCondition(Fsr<33:32>, COND4)) 672 Frd = Frs2; 673 else 674 Frd = Frd; 675 }}); 676 0x43: FpUnimpl::fmovq_fcc1(); 677 0x45: fmovrslez({{ 678 if(Rs1 <= 0) 679 Frds = Frs2s; 680 else 681 Frds = Frds; 682 }}); 683 0x46: fmovrdlez({{ 684 if(Rs1 <= 0) 685 Frd = Frs2; 686 else 687 Frd = Frd; 688 }}); 689 0x47: FpUnimpl::fmovrqlez(); 690 0x51: fcmps({{ 691 uint8_t fcc; 692 if(isnan(Frs1s) || isnan(Frs2s)) 693 fcc = 3; 694 else if(Frs1s < Frs2s) 695 fcc = 1; 696 else if(Frs1s > Frs2s) 697 fcc = 2; 698 else 699 fcc = 0; 700 uint8_t firstbit = 10; 701 if(FCMPCC) 702 firstbit = FCMPCC * 2 + 30; 703 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); 704 }}); 705 0x52: fcmpd({{ 706 uint8_t fcc; 707 if(isnan(Frs1) || isnan(Frs2)) 708 fcc = 3; 709 else if(Frs1 < Frs2) 710 fcc = 1; 711 else if(Frs1 > Frs2) 712 fcc = 2; 713 else 714 fcc = 0; 715 uint8_t firstbit = 10; 716 if(FCMPCC) 717 firstbit = FCMPCC * 2 + 30; 718 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); 719 }}); 720 0x53: FpUnimpl::fcmpq(); 721 0x55: fcmpes({{ 722 uint8_t fcc = 0; 723 if(isnan(Frs1s) || isnan(Frs2s)) 724 fault = new FpExceptionIEEE754; 725 if(Frs1s < Frs2s) 726 fcc = 1; 727 else if(Frs1s > Frs2s) 728 fcc = 2; 729 uint8_t firstbit = 10; 730 if(FCMPCC) 731 firstbit = FCMPCC * 2 + 30; 732 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); 733 }}); 734 0x56: fcmped({{ 735 uint8_t fcc = 0; 736 if(isnan(Frs1) || isnan(Frs2)) 737 fault = new FpExceptionIEEE754; 738 if(Frs1 < Frs2) 739 fcc = 1; 740 else if(Frs1 > Frs2) 741 fcc = 2; 742 uint8_t firstbit = 10; 743 if(FCMPCC) 744 firstbit = FCMPCC * 2 + 30; 745 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); 746 }}); 747 0x57: FpUnimpl::fcmpeq(); 748 0x65: fmovrslz({{ 749 if(Rs1 < 0) 750 Frds = Frs2s; 751 else 752 Frds = Frds; 753 }}); 754 0x66: fmovrdlz({{ 755 if(Rs1 < 0) 756 Frd = Frs2; 757 else 758 Frd = Frd; 759 }}); 760 0x67: FpUnimpl::fmovrqlz(); 761 0x81: fmovs_fcc2({{ 762 if(passesFpCondition(Fsr<35:34>, COND4)) 763 Frds = Frs2s; 764 else 765 Frds = Frds; 766 }}); 767 0x82: fmovd_fcc2({{ 768 if(passesFpCondition(Fsr<35:34>, COND4)) 769 Frd = Frs2; 770 else 771 Frd = Frd; 772 }}); 773 0x83: FpUnimpl::fmovq_fcc2(); 774 0xA5: fmovrsnz({{ 775 if(Rs1 != 0) 776 Frds = Frs2s; 777 else 778 Frds = Frds; 779 }}); 780 0xA6: fmovrdnz({{ 781 if(Rs1 != 0) 782 Frd = Frs2; 783 else 784 Frd = Frd; 785 }}); 786 0xA7: FpUnimpl::fmovrqnz(); 787 0xC1: fmovs_fcc3({{ 788 if(passesFpCondition(Fsr<37:36>, COND4)) 789 Frds = Frs2s; 790 else 791 Frds = Frds; 792 }}); 793 0xC2: fmovd_fcc3({{ 794 if(passesFpCondition(Fsr<37:36>, COND4)) 795 Frd = Frs2; 796 else 797 Frd = Frd; 798 }}); 799 0xC3: FpUnimpl::fmovq_fcc3(); 800 0xC5: fmovrsgz({{ 801 if(Rs1 > 0) 802 Frds = Frs2s; 803 else 804 Frds = Frds; 805 }}); 806 0xC6: fmovrdgz({{ 807 if(Rs1 > 0) 808 Frd = Frs2; 809 else 810 Frd = Frd; 811 }}); 812 0xC7: FpUnimpl::fmovrqgz(); 813 0xE5: fmovrsgez({{ 814 if(Rs1 >= 0) 815 Frds = Frs2s; 816 else 817 Frds = Frds; 818 }}); 819 0xE6: fmovrdgez({{ 820 if(Rs1 >= 0) 821 Frd = Frs2; 822 else 823 Frd = Frd; 824 }}); 825 0xE7: FpUnimpl::fmovrqgez(); 826 0x101: fmovs_icc({{ 827 if(passesCondition(Ccr<3:0>, COND4)) 828 Frds = Frs2s; 829 else 830 Frds = Frds; 831 }}); 832 0x102: fmovd_icc({{ 833 if(passesCondition(Ccr<3:0>, COND4)) 834 Frd = Frs2; 835 else 836 Frd = Frd; 837 }}); 838 0x103: FpUnimpl::fmovq_icc(); 839 0x181: fmovs_xcc({{ 840 if(passesCondition(Ccr<7:4>, COND4)) 841 Frds = Frs2s; 842 else 843 Frds = Frds; 844 }}); 845 0x182: fmovd_xcc({{ 846 if(passesCondition(Ccr<7:4>, COND4)) 847 Frd = Frs2; 848 else 849 Frd = Frd; 850 }}); 851 0x183: FpUnimpl::fmovq_xcc(); 852 default: FailUnimpl::fpop2(); 853 } 854 } 855 //This used to be just impdep1, but now it's a whole bunch 856 //of instructions 857 0x36: decode OPF{ 858 0x00: FailUnimpl::edge8(); 859 0x01: FailUnimpl::edge8n(); 860 0x02: FailUnimpl::edge8l(); 861 0x03: FailUnimpl::edge8ln(); 862 0x04: FailUnimpl::edge16(); 863 0x05: FailUnimpl::edge16n(); 864 0x06: FailUnimpl::edge16l(); 865 0x07: FailUnimpl::edge16ln(); 866 0x08: FailUnimpl::edge32(); 867 0x09: FailUnimpl::edge32n(); 868 0x0A: FailUnimpl::edge32l(); 869 0x0B: FailUnimpl::edge32ln(); 870 0x10: FailUnimpl::array8(); 871 0x12: FailUnimpl::array16(); 872 0x14: FailUnimpl::array32(); 873 0x18: BasicOperate::alignaddr({{ 874 uint64_t sum = Rs1 + Rs2; 875 Rd = sum & ~7; 876 Gsr = (Gsr & ~7) | (sum & 7); 877 }}); 878 0x19: FailUnimpl::bmask(); 879 0x1A: BasicOperate::alignaddresslittle({{ 880 uint64_t sum = Rs1 + Rs2; 881 Rd = sum & ~7; 882 Gsr = (Gsr & ~7) | ((~sum + 1) & 7); 883 }}); 884 0x20: FailUnimpl::fcmple16(); 885 0x22: FailUnimpl::fcmpne16(); 886 0x24: FailUnimpl::fcmple32(); 887 0x26: FailUnimpl::fcmpne32(); 888 0x28: FailUnimpl::fcmpgt16(); 889 0x2A: FailUnimpl::fcmpeq16(); 890 0x2C: FailUnimpl::fcmpgt32(); 891 0x2E: FailUnimpl::fcmpeq32(); 892 0x31: FailUnimpl::fmul8x16(); 893 0x33: FailUnimpl::fmul8x16au(); 894 0x35: FailUnimpl::fmul8x16al(); 895 0x36: FailUnimpl::fmul8sux16(); 896 0x37: FailUnimpl::fmul8ulx16(); 897 0x38: FailUnimpl::fmuld8sux16(); 898 0x39: FailUnimpl::fmuld8ulx16(); 899 0x3A: Trap::fpack32({{fault = new IllegalInstruction;}}); 900 0x3B: Trap::fpack16({{fault = new IllegalInstruction;}}); 901 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}}); 902 0x3E: Trap::pdist({{fault = new IllegalInstruction;}}); 903 0x48: BasicOperate::faligndata({{ 904 uint64_t msbX = Frs1.udw; 905 uint64_t lsbX = Frs2.udw; 906 //Some special cases need to be split out, first 907 //because they're the most likely to be used, and 908 //second because otherwise, we end up shifting by 909 //greater than the width of the type being shifted, 910 //namely 64, which produces undefined results according 911 //to the C standard. 912 switch(Gsr<2:0>) 913 { 914 case 0: 915 Frd.udw = msbX; 916 break; 917 case 8: 918 Frd.udw = lsbX; 919 break; 920 default: 921 uint64_t msbShift = Gsr<2:0> * 8; 922 uint64_t lsbShift = (8 - Gsr<2:0>) * 8; 923 uint64_t msbMask = ((uint64_t)(-1)) >> msbShift; 924 uint64_t lsbMask = ((uint64_t)(-1)) << lsbShift; 925 Frd.udw = ((msbX & msbMask) << msbShift) | 926 ((lsbX & lsbMask) >> lsbShift); 927 } 928 }}); 929 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}}); 930 0x4C: FailUnimpl::bshuffle(); 931 0x4D: FailUnimpl::fexpand(); 932 0x50: FailUnimpl::fpadd16(); 933 0x51: FailUnimpl::fpadd16s(); 934 0x52: FailUnimpl::fpadd32(); 935 0x53: FailUnimpl::fpadd32s(); 936 0x54: FailUnimpl::fpsub16(); 937 0x55: FailUnimpl::fpsub16s(); 938 0x56: FailUnimpl::fpsub32(); 939 0x57: FailUnimpl::fpsub32s(); 940 0x60: FpBasic::fzero({{Frd.df = 0;}}); 941 0x61: FpBasic::fzeros({{Frds.sf = 0;}}); 942 0x62: FailUnimpl::fnor(); 943 0x63: FailUnimpl::fnors(); 944 0x64: FailUnimpl::fandnot2(); 945 0x65: FailUnimpl::fandnot2s(); 946 0x66: FpBasic::fnot2({{ 947 Frd.df = (double)(~((uint64_t)Frs2.df)); 948 }}); 949 0x67: FpBasic::fnot2s({{ 950 Frds.sf = (float)(~((uint32_t)Frs2s.sf)); 951 }}); 952 0x68: FailUnimpl::fandnot1(); 953 0x69: FailUnimpl::fandnot1s(); 954 0x6A: FpBasic::fnot1({{ 955 Frd.df = (double)(~((uint64_t)Frs1.df)); 956 }}); 957 0x6B: FpBasic::fnot1s({{ 958 Frds.sf = (float)(~((uint32_t)Frs1s.sf)); 959 }}); 960 0x6C: FailUnimpl::fxor(); 961 0x6D: FailUnimpl::fxors(); 962 0x6E: FailUnimpl::fnand(); 963 0x6F: FailUnimpl::fnands(); 964 0x70: FailUnimpl::fand(); 965 0x71: FailUnimpl::fands(); 966 0x72: FailUnimpl::fxnor(); 967 0x73: FailUnimpl::fxnors(); 968 0x74: FpBasic::fsrc1({{Frd.udw = Frs1.udw;}}); 969 0x75: FpBasic::fsrc1s({{Frds.uw = Frs1s.uw;}}); 970 0x76: FailUnimpl::fornot2(); 971 0x77: FailUnimpl::fornot2s(); 972 0x78: FpBasic::fsrc2({{Frd.udw = Frs2.udw;}}); 973 0x79: FpBasic::fsrc2s({{Frds.uw = Frs2s.uw;}}); 974 0x7A: FailUnimpl::fornot1(); 975 0x7B: FailUnimpl::fornot1s(); 976 0x7C: FailUnimpl::for(); 977 0x7D: FailUnimpl::fors(); 978 0x7E: FpBasic::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}}); 979 0x7F: FpBasic::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}}); 980 0x80: Trap::shutdown({{fault = new IllegalInstruction;}}); 981 0x81: FailUnimpl::siam(); 982 } 983 // M5 special opcodes use the reserved IMPDEP2A opcode space 984 0x37: decode M5FUNC { 985#if FULL_SYSTEM 986 format BasicOperate { 987 // we have 7 bits of space here to play with... 988 0x21: m5exit({{PseudoInst::m5exit(xc->tcBase(), O0); 989 }}, No_OpClass, IsNonSpeculative); 990 0x50: m5readfile({{ 991 O0 = PseudoInst::readfile(xc->tcBase(), O0, O1, O2); 992 }}, IsNonSpeculative); 993 0x51: m5break({{PseudoInst::debugbreak(xc->tcBase()); 994 }}, IsNonSpeculative); 995 0x54: m5panic({{ 996 SparcISA::PCState pc = PCS; 997 panic("M5 panic instruction called at pc=%#x.", pc.pc()); 998 }}, No_OpClass, IsNonSpeculative); 999 } 1000#endif 1001 default: Trap::impdep2({{fault = new IllegalInstruction;}}); 1002 } 1003 0x38: Branch::jmpl({{ 1004 Addr target = Rs1 + Rs2_or_imm13; 1005 if(target & 0x3) 1006 fault = new MemAddressNotAligned; 1007 else 1008 { 1009 SparcISA::PCState pc = PCS; 1010 if (Pstate<3:>) 1011 Rd = (pc.pc())<31:0>; 1012 else 1013 Rd = pc.pc(); 1014 pc.nnpc(target); 1015 PCS = pc; 1016 } 1017 }}); 1018 0x39: Branch::return({{ 1019 Addr target = Rs1 + Rs2_or_imm13; 1020 if(fault == NoFault) 1021 { 1022 //Check for fills which are higher priority than alignment 1023 //faults. 1024 if(Canrestore == 0) 1025 { 1026 if(Otherwin) 1027 fault = new FillNOther(4*Wstate<5:3>); 1028 else 1029 fault = new FillNNormal(4*Wstate<2:0>); 1030 } 1031 //Check for alignment faults 1032 else if(target & 0x3) 1033 fault = new MemAddressNotAligned; 1034 else 1035 { 1036 SparcISA::PCState pc = PCS; 1037 pc.nnpc(target); 1038 PCS = pc; 1039 Cwp = (Cwp - 1 + NWindows) % NWindows; 1040 Cansave = Cansave + 1; 1041 Canrestore = Canrestore - 1; 1042 } 1043 } 1044 }}); 1045 0x3A: decode CC 1046 { 1047 0x0: Trap::tcci({{ 1048 if(passesCondition(Ccr<3:0>, COND2)) 1049 { 1050 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); 1051 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); 1052 fault = new TrapInstruction(lTrapNum); 1053 } 1054 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall); 1055 0x2: Trap::tccx({{ 1056 if(passesCondition(Ccr<7:4>, COND2)) 1057 { 1058 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); 1059 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); 1060 fault = new TrapInstruction(lTrapNum); 1061 } 1062 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall); 1063 } 1064 0x3B: Nop::flush({{/*Instruction memory flush*/}}, IsWriteBarrier, 1065 MemWriteOp); 1066 0x3C: save({{ 1067 if(Cansave == 0) 1068 { 1069 if(Otherwin) 1070 fault = new SpillNOther(4*Wstate<5:3>); 1071 else 1072 fault = new SpillNNormal(4*Wstate<2:0>); 1073 } 1074 else if(Cleanwin - Canrestore == 0) 1075 { 1076 fault = new CleanWindow; 1077 } 1078 else 1079 { 1080 Cwp = (Cwp + 1) % NWindows; 1081 Rd_next = Rs1 + Rs2_or_imm13; 1082 Cansave = Cansave - 1; 1083 Canrestore = Canrestore + 1; 1084 } 1085 }}); 1086 0x3D: restore({{ 1087 if(Canrestore == 0) 1088 { 1089 if(Otherwin) 1090 fault = new FillNOther(4*Wstate<5:3>); 1091 else 1092 fault = new FillNNormal(4*Wstate<2:0>); 1093 } 1094 else 1095 { 1096 Cwp = (Cwp - 1 + NWindows) % NWindows; 1097 Rd_prev = Rs1 + Rs2_or_imm13; 1098 Cansave = Cansave + 1; 1099 Canrestore = Canrestore - 1; 1100 } 1101 }}); 1102 0x3E: decode FCN { 1103 0x0: Priv::done({{ 1104 Cwp = Tstate<4:0>; 1105 Pstate = Tstate<20:8>; 1106 Asi = Tstate<31:24>; 1107 Ccr = Tstate<39:32>; 1108 Gl = Tstate<42:40>; 1109 Hpstate = Htstate; 1110 SparcISA::PCState pc = PCS; 1111 pc.npc(Tnpc); 1112 pc.nnpc(Tnpc + 4); 1113 PCS = pc; 1114 Tl = Tl - 1; 1115 }}, checkTl=true); 1116 0x1: Priv::retry({{ 1117 Cwp = Tstate<4:0>; 1118 Pstate = Tstate<20:8>; 1119 Asi = Tstate<31:24>; 1120 Ccr = Tstate<39:32>; 1121 Gl = Tstate<42:40>; 1122 Hpstate = Htstate; 1123 SparcISA::PCState pc = PCS; 1124 pc.npc(Tpc); 1125 pc.nnpc(Tnpc); 1126 PCS = pc; 1127 Tl = Tl - 1; 1128 }}, checkTl=true); 1129 } 1130 } 1131 } 1132 0x3: decode OP3 { 1133 format Load { 1134 0x00: lduw({{Rd = Mem.uw;}}); 1135 0x01: ldub({{Rd = Mem.ub;}}); 1136 0x02: lduh({{Rd = Mem.uhw;}}); 1137 0x03: ldtw({{ 1138 RdLow = (Mem.tuw).a; 1139 RdHigh = (Mem.tuw).b; 1140 }}); 1141 } 1142 format Store { 1143 0x04: stw({{Mem.uw = Rd.sw;}}); 1144 0x05: stb({{Mem.ub = Rd.sb;}}); 1145 0x06: sth({{Mem.uhw = Rd.shw;}}); 1146 0x07: sttw({{ 1147 //This temporary needs to be here so that the parser 1148 //will correctly identify this instruction as a store. 1149 //It's probably either the parenthesis or referencing 1150 //the member variable that throws confuses it. 1151 Twin32_t temp; 1152 temp.a = RdLow<31:0>; 1153 temp.b = RdHigh<31:0>; 1154 Mem.tuw = temp; 1155 }}); 1156 } 1157 format Load { 1158 0x08: ldsw({{Rd = (int32_t)Mem.sw;}}); 1159 0x09: ldsb({{Rd = (int8_t)Mem.sb;}}); 1160 0x0A: ldsh({{Rd = (int16_t)Mem.shw;}}); 1161 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}}); 1162 } 1163 0x0D: Swap::ldstub({{Mem.ub = 0xFF;}}, 1164 {{ 1165 uint8_t tmp = mem_data; 1166 Rd.ub = tmp; 1167 }}, MEM_SWAP); 1168 0x0E: Store::stx({{Mem.udw = Rd}}); 1169 0x0F: Swap::swap({{Mem.uw = Rd.uw}}, 1170 {{ 1171 uint32_t tmp = mem_data; 1172 Rd.uw = tmp; 1173 }}, MEM_SWAP); 1174 format LoadAlt { 1175 0x10: lduwa({{Rd = Mem.uw;}}); 1176 0x11: lduba({{Rd = Mem.ub;}}); 1177 0x12: lduha({{Rd = Mem.uhw;}}); 1178 0x13: decode EXT_ASI { 1179 //ASI_LDTD_AIUP 1180 0x22: TwinLoad::ldtx_aiup( 1181 {{RdLow.udw = (Mem.tudw).a; 1182 RdHigh.udw = (Mem.tudw).b;}}); 1183 //ASI_LDTD_AIUS 1184 0x23: TwinLoad::ldtx_aius( 1185 {{RdLow.udw = (Mem.tudw).a; 1186 RdHigh.udw = (Mem.tudw).b;}}); 1187 //ASI_QUAD_LDD 1188 0x24: TwinLoad::ldtx_quad_ldd( 1189 {{RdLow.udw = (Mem.tudw).a; 1190 RdHigh.udw = (Mem.tudw).b;}}); 1191 //ASI_LDTX_REAL 1192 0x26: TwinLoad::ldtx_real( 1193 {{RdLow.udw = (Mem.tudw).a; 1194 RdHigh.udw = (Mem.tudw).b;}}); 1195 //ASI_LDTX_N 1196 0x27: TwinLoad::ldtx_n( 1197 {{RdLow.udw = (Mem.tudw).a; 1198 RdHigh.udw = (Mem.tudw).b;}}); 1199 //ASI_LDTX_AIUP_L 1200 0x2A: TwinLoad::ldtx_aiup_l( 1201 {{RdLow.udw = (Mem.tudw).a; 1202 RdHigh.udw = (Mem.tudw).b;}}); 1203 //ASI_LDTX_AIUS_L 1204 0x2B: TwinLoad::ldtx_aius_l( 1205 {{RdLow.udw = (Mem.tudw).a; 1206 RdHigh.udw = (Mem.tudw).b;}}); 1207 //ASI_LDTX_L 1208 0x2C: TwinLoad::ldtx_l( 1209 {{RdLow.udw = (Mem.tudw).a; 1210 RdHigh.udw = (Mem.tudw).b;}}); 1211 //ASI_LDTX_REAL_L 1212 0x2E: TwinLoad::ldtx_real_l( 1213 {{RdLow.udw = (Mem.tudw).a; 1214 RdHigh.udw = (Mem.tudw).b;}}); 1215 //ASI_LDTX_N_L 1216 0x2F: TwinLoad::ldtx_n_l( 1217 {{RdLow.udw = (Mem.tudw).a; 1218 RdHigh.udw = (Mem.tudw).b;}}); 1219 //ASI_LDTX_P 1220 0xE2: TwinLoad::ldtx_p( 1221 {{RdLow.udw = (Mem.tudw).a; 1222 RdHigh.udw = (Mem.tudw).b;}}); 1223 //ASI_LDTX_S 1224 0xE3: TwinLoad::ldtx_s( 1225 {{RdLow.udw = (Mem.tudw).a; 1226 RdHigh.udw = (Mem.tudw).b;}}); 1227 //ASI_LDTX_PL 1228 0xEA: TwinLoad::ldtx_pl( 1229 {{RdLow.udw = (Mem.tudw).a; 1230 RdHigh.udw = (Mem.tudw).b;}}); 1231 //ASI_LDTX_SL 1232 0xEB: TwinLoad::ldtx_sl( 1233 {{RdLow.udw = (Mem.tudw).a; 1234 RdHigh.udw = (Mem.tudw).b;}}); 1235 default: ldtwa({{ 1236 RdLow = (Mem.tuw).a; 1237 RdHigh = (Mem.tuw).b;}}); 1238 } 1239 } 1240 format StoreAlt { 1241 0x14: stwa({{Mem.uw = Rd;}}); 1242 0x15: stba({{Mem.ub = Rd;}}); 1243 0x16: stha({{Mem.uhw = Rd;}}); 1244 0x17: sttwa({{ 1245 //This temporary needs to be here so that the parser 1246 //will correctly identify this instruction as a store. 1247 //It's probably either the parenthesis or referencing 1248 //the member variable that throws confuses it. 1249 Twin32_t temp; 1250 temp.a = RdLow<31:0>; 1251 temp.b = RdHigh<31:0>; 1252 Mem.tuw = temp; 1253 }}); 1254 } 1255 format LoadAlt { 1256 0x18: ldswa({{Rd = (int32_t)Mem.sw;}}); 1257 0x19: ldsba({{Rd = (int8_t)Mem.sb;}}); 1258 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}); 1259 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}); 1260 } 1261 0x1D: SwapAlt::ldstuba({{Mem.ub = 0xFF;}}, 1262 {{ 1263 uint8_t tmp = mem_data; 1264 Rd.ub = tmp; 1265 }}, MEM_SWAP); 1266 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}); 1267 0x1F: SwapAlt::swapa({{Mem.uw = Rd.uw}}, 1268 {{ 1269 uint32_t tmp = mem_data; 1270 Rd.uw = tmp; 1271 }}, MEM_SWAP); 1272 1273 format Trap { 1274 0x20: Load::ldf({{Frds.uw = Mem.uw;}}); 1275 0x21: decode RD { 1276 0x0: Load::ldfsr({{fault = checkFpEnableFault(xc); 1277 if (fault) 1278 return fault; 1279 Fsr = Mem.uw | Fsr<63:32>;}}); 1280 0x1: Load::ldxfsr({{fault = checkFpEnableFault(xc); 1281 if (fault) 1282 return fault; 1283 Fsr = Mem.udw;}}); 1284 default: FailUnimpl::ldfsrOther(); 1285 } 1286 0x22: ldqf({{fault = new FpDisabled;}}); 1287 0x23: Load::lddf({{Frd.udw = Mem.udw;}}); 1288 0x24: Store::stf({{Mem.uw = Frds.uw;}}); 1289 0x25: decode RD { 1290 0x0: StoreFsr::stfsr({{fault = checkFpEnableFault(xc); 1291 if (fault) 1292 return fault; 1293 Mem.uw = Fsr<31:0>;}}); 1294 0x1: StoreFsr::stxfsr({{fault = checkFpEnableFault(xc); 1295 if (fault) 1296 return fault; 1297 Mem.udw = Fsr;}}); 1298 default: FailUnimpl::stfsrOther(); 1299 } 1300 0x26: stqf({{fault = new FpDisabled;}}); 1301 0x27: Store::stdf({{Mem.udw = Frd.udw;}}); 1302 0x2D: Nop::prefetch({{ }}); 1303 0x30: LoadAlt::ldfa({{Frds.uw = Mem.uw;}}); 1304 0x32: ldqfa({{fault = new FpDisabled;}}); 1305 format LoadAlt { 1306 0x33: decode EXT_ASI { 1307 //ASI_NUCLEUS 1308 0x04: FailUnimpl::lddfa_n(); 1309 //ASI_NUCLEUS_LITTLE 1310 0x0C: FailUnimpl::lddfa_nl(); 1311 //ASI_AS_IF_USER_PRIMARY 1312 0x10: FailUnimpl::lddfa_aiup(); 1313 //ASI_AS_IF_USER_PRIMARY_LITTLE 1314 0x18: FailUnimpl::lddfa_aiupl(); 1315 //ASI_AS_IF_USER_SECONDARY 1316 0x11: FailUnimpl::lddfa_aius(); 1317 //ASI_AS_IF_USER_SECONDARY_LITTLE 1318 0x19: FailUnimpl::lddfa_aiusl(); 1319 //ASI_REAL 1320 0x14: FailUnimpl::lddfa_real(); 1321 //ASI_REAL_LITTLE 1322 0x1C: FailUnimpl::lddfa_real_l(); 1323 //ASI_REAL_IO 1324 0x15: FailUnimpl::lddfa_real_io(); 1325 //ASI_REAL_IO_LITTLE 1326 0x1D: FailUnimpl::lddfa_real_io_l(); 1327 //ASI_PRIMARY 1328 0x80: FailUnimpl::lddfa_p(); 1329 //ASI_PRIMARY_LITTLE 1330 0x88: FailUnimpl::lddfa_pl(); 1331 //ASI_SECONDARY 1332 0x81: FailUnimpl::lddfa_s(); 1333 //ASI_SECONDARY_LITTLE 1334 0x89: FailUnimpl::lddfa_sl(); 1335 //ASI_PRIMARY_NO_FAULT 1336 0x82: FailUnimpl::lddfa_pnf(); 1337 //ASI_PRIMARY_NO_FAULT_LITTLE 1338 0x8A: FailUnimpl::lddfa_pnfl(); 1339 //ASI_SECONDARY_NO_FAULT 1340 0x83: FailUnimpl::lddfa_snf(); 1341 //ASI_SECONDARY_NO_FAULT_LITTLE 1342 0x8B: FailUnimpl::lddfa_snfl(); 1343 1344 format BlockLoad { 1345 // LDBLOCKF 1346 //ASI_BLOCK_AS_IF_USER_PRIMARY 1347 0x16: FailUnimpl::ldblockf_aiup(); 1348 //ASI_BLOCK_AS_IF_USER_SECONDARY 1349 0x17: FailUnimpl::ldblockf_aius(); 1350 //ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 1351 0x1E: FailUnimpl::ldblockf_aiupl(); 1352 //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 1353 0x1F: FailUnimpl::ldblockf_aiusl(); 1354 //ASI_BLOCK_PRIMARY 1355 0xF0: ldblockf_p({{Frd_N.udw = Mem.udw;}}); 1356 //ASI_BLOCK_SECONDARY 1357 0xF1: FailUnimpl::ldblockf_s(); 1358 //ASI_BLOCK_PRIMARY_LITTLE 1359 0xF8: FailUnimpl::ldblockf_pl(); 1360 //ASI_BLOCK_SECONDARY_LITTLE 1361 0xF9: FailUnimpl::ldblockf_sl(); 1362 } 1363 1364 //LDSHORTF 1365 //ASI_FL8_PRIMARY 1366 0xD0: FailUnimpl::ldshortf_8p(); 1367 //ASI_FL8_SECONDARY 1368 0xD1: FailUnimpl::ldshortf_8s(); 1369 //ASI_FL8_PRIMARY_LITTLE 1370 0xD8: FailUnimpl::ldshortf_8pl(); 1371 //ASI_FL8_SECONDARY_LITTLE 1372 0xD9: FailUnimpl::ldshortf_8sl(); 1373 //ASI_FL16_PRIMARY 1374 0xD2: FailUnimpl::ldshortf_16p(); 1375 //ASI_FL16_SECONDARY 1376 0xD3: FailUnimpl::ldshortf_16s(); 1377 //ASI_FL16_PRIMARY_LITTLE 1378 0xDA: FailUnimpl::ldshortf_16pl(); 1379 //ASI_FL16_SECONDARY_LITTLE 1380 0xDB: FailUnimpl::ldshortf_16sl(); 1381 //Not an ASI which is legal with lddfa 1382 default: Trap::lddfa_bad_asi( 1383 {{fault = new DataAccessException;}}); 1384 } 1385 } 1386 0x34: Store::stfa({{Mem.uw = Frds.uw;}}); 1387 0x36: stqfa({{fault = new FpDisabled;}}); 1388 format StoreAlt { 1389 0x37: decode EXT_ASI { 1390 //ASI_NUCLEUS 1391 0x04: FailUnimpl::stdfa_n(); 1392 //ASI_NUCLEUS_LITTLE 1393 0x0C: FailUnimpl::stdfa_nl(); 1394 //ASI_AS_IF_USER_PRIMARY 1395 0x10: FailUnimpl::stdfa_aiup(); 1396 //ASI_AS_IF_USER_PRIMARY_LITTLE 1397 0x18: FailUnimpl::stdfa_aiupl(); 1398 //ASI_AS_IF_USER_SECONDARY 1399 0x11: FailUnimpl::stdfa_aius(); 1400 //ASI_AS_IF_USER_SECONDARY_LITTLE 1401 0x19: FailUnimpl::stdfa_aiusl(); 1402 //ASI_REAL 1403 0x14: FailUnimpl::stdfa_real(); 1404 //ASI_REAL_LITTLE 1405 0x1C: FailUnimpl::stdfa_real_l(); 1406 //ASI_REAL_IO 1407 0x15: FailUnimpl::stdfa_real_io(); 1408 //ASI_REAL_IO_LITTLE 1409 0x1D: FailUnimpl::stdfa_real_io_l(); 1410 //ASI_PRIMARY 1411 0x80: FailUnimpl::stdfa_p(); 1412 //ASI_PRIMARY_LITTLE 1413 0x88: FailUnimpl::stdfa_pl(); 1414 //ASI_SECONDARY 1415 0x81: FailUnimpl::stdfa_s(); 1416 //ASI_SECONDARY_LITTLE 1417 0x89: FailUnimpl::stdfa_sl(); 1418 //ASI_PRIMARY_NO_FAULT 1419 0x82: FailUnimpl::stdfa_pnf(); 1420 //ASI_PRIMARY_NO_FAULT_LITTLE 1421 0x8A: FailUnimpl::stdfa_pnfl(); 1422 //ASI_SECONDARY_NO_FAULT 1423 0x83: FailUnimpl::stdfa_snf(); 1424 //ASI_SECONDARY_NO_FAULT_LITTLE 1425 0x8B: FailUnimpl::stdfa_snfl(); 1426 1427 format BlockStore { 1428 // STBLOCKF 1429 //ASI_BLOCK_AS_IF_USER_PRIMARY 1430 0x16: FailUnimpl::stblockf_aiup(); 1431 //ASI_BLOCK_AS_IF_USER_SECONDARY 1432 0x17: FailUnimpl::stblockf_aius(); 1433 //ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 1434 0x1E: FailUnimpl::stblockf_aiupl(); 1435 //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 1436 0x1F: FailUnimpl::stblockf_aiusl(); 1437 //ASI_BLOCK_PRIMARY 1438 0xF0: stblockf_p({{Mem.udw = Frd_N.udw;}}); 1439 //ASI_BLOCK_SECONDARY 1440 0xF1: FailUnimpl::stblockf_s(); 1441 //ASI_BLOCK_PRIMARY_LITTLE 1442 0xF8: FailUnimpl::stblockf_pl(); 1443 //ASI_BLOCK_SECONDARY_LITTLE 1444 0xF9: FailUnimpl::stblockf_sl(); 1445 } 1446 1447 //STSHORTF 1448 //ASI_FL8_PRIMARY 1449 0xD0: FailUnimpl::stshortf_8p(); 1450 //ASI_FL8_SECONDARY 1451 0xD1: FailUnimpl::stshortf_8s(); 1452 //ASI_FL8_PRIMARY_LITTLE 1453 0xD8: FailUnimpl::stshortf_8pl(); 1454 //ASI_FL8_SECONDARY_LITTLE 1455 0xD9: FailUnimpl::stshortf_8sl(); 1456 //ASI_FL16_PRIMARY 1457 0xD2: FailUnimpl::stshortf_16p(); 1458 //ASI_FL16_SECONDARY 1459 0xD3: FailUnimpl::stshortf_16s(); 1460 //ASI_FL16_PRIMARY_LITTLE 1461 0xDA: FailUnimpl::stshortf_16pl(); 1462 //ASI_FL16_SECONDARY_LITTLE 1463 0xDB: FailUnimpl::stshortf_16sl(); 1464 //Not an ASI which is legal with lddfa 1465 default: Trap::stdfa_bad_asi( 1466 {{fault = new DataAccessException;}}); 1467 } 1468 } 1469 0x3C: CasAlt::casa({{ 1470 mem_data = htog(Rs2.uw); 1471 Mem.uw = Rd.uw;}}, 1472 {{ 1473 uint32_t tmp = mem_data; 1474 Rd.uw = tmp; 1475 }}, MEM_SWAP_COND); 1476 0x3D: Nop::prefetcha({{ }}); 1477 0x3E: CasAlt::casxa({{mem_data = gtoh(Rs2); 1478 Mem.udw = Rd.udw; }}, 1479 {{ Rd.udw = mem_data; }}, MEM_SWAP_COND); 1480 } 1481 } 1482} 1483