utility.cc revision 10095:e8001be2e86e
112726Snikos.nikoleris@arm.com/* 29288SN/A * Copyright (c) 2007 MIPS Technologies, Inc. 39288SN/A * All rights reserved. 49288SN/A * 59288SN/A * Redistribution and use in source and binary forms, with or without 69288SN/A * modification, are permitted provided that the following conditions are 79288SN/A * met: redistributions of source code must retain the above copyright 89288SN/A * notice, this list of conditions and the following disclaimer; 99288SN/A * redistributions in binary form must reproduce the above copyright 109288SN/A * notice, this list of conditions and the following disclaimer in the 119288SN/A * documentation and/or other materials provided with the distribution; 129288SN/A * neither the name of the copyright holders nor the names of its 134486SN/A * contributors may be used to endorse or promote products derived from 144486SN/A * this software without specific prior written permission. 154486SN/A * 164486SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174486SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184486SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194486SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204486SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214486SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224486SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234486SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244486SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254486SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264486SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274486SN/A * 284486SN/A * Authors: Korey Sewell 294486SN/A */ 304486SN/A 314486SN/A#include <cmath> 324486SN/A 334486SN/A#include "arch/mips/isa_traits.hh" 344486SN/A#include "arch/mips/registers.hh" 354486SN/A#include "arch/mips/utility.hh" 364486SN/A#include "arch/mips/vtophys.hh" 374486SN/A#include "base/bitfield.hh" 384486SN/A#include "base/misc.hh" 394486SN/A#include "cpu/static_inst.hh" 4011053Sandreas.hansson@arm.com#include "cpu/thread_context.hh" 414486SN/A#include "mem/fs_translating_port_proxy.hh" 423102SN/A#include "sim/serialize.hh" 438833SN/A 4413352Snikos.nikoleris@arm.com 4513665Sandreas.sandberg@arm.comusing namespace MipsISA; 4613665Sandreas.sandberg@arm.comusing namespace std; 4713665Sandreas.sandberg@arm.com 4813665Sandreas.sandberg@arm.comnamespace MipsISA { 4913665Sandreas.sandberg@arm.com 501615SN/Auint64_t 5112724Snikos.nikoleris@arm.comgetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 5212724Snikos.nikoleris@arm.com{ 5312724Snikos.nikoleris@arm.com panic("getArgument() not implemented\n"); 5412724Snikos.nikoleris@arm.com M5_DUMMY_RETURN 5512724Snikos.nikoleris@arm.com} 5613352Snikos.nikoleris@arm.com 5713352Snikos.nikoleris@arm.comuint64_t 5813352Snikos.nikoleris@arm.comfpConvert(ConvertType cvt_type, double fp_val) 5913352Snikos.nikoleris@arm.com{ 6013352Snikos.nikoleris@arm.com 6113352Snikos.nikoleris@arm.com switch (cvt_type) 6213352Snikos.nikoleris@arm.com { 6313352Snikos.nikoleris@arm.com case SINGLE_TO_DOUBLE: 6413352Snikos.nikoleris@arm.com { 6513352Snikos.nikoleris@arm.com double sdouble_val = fp_val; 6613352Snikos.nikoleris@arm.com void *sdouble_ptr = &sdouble_val; 6713352Snikos.nikoleris@arm.com uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; 6813352Snikos.nikoleris@arm.com return sdp_bits; 6913352Snikos.nikoleris@arm.com } 7013352Snikos.nikoleris@arm.com 7113352Snikos.nikoleris@arm.com case SINGLE_TO_WORD: 7213352Snikos.nikoleris@arm.com { 7313352Snikos.nikoleris@arm.com int32_t sword_val = (int32_t) fp_val; 7412724Snikos.nikoleris@arm.com void *sword_ptr = &sword_val; 752826SN/A uint64_t sword_bits= *(uint32_t *) sword_ptr; 761366SN/A return sword_bits; 7711053Sandreas.hansson@arm.com } 789338SN/A 7910816SN/A case WORD_TO_SINGLE: 8010816SN/A { 8110816SN/A float wfloat_val = fp_val; 8210816SN/A void *wfloat_ptr = &wfloat_val; 8311722Ssophiane.senni@gmail.com uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; 8411722Ssophiane.senni@gmail.com return wfloat_bits; 8510816SN/A } 8610816SN/A 8712513Sodanrc@yahoo.com.br case WORD_TO_DOUBLE: 8812513Sodanrc@yahoo.com.br { 8912513Sodanrc@yahoo.com.br double wdouble_val = fp_val; 901310SN/A void *wdouble_ptr = &wdouble_val; 9110816SN/A uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; 9210816SN/A return wdp_bits; 9310816SN/A } 9410816SN/A 9510816SN/A default: 9610816SN/A panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); 9710816SN/A return 0; 9810884SN/A } 9910816SN/A} 10010816SN/A 1015875SN/Adouble 10210816SN/AroundFP(double val, int digits) 10310816SN/A{ 10412600Sodanrc@yahoo.com.br double digit_offset = pow(10.0,digits); 10512600Sodanrc@yahoo.com.br val = val * digit_offset; 10612600Sodanrc@yahoo.com.br val = val + 0.5; 10712600Sodanrc@yahoo.com.br val = floor(val); 10810025SN/A val = val / digit_offset; 10910025SN/A return val; 11010816SN/A} 11110816SN/A 11210816SN/Adouble 11310816SN/AtruncFP(double val) 11410816SN/A{ 11510816SN/A int trunc_val = (int) val; 11610816SN/A return (double) trunc_val; 11710816SN/A} 11811053Sandreas.hansson@arm.com 11912724Snikos.nikoleris@arm.combool 12012724Snikos.nikoleris@arm.comgetCondCode(uint32_t fcsr, int cc_idx) 12112724Snikos.nikoleris@arm.com{ 12212724Snikos.nikoleris@arm.com int shift = (cc_idx == 0) ? 23 : cc_idx + 24; 12312724Snikos.nikoleris@arm.com bool cc_val = (fcsr >> shift) & 0x00000001; 12412724Snikos.nikoleris@arm.com return cc_val; 12512724Snikos.nikoleris@arm.com} 12611197Sandreas.hansson@arm.com 12711197Sandreas.hansson@arm.comuint32_t 12811197Sandreas.hansson@arm.comgenCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val) 12911197Sandreas.hansson@arm.com{ 13011197Sandreas.hansson@arm.com int cc_idx = (cc_num == 0) ? 23 : cc_num + 24; 13111197Sandreas.hansson@arm.com 13211197Sandreas.hansson@arm.com fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) | 13311197Sandreas.hansson@arm.com cc_val << cc_idx | 13411197Sandreas.hansson@arm.com bits(fcsr, cc_idx - 1, 0); 13511197Sandreas.hansson@arm.com 13611197Sandreas.hansson@arm.com return fcsr; 13711197Sandreas.hansson@arm.com} 13811199Sandreas.hansson@arm.com 13913352Snikos.nikoleris@arm.comuint32_t 14013352Snikos.nikoleris@arm.comgenInvalidVector(uint32_t fcsr_bits) 14113352Snikos.nikoleris@arm.com{ 14213352Snikos.nikoleris@arm.com //Set FCSR invalid in "flag" field 14313352Snikos.nikoleris@arm.com int invalid_offset = Invalid + Flag_Field; 14412724Snikos.nikoleris@arm.com fcsr_bits = fcsr_bits | (1 << invalid_offset); 14512724Snikos.nikoleris@arm.com 14612724Snikos.nikoleris@arm.com //Set FCSR invalid in "cause" flag 14712724Snikos.nikoleris@arm.com int cause_offset = Invalid + Cause_Field; 14812726Snikos.nikoleris@arm.com fcsr_bits = fcsr_bits | (1 << cause_offset); 14912726Snikos.nikoleris@arm.com 15012726Snikos.nikoleris@arm.com return fcsr_bits; 15112726Snikos.nikoleris@arm.com} 15212726Snikos.nikoleris@arm.com 15312726Snikos.nikoleris@arm.combool 15412726Snikos.nikoleris@arm.comisNan(void *val_ptr, int size) 15512726Snikos.nikoleris@arm.com{ 15612726Snikos.nikoleris@arm.com switch (size) 15712726Snikos.nikoleris@arm.com { 158 case 32: 159 { 160 uint32_t val_bits = *(uint32_t *) val_ptr; 161 return (bits(val_bits, 30, 23) == 0xFF); 162 } 163 164 case 64: 165 { 166 uint64_t val_bits = *(uint64_t *) val_ptr; 167 return (bits(val_bits, 62, 52) == 0x7FF); 168 } 169 170 default: 171 panic("Type unsupported. Size mismatch\n"); 172 } 173} 174 175 176bool 177isQnan(void *val_ptr, int size) 178{ 179 switch (size) 180 { 181 case 32: 182 { 183 uint32_t val_bits = *(uint32_t *) val_ptr; 184 return (bits(val_bits, 30, 22) == 0x1FE); 185 } 186 187 case 64: 188 { 189 uint64_t val_bits = *(uint64_t *) val_ptr; 190 return (bits(val_bits, 62, 51) == 0xFFE); 191 } 192 193 default: 194 panic("Type unsupported. Size mismatch\n"); 195 } 196} 197 198bool 199isSnan(void *val_ptr, int size) 200{ 201 switch (size) 202 { 203 case 32: 204 { 205 uint32_t val_bits = *(uint32_t *) val_ptr; 206 return (bits(val_bits, 30, 22) == 0x1FF); 207 } 208 209 case 64: 210 { 211 uint64_t val_bits = *(uint64_t *) val_ptr; 212 return (bits(val_bits, 62, 51) == 0xFFF); 213 } 214 215 default: 216 panic("Type unsupported. Size mismatch\n"); 217 } 218} 219 220template <class CPU> 221void 222zeroRegisters(CPU *cpu) 223{ 224 // Insure ISA semantics 225 // (no longer very clean due to the change in setIntReg() in the 226 // cpu model. Consider changing later.) 227 cpu->thread->setIntReg(ZeroReg, 0); 228 cpu->thread->setFloatReg(ZeroReg, 0.0); 229} 230 231void 232startupCPU(ThreadContext *tc, int cpuId) 233{ 234 tc->activate(Cycles(0)); 235} 236 237void 238initCPU(ThreadContext *tc, int cpuId) 239{} 240 241void 242copyRegs(ThreadContext *src, ThreadContext *dest) 243{ 244 // First loop through the integer registers. 245 for (int i = 0; i < NumIntRegs; i++) 246 dest->setIntRegFlat(i, src->readIntRegFlat(i)); 247 248 // Then loop through the floating point registers. 249 for (int i = 0; i < NumFloatRegs; i++) 250 dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 251 252 // Would need to add condition-code regs if implemented 253 assert(NumCCRegs == 0); 254 255 // Copy misc. registers 256 for (int i = 0; i < NumMiscRegs; i++) 257 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 258 259 // Copy over the PC State 260 dest->pcState(src->pcState()); 261} 262 263void 264copyMiscRegs(ThreadContext *src, ThreadContext *dest) 265{ 266 panic("Copy Misc. Regs Not Implemented Yet\n"); 267} 268void 269skipFunction(ThreadContext *tc) 270{ 271 TheISA::PCState newPC = tc->pcState(); 272 newPC.set(tc->readIntReg(ReturnAddressReg)); 273 tc->pcState(newPC); 274} 275 276 277} // namespace MipsISA 278