emulenv.cc revision 12334
13101Sstever@eecs.umich.edu/*
27534Ssteve.reinhardt@amd.com * Copyright (c) 2007 The Hewlett-Packard Development Company
33101Sstever@eecs.umich.edu * All rights reserved.
43101Sstever@eecs.umich.edu *
53101Sstever@eecs.umich.edu * The license below extends only to copyright in the software and shall
63101Sstever@eecs.umich.edu * not be construed as granting a license to any other intellectual
73101Sstever@eecs.umich.edu * property including but not limited to intellectual property relating
83101Sstever@eecs.umich.edu * to a hardware implementation of the functionality of the software
93101Sstever@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
103101Sstever@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
113101Sstever@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
123101Sstever@eecs.umich.edu * modified or unmodified, in source code or in binary form.
133101Sstever@eecs.umich.edu *
143101Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
153101Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are
163101Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright
173101Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
183101Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
193101Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
203101Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution;
213101Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its
223101Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
233101Sstever@eecs.umich.edu * this software without specific prior written permission.
243101Sstever@eecs.umich.edu *
253101Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
263101Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
273101Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
283101Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
293101Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
303101Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
313101Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
323101Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
333101Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
343101Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
353101Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
363101Sstever@eecs.umich.edu *
373101Sstever@eecs.umich.edu * Authors: Gabe Black
383101Sstever@eecs.umich.edu */
393101Sstever@eecs.umich.edu
403101Sstever@eecs.umich.edu#include "arch/x86/emulenv.hh"
413101Sstever@eecs.umich.edu
423101Sstever@eecs.umich.edu#include <cassert>
433101Sstever@eecs.umich.edu
443101Sstever@eecs.umich.edu#include "base/logging.hh"
453101Sstever@eecs.umich.edu
463101Sstever@eecs.umich.eduusing namespace X86ISA;
473101Sstever@eecs.umich.edu
483885Sbinkertn@umich.eduvoid EmulEnv::doModRM(const ExtMachInst & machInst)
493885Sbinkertn@umich.edu{
504762Snate@binkert.org    assert(machInst.modRM.mod != 3);
513885Sbinkertn@umich.edu    //Use the SIB byte for addressing if the modrm byte calls for it.
523885Sbinkertn@umich.edu    if (machInst.modRM.rm == 4 && machInst.addrSize != 2) {
537528Ssteve.reinhardt@amd.com        scale = 1 << machInst.sib.scale;
543885Sbinkertn@umich.edu        index = machInst.sib.index | (machInst.rex.x << 3);
554380Sbinkertn@umich.edu        base = machInst.sib.base | (machInst.rex.b << 3);
564167Sbinkertn@umich.edu        //In this special case, we don't use a base. The displacement also
573102Sstever@eecs.umich.edu        //changes, but that's managed by the decoder.
583101Sstever@eecs.umich.edu        if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0)
594762Snate@binkert.org            base = NUM_INTREGS;
604762Snate@binkert.org        //In -this- special case, we don't use an index.
614762Snate@binkert.org        if (index == INTREG_RSP)
624762Snate@binkert.org            index = NUM_INTREGS;
634762Snate@binkert.org    } else {
644762Snate@binkert.org        if (machInst.addrSize == 2) {
654762Snate@binkert.org            unsigned rm = machInst.modRM.rm;
664762Snate@binkert.org            if (rm <= 3) {
674762Snate@binkert.org                scale = 1;
685033Smilesck@eecs.umich.edu                if (rm < 2) {
695033Smilesck@eecs.umich.edu                    base = INTREG_RBX;
705033Smilesck@eecs.umich.edu                } else {
715033Smilesck@eecs.umich.edu                    base = INTREG_RBP;
725033Smilesck@eecs.umich.edu                }
735033Smilesck@eecs.umich.edu                index = (rm % 2) ? INTREG_RDI : INTREG_RSI;
745033Smilesck@eecs.umich.edu            } else {
755033Smilesck@eecs.umich.edu                scale = 0;
765033Smilesck@eecs.umich.edu                switch (rm) {
775033Smilesck@eecs.umich.edu                  case 4:
783101Sstever@eecs.umich.edu                    base = INTREG_RSI;
793101Sstever@eecs.umich.edu                    break;
803101Sstever@eecs.umich.edu                  case 5:
815033Smilesck@eecs.umich.edu                    base = INTREG_RDI;
823101Sstever@eecs.umich.edu                    break;
837673Snate@binkert.org                  case 6:
847673Snate@binkert.org                    base = INTREG_RBP;
857673Snate@binkert.org                    break;
867673Snate@binkert.org                  case 7:
877673Snate@binkert.org                    base = INTREG_RBX;
887673Snate@binkert.org                    break;
897673Snate@binkert.org                }
903101Sstever@eecs.umich.edu            }
913101Sstever@eecs.umich.edu        } else {
923101Sstever@eecs.umich.edu            scale = 0;
933101Sstever@eecs.umich.edu            base = machInst.modRM.rm | (machInst.rex.b << 3);
943101Sstever@eecs.umich.edu            if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
953101Sstever@eecs.umich.edu                //Since we need to use a different encoding of this
963101Sstever@eecs.umich.edu                //instruction anyway, just ignore the base in those cases
973101Sstever@eecs.umich.edu                base = NUM_INTREGS;
983101Sstever@eecs.umich.edu            }
993101Sstever@eecs.umich.edu        }
1003101Sstever@eecs.umich.edu    }
1013101Sstever@eecs.umich.edu    //Figure out what segment to use. This won't be entirely accurate since
1023101Sstever@eecs.umich.edu    //the presence of a displacement is supposed to make the instruction
1036656Snate@binkert.org    //default to the data segment.
1046656Snate@binkert.org    if ((base != INTREG_RBP && base != INTREG_RSP) || machInst.dispSize) {
1053101Sstever@eecs.umich.edu        seg = SEGMENT_REG_DS;
1063101Sstever@eecs.umich.edu        //Handle any segment override that might have been in the instruction
1073101Sstever@eecs.umich.edu        int segFromInst = machInst.legacy.seg;
1083101Sstever@eecs.umich.edu        if (segFromInst)
1093101Sstever@eecs.umich.edu            seg = (SegmentRegIndex)(segFromInst - 1);
1103101Sstever@eecs.umich.edu    } else {
1113101Sstever@eecs.umich.edu        seg = SEGMENT_REG_SS;
1123101Sstever@eecs.umich.edu    }
1133101Sstever@eecs.umich.edu}
1143101Sstever@eecs.umich.edu
1153101Sstever@eecs.umich.eduvoid EmulEnv::setSeg(const ExtMachInst & machInst)
1163101Sstever@eecs.umich.edu{
1173101Sstever@eecs.umich.edu    seg = SEGMENT_REG_DS;
1183101Sstever@eecs.umich.edu    //Handle any segment override that might have been in the instruction
1193101Sstever@eecs.umich.edu    int segFromInst = machInst.legacy.seg;
1203101Sstever@eecs.umich.edu    if (segFromInst)
1213101Sstever@eecs.umich.edu        seg = (SegmentRegIndex)(segFromInst - 1);
1223101Sstever@eecs.umich.edu}
1233101Sstever@eecs.umich.edu