diff options
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r-- | src/arch/sparc/isa/base.isa | 24 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 89 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/basic.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 6 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 6 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/util.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 5 |
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" |