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