diff options
Diffstat (limited to 'src/arch/x86')
37 files changed, 1008 insertions, 279 deletions
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index f4a8782f2..623d61aec 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -88,6 +88,7 @@ Import('*') if env['TARGET_ISA'] == 'x86': Source('emulenv.cc') Source('floatregfile.cc') + Source('faults.cc') Source('insts/microfpop.cc') Source('insts/microldstop.cc') Source('insts/microop.cc') @@ -95,6 +96,7 @@ if env['TARGET_ISA'] == 'x86': Source('insts/static_inst.cc') Source('intregfile.cc') Source('miscregfile.cc') + Source('pagetable.cc') Source('predecoder.cc') Source('predecoder_tables.cc') Source('regfile.cc') diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index f16408e63..ce4db4f4c 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -58,18 +58,18 @@ from m5.params import * class X86TLB(SimObject): type = 'X86TLB' abstract = True - #size = Param.Int("TLB size") + size = Param.Int("TLB size") class X86DTB(X86TLB): type = 'X86DTB' cxx_namespace = 'X86ISA' cxx_class = 'DTB' - #size = 64 + size = 64 class X86ITB(X86TLB): type = 'X86ITB' cxx_namespace = 'X86ISA' cxx_class = 'ITB' - #size = 64 + size = 64 diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc new file mode 100644 index 000000000..124dcf41e --- /dev/null +++ b/src/arch/x86/faults.cc @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2003-2007 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +/* + * Copyright (c) 2007 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/faults.hh" +#include "base/trace.hh" +#include "config/full_system.hh" +#include "cpu/thread_context.hh" +#if !FULL_SYSTEM +#include "arch/x86/isa_traits.hh" +#include "mem/page_table.hh" +#include "sim/process.hh" +#endif + +namespace X86ISA +{ +#if FULL_SYSTEM + void X86Trap::invoke(TheeadContext * tc) + { + panic("X86 faults are not implemented!"); + } + + void X86Abort::invoke(TheeadContext * tc) + { + panic("X86 faults are not implemented!"); + } + + void X86Interrupt::invoke(TheeadContext * tc) + { + panic("X86 faults are not implemented!"); + } +#else // !FULL_SYSTEM + void FakeITLBFault::invoke(ThreadContext * tc) + { + DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n", + vaddr, tc->readPC()); + Process *p = tc->getProcessPtr(); + Addr paddr; + bool success = p->pTable->translate(vaddr, paddr); + if(!success) { + panic("Tried to execute unmapped address %#x.\n", vaddr); + } else { + TlbEntry entry; + entry.pageStart = p->pTable->pageAlign(paddr); + entry.writeable = false; + entry.user = true; + entry.uncacheable = false; + entry.global = false; + entry.patBit = 0; + entry.noExec = false; + entry.size = PageBytes; + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart); + tc->getITBPtr()->insert(alignedVaddr, entry); + } + } + + void FakeDTLBFault::invoke(ThreadContext * tc) + { + DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n", + vaddr, tc->readPC()); + Process *p = tc->getProcessPtr(); + Addr paddr; + bool success = p->pTable->translate(vaddr, paddr); + if(!success) { + p->checkAndAllocNextPage(vaddr); + success = p->pTable->translate(vaddr, paddr); + } + if(!success) { + panic("Tried to access unmapped address %#x.\n", vaddr); + } else { + TlbEntry entry; + entry.pageStart = p->pTable->pageAlign(paddr); + entry.writeable = true; + entry.user = true; + entry.uncacheable = false; + entry.global = false; + entry.patBit = 0; + entry.noExec = true; + entry.size = PageBytes; + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart); + tc->getDTBPtr()->insert(alignedVaddr, entry); + } + } +#endif +} // namespace X86ISA + diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 936d0357c..0579be9b5 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -63,20 +63,84 @@ namespace X86ISA { - class X86Fault : public FaultBase + // Base class for all x86 "faults" where faults is in the m5 sense + class X86FaultBase : public FaultBase { protected: + const char * faultName; + const char * mnem; + + X86FaultBase(const char * _faultName, const char * _mnem) : + faultName(_faultName), mnem(_mnem) + { + } + const char * name() const { - return "generic_x86_fault"; + return faultName; } - void invoke(ThreadContext * tc) + virtual bool isBenign() + { + return true; + } + + virtual const char * mnemonic() const { - panic("X86 faults are not implemented!"); + return mnem; } }; + // Base class for x86 faults which behave as if the underlying instruction + // didn't happen. + class X86Fault : public X86FaultBase + { + protected: + X86Fault(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + }; + + // Base class for x86 traps which behave as if the underlying instruction + // completed. + class X86Trap : public X86FaultBase + { + protected: + X86Trap(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif + }; + + // Base class for x86 aborts which seem to be catastrophic failures. + class X86Abort : public X86FaultBase + { + protected: + X86Abort(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif + }; + + // Base class for x86 interrupts. + class X86Interrupt : public X86FaultBase + { + protected: + X86Interrupt(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif + }; + class UnimpInstFault : public FaultBase { public: @@ -95,6 +159,249 @@ namespace X86ISA { panic("Machine check fault not implemented in x86!\n"); } + + // Below is a summary of the interrupt/exception information in the + // architecture manuals. + + // Class | Type | vector | Cause | mnem + //------------------------------------------------------------------------ + //Contrib Fault 0 Divide-by-Zero-Error #DE + //Benign Either 1 Debug #DB + //Benign Interrupt 2 Non-Maskable-Interrupt #NMI + //Benign Trap 3 Breakpoint #BP + //Benign Trap 4 Overflow #OF + //Benign Fault 5 Bound-Range #BR + //Benign Fault 6 Invalid-Opcode #UD + //Benign Fault 7 Device-Not-Available #NM + //Benign Abort 8 Double-Fault #DF + // 9 Coprocessor-Segment-Overrun + //Contrib Fault 10 Invalid-TSS #TS + //Contrib Fault 11 Segment-Not-Present #NP + //Contrib Fault 12 Stack #SS + //Contrib Fault 13 General-Protection #GP + //Either Fault 14 Page-Fault #PF + // 15 Reserved + //Benign Fault 16 x87 Floating-Point Exception Pending #MF + //Benign Fault 17 Alignment-Check #AC + //Benign Abort 18 Machine-Check #MC + //Benign Fault 19 SIMD Floating-Point #XF + // 20-29 Reserved + //Contrib ? 30 Security Exception #SX + // 31 Reserved + //Benign Interrupt 0-255 External Interrupts #INTR + //Benign Interrupt 0-255 Software Interrupts INTn + + class DivideByZero : public X86Fault + { + public: + DivideByZero() : + X86Fault("Divide-by-Zero-Error", "#DE") + {} + }; + + class DebugException : public X86FaultBase + { + public: + DebugException() : + X86FaultBase("Debug", "#DB") + {} + }; + + class NonMaskableInterrupt : public X86Interrupt + { + public: + NonMaskableInterrupt() : + X86Interrupt("Non-Maskable-Interrupt", "#NMI") + {} + }; + + class Breakpoint : public X86Trap + { + public: + Breakpoint() : + X86Trap("Breakpoint", "#BP") + {} + }; + + class OverflowTrap : public X86Trap + { + public: + OverflowTrap() : + X86Trap("Overflow", "#OF") + {} + }; + + class BoundRange : public X86Fault + { + public: + BoundRange() : + X86Fault("Bound-Range", "#BR") + {} + }; + + class InvalidOpcode : public X86Fault + { + public: + InvalidOpcode() : + X86Fault("Invalid-Opcode", "#UD") + {} + }; + + class DeviceNotAvailable : public X86Fault + { + public: + DeviceNotAvailable() : + X86Fault("Device-Not-Available", "#NM") + {} + }; + + class DoubleFault : public X86Abort + { + public: + DoubleFault() : + X86Abort("Double-Fault", "#DF") + {} + }; + + class InvalidTSS : public X86Fault + { + public: + InvalidTSS() : + X86Fault("Invalid-TSS", "#TS") + {} + }; + + class SegmentNotPresent : public X86Fault + { + public: + SegmentNotPresent() : + X86Fault("Segment-Not-Present", "#NP") + {} + }; + + class StackFault : public X86Fault + { + public: + StackFault() : + X86Fault("Stack", "#SS") + {} + }; + + class GeneralProtection : public X86Fault + { + public: + GeneralProtection() : + X86Fault("General-Protection", "#GP") + {} + }; + + class PageFault : public X86Fault + { + public: + PageFault() : + X86Fault("Page-Fault", "#PF") + {} + }; + + class X87FpExceptionPending : public X86Fault + { + public: + X87FpExceptionPending() : + X86Fault("x87 Floating-Point Exception Pending", "#MF") + {} + }; + + class AlignmentCheck : X86Fault + { + public: + AlignmentCheck() : + X86Fault("Alignment-Check", "#AC") + {} + }; + + class MachineCheck : X86Abort + { + public: + MachineCheck() : + X86Abort("Machine-Check", "#MC") + {} + }; + + class SIMDFloatingPointFault : X86Fault + { + public: + SIMDFloatingPointFault() : + X86Fault("SIMD Floating-Point", "#XF") + {} + }; + + class SecurityException : X86FaultBase + { + public: + SecurityException() : + X86FaultBase("Security Exception", "#SX") + {} + }; + + class ExternalInterrupt : X86Interrupt + { + public: + ExternalInterrupt() : + X86Interrupt("External Interrupt", "#INTR") + {} + }; + + class SoftwareInterrupt : X86Interrupt + { + public: + SoftwareInterrupt() : + X86Interrupt("Software Interrupt", "INTn") + {} + }; + + // These faults aren't part of the ISA definition. They trigger filling + // the tlb on a miss and are to take the place of a hardware table walker. + class FakeITLBFault : public X86Fault + { +#if !FULL_SYSTEM + protected: + Addr vaddr; + public: + FakeITLBFault(Addr _vaddr) : + X86Fault("fake instruction tlb fault", "itlb"), + vaddr(_vaddr) +#else + public: + FakeITLBFault() : + X86Fault("fake instruction tlb fault", "itlb") +#endif + {} + +#if !FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif + }; + + class FakeDTLBFault : public X86Fault + { +#if !FULL_SYSTEM + protected: + Addr vaddr; + public: + FakeDTLBFault(Addr _vaddr) : + X86Fault("fake data tlb fault", "dtlb"), + vaddr(_vaddr) +#else + public: + FakeDTLBFault() : + X86Fault("fake data tlb fault", "dtlb") +#endif + {} + +#if !FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif + }; }; #endif // __ARCH_X86_FAULTS_HH__ diff --git a/src/arch/x86/floatregs.hh b/src/arch/x86/floatregs.hh index 30846ec00..dc9867c42 100644 --- a/src/arch/x86/floatregs.hh +++ b/src/arch/x86/floatregs.hh @@ -166,7 +166,7 @@ namespace X86ISA static inline FloatRegIndex FLOATREG_STACK(int index, int top) { - return (FloatRegIndex)(NUM_FLOATREGS + ((top - index + 8) % 8)); + return (FloatRegIndex)(NUM_FLOATREGS + ((top + index + 8) % 8)); } }; diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index 4f6ec5390..510295157 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -198,13 +198,18 @@ namespace X86ISA return; } fpindex -= NumMMXRegs; - if(fpindex < NumXMMRegs) { + if(fpindex < NumXMMRegs * 2) { ccprintf(os, "%%xmm%d_%s", fpindex / 2, (fpindex % 2) ? "high": "low"); return; } - fpindex -= NumXMMRegs; - ccprintf(os, "%%ufp%d", fpindex); + fpindex -= NumXMMRegs * 2; + if(fpindex < NumMicroFpRegs) { + ccprintf(os, "%%ufp%d", fpindex); + return; + } + fpindex -= NumMicroFpRegs; + ccprintf(os, "%%st(%d)", fpindex); } else { switch (reg - Ctrl_Base_DepTag) { default: diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index ecb92947f..f76912f06 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -302,7 +302,7 @@ } 0x12: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::NOP(); //XXX repe makes this a "pause" - default: xchg_B_rAX(); + default: Inst::XCHG(Bv,rAv); } 0x13: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::CDQE(rAv); @@ -330,20 +330,20 @@ 0x1: mov_rAX_Ov(); 0x2: mov_Ob_Al(); 0x3: mov_Ov_rAX(); - 0x4: movs_Yb_Xb(); - 0x5: movs_Yv_Xv(); - 0x6: StringInst::CMPS(Yb,Xb); - 0x7: StringInst::CMPS(Yv,Xv); + 0x4: StringInst::MOVS(Yb,Xb); + 0x5: StringInst::MOVS(Yv,Xv); + 0x6: StringTestInst::CMPS(Yb,Xb); + 0x7: StringTestInst::CMPS(Yv,Xv); } 0x15: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::TEST(rAb,Ib); 0x1: Inst::TEST(rAv,Iz); - 0x2: stos_Yb_Al(); - 0x3: stos_Yv_rAX(); + 0x2: StringInst::STOS(Yb); + 0x3: StringInst::STOS(Yv); 0x4: lods_Al_Xb(); 0x5: lods_rAX_Xv(); - 0x6: StringInst::SCAS(Yb); - 0x7: StringInst::SCAS(Yv); + 0x6: StringTestInst::SCAS(Yb); + 0x7: StringTestInst::SCAS(Yv); } format Inst { 0x16: MOV(Bb,Ib); diff --git a/src/arch/x86/isa/formats/string.isa b/src/arch/x86/isa/formats/string.isa index cd182ff62..b1d3c4bbe 100644 --- a/src/arch/x86/isa/formats/string.isa +++ b/src/arch/x86/isa/formats/string.isa @@ -61,7 +61,7 @@ // ////////////////////////////////////////////////////////////////////////// -def format StringInst(*opTypeSet) {{ +def format StringTestInst(*opTypeSet) {{ allBlocks = OutputBlocks() regBlocks = specializeInst(Name, list(opTypeSet), EmulEnv()) @@ -86,3 +86,29 @@ def format StringInst(*opTypeSet) {{ (header_output, decoder_output, decode_block, exec_output) = allBlocks.makeList() }}; + +def format StringInst(*opTypeSet) {{ + allBlocks = OutputBlocks() + + regBlocks = specializeInst(Name, list(opTypeSet), EmulEnv()) + eBlocks = specializeInst(Name + "_E", list(opTypeSet), EmulEnv()) + + for blocks in (regBlocks, eBlocks): + allBlocks.header_output += blocks.header_output + allBlocks.decoder_output += blocks.decoder_output + allBlocks.exec_output += blocks.exec_output + + allBlocks.decode_block = ''' + if (LEGACY_REP) { + %s + } else if (LEGACY_REPNE) { + // The repne prefix is illegal + return new MicroFault(machInst, "illprefix", new InvalidOpcode); + } else { + %s + } + ''' % (eBlocks.decode_block, regBlocks.decode_block) + + (header_output, decoder_output, + decode_block, exec_output) = allBlocks.makeList() +}}; diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 0679e972b..6724ea9b0 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -145,6 +145,7 @@ output exec {{ #include <cmath> #include "arch/x86/miscregs.hh" +#include "arch/x86/tlb.hh" #include "base/bigint.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py index 87fbb796c..e58fc00d7 100644 --- a/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py @@ -68,7 +68,7 @@ def macroop ADD_R_I def macroop ADD_M_I { limm t2, imm - ld t1, seg, sib, disp + ldst t1, seg, sib, disp add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -77,14 +77,14 @@ def macroop ADD_P_I { rdip t7 limm t2, imm - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; def macroop ADD_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -92,7 +92,7 @@ def macroop ADD_M_R def macroop ADD_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; @@ -137,7 +137,7 @@ def macroop SUB_R_P def macroop SUB_M_I { limm t2, imm - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -146,14 +146,14 @@ def macroop SUB_P_I { rdip t7 limm t2, imm - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; def macroop SUB_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -161,7 +161,7 @@ def macroop SUB_M_R def macroop SUB_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; @@ -180,7 +180,7 @@ def macroop ADC_R_I def macroop ADC_M_I { limm t2, imm - ld t1, seg, sib, disp + ldst t1, seg, sib, disp adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -189,14 +189,14 @@ def macroop ADC_P_I { rdip t7 limm t2, imm - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; def macroop ADC_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -204,7 +204,7 @@ def macroop ADC_M_R def macroop ADC_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; @@ -249,7 +249,7 @@ def macroop SBB_R_P def macroop SBB_M_I { limm t2, imm - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -258,14 +258,14 @@ def macroop SBB_P_I { rdip t7 limm t2, imm - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; def macroop SBB_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, sib, disp }; @@ -273,7 +273,7 @@ def macroop SBB_M_R def macroop SBB_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) st t1, seg, riprel, disp }; @@ -285,7 +285,7 @@ def macroop NEG_R def macroop NEG_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF) st t1, seg, sib, disp }; @@ -293,7 +293,7 @@ def macroop NEG_M def macroop NEG_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF) st t1, seg, riprel, disp }; diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py index 2a8024eee..7afd24992 100644 --- a/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py +++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py @@ -61,7 +61,7 @@ def macroop INC_R def macroop INC_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) st t1, seg, sib, disp }; @@ -69,7 +69,7 @@ def macroop INC_M def macroop INC_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) st t1, seg, riprel, disp }; @@ -81,7 +81,7 @@ def macroop DEC_R def macroop DEC_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) st t1, seg, sib, disp }; @@ -89,7 +89,7 @@ def macroop DEC_M def macroop DEC_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) st t1, seg, riprel, disp }; diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py index 504e9ab0a..f4f856974 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py @@ -61,8 +61,9 @@ def macroop CALL_NEAR_I limm t1, imm rdip t7 + # Check target of call + st t7, ss, [0, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st t7, ss, [0, t0, rsp] wrip t7, t1 }; @@ -72,8 +73,9 @@ def macroop CALL_NEAR_R .adjust_env oszIn64Override rdip t1 + # Check target of call + st t1, ss, [0, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st t1, ss, [0, t0, rsp] wripi reg, 0 }; @@ -84,8 +86,9 @@ def macroop CALL_NEAR_M rdip t7 ld t1, seg, sib, disp + # Check target of call + st t7, ss, [0, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st t7, ss, [0, t0, rsp] wripi t1, 0 }; @@ -96,8 +99,9 @@ def macroop CALL_NEAR_P rdip t7 ld t1, seg, riprel, disp + # Check target of call + st t7, ss, [0, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st t7, ss, [0, t0, rsp] wripi t1, 0 }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py index 1efddf1d2..8993f5ac4 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py @@ -60,6 +60,7 @@ def macroop RET_NEAR .adjust_env oszIn64Override ld t1, ss, [1, t0, rsp] + # Check address of return addi rsp, rsp, dsz wripi t1, 0 }; @@ -71,6 +72,7 @@ def macroop RET_NEAR_I limm t2, imm ld t1, ss, [1, t0, rsp] + # Check address of return addi rsp, rsp, dsz add rsp, rsp, t2 wripi t1, 0 diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py index 9e6807039..5fb2b2172 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py @@ -67,6 +67,7 @@ def macroop POP_M { .adjust_env oszIn64Override ld t1, ss, [1, t0, rsp] + # Check stack address addi rsp, rsp, dsz st t1, seg, sib, disp }; @@ -77,6 +78,7 @@ def macroop POP_P { rdip t7 ld t1, ss, [1, t0, rsp] + # Check stack address addi rsp, rsp, dsz st t1, seg, riprel, disp }; @@ -96,8 +98,8 @@ def macroop PUSH_I { .adjust_env oszIn64Override limm t1, imm + st t1, ss, [1, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st t1, ss, [1, t0, rsp] }; def macroop PUSH_M { @@ -105,8 +107,8 @@ def macroop PUSH_M { .adjust_env oszIn64Override ld t1, seg, sib, disp + st t1, ss, [1, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st t1, ss, [1, t0, rsp] }; def macroop PUSH_P { @@ -115,11 +117,13 @@ def macroop PUSH_P { rdip t7 ld t1, seg, riprel, disp + # Check stack address subi rsp, rsp, dsz st t1, ss, [1, t0, rsp] }; def macroop PUSHA { + # Check all the stack addresses. st rax, ss, [1, t0, rsp], "-0 * env.dataSize" st rcx, ss, [1, t0, rsp], "-1 * env.dataSize" st rdx, ss, [1, t0, rsp], "-2 * env.dataSize" @@ -132,6 +136,7 @@ def macroop PUSHA { }; def macroop POPA { + # Check all the stack addresses. ld rdi, ss, [1, t0, rsp], "0 * env.dataSize" ld rsi, ss, [1, t0, rsp], "1 * env.dataSize" ld rbp, ss, [1, t0, rsp], "2 * env.dataSize" @@ -146,8 +151,9 @@ def macroop LEAVE { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override - mov rsp, rsp, rbp - ld rbp, ss, [1, t0, rsp] + mov t1, t1, rbp + ld rbp, ss, [1, t0, t1] + mov rsp, rsp, t1 addi rsp, rsp, dsz }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py index 9478c71fc..3f243f5d8 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py @@ -68,7 +68,7 @@ def macroop XCHG_R_R def macroop XCHG_R_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp st reg, seg, sib, disp mov reg, reg, t1 }; @@ -76,14 +76,14 @@ def macroop XCHG_R_M def macroop XCHG_R_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp st reg, seg, riprel, disp mov reg, reg, t1 }; def macroop XCHG_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp st reg, seg, sib, disp mov reg, reg, t1 }; @@ -91,7 +91,7 @@ def macroop XCHG_M_R def macroop XCHG_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp st reg, seg, riprel, disp mov reg, reg, t1 }; diff --git a/src/arch/x86/isa/insts/general_purpose/logical.py b/src/arch/x86/isa/insts/general_purpose/logical.py index 2137ae82f..a8b7c6a45 100644 --- a/src/arch/x86/isa/insts/general_purpose/logical.py +++ b/src/arch/x86/isa/insts/general_purpose/logical.py @@ -62,7 +62,7 @@ def macroop OR_R_R def macroop OR_M_I { limm t2, imm - ld t1, seg, sib, disp + ldst t1, seg, sib, disp or t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, seg, sib, disp }; @@ -71,14 +71,14 @@ def macroop OR_P_I { limm t2, imm rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp or t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, seg, riprel, disp }; def macroop OR_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp or t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, seg, sib, disp }; @@ -86,7 +86,7 @@ def macroop OR_M_R def macroop OR_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp or t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, seg, riprel, disp }; @@ -124,7 +124,7 @@ def macroop XOR_R_I def macroop XOR_M_I { limm t2, imm - ld t1, seg, sib, disp + ldst t1, seg, sib, disp xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, seg, sib, disp }; @@ -133,14 +133,14 @@ def macroop XOR_P_I { limm t2, imm rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF) st t1, seg, riprel, disp }; def macroop XOR_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, seg, sib, disp }; @@ -148,7 +148,7 @@ def macroop XOR_M_R def macroop XOR_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, seg, riprel, disp }; @@ -192,7 +192,7 @@ def macroop AND_R_I def macroop AND_M_I { - ld t2, seg, sib, disp + ldst t2, seg, sib, disp limm t1, imm and t2, t2, t1, flags=(OF,SF,ZF,PF,CF) st t2, seg, sib, disp @@ -201,7 +201,7 @@ def macroop AND_M_I def macroop AND_P_I { rdip t7 - ld t2, seg, riprel, disp + ldst t2, seg, riprel, disp limm t1, imm and t2, t2, t1, flags=(OF,SF,ZF,PF,CF) st t2, seg, riprel, disp @@ -209,7 +209,7 @@ def macroop AND_P_I def macroop AND_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp and t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, seg, sib, disp }; @@ -217,7 +217,7 @@ def macroop AND_M_R def macroop AND_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp and t1, t1, reg, flags=(OF,SF,ZF,PF,CF) st t1, seg, riprel, disp }; @@ -231,7 +231,7 @@ def macroop NOT_R def macroop NOT_M { limm t1, -1 - ld t2, seg, sib, disp + ldst t2, seg, sib, disp xor t2, t2, t1 st t2, seg, sib, disp }; @@ -240,7 +240,7 @@ def macroop NOT_P { limm t1, -1 rdip t7 - ld t2, seg, riprel, disp + ldst t2, seg, riprel, disp xor t2, t2, t1 st t2, seg, riprel, disp }; diff --git a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/rotate.py b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/rotate.py index a13df3a64..b5ae9560e 100644 --- a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/rotate.py +++ b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/rotate.py @@ -61,7 +61,7 @@ def macroop ROL_R_I def macroop ROL_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp roli t1, t1, imm st t1, seg, sib, disp }; @@ -69,7 +69,7 @@ def macroop ROL_M_I def macroop ROL_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp roli t1, t1, imm st t1, seg, riprel, disp }; @@ -81,7 +81,7 @@ def macroop ROL_1_R def macroop ROL_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp roli t1, t1, 1 st t1, seg, sib, disp }; @@ -89,7 +89,7 @@ def macroop ROL_1_M def macroop ROL_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp roli t1, t1, 1 st t1, seg, riprel, disp }; @@ -101,7 +101,7 @@ def macroop ROL_R_R def macroop ROL_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rol t1, t1, reg st t1, seg, sib, disp }; @@ -109,7 +109,7 @@ def macroop ROL_M_R def macroop ROL_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rol t1, t1, reg st t1, seg, riprel, disp }; @@ -121,7 +121,7 @@ def macroop ROR_R_I def macroop ROR_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rori t1, t1, imm st t1, seg, sib, disp }; @@ -129,7 +129,7 @@ def macroop ROR_M_I def macroop ROR_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rori t1, t1, imm st t1, seg, riprel, disp }; @@ -141,7 +141,7 @@ def macroop ROR_1_R def macroop ROR_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rori t1, t1, 1 st t1, seg, sib, disp }; @@ -149,7 +149,7 @@ def macroop ROR_1_M def macroop ROR_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rori t1, t1, 1 st t1, seg, riprel, disp }; @@ -161,7 +161,7 @@ def macroop ROR_R_R def macroop ROR_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp ror t1, t1, reg st t1, seg, sib, disp }; @@ -169,7 +169,7 @@ def macroop ROR_M_R def macroop ROR_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp ror t1, t1, reg st t1, seg, riprel, disp }; @@ -181,7 +181,7 @@ def macroop RCL_R_I def macroop RCL_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rcli t1, t1, imm st t1, seg, sib, disp }; @@ -189,7 +189,7 @@ def macroop RCL_M_I def macroop RCL_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rcli t1, t1, imm st t1, seg, riprel, disp }; @@ -201,7 +201,7 @@ def macroop RCL_1_R def macroop RCL_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rcli t1, t1, 1 st t1, seg, sib, disp }; @@ -209,7 +209,7 @@ def macroop RCL_1_M def macroop RCL_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rcli t1, t1, 1 st t1, seg, riprel, disp }; @@ -221,7 +221,7 @@ def macroop RCL_R_R def macroop RCL_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rcl t1, t1, reg st t1, seg, sib, disp }; @@ -229,7 +229,7 @@ def macroop RCL_M_R def macroop RCL_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rcl t1, t1, reg st t1, seg, riprel, disp }; @@ -241,7 +241,7 @@ def macroop RCR_R_I def macroop RCR_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rcri t1, t1, imm st t1, seg, sib, disp }; @@ -249,7 +249,7 @@ def macroop RCR_M_I def macroop RCR_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rcri t1, t1, imm st t1, seg, riprel, disp }; @@ -261,7 +261,7 @@ def macroop RCR_1_R def macroop RCR_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rcri t1, t1, 1 st t1, seg, sib, disp }; @@ -269,7 +269,7 @@ def macroop RCR_1_M def macroop RCR_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rcri t1, t1, 1 st t1, seg, riprel, disp }; @@ -281,7 +281,7 @@ def macroop RCR_R_R def macroop RCR_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp rcr t1, t1, reg st t1, seg, sib, disp }; @@ -289,7 +289,7 @@ def macroop RCR_M_R def macroop RCR_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp rcr t1, t1, reg st t1, seg, riprel, disp }; diff --git a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py index 6c688cca3..ed7d761b8 100644 --- a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py @@ -61,7 +61,7 @@ def macroop SAL_R_I def macroop SAL_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp slli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -69,7 +69,7 @@ def macroop SAL_M_I def macroop SAL_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp slli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -81,7 +81,7 @@ def macroop SAL_1_R def macroop SAL_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp slli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -89,7 +89,7 @@ def macroop SAL_1_M def macroop SAL_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp slli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -101,7 +101,7 @@ def macroop SAL_R_R def macroop SAL_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sll t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -109,7 +109,7 @@ def macroop SAL_M_R def macroop SAL_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sll t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -121,7 +121,7 @@ def macroop SHR_R_I def macroop SHR_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp srli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -129,7 +129,7 @@ def macroop SHR_M_I def macroop SHR_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp srli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -141,7 +141,7 @@ def macroop SHR_1_R def macroop SHR_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp srli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -149,7 +149,7 @@ def macroop SHR_1_M def macroop SHR_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp srli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -161,7 +161,7 @@ def macroop SHR_R_R def macroop SHR_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp srl t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -169,7 +169,7 @@ def macroop SHR_M_R def macroop SHR_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp srl t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -181,7 +181,7 @@ def macroop SAR_R_I def macroop SAR_M_I { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp srai t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -189,7 +189,7 @@ def macroop SAR_M_I def macroop SAR_P_I { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp srai t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -201,7 +201,7 @@ def macroop SAR_1_R def macroop SAR_1_M { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp srai t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -209,7 +209,7 @@ def macroop SAR_1_M def macroop SAR_1_P { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp srai t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; @@ -221,7 +221,7 @@ def macroop SAR_R_R def macroop SAR_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sra t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -229,7 +229,7 @@ def macroop SAR_M_R def macroop SAR_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sra t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; diff --git a/src/arch/x86/isa/insts/general_purpose/semaphores.py b/src/arch/x86/isa/insts/general_purpose/semaphores.py index 800f1b325..27a31dbd9 100644 --- a/src/arch/x86/isa/insts/general_purpose/semaphores.py +++ b/src/arch/x86/isa/insts/general_purpose/semaphores.py @@ -61,7 +61,7 @@ def macroop CMPXCHG_R_R { }; def macroop CMPXCHG_M_R { - ld t1, seg, sib, disp + ldst t1, seg, sib, disp sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF) mov t1, t1, reg, flags=(CZF,) @@ -71,7 +71,7 @@ def macroop CMPXCHG_M_R { def macroop CMPXCHG_P_R { rdip t7 - ld t1, seg, riprel, disp + ldst t1, seg, riprel, disp sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF) mov t1, t1, reg, flags=(CZF,) diff --git a/src/arch/x86/isa/insts/general_purpose/string/move_string.py b/src/arch/x86/isa/insts/general_purpose/string/move_string.py index 0a855b384..b64acfdc2 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/move_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/move_string.py @@ -53,16 +53,36 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class MOVS(Inst): -# "GenFault ${new UnimpInstFault}" -# class MOVSB(Inst): -# "GenFault ${new UnimpInstFault}" -# class MOVSW(Inst): -# "GenFault ${new UnimpInstFault}" -# class MOVSD(Inst): -# "GenFault ${new UnimpInstFault}" -# class MOVSQ(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop MOVS_M_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + ld t1, seg, [1, t0, rsi] + st t1, es, [1, t0, rdi] + + add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz +}; + +def macroop MOVS_E_M_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + +topOfLoop: + ld t1, seg, [1, t0, rsi] + st t1, es, [1, t0, rdi] + + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz + bri t0, label("topOfLoop"), flags=(nCEZF,) + fault "NoFault" +}; +''' diff --git a/src/arch/x86/isa/insts/general_purpose/string/store_string.py b/src/arch/x86/isa/insts/general_purpose/string/store_string.py index 08a126c1f..a8d558929 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/store_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/store_string.py @@ -53,16 +53,32 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class STOS(Inst): -# "Add 0 0 0" -# class STOSB(Inst): -# "Add 0 0 0" -# class STOSW(Inst): -# "Add 0 0 0" -# class STOSD(Inst): -# "Add 0 0 0" -# class STOSQ(Inst): -# "Add 0 0 0" -#}}; +microcode = ''' +def macroop STOS_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + st rax, es, [1, t0, rdi] + + add rdi, rdi, t3, dataSize=asz +}; + +def macroop STOS_E_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + +topOfLoop: + st rax, es, [1, t0, rdi] + + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + add rdi, rdi, t3, dataSize=asz + bri t0, label("topOfLoop"), flags=(nCEZF,) + fault "NoFault" +}; +''' diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index de89005f2..76279fc70 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -55,30 +55,35 @@ microcode = ''' def macroop MOVAPS_R_M { + # Check low address. ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 ldfp xmml, seg, sib, disp, dataSize=8 }; def macroop MOVAPS_R_P { rdip t7 + # Check low address. ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 ldfp xmml, seg, riprel, disp, dataSize=8 }; def macroop MOVAPS_M_R { + # Check low address. stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 stfp xmml, seg, sib, disp, dataSize=8 }; def macroop MOVAPS_P_R { rdip t7 + # Check low address. stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 stfp xmml, seg, riprel, disp, dataSize=8 }; def macroop MOVAPS_R_R { - movfp xmml, xmml, xmmlm, dataSize=8 - movfp xmmh, xmmh, xmmhm, dataSize=8 + # Check low address. + movfp xmml, xmmlm, dataSize=8 + movfp xmmh, xmmhm, dataSize=8 }; # MOVAPD @@ -107,7 +112,7 @@ def macroop MOVLPD_P_R { }; def macroop MOVLPD_R_R { - movfp xmml, xmml, xmmlm, dataSize=8 + movfp xmml, xmmlm, dataSize=8 }; # MOVHLPS @@ -135,6 +140,6 @@ def macroop MOVSD_P_R { }; def macroop MOVSD_R_R { - movfp xmml, xmml, xmmlm, dataSize=8 + movfp xmml, xmmlm, dataSize=8 }; ''' diff --git a/src/arch/x86/isa/insts/system/undefined_operation.py b/src/arch/x86/isa/insts/system/undefined_operation.py index e5544b6e7..9f129522b 100644 --- a/src/arch/x86/isa/insts/system/undefined_operation.py +++ b/src/arch/x86/isa/insts/system/undefined_operation.py @@ -56,6 +56,6 @@ microcode = ''' def macroop UD2 { - fault "new X86Fault" + fault "new InvalidOpcode()" }; ''' diff --git a/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py b/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py index 37574da34..2a4c3f0ed 100644 --- a/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py +++ b/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py @@ -56,33 +56,31 @@ microcode = ''' def macroop FLD_M { ldfp ufp1, seg, sib, disp - movfp st(1), ufp1, spm=-1 + movfp st(-1), ufp1, spm=-1 }; def macroop FLD_P { rdip t7 ldfp ufp1, seg, riprel, disp - movfp st(1), ufp1, spm=-1 + movfp st(-1), ufp1, spm=-1 }; def macroop FST_M { - movfp st(0), ufp1 - stfp ufp1, seg, sib, disp + stfp st(0), seg, sib, disp }; def macroop FST_P { - movfp st(0), ufp1 rdip t7 - stfp ufp1, seg, riprel, disp + stfp st(0), seg, riprel, disp }; def macroop FSTP_M { - movfp st(0), ufp1, spm=1 + movfp ufp1, st(0), spm=1 stfp ufp1, seg, sib, disp }; def macroop FSTP_P { - movfp st(0), ufp1, spm=1 + movfp ufp1, st(0), spm=1 rdip t7 stfp ufp1, seg, riprel, disp }; diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index e961cc63c..c8bc36b69 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -137,7 +137,7 @@ let {{ assembler.symbols["label"] = labeler def stack_index(index): - return "(NUM_FLOATREGS + (%s))" % index + return "(NUM_FLOATREGS + (((%s) + 8) %% 8))" % index assembler.symbols["st"] = stack_index diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index e9a7cb84f..2919aa277 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -260,7 +260,7 @@ let {{ SetStatus=False, dataSize="env.dataSize"): super(Movfp, self).__init__(dest, src1, flags, \ spm, SetStatus, dataSize) - code = 'FpDestReg.uqw = FpSrcReg2.uqw;' + code = 'FpDestReg.uqw = FpSrcReg1.uqw;' else_code = 'FpDestReg.uqw = FpDestReg.uqw;' cond_check = "checkCondition(ccFlagBits, src2)" diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 1bdc1d37a..106a8a0fe 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -123,7 +123,7 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, 0); + fault = read(xc, EA, Mem, (%(mem_flags)s) | (1 << segment)); if(fault == NoFault) { @@ -150,7 +150,7 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, 0); + fault = read(xc, EA, Mem, (%(mem_flags)s) | (1 << segment)); return fault; } @@ -197,7 +197,7 @@ def template MicroStoreExecute {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, 0); + fault = write(xc, Mem, EA, (%(mem_flags)s) | (1 << segment)); if(fault == NoFault) { %(op_wb)s; @@ -224,7 +224,7 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, 0); + fault = write(xc, Mem, EA, (%(mem_flags)s) | (1 << segment)); if(fault == NoFault) { %(op_wb)s; @@ -358,7 +358,7 @@ let {{ calculateEA = "EA = SegBase + scale * Index + Base + disp;" - def defineMicroLoadOp(mnemonic, code): + def defineMicroLoadOp(mnemonic, code, mem_flags=0): global header_output global decoder_output global exec_output @@ -368,7 +368,9 @@ let {{ # Build up the all register version of this micro op iop = InstObjParams(name, Name, 'X86ISA::LdStOp', - {"code": code, "ea_code": calculateEA}) + {"code": code, + "ea_code": calculateEA, + "mem_flags": mem_flags}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLoadExecute.subst(iop) @@ -386,9 +388,10 @@ let {{ microopClasses[name] = LoadOp defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') + defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck') defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') - def defineMicroStoreOp(mnemonic, code): + def defineMicroStoreOp(mnemonic, code, mem_flags=0): global header_output global decoder_output global exec_output @@ -398,7 +401,9 @@ let {{ # Build up the all register version of this micro op iop = InstObjParams(name, Name, 'X86ISA::LdStOp', - {"code": code, "ea_code": calculateEA}) + {"code": code, + "ea_code": calculateEA, + "mem_flags": mem_flags}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroStoreExecute.subst(iop) @@ -419,7 +424,9 @@ let {{ defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', - {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA}) + {"code": "Data = merge(Data, EA, dataSize);", + "ea_code": calculateEA, + "mem_flags": 0}) header_output += MicroLeaDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 40a441b1e..de2e6692d 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -439,10 +439,11 @@ let {{ abstract = True flag_code = ''' //Don't have genFlags handle the OF or CF bits - uint64_t mask = CFBit | OFBit; + uint64_t mask = CFBit | ECFBit | OFBit; ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2); //If a logic microop wants to set these, it wants to set them to 0. ccFlagBits &= ~(CFBit & ext); + ccFlagBits &= ~(ECFBit & ext); ccFlagBits &= ~(OFBit & ext); ''' @@ -852,7 +853,7 @@ let {{ class Ruflag(RegOp): code = ''' - int flag = bits(ccFlagBits, imm8 + 0*psrc1); + int flag = bits(ccFlagBits, imm8); DestReg = merge(DestReg, flag, dataSize); ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : (ccFlagBits & ~EZFBit); diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index e69813836..6e8cac94a 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -90,7 +90,9 @@ namespace X86ISA //mmx/x87 registers 8 + //xmm registers - 16 + + 16 * 2 + + //The microcode fp registers + 8 + //The indices that are mapped over the fp stack 8 }; diff --git a/src/arch/x86/pagetable.cc b/src/arch/x86/pagetable.cc new file mode 100644 index 000000000..49aaab068 --- /dev/null +++ b/src/arch/x86/pagetable.cc @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2007 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/pagetable.hh" +#include "sim/serialize.hh" + +namespace X86ISA +{ + +void +TlbEntry::serialize(std::ostream &os) +{ +} + +void +TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) +{ +} + +} diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh index 8ca179c86..aaf82ed70 100644 --- a/src/arch/x86/pagetable.hh +++ b/src/arch/x86/pagetable.hh @@ -58,9 +58,14 @@ #ifndef __ARCH_X86_PAGETABLE_HH__ #define __ARCH_X86_PAGETABLE_HH__ +#include <iostream> +#include <string> + #include "sim/host.hh" #include "base/misc.hh" +class Checkpoint; + namespace X86ISA { struct VAddr @@ -68,8 +73,37 @@ namespace X86ISA VAddr(Addr a) { panic("not implemented yet."); } }; - class PageTableEntry + struct TlbEntry { + // The base of the physical page. + Addr pageStart; + // Read permission is always available, assuming it isn't blocked by + // other mechanisms. + bool writeable; + // Whether this page is accesible without being in supervisor mode. + bool user; + // Whether to use write through or write back. M5 ignores this and + // lets the caches handle the writeback policy. + //bool pwt; + // Whether the page is cacheable or not. + bool uncacheable; + // Whether or not to kick this page out on a write to CR3. + bool global; + // A bit used to form an index into the PAT table. + bool patBit; + // Whether or not memory on this page can be executed. + bool noExec; + + // The beginning of the virtual page this entry maps. + Addr vaddr; + // The size of the page this entry represents. + Addr size; + + TlbEntry() {} + TlbEntry(Addr paddr) : pageStart(paddr) {} + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); }; } diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 7f8bc7abc..62899e65a 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -62,7 +62,7 @@ namespace X86ISA { - void Predecoder::reset() + void Predecoder::doReset() { origPC = basePC + offset; DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC); @@ -96,7 +96,7 @@ namespace X86ISA switch(state) { case ResetState: - reset(); + doReset(); state = PrefixState; case PrefixState: state = doPrefixState(nextByte); diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index 450ebd79b..6e41e8134 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -134,7 +134,7 @@ namespace X86ISA outOfBytes = true; } - void reset(); + void doReset(); //State machine state protected: @@ -182,6 +182,11 @@ namespace X86ISA emi.mode.submode = SixtyFourBitMode; } + void reset() + { + state = ResetState; + } + ThreadContext * getTC() { return tc; diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index 889f2f5cd..c27ab08ba 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -221,7 +221,7 @@ int X86ISA::flattenIntIndex(ThreadContext * tc, int reg) int X86ISA::flattenFloatIndex(ThreadContext * tc, int reg) { - if (reg > NUM_FLOATREGS) { + if (reg >= NUM_FLOATREGS) { int top = tc->readMiscRegNoEffect(MISCREG_X87_TOP); reg = FLOATREG_STACK(reg - NUM_FLOATREGS, top); } diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index d7f9e6665..6cec246d1 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -59,8 +59,7 @@ #include "config/full_system.hh" -#if FULL_SYSTEM - +#include "arch/x86/pagetable.hh" #include "arch/x86/tlb.hh" #include "base/bitfield.hh" #include "base/trace.hh" @@ -72,21 +71,114 @@ namespace X86ISA { -TLB::TLB(const Params *p) : SimObject(p) +TLB::TLB(const Params *p) : SimObject(p), size(p->size) +{ + tlb = new TlbEntry[size]; + std::memset(tlb, 0, sizeof(TlbEntry) * size); + + for (int x = 0; x < size; x++) + freeList.push_back(&tlb[x]); +} + +void +TLB::insert(Addr vpn, TlbEntry &entry) +{ + //TODO Deal with conflicting entries + + TlbEntry *newEntry = NULL; + if (!freeList.empty()) { + newEntry = freeList.front(); + freeList.pop_front(); + } else { + newEntry = entryList.back(); + entryList.pop_back(); + } + *newEntry = entry; + newEntry->vaddr = vpn; + entryList.push_front(newEntry); +} + +TlbEntry * +TLB::lookup(Addr va, bool update_lru) +{ + //TODO make this smarter at some point + EntryList::iterator entry; + for (entry = entryList.begin(); entry != entryList.end(); entry++) { + if ((*entry)->vaddr <= va && (*entry)->vaddr + (*entry)->size > va) { + DPRINTF(TLB, "Matched vaddr %#x to entry starting at %#x " + "with size %#x.\n", va, (*entry)->vaddr, (*entry)->size); + TlbEntry *e = *entry; + if (update_lru) { + entryList.erase(entry); + entryList.push_front(e); + } + return e; + } + } + return NULL; +} + +void +TLB::invalidateAll() +{ +} + +void +TLB::invalidateNonGlobal() +{ +} + +void +TLB::demapPage(Addr va) { } Fault ITB::translate(RequestPtr &req, ThreadContext *tc) { + Addr vaddr = req->getVaddr(); + // Check against the limit of the CS segment, and permissions. + // The vaddr already has the segment base applied. + TlbEntry *entry = lookup(vaddr); + if (!entry) { +#if FULL_SYSTEM + return new FakeITLBFault(); +#else + return new FakeITLBFault(vaddr); +#endif + } else { + Addr paddr = entry->pageStart | (vaddr & mask(12)); + DPRINTF(TLB, "Translated %#x to %#x\n", vaddr, paddr); + req->setPaddr(paddr); + } + return NoFault; } - - Fault DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) { + Addr vaddr = req->getVaddr(); + uint32_t flags = req->getFlags(); + bool storeCheck = flags & StoreCheck; + int seg = flags & (mask(NUM_SEGMENTREGS)); + + //XXX Junk code to surpress the warning + if (storeCheck) seg = seg; + + // Check the limit of the segment "seg", and permissions. + // The vaddr already has the segment base applied. + TlbEntry *entry = lookup(vaddr); + if (!entry) { +#if FULL_SYSTEM + return new FakeDTLBFault(); +#else + return new FakeDTLBFault(vaddr); +#endif + } else { + Addr paddr = entry->pageStart | (vaddr & mask(12)); + req->setPaddr(paddr); + } return NoFault; }; @@ -130,31 +222,6 @@ DTB::unserialize(Checkpoint *cp, const std::string §ion) /* end namespace X86ISA */ } -#else - -#include <cstring> - -#include "arch/x86/tlb.hh" -#include "params/X86DTB.hh" -#include "params/X86ITB.hh" -#include "sim/serialize.hh" - -namespace X86ISA { - void - TlbEntry::serialize(std::ostream &os) - { - SERIALIZE_SCALAR(pageStart); - } - - void - TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_SCALAR(pageStart); - } -}; - -#endif - X86ISA::ITB * X86ITBParams::create() { diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 386d1635d..720b03b98 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -58,10 +58,11 @@ #ifndef __ARCH_X86_TLB_HH__ #define __ARCH_X86_TLB_HH__ -#include "config/full_system.hh" - -#if FULL_SYSTEM +#include <list> +#include "arch/x86/pagetable.hh" +#include "arch/x86/segmentregs.hh" +#include "config/full_system.hh" #include "mem/request.hh" #include "params/X86DTB.hh" #include "params/X86ITB.hh" @@ -73,99 +74,77 @@ class Packet; namespace X86ISA { - struct TlbEntry - { - Addr pageStart; - TlbEntry() {} - TlbEntry(Addr paddr) : pageStart(paddr) {} - - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - }; - -class TLB : public SimObject -{ - public: - typedef X86TLBParams Params; - TLB(const Params *p); - - void dumpAll(); + static const unsigned StoreCheck = 1 << NUM_SEGMENTREGS; - // Checkpointing - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -class ITB : public TLB -{ - public: - typedef X86ITBParams Params; - ITB(const Params *p) : TLB(p) + class TLB : public SimObject { - } - - Fault translate(RequestPtr &req, ThreadContext *tc); - - friend class DTB; -}; +#if !FULL_SYSTEM + protected: + friend class FakeITLBFault; + friend class FakeDTLBFault; +#endif + public: + typedef X86TLBParams Params; + TLB(const Params *p); -class DTB : public TLB -{ - public: - typedef X86DTBParams Params; - DTB(const Params *p) : TLB(p) - { - } + void dumpAll(); - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); -#if FULL_SYSTEM - Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); - Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); -#endif + TlbEntry *lookup(Addr va, bool update_lru = true); - // Checkpointing - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; + protected: + int size; -} + TlbEntry * tlb; -#else + typedef std::list<TlbEntry *> EntryList; + EntryList freeList; + EntryList entryList; -#include <iostream> + void insert(Addr vpn, TlbEntry &entry); -#include "sim/host.hh" -#include "sim/tlb.hh" + void invalidateAll(); -class Checkpoint; + void invalidateNonGlobal(); -namespace X86ISA -{ - struct TlbEntry - { - Addr pageStart; - TlbEntry() {} - TlbEntry(Addr paddr) : pageStart(paddr) {} + void demapPage(Addr va); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + public: + // Checkpointing + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; - class ITB : public GenericTLB + class ITB : public TLB { public: - ITB(const Params *p) : GenericTLB(p) - {} + typedef X86ITBParams Params; + ITB(const Params *p) : TLB(p) + { + } + + Fault translate(RequestPtr &req, ThreadContext *tc); + + friend class DTB; }; - class DTB : public GenericTLB + class DTB : public TLB { public: - DTB(const Params *p) : GenericTLB(p) - {} - }; -}; + typedef X86DTBParams Params; + DTB(const Params *p) : TLB(p) + { + } + Fault translate(RequestPtr &req, ThreadContext *tc, bool write); +#if FULL_SYSTEM + Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); + Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); #endif + // Checkpointing + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; +} + #endif // __ARCH_X86_TLB_HH__ diff --git a/src/arch/x86/vtophys.hh b/src/arch/x86/vtophys.hh index 00d0f9499..be5e2700f 100644 --- a/src/arch/x86/vtophys.hh +++ b/src/arch/x86/vtophys.hh @@ -68,9 +68,6 @@ class FunctionalPort; namespace X86ISA { -PageTableEntry -kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, X86ISA::VAddr vaddr); - Addr vtophys(Addr vaddr); Addr vtophys(ThreadContext *tc, Addr vaddr); |