utility.cc revision 12334
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 2007 MIPS Technologies, Inc.
36145Snate@binkert.org * All rights reserved.
46145Snate@binkert.org *
56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
66145Snate@binkert.org * modification, are permitted provided that the following conditions are
76145Snate@binkert.org * met: redistributions of source code must retain the above copyright
86145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
116145Snate@binkert.org * documentation and/or other materials provided with the distribution;
126145Snate@binkert.org * neither the name of the copyright holders nor the names of its
136145Snate@binkert.org * contributors may be used to endorse or promote products derived from
146145Snate@binkert.org * this software without specific prior written permission.
156145Snate@binkert.org *
166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276145Snate@binkert.org *
286145Snate@binkert.org * Authors: Korey Sewell
296145Snate@binkert.org */
307054Snate@binkert.org
316145Snate@binkert.org#include "arch/mips/utility.hh"
326145Snate@binkert.org
336145Snate@binkert.org#include <cmath>
346145Snate@binkert.org
356145Snate@binkert.org#include "arch/mips/isa_traits.hh"
366145Snate@binkert.org#include "arch/mips/registers.hh"
376145Snate@binkert.org#include "arch/mips/vtophys.hh"
386145Snate@binkert.org#include "base/bitfield.hh"
396145Snate@binkert.org#include "base/logging.hh"
406145Snate@binkert.org#include "cpu/static_inst.hh"
416145Snate@binkert.org#include "cpu/thread_context.hh"
426145Snate@binkert.org#include "mem/fs_translating_port_proxy.hh"
436145Snate@binkert.org#include "sim/serialize.hh"
446145Snate@binkert.org
456145Snate@binkert.orgusing namespace MipsISA;
466145Snate@binkert.orgusing namespace std;
476145Snate@binkert.org
486145Snate@binkert.orgnamespace MipsISA {
496145Snate@binkert.org
506145Snate@binkert.orguint64_t
516145Snate@binkert.orggetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
526145Snate@binkert.org{
536145Snate@binkert.org    panic("getArgument() not implemented\n");
546145Snate@binkert.org    M5_DUMMY_RETURN
556284Snate@binkert.org}
566145Snate@binkert.org
576145Snate@binkert.orguint64_t
586145Snate@binkert.orgfpConvert(ConvertType cvt_type, double fp_val)
596145Snate@binkert.org{
606145Snate@binkert.org
616145Snate@binkert.org    switch (cvt_type)
626145Snate@binkert.org    {
637054Snate@binkert.org      case SINGLE_TO_DOUBLE:
647054Snate@binkert.org        {
656145Snate@binkert.org            double sdouble_val = fp_val;
667055Snate@binkert.org            void  *sdouble_ptr = &sdouble_val;
677055Snate@binkert.org            uint64_t sdp_bits  = *(uint64_t *) sdouble_ptr;
687054Snate@binkert.org            return sdp_bits;
696154Snate@binkert.org        }
706154Snate@binkert.org
716154Snate@binkert.org      case SINGLE_TO_WORD:
727054Snate@binkert.org        {
736876Ssteve.reinhardt@amd.com            int32_t sword_val  = (int32_t) fp_val;
746145Snate@binkert.org            void  *sword_ptr   = &sword_val;
756145Snate@binkert.org            uint64_t sword_bits= *(uint32_t *) sword_ptr;
766145Snate@binkert.org            return sword_bits;
776145Snate@binkert.org        }
786145Snate@binkert.org
796145Snate@binkert.org      case WORD_TO_SINGLE:
806145Snate@binkert.org        {
817054Snate@binkert.org            float wfloat_val   = fp_val;
827054Snate@binkert.org            void  *wfloat_ptr  = &wfloat_val;
837054Snate@binkert.org            uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
846876Ssteve.reinhardt@amd.com            return wfloat_bits;
856876Ssteve.reinhardt@amd.com        }
867054Snate@binkert.org
876145Snate@binkert.org      case WORD_TO_DOUBLE:
887054Snate@binkert.org        {
896145Snate@binkert.org            double wdouble_val = fp_val;
907055Snate@binkert.org            void  *wdouble_ptr = &wdouble_val;
917054Snate@binkert.org            uint64_t wdp_bits  = *(uint64_t *) wdouble_ptr;
927055Snate@binkert.org            return wdp_bits;
936285Snate@binkert.org        }
947054Snate@binkert.org
956145Snate@binkert.org      default:
967054Snate@binkert.org        panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
977054Snate@binkert.org        return 0;
987054Snate@binkert.org    }
997054Snate@binkert.org}
1006145Snate@binkert.org
1017054Snate@binkert.orgdouble
1027054Snate@binkert.orgroundFP(double val, int digits)
1036145Snate@binkert.org{
1047054Snate@binkert.org    double digit_offset = pow(10.0,digits);
1056145Snate@binkert.org    val = val * digit_offset;
1067054Snate@binkert.org    val = val + 0.5;
1077054Snate@binkert.org    val = floor(val);
1087054Snate@binkert.org    val = val / digit_offset;
1097054Snate@binkert.org    return val;
1107054Snate@binkert.org}
1117054Snate@binkert.org
1127054Snate@binkert.orgdouble
1137054Snate@binkert.orgtruncFP(double val)
1147054Snate@binkert.org{
1157054Snate@binkert.org    int trunc_val = (int) val;
1166145Snate@binkert.org    return (double) trunc_val;
1177055Snate@binkert.org}
1186145Snate@binkert.org
1197054Snate@binkert.orgbool
1207054Snate@binkert.orggetCondCode(uint32_t fcsr, int cc_idx)
1217054Snate@binkert.org{
1227054Snate@binkert.org    int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
1237054Snate@binkert.org    bool cc_val = (fcsr >> shift) & 0x00000001;
1247054Snate@binkert.org    return cc_val;
1257054Snate@binkert.org}
1267054Snate@binkert.org
1276145Snate@binkert.orguint32_t
1287054Snate@binkert.orggenCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
1297054Snate@binkert.org{
1307054Snate@binkert.org    int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
1316145Snate@binkert.org
1327054Snate@binkert.org    fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) |
1337054Snate@binkert.org           cc_val << cc_idx |
1347054Snate@binkert.org           bits(fcsr, cc_idx - 1, 0);
1356145Snate@binkert.org
1367054Snate@binkert.org    return fcsr;
1377054Snate@binkert.org}
1387054Snate@binkert.org
1397054Snate@binkert.orguint32_t
1407054Snate@binkert.orggenInvalidVector(uint32_t fcsr_bits)
1416145Snate@binkert.org{
1426145Snate@binkert.org    //Set FCSR invalid in "flag" field
1437055Snate@binkert.org    int invalid_offset = Invalid + Flag_Field;
1447055Snate@binkert.org    fcsr_bits = fcsr_bits | (1 << invalid_offset);
1456145Snate@binkert.org
1467054Snate@binkert.org    //Set FCSR invalid in "cause" flag
1477055Snate@binkert.org    int cause_offset = Invalid + Cause_Field;
1487054Snate@binkert.org    fcsr_bits = fcsr_bits | (1 << cause_offset);
1496145Snate@binkert.org
1506145Snate@binkert.org    return fcsr_bits;
1517054Snate@binkert.org}
152
153bool
154isNan(void *val_ptr, int size)
155{
156    switch (size)
157    {
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();
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