decoder.cc revision 9023
19022Sgblack@eecs.umich.edu/* 29023Sgblack@eecs.umich.edu * Copyright (c) 2012 Google 39022Sgblack@eecs.umich.edu * All rights reserved. 49022Sgblack@eecs.umich.edu * 59022Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 69022Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 79022Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 89022Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 99022Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 109022Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 119022Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 129022Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 139022Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 149022Sgblack@eecs.umich.edu * this software without specific prior written permission. 159022Sgblack@eecs.umich.edu * 169022Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179022Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189022Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199022Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209022Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219022Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229022Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239022Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249022Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259022Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269022Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279022Sgblack@eecs.umich.edu * 289022Sgblack@eecs.umich.edu * Authors: Gabe Black 299022Sgblack@eecs.umich.edu */ 309022Sgblack@eecs.umich.edu 319022Sgblack@eecs.umich.edu#include "arch/arm/decoder.hh" 329023Sgblack@eecs.umich.edu#include "arch/arm/isa_traits.hh" 339023Sgblack@eecs.umich.edu#include "arch/arm/utility.hh" 349023Sgblack@eecs.umich.edu#include "base/trace.hh" 359023Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 369023Sgblack@eecs.umich.edu#include "debug/Decoder.hh" 379022Sgblack@eecs.umich.edu 389022Sgblack@eecs.umich.edunamespace ArmISA 399022Sgblack@eecs.umich.edu{ 409022Sgblack@eecs.umich.edu 419022Sgblack@eecs.umich.eduDecodeCache Decoder::defaultCache; 429022Sgblack@eecs.umich.edu 439023Sgblack@eecs.umich.eduvoid 449023Sgblack@eecs.umich.eduDecoder::process() 459023Sgblack@eecs.umich.edu{ 469023Sgblack@eecs.umich.edu // emi is typically ready, with some caveats below... 479023Sgblack@eecs.umich.edu instDone = true; 489023Sgblack@eecs.umich.edu 499023Sgblack@eecs.umich.edu if (!emi.thumb) { 509023Sgblack@eecs.umich.edu emi.instBits = data; 519023Sgblack@eecs.umich.edu emi.sevenAndFour = bits(data, 7) && bits(data, 4); 529023Sgblack@eecs.umich.edu emi.isMisc = (bits(data, 24, 23) == 0x2 && 539023Sgblack@eecs.umich.edu bits(data, 20) == 0); 549023Sgblack@eecs.umich.edu consumeBytes(4); 559023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Arm inst: %#x.\n", (uint64_t)emi); 569023Sgblack@eecs.umich.edu } else { 579023Sgblack@eecs.umich.edu uint16_t word = (data >> (offset * 8)); 589023Sgblack@eecs.umich.edu if (bigThumb) { 599023Sgblack@eecs.umich.edu // A 32 bit thumb inst is half collected. 609023Sgblack@eecs.umich.edu emi.instBits = emi.instBits | word; 619023Sgblack@eecs.umich.edu bigThumb = false; 629023Sgblack@eecs.umich.edu consumeBytes(2); 639023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Second half of 32 bit Thumb: %#x.\n", 649023Sgblack@eecs.umich.edu emi.instBits); 659023Sgblack@eecs.umich.edu } else { 669023Sgblack@eecs.umich.edu uint16_t highBits = word & 0xF800; 679023Sgblack@eecs.umich.edu if (highBits == 0xE800 || highBits == 0xF000 || 689023Sgblack@eecs.umich.edu highBits == 0xF800) { 699023Sgblack@eecs.umich.edu // The start of a 32 bit thumb inst. 709023Sgblack@eecs.umich.edu emi.bigThumb = 1; 719023Sgblack@eecs.umich.edu if (offset == 0) { 729023Sgblack@eecs.umich.edu // We've got the whole thing. 739023Sgblack@eecs.umich.edu emi.instBits = (data >> 16) | (data << 16); 749023Sgblack@eecs.umich.edu DPRINTF(Decoder, "All of 32 bit Thumb: %#x.\n", 759023Sgblack@eecs.umich.edu emi.instBits); 769023Sgblack@eecs.umich.edu consumeBytes(4); 779023Sgblack@eecs.umich.edu } else { 789023Sgblack@eecs.umich.edu // We only have the first half word. 799023Sgblack@eecs.umich.edu DPRINTF(Decoder, 809023Sgblack@eecs.umich.edu "First half of 32 bit Thumb.\n"); 819023Sgblack@eecs.umich.edu emi.instBits = (uint32_t)word << 16; 829023Sgblack@eecs.umich.edu bigThumb = true; 839023Sgblack@eecs.umich.edu consumeBytes(2); 849023Sgblack@eecs.umich.edu // emi not ready yet. 859023Sgblack@eecs.umich.edu instDone = false; 869023Sgblack@eecs.umich.edu } 879023Sgblack@eecs.umich.edu } else { 889023Sgblack@eecs.umich.edu // A 16 bit thumb inst. 899023Sgblack@eecs.umich.edu consumeBytes(2); 909023Sgblack@eecs.umich.edu emi.instBits = word; 919023Sgblack@eecs.umich.edu // Set the condition code field artificially. 929023Sgblack@eecs.umich.edu emi.condCode = COND_UC; 939023Sgblack@eecs.umich.edu DPRINTF(Decoder, "16 bit Thumb: %#x.\n", 949023Sgblack@eecs.umich.edu emi.instBits); 959023Sgblack@eecs.umich.edu if (bits(word, 15, 8) == 0xbf && 969023Sgblack@eecs.umich.edu bits(word, 3, 0) != 0x0) { 979023Sgblack@eecs.umich.edu foundIt = true; 989023Sgblack@eecs.umich.edu itBits = bits(word, 7, 0); 999023Sgblack@eecs.umich.edu DPRINTF(Decoder, 1009023Sgblack@eecs.umich.edu "IT detected, cond = %#x, mask = %#x\n", 1019023Sgblack@eecs.umich.edu itBits.cond, itBits.mask); 1029023Sgblack@eecs.umich.edu } 1039023Sgblack@eecs.umich.edu } 1049023Sgblack@eecs.umich.edu } 1059023Sgblack@eecs.umich.edu } 1069022Sgblack@eecs.umich.edu} 1079023Sgblack@eecs.umich.edu 1089023Sgblack@eecs.umich.edu//Use this to give data to the decoder. This should be used 1099023Sgblack@eecs.umich.edu//when there is control flow. 1109023Sgblack@eecs.umich.eduvoid 1119023Sgblack@eecs.umich.eduDecoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst) 1129023Sgblack@eecs.umich.edu{ 1139023Sgblack@eecs.umich.edu data = inst; 1149023Sgblack@eecs.umich.edu offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC; 1159023Sgblack@eecs.umich.edu emi.thumb = pc.thumb(); 1169023Sgblack@eecs.umich.edu FPSCR fpscr = tc->readMiscReg(MISCREG_FPSCR); 1179023Sgblack@eecs.umich.edu emi.fpscrLen = fpscr.len; 1189023Sgblack@eecs.umich.edu emi.fpscrStride = fpscr.stride; 1199023Sgblack@eecs.umich.edu 1209023Sgblack@eecs.umich.edu outOfBytes = false; 1219023Sgblack@eecs.umich.edu process(); 1229023Sgblack@eecs.umich.edu} 1239023Sgblack@eecs.umich.edu 1249023Sgblack@eecs.umich.edu} 125