diff options
Diffstat (limited to 'arch/alpha/isa_desc')
-rw-r--r-- | arch/alpha/isa_desc | 231 |
1 files changed, 108 insertions, 123 deletions
diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index f964101df..080699ddb 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -811,7 +811,7 @@ output header {{ public: /// Constructor EACompBase(MachInst machInst) - : AlphaStaticInst("(eacomp)", machInst, IntALU) + : AlphaStaticInst("(eacomp)", machInst, IntAluOp) { } @@ -1072,7 +1072,7 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ # Declare the prefetch instruction object. # convert flags from tuple to list to make them mutable - pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'RdPort'] + pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ LoadStoreBase(name, Name + 'Prefetch', ea_code, '', @@ -1374,8 +1374,8 @@ output decoder {{ } }}; -def format EmulatedCallPal(code) {{ - iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code)) +def format EmulatedCallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -1436,8 +1436,8 @@ output decoder {{ } }}; -def format CallPal(code) {{ - iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code)) +def format CallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -1588,6 +1588,9 @@ output header {{ FailUnimplemented(const char *_mnemonic, MachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1615,6 +1618,9 @@ output header {{ WarnUnimplemented(const char *_mnemonic, MachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1646,9 +1652,8 @@ output exec {{ FailUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - panic("attempt to execute unimplemented instruction '%s' " - "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); return Unimplemented_Opcode_Fault; } @@ -1656,42 +1661,24 @@ output exec {{ WarnUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - if (!warned) { - warn("instruction '%s' unimplemented\n", mnemonic); - warned = true; - } + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } return No_Fault; } }}; -def template WarnUnimplDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - public: - /// Constructor - %(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst) - { - } - }; -}}; - - def format FailUnimpl() {{ iop = InstObjParams(name, 'FailUnimplemented') decode_block = BasicDecodeWithMnemonic.subst(iop) }}; def format WarnUnimpl() {{ - iop = InstObjParams(name, Name, 'WarnUnimplemented') - header_output = WarnUnimplDeclare.subst(iop) - decode_block = BasicDecode.subst(iop) + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) }}; output header {{ @@ -1707,6 +1694,9 @@ output header {{ Unknown(MachInst _machInst) : AlphaStaticInst("unknown", _machInst, No_OpClass) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1733,9 +1723,8 @@ output exec {{ Fault Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - panic("attempt to execute unknown instruction " - "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); return Unimplemented_Opcode_Fault; } }}; @@ -2094,13 +2083,13 @@ decode OPCODE default Unknown::unknown() { } 0x13: decode INTFUNC { // integer multiplies - 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMULT); - 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMULT); + 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); + 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); 0x30: umulh({{ uint64_t hi, lo; mul128(Ra, Rb_or_imm, hi, lo); Rc = hi; - }}, IntMULT); + }}, IntMultOp); 0x40: mullv({{ // 32-bit multiply with trap on overflow int64_t Rax = Ra.sl; // sign extended version of Ra.sl @@ -2113,7 +2102,7 @@ decode OPCODE default Unknown::unknown() { if (sign_bits != 0 && sign_bits != mask(33)) fault = Integer_Overflow_Fault; Rc.sl = tmp<31:0>; - }}, IntMULT); + }}, IntMultOp); 0x60: mulqv({{ // 64-bit multiply with trap on overflow uint64_t hi, lo; @@ -2124,18 +2113,40 @@ decode OPCODE default Unknown::unknown() { (hi == mask(64) && lo<63:> == 1))) fault = Integer_Overflow_Fault; Rc = lo; - }}, IntMULT); + }}, IntMultOp); } 0x1c: decode INTFUNC { 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } + 0x32: ctlz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (temp<63:32>) temp >>= 32; else count += 32; + if (temp<31:16>) temp >>= 16; else count += 16; + if (temp<15:8>) temp >>= 8; else count += 8; + if (temp<7:4>) temp >>= 4; else count += 4; + if (temp<3:2>) temp >>= 2; else count += 2; + if (temp<1:1>) temp >>= 1; else count += 1; + if ((temp<0:0>) != 0x1) count += 1; + Rc = count; + }}, IntAluOp); + + 0x33: cttz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (!(temp<31:0>)) { temp >>= 32; count += 32; } + if (!(temp<15:0>)) { temp >>= 16; count += 16; } + if (!(temp<7:0>)) { temp >>= 8; count += 8; } + if (!(temp<3:0>)) { temp >>= 4; count += 4; } + if (!(temp<1:0>)) { temp >>= 2; count += 2; } + if (!(temp<0:0> & ULL(0x1))) count += 1; + Rc = count; + }}, IntAluOp); format FailUnimpl { 0x30: ctpop(); 0x31: perr(); - 0x32: ctlz(); - 0x33: cttz(); 0x34: unpkbw(); 0x35: unpkbl(); 0x36: pkwb(); @@ -2152,11 +2163,11 @@ decode OPCODE default Unknown::unknown() { format BasicOperateWithNopCheck { 0x70: decode RB { - 31: ftoit({{ Rc = Fa.uq; }}, FloatCVT); + 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); } 0x78: decode RB { 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, - FloatCVT); + FloatCvtOp); } } } @@ -2203,8 +2214,8 @@ decode OPCODE default Unknown::unknown() { 0x4: decode RB { 31: decode FP_FULLFUNC { format BasicOperateWithNopCheck { - 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCVT); - 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCVT); + 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); + 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); 0x014: FailUnimpl::itoff(); // VAX-format conversion } } @@ -2219,19 +2230,19 @@ decode OPCODE default Unknown::unknown() { if (Fb < 0.0) fault = Arithmetic_Fault; Fc = sqrt(Fb); - }}, FloatSQRT); + }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) fault = Arithmetic_Fault; Fc.sf = sqrt(Fb.sf); - }}, FloatSQRT); + }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) fault = Arithmetic_Fault; Fc = sqrt(Fb); - }}, FloatSQRT); + }}, FloatSqrtOp); } } } @@ -2257,19 +2268,19 @@ decode OPCODE default Unknown::unknown() { #ifdef SS_COMPATIBLE_FP 0x00: adds({{ Fc = Fa + Fb; }}); 0x01: subs({{ Fc = Fa - Fb; }}); - 0x02: muls({{ Fc = Fa * Fb; }}, FloatMULT); - 0x03: divs({{ Fc = Fa / Fb; }}, FloatDIV); + 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); #else 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); - 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMULT); - 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDIV); + 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); + 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); #endif 0x20: addt({{ Fc = Fa + Fb; }}); 0x21: subt({{ Fc = Fa - Fb; }}); - 0x22: mult({{ Fc = Fa * Fb; }}, FloatMULT); - 0x23: divt({{ Fc = Fa / Fb; }}, FloatDIV); + 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); } } @@ -2283,14 +2294,14 @@ decode OPCODE default Unknown::unknown() { 1: decode FP_FULLFUNC { format BasicOperateWithNopCheck { 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, - FloatCMP); + FloatCmpOp); 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, - FloatCMP); + FloatCmpOp); 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, - FloatCMP); + FloatCmpOp); 0x0a4, 0x5a4: cmptun({{ // unordered Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; - }}, FloatCMP); + }}, FloatCmpOp); } } @@ -2382,7 +2393,7 @@ decode OPCODE default Unknown::unknown() { format MiscPrefetch { 0xf800: wh64({{ EA = Rb; }}, {{ xc->writeHint(EA, 64); }}, - IsMemRef, IsStore, WrPort); + IsMemRef, IsStore, MemWriteOp); } format BasicOperate { @@ -2412,24 +2423,20 @@ decode OPCODE default Unknown::unknown() { // them the same though. 0x0000: trapb({{ }}, IsSerializing, No_OpClass); 0x0400: excb({{ }}, IsSerializing, No_OpClass); - 0x4000: mb({{ }}, IsMemBarrier, RdPort); - 0x4400: wmb({{ }}, IsWriteBarrier, WrPort); + 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); + 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); } #ifdef FULL_SYSTEM format BasicOperate { 0xe000: rc({{ Ra = xc->readIntrFlag(); - if (!xc->misspeculating()) { - xc->setIntrFlag(0); - } - }}); + xc->setIntrFlag(0); + }}, IsNonSpeculative); 0xf000: rs({{ Ra = xc->readIntrFlag(); - if (!xc->misspeculating()) { - xc->setIntrFlag(1); - } - }}); + xc->setIntrFlag(1); + }}, IsNonSpeculative); } #else format FailUnimpl { @@ -2449,38 +2456,26 @@ decode OPCODE default Unknown::unknown() { fault = Unimplemented_Opcode_Fault; } else { - bool dopal = true; - - if (!xc->misspeculating()) { - // check to see if simulator wants to do something special - // on this PAL call (including maybe suppress it) - dopal = xc->simPalCheck(palFunc); - - if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - } - } + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); - // if we're misspeculating, it's still safe (if - // unrealistic) to set NPC, as the control-flow change - // won't get committed. if (dopal) { + AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); + xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } } - }}); + }}, IsNonSpeculative); #else 0x00: decode PALFUNC { format EmulatedCallPal { 0x00: halt ({{ - if (!xc->misspeculating()) - SimExit(curTick, "halt instruction encountered"); - }}); + SimExit(curTick, "halt instruction encountered"); + }}, IsNonSpeculative); 0x83: callsys({{ - if (!xc->misspeculating()) - xc->syscall(); - }}); + xc->syscall(); + }}, IsNonSpeculative); // Read uniq reg into ABI return value register (r0) 0x9e: rduniq({{ R0 = Runiq; }}); // Write uniq reg with value from ABI arg register (r16) @@ -2514,46 +2509,36 @@ decode OPCODE default Unknown::unknown() { // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { 0x00: arm({{ - if (!xc->misspeculating()) - AlphaPseudo::arm(xc->xcBase()); - }}); + AlphaPseudo::arm(xc->xcBase()); + }}, IsNonSpeculative); 0x01: quiesce({{ - if (!xc->misspeculating()) - AlphaPseudo::quiesce(xc->xcBase()); - }}); + AlphaPseudo::quiesce(xc->xcBase()); + }}, IsNonSpeculative); 0x10: ivlb({{ - if (!xc->misspeculating()) - AlphaPseudo::ivlb(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::ivlb(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x11: ivle({{ - if (!xc->misspeculating()) - AlphaPseudo::ivle(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::ivle(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x20: m5exit_old({{ - if (!xc->misspeculating()) - AlphaPseudo::m5exit_old(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::m5exit_old(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ - if (!xc->misspeculating()) - AlphaPseudo::m5exit(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::m5exit(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); 0x40: resetstats({{ - if (!xc->misspeculating()) - AlphaPseudo::resetstats(xc->xcBase()); - }}); + AlphaPseudo::resetstats(xc->xcBase()); + }}, IsNonSpeculative); 0x41: dumpstats({{ - if (!xc->misspeculating()) - AlphaPseudo::dumpstats(xc->xcBase()); - }}); + AlphaPseudo::dumpstats(xc->xcBase()); + }}, IsNonSpeculative); 0x42: dumpresetstats({{ - if (!xc->misspeculating()) - AlphaPseudo::dumpresetstats(xc->xcBase()); - }}); + AlphaPseudo::dumpresetstats(xc->xcBase()); + }}, IsNonSpeculative); 0x43: m5checkpoint({{ - if (!xc->misspeculating()) - AlphaPseudo::m5checkpoint(xc->xcBase()); - }}); + AlphaPseudo::m5checkpoint(xc->xcBase()); + }}, IsNonSpeculative); } } |