utility.cc revision 7720:65d338a8dba4
1/*
2 * Copyright (c) 2007 MIPS Technologies, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Korey Sewell
29 */
30
31#include <cmath>
32
33#include "arch/mips/isa_traits.hh"
34#include "arch/mips/utility.hh"
35#include "config/full_system.hh"
36#include "cpu/thread_context.hh"
37#include "cpu/static_inst.hh"
38#include "sim/serialize.hh"
39#include "base/bitfield.hh"
40#include "base/misc.hh"
41
42#if FULL_SYSTEM
43#include "arch/mips/registers.hh"
44#include "arch/mips/vtophys.hh"
45#include "mem/vport.hh"
46#endif
47
48
49using namespace MipsISA;
50using namespace std;
51
52namespace MipsISA {
53
54uint64_t
55getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
56{
57#if FULL_SYSTEM
58    if (number < 4) {
59        if (fp)
60            return tc->readFloatRegBits(FirstArgumentReg + number);
61        else
62            return tc->readIntReg(FirstArgumentReg + number);
63    } else {
64        Addr sp = tc->readIntReg(StackPointerReg);
65        VirtualPort *vp = tc->getVirtPort();
66        uint64_t arg = vp->read<uint64_t>(sp +
67                (number - 4) * sizeof(uint64_t));
68        return arg;
69    }
70#else
71    panic("getArgument() is Full system only\n");
72    M5_DUMMY_RETURN
73#endif
74}
75
76uint64_t
77fpConvert(ConvertType cvt_type, double fp_val)
78{
79
80    switch (cvt_type)
81    {
82      case SINGLE_TO_DOUBLE:
83        {
84            double sdouble_val = fp_val;
85            void  *sdouble_ptr = &sdouble_val;
86            uint64_t sdp_bits  = *(uint64_t *) sdouble_ptr;
87            return sdp_bits;
88        }
89
90      case SINGLE_TO_WORD:
91        {
92            int32_t sword_val  = (int32_t) fp_val;
93            void  *sword_ptr   = &sword_val;
94            uint64_t sword_bits= *(uint32_t *) sword_ptr;
95            return sword_bits;
96        }
97
98      case WORD_TO_SINGLE:
99        {
100            float wfloat_val   = fp_val;
101            void  *wfloat_ptr  = &wfloat_val;
102            uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
103            return wfloat_bits;
104        }
105
106      case WORD_TO_DOUBLE:
107        {
108            double wdouble_val = fp_val;
109            void  *wdouble_ptr = &wdouble_val;
110            uint64_t wdp_bits  = *(uint64_t *) wdouble_ptr;
111            return wdp_bits;
112        }
113
114      default:
115        panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
116        return 0;
117    }
118}
119
120double
121roundFP(double val, int digits)
122{
123    double digit_offset = pow(10.0,digits);
124    val = val * digit_offset;
125    val = val + 0.5;
126    val = floor(val);
127    val = val / digit_offset;
128    return val;
129}
130
131double
132truncFP(double val)
133{
134    int trunc_val = (int) val;
135    return (double) trunc_val;
136}
137
138bool
139getCondCode(uint32_t fcsr, int cc_idx)
140{
141    int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
142    bool cc_val = (fcsr >> shift) & 0x00000001;
143    return cc_val;
144}
145
146uint32_t
147genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
148{
149    int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
150
151    fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) |
152           cc_val << cc_idx |
153           bits(fcsr, cc_idx - 1, 0);
154
155    return fcsr;
156}
157
158uint32_t
159genInvalidVector(uint32_t fcsr_bits)
160{
161    //Set FCSR invalid in "flag" field
162    int invalid_offset = Invalid + Flag_Field;
163    fcsr_bits = fcsr_bits | (1 << invalid_offset);
164
165    //Set FCSR invalid in "cause" flag
166    int cause_offset = Invalid + Cause_Field;
167    fcsr_bits = fcsr_bits | (1 << cause_offset);
168
169    return fcsr_bits;
170}
171
172bool
173isNan(void *val_ptr, int size)
174{
175    switch (size)
176    {
177      case 32:
178        {
179            uint32_t val_bits = *(uint32_t *) val_ptr;
180            return (bits(val_bits, 30, 23) == 0xFF);
181        }
182
183      case 64:
184        {
185            uint64_t val_bits = *(uint64_t *) val_ptr;
186            return (bits(val_bits, 62, 52) == 0x7FF);
187        }
188
189      default:
190        panic("Type unsupported. Size mismatch\n");
191    }
192}
193
194
195bool
196isQnan(void *val_ptr, int size)
197{
198    switch (size)
199    {
200      case 32:
201        {
202            uint32_t val_bits = *(uint32_t *) val_ptr;
203            return (bits(val_bits, 30, 22) == 0x1FE);
204        }
205
206      case 64:
207        {
208            uint64_t val_bits = *(uint64_t *) val_ptr;
209            return (bits(val_bits, 62, 51) == 0xFFE);
210        }
211
212      default:
213        panic("Type unsupported. Size mismatch\n");
214    }
215}
216
217bool
218isSnan(void *val_ptr, int size)
219{
220    switch (size)
221    {
222      case 32:
223        {
224            uint32_t val_bits = *(uint32_t *) val_ptr;
225            return (bits(val_bits, 30, 22) == 0x1FF);
226        }
227
228      case 64:
229        {
230            uint64_t val_bits = *(uint64_t *) val_ptr;
231            return (bits(val_bits, 62, 51) == 0xFFF);
232        }
233
234      default:
235        panic("Type unsupported. Size mismatch\n");
236    }
237}
238
239template <class CPU>
240void
241zeroRegisters(CPU *cpu)
242{
243    // Insure ISA semantics
244    // (no longer very clean due to the change in setIntReg() in the
245    // cpu model.  Consider changing later.)
246    cpu->thread->setIntReg(ZeroReg, 0);
247    cpu->thread->setFloatReg(ZeroReg, 0.0);
248}
249
250void
251startupCPU(ThreadContext *tc, int cpuId)
252{
253    tc->activate(0/*tc->threadId()*/);
254}
255
256void
257copyRegs(ThreadContext *src, ThreadContext *dest)
258{
259    panic("Copy Regs Not Implemented Yet\n");
260}
261
262void
263copyMiscRegs(ThreadContext *src, ThreadContext *dest)
264{
265    panic("Copy Misc. Regs Not Implemented Yet\n");
266}
267void
268skipFunction(ThreadContext *tc)
269{
270    TheISA::PCState newPC = tc->pcState();
271    newPC.set(tc->readIntReg(ReturnAddressReg));
272    tc->pcState(newPC);
273}
274
275
276} // namespace MipsISA
277