diff options
Diffstat (limited to 'src/arch/arm')
24 files changed, 759 insertions, 1527 deletions
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 60a5ca3b0..519435489 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -40,7 +40,6 @@ if env['TARGET_ISA'] == 'arm': Source('insts/pred_inst.cc') Source('insts/static_inst.cc') Source('pagetable.cc') - Source('regfile/regfile.cc') Source('tlb.cc') Source('vtophys.cc') diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index b79c09174..3d882c97f 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -433,7 +433,6 @@ void InterruptFault::invoke(ThreadContext *tc) { #if FULL_SYSTEM DPRINTF(Arm,"%s encountered.\n", name()); - //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil setExceptionState(tc,0x0A); Addr HandlerBase; @@ -469,7 +468,6 @@ void ReservedInstructionFault::invoke(ThreadContext *tc) { #if FULL_SYSTEM DPRINTF(Arm,"%s encountered.\n", name()); - //RegFile *Reg = tc->getRegFilePtr(); // Get pointer to the register fil setExceptionState(tc,0x0A); Addr HandlerBase; HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index cfc2075a1..541c9e3f5 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -47,6 +47,39 @@ number_of_ones(int32_t val) } /** + * Microops of the form IntRegA = IntRegB op Imm + */ +class MicroIntOp : public PredOp +{ + protected: + RegIndex ura, urb; + uint8_t imm; + + MicroIntOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, + RegIndex _ura, RegIndex _urb, uint8_t _imm) + : PredOp(mnem, machInst, __opClass), + ura(_ura), urb(_urb), imm(_imm) + { + } +}; + +/** + * Memory microops which use IntReg + Imm addressing + */ +class MicroMemOp : public MicroIntOp +{ + protected: + unsigned memAccessFlags; + + MicroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, + RegIndex _ura, RegIndex _urb, uint8_t _imm) + : MicroIntOp(mnem, machInst, __opClass, _ura, _urb, _imm), + memAccessFlags(0) + { + } +}; + +/** * Arm Macro Memory operations like LDM/STM */ class ArmMacroMemoryOp : public PredMacroOp @@ -54,10 +87,6 @@ class ArmMacroMemoryOp : public PredMacroOp protected: /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; - /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; - /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; uint32_t reglist; uint32_t ones; @@ -69,12 +98,9 @@ class ArmMacroMemoryOp : public PredMacroOp loadop; ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, - OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) + OpClass __opClass) : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0), - eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), reglist(machInst.regList), ones(0), puswl(machInst.puswl), prepost(machInst.puswl.prepost), diff --git a/src/arch/arm/insts/mem.cc b/src/arch/arm/insts/mem.cc index 7909330aa..afbf05e44 100644 --- a/src/arch/arm/insts/mem.cc +++ b/src/arch/arm/insts/mem.cc @@ -37,14 +37,17 @@ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; printMnemonic(ss); - return ss.str(); -} - -std::string -MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const -{ - std::stringstream ss; - printMnemonic(ss); + printReg(ss, machInst.rd); + ss << ", ["; + printReg(ss, machInst.rn); + ss << ", "; + if (machInst.puswl.prepost == 1) + printOffset(ss); + ss << "]"; + if (machInst.puswl.prepost == 0) + printOffset(ss); + else if (machInst.puswl.writeback) + ss << "!"; return ss.str(); } } diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh index 80f966e9c..bf0aa1c92 100644 --- a/src/arch/arm/insts/mem.hh +++ b/src/arch/arm/insts/mem.hh @@ -42,10 +42,6 @@ class Memory : public PredOp /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; - /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; - /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; /// Displacement for EA calculation (signed). int32_t disp; @@ -56,53 +52,88 @@ class Memory : public PredOp shift; /// Constructor - Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) + Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : PredOp(mnem, _machInst, __opClass), memAccessFlags(0), - eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), disp(machInst.immed11_0), disp8(machInst.immed7_0 << 2), up(machInst.puswl.up), hilo((machInst.immedHi11_8 << 4) | machInst.immedLo3_0), shift_size(machInst.shiftSize), shift(machInst.shift) { - // When Up is not set, then we must subtract by the displacement - if (!up) - { - disp = -disp; - disp8 = -disp8; - hilo = -hilo; - } } std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - public: + virtual void + printOffset(std::ostream &os) const + {} +}; - const StaticInstPtr &eaCompInst() const { return eaCompPtr; } - const StaticInstPtr &memAccInst() const { return memAccPtr; } +class MemoryDisp : public Memory +{ + protected: + /// Constructor + MemoryDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) + : Memory(mnem, _machInst, __opClass) + { + } + + void + printOffset(std::ostream &os) const + { + ccprintf(os, "#%#x", (machInst.puswl.up ? disp : -disp)); + } }; - /** - * Base class for a few miscellaneous memory-format insts - * that don't interpret the disp field - */ -class MemoryNoDisp : public Memory +class MemoryHilo : public Memory { protected: /// Constructor - MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) + MemoryHilo(const char *mnem, ExtMachInst _machInst, OpClass __opClass) + : Memory(mnem, _machInst, __opClass) { } - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; + void + printOffset(std::ostream &os) const + { + ccprintf(os, "#%#x", (machInst.puswl.up ? hilo : -hilo)); + } +}; + +class MemoryShift : public Memory +{ + protected: + /// Constructor + MemoryShift(const char *mnem, ExtMachInst _machInst, OpClass __opClass) + : Memory(mnem, _machInst, __opClass) + { + } + + void + printOffset(std::ostream &os) const + { + printShiftOperand(os); + } +}; + +class MemoryReg : public Memory +{ + protected: + /// Constructor + MemoryReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass) + : Memory(mnem, _machInst, __opClass) + { + } + + void + printOffset(std::ostream &os) const + { + os << (machInst.puswl.up ? "+ " : "- "); + printReg(os, machInst.rm); + } }; } diff --git a/src/arch/arm/insts/pred_inst.cc b/src/arch/arm/insts/pred_inst.cc index 539cfc2d2..f98db1c8e 100644 --- a/src/arch/arm/insts/pred_inst.cc +++ b/src/arch/arm/insts/pred_inst.cc @@ -32,10 +32,18 @@ namespace ArmISA { std::string -PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; - printDataInst(ss); + printDataInst(ss, false); + return ss.str(); +} + +std::string +PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + printDataInst(ss, true); return ss.str(); } diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh index 38ac69358..6f9bd9dc2 100644 --- a/src/arch/arm/insts/pred_inst.hh +++ b/src/arch/arm/insts/pred_inst.hh @@ -56,8 +56,6 @@ class PredOp : public ArmStaticInst condCode((ConditionCode)(unsigned)machInst.condCode) { } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /** @@ -65,23 +63,25 @@ class PredOp : public ArmStaticInst */ class PredImmOp : public PredOp { - protected: - - uint32_t imm; - uint32_t rotate; - uint32_t rotated_imm; - uint32_t rotated_carry; - - /// Constructor - PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass), - imm(machInst.imm), rotate(machInst.rotate << 1), - rotated_imm(0), rotated_carry(0) - { - rotated_imm = rotate_imm(imm, rotate); - if (rotate != 0) - rotated_carry = (rotated_imm >> 31) & 1; - } + protected: + + uint32_t imm; + uint32_t rotate; + uint32_t rotated_imm; + uint32_t rotated_carry; + + /// Constructor + PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass), + imm(machInst.imm), rotate(machInst.rotate << 1), + rotated_imm(0), rotated_carry(0) + { + rotated_imm = rotate_imm(imm, rotate); + if (rotate != 0) + rotated_carry = (rotated_imm >> 31) & 1; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /** @@ -89,17 +89,19 @@ class PredImmOp : public PredOp */ class PredIntOp : public PredOp { - protected: + protected: - uint32_t shift_size; - uint32_t shift; + uint32_t shift_size; + uint32_t shift; - /// Constructor - PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass), - shift_size(machInst.shiftSize), shift(machInst.shift) - { - } + /// Constructor + PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass), + shift_size(machInst.shiftSize), shift(machInst.shift) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /** @@ -107,36 +109,36 @@ class PredIntOp : public PredOp */ class PredMacroOp : public PredOp { - protected: - - uint32_t numMicroops; - StaticInstPtr * microOps; - - /// Constructor - PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass), - numMicroops(0) - { - // We rely on the subclasses of this object to handle the - // initialization of the micro-operations, since they are - // all of variable length - flags[IsMacroop] = true; - } - - ~PredMacroOp() - { - if (numMicroops) - delete [] microOps; - } - - StaticInstPtr - fetchMicroop(MicroPC microPC) - { - assert(microPC < numMicroops); - return microOps[microPC]; - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + protected: + + uint32_t numMicroops; + StaticInstPtr * microOps; + + /// Constructor + PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass), + numMicroops(0) + { + // We rely on the subclasses of this object to handle the + // initialization of the micro-operations, since they are + // all of variable length + flags[IsMacroop] = true; + } + + ~PredMacroOp() + { + if (numMicroops) + delete [] microOps; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC) + { + assert(microPC < numMicroops); + return microOps[microPC]; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /** @@ -144,12 +146,12 @@ class PredMacroOp : public PredOp */ class PredMicroop : public PredOp { - /// Constructor - PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass) - { - flags[IsMicroop] = true; - } + /// Constructor + PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass) + { + flags[IsMicroop] = true; + } }; } diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index f3ad1127b..df2d5de25 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -330,61 +330,52 @@ ArmStaticInst::printMemSymbol(std::ostream &os, void ArmStaticInst::printShiftOperand(std::ostream &os) const { - // Shifter operand - if (bits((uint32_t)machInst, 25)) { - // Immediate form - unsigned rotate = machInst.rotate * 2; - uint32_t imm = machInst.imm; - ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate)); - } else { - // Register form - printReg(os, machInst.rm); + printReg(os, machInst.rm); - bool immShift = (machInst.opcode4 == 0); - bool done = false; - unsigned shiftAmt = (machInst.shiftSize); - ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift; + bool immShift = (machInst.opcode4 == 0); + bool done = false; + unsigned shiftAmt = (machInst.shiftSize); + ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift; - if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) - shiftAmt = 32; + if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) + shiftAmt = 32; - switch (type) { - case LSL: - if (immShift && shiftAmt == 0) { - done = true; - break; - } - os << ", LSL"; - break; - case LSR: - os << ", LSR"; - break; - case ASR: - os << ", ASR"; - break; - case ROR: - if (immShift && shiftAmt == 0) { - os << ", RRX"; - done = true; - break; - } - os << ", ROR"; + switch (type) { + case LSL: + if (immShift && shiftAmt == 0) { + done = true; break; - default: - panic("Tried to disassemble unrecognized shift type.\n"); } - if (!done) { - os << " "; - if (immShift) - os << "#" << shiftAmt; - else - printReg(os, machInst.rs); + os << ", LSL"; + break; + case LSR: + os << ", LSR"; + break; + case ASR: + os << ", ASR"; + break; + case ROR: + if (immShift && shiftAmt == 0) { + os << ", RRX"; + done = true; + break; } + os << ", ROR"; + break; + default: + panic("Tried to disassemble unrecognized shift type.\n"); + } + if (!done) { + os << " "; + if (immShift) + os << "#" << shiftAmt; + else + printReg(os, machInst.rs); } } void -ArmStaticInst::printDataInst(std::ostream &os) const +ArmStaticInst::printDataInst(std::ostream &os, bool withImm) const { printMnemonic(os, machInst.sField ? "s" : ""); //XXX It would be nice if the decoder figured this all out for us. @@ -409,7 +400,13 @@ ArmStaticInst::printDataInst(std::ostream &os) const if (!firstOp) os << ", "; - printShiftOperand(os); + if (withImm) { + unsigned rotate = machInst.rotate * 2; + uint32_t imm = machInst.imm; + ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate)); + } else { + printShiftOperand(os); + } } std::string diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index 22b59791c..c963c1827 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -71,7 +71,7 @@ class ArmStaticInst : public StaticInst void printShiftOperand(std::ostream &os) const; - void printDataInst(std::ostream &os) const; + void printDataInst(std::ostream &os, bool withImm) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; diff --git a/src/arch/arm/regfile/misc_regfile.hh b/src/arch/arm/isa.hh index f7e5fbd98..39acc9c08 100644 --- a/src/arch/arm/regfile/misc_regfile.hh +++ b/src/arch/arm/isa.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,60 +25,82 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Stephen Hines + * Authors: Gabe Black */ -#ifndef __ARCH_ARM_REGFILE_MISC_REGFILE_HH__ -#define __ARCH_ARM_REGFILE_MISC_REGFILE_HH__ +#ifndef __ARCH_ARM_ISA_HH__ +#define __ARCH_MRM_ISA_HH__ +#include "arch/arm/registers.hh" #include "arch/arm/types.hh" -#include "sim/faults.hh" class ThreadContext; +class Checkpoint; +class EventManager; namespace ArmISA { - static inline std::string getMiscRegName(RegIndex) + class ISA { - return ""; - } - - class MiscRegFile { - protected: - MiscReg miscRegFile[NumMiscRegs]; + MiscReg miscRegs[NumMiscRegs]; public: void clear() { - // Unknown startup state in misc register file currently + // Unknown startup state currently + } + + MiscReg + readMiscRegNoEffect(int misc_reg) + { + assert(misc_reg < NumMiscRegs); + return miscRegs[misc_reg]; } - void copyMiscRegs(ThreadContext *tc); + MiscReg + readMiscReg(int misc_reg, ThreadContext *tc) + { + assert(misc_reg < NumMiscRegs); + return miscRegs[misc_reg]; + } - MiscReg readRegNoEffect(int misc_reg) + void + setMiscRegNoEffect(int misc_reg, const MiscReg &val) { - return miscRegFile[misc_reg]; + assert(misc_reg < NumMiscRegs); + miscRegs[misc_reg] = val; } - MiscReg readReg(int misc_reg, ThreadContext *tc) + void + setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) { - return miscRegFile[misc_reg]; + assert(misc_reg < NumMiscRegs); + miscRegs[misc_reg] = val; } - void setRegNoEffect(int misc_reg, const MiscReg &val) + int + flattenIntIndex(int reg) { - miscRegFile[misc_reg] = val; + return reg; } - void setReg(int misc_reg, const MiscReg &val, - ThreadContext *tc) + int + flattenFloatIndex(int reg) { - miscRegFile[misc_reg] = val; + return reg; } - friend class RegFile; + void serialize(std::ostream &os) + {} + void unserialize(Checkpoint *cp, const std::string §ion) + {} + + ISA() + { + clear(); + } }; -} // namespace ArmISA +} #endif diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 623b2415d..76d584858 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -37,47 +37,8 @@ // in the ARM ISA specification document starting with Table B.1 or 3-1 // // -decode COND_CODE default Unknown::unknown() { - 0xf: decode COND_CODE { - 0x0: decode OPCODE { - // Just a simple trick to allow us to specify our new uops here - 0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }}, - 'IsMicroop'); - 0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }}, - 'IsMicroop'); - 0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }}, - {{ EA = Raddr + disp; }}, - inst_flags = [IsMicroop]); - 0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }}, - {{ EA = Raddr + disp; }}, - inst_flags = [IsMicroop]); - 0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }}, - 'IsMicroop'); - 0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }}, - 'IsMicroop'); - } - 0x1: decode OPCODE { - 0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }}, - 'IsMicroop'); - 0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff; - Rlo = Fd.ud & 0xffffffff; }}, - 'IsMicroop'); - 0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }}, - {{ EA = Rn + disp; }}, - inst_flags = [IsMicroop]); - 0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }}, - {{ EA = Rn + disp; }}, - inst_flags = [IsMicroop]); - 0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }}, - {{ EA = Rn + disp; }}, - inst_flags = [IsMicroop]); - 0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }}, - {{ EA = Rn + disp; }}, - inst_flags = [IsMicroop]); - } - default: Unknown::unknown(); // TODO: Ignore other NV space for now - } -default: decode ENCODING { + +decode ENCODING default Unknown::unknown() { format DataOp { 0x0: decode SEVEN_AND_FOUR { 1: decode MISC_OPCODE { @@ -112,145 +73,15 @@ format DataOp { 0x19: WarnUnimpl::ldrex(); } } - 0xb: decode PUBWL { - format ArmStoreMemory { - 0x0: strh_({{ Mem.uh = Rd; - Rn = Rn - Rm; }}, - {{ EA = Rn; }}); - 0x4: strh_i({{ Mem.uh = Rd; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x8: strh_u({{ Mem.uh = Rd; - Rn = Rn + Rm; }}, - {{ EA = Rn; }}); - 0xc: strh_ui({{ Mem.uh = Rd; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x10: strh_p({{ Mem.uh = Rd; }}, - {{ EA = Rn - Rm; }}); - 0x12: strh_pw({{ Mem.uh = Rd; - Rn = Rn - Rm; }}, - {{ EA = Rn - Rm; }}); - 0x14: strh_pi({{ Mem.uh = Rd.uh; }}, - {{ EA = Rn + hilo; }}); - 0x16: strh_piw({{ Mem.uh = Rd; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - 0x18: strh_pu({{ Mem.uh = Rd; }}, - {{ EA = Rn + Rm; }}); - 0x1a: strh_puw({{ Mem.uh = Rd; - Rn = Rn + Rm; }}, - {{ EA = Rn + Rm; }}); - 0x1c: strh_pui({{ Mem.uh = Rd; }}, - {{ EA = Rn + hilo; }}); - 0x1e: strh_puiw({{ Mem.uh = Rd; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - } - format ArmLoadMemory { - 0x1: ldrh_l({{ Rd = Mem.uh; - Rn = Rn - Rm; }}, - {{ EA = Rn; }}); - 0x5: ldrh_il({{ Rd = Mem.uh; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x9: ldrh_ul({{ Rd = Mem.uh; - Rn = Rn + Rm; }}, - {{ EA = Rn; }}); - 0xd: ldrh_uil({{ Rd = Mem.uh; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x11: ldrh_pl({{ Rd = Mem.uh; }}, - {{ EA = Rn - Rm; }}); - 0x13: ldrh_pwl({{ Rd = Mem.uh; - Rn = Rn - Rm; }}, - {{ EA = Rn - Rm; }}); - 0x15: ldrh_pil({{ Rd = Mem.uh; }}, - {{ EA = Rn + hilo; }}); - 0x17: ldrh_piwl({{ Rd = Mem.uh; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - 0x19: ldrh_pul({{ Rd = Mem.uh; }}, - {{ EA = Rn + Rm; }}); - 0x1b: ldrh_puwl({{ Rd = Mem.uh; - Rn = Rn + Rm; }}, - {{ EA = Rn + Rm; }}); - 0x1d: ldrh_puil({{ Rd = Mem.uh; }}, - {{ EA = Rn + hilo; }}); - 0x1f: ldrh_puiwl({{ Rd = Mem.uh; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - } - } - format ArmLoadMemory { - 0xd: decode PUBWL { - 0x1: ldrsb_l({{ Rd = Mem.sb; - Rn = Rn - Rm; }}, - {{ EA = Rn; }}); - 0x5: ldrsb_il({{ Rd = Mem.sb; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x9: ldrsb_ul({{ Rd = Mem.sb; - Rn = Rn + Rm; }}, - {{ EA = Rn; }}); - 0xd: ldrsb_uil({{ Rd = Mem.sb; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x11: ldrsb_pl({{ Rd = Mem.sb; }}, - {{ EA = Rn - Rm; }}); - 0x13: ldrsb_pwl({{ Rd = Mem.sb; - Rn = Rn - Rm; }}, - {{ EA = Rn - Rm; }}); - 0x15: ldrsb_pil({{ Rd = Mem.sb; }}, - {{ EA = Rn + hilo; }}); - 0x17: ldrsb_piwl({{ Rd = Mem.sb; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - 0x19: ldrsb_pul({{ Rd = Mem.sb; }}, - {{ EA = Rn + Rm; }}); - 0x1b: ldrsb_puwl({{ Rd = Mem.sb; - Rn = Rn + Rm; }}, - {{ EA = Rn + Rm; }}); - 0x1d: ldrsb_puil({{ Rd = Mem.sb; }}, - {{ EA = Rn + hilo; }}); - 0x1f: ldrsb_puiwl({{ Rd = Mem.sb; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - } - 0xf: decode PUBWL { - 0x1: ldrsh_l({{ Rd = Mem.sh; - Rn = Rn - Rm; }}, - {{ EA = Rn; }}); - 0x5: ldrsh_il({{ Rd = Mem.sh; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x9: ldrsh_ul({{ Rd = Mem.sh; - Rn = Rn + Rm; }}, - {{ EA = Rn; }}); - 0xd: ldrsh_uil({{ Rd = Mem.sh; - Rn = Rn + hilo; }}, - {{ EA = Rn; }}); - 0x11: ldrsh_pl({{ Rd = Mem.sh; }}, - {{ EA = Rn - Rm; }}); - 0x13: ldrsh_pwl({{ Rd = Mem.sh; - Rn = Rn - Rm; }}, - {{ EA = Rn - Rm; }}); - 0x15: ldrsh_pil({{ Rd = Mem.sh; }}, - {{ EA = Rn + hilo; }}); - 0x17: ldrsh_piwl({{ Rd = Mem.sh; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - 0x19: ldrsh_pul({{ Rd = Mem.sh; }}, - {{ EA = Rn + Rm; }}); - 0x1b: ldrsh_puwl({{ Rd = Mem.sh; - Rn = Rn + Rm; }}, - {{ EA = Rn + Rm; }}); - 0x1d: ldrsh_puil({{ Rd = Mem.sh; }}, - {{ EA = Rn + hilo; }}); - 0x1f: ldrsh_puiwl({{ Rd = Mem.sh; - Rn = Rn + hilo; }}, - {{ EA = Rn + hilo; }}); - } + format AddrMode3 { + 0xb: strh_ldrh(store, {{ Mem.uh = Rd; }}, + load, {{ Rd = Mem.uh; }}); + 0xd: ldrd_ldrsb(load, {{ Rde = bits(Mem.ud, 31, 0); + Rdo = bits(Mem.ud, 63, 32); }}, + load, {{ Rd = Mem.sb; }}); + 0xf: strd_ldrsh(store, {{ Mem.ud = (Rde.ud & mask(32)) | + (Rdo.ud << 32); }}, + load, {{ Rd = Mem.sh; }}); } } 0: decode IS_MISC { @@ -355,107 +186,9 @@ format DataOp { 0xb: WarnUnimpl::mrs_i_spsr(); } } - 0x2: decode PUBWL { - // CAREFUL: - // Can always do EA + disp, since we negate disp using the UP flag - // Post-indexed variants - 0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd; - Rn = Rn + disp; }}, - {{ EA = Rn; }}); - 0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; - Rd = Mem; }}, - {{ EA = Rn; }}); - 0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub; - Rn = Rn + disp; }}, - {{ EA = Rn; }}); - 0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; - Rd.ub = Mem.ub; }}, - {{ EA = Rn; }}); - // Pre-indexed variants - 0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }}); - 0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }}); - 0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd; - Rn = Rn + disp; }}); - 0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; - Rd = Mem; }}); - 0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }}); - 0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }}); - 0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub; - Rn = Rn + disp; }}); - 0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; - Rd.ub = Mem.ub; }}); - } + 0x2: AddrMode2::addrMode2(Disp, disp); 0x3: decode OPCODE_4 { - 0: decode PUBWL { - format ArmStoreMemory { - 0x00, 0x02: strr_({{ Mem = Rd; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x04, 0x06: strr_b({{ Mem = Rd.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x08, 0x0a: strr_u({{ Mem = Rd; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x0c, 0x0e: strr_ub({{ Mem.ub = Rd.ub; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x10: strr_p({{ Mem = Rd; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x12: strr_pw({{ Mem = Rd; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x14: strr_pb({{ Mem.ub = Rd.ub; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x16: strr_pbw({{ Mem.ub = Rd.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x18: strr_pu({{ Mem = Rd; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1a: strr_puw({{ Mem = Rd; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1c: strr_pub({{ Mem.ub = Rd; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1e: strr_pubw({{ Mem.ub = Rd; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - } - format ArmLoadMemory { - 0x01,0x03: ldrr_l({{ Rd = Mem; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x05,0x07: ldrr_bl({{ Rd = Mem.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x09,0x0b: ldrr_ul({{ Rd = Mem; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x0d,0x0f: ldrr_ubl({{ Rd = Mem.ub; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x11: ldrr_pl({{ Rd = Mem; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x13: ldrr_pwl({{ Rd = Mem; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x15: ldrr_pbl({{ Rd = Mem.ub; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x17: ldrr_pbwl({{ Rd = Mem.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x19: ldrr_pul({{ Rd = Mem; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1b: ldrr_puwl({{ Rd = Mem; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1d: ldrr_publ({{ Rd = Mem.ub; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1f: ldrr_pubwl({{ Rd = Mem.ub; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - } - } + 0: AddrMode2::addrMode2(Shift, Rm_Imm); 1: decode MEDIA_OPCODE { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); 0x8: decode MISC_OPCODE { @@ -696,5 +429,4 @@ format DataOp { } } } -} diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index df52f9413..355a67ea9 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -27,6 +27,133 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: Stephen Hines +// Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Common microop templates +// + +def template MicroConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst, + RegIndex _ura, + RegIndex _urb, + uint8_t _imm) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + _ura, _urb, _imm) + { + %(constructor)s; + } +}}; + +//////////////////////////////////////////////////////////////////// +// +// Load/store microops +// + +def template MicroMemDeclare {{ + class %(class_name)s : public %(base_class)s + { + public: + %(class_name)s(ExtMachInst machInst, + RegIndex _ura, RegIndex _urb, + uint8_t _imm); + %(BasicExecDeclare)s + %(InitiateAccDeclare)s + %(CompleteAccDeclare)s + }; +}}; + +let {{ + microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', + 'MicroMemOp', + {'memacc_code': 'Ra = Mem;', + 'ea_code': 'EA = Rb + (UP ? imm : -imm);', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', + 'MicroMemOp', + {'memacc_code': 'Mem = Ra;', + 'ea_code': 'EA = Rb + (UP ? imm : -imm);', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + header_output = MicroMemDeclare.subst(microLdrUopIop) + \ + MicroMemDeclare.subst(microStrUopIop) + decoder_output = MicroConstructor.subst(microLdrUopIop) + \ + MicroConstructor.subst(microStrUopIop) + exec_output = LoadExecute.subst(microLdrUopIop) + \ + StoreExecute.subst(microStrUopIop) + \ + LoadInitiateAcc.subst(microLdrUopIop) + \ + StoreInitiateAcc.subst(microStrUopIop) + \ + LoadCompleteAcc.subst(microLdrUopIop) + \ + StoreCompleteAcc.subst(microStrUopIop) +}}; + +//////////////////////////////////////////////////////////////////// +// +// Integer = Integer op Immediate microops +// + +def template MicroIntDeclare {{ + class %(class_name)s : public %(base_class)s + { + public: + %(class_name)s(ExtMachInst machInst, + RegIndex _ura, RegIndex _urb, + uint8_t _imm); + %(BasicExecDeclare)s + }; +}}; + +let {{ + microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', + 'MicroIntOp', + {'code': 'Ra = Rb + imm;', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', + 'MicroIntOp', + {'code': 'Ra = Rb - imm;', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + header_output = MicroIntDeclare.subst(microAddiUopIop) + \ + MicroIntDeclare.subst(microSubiUopIop) + decoder_output = MicroConstructor.subst(microAddiUopIop) + \ + MicroConstructor.subst(microSubiUopIop) + exec_output = PredOpExecute.subst(microAddiUopIop) + \ + PredOpExecute.subst(microSubiUopIop) +}}; + +//////////////////////////////////////////////////////////////////// +// +// Moving to/from double floating point registers +// + +let {{ + microMvtdUopIop = InstObjParams('mvtd_uop', 'MicroMvtdUop', + 'PredOp', + {'code': 'Fd.ud = (Rhi.ud << 32) | Rlo;', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + microMvfdUopIop = InstObjParams('mvfd_uop', 'MicroMvfdUop', + 'PredOp', + {'code': '''Rhi = bits(Fd.ud, 63, 32); + Rlo = bits(Fd.ud, 31, 0);''', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + header_output = BasicDeclare.subst(microMvtdUopIop) + \ + BasicDeclare.subst(microMvfdUopIop) + decoder_output = BasicConstructor.subst(microMvtdUopIop) + \ + BasicConstructor.subst(microMvfdUopIop) + exec_output = PredOpExecute.subst(microMvtdUopIop) + \ + PredOpExecute.subst(microMvfdUopIop) +}}; //////////////////////////////////////////////////////////////////// // @@ -52,9 +179,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) { %(constructor)s; uint32_t regs_to_handle = reglist; - uint32_t j = 0, - start_addr = 0, - end_addr = 0; + uint32_t start_addr = 0; switch (puswl) { @@ -63,28 +188,24 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) case 0x02: // W stmda_w case 0x03: // WL ldmda_wl start_addr = (ones << 2) - 4; - end_addr = 0; break; case 0x08: // U stmia_u case 0x09: // U L ldmia_ul case 0x0a: // U W stmia case 0x0b: // U WL ldmia start_addr = 0; - end_addr = (ones << 2) - 4; break; case 0x10: // P stmdb case 0x11: // P L ldmdb case 0x12: // P W stmdb case 0x13: // P WL ldmdb start_addr = (ones << 2); // U-bit is already 0 for subtract - end_addr = 4; // negative 4 break; case 0x18: // PU stmib case 0x19: // PU L ldmib case 0x1a: // PU W stmib case 0x1b: // PU WL ldmib start_addr = 4; - end_addr = (ones << 2) + 4; break; default: panic("Unhandled Load/Store Multiple Instruction, " @@ -92,20 +213,21 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) break; } - //TODO - Add addi_uop/subi_uop here to create starting addresses - //Just using addi with 0 offset makes a "copy" of Rn for our use - uint32_t newMachInst = 0; - newMachInst = machInst & 0xffff0000; - microOps[0] = new Addi_uop(newMachInst); + // Add 0 to Rn and stick it in Raddr (register 17). + // This is equivalent to a move. + microOps[0] = new MicroAddiUop(machInst, 17, RN, 0); - for (int i = 1; i < ones+1; i++) - { + unsigned j = 0; + for (int i = 1; i < ones+1; i++) { // Get next available bit for transfer while (! ( regs_to_handle & (1<<j))) j++; regs_to_handle &= ~(1<<j); - microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr); + if (loadop) + microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr); + else + microOps[i] = new MicroStrUop(machInst, j, 17, start_addr); if (up) start_addr += 4; @@ -113,33 +235,13 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) start_addr -= 4; } - /* TODO: Take a look at how these 2 values should meet together - if (start_addr != (end_addr - 4)) - { - fprintf(stderr, "start_addr: %d\n", start_addr); - fprintf(stderr, "end_addr: %d\n", end_addr); - panic("start_addr does not meet end_addr"); - } - */ - - if (writeback) - { - uint32_t newMachInst = machInst & 0xf0000000; - uint32_t rn = (machInst >> 16) & 0x0f; - // 3322 2222 2222 1111 1111 11 - // 1098 7654 3210 9876 5432 1098 7654 3210 - // COND 0010 0100 [RN] [RD] 0000 [ IMM ] - // sub rn, rn, imm - newMachInst |= 0x02400000; - newMachInst |= ((rn << 16) | (rn << 12)); - newMachInst |= (ones << 2); - if (up) - { - microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); - } - else - { - microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); + if (writeback) { + if (up) { + microOps[numMicroops-1] = + new MicroAddiUop(machInst, RN, RN, ones * 4); + } else { + microOps[numMicroops-1] = + new MicroSubiUop(machInst, RN, RN, ones * 4); } } microOps[numMicroops-1]->setLastMicroop(); @@ -182,23 +284,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { - uint32_t newMachInst = machInst & 0xf0000000; - uint32_t rn = (machInst >> 16) & 0x0f; - // 3322 2222 2222 1111 1111 11 - // 1098 7654 3210 9876 5432 1098 7654 3210 - // COND 0010 0100 [RN] [RD] 0000 [ IMM ] - // sub rn, rn, imm - newMachInst |= 0x02400000; - newMachInst |= ((rn << 16) | (rn << 12)); - if (up) - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); - } - else - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); + if (up) { + microOps[numMicroops-1] = + new MicroAddiUop(machInst, RN, RN, disp8); + } else { + microOps[numMicroops-1] = + new MicroSubiUop(machInst, RN, RN, disp8); } } microOps[numMicroops-1]->setLastMicroop(); @@ -221,29 +312,15 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) start_addr = 0; for (int i = 0; i < count; i++) - { emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr); - } - if (writeback) - { - uint32_t newMachInst = machInst & 0xf0000000; - uint32_t rn = (machInst >> 16) & 0x0f; - // 3322 2222 2222 1111 1111 11 - // 1098 7654 3210 9876 5432 1098 7654 3210 - // COND 0010 0100 [RN] [RD] 0000 [ IMM ] - // sub rn, rn, imm - newMachInst |= 0x02400000; - newMachInst |= ((rn << 16) | (rn << 12)); - if (up) - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); - } - else - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); + if (writeback) { + if (up) { + microOps[numMicroops-1] = + new MicroAddiUop(machInst, RN, RN, disp8); + } else { + microOps[numMicroops-1] = + new MicroSubiUop(machInst, RN, RN, disp8); } } microOps[numMicroops-1]->setLastMicroop(); diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index c8ac19c61..0b0a4c9fa 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -39,32 +39,6 @@ def template LoadStoreDeclare {{ */ class %(class_name)s : public %(base_class)s { - protected: - - /** - * "Fake" effective address computation class for "%(mnemonic)s". - */ - class EAComp : public %(base_class)s - { - public: - /// Constructor - EAComp(ExtMachInst machInst); - - %(BasicExecDeclare)s - }; - - /** - * "Fake" memory access instruction class for "%(mnemonic)s". - */ - class MemAcc : public %(base_class)s - { - public: - /// Constructor - MemAcc(ExtMachInst machInst); - - %(BasicExecDeclare)s - }; - public: /// Constructor. @@ -89,87 +63,15 @@ def template CompleteAccDeclare {{ }}; -def template EACompConstructor {{ - inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) - { - %(constructor)s; - } -}}; - - -def template MemAccConstructor {{ - inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) - { - %(constructor)s; - } -}}; - - def template LoadStoreConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, - new EAComp(machInst), new MemAcc(machInst)) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; } }}; -def template EACompExecute {{ - Fault - %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = NoFault; - - %(op_decl)s; - %(op_rd)s; - %(ea_code)s; - - if (%(predicate_test)s) - { - if (fault == NoFault) { - %(op_wb)s; - xc->setEA(EA); - } - } - - return fault; - } -}}; - -def template LoadMemAccExecute {{ - Fault - %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = NoFault; - - %(op_decl)s; - %(op_rd)s; - EA = xc->getEA(); - - if (%(predicate_test)s) - { - if (fault == NoFault) { - fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); - %(memacc_code)s; - } - - if (fault == NoFault) { - %(op_wb)s; - } - } - - return fault; - } -}}; - - def template LoadExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const @@ -250,37 +152,6 @@ def template LoadCompleteAcc {{ }}; -def template StoreMemAccExecute {{ - Fault - %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = NoFault; - - %(op_decl)s; - %(op_rd)s; - - if (%(predicate_test)s) - { - EA = xc->getEA(); - - if (fault == NoFault) { - fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, - memAccessFlags, NULL); - if (traceData) { traceData->setData(Mem); } - } - - if (fault == NoFault) { - %(op_wb)s; - } - } - - return fault; - } -}}; - - def template StoreExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const @@ -354,7 +225,8 @@ def template StoreCompleteAcc {{ { Fault fault = NoFault; - %(op_dest_decl)s; + %(op_decl)s; + %(op_rd)s; if (%(predicate_test)s) { @@ -387,71 +259,114 @@ def template StoreCondCompleteAcc {{ } }}; - -def template MiscMemAccExecute {{ - Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = NoFault; - - %(op_decl)s; - %(op_rd)s; - - if (%(predicate_test)s) - { - EA = xc->getEA(); - - if (fault == NoFault) { - %(memacc_code)s; - } - } - - return NoFault; - } -}}; - -def template MiscExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = NoFault; - - %(op_decl)s; - %(op_rd)s; - %(ea_code)s; - - if (%(predicate_test)s) - { - if (fault == NoFault) { - %(memacc_code)s; - } - } - - return NoFault; - } +let {{ + def buildPUBWLCase(p, u, b, w, l): + return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) + + def buildMode2Inst(p, u, b, w, l, suffix, offset): + mnem = ("str", "ldr")[l] + op = ("-", "+")[u] + offset = op + ArmGenericCodeSubs(offset); + mem = ("Mem", "Mem.ub")[b] + code = ("%s = Rd;", "Rd = %s;")[l] % mem + ea_code = "EA = Rn %s;" % ("", offset)[p] + if p == 0 or w == 1: + code += "Rn = Rn %s;" % offset + if p == 0 and w == 0: + # Here's where we'll tack on a flag to make this a usermode access. + mnem += "t" + type = ("Store", "Load")[l] + newSuffix = "_%s_P%dU%dB%dW%d" % (suffix, p, u, b, w) + if b == 1: + mnem += "b" + return LoadStoreBase(mnem, mnem.capitalize() + newSuffix, + ea_code, code, mem_flags = [], inst_flags = [], + base_class = 'Memory' + suffix, + exec_template_base = type.capitalize()) + + def buildMode3Inst(p, u, i, w, type, code, mnem): + op = ("-", "+")[u] + offset = ("%s Rm", "%s hilo")[i] % op + ea_code = "EA = Rn %s;" % ("", offset)[p] + if p == 0 or w == 1: + code += "Rn = Rn %s;" % offset + newSuffix = "_P%dU%dI%dW%d" % (p, u, i, w) + suffix = ("Reg", "Hilo")[i] + return LoadStoreBase(mnem, mnem.capitalize() + newSuffix, + ea_code, code, mem_flags = [], inst_flags = [], + base_class = 'Memory' + suffix, + exec_template_base = type.capitalize()) }}; -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 format AddrMode2(suffix, offset) {{ + header_output = decoder_output = exec_output = "" + decode_block = "switch(PUBWL) {\n" + + # Loop over all the values of p, u, b, w and l and build instructions and + # a decode block for them. + for p in (0, 1): + for u in (0, 1): + for b in (0, 1): + for w in (0, 1): + for l in (0, 1): + (new_header_output, + new_decoder_output, + new_decode_block, + new_exec_output) = buildMode2Inst(p, u, b, w, l, + suffix, offset) + header_output += new_header_output + decoder_output += new_decoder_output + exec_output += new_exec_output + decode_block += ''' + case %#x: + {%s} + break; + ''' % (buildPUBWLCase(p,u,b,w,l), new_decode_block) + decode_block += ''' + default: + return new Unknown(machInst); + break; + }''' }}; - -def template MiscCompleteAcc {{ - Fault %(class_name)s::completeAcc(PacketPtr pkt, - %(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - panic("Misc instruction does not support split access method!"); - - return NoFault; - } +def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{ + l0Code = ArmGenericCodeSubs(l0Code); + l1Code = ArmGenericCodeSubs(l1Code); + + header_output = decoder_output = exec_output = "" + decode_block = "switch(PUBWL) {\n" + (l0Mnem, l1Mnem) = name.split("_"); + + # Loop over all the values of p, u, i, w and l and build instructions and + # a decode block for them. + for (l, type, code, mnem) in ((0, l0Type, l0Code, l0Mnem), + (1, l1Type, l1Code, l1Mnem)): + for p in (0, 1): + wset = (0, 1) + if (p == 0): + wset = (0,) + for u in (0, 1): + for i in (0, 1): + for w in wset: + (new_header_output, + new_decoder_output, + new_decode_block, + new_exec_output) = buildMode3Inst(p, u, i, w, + type, code, mnem) + header_output += new_header_output + decoder_output += new_decoder_output + exec_output += new_exec_output + decode_block += ''' + case %#x: + {%s} + break; + ''' % (buildPUBWLCase(p,u,i,w,l), new_decode_block) + + decode_block += ''' + default: + return new Unknown(machInst); + break; + }''' }}; def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa index 5caab642c..b5efec568 100644 --- a/src/arch/arm/isa/formats/util.isa +++ b/src/arch/arm/isa/formats/util.isa @@ -35,7 +35,6 @@ def ArmGenericCodeSubs(code): # Substitute in the shifted portion of operations new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code) new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code) - new_code = re.sub(r'^', 'Cpsr = Cpsr;', new_code) return new_code def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, @@ -45,31 +44,11 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, mem_flags = makeList(mem_flags) inst_flags = makeList(inst_flags) - # add hook to get effective addresses into execution trace output. - ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' - - # Some CPU models execute the memory operation as an atomic unit, - # while others want to separate them into an effective address - # computation and a memory access operation. As a result, we need - # to generate three StaticInst objects. Note that the latter two - # are nested inside the larger "atomic" one. - - # Generate InstObjParams for each of the three objects. Note that - # they differ only in the set of code objects contained (which in - # turn affects the object's overall operand list). iop = InstObjParams(name, Name, base_class, {'ea_code': ea_code, 'memacc_code': memacc_code, 'predicate_test': predicateTest}, inst_flags) - ea_iop = InstObjParams(name, Name, base_class, - {'ea_code': ea_code, - 'predicate_test': predicateTest}, - inst_flags) - memacc_iop = InstObjParams(name, Name, base_class, - {'memacc_code': memacc_code, - 'predicate_test': predicateTest}, - inst_flags) if mem_flags: s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' @@ -82,20 +61,15 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # corresponding Store template.. StoreCondInitiateAcc = StoreInitiateAcc - 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), - EACompConstructor.subst(ea_iop) - + MemAccConstructor.subst(memacc_iop) - + LoadStoreConstructor.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(iop) + completeAccTemplate.subst(iop)) }}; @@ -127,67 +101,25 @@ output decoder {{ return str; } - // Generate the bit pattern for an Ldr_uop or Str_uop; - StaticInstPtr - gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp) - { - StaticInstPtr newInst; - uint32_t newMachInst = baseinst & 0xffff0000; - newMachInst |= (rd << 12); - newMachInst |= disp; - if (loadop) - newInst = new Ldr_uop(newMachInst); - else - newInst = new Str_uop(newMachInst); - return newInst; - } - // Emits uops for a double fp move - int - emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp) + void + emit_ldfstf_uops(StaticInstPtr* microOps, int index, ExtMachInst machInst, + bool loadop, bool up, int32_t disp) { - StaticInstPtr newInst; - uint32_t newMachInst; - if (loadop) { - newMachInst = baseinst & 0xfffff000; - newMachInst |= (disp & 0x0fff); - newInst = new Ldlo_uop(newMachInst); - microOps[index++] = newInst; - - newMachInst = baseinst & 0xfffff000; - if (up) - newMachInst |= ((disp + 4) & 0x0fff); - else - newMachInst |= ((disp - 4) & 0x0fff); - newInst = new Ldhi_uop(newMachInst); - microOps[index++] = newInst; - - newMachInst = baseinst & 0xf000f000; - newInst = new Mvtd_uop(newMachInst); - microOps[index++] = newInst; + microOps[index++] = new MicroLdrUop(machInst, 19, RN, disp); + microOps[index++] = + new MicroLdrUop(machInst, 18, RN, disp + (up ? 4 : -4)); + microOps[index++] = new MicroMvtdUop(machInst); } else { - newMachInst = baseinst & 0xf000f000; - newInst = new Mvfd_uop(newMachInst); - microOps[index++] = newInst; - - newMachInst = baseinst & 0xfffff000; - newMachInst |= (disp & 0x0fff); - newInst = new Stlo_uop(newMachInst); - microOps[index++] = newInst; - - newMachInst = baseinst & 0xfffff000; - if (up) - newMachInst |= ((disp + 4) & 0x0fff); - else - newMachInst |= ((disp - 4) & 0x0fff); - newInst = new Sthi_uop(newMachInst); - microOps[index++] = newInst; + microOps[index++] = new MicroMvfdUop(machInst); + microOps[index++] = new MicroStrUop(machInst, 19, RN, disp); + microOps[index++] = + new MicroStrUop(machInst, 18, RN, disp + (up ? 4 : -4)); } - return 3; } }}; diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index c056d41f2..fa41918c1 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -40,29 +40,48 @@ def operand_types {{ 'df' : ('float', 64) }}; +let {{ + maybePCRead = ''' + ((%(reg_idx)s == PCReg) ? (xc->readPC() + 8) : + xc->%(func)s(this, %(op_idx)s)) + ''' + maybePCWrite = ''' + ((%(reg_idx)s == PCReg) ? xc->setNextPC(%(final_val)s) : + xc->%(func)s(this, %(op_idx)s, %(final_val)s)) + ''' +}}; + def operands {{ #General Purpose Integer Reg Operands - 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1), - 'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2), - 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3), - 'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4), + 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1, maybePCRead, maybePCWrite), + 'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2, maybePCRead, maybePCWrite), + 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite), + 'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite), + + #Destination register for load/store double instructions + 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), + 'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite), + + 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6), + 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7), + 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8), + 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9), - 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 5), - 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 5), - 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 6), - 'LR': ('IntReg', 'uw', '14', 'IsInteger', 6), + #Register fields for microops + 'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite), + 'Rb' : ('IntReg', 'uw', 'urb', 'IsInteger', 12, maybePCRead, maybePCWrite), #General Purpose Floating Point Reg Operands - 'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 1), - 'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 2), - 'Fm': ('FloatReg', 'df', 'FM', 'IsFloating', 3), + 'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20), + 'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 21), + 'Fm': ('FloatReg', 'df', 'FM', 'IsFloating', 22), #Memory Operand - 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8), + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30), - 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 7), - 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 7), - 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9), - 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 9), + 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40), + 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 42), + 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 43), }}; diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh index 6f5e17497..542174b6b 100644 --- a/src/arch/arm/isa_traits.hh +++ b/src/arch/arm/isa_traits.hh @@ -95,46 +95,6 @@ namespace ArmISA // return a no-op instruction... used for instruction fetch faults const ExtMachInst NoopMachInst = 0x00000000; - // Constants Related to the number of registers - const int NumIntArchRegs = 16; - const int NumIntSpecialRegs = 19; - const int NumFloatArchRegs = 16; - const int NumFloatSpecialRegs = 5; - const int NumControlRegs = 7; - const int NumInternalProcRegs = 0; - - const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; - const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; - const int NumMiscRegs = NumControlRegs; - - const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs; - - const int TotalDataRegs = NumIntRegs + NumFloatRegs; - - // Static instruction parameters - const int MaxInstSrcRegs = 5; - const int MaxInstDestRegs = 3; - - // semantically meaningful register indices - const int ReturnValueReg = 0; - const int ReturnValueReg1 = 1; - const int ReturnValueReg2 = 2; - const int ArgumentReg0 = 0; - const int ArgumentReg1 = 1; - const int ArgumentReg2 = 2; - const int ArgumentReg3 = 3; - const int FramePointerReg = 11; - const int StackPointerReg = 13; - const int ReturnAddressReg = 14; - const int PCReg = 15; - - const int ZeroReg = NumIntArchRegs; - const int AddrReg = ZeroReg + 1; // Used to generate address for uops - - const int SyscallNumReg = ReturnValueReg; - const int SyscallPseudoReturnReg = ReturnValueReg; - const int SyscallSuccessReg = ReturnValueReg; - const int LogVMPageSize = 12; // 4K bytes const int VMPageSize = (1 << LogVMPageSize); @@ -144,10 +104,6 @@ namespace ArmISA const int WordBytes = 4; const int HalfwordBytes = 2; const int ByteBytes = 1; - - // These help enumerate all the registers for dependence tracking. - const int FP_Base_DepTag = NumIntRegs; - const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs; }; using namespace ArmISA; diff --git a/src/arch/arm/regfile.hh b/src/arch/arm/regfile.hh deleted file mode 100644 index 91cc67be0..000000000 --- a/src/arch/arm/regfile.hh +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2007-2008 The Florida State University - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Stephen Hines - */ - -#ifndef __ARCH_ARM_REGFILE_HH__ -#define __ARCH_ARM_REGFILE_HH__ - -#include "arch/arm/regfile/regfile.hh" - -#endif diff --git a/src/arch/arm/regfile/float_regfile.hh b/src/arch/arm/regfile/float_regfile.hh deleted file mode 100644 index 757f5f0df..000000000 --- a/src/arch/arm/regfile/float_regfile.hh +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2007-2008 The Florida State University - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Stephen Hines - */ - -#ifndef __ARCH_ARM_REGFILE_FLOAT_REGFILE_HH__ -#define __ARCH_ARM_REGFILE_FLOAT_REGFILE_HH__ - -#include "arch/arm/types.hh" -#include "arch/arm/isa_traits.hh" -#include "base/misc.hh" -#include "base/bitfield.hh" -#include "sim/faults.hh" -#include "sim/serialize.hh" - -#include <string> - -class Checkpoint; - -namespace ArmISA -{ - static inline std::string getFloatRegName(RegIndex) - { - return ""; - } - - const uint32_t ARM32_QNAN = 0x7fbfffff; - const uint64_t ARM64_QNAN = ULL(0x7fbfffffffffffff); - - enum FPControlRegNums { - FIR = NumFloatArchRegs, - FCCR, - FEXR, - FENR, - FCSR - }; - - enum FCSRBits { - Inexact = 1, - Underflow, - Overflow, - DivideByZero, - Invalid, - Unimplemented - }; - - enum FCSRFields { - Flag_Field = 1, - Enable_Field = 6, - Cause_Field = 11 - }; - - const int SingleWidth = 32; - const int SingleBytes = SingleWidth / 4; - - const int DoubleWidth = 64; - const int DoubleBytes = DoubleWidth / 4; - - const int QuadWidth = 128; - const int QuadBytes = QuadWidth / 4; - - class FloatRegFile - { - protected: - union { - FloatRegBits qregs[NumFloatRegs]; - FloatRegVal regs[NumFloatRegs]; - }; - - public: - - void clear() - { - bzero(regs, sizeof(regs)); - regs[8] = 0.0; - regs[9] = 1.0; - regs[10] = 2.0; - regs[11] = 3.0; - regs[12] = 4.0; - regs[13] = 5.0; - regs[14] = 0.5; - regs[15] = 10.0; - } - - FloatRegVal readReg(int floatReg, int width) - { - return regs[floatReg]; - } - - FloatRegBits readRegBits(int floatReg, int width) - { - //return qregs[floatReg]; - switch(width) - { - case SingleWidth: - { - union { - float f; - uint32_t i; - } s; - s.f = (float) regs[floatReg]; - return s.i; - } - case DoubleWidth: - { - uint64_t tmp = (qregs[floatReg]<<32|qregs[floatReg]>>32); - return tmp; - } - default: - panic("Attempted to read a %d bit floating point " - "register!", width); - - } - } - - Fault setReg(int floatReg, const FloatRegVal &val, int width) - { - if (floatReg > 7) - panic("Writing to a hard-wired FP register"); - regs[floatReg] = val; - return NoFault; - } - - Fault setRegBits(int floatReg, const FloatRegBits &val, int width) - { - if (floatReg > 7) - panic("Writing to a hard-wired FP register"); - switch(width) - { - case DoubleWidth: - { - uint64_t tmp = (val << 32 | val >> 32); - qregs[floatReg] = tmp; - return NoFault; - } - case SingleWidth: - default: - panic("Attempted to write a %d bit floating point " - "register!", width); - } - } - - void serialize(std::ostream &os) - { - SERIALIZE_ARRAY(regs, NumFloatRegs); - } - - void unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(regs, NumFloatRegs); - } - }; - -} // namespace ArmISA - -#endif diff --git a/src/arch/arm/regfile/int_regfile.hh b/src/arch/arm/regfile/int_regfile.hh deleted file mode 100644 index b22129f33..000000000 --- a/src/arch/arm/regfile/int_regfile.hh +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2007-2008 The Florida State University - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Stephen Hines - */ - -#ifndef __ARCH_ARM_REGFILE_INT_REGFILE_HH__ -#define __ARCH_ARM_REGFILE_INT_REGFILE_HH__ - -#include "arch/arm/isa_traits.hh" -#include "arch/arm/types.hh" -#include "base/misc.hh" -#include "base/trace.hh" -#include "sim/faults.hh" -#include "sim/serialize.hh" - -class Checkpoint; -class ThreadContext; - -namespace ArmISA -{ - static inline std::string getIntRegName(RegIndex) - { - return ""; - } - - enum MiscIntRegNums { - zero_reg = NumIntArchRegs, - addr_reg, - - rhi, - rlo, - - r8_fiq, /* FIQ mode register bank */ - r9_fiq, - r10_fiq, - r11_fiq, - r12_fiq, - - r13_fiq, /* FIQ mode SP and LR */ - r14_fiq, - - r13_irq, /* IRQ mode SP and LR */ - r14_irq, - - r13_svc, /* SVC mode SP and LR */ - r14_svc, - - r13_undef, /* UNDEF mode SP and LR */ - r14_undef, - - r13_abt, /* ABT mode SP and LR */ - r14_abt - }; - - class IntRegFile - { - protected: - IntReg regs[NumIntRegs]; - - public: - IntReg readReg(int intReg) - { - DPRINTF(IntRegs, "Reading int reg %d as %#x.\n", - intReg, regs[intReg]); - return regs[intReg]; - } - - void clear() - { - bzero(regs, sizeof(regs)); - } - - Fault setReg(int intReg, const IntReg &val) - { - DPRINTF(IntRegs, "Setting int reg %d to %#x.\n", intReg, val); - regs[intReg] = val; - return NoFault; - } - - void serialize(std::ostream &os) - { - SERIALIZE_ARRAY(regs, NumIntRegs); - } - - void unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(regs, NumIntRegs); - } - }; - -} // namespace ArmISA - -#endif diff --git a/src/arch/arm/regfile/regfile.cc b/src/arch/arm/regfile/regfile.cc deleted file mode 100644 index a4d6e9a4a..000000000 --- a/src/arch/arm/regfile/regfile.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2007-2008 The Florida State University - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Stephen Hines - */ - -#include "arch/arm/regfile/regfile.hh" -#include "sim/serialize.hh" - -using namespace std; - -namespace ArmISA -{ - -void -copyRegs(ThreadContext *src, ThreadContext *dest) -{ - panic("Copy Regs Not Implemented Yet\n"); -} - -void -copyMiscRegs(ThreadContext *src, ThreadContext *dest) -{ - panic("Copy Misc. Regs Not Implemented Yet\n"); -} - -void -MiscRegFile::copyMiscRegs(ThreadContext *tc) -{ - panic("Copy Misc. Regs Not Implemented Yet\n"); -} - -void -RegFile::serialize(EventManager *em, ostream &os) -{ - intRegFile.serialize(os); - //SERIALIZE_ARRAY(floatRegFile, NumFloatRegs); - //SERIALZE_ARRAY(miscRegFile); - //SERIALIZE_SCALAR(miscRegs.fpcr); - //SERIALIZE_SCALAR(miscRegs.lock_flag); - //SERIALIZE_SCALAR(miscRegs.lock_addr); - //SERIALIZE_SCALAR(pc); - SERIALIZE_SCALAR(npc); - SERIALIZE_SCALAR(nnpc); -} - -void -RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) -{ - intRegFile.unserialize(cp, section); - //UNSERIALIZE_ARRAY(floatRegFile); - //UNSERIALZE_ARRAY(miscRegFile); - //UNSERIALIZE_SCALAR(miscRegs.fpcr); - //UNSERIALIZE_SCALAR(miscRegs.lock_flag); - //UNSERIALIZE_SCALAR(miscRegs.lock_addr); - //UNSERIALIZE_SCALAR(pc); - UNSERIALIZE_SCALAR(npc); - UNSERIALIZE_SCALAR(nnpc); - -} - -} // namespace ArmISA diff --git a/src/arch/arm/regfile/regfile.hh b/src/arch/arm/regfile/regfile.hh deleted file mode 100644 index 7f4d21353..000000000 --- a/src/arch/arm/regfile/regfile.hh +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2007-2008 The Florida State University - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Stephen Hines - */ - -#ifndef __ARCH_ARM_REGFILE_REGFILE_HH__ -#define __ARCH_ARM_REGFILE_REGFILE_HH__ - -#include "arch/arm/types.hh" -#include "arch/arm/regfile/int_regfile.hh" -#include "arch/arm/regfile/float_regfile.hh" -#include "arch/arm/regfile/misc_regfile.hh" -#include "sim/faults.hh" - -class Checkpoint; -class EventManager; -class ThreadContext; - -namespace ArmISA -{ - class RegFile - { - protected: - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file - - public: - - void clear() - { - intRegFile.clear(); - floatRegFile.clear(); - miscRegFile.clear(); - } - - MiscReg readMiscRegNoEffect(int miscReg) - { - return miscRegFile.readRegNoEffect(miscReg); - } - - MiscReg readMiscReg(int miscReg, ThreadContext *tc) - { - return miscRegFile.readReg(miscReg, tc); - } - - void setMiscRegNoEffect(int miscReg, const MiscReg &val) - { - miscRegFile.setRegNoEffect(miscReg, val); - } - - void setMiscReg(int miscReg, const MiscReg &val, - ThreadContext * tc) - { - miscRegFile.setReg(miscReg, val, tc); - } - - FloatRegVal readFloatReg(int floatReg) - { - return floatRegFile.readReg(floatReg,SingleWidth); - } - - FloatRegVal readFloatReg(int floatReg, int width) - { - return floatRegFile.readReg(floatReg,width); - } - - FloatRegBits readFloatRegBits(int floatReg) - { - return floatRegFile.readRegBits(floatReg,SingleWidth); - } - - FloatRegBits readFloatRegBits(int floatReg, int width) - { - return floatRegFile.readRegBits(floatReg,width); - } - - void setFloatReg(int floatReg, const FloatRegVal &val) - { - floatRegFile.setReg(floatReg, val, SingleWidth); - } - - void setFloatReg(int floatReg, const FloatRegVal &val, int width) - { - floatRegFile.setReg(floatReg, val, width); - } - - void setFloatRegBits(int floatReg, const FloatRegBits &val) - { - floatRegFile.setRegBits(floatReg, val, SingleWidth); - } - - void setFloatRegBits(int floatReg, const FloatRegBits &val, int width) - { - floatRegFile.setRegBits(floatReg, val, width); - } - - IntReg readIntReg(int intReg) - { - // In the Arm, reading from the PC for a generic instruction yields - // the current PC + 8, due to previous pipeline implementations - if (intReg == PCReg) - return intRegFile.readReg(intReg) + 8; - //return pc + 8; - else - return intRegFile.readReg(intReg); - } - - void setIntReg(int intReg, const IntReg &val) - { - // Have to trap writes to PC so that they update NPC instead - if (intReg == PCReg) - setNextPC(val); - else - intRegFile.setReg(intReg, val); - } - protected: - - Addr pc; // program counter - Addr npc; // next-cycle program counter - Addr nnpc; // next-next-cycle program counter - - public: - Addr readPC() - { - return intRegFile.readReg(PCReg); - //return pc; - } - - void setPC(Addr val) - { - intRegFile.setReg(PCReg, val); - //pc = val; - } - - Addr readNextPC() - { - return npc; - } - - void setNextPC(Addr val) - { - npc = val; - } - - Addr readNextNPC() - { - return npc + sizeof(MachInst); - } - - void setNextNPC(Addr val) - { - //nnpc = val; - } - - void serialize(EventManager *em, std::ostream &os); - void unserialize(EventManager *em, Checkpoint *cp, - const std::string §ion); - - void changeContext(RegContextParam param, RegContextVal val) - { - } - }; - - static inline int flattenIntIndex(ThreadContext * tc, int reg) - { - return reg; - } - - static inline int flattenFloatIndex(ThreadContext * tc, int reg) - { - return reg; - } - - void copyRegs(ThreadContext *src, ThreadContext *dest); - - void copyMiscRegs(ThreadContext *src, ThreadContext *dest); - -} // namespace ArmISA - -#endif diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh new file mode 100644 index 000000000..7f9b6b828 --- /dev/null +++ b/src/arch/arm/registers.hh @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ + +#ifndef __ARCH_ARM_REGISTERS_HH__ +#define __ARCH_ARM_REGISTERS_HH__ + +#include "arch/arm/max_inst_regs.hh" +#include "arch/arm/miscregs.hh" + +namespace ArmISA { + +using ArmISAInst::MaxInstSrcRegs; +using ArmISAInst::MaxInstDestRegs; + +typedef uint8_t RegIndex; + +typedef uint64_t IntReg; + +// floating point register file entry type +typedef uint32_t FloatRegBits; +typedef float FloatReg; + +// cop-0/cop-1 system control register +typedef uint64_t MiscReg; + +// Constants Related to the number of registers +const int NumIntArchRegs = 16; +const int NumIntSpecialRegs = 19; +const int NumFloatArchRegs = 16; +const int NumFloatSpecialRegs = 5; +const int NumInternalProcRegs = 0; + +const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; +const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; + +const int NumMiscRegs = NUM_MISCREGS; + + +// semantically meaningful register indices +const int ReturnValueReg = 0; +const int ReturnValueReg1 = 1; +const int ReturnValueReg2 = 2; +const int ArgumentReg0 = 0; +const int ArgumentReg1 = 1; +const int ArgumentReg2 = 2; +const int ArgumentReg3 = 3; +const int FramePointerReg = 11; +const int StackPointerReg = 13; +const int ReturnAddressReg = 14; +const int PCReg = 15; + +const int ZeroReg = NumIntArchRegs; +const int AddrReg = ZeroReg + 1; // Used to generate address for uops + +const int SyscallNumReg = ReturnValueReg; +const int SyscallPseudoReturnReg = ReturnValueReg; +const int SyscallSuccessReg = ReturnValueReg; + +// These help enumerate all the registers for dependence tracking. +const int FP_Base_DepTag = NumIntRegs; +const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs; + +typedef union { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; +} AnyReg; + +enum FPControlRegNums { + FIR = NumFloatArchRegs, + FCCR, + FEXR, + FENR, + FCSR +}; + +enum FCSRBits { + Inexact = 1, + Underflow, + Overflow, + DivideByZero, + Invalid, + Unimplemented +}; + +enum FCSRFields { + Flag_Field = 1, + Enable_Field = 6, + Cause_Field = 11 +}; + +enum MiscIntRegNums { + zero_reg = NumIntArchRegs, + addr_reg, + + rhi, + rlo, + + r8_fiq, /* FIQ mode register bank */ + r9_fiq, + r10_fiq, + r11_fiq, + r12_fiq, + + r13_fiq, /* FIQ mode SP and LR */ + r14_fiq, + + r13_irq, /* IRQ mode SP and LR */ + r14_irq, + + r13_svc, /* SVC mode SP and LR */ + r14_svc, + + r13_undef, /* UNDEF mode SP and LR */ + r14_undef, + + r13_abt, /* ABT mode SP and LR */ + r14_abt +}; + +} // namespace ArmISA + +#endif diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 3a0fdf2a5..2c4e1291c 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -113,29 +113,9 @@ namespace ArmISA ROR }; - typedef uint8_t RegIndex; - - typedef uint64_t IntReg; typedef uint64_t LargestRead; // Need to use 64 bits to make sure that read requests get handled properly - // floating point register file entry type - typedef uint32_t FloatReg32; - typedef uint64_t FloatReg64; - typedef uint64_t FloatRegBits; - - typedef double FloatRegVal; - typedef double FloatReg; - - // cop-0/cop-1 system control register - typedef uint64_t MiscReg; - - typedef union { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; - typedef int RegContextParam; typedef int RegContextVal; diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 93f207ec7..a2f0ef170 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -113,6 +113,18 @@ namespace ArmISA { { return NoFault; } + + static inline void + copyRegs(ThreadContext *src, ThreadContext *dest) + { + panic("Copy Regs Not Implemented Yet\n"); + } + + static inline void + copyMiscRegs(ThreadContext *src, ThreadContext *dest) + { + panic("Copy Misc. Regs Not Implemented Yet\n"); + } }; |