summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r--src/arch/sparc/isa/base.isa24
-rw-r--r--src/arch/sparc/isa/decoder.isa89
-rw-r--r--src/arch/sparc/isa/formats/basic.isa4
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa6
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa6
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa4
-rw-r--r--src/arch/sparc/isa/includes.isa5
7 files changed, 86 insertions, 52 deletions
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index b78511398..58a17f23e 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -416,3 +416,27 @@ output decoder {{
}
}};
+output exec {{
+ /// Check "FP enabled" machine status bit. Called when executing any FP
+ /// instruction in full-system mode.
+ /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
+ /// if not. Non-full-system mode: always returns NoFault.
+#if FULL_SYSTEM
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+ {
+ Fault fault = NoFault; // dummy... this ipr access should not fault
+ if (xc->readMiscRegWithEffect(MISCREG_PSTATE) & PSTATE::pef &&
+ xc->readMiscRegWithEffect(MISCREG_FPRS) & 0x4)
+ return NoFault;
+ else
+ return new FpDisabled;
+ }
+#else
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+ {
+ return NoFault;
+ }
+#endif
+}};
+
+
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 138485a17..cc6eded1d 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -192,7 +192,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<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
Y = Rd.sdw<63:32>;
}});
0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
@@ -215,10 +215,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);
}
}});
}
@@ -252,8 +252,7 @@ decode OP default Unknown::unknown()
Rd = resTemp = Rs1 + val2 + carryin;}},
{{(Rs1<31:0> + val2<31:0> + carryin)<32:>}},
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{(Rs1<63:1> + val2<63:1> +
- ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}},
+ {{((Rs1 & val2) | (~resTemp & (Rs1 | val2)))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
0x1A: IntOpCcRes::umulcc({{
@@ -262,15 +261,15 @@ decode OP default Unknown::unknown()
Y = resTemp<63:32>;}});
0x1B: IntOpCcRes::smulcc({{
int64_t resTemp;
- Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>;
+ Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
Y = resTemp<63:32>;}});
0x1C: subccc({{
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = Ccr<0:0>;
Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
- {{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
+ {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<31:>}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
+ {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<63:>}},
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
);
0x1D: IntOpCcRes::udivxcc({{
@@ -299,10 +298,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}},
@@ -379,7 +378,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;}});
@@ -529,7 +528,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;}});
@@ -667,7 +666,7 @@ decode OP default Unknown::unknown()
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
}});
- 0x03: Trap::fmovq({{fault = new FpDisabled;}});
+ 0x03: Trap::fmovq({{fault = new FpExceptionOther;}});
0x05: fnegs({{
Frds.uw = Frs2s.uw ^ (1UL << 31);
//fsr.ftt = fsr.cexc = 0
@@ -694,8 +693,8 @@ decode OP default Unknown::unknown()
Fsr &= ~(0x1F);
}});
0x0B: Trap::fabsq({{fault = new FpDisabled;}});
- 0x29: fsqrts({{Frds.sf = sqrt(Frs2s.sf);}});
- 0x2A: fsqrtd({{Frd.df = sqrt(Frs2.df);}});
+ 0x29: fsqrts({{Frds.sf = std::sqrt(Frs2s.sf);}});
+ 0x2A: fsqrtd({{Frd.df = std::sqrt(Frs2.df);}});
0x2B: Trap::fsqrtq({{fault = new FpDisabled;}});
0x41: fadds({{Frds.sf = Frs1s.sf + Frs2s.sf;}});
0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
@@ -863,11 +862,11 @@ decode OP default Unknown::unknown()
0x72: Trap::fxnor({{fault = new IllegalInstruction;}});
0x73: Trap::fxnors({{fault = new IllegalInstruction;}});
0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}});
- 0x75: BasicOperate::fsrc1s({{Frd.uw = Frs1.uw;}});
+ 0x75: BasicOperate::fsrc1s({{Frds.uw = Frs1s.uw;}});
0x76: Trap::fornot2({{fault = new IllegalInstruction;}});
0x77: Trap::fornot2s({{fault = new IllegalInstruction;}});
0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}});
- 0x79: BasicOperate::fsrc2s({{Frd.uw = Frs2.uw;}});
+ 0x79: BasicOperate::fsrc2s({{Frds.uw = Frs2s.uw;}});
0x7A: Trap::fornot1({{fault = new IllegalInstruction;}});
0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}});
0x7C: Trap::for({{fault = new IllegalInstruction;}});
@@ -885,7 +884,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;
@@ -1037,13 +1036,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}});
@@ -1051,34 +1051,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>;
@@ -1099,22 +1099,23 @@ 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;}});
+ 0x20: Load::ldf({{Frds.uw = Mem.uw;}});
0x21: decode X {
0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}});
0x1: Load::ldxfsr({{Fsr = Mem.udw;}});
}
0x22: ldqf({{fault = new FpDisabled;}});
0x23: Load::lddf({{Frd.udw = Mem.udw;}});
- 0x24: Store::stf({{Mem.uw = Frd.uw;}});
+ 0x24: Store::stf({{Mem.uw = Frds.uw;}});
0x25: decode X {
0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}});
0x1: Store::stxfsr({{Mem.udw = Fsr;}});
@@ -1122,7 +1123,7 @@ decode OP default Unknown::unknown()
0x26: stqf({{fault = new FpDisabled;}});
0x27: Store::stdf({{Mem.udw = Frd.udw;}});
0x2D: Nop::prefetch({{ }});
- 0x30: LoadAlt::ldfa({{Frd.uw = Mem.uw;}}, {{EXT_ASI}});
+ 0x30: LoadAlt::ldfa({{Frds.uw = Mem.uw;}}, {{EXT_ASI}});
0x32: ldqfa({{fault = new FpDisabled;}});
format LoadAlt {
0x33: decode EXT_ASI {
@@ -1205,7 +1206,7 @@ decode OP default Unknown::unknown()
{{fault = new DataAccessException;}});
}
}
- 0x34: Store::stfa({{Mem.uw = Frd.uw;}});
+ 0x34: Store::stfa({{Mem.uw = Frds.uw;}});
0x36: stqfa({{fault = new FpDisabled;}});
format StoreAlt {
0x37: decode EXT_ASI {
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 56e933763..e8762a205 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -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
@@ -38,6 +38,7 @@ def template BasicExecPanic {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Execute method called when it shouldn't!");
+ M5_DUMMY_RETURN
}
}};
@@ -71,6 +72,7 @@ def template BasicExecute {{
{
Fault fault = NoFault;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 363aca1a1..f877b8790 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -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
@@ -154,7 +154,7 @@ output decoder {{
bool IntOp::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
- if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
+ if(!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
{
printMnemonic(os, "mov");
printSrcReg(os, 1);
@@ -168,7 +168,7 @@ output decoder {{
bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
- if(!strcmp(mnemonic, "or"))
+ if(!std::strcmp(mnemonic, "or"))
{
if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
{
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
index 352e963b3..9795d2342 100644
--- a/src/arch/sparc/isa/formats/mem/blockmem.isa
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -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',
{"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
index 5bb4e1fe6..dbaabdca4 100644
--- a/src/arch/sparc/isa/formats/mem/util.isa
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -141,6 +141,7 @@ def template LoadExecute {{
{
Fault fault = NoFault;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
@@ -170,6 +171,7 @@ def template LoadInitiateAcc {{
{
Fault fault = NoFault;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
@@ -210,6 +212,7 @@ def template StoreExecute {{
//It should be optomized out in all the others
bool storeCond = true;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
@@ -241,6 +244,7 @@ def template StoreInitiateAcc {{
Fault fault = NoFault;
bool storeCond = true;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 2e7b16f20..474af3ad9 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -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
@@ -34,6 +34,7 @@
//
output header {{
+#include <cstring>
#include <sstream>
#include <iostream>
@@ -64,7 +65,9 @@ output exec {{
#if defined(linux)
#include <fenv.h>
#endif
+#include <limits>
+#include <cmath>
#include "arch/sparc/asi.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"