utility.cc revision 2686:f0d591379ac3
1/*
2 * Copyright (c) 2003-2006 The Regents of The University of Michigan
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
29#include "arch/mips/isa_traits.hh"
30#include "arch/mips/utility.hh"
31#include "config/full_system.hh"
32#include "cpu/static_inst.hh"
33#include "sim/serialize.hh"
34#include "base/bitfield.hh"
35
36using namespace MipsISA;
37using namespace std;
38
39uint64_t
40MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
41{
42
43    switch (cvt_type)
44    {
45      case SINGLE_TO_DOUBLE:
46        {
47            double sdouble_val = fp_val;
48            void  *sdouble_ptr = &sdouble_val;
49            uint64_t sdp_bits  = *(uint64_t *) sdouble_ptr;
50            return sdp_bits;
51        }
52
53      case SINGLE_TO_WORD:
54        {
55            int32_t sword_val  = (int32_t) fp_val;
56            void  *sword_ptr   = &sword_val;
57            uint64_t sword_bits= *(uint32_t *) sword_ptr;
58            return sword_bits;
59        }
60
61      case WORD_TO_SINGLE:
62        {
63            float wfloat_val   = fp_val;
64            void  *wfloat_ptr  = &wfloat_val;
65            uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
66            return wfloat_bits;
67        }
68
69      case WORD_TO_DOUBLE:
70        {
71            double wdouble_val = fp_val;
72            void  *wdouble_ptr = &wdouble_val;
73            uint64_t wdp_bits  = *(uint64_t *) wdouble_ptr;
74            return wdp_bits;
75        }
76
77      default:
78        panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
79        return 0;
80    }
81}
82
83double
84MipsISA::roundFP(double val, int digits)
85{
86    double digit_offset = pow(10.0,digits);
87    val = val * digit_offset;
88    val = val + 0.5;
89    val = floor(val);
90    val = val / digit_offset;
91    return val;
92}
93
94double
95MipsISA::truncFP(double val)
96{
97    int trunc_val = (int) val;
98    return (double) trunc_val;
99}
100
101bool
102MipsISA::getCondCode(uint32_t fcsr, int cc_idx)
103{
104    int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
105    bool cc_val = (fcsr >> shift) & 0x00000001;
106    return cc_val;
107}
108
109uint32_t
110MipsISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
111{
112    int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
113
114    fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 |
115           cc_val << cc_idx |
116           bits(fcsr, cc_idx - 1, 0);
117
118    return fcsr;
119}
120
121uint32_t
122MipsISA::genInvalidVector(uint32_t fcsr_bits)
123{
124    //Set FCSR invalid in "flag" field
125    int invalid_offset = Invalid + Flag_Field;
126    fcsr_bits = fcsr_bits | (1 << invalid_offset);
127
128    //Set FCSR invalid in "cause" flag
129    int cause_offset = Invalid + Cause_Field;
130    fcsr_bits = fcsr_bits | (1 << cause_offset);
131
132    return fcsr_bits;
133}
134
135bool
136MipsISA::isNan(void *val_ptr, int size)
137{
138    switch (size)
139    {
140      case 32:
141        {
142            uint32_t val_bits = *(uint32_t *) val_ptr;
143            return (bits(val_bits, 30, 23) == 0xFF);
144        }
145
146      case 64:
147        {
148            uint64_t val_bits = *(uint64_t *) val_ptr;
149            return (bits(val_bits, 62, 52) == 0x7FF);
150        }
151
152      default:
153        panic("Type unsupported. Size mismatch\n");
154    }
155}
156
157
158bool
159MipsISA::isQnan(void *val_ptr, int size)
160{
161    switch (size)
162    {
163      case 32:
164        {
165            uint32_t val_bits = *(uint32_t *) val_ptr;
166            return (bits(val_bits, 30, 22) == 0x1FE);
167        }
168
169      case 64:
170        {
171            uint64_t val_bits = *(uint64_t *) val_ptr;
172            return (bits(val_bits, 62, 51) == 0xFFE);
173        }
174
175      default:
176        panic("Type unsupported. Size mismatch\n");
177    }
178}
179
180bool
181MipsISA::isSnan(void *val_ptr, int size)
182{
183    switch (size)
184    {
185      case 32:
186        {
187            uint32_t val_bits = *(uint32_t *) val_ptr;
188            return (bits(val_bits, 30, 22) == 0x1FF);
189        }
190
191      case 64:
192        {
193            uint64_t val_bits = *(uint64_t *) val_ptr;
194            return (bits(val_bits, 62, 51) == 0xFFF);
195        }
196
197      default:
198        panic("Type unsupported. Size mismatch\n");
199    }
200}
201