Merging in a month of changes
authorKorey Sewell <ksewell@umich.edu>
Fri, 9 Jun 2006 07:57:25 +0000 (03:57 -0400)
committerKorey Sewell <ksewell@umich.edu>
Fri, 9 Jun 2006 07:57:25 +0000 (03:57 -0400)
src/arch/isa_parser.py:
    Sign extend bit if you read int reg that is greater than default size
src/arch/mips/SConscript:
src/arch/mips/faults.cc:
src/arch/mips/faults.hh:
src/arch/mips/isa/base.isa:
src/arch/mips/isa/bitfields.isa:
src/arch/mips/isa/decoder.isa:
src/arch/mips/isa/formats/basic.isa:
src/arch/mips/isa/formats/branch.isa:
src/arch/mips/isa/formats/formats.isa:
src/arch/mips/isa/formats/fp.isa:
src/arch/mips/isa/formats/int.isa:
src/arch/mips/isa/formats/mem.isa:
src/arch/mips/isa/formats/noop.isa:
src/arch/mips/isa/formats/tlbop.isa:
src/arch/mips/isa/formats/trap.isa:
src/arch/mips/isa/formats/unimp.isa:
src/arch/mips/isa/formats/unknown.isa:
src/arch/mips/isa/formats/util.isa:
src/arch/mips/isa/includes.isa:
src/arch/mips/isa/main.isa:
src/arch/mips/isa/operands.isa:
src/arch/mips/isa_traits.cc:
src/arch/mips/linux/process.cc:
src/arch/mips/linux/process.hh:
src/arch/mips/process.cc:
src/arch/mips/process.hh:
src/arch/mips/regfile/float_regfile.hh:
src/arch/mips/utility.hh:
    1 month of changes!
src/arch/mips/isa/formats/control.isa:
    control formats
src/arch/mips/isa/formats/mt.isa:
    mips mt format
src/arch/mips/utility.cc:
    utility functions

--HG--
extra : convert_revision : c1332cb5ce08b464b99fbf04f4a5cac312898784

29 files changed:
src/arch/isa_parser.py
src/arch/mips/SConscript
src/arch/mips/isa/base.isa
src/arch/mips/isa/bitfields.isa
src/arch/mips/isa/decoder.isa
src/arch/mips/isa/formats/basic.isa
src/arch/mips/isa/formats/branch.isa
src/arch/mips/isa/formats/control.isa [new file with mode: 0644]
src/arch/mips/isa/formats/formats.isa
src/arch/mips/isa/formats/fp.isa
src/arch/mips/isa/formats/int.isa
src/arch/mips/isa/formats/mem.isa
src/arch/mips/isa/formats/mt.isa [new file with mode: 0644]
src/arch/mips/isa/formats/noop.isa
src/arch/mips/isa/formats/tlbop.isa
src/arch/mips/isa/formats/trap.isa
src/arch/mips/isa/formats/unimp.isa
src/arch/mips/isa/formats/unknown.isa
src/arch/mips/isa/formats/util.isa
src/arch/mips/isa/includes.isa
src/arch/mips/isa/operands.isa
src/arch/mips/isa_traits.cc
src/arch/mips/linux/process.cc
src/arch/mips/linux/process.hh
src/arch/mips/process.cc
src/arch/mips/process.hh
src/arch/mips/regfile/float_regfile.hh
src/arch/mips/utility.cc [new file with mode: 0644]
src/arch/mips/utility.hh

index 22baaf98e0f0801b234a5546cc463a04e85c721a..4d522e18a049d29810d16967f3687d45e6b89ad1 100755 (executable)
@@ -25,6 +25,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 # Authors: Steve Reinhardt
+#          Korey Sewell
 
 import os
 import sys
@@ -1181,6 +1182,11 @@ class IntRegOperand(Operand):
         if (self.size == self.dflt_size):
             return '%s = xc->readIntReg(this, %d);\n' % \
                    (self.base_name, self.src_reg_idx)
+        elif (self.size > self.dflt_size):
+            int_reg_val = 'xc->readIntReg(this, %d)' % (self.src_reg_idx)
+            if (self.is_signed):
+                int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val)
+            return '%s = %s;\n' % (self.base_name, int_reg_val)
         else:
             return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \
                    (self.base_name, self.src_reg_idx, self.size-1)
index 0365f5373b139ed12e9f4f5eec715af31d35b1ae..6295a6c119f864e94e34518f9f145d86b0d36e51 100644 (file)
@@ -28,6 +28,7 @@
 #
 # Authors: Gabe Black
 #          Steve Reinhardt
+#          Korey Sewell
 
 import os
 import sys
@@ -46,6 +47,7 @@ Import('env')
 base_sources = Split('''
        faults.cc
        isa_traits.cc
+        utility.cc
        ''')
 
 # Full-system sources
index b2a31c018094e79d8f6bdbf2682f5f4562772be1..848438cb3d4936266d801a9c3bfc614db06016dd 100644 (file)
@@ -18,16 +18,6 @@ output header {{
     {
       protected:
 
-        /// 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 {
-            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)
             : StaticInst(mnem, _machInst, __opClass)
@@ -67,12 +57,12 @@ output decoder {{
         }
 
         if(_numSrcRegs > 0) {
-            ss << ",";
+            ss << ", ";
             printReg(ss, _srcRegIdx[0]);
         }
 
         if(_numSrcRegs > 1) {
-            ss << ",";
+            ss << ", ";
             printReg(ss, _srcRegIdx[1]);
         }
 
index e1124a5911bf6dc29febb3b8e30c71625650c749..516cead8480aa1ed7028d0a8ca6962b6d528d5a0 100644 (file)
@@ -17,20 +17,19 @@ def bitfield FUNCTION      < 5: 0>;
 def bitfield FUNCTION_HI   < 5: 3>;
 def bitfield FUNCTION_LO   < 2: 0>;
 
-// Integer operate format
-def bitfield RT              <20:16>;
-def bitfield RT_HI    <20:19>;
-def bitfield RT_LO    <18:16>;
-
 def bitfield RS              <25:21>;
 def bitfield RS_MSB   <25:25>;
 def bitfield RS_HI    <25:24>;
 def bitfield RS_LO    <23:21>;
-def bitfield RS_SRL    <25:22>;
-
+def bitfield RS_SRL   <25:22>;
+def bitfield RS_RT    <25:16>;
+def bitfield RT              <20:16>;
+def bitfield RT_HI    <20:19>;
+def bitfield RT_LO    <18:16>;
+def bitfield RT_RD    <20:11>;
 def bitfield RD              <15:11>;
 
-def bitfield INTIMM    <15: 0>; // integer immediate (literal)
+def bitfield INTIMM      <15: 0>;
 
 // Floating-point operate format
 def bitfield FMT      <25:21>;
@@ -67,5 +66,9 @@ def bitfield HINT     <10: 6>;
 def bitfield SYSCALLCODE <25: 6>;
 def bitfield TRAPCODE    <15:13>;
 
+// EXT/INS instructions
+def bitfield MSB       <15:11>;
+def bitfield LSB       <10: 6>;
+
 // M5 instructions
 def bitfield M5FUNC <7:0>;
index 1454aba39325cf8b9f3aca62345bd932592c2d97..b8f049e3081457e8ee4158c71c534639d4ca1fae 100644 (file)
@@ -1,4 +1,4 @@
- // -*- mode:c++ -*-
+// -*- mode:c++ -*-
 
 ////////////////////////////////////////////////////////////////////
 //
@@ -6,41 +6,33 @@
 // -----------------------------
 // The following instructions are specified in the MIPS32 ISA
 // Specification. Decoding closely follows the style specified
-// in the MIPS32 ISAthe specification document starting with Table
+// in the MIPS32 ISA specification document starting with Table
 // A-2 (document available @ www.mips.com)
 //
-//@todo: Distinguish "unknown/future" use insts from "reserved"
-// ones
 decode OPCODE_HI default Unknown::unknown() {
-
-    // Derived From ... Table A-2 MIPS32 ISA Manual
+    //Table A-2
     0x0: decode OPCODE_LO {
-
         0x0: decode FUNCTION_HI {
             0x0: decode FUNCTION_LO {
                 0x1: decode MOVCI {
                     format BasicOp {
-                        0: movf({{ if (getFPConditionCode(FCSR, CC) == 0) Rd = Rs}});
-                        1: movt({{ if (getFPConditionCode(FCSR, CC) == 1) Rd = Rs}});
+                        0: movf({{ Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs; }});
+                        1: movt({{ Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs; }});
                     }
                 }
 
                 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: "Specific encodings of the rd, rs, and
+                    //rt fields are used to distinguish SLL, SSNOP, and EHB
+                    //functions
                     0x0: decode RS  {
-                        0x0: decode RT {     //fix Nop traditional vs. Nop converted disassembly later
-                             0x0: decode RD  default Nop::nop(){
-                                  0x0: decode SA {
-                                      0x1: ssnop({{ ; }}); //really sll r0,r0,1
-                                      0x3: ehb({{ ; }});   //really sll r0,r0,3
-                                  }
-                             }
-
-                             default: sll({{ Rd = Rt.uw << SA; }});
+                        0x0: decode RT_RD {
+                            0x0: decode SA default Nop::nop(){
+                                0x1: WarnUnimpl::ssnop();
+                                0x3: WarnUnimpl::ehb();
+                            }
+                            default: sll({{ Rd = Rt.uw << SA; }});
                         }
-
                     }
 
                     0x2: decode RS_SRL {
@@ -55,7 +47,6 @@ decode OPCODE_HI default Unknown::unknown() {
                     0x3: decode RS {
                         0x0: sra({{
                             uint32_t temp = Rt >> SA;
-
                             if ( (Rt & 0x80000000) > 0 ) {
                                 uint32_t mask = 0x80000000;
                                 for(int i=0; i < SA; i++) {
@@ -63,7 +54,6 @@ decode OPCODE_HI default Unknown::unknown() {
                                     mask = mask >> 1;
                                 }
                             }
-
                             Rd = temp;
                         }});
                     }
@@ -96,37 +86,36 @@ decode OPCODE_HI default Unknown::unknown() {
             }
 
             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"
+                //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: decode HINT {
-                        0:jr({{ NNPC = Rs & ~1; }},IsReturn);
-
-                        1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
+                        0x1: jr_hb({{ NNPC = Rs & ~1; }}, IsReturn, ClearHazards);
+                        default: jr({{ NNPC = Rs & ~1; }}, IsReturn);
                     }
 
                     0x1: decode HINT {
-                        0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn);
-
-                        1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
+                        0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link
+                                     , ClearHazards);
+                        default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall,
+                                      Link);
                     }
                 }
 
                 format BasicOp {
-                    0x2: movz({{ if (Rt == 0) Rd = Rs; }});
-                    0x3: movn({{ if (Rt != 0) Rd = Rs; }});
+                    0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
+                    0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
+                    0x4: syscall({{ xc->syscall(R2); }}, IsNonSpeculative);
+                    0x7: sync({{ ; }}, IsMemBarrier);
                 }
 
-                format BasicOp {
-                    0x4: syscall({{ xc->syscall(R2); }},IsNonSpeculative);
-                    0x5: break({{ panic("Not implemented break yet"); }},IsNonSpeculative);
-                    0x7: sync({{  panic("Not implemented sync yet"); }},IsNonSpeculative);
+                format FailUnimpl {
+                    0x5: break();
                 }
             }
 
             0x2: decode FUNCTION_LO {
-                format BasicOp {
+                format HiLoMiscOp {
                     0x0: mfhi({{ Rd = HI; }});
                     0x1: mthi({{ HI = Rs; }});
                     0x2: mflo({{ Rd = LO; }});
@@ -135,24 +124,16 @@ decode OPCODE_HI default Unknown::unknown() {
             }
 
             0x3: decode FUNCTION_LO {
-                format IntOp {
-                    0x0: mult({{
-                        int64_t temp1 = Rs.sd * Rt.sd;
-                        HI = temp1<63:32>;
-                        LO = temp1<31:0>;
-                    }});
-
-                    0x1: multu({{
-                        uint64_t temp1 = Rs.ud * Rt.ud;
-                        HI = temp1<63:32>;
-                        LO = temp1<31:0>;
-                    }});
+                format HiLoOp {
+                    0x0: mult({{ val = Rs.sd * Rt.sd; }});
+                    0x1: multu({{ val = Rs.ud * Rt.ud; }});
+                }
 
+                format HiLoMiscOp {
                     0x2: div({{
                         HI = Rs.sd % Rt.sd;
                         LO = Rs.sd / Rt.sd;
                     }});
-
                     0x3: divu({{
                         HI = Rs.ud % Rt.ud;
                         LO = Rs.ud / Rt.ud;
@@ -201,11 +182,8 @@ decode OPCODE_HI default Unknown::unknown() {
                 format Branch {
                     0x0: bltz({{ cond = (Rs.sw < 0); }});
                     0x1: bgez({{ cond = (Rs.sw >= 0); }});
-                }
-
-                format BranchLikely {
-                    0x2: bltzl({{ cond = (Rs.sw < 0); }});
-                    0x3: bgezl({{ cond = (Rs.sw >= 0); }});
+                    0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely);
+                    0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely);
                 }
             }
 
@@ -222,13 +200,13 @@ decode OPCODE_HI default Unknown::unknown() {
 
             0x2: decode REGIMM_LO {
                 format Branch {
-                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
-                    0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
-                }
-
-                format BranchLikely {
-                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
-                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
+                    0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link);
+                    0x1: decode RS {
+                        0x0: bal ({{ cond = 1; }}, IsCall, Link);
+                        default: bgezal({{ cond = (Rs.sw >= 0); }}, Link);
+                    }
+                    0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely);
+                    0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely);
                 }
             }
 
@@ -241,25 +219,23 @@ decode OPCODE_HI default Unknown::unknown() {
 
         format Jump {
             0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
-
-            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
+            0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, IsCall,
+                     Link);
         }
 
         format Branch {
-            0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
-            0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
-            0x6: decode RT {
-                0x0: blez({{ cond = (Rs.sw <= 0); }});
-            }
-
-            0x7: decode RT {
-                0x0: bgtz({{ cond = (Rs.sw > 0); }});
+            0x4: decode RS_RT  {
+                0x0: b({{ cond = 1; }});
+                default: 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); }});
         }
     }
 
     0x1: decode OPCODE_LO {
-        format IntOp {
+        format IntImmOp {
             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 }});
@@ -275,112 +251,47 @@ decode OPCODE_HI default Unknown::unknown() {
     }
 
     0x2: decode OPCODE_LO {
-
         //Table A-11 MIPS32 COP0 Encoding of rs Field
         0x0: decode RS_MSB {
             0x0: decode RS {
-                format System {
-                    0x0: mfc0({{
-                        //uint64_t reg_num = Rd.uw;
-
-                        Rt = xc->readMiscReg(RD << 5 | SEL);
-                    }});
-
-                    0x4: mtc0({{
-                        //uint64_t reg_num = Rd.uw;
-
-                        xc->setMiscReg(RD << 5 | SEL,Rt);
-                    }});
-
-                    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({{
-                        //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({{
-                        //Accessing Previous Shadow Set Register Number
-                        //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
-                        //uint64_t reg_num = Rt.uw;
-
-                        //Rd = xc->regs.IntRegFile[prev];
-                       //Rd = xc->shadowIntRegFile[prev][reg_num];
-                    }});
+                format CP0Control {
+                    0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }});
+                    0x4: mtc0({{ xc->setMiscReg(RD << 5 | SEL, Rt); }});
+                }
 
+                format MipsMT {
+                    0x8: mftr();
+                    0xC: mttr();
                     0xB: decode RD {
-
                         0x0: decode SC {
-                            0x0: dvpe({{
-                                Rt.sw = xc->readMiscReg(MVPControl);
-                                xc->setMiscReg(MVPControl,0);
-                            }});
-
-                            0x1: evpe({{
-                                Rt.sw = xc->readMiscReg(MVPControl);
-                                xc->setMiscReg(MVPControl,1);
-                            }});
+                            0x0: dvpe();
+                            0x1: evpe();
                         }
-
                         0x1: decode SC {
-                            0x0: dmt({{
-                                Rt.sw = xc->readMiscReg(VPEControl);
-                                xc->setMiscReg(VPEControl,0);
-                            }});
-
-                            0x1: emt({{
-                                Rt.sw = xc->readMiscReg(VPEControl);
-                                xc->setMiscReg(VPEControl,1);
-                            }});
-                        }
-
-                        0xC: decode SC {
-                            0x0: di({{
-                                Rt.sw = xc->readMiscReg(Status);
-                                xc->setMiscReg(Status,0);
-                            }});
-
-                            0x1: ei({{
-                                Rt.sw = xc->readMiscReg(Status);
-                                xc->setMiscReg(Status,1);
-                            }});
+                            0x0: dmt();
+                            0x1: emt();
+                            0xC: decode SC {
+                                0x0: di();
+                                0x1: ei();
+                            }
                         }
                     }
+                }
 
-                    0xE: wrpgpr({{
-                        //Accessing Previous Shadow Set Register Number
-                        //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
-                        //uint64_t reg_num = Rd.uw;
-
-                        //xc->regs.IntRegFile[prev];
-                        //xc->shadowIntRegFile[prev][reg_num] = Rt;
-                    }});
+                format FailUnimpl {
+                    0xA: rdpgpr();
+                    0xE: wrpgpr();
                 }
             }
 
             //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
             0x1: decode FUNCTION {
-                format System {
-                    0x01: tlbr({{ }});
-                    0x02: tlbwi({{ }});
-                    0x06: tlbwr({{ }});
-                    0x08: tlbp({{ }});
-                }
+                format FailUnimpl {
+                    0x01: tlbr();
+                    0x02: tlbwi();
+                    0x06: tlbwr();
+                    0x08: tlbp();
 
-                format WarnUnimpl {
                     0x18: eret();
                     0x1F: deret();
                     0x20: wait();
@@ -393,18 +304,9 @@ decode OPCODE_HI default Unknown::unknown() {
 
             0x0: decode RS_HI {
                 0x0: decode RS_LO {
-                    format FloatOp {
+                    format CP1Control {
                         0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }});
-                        0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
-                        0x4: mtc1 ({{ Fs.uw = Rt.uw;       }});
-                        0x7: mthc1({{
-                             uint64_t fs_hi = Rt.uw;
-                             uint64_t fs_lo = Fs.ud & 0x0000FFFF;
-                             Fs.ud = fs_hi << 32 | fs_lo;
-                        }});
-                    }
 
-                    format System {
                         0x2: cfc1({{
                             switch (FS)
                             {
@@ -424,11 +326,14 @@ decode OPCODE_HI default Unknown::unknown() {
                                 Rt = FCSR;
                                 break;
                               default:
-                                panic("FP Control Value (%d) Not Available. Ignoring Access to"
-                                      "Floating Control Status Register",FS);
+                                panic("FP Control Value (%d) Not Valid");
                             }
                         }});
 
+                        0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
+
+                        0x4: mtc1 ({{ Fs.uw = Rt.uw;       }});
+
                         0x6: ctc1({{
                             switch (FS)
                             {
@@ -464,21 +369,29 @@ decode OPCODE_HI default Unknown::unknown() {
                                       "Floating Control Status Register", FS);
                             }
                         }});
+
+                        0x7: mthc1({{
+                             uint64_t fs_hi = Rt.uw;
+                             uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF;
+                             Fs.ud = (fs_hi << 32) | fs_lo;
+                        }});
+
                     }
                 }
 
                 0x1: decode ND {
-                    0x0: decode TF {
-                        format Branch {
-                            0x0: bc1f({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
-                            0x1: bc1t({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
+                    format Branch {
+                        0x0: decode TF {
+                            0x0: bc1f({{ cond = getCondCode(FCSR, BRANCH_CC) == 0;
+                                      }});
+                            0x1: bc1t({{ cond = getCondCode(FCSR, BRANCH_CC) == 1;
+                                      }});
                         }
-                    }
-
-                    0x1: decode TF {
-                        format BranchLikely {
-                            0x0: bc1fl({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
-                            0x1: bc1tl({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
+                        0x1: decode TF {
+                            0x0: bc1fl({{ cond = getCondCode(FCSR, BRANCH_CC) == 0;
+                                       }}, Likely);
+                            0x1: bc1tl({{ cond = getCondCode(FCSR, BRANCH_CC) == 1;
+                                       }}, Likely);
                         }
                     }
                 }
@@ -486,9 +399,8 @@ decode OPCODE_HI default Unknown::unknown() {
 
             0x1: decode RS_HI {
                 0x2: decode RS_LO {
-
                     //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
-                    //(( single-word ))
+                    //(( single-precision floating point))
                     0x0: decode FUNCTION_HI {
                         0x0: decode FUNCTION_LO {
                             format FloatOp {
@@ -499,194 +411,102 @@ decode OPCODE_HI default Unknown::unknown() {
                                 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}});
                                 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}});
                                 0x6: mov_s({{ Fd.sf = Fs.sf;}});
-                                0x7: neg_s({{ Fd.sf = -1 * Fs.sf;}});
+                                0x7: neg_s({{ Fd.sf = -Fs.sf;}});
                             }
                         }
 
                         0x1: decode FUNCTION_LO {
-                            format Float64Op {
-                                0x0: round_l_s({{
-                                    Fd.ud = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_LONG);
-                                }});
-
-                                0x1: trunc_l_s({{
-                                    Fd.ud = fpConvert(truncFP(Fs.sf), SINGLE_TO_LONG);
-                                }});
-
-                                0x2: ceil_l_s({{
-                                    Fd.ud = fpConvert(ceil(Fs.sf),  SINGLE_TO_LONG);
-                                }});
-
-                                0x3: floor_l_s({{
-                                    Fd.ud = fpConvert(floor(Fs.sf), SINGLE_TO_LONG);
-                                }});
-                            }
-
-                            format FloatOp {
-                                0x4: round_w_s({{
-                                    Fd.uw = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_WORD);
-                                }});
-
-                                0x5: trunc_w_s({{
-                                    Fd.uw = fpConvert(truncFP(Fs.sf), SINGLE_TO_WORD);
-                                }});
-
-                                0x6: ceil_w_s({{
-                                    Fd.uw = fpConvert(ceil(Fs.sf),  SINGLE_TO_WORD);
-                                }});
-
-                                0x7: floor_w_s({{
-                                    Fd.uw = fpConvert(floor(Fs.sf), SINGLE_TO_WORD);
-                                }});
+                            format FloatConvertOp {
+                                0x0: round_l_s({{ val = Fs.sf; }}, ToLong,
+                                               Round);
+                                0x1: trunc_l_s({{ val = Fs.sf; }}, ToLong,
+                                               Trunc);
+                                0x2: ceil_l_s({{ val = Fs.sf; }}, ToLong,
+                                               Ceil);
+                                0x3: floor_l_s({{ val = Fs.sf; }}, ToLong,
+                                               Floor);
+                                0x4: round_w_s({{ val = Fs.sf; }}, ToWord,
+                                               Round);
+                                0x5: trunc_w_s({{ val = Fs.sf; }}, ToWord,
+                                               Trunc);
+                                0x6: ceil_w_s({{ val = Fs.sf; }}, ToWord,
+                                               Ceil);
+                                0x7: floor_w_s({{ val = Fs.sf; }}, ToWord,
+                                               Floor);
                             }
                         }
 
                         0x2: decode FUNCTION_LO {
                             0x1: decode MOVCF {
-                                format FloatOp {
-                                    0x0: movf_s({{if (getFPConditionCode(FCSR,CC) == 0) Fd = Fs;}});
-                                    0x1: movt_s({{if (getFPConditionCode(FCSR,CC) == 1) Fd = Fs;}});
+                                format BasicOp {
+                                    0x0: movf_s({{ Fd = (getCondCode(FCSR,CC) == 0) ? Fs : Fd; }});
+                                    0x1: movt_s({{ Fd = (getCondCode(FCSR,CC) == 1) ? Fs : Fd; }});
                                 }
                             }
 
+                            format BasicOp {
+                                0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
+                                0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
+                            }
+
                             format FloatOp {
-                                0x2: movz_s({{ if (Rt == 0) Fd = Fs; }});
-                                0x3: movn_s({{ if (Rt != 0) Fd = Fs; }});
                                 0x5: recip_s({{ Fd = 1 / Fs; }});
                                 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}});
                             }
                         }
 
                         0x4: decode FUNCTION_LO {
-
                             format FloatConvertOp {
-                                0x1: cvt_d_s({{
-                                    Fd.ud = fpConvert(Fs.sf, SINGLE_TO_DOUBLE);
-                                }});
-
-                                0x4: cvt_w_s({{
-                                    Fd.uw = fpConvert(Fs.sf, SINGLE_TO_WORD);
-                                }});
+                                0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble);
+                                0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord);
+                                0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong);
                             }
 
-                            format FloatConvertOp {
-                                0x5: cvt_l_s({{
-                                    Fd.ud = fpConvert(Fs.sf, SINGLE_TO_LONG);
+                            0x6: FloatOp::cvt_ps_s({{
+                                    Fd.ud = (uint64_t) Fs.uw << 32 |
+                                            (uint64_t) Ft.uw;
                                 }});
-
-                                0x6: cvt_ps_st({{
-                                    Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw;
-                                }});
-                            }
                         }
 
                         0x6: decode FUNCTION_LO {
                             format FloatCompareOp {
-                                0x0: c_f_s({{ cond = 0; }});
-
-                                0x1: c_un_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = 0;
-                                }});
-
-                                0x2: c_eq_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.sf == Ft.sf);
-                                }});
-
-                                0x3: c_ueq_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.sf == Ft.sf);
-                                }});
-
-                                0x4: c_olt_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.sf < Ft.sf);
-                                }});
-
-                                0x5: c_ult_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.sf < Ft.sf);
-                                }});
-
-                                0x6: c_ole_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.sf <= Ft.sf);
-                                }});
-
-                                0x7: c_ule_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.sf <= Ft.sf);
-                                }});
+                                0x0: c_f_s({{ cond = 0; }}, SinglePrecision,
+                                           UnorderedFalse);
+                                0x1: c_un_s({{ cond = 0; }}, SinglePrecision,
+                                            UnorderedTrue);
+                                0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }},
+                                            UnorderedFalse);
+                                0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }},
+                                             UnorderedTrue);
+                                0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf);        }},
+                                             UnorderedFalse);
+                                0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }},
+                                             UnorderedTrue);
+                                0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }},
+                                             UnorderedFalse);
+                                0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }},
+                                             UnorderedTrue);
                             }
                         }
 
                         0x7: decode FUNCTION_LO {
-                            format FloatCompareWithXcptOp {
-                                0x0: c_sf_s({{ cond = 0; }});
-
-                                0x1: c_ngle_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = 0;
-                                  }});
-
-                                0x2: c_seq_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.sf == Ft.sf);
-                                  }});
-
-                                0x3: c_ngl_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.sf == Ft.sf);
-                                  }});
-
-                                0x4: c_lt_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.sf < Ft.sf);
-                                  }});
-
-                                0x5: c_nge_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.sf < Ft.sf);
-                                  }});
-
-                                0x6: c_le_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.sf <= Ft.sf);
-                                  }});
-
-                                0x7: c_ngt_s({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.sf <= Ft.sf);
-                                  }});
+                            format FloatCompareOp {
+                                0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
+                                            UnorderedFalse, QnanException);
+                                0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
+                                              UnorderedTrue, QnanException);
+                                0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf);}},
+                                             UnorderedFalse, QnanException);
+                                0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }},
+                                             UnorderedTrue, QnanException);
+                                0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }},
+                                            UnorderedFalse, QnanException);
+                                0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }},
+                                             UnorderedTrue, QnanException);
+                                0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }},
+                                            UnorderedFalse, QnanException);
+                                0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }},
+                                             UnorderedTrue, QnanException);
                             }
                         }
                     }
@@ -695,197 +515,108 @@ decode OPCODE_HI default Unknown::unknown() {
                     0x1: decode FUNCTION_HI {
                         0x0: decode FUNCTION_LO {
                             format FloatOp {
-                                0x0: add_d({{ Fd.df = Fs.df + Ft.df;}});
-                                0x1: sub_d({{ Fd.df = Fs.df - Ft.df;}});
-                                0x2: mul_d({{ Fd.df = Fs.df * Ft.df;}});
-                                0x3: div_d({{ Fd.df = Fs.df / Ft.df;}});
-                                0x4: sqrt_d({{ Fd.df = sqrt(Fs.df);}});
-                                0x5: abs_d({{ Fd.df = fabs(Fs.df);}});
-                                0x6: mov_d({{ Fd.ud = Fs.ud;}});
-                                0x7: neg_d({{ Fd.df = -1 * Fs.df;}});
+                                0x0: add_d({{ Fd.df = Fs.df + Ft.df; }});
+                                0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }});
+                                0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }});
+                                0x3: div_d({{ Fd.df = Fs.df / Ft.df; }});
+                                0x4: sqrt_d({{ Fd.df = sqrt(Fs.df);  }});
+                                0x5: abs_d({{ Fd.df = fabs(Fs.df);   }});
+                                0x6: mov_d({{ Fd.df = Fs.df;         }});
+                                0x7: neg_d({{ Fd.df = -1 * Fs.df;    }});
                             }
                         }
 
                         0x1: decode FUNCTION_LO {
-                            format FloatOp {
-                                0x0: round_l_d({{
-                                    Fd.ud = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_LONG);
-                                }});
-
-                                0x1: trunc_l_d({{
-                                    Fd.ud = fpConvert(truncFP(Fs.df), DOUBLE_TO_LONG);
-                                }});
-
-                                0x2: ceil_l_d({{
-                                    Fd.ud = fpConvert(ceil(Fs.df), DOUBLE_TO_LONG);
-                                }});
-
-                                0x3: floor_l_d({{
-                                    Fd.ud = fpConvert(floor(Fs.df), DOUBLE_TO_LONG);
-                                }});
-                            }
-
-                            format FloatOp {
-                                0x4: round_w_d({{
-                                    Fd.uw = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_WORD);
-                                }});
-
-                                0x5: trunc_w_d({{
-                                    Fd.uw = fpConvert(truncFP(Fs.df), DOUBLE_TO_WORD);
-                                }});
-
-                                0x6: ceil_w_d({{
-                                    Fd.uw = fpConvert(ceil(Fs.df), DOUBLE_TO_WORD);
-                                }});
-
-                                0x7: floor_w_d({{
-                                    Fd.uw = fpConvert(floor(Fs.df), DOUBLE_TO_WORD);
-                                }});
+                            format FloatConvertOp {
+                                0x0: round_l_d({{ val = Fs.df; }}, ToLong,
+                                               Round);
+                                0x1: trunc_l_d({{ val = Fs.df; }}, ToLong,
+                                               Trunc);
+                                0x2: ceil_l_d({{ val = Fs.df; }}, ToLong,
+                                               Ceil);
+                                0x3: floor_l_d({{ val = Fs.df; }}, ToLong,
+                                               Floor);
+                                0x4: round_w_d({{ val = Fs.df; }}, ToWord,
+                                               Round);
+                                0x5: trunc_w_d({{ val = Fs.df; }}, ToWord,
+                                               Trunc);
+                                0x6: ceil_w_d({{ val = Fs.df; }}, ToWord,
+                                               Ceil);
+                                0x7: floor_w_d({{ val = Fs.df; }}, ToWord,
+                                               Floor);
                             }
                         }
 
                         0x2: decode FUNCTION_LO {
                             0x1: decode MOVCF {
-                                format FloatOp {
-                                    0x0: movf_d({{if (getFPConditionCode(FCSR,CC) == 0) Fd.df = Fs.df; }});
-                                    0x1: movt_d({{if (getFPConditionCode(FCSR,CC) == 1) Fd.df = Fs.df; }});
+                                format BasicOp {
+                                    0x0: movf_d({{ Fd.df = (getCondCode(FCSR,CC) == 0) ?
+                                                       Fs.df : Fd.df;
+                                                }});
+                                    0x1: movt_d({{ Fd.df = (getCondCode(FCSR,CC) == 1) ?
+                                                       Fs.df : Fd.df;
+                                                }});
                                 }
                             }
 
                             format BasicOp {
-                                0x2: movz_d({{ if (Rt == 0) Fd.df = Fs.df; }});
-                                0x3: movn_d({{ if (Rt != 0) Fd.df = Fs.df; }});
+                                0x2: movz_d({{ Fd.df = (Rt == 0) ? Fs.df : Fd.df; }});
+                                0x3: movn_d({{ Fd.df = (Rt != 0) ? Fs.df : Fd.df; }});
                             }
 
                             format FloatOp {
-                                0x5: recip_d({{ Fd.df = 1 / Fs.df}});
+                                0x5: recip_d({{ Fd.df = 1 / Fs.df }});
                                 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }});
                             }
                         }
 
                         0x4: decode FUNCTION_LO {
-                            format FloatOp {
-                                0x0: cvt_s_d({{
-                                    Fd.uw = fpConvert(Fs.df, DOUBLE_TO_SINGLE);
-                                }});
-
-                                0x4: cvt_w_d({{
-                                    Fd.uw = fpConvert(Fs.df, DOUBLE_TO_WORD);
-                                }});
-
-                                0x5: cvt_l_d({{
-                                    Fd.ud = fpConvert(Fs.df, DOUBLE_TO_LONG);
-                                }});
+                            format FloatConvertOp {
+                                0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle);
+                                0x4: cvt_w_d({{ val = Fs.df; }}, ToWord);
+                                0x5: cvt_l_d({{ val = Fs.df; }}, ToLong);
                             }
                         }
 
                         0x6: decode FUNCTION_LO {
                             format FloatCompareOp {
-                                0x0: c_f_d({{ cond = 0; }});
-
-                                0x1: c_un_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = 0;
-                                }});
-
-                                0x2: c_eq_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.df == Ft.df);
-                                }});
-
-                                0x3: c_ueq_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.df == Ft.df);
-                                }});
-
-                                0x4: c_olt_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.df < Ft.df);
-                                }});
-
-                                0x5: c_ult_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.df < Ft.df);
-                                }});
-
-                                0x6: c_ole_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.df <= Ft.df);
-                                }});
-
-                                0x7: c_ule_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.df <= Ft.df);
-                                }});
+                                0x0: c_f_d({{ cond = 0; }}, DoublePrecision,
+                                           UnorderedFalse);
+                                0x1: c_un_d({{ cond = 0; }}, DoublePrecision,
+                                            UnorderedTrue);
+                                0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }},
+                                            UnorderedFalse);
+                                0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }},
+                                             UnorderedTrue);
+                                0x4: c_olt_d({{ cond = (Fs.df < Ft.df);        }},
+                                             UnorderedFalse);
+                                0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }},
+                                             UnorderedTrue);
+                                0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }},
+                                             UnorderedFalse);
+                                0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }},
+                                             UnorderedTrue);
                             }
                         }
 
                         0x7: decode FUNCTION_LO {
-                            format FloatCompareWithXcptOp {
-                                0x0: c_sf_d({{ cond = 0; }});
-
-                                0x1: c_ngle_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = 0;
-                                  }});
-
-                                0x2: c_seq_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.df == Ft.df);
-                                  }});
-
-                                0x3: c_ngl_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.df == Ft.df);
-                                  }});
-
-                                0x4: c_lt_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.df < Ft.df);
-                                  }});
-
-                                0x5: c_nge_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.df < Ft.df);
-                                  }});
-
-                                0x6: c_le_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 0;
-                                    else
-                                        cond = (Fs.df <= Ft.df);
-                                  }});
-
-                                0x7: c_ngt_d({{
-                                    if (isnan(Fs.df) || isnan(Ft.df))
-                                        cond = 1;
-                                    else
-                                        cond = (Fs.df <= Ft.df);
-                                  }});
+                            format FloatCompareOp {
+                                0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
+                                            UnorderedFalse, QnanException);
+                                0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
+                                              UnorderedTrue, QnanException);
+                                0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }},
+                                             UnorderedFalse, QnanException);
+                                0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }},
+                                             UnorderedTrue, QnanException);
+                                0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }},
+                                            UnorderedFalse, QnanException);
+                                0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }},
+                                             UnorderedTrue, QnanException);
+                                0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }},
+                                            UnorderedFalse, QnanException);
+                                0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }},
+                                             UnorderedTrue, QnanException);
                             }
                         }
                     }
@@ -893,19 +624,9 @@ decode OPCODE_HI default Unknown::unknown() {
                     //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
                     0x4: decode FUNCTION {
                         format FloatConvertOp {
-                            0x20: cvt_s_w({{
-                                Fd.uw = fpConvert(Fs.sf, WORD_TO_SINGLE);
-                            }});
-
-                            0x21: cvt_d_w({{
-                                Fd.ud = fpConvert(Fs.sf, WORD_TO_DOUBLE);
-                            }});
-                        }
-
-                        format Float64ConvertOp {
-                            0x26: cvt_ps_pw({{
-                                Fd.ud = fpConvert(Fs.ud, WORD_TO_PS);
-                            }});
+                            0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
+                            0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
+                            0x26: FailUnimpl::cvt_ps_w();
                         }
                     }
 
@@ -913,18 +634,10 @@ decode OPCODE_HI default Unknown::unknown() {
                     //Note: "1. Format type L is legal only if 64-bit floating point operations
                     //are enabled."
                     0x5: decode FUNCTION_HI {
-                        format Float64ConvertOp {
-                            0x20: cvt_s_l({{
-                                Fd.uw = fpConvert(Fs.ud, LONG_TO_SINGLE);
-                            }});
-
-                            0x21: cvt_d_l({{
-                                Fd.ud = fpConvert(Fs.ud, LONG_TO_DOUBLE);
-                            }});
-
-                            0x26: cvt_ps_l({{
-                                Fd.ud = fpConvert(Fs.ud, LONG_TO_PS);
-                            }});
+                        format FloatConvertOp {
+                            0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle);
+                            0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble);
+                            0x26: FailUnimpl::cvt_ps_l();
                         }
                     }
 
@@ -938,30 +651,25 @@ decode OPCODE_HI default Unknown::unknown() {
                                     Fd1.sf = Fs1.sf + Ft2.sf;
                                     Fd2.sf = Fs2.sf + Ft2.sf;
                                 }});
-
                                 0x1: sub_ps({{
                                     Fd1.sf = Fs1.sf - Ft2.sf;
                                     Fd2.sf = Fs2.sf - Ft2.sf;
                                 }});
-
                                 0x2: mul_ps({{
                                     Fd1.sf = Fs1.sf * Ft2.sf;
                                     Fd2.sf = Fs2.sf * Ft2.sf;
                                 }});
-
                                 0x5: abs_ps({{
                                     Fd1.sf = fabs(Fs1.sf);
                                     Fd2.sf = fabs(Fs2.sf);
                                 }});
-
                                 0x6: mov_ps({{
                                     Fd1.sf = Fs1.sf;
                                     Fd2.sf = Fs2.sf;
                                 }});
-
                                 0x7: neg_ps({{
-                                    Fd1.sf = -1 * Fs1.sf;
-                                    Fd2.sf = -1 * Fs2.sf;
+                                    Fd1.sf = -(Fs1.sf);
+                                    Fd2.sf = -(Fs2.sf);
                                 }});
                             }
                         }
@@ -970,236 +678,112 @@ decode OPCODE_HI default Unknown::unknown() {
                             0x1: decode MOVCF {
                                 format Float64Op {
                                     0x0: movf_ps({{
-                                        if (getFPConditionCode(FCSR, CC) == 0)
-                                            Fd1 = Fs1;
-                                        if (getFPConditionCode(FCSR, CC+1) == 0)
-                                            Fd2 = Fs2;
+                                        Fd1 = (getCondCode(FCSR, CC) == 0) ?
+                                            Fs1 : Fd1;
+                                        Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
+                                            Fs2 : Fd2;
                                     }});
-
                                     0x1: movt_ps({{
-                                        if (getFPConditionCode(FCSR, CC) == 1)
-                                            Fd1 = Fs1;
-                                        if (getFPConditionCode(FCSR, CC+1) == 1)
-                                            Fd2 = Fs2;
+                                        Fd2 = (getCondCode(FCSR, CC) == 1) ?
+                                            Fs1 : Fd1;
+                                        Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
+                                            Fs2 : Fd2;
                                     }});
                                 }
                             }
 
                             format Float64Op {
                                 0x2: movz_ps({{
-                                    if (getFPConditionCode(FCSR, CC) == 0)
-                                        Fd1 = Fs1;
-                                    if (getFPConditionCode(FCSR, CC) == 0)
-                                        Fd2 = Fs2;
+                                    Fd1 = (getCondCode(FCSR, CC) == 0) ?
+                                        Fs1 : Fd1;
+                                    Fd2 = (getCondCode(FCSR, CC) == 0) ?
+                                        Fs2 : Fd2;
                                 }});
-
                                 0x3: movn_ps({{
-                                    if (getFPConditionCode(FCSR, CC) == 1)
-                                        Fd1 = Fs1;
-                                    if (getFPConditionCode(FCSR, CC) == 1)
-                                        Fd2 = Fs2;
+                                    Fd1 = (getCondCode(FCSR, CC) == 1) ?
+                                        Fs1 : Fd1;
+                                    Fd2 = (getCondCode(FCSR, CC) == 1) ?
+                                        Fs2 : Fd2;
                                 }});
                             }
 
                         }
 
                         0x4: decode FUNCTION_LO {
-                            0x0: Float64Op::cvt_s_pu({{
-                                Fd.uw = fpConvert(Fs2.uw, PU_TO_SINGLE);
-                            }});
+                            0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }});
                         }
 
                         0x5: decode FUNCTION_LO {
-                            format Float64Op {
-                                0x0: cvt_s_pl({{
-                                    Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE);
-                                }});
+                            0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }});
 
-                                0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft1.uw; }});
-                                0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft2.uw; }});
-                                0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft1.uw; }});
-                                0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft2.uw; }});
+                            format Float64Op {
+                                0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 |
+                                                    Ft1.uw;
+                                         }});
+                                0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 |
+                                                    Ft2.uw;
+                                         }});
+                                0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 |
+                                                    Ft1.uw;
+                                         }});
+                                0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 |
+                                                    Ft2.uw;
+                                         }});
                             }
                         }
 
                         0x6: decode FUNCTION_LO {
                             format FloatPSCompareOp {
-                                0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }});
-
-                                0x1: c_un_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = 0;
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = 0;
-
-                                }});
-
-                                0x2: c_eq_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 0;
-                                    else
-                                        cond1 = (Fs1.sf == Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 0;
-                                    else
-                                        cond2 = (Fs2.sf == Ft2.sf);
-                                }});
-
-                                0x3: c_ueq_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = (Fs1.sf == Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = (Fs2.sf == Ft2.sf);
-                                }});
-
-                                0x4: c_olt_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 0;
-                                    else
-                                        cond1 = (Fs1.sf < Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 0;
-                                    else
-                                        cond2 = (Fs2.sf < Ft2.sf);
-                                }});
-
-                                0x5: c_ult_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = (Fs.sf < Ft.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = (Fs2.sf < Ft2.sf);
-                                }});
-
-                                0x6: c_ole_ps({{
-                                    if (isnan(Fs.sf) || isnan(Ft.sf))
-                                        cond1 = 0;
-                                    else
-                                        cond1 = (Fs.sf <= Ft.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 0;
-                                    else
-                                        cond2 = (Fs2.sf <= Ft2.sf);
-                                }});
-
-                                0x7: c_ule_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = (Fs1.sf <= Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = (Fs2.sf <= Ft2.sf);
-                                }});
+                                0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+                                            UnorderedFalse);
+                                0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+                                             UnorderedTrue);
+                                0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+                                             {{ cond2 = (Fs2.sf == Ft2.sf); }},
+                                             UnorderedFalse);
+                                0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf == Ft2.sf); }},
+                                              UnorderedTrue);
+                                0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf < Ft2.sf); }},
+                                              UnorderedFalse);
+                                0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }},
+                                              {{ cond2 = (Fs2.sf < Ft2.sf); }},
+                                              UnorderedTrue);
+                                0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }},
+                                              {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+                                              UnorderedFalse);
+                                0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+                                              UnorderedTrue);
                             }
                         }
 
                         0x7: decode FUNCTION_LO {
-                            format FloatPSCompareWithXcptOp {
-                                0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }});
-
-                                0x1: c_ngle_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = 0;
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = 0;
-                                  }});
-
-                                0x2: c_seq_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 0;
-                                    else
-                                        cond1 = (Fs1.sf == Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 0;
-                                    else
-                                        cond2 = (Fs2.sf == Ft2.sf);
-                                  }});
-
-                                0x3: c_ngl_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = (Fs1.sf == Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = (Fs2.sf == Ft2.sf);
-                                  }});
-
-                                0x4: c_lt_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 0;
-                                    else
-                                        cond1 = (Fs1.sf < Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 0;
-                                    else
-                                        cond2 = (Fs2.sf < Ft2.sf);
-                                  }});
-
-                                0x5: c_nge_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = (Fs1.sf < Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = (Fs2.sf < Ft2.sf);
-                                  }});
-
-                                0x6: c_le_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 0;
-                                    else
-                                        cond1 = (Fs1.sf <= Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 0;
-                                    else
-                                        cond2 = (Fs2.sf <= Ft2.sf);
-                                  }});
-
-                                0x7: c_ngt_ps({{
-                                    if (isnan(Fs1.sf) || isnan(Ft1.sf))
-                                        cond1 = 1;
-                                    else
-                                        cond1 = (Fs1.sf <= Ft1.sf);
-
-                                    if (isnan(Fs2.sf) || isnan(Ft2.sf))
-                                        cond2 = 1;
-                                    else
-                                        cond2 = (Fs2.sf <= Ft2.sf);
-                                  }});
+                            format FloatPSCompareOp {
+                                0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+                                             UnorderedFalse, QnanException);
+                                0x1: c_ngle_ps({{ cond1 = 0; }},
+                                               {{ cond2 = 0; }},
+                                               UnorderedTrue, QnanException);
+                                0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf == Ft2.sf); }},
+                                              UnorderedFalse, QnanException);
+                                0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf == Ft2.sf); }},
+                                              UnorderedTrue, QnanException);
+                                0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+                                             {{ cond2 = (Fs2.sf < Ft2.sf); }},
+                                             UnorderedFalse, QnanException);
+                                0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf < Ft2.sf); }},
+                                              UnorderedTrue, QnanException);
+                                0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+                                             {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+                                             UnorderedFalse, QnanException);
+                                0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+                                              {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+                                              UnorderedTrue, QnanException);
                             }
                         }
                     }
@@ -1209,9 +793,9 @@ decode OPCODE_HI default Unknown::unknown() {
 
         //Table A-19 MIPS32 COP2 Encoding of rs Field
         0x2: decode RS_MSB {
-            0x0: decode RS_HI {
-                0x0: decode RS_LO {
-                    format WarnUnimpl {
+            format FailUnimpl {
+                0x0: decode RS_HI {
+                    0x0: decode RS_LO {
                         0x0: mfc2();
                         0x2: cfc2();
                         0x3: mfhc2();
@@ -1219,18 +803,14 @@ decode OPCODE_HI default Unknown::unknown() {
                         0x6: ctc2();
                         0x7: mftc2();
                     }
-                }
 
-                0x1: decode ND {
-                    0x0: decode TF {
-                        format WarnUnimpl {
+                    0x1: decode ND {
+                        0x0: decode TF {
                             0x0: bc2f();
                             0x1: bc2t();
                         }
-                    }
 
-                    0x1: decode TF {
-                        format WarnUnimpl {
+                        0x1: decode TF {
                             0x0: bc2fl();
                             0x1: bc2tl();
                         }
@@ -1244,441 +824,240 @@ decode OPCODE_HI default Unknown::unknown() {
         //operations are enabled."
         0x3: decode FUNCTION_HI {
             0x0: decode FUNCTION_LO {
-                format LoadFloatMemory {
-                    0x0: lwxc1({{ Ft.uw = Mem.uw;}}, {{ EA = Rs + Rt; }});
-                    0x1: ldxc1({{ Ft.ud = Mem.ud;}}, {{ EA = Rs + Rt; }});
-                    0x5: luxc1({{ Ft.uw = Mem.ud;}}, {{ EA = Rs + Rt; }});
+                format LoadIndexedMemory {
+                    0x0: lwxc1({{ Ft.uw = Mem.uw;}});
+                    0x1: ldxc1({{ Ft.ud = Mem.ud;}});
+                    0x5: luxc1({{ Ft.uw = Mem.ud;}});
                 }
             }
 
             0x1: decode FUNCTION_LO {
-                format StoreFloatMemory {
-                    0x0: swxc1({{ Mem.uw = Ft.uw;}}, {{ EA = Rs + Rt; }});
-                    0x1: sdxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }});
-                    0x5: suxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }});
+                format StoreIndexedMemory {
+                    0x0: swxc1({{ Mem.uw = Ft.uw;}});
+                    0x1: sdxc1({{ Mem.ud = Ft.ud;}});
+                    0x5: suxc1({{ Mem.ud = Ft.ud;}});
                 }
 
-                0x7: WarnUnimpl::prefx();
+                0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
             }
 
-            format FloatOp {
-                0x3: WarnUnimpl::alnv_ps();
+            0x3: decode FUNCTION_LO {
+                0x6: Float64Op::alnv_ps({{ if (Rs<2:0> == 0) {
+                                               Fd.ud = Fs.ud;
+                                           } else if (Rs<2:0> == 4) {
+                                             #if BYTE_ORDER == BIG_ENDIAN
+                                               Fd.ud = Fs.ud<31:0> << 32 |
+                                                       Ft.ud<63:32>;
+                                             #elif BYTE_ORDER == LITTLE_ENDIAN
+                                               Fd.ud = Ft.ud<31:0> << 32 |
+                                                       Fs.ud<63:32>;
+                                             #endif
+                                           } else {
+                                               Fd.ud = Fd.ud;
+                                           }
+                                        }});
+            }
 
-                format BasicOp {
-                    0x4: decode FUNCTION_LO {
-                        0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
-                        0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
-                        0x6: madd_ps({{
-                            Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
-                            Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
-                        }});
-                    }
+            format FloatAccOp {
+                0x4: decode FUNCTION_LO {
+                    0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
+                    0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
+                    0x6: madd_ps({{
+                        Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
+                        Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
+                    }});
+                }
 
-                    0x5: decode FUNCTION_LO {
-                        0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
-                        0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
-                        0x6: msub_ps({{
-                            Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
-                            Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
-                        }});
-                    }
+                0x5: decode FUNCTION_LO {
+                    0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
+                    0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
+                    0x6: msub_ps({{
+                        Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
+                        Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
+                    }});
+                }
 
-                    0x6: decode FUNCTION_LO {
-                        0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
-                        0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
-                        0x6: nmadd_ps({{
-                            Fd1.sf = -1 * ((Fs1.df * Ft1.df) + Fr1.df);
-                            Fd2.sf = -1 * ((Fs2.df * Ft2.df) + Fr2.df);
-                        }});
-                    }
+                0x6: decode FUNCTION_LO {
+                    0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
+                    0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
+                    0x6: nmadd_ps({{
+                        Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df);
+                        Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df);
+                    }});
+                }
 
-                    0x7: decode FUNCTION_LO {
-                        0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
-                        0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
-                        0x6: nmsub_ps({{
-                            Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df);
-                            Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df);
-                        }});
-                    }
+                0x7: decode FUNCTION_LO {
+                    0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
+                    0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
+                    0x6: nmsub_ps({{
+                        Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df);
+                        Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df);
+                    }});
                 }
+
             }
         }
 
-        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); }});
+        format Branch {
+            0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely);
+            0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely);
+            0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely);
+            0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely);
         }
     }
 
-    0x3: decode OPCODE_LO default FailUnimpl::reserved() {
-
+    0x3: decode OPCODE_LO {
         //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
         0x4: decode FUNCTION_HI {
-
             0x0: decode FUNCTION_LO {
-                format IntOp {
-                    0x0: madd({{
-                        int64_t temp1 = (int64_t) HI << 32 | LO;
-                        temp1 = temp1 + (Rs.sw * Rt.sw);
-                        HI = temp1<63:32>;
-                        LO = temp1<31:0>;
-                    }});
-
-                    0x1: maddu({{
-                        int64_t temp1 = (int64_t) HI << 32 | LO;
-                        temp1 = temp1 + (Rs.uw * Rt.uw);
-                        HI = temp1<63:32>;
-                        LO = temp1<31:0>;
-                    }});
-
-                    0x2: mul({{ Rd.sw = Rs.sw * Rt.sw;         }});
-
-                    0x4: msub({{
-                        int64_t temp1 = (int64_t) HI << 32 | LO;
-                        temp1 = temp1 - (Rs.sw * Rt.sw);
-                        HI = temp1<63:32>;
-                        LO = temp1<31:0>;
-                    }});
+                0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd;
+                                   Rd.sw = temp1<31:0>
+                                }});
 
-                    0x5: msubu({{
-                        int64_t temp1 = (int64_t) HI << 32 | LO;
-                        temp1 = temp1 - (Rs.uw * Rt.uw);
-                        HI = temp1<63:32>;
-                        LO = temp1<31:0>;
-                    }});
+                format HiLoOp {
+                    0x0: madd({{ val = ((int64_t) HI << 32 | LO) +
+                                       (Rs.sd * Rt.sd);
+                              }});
+                    0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) +
+                                        (Rs.ud * Rt.ud);
+                               }});
+                    0x4: msub({{ val = ((int64_t) HI << 32 | LO) -
+                                       (Rs.sd * Rt.sd);
+                              }});
+                    0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) -
+                                        (Rs.ud * Rt.ud);
+                               }});
                 }
             }
 
             0x4: decode FUNCTION_LO {
                 format BasicOp {
-                    0x0: clz({{
-                        int cnt = 0;
-                        uint32_t mask = 0x80000000;
-                        for (int i=0; i < 32; i++) {
-                            if( (Rs & mask) == 0) {
-                                cnt++;
-                            } else {
-                                break;
-                            }
-                        }
-                        Rd.uw = cnt;
-                    }});
-
-                    0x1: clo({{
-                        int cnt = 0;
-                        uint32_t mask = 0x80000000;
-                        for (int i=0; i < 32; i++) {
-                            if( (Rs & mask) != 0) {
-                                cnt++;
-                            } else {
-                                break;
-                            }
-                        }
-                        Rd.uw = cnt;
-                    }});
+                    0x0: clz({{ int cnt = 32;
+                                for (int idx = 31; idx >= 0; idx--) {
+                                    if( Rs<idx:idx> == 1) {
+                                        cnt = 31 - idx;
+                                        break;
+                                    }
+                                }
+                                Rd.uw = cnt;
+                             }});
+                    0x1: clo({{ int cnt = 32;
+                                for (int idx = 31; idx >= 0; idx--) {
+                                    if( Rs<idx:idx> == 0) {
+                                        cnt = 31 - idx;
+                                        break;
+                                    }
+                                }
+                                Rd.uw = cnt;
+                             }});
                 }
             }
 
             0x7: decode FUNCTION_LO {
-                0x7: WarnUnimpl::sdbbp();
+                0x7: FailUnimpl::sdbbp();
             }
         }
 
-        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
+        //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
+        //of the Architecture
         0x7: decode FUNCTION_HI {
-
             0x0: decode FUNCTION_LO {
-                format FailUnimpl {
-                    0x1: ext();
-                    0x4: ins();
+                format BasicOp {
+                    0x1: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }});
+                    0x4: ins({{ Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) |
+                                        bits(Rs.uw, MSB-LSB, 0) << LSB |
+                                        bits(Rt.uw, LSB-1, 0);
+                             }});
                 }
             }
 
             0x1: decode FUNCTION_LO {
-                format FailUnimpl {
+                format MipsMT {
                     0x0: fork();
                     0x1: yield();
                 }
             }
 
-
             //Table A-10 MIPS32 BSHFL Encoding of sa Field
             0x4: decode SA {
-
-                0x02: FailUnimpl::wsbh();
-
                 format BasicOp {
+                    0x02: wsbh({{ Rd.uw = Rt.uw<23:16> << 24 |
+                                          Rt.uw<31:24> << 16 |
+                                          Rt.uw<7:0>   << 8  |
+                                          Rt.uw<15:8>;
+                    }});
                     0x10: seb({{ Rd.sw = Rt.sw<7:0>}});
                     0x18: seh({{ Rd.sw = Rt.sw<15:0>}});
                 }
             }
 
             0x6: decode FUNCTION_LO {
-                0x7: FailUnimpl::rdhwr();//{{ /*Rt = xc->hwRegs[RD];*/ }}
+                0x7: FailUnimpl::rdhwr();
             }
         }
     }
 
-    0x4: decode OPCODE_LO default FailUnimpl::reserved() {
+    0x4: decode OPCODE_LO {
         format LoadMemory {
             0x0: lb({{ Rt.sw = Mem.sb; }});
             0x1: lh({{ Rt.sw = Mem.sh; }});
-
-            0x2: lwl({{
-                uint32_t mem_word = Mem.uw;
-                uint32_t unalign_addr = Rs + disp;
-                uint32_t offset = unalign_addr & 0x00000003;
-#if BYTE_ORDER == BIG_ENDIAN
-                switch(offset)
-                {
-                  case 0:
-                    Rt = mem_word;
-                    break;
-
-                  case 1:
-                    Rt &= 0x000F;
-                    Rt |= (mem_word << 4);
-                    break;
-
-                  case 2:
-                    Rt &= 0x00FF;
-                    Rt |= (mem_word << 8);
-                    break;
-
-                  case 3:
-                    Rt &= 0x0FFF;
-                    Rt |= (mem_word << 12);
-                    break;
-
-                  default:
-                    panic("lwl: bad offset");
-                }
-#elif BYTE_ORDER == LITTLE_ENDIAN
-                switch(offset)
-                {
-                  case 0:
-                    Rt &= 0x0FFF;
-                    Rt |= (mem_word << 12);
-                    break;
-
-                  case 1:
-                    Rt &= 0x00FF;
-                    Rt |= (mem_word << 8);
-                    break;
-
-                  case 2:
-                    Rt &= 0x000F;
-                    Rt |= (mem_word << 4);
-                    break;
-
-                  case 3:
-                    Rt = mem_word;
-                    break;
-
-                  default:
-                    panic("lwl: bad offset");
-                }
-#endif
-            }}, {{ EA = (Rs + disp) & ~3; }});
-
             0x3: lw({{ Rt.sw = Mem.sw; }});
             0x4: lbu({{ Rt.uw = Mem.ub; }});
             0x5: lhu({{ Rt.uw = Mem.uh; }});
-            0x6: lwr({{
-                uint32_t mem_word = Mem.uw;
-                uint32_t unalign_addr = Rs + disp;
-                uint32_t offset = unalign_addr & 0x00000003;
-
-#if BYTE_ORDER == BIG_ENDIAN
-                switch(offset)
-                {
-                  case 0: Rt &= 0xFFF0;  Rt |= (mem_word >> 12); break;
-                  case 1: Rt &= 0xFF00;  Rt |= (mem_word >> 8);  break;
-                  case 2: Rt &= 0xF000;  Rt |= (mem_word >> 4);  break;
-                  case 3: Rt = mem_word; break;
-                  default: panic("lwr: bad offset");
-                }
-#elif BYTE_ORDER == LITTLE_ENDIAN
-                switch(offset)
-                {
-                  case 0: Rt = mem_word; break;
-                  case 1: Rt &= 0xF000;  Rt |= (mem_word >> 4);  break;
-                  case 2: Rt &= 0xFF00;  Rt |= (mem_word >> 8);  break;
-                  case 3: Rt &= 0xFFF0;  Rt |= (mem_word >> 12); break;
-                  default: panic("lwr: bad offset");
-                }
-#endif
-            }},
-            {{ EA = (Rs + disp) & ~3; }});
+        }
+
+        format LoadUnalignedMemory {
+            0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset);
+                        Rt.uw = mem_word << mem_shift |
+                                Rt.uw & mask(mem_shift);
+                     }});
+            0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset;
+                        Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) |
+                                mem_word >> mem_shift;
+                     }});
         }
     }
 
-    0x5: decode OPCODE_LO default FailUnimpl::reserved() {
+    0x5: decode OPCODE_LO {
         format StoreMemory {
             0x0: sb({{ Mem.ub = Rt<7:0>; }});
             0x1: sh({{ Mem.uh = Rt<15:0>; }});
-            0x2: swl({{
-                uint32_t mem_word = 0;
-                uint32_t aligned_addr = (Rs + disp) & ~3;
-                uint32_t unalign_addr = Rs + disp;
-                uint32_t offset = unalign_addr & 0x00000003;
-
-                DPRINTF(IEW,"Execute: aligned=0x%x unaligned=0x%x\n offset=0x%x",
-                        aligned_addr,unalign_addr,offset);
-
-                fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
-
-#if BYTE_ORDER == BIG_ENDIAN
-                switch(offset)
-                {
-                  case 0:
-                    Mem = Rt;
-                    break;
-
-                  case 1:
-                    mem_word &= 0xF000;
-                    mem_word |= (Rt >> 4);
-                    Mem = mem_word;
-                    break;
-
-                  case 2:
-                    mem_word &= 0xFF00;
-                    mem_word |= (Rt >> 8);
-                    Mem = mem_word;
-                    break;
-
-                  case 3:
-                    mem_word &= 0xFFF0;
-                    mem_word |= (Rt >> 12);
-                    Mem = mem_word;
-                   break;
-
-                  default:
-                    panic("swl: bad offset");
-                }
-#elif BYTE_ORDER == LITTLE_ENDIAN
-                switch(offset)
-                {
-                  case 0:
-                    mem_word &= 0xFFF0;
-                    mem_word |= (Rt >> 12);
-                    Mem = mem_word;
-                    break;
-
-                  case 1:
-                    mem_word &= 0xFF00;
-                    mem_word |= (Rt >> 8);
-                    Mem = mem_word;
-                    break;
-
-                  case 2:
-                    mem_word &= 0xF000;
-                    mem_word |= (Rt >> 4);
-                    Mem = mem_word;
-                    break;
-
-                  case 3:
-                    Mem = Rt;
-                   break;
-
-                  default:
-                    panic("swl: bad offset");
-                }
-#endif
-            }},{{ EA = (Rs + disp) & ~3; }},mem_flags = NO_ALIGN_FAULT);
-
             0x3: sw({{ Mem.uw = Rt<31:0>; }});
-
-            0x6: swr({{
-                uint32_t mem_word = 0;
-                uint32_t aligned_addr = (Rs + disp) & ~3;
-                uint32_t unalign_addr = Rs + disp;
-                uint32_t offset = unalign_addr & 0x00000003;
-
-                fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
-
-#if BYTE_ORDER == BIG_ENDIAN
-                switch(offset)
-                {
-                  case 0:
-                    mem_word &= 0x0FFF;
-                    mem_word |= (Rt << 12);
-                    Mem = mem_word;
-                    break;
-
-                  case 1:
-                    mem_word &= 0x00FF;
-                    mem_word |= (Rt << 8);
-                    Mem = mem_word;
-                    break;
-
-                  case 2:
-                    mem_word &= 0x000F;
-                    mem_word |= (Rt << 4);
-                    Mem = mem_word;
-                    break;
-
-                  case 3:
-                    Mem = Rt;
-                    break;
-
-                  default:
-                    panic("swr: bad offset");
-                }
-#elif BYTE_ORDER == LITTLE_ENDIAN
-                switch(offset)
-                {
-                  case 0:
-                    Mem = Rt;
-                    break;
-
-                  case 1:
-                    mem_word &= 0x000F;
-                    mem_word |= (Rt << 4);
-                    Mem = mem_word;
-                    break;
-
-                  case 2:
-                    mem_word &= 0x00FF;
-                    mem_word |= (Rt << 8);
-                    Mem = mem_word;
-                    break;
-
-                  case 3:
-                    mem_word &= 0x0FFF;
-                    mem_word |= (Rt << 12);
-                    Mem = mem_word;
-                    break;
-
-                  default:
-                    panic("swr: bad offset");
-                }
-#endif
-            }},{{ EA = (Rs + disp) & ~3;}},mem_flags = NO_ALIGN_FAULT);
         }
 
-        format WarnUnimpl {
-            0x7: cache();
+        format StoreUnalignedMemory {
+            0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset);
+                        uint32_t mem_shift = 32 - reg_shift;
+                        mem_word = mem_word & (mask(reg_shift) << mem_shift) |
+                                   Rt.uw >> reg_shift;
+                     }});
+            0x6: swr({{ uint32_t reg_shift = 8 * byte_offset;
+                        mem_word = Rt.uw << reg_shift |
+                                   mem_word & (mask(reg_shift));
+                     }});
         }
 
+        0x7: FailUnimpl::cache();
     }
 
-    0x6: decode OPCODE_LO default FailUnimpl::reserved() {
-        0x0: LoadMemory::ll({{Rt.uw = Mem.uw}},mem_flags=LOCKED);
-
-        format LoadFloatMemory {
-            0x1: lwc1({{ Ft.uw = Mem.uw;    }});
+    0x6: decode OPCODE_LO {
+        format LoadMemory {
+            0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LOCKED);
+            0x1: lwc1({{ Ft.uw = Mem.uw; }});
             0x5: ldc1({{ Ft.ud = Mem.ud; }});
         }
+
+        0x3: Prefetch::pref();
     }
 
 
-    0x7: decode OPCODE_LO default FailUnimpl::reserved() {
-        0x0: StoreMemory::sc({{ Mem.uw = Rt.uw; Rt.uw = 1; }});
+    0x7: decode OPCODE_LO {
+        0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}},
+                           {{ uint64_t tmp = write_result;
+                              Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
+                           }}, mem_flags=LOCKED);
 
-        format StoreFloatMemory {
+        format StoreMemory {
             0x1: swc1({{ Mem.uw = Ft.uw; }});
             0x5: sdc1({{ Mem.ud = Ft.ud; }});
         }
index c02af7ddc0d773aa07a756ed16998ebdebc46857..e6c53d4900c679945c26cf9b70ef9dd964c2f719 100644 (file)
@@ -12,11 +12,11 @@ def template BasicDeclare {{
          */
         class %(class_name)s : public %(base_class)s
         {
-        public:
+          public:
                 /// Constructor.
                 %(class_name)s(MachInst machInst);
                 %(BasicExecDeclare)s
-    };
+        };
 }};
 
 // Basic instruction class constructor template.
@@ -27,6 +27,7 @@ def template BasicConstructor {{
         }
 }};
 
+
 // Basic instruction class execute method template.
 def template BasicExecute {{
         Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
index 8cfa37a20156184aad236edd7f926662f0ed02ba..6f8cebed0f5c35d64606006cdd521e9d619a47b2 100644 (file)
@@ -67,29 +67,6 @@ output header {{
         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.
-        BranchLikely(const char *mnem, MachInst _machInst, OpClass __opClass)
-            : PCDependentDisassembly(mnem, _machInst, __opClass),
-              disp(OFFSET << 2)
-        {
-
-        }
-
-        Addr branchTarget(Addr branchPC) const;
-
-        std::string
-        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
-    };
-
     /**
      * Base class for jumps (register-indirect control transfers).  In
      * the Mips ISA, these are always unconditional.
@@ -125,12 +102,6 @@ output decoder {{
         return branchPC + 4 + disp;
     }
 
-    Addr
-    BranchLikely::branchTarget(Addr branchPC) const
-    {
-        return branchPC + 4 + disp;
-    }
-
     Addr
     Jump::branchTarget(ExecContext *xc) const
     {
@@ -171,49 +142,12 @@ output decoder {{
         // unconditional branches)
         if (_numSrcRegs == 1) {
             printReg(ss, _srcRegIdx[0]);
-            ss << ",";
+            ss << ", ";
         } else if(_numSrcRegs == 2) {
             printReg(ss, _srcRegIdx[0]);
-            ss << ",";
+            ss << ", ";
             printReg(ss, _srcRegIdx[1]);
-            ss << ",";
-        }
-
-        Addr target = pc + 4 + disp;
-
-        std::string str;
-        if (symtab && symtab->findSymbol(target, str))
-            ss << str;
-        else
-            ccprintf(ss, "0x%x", target);
-
-        string inst_name = mnemonic;
-
-        if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){
-            ccprintf(ss, " (r31=0x%x)",pc+8);
-        }
-
-        return ss.str();
-    }
-
-    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 << ",";
+            ss << ", ";
         }
 
         Addr target = pc + 4 + disp;
@@ -247,72 +181,64 @@ output decoder {{
              printReg(ss, _srcRegIdx[0]);
         } else if(_numSrcRegs == 2) {
             printReg(ss, _srcRegIdx[0]);
-            ss << ",";
+            ss << ", ";
             printReg(ss, _srcRegIdx[1]);
-        } else {
-            panic(">= 3 Source Registers!!!");
         }
 
         return ss.str();
     }
 }};
 
-def format Branch(code,*flags) {{
-    #Add Link Code if Link instruction
-    strlen = len(name)
-    if name[strlen-2:] == 'al':
-        code += 'R31 = NNPC;\n'
+def format Branch(code,*opt_flags) {{
+    not_taken_code = '  NNPC = NNPC;\n'
+    not_taken_code += '} \n'
+
+    #Build Instruction Flags
+    #Use Link & Likely Flags to Add Link/Condition Code
+    inst_flags = ('IsDirectControl', )
+    for x in opt_flags:
+        if x == 'Link':
+            code += 'R31 = NNPC;\n'
+        elif x == 'Likely':
+            not_taken_code = '  NPC = NNPC;\n'
+            not_taken_code += '  NNPC = NNPC + 4;\n'
+            not_taken_code += '} \n'
+            inst_flags = ('IsCondDelaySlot', )
+        else:
+            inst_flags += (x, )
+
+    if 'cond == 1' in code:
+         inst_flags += ('IsCondControl', )
+    else:
+         inst_flags += ('IsUncondControl', )
 
     #Condition code
     code = 'bool cond;\n' + code
     code += 'if (cond) {\n'
     code += '  NNPC = NPC + disp;\n'
     code += '} else {\n'
-    code += '  NNPC = NNPC;\n'
-    code += '} \n'
-
-    iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
-                        ('IsDirectControl', 'IsCondControl'))
+    code += not_taken_code
 
+    iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
     decode_block = BasicDecode.subst(iop)
     exec_output = BasicExecute.subst(iop)
 }};
 
-
-def format BranchLikely(code,*flags) {{
-    #Add Link Code if Link instruction
-    strlen = len(name)
-    if name[strlen-3:] == 'all':
-        code += 'R31 = NNPC;\n'
-
-    #Condition code
-    code = 'bool cond;\n' + code
-    code += 'if (cond) {'
-    code += 'NNPC = NPC + disp;\n'
-    code += '} \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(code,*flags) {{
-    #Add Link Code if Link instruction
-    strlen = len(name)
-    if strlen > 1 and name[1:] == 'al':
+def format Jump(code, *opt_flags) {{
+    #Build Instruction Flags
+    #Use Link Flag to Add Link Code
+    inst_flags = ('IsIndirectControl', 'IsUncondControl')
+    for x in opt_flags:
+        if x == 'Link':
             code = 'R31 = NNPC;\n' + code
+        elif x == 'ClearHazards':
+            code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
+        else:
+            inst_flags += (x, )
 
-
-    iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
-                        ('IsIndirectControl', 'IsUncondControl'))
-
+    iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
     decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa
new file mode 100644 (file)
index 0000000..f2f69d6
--- /dev/null
@@ -0,0 +1,128 @@
+// -*- mode:c++ -*-
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer operate instructions
+//
+
+//Outputs to decoder.hh
+output header {{
+
+        class Control : public MipsStaticInst
+        {
+                protected:
+
+                /// Constructor
+                Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                           MipsStaticInst(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+        class CP0Control : public Control
+        {
+                protected:
+
+                /// Constructor
+                CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                           Control(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+        class CP1Control : public Control
+        {
+                protected:
+
+                /// Constructor
+                CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                           Control(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+}};
+
+//Outputs to decoder.cc
+output decoder {{
+        std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+
+            ccprintf(ss, "%-10s ", mnemonic);
+
+            if (mnemonic == "mfc0" || mnemonic == "mtc0") {
+                ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL);
+            } else {
+
+                // 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 CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+            ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
+            return ss.str();
+        }
+
+        std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+            ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
+            return ss.str();
+        }
+
+}};
+
+def format System(code, *flags) {{
+        iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = BasicExecute.subst(iop)
+}};
+
+def format CP0Control(code, *flags) {{
+        iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = BasicExecute.subst(iop)
+}};
+
+def format CP1Control(code, *flags) {{
+        iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = BasicExecute.subst(iop)
+}};
+
+
index 7d493ffaec96f09dfc8c5a73ab65dd6e73733825..ed31788a6fcec2eb9401d33f83bcc5adb423f8bf 100644 (file)
@@ -10,8 +10,8 @@
 //Include utility functions
 ##include "util.isa"
 
-//Include the cop0 formats
-##include "cop0.isa"
+//Include the control/cp0/cp1 formats
+##include "control.isa"
 
 //Include the integer formats
 ##include "int.isa"
@@ -22,6 +22,9 @@
 //Include the mem format
 ##include "mem.isa"
 
+//Include the mem format
+##include "mt.isa"
+
 //Include the trap format
 ##include "trap.isa"
 
index 9f2c24755e35bd74cca8bc1711ada252430e2ea7..6647f93619f05cfb2f4068d291414340db29be90 100644 (file)
@@ -18,49 +18,264 @@ output header {{
                 {
                 }
 
-                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+            //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+                //needs function to check for fpEnable or not
+        };
+
+        class FPCompareOp : public FPOp
+        {
+          protected:
+            FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)
+                {
+                }
+
+            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
         };
 }};
 
 output decoder {{
-        std::string FPOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
         {
-                return "Disassembly of integer instruction\n";
+            std::stringstream ss;
+
+            ccprintf(ss, "%-10s ", mnemonic);
+
+            ccprintf(ss,"%d",CC);
+
+            if(_numSrcRegs > 0) {
+                ss << ", ";
+                printReg(ss, _srcRegIdx[0]);
+            }
+
+            if(_numSrcRegs > 1) {
+                ss << ", ";
+                printReg(ss, _srcRegIdx[1]);
+            }
+
+            return ss.str();
         }
 }};
 
+output exec {{
 
-// Primary format for float operate instructions:
-def format FloatOp(code, *flags) {{
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+        //If any operand is Nan return the appropriate QNaN
+        template <class T>
+        bool
+        fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type,
+                      Trace::InstRecord *traceData)
+        {
+            uint64_t mips_nan = 0;
+            T src_op = 0;
+            int size = sizeof(src_op) * 8;
+
+            for (int i = 0; i < inst->numSrcRegs(); i++) {
+                uint64_t src_bits = xc->readFloatRegBits(inst, 0, size);
+
+                if (isNan(&src_bits, size) ) {
+                    if (isSnan(&src_bits, size)) {
+                        switch (size)
+                        {
+                          case 32: mips_nan = MIPS32_QNAN; break;
+                          case 64: mips_nan = MIPS64_QNAN; break;
+                          default: panic("Unsupported Floating Point Size (%d)", size);
+                        }
+                    } else {
+                        mips_nan = src_bits;
+                    }
+
+                    xc->setFloatRegBits(inst, 0, mips_nan, size);
+                    if (traceData) { traceData->setData(mips_nan); }
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        template <class T>
+        bool
+        fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *xc, const T dest_val,
+                    Trace::InstRecord *traceData)
+        {
+            uint64_t mips_nan = 0;
+            T src_op = dest_val;
+            int size = sizeof(src_op) * 8;
+
+            if (isNan(&src_op, size)) {
+                switch (size)
+                {
+                  case 32: mips_nan = MIPS32_QNAN; break;
+                  case 64: mips_nan = MIPS64_QNAN; break;
+                  default: panic("Unsupported Floating Point Size (%d)", size);
+                }
+
+                //Set value to QNAN
+                xc->setFloatRegBits(inst, 0, mips_nan, size);
+
+                //Read FCSR from FloatRegFile
+                uint32_t fcsr_bits = xc->cpuXC->readFloatRegBits(FCSR);
+
+                //Write FCSR from FloatRegFile
+                xc->cpuXC->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
+
+                if (traceData) { traceData->setData(mips_nan); }
+                return true;
+            }
+
+            return false;
+        }
+
+        void
+        fpResetCauseBits(%(CPU_exec_context)s *xc)
+        {
+            //Read FCSR from FloatRegFile
+            uint32_t fcsr = xc->cpuXC->readFloatRegBits(FCSR);
+
+            fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
+
+            //Write FCSR from FloatRegFile
+            xc->cpuXC->setFloatRegBits(FCSR, fcsr);
+        }
 }};
 
-def format FloatCompareOp(code, *flags) {{
-        code = 'bool cond;\n' + code
-        code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+def template FloatingPointExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(fp_enable_check)s;
+
+                //When is the right time to reset cause bits?
+                //start of every instruction or every cycle?
+                fpResetCauseBits(xc);
+
+                %(op_decl)s;
+                %(op_rd)s;
+
+                //Check if any FP operand is a NaN value
+                if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
+                    %(code)s;
+
+                    //Change this code for Full-System/Sycall Emulation
+                    //separation
+                    //----
+                    //Should Full System-Mode throw a fault here?
+                    //----
+                    //Check for IEEE 754 FP Exceptions
+                    //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
+                    if (!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
+                        fault == NoFault)
+                    {
+                        %(op_wb)s;
+                    }
+                }
+
+                return fault;
+        }
 }};
 
-def format FloatCompareWithXcptOp(code, *flags) {{
-        code = 'bool cond;\n' + code
-        code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+// Primary format for float point operate instructions:
+def format FloatOp(code, *flags) {{
+        iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+        exec_output = FloatingPointExecute.subst(iop)
+}};
+
+def format FloatCompareOp(cond_code, *flags) {{
+    import sys
+
+    code = 'bool cond;\n'
+    if '.sf' in cond_code or 'SinglePrecision' in flags:
+        if 'QnanException' in flags:
+            code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n'
+            code += '\tFCSR = genInvalidVector(FCSR);\n'
+            code += '\treturn NoFault;'
+            code += '}\n else '
+        code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n'
+    elif '.df' in cond_code or 'DoublePrecision' in flags:
+        if 'QnanException' in flags:
+            code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n'
+            code += '\tFCSR = genInvalidVector(FCSR);\n'
+            code += '\treturn NoFault;'
+            code += '}\n else '
+        code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n'
+    else:
+       sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')
+
+    if 'UnorderedTrue' in flags:
+       code += 'cond = 1;\n'
+    elif 'UnorderedFalse' in flags:
+       code += 'cond = 0;\n'
+    else:
+       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+
+    code += '} else {\n'
+    code +=  cond_code + '}'
+    code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
+
+    iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
 }};
 
 def format FloatConvertOp(code, *flags) {{
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+    import sys
+
+    #Determine Source Type
+    convert = 'fpConvert('
+    if '.sf' in code:
+        code = 'float ' + code + '\n'
+        convert += 'SINGLE_TO_'
+    elif '.df' in code:
+        code = 'double ' + code + '\n'
+        convert += 'DOUBLE_TO_'
+    elif '.uw' in code:
+        code = 'uint32_t ' + code + '\n'
+        convert += 'WORD_TO_'
+    elif '.ud' in code:
+        code = 'uint64_t ' + code + '\n'
+        convert += 'LONG_TO_'
+    else:
+        sys.exit("Error Determining Source Type for Conversion")
+
+    #Determine Destination Type
+    if 'ToSingle' in flags:
+        code += 'Fd.uw = ' + convert + 'SINGLE, '
+    elif 'ToDouble' in flags:
+        code += 'Fd.ud = ' + convert + 'DOUBLE, '
+    elif 'ToWord' in flags:
+        code += 'Fd.uw = ' + convert + 'WORD, '
+    elif 'ToLong' in flags:
+        code += 'Fd.ud = ' + convert + 'LONG, '
+    else:
+        sys.exit("Error Determining Destination Type for Conversion")
+
+    #Figure out how to round value
+    if 'Ceil' in flags:
+        code += 'ceil(val)); '
+    elif 'Floor' in flags:
+        code += 'floor(val)); '
+    elif 'Round' in flags:
+        code += 'roundFP(val, 0)); '
+    elif 'Trunc' in flags:
+        code += 'truncFP(val));'
+    else:
+        code += 'val); '
+
+    iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code))
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
+}};
+
+def format FloatAccOp(code, *flags) {{
+        iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
@@ -76,34 +291,51 @@ def format Float64Op(code, *flags) {{
         exec_output = BasicExecute.subst(iop)
 }};
 
-def format Float64ConvertOp(code, *flags) {{
-        code = 'bool cond;\n' + code
-        code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
-}};
+def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
+    import sys
 
-def format FloatPSCompareOp(code, *flags) {{
-        code = 'bool cond1;\nbool cond2;\n' + code
-        code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
-        code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
-}};
+    code = 'bool cond1, cond2;\n'
+    code += 'bool code_block1, code_block2;\n'
+    code += 'code_block1 = code_block2 = true;\n'
 
-def format FloatPSCompareWithXcptOp(code, *flags) {{
-        code = 'bool cond1;\nbool cond2;\n' + code
-        code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
-        code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
-        iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+    if 'QnanException' in flags:
+        code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n'
+        code += '\tFCSR = genInvalidVector(FCSR);\n'
+        code += 'code_block1 = false;'
+        code += '}\n'
+        code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n'
+        code += '\tFCSR = genInvalidVector(FCSR);\n'
+        code += 'code_block2 = false;'
+        code += '}\n'
+
+    code += 'if (code_block1) {'
+    code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n'
+    if 'UnorderedTrue' in flags:
+       code += 'cond1 = 1;\n'
+    elif 'UnorderedFalse' in flags:
+       code += 'cond1 = 0;\n'
+    else:
+       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+    code += '} else {\n'
+    code +=  cond_code1
+    code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'
+
+    code += 'if (code_block2) {'
+    code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n'
+    if 'UnorderedTrue' in flags:
+       code += 'cond2 = 1;\n'
+    elif 'UnorderedFalse' in flags:
+       code += 'cond2 = 0;\n'
+    else:
+       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+    code += '} else {\n'
+    code +=  cond_code2
+    code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'
+
+    iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
 }};
+
index 7d38b9ff5f3cf590b90731c219936562c8d25c3d..99aee828f2a70447dbbc450864093b293a03c7ed 100644 (file)
@@ -4,8 +4,6 @@
 //
 // Integer operate instructions
 //
-
-//Outputs to decoder.hh
 output header {{
 #include <iostream>
     using namespace std;
@@ -25,6 +23,34 @@ output header {{
                 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
         };
 
+
+        class HiLoOp: public IntOp
+        {
+                protected:
+
+                /// Constructor
+                HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                                IntOp(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+        class HiLoMiscOp: public HiLoOp
+        {
+                protected:
+
+                /// Constructor
+                HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                                HiLoOp(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+
         class IntImmOp : public MipsStaticInst
         {
                 protected:
@@ -52,6 +78,33 @@ output header {{
 
 }};
 
+// HiLo<Misc> instruction class execute method template.
+// Mainly to get instruction trace data to print out
+// correctly
+def template HiLoExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(fp_enable_check)s;
+                %(op_decl)s;
+                %(op_rd)s;
+                %(code)s;
+
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
+                    //If there are 2 Destination Registers then
+                    //concatenate the values for the traceData
+                    if(traceData && _numDestRegs == 2) {
+                        uint64_t hilo_final_val = (uint64_t)HI << 32 | LO;
+                        traceData->setData(hilo_final_val);
+                    }
+                }
+                return fault;
+        }
+}};
+
 //Outputs to decoder.cc
 output decoder {{
         std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
@@ -64,7 +117,7 @@ output decoder {{
             // it's generally implicit
             if (_numDestRegs > 0) {
                 printReg(ss, _destRegIdx[0]);
-                ss << ",";
+                ss << ", ";
             }
 
             // just print the first two source regs... if there's
@@ -75,13 +128,47 @@ output decoder {{
             }
 
             if (_numSrcRegs > 1) {
-                ss << ",";
+                ss << ", ";
+                printReg(ss, _srcRegIdx[1]);
+            }
+
+            return ss.str();
+        }
+
+        std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+
+            ccprintf(ss, "%-10s ", mnemonic);
+
+            //Destination Registers are implicit for HI/LO ops
+            if (_numSrcRegs > 0) {
+                printReg(ss, _srcRegIdx[0]);
+            }
+
+            if (_numSrcRegs > 1) {
+                ss << ", ";
                 printReg(ss, _srcRegIdx[1]);
             }
 
             return ss.str();
         }
 
+        std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+
+            ccprintf(ss, "%-10s ", mnemonic);
+
+            if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+                printReg(ss, _destRegIdx[0]);
+            } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+                printReg(ss, _srcRegIdx[0]);
+            }
+
+            return ss.str();
+        }
+
         std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
         {
             std::stringstream ss;
@@ -92,15 +179,15 @@ output decoder {{
                 printReg(ss, _destRegIdx[0]);
             }
 
-            ss << ",";
+            ss << ", ";
 
             if (_numSrcRegs > 0) {
                 printReg(ss, _srcRegIdx[0]);
-                ss << ",";
+                ss << ", ";
             }
 
             if( mnemonic == "lui")
-                ccprintf(ss, "%08p ", sextImm);
+                ccprintf(ss, "0x%x ", sextImm);
             else
                 ss << (int) sextImm;
 
@@ -109,23 +196,47 @@ output decoder {{
 
 }};
 
-//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, 'IntImmOp', cblk, opt_flags)
-
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = OperateNopCheckDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+    iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = OperateNopCheckDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
+}};
+
+def format IntImmOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = OperateNopCheckDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
 }};
 
+def format HiLoOp(code, *opt_flags) {{
+    if '.sd' in code:
+        code = 'int64_t ' + code
+    elif '.ud' in code:
+        code = 'uint64_t ' + code
+
+    code += 'HI = val<63:32>;\n'
+    code += 'LO = val<31:0>;\n'
+
+    iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = OperateNopCheckDecode.subst(iop)
+    exec_output = HiLoExecute.subst(iop)
+}};
+
+def format HiLoMiscOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = OperateNopCheckDecode.subst(iop)
+    exec_output = HiLoExecute.subst(iop)
+}};
+
+
+
 
 
index d5436b3084ac1373c44b7ee16496744e8f26b3c9..0997230a29ad7a0f38c11e35c0fd97076d39736c 100644 (file)
@@ -90,15 +90,6 @@ output decoder {{
 
 }};
 
-def format LoadAddress(code) {{
-    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
-    header_output = BasicDeclare.subst(iop)
-    decoder_output = BasicConstructor.subst(iop)
-    decode_block = BasicDecode.subst(iop)
-    exec_output = BasicExecute.subst(iop)
-}};
-
-
 def template LoadStoreDeclare {{
     /**
      * Static instruction class for "%(mnemonic)s".
@@ -426,8 +417,70 @@ def template StoreCompleteAcc {{
     }
 }};
 
+
+def template MiscMemAccExecute {{
+    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+                                          Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        EA = xc->getEA();
+
+        if (fault == NoFault) {
+            %(code)s;
+        }
+
+        return NoFault;
+    }
+}};
+
+def template MiscExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+                                  Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = NoFault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (fault == NoFault) {
+            %(memacc_code)s;
+        }
+
+        return NoFault;
+    }
+}};
+
+def template MiscInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        panic("Misc instruction does not support split access method!");
+        return NoFault;
+    }
+}};
+
+
+def template MiscCompleteAcc {{
+    Fault %(class_name)s::completeAcc(uint8_t *data,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        panic("Misc instruction does not support split access method!");
+
+        return NoFault;
+    }
+}};
+
 // load instructions use Rt as dest, so check for
-// Rt == 31 to detect nops
+// Rt == 0 to detect nops
 def template LoadNopCheckDecode {{
  {
      MipsStaticInst *i = new %(class_name)s(machInst);
@@ -446,7 +499,6 @@ def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
                       exec_template_base = 'Load')
 }};
 
-
 def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
                      mem_flags = [], inst_flags = []) {{
     (header_output, decoder_output, decode_block, exec_output) = \
@@ -454,26 +506,70 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
                       exec_template_base = 'Store')
 }};
 
-//FP loads are offloaded to these formats for now ...
-def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                      mem_flags = [], inst_flags = []) {{
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
-                      decode_template = BasicDecode,
+                      decode_template = LoadNopCheckDecode,
                       exec_template_base = 'Load')
 }};
 
+def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
+                     mem_flags = [], inst_flags = []) {{
+    (header_output, decoder_output, decode_block, exec_output) = \
+        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+                      exec_template_base = 'Store')
+}};
+
+def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
+                     mem_flags = [], inst_flags = []) {{
+    decl_code = 'uint32_t mem_word = Mem.uw;\n'
+    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
+    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
+    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
+    decl_code += '\tbyte_offset ^= 3;\n'
+    decl_code += '#endif\n'
+
+    memacc_code = decl_code + memacc_code
+
+    (header_output, decoder_output, decode_block, exec_output) = \
+        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+                      decode_template = LoadNopCheckDecode,
+                      exec_template_base = 'Load')
+}};
 
-def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
                      mem_flags = [], inst_flags = []) {{
+    decl_code = 'uint32_t mem_word = 0;\n'
+    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
+    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
+    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
+    decl_code += '\tbyte_offset ^= 3;\n'
+    decl_code += '#endif\n'
+    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
+    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
+
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+                      decode_template = LoadNopCheckDecode,
                       exec_template_base = 'Store')
 }};
 
+def format Prefetch(ea_code = {{ EA = Rs + disp; }},
+                          mem_flags = [], pf_flags = [], inst_flags = []) {{
+    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
+    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
+                                  'IsDataPrefetch', 'MemReadOp']
+
+    (header_output, decoder_output, decode_block, exec_output) = \
+        LoadStoreBase(name, Name, ea_code,
+                      'xc->prefetch(EA, memAccessFlags);',
+                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
+
+}};
 
-def format UnalignedStore(memacc_code, postacc_code,
-                     ea_code = {{ EA = Rb + disp; }},
+def format StoreCond(memacc_code, postacc_code,
+                     ea_code = {{ EA = Rs + disp; }},
                      mem_flags = [], inst_flags = []) {{
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
new file mode 100644 (file)
index 0000000..2eae8a2
--- /dev/null
@@ -0,0 +1,53 @@
+// -*- mode:c++ -*-
+
+////////////////////////////////////////////////////////////////////
+//
+// MT instructions
+//
+
+output header {{
+        /**
+         * Base class for integer operations.
+         */
+        class MT : public MipsStaticInst
+        {
+                protected:
+
+                /// Constructor
+                MT(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+}};
+
+output decoder {{
+        //Edit This Template When MT is Implemented
+        std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+                return "Disassembly of MT instruction\n";
+        }
+}};
+
+def template MTExecute {{
+        //Edit This Template When MT is Implemented
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                //Write the resulting state to the execution context
+                %(op_wb)s;
+
+                //Call into the trap handler with the appropriate fault
+                return No_Fault;
+        }
+}};
+
+// Primary format for integer operate instructions:
+def format MipsMT() {{
+        code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
+        iop = InstObjParams(name, Name, 'MT', CodeBlock(code))
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = BasicExecute.subst(iop)
+}};
index 2aa4816e3e5f2622498ebc6c369392f3e7628996..a1a80fc563ade51a9ca040580f44ce3cd268b5ba 100644 (file)
@@ -36,11 +36,7 @@ output decoder {{
     std::string Nop::generateDisassembly(Addr pc,
                                          const SymbolTable *symtab) const
     {
-#ifdef SS_COMPATIBLE_DISASSEMBLY
-        return originalDisassembly;
-#else
-        return csprintf("%-10s (%s)", "nop", originalDisassembly);
-#endif
+        return csprintf("%-10s %s", "nop", originalDisassembly);
     }
 
     /// Helper function for decoding nops.  Substitute Nop object
@@ -89,6 +85,6 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{
 }};
 
 def format Nop() {{
-        decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n'
+        decode_block = 'return new Nop(\"\",machInst);\n'
 }};
 
index f5e4076f292ccc2a3fbbded28ae222c4f4288389..dffa31c04e58f0cead0fb8eb6e8028723f914a60 100644 (file)
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
 ////////////////////////////////////////////////////////////////////
 //
 // TlbOp instructions
@@ -30,13 +32,10 @@ output decoder {{
 def template TlbOpExecute {{
         Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
         {
-                //Call into the trap handler with the appropriate fault
-                return No_Fault;
-        }
-
                 //Write the resulting state to the execution context
                 %(op_wb)s;
 
+                //Call into the trap handler with the appropriate fault
                 return No_Fault;
         }
 }};
index 6884d4fa89341156e325765dcc4273a1896182d6..f54efdf69aa68f3ab72ea49d7138d3a003ca1561 100644 (file)
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
 ////////////////////////////////////////////////////////////////////
 //
 // Trap instructions
@@ -23,27 +25,26 @@ output header {{
 output decoder {{
         std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
         {
-                return "Disassembly of integer instruction\n";
+                return "Disassembly of trap instruction\n";
         }
 }};
 
 def template TrapExecute {{
+        //Edit This Template When Traps Are Implemented
         Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
         {
-                //Call into the trap handler with the appropriate fault
-                return No_Fault;
-        }
-
                 //Write the resulting state to the execution context
                 %(op_wb)s;
 
+                //Call into the trap handler with the appropriate fault
                 return No_Fault;
         }
 }};
 
-// Primary format for integer operate instructions:
 def format Trap(code, *flags) {{
-        code = 'bool cond;\n' + code;
+        code = 'panic(\"'
+        code += 'Trap Exception Handler Is Currently Not Implemented.'
+        code += '\");'
         iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
index 8e42da49989c2cbda333c1b49c7d2dd7e2e88e64..cd079a32a5b4e7fd63e17032f17d756c362a5267 100644 (file)
 // 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.
-//
-// Authors: Korey Sewell
-
-////////////////////////////////////////////////////////////////////
-//
-// Unimplemented instructions
-//
 
 output header {{
     /**
@@ -103,11 +96,7 @@ output decoder {{
     WarnUnimplemented::generateDisassembly(Addr pc,
                                            const SymbolTable *symtab) const
     {
-#ifdef SS_COMPATIBLE_DISASSEMBLY
-        return csprintf("%-10s", mnemonic);
-#else
         return csprintf("%-10s (unimplemented)", mnemonic);
-#endif
     }
 }};
 
@@ -127,7 +116,7 @@ output exec {{
                                Trace::InstRecord *traceData) const
     {
         if (!warned) {
-            warn("instruction '%s' unimplemented\n", mnemonic);
+            warn("\tinstruction '%s' unimplemented\n", mnemonic);
             warned = true;
         }
 
@@ -146,28 +135,3 @@ def format WarnUnimpl() {{
     decode_block = BasicDecodeWithMnemonic.subst(iop)
 }};
 
-output header {{
-    /**
-     * Static instruction class for unknown (illegal) instructions.
-     * These cause simulator termination if they are executed in a
-     * non-speculative mode.  This is a leaf class.
-     */
-    class Unknown : public MipsStaticInst
-    {
-      public:
-        /// Constructor
-        Unknown(MachInst _machInst)
-            : MipsStaticInst("unknown", _machInst, No_OpClass)
-        {
-            // don't call execute() (which panics) if we're on a
-            // speculative path
-            flags[IsNonSpeculative] = true;
-        }
-
-        %(BasicExecDeclare)s
-
-        std::string
-        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
-    };
-}};
-
index 7c227559837b0a16f28a9093603304b06b920b06..b4f8346518a7bc4a21a7f073000169c10c6674c2 100644 (file)
 //
 
 output header {{
-        std::string inst2string(MachInst machInst);
-}};
-output decoder {{
-
-std::string inst2string(MachInst machInst)
-{
-    string str = "";
-    uint32_t mask = 0x80000000;
-
-    for(int i=0; i < 32; i++) {
-        if ((machInst & mask) == 0) {
-            str += "0";
-        } else {
-            str += "1";
+    /**
+     * Static instruction class for unknown (illegal) instructions.
+     * These cause simulator termination if they are executed in a
+     * non-speculative mode.  This is a leaf class.
+     */
+    class Unknown : public MipsStaticInst
+    {
+      public:
+        /// Constructor
+        Unknown(MachInst _machInst)
+            : MipsStaticInst("unknown", _machInst, No_OpClass)
+        {
+            // don't call execute() (which panics) if we're on a
+            // speculative path
+            flags[IsNonSpeculative] = true;
         }
 
-        mask = mask >> 1;
-    }
+        %(BasicExecDeclare)s
 
-    return str;
-}
+        std::string
+        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+    };
+}};
 
+output decoder {{
     std::string
     Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
     {
index 615160931cb00f7f184a71a4bd294ffe76cc6a04..63b5f7e5f19b43b2e0ce38664620a1534002a6c9 100644 (file)
@@ -90,7 +90,31 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
             + completeAccTemplate.subst(completeacc_iop))
 }};
 
+output header {{
+        std::string inst2string(MachInst machInst);
+}};
+
+output decoder {{
+
+std::string inst2string(MachInst machInst)
+{
+    string str = "";
+    uint32_t mask = 0x80000000;
+
+    for(int i=0; i < 32; i++) {
+        if ((machInst & mask) == 0) {
+            str += "0";
+        } else {
+            str += "1";
+        }
 
+        mask = mask >> 1;
+    }
+
+    return str;
+}
+
+}};
 output exec {{
 
     using namespace MipsISA;
@@ -124,6 +148,7 @@ output exec {{
 #endif
 
 
+
 }};
 
 
index 9c370fbe308582ac8d53219008a21dc419425ed2..fe21d65cb170e0e75b15a5f682754d1ea833ed1b 100644 (file)
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
 ////////////////////////////////////////////////////////////////////
 //
 // Output include file directives.
@@ -19,6 +21,7 @@ output decoder {{
 #include "cpu/exec_context.hh"  // for Jump::branchTarget()
 #include "arch/mips/faults.hh"
 #include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
 
 #include <math.h>
 #if defined(linux)
@@ -31,6 +34,8 @@ using namespace MipsISA;
 output exec {{
 #include "arch/mips/faults.hh"
 #include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
+
 #include <math.h>
 #if defined(linux)
 #include <fenv.h>
index 0f9c74b48663f8acf5686f39049aa8b2eac976de..a9269a6159394b2c63934bbcef0895a41a44d271 100644 (file)
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
 def operand_types {{
     'sb' : ('signed int', 8),
     'ub' : ('unsigned int', 8),
index 056c8baff6b03b417896045e52f31da3fdd4870c..9f3817a60a5c2b211c33052a9400e0c8971f94b5 100644 (file)
@@ -42,6 +42,7 @@ using namespace std;
 void
 MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
 {
+    panic("Copy Regs Not Implemented Yet\n");
     /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
     uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
     lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
@@ -55,6 +56,7 @@ MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
 void
 MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
 {
+    panic("Copy Misc. Regs Not Implemented Yet\n");
     /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
     uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
     lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
@@ -63,77 +65,6 @@ MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
     #endif*/
 }
 
-uint64_t
-MipsISA::fpConvert(double fp_val, ConvertType cvt_type)
-{
-
-    switch (cvt_type)
-    {
-      case SINGLE_TO_DOUBLE:
-        double sdouble_val = fp_val;
-        void  *sdouble_ptr = &sdouble_val;
-        uint64_t sdp_bits  = *(uint64_t *) sdouble_ptr;
-        return sdp_bits;
-
-      case SINGLE_TO_WORD:
-        int32_t sword_val  = (int32_t) fp_val;
-        void  *sword_ptr   = &sword_val;
-        uint64_t sword_bits= *(uint32_t *) sword_ptr;
-        return sword_bits;
-
-      case WORD_TO_SINGLE:
-        float wfloat_val   = fp_val;
-        void  *wfloat_ptr  = &wfloat_val;
-        uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
-        return wfloat_bits;
-
-      case WORD_TO_DOUBLE:
-        double wdouble_val = fp_val;
-        void  *wdouble_ptr = &wdouble_val;
-        uint64_t wdp_bits  = *(uint64_t *) wdouble_ptr;
-        return wdp_bits;
-
-      default:
-        panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
-        return 0;
-    }
-}
-
-double
-MipsISA::roundFP(double val, int digits)
-{
-    double digit_offset = pow(10.0,digits);
-    val = val * digit_offset;
-    val = val + 0.5;
-    val = floor(val);
-    val = val / digit_offset;
-    return val;
-}
-
-double
-MipsISA::truncFP(double val)
-{
-    int trunc_val = (int) val;
-    return (double) trunc_val;
-}
-
-bool
-MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc)
-{
-    //uint32_t cc_bits = xc->readFloatReg(35);
-    return false;//regFile.floatRegfile.getConditionCode(cc);
-}
-
-uint32_t
-MipsISA::makeCCVector(uint32_t fcsr, int num, bool val)
-{
-    int shift = (num == 0) ? 22 : num + 23;
-
-    fcsr = fcsr | (val << shift);
-
-    return fcsr;
-}
-
 #if FULL_SYSTEM
 
 static inline Addr
index 4a919ac274d64fb92c15265cd76bd68bbc3aea88..17e735527107e53d9b595338b1008d5b1ae60240 100644 (file)
@@ -135,7 +135,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 14 */ SyscallDesc("mknod", unimplementedFunc),
     /* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
     /* 16 */ SyscallDesc("lchown", chownFunc),
-    /* 17 */ SyscallDesc("break", obreakFunc), /*obreak*/
+    /* 17 */ SyscallDesc("break", obreakFunc),
     /* 18 */ SyscallDesc("unused#18", unimplementedFunc),
     /* 19 */ SyscallDesc("lseek", lseekFunc),
     /* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -163,7 +163,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 42 */ SyscallDesc("pipe", unimplementedFunc),
     /* 43 */ SyscallDesc("times", unimplementedFunc),
     /* 44 */ SyscallDesc("prof", unimplementedFunc),
-    /* 45 */ SyscallDesc("brk", obreakFunc),/*openFunc<MipsLinux>*/
+    /* 45 */ SyscallDesc("brk", obreakFunc),
     /* 46 */ SyscallDesc("setgid", unimplementedFunc),
     /* 47 */ SyscallDesc("getgid", getgidFunc),
     /* 48 */ SyscallDesc("signal", ignoreFunc),
@@ -173,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 52 */ SyscallDesc("umount2", unimplementedFunc),
     /* 53 */ SyscallDesc("lock", unimplementedFunc),
     /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
-    /* 55 */ SyscallDesc("fcntl", unimplementedFunc),
+    /* 55 */ SyscallDesc("fcntl", fcntlFunc),
     /* 56 */ SyscallDesc("mpx", unimplementedFunc),
     /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
     /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
@@ -210,8 +210,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 89 */ SyscallDesc("readdir", unimplementedFunc),
     /* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>),
     /* 91 */ SyscallDesc("munmap",munmapFunc),
-    /* 92 */ SyscallDesc("truncate", fcntlFunc),
-    /* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
+    /* 92 */ SyscallDesc("truncate", truncateFunc),
+    /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
     /* 94 */ SyscallDesc("fchmod", unimplementedFunc),
     /* 95 */ SyscallDesc("fchown", unimplementedFunc),
     /* 96 */ SyscallDesc("getpriority", unimplementedFunc),
@@ -262,7 +262,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 141 */ SyscallDesc("getdents", unimplementedFunc),
     /* 142 */ SyscallDesc("newselect", unimplementedFunc),
     /* 143 */ SyscallDesc("flock", unimplementedFunc),
-    /* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<MipsLinux>*/
+    /* 144 */ SyscallDesc("msync", unimplementedFunc),
     /* 145 */ SyscallDesc("readv", unimplementedFunc),
     /* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>),
     /* 147 */ SyscallDesc("cacheflush", unimplementedFunc),
@@ -338,7 +338,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 217 */ SyscallDesc("mincore", unimplementedFunc),
     /* 218 */ SyscallDesc("madvise", unimplementedFunc),
     /* 219 */ SyscallDesc("getdents64", unimplementedFunc),
-    /* 220 */ SyscallDesc("fcntl64", fcntlFunc),
+    /* 220 */ SyscallDesc("fcntl64", fcntl64Func),
     /* 221 */ SyscallDesc("reserved#221", unimplementedFunc),
     /* 222 */ SyscallDesc("gettid", unimplementedFunc),
     /* 223 */ SyscallDesc("readahead", unimplementedFunc),
@@ -414,9 +414,7 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
     : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
                       argv, envp),
      Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
-{
-    //init_regs->intRegFile[0] = 0;
-}
+{ }
 
 SyscallDesc*
 MipsLinuxProcess::getDesc(int callnum)
index 2c2dadc8ba812d56b9c096d3d8830a4b0d15bf01..68da3227be3df744db84e54166620da5277693d8 100644 (file)
@@ -24,8 +24,6 @@
  * 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.
- *
- * Authors: Korey Sewell
  */
 
 #ifndef __MIPS_LINUX_PROCESS_HH__
index bd7aa394e8d63cfdc293b7136b8bc324c5188e95..6f2c88f6976aeb69c455d0b9d115d83c192e0b25 100644 (file)
@@ -27,6 +27,7 @@
  *
  * Authors: Gabe Black
  *          Ali Saidi
+ *          Korey Sewell
  */
 
 #include "arch/mips/isa_traits.hh"
@@ -56,7 +57,8 @@ MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
 
 
     if (objFile->getArch() != ObjectFile::Mips)
-        fatal("Object file does not match architecture.");
+        fatal("Object file does not match MIPS architecture.");
+
     switch (objFile->getOpSys()) {
       case ObjectFile::Linux:
         process = new MipsLinuxProcess(nm, objFile, system,
@@ -79,22 +81,19 @@ MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
     : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
         argv, envp)
 {
+    // Set up stack. On MIPS, stack starts at the top of kuseg
+    // user address space. MIPS stack grows down from here
+    stack_base = 0x7FFFFFFF;
 
-    // XXX all the below need to be updated for SPARC - Ali
+    // Set pointer for next thread stack.  Reserve 8M for main stack.
+    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+    // Set up break point (Top of Heap)
     brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
     brk_point = roundUp(brk_point, VMPageSize);
 
-    // Set up stack.  On Alpha, stack goes below text section.  This
-    // code should get moved to some architecture-specific spot.
-    stack_base = objFile->textBase() - (409600+4096);
-
-    // Set up region for mmaps.  Tru64 seems to start just above 0 and
-    // grow up from there.
+    // Set up region for mmaps. For now, start at bottom of kuseg space.
     mmap_start = mmap_end = 0x10000;
-
-    // Set pointer for next thread stack.  Reserve 8M for main stack.
-    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
-
 }
 
 void
index 45513af46fa3c7b791288713d8943e21237192fb..dae8911253ed1e1801b630360de10fc48e9561ad 100644 (file)
@@ -27,6 +27,7 @@
  *
  * Authors: Gabe Black
  *          Ali Saidi
+ *          Korey Sewell
  */
 
 #ifndef __MIPS_PROCESS_HH__
index 013aa01c7570688046202248368ffba05557d063..d1a60298adc3fd9fcc1b3c66753d951fa9e72781 100644 (file)
@@ -62,13 +62,17 @@ namespace MipsISA
             switch(width)
             {
               case SingleWidth:
-                void *float_ptr = &regs[floatReg];
-                return *(float *) float_ptr;
+                {
+                    void *float_ptr = &regs[floatReg];
+                    return *(float *) float_ptr;
+                }
 
               case DoubleWidth:
-                uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
-                void *double_ptr = &double_val;
-                return *(double *) double_ptr;
+                {
+                    uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
+                    void *double_ptr = &double_val;
+                    return *(double *) double_ptr;
+                }
 
               default:
                 panic("Attempted to read a %d bit floating point register!", width);
@@ -99,21 +103,24 @@ namespace MipsISA
 
         Fault setReg(int floatReg, const FloatReg &val, int width)
         {
-
             switch(width)
             {
               case SingleWidth:
-                float temp = val;
-                void *float_ptr = &temp;
-                regs[floatReg] = *(FloatReg32 *) float_ptr;
-                break;
+                {
+                    float temp = val;
+                    void *float_ptr = &temp;
+                    regs[floatReg] = *(FloatReg32 *) float_ptr;
+                    break;
+                }
 
               case DoubleWidth:
-                const void *double_ptr = &val;
-                FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
-                regs[floatReg + 1] = temp_double >> 32;
-                regs[floatReg] = temp_double;
-                break;
+                {
+                    const void *double_ptr = &val;
+                    FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
+                    regs[floatReg + 1] = temp_double >> 32;
+                    regs[floatReg] = 0x0000FFFF & temp_double;
+                    break;
+                }
 
               default:
                 panic("Attempted to read a %d bit floating point register!", width);
@@ -148,14 +155,6 @@ namespace MipsISA
         void unserialize(Checkpoint *cp, const std::string &section);
     };
 
-    enum MiscFloatRegNums {
-       FIR = NumFloatArchRegs,
-       FCCR,
-       FEXR,
-       FENR,
-       FCSR
-    };
-
 } // namespace MipsISA
 
 #endif
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
new file mode 100644 (file)
index 0000000..b68619f
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2003-2006 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.
+ */
+
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
+#include "config/full_system.hh"
+#include "cpu/static_inst.hh"
+#include "sim/serialize.hh"
+#include "base/bitfield.hh"
+
+using namespace MipsISA;
+using namespace std;
+
+uint64_t
+MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
+{
+
+    switch (cvt_type)
+    {
+      case SINGLE_TO_DOUBLE:
+        {
+            double sdouble_val = fp_val;
+            void  *sdouble_ptr = &sdouble_val;
+            uint64_t sdp_bits  = *(uint64_t *) sdouble_ptr;
+            return sdp_bits;
+        }
+
+      case SINGLE_TO_WORD:
+        {
+            int32_t sword_val  = (int32_t) fp_val;
+            void  *sword_ptr   = &sword_val;
+            uint64_t sword_bits= *(uint32_t *) sword_ptr;
+            return sword_bits;
+        }
+
+      case WORD_TO_SINGLE:
+        {
+            float wfloat_val   = fp_val;
+            void  *wfloat_ptr  = &wfloat_val;
+            uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
+            return wfloat_bits;
+        }
+
+      case WORD_TO_DOUBLE:
+        {
+            double wdouble_val = fp_val;
+            void  *wdouble_ptr = &wdouble_val;
+            uint64_t wdp_bits  = *(uint64_t *) wdouble_ptr;
+            return wdp_bits;
+        }
+
+      default:
+        panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
+        return 0;
+    }
+}
+
+double
+MipsISA::roundFP(double val, int digits)
+{
+    double digit_offset = pow(10.0,digits);
+    val = val * digit_offset;
+    val = val + 0.5;
+    val = floor(val);
+    val = val / digit_offset;
+    return val;
+}
+
+double
+MipsISA::truncFP(double val)
+{
+    int trunc_val = (int) val;
+    return (double) trunc_val;
+}
+
+bool
+MipsISA::getCondCode(uint32_t fcsr, int cc_idx)
+{
+    int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
+    bool cc_val = (fcsr >> shift) & 0x00000001;
+    return cc_val;
+}
+
+uint32_t
+MipsISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
+{
+    int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
+
+    fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 |
+           cc_val << cc_idx |
+           bits(fcsr, cc_idx - 1, 0);
+
+    return fcsr;
+}
+
+uint32_t
+MipsISA::genInvalidVector(uint32_t fcsr_bits)
+{
+    //Set FCSR invalid in "flag" field
+    int invalid_offset = Invalid + Flag_Field;
+    fcsr_bits = fcsr_bits | (1 << invalid_offset);
+
+    //Set FCSR invalid in "cause" flag
+    int cause_offset = Invalid + Cause_Field;
+    fcsr_bits = fcsr_bits | (1 << cause_offset);
+
+    return fcsr_bits;
+}
+
+bool
+MipsISA::isNan(void *val_ptr, int size)
+{
+    switch (size)
+    {
+      case 32:
+        {
+            uint32_t val_bits = *(uint32_t *) val_ptr;
+            return (bits(val_bits, 30, 23) == 0xFF);
+        }
+
+      case 64:
+        {
+            uint64_t val_bits = *(uint64_t *) val_ptr;
+            return (bits(val_bits, 62, 52) == 0x7FF);
+        }
+
+      default:
+        panic("Type unsupported. Size mismatch\n");
+    }
+}
+
+
+bool
+MipsISA::isQnan(void *val_ptr, int size)
+{
+    switch (size)
+    {
+      case 32:
+        {
+            uint32_t val_bits = *(uint32_t *) val_ptr;
+            return (bits(val_bits, 30, 22) == 0x1FE);
+        }
+
+      case 64:
+        {
+            uint64_t val_bits = *(uint64_t *) val_ptr;
+            return (bits(val_bits, 62, 51) == 0xFFE);
+        }
+
+      default:
+        panic("Type unsupported. Size mismatch\n");
+    }
+}
+
+bool
+MipsISA::isSnan(void *val_ptr, int size)
+{
+    switch (size)
+    {
+      case 32:
+        {
+            uint32_t val_bits = *(uint32_t *) val_ptr;
+            return (bits(val_bits, 30, 22) == 0x1FF);
+        }
+
+      case 64:
+        {
+            uint64_t val_bits = *(uint64_t *) val_ptr;
+            return (bits(val_bits, 62, 51) == 0xFFF);
+        }
+
+      default:
+        panic("Type unsupported. Size mismatch\n");
+    }
+}
index 5c7dc3ea4d83d9b07da3d1ee991db7de03dc67ac..c5c69ddcd802994c7ff7a72ca24c3de719f8eff0 100644 (file)
 
 namespace MipsISA {
 
+    //Floating Point Utility Functions
+    uint64_t fpConvert(ConvertType cvt_type, double fp_val);
+    double roundFP(double val, int digits);
+    double truncFP(double val);
+
+    bool getCondCode(uint32_t fcsr, int cc);
+    uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val);
+    uint32_t genInvalidVector(uint32_t fcsr);
+
+    bool isNan(void *val_ptr, int size);
+    bool isQnan(void *val_ptr, int size);
+    bool isSnan(void *val_ptr, int size);
 };
 
+
 #endif