diff options
Diffstat (limited to 'src/arch/x86')
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; |