diff options
Diffstat (limited to 'arch')
27 files changed, 1332 insertions, 341 deletions
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 8dda4d9c4..615ce92a4 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -303,7 +303,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const } -Fault +Fault * AlphaITB::translate(MemReqPtr &req) const { InternalProcReg *ipr = req->xc->regs.ipr; @@ -312,7 +312,7 @@ AlphaITB::translate(MemReqPtr &req) const // strip off PAL PC marker (lsb is 1) req->paddr = (req->vaddr & ~3) & PAddrImplMask; hits++; - return No_Fault; + return NoFault; } if (req->flags & PHYSICAL) { @@ -322,7 +322,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!validVirtualAddress(req->vaddr)) { fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } @@ -339,7 +339,7 @@ AlphaITB::translate(MemReqPtr &req) const AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -360,7 +360,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!pte) { fault(req->vaddr, req->xc); misses++; - return ITB_Fault_Fault; + return ItbPageFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -371,7 +371,7 @@ AlphaITB::translate(MemReqPtr &req) const // instruction access fault fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } hits++; @@ -380,11 +380,11 @@ AlphaITB::translate(MemReqPtr &req) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return Machine_Check_Fault; + return MachineCheckFault; checkCacheability(req); - return No_Fault; + return NoFault; } /////////////////////////////////////////////////////////////////////// @@ -493,7 +493,7 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const } } -Fault +Fault * AlphaDTB::translate(MemReqPtr &req, bool write) const { RegFile *regs = &req->xc->regs; @@ -511,7 +511,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); - return Alignment_Fault; + return AlignmentFault; } if (pc & 0x1) { @@ -530,7 +530,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } - return DTB_Fault_Fault; + return DtbPageFault; } // Check for "superpage" mapping @@ -547,7 +547,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } - return DTB_Acv_Fault; + return DtbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -575,7 +575,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } - return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; + return (req->flags & VPTE) ? (Fault *)PDtbMissFault : (Fault *)NDtbMissFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -588,25 +588,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } if (pte->fonw) { fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); write_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } } else { if (!(pte->xre & MODE2MASK(mode))) { fault(req, MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; - return DTB_Acv_Fault; + return DtbAcvFault; } if (pte->fonr) { fault(req, MM_STAT_FONR_MASK); read_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } } } @@ -619,11 +619,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return Machine_Check_Fault; + return MachineCheckFault; checkCacheability(req); - return No_Fault; + return NoFault; } AlphaISA::PTE & diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 788923434..849063f59 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -32,6 +32,7 @@ #include <map> #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/faults.hh" #include "base/statistics.hh" #include "mem/mem_req.hh" #include "sim/sim_object.hh" @@ -93,7 +94,7 @@ class AlphaITB : public AlphaTLB AlphaITB(const std::string &name, int size); virtual void regStats(); - Fault translate(MemReqPtr &req) const; + Fault * translate(MemReqPtr &req) const; }; class AlphaDTB : public AlphaTLB @@ -119,7 +120,7 @@ class AlphaDTB : public AlphaTLB AlphaDTB(const std::string &name, int size); virtual void regStats(); - Fault translate(MemReqPtr &req, bool write) const; + Fault * translate(MemReqPtr &req, bool write) const; }; #endif // __ALPHA_MEMORY_HH__ diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 125affd03..72f48bfb2 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -76,7 +76,7 @@ AlphaISA::initCPU(RegFile *regs) // CPU comes up with PAL regs enabled swap_palshadow(regs, true); - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; + regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); regs->npc = regs->pc + sizeof(MachInst); } @@ -84,25 +84,15 @@ AlphaISA::initCPU(RegFile *regs) // // alpha exceptions - value equals trap address, update with MD_FAULT_TYPE // -Addr -AlphaISA::fault_addr[Num_Faults] = { - 0x0000, /* No_Fault */ - 0x0001, /* Reset_Fault */ - 0x0401, /* Machine_Check_Fault */ - 0x0501, /* Arithmetic_Fault */ - 0x0101, /* Interrupt_Fault */ - 0x0201, /* Ndtb_Miss_Fault */ - 0x0281, /* Pdtb_Miss_Fault */ - 0x0301, /* Alignment_Fault */ - 0x0381, /* DTB_Fault_Fault */ - 0x0381, /* DTB_Acv_Fault */ - 0x0181, /* ITB_Miss_Fault */ - 0x0181, /* ITB_Fault_Fault */ - 0x0081, /* ITB_Acv_Fault */ - 0x0481, /* Unimplemented_Opcode_Fault */ - 0x0581, /* Fen_Fault */ - 0x2001, /* Pal_Fault */ - 0x0501, /* Integer_Overflow_Fault: maps to Arithmetic_Fault */ +const Addr +AlphaISA::fault_addr(Fault * fault) +{ + //Check for the system wide faults + if(fault == NoFault) return 0x0000; + else if(fault == MachineCheckFault) return 0x0401; + else if(fault == AlignmentFault) return 0x0301; + //Deal with the alpha specific faults + return ((AlphaFault*)fault)->vect; }; const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { @@ -168,7 +158,7 @@ AlphaISA::processInterrupts(CPU *cpu) if (ipl && ipl > ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - cpu->trap(Interrupt_Fault); + cpu->trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); } @@ -187,25 +177,25 @@ AlphaISA::zeroRegisters(CPU *cpu) } void -ExecContext::ev5_trap(Fault fault) +ExecContext::ev5_trap(Fault * fault) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", FaultName(fault), regs.pc); - cpu->recordEvent(csprintf("Fault %s", FaultName(fault))); + DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); + cpu->recordEvent(csprintf("Fault %s", fault->name)); assert(!misspeculating()); kernelStats->fault(fault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); AlphaISA::InternalProcReg *ipr = regs.ipr; // exception restart address - if (fault != Interrupt_Fault || !inPalMode()) + if (fault != InterruptFault || !inPalMode()) ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; - if (fault == Pal_Fault || fault == Arithmetic_Fault /* || - fault == Interrupt_Fault && !inPalMode() */) { + if (fault == PalFault || fault == ArithmeticFault /* || + fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; } @@ -213,22 +203,22 @@ ExecContext::ev5_trap(Fault fault) if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; + regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); regs.npc = regs.pc + sizeof(MachInst); } void -AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) +AlphaISA::intr_post(RegFile *regs, Fault * fault, Addr pc) { InternalProcReg *ipr = regs->ipr; - bool use_pc = (fault == No_Fault); + bool use_pc = (fault == NoFault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("arithmetic faults NYI..."); // compute exception restart address - if (use_pc || fault == Pal_Fault || fault == Arithmetic_Fault) { + if (use_pc || fault == PalFault || fault == ArithmeticFault) { // traps... skip faulting instruction ipr[IPR_EXC_ADDR] = regs->pc + 4; } else { @@ -238,20 +228,20 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr[fault]; + regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); else regs->npc = ipr[IPR_PAL_BASE] + pc; // that's it! (orders of magnitude less painful than x86) } -Fault +Fault * ExecContext::hwrei() { uint64_t *ipr = regs.ipr; if (!inPalMode()) - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -265,11 +255,11 @@ ExecContext::hwrei() } // FIXME: XXX check for interrupts? XXX - return No_Fault; + return NoFault; } uint64_t -ExecContext::readIpr(int idx, Fault &fault) +ExecContext::readIpr(int idx, Fault * &fault) { uint64_t *ipr = regs.ipr; uint64_t retval = 0; // return value, default 0 @@ -363,12 +353,12 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; default: // invalid IPR - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; } @@ -380,14 +370,14 @@ ExecContext::readIpr(int idx, Fault &fault) int break_ipl = -1; #endif -Fault +Fault * ExecContext::setIpr(int idx, uint64_t val) { uint64_t *ipr = regs.ipr; uint64_t old; if (misspeculating()) - return No_Fault; + return NoFault; switch (idx) { case AlphaISA::IPR_PALtemp0: @@ -533,7 +523,7 @@ ExecContext::setIpr(int idx, uint64_t val) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -635,11 +625,11 @@ ExecContext::setIpr(int idx, uint64_t val) default: // invalid IPR - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } // no error... - return No_Fault; + return NoFault; } /** diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 3aecf029d..e05b3fe59 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,34 +28,53 @@ #include "arch/alpha/faults.hh" -namespace { - const char * - fault_name[Num_Faults] = { - "none", - "reset", - "mchk", - "arith", - "interrupt", - "dtb_miss_single", - "dtb_miss_double", - "unalign", - "dfault", - "dfault", - "itbmiss", - "itbmiss", - "iaccvio", - "opdec", - "fen", - "pal", - }; -} +ResetFaultType * const ResetFault = + new ResetFaultType("reset", 1, 0x0001); +ArithmeticFaultType * const ArithmeticFault = + new ArithmeticFaultType("arith", 3, 0x0501); +InterruptFaultType * const InterruptFault = + new InterruptFaultType("interrupt", 4, 0x0101); +NDtbMissFaultType * const NDtbMissFault = + new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); +PDtbMissFaultType * const PDtbMissFault = + new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); +DtbPageFaultType * const DtbPageFault = + new DtbPageFaultType("dfault", 8, 0x0381); +DtbAcvFaultType * const DtbAcvFault = + new DtbAcvFaultType("dfault", 9, 0x0381); +ItbMissFaultType * const ItbMissFault = + new ItbMissFaultType("itbmiss", 10, 0x0181); +ItbPageFaultType * const ItbPageFault = + new ItbPageFaultType("itbmiss", 11, 0x0181); +ItbAcvFaultType * const ItbAcvFault = + new ItbAcvFaultType("iaccvio", 12, 0x0081); +UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault = + new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); +FloatEnableFaultType * const FloatEnableFault = + new FloatEnableFaultType("fen", 14, 0x0581); +PalFaultType * const PalFault = + new PalFaultType("pal", 15, 0x2001); +IntegerOverflowFaultType * const IntegerOverflowFault = + new IntegerOverflowFaultType("intover", 16, 0x0501); -const char * -FaultName(int index) -{ - if (index < 0 || index >= Num_Faults) - return 0; - - return fault_name[index]; -} +Fault ** ListOfFaults[] = { + (Fault **)&NoFault, + (Fault **)&ResetFault, + (Fault **)&MachineCheckFault, + (Fault **)&ArithmeticFault, + (Fault **)&InterruptFault, + (Fault **)&NDtbMissFault, + (Fault **)&PDtbMissFault, + (Fault **)&AlignmentFault, + (Fault **)&DtbPageFault, + (Fault **)&DtbAcvFault, + (Fault **)&ItbMissFault, + (Fault **)&ItbPageFault, + (Fault **)&ItbAcvFault, + (Fault **)&UnimplementedOpcodeFault, + (Fault **)&FloatEnableFault, + (Fault **)&PalFault, + (Fault **)&IntegerOverflowFault, + }; +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index bbac7cbf2..06605861a 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -26,32 +26,135 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __FAULTS_HH__ -#define __FAULTS_HH__ - -enum Fault { - No_Fault, - Reset_Fault, // processor reset - Machine_Check_Fault, // machine check (also internal S/W fault) - Arithmetic_Fault, // FP exception - Interrupt_Fault, // external interrupt - Ndtb_Miss_Fault, // DTB miss - Pdtb_Miss_Fault, // nested DTB miss - Alignment_Fault, // unaligned access - DTB_Fault_Fault, // DTB page fault - DTB_Acv_Fault, // DTB access violation - ITB_Miss_Fault, // ITB miss - ITB_Fault_Fault, // ITB page fault - ITB_Acv_Fault, // ITB access violation - Unimplemented_Opcode_Fault, // invalid/unimplemented instruction - Fen_Fault, // FP not-enabled fault - Pal_Fault, // call_pal S/W interrupt - Integer_Overflow_Fault, - Fake_Mem_Fault, - Num_Faults // number of faults +#ifndef __ALPHA_FAULTS_HH__ +#define __ALPHA_FAULTS_HH__ + +#include "sim/faults.hh" +#include "arch/isa_traits.hh" //For the Addr type + +class AlphaFault : public Fault +{ + public: + AlphaFault(char * newName, int newId, Addr newVect) + : Fault(newName, newId), vect(newVect) + {;} + + TheISA::Addr vect; }; -const char * -FaultName(int index); +extern class ResetFaultType : public AlphaFault +{ + public: + ResetFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ResetFault; + +extern class ArithmeticFaultType : public AlphaFault +{ + public: + ArithmeticFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ArithmeticFault; + +extern class InterruptFaultType : public AlphaFault +{ + public: + InterruptFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const InterruptFault; + +extern class NDtbMissFaultType : public AlphaFault +{ + public: + NDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const NDtbMissFault; + +extern class PDtbMissFaultType : public AlphaFault +{ + public: + PDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PDtbMissFault; + +extern class DtbPageFaultType : public AlphaFault +{ + public: + DtbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbPageFault; + +extern class DtbAcvFaultType : public AlphaFault +{ + public: + DtbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbAcvFault; + +extern class ItbMissFaultType : public AlphaFault +{ + public: + ItbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbMissFault; + +extern class ItbPageFaultType : public AlphaFault +{ + public: + ItbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbPageFault; + +extern class ItbAcvFaultType : public AlphaFault +{ + public: + ItbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbAcvFault; + +extern class UnimplementedOpcodeFaultType : public AlphaFault +{ + public: + UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const UnimplementedOpcodeFault; + +extern class FloatEnableFaultType : public AlphaFault +{ + public: + FloatEnableFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const FloatEnableFault; + +extern class PalFaultType : public AlphaFault +{ + public: + PalFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PalFault; + +extern class IntegerOverflowFaultType : public AlphaFault +{ + public: + IntegerOverflowFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const IntegerOverflowFault; + +extern Fault ** ListOfFaults[]; +extern int NumFaults; #endif // __FAULTS_HH__ diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index aff8571e9..37b15416b 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -98,7 +98,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp; }}); 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); @@ -110,7 +110,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = tmp; }}); 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); @@ -124,7 +124,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp; }}); 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); @@ -138,7 +138,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = tmp; }}); 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); @@ -299,7 +299,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = tmp<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp<31:0>; }}, IntMultOp); 0x60: mulqv({{ @@ -310,7 +310,7 @@ decode OPCODE default Unknown::unknown() { // the lower 64 if (!((hi == 0 && lo<63:> == 0) || (hi == mask(64) && lo<63:> == 1))) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = lo; }}, IntMultOp); } @@ -427,19 +427,19 @@ decode OPCODE default Unknown::unknown() { #if SS_COMPATIBLE_FP 0x0b: sqrts({{ if (Fb < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc.sf = sqrt(Fb.sf); }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); } @@ -570,7 +570,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = Fb.uq<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); }}); @@ -673,7 +673,7 @@ decode OPCODE default Unknown::unknown() { && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { // check to see if simulator wants to do something special @@ -729,7 +729,7 @@ decode OPCODE default Unknown::unknown() { 0x19: hw_mfpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { Ra = xc->readIpr(ipr_index, fault); @@ -738,7 +738,7 @@ decode OPCODE default Unknown::unknown() { 0x1d: hw_mtpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { xc->setIpr(ipr_index, Ra); diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 0abc814be..c718c5524 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -29,21 +29,21 @@ output exec {{ /// Check "FP enabled" machine status bit. Called when executing any FP /// instruction in full-system mode. - /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault - /// if not. Non-full-system mode: always returns No_Fault. + /// @retval Full-system mode: NoFault if FP is enabled, FenFault + /// if not. Non-full-system mode: always returns NoFault. #if FULL_SYSTEM - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc) { - Fault fault = No_Fault; // dummy... this ipr access should not fault + Fault * fault = NoFault; // dummy... this ipr access should not fault if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { - fault = Fen_Fault; + fault = FloatEnableFault; } return fault; } #else - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc) { - return No_Fault; + return NoFault; } #endif }}; @@ -199,7 +199,7 @@ output decoder {{ // FP instruction class execute method template. Handles non-standard // rounding modes. def template FloatingPointExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { if (trappingMode != Imprecise && !warnedOnTrapping) { @@ -208,7 +208,7 @@ def template FloatingPointExecute {{ warnedOnTrapping = true; } - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -230,7 +230,7 @@ def template FloatingPointExecute {{ %(code)s; #endif - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -242,7 +242,7 @@ def template FloatingPointExecute {{ // rounding mode control is needed. Like BasicExecute, but includes // check & warning for non-standard trapping mode. def template FPFixedRoundingExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { if (trappingMode != Imprecise && !warnedOnTrapping) { @@ -251,14 +251,14 @@ def template FPFixedRoundingExecute {{ warnedOnTrapping = true; } - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index ef4d83ce2..42fb29404 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -33,6 +33,7 @@ output header {{ #include "config/ss_compatible_fp.hh" #include "cpu/static_inst.hh" +#include "arch/alpha/faults.hh" #include "mem/mem_req.hh" // some constructors use MemReq flags }}; @@ -253,7 +254,7 @@ output decoder {{ // Declarations for execute() methods. def template BasicExecDeclare {{ - Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault * execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; // Basic instruction class declaration template. @@ -282,17 +283,17 @@ def template BasicConstructor {{ // Basic instruction class execute method template. def template BasicExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -377,10 +378,10 @@ output decoder {{ }}; output exec {{ - Fault + Fault * Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 45afd378c..df26a534d 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -164,9 +164,24 @@ def template LoadStoreDeclare {{ %(class_name)s(MachInst machInst); %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s }; }}; + +def template InitiateAccDeclare {{ + Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + def template LoadStoreConstructor {{ /** TODO: change op_class to AddrGenOp or something (requires * creating new member of OpClass enum in op_class.hh, updating @@ -193,19 +208,19 @@ def template LoadStoreConstructor {{ def template EACompExecute {{ - Fault + Fault * %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; xc->setEA(EA); } @@ -215,24 +230,24 @@ def template EACompExecute {{ }}; def template LoadMemAccExecute {{ - Fault + Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -242,23 +257,70 @@ def template LoadMemAccExecute {{ def template LoadExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template LoadInitiateAcc {{ + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault * %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_dest_decl)s; + + memcpy(&Mem, data, sizeof(Mem)); + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { %(op_wb)s; } @@ -268,12 +330,12 @@ def template LoadExecute {{ def template StoreMemAccExecute {{ - Fault + Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -281,21 +343,21 @@ def template StoreMemAccExecute {{ %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { %(code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } } - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -305,11 +367,11 @@ def template StoreMemAccExecute {{ def template StoreExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -317,21 +379,75 @@ def template StoreExecute {{ %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } } - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + +def template StoreInitiateAcc {{ + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_dest_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault * %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault * fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_dest_decl)s; + + memcpy(&write_result, data, sizeof(write_result)); + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { %(op_wb)s; } @@ -341,42 +457,63 @@ def template StoreExecute {{ def template MiscMemAccExecute {{ - Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { %(code)s; } - return No_Fault; + return NoFault; } }}; def template MiscExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - return No_Fault; + return NoFault; + } +}}; + +def template MiscInitiateAcc {{ + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + return NoFault; + } +}}; + + +def template MiscCompleteAcc {{ + Fault * %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + + return NoFault; } }}; @@ -437,6 +574,34 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # for the post-access code. memacc_iop.postacc_code = postacc_cblk.code + # generate InstObjParams for InitiateAcc, CompleteAcc object + # The code used depends on the template being used + if (exec_template_base == 'Load'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(memacc_code + postacc_code) + elif (exec_template_base == 'Store'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(postacc_code) + else: + initiateacc_cblk = '' + completeacc_cblk = '' + + initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, + inst_flags) + + completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, + inst_flags) + + if (exec_template_base == 'Load'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + elif (exec_template_base == 'Store'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + # generate InstObjParams for unified execution cblk = CodeBlock(ea_code + memacc_code + postacc_code) iop = InstObjParams(name, Name, base_class, cblk, inst_flags) @@ -455,13 +620,17 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # select templates memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') # (header_output, decoder_output, decode_block, exec_output) return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), decode_template.subst(iop), EACompExecute.subst(ea_iop) + memAccExecTemplate.subst(memacc_iop) - + fullExecTemplate.subst(iop)) + + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(initiateacc_iop) + + completeAccTemplate.subst(completeacc_iop)) }}; diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa index 767888157..ce8197708 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -105,16 +105,16 @@ output decoder {{ }}; output exec {{ - Fault + Fault * FailUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } - Fault + Fault * WarnUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { @@ -123,7 +123,7 @@ output exec {{ warned = true; } - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa index 6eba5b4f9..e7f8bc8db 100644 --- a/arch/alpha/isa/unknown.isa +++ b/arch/alpha/isa/unknown.isa @@ -36,13 +36,13 @@ output decoder {{ }}; output exec {{ - Fault + Fault * Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } }}; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a17cde49b..a6e34acbb 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -32,10 +32,11 @@ namespace LittleEndianGuest {} using namespace LittleEndianGuest; -#include "arch/alpha/faults.hh" +//#include "arch/alpha/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" #include "sim/host.hh" +#include "sim/faults.hh" class FastCPU; class FullCPU; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 030bb5a7c..bcef77ddf 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1138,6 +1138,7 @@ class Operand(object): # template must be careful not to use it if it doesn't apply. if self.isMem(): self.mem_acc_size = self.makeAccSize() + self.mem_acc_type = self.ctype # Finalize additional fields (primarily code fields). This step # is done separately since some of these fields may depend on the @@ -1150,13 +1151,17 @@ class Operand(object): if self.is_src: self.op_rd = self.makeRead() + self.op_src_decl = self.makeDecl() else: self.op_rd = '' + self.op_src_decl = '' if self.is_dest: self.op_wb = self.makeWrite() + self.op_dest_decl = self.makeDecl() else: self.op_wb = '' + self.op_dest_decl = '' def isMem(self): return 0 @@ -1589,6 +1594,14 @@ class CodeBlock: self.op_decl = self.operands.concatAttrStrings('op_decl') + is_src = lambda op: op.is_src + is_dest = lambda op: op.is_dest + + self.op_src_decl = \ + self.operands.concatSomeAttrStrings(is_src, 'op_src_decl') + self.op_dest_decl = \ + self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl') + self.op_rd = self.operands.concatAttrStrings('op_rd') self.op_wb = self.operands.concatAttrStrings('op_wb') @@ -1596,6 +1609,7 @@ class CodeBlock: if self.operands.memOperand: self.mem_acc_size = self.operands.memOperand.mem_acc_size + self.mem_acc_type = self.operands.memOperand.mem_acc_type # Make a basic guess on the operand class (function unit type). # These are good enough for most cases, and will be overridden diff --git a/arch/mips/SConscript b/arch/mips/SConscript new file mode 100644 index 000000000..bd67c98e9 --- /dev/null +++ b/arch/mips/SConscript @@ -0,0 +1,81 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-2005 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. + +import os +import sys +from os.path import isdir + +# Import build environment variable from SConstruct. +Import('env') + +################################################### +# +# Define needed sources. +# +################################################### + +# Base sources used by all configurations. +arch_base_sources = Split(''' + arch/mips/decoder.cc + arch/mips/alpha_o3_exec.cc + arch/mips/fast_cpu_exec.cc + arch/mips/simple_cpu_exec.cc + arch/mips/full_cpu_exec.cc + arch/mips/faults.cc + arch/mips/isa_traits.cc + ''') + +# Full-system sources +arch_full_system_sources = Split(''' + arch/mips/alpha_memory.cc + arch/mips/arguments.cc + arch/mips/ev5.cc + arch/mips/osfpal.cc + arch/mips/stacktrace.cc + arch/mips/vtophys.cc + ''') + +# Syscall emulation (non-full-system) sources +arch_syscall_emulation_sources = Split(''' + arch/mips/alpha_common_syscall_emul.cc + arch/mips/alpha_linux_process.cc + arch/mips/alpha_tru64_process.cc + ''') + +# Set up complete list of sources based on configuration. +sources = arch_base_sources + +if env['FULL_SYSTEM']: + sources += arch_full_system_sources +else: + sources += arch_syscall_emulation_sources + +for opt in env.ExportOptions: + env.ConfigFile(opt) + +Return('sources') diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 2ec7da805..6bb5bf4d8 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -9,7 +9,7 @@ // //@todo: Distinguish "unknown/future" use insts from "reserved" // ones -decode OPCODE_HI default FailUnimpl::unknown() { +decode OPCODE_HI default Unknown::unknown() { // Derived From ... Table A-2 MIPS32 ISA Manual 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ @@ -66,10 +66,11 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } + format WarnUnimpl { - 0x4: syscall({{ xc->syscall()}},IsNonSpeculative); - 0x5: break({{ }}); - 0x7: sync({{ }}); + 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative + 0x5: break(); + 0x7: sync(); } } @@ -80,14 +81,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); } - }; + } 0x3: decode FUNCTION_LO { format IntOp { 0x0: mult({{ INT64 temp1 = Rs.sw * Rt.sw; xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->miscRegs.lo->temp1<31:0>; }}); 0x1: multu({{ @@ -107,7 +108,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { xc->miscRegs.lo = Rs.uw / Rt.uw; }}); } - }; + } 0x4: decode FUNCTION_LO { format IntOp { @@ -127,7 +128,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); } - }; + } 0x6: decode FUNCTION_LO { format Trap { @@ -143,13 +144,13 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode REGIMM_HI { 0x0: decode REGIMM_LO { - format Branch { - 0x0: bltz({{ cond = (Rs.sq < 0); }}); - 0x1: bgez({{ cond = (Rs.sq >= 0); }}); + format CondBranch { + 0x0: bltz({{ cond = (Rs.sw < 0); }}); + 0x1: bgez({{ cond = (Rs.sw >= 0); }}); //MIPS obsolete instructions - 0x2: bltzl({{ cond = (Rs.sq < 0); }}); - 0x3: bgezl({{ cond = (Rs.sq >= 0); }}); + 0x2: bltzl({{ cond = (Rs.sw < 0); }}); + 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); } } @@ -165,19 +166,19 @@ decode OPCODE_HI default FailUnimpl::unknown() { } 0x2: decode REGIMM_LO { - format Branch { - 0x0: bltzal({{ cond = (Rs.sq < 0); }}); - 0x1: bgezal({{ cond = (Rs.sq >= 0); }}); + format CondBranch { + 0x0: bltzal({{ cond = (Rs.sw < 0); }}); + 0x1: bgezal({{ cond = (Rs.sw >= 0); }}); //MIPS obsolete instructions - 0x2: bltzall({{ cond = (Rs.sq < 0); }}); - 0x3: bgezall({{ cond = (Rs.sq >= 0); }}); + 0x2: bltzall({{ cond = (Rs.sw < 0); }}); + 0x3: bgezall({{ cond = (Rs.sw >= 0); }}); } } 0x3: decode REGIMM_LO { format WarnUnimpl { - 0x7: synci({{ }}); + 0x7: synci(); } } } @@ -187,13 +188,13 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x3: jal(IsCall); } - format Branch { - 0x4: beq({{ cond = (Rs.sq == 0); }}); - 0x5: bne({{ cond = (Rs.sq != 0); }}); - 0x6: blez({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtz({{ cond = (Rs.sq > 0); }}); + format CondBranch { + 0x4: beq({{ cond = (Rs.sw == 0); }}); + 0x5: bne({{ cond = (Rs.sw != 0); }}); + 0x6: blez({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtz({{ cond = (Rs.sw > 0); }}); } - }; + } 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ format IntOp { @@ -205,8 +206,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); 0x7: lui({{ Rt = INTIMM << 16}}); - }; - }; + } + } 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ @@ -335,9 +336,9 @@ decode OPCODE_HI default FailUnimpl::unknown() { } format WarnUnimpl { - 0x18: eret({{ }}); - 0x1F: deret({{ }}); - 0x20: wait({{ }}); + 0x18: eret(); + 0x1F: deret(); + 0x20: wait(); } } } @@ -359,14 +360,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode ND { 0x0: decode TF { - format Branch { + format CondBranch { 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); } } 0x1: decode TF { - format Branch { + format CondBranch { 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); } @@ -394,7 +395,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } 0x1: decode RS_LO { - //only legal for 64 bit + //only legal for 64 bit-FP format Float64Op { 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}}); 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}}); @@ -425,18 +426,21 @@ decode OPCODE_HI default FailUnimpl::unknown() { format Float64Op { 0x2: recips({{ Fd = 1 / Fs; }}); - 0x3: rsqrts{{ Fd = 1 / sqrt(Fs); }}); + 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); } } 0x4: decode RS_LO { - 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; + + format FloatOp { + 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); }}); - 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); }}); + } //only legal for 64 bit format Float64Op { @@ -466,7 +470,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode RS_LO { //only legal for 64 bit - format FloatOp64 { + format Float64Op { 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}}); 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}}); @@ -494,9 +498,9 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }}); } - format FloatOp64 { + format Float64Op { 0x5: recipd({{ Fd.df = 1 / Fs.df}}); - 0x6: rsqrtd{{ Fd.df = 1 / sqrt(Fs.df) }}); + 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }}); } } @@ -514,7 +518,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } //only legal for 64 bit - format FloatOp64 { + format Float64Op { 0x5: cvt_l_d({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); @@ -560,7 +564,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { //are enabled. " 0x6: decode RS_HI { 0x0: decode RS_LO { - format FloatOp64 { + format Float64Op { 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut Fd.df = Fs.df + Ft.df; @@ -595,23 +599,23 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { - format FloatOp64 { - 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}) - 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}) + format Float64Op { + 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); + 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); } } } 0x4: decode RS_LO { - 0x0: FloatOp64::cvt_s_pu({{ + 0x0: Float64Op::cvt_s_pu({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); }}); } 0x5: decode RS_LO { - format FloatOp64 { + format Float64Op { 0x0: cvt_s_pl({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); @@ -630,27 +634,27 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { format WarnUnimpl { - 0x0: mfc2({{ }}); - 0x2: cfc2({{ }}); - 0x3: mfhc2({{ }}); - 0x4: mtc2({{ }}); - 0x6: ctc2({{ }}); - 0x7: mftc2({{ }}); + 0x0: mfc2(); + 0x2: cfc2(); + 0x3: mfhc2(); + 0x4: mtc2(); + 0x6: ctc2(); + 0x7: mftc2(); } } 0x1: decode ND { 0x0: decode TF { format WarnUnimpl { - 0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2); - 0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); + 0x0: bc2f(); + 0x1: bc2t(); } } 0x1: decode TF { format WarnUnimpl { - 0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}}); - 0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); + 0x0: bc2fl(); + 0x1: bc2tl(); } } } @@ -680,12 +684,13 @@ decode OPCODE_HI default FailUnimpl::unknown() { EA = Rs + Rt; }}, {{ Mem.df = Ft<63:0>;}}); - 0x7: prefx({{ }}); } + + 0x7: WarnUnimpl::prefx(); } format FloatOp { - 0x3: WarnUnimpl::alnv_ps({{ }}); + 0x3: WarnUnimpl::alnv_ps(); format BasicOp { 0x4: decode FUNCTION_LO { @@ -732,13 +737,13 @@ decode OPCODE_HI default FailUnimpl::unknown() { } //MIPS obsolete instructions - format Branch { - 0x4: beql({{ cond = (Rs.sq == 0); }}); - 0x5: bnel({{ cond = (Rs.sq != 0); }}); - 0x6: blezl({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); + format CondBranch { + 0x4: beql({{ cond = (Rs.sw == 0); }}); + 0x5: bnel({{ cond = (Rs.sw != 0); }}); + 0x6: blezl({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtzl({{ cond = (Rs.sw > 0); }}); } - }; + } 0x3: decode OPCODE_LO default FailUnimpl::reserved() { @@ -806,7 +811,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } 0x7: decode FUNCTION_LO { - 0x7: WarnUnimpl::sdbbp({{ }}); + 0x7: WarnUnimpl::sdbbp(); } } @@ -815,15 +820,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode FUNCTION_LO { format WarnUnimpl { - 0x1: ext({{ }}); - 0x4: ins({{ }}); + 0x1: ext(); + 0x4: ins(); } } 0x1: decode FUNCTION_LO { format WarnUnimpl { - 0x0: fork({{ }}); - 0x1: yield({{ }}); + 0x0: fork(); + 0x1: yield(); } } @@ -831,7 +836,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { - 0x02: WarnUnimpl::wsbh({{ }}); + 0x02: WarnUnimpl::wsbh(); format BasicOp { 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); @@ -843,53 +848,53 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); } } - }; + } 0x4: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }}); 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }}); - 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }}, WordAlign); + 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }});//, WordAlign); 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }}); 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }}); 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }}); - 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }}, WordAlign); - }; + 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }});//, WordAlign); + } - 0x7: FailUnimpl::reserved({{ }}); - }; + 0x7: FailUnimpl::reserved(); + } 0x5: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }}); 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }}); - 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); + 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign); 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }}); - 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); - }; + 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign); + } format WarnUnimpl { - 0x7: cache({{ }}); - }; + 0x7: cache(); + } - }; + } 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::ll({{ }}); + 0x0: WarnUnimpl::ll(); format Memory { 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); - }; - }; + } + } 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::sc({{ }}); + 0x0: WarnUnimpl::sc(); format Memory { 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); - }; + } } } diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index 404314c7a..20ef49d82 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -1,22 +1,29 @@ //Include the basic format //Templates from this format are used later -##include "m5/arch/mips/isa_desc/formats/basic.format" +##include "m5/arch/mips/isa/formats/basic.isa" //Include the integerOp and integerOpCc format -##include "m5/arch/mips/isa_desc/formats/integerop.format" +##include "m5/arch/mips/isa/formats/int.isa" //Include the floatOp format -##include "m5/arch/mips/isa_desc/formats/floatop.format" +##include "m5/arch/mips/isa/formats/fp.isa" //Include the mem format -##include "m5/arch/mips/isa_desc/formats/mem.format" +##include "m5/arch/mips/isa/formats/mem.isa" //Include the trap format -##include "m5/arch/mips/isa_desc/formats/trap.format" +##include "m5/arch/mips/isa/formats/trap.isa" //Include the branch format -##include "m5/arch/mips/isa_desc/formats/branch.format" +##include "m5/arch/mips/isa/formats/branch.isa" //Include the noop format -##include "m5/arch/mips/isa_desc/formats/noop.format" +##include "m5/arch/mips/isa/formats/noop.isa" + + +//Include the noop format +##include "m5/arch/mips/isa/formats/unimp.isa" + +//Include the noop format +##include "m5/arch/mips/isa/formats/unknown.isa" diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa index 8fba9845a..fc97c6ffa 100644 --- a/arch/mips/isa/formats/basic.isa +++ b/arch/mips/isa/formats/basic.isa @@ -56,7 +56,7 @@ def template BasicDecodeWithMnemonic {{ }}; // The most basic instruction format... used only for a few misc. insts -def format BasicOperate(code, *flags) {{ +def format BasicOp(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index a565eb71b..e9c790c53 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -1,57 +1,212 @@ -//////////////////////////////////////////////////////////////////// +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// All rights reserved. // -// Branch instructions +// 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. output header {{ - /** - * Base class for integer operations. - */ - class Branch : public MipsStaticInst + + /** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ + class PCDependentDisassembly : public AlphaStaticInst + { + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) { - protected: + } - /// Constructor - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) - { - } + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; + }; - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; + /** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ + class Branch : public PCDependentDisassembly + { + protected: + /// Displacement to target address (signed). + int32_t disp; -output decoder {{ - std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP << 2) + { + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for jumps (register-indirect control transfers). In + * the Alpha ISA, these are always unconditional. + */ + class Jump : public PCDependentDisassembly + { + protected: + + /// Displacement to target address (signed). + int32_t disp; + + public: + /// Constructor + Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP) { - return "Disassembly of integer instruction\n"; } + + Addr branchTarget(ExecContext *xc) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; }}; -def template BranchExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const +output decoder {{ + Addr + Branch::branchTarget(Addr branchPC) const + { + return branchPC + 4 + disp; + } + + Addr + Jump::branchTarget(ExecContext *xc) const + { + Addr NPC = xc->readPC() + 4; + uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); + return (Rb & ~3) | (NPC & 1); + } + + const std::string & + PCDependentDisassembly::disassemble(Addr pc, + const SymbolTable *symtab) const + { + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) { - //Attempt to execute the instruction - try - { - checkPriv; - - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(MipsException except) - { - //Deal with exception - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - - return No_Fault; + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; + } + + std::string + Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // There's only one register arg (RA), but it could be + // either a source (the condition for conditional + // branches) or a destination (the link reg for + // unconditional branches) + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + else if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; } + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numSrcRegs == 0 && _numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + Addr target = pc + 4 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); + } + + std::string + Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + + ccprintf(ss, "(r%d)", RB); + + return ss.str(); + } +}}; + +def template JumpOrBranchDecode {{ + return (RA == 31) + ? (StaticInst<AlphaISA> *)new %(class_name)s(machInst) + : (StaticInst<AlphaISA> *)new %(class_name)sAndLink(machInst); }}; def format CondBranch(code) {{ @@ -64,3 +219,41 @@ def format CondBranch(code) {{ exec_output = BasicExecute.subst(iop) }}; +let {{ +def UncondCtrlBase(name, Name, base_class, npc_expr, flags): + # Declare basic control transfer w/o link (i.e. link reg is R31) + nolink_code = 'NPC = %s;\n' % npc_expr + nolink_iop = InstObjParams(name, Name, base_class, + CodeBlock(nolink_code), flags) + header_output = BasicDeclare.subst(nolink_iop) + decoder_output = BasicConstructor.subst(nolink_iop) + exec_output = BasicExecute.subst(nolink_iop) + + # Generate declaration of '*AndLink' version, append to decls + link_code = 'Ra = NPC & ~3;\n' + nolink_code + link_iop = InstObjParams(name, Name + 'AndLink', base_class, + CodeBlock(link_code), flags) + header_output += BasicDeclare.subst(link_iop) + decoder_output += BasicConstructor.subst(link_iop) + exec_output += BasicExecute.subst(link_iop) + + # need to use link_iop for the decode template since it is expecting + # the shorter version of class_name (w/o "AndLink") + + return (header_output, decoder_output, + JumpOrBranchDecode.subst(nolink_iop), exec_output) +}}; + +def format UncondBranch(*flags) {{ + flags += ('IsUncondControl', 'IsDirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) +}}; + +def format Jump(*flags) {{ + flags += ('IsUncondControl', 'IsIndirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) +}}; + + diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 707109fc2..23fcbaa67 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -27,7 +27,7 @@ output decoder {{ } }}; -def template FPExecute {{ +def template FloatingPointExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { //These are set to constants when the execute method @@ -70,7 +70,7 @@ def template FPExecute {{ }}; // Primary format for integer operate instructions: -def format FPOp(code, *opt_flags) {{ +def format FloatOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) checkPriv = (code.find('checkPriv') != -1) @@ -86,12 +86,33 @@ def format FPOp(code, *opt_flags) {{ header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = IntegerExecute.subst(iop) + exec_output = FloatingPointExecute.subst(iop) +}}; + +// Primary format for integer operate instructions: +def format Float64Op(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', '0'), ('icValue', '0'), + ('xvValue', '0'), ('xcValue', '0')): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = FloatingPointExecute.subst(iop) }}; // Primary format for integer operate instructions: def format FPOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ orig_code = code + cblk = CodeBlock(code) checkPriv = (code.find('checkPriv') != -1) code.replace('checkPriv', '') diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index 5b8df54e9..521f3a130 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -53,9 +53,9 @@ def format IntOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - //Figure out if we are creating a IntImmOp or a IntOp + # Figure out if we are creating a IntImmOp or a IntOp strlen = len(name) - if ( name[strlen-1] = 'i' or ( name[strlen-2:] = 'iu')) + if name[strlen-1] == 'i' or name[strlen-2:] == 'iu': iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags) else: iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags) diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index 5ed5237c5..e3028eb7c 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -55,7 +55,7 @@ def template MemExecute {{ }}; // Primary format for integer operate instructions: -def format Mem(code, *opt_flags) {{ +def format Memory(code, ea_code = {{ EA = Rb + disp; }},*opt_flags) {{ orig_code = code cblk = CodeBlock(code) iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa index b1ece654d..6d45ba9b6 100644 --- a/arch/mips/isa/formats/noop.isa +++ b/arch/mips/isa/formats/noop.isa @@ -45,3 +45,90 @@ def format Noop(code, *opt_flags) {{ decode_block = BasicDecodeWithMnemonic.subst(iop) exec_output = NoopExecute.subst(iop) }}; + +//////////////////////////////////////////////////////////////////// +// +// Nop +// + +output header {{ + /** + * Static instruction class for no-ops. This is a leaf class. + */ + class Nop : public AlphaStaticInst + { + /// Disassembly of original instruction. + const std::string originalDisassembly; + + public: + /// Constructor + Nop(const std::string _originalDisassembly, MachInst _machInst) + : AlphaStaticInst("nop", _machInst, No_OpClass), + originalDisassembly(_originalDisassembly) + { + flags[IsNop] = true; + } + + ~Nop() { } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + %(BasicExecDeclare)s + }; +}}; + +output decoder {{ + std::string Nop::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return originalDisassembly; +#else + return csprintf("%-10s (%s)", "nop", originalDisassembly); +#endif + } + + /// Helper function for decoding nops. Substitute Nop object + /// for original inst passed in as arg (and delete latter). + inline + AlphaStaticInst * + makeNop(AlphaStaticInst *inst) + { + AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); + delete inst; + return nop; + } +}}; + +output exec {{ + Fault + Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const + { + return No_Fault; + } +}}; + +// integer & FP operate instructions use Rc as dest, so check for +// Rc == 31 to detect nops +def template OperateNopCheckDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (RC == 31) { + i = makeNop(i); + } + return i; + } +}}; + + +// Like BasicOperate format, but generates NOP if RC/FC == 31 +def format BasicOperateWithNopCheck(code, *opt_args) {{ + iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), + opt_args) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa new file mode 100644 index 000000000..767888157 --- /dev/null +++ b/arch/mips/isa/formats/unimp.isa @@ -0,0 +1,165 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 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. + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public AlphaStaticInst + { + public: + /// Constructor + 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 + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public AlphaStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + 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 + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s", mnemonic); +#else + return csprintf("%-10s (unimplemented)", mnemonic); +#endif + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return No_Fault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public AlphaStaticInst + { + public: + /// Constructor + 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 + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa new file mode 100644 index 000000000..6eba5b4f9 --- /dev/null +++ b/arch/mips/isa/formats/unknown.isa @@ -0,0 +1,52 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 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. + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x)", + "unknown", machInst, OPCODE); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/arch/mips/isa/main.isa b/arch/mips/isa/main.isa index a8c71872b..411e398b4 100644 --- a/arch/mips/isa/main.isa +++ b/arch/mips/isa/main.isa @@ -26,7 +26,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -##include "m5/arch/sparc/isa_desc/includes.h" +##include "m5/arch/mips/isa/includes.isa" //////////////////////////////////////////////////////////////////// // @@ -37,16 +37,16 @@ namespace MipsISA; //Include the bitfield definitions -##include "m5/arch/mips/isa_desc/bitfields.h" +##include "m5/arch/mips/isa/bitfields.isa" //Include the operand_types and operand definitions -##include "m5/arch/mips/isa_desc/operands.h" +##include "m5/arch/mips/isa/operands.isa" //Include the base class for mips instructions, and some support code -##include "m5/arch/mips/isa_desc/base.h" +##include "m5/arch/mips/isa/base.isa" //Include the definitions for the instruction formats -##include "m5/arch/mips/isa_desc/formats.h" +##include "m5/arch/mips/isa/formats.isa" //Include the decoder definition -##include "m5/arch/mips/isa_desc/decoder.h" +##include "m5/arch/mips/isa/decoder.isa" diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index c8e08a436..cf6f10e0b 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -5,8 +5,8 @@ def operand_types {{ 'uhw' : ('unsigned int', 16), 'sw' : ('signed int', 32), 'uw' : ('unsigned int', 32), - 'sdw' : ('signed int', 64), - 'udw' : ('unsigned int', 64), + 'sd' : ('signed int', 64), + 'ud' : ('unsigned int', 64), 'sf' : ('float', 32), 'df' : ('float', 64), 'qf' : ('float', 128) @@ -24,7 +24,7 @@ def operands {{ 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), - 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) + 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript new file mode 100644 index 000000000..d8a3749a1 --- /dev/null +++ b/arch/sparc/SConscript @@ -0,0 +1,82 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-2005 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. + +import os +import sys +from os.path import isdir + +# Import build environment variable from SConstruct. +Import('env') + +################################################### +# +# Define needed sources. +# +################################################### + +# Base sources used by all configurations. +arch_base_sources = Split(''' + arch/sparc/decoder.cc + arch/sparc/alpha_o3_exec.cc + arch/sparc/fast_cpu_exec.cc + arch/sparc/simple_cpu_exec.cc + arch/sparc/full_cpu_exec.cc + arch/sparc/faults.cc + arch/sparc/isa_traits.cc + ''') + +# Full-system sources +arch_full_system_sources = Split(''' + arch/sparc/alpha_memory.cc + arch/sparc/arguments.cc + arch/sparc/ev5.cc + arch/sparc/osfpal.cc + arch/sparc/stacktrace.cc + arch/sparc/vtophys.cc + ''') + +# Syscall emulation (non-full-system) sources +arch_syscall_emulation_sources = Split(''' + arch/sparc/alpha_common_syscall_emul.cc + arch/sparc/alpha_linux_process.cc + arch/sparc/alpha_tru64_process.cc + ''') + +sources = arch_base_sources + +if env['FULL_SYSTEM']: + sources += arch_full_system_sources + if env['ALPHA_TLASER']: + sources += arch_turbolaser_sources +else: + sources += arch_syscall_emulation_sources + +for opt in env.ExportOptions: + env.ConfigFile(opt) + +Return('sources') |