emulenv.cc revision 6437
14486Sbinkertn@umich.edu/*
24486Sbinkertn@umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
34486Sbinkertn@umich.edu * All rights reserved.
44486Sbinkertn@umich.edu *
54486Sbinkertn@umich.edu * Redistribution and use of this software in source and binary forms,
64486Sbinkertn@umich.edu * with or without modification, are permitted provided that the
74486Sbinkertn@umich.edu * following conditions are met:
84486Sbinkertn@umich.edu *
94486Sbinkertn@umich.edu * The software must be used only for Non-Commercial Use which means any
104486Sbinkertn@umich.edu * use which is NOT directed to receiving any direct monetary
114486Sbinkertn@umich.edu * compensation for, or commercial advantage from such use.  Illustrative
124486Sbinkertn@umich.edu * examples of non-commercial use are academic research, personal study,
134486Sbinkertn@umich.edu * teaching, education and corporate research & development.
144486Sbinkertn@umich.edu * Illustrative examples of commercial use are distributing products for
154486Sbinkertn@umich.edu * commercial advantage and providing services using the software for
164486Sbinkertn@umich.edu * commercial advantage.
174486Sbinkertn@umich.edu *
184486Sbinkertn@umich.edu * If you wish to use this software or functionality therein that may be
194486Sbinkertn@umich.edu * covered by patents for commercial use, please contact:
204486Sbinkertn@umich.edu *     Director of Intellectual Property Licensing
214486Sbinkertn@umich.edu *     Office of Strategy and Technology
224486Sbinkertn@umich.edu *     Hewlett-Packard Company
234486Sbinkertn@umich.edu *     1501 Page Mill Road
244486Sbinkertn@umich.edu *     Palo Alto, California  94304
254486Sbinkertn@umich.edu *
264486Sbinkertn@umich.edu * Redistributions of source code must retain the above copyright notice,
274486Sbinkertn@umich.edu * this list of conditions and the following disclaimer.  Redistributions
284486Sbinkertn@umich.edu * in binary form must reproduce the above copyright notice, this list of
293102SN/A * conditions and the following disclaimer in the documentation and/or
303102SN/A * other materials provided with the distribution.  Neither the name of
312667SN/A * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
321681SN/A * contributors may be used to endorse or promote products derived from
333223SN/A * this software without specific prior written permission.  No right of
341681SN/A * sublicense is granted herewith.  Derivatives of the software and
354486Sbinkertn@umich.edu * output created using the software may be prepared, but only for
364486Sbinkertn@umich.edu * Non-Commercial Uses.  Derivatives of the software may be shared with
374486Sbinkertn@umich.edu * others provided: (i) the others agree to abide by the list of
382817SN/A * conditions herein which includes the Non-Commercial Use restrictions;
392817SN/A * and (ii) such Derivatives of the software include the above copyright
402932SN/A * notice to acknowledge the contribution from this software where
412932SN/A * applicable, this list of conditions and the disclaimer below.
421681SN/A *
432362SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
442362SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
452932SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
462932SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
472932SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
483223SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
493223SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
502932SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
512932SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
522932SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
533223SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
543223SN/A *
552932SN/A * Authors: Gabe Black
562932SN/A */
572318SN/A
582294SN/A#include <cassert>
592871SN/A
602871SN/A#include "arch/x86/emulenv.hh"
612998SN/A#include "base/misc.hh"
621681SN/A
632932SN/Ausing namespace X86ISA;
642932SN/A
652932SN/Avoid EmulEnv::doModRM(const ExtMachInst & machInst)
662932SN/A{
672932SN/A    assert(machInst.modRM.mod != 3);
682932SN/A    //Use the SIB byte for addressing if the modrm byte calls for it.
692932SN/A    if (machInst.modRM.rm == 4 && machInst.addrSize != 2) {
702932SN/A        scale = 1 << machInst.sib.scale;
712932SN/A        index = machInst.sib.index | (machInst.rex.x << 3);
721681SN/A        base = machInst.sib.base | (machInst.rex.b << 3);
732932SN/A        //In this special case, we don't use a base. The displacement also
742932SN/A        //changes, but that's managed by the predecoder.
752932SN/A        if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0)
761681SN/A            base = NUM_INTREGS;
772932SN/A        //In -this- special case, we don't use an index.
781681SN/A        if (index == INTREG_RSP)
792932SN/A            index = NUM_INTREGS;
802932SN/A    } else {
812932SN/A        if (machInst.addrSize == 2) {
821681SN/A            unsigned rm = machInst.modRM.rm;
832932SN/A            if (rm <= 3) {
842932SN/A                scale = 1;
852932SN/A                if (rm < 2) {
862932SN/A                    base = INTREG_RBX;
872932SN/A                } else {
882932SN/A                    base = INTREG_RBP;
892932SN/A                }
902932SN/A                index = (rm % 2) ? INTREG_RDI : INTREG_RSI;
912932SN/A            } else {
922932SN/A                scale = 0;
933223SN/A                switch (rm) {
942932SN/A                  case 4:
952932SN/A                    base = INTREG_RSI;
961681SN/A                    break;
972932SN/A                  case 5:
982932SN/A                    base = INTREG_RDI;
992932SN/A                    break;
1002932SN/A                  case 6:
1012932SN/A                    base = INTREG_RBP;
1021681SN/A                    break;
1032932SN/A                  case 7:
1042932SN/A                    base = INTREG_RBX;
1051681SN/A                    break;
1062932SN/A                }
1072932SN/A            }
1082932SN/A        } else {
1092932SN/A            scale = 0;
1102932SN/A            base = machInst.modRM.rm | (machInst.rex.b << 3);
1112932SN/A            if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
1122932SN/A                //Since we need to use a different encoding of this
1133223SN/A                //instruction anyway, just ignore the base in those cases
1142932SN/A                base = NUM_INTREGS;
1152932SN/A            }
1161681SN/A        }
1172932SN/A    }
1182932SN/A    //Figure out what segment to use. This won't be entirely accurate since
1192873SN/A    //the presence of a displacement is supposed to make the instruction
1202932SN/A    //default to the data segment.
1211681SN/A    if ((base != INTREG_RBP && base != INTREG_RSP) || machInst.dispSize) {
1222932SN/A        seg = SEGMENT_REG_DS;
1232932SN/A        //Handle any segment override that might have been in the instruction
1242932SN/A        int segFromInst = machInst.legacy.seg;
1252932SN/A        if (segFromInst)
1261681SN/A            seg = (SegmentRegIndex)(segFromInst - 1);
1272932SN/A    } else {
1281681SN/A        seg = SEGMENT_REG_SS;
1292932SN/A    }
1302932SN/A}
1312932SN/A
1322932SN/Avoid EmulEnv::setSeg(const ExtMachInst & machInst)
1332932SN/A{
1341681SN/A    seg = SEGMENT_REG_DS;
1352932SN/A    //Handle any segment override that might have been in the instruction
1361681SN/A    int segFromInst = machInst.legacy.seg;
1371681SN/A    if (segFromInst)
1381681SN/A        seg = (SegmentRegIndex)(segFromInst - 1);
1392294SN/A}
1402294SN/A