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 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
This commit is contained in:
parent
4301e4cd08
commit
8561c8366c
6 changed files with 58 additions and 37 deletions
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Reference in a new issue