utility.cc revision 6019:76890d8b28f5
1/* 2 * Copyright (c) 2003-2006 The Regents of The University of Michigan 3 * Copyright (c) 2007-2008 The Florida State University 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Authors: Korey Sewell 30 * Stephen Hines 31 */ 32 33#include "arch/arm/regfile.hh" 34#include "arch/arm/utility.hh" 35#include "base/misc.hh" 36#include "base/bitfield.hh" 37 38using namespace ArmISA; 39 40uint64_t 41ArmISA::fpConvert(ConvertType cvt_type, double fp_val) 42{ 43 44 switch (cvt_type) 45 { 46 case SINGLE_TO_DOUBLE: 47 { 48 double sdouble_val = fp_val; 49 void *sdouble_ptr = &sdouble_val; 50 uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; 51 return sdp_bits; 52 } 53 54 case SINGLE_TO_WORD: 55 { 56 int32_t sword_val = (int32_t) fp_val; 57 void *sword_ptr = &sword_val; 58 uint64_t sword_bits= *(uint32_t *) sword_ptr; 59 return sword_bits; 60 } 61 62 case WORD_TO_SINGLE: 63 { 64 float wfloat_val = fp_val; 65 void *wfloat_ptr = &wfloat_val; 66 uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; 67 return wfloat_bits; 68 } 69 70 case WORD_TO_DOUBLE: 71 { 72 double wdouble_val = fp_val; 73 void *wdouble_ptr = &wdouble_val; 74 uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; 75 return wdp_bits; 76 } 77 78 default: 79 panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); 80 return 0; 81 } 82} 83 84double 85ArmISA::roundFP(double val, int digits) 86{ 87 double digit_offset = pow(10.0,digits); 88 val = val * digit_offset; 89 val = val + 0.5; 90 val = floor(val); 91 val = val / digit_offset; 92 return val; 93} 94 95double 96ArmISA::truncFP(double val) 97{ 98 int trunc_val = (int) val; 99 return (double) trunc_val; 100} 101 102bool 103ArmISA::getCondCode(uint32_t fcsr, int cc_idx) 104{ 105 int shift = (cc_idx == 0) ? 23 : cc_idx + 24; 106 bool cc_val = (fcsr >> shift) & 0x00000001; 107 return cc_val; 108} 109 110uint32_t 111ArmISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val) 112{ 113 int cc_idx = (cc_num == 0) ? 23 : cc_num + 24; 114 115 fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) | 116 cc_val << cc_idx | 117 bits(fcsr, cc_idx - 1, 0); 118 119 return fcsr; 120} 121 122uint32_t 123ArmISA::genInvalidVector(uint32_t fcsr_bits) 124{ 125 //Set FCSR invalid in "flag" field 126 int invalid_offset = Invalid + Flag_Field; 127 fcsr_bits = fcsr_bits | (1 << invalid_offset); 128 129 //Set FCSR invalid in "cause" flag 130 int cause_offset = Invalid + Cause_Field; 131 fcsr_bits = fcsr_bits | (1 << cause_offset); 132 133 return fcsr_bits; 134} 135 136bool 137ArmISA::isNan(void *val_ptr, int size) 138{ 139 switch (size) 140 { 141 case 32: 142 { 143 uint32_t val_bits = *(uint32_t *) val_ptr; 144 return (bits(val_bits, 30, 23) == 0xFF); 145 } 146 147 case 64: 148 { 149 uint64_t val_bits = *(uint64_t *) val_ptr; 150 return (bits(val_bits, 62, 52) == 0x7FF); 151 } 152 153 default: 154 panic("Type unsupported. Size mismatch\n"); 155 } 156} 157 158 159bool 160ArmISA::isQnan(void *val_ptr, int size) 161{ 162 switch (size) 163 { 164 case 32: 165 { 166 uint32_t val_bits = *(uint32_t *) val_ptr; 167 return (bits(val_bits, 30, 22) == 0x1FE); 168 } 169 170 case 64: 171 { 172 uint64_t val_bits = *(uint64_t *) val_ptr; 173 return (bits(val_bits, 62, 51) == 0xFFE); 174 } 175 176 default: 177 panic("Type unsupported. Size mismatch\n"); 178 } 179} 180 181bool 182ArmISA::isSnan(void *val_ptr, int size) 183{ 184 switch (size) 185 { 186 case 32: 187 { 188 uint32_t val_bits = *(uint32_t *) val_ptr; 189 return (bits(val_bits, 30, 22) == 0x1FF); 190 } 191 192 case 64: 193 { 194 uint64_t val_bits = *(uint64_t *) val_ptr; 195 return (bits(val_bits, 62, 51) == 0xFFF); 196 } 197 198 default: 199 panic("Type unsupported. Size mismatch\n"); 200 } 201} 202