decoder.isa revision 7720:65d338a8dba4
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