summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/SConscript3
-rw-r--r--src/arch/x86/intregfile.hh5
-rw-r--r--src/arch/x86/intregs.hh3
-rw-r--r--src/arch/x86/isa/base.isa181
-rw-r--r--src/arch/x86/isa/bitfields.isa27
-rw-r--r--src/arch/x86/isa/decoder/decoder.isa89
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa398
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa393
-rw-r--r--src/arch/x86/isa/formats/basic.isa9
-rw-r--r--src/arch/x86/isa/formats/error.isa (renamed from src/arch/x86/isa/decoder.isa)23
-rw-r--r--src/arch/x86/isa/formats/formats.isa11
-rw-r--r--src/arch/x86/isa/formats/multi.isa106
-rw-r--r--src/arch/x86/isa/formats/unimp.isa174
-rw-r--r--src/arch/x86/isa/formats/unknown.isa3
-rw-r--r--src/arch/x86/isa/main.isa4
-rw-r--r--src/arch/x86/isa/operands.isa3
-rw-r--r--src/arch/x86/predecoder.cc358
-rw-r--r--src/arch/x86/predecoder.hh225
-rw-r--r--src/arch/x86/predecoder_tables.cc222
-rw-r--r--src/arch/x86/types.hh106
-rw-r--r--src/arch/x86/utility.hh17
21 files changed, 2338 insertions, 22 deletions
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
index f49225758..2e2c5b006 100644
--- a/src/arch/x86/SConscript
+++ b/src/arch/x86/SConscript
@@ -84,11 +84,12 @@
# Authors: Gabe Black
Import('*')
-
if env['TARGET_ISA'] == 'x86':
Source('floatregfile.cc')
Source('intregfile.cc')
Source('miscregfile.cc')
+ Source('predecoder.cc')
+ Source('predecoder_tables.cc')
Source('regfile.cc')
Source('remote_gdb.cc')
diff --git a/src/arch/x86/intregfile.hh b/src/arch/x86/intregfile.hh
index da631d444..f7b03f0f0 100644
--- a/src/arch/x86/intregfile.hh
+++ b/src/arch/x86/intregfile.hh
@@ -88,8 +88,9 @@
#ifndef __ARCH_X86_INTREGFILE_HH__
#define __ARCH_X86_INTREGFILE_HH__
-#include "arch/x86/x86_traits.hh"
+#include "arch/x86/intregs.hh"
#include "arch/x86/types.hh"
+#include "arch/x86/x86_traits.hh"
#include <string>
@@ -102,7 +103,7 @@ namespace X86ISA
//This function translates integer register file indices into names
std::string getIntRegName(RegIndex);
- const int NumIntArchRegs = 16;
+ const int NumIntArchRegs = NUM_INTREGS;
const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs;
class IntRegFile
diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh
index 3fe25bd5f..ed801cc48 100644
--- a/src/arch/x86/intregs.hh
+++ b/src/arch/x86/intregs.hh
@@ -77,7 +77,8 @@ namespace X86ISA
INTREG_R12W,
INTREG_R13W,
INTREG_R14W,
- INTREG_R15W
+ INTREG_R15W,
+ NUM_INTREGS
};
};
diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa
new file mode 100644
index 000000000..4776f7a7e
--- /dev/null
+++ b/src/arch/x86/isa/base.isa
@@ -0,0 +1,181 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for sparc instructions, and some support functions
+//
+
+output header {{
+
+ /**
+ * Base class for all X86 static instructions.
+ */
+ class X86StaticInst : public StaticInst
+ {
+ protected:
+ // Constructor.
+ X86StaticInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : StaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ void printReg(std::ostream &os, int reg) const;
+ void printSrcReg(std::ostream &os, int reg) const;
+ void printDestReg(std::ostream &os, int reg) const;
+ };
+}};
+
+output decoder {{
+
+ inline void printMnemonic(std::ostream &os, const char * mnemonic)
+ {
+ ccprintf(os, "\t%s ", mnemonic);
+ }
+
+ void
+ X86StaticInst::printSrcReg(std::ostream &os, int reg) const
+ {
+ if(_numSrcRegs > reg)
+ printReg(os, _srcRegIdx[reg]);
+ }
+
+ void
+ X86StaticInst::printDestReg(std::ostream &os, int reg) const
+ {
+ if(_numDestRegs > reg)
+ printReg(os, _destRegIdx[reg]);
+ }
+
+ void
+ X86StaticInst::printReg(std::ostream &os, int reg) const
+ {
+ if (reg < FP_Base_DepTag) {
+ //FIXME These should print differently depending on the
+ //mode etc, but for now this will get the point across
+ switch (reg) {
+ case INTREG_RAX:
+ ccprintf(os, "rax");
+ break;
+ case INTREG_RBX:
+ ccprintf(os, "rbx");
+ break;
+ case INTREG_RCX:
+ ccprintf(os, "rcx");
+ break;
+ case INTREG_RDX:
+ ccprintf(os, "rdx");
+ break;
+ case INTREG_RSP:
+ ccprintf(os, "rsp");
+ break;
+ case INTREG_RBP:
+ ccprintf(os, "rbp");
+ break;
+ case INTREG_RSI:
+ ccprintf(os, "rsi");
+ break;
+ case INTREG_RDI:
+ ccprintf(os, "rdi");
+ break;
+ case INTREG_R8W:
+ ccprintf(os, "r8");
+ break;
+ case INTREG_R9W:
+ ccprintf(os, "r9");
+ break;
+ case INTREG_R10W:
+ ccprintf(os, "r10");
+ break;
+ case INTREG_R11W:
+ ccprintf(os, "r11");
+ break;
+ case INTREG_R12W:
+ ccprintf(os, "r12");
+ break;
+ case INTREG_R13W:
+ ccprintf(os, "r13");
+ break;
+ case INTREG_R14W:
+ ccprintf(os, "r14");
+ break;
+ case INTREG_R15W:
+ ccprintf(os, "r15");
+ break;
+ }
+ } else if (reg < Ctrl_Base_DepTag) {
+ ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+ } else {
+ switch (reg - Ctrl_Base_DepTag) {
+ default:
+ ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
+ }
+ }
+ }
+
+ std::string X86StaticInst::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ printMnemonic(ss, mnemonic);
+
+ return ss.str();
+ }
+}};
diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa
index 47aec4fa1..fff324caa 100644
--- a/src/arch/x86/isa/bitfields.isa
+++ b/src/arch/x86/isa/bitfields.isa
@@ -58,5 +58,30 @@
// Bitfield definitions.
//
-def bitfield EXAMPLE <24>;
+//Prefixes
+def bitfield REX rex;
+def bitfield LEGACY legacy;
+// Pieces of the opcode
+def bitfield OPCODE_NUM opcode.num;
+def bitfield OPCODE_PREFIXA opcode.prefixA;
+def bitfield OPCODE_PREFIXB opcode.prefixB;
+def bitfield OPCODE_OP opcode.op;
+//The top 5 bits of the opcode tend to split the instructions into groups
+def bitfield OPCODE_OP_TOP5 opcode.op.top5;
+def bitfield OPCODE_OP_BOTTOM3 opcode.op.bottom3;
+
+// Immediate fields
+def bitfield IMMEDIATE immediate;
+def bitfield DISPLACEMENT displacement;
+
+//Modifier bytes
+def bitfield MODRM modRM;
+def bitfield MODRM_MOD modRM.mod;
+def bitfield MODRM_REG modRM.reg;
+def bitfield MODRM_RM modRM.rm;
+
+def bitfield SIB sib;
+def bitfield SIB_SCALE sib.scale;
+def bitfield SIB_INDEX sib.index;
+def bitfield SIB_BASE sib.base;
diff --git a/src/arch/x86/isa/decoder/decoder.isa b/src/arch/x86/isa/decoder/decoder.isa
new file mode 100644
index 000000000..20f31f882
--- /dev/null
+++ b/src/arch/x86/isa/decoder/decoder.isa
@@ -0,0 +1,89 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// The actual decoder specification
+//
+
+decode OPCODE_NUM default Unknown::unknown()
+{
+ 0x0: M5InternalError::error(
+ {{"Saw an ExtMachInst with zero opcode bytes!"}});
+ //1 byte opcodes
+ ##include "one_byte_opcodes.isa"
+ //2 byte opcodes
+ ##include "two_byte_opcodes.isa"
+ //3 byte opcodes
+ 0x3: decode OPCODE_PREFIXA {
+ 0xF0: decode OPCODE_PREFIXB {
+ //We don't handle these properly in the predecoder yet, so there's
+ //no reason to implement them for now.
+ 0x38: decode OPCODE_OP {
+ default: FailUnimpl::sseThreeEight();
+ }
+ 0x3A: decode OPCODE_OP {
+ default: FailUnimpl::sseThreeA();
+ }
+ 0xF0: decode OPCODE_OP {
+ default: FailUnimpl::threednow();
+ }
+ default: M5InternalError::error(
+ {{"Unexpected second opcode byte in three byte opcode!"}});
+ }
+ default: M5InternalError::error(
+ {{"Unexpected first opcode byte in three byte opcode!"}});
+ }
+}
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
new file mode 100644
index 000000000..c56a8bf92
--- /dev/null
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -0,0 +1,398 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Decode the one byte opcodes
+//
+
+0x1: decode OPCODE_OP_TOP5 {
+ format WarnUnimpl {
+ 0x00: decode OPCODE_OP_BOTTOM3 {
+ 0x6: push_ES();
+ 0x7: pop_ES();
+ default: MultiOp::add(
+ {{out1 = in1 + in2}},
+ OPCODE_OP_BOTTOM3,
+ [[Eb,Gb],[Ev,Gv],
+ [Gb,Eb],[Gv,Ev],
+ [Al,Ib],[rAx,Iz]]);
+ }
+ 0x01: decode OPCODE_OP_BOTTOM3 {
+ 0x0: or_Eb_Gb();
+ 0x1: or_Ev_Gv();
+ 0x2: or_Gb_Eb();
+ 0x3: or_Gv_Ev();
+ 0x4: or_Al_Ib();
+ 0x5: or_rAX_Iz();
+ 0x6: push_CS();
+ //Any time this is seen, it should generate a two byte opcode
+ 0x7: M5InternalError::error(
+ {{"Saw a one byte opcode whose value was 0x0F!"}});
+ }
+ 0x02: decode OPCODE_OP_BOTTOM3 {
+ 0x0: adc_Eb_Gb();
+ 0x1: adc_Ev_Gv();
+ 0x2: adc_Gb_Eb();
+ 0x3: adc_Gv_Ev();
+ 0x4: adc_Al_Ib();
+ 0x5: adc_rAX_Iz();
+ 0x6: push_SS();
+ 0x7: pop_SS();
+ }
+ 0x03: decode OPCODE_OP_BOTTOM3 {
+ 0x0: sbb_Eb_Gb();
+ 0x1: sbb_Ev_Gv();
+ 0x2: sbb_Gb_Eb();
+ 0x3: sbb_Gv_Ev();
+ 0x4: sbb_Al_Ib();
+ 0x5: sbb_rAX_Iz();
+ 0x6: push_DS();
+ 0x7: pop_DS();
+ }
+ 0x04: decode OPCODE_OP_BOTTOM3 {
+ 0x0: and_Eb_Gb();
+ 0x1: and_Ev_Gv();
+ 0x2: and_Gb_Eb();
+ 0x3: and_Gv_Ev();
+ 0x4: and_Al_Ib();
+ 0x5: and_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the ES segment override prefix!"}});
+ 0x7: daa();
+ }
+ 0x05: decode OPCODE_OP_BOTTOM3 {
+ 0x0: sub_Eb_Gb();
+ 0x1: sub_Ev_Gv();
+ 0x2: sub_Gb_Eb();
+ 0x3: sub_Gv_Ev();
+ 0x4: sub_Al_Ib();
+ 0x5: sub_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the CS segment override prefix!"}});
+ 0x7: das();
+ }
+ 0x06: decode OPCODE_OP_BOTTOM3 {
+ 0x0: xor_Eb_Gb();
+ 0x1: xor_Ev_Gv();
+ 0x2: xor_Gb_Eb();
+ 0x3: xor_Gv_Ev();
+ 0x4: xor_Al_Ib();
+ 0x5: xor_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the SS segment override prefix!"}});
+ 0x7: aaa();
+ }
+ 0x07: decode OPCODE_OP_BOTTOM3 {
+ 0x0: cmp_Eb_Gb();
+ 0x1: cmp_Ev_Gv();
+ 0x2: cmp_Gb_Eb();
+ 0x3: cmp_Gv_Ev();
+ 0x4: cmp_Al_Ib();
+ 0x5: cmp_rAX_Iz();
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the DS segment override prefix!"}});
+ 0x7: aas();
+ }
+ 0x08: decode OPCODE_OP_BOTTOM3 {
+ 0x0: inc_eAX();
+ 0x1: inc_eCX();
+ 0x2: inc_eDX();
+ 0x3: inc_eBX();
+ 0x4: inc_eSP();
+ 0x5: inc_eBP();
+ 0x6: inc_eSI();
+ 0x7: inc_eDI();
+ }
+ 0x09: decode OPCODE_OP_BOTTOM3 {
+ 0x0: dec_eAX();
+ 0x1: dec_eCX();
+ 0x2: dec_eDX();
+ 0x3: dec_eBX();
+ 0x4: dec_eSP();
+ 0x5: dec_eBP();
+ 0x6: dec_eSI();
+ 0x7: dec_eDI();
+ }
+ 0x0A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: push_rAX();
+ 0x1: push_rCX();
+ 0x2: push_rDX();
+ 0x3: push_rBX();
+ 0x4: push_rSP();
+ 0x5: push_rBP();
+ 0x6: push_rSI();
+ 0x7: push_rDI();
+ }
+ 0x0B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: pop_rAX();
+ 0x1: pop_rCX();
+ 0x2: pop_rDX();
+ 0x3: pop_rBX();
+ 0x4: pop_rSP();
+ 0x5: pop_rBP();
+ 0x6: pop_rSI();
+ 0x7: pop_rDI();
+ }
+ 0x0C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: pusha();
+ 0x1: popa();
+ 0x2: bound_Gv_Ma();
+ 0x3: arpl_Ew_Gw();
+ 0x4: M5InternalError::error(
+ {{"Tried to execute the FS segment override prefix!"}});
+ 0x5: M5InternalError::error(
+ {{"Tried to execute the GS segment override prefix!"}});
+ 0x6: M5InternalError::error(
+ {{"Tried to execute the operand size override prefix!"}});
+ 0x7: M5InternalError::error(
+ {{"Tried to execute the DS address size override prefix!"}});
+ }
+ 0x0D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: push_Iz();
+ 0x1: imul_Gv_Ev_Iz();
+ 0x2: push_Ib();
+ 0x3: imul_Gv_Ev_Ib();
+ 0x4: ins_Yb_Dx();
+ 0x5: ins_Yz_Dx();
+ 0x6: outs_Dx_Xb();
+ 0x7: outs_Dx_Xz();
+ }
+ 0x0E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: jo_Jb();
+ 0x1: jno_Jb();
+ 0x2: jb_Jb();
+ 0x3: jnb_Jb();
+ 0x4: jz_Jb();
+ 0x5: jnz_Jb();
+ 0x6: jbe_Jb();
+ 0x7: jnbe_Jb();
+ }
+ 0x0F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: js_Jb();
+ 0x1: jns_Jb();
+ 0x2: jp_Jb();
+ 0x3: jnp_Jb();
+ 0x4: jl_Jb();
+ 0x5: jnl_Jb();
+ 0x6: jle_Jb();
+ 0x7: jnke_Jb();
+ }
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ 0x0: group1_Eb_Ib();
+ 0x1: group1_Ev_Iz();
+ 0x2: group1_Eb_Ib();
+ 0x3: group1_Ev_Ib();
+ 0x4: test_Eb_Gb();
+ 0x5: test_Ev_Gv();
+ 0x6: xchg_Eb_Gb();
+ 0x7: xchg_Ev_Gv();
+ }
+ 0x11: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_Eb_Gb();
+ 0x1: mov_Ev_Gv();
+ 0x2: mov_Gb_Eb();
+ 0x3: mov_Gv_Ev();
+ 0x4: mov_MwRv_Sw();
+ 0x5: lea_Gv_M();
+ 0x6: mov_Sw_MwRv();
+ 0x7: group10_Ev(); //Make sure this is Ev
+ }
+ 0x12: decode OPCODE_OP_BOTTOM3 {
+ 0x0: nop_or_pause(); //Check for repe prefix
+ 0x1: xchg_rCX_rAX();
+ 0x2: xchg_rDX_rAX();
+ 0x3: xchg_rVX_rAX();
+ 0x4: xchg_rSP_rAX();
+ 0x5: xchg_rBP_rAX();
+ 0x6: xchg_rSI_rAX();
+ 0x7: xchg_rDI_rAX();
+ }
+ 0x13: decode OPCODE_OP_BOTTOM3 {
+ 0x0: cbw_or_cwde_or_cdqe_rAX();
+ 0x1: cwd_or_cdq_or_cqo_rAX_rDX();
+ 0x2: call_Ap();
+ 0x3: fwait(); //aka wait
+ 0x4: pushf_Fv();
+ 0x5: popf_Fv();
+ 0x6: sahf();
+ 0x7: lahf();
+ }
+ 0x14: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_Al_Ob();
+ 0x1: mov_rAX_Ov();
+ 0x2: mov_Ob_Al();
+ 0x3: mov_Ov_rAX();
+ 0x4: movs_Yb_Xb();
+ 0x5: movs_Yv_Xv();
+ 0x6: cmps_Yb_Xb();
+ 0x7: cmps_Yv_Xv();
+ }
+ 0x15: decode OPCODE_OP_BOTTOM3 {
+ 0x0: test_Al_Ib();
+ 0x1: test_rAX_Iz();
+ 0x2: stos_Yb_Al();
+ 0x3: stos_Yv_rAX();
+ 0x4: lods_Al_Xb();
+ 0x5: lods_rAX_Xv();
+ 0x6: scas_Yb_Al();
+ 0x7: scas_Yv_rAX();
+ }
+ 0x16: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_Al_Ib();
+ 0x1: mov_Cl_Ib();
+ 0x2: mov_Dl_Ib();
+ 0x3: mov_Bl_Ib();
+ 0x4: mov_Ah_Ib();
+ 0x5: mov_Ch_Ib();
+ 0x6: mov_Dh_Ib();
+ 0x7: mov_Bh_Ib();
+ }
+ 0x17: decode OPCODE_OP_BOTTOM3 {
+ 0x0: mov_rAX_Iv();
+ 0x1: mov_rCX_Iv();
+ 0x2: mov_rDX_Iv();
+ 0x3: mov_rBX_Iv();
+ 0x4: mov_rSP_Iv();
+ 0x5: mov_rBP_Iv();
+ 0x6: mov_rSI_Iv();
+ 0x7: mov_rDI_Iv();
+ }
+ 0x18: decode OPCODE_OP_BOTTOM3 {
+ 0x0: group2_Eb_Ib();
+ 0x1: group2_Ev_Ib();
+ 0x2: ret_near_Iw();
+ 0x3: ret_near();
+ 0x4: les_Gz_Mp();
+ 0x5: lds_Gz_Mp();
+ 0x6: group12_Eb_Ib();
+ 0x7: group12_Ev_Iz();
+ }
+ 0x19: decode OPCODE_OP_BOTTOM3 {
+ 0x0: enter_Iw_Ib();
+ 0x1: leave();
+ 0x2: ret_far_Iw();
+ 0x3: ret_far();
+ 0x4: int3();
+ 0x5: int_Ib();
+ 0x6: into();
+ 0x7: iret();
+ }
+ 0x1A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: group2_Eb_1();
+ 0x1: group2_Ev_1();
+ 0x2: group2_Eb_Cl();
+ 0x3: group2_Ev_Cl();
+ 0x4: aam_Ib();
+ 0x5: aad_Ib();
+ 0x6: salc();
+ 0x7: xlat();
+ }
+ 0x1B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: esc0();
+ 0x1: esc1();
+ 0x2: esc2();
+ 0x3: esc3();
+ 0x4: esc4();
+ 0x5: esc5();
+ 0x6: esc6();
+ 0x7: esc7();
+ }
+ 0x1C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: loopne_Jb();
+ 0x1: loope_Jb();
+ 0x2: loop_Jb();
+ 0x3: jcxz_or_jecx_or_jrcx();
+ 0x4: in_Al_Ib();
+ 0x5: in_eAX_Ib();
+ 0x6: out_Ib_Al();
+ 0x7: out_Ib_eAX();
+ }
+ 0x1D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: call_Jz();
+ 0x1: jmp_Jz();
+ 0x2: jmp_Ap();
+ 0x3: jmp_Jb();
+ 0x4: in_Al_Dx();
+ 0x5: in_eAX_Dx();
+ 0x6: out_Dx_Al();
+ 0x7: out_Dx_eAX();
+ }
+ 0x1E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: M5InternalError::error(
+ {{"Tried to execute the lock prefix!"}});
+ 0x1: int1();
+ 0x2: M5InternalError::error(
+ {{"Tried to execute the repne prefix!"}});
+ 0x3: M5InternalError::error(
+ {{"Tried to execute the rep/repe prefix!"}});
+ 0x4: hlt();
+ 0x5: cmc();
+ 0x6: group3_Eb();
+ 0x7: group3_Ev();
+ }
+ 0x1F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: clc();
+ 0x1: stc();
+ 0x2: cli();
+ 0x3: sti();
+ 0x4: cld();
+ 0x5: std();
+ 0x6: group4();
+ 0x7: group5();
+ }
+ }
+ default: FailUnimpl::oneByteOps();
+}
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
new file mode 100644
index 000000000..f05c33bdb
--- /dev/null
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -0,0 +1,393 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Decode the two byte opcodes
+//
+0x2: decode OPCODE_PREFIXA {
+ 0xF0: decode OPCODE_OP_TOP5 {
+ format WarnUnimpl {
+ 0x00: decode OPCODE_OP_BOTTOM3 {
+ 0x00: group6();
+ 0x01: group7();
+ 0x02: lar_Gv_Ew();
+ 0x03: lsl_Gv_Ew();
+ //sandpile.org doesn't seem to know what this is... ?
+ 0x04: loadall_or_reset_or_hang();
+ //sandpile.org says (AMD) after syscall, so I might want to check
+ //if that means amd64 or AMD machines
+ 0x05: loadall_or_syscall();
+ 0x06: clts();
+ //sandpile.org says (AMD) after sysret, so I might want to check
+ //if that means amd64 or AMD machines
+ 0x07: loadall_or_sysret();
+ }
+ 0x01: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holderholder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x02: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x03: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x04: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x05: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x06: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x07: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x08: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x09: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x0F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x11: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x12: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x13: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x14: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x15: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x16: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x17: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x18: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x19: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1A: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1B: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1C: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1D: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1E: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ 0x1F: decode OPCODE_OP_BOTTOM3 {
+ 0x0: holder();
+ 0x1: holder();
+ 0x2: holder();
+ 0x3: holder();
+ 0x4: holder();
+ 0x5: holder();
+ 0x6: holder();
+ 0x7: holder();
+ }
+ default: FailUnimpl::twoByteOps();
+ }
+ }
+ default: M5InternalError::error(
+ {{"Unexpected first opcode byte in two byte opcode!"}});
+}
diff --git a/src/arch/x86/isa/formats/basic.isa b/src/arch/x86/isa/formats/basic.isa
index 7aea7085f..ea224d638 100644
--- a/src/arch/x86/isa/formats/basic.isa
+++ b/src/arch/x86/isa/formats/basic.isa
@@ -147,3 +147,12 @@ def template BasicDecode {{
def template BasicDecodeWithMnemonic {{
return new %(class_name)s("%(mnemonic)s", machInst);
}};
+
+// The most basic instruction format... used only for a few misc. insts
+def format BasicOperate(code, *flags) {{
+ iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/x86/isa/decoder.isa b/src/arch/x86/isa/formats/error.isa
index 85f376b49..8ac2ea44d 100644
--- a/src/arch/x86/isa/decoder.isa
+++ b/src/arch/x86/isa/formats/error.isa
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
// Copyright (c) 2007 The Hewlett-Packard Development Company
// All rights reserved.
//
@@ -55,10 +57,21 @@
////////////////////////////////////////////////////////////////////
//
-// The actual decoder specification
+// "Format" which really indicates an internal error. This is a more
+// significant problem for x86 than for other ISAs because of it's complex
+// ExtMachInst type.
//
-decode EXAMPLE default Unknown::unknown()
-{
- 0x0: Unknown::unknown2();
-}
+def template ErrorDecode {{
+ {
+ panic("X86 decoder internal error: '%%s' %%s",
+ %(message)s, machInst);
+ }
+}};
+
+def format M5InternalError(error_message) {{
+ iop = InstObjParams(name, 'M5InternalError')
+ iop.message = error_message
+ decode_block = ErrorDecode.subst(iop)
+}};
+
diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa
index 0d3d1c6dc..d763c05bc 100644
--- a/src/arch/x86/isa/formats/formats.isa
+++ b/src/arch/x86/isa/formats/formats.isa
@@ -87,3 +87,14 @@
//Include the "unknown" format
##include "unknown.isa"
+
+//Include the "unimp" format
+##include "unimp.isa"
+
+//Include a format to signal m5 internal errors. This is used to indicate a
+//malfunction of the decode mechanism.
+##include "error.isa"
+
+//Include a format which implements a batch of instructions which do the same
+//thing on a variety of inputs
+##include "multi.isa"
diff --git a/src/arch/x86/isa/formats/multi.isa b/src/arch/x86/isa/formats/multi.isa
new file mode 100644
index 000000000..3e80f9cfb
--- /dev/null
+++ b/src/arch/x86/isa/formats/multi.isa
@@ -0,0 +1,106 @@
+// -*- mode:c++ -*-
+
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Instructions that do the same thing to multiple sets of arguments.
+//
+
+output header {{
+}};
+
+output decoder {{
+}};
+
+output exec {{
+}};
+
+let {{
+ multiops = {}
+}};
+
+def format MultiOp(code, switchVal, opTags, *opt_flags) {{
+ # Loads and stores that bring in and write out values from the
+ # instructions. These are determined by the input and output tags,
+ # and the resulting instruction will have the right number of micro ops,
+ # or could be implemented as an atomic macro op.
+ instNames = []
+ for tagSet in opTags:
+ loads = []
+ stores = []
+ postfix = ''
+ for tag in tagSet:
+ postfix += '_' + tag
+ gather_inputs = ''
+ if len(loads) + len(stores) == 0:
+ # If there are no loads or stores, make this a single instruction.
+ iop = InstObjParams(name, Name + postfix, 'X86StaticInst',
+ {"code": code, "gather_inputs": gather_inputs},
+ opt_flags)
+ else:
+ # Build up a macro op. We'll punt on this for now
+ pass
+
+ decodeBlob = 'switch(%s) {\n' % switchVal
+ counter = 0
+ for inst in instNames:
+ decodeBlob += '%d: return (X86StaticInst *)(new %s(machInst));\n' % \
+ (counter, inst)
+ counter += 1
+ decodeBlob += '}\n'
+ # decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
diff --git a/src/arch/x86/isa/formats/unimp.isa b/src/arch/x86/isa/formats/unimp.isa
new file mode 100644
index 000000000..12fa8387b
--- /dev/null
+++ b/src/arch/x86/isa/formats/unimp.isa
@@ -0,0 +1,174 @@
+// -*- mode:c++ -*-
+
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public X86StaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : X86StaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public X86StaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+#ifdef SS_COMPATIBLE_DISASSEMBLY
+ return csprintf("%-10s", mnemonic);
+#else
+ return csprintf("%-10s (unimplemented)", mnemonic);
+#endif
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' %s",
+ mnemonic, machInst);
+ return NoFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("instruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
diff --git a/src/arch/x86/isa/formats/unknown.isa b/src/arch/x86/isa/formats/unknown.isa
index 605ddcb69..43ddc20c1 100644
--- a/src/arch/x86/isa/formats/unknown.isa
+++ b/src/arch/x86/isa/formats/unknown.isa
@@ -120,7 +120,8 @@ output exec {{
Fault Unknown::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
- panic("No instructions are implemented for X86!\n");
+ warn("No instructions are implemented for X86!\n");
+ return NoFault;
}
}};
diff --git a/src/arch/x86/isa/main.isa b/src/arch/x86/isa/main.isa
index fd1b461f0..146f714a7 100644
--- a/src/arch/x86/isa/main.isa
+++ b/src/arch/x86/isa/main.isa
@@ -79,10 +79,10 @@ namespace X86ISA;
##include "operands.isa"
//Include the base class for x86 instructions, and some support code
-//##include "base.isa"
+##include "base.isa"
//Include the definitions for the instruction formats
##include "formats/formats.isa"
//Include the decoder definition
-##include "decoder.isa"
+##include "decoder/decoder.isa"
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index 4b144dce0..20376f38f 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -96,4 +96,7 @@ def operand_types {{
}};
def operands {{
+ # This is just copied from SPARC, because having no operands confuses
+ # the parser.
+ 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1)
}};
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
new file mode 100644
index 000000000..fbed4fe41
--- /dev/null
+++ b/src/arch/x86/predecoder.cc
@@ -0,0 +1,358 @@
+/*
+ * 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/predecoder.hh"
+#include "base/misc.hh"
+#include "base/trace.hh"
+#include "sim/host.hh"
+
+namespace X86ISA
+{
+ void Predecoder::process()
+ {
+ //This function drives the predecoder state machine.
+
+ //Some sanity checks. You shouldn't try to process more bytes if
+ //there aren't any, and you shouldn't overwrite an already
+ //predecoder ExtMachInst.
+ assert(!outOfBytes);
+ assert(!emiIsReady);
+
+ //While there's still something to do...
+ while(!emiIsReady && !outOfBytes)
+ {
+ uint8_t nextByte = getNextByte();
+ switch(state)
+ {
+ case PrefixState:
+ state = doPrefixState(nextByte);
+ break;
+ case OpcodeState:
+ state = doOpcodeState(nextByte);
+ break;
+ case ModRMState:
+ state = doModRMState(nextByte);
+ break;
+ case SIBState:
+ state = doSIBState(nextByte);
+ break;
+ case DisplacementState:
+ state = doDisplacementState();
+ break;
+ case ImmediateState:
+ state = doImmediateState();
+ break;
+ case ErrorState:
+ panic("Went to the error state in the predecoder.\n");
+ default:
+ panic("Unrecognized state! %d\n", state);
+ }
+ }
+ }
+
+ //Either get a prefix and record it in the ExtMachInst, or send the
+ //state machine on to get the opcode(s).
+ Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
+ {
+ uint8_t prefix = Prefixes[nextByte];
+ State nextState = PrefixState;
+ if(prefix)
+ consumeByte();
+ switch(prefix)
+ {
+ //Operand size override prefixes
+ case OperandSizeOverride:
+ DPRINTF(Predecoder, "Found operand size override prefix.\n");
+ break;
+ case AddressSizeOverride:
+ DPRINTF(Predecoder, "Found address size override prefix.\n");
+ break;
+ //Segment override prefixes
+ case CSOverride:
+ DPRINTF(Predecoder, "Found cs segment override.\n");
+ break;
+ case DSOverride:
+ DPRINTF(Predecoder, "Found ds segment override.\n");
+ break;
+ case ESOverride:
+ DPRINTF(Predecoder, "Found es segment override.\n");
+ break;
+ case FSOverride:
+ DPRINTF(Predecoder, "Found fs segment override.\n");
+ break;
+ case GSOverride:
+ DPRINTF(Predecoder, "Found gs segment override.\n");
+ break;
+ case SSOverride:
+ DPRINTF(Predecoder, "Found ss segment override.\n");
+ break;
+ case Lock:
+ DPRINTF(Predecoder, "Found lock prefix.\n");
+ break;
+ case Rep:
+ DPRINTF(Predecoder, "Found rep prefix.\n");
+ break;
+ case Repne:
+ DPRINTF(Predecoder, "Found repne prefix.\n");
+ break;
+ case RexPrefix:
+ DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
+ emi.rex = nextByte;
+ break;
+ case 0:
+ emi.opcode.num = 0;
+ nextState = OpcodeState;
+ break;
+ default:
+ panic("Unrecognized prefix %#x\n", nextByte);
+ }
+ return nextState;
+ }
+
+ //Load all the opcodes (currently up to 2) and then figure out
+ //what immediate and/or ModRM is needed.
+ Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
+ {
+ State nextState = ErrorState;
+ emi.opcode.num++;
+ //We can't handle 3+ byte opcodes right now
+ assert(emi.opcode.num < 3);
+ consumeByte();
+ if(emi.opcode.num == 1 && nextByte == 0x0f)
+ {
+ nextState = OpcodeState;
+ DPRINTF(Predecoder, "Found two byte opcode.\n");
+ emi.opcode.prefixA = nextByte;
+ }
+ else if(emi.opcode.num == 2 &&
+ (nextByte == 0x0f ||
+ (nextByte & 0xf8) == 0x38))
+ {
+ panic("Three byte opcodes aren't yet supported!\n");
+ nextState = OpcodeState;
+ DPRINTF(Predecoder, "Found three byte opcode.\n");
+ emi.opcode.prefixB = nextByte;
+ }
+ else
+ {
+ DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
+ emi.opcode.op = nextByte;
+
+ //Prepare for any immediate/displacement we might need
+ immediateCollected = 0;
+ emi.immediate = 0;
+ displacementCollected = 0;
+ emi.displacement = 0;
+
+ //Figure out how big of an immediate we'll retreive based
+ //on the opcode.
+ int immType = ImmediateType[
+ emi.opcode.num - 1][nextByte];
+ if(0) //16 bit mode
+ immediateSize = ImmediateTypeToSize[0][immType];
+ else if(!(emi.rex & 0x4)) //32 bit mode
+ immediateSize = ImmediateTypeToSize[1][immType];
+ else //64 bit mode
+ immediateSize = ImmediateTypeToSize[2][immType];
+
+ //Determine what to expect next
+ if (UsesModRM[emi.opcode.num - 1][nextByte]) {
+ nextState = ModRMState;
+ } else if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ }
+ return nextState;
+ }
+
+ //Get the ModRM byte and determine what displacement, if any, there is.
+ //Also determine whether or not to get the SIB byte, displacement, or
+ //immediate next.
+ Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
+ {
+ State nextState = ErrorState;
+ emi.modRM = nextByte;
+ DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
+ if (0) {//FIXME in 16 bit mode
+ //figure out 16 bit displacement size
+ if(nextByte & 0xC7 == 0x06 ||
+ nextByte & 0xC0 == 0x80)
+ displacementSize = 2;
+ else if(nextByte & 0xC0 == 0x40)
+ displacementSize = 1;
+ else
+ displacementSize = 0;
+ } else {
+ //figure out 32/64 bit displacement size
+ if(nextByte & 0xC7 == 0x05 ||
+ nextByte & 0xC0 == 0x80)
+ displacementSize = 4;
+ else if(nextByte & 0xC0 == 0x40)
+ displacementSize = 2;
+ else
+ displacementSize = 0;
+ }
+ //If there's an SIB, get that next.
+ //There is no SIB in 16 bit mode.
+ if(nextByte & 0x7 == 4 &&
+ nextByte & 0xC0 != 0xC0) {
+ // && in 32/64 bit mode)
+ nextState = SIBState;
+ } else if(displacementSize) {
+ nextState = DisplacementState;
+ } else if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ //The ModRM byte is consumed no matter what
+ consumeByte();
+ return nextState;
+ }
+
+ //Get the SIB byte. We don't do anything with it at this point, other
+ //than storing it in the ExtMachInst. Determine if we need to get a
+ //displacement or immediate next.
+ Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
+ {
+ State nextState = ErrorState;
+ emi.sib = nextByte;
+ DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
+ consumeByte();
+ if(displacementSize) {
+ nextState = DisplacementState;
+ } else if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ return nextState;
+ }
+
+ //Gather up the displacement, or at least as much of it
+ //as we can get.
+ Predecoder::State Predecoder::doDisplacementState()
+ {
+ State nextState = ErrorState;
+
+ getImmediate(displacementCollected,
+ emi.displacement,
+ displacementSize);
+
+ DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
+ displacementSize, displacementCollected);
+
+ if(displacementSize == displacementCollected) {
+ //Sign extend the displacement
+ switch(displacementSize)
+ {
+ case 1:
+ emi.displacement = sext<8>(emi.displacement);
+ break;
+ case 2:
+ emi.displacement = sext<16>(emi.displacement);
+ break;
+ case 4:
+ emi.displacement = sext<32>(emi.displacement);
+ break;
+ default:
+ panic("Undefined displacement size!\n");
+ }
+ DPRINTF(Predecoder, "Collected displacement %#x.\n",
+ emi.displacement);
+ if(immediateSize) {
+ nextState = ImmediateState;
+ } else {
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ }
+ else
+ nextState = DisplacementState;
+ return nextState;
+ }
+
+ //Gather up the immediate, or at least as much of it
+ //as we can get
+ Predecoder::State Predecoder::doImmediateState()
+ {
+ State nextState = ErrorState;
+
+ getImmediate(immediateCollected,
+ emi.immediate,
+ immediateSize);
+
+ DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n",
+ immediateSize, immediateCollected);
+
+ if(immediateSize == immediateCollected)
+ {
+ DPRINTF(Predecoder, "Collected immediate %#x.\n",
+ emi.immediate);
+ emiIsReady = true;
+ nextState = PrefixState;
+ }
+ else
+ nextState = ImmediateState;
+ return nextState;
+ }
+}
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh
new file mode 100644
index 000000000..1df17d6d2
--- /dev/null
+++ b/src/arch/x86/predecoder.hh
@@ -0,0 +1,225 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_X86_PREDECODER_HH__
+#define __ARCH_X86_PREDECODER_HH__
+
+#include "arch/x86/types.hh"
+#include "base/bitfield.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace X86ISA
+{
+ class Predecoder
+ {
+ private:
+ //These are defined and documented in predecoder_tables.cc
+ static const uint8_t Prefixes[256];
+ static const uint8_t UsesModRM[2][256];
+ static const uint8_t ImmediateType[2][256];
+ static const uint8_t ImmediateTypeToSize[3][10];
+
+ protected:
+ ThreadContext * tc;
+ //The bytes to be predecoded
+ MachInst fetchChunk;
+ //The pc of the start of fetchChunk
+ Addr basePC;
+ //The offset into fetchChunk of current processing
+ int offset;
+ //The extended machine instruction being generated
+ ExtMachInst emi;
+
+ inline uint8_t getNextByte()
+ {
+ return (fetchChunk >> (offset * 8)) & 0xff;
+ }
+
+ void getImmediate(int &collected, uint64_t &current, int size)
+ {
+ //Figure out how many bytes we still need to get for the
+ //immediate.
+ int toGet = size - collected;
+ //Figure out how many bytes are left in our "buffer"
+ int remaining = sizeof(MachInst) - offset;
+ //Get as much as we need, up to the amount available.
+ toGet = toGet > remaining ? remaining : toGet;
+
+ //Shift the bytes we want to be all the way to the right
+ uint64_t partialDisp = fetchChunk >> (offset * 8);
+ //Mask off what we don't want
+ partialDisp &= mask(toGet * 8);
+ //Shift it over to overlay with our displacement.
+ partialDisp <<= (displacementCollected * 8);
+ //Put it into our displacement
+ current |= partialDisp;
+ //Update how many bytes we've collected.
+ collected += toGet;
+ consumeBytes(toGet);
+ }
+
+ inline void consumeByte()
+ {
+ offset++;
+ assert(offset <= sizeof(MachInst));
+ if(offset == sizeof(MachInst))
+ outOfBytes = true;
+ }
+
+ inline void consumeBytes(int numBytes)
+ {
+ offset += numBytes;
+ assert(offset <= sizeof(MachInst));
+ if(offset == sizeof(MachInst))
+ outOfBytes = true;
+ }
+
+ //State machine state
+ protected:
+ //Whether or not we're out of bytes
+ bool outOfBytes;
+ //Whether we've completed generating an ExtMachInst
+ bool emiIsReady;
+ //The size of the displacement value
+ int displacementSize;
+ int displacementCollected;
+ //The size of the immediate value
+ int immediateSize;
+ int immediateCollected;
+
+ enum State {
+ PrefixState,
+ OpcodeState,
+ ModRMState,
+ SIBState,
+ DisplacementState,
+ ImmediateState,
+ //We should never get to this state. Getting here is an error.
+ ErrorState
+ };
+
+ State state;
+
+ //Functions to handle each of the states
+ State doPrefixState(uint8_t);
+ State doOpcodeState(uint8_t);
+ State doModRMState(uint8_t);
+ State doSIBState(uint8_t);
+ State doDisplacementState();
+ State doImmediateState();
+
+ public:
+ Predecoder(ThreadContext * _tc) :
+ tc(_tc), basePC(0), offset(0),
+ outOfBytes(true), emiIsReady(false),
+ state(PrefixState)
+ {}
+
+ ThreadContext * getTC()
+ {
+ return tc;
+ }
+
+ void setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void process();
+
+ //Use this to give data to the predecoder. This should be used
+ //when there is control flow.
+ void moreBytes(Addr currPC, Addr off, MachInst data)
+ {
+ basePC = currPC;
+ offset = off;
+ fetchChunk = data;
+ assert(off < sizeof(MachInst));
+ outOfBytes = false;
+ process();
+ }
+
+ //Use this to give data to the predecoder. This should be used
+ //when instructions are executed in order.
+ void moreBytes(MachInst machInst)
+ {
+ moreBytes(basePC + sizeof(machInst), 0, machInst);
+ }
+
+ bool needMoreBytes()
+ {
+ return outOfBytes;
+ }
+
+ bool extMachInstReady()
+ {
+ return emiIsReady;
+ }
+
+ //This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst & getExtMachInst()
+ {
+ assert(emiIsReady);
+ emiIsReady = false;
+ return emi;
+ }
+ };
+};
+
+#endif // __ARCH_X86_PREDECODER_HH__
diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc
new file mode 100644
index 000000000..f233ad234
--- /dev/null
+++ b/src/arch/x86/predecoder_tables.cc
@@ -0,0 +1,222 @@
+/*
+ * 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/predecoder.hh"
+#include "arch/x86/types.hh"
+
+namespace X86ISA
+{
+ const uint8_t CS = CSOverride;
+ const uint8_t DS = DSOverride;
+ const uint8_t ES = ESOverride;
+ const uint8_t FS = FSOverride;
+ const uint8_t GS = GSOverride;
+ const uint8_t SS = SSOverride;
+
+ const uint8_t OO = OperandSizeOverride;
+ const uint8_t AO = AddressSizeOverride;
+ const uint8_t LO = Lock;
+ const uint8_t RE = Rep;
+ const uint8_t RN = Repne;
+ const uint8_t RX = RexPrefix;
+
+ //This table identifies whether a byte is a prefix, and if it is,
+ //which prefix it is.
+ const uint8_t Predecoder::Prefixes[256] =
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 1*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 2*/ 0 , 0 , 0 , 0 , 0 , 0 , ES, 0 , 0 , 0 , 0 , 0 , 0 , 0 , CS, 0,
+/* 3*/ 0 , 0 , 0 , 0 , 0 , 0 , SS, 0 , 0 , 0 , 0 , 0 , 0 , 0 , DS, 0,
+/* 4*/ RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX, RX,
+/* 5*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 6*/ 0 , 0 , 0 , 0 , FS, GS, OO, AO, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 7*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 8*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 9*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* A*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* B*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* C*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* D*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* E*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* F*/ LO, 0 , RN, RE, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ };
+
+ //This table identifies whether a particular opcode uses the ModRM byte
+ const uint8_t Predecoder::UsesModRM[2][256] =
+ {//For one byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 1 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 2 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 3 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/* 4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 6 */ 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0,
+/* 7 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 8 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* A */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* C */ 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* D */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* F */ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1
+ },
+ //For two byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1,
+/* 1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 2 */ 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 4 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 5 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 6 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* 7 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1,
+/* 8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* 9 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* A */ 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1,
+/* B */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1,
+/* C */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/* D */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* E */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/* F */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0
+ }
+ };
+
+ enum ImmediateTypes {
+ NoImm,
+ NI = NoImm,
+ ByteImm,
+ BY = ByteImm,
+ WordImm,
+ WO = WordImm,
+ DWordImm,
+ DW = DWordImm,
+ QWordImm,
+ QW = QWordImm,
+ OWordImm,
+ OW = OWordImm,
+ VWordImm,
+ VW = VWordImm,
+ ZWordImm,
+ ZW = ZWordImm,
+ Pointer,
+ PO = Pointer,
+ //The enter instruction takes -2- immediates for a total of 3 bytes
+ Enter,
+ EN = Enter
+ };
+
+ const uint8_t Predecoder::ImmediateTypeToSize[3][10] =
+ {
+// noimm byte word dword qword oword vword zword enter
+ {0, 1, 2, 4, 8, 16, 2, 2, 3, 4}, //16 bit
+ {0, 1, 2, 4, 8, 16, 4, 4, 3, 6}, //32 bit
+ {0, 1, 2, 4, 8, 16, 4, 8, 3, 0} //64 bit
+ };
+
+ //This table determines the immediate type. The first index is the
+ //number of bytes in the instruction, and the second is the meaningful
+ //byte of the opcode. I didn't use the NI constant here for the sake
+ //of clarity.
+ const uint8_t Predecoder::ImmediateType[2][256] =
+ {//For one byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 1 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 2 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 3 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/* 4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 6 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ZW, ZW, BY, BY, 0 , 0 , 0 , 0 ,
+/* 7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY,
+/* 8 */ BY, ZW, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* A */ BY, VW, BY, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 ,
+/* B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW,
+/* C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 ,
+/* D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* E */ BY, BY, BY, BY, BY, BY, BY, BY, ZW, ZW, PO, BY, 0 , 0 , 0 , 0 ,
+/* F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ },
+ //For two byte instructions
+ { //LSB
+// MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 6 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 7 */ BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* 8 */ ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW,
+/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* A */ 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 ,
+/* B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ZW, 0 , BY, 0 , 0 , 0 , 0 , 0 ,
+/* C */ 0 , 0 , BY, 0 , BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* D */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/* F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ }
+ };
+}
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
index 63f65eee5..ca4a15d24 100644
--- a/src/arch/x86/types.hh
+++ b/src/arch/x86/types.hh
@@ -59,13 +59,111 @@
#define __ARCH_X86_TYPES_HH__
#include <inttypes.h>
+#include <iostream>
+
+#include "base/bitfield.hh"
+#include "base/cprintf.hh"
namespace X86ISA
{
- //XXX This won't work
- typedef uint32_t MachInst;
- //XXX This won't work either
- typedef uint64_t ExtMachInst;
+ //This really determines how many bytes are passed to the predecoder.
+ typedef uint64_t MachInst;
+
+ enum Prefixes {
+ NoOverride = 0,
+ CSOverride = 1,
+ DSOverride = 2,
+ ESOverride = 3,
+ FSOverride = 4,
+ GSOverride = 5,
+ SSOverride = 6,
+ //The Rex prefix obviously doesn't fit in with the above, but putting
+ //it here lets us save double the space the enums take up.
+ RexPrefix = 7,
+ //There can be only one segment override, so they share the
+ //first 3 bits in the legacyPrefixes bitfield.
+ SegmentOverride = 0x7,
+ OperandSizeOverride = 8,
+ AddressSizeOverride = 16,
+ Lock = 32,
+ Rep = 64,
+ Repne = 128
+ };
+
+ BitUnion8(ModRM)
+ Bitfield<7,6> mod;
+ Bitfield<5,3> reg;
+ Bitfield<2,0> rm;
+ EndBitUnion(ModRM)
+
+ BitUnion8(Sib)
+ Bitfield<7,6> scale;
+ Bitfield<5,3> index;
+ Bitfield<2,0> base;
+ EndBitUnion(Sib)
+
+ BitUnion8(Rex)
+ Bitfield<3> w;
+ Bitfield<2> r;
+ Bitfield<1> x;
+ Bitfield<0> b;
+ EndBitUnion(Rex)
+
+ BitUnion8(Opcode)
+ Bitfield<7,3> top5;
+ Bitfield<2,0> bottom3;
+ EndBitUnion(Opcode)
+
+ //The intermediate structure the x86 predecoder returns.
+ struct ExtMachInst
+ {
+ //Prefixes
+ uint8_t legacy;
+ Rex rex;
+ //This holds all of the bytes of the opcode
+ struct
+ {
+ //The number of bytes in this opcode. Right now, we ignore that
+ //this can be 3 in some cases
+ uint8_t num;
+ //The first byte detected in a 2+ byte opcode. Should be 0xF0.
+ uint8_t prefixA;
+ //The second byte detected in a 3+ byte opcode. Could be 0xF0 for
+ //3dnow instructions, or 0x38-0x3F for some SSE instructions.
+ uint8_t prefixB;
+ //The main opcode byte. The highest addressed byte in the opcode.
+ Opcode op;
+ } opcode;
+ //Modifier bytes
+ ModRM modRM;
+ uint8_t sib;
+ //Immediate fields
+ uint64_t immediate;
+ uint64_t displacement;
+ };
+
+ inline static std::ostream &
+ operator << (std::ostream & os, const ExtMachInst & emi)
+ {
+ ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t"
+ "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t"
+ "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t"
+ "modRM = %#x,\n\tsib = %#x,\n\t"
+ "immediate = %#x,\n\tdisplacement = %#x\n}\n",
+ emi.legacy, (uint8_t)emi.rex,
+ emi.opcode.num, emi.opcode.op,
+ emi.opcode.prefixA, emi.opcode.prefixB,
+ (uint8_t)emi.modRM, (uint8_t)emi.sib,
+ emi.immediate, emi.displacement);
+ return os;
+ }
+
+ inline static bool
+ operator == (const ExtMachInst &emi1, const ExtMachInst &emi2)
+ {
+ //Since this is empty, it's always equal
+ return true;
+ }
typedef uint64_t IntReg;
//XXX Should this be a 128 bit structure for XMM memory ops?
diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh
index 1fbe1fffe..d89e223de 100644
--- a/src/arch/x86/utility.hh
+++ b/src/arch/x86/utility.hh
@@ -59,11 +59,23 @@
#define __ARCH_X86_UTILITY_HH__
#include "arch/x86/types.hh"
+#include "base/hashmap.hh"
#include "base/misc.hh"
+#include "cpu/thread_context.hh"
#include "sim/host.hh"
class ThreadContext;
+namespace __hash_namespace {
+ template<>
+ struct hash<X86ISA::ExtMachInst> {
+ size_t operator()(const X86ISA::ExtMachInst &emi) const {
+ //Because these are all the same, return 0
+ return 0;
+ };
+ };
+}
+
namespace X86ISA
{
static inline bool
@@ -72,11 +84,6 @@ namespace X86ISA
return false;
}
- inline ExtMachInst
- makeExtMI(MachInst inst, ThreadContext * xc) {
- return inst;
- }
-
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
panic("register classification not implemented");
return false;