summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/SConscript2
-rw-r--r--src/arch/x86/X86TLB.py6
-rw-r--r--src/arch/x86/faults.cc171
-rw-r--r--src/arch/x86/faults.hh315
-rw-r--r--src/arch/x86/floatregs.hh2
-rw-r--r--src/arch/x86/insts/static_inst.cc11
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa18
-rw-r--r--src/arch/x86/isa/formats/string.isa28
-rw-r--r--src/arch/x86/isa/includes.isa1
-rw-r--r--src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py36
-rw-r--r--src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py8
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/call.py12
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py14
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py8
-rw-r--r--src/arch/x86/isa/insts/general_purpose/logical.py28
-rw-r--r--src/arch/x86/isa/insts/general_purpose/rotate_and_shift/rotate.py48
-rw-r--r--src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py36
-rw-r--r--src/arch/x86/isa/insts/general_purpose/semaphores.py4
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/move_string.py46
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/store_string.py42
-rw-r--r--src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py13
-rw-r--r--src/arch/x86/isa/insts/system/undefined_operation.py2
-rw-r--r--src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py14
-rw-r--r--src/arch/x86/isa/microasm.isa2
-rw-r--r--src/arch/x86/isa/microops/fpop.isa2
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa25
-rw-r--r--src/arch/x86/isa/microops/regop.isa5
-rw-r--r--src/arch/x86/isa_traits.hh4
-rw-r--r--src/arch/x86/pagetable.cc74
-rw-r--r--src/arch/x86/pagetable.hh36
-rw-r--r--src/arch/x86/predecoder.cc4
-rw-r--r--src/arch/x86/predecoder.hh7
-rw-r--r--src/arch/x86/regfile.cc2
-rw-r--r--src/arch/x86/tlb.cc127
-rw-r--r--src/arch/x86/tlb.hh129
-rw-r--r--src/arch/x86/vtophys.hh3
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 &section)
+{
+}
+
+}
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 &section);
};
}
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 &section)
/* 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 &section)
- {
- 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 &section);
- };
-
-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 &section);
-};
-
-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 &section);
-};
+ 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 &section);
+ public:
+ // Checkpointing
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
};
- 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 &section);
+ };
+}
+
#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);