diff options
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r-- | src/arch/sparc/isa/base.isa | 253 | ||||
-rw-r--r-- | src/arch/sparc/isa/bitfields.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 425 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/basic.isa | 7 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/branch.isa | 18 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 15 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/basicmem.isa | 24 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 30 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/util.isa | 57 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/nop.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/priv.isa | 8 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/trap.isa | 49 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 10 | ||||
-rw-r--r-- | src/arch/sparc/isa/operands.isa | 53 |
14 files changed, 676 insertions, 281 deletions
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa index 4a806bfd0..693cc6876 100644 --- a/src/arch/sparc/isa/base.isa +++ b/src/arch/sparc/isa/base.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 @@ -67,6 +67,26 @@ output header {{ OverflowSet=0x7 }; + enum FpCondTest + { + FAlways=0x8, + FNever=0x0, + FUnordered=0x7, + FGreater=0x6, + FUnorderedOrGreater=0x5, + FLess=0x4, + FUnorderedOrLess=0x3, + FLessOrGreater=0x2, + FNotEqual=0x1, + FEqual=0x9, + FUnorderedOrEqual=0xA, + FGreaterOrEqual=0xB, + FUnorderedOrGreaterOrEqual=0xC, + FLessOrEqual=0xD, + FUnorderedOrLessOrEqual=0xE, + FOrdered=0xF + }; + extern char * CondTestAbbrev[]; /** @@ -93,6 +113,8 @@ output header {{ const RegIndex indexArray[], int num) const; }; + bool passesFpCondition(uint32_t fcc, uint32_t condition); + bool passesCondition(uint32_t codes, uint32_t condition); inline int64_t sign_ext(uint64_t data, int origWidth) @@ -189,23 +211,149 @@ output decoder {{ const int MaxOutput = 16; const int MaxLocal = 24; const int MaxInput = 32; - const int MaxMicroReg = 33; - if (reg == FramePointerReg) - ccprintf(os, "%%fp"); - else if (reg == StackPointerReg) - ccprintf(os, "%%sp"); - else if(reg < MaxGlobal) - ccprintf(os, "%%g%d", reg); - else if(reg < MaxOutput) - ccprintf(os, "%%o%d", reg - MaxGlobal); - else if(reg < MaxLocal) - ccprintf(os, "%%l%d", reg - MaxOutput); - else if(reg < MaxInput) - ccprintf(os, "%%i%d", reg - MaxLocal); - else if(reg < MaxMicroReg) - ccprintf(os, "%%u%d", reg - MaxInput); - else { - ccprintf(os, "%%f%d", reg - MaxMicroReg); + const int MaxMicroReg = 40; + if (reg < FP_Base_DepTag) { + //If we used a register from the next or previous window, + //take out the offset. + while (reg >= MaxMicroReg) + reg -= MaxMicroReg; + if (reg == FramePointerReg) + ccprintf(os, "%%fp"); + else if (reg == StackPointerReg) + ccprintf(os, "%%sp"); + else if(reg < MaxGlobal) + ccprintf(os, "%%g%d", reg); + else if(reg < MaxOutput) + ccprintf(os, "%%o%d", reg - MaxGlobal); + else if(reg < MaxLocal) + ccprintf(os, "%%l%d", reg - MaxOutput); + else if(reg < MaxInput) + ccprintf(os, "%%i%d", reg - MaxLocal); + else if(reg < MaxMicroReg) + ccprintf(os, "%%u%d", reg - MaxInput); + //The fake int regs that are really control regs + else { + switch (reg - MaxMicroReg) { + case 1: + ccprintf(os, "%%y"); + break; + case 2: + ccprintf(os, "%%ccr"); + break; + case 3: + ccprintf(os, "%%cansave"); + break; + case 4: + ccprintf(os, "%%canrestore"); + break; + case 5: + ccprintf(os, "%%cleanwin"); + break; + case 6: + ccprintf(os, "%%otherwin"); + break; + case 7: + ccprintf(os, "%%wstate"); + break; + } + } + } else if (reg < Ctrl_Base_DepTag) { + ccprintf(os, "%%f%d", reg - FP_Base_DepTag); + } else { + switch (reg - Ctrl_Base_DepTag) { + case MISCREG_ASI: + ccprintf(os, "%%asi"); + break; + case MISCREG_FPRS: + ccprintf(os, "%%fprs"); + break; + case MISCREG_PCR: + ccprintf(os, "%%pcr"); + break; + case MISCREG_PIC: + ccprintf(os, "%%pic"); + break; + case MISCREG_GSR: + ccprintf(os, "%%gsr"); + break; + case MISCREG_SOFTINT: + ccprintf(os, "%%softint"); + break; + case MISCREG_SOFTINT_SET: + ccprintf(os, "%%softint_set"); + break; + case MISCREG_SOFTINT_CLR: + ccprintf(os, "%%softint_clr"); + break; + case MISCREG_TICK_CMPR: + ccprintf(os, "%%tick_cmpr"); + break; + case MISCREG_STICK: + ccprintf(os, "%%stick"); + break; + case MISCREG_STICK_CMPR: + ccprintf(os, "%%stick_cmpr"); + break; + case MISCREG_TPC: + ccprintf(os, "%%tpc"); + break; + case MISCREG_TNPC: + ccprintf(os, "%%tnpc"); + break; + case MISCREG_TSTATE: + ccprintf(os, "%%tstate"); + break; + case MISCREG_TT: + ccprintf(os, "%%tt"); + break; + case MISCREG_TICK: + ccprintf(os, "%%tick"); + break; + case MISCREG_TBA: + ccprintf(os, "%%tba"); + break; + case MISCREG_PSTATE: + ccprintf(os, "%%pstate"); + break; + case MISCREG_TL: + ccprintf(os, "%%tl"); + break; + case MISCREG_PIL: + ccprintf(os, "%%pil"); + break; + case MISCREG_CWP: + ccprintf(os, "%%cwp"); + break; + case MISCREG_GL: + ccprintf(os, "%%gl"); + break; + case MISCREG_HPSTATE: + ccprintf(os, "%%hpstate"); + break; + case MISCREG_HTSTATE: + ccprintf(os, "%%htstate"); + break; + case MISCREG_HINTP: + ccprintf(os, "%%hintp"); + break; + case MISCREG_HTBA: + ccprintf(os, "%%htba"); + break; + case MISCREG_HSTICK_CMPR: + ccprintf(os, "%%hstick_cmpr"); + break; + case MISCREG_HVER: + ccprintf(os, "%%hver"); + break; + case MISCREG_STRAND_STS_REG: + ccprintf(os, "%%strand_sts_reg"); + break; + case MISCREG_FSR: + ccprintf(os, "%%fsr"); + break; + default: + ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag); + } } } @@ -241,6 +389,51 @@ output decoder {{ return ss.str(); } + bool passesFpCondition(uint32_t fcc, uint32_t condition) + { + bool u = (fcc == 3); + bool g = (fcc == 2); + bool l = (fcc == 1); + bool e = (fcc == 0); + switch(condition) + { + case FAlways: + return 1; + case FNever: + return 0; + case FUnordered: + return u; + case FGreater: + return g; + case FUnorderedOrGreater: + return u || g; + case FLess: + return l; + case FUnorderedOrLess: + return u || l; + case FLessOrGreater: + return l || g; + case FNotEqual: + return l || g || u; + case FEqual: + return e; + case FUnorderedOrEqual: + return u || e; + case FGreaterOrEqual: + return g || e; + case FUnorderedOrGreaterOrEqual: + return u || g || e; + case FLessOrEqual: + return l || e; + case FUnorderedOrLessOrEqual: + return u || l || e; + case FOrdered: + return e || l || g; + } + panic("Tried testing condition nonexistant " + "condition code %d", condition); + } + bool passesCondition(uint32_t codes, uint32_t condition) { CondCodes condCodes; @@ -290,3 +483,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/bitfields.isa b/src/arch/sparc/isa/bitfields.isa index 7e884866c..e75680d2b 100644 --- a/src/arch/sparc/isa/bitfields.isa +++ b/src/arch/sparc/isa/bitfields.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,7 +38,7 @@ def bitfield A <29>; def bitfield BPCC <21:20>; // for BPcc & FBPcc -def bitfield FCMPCC <26:56>; // for FCMP & FCMPEa +def bitfield FCMPCC <26:25>; // for FCMP & FCMPEa def bitfield FMOVCC <13:11>; // for FMOVcc def bitfield CC <12:11>; // for MOVcc & Tcc def bitfield MOVCC3 <18>; // also for MOVcc diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 425ebc9d0..81443fecb 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -62,8 +62,8 @@ decode OP default Unknown::unknown() NNPC = NNPC;//Don't do anything }}); 0x1: bpn(19, {{ - NPC = xc->readNextPC() + 4; - NNPC = NPC + 4; + NNPC = NPC + 8; + NPC = NPC + 4; }}, ',a'); } default: decode BPCC @@ -103,8 +103,8 @@ decode OP default Unknown::unknown() NNPC = NNPC;//Don't do anything }}); 0x1: bn(22, {{ - NPC = xc->readNextPC() + 4; - NNPC = NPC + 4; + NNPC = NPC + 8; + NPC = NPC + 4; }}, ',a'); } default: bicc(22, {{ @@ -159,8 +159,92 @@ decode OP default Unknown::unknown() } //SETHI (or NOP if rd == 0 and imm == 0) 0x4: SetHi::sethi({{Rd.udw = imm;}}); - 0x5: Trap::fbpfcc({{fault = new FpDisabled;}}); - 0x6: Trap::fbfcc({{fault = new FpDisabled;}}); + //fbpfcc + 0x5: decode COND2 { + format BranchN { + //Branch Always + 0x8: decode A + { + 0x0: fbpa(22, {{ + NNPC = xc->readPC() + disp; + }}); + 0x1: fbpa(22, {{ + NPC = xc->readPC() + disp; + NNPC = NPC + 4; + }}, ',a'); + } + //Branch Never + 0x0: decode A + { + 0x0: fbpn(22, {{ + NNPC = NNPC;//Don't do anything + }}); + 0x1: fbpn(22, {{ + NNPC = NPC + 8; + NPC = NPC + 4; + }}, ',a'); + } + default: decode BPCC { + 0x0: fbpcc0(22, {{ + if(passesFpCondition(Fsr<11:10>, COND2)) + NNPC = xc->readPC() + disp; + else + handle_annul + }}); + 0x1: fbpcc1(22, {{ + if(passesFpCondition(Fsr<33:32>, COND2)) + NNPC = xc->readPC() + disp; + else + handle_annul + }}); + 0x2: fbpcc2(22, {{ + if(passesFpCondition(Fsr<35:34>, COND2)) + NNPC = xc->readPC() + disp; + else + handle_annul + }}); + 0x3: fbpcc3(22, {{ + if(passesFpCondition(Fsr<37:36>, COND2)) + NNPC = xc->readPC() + disp; + else + handle_annul + }}); + } + } + } + //fbfcc + 0x6: decode COND2 { + format BranchN { + //Branch Always + 0x8: decode A + { + 0x0: fba(22, {{ + NNPC = xc->readPC() + disp; + }}); + 0x1: fba(22, {{ + NPC = xc->readPC() + disp; + NNPC = NPC + 4; + }}, ',a'); + } + //Branch Never + 0x0: decode A + { + 0x0: fbn(22, {{ + NNPC = NNPC;//Don't do anything + }}); + 0x1: fbn(22, {{ + NNPC = NPC + 8; + NPC = NPC + 4; + }}, ',a'); + } + default: fbfcc(22, {{ + if(passesFpCondition(Fsr<11:10>, COND2)) + NNPC = xc->readPC() + disp; + else + handle_annul + }}); + } + } } 0x1: BranchN::call(30, {{ if (Pstate<3:>) @@ -186,7 +270,7 @@ decode OP default Unknown::unknown() Y = Rd<63:32>; }}); 0x0B: smul({{ - Rd.sdw = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13); + 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>}}); @@ -246,33 +330,29 @@ 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: umulcc({{ + 0x1A: IntOpCcRes::umulcc({{ uint64_t resTemp; Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); - 0x1B: smulcc({{ + Y = resTemp<63:32>;}}); + 0x1B: IntOpCcRes::smulcc({{ int64_t resTemp; - Rd = resTemp = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13); - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{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: udivxcc({{ + 0x1D: IntOpCcRes::udivxcc({{ if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; - else Rd = Rs1.udw / Rs2_or_imm13.udw;}} - ,{{0}},{{0}},{{0}},{{0}}); + else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: udivcc({{ uint32_t resTemp, val2 = Rs2_or_imm13.udw; int32_t overflow = 0; @@ -502,20 +582,7 @@ decode OP default Unknown::unknown() if(Rs2_or_imm13.sdw == 0) fault = new DivisionByZero; else Rd.sdw = Rs1.sdw / Rs2_or_imm13.sdw; }}); - 0x2E: decode RS1 { - 0x0: IntOp::popc({{ - int64_t count = 0; - uint64_t temp = Rs2_or_imm13; - //Count the 1s in the front 4bits until none are left - uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; - while(temp) - { - count += oneBits[temp & 0xF]; - temp = temp >> 4; - } - Rd = count; - }}); - } + 0x2E: Trap::popc({{fault = new IllegalInstruction;}}); 0x2F: decode RCOND3 { 0x1: movreq({{Rd = (Rs1.sdw == 0) ? Rs2_or_imm10 : Rd;}}); @@ -664,7 +731,7 @@ decode OP default Unknown::unknown() Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); - 0x03: Trap::fmovq({{fault = new FpDisabled;}}); + 0x03: FpUnimpl::fmovq(); 0x05: fnegs({{ Frds.uw = Frs2s.uw ^ (1UL << 31); //fsr.ftt = fsr.cexc = 0 @@ -677,7 +744,7 @@ decode OP default Unknown::unknown() Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); - 0x07: Trap::fnegq({{fault = new FpDisabled;}}); + 0x07: FpUnimpl::fnegq(); 0x09: fabss({{ Frds.uw = ((1UL << 31) - 1) & Frs2s.uw; //fsr.ftt = fsr.cexc = 0 @@ -690,106 +757,168 @@ decode OP default Unknown::unknown() Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); - 0x0B: Trap::fabsq({{fault = new FpDisabled;}}); - 0x29: fsqrts({{Frds.sf = sqrt(Frs2s.sf);}}); - 0x2A: fsqrtd({{Frd.df = sqrt(Frs2.df);}}); - 0x2B: Trap::fsqrtq({{fault = new FpDisabled;}}); + 0x0B: FpUnimpl::fabsq(); + 0x29: fsqrts({{Frds.sf = std::sqrt(Frs2s.sf);}}); + 0x2A: fsqrtd({{Frd.df = std::sqrt(Frs2.df);}}); + 0x2B: FpUnimpl::fsqrtq(); 0x41: fadds({{Frds.sf = Frs1s.sf + Frs2s.sf;}}); 0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}}); - 0x43: Trap::faddq({{fault = new FpDisabled;}}); + 0x43: FpUnimpl::faddq(); 0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}}); 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}}); - 0x47: Trap::fsubq({{fault = new FpDisabled;}}); + 0x47: FpUnimpl::fsubq(); 0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}}); 0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}}); - 0x4B: Trap::fmulq({{fault = new FpDisabled;}}); + 0x4B: FpUnimpl::fmulq(); 0x4D: fdivs({{Frds.sf = Frs1s.sf / Frs2s.sf;}}); 0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}}); - 0x4F: Trap::fdivq({{fault = new FpDisabled;}}); + 0x4F: FpUnimpl::fdivq(); 0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}}); - 0x6E: Trap::fdmulq({{fault = new FpDisabled;}}); + 0x6E: FpUnimpl::fdmulq(); 0x81: fstox({{ Frd.df = (double)static_cast<int64_t>(Frs2s.sf); }}); 0x82: fdtox({{ Frd.df = (double)static_cast<int64_t>(Frs2.df); }}); - 0x83: Trap::fqtox({{fault = new FpDisabled;}}); + 0x83: FpUnimpl::fqtox(); 0x84: fxtos({{ Frds.sf = static_cast<float>((int64_t)Frs2.df); }}); 0x88: fxtod({{ Frd.df = static_cast<double>((int64_t)Frs2.df); }}); - 0x8C: Trap::fxtoq({{fault = new FpDisabled;}}); + 0x8C: FpUnimpl::fxtoq(); 0xC4: fitos({{ Frds.sf = static_cast<float>((int32_t)Frs2s.sf); }}); 0xC6: fdtos({{Frds.sf = Frs2.df;}}); - 0xC7: Trap::fqtos({{fault = new FpDisabled;}}); + 0xC7: FpUnimpl::fqtos(); 0xC8: fitod({{ Frd.df = static_cast<double>((int32_t)Frs2s.sf); }}); 0xC9: fstod({{Frd.df = Frs2s.sf;}}); - 0xCB: Trap::fqtod({{fault = new FpDisabled;}}); - 0xCC: Trap::fitoq({{fault = new FpDisabled;}}); - 0xCD: Trap::fstoq({{fault = new FpDisabled;}}); - 0xCE: Trap::fdtoq({{fault = new FpDisabled;}}); + 0xCB: FpUnimpl::fqtod(); + 0xCC: FpUnimpl::fitoq(); + 0xCD: FpUnimpl::fstoq(); + 0xCE: FpUnimpl::fdtoq(); 0xD1: fstoi({{ Frds.sf = (float)static_cast<int32_t>(Frs2s.sf); }}); 0xD2: fdtoi({{ Frds.sf = (float)static_cast<int32_t>(Frs2.df); }}); - 0xD3: Trap::fqtoi({{fault = new FpDisabled;}}); - default: Trap::fpop1({{fault = new FpDisabled;}}); + 0xD3: FpUnimpl::fqtoi(); + default: FailUnimpl::fpop1(); + } + } + 0x35: decode OPF{ + format BasicOperate{ + 0x51: fcmps({{ + uint8_t fcc; + if(isnan(Frs1s) || isnan(Frs2s)) + fcc = 3; + else if(Frs1s < Frs2s) + fcc = 1; + else if(Frs1s > Frs2s) + fcc = 2; + else + fcc = 0; + uint8_t firstbit = 10; + if(FCMPCC) + firstbit = FCMPCC * 2 + 30; + Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); + }}); + 0x52: fcmpd({{ + uint8_t fcc; + if(isnan(Frs1s) || isnan(Frs2s)) + fcc = 3; + else if(Frs1s < Frs2s) + fcc = 1; + else if(Frs1s > Frs2s) + fcc = 2; + else + fcc = 0; + uint8_t firstbit = 10; + if(FCMPCC) + firstbit = FCMPCC * 2 + 30; + Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); + }}); + 0x53: FpUnimpl::fcmpq(); + 0x55: fcmpes({{ + uint8_t fcc = 0; + if(isnan(Frs1s) || isnan(Frs2s)) + fault = new FpExceptionIEEE754; + if(Frs1s < Frs2s) + fcc = 1; + else if(Frs1s > Frs2s) + fcc = 2; + uint8_t firstbit = 10; + if(FCMPCC) + firstbit = FCMPCC * 2 + 30; + Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); + }}); + 0x56: fcmped({{ + uint8_t fcc = 0; + if(isnan(Frs1s) || isnan(Frs2s)) + fault = new FpExceptionIEEE754; + if(Frs1s < Frs2s) + fcc = 1; + else if(Frs1s > Frs2s) + fcc = 2; + uint8_t firstbit = 10; + if(FCMPCC) + firstbit = FCMPCC * 2 + 30; + Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); + }}); + 0x57: FpUnimpl::fcmpeq(); + default: FailUnimpl::fpop2(); } } - 0x35: Trap::fpop2({{fault = new FpDisabled;}}); //This used to be just impdep1, but now it's a whole bunch //of instructions 0x36: decode OPF{ - 0x00: Trap::edge8({{fault = new IllegalInstruction;}}); - 0x01: Trap::edge8n({{fault = new IllegalInstruction;}}); - 0x02: Trap::edge8l({{fault = new IllegalInstruction;}}); - 0x03: Trap::edge8ln({{fault = new IllegalInstruction;}}); - 0x04: Trap::edge16({{fault = new IllegalInstruction;}}); - 0x05: Trap::edge16n({{fault = new IllegalInstruction;}}); - 0x06: Trap::edge16l({{fault = new IllegalInstruction;}}); - 0x07: Trap::edge16ln({{fault = new IllegalInstruction;}}); - 0x08: Trap::edge32({{fault = new IllegalInstruction;}}); - 0x09: Trap::edge32n({{fault = new IllegalInstruction;}}); - 0x0A: Trap::edge32l({{fault = new IllegalInstruction;}}); - 0x0B: Trap::edge32ln({{fault = new IllegalInstruction;}}); - 0x10: Trap::array8({{fault = new IllegalInstruction;}}); - 0x12: Trap::array16({{fault = new IllegalInstruction;}}); - 0x14: Trap::array32({{fault = new IllegalInstruction;}}); + 0x00: FailUnimpl::edge8(); + 0x01: FailUnimpl::edge8n(); + 0x02: FailUnimpl::edge8l(); + 0x03: FailUnimpl::edge8ln(); + 0x04: FailUnimpl::edge16(); + 0x05: FailUnimpl::edge16n(); + 0x06: FailUnimpl::edge16l(); + 0x07: FailUnimpl::edge16ln(); + 0x08: FailUnimpl::edge32(); + 0x09: FailUnimpl::edge32n(); + 0x0A: FailUnimpl::edge32l(); + 0x0B: FailUnimpl::edge32ln(); + 0x10: FailUnimpl::array8(); + 0x12: FailUnimpl::array16(); + 0x14: FailUnimpl::array32(); 0x18: BasicOperate::alignaddr({{ uint64_t sum = Rs1 + Rs2; Rd = sum & ~7; Gsr = (Gsr & ~7) | (sum & 7); }}); - 0x19: Trap::bmask({{fault = new IllegalInstruction;}}); + 0x19: FailUnimpl::bmask(); 0x1A: BasicOperate::alignaddresslittle({{ uint64_t sum = Rs1 + Rs2; Rd = sum & ~7; Gsr = (Gsr & ~7) | ((~sum + 1) & 7); }}); - 0x20: Trap::fcmple16({{fault = new IllegalInstruction;}}); - 0x22: Trap::fcmpne16({{fault = new IllegalInstruction;}}); - 0x24: Trap::fcmple32({{fault = new IllegalInstruction;}}); - 0x26: Trap::fcmpne32({{fault = new IllegalInstruction;}}); - 0x28: Trap::fcmpgt16({{fault = new IllegalInstruction;}}); - 0x2A: Trap::fcmpeq16({{fault = new IllegalInstruction;}}); - 0x2C: Trap::fcmpgt32({{fault = new IllegalInstruction;}}); - 0x2E: Trap::fcmpeq32({{fault = new IllegalInstruction;}}); - 0x31: Trap::fmul8x16({{fault = new IllegalInstruction;}}); - 0x33: Trap::fmul8x16au({{fault = new IllegalInstruction;}}); - 0x35: Trap::fmul8x16al({{fault = new IllegalInstruction;}}); - 0x36: Trap::fmul8sux16({{fault = new IllegalInstruction;}}); - 0x37: Trap::fmul8ulx16({{fault = new IllegalInstruction;}}); - 0x38: Trap::fmuld8sux16({{fault = new IllegalInstruction;}}); - 0x39: Trap::fmuld8ulx16({{fault = new IllegalInstruction;}}); + 0x20: FailUnimpl::fcmple16(); + 0x22: FailUnimpl::fcmpne16(); + 0x24: FailUnimpl::fcmple32(); + 0x26: FailUnimpl::fcmpne32(); + 0x28: FailUnimpl::fcmpgt16(); + 0x2A: FailUnimpl::fcmpeq16(); + 0x2C: FailUnimpl::fcmpgt32(); + 0x2E: FailUnimpl::fcmpeq32(); + 0x31: FailUnimpl::fmul8x16(); + 0x33: FailUnimpl::fmul8x16au(); + 0x35: FailUnimpl::fmul8x16al(); + 0x36: FailUnimpl::fmul8sux16(); + 0x37: FailUnimpl::fmul8ulx16(); + 0x38: FailUnimpl::fmuld8sux16(); + 0x39: FailUnimpl::fmuld8ulx16(); 0x3A: Trap::fpack32({{fault = new IllegalInstruction;}}); 0x3B: Trap::fpack16({{fault = new IllegalInstruction;}}); 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}}); @@ -821,58 +950,58 @@ decode OP default Unknown::unknown() } }}); 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}}); - 0x4C: Trap::bshuffle({{fault = new IllegalInstruction;}}); - 0x4D: Trap::fexpand({{fault = new IllegalInstruction;}}); - 0x50: Trap::fpadd16({{fault = new IllegalInstruction;}}); - 0x51: Trap::fpadd16s({{fault = new IllegalInstruction;}}); - 0x52: Trap::fpadd32({{fault = new IllegalInstruction;}}); - 0x53: Trap::fpadd32s({{fault = new IllegalInstruction;}}); - 0x54: Trap::fpsub16({{fault = new IllegalInstruction;}}); - 0x55: Trap::fpsub16s({{fault = new IllegalInstruction;}}); - 0x56: Trap::fpsub32({{fault = new IllegalInstruction;}}); - 0x57: Trap::fpsub32s({{fault = new IllegalInstruction;}}); + 0x4C: FailUnimpl::bshuffle(); + 0x4D: FailUnimpl::fexpand(); + 0x50: FailUnimpl::fpadd16(); + 0x51: FailUnimpl::fpadd16s(); + 0x52: FailUnimpl::fpadd32(); + 0x53: FailUnimpl::fpadd32s(); + 0x54: FailUnimpl::fpsub16(); + 0x55: FailUnimpl::fpsub16s(); + 0x56: FailUnimpl::fpsub32(); + 0x57: FailUnimpl::fpsub32s(); 0x60: BasicOperate::fzero({{Frd.df = 0;}}); 0x61: BasicOperate::fzeros({{Frds.sf = 0;}}); - 0x62: Trap::fnor({{fault = new IllegalInstruction;}}); - 0x63: Trap::fnors({{fault = new IllegalInstruction;}}); - 0x64: Trap::fandnot2({{fault = new IllegalInstruction;}}); - 0x65: Trap::fandnot2s({{fault = new IllegalInstruction;}}); + 0x62: FailUnimpl::fnor(); + 0x63: FailUnimpl::fnors(); + 0x64: FailUnimpl::fandnot2(); + 0x65: FailUnimpl::fandnot2s(); 0x66: BasicOperate::fnot2({{ Frd.df = (double)(~((uint64_t)Frs2.df)); }}); 0x67: BasicOperate::fnot2s({{ Frds.sf = (float)(~((uint32_t)Frs2s.sf)); }}); - 0x68: Trap::fandnot1({{fault = new IllegalInstruction;}}); - 0x69: Trap::fandnot1s({{fault = new IllegalInstruction;}}); + 0x68: FailUnimpl::fandnot1(); + 0x69: FailUnimpl::fandnot1s(); 0x6A: BasicOperate::fnot1({{ Frd.df = (double)(~((uint64_t)Frs1.df)); }}); 0x6B: BasicOperate::fnot1s({{ Frds.sf = (float)(~((uint32_t)Frs1s.sf)); }}); - 0x6C: Trap::fxor({{fault = new IllegalInstruction;}}); - 0x6D: Trap::fxors({{fault = new IllegalInstruction;}}); - 0x6E: Trap::fnand({{fault = new IllegalInstruction;}}); - 0x6F: Trap::fnands({{fault = new IllegalInstruction;}}); - 0x70: Trap::fand({{fault = new IllegalInstruction;}}); - 0x71: Trap::fands({{fault = new IllegalInstruction;}}); - 0x72: Trap::fxnor({{fault = new IllegalInstruction;}}); - 0x73: Trap::fxnors({{fault = new IllegalInstruction;}}); + 0x6C: FailUnimpl::fxor(); + 0x6D: FailUnimpl::fxors(); + 0x6E: FailUnimpl::fnand(); + 0x6F: FailUnimpl::fnands(); + 0x70: FailUnimpl::fand(); + 0x71: FailUnimpl::fands(); + 0x72: FailUnimpl::fxnor(); + 0x73: FailUnimpl::fxnors(); 0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}}); - 0x75: BasicOperate::fsrc1s({{Frd.uw = Frs1.uw;}}); - 0x76: Trap::fornot2({{fault = new IllegalInstruction;}}); - 0x77: Trap::fornot2s({{fault = new IllegalInstruction;}}); + 0x75: BasicOperate::fsrc1s({{Frds.uw = Frs1s.uw;}}); + 0x76: FailUnimpl::fornot2(); + 0x77: FailUnimpl::fornot2s(); 0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}}); - 0x79: BasicOperate::fsrc2s({{Frd.uw = Frs2.uw;}}); - 0x7A: Trap::fornot1({{fault = new IllegalInstruction;}}); - 0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}}); - 0x7C: Trap::for({{fault = new IllegalInstruction;}}); - 0x7D: Trap::fors({{fault = new IllegalInstruction;}}); - 0x7E: Trap::fone({{fault = new IllegalInstruction;}}); - 0x7F: Trap::fones({{fault = new IllegalInstruction;}}); + 0x79: BasicOperate::fsrc2s({{Frds.uw = Frs2s.uw;}}); + 0x7A: FailUnimpl::fornot1(); + 0x7B: FailUnimpl::fornot1s(); + 0x7C: FailUnimpl::for(); + 0x7D: FailUnimpl::fors(); + 0x7E: BasicOperate::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}}); + 0x7F: BasicOperate::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}}); 0x80: Trap::shutdown({{fault = new IllegalInstruction;}}); - 0x81: Trap::siam({{fault = new IllegalInstruction;}}); + 0x81: FailUnimpl::siam(); } 0x37: Trap::impdep2({{fault = new IllegalInstruction;}}); 0x38: Branch::jmpl({{ @@ -889,16 +1018,11 @@ decode OP default Unknown::unknown() } }}); 0x39: Branch::return({{ - //If both MemAddressNotAligned and - //a fill trap happen, it's not clear - //which one should be returned. Addr target = Rs1 + Rs2_or_imm13; - if(target & 0x3) - fault = new MemAddressNotAligned; - else - NNPC = target; if(fault == NoFault) { + //Check for fills which are higher priority than alignment + //faults. if(Canrestore == 0) { if(Otherwin) @@ -906,18 +1030,15 @@ decode OP default Unknown::unknown() else fault = new FillNNormal(4*Wstate<2:0>); } + //Check for alignment faults + else if(target & 0x3) + fault = new MemAddressNotAligned; else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one + NNPC = target; Cwp = (Cwp - 1 + NWindows) % NWindows; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } } }}); @@ -935,7 +1056,7 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); 0x2: Trap::tccx({{ if(passesCondition(Ccr<7:4>, COND2)) { @@ -948,36 +1069,27 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); } 0x3B: Nop::flush({{/*Instruction memory flush*/}}); 0x3C: save({{ - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one if(Cansave == 0) { if(Otherwin) fault = new SpillNOther(4*Wstate<5:3>); else fault = new SpillNNormal(4*Wstate<2:0>); - //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) { - //Cwp = (Cwp + 1) % NWindows; fault = new CleanWindow; } else { Cwp = (Cwp + 1) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_next = Rs1 + Rs2_or_imm13; Cansave = Cansave - 1; Canrestore = Canrestore + 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3D: restore({{ @@ -990,17 +1102,10 @@ decode OP default Unknown::unknown() } else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one Cwp = (Cwp - 1 + NWindows) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_prev = Rs1 + Rs2_or_imm13; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3E: decode FCN { @@ -1130,14 +1235,14 @@ decode OP default Unknown::unknown() {{ 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;}}); @@ -1145,7 +1250,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 { @@ -1228,7 +1333,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 a4c05387b..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; @@ -95,8 +97,7 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... used only for a few misc. insts def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'SparcStaticInst', - CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa index 5fb7ade2d..5cd3ab598 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.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 @@ -170,7 +170,7 @@ output decoder {{ printMnemonic(response, mnemonic); ccprintf(response, "0x%x", target); - if(symtab->findNearestSymbol(target, symbol, symbolAddr)) + if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { ccprintf(response, " <%s", symbol); if(symbolAddr != target) @@ -211,13 +211,13 @@ let {{ { if(A) { - NPC = xc->readNextNPC(); - NNPC = NPC + 4; + NNPC = NPC + 8; + NPC = NPC + 4; } else { - NPC = xc->readNextPC(); - NNPC = xc->readNextNPC(); + NPC = NPC; + NNPC = NNPC; } }''' }}; @@ -244,7 +244,6 @@ def format Branch(code, *opt_flags) {{ // Primary format for branch instructions: def format BranchN(bits, code, *opt_flags) {{ code = re.sub(r'handle_annul', handle_annul, code) - codeBlk = CodeBlock(code) new_opt_flags = [] for flag in opt_flags: if flag == ',a': @@ -252,7 +251,7 @@ def format BranchN(bits, code, *opt_flags) {{ Name += 'Annul' else: new_opt_flags += flag - iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags) + iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) @@ -262,8 +261,7 @@ def format BranchN(bits, code, *opt_flags) {{ // Primary format for branch instructions: def format BranchSplit(code, *opt_flags) {{ code = re.sub(r'handle_annul', handle_annul, code) - codeBlk = CodeBlock(code) - iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) + iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index 4f8ebebcc..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) { @@ -263,14 +263,15 @@ let {{ def doIntFormat(code, ccCode, name, Name, opt_flags): (usesImm, code, immCode, rString, iString) = splitOutImm(code) - iop = InstObjParams(name, Name, 'IntOp', code, - opt_flags, {"cc_code": ccCode}) + iop = InstObjParams(name, Name, 'IntOp', + {"code": code, "cc_code": ccCode}, + opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = IntOpExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, - immCode, opt_flags, {"cc_code": ccCode}) + {"code": immCode, "cc_code": ccCode}, opt_flags) header_output += BasicDeclare.subst(imm_iop) decoder_output += BasicConstructor.subst(imm_iop) exec_output += IntOpExecute.subst(imm_iop) @@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{ def format SetHi(code, *opt_flags) {{ iop = InstObjParams(name, Name, 'SetHi', - code, opt_flags, {"cc_code": ''}) + {"code": code, "cc_code": ''}, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = IntOpExecute.subst(iop) diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index 55e9fba45..1d9075a57 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -55,16 +55,20 @@ let {{ def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags): addrCalcReg = 'EA = Rs1 + Rs2;' addrCalcImm = 'EA = Rs1 + imm;' - iop = InstObjParams(name, Name, 'Mem', code, - opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg}) - iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code, - opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm}) + iop = InstObjParams(name, Name, 'Mem', + {"code": code, "fault_check": faultCode, + "ea_code": addrCalcReg}, + opt_flags) + iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', + {"code": code, "fault_check": faultCode, + "ea_code": addrCalcImm}, + opt_flags) header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm) decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm) decode_block = ROrImmDecode.subst(iop) exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, - execute, faultCode, name, name + "Imm", Name, Name + "Imm", - asi, opt_flags) + execute, faultCode, name, name + "Imm", + Name, Name + "Imm", asi, opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; @@ -72,7 +76,7 @@ def format LoadAlt(code, asi, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, LoadExecute, + decode_block) = doMemFormat(code, LoadFuncs, AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) }}; @@ -80,7 +84,7 @@ def format StoreAlt(code, asi, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, StoreExecute, + decode_block) = doMemFormat(code, StoreFuncs, AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) }}; @@ -89,7 +93,7 @@ def format Load(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - LoadExecute, '', name, Name, 0, opt_flags) + LoadFuncs, '', name, Name, 0, opt_flags) }}; def format Store(code, *opt_flags) {{ @@ -97,5 +101,5 @@ def format Store(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - StoreExecute, '', name, Name, 0, opt_flags) + StoreFuncs, '', name, Name, 0, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index c36fede2e..9795d2342 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -456,14 +456,14 @@ let {{ else: flag_code = "flags[IsDelayedCommit] = true;" pcedCode = matcher.sub("Frd_%d" % microPc, code) - iop = InstObjParams(name, Name, 'BlockMem', pcedCode, - opt_flags, {"ea_code": addrCalcReg, + iop = InstObjParams(name, Name, 'BlockMem', + {"code": pcedCode, "ea_code": addrCalcReg, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) - iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode, - opt_flags, {"ea_code": addrCalcImm, + "set_flags": flag_code}, opt_flags) + iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', + {"code": pcedCode, "ea_code": addrCalcImm, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) + "set_flags": flag_code}, opt_flags) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) exec_output += doDualSplitExecute( @@ -496,18 +496,18 @@ let {{ else: flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" pcedCode = matcher.sub("uReg0", code) - iop = InstObjParams(name, Name, 'TwinMem', pcedCode, - opt_flags, {"ea_code": addrCalcReg, + iop = InstObjParams(name, Name, 'TwinMem', + {"code": pcedCode, "ea_code": addrCalcReg, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) - iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', pcedCode, - opt_flags, {"ea_code": addrCalcImm, + "set_flags": flag_code}, opt_flags) + iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', + {"code": pcedCode, "ea_code": addrCalcImm, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) + "set_flags": flag_code}, opt_flags) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) exec_output += doDualSplitExecute( - pcedCode, addrCalcReg, addrCalcImm, LoadExecute, faultCode, + pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), makeMicroName(Name, microPc), @@ -527,7 +527,7 @@ def format BlockLoad(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - LoadExecute, name, Name, asi, opt_flags) + LoadFuncs, name, Name, asi, opt_flags) }}; def format BlockStore(code, asi, *opt_flags) {{ @@ -539,7 +539,7 @@ def format BlockStore(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - StoreExecute, name, Name, asi, opt_flags) + StoreFuncs, name, Name, asi, opt_flags) }}; def format TwinLoad(code, asi, *opt_flags) {{ diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index b6e0945b7..dbaabdca4 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.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 @@ -141,10 +141,11 @@ def template LoadExecute {{ { Fault fault = NoFault; Addr EA; + %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -162,16 +163,19 @@ def template LoadExecute {{ return fault; } +}}; +def template LoadInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; Addr EA; - uint%(mem_acc_size)s_t Mem; - %(ea_decl)s; - %(ea_rd)s; + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; %(ea_code)s; + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -179,18 +183,20 @@ def template LoadExecute {{ } return fault; } +}}; +def template LoadCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; - %(code_decl)s; - %(code_rd)s; + %(op_decl)s; + %(op_rd)s; Mem = pkt->get<typeof(Mem)>(); %(code)s; if(fault == NoFault) { - %(code_wb)s; + %(op_wb)s; } return fault; } @@ -206,10 +212,11 @@ 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; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -228,17 +235,20 @@ def template StoreExecute {{ return fault; } +}}; +def template StoreInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; bool storeCond = true; Addr EA; + %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -256,7 +266,9 @@ def template StoreExecute {{ } return fault; } +}}; +def template StoreCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { @@ -276,6 +288,8 @@ def template CompleteAccDeclare {{ //Here are some code snippets which check for various fault conditions let {{ + LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] + StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] # The LSB can be zero, since it's really the MSB in doubles and quads # and we're dealing with doubles BlockAlignmentFaultCheck = ''' @@ -316,21 +330,11 @@ let {{ //and in the other they're distributed across two. Also note that for //execute functions, the name of the base class doesn't matter. let {{ - def doSplitExecute(code, execute, name, Name, asi, opt_flags, microParam): + def doSplitExecute(execute, name, Name, asi, opt_flags, microParam): microParam["asi_val"] = asi; - codeParam = microParam.copy() - codeParam["ea_code"] = '' - codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam) - eaIop = InstObjParams(name, Name, '', microParam["ea_code"], - opt_flags, microParam) - iop = InstObjParams(name, Name, '', code, opt_flags, microParam) - (iop.ea_decl, - iop.ea_rd, - iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) - (iop.code_decl, - iop.code_rd, - iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) - return execute.subst(iop) + iop = InstObjParams(name, Name, '', microParam, opt_flags) + (execf, initf, compf) = execute + return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, @@ -339,8 +343,9 @@ let {{ for (eaCode, name, Name) in ( (eaRegCode, nameReg, NameReg), (eaImmCode, nameImm, NameImm)): - microParams = {"ea_code" : eaCode, "fault_check": faultCode} - executeCode += doSplitExecute(code, execute, name, Name, + microParams = {"code": code, "ea_code": eaCode, + "fault_check": faultCode} + executeCode += doSplitExecute(execute, name, Name, asi, opt_flags, microParams) return executeCode }}; diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa index 37ef2e8d0..de2ba2f54 100644 --- a/src/arch/sparc/isa/formats/nop.isa +++ b/src/arch/sparc/isa/formats/nop.isa @@ -88,9 +88,7 @@ def template NopExecute {{ // Primary format for integer operate instructions: def format Nop(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags) + iop = InstObjParams(name, Name, 'Nop', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 3d47ca02f..36403afb4 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -235,8 +235,9 @@ let {{ name = mnem regBase = 'WrPriv' break - iop = InstObjParams(name, Name, regBase, code, - opt_flags, {"check": checkCode, "reg_name": regName}) + iop = InstObjParams(name, Name, regBase, + {"code": code, "check": checkCode, "reg_name": regName}, + opt_flags) header_output = BasicDeclare.subst(iop) if regName == '': decoder_output = BasicConstructor.subst(iop) @@ -245,7 +246,8 @@ let {{ exec_output = PrivExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', - immCode, opt_flags, {"check": checkCode, "reg_name": regName}) + {"code": immCode, "check": checkCode, "reg_name": regName}, + opt_flags) header_output += BasicDeclare.subst(imm_iop) if regName == '': decoder_output += BasicConstructor.subst(imm_iop) diff --git a/src/arch/sparc/isa/formats/trap.isa b/src/arch/sparc/isa/formats/trap.isa index 04d467cfe..66eff35d4 100644 --- a/src/arch/sparc/isa/formats/trap.isa +++ b/src/arch/sparc/isa/formats/trap.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 @@ -82,12 +82,53 @@ def template TrapExecute {{ } }}; +def template FpUnimplExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + %(code)s + %(op_wb)s; + return fault; + } +}}; + def format Trap(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags) + iop = InstObjParams(name, Name, 'Trap', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = TrapExecute.subst(iop) }}; + +output header {{ + class FpUnimpl : public SparcStaticInst + { + protected: + FpUnimpl(const char *mnem, + ExtMachInst _machInst, OpClass __opClass) + : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return mnemonic; + } + }; +}}; + +def format FpUnimpl(*flags) {{ + fpunimpl_code = ''' + Fsr = insertBits(Fsr, 16, 14, 3); + fault = new FpExceptionOther; + ''' + iop = InstObjParams(name, Name, 'FpUnimpl', fpunimpl_code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = FpUnimplExecute.subst(iop) +}}; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 0c112d481..a6dca9bf1 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -34,15 +34,17 @@ // output header {{ +#include <cstring> #include <sstream> #include <iostream> -#include "cpu/static_inst.hh" #include "arch/sparc/faults.hh" -#include "mem/request.hh" // some constructors use MemReq flags -#include "mem/packet.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/regfile.hh" +#include "base/misc.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" +#include "mem/request.hh" // some constructors use MemReq flags }}; output decoder {{ @@ -65,6 +67,7 @@ output exec {{ #endif #include <limits> +#include <cmath> #include "arch/sparc/asi.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" @@ -73,5 +76,6 @@ output exec {{ #include "mem/packet_access.hh" using namespace SparcISA; +using namespace std; }}; diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index abb82f88c..140055010 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.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 @@ -56,15 +56,26 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. + 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1), + # The Rd from the previous window + 'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2), + # The Rd from the next window + 'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3), # For microcoded twin load instructions, RdTwin appears in the "code" - # for the instruction and is replaced by RdLow or RdHigh by the format + # for the instruction is replaced by RdLow or RdHigh by the format # before it's processed by the iop. - 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 2), - 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3), - 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4), - 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5), - 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 6), + # The low (even) register of a two register pair + 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4), + # The high (odd) register of a two register pair + 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5), + 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6), + 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7), + # A microcode register. Right now, this is the only one. + 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8), + # Because double and quad precision register numbers are decoded + # differently, they get different operands. The single precision versions + # have an s post pended to their name. 'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10), 'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10), # Each Frd_N refers to the Nth double precision register from Frd. @@ -77,20 +88,23 @@ def operands {{ 'Frd_5': ('FloatReg', 'df', 'dfpr(RD) + 10', 'IsFloating', 10), 'Frd_6': ('FloatReg', 'df', 'dfpr(RD) + 12', 'IsFloating', 10), 'Frd_7': ('FloatReg', 'df', 'dfpr(RD) + 14', 'IsFloating', 10), - 'Frs1s': ('FloatReg', 'df', 'RS1', 'IsFloating', 11), + 'Frs1s': ('FloatReg', 'sf', 'RS1', 'IsFloating', 11), 'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11), - 'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12), + 'Frs2s': ('FloatReg', 'sf', 'RS2', 'IsFloating', 12), 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), + # Registers which are used explicitly in instructions 'R0': ('IntReg', 'udw', '0', None, 6), 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), # Control registers - 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), - 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), +# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), +# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), + 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40), + 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), @@ -112,12 +126,17 @@ def operands {{ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62), +# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), +# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), +# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), +# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), +# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63), + 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64), + 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65), + 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66), + 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67), 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), |