fix smul and sdiv to sign extend, and handle overflow/underflow corretly
authorAli Saidi <saidi@eecs.umich.edu>
Thu, 25 Jan 2007 18:43:46 +0000 (13:43 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Thu, 25 Jan 2007 18:43:46 +0000 (13:43 -0500)
Only allow writing/reading of 32 bits of Y
Only allow writing/reading 32 bits of pc when pstate.am
Put any loaded data on the first half of a micro-op in uReg0 so it can't
overwrite the register we are using for address calculation
only erase a entry from the lookup table if it's valid
Put in a temporary check to make sure that lookup table and tlb array stay in sync
if we are interrupted in the middle of a mico-op, reset the micropc/nexpc
so we start  on the first part of it when we come back

src/arch/sparc/isa/decoder.isa:
    fix smul and sdiv to sign extend, and handle overflow/underflow corretly
    Only allow writing/reading of 32 bits of Y
    Only allow writing/reading 32 bits of pc when pstate.am
    Put any loaded data on the first half of a micro-op in uReg0 so it can't
    overwrite the register we are using for address calculation
src/arch/sparc/isa/formats/mem/blockmem.isa:
    Put any loaded data on the first half of a micro-op in uReg0 so it can't
    overwrite the register we are using for address calculation
src/arch/sparc/isa/includes.isa:
    Use limits for 32bit underflow/overflow detection
src/arch/sparc/tlb.cc:
    only erase a entry from the lookup table if it's valid
    Put in a temporary check to make sure that lookup table and tlb array stay in sync
src/arch/sparc/tlb_map.hh:
    add a print function to dump the tlb lookup table
src/cpu/simple/base.cc:
    if we are interrupted in the middle of a mico-op, reset the micropc/nexpc
    so we start  on the first part of it when we come back

--HG--
extra : convert_revision : 50a23837fd888393a5c2aa35cbd1abeebb7f55d4

src/arch/sparc/isa/decoder.isa
src/arch/sparc/isa/formats/mem/blockmem.isa
src/arch/sparc/isa/includes.isa
src/arch/sparc/tlb.cc
src/arch/sparc/tlb_map.hh
src/cpu/simple/base.cc

index 5489539823666cf230b2b0d0278277b5b2c20b45..425ebc9d0607b167ef4d0c9fbc4357a1d25a2262 100644 (file)
@@ -186,7 +186,7 @@ decode OP default Unknown::unknown()
                 Y = Rd<63:32>;
             }});
             0x0B: smul({{
-                Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>;
+                Rd.sdw = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13);
                 Y = Rd.sdw<63:32>;
             }});
             0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
@@ -209,10 +209,10 @@ decode OP default Unknown::unknown()
                 else
                 {
                     Rd.udw = ((int64_t)((Y << 32) | Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw;
-                    if(Rd.udw<63:31> != 0)
+                    if((int64_t)Rd.udw >= std::numeric_limits<int32_t>::max())
                         Rd.udw = 0x7FFFFFFF;
-                    else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF)
-                        Rd.udw = 0xFFFFFFFF80000000ULL;
+                    else if((int64_t)Rd.udw <= std::numeric_limits<int32_t>::min())
+                        Rd.udw = ULL(0xFFFFFFFF80000000);
                 }
             }});
         }
@@ -257,7 +257,7 @@ decode OP default Unknown::unknown()
                 {{0}},{{0}},{{0}},{{0}});
             0x1B: smulcc({{
                 int64_t resTemp;
-                Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>;
+                Rd = resTemp = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13);
                 Y = resTemp<63:32>;}},
                 {{0}},{{0}},{{0}},{{0}});
             0x1C: subccc({{
@@ -296,10 +296,10 @@ decode OP default Unknown::unknown()
                 else
                 {
                     Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2;
-                    overflow = (Rd<63:31> != 0);
-                    underflow = (Rd<63:> && Rd<62:31> != 0xFFFFFFFF);
+                    overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max());
+                    underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min());
                     if(overflow) Rd = 0x7FFFFFFF;
-                    else if(underflow) Rd = 0xFFFFFFFF80000000ULL;
+                    else if(underflow) Rd = ULL(0xFFFFFFFF80000000);
                 } }},
                 {{0}},
                 {{overflow || underflow}},
@@ -376,7 +376,7 @@ decode OP default Unknown::unknown()
                 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
             }
             0x28: decode RS1 {
-                0x00: NoPriv::rdy({{Rd = Y;}});
+                0x00: NoPriv::rdy({{Rd = Y<31:0>;}});
                 //1 should cause an illegal instruction exception
                 0x02: NoPriv::rdccr({{Rd = Ccr;}});
                 0x03: NoPriv::rdasi({{Rd = Asi;}});
@@ -526,7 +526,7 @@ decode OP default Unknown::unknown()
                 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}});
             }
             0x30: decode RD {
-                0x00: NoPriv::wry({{Y = Rs1 ^ Rs2_or_imm13;}});
+                0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}});
                 //0x01 should cause an illegal instruction exception
                 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
                 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}});
@@ -882,7 +882,7 @@ decode OP default Unknown::unknown()
                 else
                 {
                     if (Pstate<3:>)
-                        (Rd = xc->readPC())<31:0>;
+                        Rd = (xc->readPC())<31:0>;
                     else
                         Rd = xc->readPC();
                     NNPC = target;
@@ -1058,13 +1058,14 @@ decode OP default Unknown::unknown()
             0x0B: ldx({{Rd = (int64_t)Mem.sdw;}});
         }
         0x0D: LoadStore::ldstub(
-        {{Rd = Mem.ub;}},
-        {{Mem.ub = 0xFF;}});
+        {{uReg0 = Mem.ub;}},
+        {{Rd.ub = uReg0;
+          Mem.ub = 0xFF;}});
         0x0E: Store::stx({{Mem.udw = Rd}});
         0x0F: LoadStore::swap(
-            {{uReg0 = Rd.uw;
-            Rd.uw = Mem.uw;}},
-            {{Mem.uw = uReg0;}});
+            {{ uReg0 = Mem.uw}},
+            {{ Mem.uw = Rd.uw;
+               Rd.uw = uReg0;}});
         format LoadAlt {
             0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}});
             0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}});
@@ -1072,34 +1073,34 @@ decode OP default Unknown::unknown()
             0x13: decode EXT_ASI {
                 //ASI_LDTD_AIUP
                 0x22: TwinLoad::ldtx_aiup(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_LDTD_AIUS
                 0x23: TwinLoad::ldtx_aius(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_QUAD_LDD
                 0x24: TwinLoad::ldtx_quad_ldd(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_LDTX_REAL
                 0x26: TwinLoad::ldtx_real(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                //ASI_LDTX_N
                0x27: TwinLoad::ldtx_n(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                //ASI_LDTX_L
                0x2C: TwinLoad::ldtx_l(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_LDTX_REAL_L
                 0x2E: TwinLoad::ldtx_real_l(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_LDTX_N_L
                 0x2F: TwinLoad::ldtx_n_l(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_LDTX_P
                 0xE2: TwinLoad::ldtx_p(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 //ASI_LDTX_S
                 0xE3: TwinLoad::ldtx_s(
-                    {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
+                    {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}});
                 default: ldtwa({{
                         uint64_t val = Mem.udw;
                         RdLow = val<31:0>;
@@ -1120,13 +1121,14 @@ decode OP default Unknown::unknown()
             0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}});
         }
         0x1D: LoadStoreAlt::ldstuba(
-                {{Rd = Mem.ub;}},
-                {{Mem.ub = 0xFF}}, {{EXT_ASI}});
+                {{uReg0 = Mem.ub;}},
+                {{Rd.ub = uReg0;
+                  Mem.ub = 0xFF;}}, {{EXT_ASI}});
         0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}});
         0x1F: LoadStoreAlt::swapa(
-            {{uReg0 = Rd.uw;
-            Rd.uw = Mem.uw;}},
-            {{Mem.uw = uReg0;}}, {{EXT_ASI}});
+            {{ uReg0 = Mem.uw}},
+            {{ Mem.uw = Rd.uw;
+               Rd.uw = uReg0;}}, {{EXT_ASI}});
         format Trap {
             0x20: Load::ldf({{Frd.uw = Mem.uw;}});
             0x21: decode X {
index 32421a75f29b2366299205d66355b6bbb0a4c8cc..c36fede2e6dbfa68c89bd18911cfb1cde61353ad 100644 (file)
@@ -476,7 +476,6 @@ let {{
             faultCode = ''
         return (header_output, decoder_output, exec_output, decode_block)
 
-
     def doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags):
         addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
         addrCalcImm = 'EA = Rs1 + imm + offset;'
@@ -492,10 +491,11 @@ let {{
             pcedCode = ''
             if (microPc == 1):
                 flag_code = "flags[IsLastMicroOp] = true;"
-                pcedCode = matcher.sub("RdHigh", code)
+                pcedCode = "RdLow = uReg0;\n"
+                pcedCode += matcher.sub("RdHigh", code)
             else:
                 flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;"
-                pcedCode = matcher.sub("RdLow", code)
+                pcedCode = matcher.sub("uReg0", code)
             iop = InstObjParams(name, Name, 'TwinMem', pcedCode,
                     opt_flags, {"ea_code": addrCalcReg,
                     "fault_check": faultCode, "micro_pc": microPc,
index 624afb693e8e230fbffd536d01afcb01885b71b3..0c112d481a3a6528dde3068bceb43372701304b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,7 @@ output exec {{
 #if defined(linux)
 #include <fenv.h>
 #endif
+#include <limits>
 
 #include "arch/sparc/asi.hh"
 #include "cpu/base.hh"
index 0e59f3e15856bfcf3b34caf9bc1e3b4759c9ed39..bf57c894fa5780297cea8b4f46b9cd18dbe5b936 100644 (file)
@@ -170,8 +170,8 @@ insertAllLocked:
     freeList.remove(new_entry);
     if (new_entry->valid && new_entry->used)
         usedEntries--;
-
-    lookupTable.erase(new_entry->range);
+    if (new_entry->valid)
+        lookupTable.erase(new_entry->range);
 
 
     DPRINTF(TLB, "Using entry: %#X\n", new_entry);
@@ -582,6 +582,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
     DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
             vaddr, size, asi);
 
+    if (lookupTable.size() != 64 - freeList.size())
+       panic("Lookup table size: %d tlb size: %d\n", lookupTable.size(),
+               freeList.size());
     if (asi == ASI_IMPLICIT)
         implicit = true;
 
index 688daf5b91bb035013e28ab991a7a6388459700b..8285db939457e033fb3e1ad39a8a453bbdced795 100644 (file)
@@ -135,6 +135,19 @@ class TlbMap
     {
         return tree.empty();
     }
+
+    void print()
+    {
+        iterator i;
+        i = tree.begin();
+        while (i != tree.end()) {
+           std::cout << std::hex << i->first.va << " " << i->first.size << " " <<
+                i->first.contextId << " " << i->first.partitionId << " " <<
+                i->first.real << " " << i->second << std::endl;
+            i++;
+        }
+    }
+
 };
 
 };
index ddccc5a9b8670e506a778f98656866231a20f1d5..14fefe103fa50e72e437a84f16b779dd0d23f86c 100644 (file)
@@ -439,6 +439,8 @@ BaseSimpleCPU::advancePC(Fault fault)
     if (fault != NoFault) {
         curMacroStaticInst = StaticInst::nullStaticInstPtr;
         fault->invoke(tc);
+        thread->setMicroPC(0);
+        thread->setNextMicroPC(1);
     } else {
         //If we're at the last micro op for this instruction
         if (curStaticInst->isLastMicroOp()) {