summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r--src/arch/x86/isa/base.isa303
-rw-r--r--src/arch/x86/isa/bitfields.isa3
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa409
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa253
-rw-r--r--src/arch/x86/isa/formats/error.isa2
-rw-r--r--src/arch/x86/isa/formats/formats.isa4
-rw-r--r--src/arch/x86/isa/formats/syscall.isa112
-rw-r--r--src/arch/x86/isa/formats/unimp.isa8
-rw-r--r--src/arch/x86/isa/includes.isa4
-rw-r--r--src/arch/x86/isa/insts/__init__.py3
-rw-r--r--src/arch/x86/isa/insts/arithmetic/add_and_subtract.py210
-rw-r--r--src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py42
-rw-r--r--src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py26
-rw-r--r--src/arch/x86/isa/insts/compare_and_test/compare.py58
-rw-r--r--src/arch/x86/isa/insts/compare_and_test/test.py16
-rw-r--r--src/arch/x86/isa/insts/control_transfer/call.py43
-rw-r--r--src/arch/x86/isa/insts/control_transfer/jump.py194
-rw-r--r--src/arch/x86/isa/insts/control_transfer/xreturn.py28
-rw-r--r--src/arch/x86/isa/insts/data_transfer/__init__.py3
-rw-r--r--src/arch/x86/isa/insts/data_transfer/move.py89
-rw-r--r--src/arch/x86/isa/insts/data_transfer/stack_operations.py19
-rw-r--r--src/arch/x86/isa/insts/data_transfer/xchg.py98
-rw-r--r--src/arch/x86/isa/insts/logical.py106
-rw-r--r--src/arch/x86/isa/insts/no_operation.py11
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/rotate.py86
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/shift.py62
-rw-r--r--src/arch/x86/isa/insts/system/__init__.py62
-rw-r--r--src/arch/x86/isa/insts/system/undefined_operation.py61
-rw-r--r--src/arch/x86/isa/main.isa4
-rw-r--r--src/arch/x86/isa/microasm.isa19
-rw-r--r--src/arch/x86/isa/microops/base.isa36
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa168
-rw-r--r--src/arch/x86/isa/microops/limmop.isa23
-rw-r--r--src/arch/x86/isa/microops/regop.isa419
-rw-r--r--src/arch/x86/isa/microops/specop.isa21
-rw-r--r--src/arch/x86/isa/operands.isa2
-rw-r--r--src/arch/x86/isa/outputblock.isa91
-rw-r--r--src/arch/x86/isa/specialize.isa5
38 files changed, 2106 insertions, 997 deletions
diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa
deleted file mode 100644
index eed969b47..000000000
--- a/src/arch/x86/isa/base.isa
+++ /dev/null
@@ -1,303 +0,0 @@
-// 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
-//
-
-let {{
- # This class will help make dealing with output a little less verbose
- class OutputBlocks(object):
- def __init__(self, header_output="",
- decoder_output="",
- decode_block="",
- exec_output=""):
- self.header_output = header_output
- self.decoder_output = decoder_output
- self.decode_block = decode_block
- self.exec_output = exec_output
-
- def append(self, blocks):
- if isinstance(blocks, list) or isinstance(blocks, tuple):
- assert(len(blocks) == 4)
- self.header_output += blocks[0]
- self.decoder_output += blocks[1]
- self.decode_block += blocks[2]
- self.exec_output += blocks[3]
- else:
- self.header_output += blocks.header_output
- self.decoder_output += blocks.decoder_output
- self.decode_block += blocks.decode_block
- self.exec_output += blocks.exec_output
-
- def makeList(self):
- return (self.header_output,
- self.decoder_output,
- self.decode_block,
- self.exec_output)
-}};
-
-output header {{
-
- /**
- * Base class for all X86 static instructions.
- */
- BitUnion64(X86IntReg)
- Bitfield<63,0> R;
- Bitfield<31,0> E;
- Bitfield<15,0> X;
- Bitfield<15,8> H;
- Bitfield<7, 0> L;
- EndBitUnion(X86IntReg)
-
- 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;
-
- inline uint64_t merge(uint64_t into, uint64_t val, int size) const
- {
- X86IntReg reg;
- reg = into;
- //FIXME This needs to be handle high bytes as well
- switch(size)
- {
- case 1:
- reg.L = val;
- break;
- case 2:
- reg.X = val;
- break;
- case 4:
- //XXX Check if this should be zeroed or sign extended
- reg = 0;
- reg.E = val;
- break;
- case 8:
- reg.R = val;
- break;
- default:
- panic("Tried to merge with unrecognized size %d.\n", size);
- }
- return val;
- }
-
- inline uint64_t pick(uint64_t from, int size)
- {
- X86IntReg reg;
- reg = from;
- switch(size)
- {
- case 1:
- return reg.L;
- case 2:
- return reg.E;
- case 4:
- return reg.X;
- case 8:
- return reg.R;
- default:
- panic("Tried to pick with unrecognized size %d.\n", size);
- }
- }
-
- };
-}};
-
-output decoder {{
-
- inline void printMnemonic(std::ostream &os, const char * mnemonic)
- {
- ccprintf(os, "\t%s ", mnemonic);
- }
-
- inline void printMnemonic(std::ostream &os,
- const char * instMnemonic, const char * mnemonic)
- {
- ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
- }
-
- void printSegment(std::ostream &os, int segment)
- {
- switch (segment)
- {
- case 0:
- ccprintf(os, "ES");
- break;
- case 1:
- ccprintf(os, "CS");
- break;
- case 2:
- ccprintf(os, "SS");
- break;
- case 3:
- ccprintf(os, "DS");
- break;
- case 4:
- ccprintf(os, "FS");
- break;
- case 5:
- ccprintf(os, "GS");
- break;
- default:
- panic("Unrecognized segment %d\n", segment);
- }
- }
-
- 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;
- default:
- ccprintf(os, "t%d", reg - NUM_INTREGS);
- }
- } 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 8707bbb4c..43fee5fef 100644
--- a/src/arch/x86/isa/bitfields.isa
+++ b/src/arch/x86/isa/bitfields.isa
@@ -67,11 +67,12 @@ def bitfield REX_B rex.b;
//Legacy prefixes
def bitfield LEGACY legacy;
+def bitfield LEGACY_DECODEVAL legacy.decodeVal;
def bitfield LEGACY_REPNE legacy.repne;
def bitfield LEGACY_REP legacy.rep;
def bitfield LEGACY_LOCK legacy.lock;
-def bitfield LEGACY_ADDR legacy.addr;
def bitfield LEGACY_OP legacy.op;
+def bitfield LEGACY_ADDR legacy.addr;
def bitfield LEGACY_SEG legacy.seg;
// Pieces of the opcode
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 484f8160d..b28f2029c 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -61,178 +61,130 @@
0x1: decode OPCODE_OP_TOP5 {
format WarnUnimpl {
0x00: decode OPCODE_OP_BOTTOM3 {
- 0x4: ADD();
- 0x5: ADD();
0x6: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: push_ES();
}
0x7: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: pop_ES();
}
- default: ADD();
+ default: MultiInst::ADD(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,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: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: 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!"}});
+ default: MultiInst::OR(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
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: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: push_SS();
}
0x7: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: pop_SS();
}
+ default: MultiInst::ADC(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
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: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: push_DS();
}
0x7: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: pop_DS();
}
+ default: MultiInst::SBB(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
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: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: daa();
}
+ default: MultiInst::AND(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
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();
+ default: MultiInst::SUB(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
0x06: decode OPCODE_OP_BOTTOM3 {
- 0x4: Inst::XOR(rAl,Ib);
- 0x5: Inst::XOR(rAx,Iz);
0x6: M5InternalError::error(
{{"Tried to execute the SS segment override prefix!"}});
0x7: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: aaa();
}
default: MultiInst::XOR(OPCODE_OP_BOTTOM3,
[Eb,Gb], [Ev,Gv],
- [Gb,Eb], [Gv,Ev]);
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
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: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: aas();
}
+ default: MultiInst::CMP(OPCODE_OP_BOTTOM3,
+ [Eb,Gb], [Ev,Gv],
+ [Gb,Eb], [Gv,Ev],
+ [rAl,Ib], [rAx,Iz]);
}
0x08: decode MODE_SUBMODE {
0x0: M5InternalError::error (
{{"Tried to execute an REX prefix!"}});
- default: 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();
- }
+ default: Inst::INC(B);
}
0x09: decode MODE_SUBMODE {
0x0: M5InternalError::error (
{{"Tried to execute an REX prefix!"}});
- default: 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();
- }
+ default: Inst::DEC(B);
}
format Inst {
- 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);
- }
+ 0x0A: PUSH(B);
+ 0x0B: POP(B);
}
0x0C: decode OPCODE_OP_BOTTOM3 {
0x0: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: pusha();
}
0x1: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: popa();
}
0x2: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: bound_Gv_Ma();
}
0x3: decode MODE_SUBMODE {
@@ -258,58 +210,82 @@
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();
- 0x1: decode MODRM_REG {
- 0x0: add_Ev_Iz();
- 0x1: or_Ev_Ibz();
- 0x2: adc_Ev_Iz();
- 0x3: sbb_Ev_Iz();
- 0x4: Inst::AND(Ev,Iz);
- 0x5: Inst::SUB(Ev,Iz);
- 0x6: xor_Ev_Iz();
- 0x7: cmp_Ev_Iz();
- }
- 0x2: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: group1_Eb_Ib();
+ format Inst {
+ 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: JNLE(Jb);
}
- //0x3: group1_Ev_Ib();
- 0x3: decode MODRM_REG {
- 0x0: add_Eb_Ib();
- 0x1: or_Eb_Ib();
- 0x2: adc_Eb_Ib();
- 0x3: sbb_Eb_Ib();
- 0x4: Inst::AND(Eb,Ib);
- 0x5: sub_Eb_Ib();
- 0x6: xor_Eb_Ib();
- 0x7: cmp_Eb_Ib();
+ }
+ format Inst {
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ //0x0: group1_Eb_Ib();
+ 0x0: decode MODRM_REG {
+ 0x0: ADD(Eb,Ib);
+ 0x1: OR(Eb,Ib);
+ 0x2: ADC(Eb,Ib);
+ 0x3: SBB(Eb,Ib);
+ 0x4: AND(Eb,Ib);
+ 0x5: SUB(Eb,Ib);
+ 0x6: XOR(Eb,Ib);
+ 0x7: CMP(Eb,Ib);
+ }
+ //0x1: group1_Ev_Iz();
+ 0x1: decode MODRM_REG {
+ 0x0: ADD(Ev,Iz);
+ 0x1: OR(Ev,Iz);
+ 0x2: ADC(Ev,Iz);
+ 0x3: SBB(Ev,Iz);
+ 0x4: AND(Ev,Iz);
+ 0x5: SUB(Ev,Iz);
+ 0x6: XOR(Ev,Iz);
+ 0x7: CMP(Ev,Iz);
+ }
+ 0x2: decode MODE_SUBMODE {
+ 0x0: UD2();
+ //default: group1_Eb_Ib();
+ default: decode MODRM_REG {
+ 0x0: ADD(Eb,Ib);
+ 0x1: OR(Eb,Ib);
+ 0x2: ADC(Eb,Ib);
+ 0x3: SBB(Eb,Ib);
+ 0x4: AND(Eb,Ib);
+ 0x5: SUB(Eb,Ib);
+ 0x6: XOR(Eb,Ib);
+ 0x7: CMP(Eb,Ib);
+ }
+ }
+ //0x3: group1_Ev_Ib();
+ 0x3: decode MODRM_REG {
+ 0x0: ADD(Ev,Ib);
+ 0x1: OR(Ev,Ib);
+ 0x2: ADC(Ev,Ib);
+ 0x3: SBB(Ev,Ib);
+ 0x4: AND(Ev,Ib);
+ 0x5: SUB(Ev,Ib);
+ 0x6: XOR(Ev,Ib);
+ 0x7: CMP(Ev,Ib);
+ }
+ 0x4: TEST(Eb,Gb);
+ 0x5: TEST(Ev,Gv);
+ 0x6: XCHG(Eb,Gb);
+ 0x7: XCHG(Ev,Gv);
}
- 0x4: Inst::TEST(Eb,Gb);
- 0x5: Inst::TEST(Ev,Gv);
- 0x6: xchg_Eb_Gb();
- 0x7: xchg_Ev_Gv();
}
0x11: decode OPCODE_OP_BOTTOM3 {
0x0: Inst::MOV(Eb,Gb);
@@ -322,21 +298,15 @@
0x7: group10_Ev(); //Make sure this is Ev
}
0x12: decode OPCODE_OP_BOTTOM3 {
- default: 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();
+ 0x0: Inst::NOP(); //XXX repe makes this a "pause"
+ default: xchg_B_rAX();
}
0x13: decode OPCODE_OP_BOTTOM3 {
0x0: cbw_or_cwde_or_cdqe_rAX();
0x1: cwd_or_cdq_or_cqo_rAX_rDX();
0x2: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: call_Ap();
+ 0x0: Inst::UD2();
+ default: call_far_Ap();
}
0x3: fwait(); //aka wait
0x4: pushf_Fv();
@@ -344,11 +314,11 @@
//Both of these should be illegal only if CPUID.AHF64=0,
//according to sandpile.org
0x6: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: sahf();
}
0x7: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: lahf();
}
}
@@ -372,48 +342,52 @@
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();
- }
format Inst {
- 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: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: les_Gz_Mp();
- }
- 0x5: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: lds_Gz_Mp();
- }
- //0x6: group12_Eb_Ib();
- 0x6: decode MODRM_REG {
- 0x0: Inst::MOV(Eb,Ib);
- }
- //0x7: group12_Ev_Iz();
- 0x7: decode MODRM_REG {
- 0x0: Inst::MOV(Ev,Iz);
+ 0x16: MOV(B,Ib);
+ 0x17: MOV(B,Iv);
+ 0x18: decode OPCODE_OP_BOTTOM3 {
+ //0x0: group2_Eb_Ib();
+ 0x0: decode MODRM_REG {
+ 0x0: ROL(Eb,Ib);
+ 0x1: ROR(Eb,Ib);
+ 0x2: RCL(Eb,Ib);
+ 0x3: RCR(Eb,Ib);
+ 0x4: SAL(Eb,Ib);
+ 0x5: SHR(Eb,Ib);
+ 0x6: SAL(Eb,Ib);
+ 0x7: SAR(Eb,Ib);
+ }
+ //0x1: group2_Ev_Ib();
+ 0x1: decode MODRM_REG {
+ 0x0: ROL(Ev,Ib);
+ 0x1: ROR(Ev,Ib);
+ 0x2: RCL(Ev,Ib);
+ 0x3: RCR(Ev,Ib);
+ 0x4: SAL(Ev,Ib);
+ 0x5: SHR(Ev,Ib);
+ 0x6: SAL(Ev,Ib);
+ 0x7: SAR(Ev,Ib);
+ }
+ 0x2: RET_NEAR(Iw);
+ 0x3: RET_NEAR();
+ 0x4: decode MODE_SUBMODE {
+ 0x0: UD2();
+ default: WarnUnimpl::les_Gz_Mp();
+ }
+ 0x5: decode MODE_SUBMODE {
+ 0x0: UD2();
+ default: WarnUnimpl::lds_Gz_Mp();
+ }
+ //0x6: group12_Eb_Ib();
+ 0x6: decode MODRM_REG {
+ 0x0: MOV(Eb,Ib);
+ default: UD2();
+ }
+ //0x7: group12_Ev_Iz();
+ 0x7: decode MODRM_REG {
+ 0x0: MOV(Ev,Iz);
+ default: UD2();
+ }
}
}
0x19: decode OPCODE_OP_BOTTOM3 {
@@ -424,7 +398,7 @@
0x4: int3();
0x5: int_Ib();
0x6: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: into();
}
0x7: iret();
@@ -435,15 +409,15 @@
0x2: group2_Eb_Cl();
0x3: group2_Ev_Cl();
0x4: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: aam_Ib();
}
0x5: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: aad_Ib();
}
0x6: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
+ 0x0: Inst::UD2();
default: salc();
}
0x7: xlat();
@@ -469,13 +443,13 @@
0x7: out_Ib_eAX();
}
0x1D: decode OPCODE_OP_BOTTOM3 {
- 0x0: Inst::CALL(Jz);
- 0x1: jmp_Jz();
+ 0x0: Inst::CALL_NEAR(Jz);
+ 0x1: Inst::JMP(Jz);
0x2: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: jmp_Ap();
+ 0x0: Inst::UD2();
+ default: jmp_far_Ap();
}
- 0x3: jmp_Jb();
+ 0x3: Inst::JMP(Jb);
0x4: in_Al_Dx();
0x5: in_eAX_Dx();
0x6: out_Dx_Al();
@@ -501,8 +475,25 @@
0x3: sti();
0x4: cld();
0x5: std();
- 0x6: group4();
- 0x7: group5();
+ format Inst {
+ //0x6: group4();
+ 0x6: decode MODRM_REG {
+ 0x0: INC(Eb);
+ 0x1: DEC(Eb);
+ default: UD2();
+ }
+ //0x7: group5();
+ 0x7: decode MODRM_REG {
+ 0x0: INC(Ev);
+ 0x1: DEC(Ev);
+ 0x2: CALL_NEAR(Ev);
+ 0x3: WarnUnimpl::call_far_Mp();
+ 0x4: JMP(Ev);
+ 0x5: WarnUnimpl::jmp_far_Mp();
+ 0x6: PUSH(Ev);
+ 0x7: UD2();
+ }
+ }
}
}
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
index f05c33bdb..e5631d37b 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -58,7 +58,7 @@
// Decode the two byte opcodes
//
0x2: decode OPCODE_PREFIXA {
- 0xF0: decode OPCODE_OP_TOP5 {
+ 0x0F: decode OPCODE_OP_TOP5 {
format WarnUnimpl {
0x00: decode OPCODE_OP_BOTTOM3 {
0x00: group6();
@@ -67,23 +67,25 @@
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();
+#if FULL_SYSTEM
+ 0x05: syscall();
+#else
+ 0x05: SyscallInst::syscall('xc->syscall(rax)');
+#endif
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();
+ 0x0: invd();
+ 0x1: wbinvd();
+ 0x2: Inst::UD2();
+ 0x3: UD2();
+ 0x4: Inst::UD2();
+ 0x5: threednow();
+ 0x6: threednow();
+ 0x7: threednow();
}
0x02: decode OPCODE_OP_BOTTOM3 {
0x0: holder();
@@ -96,14 +98,14 @@
0x7: holder();
}
0x03: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: group17();
+ 0x1: group17();
+ 0x2: group17();
+ 0x3: group17();
+ 0x4: group17();
+ 0x5: group17();
+ 0x6: group17();
+ 0x7: group17();
}
0x04: decode OPCODE_OP_BOTTOM3 {
0x0: holder();
@@ -126,44 +128,44 @@
0x7: holder();
}
0x06: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: wrmsr();
+ 0x1: rdtsc();
+ 0x2: rdmsr();
+ 0x3: rdpmc();
+ 0x4: sysenter();
+ 0x5: sysexit();
+ 0x6: Inst::UD2();
+ 0x7: getsec();
}
0x07: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: three_byte_opcode();
+ 0x1: three_byte_opcode();
+ 0x2: three_byte_opcode();
+ 0x3: three_byte_opcode();
+ 0x4: three_byte_opcode();
+ 0x5: three_byte_opcode();
+ 0x6: three_byte_opcode();
+ 0x7: three_byte_opcode();
}
0x08: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: cmovo_Gv_Ev();
+ 0x1: cmovno_Gv_Ev();
+ 0x2: cmovb_Gv_Ev();
+ 0x3: cmovnb_Gv_Ev();
+ 0x4: cmovz_Gv_Ev();
+ 0x5: cmovnz_Gv_Ev();
+ 0x6: cmovbe_Gv_Ev();
+ 0x7: cmovnbe_Gv_Ev();
}
0x09: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: cmovs_Gv_Ev();
+ 0x1: cmovns_Gv_Ev();
+ 0x2: cmovp_Gv_Ev();
+ 0x3: cmovnp_Gv_Ev();
+ 0x4: cmovl_Gv_Ev();
+ 0x5: cmovnl_Gv_Ev();
+ 0x6: cmovle_Gv_Ev();
+ 0x7: cmovnle_Gv_Ev();
}
0x0A: decode OPCODE_OP_BOTTOM3 {
0x0: holder();
@@ -225,85 +227,87 @@
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();
+ format Inst {
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ 0x0: JO(Jz);
+ 0x1: JNO(Jz);
+ 0x2: JB(Jz);
+ 0x3: JNB(Jz);
+ 0x4: JZ(Jz);
+ 0x5: JNZ(Jz);
+ 0x6: JBE(Jz);
+ 0x7: JNBE(Jz);
+ }
+ 0x11: decode OPCODE_OP_BOTTOM3 {
+ 0x0: JS(Jz);
+ 0x1: JNS(Jz);
+ 0x2: JP(Jz);
+ 0x3: JNP(Jz);
+ 0x4: JL(Jz);
+ 0x5: JNL(Jz);
+ 0x6: JLE(Jz);
+ 0x7: JNLE(Jz);
+ }
}
0x12: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: seto_Eb();
+ 0x1: setno_Eb();
+ 0x2: setb_Eb();
+ 0x3: setnb_Eb();
+ 0x4: setz_Eb();
+ 0x5: setnz_Eb();
+ 0x6: setbe_Eb();
+ 0x7: setnbe_Eb();
}
0x13: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: sets_Eb();
+ 0x1: setns_Eb();
+ 0x2: setp_Eb();
+ 0x3: setnp_Eb();
+ 0x4: setl_Eb();
+ 0x5: setnl_Eb();
+ 0x6: setle_Eb();
+ 0x7: setnle_Eb();
}
0x14: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: push_fs();
+ 0x1: pop_fs();
+ 0x2: cpuid();
+ 0x3: bt_Ev_Gv();
+ 0x4: shld_Ev_Gv_Ib();
+ 0x5: shld_Ev_Gv_rCl();
+ 0x6: xbts_and_cmpxchg();
+ 0x7: ibts_and_cmpxchg();
}
0x15: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: push_gs();
+ 0x1: pop_gs();
+ 0x2: rsm_smm();
+ 0x3: bts_Ev_Gv();
+ 0x4: shrd_Ev_Gv_Ib();
+ 0x5: shrd_Ev_Gv_rCl();
+ 0x6: group16();
+ 0x7: Inst::IMUL(Gv,Ev);
}
0x16: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: cmpxchg_Eb_Gb();
+ 0x1: cmpxchg_Ev_Gv();
+ 0x2: lss_Gz_Mp();
+ 0x3: btr_Ev_Gv();
+ 0x4: lfs_Gz_Mp();
+ 0x5: lgs_Gz_Mp();
+ 0x6: Inst::MOVZX_B(Gv,Eb);
+ 0x7: Inst::MOVZX_W(Gv,Ew);
}
0x17: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ 0x0: jmpe_Jz(); // IA-64?
+ 0x1: group11_UD2();
+ 0x2: group8_Ev_Ib();
+ 0x3: btc_Ev_Gv();
+ 0x4: bsf_Gv_Ev();
+ 0x5: bsr_Gv_Ev();
+ 0x6: Inst::MOVSX_B(Gv,Eb);
+ 0x7: Inst::MOVSX_W(Gv,Ew);
}
0x18: decode OPCODE_OP_BOTTOM3 {
0x0: holder();
@@ -315,16 +319,7 @@
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();
- }
+ 0x19: bswap_B();
0x1A: decode OPCODE_OP_BOTTOM3 {
0x0: holder();
0x1: holder();
diff --git a/src/arch/x86/isa/formats/error.isa b/src/arch/x86/isa/formats/error.isa
index 8ac2ea44d..e85eff762 100644
--- a/src/arch/x86/isa/formats/error.isa
+++ b/src/arch/x86/isa/formats/error.isa
@@ -64,7 +64,7 @@
def template ErrorDecode {{
{
- panic("X86 decoder internal error: '%%s' %%s",
+ panic("X86 decoder internal error: '%s' %s",
%(message)s, machInst);
}
}};
diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa
index d763c05bc..1e7bb4a74 100644
--- a/src/arch/x86/isa/formats/formats.isa
+++ b/src/arch/x86/isa/formats/formats.isa
@@ -98,3 +98,7 @@
//Include a format which implements a batch of instructions which do the same
//thing on a variety of inputs
##include "multi.isa"
+
+//Include a format which makes instructions who's sole purpose is to generate
+//a syscall.
+##include "syscall.isa"
diff --git a/src/arch/x86/isa/formats/syscall.isa b/src/arch/x86/isa/formats/syscall.isa
new file mode 100644
index 000000000..8b860dba4
--- /dev/null
+++ b/src/arch/x86/isa/formats/syscall.isa
@@ -0,0 +1,112 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// "Format" which describes an instruction whose only purpose is to
+// call a syscall in SE mode.
+//
+
+output header {{
+ class SyscallInst : public X86ISA::X86StaticInst
+ {
+ public:
+ /// Constructor
+ SyscallInst(const char *_mnemonic, ExtMachInst _machInst,
+ OpClass __opClass) :
+ X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string SyscallInst::generateDisassembly(Addr PC,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+ ccprintf(response, " ");
+ printReg(response, _srcRegIdx[0], machInst.opSize);
+ return response.str();
+ }
+}};
+
+def template SyscallExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+ return fault;
+ }
+}};
+
+def format SyscallInst(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'SyscallInst', code, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = SyscallExecute.subst(iop)
+}};
+
diff --git a/src/arch/x86/isa/formats/unimp.isa b/src/arch/x86/isa/formats/unimp.isa
index 12fa8387b..183beb3b8 100644
--- a/src/arch/x86/isa/formats/unimp.isa
+++ b/src/arch/x86/isa/formats/unimp.isa
@@ -68,12 +68,12 @@ output header {{
* 'Unknown' class is used for unrecognized/illegal instructions.
* This is a leaf class.
*/
- class FailUnimplemented : public X86StaticInst
+ class FailUnimplemented : public X86ISA::X86StaticInst
{
public:
/// Constructor
FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
- : X86StaticInst(_mnemonic, _machInst, No_OpClass)
+ : X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
@@ -95,7 +95,7 @@ output header {{
* probably make the 'warned' flag a static member of the derived
* class.
*/
- class WarnUnimplemented : public X86StaticInst
+ class WarnUnimplemented : public X86ISA::X86StaticInst
{
private:
/// Have we warned on this instruction yet?
@@ -104,7 +104,7 @@ output header {{
public:
/// Constructor
WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
- : X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ : X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
{
// don't call execute() (which panics) if we're on a
// speculative path
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa
index 4f27c72f5..58aef7b1d 100644
--- a/src/arch/x86/isa/includes.isa
+++ b/src/arch/x86/isa/includes.isa
@@ -97,6 +97,9 @@ output header {{
#include <iostream>
#include "arch/x86/emulenv.hh"
+#include "arch/x86/insts/microldstop.hh"
+#include "arch/x86/insts/microregop.hh"
+#include "arch/x86/insts/static_inst.hh"
#include "arch/x86/isa_traits.hh"
#include "arch/x86/regfile.hh"
#include "arch/x86/types.hh"
@@ -108,6 +111,7 @@ output header {{
output decoder {{
#include "arch/x86/faults.hh"
+#include "arch/x86/miscregs.hh"
#include "arch/x86/segmentregs.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
diff --git a/src/arch/x86/isa/insts/__init__.py b/src/arch/x86/isa/insts/__init__.py
index 717690926..f5c4e3113 100644
--- a/src/arch/x86/isa/insts/__init__.py
+++ b/src/arch/x86/isa/insts/__init__.py
@@ -69,7 +69,8 @@ categories = ["arithmetic",
"rotate_and_shift",
"semaphores",
"string",
- "system_calls"]
+ "system_calls",
+ "system"]
microcode = '''
# X86 microcode
diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
index 809b9ac7c..05aa6cd69 100644
--- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
+++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
@@ -54,23 +54,227 @@
# Authors: Gabe Black
microcode = '''
+def macroop ADD_R_R
+{
+ add reg, reg, regm
+};
+
+def macroop ADD_R_I
+{
+ limm t1, imm
+ add reg, reg, t1
+};
+
+def macroop ADD_M_I
+{
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ add t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADD_P_I
+{
+ rdip t7
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ add t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADD_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ add t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADD_P_R
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ add t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADD_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ add reg, reg, t1
+};
+
+def macroop ADD_R_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ add reg, reg, t1
+};
+
+def macroop SUB_R_R
+{
+ sub reg, reg, regm
+};
+
def macroop SUB_R_I
{
- subi reg, reg, imm
+ limm t1, imm
+ sub reg, reg, t1
+};
+
+def macroop SUB_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ sub reg, reg, t1
+};
+
+def macroop SUB_R_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ sub reg, reg, t1
};
def macroop SUB_M_I
{
+ limm t2, imm
ld t1, ds, [scale, index, base], disp
- subi t1, t1, imm
+ sub t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop SUB_P_I
{
rdip t7
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ sub t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SUB_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ sub t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SUB_P_R
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ sub t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADC_R_R
+{
+ adc reg, reg, regm
+};
+
+def macroop ADC_R_I
+{
+ limm t1, imm
+ adc reg, reg, t1
+};
+
+def macroop ADC_M_I
+{
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ adc t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADC_P_I
+{
+ rdip t7
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ adc t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADC_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ adc t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADC_P_R
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ adc t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ADC_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ adc reg, reg, t1
+};
+
+def macroop ADC_R_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ adc reg, reg, t1
+};
+
+def macroop SBB_R_R
+{
+ sbb reg, reg, regm
+};
+
+def macroop SBB_R_I
+{
+ limm t1, imm
+ sbb reg, reg, t1
+};
+
+def macroop SBB_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ sbb reg, reg, t1
+};
+
+def macroop SBB_R_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ sbb reg, reg, t1
+};
+
+def macroop SBB_M_I
+{
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ sbb t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SBB_P_I
+{
+ rdip t7
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ sbb t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SBB_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ sbb t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SBB_P_R
+{
+ rdip t7
ld t1, ds, [scale, index, base], disp
- subi t1, t1, imm
+ sbb t1, t1, reg
st t1, ds, [scale, index, base], disp
};
'''
diff --git a/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py b/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py
index c504d47ce..eed39c10c 100644
--- a/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py
+++ b/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py
@@ -53,7 +53,47 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop INC_R
+{
+ addi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
+};
+
+def macroop INC_M
+{
+ ld t1, ds, [scale, index, base], disp
+ addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF)
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop INC_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ addi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop DEC_R
+{
+ subi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
+};
+
+def macroop DEC_M
+{
+ ld t1, ds, [scale, index, base], disp
+ subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF)
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop DEC_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ subi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
+ st t1, ds, [0, t0, t7], disp
+};
+'''
#let {{
# class DEC(Inst):
# "GenFault ${new UnimpInstFault}"
diff --git a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
index 662022e6a..8697bef65 100644
--- a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
+++ b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
@@ -53,7 +53,31 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+
+#
+# Two operand signed multiply. These should set the CF and OF flags if the
+# result is too large for the destination register
+#
+
+def macroop IMUL_R_R
+{
+ mul1s reg, reg, regm
+};
+
+def macroop IMUL_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ mul1s reg, reg, t1
+};
+
+def macroop IMUL_R_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ mul1s reg, reg, t1
+};
+'''
#let {{
# class MUL(Inst):
# "GenFault ${new UnimpInstFault}"
diff --git a/src/arch/x86/isa/insts/compare_and_test/compare.py b/src/arch/x86/isa/insts/compare_and_test/compare.py
index 12b5b859f..8f5890b23 100644
--- a/src/arch/x86/isa/insts/compare_and_test/compare.py
+++ b/src/arch/x86/isa/insts/compare_and_test/compare.py
@@ -53,8 +53,56 @@
#
# Authors: Gabe Black
-microcode = ""
-#let {{
-# class CMP(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
+microcode = '''
+def macroop CMP_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_R_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_M_I
+{
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_P_I
+{
+ limm t2, imm
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_P_R
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_R_R
+{
+ sub t0, reg, regm, flags=(OF, SF, ZF, AF, PF, CF)
+};
+
+def macroop CMP_R_I
+{
+ limm t1, imm
+ sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF)
+};
+'''
diff --git a/src/arch/x86/isa/insts/compare_and_test/test.py b/src/arch/x86/isa/insts/compare_and_test/test.py
index 89d406912..8da33899a 100644
--- a/src/arch/x86/isa/insts/compare_and_test/test.py
+++ b/src/arch/x86/isa/insts/compare_and_test/test.py
@@ -57,39 +57,39 @@ microcode = '''
def macroop TEST_M_R
{
ld t1, ds, [scale, index, base], disp
- and t0, t1, reg
+ and t0, t1, reg, flags=(SF, ZF, PF)
};
def macroop TEST_P_R
{
rdip t7
- ld t1, ds, [scale, index, base], disp
- and t0, t1, reg
+ ld t1, ds, [0, t0, t7], disp
+ and t0, t1, reg, flags=(SF, ZF, PF)
};
def macroop TEST_R_R
{
- and t0, reg, regm
+ and t0, reg, regm, flags=(SF, ZF, PF)
};
def macroop TEST_M_I
{
ld t1, ds, [scale, index, base], disp
limm t2, imm
- and t0, t1, t2
+ and t0, t1, t2, flags=(SF, ZF, PF)
};
def macroop TEST_P_I
{
rdip t7
- ld t1, ds, [scale, index, base], disp
+ ld t1, ds, [0, t0, t7], disp
limm t2, imm
- and t0, t1, t2
+ and t0, t1, t2, flags=(SF, ZF, PF)
};
def macroop TEST_R_I
{
limm t1, imm
- and t0, reg, t1
+ and t0, reg, t1, flags=(SF, ZF, PF)
};
'''
diff --git a/src/arch/x86/isa/insts/control_transfer/call.py b/src/arch/x86/isa/insts/control_transfer/call.py
index 530162bfd..c5bb66e58 100644
--- a/src/arch/x86/isa/insts/control_transfer/call.py
+++ b/src/arch/x86/isa/insts/control_transfer/call.py
@@ -54,16 +54,51 @@
# Authors: Gabe Black
microcode = '''
-def macroop CALL_I
+def macroop CALL_NEAR_I
{
- # Make the default data size of pops 64 bits in 64 bit mode
+ # Make the default data size of calls 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ limm t1, imm
+ rdip t7
+ subi rsp, rsp, dsz
+ st t7, ss, [0, t0, rsp]
+ wrip t7, t1
+};
+
+def macroop CALL_NEAR_R
+{
+ # Make the default data size of calls 64 bits in 64 bit mode
.adjust_env oszIn64Override
- limm t2, imm
rdip t1
subi rsp, rsp, dsz
st t1, ss, [0, t0, rsp]
- wrip t1, t2
+ wripi reg, 0
+};
+
+def macroop CALL_NEAR_M
+{
+ # Make the default data size of calls 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ subi rsp, rsp, dsz
+ st t7, ss, [0, t0, rsp]
+ wripi t1, 0
+};
+
+def macroop CALL_NEAR_P
+{
+ # Make the default data size of calls 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ subi rsp, rsp, dsz
+ st t7, ss, [0, t0, rsp]
+ wripi t1, 0
};
'''
#let {{
diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py
index e90e5b12b..158861a3d 100644
--- a/src/arch/x86/isa/insts/control_transfer/jump.py
+++ b/src/arch/x86/isa/insts/control_transfer/jump.py
@@ -53,8 +53,192 @@
#
# Authors: Gabe Black
-microcode = ""
-#let {{
-# class JMP(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
+microcode = '''
+def macroop JZ_I
+{
+ # Make the defualt data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CZF,)
+};
+
+def macroop JNZ_I
+{
+ # Make the defualt data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCZF,)
+};
+
+def macroop JB_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CCF,)
+};
+
+def macroop JNB_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCCF,)
+};
+
+def macroop JBE_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CCvZF,)
+};
+
+def macroop JNBE_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCCvZF,)
+};
+
+def macroop JS_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CSF,)
+};
+
+def macroop JNS_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCSF,)
+};
+
+def macroop JP_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CPF,)
+};
+
+def macroop JNP_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCPF,)
+};
+
+def macroop JL_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CSxOF,)
+};
+
+def macroop JNL_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCSxOF,)
+};
+
+def macroop JLE_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(CSxOvZF,)
+};
+
+def macroop JNLE_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCSxOvZF,)
+};
+
+def macroop JO_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(COF,)
+};
+
+def macroop JNO_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2, flags=(nCOF,)
+};
+
+def macroop JMP_I
+{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t1
+ limm t2, imm
+ wrip t1, t2
+};
+
+def macroop JMP_R
+{
+ wripi reg, 0
+};
+
+def macroop JMP_M
+{
+ ld t1, ds, [scale, index, base], disp
+ wripi t1, 0
+};
+
+def macroop JMP_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ wripi t1, 0
+};
+'''
diff --git a/src/arch/x86/isa/insts/control_transfer/xreturn.py b/src/arch/x86/isa/insts/control_transfer/xreturn.py
index aaffa2b92..0000cd3c1 100644
--- a/src/arch/x86/isa/insts/control_transfer/xreturn.py
+++ b/src/arch/x86/isa/insts/control_transfer/xreturn.py
@@ -53,8 +53,26 @@
#
# Authors: Gabe Black
-microcode = ""
-#let {{
-# class RET(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
+microcode = '''
+def macroop RET_NEAR
+{
+ # Make the default data size of rets 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ ld t1, ss, [0, t0, rsp]
+ addi rsp, rsp, dsz
+ wripi t1, 0
+};
+
+def macroop RET_NEAR_I
+{
+ # Make the default data size of rets 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ limm t2, imm
+ ld t1, ss, [0, t0, rsp]
+ addi rsp, rsp, dsz
+ add rsp, rsp, t2
+ wripi t1, 0
+};
+'''
diff --git a/src/arch/x86/isa/insts/data_transfer/__init__.py b/src/arch/x86/isa/insts/data_transfer/__init__.py
index eda173b34..365f95eaa 100644
--- a/src/arch/x86/isa/insts/data_transfer/__init__.py
+++ b/src/arch/x86/isa/insts/data_transfer/__init__.py
@@ -55,7 +55,8 @@
categories = ["conditional_move",
"move",
- "stack_operations"]
+ "stack_operations",
+ "xchg"]
microcode = ""
for category in categories:
diff --git a/src/arch/x86/isa/insts/data_transfer/move.py b/src/arch/x86/isa/insts/data_transfer/move.py
index c85dd7cc4..bbc55e47c 100644
--- a/src/arch/x86/isa/insts/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/data_transfer/move.py
@@ -54,6 +54,11 @@
# Authors: Gabe Black
microcode = '''
+
+#
+# Regular moves
+#
+
def macroop MOV_R_R {
mov reg, reg, regm
};
@@ -64,7 +69,7 @@ def macroop MOV_M_R {
def macroop MOV_P_R {
rdip t7
- st reg, ds, [scale, index, base], disp
+ st reg, ds, [0, t0, t7], disp
};
def macroop MOV_R_M {
@@ -73,7 +78,7 @@ def macroop MOV_R_M {
def macroop MOV_R_P {
rdip t7
- ld reg, ds, [scale, index, base], disp
+ ld reg, ds, [0, t0, t7], disp
};
def macroop MOV_R_I {
@@ -88,22 +93,90 @@ def macroop MOV_M_I {
def macroop MOV_P_I {
rdip t7
limm t1, imm
- st t1, ds, [scale, index, base], disp
+ st t1, ds, [0, t0, t7], disp
};
+#
+# Sign extending moves
+#
+
def macroop MOVSXD_R_R {
- sext reg, regm, dsz
+ sext reg, regm, 32
};
def macroop MOVSXD_R_M {
- ld t1, ds, [scale, index, base], disp
- sext reg, t1, dsz
+ ld t1, ds, [scale, index, base], disp, dataSize=4
+ sext reg, t1, 32
};
def macroop MOVSXD_R_P {
rdip t7
- ld t1, ds, [scale, index, base], disp
- sext reg, t1, dsz
+ ld t1, ds, [0, t0, t7], disp, dataSize=4
+ sext reg, t1, 32
+};
+
+def macroop MOVSX_B_R_R {
+ sext reg, regm, 8
+};
+
+def macroop MOVSX_B_R_M {
+ ld reg, ds, [scale, index, base], disp, dataSize=1
+ sext reg, reg, 8
+};
+
+def macroop MOVSX_B_R_P {
+ rdip t7
+ ld reg, ds, [0, t0, t7], disp, dataSize=1
+ sext reg, reg, 8
+};
+
+def macroop MOVSX_W_R_R {
+ sext reg, regm, 16
+};
+
+def macroop MOVSX_W_R_M {
+ ld reg, ds, [scale, index, base], disp, dataSize=2
+ sext reg, reg, 16
+};
+
+def macroop MOVSX_W_R_P {
+ rdip t7
+ ld reg, ds, [0, t0, t7], disp, dataSize=2
+ sext reg, reg, 16
+};
+
+#
+# Zero extending moves
+#
+
+def macroop MOVZX_B_R_R {
+ zext reg, regm, 8
+};
+
+def macroop MOVZX_B_R_M {
+ ld t1, ds, [scale, index, base], disp, dataSize=1
+ zext reg, t1, 8
+};
+
+def macroop MOVZX_B_R_P {
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp, dataSize=1
+ zext reg, t1, 8
+};
+
+def macroop MOVZX_W_R_R {
+ zext reg, regm, 16
+};
+
+def macroop MOVZX_W_R_M {
+ ld t1, ds, [scale, index, base], disp, dataSize=2
+ zext reg, t1, 16
+};
+
+def macroop MOVZX_W_R_P {
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp, dataSize=2
+ zext reg, t1, 16
};
'''
#let {{
diff --git a/src/arch/x86/isa/insts/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
index 585437b8c..c381dc4f4 100644
--- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
@@ -69,6 +69,25 @@ def macroop PUSH_R {
subi rsp, rsp, dsz
st reg, ss, [0, t0, rsp]
};
+
+def macroop PUSH_M {
+ # Make the default data size of pops 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ ld t1, ds, [scale, index, base], disp
+ subi rsp, rsp, dsz
+ st t1, ss, [0, t0, rsp]
+};
+
+def macroop PUSH_P {
+ # Make the default data size of pops 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ subi rsp, rsp, dsz
+ st t1, ss, [0, t0, rsp]
+};
'''
#let {{
# class POPA(Inst):
diff --git a/src/arch/x86/isa/insts/data_transfer/xchg.py b/src/arch/x86/isa/insts/data_transfer/xchg.py
new file mode 100644
index 000000000..4f401deb7
--- /dev/null
+++ b/src/arch/x86/isa/insts/data_transfer/xchg.py
@@ -0,0 +1,98 @@
+# 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
+
+microcode = '''
+
+# All the memory versions need to use LOCK, regardless of if it was set
+
+def macroop XCHG_R_R
+{
+ # Use the xor trick instead of moves to reduce register pressure.
+ # This probably doesn't make much of a difference, but it's easy.
+ xor reg, reg, regm
+ xor regm, regm, reg
+ xor reg, reg, regm
+};
+
+def macroop XCHG_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ st reg, ds, [scale, index, base], disp
+ mov reg, reg, t1
+};
+
+def macroop XCHG_R_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ st reg, ds, [0, t0, t7], disp
+ mov reg, reg, t1
+};
+
+def macroop XCHG_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ st reg, ds, [scale, index, base], disp
+ mov reg, reg, t1
+};
+
+def macroop XCHG_P_R
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ st reg, ds, [0, t0, t7], disp
+ mov reg, reg, t1
+};
+'''
diff --git a/src/arch/x86/isa/insts/logical.py b/src/arch/x86/isa/insts/logical.py
index 2fd369d60..f99638cac 100644
--- a/src/arch/x86/isa/insts/logical.py
+++ b/src/arch/x86/isa/insts/logical.py
@@ -54,6 +54,62 @@
# Authors: Gabe Black
microcode = '''
+def macroop OR_R_R
+{
+ or reg, reg, regm
+};
+
+def macroop OR_M_I
+{
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ or t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop OR_P_I
+{
+ limm t2, imm
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ or t1, t1, t2
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop OR_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ or t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop OR_P_R
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ or t1, t1, reg
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop OR_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ or reg, reg, t1
+};
+
+def macroop OR_R_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ or reg, reg, t1
+};
+
+def macroop OR_R_I
+{
+ limm t1, imm
+ or reg, reg, t1
+};
+
def macroop XOR_R_R
{
xor reg, reg, regm
@@ -65,6 +121,23 @@ def macroop XOR_R_I
xor reg, reg, t1
};
+def macroop XOR_M_I
+{
+ limm t2, imm
+ ld t1, ds, [scale, index, base], disp
+ xor t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop XOR_P_I
+{
+ limm t2, imm
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ xor t1, t1, t2
+ st t1, ds, [scale, index, base], disp
+};
+
def macroop XOR_M_R
{
ld t1, ds, [scale, index, base], disp
@@ -93,6 +166,24 @@ def macroop XOR_R_P
xor reg, reg, t1
};
+def macroop AND_R_R
+{
+ and reg, reg, regm
+};
+
+def macroop AND_R_M
+{
+ ld t1, ds, [scale, index, base], disp
+ and reg, reg, t1
+};
+
+def macroop AND_R_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ and reg, reg, t1
+};
+
def macroop AND_R_I
{
limm t1, imm
@@ -115,6 +206,21 @@ def macroop AND_P_I
and t2, t2, t1
st t2, ds, [scale, index, base], disp
};
+
+def macroop AND_M_R
+{
+ ld t1, ds, [scale, index, base], disp
+ and t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop AND_P_R
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ and t1, t1, reg
+ st t1, ds, [scale, index, base], disp
+};
'''
#let {{
#microcodeString = '''
diff --git a/src/arch/x86/isa/insts/no_operation.py b/src/arch/x86/isa/insts/no_operation.py
index 1a287aea7..306ee2797 100644
--- a/src/arch/x86/isa/insts/no_operation.py
+++ b/src/arch/x86/isa/insts/no_operation.py
@@ -53,8 +53,9 @@
#
# Authors: Gabe Black
-microcode = ""
-#let {{
-# class NOP(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
+microcode = '''
+def macroop NOP
+{
+ fault "NoFault"
+};
+'''
diff --git a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
index e3aaf0043..0988f8815 100644
--- a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
+++ b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
@@ -53,14 +53,90 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop ROL_R_I
+{
+ rol reg, reg, imm
+};
+
+def macroop ROL_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ rol t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ROL_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ rol t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop ROR_R_I
+{
+ ror reg, reg, imm
+};
+
+def macroop ROR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ ror t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ROR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ ror t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop RCL_R_I
+{
+ rcl reg, reg, imm
+};
+
+def macroop RCL_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ rcl t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop RCL_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ rcl t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop RCR_R_I
+{
+ rcr reg, reg, imm
+};
+
+def macroop RCR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ rcr t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop RCR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ rcr t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+'''
#let {{
# class RCL(Inst):
# "GenFault ${new UnimpInstFault}"
# class RCR(Inst):
# "GenFault ${new UnimpInstFault}"
-# class ROL(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class ROR(Inst):
-# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py
index f72794657..5a04317d9 100644
--- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py
+++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py
@@ -53,7 +53,67 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop SAL_R_I
+{
+ sll reg, reg, imm
+};
+
+def macroop SAL_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ sll t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SAL_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sll t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop SHR_R_I
+{
+ srl reg, reg, imm
+};
+
+def macroop SHR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ srl t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SHR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ srl t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop SAR_R_I
+{
+ sra reg, reg, imm
+};
+
+def macroop SAR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ sra t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SAR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sra t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+'''
#let {{
# class SAL(Inst):
# "GenFault ${new UnimpInstFault}"
diff --git a/src/arch/x86/isa/insts/system/__init__.py b/src/arch/x86/isa/insts/system/__init__.py
new file mode 100644
index 000000000..72e3bdf0a
--- /dev/null
+++ b/src/arch/x86/isa/insts/system/__init__.py
@@ -0,0 +1,62 @@
+# 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
+
+categories = ["undefined_operation"]
+
+microcode = ""
+for category in categories:
+ exec "import %s as cat" % category
+ microcode += cat.microcode
+
diff --git a/src/arch/x86/isa/insts/system/undefined_operation.py b/src/arch/x86/isa/insts/system/undefined_operation.py
new file mode 100644
index 000000000..e5544b6e7
--- /dev/null
+++ b/src/arch/x86/isa/insts/system/undefined_operation.py
@@ -0,0 +1,61 @@
+# 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
+
+microcode = '''
+def macroop UD2
+{
+ fault "new X86Fault"
+};
+'''
diff --git a/src/arch/x86/isa/main.isa b/src/arch/x86/isa/main.isa
index fed8903c0..73cebc12b 100644
--- a/src/arch/x86/isa/main.isa
+++ b/src/arch/x86/isa/main.isa
@@ -79,8 +79,8 @@ namespace X86ISA;
//Include the bitfield definitions
##include "bitfields.isa"
-//Include the base class for x86 instructions, and some support code.
-##include "base.isa"
+//Include the OutputBlocks class which is used to bundle output.
+##include "outputblock.isa"
//Include the definitions for the instruction formats
##include "formats/formats.isa"
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index ee2b92f53..213468b0b 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -56,9 +56,9 @@
// Authors: Gabe Black
//Include the definitions of the micro ops.
-//These are StaticInst classes which stand on their own and make up an
-//internal instruction set, and also python representations which are passed
-//into the microcode assembler.
+//These are python representations of static insts which stand on their own
+//and make up an internal instruction set. They are used by the micro
+//assembler.
##include "microops/microops.isa"
//Include code to build macroops in both C++ and python.
@@ -96,6 +96,19 @@ let {{
assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper()
assembler.symbols.update(symbols)
+ for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'):
+ assembler.symbols[flag] = flag + "Bit"
+
+ for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF',
+ 'MSTRZ', 'STRZ', 'MSTRC', 'STRZnZF',
+ 'OF', 'CF', 'ZF', 'CvZF',
+ 'SF', 'PF', 'SxOF', 'SxOvZF'):
+ assembler.symbols["C%s" % cond] = "ConditionTests::%s" % cond
+ assembler.symbols["nC%s" % cond] = "ConditionTests::Not%s" % cond
+
+ assembler.symbols["CTrue"] = "ConditionTests::True"
+ assembler.symbols["CFalse"] = "ConditionTests::False"
+
# Code literal which forces a default 64 bit operand size in 64 bit mode.
assembler.symbols["oszIn64Override"] = '''
if (machInst.mode.submode == SixtyFourBitMode &&
diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa
index 79ac4493a..71fc3b3a5 100644
--- a/src/arch/x86/isa/microops/base.isa
+++ b/src/arch/x86/isa/microops/base.isa
@@ -61,42 +61,6 @@ let {{
microopClasses = {}
}};
-//A class which is the base of all x86 micro ops. It provides a function to
-//set necessary flags appropriately.
-output header {{
- class X86MicroopBase : public X86StaticInst
- {
- protected:
- const char * instMnem;
- uint8_t opSize;
- uint8_t addrSize;
-
- X86MicroopBase(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem,
- bool isMicro, bool isDelayed,
- bool isFirst, bool isLast,
- OpClass __opClass) :
- X86StaticInst(mnem, _machInst, __opClass),
- instMnem(_instMnem)
- {
- flags[IsMicroop] = isMicro;
- flags[IsDelayedCommit] = isDelayed;
- flags[IsFirstMicroop] = isFirst;
- flags[IsLastMicroop] = isLast;
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream ss;
-
- ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
-
- return ss.str();
- }
- };
-}};
-
//////////////////////////////////////////////////////////////////////////
//
// Base class for the python representation of x86 microops
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index fbff899a0..ccf519963 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -59,63 +59,6 @@
//
//////////////////////////////////////////////////////////////////////////
-output header {{
- /**
- * Base class for load and store ops
- */
- class LdStOp : public X86MicroopBase
- {
- protected:
- const uint8_t scale;
- const RegIndex index;
- const RegIndex base;
- const uint64_t disp;
- const uint8_t segment;
- const RegIndex data;
- const uint8_t dataSize;
- const uint8_t addressSize;
-
- //Constructor
- LdStOp(ExtMachInst _machInst,
- const char * mnem, const char * _instMnem,
- bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- uint8_t _scale, RegIndex _index, RegIndex _base,
- uint64_t _disp, uint8_t _segment,
- RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize,
- OpClass __opClass) :
- X86MicroopBase(machInst, mnem, _instMnem,
- isMicro, isDelayed, isFirst, isLast, __opClass),
- scale(_scale), index(_index), base(_base),
- disp(_disp), segment(_segment),
- data(_data),
- dataSize(_dataSize), addressSize(_addressSize)
- {}
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-}};
-
-output decoder {{
- std::string LdStOp::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, instMnem, mnemonic);
- printReg(response, data);
- response << ", ";
- printSegment(response, segment);
- ccprintf(response, ":[%d*", scale);
- printReg(response, index);
- response << " + ";
- printReg(response, base);
- ccprintf(response, " + %#x]", disp);
- return response.str();
- }
-}};
-
// LEA template
def template MicroLeaExecute {{
@@ -180,7 +123,25 @@ def template MicroLoadExecute {{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
+ unsigned flags = 0;
+ switch(dataSize)
+ {
+ case 1:
+ fault = xc->read(EA, (uint8_t&)Mem, flags);
+ break;
+ case 2:
+ fault = xc->read(EA, (uint16_t&)Mem, flags);
+ break;
+ case 4:
+ fault = xc->read(EA, (uint32_t&)Mem, flags);
+ break;
+ case 8:
+ fault = xc->read(EA, (uint64_t&)Mem, flags);
+ break;
+ default:
+ panic("Bad operand size!\n");
+ }
+
if(fault == NoFault)
{
%(code)s;
@@ -206,7 +167,24 @@ def template MicroLoadInitiateAcc {{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
+ unsigned flags = 0;
+ switch(dataSize)
+ {
+ case 1:
+ fault = xc->read(EA, (uint8_t&)Mem, flags);
+ break;
+ case 2:
+ fault = xc->read(EA, (uint16_t&)Mem, flags);
+ break;
+ case 4:
+ fault = xc->read(EA, (uint32_t&)Mem, flags);
+ break;
+ case 8:
+ fault = xc->read(EA, (uint64_t&)Mem, flags);
+ break;
+ default:
+ panic("Bad operand size!\n");
+ }
return fault;
}
@@ -252,8 +230,25 @@ def template MicroStoreExecute {{
if(fault == NoFault)
{
- fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
- EA, 0, 0);
+ unsigned flags = 0;
+ uint64_t *res = 0;
+ switch(dataSize)
+ {
+ case 1:
+ fault = xc->write((uint8_t&)Mem, EA, flags, res);
+ break;
+ case 2:
+ fault = xc->write((uint16_t&)Mem, EA, flags, res);
+ break;
+ case 4:
+ fault = xc->write((uint32_t&)Mem, EA, flags, res);
+ break;
+ case 8:
+ fault = xc->write((uint64_t&)Mem, EA, flags, res);
+ break;
+ default:
+ panic("Bad operand size!\n");
+ }
}
if(fault == NoFault)
{
@@ -280,8 +275,25 @@ def template MicroStoreInitiateAcc {{
if(fault == NoFault)
{
- fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
- EA, 0, 0);
+ unsigned flags = 0;
+ uint64_t *res = 0;
+ switch(dataSize)
+ {
+ case 1:
+ fault = xc->write((uint8_t&)Mem, EA, flags, res);
+ break;
+ case 2:
+ fault = xc->write((uint16_t&)Mem, EA, flags, res);
+ break;
+ case 4:
+ fault = xc->write((uint32_t&)Mem, EA, flags, res);
+ break;
+ case 8:
+ fault = xc->write((uint64_t&)Mem, EA, flags, res);
+ break;
+ default:
+ panic("Bad operand size!\n");
+ }
}
if(fault == NoFault)
{
@@ -382,12 +394,12 @@ def template MicroLdStOpConstructor {{
let {{
class LdStOp(X86Microop):
- def __init__(self, data, segment, addr, disp):
+ def __init__(self, data, segment, addr, disp, dataSize):
self.data = data
[self.scale, self.index, self.base] = addr
self.disp = disp
self.segment = segment
- self.dataSize = "env.dataSize"
+ self.dataSize = dataSize
self.addressSize = "env.addressSize"
def getAllocator(self, *microFlags):
@@ -424,7 +436,7 @@ let {{
name = mnemonic.lower()
# Build up the all register version of this micro op
- iop = InstObjParams(name, Name, 'LdStOp',
+ iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
{"code": code, "ea_code": calculateEA})
header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
@@ -433,8 +445,10 @@ let {{
exec_output += MicroLoadCompleteAcc.subst(iop)
class LoadOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0):
- super(LoadOp, self).__init__(data, segment, addr, disp)
+ def __init__(self, data, segment, addr,
+ disp = 0, dataSize="env.dataSize"):
+ super(LoadOp, self).__init__(data, segment,
+ addr, disp, dataSize)
self.className = Name
self.mnemonic = name
@@ -451,7 +465,7 @@ let {{
name = mnemonic.lower()
# Build up the all register version of this micro op
- iop = InstObjParams(name, Name, 'LdStOp',
+ iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
{"code": code, "ea_code": calculateEA})
header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
@@ -460,24 +474,28 @@ let {{
exec_output += MicroStoreCompleteAcc.subst(iop)
class StoreOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0):
- super(LoadOp, self).__init__(data, segment, addr, disp)
+ def __init__(self, data, segment, addr,
+ disp = 0, dataSize="env.dataSize"):
+ super(StoreOp, self).__init__(data, segment,
+ addr, disp, dataSize)
self.className = Name
self.mnemonic = name
microopClasses[name] = StoreOp
- defineMicroLoadOp('St', 'Mem = Data;')
+ defineMicroStoreOp('St', 'Mem = Data;')
- iop = InstObjParams("lea", "Lea", 'LdStOp',
+ iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
{"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
header_output += MicroLeaDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLeaExecute.subst(iop)
class LeaOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0):
- super(LeaOp, self).__init__(data, segment, addr, disp)
+ def __init__(self, data, segment, addr,
+ disp = 0, dataSize="env.dataSize"):
+ super(LeaOp, self).__init__(data, segment,
+ addr, disp, dataSize)
self.className = "Lea"
self.mnemonic = "lea"
diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa
index 141d7523f..37180d7fa 100644
--- a/src/arch/x86/isa/microops/limmop.isa
+++ b/src/arch/x86/isa/microops/limmop.isa
@@ -72,11 +72,12 @@ def template MicroLimmOpExecute {{
}};
def template MicroLimmOpDeclare {{
- class %(class_name)s : public X86MicroopBase
+ class %(class_name)s : public X86ISA::X86MicroopBase
{
protected:
const RegIndex dest;
const uint64_t imm;
+ const uint8_t dataSize;
void buildMe();
std::string generateDisassembly(Addr pc,
@@ -86,11 +87,11 @@ def template MicroLimmOpDeclare {{
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- RegIndex _dest, uint64_t _imm);
+ RegIndex _dest, uint64_t _imm, uint8_t _dataSize);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
- RegIndex _dest, uint64_t _imm);
+ RegIndex _dest, uint64_t _imm, uint8_t _dataSize);
%(BasicExecDeclare)s
};
@@ -103,7 +104,7 @@ def template MicroLimmOpDisassembly {{
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest);
+ printReg(response, dest, dataSize);
response << ", ";
ccprintf(response, "%#x", imm);
return response.str();
@@ -119,10 +120,10 @@ def template MicroLimmOpConstructor {{
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
- RegIndex _dest, uint64_t _imm) :
+ RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false, %(op_class)s),
- dest(_dest), imm(_imm)
+ dest(_dest), imm(_imm), dataSize(_dataSize)
{
buildMe();
}
@@ -130,10 +131,10 @@ def template MicroLimmOpConstructor {{
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- RegIndex _dest, uint64_t _imm) :
+ RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast, %(op_class)s),
- dest(_dest), imm(_imm)
+ dest(_dest), imm(_imm), dataSize(_dataSize)
{
buildMe();
}
@@ -146,14 +147,16 @@ let {{
self.mnemonic = "limm"
self.dest = dest
self.imm = imm
+ self.dataSize = "env.dataSize"
def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, mnemonic
- %(flags)s, %(dest)s, %(imm)s)''' % {
+ %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
"class_name" : self.className,
"mnemonic" : self.mnemonic,
"flags" : self.microFlagsText(microFlags),
- "dest" : self.dest, "imm" : self.imm }
+ "dest" : self.dest, "imm" : self.imm,
+ "dataSize" : self.dataSize}
return allocator
microopClasses["limm"] = LimmOp
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 65b75fab8..dbbe11c90 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -59,100 +59,6 @@
//
//////////////////////////////////////////////////////////////////////////
-output header {{
- /**
- * Base classes for RegOps which provides a generateDisassembly method.
- */
- class RegOp : public X86MicroopBase
- {
- protected:
- const RegIndex src1;
- const RegIndex src2;
- const RegIndex dest;
- const bool setStatus;
- const uint8_t dataSize;
- const uint8_t ext;
-
- // Constructor
- RegOp(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem,
- bool isMicro, bool isDelayed,
- bool isFirst, bool isLast,
- RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem,
- isMicro, isDelayed, isFirst, isLast,
- __opClass),
- src1(_src1), src2(_src2), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-
- class RegOpImm : public X86MicroopBase
- {
- protected:
- const RegIndex src1;
- const uint8_t imm8;
- const RegIndex dest;
- const bool setStatus;
- const uint8_t dataSize;
- const uint8_t ext;
-
- // Constructor
- RegOpImm(ExtMachInst _machInst,
- const char * mnem, const char *_instMnem,
- bool isMicro, bool isDelayed,
- bool isFirst, bool isLast,
- RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem,
- isMicro, isDelayed, isFirst, isLast,
- __opClass),
- src1(_src1), imm8(_imm8), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-}};
-
-output decoder {{
- std::string RegOp::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest);
- response << ", ";
- printReg(response, src1);
- response << ", ";
- printReg(response, src2);
- return response.str();
- }
-
- std::string RegOpImm::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest);
- response << ", ";
- printReg(response, src1);
- ccprintf(response, ", %#x", imm8);
- return response.str();
- }
-}};
-
def template MicroRegOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
@@ -161,8 +67,16 @@ def template MicroRegOpExecute {{
%(op_decl)s;
%(op_rd)s;
- %(code)s;
- %(flag_code)s;
+
+ if(%(cond_check)s)
+ {
+ %(code)s;
+ %(flag_code)s;
+ }
+ else
+ {
+ %(else_code)s;
+ }
//Write the resulting state to the execution context
if(fault == NoFault)
@@ -181,8 +95,16 @@ def template MicroRegOpImmExecute {{
%(op_decl)s;
%(op_rd)s;
- %(code)s;
- %(flag_code)s;
+
+ if(%(cond_check)s)
+ {
+ %(code)s;
+ %(flag_code)s;
+ }
+ else
+ {
+ %(else_code)s;
+ }
//Write the resulting state to the execution context
if(fault == NoFault)
@@ -204,12 +126,12 @@ def template MicroRegOpDeclare {{
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s
};
@@ -227,12 +149,12 @@ def template MicroRegOpImmDeclare {{
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(class_name)sImm(ExtMachInst _machInst,
const char * instMnem,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s
};
@@ -248,10 +170,10 @@ def template MicroRegOpConstructor {{
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
- _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+ _src1, _src2, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -261,10 +183,10 @@ def template MicroRegOpConstructor {{
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
- _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+ _src1, _src2, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -281,10 +203,10 @@ def template MicroRegOpImmConstructor {{
inline %(class_name)sImm::%(class_name)sImm(
ExtMachInst machInst, const char * instMnem,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
- _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+ _src1, _imm8, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -294,10 +216,10 @@ def template MicroRegOpImmConstructor {{
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
- _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+ _src1, _imm8, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -305,46 +227,74 @@ def template MicroRegOpImmConstructor {{
}};
let {{
+ class X86MicroMeta(type):
+ def __new__(mcls, name, bases, dict):
+ abstract = False
+ if "abstract" in dict:
+ abstract = dict['abstract']
+ del dict['abstract']
+
+ cls = type.__new__(mcls, name, bases, dict)
+ if not abstract:
+ allClasses[name] = cls
+ return cls
+
+ class XXX86Microop(object):
+ __metaclass__ = X86MicroMeta
+ abstract = True
+
class RegOp(X86Microop):
- def __init__(self, dest, src1, src2, setStatus):
+ abstract = True
+ def __init__(self, dest, src1, src2, flags, dataSize):
self.dest = dest
self.src1 = src1
self.src2 = src2
- self.setStatus = setStatus
- self.dataSize = "env.dataSize"
- self.ext = 0
+ self.flags = flags
+ self.dataSize = dataSize
+ if flags is None:
+ self.ext = 0
+ else:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.ext = " | ".join(flags)
+ self.className += "Flags"
def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, mnemonic
%(flags)s, %(src1)s, %(src2)s, %(dest)s,
- %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
+ %(dataSize)s, %(ext)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "src2" : self.src2,
"dest" : self.dest,
- "setStatus" : self.cppBool(self.setStatus),
"dataSize" : self.dataSize,
"ext" : self.ext}
return allocator
class RegOpImm(X86Microop):
- def __init__(self, dest, src1, imm8, setStatus):
+ abstract = True
+ def __init__(self, dest, src1, imm8, flags, dataSize):
self.dest = dest
self.src1 = src1
self.imm8 = imm8
- self.setStatus = setStatus
- self.dataSize = "env.dataSize"
- self.ext = 0
+ self.flags = flags
+ self.dataSize = dataSize
+ if flags is None:
+ self.ext = 0
+ else:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.ext = " | ".join(flags)
+ self.className += "Flags"
def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, mnemonic
%(flags)s, %(src1)s, %(imm8)s, %(dest)s,
- %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
+ %(dataSize)s, %(ext)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "imm8" : self.imm8,
"dest" : self.dest,
- "setStatus" : self.cppBool(self.setStatus),
"dataSize" : self.dataSize,
"ext" : self.ext}
return allocator
@@ -358,7 +308,8 @@ let {{
decoder_output = ""
exec_output = ""
- def setUpMicroRegOp(name, Name, base, code, child, flagCode):
+ # A function which builds the C++ classes that implement the microops
+ def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";"):
global header_output
global decoder_output
global exec_output
@@ -366,14 +317,21 @@ let {{
iop = InstObjParams(name, Name, base,
{"code" : code,
- "flag_code" : flagCode})
+ "flag_code" : flagCode,
+ "cond_check" : condCheck,
+ "else_code" : elseCode})
header_output += MicroRegOpDeclare.subst(iop)
decoder_output += MicroRegOpConstructor.subst(iop)
exec_output += MicroRegOpExecute.subst(iop)
- microopClasses[name] = child
- def defineMicroRegOp(mnemonic, code, flagCode):
+ checkCCFlagBits = "checkCondition(ccFlagBits)"
+ genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
+
+
+ # This creates a python representations of a microop which are a cross
+ # product of reg/immediate and flag/no flag versions.
+ def defineMicroRegOp(mnemonic, code, subtract = False, cc=False, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@@ -384,36 +342,47 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
- # Build the all register version of this micro op
+ if subtract:
+ secondSrc = "-op2, true"
+ else:
+ secondSrc = "op2"
+
+ if not cc:
+ flagCode = genCCFlagBits % secondSrc
+ condCode = "true"
+ else:
+ flagCode = ""
+ condCode = checkCCFlagBits
+
+ regFlagCode = matcher.sub("SrcReg2", flagCode)
+ immFlagCode = matcher.sub("imm8", flagCode)
+
class RegOpChild(RegOp):
- def __init__(self, dest, src1, src2, setStatus=False):
- super(RegOpChild, self).__init__(dest, src1, src2, setStatus)
- self.className = Name
- self.mnemonic = name
+ mnemonic = name
+ className = Name
+ def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
+ super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize)
+
+ microopClasses[name] = RegOpChild
- setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode);
+ setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
+ setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
+ flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
- # Build the immediate version of this micro op
class RegOpChildImm(RegOpImm):
- def __init__(self, dest, src1, src2, setStatus=False):
- super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus)
- self.className = Name + "Imm"
- self.mnemonic = name + "i"
-
- setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode);
-
- defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF
- defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "")
- defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF
- defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF
- defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "")
- defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF
- defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "")
- defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg
- defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "")
+ mnemonic = name + 'i'
+ className = Name + 'Imm'
+ def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
+ super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize)
+
+ microopClasses[name + 'i'] = RegOpChildImm
+
+ setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
+ setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
+ flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
# This has it's own function because Wr ops have implicit destinations
- def defineMicroRegOpWr(mnemonic, code):
+ def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@@ -424,25 +393,29 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
- # Build the all register version of this micro op
class RegOpChild(RegOp):
- def __init__(self, src1, src2):
- super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False)
- self.className = Name
- self.mnemonic = name
+ mnemonic = name
+ className = Name
+ def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
+ super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
+
+ microopClasses[name] = RegOpChild
- setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, "");
+ setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
+ setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
+ condCheck = checkCCFlagBits, elseCode = elseCode);
- # Build the immediate version of this micro op
class RegOpChildImm(RegOpImm):
- def __init__(self, src1, src2):
- super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False)
- self.className = Name + "Imm"
- self.mnemonic = name + "i"
+ mnemonic = name + 'i'
+ className = Name + 'Imm'
+ def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
+ super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
- setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, "");
+ microopClasses[name + 'i'] = RegOpChildImm
- defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
+ setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode);
+ setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
+ condCheck = checkCCFlagBits, elseCode = elseCode);
# This has it's own function because Rd ops don't always have two parameters
def defineMicroRegOpRd(mnemonic, code):
@@ -450,30 +423,136 @@ let {{
name = mnemonic.lower()
class RegOpChild(RegOp):
- def __init__(self, dest, src1 = "NUM_INTREGS"):
- super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False)
+ def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
+ super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
self.className = Name
self.mnemonic = name
- setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, "");
+ microopClasses[name] = RegOpChild
- defineMicroRegOpRd('Rdip', 'DestReg = RIP')
+ setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
def defineMicroRegOpImm(mnemonic, code):
Name = mnemonic
name = mnemonic.lower()
class RegOpChild(RegOpImm):
- def __init__(self, dest, src1, src2):
- super(RegOpChild, self).__init__(dest, src1, src2, False)
+ def __init__(self, dest, src1, src2, dataSize="env.dataSize"):
+ super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize)
self.className = Name
self.mnemonic = name
- setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, "");
+ microopClasses[name] = RegOpChild
+
+ setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
+
+ defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
+ defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
+ defineMicroRegOp('Adc', '''
+ CCFlagBits flags = ccFlagBits;
+ DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
+ ''')
+ defineMicroRegOp('Sbb', '''
+ CCFlagBits flags = ccFlagBits;
+ DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
+ ''', True)
+ defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
+ defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
+ defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
+ # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
+ defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
+ defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
+ elseCode='DestReg=DestReg;', cc=True)
+
+ # Shift instructions
+ defineMicroRegOp('Sll', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
+ ''')
+ defineMicroRegOp('Srl', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ // Because what happens to the bits shift -in- on a right shift
+ // is not defined in the C/C++ standard, we have to mask them out
+ // to be sure they're zero.
+ uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
+ ''')
+ defineMicroRegOp('Sra', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ // Because what happens to the bits shift -in- on a right shift
+ // is not defined in the C/C++ standard, we have to sign extend
+ // them manually to be sure.
+ uint64_t arithMask =
+ -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
+ ''')
+ defineMicroRegOp('Ror', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
+ uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rcr', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ CCFlagBits flags = ccFlagBits;
+ uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
+ if(shiftAmt > 1)
+ top |= SrcReg1 << (dataSize * 8 - shiftAmt - 1);
+ uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rol', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t bottom =
+ bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rcl', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ CCFlagBits flags = ccFlagBits;
+ uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t bottom = flags.CF << (shiftAmt - 1);
+ if(shiftAmt > 1)
+ bottom |=
+ bits(SrcReg1, dataSize * 8 - 1,
+ dataSize * 8 - shiftAmt + 1);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+
+ defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
+
+ defineMicroRegOpRd('Rdip', 'DestReg = RIP')
defineMicroRegOpImm('Sext', '''
IntReg val = SrcReg1;
int sign_bit = bits(val, imm8-1, imm8-1);
val = sign_bit ? (val | ~mask(imm8)) : val;
DestReg = merge(DestReg, val, dataSize);''')
+
+ defineMicroRegOpImm('Zext', 'DestReg = bits(SrcReg1, imm8-1, 0);')
}};
diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa
index b56223390..5c9e8dda9 100644
--- a/src/arch/x86/isa/microops/specop.isa
+++ b/src/arch/x86/isa/microops/specop.isa
@@ -60,7 +60,7 @@
//////////////////////////////////////////////////////////////////////////
output header {{
- class MicroFault : public X86MicroopBase
+ class MicroFault : public X86ISA::X86MicroopBase
{
protected:
Fault fault;
@@ -75,6 +75,9 @@ output header {{
Fault _fault);
%(BasicExecDeclare)s
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
};
}};
@@ -106,6 +109,22 @@ output decoder {{
}
}};
+output decoder {{
+ std::string MicroFault::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ if(fault)
+ response << fault->name();
+ else
+ response << "No Fault";
+
+ return response.str();
+ }
+}};
+
let {{
class Fault(X86Microop):
def __init__(self, fault):
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index b2ac17d66..406c74a1f 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -102,6 +102,8 @@ def operands {{
'Base': ('IntReg', 'uqw', 'base', 'IsInteger', 4),
'Index': ('IntReg', 'uqw', 'index', 'IsInteger', 5),
'Data': ('IntReg', 'uqw', 'data', 'IsInteger', 6),
+ 'rax': ('IntReg', 'uqw', 'INTREG_RAX', 'IsInteger', 7),
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10),
+ 'ccFlagBits': ('IntReg', 'uqw', 'NUM_INTREGS + NumMicroIntRegs', None, 20),
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
}};
diff --git a/src/arch/x86/isa/outputblock.isa b/src/arch/x86/isa/outputblock.isa
new file mode 100644
index 000000000..342d6ac4b
--- /dev/null
+++ b/src/arch/x86/isa/outputblock.isa
@@ -0,0 +1,91 @@
+// 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Output blocks which group together code generated by the parser.
+//
+
+let {{
+ # This class will help make dealing with output a little less verbose
+ class OutputBlocks(object):
+ def __init__(self, header_output="",
+ decoder_output="",
+ decode_block="",
+ exec_output=""):
+ self.header_output = header_output
+ self.decoder_output = decoder_output
+ self.decode_block = decode_block
+ self.exec_output = exec_output
+
+ def append(self, blocks):
+ if isinstance(blocks, list) or isinstance(blocks, tuple):
+ assert(len(blocks) == 4)
+ self.header_output += blocks[0]
+ self.decoder_output += blocks[1]
+ self.decode_block += blocks[2]
+ self.exec_output += blocks[3]
+ else:
+ self.header_output += blocks.header_output
+ self.decoder_output += blocks.decoder_output
+ self.decode_block += blocks.decode_block
+ self.exec_output += blocks.exec_output
+
+ def makeList(self):
+ return (self.header_output,
+ self.decoder_output,
+ self.decode_block,
+ self.exec_output)
+}};
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index 3183f32ba..5165ea206 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -118,6 +118,7 @@ let {{
ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
+ InstRegIndex = "(OPCODE_OP_BOTTOM3 | (REX_B << 3))"
# This function specializes the given piece of code to use a particular
# set of argument types described by "opTypes".
@@ -143,6 +144,10 @@ let {{
else:
print "Didn't recognize fixed register size %s!" % opType.rsize
Name += "_R"
+ elif opType.tag == "B":
+ # This refers to registers whose index is encoded as part of the opcode
+ Name += "_R"
+ env.addReg(InstRegIndex)
elif opType.tag == "M":
# This refers to memory. The macroop constructor sets up modrm
# addressing. Non memory modrm settings should cause an error.