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/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
16 files changed, 726 insertions, 138 deletions
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"):