diff options
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r-- | src/arch/sparc/isa/base.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/bitfields.isa | 1 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 365 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/branch.isa | 10 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/basicmem.isa | 28 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 212 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/mem.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/swap.isa | 183 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/util.isa | 16 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 5 | ||||
-rw-r--r-- | src/arch/sparc/isa/operands.isa | 8 |
11 files changed, 514 insertions, 322 deletions
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa index 693cc6876..bba63f407 100644 --- a/src/arch/sparc/isa/base.isa +++ b/src/arch/sparc/isa/base.isa @@ -492,8 +492,8 @@ output exec {{ 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) + if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef && + xc->readMiscReg(MISCREG_FPRS) & 0x4) return NoFault; else return new FpDisabled; diff --git a/src/arch/sparc/isa/bitfields.isa b/src/arch/sparc/isa/bitfields.isa index e75680d2b..afa8f88a2 100644 --- a/src/arch/sparc/isa/bitfields.isa +++ b/src/arch/sparc/isa/bitfields.isa @@ -54,6 +54,7 @@ def bitfield FCN <29:25>; def bitfield I <13>; def bitfield IMM_ASI <12:5>; def bitfield IMM22 <21:0>; +def bitfield M5FUNC <15:7>; def bitfield MMASK <3:0>; def bitfield OP <31:30>; def bitfield OP2 <24:22>; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index fb606c7cc..556bb4bca 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -185,25 +185,25 @@ decode OP default Unknown::unknown() }}, ',a'); } default: decode BPCC { - 0x0: fbpcc0(22, {{ + 0x0: fbpfcc0(19, {{ if(passesFpCondition(Fsr<11:10>, COND2)) NNPC = xc->readPC() + disp; else handle_annul }}); - 0x1: fbpcc1(22, {{ + 0x1: fbpfcc1(19, {{ if(passesFpCondition(Fsr<33:32>, COND2)) NNPC = xc->readPC() + disp; else handle_annul }}); - 0x2: fbpcc2(22, {{ + 0x2: fbpfcc2(19, {{ if(passesFpCondition(Fsr<35:34>, COND2)) NNPC = xc->readPC() + disp; else handle_annul }}); - 0x3: fbpcc3(22, {{ + 0x3: fbpfcc3(19, {{ if(passesFpCondition(Fsr<37:36>, COND2)) NNPC = xc->readPC() + disp; else @@ -426,19 +426,22 @@ decode OP default Unknown::unknown() {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} ); 0x24: mulscc({{ - int64_t resTemp, multiplicand = Rs2_or_imm13; - int32_t multiplier = Rs1<31:0>; int32_t savedLSB = Rs1<0:>; - multiplier = multiplier<31:1> | - ((Ccr<3:3> ^ Ccr<1:1>) << 32); - if(!Y<0:>) - multiplicand = 0; - Rd = resTemp = multiplicand + multiplier; + + //Step 1 + int64_t multiplicand = Rs2_or_imm13; + //Step 2 + int32_t partialP = Rs1<31:1> | + ((Ccr<3:3> ^ Ccr<1:1>) << 31); + //Step 3 + int32_t added = Y<0:> ? multiplicand : 0; + Rd = partialP + added; + //Steps 4 & 5 Y = Y<31:1> | (savedLSB << 31);}}, - {{((multiplicand<31:0> + multiplier<31:0>)<32:0>)}}, - {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}}, - {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}}, - {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}} + {{((partialP<31:0> + added<31:0>)<32:0>)}}, + {{partialP<31:> == added<31:> && added<31:> != Rd<31:>}}, + {{((partialP >> 1) + (added >> 1) + (partialP & added & 0x1))<63:>}}, + {{partialP<63:> == added<63:> && partialP<63:> != Rd<63:>}} ); } format IntOp @@ -472,8 +475,8 @@ decode OP default Unknown::unknown() }}); //7-14 should cause an illegal instruction exception 0x0F: decode I { - 0x0: Nop::stbar({{/*stuff*/}}); - 0x1: Nop::membar({{/*stuff*/}}); + 0x0: Nop::stbar({{/*stuff*/}}, IsWriteBarrier, MemWriteOp); + 0x1: Nop::membar({{/*stuff*/}}, IsMemBarrier, MemReadOp); } 0x10: Priv::rdpcr({{Rd = Pcr;}}); 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); @@ -620,10 +623,6 @@ decode OP default Unknown::unknown() }}); 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}}); 0x1A: Priv::wrstrand_sts_reg({{ - if(Pstate<2:> && !Hpstate<2:>) - StrandStsReg = StrandStsReg<63:1> | - (Rs1 ^ Rs2_or_imm13)<0:>; - else StrandStsReg = Rs1 ^ Rs2_or_imm13; }}); //0x1A is supposed to be reserved, but it writes the strand @@ -820,6 +819,58 @@ decode OP default Unknown::unknown() } 0x35: decode OPF{ format FpBasic{ + 0x01: fmovs_fcc0({{ + if(passesFpCondition(Fsr<11:10>, COND4)) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x02: fmovd_fcc0({{ + if(passesFpCondition(Fsr<11:10>, COND4)) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x03: FpUnimpl::fmovq_fcc0(); + 0x25: fmovrsz({{ + if(Rs1 == 0) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x26: fmovrdz({{ + if(Rs1 == 0) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x27: FpUnimpl::fmovrqz(); + 0x41: fmovs_fcc1({{ + if(passesFpCondition(Fsr<33:32>, COND4)) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x42: fmovd_fcc1({{ + if(passesFpCondition(Fsr<33:32>, COND4)) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x43: FpUnimpl::fmovq_fcc1(); + 0x45: fmovrslez({{ + if(Rs1 <= 0) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x46: fmovrdlez({{ + if(Rs1 <= 0) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x47: FpUnimpl::fmovrqlez(); 0x51: fcmps({{ uint8_t fcc; if(isnan(Frs1s) || isnan(Frs2s)) @@ -878,6 +929,110 @@ decode OP default Unknown::unknown() Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc); }}); 0x57: FpUnimpl::fcmpeq(); + 0x65: fmovrslz({{ + if(Rs1 < 0) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x66: fmovrdlz({{ + if(Rs1 < 0) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x67: FpUnimpl::fmovrqlz(); + 0x81: fmovs_fcc2({{ + if(passesFpCondition(Fsr<35:34>, COND4)) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x82: fmovd_fcc2({{ + if(passesFpCondition(Fsr<35:34>, COND4)) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x83: FpUnimpl::fmovq_fcc2(); + 0xA5: fmovrsnz({{ + if(Rs1 != 0) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0xA6: fmovrdnz({{ + if(Rs1 != 0) + Frd = Frs2; + else + Frd = Frd; + }}); + 0xA7: FpUnimpl::fmovrqnz(); + 0xC1: fmovs_fcc3({{ + if(passesFpCondition(Fsr<37:36>, COND4)) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0xC2: fmovd_fcc3({{ + if(passesFpCondition(Fsr<37:36>, COND4)) + Frd = Frs2; + else + Frd = Frd; + }}); + 0xC3: FpUnimpl::fmovq_fcc3(); + 0xC5: fmovrsgz({{ + if(Rs1 > 0) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0xC6: fmovrdgz({{ + if(Rs1 > 0) + Frd = Frs2; + else + Frd = Frd; + }}); + 0xC7: FpUnimpl::fmovrqgz(); + 0xE5: fmovrsgez({{ + if(Rs1 >= 0) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0xE6: fmovrdgez({{ + if(Rs1 >= 0) + Frd = Frs2; + else + Frd = Frd; + }}); + 0xE7: FpUnimpl::fmovrqgez(); + 0x101: fmovs_icc({{ + if(passesCondition(Ccr<3:0>, COND4)) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x102: fmovd_icc({{ + if(passesCondition(Ccr<3:0>, COND4)) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x103: FpUnimpl::fmovq_icc(); + 0x181: fmovs_xcc({{ + if(passesCondition(Ccr<7:4>, COND4)) + Frds = Frs2s; + else + Frds = Frds; + }}); + 0x182: fmovd_xcc({{ + if(passesCondition(Ccr<7:4>, COND4)) + Frd = Frs2; + else + Frd = Frd; + }}); + 0x183: FpUnimpl::fmovq_xcc(); default: FailUnimpl::fpop2(); } } @@ -1009,7 +1164,25 @@ decode OP default Unknown::unknown() 0x80: Trap::shutdown({{fault = new IllegalInstruction;}}); 0x81: FailUnimpl::siam(); } - 0x37: Trap::impdep2({{fault = new IllegalInstruction;}}); + // M5 special opcodes use the reserved IMPDEP2A opcode space + 0x37: decode M5FUNC { +#if FULL_SYSTEM + format BasicOperate { + // we have 7 bits of space here to play with... + 0x21: m5exit({{PseudoInst::m5exit(xc->tcBase(), O0); + }}, No_OpClass, IsNonSpeculative); + 0x50: m5readfile({{ + O0 = PseudoInst::readfile(xc->tcBase(), O0, O1, O2); + }}, IsNonSpeculative); + 0x51: m5break({{PseudoInst::debugbreak(xc->tcBase()); + }}, IsNonSpeculative); + 0x54: m5panic({{ + panic("M5 panic instruction called at pc=%#x.", xc->readPC()); + }}, No_OpClass, IsNonSpeculative); + } +#endif + default: Trap::impdep2({{fault = new IllegalInstruction;}}); + } 0x38: Branch::jmpl({{ Addr target = Rs1 + Rs2_or_imm13; if(target & 0x3) @@ -1053,31 +1226,22 @@ decode OP default Unknown::unknown() 0x0: Trap::tcci({{ if(passesCondition(Ccr<3:0>, COND2)) { -#if FULL_SYSTEM int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); fault = new TrapInstruction(lTrapNum); -#else - DPRINTF(Sparc, "The syscall number is %d\n", R1); - xc->syscall(R1); -#endif } }}, IsSerializeAfter, IsNonSpeculative); 0x2: Trap::tccx({{ if(passesCondition(Ccr<7:4>, COND2)) { -#if FULL_SYSTEM int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); fault = new TrapInstruction(lTrapNum); -#else - DPRINTF(Sparc, "The syscall number is %d\n", R1); - xc->syscall(R1); -#endif } }}, IsSerializeAfter, IsNonSpeculative); } - 0x3B: Nop::flush({{/*Instruction memory flush*/}}); + 0x3B: Nop::flush({{/*Instruction memory flush*/}}, IsWriteBarrier, + MemWriteOp); 0x3C: save({{ if(Cansave == 0) { @@ -1151,16 +1315,18 @@ decode OP default Unknown::unknown() 0x01: ldub({{Rd = Mem.ub;}}); 0x02: lduh({{Rd = Mem.uhw;}}); 0x03: ldtw({{ - uint64_t val = Mem.udw; - RdLow = val<31:0>; - RdHigh = val<63:32>; + RdLow = (Mem.tuw).a; + RdHigh = (Mem.tuw).b; }}); } format Store { 0x04: stw({{Mem.uw = Rd.sw;}}); 0x05: stb({{Mem.ub = Rd.sb;}}); 0x06: sth({{Mem.uhw = Rd.shw;}}); - 0x07: sttw({{Mem.udw = RdLow<31:0> | (RdHigh<31:0> << 32);}}); + 0x07: sttw({{ + (Mem.tuw).a = RdLow<31:0>; + (Mem.tuw).b = RdHigh<31:0>; + }}); } format Load { 0x08: ldsw({{Rd = (int32_t)Mem.sw;}}); @@ -1168,15 +1334,17 @@ decode OP default Unknown::unknown() 0x0A: ldsh({{Rd = (int16_t)Mem.shw;}}); 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}}); } - 0x0D: LoadStore::ldstub( - {{uReg0 = Mem.ub;}}, - {{Rd.ub = uReg0; - Mem.ub = 0xFF;}}); + 0x0D: Swap::ldstub({{Mem.ub = 0xFF;}}, + {{ + uint8_t tmp = mem_data; + Rd.ub = tmp; + }}, MEM_SWAP); 0x0E: Store::stx({{Mem.udw = Rd}}); - 0x0F: LoadStore::swap( - {{ uReg0 = Mem.uw}}, - {{ Mem.uw = Rd.uw; - Rd.uw = uReg0;}}); + 0x0F: Swap::swap({{Mem.uw = Rd.uw}}, + {{ + uint32_t tmp = mem_data; + Rd.uw = tmp; + }}, MEM_SWAP); format LoadAlt { 0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}}); 0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}}); @@ -1184,38 +1352,63 @@ decode OP default Unknown::unknown() 0x13: decode EXT_ASI { //ASI_LDTD_AIUP 0x22: TwinLoad::ldtx_aiup( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTD_AIUS 0x23: TwinLoad::ldtx_aius( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_QUAD_LDD 0x24: TwinLoad::ldtx_quad_ldd( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_REAL 0x26: TwinLoad::ldtx_real( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); - //ASI_LDTX_N - 0x27: TwinLoad::ldtx_n( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); - //ASI_LDTX_L - 0x2C: TwinLoad::ldtx_l( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_N + 0x27: TwinLoad::ldtx_n( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_AIUP_L + 0x2A: TwinLoad::ldtx_aiup_l( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_AIUS_L + 0x2B: TwinLoad::ldtx_aius_l( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_L + 0x2C: TwinLoad::ldtx_l( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_REAL_L 0x2E: TwinLoad::ldtx_real_l( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_N_L 0x2F: TwinLoad::ldtx_n_l( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_P 0xE2: TwinLoad::ldtx_p( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_S 0xE3: TwinLoad::ldtx_s( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_PL + 0xEA: TwinLoad::ldtx_pl( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_SL + 0xEB: TwinLoad::ldtx_sl( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); default: ldtwa({{ - uint64_t val = Mem.udw; - RdLow = val<31:0>; - RdHigh = val<63:32>; + RdLow = (Mem.tuw).a; + RdHigh = (Mem.tuw).b; }}, {{EXT_ASI}}); } } @@ -1223,7 +1416,10 @@ decode OP default Unknown::unknown() 0x14: stwa({{Mem.uw = Rd;}}, {{EXT_ASI}}); 0x15: stba({{Mem.ub = Rd;}}, {{EXT_ASI}}); 0x16: stha({{Mem.uhw = Rd;}}, {{EXT_ASI}}); - 0x17: sttwa({{Mem.udw = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{EXT_ASI}}); + 0x17: sttwa({{ + (Mem.tuw).a = RdLow<31:0>; + (Mem.tuw).b = RdHigh<31:0>; + }}, {{EXT_ASI}}); } format LoadAlt { 0x18: ldswa({{Rd = (int32_t)Mem.sw;}}, {{EXT_ASI}}); @@ -1231,15 +1427,18 @@ decode OP default Unknown::unknown() 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}, {{EXT_ASI}}); 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}}); } - 0x1D: LoadStoreAlt::ldstuba( - {{uReg0 = Mem.ub;}}, - {{Rd.ub = uReg0; - Mem.ub = 0xFF;}}, {{EXT_ASI}}); + 0x1D: SwapAlt::ldstuba({{Mem.ub = 0xFF;}}, + {{ + uint8_t tmp = mem_data; + Rd.ub = tmp; + }}, {{EXT_ASI}}, MEM_SWAP); 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}}); - 0x1F: LoadStoreAlt::swapa( - {{ uReg0 = Mem.uw}}, - {{ Mem.uw = Rd.uw; - Rd.uw = uReg0;}}, {{EXT_ASI}}); + 0x1F: SwapAlt::swapa({{Mem.uw = Rd.uw}}, + {{ + uint32_t tmp = mem_data; + Rd.uw = tmp; + }}, {{EXT_ASI}}, MEM_SWAP); + format Trap { 0x20: Load::ldf({{Frds.uw = Mem.uw;}}); 0x21: decode RD { @@ -1438,21 +1637,17 @@ decode OP default Unknown::unknown() {{fault = new DataAccessException;}}); } } - 0x3C: Cas::casa( - {{uReg0 = Mem.uw;}}, - {{if(Rs2.uw == uReg0) - Mem.uw = Rd.uw; - else - storeCond = false; - Rd.uw = uReg0;}}, {{EXT_ASI}}); + 0x3C: CasAlt::casa({{ + mem_data = htog(Rs2.uw); + Mem.uw = Rd.uw;}}, + {{ + uint32_t tmp = mem_data; + Rd.uw = tmp; + }}, {{EXT_ASI}}, MEM_SWAP_COND); 0x3D: Nop::prefetcha({{ }}); - 0x3E: Cas::casxa( - {{uReg0 = Mem.udw;}}, - {{if(Rs2 == uReg0) - Mem.udw = Rd; - else - storeCond = false; - Rd = uReg0;}}, {{EXT_ASI}}); + 0x3E: CasAlt::casxa({{mem_data = gtoh(Rs2); + Mem.udw = Rd.udw; }}, + {{ Rd.udw = mem_data; }}, {{EXT_ASI}}, MEM_SWAP_COND); } } } diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa index 5cd3ab598..f5ab940bb 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.isa @@ -40,7 +40,7 @@ output header {{ { protected: // Constructor - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : + Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) { } @@ -56,7 +56,7 @@ output header {{ { protected: // Constructor - BranchDisp(const char *mnem, MachInst _machInst, + BranchDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : Branch(mnem, _machInst, __opClass) { @@ -76,7 +76,7 @@ output header {{ { protected: // Constructor - BranchNBits(const char *mnem, MachInst _machInst, + BranchNBits(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : BranchDisp(mnem, _machInst, __opClass) { @@ -91,7 +91,7 @@ output header {{ { protected: // Constructor - BranchSplit(const char *mnem, MachInst _machInst, + BranchSplit(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : BranchDisp(mnem, _machInst, __opClass) { @@ -107,7 +107,7 @@ output header {{ { protected: // Constructor - BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : + BranchImm13(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) { } diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index 1d9075a57..751262811 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.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 @@ -52,22 +52,20 @@ def template MemDeclare {{ }}; let {{ - def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags): + def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''): addrCalcReg = 'EA = Rs1 + Rs2;' addrCalcImm = 'EA = Rs1 + imm;' iop = InstObjParams(name, Name, 'Mem', - {"code": code, "fault_check": faultCode, - "ea_code": addrCalcReg}, - opt_flags) + {"code": code, "postacc_code" : postacc_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) + {"code": code, "postacc_code" : postacc_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", + exec_output = doDualSplitExecute(code, postacc_code, addrCalcReg, + addrCalcImm, execute, faultCode, name, name + "Imm", Name, Name + "Imm", asi, opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; @@ -103,3 +101,13 @@ def format Store(code, *opt_flags) {{ decode_block) = doMemFormat(code, StoreFuncs, '', name, Name, 0, opt_flags) }}; + +def format TwinLoad(code, asi, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, LoadFuncs, + AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck, + name, Name, asi, opt_flags) +}}; + diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 9795d2342..499685a5c 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -91,65 +91,6 @@ output header {{ }; }}; -output header {{ - - class TwinMem : public SparcMacroInst - { - protected: - - // Constructor - // We make the assumption that all block memory operations - // Will take 8 instructions to execute - TwinMem(const char *mnem, ExtMachInst _machInst) : - SparcMacroInst(mnem, _machInst, No_OpClass, 2) - {} - }; - - class TwinMemImm : public BlockMem - { - protected: - - // Constructor - TwinMemImm(const char *mnem, ExtMachInst _machInst) : - BlockMem(mnem, _machInst) - {} - }; - - class TwinMemMicro : public SparcMicroInst - { - protected: - - // Constructor - TwinMemMicro(const char *mnem, ExtMachInst _machInst, - OpClass __opClass, int8_t _offset) : - SparcMicroInst(mnem, _machInst, __opClass), - offset(_offset) - {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - const int8_t offset; - }; - - class TwinMemImmMicro : public BlockMemMicro - { - protected: - - // Constructor - TwinMemImmMicro(const char *mnem, ExtMachInst _machInst, - OpClass __opClass, int8_t _offset) : - BlockMemMicro(mnem, _machInst, __opClass, _offset), - imm(sext<13>(SIMM13)) - {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - const int32_t imm; - }; -}}; - output decoder {{ std::string BlockMemMicro::generateDisassembly(Addr pc, const SymbolTable *symtab) const @@ -208,64 +149,6 @@ output decoder {{ }}; -output decoder {{ - std::string TwinMemMicro::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - bool load = flags[IsLoad]; - bool save = flags[IsStore]; - - printMnemonic(response, mnemonic); - if(save) - { - printReg(response, _srcRegIdx[0]); - ccprintf(response, ", "); - } - ccprintf(response, "[ "); - printReg(response, _srcRegIdx[!save ? 0 : 1]); - ccprintf(response, " + "); - printReg(response, _srcRegIdx[!save ? 1 : 2]); - ccprintf(response, " ]"); - if(load) - { - ccprintf(response, ", "); - printReg(response, _destRegIdx[0]); - } - - return response.str(); - } - - std::string TwinMemImmMicro::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - bool load = flags[IsLoad]; - bool save = flags[IsStore]; - - printMnemonic(response, mnemonic); - if(save) - { - printReg(response, _srcRegIdx[1]); - ccprintf(response, ", "); - } - ccprintf(response, "[ "); - printReg(response, _srcRegIdx[0]); - if(imm >= 0) - ccprintf(response, " + 0x%x ]", imm); - else - ccprintf(response, " + -0x%x ]", -imm); - if(load) - { - ccprintf(response, ", "); - printReg(response, _destRegIdx[0]); - } - - return response.str(); - } - -}}; - def template BlockMemDeclare {{ /** * Static instruction class for a block memory operation @@ -359,39 +242,6 @@ def template BlockMemDeclare {{ }; }}; -def template TwinMemDeclare {{ - /** - * Static instruction class for a block memory operation - */ - class %(class_name)s : public %(base_class)s - { - public: - //Constructor - %(class_name)s(ExtMachInst machInst); - - protected: - class %(class_name)s_0 : public %(base_class)sMicro - { - public: - //Constructor - %(class_name)s_0(ExtMachInst machInst); - %(BasicExecDeclare)s - %(InitiateAccDeclare)s - %(CompleteAccDeclare)s - }; - - class %(class_name)s_1 : public %(base_class)sMicro - { - public: - //Constructor - %(class_name)s_1(ExtMachInst machInst); - %(BasicExecDeclare)s - %(InitiateAccDeclare)s - %(CompleteAccDeclare)s - }; - }; -}}; - // Basic instruction class constructor template. def template BlockMemConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) @@ -409,17 +259,6 @@ def template BlockMemConstructor {{ } }}; -// Basic instruction class constructor template. -def template TwinMemConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst) - { - %(constructor)s; - microOps[0] = new %(class_name)s_0(machInst); - microOps[1] = new %(class_name)s_1(machInst); - } -}}; - def template BlockMemMicroConstructor {{ inline %(class_name)s:: %(class_name)s_%(micro_pc)s:: @@ -467,47 +306,7 @@ let {{ decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) exec_output += doDualSplitExecute( - pcedCode, addrCalcReg, addrCalcImm, execute, faultCode, - makeMicroName(name, microPc), - makeMicroName(name + "Imm", microPc), - makeMicroName(Name, microPc), - makeMicroName(Name + "Imm", microPc), - asi, opt_flags); - 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;' - iop = InstObjParams(name, Name, 'TwinMem', code, opt_flags) - iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', code, opt_flags) - header_output = TwinMemDeclare.subst(iop) + TwinMemDeclare.subst(iop_imm) - decoder_output = TwinMemConstructor.subst(iop) + TwinMemConstructor.subst(iop_imm) - decode_block = ROrImmDecode.subst(iop) - matcher = re.compile(r'RdTwin') - exec_output = '' - for microPc in range(2): - flag_code = '' - pcedCode = '' - if (microPc == 1): - flag_code = "flags[IsLastMicroOp] = true;" - pcedCode = "RdLow = uReg0;\n" - pcedCode += matcher.sub("RdHigh", code) - else: - flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" - pcedCode = matcher.sub("uReg0", code) - iop = InstObjParams(name, Name, 'TwinMem', - {"code": pcedCode, "ea_code": addrCalcReg, - "fault_check": faultCode, "micro_pc": microPc, - "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}, opt_flags) - decoder_output += BlockMemMicroConstructor.subst(iop) - decoder_output += BlockMemMicroConstructor.subst(iop_imm) - exec_output += doDualSplitExecute( - pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode, + pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), makeMicroName(Name, microPc), @@ -515,7 +314,6 @@ let {{ asi, opt_flags); faultCode = '' return (header_output, decoder_output, exec_output, decode_block) - }}; def format BlockLoad(code, asi, *opt_flags) {{ @@ -541,11 +339,3 @@ def format BlockStore(code, asi, *opt_flags) {{ decode_block) = doBlockMemFormat(code, faultCode, StoreFuncs, name, Name, asi, opt_flags) }}; - -def format TwinLoad(code, asi, *opt_flags) {{ - faultCode = AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck - (header_output, - decoder_output, - exec_output, - decode_block) = doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags) -}}; diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa index fedece2b8..db45e226d 100644 --- a/src/arch/sparc/isa/formats/mem/mem.isa +++ b/src/arch/sparc/isa/formats/mem/mem.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 @@ -42,4 +42,4 @@ ##include "blockmem.isa" //Include the load/store and cas memory format -##include "loadstore.isa" +##include "swap.isa" diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa new file mode 100644 index 000000000..818597a84 --- /dev/null +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -0,0 +1,183 @@ +// Copyright (c) 2007 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black +// Ali Saidi + +//This template provides the execute functions for a swap +def template SwapExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + //This is to support the conditional store in cas instructions. + //It should be optomized out in all the others + bool storeCond = true; + Addr EA; + %(fp_enable_check)s; + %(op_decl)s; + uint64_t mem_data; + + %(op_rd)s; + %(ea_code)s; + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); + %(fault_check)s; + if(fault == NoFault) + { + %(code)s; + } + if(storeCond && fault == NoFault) + { + fault = xc->write((uint%(mem_acc_size)s_t)Mem, + EA, %(asi_val)s, &mem_data); + } + if(fault == NoFault) + { + //Handle the swapping + %(postacc_code)s; + } + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } +}}; + + +def template SwapInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, + Trace::InstRecord * traceData) const + { + Fault fault = NoFault; + Addr EA; + %(fp_enable_check)s; + uint64_t mem_data = 0; + %(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) + { + %(code)s; + } + if(fault == NoFault) + { + fault = xc->write((uint%(mem_acc_size)s_t)Mem, + EA, %(asi_val)s, &mem_data); + } + return fault; + } +}}; + + + +def template SwapCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, + Trace::InstRecord * traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + + uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>(); + + if(fault == NoFault) + { + //Handle the swapping + %(postacc_code)s; + } + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } +}}; + +let {{ + SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc] +}}; + + +def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ + mem_flags = makeList(mem_flags) + flags = string.join(mem_flags, '|') + + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags, + opt_flags, postacc_code) +}}; + +def format SwapAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ + mem_flags = makeList(mem_flags) + mem_flags.append(asi) + flags = string.join(mem_flags, '|') + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck, + name, Name, flags, opt_flags, postacc_code) +}}; + + +let {{ + def doCasFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''): + addrCalcReg = 'EA = Rs1;' + iop = InstObjParams(name, Name, 'Mem', + {"code": code, "postacc_code" : postacc_code, + "fault_check": faultCode, "ea_code": addrCalcReg}, opt_flags) + header_output = MemDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + microParams = {"code": code, "postacc_code" : postacc_code, + "ea_code" : addrCalcReg, "fault_check" : faultCode} + exec_output = doSplitExecute(execute, name, Name, asi, opt_flags, + microParams); + return (header_output, decoder_output, exec_output, decode_block) +}}; + + +def format CasAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ + mem_flags = makeList(mem_flags) + mem_flags.append(asi) + flags = string.join(mem_flags, '|') + (header_output, + decoder_output, + exec_output, + decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck, + name, Name, flags, opt_flags, postacc_code) +}}; + + diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index dbaabdca4..dfe937371 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -149,7 +149,7 @@ def template LoadExecute {{ %(fault_check)s; if(fault == NoFault) { - fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); + fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s); } if(fault == NoFault) { @@ -179,7 +179,7 @@ def template LoadInitiateAcc {{ %(fault_check)s; if(fault == NoFault) { - fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); + fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s); } return fault; } @@ -224,7 +224,7 @@ def template StoreExecute {{ } if(storeCond && fault == NoFault) { - fault = xc->write((uint%(mem_acc_size)s_t)Mem, + fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, EA, %(asi_val)s, 0); } if(fault == NoFault) @@ -246,6 +246,7 @@ def template StoreInitiateAcc {{ Addr EA; %(fp_enable_check)s; %(op_decl)s; + %(op_rd)s; %(ea_code)s; DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); @@ -256,7 +257,7 @@ def template StoreInitiateAcc {{ } if(storeCond && fault == NoFault) { - fault = xc->write((uint%(mem_acc_size)s_t)Mem, + fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, EA, %(asi_val)s, 0); } if(fault == NoFault) @@ -290,6 +291,7 @@ def template CompleteAccDeclare {{ 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 = ''' @@ -337,14 +339,14 @@ let {{ return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) - def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, + def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute, faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags): executeCode = '' for (eaCode, name, Name) in ( (eaRegCode, nameReg, NameReg), (eaImmCode, nameImm, NameImm)): - microParams = {"code": code, "ea_code": eaCode, - "fault_check": faultCode} + microParams = {"code": code, "postacc_code" : postacc_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/includes.isa b/src/arch/sparc/isa/includes.isa index d2ef67154..05e9e8731 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -70,10 +70,15 @@ output exec {{ #include <ieeefp.h> #endif +#if FULL_SYSTEM +#include "sim/pseudo_inst.hh" +#endif + #include <limits> #include <cmath> #include "arch/sparc/asi.hh" +#include "base/bigint.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "sim/sim_exit.hh" diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 140055010..038919bd1 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -37,6 +37,8 @@ def operand_types {{ 'uw' : ('unsigned int', 32), 'sdw' : ('signed int', 64), 'udw' : ('unsigned int', 64), + 'tudw' : ('twin64 int', 64), + 'tuw' : ('twin32 int', 32), 'sf' : ('float', 32), 'df' : ('float', 64), 'qf' : ('float', 128) @@ -99,6 +101,12 @@ def operands {{ 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), + 'O0': ('IntReg', 'udw', '8', 'IsInteger', 10), + 'O1': ('IntReg', 'udw', '9', 'IsInteger', 11), + 'O2': ('IntReg', 'udw', '10', 'IsInteger', 12), + 'O3': ('IntReg', 'udw', '11', 'IsInteger', 13), + 'O4': ('IntReg', 'udw', '12', 'IsInteger', 14), + 'O5': ('IntReg', 'udw', '13', 'IsInteger', 15), # Control registers # 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), |