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