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');
//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');
}});
}
}
- 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
{
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)
{
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({{
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)
}
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
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
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)
}
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({{
Ccr = Tstate<39:32>;
Gl = Tstate<42:40>;
NPC = Tpc;
- NNPC = Tnpc + 4;
+ NNPC = Tnpc;
Tl = Tl - 1;
}});
}
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;}});
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 {
{{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;}});
}
}
}