diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc index e05b3fe59..142dfe0a4 100644 --- a/arch/mips/faults.cc +++ b/arch/mips/faults.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/faults.hh" +#include "arch/mips/faults.hh" ResetFaultType * const ResetFault = new ResetFaultType("reset", 1, 0x0001); diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh index 60c9e735c..c1cb956b0 100644 --- a/arch/mips/faults.hh +++ b/arch/mips/faults.hh @@ -26,131 +26,131 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ALPHA_FAULTS_HH__ -#define __ALPHA_FAULTS_HH__ +#ifndef __MIPS_FAULTS_HH__ +#define __MIPS_FAULTS_HH__ #include "sim/faults.hh" #include "arch/isa_traits.hh" //For the Addr type -class AlphaFault : public Fault +class MipsFault : public FaultBase { public: - AlphaFault(char * newName, int newId, Addr newVect) - : Fault(newName, newId), vect(newVect) + MipsFault(char * newName, int newId, Addr newVect) + : FaultBase(newName, newId), vect(newVect) {;} Addr vect; }; -extern class ResetFaultType : public AlphaFault +extern class ResetFaultType : public MipsFault { public: ResetFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ResetFault; -extern class ArithmeticFaultType : public AlphaFault +extern class ArithmeticFaultType : public MipsFault { public: ArithmeticFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ArithmeticFault; -extern class InterruptFaultType : public AlphaFault +extern class InterruptFaultType : public MipsFault { public: InterruptFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const InterruptFault; -extern class NDtbMissFaultType : public AlphaFault +extern class NDtbMissFaultType : public MipsFault { public: NDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const NDtbMissFault; -extern class PDtbMissFaultType : public AlphaFault +extern class PDtbMissFaultType : public MipsFault { public: PDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const PDtbMissFault; -extern class DtbPageFaultType : public AlphaFault +extern class DtbPageFaultType : public MipsFault { public: DtbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const DtbPageFault; -extern class DtbAcvFaultType : public AlphaFault +extern class DtbAcvFaultType : public MipsFault { public: DtbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const DtbAcvFault; -extern class ItbMissFaultType : public AlphaFault +extern class ItbMissFaultType : public MipsFault { public: ItbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ItbMissFault; -extern class ItbPageFaultType : public AlphaFault +extern class ItbPageFaultType : public MipsFault { public: ItbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ItbPageFault; -extern class ItbAcvFaultType : public AlphaFault +extern class ItbAcvFaultType : public MipsFault { public: ItbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ItbAcvFault; -extern class UnimplementedOpcodeFaultType : public AlphaFault +extern class UnimplementedOpcodeFaultType : public MipsFault { public: UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const UnimplementedOpcodeFault; -extern class FloatEnableFaultType : public AlphaFault +extern class FloatEnableFaultType : public MipsFault { public: FloatEnableFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const FloatEnableFault; -extern class PalFaultType : public AlphaFault +extern class PalFaultType : public MipsFault { public: PalFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const PalFault; -extern class IntegerOverflowFaultType : public AlphaFault +extern class IntegerOverflowFaultType : public MipsFault { public: IntegerOverflowFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const IntegerOverflowFault; diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 7600632d3..4125b5101 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -7,7 +7,13 @@ //Outputs to decoder.hh output header {{ + #define R31 31 +#include "arch/mips/faults.hh" +#include "arch/mips/isa_traits.hh" + + using namespace MipsISA; + /** * Base class for all MIPS static instructions. @@ -19,12 +25,12 @@ output header {{ /// Make MipsISA register dependence tags directly visible in /// this class and derived classes. Maybe these should really /// live here and not in the MipsISA namespace. - enum DependenceTags { + /*enum DependenceTags { FP_Base_DepTag = MipsISA::FP_Base_DepTag, Fpcr_DepTag = MipsISA::Fpcr_DepTag, Uniq_DepTag = MipsISA::Uniq_DepTag, IPR_Base_DepTag = MipsISA::IPR_Base_DepTag - }; + };*/ // Constructor MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) @@ -67,6 +73,7 @@ output decoder {{ { printReg(ss, _srcRegIdx[0]); } + if(_numSrcRegs > 1) { ss << ","; diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index 3a01b64ee..58d487ad2 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -33,10 +33,12 @@ def bitfield INTIMM <15: 0>; // integer immediate (literal) // Floating-point operate format def bitfield FMT <25:21>; +def bitfield FR <25:21>; def bitfield FT <20:16>; def bitfield FS <15:11>; def bitfield FD <10:6>; +def bitfield CC <20:18>; def bitfield ND <17:17>; def bitfield TF <16:16>; def bitfield MOVCI <16:16>; @@ -45,6 +47,9 @@ def bitfield SRL <21:21>; def bitfield SRLV < 6: 6>; def bitfield SA <10: 6>; +// CP0 Register Select +def bitfield SEL < 2: 0>; + // Interrupts def bitfield SC < 5: 5>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index f16da7f87..b2410f9b9 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -20,8 +20,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format BasicOp { - 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); - 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); + 0: movf({{ if (xc->readMiscReg(FPCR,0) != CC) Rd = Rs}}); + 1: movt({{ if (xc->readMiscReg(FPCR,0) == CC) Rd = Rs}}); } } @@ -60,9 +60,9 @@ decode OPCODE_HI default Unknown::unknown() { //to distinguish JR from JR.HB and JALR from JALR.HB" format Jump { 0x0: decode HINT { - 0:jr({{ NNPC = Rs; }},IsReturn); + 0:jr({{ NNPC = Rs & ~1; }},IsReturn); - 1:jr_hb({{ NNPC = Rs; clear_exe_inst_hazards(); }},IsReturn); + 1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn); } 0x1: decode HINT { @@ -86,10 +86,10 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { format BasicOp { - 0x0: mfhi({{ Rd = xc->miscRegs.hi; }}); - 0x1: mthi({{ xc->miscRegs.hi = Rs; }}); - 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); - 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); + 0x0: mfhi({{ Rd = xc->readMiscReg(Hi,0); }}); + 0x1: mthi({{ xc->setMiscReg(Hi,0,Rs); }}); + 0x2: mflo({{ Rd = xc->readMiscReg(Lo,0); }}); + 0x3: mtlo({{ xc->setMiscReg(Lo,0,Rs); }}); } } @@ -97,39 +97,38 @@ decode OPCODE_HI default Unknown::unknown() { format IntOp { 0x0: mult({{ int64_t temp1 = Rs.sw * Rt.sw; - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0>; + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x1: multu({{ int64_t temp1 = Rs.uw * Rt.uw; - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> - Rd.sw = Rs.uw * Rt.uw; + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x2: div({{ - xc->miscRegs.hi = Rs.sw % Rt.sw; - xc->miscRegs.lo = Rs.sw / Rt.sw; + xc->setMiscReg(Hi,0,Rs.sw % Rt.sw); + xc->setMiscReg(Lo,0,Rs.sw / Rt.sw); }}); 0x3: divu({{ - xc->miscRegs.hi = Rs.uw % Rt.uw; - xc->miscRegs.lo = Rs.uw / Rt.uw; + xc->setMiscReg(Hi,0,Rs.uw % Rt.uw); + xc->setMiscReg(Lo,0,Rs.uw / Rt.uw); }}); } } 0x4: decode FUNCTION_LO { format IntOp { - 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); - 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); - 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); - 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); - 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); - 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); - 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); - 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}}); + 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); + 0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}}); + 0x4: and({{ Rd = Rs & Rt;}}); + 0x5: or({{ Rd = Rs | Rt;}}); + 0x6: xor({{ Rd = Rs ^ Rt;}}); + 0x7: nor({{ Rd = ~(Rs | Rt);}}); } } @@ -141,8 +140,8 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode FUNCTION_LO { - format BasicOp { - 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); + format Trap { + 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); @@ -167,7 +166,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode REGIMM_LO { - format BasicOp { + format Trap { 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); @@ -198,14 +197,14 @@ decode OPCODE_HI default Unknown::unknown() { } format Jump { - 0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}}); + 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}}); - 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn); + 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn); } format Branch { - 0x4: beq({{ cond = (Rs.sw == 0); }}); - 0x5: bne({{ cond = (Rs.sw != 0); }}); + 0x4: beq({{ cond = (Rs.sw == Rt.sw); }}); + 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); 0x6: blez({{ cond = (Rs.sw <= 0); }}); 0x7: bgtz({{ cond = (Rs.sw > 0); }}); } @@ -213,10 +212,10 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode OPCODE_LO { format IntOp { - 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }}); - 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}}); - 0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }}); - 0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }}); + 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); + 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); + 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); + 0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }}); 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); @@ -229,33 +228,17 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-11 MIPS32 COP0 Encoding of rs Field 0x0: decode RS_MSB { 0x0: decode RS { - format BasicOp { + format System { 0x0: mfc0({{ - //The contents of the coprocessor 0 register specified by the - //combination of rd and sel are loaded into general register - //rt. Note that not all coprocessor 0 registers support the - //sel field. In those instances, the sel field must be zero. + //uint64_t reg_num = Rd.uw; - if (SEL > 0) - panic("Can't Handle Cop0 with register select yet\n"); - - uint64_t reg_num = Rd.uw; - - Rt = xc->miscRegs.cop0[reg_num]; + Rt = xc->readMiscReg(RD,SEL); }}); 0x4: mtc0({{ - //The contents of the coprocessor 0 register specified by the - //combination of rd and sel are loaded into general register - //rt. Note that not all coprocessor 0 registers support the - //sel field. In those instances, the sel field must be zero. + //uint64_t reg_num = Rd.uw; - if (SEL > 0) - panic("Can't Handle Cop0 with register select yet\n"); - - uint64_t reg_num = Rd.uw; - - xc->miscRegs.cop0[reg_num] = Rt; + xc->setMiscReg(RD,SEL,Rt); }}); 0x8: mftr({{ @@ -279,64 +262,84 @@ decode OPCODE_HI default Unknown::unknown() { 0xA: rdpgpr({{ //Accessing Previous Shadow Set Register Number - uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; - uint64_t reg_num = Rt.uw; + //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/; + //uint64_t reg_num = Rt.uw; - Rd = xc->shadowIntRegFile[prev][reg_num]; + //Rd = xc->regs.IntRegFile[prev]; + //Rd = xc->shadowIntRegFile[prev][reg_num]; }}); 0xB: decode RD { 0x0: decode SC { 0x0: dvpe({{ - Rt.sw = xc->miscRegs.cop0.MVPControl; - xc->miscRegs.cop0.MVPControl[EVP] = 0; + int idx; + int sel; + getMiscRegIdx(MVPControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,0); }}); 0x1: evpe({{ - Rt.sw = xc->miscRegs.cop0.MVPControl; - xc->miscRegs.cop0.MVPControl[EVP] = 1; + int idx; + int sel; + getMiscRegIdx(MVPControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,1); }}); } 0x1: decode SC { 0x0: dmt({{ - Rt.sw = xc->miscRegs.cop0.VPEControl; - xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0; + int idx; + int sel; + getMiscRegIdx(VPEControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,0); }}); 0x1: emt({{ - Rt.sw = xc->miscRegs.cop0.VPEControl; - xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1; + int idx; + int sel; + getMiscRegIdx(VPEControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,1); }}); } 0xC: decode SC { 0x0: di({{ - Rt.sw = xc->miscRegs.cop0.Status; - xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0; + int idx; + int sel; + getMiscRegIdx(Status,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,0); }}); 0x1: ei({{ - Rt.sw = xc->miscRegs.cop0.Status; - xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1; + int idx; + int sel; + getMiscRegIdx(Status,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,1); }}); } } 0xE: wrpgpr({{ //Accessing Previous Shadow Set Register Number - uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; - uint64_t reg_num = Rd.uw; + //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/); + //uint64_t reg_num = Rd.uw; - xc->shadowIntRegFile[prev][reg_num] = Rt; + //xc->regs.IntRegFile[prev]; + //xc->shadowIntRegFile[prev][reg_num] = Rt; }}); } } //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 0x1: decode FUNCTION { - format BasicOp { + format System { 0x01: tlbr({{ }}); 0x02: tlbwi({{ }}); 0x06: tlbwr({{ }}); @@ -357,27 +360,27 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { format FloatOp { - 0x0: mfc1({{ Rt = Fs<31:0>; }}); - 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}}); - 0x3: mfhc1({{ Rt = Fs<63:32>;}}); - 0x4: mtc1({{ Fs<31:0> = Rt}}); - 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}}); - 0x7: mftc1({{ Fs<63:32> = Rt}}); + 0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }}); + 0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}}); + 0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}}); + 0x4: mtc1({{ /*Fs = Rt.uw*/}}); + 0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}}); + 0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}}); } } 0x1: decode ND { 0x0: decode TF { format Branch { - 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); + 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); + 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); } } 0x1: decode TF { format BranchLikely { - 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); + 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); + 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); } } } @@ -396,7 +399,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); - 0x5: abss({{ Fd.sf = abs(Fs.sf);}}); + 0x5: abss({{ Fd.sf = fabs(Fs.sf);}}); 0x6: movs({{ Fd.sf = Fs.sf;}}); 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); } @@ -422,8 +425,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }}); - 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}}); + 0x0: movfs({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); + 0x1: movts({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); } } @@ -434,29 +437,29 @@ decode OPCODE_HI default Unknown::unknown() { format Float64Op { 0x5: recips({{ Fd = 1 / Fs; }}); - 0x6: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); + 0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}}); } } 0x4: decode RS_LO { format FloatOp { - 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); }}); - 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); }}); } //only legal for 64 bit format Float64Op { - 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); }}); - 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }}); + 0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }}); } } } @@ -470,7 +473,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); - 0x5: absd({{ Fd.df = abs(Fs.df);}}); + 0x5: absd({{ Fd.df = fabs(Fs.df);}}); 0x6: movd({{ Fd.df = Fs.df;}}); 0x7: negd({{ Fd.df = -1 * Fs.df;}}); } @@ -496,8 +499,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }}); - 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }}); + 0x0: movfd({{if (xc->readMiscReg(FPCR,0) != CC) Fd.df = Fs.df; }}); + 0x1: movtd({{if (xc->readMiscReg(FPCR,0) == CC) Fd.df = Fs.df; }}); } } @@ -515,12 +518,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode RS_LO { format FloatOp { 0x0: cvt_s_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); }}); 0x4: cvt_w_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); }}); } @@ -528,7 +531,7 @@ decode OPCODE_HI default Unknown::unknown() { //only legal for 64 bit format Float64Op { 0x5: cvt_l_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); }}); } @@ -539,12 +542,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION { format FloatOp { 0x20: cvt_s({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); }}); 0x21: cvt_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); }}); } @@ -556,12 +559,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: decode FUNCTION_HI { format FloatOp { 0x10: cvt_s_l({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); }}); 0x11: cvt_d_l({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); }}); } @@ -590,12 +593,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut - Fd.df = abs(Fs.df); + Fd.df = fabs(Fs.df); }}); 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs<31:0> | Ft<31:0>; + //Fd.df = Fs<31:0> | Ft<31:0>; }}); 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and @@ -608,21 +611,21 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format Float64Op { - 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); - 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); + 0x0: movfps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs;}}); + 0x1: movtps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); } } format BasicOp { - 0x2: movzps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }}); - 0x3: movnps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }}); + 0x2: movzps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); + 0x3: movnps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs; }}); } } 0x4: decode RS_LO { 0x0: Float64Op::cvt_s_pu({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); }}); } @@ -630,13 +633,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: decode RS_LO { format Float64Op { 0x0: cvt_s_pl({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); }}); - 0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}}); - 0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}}); - 0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}}); - 0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}}); + 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}}); + 0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}}); + 0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}}); + 0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}}); } } } @@ -682,23 +685,23 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format LoadMemory2 { - 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }}); - 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }}); + 0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}}); + 0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }}); 0x5: luxc1({{ //Need to make EA<2:0> = 0 EA = Rs + Rt; }}, - {{ Ft<31:0> = Mem.df; }}); + {{ /*F_t<31:0> = Mem.df; */}}); } } 0x1: decode FUNCTION_LO { format StoreMemory2 { - 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.sf = Ft<31:0>; }}); - 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.df = Ft<63:0>}}); + 0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}}); + 0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}}); 0x5: suxc1({{ //Need to make EA<2:0> = 0 EA = Rs + Rt; }}, - {{ Mem.df = Ft<63:0>;}}); + {{ /*Mem.df = F_t<63:0>;*/}}); } 0x7: WarnUnimpl::prefx(); @@ -768,33 +771,33 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format IntOp { 0x0: madd({{ - int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 + (Rs.sw * Rt.sw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x1: maddu({{ - int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 + (Rs.uw * Rt.uw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); - 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); + 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); 0x4: msub({{ - int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 - (Rs.sw * Rt.sw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x5: msubu({{ - int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 - (Rs.uw * Rt.uw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); } } @@ -802,25 +805,25 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION_LO { format BasicOp { 0x0: clz({{ - int cnt = 0; + /*int cnt = 0; int idx = 0; - while ( Rs.uw!= 1) { + while ( Rs.uw != 1) { cnt++; idx--; } - Rd.uw = cnt; + Rd.uw = cnt;*/ }}); 0x1: clo({{ - int cnt = 0; + /*int cnt = 0; int idx = 0; - while ( Rs.uw!= 0) { + while ( Rs.uw != 0) { cnt++; idx--; } - Rd.uw = cnt; + Rd.uw = cnt;*/ }}); } } @@ -860,20 +863,20 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode FUNCTION_LO { - 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); + 0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }}); } } } 0x4: decode OPCODE_LO default FailUnimpl::reserved() { format LoadMemory { - 0x0: lb({{ Rb.sw = Mem.sb; }}); - 0x1: lh({{ Rb.sw = Mem.sh; }}); - 0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign); - 0x3: lw({{ Rb.uq = Mem.sb; }}); - 0x4: lbu({{ Rb.uw = Mem.ub; }}); - 0x5: lhu({{ Rb.uw = Mem.uh; }}); - 0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign); + 0x0: lb({{ Rt.sw = Mem.sb; }}); + 0x1: lh({{ Rt.sw = Mem.sh; }}); + 0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign); + 0x3: lw({{ Rt.sw = Mem.sb; }}); + 0x4: lbu({{ Rt.uw = Mem.ub; }}); + 0x5: lhu({{ Rt.uw = Mem.uh; }}); + 0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign); } 0x7: FailUnimpl::reserved(); @@ -898,19 +901,19 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: WarnUnimpl::ll(); format LoadMemory { - 0x1: lwc1({{ Ft<31:0> = Mem.sf; }}); - 0x5: ldc1({{ Ft<63:0> = Mem.df; }}); + 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}}); + 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}}); } } + 0x7: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: WarnUnimpl::sc(); format StoreMemory { - 0x1: swc1({{ Mem.sf = Ft<31:0>; }}); - 0x5: sdc1({{ Mem.df = Ft<63:0>; }}); + 0x1: swc1({{ //Mem.sf = Ft<31:0>; }}); + 0x5: sdc1({{ //Mem.df = Ft<63:0>; }}); } - } } diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index a6aec9437..f7a9e4ce2 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -10,6 +10,9 @@ //Include utility formats/functions ##include "m5/arch/mips/isa/formats/util.isa" +//Include the cop0 formats +##include "m5/arch/mips/isa/formats/cop0.isa" + //Include the integer formats ##include "m5/arch/mips/isa/formats/int.isa" diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa index 3b62aa5c3..c02af7ddc 100644 --- a/arch/mips/isa/formats/basic.isa +++ b/arch/mips/isa/formats/basic.isa @@ -31,14 +31,14 @@ def template BasicConstructor {{ def template BasicExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if(fault == No_Fault) + if(fault == NoFault) { %(op_wb)s; } diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index c896e9b2d..0d2ad7855 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -7,6 +7,9 @@ output header {{ +#include + using namespace std; + /** * Base class for instructions whose disassembly is not purely a * function of the machine instruction (i.e., it depends on the @@ -52,6 +55,10 @@ output header {{ : PCDependentDisassembly(mnem, _machInst, __opClass), disp(OFFSET << 2) { + //If Bit 17 is 1 then Sign Extend + if ( (disp & 0x00020000) > 0 ) { + disp |= 0xFFFE0000; + } } Addr branchTarget(Addr branchPC) const; @@ -74,6 +81,7 @@ output header {{ : PCDependentDisassembly(mnem, _machInst, __opClass), disp(OFFSET << 2) { + } Addr branchTarget(Addr branchPC) const; @@ -93,11 +101,13 @@ output header {{ /// Displacement to target address (signed). int32_t disp; + uint32_t target; + public: /// Constructor Jump(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(OFFSET) + disp(JMPTARG << 2) { } @@ -159,23 +169,17 @@ output decoder {{ // either a source (the condition for conditional // branches) or a destination (the link reg for // unconditional branches) - if (_numSrcRegs > 0) { + if (_numSrcRegs == 1) { printReg(ss, _srcRegIdx[0]); ss << ","; - } - else if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); + } else if(_numSrcRegs == 2) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + printReg(ss, _srcRegIdx[1]); ss << ","; } -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numSrcRegs == 0 && _numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - - Addr target = pc + 4 + disp; + Addr target = pc + 8 + disp; std::string str; if (symtab && symtab->findSymbol(target, str)) @@ -206,13 +210,6 @@ output decoder {{ ss << ","; } -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numSrcRegs == 0 && _numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - Addr target = pc + 4 + disp; std::string str; @@ -231,19 +228,24 @@ output decoder {{ ccprintf(ss, "%-10s ", mnemonic); -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numDestRegs == 0) { - printReg(ss, 31); + if ( mnemonic == "jal" ) { + Addr npc = pc + 4; + ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp); + } else if (_numSrcRegs == 0) { + std::string str; + if (symtab && symtab->findSymbol(disp, str)) + ss << str; + else + ccprintf(ss, "0x%x", disp); + } else if (_numSrcRegs == 1) { + printReg(ss, _srcRegIdx[0]); + } else if(_numSrcRegs == 2) { + printReg(ss, _srcRegIdx[0]); ss << ","; + printReg(ss, _srcRegIdx[1]); + } else { + panic(">= 3 Source Registers!!!"); } -#endif - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; - } - - ccprintf(ss, "(r%d)", RT); return ss.str(); } @@ -253,16 +255,18 @@ def format Branch(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-2:] == 'al': - code += 'R31 = NNPC;\n' + code += 'r31 = NNPC;\n' #Condition code code = 'bool cond;\n' + code code += 'if (cond) {\n' - #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n' - #code += ' NPC = NPC; \n' code += ' NNPC = NPC + disp;\n' + code += '} else {\n' + code += ' NNPC = NNPC;\n' code += '} \n' + code += 'cout << hex << "NPC: " << NPC << " + " << disp << " = " << NNPC << endl;' + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl')) @@ -277,13 +281,11 @@ def format BranchLikely(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-3:] == 'all': - code += 'R31 = NNPC;\n' + code += 'r31 = NNPC;\n' #Condition code code = 'bool cond;\n' + code code += 'if (cond) {' - #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n' - #code += 'NPC = NPC; \n' code += 'NNPC = NPC + disp;\n' code += '} \n' @@ -300,8 +302,11 @@ def format BranchLikely(code,*flags) {{ def format Jump(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) - if strlen >= 3 and name[2:3] == 'al': - code = 'R31 = NNPC;\n' + code + if strlen > 1 and name[1:] == 'al': + code = 'r31 = NNPC;\n' + code + + #code += 'if(NNPC == 0x80000638) { NNPC = r31; cout << "SKIPPING JUMP TO SIM_GET_MEM_CONF" << endl;}' + #code += 'target = NNPC;' iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\ ('IsIndirectControl', 'IsUncondControl')) diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 7dd1e8442..34b71acf7 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -29,47 +29,6 @@ output decoder {{ } }}; -def template FloatingPointExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const - { - //These are set to constants when the execute method - //is generated - bool useCc = ; - bool checkPriv = ; - - //Attempt to execute the instruction - try - { - checkPriv; - - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(MipsException except) - { - //Deal with exception - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - if(useCc) - { - xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63); - xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0); - xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue; - xc->regs.miscRegFile.ccrFields.iccFields.c = icValue; - xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31); - xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0); - xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue; - xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue; - } - return No_Fault; - } -}}; // Primary format for integer operate instructions: def format FloatOp(code, *flags) {{ diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index cf06741a1..a47844bee 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -7,6 +7,8 @@ //Outputs to decoder.hh output header {{ +#include + using namespace std; /** * Base class for integer operations. */ @@ -26,15 +28,24 @@ output header {{ class IntImmOp : public MipsStaticInst { protected: - uint16_t imm; + + int32_t imm; /// Constructor IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM) { + //If Bit 15 is 1 then Sign Extend + int32_t temp = imm & 0x00008000; + + if (temp > 0 && mnemonic != "lui") { + imm |= 0xFFFF0000; + } } std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + }; }}; @@ -43,15 +54,59 @@ output header {{ output decoder {{ std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ","; + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + + if (_numSrcRegs > 1) { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); } std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer immediate instruction\n"; - } -}}; + std::stringstream ss; + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ","; + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + + if( mnemonic == "lui") + ccprintf(ss, "%08p ", imm); + else + ss << (int) imm; + + return ss.str(); + } + +}}; //Used by decoder.isa def format IntOp(code, *opt_flags) {{ diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index fcdb577c6..8a07e63d4 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -40,6 +40,7 @@ output header {{ const StaticInstPtr eaCompPtr; /// Pointer to MemAcc object. const StaticInstPtr memAccPtr; + /// Displacement for EA calculation (signed). int32_t disp; @@ -51,6 +52,12 @@ output header {{ memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), disp(OFFSET) { + //If Bit 15 is 1 then Sign Extend + int32_t temp = disp & 0x00008000; + + if (temp > 0) { + disp |= 0xFFFF0000; + } } std::string @@ -70,7 +77,7 @@ output decoder {{ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const { return csprintf("%-10s %c%d,%d(r%d)", mnemonic, - flags[IsFloating] ? 'f' : 'r', RS, JMPTARG, RT); + flags[IsFloating] ? 'f' : 'r', RT, disp, RS); } }}; diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa index 05c5ac10f..d35179005 100644 --- a/arch/mips/isa/formats/noop.isa +++ b/arch/mips/isa/formats/noop.isa @@ -59,7 +59,7 @@ output exec {{ Fault Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { - return No_Fault; + return NoFault; } }}; @@ -68,9 +68,11 @@ output exec {{ def template OperateNopCheckDecode {{ { MipsStaticInst *i = new %(class_name)s(machInst); - if (RD == 0) { - i = makeNop(i); - } + + //if (RD == 0) { + // i = makeNop(i); + //} + return i; } }}; diff --git a/arch/mips/isa/formats/trap.isa b/arch/mips/isa/formats/trap.isa index 78f8d87b0..6884d4fa8 100644 --- a/arch/mips/isa/formats/trap.isa +++ b/arch/mips/isa/formats/trap.isa @@ -42,12 +42,11 @@ def template TrapExecute {{ }}; // Primary format for integer operate instructions: -def format Trap(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) +def format Trap(code, *flags) {{ + code = 'bool cond;\n' + code; + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = TrapExecute.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa index a7a71c681..adbd5b5b1 100644 --- a/arch/mips/isa/formats/unimp.isa +++ b/arch/mips/isa/formats/unimp.isa @@ -111,7 +111,7 @@ output exec {{ { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } Fault @@ -123,7 +123,7 @@ output exec {{ warned = true; } - return No_Fault; + return NoFault; } }}; diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa index 6eba5b4f9..4601b3684 100644 --- a/arch/mips/isa/formats/unknown.isa +++ b/arch/mips/isa/formats/unknown.isa @@ -42,7 +42,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } }}; diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index c06877b35..db4bf204a 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -1,29 +1,6 @@ // -*- mode:c++ -*- let {{ -def UncondCtrlBase(name, Name, base_class, npc_expr, flags): - # Declare basic control transfer w/o link (i.e. link reg is R31) - nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, - CodeBlock(nolink_code), flags) - header_output = BasicDeclare.subst(nolink_iop) - decoder_output = BasicConstructor.subst(nolink_iop) - exec_output = BasicExecute.subst(nolink_iop) - - # Generate declaration of '*AndLink' version, append to decls - link_code = 'Ra = NPC & ~3;\n' + nolink_code - link_iop = InstObjParams(name, Name + 'AndLink', base_class, - CodeBlock(link_code), flags) - header_output += BasicDeclare.subst(link_iop) - decoder_output += BasicConstructor.subst(link_iop) - exec_output += BasicExecute.subst(link_iop) - - # need to use link_iop for the decode template since it is expecting - # the shorter version of class_name (w/o "AndLink") - - return (header_output, decoder_output, - JumpOrBranchDecode.subst(nolink_iop), exec_output) - def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, postacc_code = '', base_class = 'Memory', decode_template = BasicDecode, exec_template_base = ''): @@ -116,10 +93,56 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, output exec {{ +using namespace MipsISA; + + /// CLEAR ALL CPU INST/EXE HAZARDS inline void clear_exe_inst_hazards() { //CODE HERE } + + + /// Check "FP enabled" machine status bit. Called when executing any FP + /// instruction in full-system mode. + /// @retval Full-system mode: NoFault if FP is enabled, FenFault + /// if not. Non-full-system mode: always returns NoFault. +#if FULL_SYSTEM + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + Fault fault = NoFault; // dummy... this ipr access should not fault + if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) { + fault = FloatEnableFault; + } + return fault; + } +#else + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + return NoFault; + } +#endif + + double convert_and_round(float w, int x, int y, int z) + { + double temp = .34000; + + return temp; + } + + enum FPTypes{ + FP_SINGLE, + FP_DOUBLE, + FP_LONG, + FP_PS_LO, + FP_PS_HI, + FP_WORD, + RND_NEAREST, + RND_ZERO, + RND_UP, + RND_DOWN + }; }}; + + diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index 65ef2245f..13870337b 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -16,21 +16,18 @@ def operands {{ 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1), 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2), 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3), - 'R31': ('IntReg', 'uw','R31','IsInteger', 4), + 'r31': ('IntReg', 'uw','R31','IsInteger', 4), + 'R0': ('IntReg', 'uw','R0', 'IsInteger', 5), 'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3), - 'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4), 'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1), 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), + 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3), 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), - 'NNPC': ('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) - #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), - #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), - # The next two are hacks for non-full-system call-pal emulation - #'R0': ('IntReg', 'uq', '0', None, 1), + 'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 02a857af7..85afd4a02 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -33,6 +33,256 @@ using namespace MipsISA; + +void +MipsISA::getMiscRegIdx(int reg_name,int &idx, int &sel) +{ + switch(reg_name) + { + case Index: idx = 0; sel = 0; break; //0-0 Index into the TLB array + case MVPControl: idx = 0; sel = 1; break; //0-1 Per-processor register containing global + case MVPConf0: idx = 0; sel = 2; break; //0-2 Per-processor register containing global + case MVPConf1: idx = 0; sel = 3; break; //0-3 Per-processor register containing global + case Random: idx = 1; sel = 3; break; //1-0 Randomly generated index into the TLB array + case VPEControl: idx = 1; sel = 1; break; //1-1 Per-VPE register containing relatively volatile + //thread configuration data + case VPEConf0: idx = 1; sel = 2; break; //1-2 Per-VPE multi-thread configuration + //information + case VPEConf1: idx = 1; sel = 3; break; //1-3 Per-VPE multi-thread configuration + //information + case YQMask: idx = 1; sel = 4; break; //Per-VPE register defining which YIELD + //qualifier bits may be used without generating + //an exception + case VPESchedule: idx = 1; sel = 5; break; + case VPEScheFBack: idx = 1; sel = 6; break; + case VPEOpt: idx = 1; sel = 7; break; + case EntryLo0: idx = 1; sel = 5; break; + case TCStatus: idx = 1; sel = 5; break; + case TCBind: idx = 1; sel = 5; break; + case TCRestart: idx = 1; sel = 5; break; + case TCHalt: idx = 1; sel = 5; break; + case TCContext: idx = 1; sel = 5; break; + case TCSchedule: idx = 1; sel = 5; break; + case TCScheFBack: panic("Accessing Unimplemented CP0 Register"); break; + case EntryLo1: panic("Accessing Unimplemented CP0 Register"); break; + case Context: panic("Accessing Unimplemented CP0 Register"); break; + case ContextConfig: panic("Accessing Unimplemented CP0 Register"); break; + //case PageMask: panic("Accessing Unimplemented CP0 Register"); break; + case PageGrain: panic("Accessing Unimplemented CP0 Register"); break; + case Wired: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf0: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf1: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf2: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf3: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf4: panic("Accessing Unimplemented CP0 Register"); break; + case BadVAddr: panic("Accessing Unimplemented CP0 Register"); break; + case Count: panic("Accessing Unimplemented CP0 Register"); break; + case EntryHi: panic("Accessing Unimplemented CP0 Register"); break; + case Compare: panic("Accessing Unimplemented CP0 Register"); break; + case Status: idx = 12; sel = 0; break; //12-0 Processor status and control + case IntCtl: idx = 12; sel = 1; break; //12-1 Interrupt system status and control + case SRSCtl: idx = 12; sel = 2; break; //12-2 Shadow register set status and control + case SRSMap: idx = 12; sel = 3; break; //12-3 Shadow set IPL mapping + case Cause: idx = 13; sel = 0; break; //13-0 Cause of last general exception + case EPC: idx = 14; sel = 0; break; //14-0 Program counter at last exception + case PRId: idx = 15; sel = 0; break; //15-0 Processor identification and revision + case EBase: idx = 15; sel = 1; break; //15-1 Exception vector base register + case Config: panic("Accessing Unimplemented CP0 Register"); break; + case Config1: panic("Accessing Unimplemented CP0 Register"); break; + case Config2: panic("Accessing Unimplemented CP0 Register"); break; + case Config3: panic("Accessing Unimplemented CP0 Register"); break; + case LLAddr: panic("Accessing Unimplemented CP0 Register"); break; + case WatchLo: panic("Accessing Unimplemented CP0 Register"); break; + case WatchHi: panic("Accessing Unimplemented CP0 Register"); break; + case Debug: panic("Accessing Unimplemented CP0 Register"); break; + case TraceControl1: panic("Accessing Unimplemented CP0 Register"); break; + case TraceControl2: panic("Accessing Unimplemented CP0 Register"); break; + case UserTraceData: panic("Accessing Unimplemented CP0 Register"); break; + case TraceBPC: panic("Accessing Unimplemented CP0 Register"); break; + case DEPC: panic("Accessing Unimplemented CP0 Register"); break; + case PerfCnt: panic("Accessing Unimplemented CP0 Register"); break; + case ErrCtl: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr0: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr1: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr2: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr3: panic("Accessing Unimplemented CP0 Register"); break; + case TagLo: panic("Accessing Unimplemented CP0 Register"); break; + case DataLo: panic("Accessing Unimplemented CP0 Register"); break; + case TagHi: panic("Accessing Unimplemented CP0 Register"); break; + case DataHi: panic("Accessing Unimplemented CP0 Register"); break; + case ErrorEPC: panic("Accessing Unimplemented CP0 Register"); break; + + default: + panic("Accessing Unimplemented Misc. Register"); + } +} + +void RegFile::coldReset() +{ + //CP0 Random Reg: + //Randomly generated index into the TLB array + miscRegs[1][0] = 0x0000003f; + + //CP0 Wired Reg. + miscRegs[6][0] = 0x0000000; + + //CP0 HWRENA + miscRegs[7][0] = 0x0000000; + + //CP0 Status Reg. + miscRegs[12][0] = 0x0400004; + + //CP0 INTCNTL + miscRegs[12][1] = 0xfc00000; + + //CP0 SRSCNTL + miscRegs[12][2] = 0x0c00000; + + //CP0 SRSMAP + miscRegs[12][3] = 0x0000000; + + //CP0 Cause + miscRegs[13][0] = 0x0000000; + + //CP0 Processor ID + miscRegs[15][0] = 0x0019300; + + //CP0 EBASE + miscRegs[15][1] = 0x8000000; + + //CP0 Config Reg. + miscRegs[16][0] = 0x80040482; + + //CP0 Config 1 Reg. + miscRegs[16][1] = 0xfee3719e; + + //CP0 Config 2 Reg. + miscRegs[16][2] = 0x8000000; + + //CP0 Config 3 Reg. + miscRegs[16][3] = 0x0000020; + + //CP0 Config 7 Reg. + miscRegs[16][7] = 0x0000000; + + //CP0 Debug + miscRegs[23][0] = 0x0201800; + + //CP0 PERFCNTL1 + miscRegs[25][0] = 0x0000000; + + //CP0 PERFCNTL2 + miscRegs[25][1] = 0x0000000; + +} + +void RegFile::createCP0Regs() +{ +//Resize Coprocessor Register Banks to +// the number specified in MIPS32K VOL.III +// Chapter 8 + // + //Cop-0 Regs. Bank 0: Index, + miscRegs[0].resize(4); + + //Cop-0 Regs. Bank 1: + miscRegs[1].resize(8); + + //Cop-0 Regs. Bank 2: + miscRegs[2].resize(8); + + //Cop-0 Regs. Bank 3: + miscRegs[3].resize(1); + + //Cop-0 Regs. Bank 4: + miscRegs[4].resize(2); + + //Cop-0 Regs. Bank 5: + miscRegs[5].resize(2); + + //Cop-0 Regs. Bank 6: + miscRegs[6].resize(6); + + //Cop-0 Regs. Bank 7: + miscRegs[7].resize(1); + + //Cop-0 Regs. Bank 8: + miscRegs[8].resize(1); + + //Cop-0 Regs. Bank 9: + miscRegs[9].resize(1); + + //Cop-0 Regs. Bank 10: + miscRegs[10].resize(1); + + //Cop-0 Regs. Bank 11: + miscRegs[11].resize(1); + + //Cop-0 Regs. Bank 12: + miscRegs[12].resize(4); + + //Cop-0 Regs. Bank 13: + miscRegs[13].resize(1); + + //Cop-0 Regs. Bank 14: + miscRegs[14].resize(1); + + //Cop-0 Regs. Bank 15: + miscRegs[15].resize(2); + + //Cop-0 Regs. Bank 16: + miscRegs[16].resize(4); + + //Cop-0 Regs. Bank 17: + miscRegs[17].resize(1); + + //Cop-0 Regs. Bank 18: + miscRegs[18].resize(8); + + //Cop-0 Regs. Bank 19: + miscRegs[19].resize(8); + + //Cop-0 Regs. Bank 20: + miscRegs[20].resize(1); + + //Cop-0 Regs. Bank 21: + //miscRegs[21].resize(1); + //Reserved for future extensions + + //Cop-0 Regs. Bank 22: + //miscRegs[22].resize(4); + //Available for implementation dependent use + + //Cop-0 Regs. Bank 23: + miscRegs[23].resize(5); + + //Cop-0 Regs. Bank 24: + miscRegs[24].resize(1); + + //Cop-0 Regs. Bank 25: + miscRegs[25].resize(8); + + //Cop-0 Regs. Bank 26: + miscRegs[26].resize(1); + + //Cop-0 Regs. Bank 27: + miscRegs[27].resize(4); + + //Cop-0 Regs. Bank 28: + miscRegs[28].resize(8); + + //Cop-0 Regs. Bank 29: + miscRegs[29].resize(8); + + //Cop-0 Regs. Bank 30: + miscRegs[30].resize(1); + + //Cop-0 Regs. Bank 31: + miscRegs[31].resize(1); + +} + + const Addr MipsISA::PageShift = 13; const Addr MipsISA::PageBytes = ULL(1) << PageShift; const Addr MipsISA::PageMask = ~(PageBytes - 1); @@ -64,8 +314,8 @@ const Addr MipsISA::K1SegEnd = ULL(0xffffffffffffffff); #endif -// Mips UNOP (ldq_u r31,0(r0)) -const MachInst MipsISA::NoopMachInst = 0x2ffe0000; +// Mips UNOP (sll r0,r0,r0) +const MachInst MipsISA::NoopMachInst = 0x00000000; static inline Addr TruncPage(Addr addr) @@ -74,17 +324,19 @@ TruncPage(Addr addr) static inline Addr RoundPage(Addr addr) { return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); } + void RegFile::serialize(std::ostream &os) { SERIALIZE_ARRAY(intRegFile, NumIntRegs); SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); - SERIALIZE_SCALAR(miscRegs.fpcr); - SERIALIZE_SCALAR(miscRegs.uniq); - SERIALIZE_SCALAR(miscRegs.lock_flag); - SERIALIZE_SCALAR(miscRegs.lock_addr); + //SERIALIZE_SCALAR(miscRegs.fpcr); + //SERIALIZE_SCALAR(miscRegs.uniq); + //SERIALIZE_SCALAR(miscRegs.lock_flag); + //SERIALIZE_SCALAR(miscRegs.lock_addr); SERIALIZE_SCALAR(pc); SERIALIZE_SCALAR(npc); + SERIALIZE_SCALAR(nnpc); #if FULL_SYSTEM SERIALIZE_ARRAY(palregs, NumIntRegs); SERIALIZE_ARRAY(ipr, NumInternalProcRegs); @@ -99,12 +351,13 @@ RegFile::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(intRegFile, NumIntRegs); UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); - UNSERIALIZE_SCALAR(miscRegs.fpcr); - UNSERIALIZE_SCALAR(miscRegs.uniq); - UNSERIALIZE_SCALAR(miscRegs.lock_flag); - UNSERIALIZE_SCALAR(miscRegs.lock_addr); + //UNSERIALIZE_SCALAR(miscRegs.fpcr); + //UNSERIALIZE_SCALAR(miscRegs.uniq); + //UNSERIALIZE_SCALAR(miscRegs.lock_flag); + //UNSERIALIZE_SCALAR(miscRegs.lock_addr); UNSERIALIZE_SCALAR(pc); UNSERIALIZE_SCALAR(npc); + UNSERIALIZE_SCALAR(nnpc); #if FULL_SYSTEM UNSERIALIZE_ARRAY(palregs, NumIntRegs); UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 71da82ffa..35f33c237 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -29,19 +29,21 @@ #ifndef __ARCH_MIPS_ISA_TRAITS_HH__ #define __ARCH_MIPS_ISA_TRAITS_HH__ -namespace LittleEndianGuest {} -using namespace LittleEndianGuest; - -//#include "arch/mips/faults.hh" +//#include "arch/mips/misc_regfile.hh" #include "base/misc.hh" #include "config/full_system.hh" #include "sim/host.hh" #include "sim/faults.hh" +#include + class FastCPU; class FullCPU; class Checkpoint; +namespace LittleEndianGuest {}; +using namespace LittleEndianGuest; + #define TARGET_MIPS class StaticInst; @@ -50,11 +52,10 @@ class StaticInstPtr; namespace MIPS34K { int DTB_ASN_ASN(uint64_t reg); int ITB_ASN_ASN(uint64_t reg); -} +}; namespace MipsISA { - typedef uint32_t MachInst; // typedef uint64_t Addr; typedef uint8_t RegIndex; @@ -64,7 +65,7 @@ namespace MipsISA NumIntRegs = 32, NumFloatRegs = 32, - NumMiscRegs = 32, + NumMiscRegs = 256, MaxRegsOfAnyType = 32, // Static instruction parameters @@ -72,7 +73,7 @@ namespace MipsISA MaxInstDestRegs = 2, // semantically meaningful register indices - ZeroReg = 31, // architecturally meaningful + ZeroReg = 0, // architecturally meaningful // the rest of these depend on the ABI StackPointerReg = 30, GlobalPointerReg = 29, @@ -106,7 +107,8 @@ namespace MipsISA Ctrl_Base_DepTag = 64, Fpcr_DepTag = 64, // floating point control register Uniq_DepTag = 65, - IPR_Base_DepTag = 66 + IPR_Base_DepTag = 66, + MiscReg_DepTag = 67 }; typedef uint64_t IntReg; @@ -123,14 +125,123 @@ namespace MipsISA double d[NumFloatRegs]; // double-precision floating point view } FloatRegFile; - // control register file contents + // cop-0/cop-1 system control register file typedef uint64_t MiscReg; - typedef struct { - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - } MiscRegFile; +//typedef MiscReg MiscRegFile[NumMiscRegs]; + + typedef std::vector MiscRegFile[NumMiscRegs]; +// typedef MiscRegBank MiscRegBanks[NumMiscRegs]; + + + enum MiscRegTags { + //Coprocessor 0 Registers + //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8 + //(Register Number-Register Select) Summary of Register + //------------------------------------------------------ + Index, //0-0 Index into the TLB array + + MVPControl, //0-1 Per-processor register containing global + //MIPSŪ MT configuration data + + MVPConf0, //0-2 Per-processor register containing global + //MIPSŪ MT configuration data + + MVPConf1, //0-3 Per-processor register containing global + //MIPSŪ MT configuration data + + Random, //1-0 Randomly generated index into the TLB array + + VPEControl, //1-1 Per-VPE register containing relatively volatile + //thread configuration data + + VPEConf0, //1-2 Per-VPE multi-thread configuration + //information + + + VPEConf1, //1-2 Per-VPE multi-thread configuration + //information + + YQMask, //Per-VPE register defining which YIELD + //qualifier bits may be used without generating + //an exception + + VPESchedule, + VPEScheFBack, + VPEOpt, + EntryLo0, + TCStatus, + TCBind, + TCRestart, + TCHalt, + TCContext, + TCSchedule, + TCScheFBack, + EntryLo1, + Context, + ContextConfig, + //PageMask, + PageGrain, + Wired, + SRSConf0, + SRSConf1, + SRSConf2, + SRSConf3, + SRSConf4, + BadVAddr, + Count, + EntryHi, + Compare, + Status, //12-0 Processor status and control + IntCtl, //12-1 Interrupt system status and control + SRSCtl, //12-2 Shadow register set status and control + SRSMap, //12-3 Shadow set IPL mapping + Cause, //13-0 Cause of last general exception + EPC, //14-0 Program counter at last exception + PRId, //15-0 Processor identification and revision + EBase, //15-1 Exception vector base register + Config, + Config1, + Config2, + Config3, + LLAddr, + WatchLo, + WatchHi, + Debug, + TraceControl1, + TraceControl2, + UserTraceData, + TraceBPC, + + DEPC, + + PerfCnt, + + ErrCtl, + + CacheErr0, + CacheErr1, + CacheErr2, + CacheErr3, + + TagLo, + DataLo, + TagHi, + DataHi, + ErrorEPC, + DESAVE, + + //More Misc. Regs + Hi, + Lo, + FCSR, + FPCR, + LockAddr, + LockFlag, + + //Alpha Regs, but here now, for + //compiling sake + UNIQ + }; extern const Addr PageShift; extern const Addr PageBytes; @@ -168,19 +279,33 @@ extern const Addr PageOffset; IntRegFile intRegFile; // (signed) integer register file FloatRegFile floatRegFile; // floating point register file MiscRegFile miscRegs; // control register file + + Addr pc; // program counter Addr npc; // next-cycle program counter + Addr nnpc; // next-next-cycle program counter + // used to implement branch delay slot + // not real register + + MiscReg hi; // MIPS HI Register + MiscReg lo; // MIPS LO Register + + #if FULL_SYSTEM IntReg palregs[NumIntRegs]; // PAL shadow registers InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers - inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } - inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } + inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } + inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } #endif // FULL_SYSTEM + //void initCP0Regs(); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); + + void createCP0Regs(); + void coldReset(); }; StaticInstPtr decodeInst(MachInst); @@ -194,6 +319,9 @@ extern const Addr PageOffset; ITOUCH_ANNOTE = 0xffffffff, }; + void getMiscRegIdx(int reg_name,int &idx, int &sel); + + static inline bool isCallerSaveIntegerRegister(unsigned int reg) { panic("register classification not implemented"); return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); @@ -264,37 +392,7 @@ extern const Addr PageOffset; template void zeroRegisters(XC *xc); - -//typedef MipsISA TheISA; - -//typedef TheISA::MachInst MachInst; -//typedef TheISA::Addr Addr; -//typedef TheISA::RegIndex RegIndex; -//typedef TheISA::IntReg IntReg; -//typedef TheISA::IntRegFile IntRegFile; -//typedef TheISA::FloatReg FloatReg; -//typedef TheISA::FloatRegFile FloatRegFile; -//typedef TheISA::MiscReg MiscReg; -//typedef TheISA::MiscRegFile MiscRegFile; -//typedef TheISA::AnyReg AnyReg; -//typedef TheISA::RegFile RegFile; - -//const int NumIntRegs = TheISA::NumIntRegs; -//const int NumFloatRegs = TheISA::NumFloatRegs; -//const int NumMiscRegs = TheISA::NumMiscRegs; -//const int TotalNumRegs = TheISA::TotalNumRegs; -//const int VMPageSize = TheISA::VMPageSize; -//const int LogVMPageSize = TheISA::LogVMPageSize; -//const int ZeroReg = TheISA::ZeroReg; -//const int StackPointerReg = TheISA::StackPointerReg; -//const int GlobalPointerReg = TheISA::GlobalPointerReg; -//const int ReturnAddressReg = TheISA::ReturnAddressReg; -//const int ReturnValueReg = TheISA::ReturnValueReg; -//const int ArgumentReg0 = TheISA::ArgumentReg0; -//const int ArgumentReg1 = TheISA::ArgumentReg1; -//const int ArgumentReg2 = TheISA::ArgumentReg2; -//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; -const Addr MaxAddr = (Addr)-1; + const Addr MaxAddr = (Addr)-1; }; #if !FULL_SYSTEM diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc index d3aca15bc..1d4f62350 100644 --- a/arch/mips/linux_process.cc +++ b/arch/mips/linux_process.cc @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/mips/mips_common_syscall_emul.hh" -#include "arch/mips/mips_linux_process.hh" +#include "arch/mips/common_syscall_emul.hh" +#include "arch/mips/linux_process.hh" #include "arch/mips/isa_traits.hh" #include "base/trace.hh" diff --git a/arch/mips/stacktrace.hh b/arch/mips/stacktrace.hh new file mode 100644 index 000000000..1d8d97a79 --- /dev/null +++ b/arch/mips/stacktrace.hh @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_STACKTRACE_HH__ +#define __ARCH_ALPHA_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ExecContext; +class StackTrace; + +class ProcessInfo +{ + private: + ExecContext *xc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ExecContext *_xc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ExecContext *xc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ExecContext *xc, bool is_call); + + public: + StackTrace(); + StackTrace(ExecContext *xc, StaticInstPtr inst); + ~StackTrace(); + + void clear() + { + xc = 0; + stack.clear(); + } + + bool valid() const { return xc != NULL; } + bool trace(ExecContext *xc, StaticInstPtr inst); + + public: + const std::vector &getstack() const { return stack; } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void dprintf() { if (DTRACE(Stack)) dump(); } +#else + public: + void dprintf() {} +#endif +}; + +inline bool +StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(xc, !inst->isReturn()); + return true; +} + +#endif // __ARCH_ALPHA_STACKTRACE_HH__