utility.cc revision 13611:c8b7847b4171
112841Sgabeblack@google.com/* 212841Sgabeblack@google.com * Copyright (c) 2007 MIPS Technologies, Inc. 312841Sgabeblack@google.com * All rights reserved. 412841Sgabeblack@google.com * 512841Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612841Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712841Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912841Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112841Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212841Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312841Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412841Sgabeblack@google.com * this software without specific prior written permission. 1512841Sgabeblack@google.com * 1612841Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712841Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812841Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912841Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012841Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112841Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212841Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312841Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412841Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512841Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612841Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712841Sgabeblack@google.com * 2812841Sgabeblack@google.com * Authors: Korey Sewell 2912841Sgabeblack@google.com */ 3012841Sgabeblack@google.com 3112841Sgabeblack@google.com#include "arch/mips/utility.hh" 3212841Sgabeblack@google.com 3312841Sgabeblack@google.com#include <cmath> 3412841Sgabeblack@google.com 3513054Sgabeblack@google.com#include "arch/mips/isa_traits.hh" 3613269Sgabeblack@google.com#include "arch/mips/registers.hh" 3712841Sgabeblack@google.com#include "arch/mips/vtophys.hh" 3813245Sgabeblack@google.com#include "base/bitfield.hh" 3912841Sgabeblack@google.com#include "base/logging.hh" 4012841Sgabeblack@google.com#include "cpu/static_inst.hh" 4112841Sgabeblack@google.com#include "cpu/thread_context.hh" 4212841Sgabeblack@google.com#include "mem/fs_translating_port_proxy.hh" 4312841Sgabeblack@google.com#include "sim/serialize.hh" 4412841Sgabeblack@google.com 4512841Sgabeblack@google.comusing namespace MipsISA; 4612841Sgabeblack@google.comusing namespace std; 4712841Sgabeblack@google.com 4812841Sgabeblack@google.comnamespace MipsISA { 4912841Sgabeblack@google.com 5012841Sgabeblack@google.comuint64_t 5112841Sgabeblack@google.comgetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 5213054Sgabeblack@google.com{ 5313054Sgabeblack@google.com panic("getArgument() not implemented\n"); 5413054Sgabeblack@google.com M5_DUMMY_RETURN 5513054Sgabeblack@google.com} 5613054Sgabeblack@google.com 5713054Sgabeblack@google.comuint64_t 5812841Sgabeblack@google.comfpConvert(ConvertType cvt_type, double fp_val) 5912841Sgabeblack@google.com{ 6012868Sgabeblack@google.com 6112868Sgabeblack@google.com switch (cvt_type) 6213054Sgabeblack@google.com { 6313054Sgabeblack@google.com case SINGLE_TO_DOUBLE: 6412868Sgabeblack@google.com { 6512868Sgabeblack@google.com double sdouble_val = fp_val; 6613054Sgabeblack@google.com void *sdouble_ptr = &sdouble_val; 6713054Sgabeblack@google.com uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; 6812868Sgabeblack@google.com return sdp_bits; 6912868Sgabeblack@google.com } 7013054Sgabeblack@google.com 7113054Sgabeblack@google.com case SINGLE_TO_WORD: 7212868Sgabeblack@google.com { 7312868Sgabeblack@google.com int32_t sword_val = (int32_t) fp_val; 7413054Sgabeblack@google.com void *sword_ptr = &sword_val; 7513054Sgabeblack@google.com uint64_t sword_bits= *(uint32_t *) sword_ptr; 7612868Sgabeblack@google.com return sword_bits; 7712868Sgabeblack@google.com } 7813054Sgabeblack@google.com 7913054Sgabeblack@google.com case WORD_TO_SINGLE: 8012868Sgabeblack@google.com { 8112868Sgabeblack@google.com float wfloat_val = fp_val; 8213054Sgabeblack@google.com void *wfloat_ptr = &wfloat_val; 8313054Sgabeblack@google.com uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; 8412868Sgabeblack@google.com return wfloat_bits; 8512868Sgabeblack@google.com } 8612841Sgabeblack@google.com 8713054Sgabeblack@google.com case WORD_TO_DOUBLE: 8812841Sgabeblack@google.com { 8913054Sgabeblack@google.com double wdouble_val = fp_val; 9013054Sgabeblack@google.com void *wdouble_ptr = &wdouble_val; 9113054Sgabeblack@google.com uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; 9213054Sgabeblack@google.com return wdp_bits; 9313054Sgabeblack@google.com } 9413054Sgabeblack@google.com 9513054Sgabeblack@google.com default: 9613054Sgabeblack@google.com panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); 9713054Sgabeblack@google.com return 0; 9812841Sgabeblack@google.com } 9912841Sgabeblack@google.com} 10013054Sgabeblack@google.com 10112841Sgabeblack@google.comdouble 10213054Sgabeblack@google.comroundFP(double val, int digits) 10312841Sgabeblack@google.com{ 10412841Sgabeblack@google.com double digit_offset = pow(10.0,digits); 10512841Sgabeblack@google.com val = val * digit_offset; 10613054Sgabeblack@google.com val = val + 0.5; 10712841Sgabeblack@google.com val = floor(val); 10813054Sgabeblack@google.com val = val / digit_offset; 10912841Sgabeblack@google.com return val; 11012841Sgabeblack@google.com} 11113054Sgabeblack@google.com 11212841Sgabeblack@google.comdouble 11313054Sgabeblack@google.comtruncFP(double val) 11412841Sgabeblack@google.com{ 11512841Sgabeblack@google.com int trunc_val = (int) val; 11613245Sgabeblack@google.com return (double) trunc_val; 11713245Sgabeblack@google.com} 11813245Sgabeblack@google.com 11913245Sgabeblack@google.combool 12013245Sgabeblack@google.comgetCondCode(uint32_t fcsr, int cc_idx) 12113245Sgabeblack@google.com{ 12213245Sgabeblack@google.com int shift = (cc_idx == 0) ? 23 : cc_idx + 24; 12313245Sgabeblack@google.com bool cc_val = (fcsr >> shift) & 0x00000001; 12412841Sgabeblack@google.com return cc_val; 12513054Sgabeblack@google.com} 12613054Sgabeblack@google.com 12712841Sgabeblack@google.comuint32_t 12813054Sgabeblack@google.comgenCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val) 12912841Sgabeblack@google.com{ 13012841Sgabeblack@google.com int cc_idx = (cc_num == 0) ? 23 : cc_num + 24; 13112841Sgabeblack@google.com 13213054Sgabeblack@google.com fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) | 13312841Sgabeblack@google.com cc_val << cc_idx | 13413054Sgabeblack@google.com bits(fcsr, cc_idx - 1, 0); 13513054Sgabeblack@google.com 13612841Sgabeblack@google.com return fcsr; 13712841Sgabeblack@google.com} 13812841Sgabeblack@google.com 13913245Sgabeblack@google.comuint32_t 14013245Sgabeblack@google.comgenInvalidVector(uint32_t fcsr_bits) 14113245Sgabeblack@google.com{ 14213245Sgabeblack@google.com //Set FCSR invalid in "flag" field 14313245Sgabeblack@google.com int invalid_offset = Invalid + Flag_Field; 14413245Sgabeblack@google.com fcsr_bits = fcsr_bits | (1 << invalid_offset); 14512841Sgabeblack@google.com 14613054Sgabeblack@google.com //Set FCSR invalid in "cause" flag 14713054Sgabeblack@google.com int cause_offset = Invalid + Cause_Field; 14813245Sgabeblack@google.com fcsr_bits = fcsr_bits | (1 << cause_offset); 14913245Sgabeblack@google.com 15012841Sgabeblack@google.com return fcsr_bits; 15113054Sgabeblack@google.com} 15213054Sgabeblack@google.com 15312841Sgabeblack@google.combool 15412841Sgabeblack@google.comisNan(void *val_ptr, int size) 15512841Sgabeblack@google.com{ 15612841Sgabeblack@google.com switch (size) 15713245Sgabeblack@google.com { 15812841Sgabeblack@google.com case 32: 15913269Sgabeblack@google.com { 16013269Sgabeblack@google.com uint32_t val_bits = *(uint32_t *) val_ptr; 16113269Sgabeblack@google.com return (bits(val_bits, 30, 23) == 0xFF); 16213245Sgabeblack@google.com } 16312841Sgabeblack@google.com 16412841Sgabeblack@google.com case 64: 16512841Sgabeblack@google.com { 16612841Sgabeblack@google.com uint64_t val_bits = *(uint64_t *) val_ptr; 16712841Sgabeblack@google.com return (bits(val_bits, 62, 52) == 0x7FF); 16812841Sgabeblack@google.com } 16913054Sgabeblack@google.com 17013054Sgabeblack@google.com default: 17113054Sgabeblack@google.com panic("Type unsupported. Size mismatch\n"); 17213054Sgabeblack@google.com } 17313054Sgabeblack@google.com} 17413054Sgabeblack@google.com 17512841Sgabeblack@google.com 17613054Sgabeblack@google.combool 17713054Sgabeblack@google.comisQnan(void *val_ptr, int size) 17813054Sgabeblack@google.com{ 17913054Sgabeblack@google.com switch (size) 18013054Sgabeblack@google.com { 18113054Sgabeblack@google.com case 32: 18212841Sgabeblack@google.com { 18312841Sgabeblack@google.com uint32_t val_bits = *(uint32_t *) val_ptr; 18412868Sgabeblack@google.com return (bits(val_bits, 30, 22) == 0x1FE); 18512868Sgabeblack@google.com } 18613054Sgabeblack@google.com 18713054Sgabeblack@google.com case 64: 18813054Sgabeblack@google.com { 18913054Sgabeblack@google.com uint64_t val_bits = *(uint64_t *) val_ptr; 19013054Sgabeblack@google.com return (bits(val_bits, 62, 51) == 0xFFE); 19112868Sgabeblack@google.com } 19212868Sgabeblack@google.com 19313054Sgabeblack@google.com default: 19413054Sgabeblack@google.com panic("Type unsupported. Size mismatch\n"); 19513054Sgabeblack@google.com } 19613054Sgabeblack@google.com} 19713054Sgabeblack@google.com 19812868Sgabeblack@google.combool 19912868Sgabeblack@google.comisSnan(void *val_ptr, int size) 20013054Sgabeblack@google.com{ 20113054Sgabeblack@google.com switch (size) 20213054Sgabeblack@google.com { 20313054Sgabeblack@google.com case 32: 20413054Sgabeblack@google.com { 20512868Sgabeblack@google.com uint32_t val_bits = *(uint32_t *) val_ptr; 20612868Sgabeblack@google.com return (bits(val_bits, 30, 22) == 0x1FF); 20713054Sgabeblack@google.com } 20813054Sgabeblack@google.com 20913054Sgabeblack@google.com case 64: 21013054Sgabeblack@google.com { 21113054Sgabeblack@google.com uint64_t val_bits = *(uint64_t *) val_ptr; 21212868Sgabeblack@google.com return (bits(val_bits, 62, 51) == 0xFFF); 21312868Sgabeblack@google.com } 21413054Sgabeblack@google.com 21513054Sgabeblack@google.com default: 21613054Sgabeblack@google.com panic("Type unsupported. Size mismatch\n"); 21713054Sgabeblack@google.com } 21813054Sgabeblack@google.com} 21912868Sgabeblack@google.com 22012868Sgabeblack@google.comtemplate <class CPU> 22113054Sgabeblack@google.comvoid 22213054Sgabeblack@google.comzeroRegisters(CPU *cpu) 22313054Sgabeblack@google.com{ 22413054Sgabeblack@google.com // Insure ISA semantics 22513054Sgabeblack@google.com // (no longer very clean due to the change in setIntReg() in the 22612868Sgabeblack@google.com // cpu model. Consider changing later.) 22712868Sgabeblack@google.com cpu->thread->setIntReg(ZeroReg, 0); 22813383Sgabeblack@google.com cpu->thread->setFloatReg(ZeroReg, 0); 22913383Sgabeblack@google.com} 23012841Sgabeblack@google.com 23113054Sgabeblack@google.comvoid 23212841Sgabeblack@google.comstartupCPU(ThreadContext *tc, int cpuId) 23313054Sgabeblack@google.com{ 23413054Sgabeblack@google.com tc->activate(); 23513054Sgabeblack@google.com} 23613054Sgabeblack@google.com 23713054Sgabeblack@google.comvoid 23813054Sgabeblack@google.cominitCPU(ThreadContext *tc, int cpuId) 23913054Sgabeblack@google.com{} 24013054Sgabeblack@google.com 24113054Sgabeblack@google.comvoid 24212841Sgabeblack@google.comcopyRegs(ThreadContext *src, ThreadContext *dest) 24312841Sgabeblack@google.com{ 24413054Sgabeblack@google.com // First loop through the integer registers. 24512841Sgabeblack@google.com for (int i = 0; i < NumIntRegs; i++) 24613054Sgabeblack@google.com dest->setIntRegFlat(i, src->readIntRegFlat(i)); 24712841Sgabeblack@google.com 24812841Sgabeblack@google.com // Then loop through the floating point registers. 24912841Sgabeblack@google.com for (int i = 0; i < NumFloatRegs; i++) 25013054Sgabeblack@google.com dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 25112841Sgabeblack@google.com 25213054Sgabeblack@google.com // Would need to add condition-code regs if implemented 25312841Sgabeblack@google.com assert(NumCCRegs == 0); 25412841Sgabeblack@google.com 25513054Sgabeblack@google.com // Copy misc. registers 25612841Sgabeblack@google.com for (int i = 0; i < NumMiscRegs; i++) 25713054Sgabeblack@google.com dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 25812841Sgabeblack@google.com 25912841Sgabeblack@google.com // Copy over the PC State 26013245Sgabeblack@google.com dest->pcState(src->pcState()); 26113245Sgabeblack@google.com} 26213245Sgabeblack@google.com 26313245Sgabeblack@google.comvoid 26413245Sgabeblack@google.comcopyMiscRegs(ThreadContext *src, ThreadContext *dest) 26513245Sgabeblack@google.com{ 26613245Sgabeblack@google.com panic("Copy Misc. Regs Not Implemented Yet\n"); 26713245Sgabeblack@google.com} 26812841Sgabeblack@google.comvoid 26913054Sgabeblack@google.comskipFunction(ThreadContext *tc) 27013054Sgabeblack@google.com{ 27112841Sgabeblack@google.com TheISA::PCState newPC = tc->pcState(); 27213054Sgabeblack@google.com newPC.set(tc->readIntReg(ReturnAddressReg)); 27312841Sgabeblack@google.com tc->pcState(newPC); 27412841Sgabeblack@google.com} 27512841Sgabeblack@google.com 27613054Sgabeblack@google.com 27712841Sgabeblack@google.com} // namespace MipsISA 27812841Sgabeblack@google.com