diff options
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r-- | src/arch/x86/isa/bitfields.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/one_byte_opcodes.isa | 26 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/x87.isa | 346 | ||||
-rw-r--r-- | src/arch/x86/isa/formats/syscall.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/arithmetic/add_and_subtract.py | 64 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py | 157 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/control_transfer/jump.py | 9 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/data_transfer/stack_operations.py | 9 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/load_effective_address.py | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/logical.py | 48 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/processor_information.py | 15 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/limmop.isa | 4 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 164 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 14 | ||||
-rw-r--r-- | src/arch/x86/isa/specialize.isa | 2 |
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"): |