Fix up the disassembly a little.
[gem5.git] / src / arch / sparc / isa / decoder.isa
index 9da6bdd33a05bcbadcbbfc67e88b058d9296563c..2c8e59a1d469317013ade41ef4a478f75b294925 100644 (file)
@@ -41,15 +41,16 @@ decode OP default Unknown::unknown()
         0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
         format BranchN
         {
+            //bpcc
             0x1: decode COND2
             {
                 //Branch Always
                 0x8: decode A
                 {
-                    0x0: b(19, {{
+                    0x0: bpa(19, {{
                         NNPC = xc->readPC() + disp;
                     }});
-                    0x1: b(19, {{
+                    0x1: bpa(19, {{
                         NPC = xc->readPC() + disp;
                         NNPC = NPC + 4;
                     }}, ',a');
@@ -57,10 +58,10 @@ decode OP default Unknown::unknown()
                 //Branch Never
                 0x0: decode A
                 {
-                    0x0: bn(19, {{
+                    0x0: bpn(19, {{
                         NNPC = NNPC;//Don't do anything
                     }});
-                    0x1: bn(19, {{
+                    0x1: bpn(19, {{
                         NPC = xc->readNextPC() + 4;
                         NNPC = NPC + 4;
                     }}, ',a');
@@ -81,12 +82,38 @@ decode OP default Unknown::unknown()
                     }});
                 }
             }
-            0x2: bicc(22, {{
-                if(passesCondition(Ccr<3:0>, COND2))
-                    NNPC = xc->readPC() + disp;
-                else
-                    handle_annul
-            }});
+            //bicc
+            0x2: decode COND2
+            {
+                //Branch Always
+                0x8: decode A
+                {
+                    0x0: ba(22, {{
+                        NNPC = xc->readPC() + disp;
+                    }});
+                    0x1: ba(22, {{
+                        NPC = xc->readPC() + disp;
+                        NNPC = NPC + 4;
+                    }}, ',a');
+                }
+                //Branch Never
+                0x0: decode A
+                {
+                    0x0: bn(22, {{
+                        NNPC = NNPC;//Don't do anything
+                    }});
+                    0x1: bn(22, {{
+                        NPC = xc->readNextPC() + 4;
+                        NNPC = NPC + 4;
+                    }}, ',a');
+                }
+                default: bicc(22, {{
+                    if(passesCondition(Ccr<3:0>, COND2))
+                        NNPC = xc->readPC() + disp;
+                    else
+                        handle_annul
+                }});
+            }
         }
         0x3: decode RCOND2
         {
@@ -346,26 +373,101 @@ decode OP default Unknown::unknown()
                 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}});
                 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
             }
-            // XXX might want a format rdipr thing here
             0x28: decode RS1 {
-                0xF: decode I {
+                0x00: NoPriv::rdy({{Rd = Y;}});
+                //1 should cause an illegal instruction exception
+                0x02: NoPriv::rdccr({{Rd = Ccr;}});
+                0x03: NoPriv::rdasi({{Rd = Asi;}});
+                0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
+                0x05: NoPriv::rdpc({{
+                    if(Pstate<3:>)
+                        Rd = (xc->readPC())<31:0>;
+                    else
+                        Rd = xc->readPC();}});
+                0x06: NoPriv::rdfprs({{
+                    //Wait for all fpops to finish.
+                    Rd = Fprs;
+                }});
+                //7-14 should cause an illegal instruction exception
+                0x0F: decode I {
                     0x0: Nop::stbar({{/*stuff*/}});
                     0x1: Nop::membar({{/*stuff*/}});
                 }
-                default: rdasr({{
-                Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault);
+                0x10: Priv::rdpcr({{Rd = Pcr;}});
+                0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}});
+                //0x12 should cause an illegal instruction exception
+                0x13: NoPriv::rdgsr({{
+                    if(Fprs<2:> == 0 || Pstate<4:> == 0)
+                        Rd = Gsr;
+                    else
+                        fault = new FpDisabled;
+                }});
+                //0x14-0x15 should cause an illegal instruction exception
+                0x16: Priv::rdsoftint({{Rd = Softint;}});
+                0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}});
+                0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}});
+                0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
+                0x1A: Priv::rdstrand_sts_reg({{
+                    if(Pstate<2:> && !Hpstate<2:>)
+                        Rd = StrandStsReg<0:>;
+                    else
+                        Rd = StrandStsReg;
                 }});
+                //0x1A is supposed to be reserved, but it reads the strand
+                //status register.
+                //0x1B-0x1F should cause an illegal instruction exception
+            }
+            0x29: decode RS1 {
+                0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}});
+                0x01: HPriv::rdhprhtstate({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    Rd = Htstate;
+                }});
+                //0x02 should cause an illegal instruction exception
+                0x03: HPriv::rdhprhintp({{Rd = Hintp;}});
+                //0x04 should cause an illegal instruction exception
+                0x05: HPriv::rdhprhtba({{Rd = Htba;}});
+                0x06: HPriv::rdhprhver({{Rd = Hver;}});
+                //0x07-0x1E should cause an illegal instruction exception
+                0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}});
+            }
+            0x2A: decode RS1 {
+                0x00: Priv::rdprtpc({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    Rd = Tpc;
+                }});
+                0x01: Priv::rdprtnpc({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    Rd = Tnpc;
+                }});
+                0x02: Priv::rdprtstate({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    Rd = Tstate;
+                }});
+                0x03: Priv::rdprtt({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    Rd = Tt;
+                }});
+                0x04: Priv::rdprtick({{Rd = Tick;}});
+                0x05: Priv::rdprtba({{Rd = Tba;}});
+                0x06: Priv::rdprpstate({{Rd = Pstate;}});
+                0x07: Priv::rdprtl({{Rd = Tl;}});
+                0x08: Priv::rdprpil({{Rd = Pil;}});
+                0x09: Priv::rdprcwp({{Rd = Cwp;}});
+                0x0A: Priv::rdprcansave({{Rd = Cansave;}});
+                0x0B: Priv::rdprcanrestore({{Rd = Canrestore;}});
+                0x0C: Priv::rdprcleanwin({{Rd = Cleanwin;}});
+                0x0D: Priv::rdprotherwin({{Rd = Otherwin;}});
+                0x0E: Priv::rdprwstate({{Rd = Wstate;}});
+                //0x0F should cause an illegal instruction exception
+                0x10: Priv::rdprgl({{Rd = Gl;}});
+                //0x11-0x1F should cause an illegal instruction exception
             }
-            0x29: HPriv::rdhpr({{
-                // XXX Need to protect with format that traps non-priv/priv
-                // access
-                Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault);
-            }});
-            0x2A: Priv::rdpr({{
-                // XXX Need to protect with format that traps non-priv
-                // access
-                Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault);
-            }});
             0x2B: BasicOperate::flushw({{
                 if(NWindows - 2 - Cansave == 0)
                 {
@@ -421,23 +523,128 @@ decode OP default Unknown::unknown()
                 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}});
                 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}});
             }
-            0x30: wrasr({{
-                xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13);
-            }});
+            0x30: decode RD {
+                0x00: NoPriv::wry({{Y = Rs1 ^ Rs2_or_imm13;}});
+                //0x01 should cause an illegal instruction exception
+                0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
+                0x03: NoPriv::wrasi({{Ccr = Rs1 ^ Rs2_or_imm13;}});
+                //0x04-0x05 should cause an illegal instruction exception
+                0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}});
+                //0x07-0x0E should cause an illegal instruction exception
+                0x0F: Trap::softreset({{fault = new SoftwareInitiatedReset;}});
+                0x10: Priv::wrpcr({{Pcr = Rs1 ^ Rs2_or_imm13;}});
+                0x11: PrivCheck::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}});
+                //0x12 should cause an illegal instruction exception
+                0x13: NoPriv::wrgsr({{
+                    if(Fprs<2:> == 0 || Pstate<4:> == 0)
+                        return new FpDisabled;
+                    Gsr = Rs1 ^ Rs2_or_imm13;
+                }});
+                0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}});
+                0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}});
+                0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}});
+                0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}});
+                0x18: NoPriv::wrstick({{
+                    if(!Hpstate<2:>)
+                        return new IllegalInstruction;
+                    Stick = Rs1 ^ Rs2_or_imm13;
+                }});
+                0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
+                0x1A: Priv::wrstrand_sts_reg({{
+                    if(Pstate<2:> && !Hpstate<2:>)
+                        StrandStsReg = StrandStsReg<63:1> |
+                                (Rs1 ^ Rs2_or_imm13)<0:>;
+                    else
+                        StrandStsReg = Rs1 ^ Rs2_or_imm13;
+                }});
+                //0x1A is supposed to be reserved, but it writes the strand
+                //status register.
+                //0x1B-0x1F should cause an illegal instruction exception
+            }
             0x31: decode FCN {
-                0x0: BasicOperate::saved({{/*Boogy Boogy*/}});
-                0x1: BasicOperate::restored({{/*Boogy Boogy*/}});
+                0x0: Priv::saved({{
+                    assert(Cansave < NWindows - 2);
+                    assert(Otherwin || Canrestore);
+                    Cansave = Cansave + 1;
+                    if(Otherwin == 0)
+                        Canrestore = Canrestore - 1;
+                    else
+                        Otherwin = Otherwin - 1;
+                }});
+                0x1: Priv::restored({{
+                    assert(Cansave || Otherwin);
+                    assert(Canrestore < NWindows - 2);
+                    Canrestore = Canrestore + 1;
+                    if(Otherwin == 0)
+                        Cansave = Cansave - 1;
+                    else
+                        Otherwin = Otherwin - 1;
+                }});
+            }
+            0x32: decode RD {
+                0x00: Priv::wrprtpc({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    else
+                        Tpc = Rs1 ^ Rs2_or_imm13;
+                }});
+                0x01: Priv::wrprtnpc({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    else
+                        Tnpc = Rs1 ^ Rs2_or_imm13;
+                }});
+                0x02: Priv::wrprtstate({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    else
+                        Tstate = Rs1 ^ Rs2_or_imm13;
+                }});
+                0x03: Priv::wrprtt({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    else
+                        Tt = Rs1 ^ Rs2_or_imm13;
+                }});
+                0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
+                0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
+                0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
+                0x07: Priv::wrprtl({{
+                    if(Pstate<2:> && !Hpstate<2:>)
+                        Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPTL);
+                    else
+                        Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxTL);
+                }});
+                0x08: Priv::wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}});
+                0x09: Priv::wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}});
+                0x0A: Priv::wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}});
+                0x0B: Priv::wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}});
+                0x0C: Priv::wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}});
+                0x0D: Priv::wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}});
+                0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}});
+                //0x0F should cause an illegal instruction exception
+                0x10: Priv::wrprgl({{
+                    if(Pstate<2:> && !Hpstate<2:>)
+                        Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPGL);
+                    else
+                        Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxGL);
+                }});
+                //0x11-0x1F should cause an illegal instruction exception
+            }
+            0x33: decode RD {
+                0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}});
+                0x01: HPriv::wrhprhtstate({{
+                    if(Tl == 0)
+                        return new IllegalInstruction;
+                    Htstate = Rs1 ^ Rs2_or_imm13;
+                }});
+                //0x02 should cause an illegal instruction exception
+                0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}});
+                //0x04 should cause an illegal instruction exception
+                0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}});
+                //0x06-0x01D should cause an illegal instruction exception
+                0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
             }
-            0x32: Priv::wrpr({{
-                // XXX Need to protect with format that traps non-priv
-                // access
-                fault = xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
-            }});
-            0x33: HPriv::wrhpr({{
-                // XXX Need to protect with format that traps non-priv/priv
-                // access
-                fault = xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
-            }});
             0x34: decode OPF{
                 format BasicOperate{
                     0x01: fmovs({{
@@ -684,10 +891,6 @@ decode OP default Unknown::unknown()
                     NNPC = target;
                 if(fault == NoFault)
                 {
-                    //CWP should be set directly so that it always happens
-                    //Also, this will allow writing to the new window and
-                    //reading from the old one
-                    Cwp = (Cwp - 1 + NWindows) % NWindows;
                     if(Canrestore == 0)
                     {
                         if(Otherwin)
@@ -697,14 +900,17 @@ decode OP default Unknown::unknown()
                     }
                     else
                     {
-                        Rd = Rs1 + Rs2_or_imm13;
+                        //CWP should be set directly so that it always happens
+                        //Also, this will allow writing to the new window and
+                        //reading from the old one
+                        Cwp = (Cwp - 1 + NWindows) % NWindows;
                         Cansave = Cansave + 1;
                         Canrestore = Canrestore - 1;
+                        //This is here to make sure the CWP is written
+                        //no matter what. This ensures that the results
+                        //are written in the new window as well.
+                        xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
                     }
-                    //This is here to make sure the CWP is written
-                    //no matter what. This ensures that the results
-                    //are written in the new window as well.
-                    xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
                 }
             }});
             0x3A: decode CC
@@ -747,11 +953,11 @@ decode OP default Unknown::unknown()
                         fault = new SpillNOther(Wstate<5:3>);
                     else
                         fault = new SpillNNormal(Wstate<2:0>);
-                    Cwp = (Cwp + 2) % NWindows;
+                    //Cwp = (Cwp + 2) % NWindows;
                 }
                 else if(Cleanwin - Canrestore == 0)
                 {
-                    Cwp = (Cwp + 1) % NWindows;
+                    //Cwp = (Cwp + 1) % NWindows;
                     fault = new CleanWindow;
                 }
                 else
@@ -760,17 +966,13 @@ decode OP default Unknown::unknown()
                     Rd = Rs1 + Rs2_or_imm13;
                     Cansave = Cansave - 1;
                     Canrestore = Canrestore + 1;
+                    //This is here to make sure the CWP is written
+                    //no matter what. This ensures that the results
+                    //are written in the new window as well.
+                    xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
                 }
-                //This is here to make sure the CWP is written
-                //no matter what. This ensures that the results
-                //are written in the new window as well.
-                xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
             }});
             0x3D: restore({{
-                //CWP should be set directly so that it always happens
-                //Also, this will allow writing to the new window and
-                //reading from the old one
-                Cwp = (Cwp - 1 + NWindows) % NWindows;
                 if(Canrestore == 0)
                 {
                     if(Otherwin)
@@ -780,14 +982,18 @@ decode OP default Unknown::unknown()
                 }
                 else
                 {
+                    //CWP should be set directly so that it always happens
+                    //Also, this will allow writing to the new window and
+                    //reading from the old one
+                    Cwp = (Cwp - 1 + NWindows) % NWindows;
                     Rd = Rs1 + Rs2_or_imm13;
                     Cansave = Cansave + 1;
                     Canrestore = Canrestore - 1;
+                    //This is here to make sure the CWP is written
+                    //no matter what. This ensures that the results
+                    //are written in the new window as well.
+                    xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
                 }
-                //This is here to make sure the CWP is written
-                //no matter what. This ensures that the results
-                //are written in the new window as well.
-                xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
             }});
             0x3E: decode FCN {
                 0x0: Priv::done({{
@@ -812,7 +1018,7 @@ decode OP default Unknown::unknown()
                     Ccr = Tstate<39:32>;
                     Gl = Tstate<42:40>;
                     NPC = Tpc;
-                    NNPC = Tnpc + 4;
+                    NNPC = Tnpc;
                     Tl = Tl - 1;
                 }});
             }
@@ -840,17 +1046,15 @@ decode OP default Unknown::unknown()
             0x09: ldsb({{Rd = (int8_t)Mem.sb;}});
             0x0A: ldsh({{Rd = (int16_t)Mem.shw;}});
             0x0B: ldx({{Rd = (int64_t)Mem.sdw;}});
-            0x0D: ldstub({{
-                Rd = Mem.ub;
-                Mem.ub = 0xFF;
-            }});
         }
+        0x0D: LoadStore::ldstub(
+        {{Rd = Mem.ub;}},
+        {{Mem.ub = 0xFF;}});
         0x0E: Store::stx({{Mem.udw = Rd}});
-        0x0F: LoadStore::swap({{
-            uint32_t temp = Rd;
-            Rd = Mem.uw;
-            Mem.uw = temp;
-        }});
+        0x0F: LoadStore::swap(
+            {{uReg0 = Rd.uw;
+            Rd.uw = Mem.uw;}},
+            {{Mem.uw = uReg0;}});
         format Load {
             0x10: lduwa({{Rd = Mem.uw;}});
             0x11: lduba({{Rd = Mem.ub;}});
@@ -873,16 +1077,14 @@ decode OP default Unknown::unknown()
             0x1A: ldsha({{Rd = (int16_t)Mem.shw;}});
             0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}});
         }
-        0x1D: LoadStore::ldstuba({{
-            Rd = Mem.ub;
-            Mem.ub = 0xFF;
-        }});
+        0x1D: LoadStore::ldstuba(
+                {{Rd = Mem.ub;}},
+                {{Mem.ub = 0xFF}});
         0x1E: Store::stxa({{Mem.udw = Rd}});
-        0x1F: LoadStore::swapa({{
-            uint32_t temp = Rd;
-            Rd = Mem.uw;
-            Mem.uw = temp;
-        }});
+        0x1F: LoadStore::swapa(
+            {{uReg0 = Rd.uw;
+            Rd.uw = Mem.uw;}},
+            {{Mem.uw = uReg0;}});
         format Trap {
             0x20: Load::ldf({{Frd.uw = Mem.uw;}});
             0x21: decode X {
@@ -1065,19 +1267,21 @@ decode OP default Unknown::unknown()
                         {{fault = new DataAccessException;}});
                 }
             }
-            0x3C: Cas::casa({{
-                uint64_t val = Mem.uw;
-                if(Rs2.uw == val)
+            0x3C: Cas::casa(
+                {{uReg0 = Mem.uw;}},
+                {{if(Rs2.uw == uReg0)
                         Mem.uw = Rd.uw;
-                Rd.uw = val;
-            }});
+                else
+                        storeCond = false;
+                Rd.uw = uReg0;}});
             0x3D: Nop::prefetcha({{ }});
-            0x3E: Cas::casxa({{
-                uint64_t val = Mem.udw;
-                if(Rs2 == val)
+            0x3E: Cas::casxa(
+                {{uReg0 = Mem.udw;}},
+                {{if(Rs2 == uReg0)
                         Mem.udw = Rd;
-                Rd = val;
-            }});
+                else
+                        storeCond = false;
+                Rd = uReg0;}});
         }
     }
 }