summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/isa/base.isa63
-rw-r--r--arch/mips/isa/decoder.isa1108
-rw-r--r--arch/mips/isa/formats.isa14
-rw-r--r--arch/mips/isa/formats/basic.isa3
-rw-r--r--arch/mips/isa/formats/branch.isa184
-rw-r--r--arch/mips/isa/formats/int.isa17
-rw-r--r--arch/mips/isa/formats/noop.isa62
-rw-r--r--arch/mips/isa/formats/util.isa26
-rw-r--r--arch/mips/isa/operands.isa7
-rw-r--r--arch/mips/isa_traits.hh2
10 files changed, 799 insertions, 687 deletions
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
new file mode 100644
index 000000000..db37cf49c
--- /dev/null
+++ b/arch/mips/isa/base.isa
@@ -0,0 +1,63 @@
+// -*- mode:c++ -*-
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for MIPS instructions, and some support functions
+//
+
+//Outputs to decoder.hh
+output header {{
+ /**
+ * Base class for all SPARC static instructions.
+ */
+ class MipsStaticInst : public StaticInst<MIPSISA>
+ {
+ protected:
+
+ // Constructor.
+ MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : StaticInst<MIPSISA>(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+}};
+
+//Ouputs to decoder.cc
+output decoder {{
+
+ std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // 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]);
+ }
+
+ // just print the first dest... if there's a second one,
+ // it's generally implicit
+ if(_numDestRegs > 0)
+ {
+ if(_numSrcRegs > 0)
+ ss << ",";
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ return ss.str();
+ }
+
+}};
+
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 6bb5bf4d8..f46024f15 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// The actual MIPS32 ISA decoder
@@ -12,183 +14,194 @@
decode OPCODE_HI default Unknown::unknown() {
// Derived From ... Table A-2 MIPS32 ISA Manual
- 0x0: decode OPCODE_LO default FailUnimpl::reserved(){
+ 0x0: decode OPCODE_LO {
0x0: decode FUNCTION_HI {
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}});
+ 0x1: decode MOVCI {
+ format BasicOp {
+ 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
+ 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
+ }
}
- }
- format BasicOp {
+ format BasicOp {
- //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
- //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
+ //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
+ //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
- 0x0: sll({{ Rd = Rt.uw << SA; }});
+ 0x0: sll({{ Rd = Rt.uw << SA; }});
- 0x2: decode SRL {
- 0: srl({{ Rd = Rt.uw >> SA; }});
+ 0x2: decode SRL {
+ 0: srl({{ Rd = Rt.uw >> SA; }});
- //Hardcoded assuming 32-bit ISA, probably need parameter here
- 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
- }
+ //Hardcoded assuming 32-bit ISA, probably need parameter here
+ 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
+ }
- 0x3: sra({{ Rd = Rt.sw >> SA; }});
+ 0x3: sra({{ Rd = Rt.sw >> SA; }});
- 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
+ 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
- 0x6: decode SRLV {
- 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
+ 0x6: decode SRLV {
+ 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
- //Hardcoded assuming 32-bit ISA, probably need parameter here
- 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
- }
+ //Hardcoded assuming 32-bit ISA, probably need parameter here
+ 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
+ }
- 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
- }
+ 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
+ }
}
0x1: decode FUNCTION_LO {
- //Table A-3 Note: "Specific encodings of the hint field are used
- //to distinguish JR from JR.HB and JALR from JALR.HB"
- format Jump {
- 0x0: jr(IsReturn);
- 0x1: jalr(IsCall,IsReturn);
- }
+ //Table A-3 Note: "Specific encodings of the hint field are used
+ //to distinguish JR from JR.HB and JALR from JALR.HB"
+ format Unconditional {
+ 0x0: decode HINT {
+ 0:jr({{ }},IsReturn,IsLink);
+ 1:jr_hb({{ }},IsReturn,IsLink);
+ }
+
+ 0x1: decode HINT {
+ 0: jalr({{ }},'IsCall','IsReturn','IsLink');
+ 1: jalr_hb({{ }},IsCall,IsReturn,IsLink);
+ }
+ }
- format BasicOp {
- 0x2: movz({{ if (Rt == 0) Rd = Rs; }});
- 0x3: movn({{ if (Rt != 0) Rd = Rs; }});
- }
+ format BasicOp {
+ 0x2: movz({{ if (Rt == 0) Rd = Rs; }});
+ 0x3: movn({{ if (Rt != 0) Rd = Rs; }});
+ }
- format WarnUnimpl {
- 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
- 0x5: break();
- 0x7: sync();
- }
+ format WarnUnimpl {
+ 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
+ 0x5: break();
+ 0x7: sync();
+ }
}
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; }});
- }
+ 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; }});
+ }
}
0x3: decode FUNCTION_LO {
- format IntOp {
- 0x0: mult({{
+ format IntOp {
+ 0x0: mult({{
INT64 temp1 = Rs.sw * Rt.sw;
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>;
- }});
+ }});
- 0x1: multu({{
+ 0x1: multu({{
INT64 temp1 = Rs.uw * Rt.uw;
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- Rd.sw = Rs.uw * Rt.uw;
- }});
+ Rd.sw = Rs.uw * Rt.uw;
+ }});
- 0x2: div({{
+ 0x2: div({{
xc->miscRegs.hi = Rs.sw % Rt.sw;
xc->miscRegs.lo = Rs.sw / Rt.sw;
- }});
+ }});
- 0x3: divu({{
+ 0x3: divu({{
xc->miscRegs.hi = Rs.uw % Rt.uw;
xc->miscRegs.lo = 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);}});
- }
+ 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);}});
+ }
}
0x5: decode FUNCTION_LO {
- format IntOp{
- 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
- 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
- }
+ format IntOp{
+ 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
+ 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
+ }
}
0x6: decode FUNCTION_LO {
- 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); }});
- 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
- 0x6: tne({{ 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); }});
+ 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
+ 0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
+ }
}
}
0x1: decode REGIMM_HI {
0x0: decode REGIMM_LO {
- format CondBranch {
- 0x0: bltz({{ cond = (Rs.sw < 0); }});
- 0x1: bgez({{ cond = (Rs.sw >= 0); }});
-
- //MIPS obsolete instructions
- 0x2: bltzl({{ cond = (Rs.sw < 0); }});
- 0x3: bgezl({{ cond = (Rs.sw >= 0); }});
- }
+ format Branch {
+ 0x0: bltz({{ cond = (Rs.sw < 0); }});
+ 0x1: bgez({{ cond = (Rs.sw >= 0); }});
+ }
+
+ format BranchLikely {
+ //MIPS obsolete instructions
+ 0x2: bltzl({{ cond = (Rs.sw < 0); }});
+ 0x3: bgezl({{ cond = (Rs.sw >= 0); }});
+ }
}
0x1: decode REGIMM_LO {
- format Trap {
- 0x0: tgei({{ cond = (Rs.sw >= INTIMM; }});
- 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }});
- 0x2: tlti({{ cond = (Rs.sw < INTIMM); }});
- 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
- 0x4: teqi({{ cond = (Rs.sw == INTIMM); }});
- 0x6: tnei({{ cond = (Rs.sw != INTIMM); }});
- }
+ format Trap {
+ 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
+ 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
+ 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
+ 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
+ 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
+ 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
+ }
}
0x2: decode REGIMM_LO {
- format CondBranch {
- 0x0: bltzal({{ cond = (Rs.sw < 0); }});
- 0x1: bgezal({{ cond = (Rs.sw >= 0); }});
-
- //MIPS obsolete instructions
- 0x2: bltzall({{ cond = (Rs.sw < 0); }});
- 0x3: bgezall({{ cond = (Rs.sw >= 0); }});
- }
+ format Branch {
+ 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsLink);
+ 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsLink);
+ }
+
+ format BranchLikely {
+ //Will be removed in future MIPS releases
+ 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsLink);
+ 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsLink);
+ }
}
0x3: decode REGIMM_LO {
- format WarnUnimpl {
- 0x7: synci();
- }
+ format WarnUnimpl {
+ 0x7: synci();
+ }
}
}
- format Jump {
- 0x2: j();
- 0x3: jal(IsCall);
+ format Unconditional {
+ 0x2: j({{ }});
+ 0x3: jal({{ }},IsCall,IsLink);
}
- format CondBranch {
+ format Branch {
0x4: beq({{ cond = (Rs.sw == 0); }});
0x5: bne({{ cond = (Rs.sw != 0); }});
0x6: blez({{ cond = (Rs.sw <= 0); }});
@@ -196,7 +209,7 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x1: decode OPCODE_LO default FailUnimpl::reserved(){
+ 0x1: decode OPCODE_LO {
format IntOp {
0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }});
0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}});
@@ -209,539 +222,534 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x2: decode OPCODE_LO default FailUnimpl::reserved(){
-
- //Table A-11 MIPS32 COP0 Encoding of rs Field
- 0x0: decode RS_MSB {
- 0x0: decode RS {
+ 0x2: decode OPCODE_LO {
- format BasicOp {
- 0x0: mfc0({{
+ //Table A-11 MIPS32 COP0 Encoding of rs Field
+ 0x0: decode RS_MSB {
+ 0x0: decode RS {
+ format BasicOp {
+ 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.
if (SEL > 0)
- panic("Can't Handle Cop0 with register select yet\n");
+ panic("Can't Handle Cop0 with register select yet\n");
uint64_t reg_num = Rd.uw;
Rt = xc->miscRegs.cop0[reg_num];
- }});
+ }});
- 0x4: mtc0({{
+ 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.
if (SEL > 0)
- panic("Can't Handle Cop0 with register select yet\n");
+ panic("Can't Handle Cop0 with register select yet\n");
uint64_t reg_num = Rd.uw;
xc->miscRegs.cop0[reg_num] = Rt;
- }});
+ }});
- 0x8: mftr({{
+ 0x8: mftr({{
//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.
//MT Code Needed Here
- }});
+ }});
- 0xC: mttr({{
+ 0xC: mttr({{
//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.
//MT Code Needed Here
- }});
+ }});
- 0xA: rdpgpr({{
+ 0xA: rdpgpr({{
//Accessing Previous Shadow Set Register Number
uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
uint64_t reg_num = Rt.uw;
Rd = xc->shadowIntRegFile[prev][reg_num];
- }});
- }
+ }});
- 0xB: decode RD {
+ 0xB: decode RD {
- 0x0: decode SC {
- format BasicOp {
- 0x0: dvpe({{
- Rt.sw = xc->miscRegs.cop0.MVPControl;
- xc->miscRegs.cop0.MVPControl[EVP] = 0;
- }});
+ 0x0: decode SC {
+ 0x0: dvpe({{
+ Rt.sw = xc->miscRegs.cop0.MVPControl;
+ xc->miscRegs.cop0.MVPControl[EVP] = 0;
+ }});
- 0x1: evpe({{
- Rt.sw = xc->miscRegs.cop0.MVPControl;
- xc->miscRegs.cop0.MVPControl[EVP] = 1;
- }});
- }
- }
+ 0x1: evpe({{
+ Rt.sw = xc->miscRegs.cop0.MVPControl;
+ xc->miscRegs.cop0.MVPControl[EVP] = 1;
+ }});
+ }
- 0x1: decode SC {
- format BasicOp {
- 0x0: dmt({{
- Rt.sw = xc->miscRegs.cop0.VPEControl;
- xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
- }});
+ 0x1: decode SC {
+ 0x0: dmt({{
+ Rt.sw = xc->miscRegs.cop0.VPEControl;
+ xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
+ }});
- 0x1: emt({{
- Rt.sw = xc->miscRegs.cop0.VPEControl;
- xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
- }});
- }
- }
+ 0x1: emt({{
+ Rt.sw = xc->miscRegs.cop0.VPEControl;
+ xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
+ }});
+ }
- 0xC: decode SC {
- format BasicOp {
- 0x0: di({{
- Rt.sw = xc->miscRegs.cop0.Status;
- xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
- }});
+ 0xC: decode SC {
+ 0x0: di({{
+ Rt.sw = xc->miscRegs.cop0.Status;
+ xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
+ }});
- 0x1: ei({{
- Rt.sw = xc->miscRegs.cop0.Status;
- xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
- }});
- }
- }
- }
+ 0x1: ei({{
+ Rt.sw = xc->miscRegs.cop0.Status;
+ xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
+ }});
+ }
+ }
- 0xE: BasicOp::wrpgpr({{
+ 0xE: wrpgpr({{
//Accessing Previous Shadow Set Register Number
uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
uint64_t reg_num = Rd.uw;
xc->shadowIntRegFile[prev][reg_num] = Rt;
- }});
- }
-
- //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
- 0x1: decode FUNCTION {
- format Trap {
- 0x01: tlbr({{ }});
- 0x02: tlbwi({{ }});
- 0x06: tlbwr({{ }});
- 0x08: tlbp({{ }});
- }
-
- format WarnUnimpl {
- 0x18: eret();
- 0x1F: deret();
- 0x20: wait();
- }
- }
- }
-
- //Table A-13 MIPS32 COP1 Encoding of rs Field
- 0x1: decode RS_MSB {
-
- 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}});
- }
- }
-
- 0x1: decode ND {
- 0x0: decode TF {
- format CondBranch {
- 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
- 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
- }
+ }});
+ }
}
- 0x1: decode TF {
- format CondBranch {
- 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
- 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
- }
+ //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
+ 0x1: decode FUNCTION {
+ format Trap {
+ 0x01: tlbr({{ }});
+ 0x02: tlbwi({{ }});
+ 0x06: tlbwr({{ }});
+ 0x08: tlbp({{ }});
+ }
+
+ format WarnUnimpl {
+ 0x18: eret();
+ 0x1F: deret();
+ 0x20: wait();
+ }
}
- }
}
- 0x1: decode RS_HI {
- 0x2: decode RS_LO {
+ //Table A-13 MIPS32 COP1 Encoding of rs Field
+ 0x1: decode RS_MSB {
- //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
- //(( single-word ))
0x0: decode RS_HI {
- 0x0: decode RS_LO {
- format FloatOp {
- 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
- 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
- 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);}});
- 0x6: movs({{ Fd.sf = Fs.sf;}});
- 0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
- }
- }
-
- 0x1: decode RS_LO {
- //only legal for 64 bit-FP
- format Float64Op {
- 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
- 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
- 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
- 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
- }
-
- format FloatOp {
- 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
- 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
- 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
- 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
- }
- }
-
- 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: 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}});
+ }
}
- format BasicOp {
- 0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
- 0x3: movns({{ if (Rt != 0) Fd = Fs; }});
- }
+ 0x1: decode ND {
+ 0x0: decode TF {
+ format Branch {
+ 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
+ 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
+ }
+ }
- format Float64Op {
- 0x2: recips({{ Fd = 1 / Fs; }});
- 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
+ 0x1: decode TF {
+ format BranchLikely {
+ 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
+ 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
+ }
+ }
}
- }
+ }
+
+ 0x1: decode RS_HI {
+ 0x2: decode RS_LO {
+
+ //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
+ //(( single-word ))
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
+ format FloatOp {
+ 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
+ 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
+ 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);}});
+ 0x6: movs({{ Fd.sf = Fs.sf;}});
+ 0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
+ }
+ }
+
+ 0x1: decode RS_LO {
+ //only legal for 64 bit-FP
+ format Float64Op {
+ 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
+ 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
+ 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
+ 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
+ }
+
+ format FloatOp {
+ 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
+ 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
+ 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
+ 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
+ }
+ }
- 0x4: decode RS_LO {
+ 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;}});
+ }
+ }
+
+ format BasicOp {
+ 0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
+ 0x3: movns({{ if (Rt != 0) Fd = Fs; }});
+ }
+
+ format Float64Op {
+ 0x2: recips({{ Fd = 1 / Fs; }});
+ 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
+ }
+ }
+
+ 0x4: decode RS_LO {
- format FloatOp {
- 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ format FloatOp {
+ 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
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->miscRegs.fcsr;
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;
+ //only legal for 64 bit
+ format Float64Op {
+ 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
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>; }});
- }
- }
- }
+ }});
- //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
- 0x1: decode RS_HI {
- 0x0: decode RS_LO {
- format FloatOp {
- 0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
- 0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
- 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);}});
- 0x6: movd({{ Fd.df = Fs.df;}});
- 0x7: negd({{ Fd.df = -1 * Fs.df;}});
- }
- }
-
- 0x1: decode RS_LO {
- //only legal for 64 bit
- format Float64Op {
- 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
- 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
- 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
- 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
- }
-
- format FloatOp {
- 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
- 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
- 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
- 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
- }
- }
-
- 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; }});
- }
- }
+ 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
+ }
+ }
+ }
+
+ //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
+ 0x1: decode RS_HI {
+ 0x0: decode RS_LO {
+ format FloatOp {
+ 0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
+ 0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
+ 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);}});
+ 0x6: movd({{ Fd.df = Fs.df;}});
+ 0x7: negd({{ Fd.df = -1 * Fs.df;}});
+ }
+ }
- format BasicOp {
- 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }});
- 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }});
- }
+ 0x1: decode RS_LO {
+ //only legal for 64 bit
+ format Float64Op {
+ 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
+ 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
+ 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
+ 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
+ }
+
+ format FloatOp {
+ 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
+ 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
+ 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
+ 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
+ }
+ }
- format Float64Op {
- 0x5: recipd({{ Fd.df = 1 / Fs.df}});
- 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
- }
- }
+ 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; }});
+ }
+ }
+
+ format BasicOp {
+ 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }});
+ 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }});
+ }
+
+ format Float64Op {
+ 0x5: recipd({{ Fd.df = 1 / Fs.df}});
+ 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
+ }
+ }
- 0x4: decode RS_LO {
- format FloatOp {
- 0x0: cvt_s_d({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
- }});
+ 0x4: decode RS_LO {
+ format FloatOp {
+ 0x0: cvt_s_d({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
+ }});
- 0x4: cvt_w_d({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
- }});
- }
+ 0x4: cvt_w_d({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
+ }});
+ }
- //only legal for 64 bit
- format Float64Op {
- 0x5: cvt_l_d({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
- }});
- }
- }
- }
+ //only legal for 64 bit
+ format Float64Op {
+ 0x5: cvt_l_d({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
+ }});
+ }
+ }
+ }
- //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
- 0x4: decode FUNCTION {
- format FloatOp {
- 0x10: cvt_s({{
+ //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
+ 0x4: decode FUNCTION {
+ format FloatOp {
+ 0x10: cvt_s({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
}});
- 0x10: cvt_d({{
+ 0x10: cvt_d({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
}});
- }
- }
-
- //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
- //Note: "1. Format type L is legal only if 64-bit floating point operations
- //are enabled."
- 0x5: decode FUNCTION_HI {
- format FloatOp {
- 0x10: cvt_s_l({{
+ }
+ }
+
+ //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
+ //Note: "1. Format type L is legal only if 64-bit floating point operations
+ //are enabled."
+ 0x5: decode FUNCTION_HI {
+ format FloatOp {
+ 0x10: cvt_s_l({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
}});
- 0x11: cvt_d_l({{
+ 0x11: cvt_d_l({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
}});
- }
- }
+ }
+ }
+
+ //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
+ //Note: "1. Format type PS is legal only if 64-bit floating point operations
+ //are enabled. "
+ 0x6: decode RS_HI {
+ 0x0: decode RS_LO {
+ format Float64Op {
+ 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs.df + Ft.df;
+ }});
- //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
- //Note: "1. Format type PS is legal only if 64-bit floating point operations
- //are enabled. "
- 0x6: decode RS_HI {
- 0x0: decode RS_LO {
- format Float64Op {
- 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs.df + Ft.df;
- }});
-
- 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs.df - Ft.df;
- }});
+ 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs.df - Ft.df;
+ }});
- 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs.df * Ft.df;
- }});
+ 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs.df * Ft.df;
+ }});
- 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);
- }});
+ 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);
+ }});
- 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>;
- }});
+ 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>;
+ }});
- 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = -1 * Fs.df;
- }});
- }
- }
+ 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = -1 * Fs.df;
+ }});
+ }
+ }
- 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;}});
- }
- }
+ 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;}});
+ }
+ }
- }
+ }
- 0x4: decode RS_LO {
- 0x0: Float64Op::cvt_s_pu({{
+ 0x4: decode RS_LO {
+ 0x0: Float64Op::cvt_s_pu({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
- }});
- }
+ }});
+ }
- 0x5: decode RS_LO {
- format Float64Op {
- 0x0: cvt_s_pl({{
- int rnd_mode = xc->miscRegs.fcsr;
- 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>}});
- }
- }
- }
- }
-
- //Table A-19 MIPS32 COP2 Encoding of rs Field
- 0x2: decode RS_MSB {
- 0x0: decode RS_HI {
- 0x0: decode RS_LO {
- format WarnUnimpl {
- 0x0: mfc2();
- 0x2: cfc2();
- 0x3: mfhc2();
- 0x4: mtc2();
- 0x6: ctc2();
- 0x7: mftc2();
- }
- }
-
- 0x1: decode ND {
- 0x0: decode TF {
- format WarnUnimpl {
- 0x0: bc2f();
- 0x1: bc2t();
- }
+ 0x5: decode RS_LO {
+ format Float64Op {
+ 0x0: cvt_s_pl({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ 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>}});
+ }
+ }
+ }
+ }
}
+ }
+
+ //Table A-19 MIPS32 COP2 Encoding of rs Field
+ 0x2: decode RS_MSB {
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
+ format WarnUnimpl {
+ 0x0: mfc2();
+ 0x2: cfc2();
+ 0x3: mfhc2();
+ 0x4: mtc2();
+ 0x6: ctc2();
+ 0x7: mftc2();
+ }
+ }
+
+ 0x1: decode ND {
+ 0x0: decode TF {
+ format WarnUnimpl {
+ 0x0: bc2f();
+ 0x1: bc2t();
+ }
+ }
- 0x1: decode TF {
- format WarnUnimpl {
- 0x0: bc2fl();
- 0x1: bc2tl();
- }
+ 0x1: decode TF {
+ format WarnUnimpl {
+ 0x0: bc2fl();
+ 0x1: bc2tl();
+ }
+ }
+ }
}
- }
}
- }
- //Table A-20 MIPS64 COP1X Encoding of Function Field 1
- //Note: "COP1X instructions are legal only if 64-bit floating point
- //operations are enabled."
- 0x3: decode FUNCTION_HI {
- 0x0: decode FUNCTION_LO {
+ //Table A-20 MIPS64 COP1X Encoding of Function Field 1
+ //Note: "COP1X instructions are legal only if 64-bit floating point
+ //operations are enabled."
+ 0x3: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
format Memory {
- 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }});
- 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
- 0x5: luxc1({{ //Need to make EA<2:0> = 0
- EA = Rs + Rt;
- }},
- {{ Ft<31:0> = Mem.df; }});
+ 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }});
+ 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
+ 0x5: luxc1({{ //Need to make EA<2:0> = 0
+ EA = Rs + Rt;
+ }},
+ {{ Ft<31:0> = Mem.df; }});
}
- }
+ }
- 0x1: decode FUNCTION_LO {
+ 0x1: decode FUNCTION_LO {
format Memory {
- 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }});
- 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}});
- 0x5: suxc1({{ //Need to make EA<2:0> = 0
- EA = Rs + Rt;
- }},
- {{ Mem.df = Ft<63:0>;}});
+ 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }});
+ 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}});
+ 0x5: suxc1({{ //Need to make EA<2:0> = 0
+ EA = Rs + Rt;
+ }},
+ {{ Mem.df = Ft<63:0>;}});
}
0x7: WarnUnimpl::prefx();
- }
+ }
- format FloatOp {
+ format FloatOp {
0x3: WarnUnimpl::alnv_ps();
format BasicOp {
- 0x4: decode FUNCTION_LO {
- 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
- 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
- 0x6: madd_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (Fs.df * Fs.df) + Fr.df;
- }});
- }
-
- 0x5: decode FUNCTION_LO {
- 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
- 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
- 0x6: msub_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (Fs.df * Fs.df) - Fr.df;
- }});
- }
-
- 0x6: decode FUNCTION_LO {
- 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
- 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
- 0x6: nmadd_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
- }});
- }
-
- 0x7: decode FUNCTION_LO {
- 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
- 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
- 0x6: nmsub_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
- }});
- }
+ 0x4: decode FUNCTION_LO {
+ 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
+ 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
+ 0x6: madd_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (Fs.df * Fs.df) + Fr.df;
+ }});
+ }
+
+ 0x5: decode FUNCTION_LO {
+ 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
+ 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
+ 0x6: msub_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (Fs.df * Fs.df) - Fr.df;
+ }});
+ }
+
+ 0x6: decode FUNCTION_LO {
+ 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
+ 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
+ 0x6: nmadd_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
+ }});
+ }
+
+ 0x7: decode FUNCTION_LO {
+ 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
+ 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
+ 0x6: nmsub_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
+ }});
+ }
}
+ }
}
- }
-
- //MIPS obsolete instructions
- format CondBranch {
- 0x4: beql({{ cond = (Rs.sw == 0); }});
- 0x5: bnel({{ cond = (Rs.sw != 0); }});
- 0x6: blezl({{ cond = (Rs.sw <= 0); }});
- 0x7: bgtzl({{ cond = (Rs.sw > 0); }});
+
+ //MIPS obsolete instructions
+ format BranchLikely {
+ 0x4: beql({{ cond = (Rs.sw == 0); }});
+ 0x5: bnel({{ cond = (Rs.sw != 0); }});
+ 0x6: blezl({{ cond = (Rs.sw <= 0); }});
+ 0x7: bgtzl({{ cond = (Rs.sw > 0); }});
}
}
@@ -752,89 +760,89 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
format IntOp {
- 0x0: madd({{
+ 0x0: madd({{
INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
temp1 = temp1 + (Rs.sw * Rt.sw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
- 0x1: maddu({{
+ 0x1: maddu({{
INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
temp1 = temp1 + (Rs.uw * Rt.uw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
- 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
+ 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
- 0x4: msub({{
+ 0x4: msub({{
INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
temp1 = temp1 - (Rs.sw * Rt.sw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
- 0x5: msubu({{
+ 0x5: msubu({{
INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
temp1 = temp1 - (Rs.uw * Rt.uw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
}
}
0x4: decode FUNCTION_LO {
- format BasicOp {
- 0x0: clz({{
+ format BasicOp {
+ 0x0: clz({{
int cnt = 0;
int idx = 0;
while ( Rs.uw<idx>!= 1) {
- cnt++;
- idx--;
+ cnt++;
+ idx--;
}
Rd.uw = cnt;
- }});
+ }});
- 0x1: clo({{
+ 0x1: clo({{
int cnt = 0;
int idx = 0;
while ( Rs.uw<idx>!= 0) {
- cnt++;
- idx--;
+ cnt++;
+ idx--;
}
Rd.uw = cnt;
- }});
- }
+ }});
+ }
}
0x7: decode FUNCTION_LO {
- 0x7: WarnUnimpl::sdbbp();
+ 0x7: WarnUnimpl::sdbbp();
}
}
//Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
0x7: decode FUNCTION_HI {
- 0x0: decode FUNCTION_LO {
+ 0x0: decode FUNCTION_LO {
format WarnUnimpl {
0x1: ext();
0x4: ins();
}
- }
+ }
- 0x1: decode FUNCTION_LO {
+ 0x1: decode FUNCTION_LO {
format WarnUnimpl {
0x0: fork();
0x1: yield();
}
- }
+ }
- //Table A-10 MIPS32 BSHFL Encoding of sa Field
- 0x4: decode SA {
+ //Table A-10 MIPS32 BSHFL Encoding of sa Field
+ 0x4: decode SA {
0x02: WarnUnimpl::wsbh();
@@ -842,11 +850,11 @@ decode OPCODE_HI default Unknown::unknown() {
0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}});
0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
}
- }
+ }
- 0x6: decode FUNCTION_LO {
- 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
- }
+ 0x6: decode FUNCTION_LO {
+ 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
+ }
}
}
@@ -880,7 +888,7 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x6: decode OPCODE_LO default FailUnimpl::reserved() {
- 0x0: WarnUnimpl::ll();
+ 0x0: WarnUnimpl::ll();
format Memory {
0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }});
diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa
index 20ef49d82..c244013df 100644
--- a/arch/mips/isa/formats.isa
+++ b/arch/mips/isa/formats.isa
@@ -1,7 +1,15 @@
-//Include the basic format
+// -*- mode:c++ -*-
+
//Templates from this format are used later
+//Include the basic format
##include "m5/arch/mips/isa/formats/basic.isa"
+//Include the basic format
+##include "m5/arch/mips/isa/formats/noop.isa"
+
+//Include utility formats/functions
+##include "m5/arch/mips/isa/formats/util.isa"
+
//Include the integerOp and integerOpCc format
##include "m5/arch/mips/isa/formats/int.isa"
@@ -18,10 +26,6 @@
##include "m5/arch/mips/isa/formats/branch.isa"
//Include the noop format
-##include "m5/arch/mips/isa/formats/noop.isa"
-
-
-//Include the noop format
##include "m5/arch/mips/isa/formats/unimp.isa"
//Include the noop format
diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa
index fc97c6ffa..3b62aa5c3 100644
--- a/arch/mips/isa/formats/basic.isa
+++ b/arch/mips/isa/formats/basic.isa
@@ -1,3 +1,4 @@
+// -*- mode:c++ -*-
// Declarations for execute() methods.
def template BasicExecDeclare {{
@@ -39,7 +40,7 @@ def template BasicExecute {{
if(fault == No_Fault)
{
- %(op_wb)s;
+ %(op_wb)s;
}
return fault;
}
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index e9c790c53..1f7a6f330 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -1,30 +1,9 @@
// -*- mode:c++ -*-
-// Copyright (c) 2003-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.
+// Control transfer instructions
//
-// 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.
output header {{
@@ -37,18 +16,19 @@ output header {{
* where the disassembly string includes the target address (which
* may depend on the PC and/or symbol table).
*/
- class PCDependentDisassembly : public AlphaStaticInst
+ class PCDependentDisassembly : public MipsStaticInst
{
protected:
/// Cached program counter from last disassembly
mutable Addr cachedPC;
+
/// Cached symbol table pointer from last disassembly
mutable const SymbolTable *cachedSymtab;
/// Constructor
PCDependentDisassembly(const char *mnem, MachInst _machInst,
OpClass __opClass)
- : AlphaStaticInst(mnem, _machInst, __opClass),
+ : MipsStaticInst(mnem, _machInst, __opClass),
cachedPC(0), cachedSymtab(0)
{
}
@@ -64,13 +44,35 @@ output header {{
class Branch : public PCDependentDisassembly
{
protected:
- /// Displacement to target address (signed).
+ /// target address (signed) Displacement .
int32_t disp;
/// Constructor.
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP << 2)
+ disp(OFFSET << 2)
+ {
+ }
+
+ Addr branchTarget(Addr branchPC) const;
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for branch likely branches (PC-relative control transfers),
+ */
+ class BranchLikely : public PCDependentDisassembly
+ {
+ protected:
+ /// target address (signed) Displacement .
+ int32_t disp;
+
+ /// Constructor.
+ Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ disp(OFFSET << 2)
{
}
@@ -82,7 +84,7 @@ output header {{
/**
* Base class for jumps (register-indirect control transfers). In
- * the Alpha ISA, these are always unconditional.
+ * the Mips ISA, these are always unconditional.
*/
class Jump : public PCDependentDisassembly
{
@@ -95,7 +97,7 @@ output header {{
/// Constructor
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP)
+ disp(OFFSET)
{
}
@@ -114,6 +116,12 @@ output decoder {{
}
Addr
+ BranchLikely::branchTarget(Addr branchPC) const
+ {
+ return branchPC + 4 + disp;
+ }
+
+ Addr
Jump::branchTarget(ExecContext *xc) const
{
Addr NPC = xc->readPC() + 4;
@@ -179,6 +187,44 @@ output decoder {{
}
std::string
+ BranchLikely::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // There's only one register arg (RA), but it could be
+ // either a source (the condition for conditional
+ // branches) or a destination (the link reg for
+ // unconditional branches)
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ",";
+ }
+ else if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ ss << ",";
+ }
+
+#ifdef SS_COMPATIBLE_DISASSEMBLY
+ if (_numSrcRegs == 0 && _numDestRegs == 0) {
+ printReg(ss, 31);
+ ss << ",";
+ }
+#endif
+
+ Addr target = pc + 4 + disp;
+
+ std::string str;
+ if (symtab && symtab->findSymbol(target, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", target);
+
+ return ss.str();
+ }
+
+ std::string
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -203,14 +249,19 @@ output decoder {{
}
}};
-def template JumpOrBranchDecode {{
- return (RA == 31)
- ? (StaticInst<AlphaISA> *)new %(class_name)s(machInst)
- : (StaticInst<AlphaISA> *)new %(class_name)sAndLink(machInst);
-}};
+def format Branch(code,*flags) {{
+ code = 'bool cond;\n\t' + code + '\n'
+
+ #Add Link Code if Link instruction
+ strlen = len(name)
+ if name[strlen-2:] == 'al':
+ code += 'R31 = NPC + 4;\n'
+
+ # condition code
+ code += 'if (cond) {'
+ code += ' NPC = NPC + disp;\n'
+ code += ' NNPC = NNPC + disp;\n } \n'
-def format CondBranch(code) {{
- code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
header_output = BasicDeclare.subst(iop)
@@ -219,41 +270,38 @@ def format CondBranch(code) {{
exec_output = BasicExecute.subst(iop)
}};
-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 format UncondBranch(*flags) {{
- flags += ('IsUncondControl', 'IsDirectControl')
- (header_output, decoder_output, decode_block, exec_output) = \
- UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags)
+def format BranchLikely(code,*flags) {{
+ code = 'bool cond;\n\t\t\t' + code
+
+ #Add Link Code if Link instruction
+ strlen = len(name)
+ if name[strlen-3:] == 'all':
+ code += 'R31 = NPC + 4;\n'
+
+ #condition code
+ code += 'if (cond) {'
+ code += ' NPC = NPC + disp;\n'
+ code += ' NNPC = NNPC + disp;\n } \n'
+
+
+ iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
+ ('IsDirectControl', 'IsCondControl','IsCondDelaySlot'))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
-def format Jump(*flags) {{
- flags += ('IsUncondControl', 'IsIndirectControl')
- (header_output, decoder_output, decode_block, exec_output) = \
- UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags)
+def format Unconditional(code,*flags) {{
+ iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),
+ ('IsIndirectControl', 'IsUncondControl'))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
+
+
diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa
index 521f3a130..cf06741a1 100644
--- a/arch/mips/isa/formats/int.isa
+++ b/arch/mips/isa/formats/int.isa
@@ -1,8 +1,11 @@
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
+//Outputs to decoder.hh
output header {{
/**
* Base class for integer operations.
@@ -12,7 +15,7 @@ output header {{
protected:
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
@@ -26,7 +29,7 @@ output header {{
uint16_t imm;
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM)
{
}
@@ -36,6 +39,7 @@ output header {{
}};
+//Outputs to decoder.cc
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
@@ -48,17 +52,18 @@ output decoder {{
}
}};
-// Primary format for integer operate instructions:
+
+//Used by decoder.isa
def format IntOp(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
# Figure out if we are creating a IntImmOp or a IntOp
+ # by looking at the instruction name
+ iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
strlen = len(name)
if name[strlen-1] == 'i' or name[strlen-2:] == 'iu':
- iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
- else:
- iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa
index 6d45ba9b6..d366461e2 100644
--- a/arch/mips/isa/formats/noop.isa
+++ b/arch/mips/isa/formats/noop.isa
@@ -1,50 +1,4 @@
-////////////////////////////////////////////////////////////////////
-//
-// Noop instruction
-//
-
-output header {{
- /**
- * Base class for integer operations.
- */
- class Noop : public MipsStaticInst
- {
- protected:
-
- /// Constructor
- Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
- {
- }
-
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
- };
-}};
-
-output decoder {{
- std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- return "Disassembly of integer instruction\n";
- }
-}};
-
-def template NoopExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
- {
- //Nothing to see here, move along
- return No_Fault;
- }
-}};
-
-// Primary format for integer operate instructions:
-def format Noop(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = NoopExecute.subst(iop)
-}};
+// -*- mode:c++ -*-
////////////////////////////////////////////////////////////////////
//
@@ -55,7 +9,7 @@ output header {{
/**
* Static instruction class for no-ops. This is a leaf class.
*/
- class Nop : public AlphaStaticInst
+ class Nop : public MipsStaticInst
{
/// Disassembly of original instruction.
const std::string originalDisassembly;
@@ -63,7 +17,7 @@ output header {{
public:
/// Constructor
Nop(const std::string _originalDisassembly, MachInst _machInst)
- : AlphaStaticInst("nop", _machInst, No_OpClass),
+ : MipsStaticInst("nop", _machInst, No_OpClass),
originalDisassembly(_originalDisassembly)
{
flags[IsNop] = true;
@@ -92,10 +46,10 @@ output decoder {{
/// Helper function for decoding nops. Substitute Nop object
/// for original inst passed in as arg (and delete latter).
inline
- AlphaStaticInst *
- makeNop(AlphaStaticInst *inst)
+ MipsStaticInst *
+ makeNop(MipsStaticInst *inst)
{
- AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
+ MipsStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
delete inst;
return nop;
}
@@ -113,7 +67,7 @@ output exec {{
// Rc == 31 to detect nops
def template OperateNopCheckDecode {{
{
- AlphaStaticInst *i = new %(class_name)s(machInst);
+ MipsStaticInst *i = new %(class_name)s(machInst);
if (RC == 31) {
i = makeNop(i);
}
@@ -124,7 +78,7 @@ def template OperateNopCheckDecode {{
// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
- iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code),
opt_args)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa
new file mode 100644
index 000000000..c6dae6783
--- /dev/null
+++ b/arch/mips/isa/formats/util.isa
@@ -0,0 +1,26 @@
+// -*- 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)
+}};
diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa
index cf6f10e0b..77035f04c 100644
--- a/arch/mips/isa/operands.isa
+++ b/arch/mips/isa/operands.isa
@@ -16,6 +16,7 @@ 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),
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4),
@@ -24,12 +25,12 @@ def operands {{
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
- 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4)
+ 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
- #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 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),
- #'R16': ('IntReg', 'uq', '16', None, 1)
}};
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 55e9c0dcb..e171737a3 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -430,6 +430,8 @@ class MipsISA
Addr pc; // Program Counter
Addr npc; // Next Program Counter
+ Addr nnpc; // Next next program Counter
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);