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