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