summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/insts/microldstop.cc6
-rw-r--r--src/arch/x86/insts/microldstop.hh7
-rw-r--r--src/arch/x86/insts/microregop.cc10
-rw-r--r--src/arch/x86/insts/microregop.hh2
-rw-r--r--src/arch/x86/insts/static_inst.cc17
-rw-r--r--src/arch/x86/insts/static_inst.hh21
-rw-r--r--src/arch/x86/isa/bitfields.isa1
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa26
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa2
-rw-r--r--src/arch/x86/isa/decoder/x87.isa346
-rw-r--r--src/arch/x86/isa/formats/syscall.isa1
-rw-r--r--src/arch/x86/isa/insts/arithmetic/add_and_subtract.py64
-rw-r--r--src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py157
-rw-r--r--src/arch/x86/isa/insts/control_transfer/jump.py9
-rw-r--r--src/arch/x86/isa/insts/data_transfer/stack_operations.py9
-rw-r--r--src/arch/x86/isa/insts/load_effective_address.py2
-rw-r--r--src/arch/x86/isa/insts/logical.py48
-rw-r--r--src/arch/x86/isa/insts/processor_information.py15
-rw-r--r--src/arch/x86/isa/microops/limmop.isa4
-rw-r--r--src/arch/x86/isa/microops/regop.isa164
-rw-r--r--src/arch/x86/isa/operands.isa14
-rw-r--r--src/arch/x86/isa/specialize.isa2
-rw-r--r--src/arch/x86/isa_traits.hh2
-rw-r--r--src/arch/x86/linux/linux.hh22
-rw-r--r--src/arch/x86/linux/syscalls.cc16
-rw-r--r--src/arch/x86/process.cc6
-rw-r--r--src/arch/x86/regfile.cc9
-rw-r--r--src/arch/x86/types.hh3
28 files changed, 804 insertions, 181 deletions
diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc
index 8a52ad932..9628256e4 100644
--- a/src/arch/x86/insts/microldstop.cc
+++ b/src/arch/x86/insts/microldstop.cc
@@ -66,13 +66,13 @@ namespace X86ISA
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
- printReg(response, data, dataSize);
+ printDestReg(response, 0, dataSize);
response << ", ";
printSegment(response, segment);
ccprintf(response, ":[%d*", scale);
- printReg(response, index, addressSize);
+ printSrcReg(response, 0, addressSize);
response << " + ";
- printReg(response, base, addressSize);
+ printSrcReg(response, 1, addressSize);
ccprintf(response, " + %#x]", disp);
return response.str();
}
diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh
index ae03d176e..8fef14121 100644
--- a/src/arch/x86/insts/microldstop.hh
+++ b/src/arch/x86/insts/microldstop.hh
@@ -76,6 +76,7 @@ namespace X86ISA
const RegIndex data;
const uint8_t dataSize;
const uint8_t addressSize;
+ RegIndex foldOBit, foldABit;
//Constructor
LdStOp(ExtMachInst _machInst,
@@ -92,7 +93,11 @@ namespace X86ISA
disp(_disp), segment(_segment),
data(_data),
dataSize(_dataSize), addressSize(_addressSize)
- {}
+ {
+ foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
+ foldABit =
+ (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
+ }
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc
index 976b04688..e67a82d4f 100644
--- a/src/arch/x86/insts/microregop.cc
+++ b/src/arch/x86/insts/microregop.cc
@@ -173,11 +173,11 @@ namespace X86ISA
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest, dataSize);
+ printDestReg(response, 0, dataSize);
response << ", ";
- printReg(response, src1, dataSize);
+ printSrcReg(response, 0, dataSize);
response << ", ";
- printReg(response, src2, dataSize);
+ printSrcReg(response, 1, dataSize);
return response.str();
}
@@ -187,9 +187,9 @@ namespace X86ISA
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest, dataSize);
+ printDestReg(response, 0, dataSize);
response << ", ";
- printReg(response, src1, dataSize);
+ printSrcReg(response, 0, dataSize);
ccprintf(response, ", %#x", imm8);
return response.str();
}
diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh
index f411c0775..f465ac651 100644
--- a/src/arch/x86/insts/microregop.hh
+++ b/src/arch/x86/insts/microregop.hh
@@ -113,6 +113,7 @@ namespace X86ISA
const RegIndex dest;
const uint8_t dataSize;
const uint16_t ext;
+ RegIndex foldOBit;
// Constructor
RegOpBase(ExtMachInst _machInst,
@@ -128,6 +129,7 @@ namespace X86ISA
src1(_src1), dest(_dest),
dataSize(_dataSize), ext(_ext)
{
+ foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
}
//Figure out what the condition code flags should be.
diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc
index 9b2f81e49..948a74bc1 100644
--- a/src/arch/x86/insts/static_inst.cc
+++ b/src/arch/x86/insts/static_inst.cc
@@ -117,15 +117,27 @@ namespace X86ISA
{
assert(size == 1 || size == 2 || size == 4 || size == 8);
static const char * abcdFormats[9] =
- {"", "%sl", "%sx", "", "e%sx", "", "", "", "r%sx"};
+ {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"};
static const char * piFormats[9] =
- {"", "%sl", "%s", "", "e%s", "", "", "", "r%s"};
+ {"", "%s", "%s", "", "e%s", "", "", "", "r%s"};
static const char * longFormats[9] =
{"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
static const char * microFormats[9] =
{"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
if (reg < FP_Base_DepTag) {
+ char * suffix = "";
+ bool fold = reg & (1 << 6);
+ reg &= ~(1 << 6);
+
+ if(fold)
+ {
+ suffix = "h";
+ reg -= 4;
+ }
+ else if(reg < 8 && size == 1)
+ suffix = "l";
+
switch (reg) {
case INTREG_RAX:
ccprintf(os, abcdFormats[size], "a");
@@ -178,6 +190,7 @@ namespace X86ISA
default:
ccprintf(os, microFormats[size], reg - NUM_INTREGS);
}
+ ccprintf(os, suffix);
} else if (reg < Ctrl_Base_DepTag) {
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
} else {
diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh
index f42e6693d..22139fc77 100644
--- a/src/arch/x86/insts/static_inst.hh
+++ b/src/arch/x86/insts/static_inst.hh
@@ -92,9 +92,12 @@ namespace X86ISA
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
+ X86IntReg reg = into;
+ if(_destRegIdx[0] & (1 << 6))
+ {
+ reg.H = val;
+ return reg;
+ }
switch(size)
{
case 1:
@@ -117,18 +120,20 @@ namespace X86ISA
return reg;
}
- inline uint64_t pick(uint64_t from, int size)
+ inline uint64_t pick(uint64_t from, int idx, int size) const
{
- X86IntReg reg;
- reg = from;
+ X86IntReg reg = from;
+ DPRINTF(X86, "Picking with size %d\n", size);
+ if(_srcRegIdx[idx] & (1 << 6))
+ return reg.H;
switch(size)
{
case 1:
return reg.L;
case 2:
- return reg.E;
- case 4:
return reg.X;
+ case 4:
+ return reg.E;
case 8:
return reg.R;
default:
diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa
index 43fee5fef..fb082f683 100644
--- a/src/arch/x86/isa/bitfields.isa
+++ b/src/arch/x86/isa/bitfields.isa
@@ -60,6 +60,7 @@
//REX prefix
def bitfield REX rex;
+def bitfield REX_PRESENT rex.present;
def bitfield REX_W rex.w;
def bitfield REX_R rex.r;
def bitfield REX_X rex.x;
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 3b51f9d73..7c627b0c2 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -395,7 +395,7 @@
}
0x19: decode OPCODE_OP_BOTTOM3 {
0x0: enter_Iw_Ib();
- 0x1: leave();
+ 0x1: Inst::LEAVE();
0x2: ret_far_Iw();
0x3: ret_far();
0x4: int3();
@@ -470,16 +470,7 @@
}
0x7: xlat();
}
- 0x1B: decode OPCODE_OP_BOTTOM3 {
- 0x0: esc0();
- 0x1: esc1();
- 0x2: esc2();
- 0x3: esc3();
- 0x4: esc4();
- 0x5: esc5();
- 0x6: esc6();
- 0x7: esc7();
- }
+ ##include "x87.isa"
0x1C: decode OPCODE_OP_BOTTOM3 {
0x0: loopne_Jb();
0x1: loope_Jb();
@@ -519,9 +510,10 @@
0x1: Inst::TEST(Eb,Iz);
0x2: Inst::NOT(Eb);
0x3: Inst::NEG(Eb);
- 0x4: mul_Eb();
- 0x5: imul_Eb();
- 0x6: div_Eb();
+ 0x4: Inst::MUL_B(Eb);
+ 0x5: Inst::IMUL_B(Eb);
+ //This should be Eb, but it access the entire word value ax.
+ 0x6: Inst::DIV_B(Ew);
0x7: idiv_Eb();
}
//0x7: group3_Ev();
@@ -530,9 +522,9 @@
0x1: Inst::TEST(Ev,Iz);
0x2: Inst::NOT(Ev);
0x3: Inst::NEG(Ev);
- 0x4: mul_Ev();
- 0x5: imul_Ev();
- 0x6: div_Ev();
+ 0x4: Inst::MUL(Ev);
+ 0x5: Inst::IMUL(Ev);
+ 0x6: Inst::DIV(Ev);
0x7: idiv_Ev();
}
}
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index da4c82afa..a8c4e7062 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -311,7 +311,7 @@
0x14: decode OPCODE_OP_BOTTOM3 {
0x0: push_fs();
0x1: pop_fs();
- 0x2: cpuid();
+ 0x2: Inst::CPUID(rAd);
0x3: bt_Ev_Gv();
0x4: shld_Ev_Gv_Ib();
0x5: shld_Ev_Gv_rCl();
diff --git a/src/arch/x86/isa/decoder/x87.isa b/src/arch/x86/isa/decoder/x87.isa
new file mode 100644
index 000000000..f16647fe5
--- /dev/null
+++ b/src/arch/x86/isa/decoder/x87.isa
@@ -0,0 +1,346 @@
+// 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
+
+0x1B: decode OPCODE_OP_BOTTOM3 {
+ //0x0: esc0();
+ 0x0: decode MODRM_REG {
+ 0x0: fadd();
+ 0x1: fmul();
+ 0x2: fcom();
+ 0x3: fcomp();
+ 0x4: fsub();
+ 0x5: fsubr();
+ 0x6: fdiv();
+ 0x7: fdivr();
+ }
+ //0x1: esc1();
+ 0x1: decode MODRM_REG {
+ 0x0: fld();
+ 0x1: decode MODRM_MOD {
+ 0x3: fxch();
+ default: Inst::UD2();
+ }
+ 0x2: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x0: fnop();
+ default: Inst::UD2();
+ }
+ default: fst();
+ }
+ 0x3: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fstp();
+ }
+ 0x4: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x0: fchs();
+ 0x1: fabs();
+ 0x4: ftst();
+ 0x5: fxam();
+ default: Inst::UD2();
+ }
+ default: fldenv();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x0: fld1();
+ 0x1: fldl2t();
+ 0x2: fldl2e();
+ 0x3: fldpi();
+ 0x4: fldlg2();
+ 0x5: fldln2();
+ 0x6: fldz();
+ }
+ default: fldcw();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x0: f2xm1();
+ 0x1: fyl2x();
+ 0x2: fptan();
+ 0x3: fpatan();
+ 0x4: fxtract();
+ 0x5: fprem1();
+ 0x6: fdecstp();
+ 0x7: fincstp();
+ }
+ default: fnstenv();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x0: fprem();
+ 0x1: fyl2xp1();
+ 0x2: fsqrt();
+ 0x3: fsincos();
+ 0x4: frndint();
+ 0x5: fscale();
+ 0x6: fsin();
+ 0x7: fcos();
+ }
+ default: fnstcw();
+ }
+ }
+ //0x2: esc2();
+ 0x2: decode MODRM_REG {
+ 0x0: decode MODRM_MOD {
+ 0x3: fcmovb();
+ default: fiadd();
+ }
+ 0x1: decode MODRM_MOD {
+ 0x3: fcmove();
+ default: fimul();
+ }
+ 0x2: decode MODRM_MOD {
+ 0x3: fcmovbe();
+ default: ficom();
+ }
+ 0x3: decode MODRM_MOD {
+ 0x3: fcmovu();
+ default: ficomp();
+ }
+ 0x4: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fisub();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x1: fucompp();
+ default: Inst::UD2();
+ }
+ default: fisubr();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fidiv();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fidivr();
+ }
+ }
+ //0x3: esc3();
+ 0x3: decode MODRM_REG {
+ 0x0: decode MODRM_MOD {
+ 0x3: fcmovnb();
+ default: fild();
+ }
+ 0x1: decode MODRM_MOD {
+ 0x3: fcmovne();
+ default: fisttp();
+ }
+ 0x2: decode MODRM_MOD {
+ 0x3: fcmovnbe();
+ default: fist();
+ }
+ 0x3: decode MODRM_MOD {
+ 0x3: fcmovnu();
+ default: fistp();
+ }
+ 0x4: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x2: fnclex();
+ 0x3: fninit();
+ default: Inst::UD2();
+ }
+ default: Inst::UD2();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: fucomi();
+ default: fld();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: fcomi();
+ default: Inst::UD2();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fstp();
+ }
+ }
+ //0x4: esc4();
+ 0x4: decode MODRM_REG {
+ 0x0: fadd();
+ 0x1: fmul();
+ 0x2: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fcom();
+ }
+ 0x3: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fcomp();
+ }
+ 0x4: decode MODRM_MOD {
+ 0x3: fsubr();
+ default: fsub();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: fsub();
+ default: fsubr();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: fdivr();
+ default: fdiv();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: fdiv();
+ default: fdivr();
+ }
+ }
+ //0x5: esc5();
+ 0x5: decode MODRM_REG {
+ 0x0: decode MODRM_MOD {
+ 0x3: ffree();
+ default: fld();
+ }
+ 0x1: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fisttp();
+ }
+ 0x2: fst();
+ 0x3: fstp();
+ 0x4: decode MODRM_MOD {
+ 0x3: fucom();
+ default: frstor();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: fucomp();
+ default: Inst::UD2();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fnsave();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fnstsw();
+ }
+ }
+ //0x6: esc6();
+ 0x6: decode MODRM_REG {
+ 0x0: decode MODRM_MOD {
+ 0x3: faddp();
+ default: fiadd();
+ }
+ 0x1: decode MODRM_MOD {
+ 0x3: fmulp();
+ default: fimul();
+ }
+ 0x2: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: ficom();
+ }
+ 0x3: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x1: fcompp();
+ default: Inst::UD2();
+ }
+ default: ficomp();
+ }
+ 0x4: decode MODRM_MOD {
+ 0x3: fsubrp();
+ default: fisub();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: fsubp();
+ default: fisubr();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: fdivrp();
+ default: fidiv();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: fdivp();
+ default: fidivr();
+ }
+ }
+ //0x7: esc7();
+ 0x7: decode MODRM_REG {
+ 0x0: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fild();
+ }
+ 0x1: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fisttp();
+ }
+ 0x2: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fist();
+ }
+ 0x3: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fistp();
+ }
+ 0x4: decode MODRM_MOD {
+ 0x3: decode MODRM_RM {
+ 0x0: fnstsw();
+ default: Inst::UD2();
+ }
+ default: fbld();
+ }
+ 0x5: decode MODRM_MOD {
+ 0x3: fucomip();
+ default: fild();
+ }
+ 0x6: decode MODRM_MOD {
+ 0x3: fcomip();
+ default: fbstp();
+ }
+ 0x7: decode MODRM_MOD {
+ 0x3: Inst::UD2();
+ default: fistp();
+ }
+ }
+}
diff --git a/src/arch/x86/isa/formats/syscall.isa b/src/arch/x86/isa/formats/syscall.isa
index 8b860dba4..2f88c8d23 100644
--- a/src/arch/x86/isa/formats/syscall.isa
+++ b/src/arch/x86/isa/formats/syscall.isa
@@ -65,6 +65,7 @@ output header {{
class SyscallInst : public X86ISA::X86StaticInst
{
public:
+ static const RegIndex foldOBit = 0;
/// Constructor
SyscallInst(const char *_mnemonic, ExtMachInst _machInst,
OpClass __opClass) :
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 7e5578a3c..de4996f54 100644
--- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
+++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
@@ -56,20 +56,20 @@
microcode = '''
def macroop ADD_R_R
{
- add reg, reg, regm
+ add reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop ADD_R_I
{
limm t1, imm
- add reg, reg, t1
+ add reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop ADD_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
- add t1, t1, t2
+ add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -78,14 +78,14 @@ def macroop ADD_P_I
rdip t7
limm t2, imm
ld t1, ds, [0, t0, t7], disp
- add t1, t1, t2
+ add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop ADD_M_R
{
ld t1, ds, [scale, index, base], disp
- add t1, t1, reg
+ add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -93,52 +93,52 @@ def macroop ADD_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- add t1, t1, reg
+ add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop ADD_R_M
{
ld t1, ds, [scale, index, base], disp
- add reg, reg, t1
+ add reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop ADD_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- add reg, reg, t1
+ add reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SUB_R_R
{
- sub reg, reg, regm
+ sub reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SUB_R_I
{
limm t1, imm
- sub reg, reg, t1
+ sub reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SUB_R_M
{
ld t1, ds, [scale, index, base], disp
- sub reg, reg, t1
+ sub reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SUB_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- sub reg, reg, t1
+ sub reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SUB_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
- sub t1, t1, t2
+ sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -147,14 +147,14 @@ def macroop SUB_P_I
rdip t7
limm t2, imm
ld t1, ds, [0, t0, t7], disp
- sub t1, t1, t2
+ sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop SUB_M_R
{
ld t1, ds, [scale, index, base], disp
- sub t1, t1, reg
+ sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -162,26 +162,26 @@ def macroop SUB_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- sub t1, t1, reg
+ sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop ADC_R_R
{
- adc reg, reg, regm
+ adc reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop ADC_R_I
{
limm t1, imm
- adc reg, reg, t1
+ adc reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop ADC_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
- adc t1, t1, t2
+ adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -190,14 +190,14 @@ def macroop ADC_P_I
rdip t7
limm t2, imm
ld t1, ds, [0, t0, t7], disp
- adc t1, t1, t2
+ adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop ADC_M_R
{
ld t1, ds, [scale, index, base], disp
- adc t1, t1, reg
+ adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -205,52 +205,52 @@ def macroop ADC_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- adc t1, t1, reg
+ adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop ADC_R_M
{
ld t1, ds, [scale, index, base], disp
- adc reg, reg, t1
+ adc reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop ADC_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- adc reg, reg, t1
+ adc reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SBB_R_R
{
- sbb reg, reg, regm
+ sbb reg, reg, regm, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SBB_R_I
{
limm t1, imm
- sbb reg, reg, t1
+ sbb reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SBB_R_M
{
ld t1, ds, [scale, index, base], disp
- sbb reg, reg, t1
+ sbb reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SBB_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- sbb reg, reg, t1
+ sbb reg, reg, t1, flags=(OF,SF,ZF,AF,PF,CF)
};
def macroop SBB_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
- sbb t1, t1, t2
+ sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -259,14 +259,14 @@ def macroop SBB_P_I
rdip t7
limm t2, imm
ld t1, ds, [0, t0, t7], disp
- sbb t1, t1, t2
+ sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop SBB_M_R
{
ld t1, ds, [scale, index, base], disp
- sbb t1, t1, reg
+ sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -274,7 +274,7 @@ def macroop SBB_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- sbb t1, t1, reg
+ sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
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 339e18cf8..5355775eb 100644
--- a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
+++ b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
@@ -56,39 +56,137 @@
microcode = '''
#
+# Byte version of one operand unsigned multiply.
+#
+
+def macroop MUL_B_R
+{
+ mul1u rax, rax, reg, dataSize="2"
+};
+
+def macroop MUL_B_M
+{
+ ld t1, ds, [scale, index, base], disp
+ mul1u rax, rax, t1, dataSize="2"
+};
+
+def macroop MUL_B_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ mul1u rax, rax, t1, dataSize="2"
+};
+
+#
+# One operand unsigned multiply.
+#
+
+def macroop MUL_R
+{
+ muleh rdx, rax, reg
+ mulel rax, rax, reg
+};
+
+def macroop MUL_M
+{
+ ld t1, ds, [scale, index, base], disp
+ muleh rdx, rax, t1
+ mulel rax, rax, t1
+};
+
+def macroop MUL_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ muleh rdx, rax, t1
+ mulel rax, rax, t1
+};
+
+#
+# Byte version of one operand signed multiply.
+#
+
+def macroop IMUL_B_R
+{
+ mul1s rax, rax, reg, dataSize="2"
+};
+
+def macroop IMUL_B_M
+{
+ ld t1, ds, [scale, index, base], disp
+ mul1s rax, rax, t1, dataSize="2"
+};
+
+def macroop IMUL_B_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ mul1s rax, rax, t1, dataSize="2"
+};
+
+#
+# One operand signed multiply.
+#
+
+def macroop IMUL_R
+{
+ muleh rdx, rax, reg
+ mulel rax, rax, reg
+};
+
+def macroop IMUL_M
+{
+ ld t1, ds, [scale, index, base], disp
+ muleh rdx, rax, t1
+ mulel rax, rax, t1
+};
+
+def macroop IMUL_P
+{
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ muleh rdx, rax, t1
+ mulel rax, rax, t1
+};
+
+#
# 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
+ mulel reg, reg, regm
};
def macroop IMUL_R_M
{
ld t1, ds, [scale, index, base], disp
- mul1s reg, reg, t1
+ mulel reg, reg, t1
};
def macroop IMUL_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
- mul1s reg, reg, t1
+ mulel reg, reg, t1
};
+#
+# Three operand signed multiply.
+#
+
def macroop IMUL_R_R_I
{
limm t1, imm
- mul1s reg, regm, t1
+ mulel reg, regm, t1
};
def macroop IMUL_R_M_I
{
limm t1, imm
ld t2, ds, [scale, index, base], disp
- mul1s reg, t2, t1
+ mulel reg, t2, t1
};
def macroop IMUL_R_P_I
@@ -96,7 +194,54 @@ def macroop IMUL_R_P_I
rdip t7
limm t1, imm
ld t2, ds, [0, t0, t7]
- mul1s reg, t2, t1
+ mulel reg, t2, t1
+};
+
+#
+# One byte version of unsigned division
+#
+
+def macroop DIV_B_R
+{
+ div1 rax, rax, reg
+};
+
+def macroop DIV_B_M
+{
+ ld t1, ds, [scale, index, base], disp
+ div1 rax, rax, t1
+};
+
+def macroop DIV_B_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ div1 rax, rax, t1
+};
+
+#
+# Unsigned division
+#
+
+def macroop DIV_R
+{
+ divr rdx, rax, reg
+ divq rax, rax, reg
+};
+
+def macroop DIV_M
+{
+ ld t1, ds, [scale, index, base], disp
+ divr rdx, rax, t1
+ divq rax, rax, t1
+};
+
+def macroop DIV_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ divr rdx, rax, t1
+ divq rax, rax, t1
};
'''
#let {{
diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py
index 158861a3d..0df84cbe8 100644
--- a/src/arch/x86/isa/insts/control_transfer/jump.py
+++ b/src/arch/x86/isa/insts/control_transfer/jump.py
@@ -226,17 +226,26 @@ def macroop JMP_I
def macroop JMP_R
{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
wripi reg, 0
};
def macroop JMP_M
{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
ld t1, ds, [scale, index, base], disp
wripi t1, 0
};
def macroop JMP_P
{
+ # Make the default data size of jumps 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
rdip t7
ld t1, ds, [0, t0, t7], disp
wripi t1, 0
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 1c13b44b4..082e24485 100644
--- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
@@ -141,6 +141,15 @@ def macroop POPA {
ld rax, ss, [0, t0, rsp], "7 * env.dataSize"
addi rsp, rsp, "8 * env.dataSize"
};
+
+def macroop LEAVE {
+ # Make the default data size of pops 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ mov rsp, rsp, rbp
+ ld rbp, ss, [0, t0, rsp]
+ addi rsp, rsp, dsz
+};
'''
#let {{
# class ENTER(Inst):
diff --git a/src/arch/x86/isa/insts/load_effective_address.py b/src/arch/x86/isa/insts/load_effective_address.py
index dcaf9778e..fc8b17629 100644
--- a/src/arch/x86/isa/insts/load_effective_address.py
+++ b/src/arch/x86/isa/insts/load_effective_address.py
@@ -60,6 +60,6 @@ def macroop LEA_R_M {
def macroop LEA_R_P {
rdip t7
- lea reg, ds, [scale, index, base], disp
+ lea reg, ds, [0, t0, t7], disp
};
'''
diff --git a/src/arch/x86/isa/insts/logical.py b/src/arch/x86/isa/insts/logical.py
index bbc15f8fa..81a4730de 100644
--- a/src/arch/x86/isa/insts/logical.py
+++ b/src/arch/x86/isa/insts/logical.py
@@ -56,14 +56,14 @@
microcode = '''
def macroop OR_R_R
{
- or reg, reg, regm
+ or reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
};
def macroop OR_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
- or t1, t1, t2
+ or t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -72,14 +72,14 @@ def macroop OR_P_I
limm t2, imm
rdip t7
ld t1, ds, [0, t0, t7], disp
- or t1, t1, t2
+ or t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop OR_M_R
{
ld t1, ds, [scale, index, base], disp
- or t1, t1, reg
+ or t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -87,45 +87,45 @@ def macroop OR_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- or t1, t1, reg
+ or t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop OR_R_M
{
ld t1, ds, [scale, index, base], disp
- or reg, reg, t1
+ or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop OR_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
- or reg, reg, t1
+ or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop OR_R_I
{
limm t1, imm
- or reg, reg, t1
+ or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_R_R
{
- xor reg, reg, regm
+ xor reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_R_I
{
limm t1, imm
- xor reg, reg, t1
+ xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
- xor t1, t1, t2
+ xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -134,14 +134,14 @@ def macroop XOR_P_I
limm t2, imm
rdip t7
ld t1, ds, [scale, index, base], disp
- xor t1, t1, t2
+ xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
def macroop XOR_M_R
{
ld t1, ds, [scale, index, base], disp
- xor t1, t1, reg
+ xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -149,52 +149,52 @@ def macroop XOR_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
- xor t1, t1, reg
+ xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
def macroop XOR_R_M
{
ld t1, ds, [scale, index, base], disp
- xor reg, reg, t1
+ xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
- xor reg, reg, t1
+ xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_R
{
- and reg, reg, regm
+ and reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_M
{
ld t1, ds, [scale, index, base], disp
- and reg, reg, t1
+ and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
- and reg, reg, t1
+ and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_I
{
limm t1, imm
- and reg, reg, t1
+ and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_M_I
{
ld t2, ds, [scale, index, base], disp
limm t1, imm
- and t2, t2, t1
+ and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
st t2, ds, [scale, index, base], disp
};
@@ -203,14 +203,14 @@ def macroop AND_P_I
rdip t7
ld t2, ds, [scale, index, base], disp
limm t1, imm
- and t2, t2, t1
+ and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
st t2, ds, [scale, index, base], disp
};
def macroop AND_M_R
{
ld t1, ds, [scale, index, base], disp
- and t1, t1, reg
+ and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -218,7 +218,7 @@ def macroop AND_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
- and t1, t1, reg
+ and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
diff --git a/src/arch/x86/isa/insts/processor_information.py b/src/arch/x86/isa/insts/processor_information.py
index b9c8a407e..f7ef4db98 100644
--- a/src/arch/x86/isa/insts/processor_information.py
+++ b/src/arch/x86/isa/insts/processor_information.py
@@ -53,7 +53,20 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop CPUID_R {
+ #
+ # For now, the CPUID function number will be hard wired to 0x8000_0000.
+ # Getting it to work more robustly will likely require microcode branching
+ # which probably doesn't work at the moment.
+ #
+
+ limm rax, 0x80000018, dataSize=4
+ limm rbx, 0x68747541, dataSize=4
+ limm rdx, 0x69746e65, dataSize=4
+ limm rcx, 0x444d4163, dataSize=4
+};
+'''
#let {{
# class CPUID(Inst):
# "GenFault ${new UnimpInstFault}"
diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa
index ec68c36dc..c357c1d6c 100644
--- a/src/arch/x86/isa/microops/limmop.isa
+++ b/src/arch/x86/isa/microops/limmop.isa
@@ -78,6 +78,7 @@ def template MicroLimmOpDeclare {{
const RegIndex dest;
const uint64_t imm;
const uint8_t dataSize;
+ RegIndex foldOBit;
void buildMe();
std::string generateDisassembly(Addr pc,
@@ -104,7 +105,7 @@ def template MicroLimmOpDisassembly {{
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest, dataSize);
+ printDestReg(response, 0, dataSize);
response << ", ";
ccprintf(response, "%#x", imm);
return response.str();
@@ -115,6 +116,7 @@ def template MicroLimmOpConstructor {{
inline void %(class_name)s::buildMe()
{
+ foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
%(constructor)s;
}
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index bb34df7df..3c562efc0 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -65,6 +65,7 @@ def template MicroRegOpExecute {{
{
Fault fault = NoFault;
+ DPRINTF(X86, "The data size is %d\n", dataSize);
%(op_decl)s;
%(op_rd)s;
@@ -326,12 +327,32 @@ let {{
checkCCFlagBits = "checkCondition(ccFlagBits)"
- genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
+ genCCFlagBits = \
+ "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);"
+ genCCFlagBitsSub = \
+ "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);"
+ genCCFlagBitsLogic = '''
+ //Don't have genFlags handle the OF or CF bits
+ uint64_t mask = CFBit | OFBit;
+ ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2);
+ //If a logic microop wants to set these, it wants to set them to 0.
+ ccFlagBits &= ~(CFBit & ext);
+ ccFlagBits &= ~(OFBit & ext);
+ '''
+
+ regPick = '''
+ IntReg psrc1 = pick(SrcReg1, 0, dataSize);
+ IntReg psrc2 = pick(SrcReg2, 1, dataSize);
+ '''
+ immPick = '''
+ IntReg psrc1 = pick(SrcReg1, 0, dataSize);
+ '''
# 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=";"):
+ def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
+ cc=False, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@@ -339,47 +360,47 @@ let {{
# of the code, one with an integer operand, and one with an immediate
# operand.
matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
- regCode = matcher.sub("SrcReg2", code)
- immCode = matcher.sub("imm8", code)
-
- if subtract:
- secondSrc = "~op2, true"
- else:
- secondSrc = "op2"
+ regCode = regPick + matcher.sub("psrc2", code)
+ immCode = immPick + matcher.sub("imm8", code)
if not cc:
- flagCode = genCCFlagBits % secondSrc
condCode = "true"
else:
flagCode = ""
condCode = checkCCFlagBits
- regFlagCode = matcher.sub("SrcReg2", flagCode)
+ regFlagCode = matcher.sub("psrc2", flagCode)
immFlagCode = matcher.sub("imm8", flagCode)
class RegOpChild(RegOp):
mnemonic = name
className = Name
- def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
- super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize)
+ 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, "X86ISA::RegOp", regCode);
- setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
- flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
+ setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp",
+ regCode, flagCode=regFlagCode,
+ condCheck=condCode, elseCode=elseCode);
class RegOpChildImm(RegOpImm):
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)
+ 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);
+ 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, elseCode=";"):
@@ -390,8 +411,8 @@ let {{
# of the code, one with an integer operand, and one with an immediate
# operand.
matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
- regCode = matcher.sub("SrcReg2", code)
- immCode = matcher.sub("imm8", code)
+ regCode = regPick + matcher.sub("psrc2", code)
+ immCode = immPick + matcher.sub("imm8", code)
class RegOpChild(RegOp):
mnemonic = name
@@ -435,6 +456,7 @@ let {{
def defineMicroRegOpImm(mnemonic, code):
Name = mnemonic
name = mnemonic.lower()
+ code = immPick + code
class RegOpChild(RegOpImm):
def __init__(self, dest, src1, src2, dataSize="env.dataSize"):
@@ -446,28 +468,76 @@ let {{
setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
- defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
- defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
+ defineMicroRegOp('Add', 'DestReg = merge(DestReg, psrc1 + op2, dataSize)')
+ defineMicroRegOp('Or', 'DestReg = merge(DestReg, psrc1 | op2, dataSize);',
+ flagCode = genCCFlagBitsLogic)
defineMicroRegOp('Adc', '''
CCFlagBits flags = ccFlagBits;
- DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
+ DestReg = merge(DestReg, psrc1 + 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)',
+ DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize);
+ ''', flagCode = genCCFlagBitsSub)
+ defineMicroRegOp('And', \
+ 'DestReg = merge(DestReg, psrc1 & op2, dataSize)', \
+ flagCode = genCCFlagBitsLogic)
+ defineMicroRegOp('Sub', \
+ 'DestReg = merge(DestReg, psrc1 - op2, dataSize)', \
+ flagCode = genCCFlagBitsSub)
+ defineMicroRegOp('Xor', \
+ 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)', \
+ flagCode = genCCFlagBitsLogic)
+ defineMicroRegOp('Mul1s', '''
+ int signPos = (dataSize * 8) / 2 - 1;
+ IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos);
+ IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos);
+ DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
+ ''')
+ defineMicroRegOp('Mul1u', '''
+ int halfSize = (dataSize * 8) / 2;
+ IntReg srcVal1 = psrc1 & mask(halfSize);
+ IntReg srcVal2 = op2 & mask(halfSize);
+ DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
+ ''')
+ defineMicroRegOp('Mulel', \
+ 'DestReg = merge(DestReg, psrc1 * op2, dataSize)')
+ defineMicroRegOp('Muleh', '''
+ int halfSize = (dataSize * 8) / 2;
+ uint64_t psrc1_h = psrc1 >> halfSize;
+ uint64_t psrc1_l = psrc1 & mask(halfSize);
+ uint64_t psrc2_h = op2 >> halfSize;
+ uint64_t psrc2_l = op2 & mask(halfSize);
+ uint64_t result =
+ ((psrc1_l * psrc2_h) >> halfSize) +
+ ((psrc1_h * psrc2_l) >> halfSize) +
+ psrc1_h * psrc2_h;
+ DestReg = merge(DestReg, result, dataSize);
+ ''')
+ defineMicroRegOp('Div1', '''
+ int halfSize = (dataSize * 8) / 2;
+ IntReg quotient = (psrc1 / op2) & mask(halfSize);
+ IntReg remainder = (psrc1 % op2) & mask(halfSize);
+ IntReg result = quotient | (remainder << halfSize);
+ DestReg = merge(DestReg, result, dataSize);
+ ''')
+ defineMicroRegOp('Divq', '''
+ DestReg = merge(DestReg, psrc1 / op2, dataSize);
+ ''')
+ defineMicroRegOp('Divr', '''
+ DestReg = merge(DestReg, psrc1 % op2, dataSize);
+ ''')
+
+ #
+ # HACK HACK HACK HACK - Put psrc1 in here but make it inert to shut up gcc.
+ #
+ defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, psrc1 * 0 + op2, dataSize)',
elseCode='DestReg=DestReg;', cc=True)
# Shift instructions
defineMicroRegOp('Sll', '''
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
- DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
+ DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize);
''')
defineMicroRegOp('Srl', '''
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
@@ -475,7 +545,7 @@ let {{
// 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);
+ DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize);
''')
defineMicroRegOp('Sra', '''
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
@@ -484,15 +554,15 @@ let {{
// them manually to be sure.
uint64_t arithMask =
-bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
- DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
+ DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize);
''')
defineMicroRegOp('Ror', '''
uint8_t shiftAmt =
(op2 & ((dataSize == 8) ? mask(6) : mask(5)));
if(shiftAmt)
{
- uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
- uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+ uint64_t top = psrc1 << (dataSize * 8 - shiftAmt);
+ uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
@@ -506,8 +576,8 @@ let {{
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);
+ top |= psrc1 << (dataSize * 8 - shiftAmt - 1);
+ uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
@@ -518,9 +588,9 @@ let {{
(op2 & ((dataSize == 8) ? mask(6) : mask(5)));
if(shiftAmt)
{
- uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t top = psrc1 << shiftAmt;
uint64_t bottom =
- bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
+ bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
@@ -532,27 +602,27 @@ let {{
if(shiftAmt)
{
CCFlagBits flags = ccFlagBits;
- uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t top = psrc1 << shiftAmt;
uint64_t bottom = flags.CF << (shiftAmt - 1);
if(shiftAmt > 1)
bottom |=
- bits(SrcReg1, dataSize * 8 - 1,
- dataSize * 8 - shiftAmt + 1);
+ bits(psrc1, dataSize * 8 - 1,
+ dataSize * 8 - shiftAmt + 1);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
DestReg = DestReg;
''')
- defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
+ defineMicroRegOpWr('Wrip', 'RIP = psrc1 + op2', elseCode="RIP = RIP;")
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
defineMicroRegOpImm('Sext', '''
- IntReg val = SrcReg1;
+ IntReg val = psrc1;
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);')
+ defineMicroRegOpImm('Zext', 'DestReg = bits(psrc1, imm8-1, 0);')
}};
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index 406c74a1f..eaedbdf17 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -96,13 +96,13 @@ def operand_types {{
}};
def operands {{
- 'DestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 1),
- 'SrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 2),
- 'SrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 3),
- '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),
+ 'SrcReg1': ('IntReg', 'uqw', '(((src1 & 0x1C) == 4 ? foldOBit : 0) | src1)', 'IsInteger', 1),
+ 'SrcReg2': ('IntReg', 'uqw', '(((src2 & 0x1C) == 4 ? foldOBit : 0) | src2)', 'IsInteger', 2),
+ 'Index': ('IntReg', 'uqw', '(((index & 0x1C) == 4 ? foldABit : 0) | index)', 'IsInteger', 3),
+ 'Base': ('IntReg', 'uqw', '(((base & 0x1C) == 4 ? foldABit : 0) | base)', 'IsInteger', 4),
+ 'DestReg': ('IntReg', 'uqw', '(((dest & 0x1C) == 4 ? foldOBit : 0) | dest)', 'IsInteger', 5),
+ 'Data': ('IntReg', 'uqw', '(((data & 0x1C) == 4 ? foldOBit : 0) | 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/specialize.isa b/src/arch/x86/isa/specialize.isa
index a45c6e80f..b5f51ab58 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -149,8 +149,8 @@ let {{
elif opType.tag == "M":
# This refers to memory. The macroop constructor sets up modrm
# addressing. Non memory modrm settings should cause an error.
- Name += "_M"
env.doModRM = True
+ return doRipRelativeDecode(Name, opTypes, env)
elif opType.tag == None or opType.size == None:
raise Exception, "Problem parsing operand tag: %s" % opType.tag
elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"):
diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh
index 63bcfead9..466422ced 100644
--- a/src/arch/x86/isa_traits.hh
+++ b/src/arch/x86/isa_traits.hh
@@ -82,7 +82,7 @@ namespace X86ISA
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
//There are 16 microcode registers at the moment
- FP_Base_DepTag = 32,
+ FP_Base_DepTag = 1 << 7,
Ctrl_Base_DepTag =
FP_Base_DepTag +
//mmx/x87 registers
diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh
index c1bb67260..bde7925a9 100644
--- a/src/arch/x86/linux/linux.hh
+++ b/src/arch/x86/linux/linux.hh
@@ -65,23 +65,25 @@ class X86Linux64 : public Linux
public:
typedef struct {
- uint32_t st_dev;
- char __pad1[4];
+ uint64_t st_dev;
uint64_t st_ino;
+ uint64_t st_nlink;
uint32_t st_mode;
- uint16_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
- uint32_t st_rdev;
- char __pad2[4];
+ uint32_t __pad0;
+ uint64_t st_rdev;
int64_t st_size;
- int64_t st_atimeX;
- int64_t st_mtimeX;
- int64_t st_ctimeX;
int64_t st_blksize;
int64_t st_blocks;
- uint64_t __unused4[2];
- } tgt_stat;
+ uint64_t st_atimeX;
+ uint64_t st_atime_nsec;
+ uint64_t st_mtimeX;
+ uint64_t st_mtime_nsec;
+ uint64_t st_ctimeX;
+ uint64_t st_ctime_nsec;
+ int64_t __unused[3];
+ } tgt_stat64;
static OpenFlagTransTable openFlagTable[];
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
index 5c756ec7f..efbe33dfa 100644
--- a/src/arch/x86/linux/syscalls.cc
+++ b/src/arch/x86/linux/syscalls.cc
@@ -71,7 +71,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
- strcpy(name->release, "2.6.12");
+ strcpy(name->release, "2.6.16.19");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "x86_64");
@@ -81,18 +81,18 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
SyscallDesc X86LinuxProcess::syscallDescs[] = {
- /* 0 */ SyscallDesc("read", unimplementedFunc),
- /* 1 */ SyscallDesc("write", unimplementedFunc),
+ /* 0 */ SyscallDesc("read", readFunc),
+ /* 1 */ SyscallDesc("write", writeFunc),
/* 2 */ SyscallDesc("open", openFunc<X86Linux64>),
- /* 3 */ SyscallDesc("close", unimplementedFunc),
+ /* 3 */ SyscallDesc("close", closeFunc),
/* 4 */ SyscallDesc("stat", unimplementedFunc),
- /* 5 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 5 */ SyscallDesc("fstat", fstat64Func<X86Linux64>),
/* 6 */ SyscallDesc("lstat", unimplementedFunc),
/* 7 */ SyscallDesc("poll", unimplementedFunc),
/* 8 */ SyscallDesc("lseek", unimplementedFunc),
/* 9 */ SyscallDesc("mmap", mmapFunc<X86Linux64>),
/* 10 */ SyscallDesc("mprotect", unimplementedFunc),
- /* 11 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 11 */ SyscallDesc("munmap", munmapFunc),
/* 12 */ SyscallDesc("brk", obreakFunc),
/* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc),
/* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
@@ -141,7 +141,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
/* 57 */ SyscallDesc("fork", unimplementedFunc),
/* 58 */ SyscallDesc("vfork", unimplementedFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
- /* 60 */ SyscallDesc("exit", unimplementedFunc),
+ /* 60 */ SyscallDesc("exit", exitFunc),
/* 61 */ SyscallDesc("wait4", unimplementedFunc),
/* 62 */ SyscallDesc("kill", unimplementedFunc),
/* 63 */ SyscallDesc("uname", unameFunc),
@@ -312,7 +312,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
/* 228 */ SyscallDesc("clock_gettime", unimplementedFunc),
/* 229 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 230 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
- /* 231 */ SyscallDesc("exit_group", unimplementedFunc),
+ /* 231 */ SyscallDesc("exit_group", exitFunc),
/* 232 */ SyscallDesc("epoll_wait", unimplementedFunc),
/* 233 */ SyscallDesc("epoll_ctl", unimplementedFunc),
/* 234 */ SyscallDesc("tgkill", unimplementedFunc),
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 6d30e53e3..036805612 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -127,9 +127,9 @@ X86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile,
// for undertermined purposes.
stack_base = (Addr)0x7FFFFFFFF000ULL;
- // Set up region for mmaps. Tru64 seems to start just above 0 and
- // grow up from there.
- mmap_start = mmap_end = 0xfffff80000000000ULL;
+ // Set up region for mmaps. This was determined empirically and may not
+ // always be correct.
+ mmap_start = mmap_end = 0x2aaaaaaab000;
}
void X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc)
diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc
index f54f531e2..96283cada 100644
--- a/src/arch/x86/regfile.cc
+++ b/src/arch/x86/regfile.cc
@@ -86,6 +86,7 @@
*/
#include "arch/x86/regfile.hh"
+#include "base/trace.hh"
#include "sim/serialize.hh"
#include "cpu/thread_context.hh"
@@ -209,8 +210,12 @@ void RegFile::setIntReg(int intReg, const IntReg &val)
int X86ISA::flattenIntIndex(ThreadContext * tc, int reg)
{
- //For right now, don't do any flattening
- return reg;
+ //If we need to fold over the index to match byte semantics, do that.
+ //Otherwise, just strip off any extra bits and pass it through.
+ if (reg & (1 << 6))
+ return (reg & ~(1 << 6) - 0x4);
+ else
+ return (reg & ~(1 << 6));
}
void RegFile::serialize(std::ostream &os)
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
index a509ff57a..f8a5dbe34 100644
--- a/src/arch/x86/types.hh
+++ b/src/arch/x86/types.hh
@@ -110,6 +110,9 @@ namespace X86ISA
EndBitUnion(Sib)
BitUnion8(Rex)
+ //This bit doesn't mean anything according to the ISA, but in
+ //this implementation, it being set means an REX prefix was present.
+ Bitfield<6> present;
Bitfield<3> w;
Bitfield<2> r;
Bitfield<1> x;