110037SARM gem5 Developers/* 213118SEdmund.Grimley-Evans@arm.com* Copyright (c) 2012-2013, 2017-2018 ARM Limited 310037SARM gem5 Developers* All rights reserved 410037SARM gem5 Developers* 510037SARM gem5 Developers* The license below extends only to copyright in the software and shall 610037SARM gem5 Developers* not be construed as granting a license to any other intellectual 710037SARM gem5 Developers* property including but not limited to intellectual property relating 810037SARM gem5 Developers* to a hardware implementation of the functionality of the software 910037SARM gem5 Developers* licensed hereunder. You may use the software subject to the license 1010037SARM gem5 Developers* terms below provided that you ensure that this notice is replicated 1110037SARM gem5 Developers* unmodified and in its entirety in all distributions of the software, 1210037SARM gem5 Developers* modified or unmodified, in source code or in binary form. 1310037SARM gem5 Developers* 1410037SARM gem5 Developers* Redistribution and use in source and binary forms, with or without 1510037SARM gem5 Developers* modification, are permitted provided that the following conditions are 1610037SARM gem5 Developers* met: redistributions of source code must retain the above copyright 1710037SARM gem5 Developers* notice, this list of conditions and the following disclaimer; 1810037SARM gem5 Developers* redistributions in binary form must reproduce the above copyright 1910037SARM gem5 Developers* notice, this list of conditions and the following disclaimer in the 2010037SARM gem5 Developers* documentation and/or other materials provided with the distribution; 2110037SARM gem5 Developers* neither the name of the copyright holders nor the names of its 2210037SARM gem5 Developers* contributors may be used to endorse or promote products derived from 2310037SARM gem5 Developers* this software without specific prior written permission. 2410037SARM gem5 Developers* 2510037SARM gem5 Developers* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610037SARM gem5 Developers* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710037SARM gem5 Developers* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810037SARM gem5 Developers* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910037SARM gem5 Developers* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010037SARM gem5 Developers* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110037SARM gem5 Developers* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210037SARM gem5 Developers* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310037SARM gem5 Developers* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410037SARM gem5 Developers* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510037SARM gem5 Developers* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610037SARM gem5 Developers* 3710037SARM gem5 Developers* Authors: Edmund Grimley Evans 3810037SARM gem5 Developers* Thomas Grocutt 3910037SARM gem5 Developers*/ 4010037SARM gem5 Developers 4110037SARM gem5 Developers#include <stdint.h> 4210037SARM gem5 Developers 4310037SARM gem5 Developers#include <cassert> 4410037SARM gem5 Developers 4513449Sgabeblack@google.com#include "base/logging.hh" 4610037SARM gem5 Developers#include "fplib.hh" 4710037SARM gem5 Developers 4810037SARM gem5 Developersnamespace ArmISA 4910037SARM gem5 Developers{ 5010037SARM gem5 Developers 5110037SARM gem5 Developers#define FPLIB_RN 0 5210037SARM gem5 Developers#define FPLIB_RP 1 5310037SARM gem5 Developers#define FPLIB_RM 2 5410037SARM gem5 Developers#define FPLIB_RZ 3 5510037SARM gem5 Developers#define FPLIB_FZ 4 5610037SARM gem5 Developers#define FPLIB_DN 8 5710037SARM gem5 Developers#define FPLIB_AHP 16 5813118SEdmund.Grimley-Evans@arm.com#define FPLIB_FZ16 32 5910037SARM gem5 Developers 6010037SARM gem5 Developers#define FPLIB_IDC 128 // Input Denormal 6110037SARM gem5 Developers#define FPLIB_IXC 16 // Inexact 6210037SARM gem5 Developers#define FPLIB_UFC 8 // Underflow 6310037SARM gem5 Developers#define FPLIB_OFC 4 // Overflow 6410037SARM gem5 Developers#define FPLIB_DZC 2 // Division by Zero 6510037SARM gem5 Developers#define FPLIB_IOC 1 // Invalid Operation 6610037SARM gem5 Developers 6713118SEdmund.Grimley-Evans@arm.com#define FP16_BITS 16 6813118SEdmund.Grimley-Evans@arm.com#define FP32_BITS 32 6913118SEdmund.Grimley-Evans@arm.com#define FP64_BITS 64 7013118SEdmund.Grimley-Evans@arm.com 7113118SEdmund.Grimley-Evans@arm.com#define FP16_EXP_BITS 5 7213118SEdmund.Grimley-Evans@arm.com#define FP32_EXP_BITS 8 7313118SEdmund.Grimley-Evans@arm.com#define FP64_EXP_BITS 11 7413118SEdmund.Grimley-Evans@arm.com 7513118SEdmund.Grimley-Evans@arm.com#define FP16_EXP_BIAS 15 7613118SEdmund.Grimley-Evans@arm.com#define FP32_EXP_BIAS 127 7713118SEdmund.Grimley-Evans@arm.com#define FP64_EXP_BIAS 1023 7813118SEdmund.Grimley-Evans@arm.com 7913118SEdmund.Grimley-Evans@arm.com#define FP16_EXP_INF ((1ULL << FP16_EXP_BITS) - 1) 8013118SEdmund.Grimley-Evans@arm.com#define FP32_EXP_INF ((1ULL << FP32_EXP_BITS) - 1) 8113118SEdmund.Grimley-Evans@arm.com#define FP64_EXP_INF ((1ULL << FP64_EXP_BITS) - 1) 8213118SEdmund.Grimley-Evans@arm.com 8313118SEdmund.Grimley-Evans@arm.com#define FP16_MANT_BITS (FP16_BITS - FP16_EXP_BITS - 1) 8413118SEdmund.Grimley-Evans@arm.com#define FP32_MANT_BITS (FP32_BITS - FP32_EXP_BITS - 1) 8513118SEdmund.Grimley-Evans@arm.com#define FP64_MANT_BITS (FP64_BITS - FP64_EXP_BITS - 1) 8613118SEdmund.Grimley-Evans@arm.com 8713118SEdmund.Grimley-Evans@arm.com#define FP16_EXP(x) ((x) >> FP16_MANT_BITS & ((1ULL << FP16_EXP_BITS) - 1)) 8813118SEdmund.Grimley-Evans@arm.com#define FP32_EXP(x) ((x) >> FP32_MANT_BITS & ((1ULL << FP32_EXP_BITS) - 1)) 8913118SEdmund.Grimley-Evans@arm.com#define FP64_EXP(x) ((x) >> FP64_MANT_BITS & ((1ULL << FP64_EXP_BITS) - 1)) 9013118SEdmund.Grimley-Evans@arm.com 9113118SEdmund.Grimley-Evans@arm.com#define FP16_MANT(x) ((x) & ((1ULL << FP16_MANT_BITS) - 1)) 9213118SEdmund.Grimley-Evans@arm.com#define FP32_MANT(x) ((x) & ((1ULL << FP32_MANT_BITS) - 1)) 9313118SEdmund.Grimley-Evans@arm.com#define FP64_MANT(x) ((x) & ((1ULL << FP64_MANT_BITS) - 1)) 9413118SEdmund.Grimley-Evans@arm.com 9510037SARM gem5 Developersstatic inline uint16_t 9610037SARM gem5 Developerslsl16(uint16_t x, uint32_t shift) 9710037SARM gem5 Developers{ 9810037SARM gem5 Developers return shift < 16 ? x << shift : 0; 9910037SARM gem5 Developers} 10010037SARM gem5 Developers 10110037SARM gem5 Developersstatic inline uint16_t 10210037SARM gem5 Developerslsr16(uint16_t x, uint32_t shift) 10310037SARM gem5 Developers{ 10410037SARM gem5 Developers return shift < 16 ? x >> shift : 0; 10510037SARM gem5 Developers} 10610037SARM gem5 Developers 10710037SARM gem5 Developersstatic inline uint32_t 10810037SARM gem5 Developerslsl32(uint32_t x, uint32_t shift) 10910037SARM gem5 Developers{ 11010037SARM gem5 Developers return shift < 32 ? x << shift : 0; 11110037SARM gem5 Developers} 11210037SARM gem5 Developers 11310037SARM gem5 Developersstatic inline uint32_t 11410037SARM gem5 Developerslsr32(uint32_t x, uint32_t shift) 11510037SARM gem5 Developers{ 11610037SARM gem5 Developers return shift < 32 ? x >> shift : 0; 11710037SARM gem5 Developers} 11810037SARM gem5 Developers 11910037SARM gem5 Developersstatic inline uint64_t 12010037SARM gem5 Developerslsl64(uint64_t x, uint32_t shift) 12110037SARM gem5 Developers{ 12210037SARM gem5 Developers return shift < 64 ? x << shift : 0; 12310037SARM gem5 Developers} 12410037SARM gem5 Developers 12510037SARM gem5 Developersstatic inline uint64_t 12610037SARM gem5 Developerslsr64(uint64_t x, uint32_t shift) 12710037SARM gem5 Developers{ 12810037SARM gem5 Developers return shift < 64 ? x >> shift : 0; 12910037SARM gem5 Developers} 13010037SARM gem5 Developers 13110037SARM gem5 Developersstatic inline void 13210037SARM gem5 Developerslsl128(uint64_t *r0, uint64_t *r1, uint64_t x0, uint64_t x1, uint32_t shift) 13310037SARM gem5 Developers{ 13411224Snathananel.premillieu@arm.com if (shift == 0) { 13511224Snathananel.premillieu@arm.com *r1 = x1; 13611224Snathananel.premillieu@arm.com *r0 = x0; 13711224Snathananel.premillieu@arm.com } else if (shift < 64) { 13810037SARM gem5 Developers *r1 = x1 << shift | x0 >> (64 - shift); 13910037SARM gem5 Developers *r0 = x0 << shift; 14010037SARM gem5 Developers } else if (shift < 128) { 14110037SARM gem5 Developers *r1 = x0 << (shift - 64); 14210037SARM gem5 Developers *r0 = 0; 14310037SARM gem5 Developers } else { 14410037SARM gem5 Developers *r1 = 0; 14510037SARM gem5 Developers *r0 = 0; 14610037SARM gem5 Developers } 14710037SARM gem5 Developers} 14810037SARM gem5 Developers 14910037SARM gem5 Developersstatic inline void 15010037SARM gem5 Developerslsr128(uint64_t *r0, uint64_t *r1, uint64_t x0, uint64_t x1, uint32_t shift) 15110037SARM gem5 Developers{ 15211224Snathananel.premillieu@arm.com if (shift == 0) { 15311224Snathananel.premillieu@arm.com *r1 = x1; 15411224Snathananel.premillieu@arm.com *r0 = x0; 15511224Snathananel.premillieu@arm.com } else if (shift < 64) { 15610037SARM gem5 Developers *r0 = x0 >> shift | x1 << (64 - shift); 15710037SARM gem5 Developers *r1 = x1 >> shift; 15810037SARM gem5 Developers } else if (shift < 128) { 15910037SARM gem5 Developers *r0 = x1 >> (shift - 64); 16010037SARM gem5 Developers *r1 = 0; 16110037SARM gem5 Developers } else { 16210037SARM gem5 Developers *r0 = 0; 16310037SARM gem5 Developers *r1 = 0; 16410037SARM gem5 Developers } 16510037SARM gem5 Developers} 16610037SARM gem5 Developers 16710037SARM gem5 Developersstatic inline void 16810037SARM gem5 Developersmul62x62(uint64_t *x0, uint64_t *x1, uint64_t a, uint64_t b) 16910037SARM gem5 Developers{ 17010037SARM gem5 Developers uint32_t mask = ((uint32_t)1 << 31) - 1; 17110037SARM gem5 Developers uint64_t a0 = a & mask; 17210037SARM gem5 Developers uint64_t a1 = a >> 31 & mask; 17310037SARM gem5 Developers uint64_t b0 = b & mask; 17410037SARM gem5 Developers uint64_t b1 = b >> 31 & mask; 17510037SARM gem5 Developers uint64_t p0 = a0 * b0; 17610037SARM gem5 Developers uint64_t p2 = a1 * b1; 17710037SARM gem5 Developers uint64_t p1 = (a0 + a1) * (b0 + b1) - p0 - p2; 17810037SARM gem5 Developers uint64_t s0 = p0; 17910037SARM gem5 Developers uint64_t s1 = (s0 >> 31) + p1; 18010037SARM gem5 Developers uint64_t s2 = (s1 >> 31) + p2; 18110037SARM gem5 Developers *x0 = (s0 & mask) | (s1 & mask) << 31 | s2 << 62; 18210037SARM gem5 Developers *x1 = s2 >> 2; 18310037SARM gem5 Developers} 18410037SARM gem5 Developers 18510037SARM gem5 Developersstatic inline 18610037SARM gem5 Developersvoid mul64x32(uint64_t *x0, uint64_t *x1, uint64_t a, uint32_t b) 18710037SARM gem5 Developers{ 18810037SARM gem5 Developers uint64_t t0 = (uint64_t)(uint32_t)a * b; 18910037SARM gem5 Developers uint64_t t1 = (t0 >> 32) + (a >> 32) * b; 19010037SARM gem5 Developers *x0 = t1 << 32 | (uint32_t)t0; 19110037SARM gem5 Developers *x1 = t1 >> 32; 19210037SARM gem5 Developers} 19310037SARM gem5 Developers 19410037SARM gem5 Developersstatic inline void 19510037SARM gem5 Developersadd128(uint64_t *x0, uint64_t *x1, uint64_t a0, uint64_t a1, uint64_t b0, 19610037SARM gem5 Developers uint64_t b1) 19710037SARM gem5 Developers{ 19810037SARM gem5 Developers *x0 = a0 + b0; 19910037SARM gem5 Developers *x1 = a1 + b1 + (*x0 < a0); 20010037SARM gem5 Developers} 20110037SARM gem5 Developers 20210037SARM gem5 Developersstatic inline void 20310037SARM gem5 Developerssub128(uint64_t *x0, uint64_t *x1, uint64_t a0, uint64_t a1, uint64_t b0, 20410037SARM gem5 Developers uint64_t b1) 20510037SARM gem5 Developers{ 20610037SARM gem5 Developers *x0 = a0 - b0; 20710037SARM gem5 Developers *x1 = a1 - b1 - (*x0 > a0); 20810037SARM gem5 Developers} 20910037SARM gem5 Developers 21010037SARM gem5 Developersstatic inline int 21110037SARM gem5 Developerscmp128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1) 21210037SARM gem5 Developers{ 21310037SARM gem5 Developers return (a1 < b1 ? -1 : a1 > b1 ? 1 : a0 < b0 ? -1 : a0 > b0 ? 1 : 0); 21410037SARM gem5 Developers} 21510037SARM gem5 Developers 21610037SARM gem5 Developersstatic inline uint16_t 21710037SARM gem5 Developersfp16_normalise(uint16_t mnt, int *exp) 21810037SARM gem5 Developers{ 21910037SARM gem5 Developers int shift; 22010037SARM gem5 Developers 22110037SARM gem5 Developers if (!mnt) { 22210037SARM gem5 Developers return 0; 22310037SARM gem5 Developers } 22410037SARM gem5 Developers 22510037SARM gem5 Developers for (shift = 8; shift; shift >>= 1) { 22610037SARM gem5 Developers if (!(mnt >> (16 - shift))) { 22710037SARM gem5 Developers mnt <<= shift; 22810037SARM gem5 Developers *exp -= shift; 22910037SARM gem5 Developers } 23010037SARM gem5 Developers } 23110037SARM gem5 Developers return mnt; 23210037SARM gem5 Developers} 23310037SARM gem5 Developers 23410037SARM gem5 Developersstatic inline uint32_t 23510037SARM gem5 Developersfp32_normalise(uint32_t mnt, int *exp) 23610037SARM gem5 Developers{ 23710037SARM gem5 Developers int shift; 23810037SARM gem5 Developers 23910037SARM gem5 Developers if (!mnt) { 24010037SARM gem5 Developers return 0; 24110037SARM gem5 Developers } 24210037SARM gem5 Developers 24310037SARM gem5 Developers for (shift = 16; shift; shift >>= 1) { 24410037SARM gem5 Developers if (!(mnt >> (32 - shift))) { 24510037SARM gem5 Developers mnt <<= shift; 24610037SARM gem5 Developers *exp -= shift; 24710037SARM gem5 Developers } 24810037SARM gem5 Developers } 24910037SARM gem5 Developers return mnt; 25010037SARM gem5 Developers} 25110037SARM gem5 Developers 25210037SARM gem5 Developersstatic inline uint64_t 25310037SARM gem5 Developersfp64_normalise(uint64_t mnt, int *exp) 25410037SARM gem5 Developers{ 25510037SARM gem5 Developers int shift; 25610037SARM gem5 Developers 25710037SARM gem5 Developers if (!mnt) { 25810037SARM gem5 Developers return 0; 25910037SARM gem5 Developers } 26010037SARM gem5 Developers 26110037SARM gem5 Developers for (shift = 32; shift; shift >>= 1) { 26210037SARM gem5 Developers if (!(mnt >> (64 - shift))) { 26310037SARM gem5 Developers mnt <<= shift; 26410037SARM gem5 Developers *exp -= shift; 26510037SARM gem5 Developers } 26610037SARM gem5 Developers } 26710037SARM gem5 Developers return mnt; 26810037SARM gem5 Developers} 26910037SARM gem5 Developers 27010037SARM gem5 Developersstatic inline void 27110037SARM gem5 Developersfp128_normalise(uint64_t *mnt0, uint64_t *mnt1, int *exp) 27210037SARM gem5 Developers{ 27310037SARM gem5 Developers uint64_t x0 = *mnt0; 27410037SARM gem5 Developers uint64_t x1 = *mnt1; 27510037SARM gem5 Developers int shift; 27610037SARM gem5 Developers 27710037SARM gem5 Developers if (!x0 && !x1) { 27810037SARM gem5 Developers return; 27910037SARM gem5 Developers } 28010037SARM gem5 Developers 28110037SARM gem5 Developers if (!x1) { 28210037SARM gem5 Developers x1 = x0; 28310037SARM gem5 Developers x0 = 0; 28410037SARM gem5 Developers *exp -= 64; 28510037SARM gem5 Developers } 28610037SARM gem5 Developers 28710037SARM gem5 Developers for (shift = 32; shift; shift >>= 1) { 28810037SARM gem5 Developers if (!(x1 >> (64 - shift))) { 28910037SARM gem5 Developers x1 = x1 << shift | x0 >> (64 - shift); 29010037SARM gem5 Developers x0 <<= shift; 29110037SARM gem5 Developers *exp -= shift; 29210037SARM gem5 Developers } 29310037SARM gem5 Developers } 29410037SARM gem5 Developers 29510037SARM gem5 Developers *mnt0 = x0; 29610037SARM gem5 Developers *mnt1 = x1; 29710037SARM gem5 Developers} 29810037SARM gem5 Developers 29910037SARM gem5 Developersstatic inline uint16_t 30010037SARM gem5 Developersfp16_pack(uint16_t sgn, uint16_t exp, uint16_t mnt) 30110037SARM gem5 Developers{ 30213118SEdmund.Grimley-Evans@arm.com return sgn << (FP16_BITS - 1) | exp << FP16_MANT_BITS | FP16_MANT(mnt); 30310037SARM gem5 Developers} 30410037SARM gem5 Developers 30510037SARM gem5 Developersstatic inline uint32_t 30610037SARM gem5 Developersfp32_pack(uint32_t sgn, uint32_t exp, uint32_t mnt) 30710037SARM gem5 Developers{ 30813118SEdmund.Grimley-Evans@arm.com return sgn << (FP32_BITS - 1) | exp << FP32_MANT_BITS | FP32_MANT(mnt); 30910037SARM gem5 Developers} 31010037SARM gem5 Developers 31110037SARM gem5 Developersstatic inline uint64_t 31210037SARM gem5 Developersfp64_pack(uint64_t sgn, uint64_t exp, uint64_t mnt) 31310037SARM gem5 Developers{ 31413118SEdmund.Grimley-Evans@arm.com return sgn << (FP64_BITS - 1) | exp << FP64_MANT_BITS | FP64_MANT(mnt); 31510037SARM gem5 Developers} 31610037SARM gem5 Developers 31710037SARM gem5 Developersstatic inline uint16_t 31810037SARM gem5 Developersfp16_zero(int sgn) 31910037SARM gem5 Developers{ 32010037SARM gem5 Developers return fp16_pack(sgn, 0, 0); 32110037SARM gem5 Developers} 32210037SARM gem5 Developers 32310037SARM gem5 Developersstatic inline uint32_t 32410037SARM gem5 Developersfp32_zero(int sgn) 32510037SARM gem5 Developers{ 32610037SARM gem5 Developers return fp32_pack(sgn, 0, 0); 32710037SARM gem5 Developers} 32810037SARM gem5 Developers 32910037SARM gem5 Developersstatic inline uint64_t 33010037SARM gem5 Developersfp64_zero(int sgn) 33110037SARM gem5 Developers{ 33210037SARM gem5 Developers return fp64_pack(sgn, 0, 0); 33310037SARM gem5 Developers} 33410037SARM gem5 Developers 33510037SARM gem5 Developersstatic inline uint16_t 33610037SARM gem5 Developersfp16_max_normal(int sgn) 33710037SARM gem5 Developers{ 33813118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, FP16_EXP_INF - 1, -1); 33910037SARM gem5 Developers} 34010037SARM gem5 Developers 34110037SARM gem5 Developersstatic inline uint32_t 34210037SARM gem5 Developersfp32_max_normal(int sgn) 34310037SARM gem5 Developers{ 34413118SEdmund.Grimley-Evans@arm.com return fp32_pack(sgn, FP32_EXP_INF - 1, -1); 34510037SARM gem5 Developers} 34610037SARM gem5 Developers 34710037SARM gem5 Developersstatic inline uint64_t 34810037SARM gem5 Developersfp64_max_normal(int sgn) 34910037SARM gem5 Developers{ 35013118SEdmund.Grimley-Evans@arm.com return fp64_pack(sgn, FP64_EXP_INF - 1, -1); 35110037SARM gem5 Developers} 35210037SARM gem5 Developers 35310037SARM gem5 Developersstatic inline uint16_t 35410037SARM gem5 Developersfp16_infinity(int sgn) 35510037SARM gem5 Developers{ 35613118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, FP16_EXP_INF, 0); 35710037SARM gem5 Developers} 35810037SARM gem5 Developers 35910037SARM gem5 Developersstatic inline uint32_t 36010037SARM gem5 Developersfp32_infinity(int sgn) 36110037SARM gem5 Developers{ 36213118SEdmund.Grimley-Evans@arm.com return fp32_pack(sgn, FP32_EXP_INF, 0); 36310037SARM gem5 Developers} 36410037SARM gem5 Developers 36510037SARM gem5 Developersstatic inline uint64_t 36610037SARM gem5 Developersfp64_infinity(int sgn) 36710037SARM gem5 Developers{ 36813118SEdmund.Grimley-Evans@arm.com return fp64_pack(sgn, FP64_EXP_INF, 0); 36910037SARM gem5 Developers} 37010037SARM gem5 Developers 37110037SARM gem5 Developersstatic inline uint16_t 37210037SARM gem5 Developersfp16_defaultNaN() 37310037SARM gem5 Developers{ 37413118SEdmund.Grimley-Evans@arm.com return fp16_pack(0, FP16_EXP_INF, 1ULL << (FP16_MANT_BITS - 1)); 37510037SARM gem5 Developers} 37610037SARM gem5 Developers 37710037SARM gem5 Developersstatic inline uint32_t 37810037SARM gem5 Developersfp32_defaultNaN() 37910037SARM gem5 Developers{ 38013118SEdmund.Grimley-Evans@arm.com return fp32_pack(0, FP32_EXP_INF, 1ULL << (FP32_MANT_BITS - 1)); 38110037SARM gem5 Developers} 38210037SARM gem5 Developers 38310037SARM gem5 Developersstatic inline uint64_t 38410037SARM gem5 Developersfp64_defaultNaN() 38510037SARM gem5 Developers{ 38613118SEdmund.Grimley-Evans@arm.com return fp64_pack(0, FP64_EXP_INF, 1ULL << (FP64_MANT_BITS - 1)); 38710037SARM gem5 Developers} 38810037SARM gem5 Developers 38910037SARM gem5 Developersstatic inline void 39010037SARM gem5 Developersfp16_unpack(int *sgn, int *exp, uint16_t *mnt, uint16_t x, int mode, 39110037SARM gem5 Developers int *flags) 39210037SARM gem5 Developers{ 39313118SEdmund.Grimley-Evans@arm.com *sgn = x >> (FP16_BITS - 1); 39413118SEdmund.Grimley-Evans@arm.com *exp = FP16_EXP(x); 39513118SEdmund.Grimley-Evans@arm.com *mnt = FP16_MANT(x); 39610037SARM gem5 Developers 39710037SARM gem5 Developers // Handle subnormals: 39810037SARM gem5 Developers if (*exp) { 39913118SEdmund.Grimley-Evans@arm.com *mnt |= 1ULL << FP16_MANT_BITS; 40010037SARM gem5 Developers } else { 40110037SARM gem5 Developers ++*exp; 40213118SEdmund.Grimley-Evans@arm.com // IDC (Input Denormal) is not set in this case. 40313118SEdmund.Grimley-Evans@arm.com if (mode & FPLIB_FZ16) 40413118SEdmund.Grimley-Evans@arm.com *mnt = 0; 40510037SARM gem5 Developers } 40610037SARM gem5 Developers} 40710037SARM gem5 Developers 40810037SARM gem5 Developersstatic inline void 40910037SARM gem5 Developersfp32_unpack(int *sgn, int *exp, uint32_t *mnt, uint32_t x, int mode, 41010037SARM gem5 Developers int *flags) 41110037SARM gem5 Developers{ 41213118SEdmund.Grimley-Evans@arm.com *sgn = x >> (FP32_BITS - 1); 41313118SEdmund.Grimley-Evans@arm.com *exp = FP32_EXP(x); 41413118SEdmund.Grimley-Evans@arm.com *mnt = FP32_MANT(x); 41510037SARM gem5 Developers 41610037SARM gem5 Developers // Handle subnormals: 41710037SARM gem5 Developers if (*exp) { 41813118SEdmund.Grimley-Evans@arm.com *mnt |= 1ULL << FP32_MANT_BITS; 41910037SARM gem5 Developers } else { 42010037SARM gem5 Developers ++*exp; 42110037SARM gem5 Developers if ((mode & FPLIB_FZ) && *mnt) { 42210037SARM gem5 Developers *flags |= FPLIB_IDC; 42310037SARM gem5 Developers *mnt = 0; 42410037SARM gem5 Developers } 42510037SARM gem5 Developers } 42610037SARM gem5 Developers} 42710037SARM gem5 Developers 42810037SARM gem5 Developersstatic inline void 42910037SARM gem5 Developersfp64_unpack(int *sgn, int *exp, uint64_t *mnt, uint64_t x, int mode, 43010037SARM gem5 Developers int *flags) 43110037SARM gem5 Developers{ 43213118SEdmund.Grimley-Evans@arm.com *sgn = x >> (FP64_BITS - 1); 43313118SEdmund.Grimley-Evans@arm.com *exp = FP64_EXP(x); 43413118SEdmund.Grimley-Evans@arm.com *mnt = FP64_MANT(x); 43510037SARM gem5 Developers 43610037SARM gem5 Developers // Handle subnormals: 43710037SARM gem5 Developers if (*exp) { 43813118SEdmund.Grimley-Evans@arm.com *mnt |= 1ULL << FP64_MANT_BITS; 43910037SARM gem5 Developers } else { 44010037SARM gem5 Developers ++*exp; 44110037SARM gem5 Developers if ((mode & FPLIB_FZ) && *mnt) { 44210037SARM gem5 Developers *flags |= FPLIB_IDC; 44310037SARM gem5 Developers *mnt = 0; 44410037SARM gem5 Developers } 44510037SARM gem5 Developers } 44610037SARM gem5 Developers} 44710037SARM gem5 Developers 44813118SEdmund.Grimley-Evans@arm.comstatic inline int 44913118SEdmund.Grimley-Evans@arm.comfp16_is_NaN(int exp, uint16_t mnt) 45013118SEdmund.Grimley-Evans@arm.com{ 45113118SEdmund.Grimley-Evans@arm.com return exp == FP16_EXP_INF && FP16_MANT(mnt); 45213118SEdmund.Grimley-Evans@arm.com} 45313118SEdmund.Grimley-Evans@arm.com 45413118SEdmund.Grimley-Evans@arm.comstatic inline int 45513118SEdmund.Grimley-Evans@arm.comfp32_is_NaN(int exp, uint32_t mnt) 45613118SEdmund.Grimley-Evans@arm.com{ 45713118SEdmund.Grimley-Evans@arm.com return exp == FP32_EXP_INF && FP32_MANT(mnt); 45813118SEdmund.Grimley-Evans@arm.com} 45913118SEdmund.Grimley-Evans@arm.com 46013118SEdmund.Grimley-Evans@arm.comstatic inline int 46113118SEdmund.Grimley-Evans@arm.comfp64_is_NaN(int exp, uint64_t mnt) 46213118SEdmund.Grimley-Evans@arm.com{ 46313118SEdmund.Grimley-Evans@arm.com return exp == FP64_EXP_INF && FP64_MANT(mnt); 46413118SEdmund.Grimley-Evans@arm.com} 46513118SEdmund.Grimley-Evans@arm.com 46613118SEdmund.Grimley-Evans@arm.comstatic inline int 46713118SEdmund.Grimley-Evans@arm.comfp16_is_signalling_NaN(int exp, uint16_t mnt) 46813118SEdmund.Grimley-Evans@arm.com{ 46913118SEdmund.Grimley-Evans@arm.com return fp16_is_NaN(exp, mnt) && !(mnt >> (FP16_MANT_BITS - 1) & 1); 47013118SEdmund.Grimley-Evans@arm.com} 47113118SEdmund.Grimley-Evans@arm.com 47213118SEdmund.Grimley-Evans@arm.comstatic inline int 47313118SEdmund.Grimley-Evans@arm.comfp32_is_signalling_NaN(int exp, uint32_t mnt) 47413118SEdmund.Grimley-Evans@arm.com{ 47513118SEdmund.Grimley-Evans@arm.com return fp32_is_NaN(exp, mnt) && !(mnt >> (FP32_MANT_BITS - 1) & 1); 47613118SEdmund.Grimley-Evans@arm.com} 47713118SEdmund.Grimley-Evans@arm.com 47813118SEdmund.Grimley-Evans@arm.comstatic inline int 47913118SEdmund.Grimley-Evans@arm.comfp64_is_signalling_NaN(int exp, uint64_t mnt) 48013118SEdmund.Grimley-Evans@arm.com{ 48113118SEdmund.Grimley-Evans@arm.com return fp64_is_NaN(exp, mnt) && !(mnt >> (FP64_MANT_BITS - 1) & 1); 48213118SEdmund.Grimley-Evans@arm.com} 48313118SEdmund.Grimley-Evans@arm.com 48413118SEdmund.Grimley-Evans@arm.comstatic inline int 48513118SEdmund.Grimley-Evans@arm.comfp16_is_quiet_NaN(int exp, uint16_t mnt) 48613118SEdmund.Grimley-Evans@arm.com{ 48713118SEdmund.Grimley-Evans@arm.com return exp == FP16_EXP_INF && (mnt >> (FP16_MANT_BITS - 1) & 1); 48813118SEdmund.Grimley-Evans@arm.com} 48913118SEdmund.Grimley-Evans@arm.com 49013118SEdmund.Grimley-Evans@arm.comstatic inline int 49113118SEdmund.Grimley-Evans@arm.comfp32_is_quiet_NaN(int exp, uint32_t mnt) 49213118SEdmund.Grimley-Evans@arm.com{ 49313118SEdmund.Grimley-Evans@arm.com return exp == FP32_EXP_INF && (mnt >> (FP32_MANT_BITS - 1) & 1); 49413118SEdmund.Grimley-Evans@arm.com} 49513118SEdmund.Grimley-Evans@arm.com 49613118SEdmund.Grimley-Evans@arm.comstatic inline int 49713118SEdmund.Grimley-Evans@arm.comfp64_is_quiet_NaN(int exp, uint64_t mnt) 49813118SEdmund.Grimley-Evans@arm.com{ 49913118SEdmund.Grimley-Evans@arm.com return exp == FP64_EXP_INF && (mnt >> (FP64_MANT_BITS - 1) & 1); 50013118SEdmund.Grimley-Evans@arm.com} 50113118SEdmund.Grimley-Evans@arm.com 50213118SEdmund.Grimley-Evans@arm.comstatic inline int 50313118SEdmund.Grimley-Evans@arm.comfp16_is_infinity(int exp, uint16_t mnt) 50413118SEdmund.Grimley-Evans@arm.com{ 50513118SEdmund.Grimley-Evans@arm.com return exp == FP16_EXP_INF && !FP16_MANT(mnt); 50613118SEdmund.Grimley-Evans@arm.com} 50713118SEdmund.Grimley-Evans@arm.com 50813118SEdmund.Grimley-Evans@arm.comstatic inline int 50913118SEdmund.Grimley-Evans@arm.comfp32_is_infinity(int exp, uint32_t mnt) 51013118SEdmund.Grimley-Evans@arm.com{ 51113118SEdmund.Grimley-Evans@arm.com return exp == FP32_EXP_INF && !FP32_MANT(mnt); 51213118SEdmund.Grimley-Evans@arm.com} 51313118SEdmund.Grimley-Evans@arm.com 51413118SEdmund.Grimley-Evans@arm.comstatic inline int 51513118SEdmund.Grimley-Evans@arm.comfp64_is_infinity(int exp, uint64_t mnt) 51613118SEdmund.Grimley-Evans@arm.com{ 51713118SEdmund.Grimley-Evans@arm.com return exp == FP64_EXP_INF && !FP64_MANT(mnt); 51813118SEdmund.Grimley-Evans@arm.com} 51913118SEdmund.Grimley-Evans@arm.com 52013118SEdmund.Grimley-Evans@arm.comstatic inline uint16_t 52113118SEdmund.Grimley-Evans@arm.comfp16_process_NaN(uint16_t a, int mode, int *flags) 52213118SEdmund.Grimley-Evans@arm.com{ 52313118SEdmund.Grimley-Evans@arm.com if (!(a >> (FP16_MANT_BITS - 1) & 1)) { 52413118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 52513118SEdmund.Grimley-Evans@arm.com a |= 1ULL << (FP16_MANT_BITS - 1); 52613118SEdmund.Grimley-Evans@arm.com } 52713118SEdmund.Grimley-Evans@arm.com return mode & FPLIB_DN ? fp16_defaultNaN() : a; 52813118SEdmund.Grimley-Evans@arm.com} 52913118SEdmund.Grimley-Evans@arm.com 53010037SARM gem5 Developersstatic inline uint32_t 53110037SARM gem5 Developersfp32_process_NaN(uint32_t a, int mode, int *flags) 53210037SARM gem5 Developers{ 53313118SEdmund.Grimley-Evans@arm.com if (!(a >> (FP32_MANT_BITS - 1) & 1)) { 53410037SARM gem5 Developers *flags |= FPLIB_IOC; 53513118SEdmund.Grimley-Evans@arm.com a |= 1ULL << (FP32_MANT_BITS - 1); 53610037SARM gem5 Developers } 53710037SARM gem5 Developers return mode & FPLIB_DN ? fp32_defaultNaN() : a; 53810037SARM gem5 Developers} 53910037SARM gem5 Developers 54010037SARM gem5 Developersstatic inline uint64_t 54110037SARM gem5 Developersfp64_process_NaN(uint64_t a, int mode, int *flags) 54210037SARM gem5 Developers{ 54313118SEdmund.Grimley-Evans@arm.com if (!(a >> (FP64_MANT_BITS - 1) & 1)) { 54410037SARM gem5 Developers *flags |= FPLIB_IOC; 54513118SEdmund.Grimley-Evans@arm.com a |= 1ULL << (FP64_MANT_BITS - 1); 54610037SARM gem5 Developers } 54710037SARM gem5 Developers return mode & FPLIB_DN ? fp64_defaultNaN() : a; 54810037SARM gem5 Developers} 54910037SARM gem5 Developers 55013118SEdmund.Grimley-Evans@arm.comstatic uint16_t 55113118SEdmund.Grimley-Evans@arm.comfp16_process_NaNs(uint16_t a, uint16_t b, int mode, int *flags) 55213118SEdmund.Grimley-Evans@arm.com{ 55313118SEdmund.Grimley-Evans@arm.com int a_exp = FP16_EXP(a); 55413118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt = FP16_MANT(a); 55513118SEdmund.Grimley-Evans@arm.com int b_exp = FP16_EXP(b); 55613118SEdmund.Grimley-Evans@arm.com uint16_t b_mnt = FP16_MANT(b); 55713118SEdmund.Grimley-Evans@arm.com 55813118SEdmund.Grimley-Evans@arm.com // Handle signalling NaNs: 55913118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(a_exp, a_mnt)) 56013118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(a, mode, flags); 56113118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(b_exp, b_mnt)) 56213118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(b, mode, flags); 56313118SEdmund.Grimley-Evans@arm.com 56413118SEdmund.Grimley-Evans@arm.com // Handle quiet NaNs: 56513118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt)) 56613118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(a, mode, flags); 56713118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(b_exp, b_mnt)) 56813118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(b, mode, flags); 56913118SEdmund.Grimley-Evans@arm.com 57013118SEdmund.Grimley-Evans@arm.com return 0; 57113118SEdmund.Grimley-Evans@arm.com} 57213118SEdmund.Grimley-Evans@arm.com 57310037SARM gem5 Developersstatic uint32_t 57410037SARM gem5 Developersfp32_process_NaNs(uint32_t a, uint32_t b, int mode, int *flags) 57510037SARM gem5 Developers{ 57613118SEdmund.Grimley-Evans@arm.com int a_exp = FP32_EXP(a); 57713118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt = FP32_MANT(a); 57813118SEdmund.Grimley-Evans@arm.com int b_exp = FP32_EXP(b); 57913118SEdmund.Grimley-Evans@arm.com uint32_t b_mnt = FP32_MANT(b); 58010037SARM gem5 Developers 58110037SARM gem5 Developers // Handle signalling NaNs: 58213118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(a_exp, a_mnt)) 58310037SARM gem5 Developers return fp32_process_NaN(a, mode, flags); 58413118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(b_exp, b_mnt)) 58510037SARM gem5 Developers return fp32_process_NaN(b, mode, flags); 58610037SARM gem5 Developers 58710037SARM gem5 Developers // Handle quiet NaNs: 58813118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt)) 58910037SARM gem5 Developers return fp32_process_NaN(a, mode, flags); 59013118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(b_exp, b_mnt)) 59110037SARM gem5 Developers return fp32_process_NaN(b, mode, flags); 59210037SARM gem5 Developers 59310037SARM gem5 Developers return 0; 59410037SARM gem5 Developers} 59510037SARM gem5 Developers 59610037SARM gem5 Developersstatic uint64_t 59710037SARM gem5 Developersfp64_process_NaNs(uint64_t a, uint64_t b, int mode, int *flags) 59810037SARM gem5 Developers{ 59913118SEdmund.Grimley-Evans@arm.com int a_exp = FP64_EXP(a); 60013118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt = FP64_MANT(a); 60113118SEdmund.Grimley-Evans@arm.com int b_exp = FP64_EXP(b); 60213118SEdmund.Grimley-Evans@arm.com uint64_t b_mnt = FP64_MANT(b); 60310037SARM gem5 Developers 60410037SARM gem5 Developers // Handle signalling NaNs: 60513118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(a_exp, a_mnt)) 60610037SARM gem5 Developers return fp64_process_NaN(a, mode, flags); 60713118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(b_exp, b_mnt)) 60810037SARM gem5 Developers return fp64_process_NaN(b, mode, flags); 60910037SARM gem5 Developers 61010037SARM gem5 Developers // Handle quiet NaNs: 61113118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt)) 61210037SARM gem5 Developers return fp64_process_NaN(a, mode, flags); 61313118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(b_exp, b_mnt)) 61410037SARM gem5 Developers return fp64_process_NaN(b, mode, flags); 61510037SARM gem5 Developers 61610037SARM gem5 Developers return 0; 61710037SARM gem5 Developers} 61810037SARM gem5 Developers 61913118SEdmund.Grimley-Evans@arm.comstatic uint16_t 62013118SEdmund.Grimley-Evans@arm.comfp16_process_NaNs3(uint16_t a, uint16_t b, uint16_t c, int mode, int *flags) 62113118SEdmund.Grimley-Evans@arm.com{ 62213118SEdmund.Grimley-Evans@arm.com int a_exp = FP16_EXP(a); 62313118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt = FP16_MANT(a); 62413118SEdmund.Grimley-Evans@arm.com int b_exp = FP16_EXP(b); 62513118SEdmund.Grimley-Evans@arm.com uint16_t b_mnt = FP16_MANT(b); 62613118SEdmund.Grimley-Evans@arm.com int c_exp = FP16_EXP(c); 62713118SEdmund.Grimley-Evans@arm.com uint16_t c_mnt = FP16_MANT(c); 62813118SEdmund.Grimley-Evans@arm.com 62913118SEdmund.Grimley-Evans@arm.com // Handle signalling NaNs: 63013118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(a_exp, a_mnt)) 63113118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(a, mode, flags); 63213118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(b_exp, b_mnt)) 63313118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(b, mode, flags); 63413118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(c_exp, c_mnt)) 63513118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(c, mode, flags); 63613118SEdmund.Grimley-Evans@arm.com 63713118SEdmund.Grimley-Evans@arm.com // Handle quiet NaNs: 63813118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt)) 63913118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(a, mode, flags); 64013118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(b_exp, b_mnt)) 64113118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(b, mode, flags); 64213118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(c_exp, c_mnt)) 64313118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(c, mode, flags); 64413118SEdmund.Grimley-Evans@arm.com 64513118SEdmund.Grimley-Evans@arm.com return 0; 64613118SEdmund.Grimley-Evans@arm.com} 64713118SEdmund.Grimley-Evans@arm.com 64810037SARM gem5 Developersstatic uint32_t 64910037SARM gem5 Developersfp32_process_NaNs3(uint32_t a, uint32_t b, uint32_t c, int mode, int *flags) 65010037SARM gem5 Developers{ 65113118SEdmund.Grimley-Evans@arm.com int a_exp = FP32_EXP(a); 65213118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt = FP32_MANT(a); 65313118SEdmund.Grimley-Evans@arm.com int b_exp = FP32_EXP(b); 65413118SEdmund.Grimley-Evans@arm.com uint32_t b_mnt = FP32_MANT(b); 65513118SEdmund.Grimley-Evans@arm.com int c_exp = FP32_EXP(c); 65613118SEdmund.Grimley-Evans@arm.com uint32_t c_mnt = FP32_MANT(c); 65710037SARM gem5 Developers 65810037SARM gem5 Developers // Handle signalling NaNs: 65913118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(a_exp, a_mnt)) 66010037SARM gem5 Developers return fp32_process_NaN(a, mode, flags); 66113118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(b_exp, b_mnt)) 66210037SARM gem5 Developers return fp32_process_NaN(b, mode, flags); 66313118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(c_exp, c_mnt)) 66410037SARM gem5 Developers return fp32_process_NaN(c, mode, flags); 66510037SARM gem5 Developers 66610037SARM gem5 Developers // Handle quiet NaNs: 66713118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt)) 66810037SARM gem5 Developers return fp32_process_NaN(a, mode, flags); 66913118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(b_exp, b_mnt)) 67010037SARM gem5 Developers return fp32_process_NaN(b, mode, flags); 67113118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(c_exp, c_mnt)) 67210037SARM gem5 Developers return fp32_process_NaN(c, mode, flags); 67310037SARM gem5 Developers 67410037SARM gem5 Developers return 0; 67510037SARM gem5 Developers} 67610037SARM gem5 Developers 67710037SARM gem5 Developersstatic uint64_t 67810037SARM gem5 Developersfp64_process_NaNs3(uint64_t a, uint64_t b, uint64_t c, int mode, int *flags) 67910037SARM gem5 Developers{ 68013118SEdmund.Grimley-Evans@arm.com int a_exp = FP64_EXP(a); 68113118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt = FP64_MANT(a); 68213118SEdmund.Grimley-Evans@arm.com int b_exp = FP64_EXP(b); 68313118SEdmund.Grimley-Evans@arm.com uint64_t b_mnt = FP64_MANT(b); 68413118SEdmund.Grimley-Evans@arm.com int c_exp = FP64_EXP(c); 68513118SEdmund.Grimley-Evans@arm.com uint64_t c_mnt = FP64_MANT(c); 68610037SARM gem5 Developers 68710037SARM gem5 Developers // Handle signalling NaNs: 68813118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(a_exp, a_mnt)) 68910037SARM gem5 Developers return fp64_process_NaN(a, mode, flags); 69013118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(b_exp, b_mnt)) 69110037SARM gem5 Developers return fp64_process_NaN(b, mode, flags); 69213118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(c_exp, c_mnt)) 69310037SARM gem5 Developers return fp64_process_NaN(c, mode, flags); 69410037SARM gem5 Developers 69510037SARM gem5 Developers // Handle quiet NaNs: 69613118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt)) 69710037SARM gem5 Developers return fp64_process_NaN(a, mode, flags); 69813118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(b_exp, b_mnt)) 69910037SARM gem5 Developers return fp64_process_NaN(b, mode, flags); 70013118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(c_exp, c_mnt)) 70110037SARM gem5 Developers return fp64_process_NaN(c, mode, flags); 70210037SARM gem5 Developers 70310037SARM gem5 Developers return 0; 70410037SARM gem5 Developers} 70510037SARM gem5 Developers 70610037SARM gem5 Developersstatic uint16_t 70710037SARM gem5 Developersfp16_round_(int sgn, int exp, uint16_t mnt, int rm, int mode, int *flags) 70810037SARM gem5 Developers{ 70910037SARM gem5 Developers int biased_exp; // non-negative exponent value for result 71013118SEdmund.Grimley-Evans@arm.com uint16_t int_mant; // mantissa for result, less than (2 << FP16_MANT_BITS) 71110037SARM gem5 Developers int error; // 0, 1, 2 or 3, where 2 means int_mant is wrong by exactly 0.5 71210037SARM gem5 Developers 71310037SARM gem5 Developers assert(rm != FPRounding_TIEAWAY); 71410037SARM gem5 Developers 71513118SEdmund.Grimley-Evans@arm.com // Flush to zero: 71613118SEdmund.Grimley-Evans@arm.com if ((mode & FPLIB_FZ16) && exp < 1) { 71713118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_UFC; 71813118SEdmund.Grimley-Evans@arm.com return fp16_zero(sgn); 71913118SEdmund.Grimley-Evans@arm.com } 72013118SEdmund.Grimley-Evans@arm.com 72113118SEdmund.Grimley-Evans@arm.com // The bottom FP16_EXP_BITS bits of mnt are orred together: 72213118SEdmund.Grimley-Evans@arm.com mnt = (4ULL << FP16_MANT_BITS | mnt >> (FP16_EXP_BITS - 1) | 72313118SEdmund.Grimley-Evans@arm.com ((mnt & ((1ULL << FP16_EXP_BITS) - 1)) != 0)); 72410037SARM gem5 Developers 72510037SARM gem5 Developers if (exp > 0) { 72610037SARM gem5 Developers biased_exp = exp; 72710037SARM gem5 Developers int_mant = mnt >> 2; 72810037SARM gem5 Developers error = mnt & 3; 72910037SARM gem5 Developers } else { 73010037SARM gem5 Developers biased_exp = 0; 73110037SARM gem5 Developers int_mant = lsr16(mnt, 3 - exp); 73210037SARM gem5 Developers error = (lsr16(mnt, 1 - exp) & 3) | !!(mnt & (lsl16(1, 1 - exp) - 1)); 73310037SARM gem5 Developers } 73410037SARM gem5 Developers 73510037SARM gem5 Developers if (!biased_exp && error) { // xx should also check fpscr_val<11> 73610037SARM gem5 Developers *flags |= FPLIB_UFC; 73710037SARM gem5 Developers } 73810037SARM gem5 Developers 73910037SARM gem5 Developers // Round up: 74010037SARM gem5 Developers if ((rm == FPLIB_RN && (error == 3 || 74110037SARM gem5 Developers (error == 2 && (int_mant & 1)))) || 74210037SARM gem5 Developers (((rm == FPLIB_RP && !sgn) || (rm == FPLIB_RM && sgn)) && error)) { 74310037SARM gem5 Developers ++int_mant; 74413118SEdmund.Grimley-Evans@arm.com if (int_mant == 1ULL << FP16_MANT_BITS) { 74510037SARM gem5 Developers // Rounded up from denormalized to normalized 74610037SARM gem5 Developers biased_exp = 1; 74710037SARM gem5 Developers } 74813118SEdmund.Grimley-Evans@arm.com if (int_mant == 2ULL << FP16_MANT_BITS) { 74910037SARM gem5 Developers // Rounded up to next exponent 75010037SARM gem5 Developers ++biased_exp; 75110037SARM gem5 Developers int_mant >>= 1; 75210037SARM gem5 Developers } 75310037SARM gem5 Developers } 75410037SARM gem5 Developers 75510037SARM gem5 Developers // Handle rounding to odd aka Von Neumann rounding: 75610037SARM gem5 Developers if (error && rm == FPRounding_ODD) 75710037SARM gem5 Developers int_mant |= 1; 75810037SARM gem5 Developers 75910037SARM gem5 Developers // Handle overflow: 76010037SARM gem5 Developers if (!(mode & FPLIB_AHP)) { 76113118SEdmund.Grimley-Evans@arm.com if (biased_exp >= (int)FP16_EXP_INF) { 76210037SARM gem5 Developers *flags |= FPLIB_OFC | FPLIB_IXC; 76310037SARM gem5 Developers if (rm == FPLIB_RN || (rm == FPLIB_RP && !sgn) || 76410037SARM gem5 Developers (rm == FPLIB_RM && sgn)) { 76510037SARM gem5 Developers return fp16_infinity(sgn); 76610037SARM gem5 Developers } else { 76710037SARM gem5 Developers return fp16_max_normal(sgn); 76810037SARM gem5 Developers } 76910037SARM gem5 Developers } 77010037SARM gem5 Developers } else { 77113118SEdmund.Grimley-Evans@arm.com if (biased_exp >= (int)FP16_EXP_INF + 1) { 77210037SARM gem5 Developers *flags |= FPLIB_IOC; 77313118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, FP16_EXP_INF, -1); 77410037SARM gem5 Developers } 77510037SARM gem5 Developers } 77610037SARM gem5 Developers 77710037SARM gem5 Developers if (error) { 77810037SARM gem5 Developers *flags |= FPLIB_IXC; 77910037SARM gem5 Developers } 78010037SARM gem5 Developers 78110037SARM gem5 Developers return fp16_pack(sgn, biased_exp, int_mant); 78210037SARM gem5 Developers} 78310037SARM gem5 Developers 78413118SEdmund.Grimley-Evans@arm.comstatic uint16_t 78513118SEdmund.Grimley-Evans@arm.comfp16_round(int sgn, int exp, uint16_t mnt, int mode, int *flags) 78613118SEdmund.Grimley-Evans@arm.com{ 78713118SEdmund.Grimley-Evans@arm.com return fp16_round_(sgn, exp, mnt, mode & 3, mode, flags); 78813118SEdmund.Grimley-Evans@arm.com} 78913118SEdmund.Grimley-Evans@arm.com 79010037SARM gem5 Developersstatic uint32_t 79110037SARM gem5 Developersfp32_round_(int sgn, int exp, uint32_t mnt, int rm, int mode, int *flags) 79210037SARM gem5 Developers{ 79310037SARM gem5 Developers int biased_exp; // non-negative exponent value for result 79413118SEdmund.Grimley-Evans@arm.com uint32_t int_mant; // mantissa for result, less than (2 << FP32_MANT_BITS) 79510037SARM gem5 Developers int error; // 0, 1, 2 or 3, where 2 means int_mant is wrong by exactly 0.5 79610037SARM gem5 Developers 79710037SARM gem5 Developers assert(rm != FPRounding_TIEAWAY); 79810037SARM gem5 Developers 79910037SARM gem5 Developers // Flush to zero: 80010037SARM gem5 Developers if ((mode & FPLIB_FZ) && exp < 1) { 80110037SARM gem5 Developers *flags |= FPLIB_UFC; 80210037SARM gem5 Developers return fp32_zero(sgn); 80310037SARM gem5 Developers } 80410037SARM gem5 Developers 80513118SEdmund.Grimley-Evans@arm.com // The bottom FP32_EXP_BITS bits of mnt are orred together: 80613118SEdmund.Grimley-Evans@arm.com mnt = (4ULL << FP32_MANT_BITS | mnt >> (FP32_EXP_BITS - 1) | 80713118SEdmund.Grimley-Evans@arm.com ((mnt & ((1ULL << FP32_EXP_BITS) - 1)) != 0)); 80810037SARM gem5 Developers 80910037SARM gem5 Developers if (exp > 0) { 81010037SARM gem5 Developers biased_exp = exp; 81110037SARM gem5 Developers int_mant = mnt >> 2; 81210037SARM gem5 Developers error = mnt & 3; 81310037SARM gem5 Developers } else { 81410037SARM gem5 Developers biased_exp = 0; 81510037SARM gem5 Developers int_mant = lsr32(mnt, 3 - exp); 81610037SARM gem5 Developers error = (lsr32(mnt, 1 - exp) & 3) | !!(mnt & (lsl32(1, 1 - exp) - 1)); 81710037SARM gem5 Developers } 81810037SARM gem5 Developers 81910037SARM gem5 Developers if (!biased_exp && error) { // xx should also check fpscr_val<11> 82010037SARM gem5 Developers *flags |= FPLIB_UFC; 82110037SARM gem5 Developers } 82210037SARM gem5 Developers 82310037SARM gem5 Developers // Round up: 82410037SARM gem5 Developers if ((rm == FPLIB_RN && (error == 3 || 82510037SARM gem5 Developers (error == 2 && (int_mant & 1)))) || 82610037SARM gem5 Developers (((rm == FPLIB_RP && !sgn) || (rm == FPLIB_RM && sgn)) && error)) { 82710037SARM gem5 Developers ++int_mant; 82813118SEdmund.Grimley-Evans@arm.com if (int_mant == 1ULL << FP32_MANT_BITS) { 82910037SARM gem5 Developers // Rounded up from denormalized to normalized 83010037SARM gem5 Developers biased_exp = 1; 83110037SARM gem5 Developers } 83213118SEdmund.Grimley-Evans@arm.com if (int_mant == 2ULL << FP32_MANT_BITS) { 83310037SARM gem5 Developers // Rounded up to next exponent 83410037SARM gem5 Developers ++biased_exp; 83510037SARM gem5 Developers int_mant >>= 1; 83610037SARM gem5 Developers } 83710037SARM gem5 Developers } 83810037SARM gem5 Developers 83910037SARM gem5 Developers // Handle rounding to odd aka Von Neumann rounding: 84010037SARM gem5 Developers if (error && rm == FPRounding_ODD) 84110037SARM gem5 Developers int_mant |= 1; 84210037SARM gem5 Developers 84310037SARM gem5 Developers // Handle overflow: 84413118SEdmund.Grimley-Evans@arm.com if (biased_exp >= (int)FP32_EXP_INF) { 84510037SARM gem5 Developers *flags |= FPLIB_OFC | FPLIB_IXC; 84610037SARM gem5 Developers if (rm == FPLIB_RN || (rm == FPLIB_RP && !sgn) || 84710037SARM gem5 Developers (rm == FPLIB_RM && sgn)) { 84810037SARM gem5 Developers return fp32_infinity(sgn); 84910037SARM gem5 Developers } else { 85010037SARM gem5 Developers return fp32_max_normal(sgn); 85110037SARM gem5 Developers } 85210037SARM gem5 Developers } 85310037SARM gem5 Developers 85410037SARM gem5 Developers if (error) { 85510037SARM gem5 Developers *flags |= FPLIB_IXC; 85610037SARM gem5 Developers } 85710037SARM gem5 Developers 85810037SARM gem5 Developers return fp32_pack(sgn, biased_exp, int_mant); 85910037SARM gem5 Developers} 86010037SARM gem5 Developers 86110037SARM gem5 Developersstatic uint32_t 86210037SARM gem5 Developersfp32_round(int sgn, int exp, uint32_t mnt, int mode, int *flags) 86310037SARM gem5 Developers{ 86410037SARM gem5 Developers return fp32_round_(sgn, exp, mnt, mode & 3, mode, flags); 86510037SARM gem5 Developers} 86610037SARM gem5 Developers 86710037SARM gem5 Developersstatic uint64_t 86810037SARM gem5 Developersfp64_round_(int sgn, int exp, uint64_t mnt, int rm, int mode, int *flags) 86910037SARM gem5 Developers{ 87010037SARM gem5 Developers int biased_exp; // non-negative exponent value for result 87113118SEdmund.Grimley-Evans@arm.com uint64_t int_mant; // mantissa for result, less than (2 << FP64_MANT_BITS) 87210037SARM gem5 Developers int error; // 0, 1, 2 or 3, where 2 means int_mant is wrong by exactly 0.5 87310037SARM gem5 Developers 87410037SARM gem5 Developers assert(rm != FPRounding_TIEAWAY); 87510037SARM gem5 Developers 87610037SARM gem5 Developers // Flush to zero: 87710037SARM gem5 Developers if ((mode & FPLIB_FZ) && exp < 1) { 87810037SARM gem5 Developers *flags |= FPLIB_UFC; 87910037SARM gem5 Developers return fp64_zero(sgn); 88010037SARM gem5 Developers } 88110037SARM gem5 Developers 88213118SEdmund.Grimley-Evans@arm.com // The bottom FP64_EXP_BITS bits of mnt are orred together: 88313118SEdmund.Grimley-Evans@arm.com mnt = (4ULL << FP64_MANT_BITS | mnt >> (FP64_EXP_BITS - 1) | 88413118SEdmund.Grimley-Evans@arm.com ((mnt & ((1ULL << FP64_EXP_BITS) - 1)) != 0)); 88510037SARM gem5 Developers 88610037SARM gem5 Developers if (exp > 0) { 88710037SARM gem5 Developers biased_exp = exp; 88810037SARM gem5 Developers int_mant = mnt >> 2; 88910037SARM gem5 Developers error = mnt & 3; 89010037SARM gem5 Developers } else { 89110037SARM gem5 Developers biased_exp = 0; 89210037SARM gem5 Developers int_mant = lsr64(mnt, 3 - exp); 89310037SARM gem5 Developers error = (lsr64(mnt, 1 - exp) & 3) | !!(mnt & (lsl64(1, 1 - exp) - 1)); 89410037SARM gem5 Developers } 89510037SARM gem5 Developers 89610037SARM gem5 Developers if (!biased_exp && error) { // xx should also check fpscr_val<11> 89710037SARM gem5 Developers *flags |= FPLIB_UFC; 89810037SARM gem5 Developers } 89910037SARM gem5 Developers 90010037SARM gem5 Developers // Round up: 90110037SARM gem5 Developers if ((rm == FPLIB_RN && (error == 3 || 90210037SARM gem5 Developers (error == 2 && (int_mant & 1)))) || 90310037SARM gem5 Developers (((rm == FPLIB_RP && !sgn) || (rm == FPLIB_RM && sgn)) && error)) { 90410037SARM gem5 Developers ++int_mant; 90513118SEdmund.Grimley-Evans@arm.com if (int_mant == 1ULL << FP64_MANT_BITS) { 90610037SARM gem5 Developers // Rounded up from denormalized to normalized 90710037SARM gem5 Developers biased_exp = 1; 90810037SARM gem5 Developers } 90913118SEdmund.Grimley-Evans@arm.com if (int_mant == 2ULL << FP64_MANT_BITS) { 91010037SARM gem5 Developers // Rounded up to next exponent 91110037SARM gem5 Developers ++biased_exp; 91210037SARM gem5 Developers int_mant >>= 1; 91310037SARM gem5 Developers } 91410037SARM gem5 Developers } 91510037SARM gem5 Developers 91610037SARM gem5 Developers // Handle rounding to odd aka Von Neumann rounding: 91710037SARM gem5 Developers if (error && rm == FPRounding_ODD) 91810037SARM gem5 Developers int_mant |= 1; 91910037SARM gem5 Developers 92010037SARM gem5 Developers // Handle overflow: 92113118SEdmund.Grimley-Evans@arm.com if (biased_exp >= (int)FP64_EXP_INF) { 92210037SARM gem5 Developers *flags |= FPLIB_OFC | FPLIB_IXC; 92310037SARM gem5 Developers if (rm == FPLIB_RN || (rm == FPLIB_RP && !sgn) || 92410037SARM gem5 Developers (rm == FPLIB_RM && sgn)) { 92510037SARM gem5 Developers return fp64_infinity(sgn); 92610037SARM gem5 Developers } else { 92710037SARM gem5 Developers return fp64_max_normal(sgn); 92810037SARM gem5 Developers } 92910037SARM gem5 Developers } 93010037SARM gem5 Developers 93110037SARM gem5 Developers if (error) { 93210037SARM gem5 Developers *flags |= FPLIB_IXC; 93310037SARM gem5 Developers } 93410037SARM gem5 Developers 93510037SARM gem5 Developers return fp64_pack(sgn, biased_exp, int_mant); 93610037SARM gem5 Developers} 93710037SARM gem5 Developers 93810037SARM gem5 Developersstatic uint64_t 93910037SARM gem5 Developersfp64_round(int sgn, int exp, uint64_t mnt, int mode, int *flags) 94010037SARM gem5 Developers{ 94110037SARM gem5 Developers return fp64_round_(sgn, exp, mnt, mode & 3, mode, flags); 94210037SARM gem5 Developers} 94310037SARM gem5 Developers 94410037SARM gem5 Developersstatic int 94513118SEdmund.Grimley-Evans@arm.comfp16_compare_eq(uint16_t a, uint16_t b, int mode, int *flags) 94610037SARM gem5 Developers{ 94710037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp; 94813118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt; 94913118SEdmund.Grimley-Evans@arm.com 95013118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 95113118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 95213118SEdmund.Grimley-Evans@arm.com 95313118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt) || 95413118SEdmund.Grimley-Evans@arm.com fp16_is_NaN(b_exp, b_mnt)) { 95513118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(a_exp, a_mnt) || 95613118SEdmund.Grimley-Evans@arm.com fp16_is_signalling_NaN(b_exp, b_mnt)) 95710037SARM gem5 Developers *flags |= FPLIB_IOC; 95810037SARM gem5 Developers return 0; 95910037SARM gem5 Developers } 96010037SARM gem5 Developers return a == b || (!a_mnt && !b_mnt); 96110037SARM gem5 Developers} 96210037SARM gem5 Developers 96310037SARM gem5 Developersstatic int 96413118SEdmund.Grimley-Evans@arm.comfp16_compare_ge(uint16_t a, uint16_t b, int mode, int *flags) 96510037SARM gem5 Developers{ 96610037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp; 96713118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt; 96813118SEdmund.Grimley-Evans@arm.com 96913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 97013118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 97113118SEdmund.Grimley-Evans@arm.com 97213118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt) || 97313118SEdmund.Grimley-Evans@arm.com fp16_is_NaN(b_exp, b_mnt)) { 97410037SARM gem5 Developers *flags |= FPLIB_IOC; 97510037SARM gem5 Developers return 0; 97610037SARM gem5 Developers } 97710037SARM gem5 Developers if (!a_mnt && !b_mnt) 97810037SARM gem5 Developers return 1; 97910037SARM gem5 Developers if (a_sgn != b_sgn) 98010037SARM gem5 Developers return b_sgn; 98110037SARM gem5 Developers if (a_exp != b_exp) 98210037SARM gem5 Developers return a_sgn ^ (a_exp > b_exp); 98310037SARM gem5 Developers if (a_mnt != b_mnt) 98410037SARM gem5 Developers return a_sgn ^ (a_mnt > b_mnt); 98510037SARM gem5 Developers return 1; 98610037SARM gem5 Developers} 98710037SARM gem5 Developers 98810037SARM gem5 Developersstatic int 98913118SEdmund.Grimley-Evans@arm.comfp16_compare_gt(uint16_t a, uint16_t b, int mode, int *flags) 99010037SARM gem5 Developers{ 99110037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp; 99213118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt; 99313118SEdmund.Grimley-Evans@arm.com 99413118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 99513118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 99613118SEdmund.Grimley-Evans@arm.com 99713118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt) || 99813118SEdmund.Grimley-Evans@arm.com fp16_is_NaN(b_exp, b_mnt)) { 99910037SARM gem5 Developers *flags |= FPLIB_IOC; 100010037SARM gem5 Developers return 0; 100110037SARM gem5 Developers } 100210037SARM gem5 Developers if (!a_mnt && !b_mnt) 100310037SARM gem5 Developers return 0; 100410037SARM gem5 Developers if (a_sgn != b_sgn) 100510037SARM gem5 Developers return b_sgn; 100610037SARM gem5 Developers if (a_exp != b_exp) 100710037SARM gem5 Developers return a_sgn ^ (a_exp > b_exp); 100810037SARM gem5 Developers if (a_mnt != b_mnt) 100910037SARM gem5 Developers return a_sgn ^ (a_mnt > b_mnt); 101010037SARM gem5 Developers return 0; 101110037SARM gem5 Developers} 101210037SARM gem5 Developers 101310037SARM gem5 Developersstatic int 101413118SEdmund.Grimley-Evans@arm.comfp16_compare_un(uint16_t a, uint16_t b, int mode, int *flags) 101510037SARM gem5 Developers{ 101610037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp; 101713118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt; 101813118SEdmund.Grimley-Evans@arm.com 101913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 102013118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 102113118SEdmund.Grimley-Evans@arm.com 102213118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt) || 102313118SEdmund.Grimley-Evans@arm.com fp16_is_NaN(b_exp, b_mnt)) { 102413118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(a_exp, a_mnt) || 102513118SEdmund.Grimley-Evans@arm.com fp16_is_signalling_NaN(b_exp, b_mnt)) 102613118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 102713118SEdmund.Grimley-Evans@arm.com return 1; 102813118SEdmund.Grimley-Evans@arm.com } 102913118SEdmund.Grimley-Evans@arm.com return 0; 103013118SEdmund.Grimley-Evans@arm.com} 103113118SEdmund.Grimley-Evans@arm.com 103213118SEdmund.Grimley-Evans@arm.comstatic int 103313118SEdmund.Grimley-Evans@arm.comfp32_compare_eq(uint32_t a, uint32_t b, int mode, int *flags) 103413118SEdmund.Grimley-Evans@arm.com{ 103513118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp; 103613118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt, b_mnt; 103713118SEdmund.Grimley-Evans@arm.com 103813118SEdmund.Grimley-Evans@arm.com fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 103913118SEdmund.Grimley-Evans@arm.com fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 104013118SEdmund.Grimley-Evans@arm.com 104113118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt) || 104213118SEdmund.Grimley-Evans@arm.com fp32_is_NaN(b_exp, b_mnt)) { 104313118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(a_exp, a_mnt) || 104413118SEdmund.Grimley-Evans@arm.com fp32_is_signalling_NaN(b_exp, b_mnt)) 104510037SARM gem5 Developers *flags |= FPLIB_IOC; 104610037SARM gem5 Developers return 0; 104710037SARM gem5 Developers } 104810037SARM gem5 Developers return a == b || (!a_mnt && !b_mnt); 104910037SARM gem5 Developers} 105010037SARM gem5 Developers 105110037SARM gem5 Developersstatic int 105213118SEdmund.Grimley-Evans@arm.comfp32_compare_ge(uint32_t a, uint32_t b, int mode, int *flags) 105310037SARM gem5 Developers{ 105410037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp; 105513118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt, b_mnt; 105613118SEdmund.Grimley-Evans@arm.com 105713118SEdmund.Grimley-Evans@arm.com fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 105813118SEdmund.Grimley-Evans@arm.com fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 105913118SEdmund.Grimley-Evans@arm.com 106013118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt) || 106113118SEdmund.Grimley-Evans@arm.com fp32_is_NaN(b_exp, b_mnt)) { 106210037SARM gem5 Developers *flags |= FPLIB_IOC; 106310037SARM gem5 Developers return 0; 106410037SARM gem5 Developers } 106510037SARM gem5 Developers if (!a_mnt && !b_mnt) 106610037SARM gem5 Developers return 1; 106710037SARM gem5 Developers if (a_sgn != b_sgn) 106810037SARM gem5 Developers return b_sgn; 106910037SARM gem5 Developers if (a_exp != b_exp) 107010037SARM gem5 Developers return a_sgn ^ (a_exp > b_exp); 107110037SARM gem5 Developers if (a_mnt != b_mnt) 107210037SARM gem5 Developers return a_sgn ^ (a_mnt > b_mnt); 107310037SARM gem5 Developers return 1; 107410037SARM gem5 Developers} 107510037SARM gem5 Developers 107610037SARM gem5 Developersstatic int 107713118SEdmund.Grimley-Evans@arm.comfp32_compare_gt(uint32_t a, uint32_t b, int mode, int *flags) 107810037SARM gem5 Developers{ 107910037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp; 108013118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt, b_mnt; 108113118SEdmund.Grimley-Evans@arm.com 108213118SEdmund.Grimley-Evans@arm.com fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 108313118SEdmund.Grimley-Evans@arm.com fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 108413118SEdmund.Grimley-Evans@arm.com 108513118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt) || 108613118SEdmund.Grimley-Evans@arm.com fp32_is_NaN(b_exp, b_mnt)) { 108710037SARM gem5 Developers *flags |= FPLIB_IOC; 108810037SARM gem5 Developers return 0; 108910037SARM gem5 Developers } 109010037SARM gem5 Developers if (!a_mnt && !b_mnt) 109110037SARM gem5 Developers return 0; 109210037SARM gem5 Developers if (a_sgn != b_sgn) 109310037SARM gem5 Developers return b_sgn; 109410037SARM gem5 Developers if (a_exp != b_exp) 109510037SARM gem5 Developers return a_sgn ^ (a_exp > b_exp); 109610037SARM gem5 Developers if (a_mnt != b_mnt) 109710037SARM gem5 Developers return a_sgn ^ (a_mnt > b_mnt); 109810037SARM gem5 Developers return 0; 109910037SARM gem5 Developers} 110010037SARM gem5 Developers 110113118SEdmund.Grimley-Evans@arm.comstatic int 110213118SEdmund.Grimley-Evans@arm.comfp32_compare_un(uint32_t a, uint32_t b, int mode, int *flags) 110313118SEdmund.Grimley-Evans@arm.com{ 110413118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp; 110513118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt, b_mnt; 110613118SEdmund.Grimley-Evans@arm.com 110713118SEdmund.Grimley-Evans@arm.com fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 110813118SEdmund.Grimley-Evans@arm.com fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 110913118SEdmund.Grimley-Evans@arm.com 111013118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt) || 111113118SEdmund.Grimley-Evans@arm.com fp32_is_NaN(b_exp, b_mnt)) { 111213118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(a_exp, a_mnt) || 111313118SEdmund.Grimley-Evans@arm.com fp32_is_signalling_NaN(b_exp, b_mnt)) 111413118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 111513118SEdmund.Grimley-Evans@arm.com return 1; 111613118SEdmund.Grimley-Evans@arm.com } 111713118SEdmund.Grimley-Evans@arm.com return 0; 111813118SEdmund.Grimley-Evans@arm.com} 111913118SEdmund.Grimley-Evans@arm.com 112013118SEdmund.Grimley-Evans@arm.comstatic int 112113118SEdmund.Grimley-Evans@arm.comfp64_compare_eq(uint64_t a, uint64_t b, int mode, int *flags) 112213118SEdmund.Grimley-Evans@arm.com{ 112313118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp; 112413118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt, b_mnt; 112513118SEdmund.Grimley-Evans@arm.com 112613118SEdmund.Grimley-Evans@arm.com fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 112713118SEdmund.Grimley-Evans@arm.com fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 112813118SEdmund.Grimley-Evans@arm.com 112913118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt) || 113013118SEdmund.Grimley-Evans@arm.com fp64_is_NaN(b_exp, b_mnt)) { 113113118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(a_exp, a_mnt) || 113213118SEdmund.Grimley-Evans@arm.com fp64_is_signalling_NaN(b_exp, b_mnt)) 113313118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 113413118SEdmund.Grimley-Evans@arm.com return 0; 113513118SEdmund.Grimley-Evans@arm.com } 113613118SEdmund.Grimley-Evans@arm.com return a == b || (!a_mnt && !b_mnt); 113713118SEdmund.Grimley-Evans@arm.com} 113813118SEdmund.Grimley-Evans@arm.com 113913118SEdmund.Grimley-Evans@arm.comstatic int 114013118SEdmund.Grimley-Evans@arm.comfp64_compare_ge(uint64_t a, uint64_t b, int mode, int *flags) 114113118SEdmund.Grimley-Evans@arm.com{ 114213118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp; 114313118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt, b_mnt; 114413118SEdmund.Grimley-Evans@arm.com 114513118SEdmund.Grimley-Evans@arm.com fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 114613118SEdmund.Grimley-Evans@arm.com fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 114713118SEdmund.Grimley-Evans@arm.com 114813118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt) || 114913118SEdmund.Grimley-Evans@arm.com fp64_is_NaN(b_exp, b_mnt)) { 115013118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 115113118SEdmund.Grimley-Evans@arm.com return 0; 115213118SEdmund.Grimley-Evans@arm.com } 115313118SEdmund.Grimley-Evans@arm.com if (!a_mnt && !b_mnt) 115413118SEdmund.Grimley-Evans@arm.com return 1; 115513118SEdmund.Grimley-Evans@arm.com if (a_sgn != b_sgn) 115613118SEdmund.Grimley-Evans@arm.com return b_sgn; 115713118SEdmund.Grimley-Evans@arm.com if (a_exp != b_exp) 115813118SEdmund.Grimley-Evans@arm.com return a_sgn ^ (a_exp > b_exp); 115913118SEdmund.Grimley-Evans@arm.com if (a_mnt != b_mnt) 116013118SEdmund.Grimley-Evans@arm.com return a_sgn ^ (a_mnt > b_mnt); 116113118SEdmund.Grimley-Evans@arm.com return 1; 116213118SEdmund.Grimley-Evans@arm.com} 116313118SEdmund.Grimley-Evans@arm.com 116413118SEdmund.Grimley-Evans@arm.comstatic int 116513118SEdmund.Grimley-Evans@arm.comfp64_compare_gt(uint64_t a, uint64_t b, int mode, int *flags) 116613118SEdmund.Grimley-Evans@arm.com{ 116713118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp; 116813118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt, b_mnt; 116913118SEdmund.Grimley-Evans@arm.com 117013118SEdmund.Grimley-Evans@arm.com fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 117113118SEdmund.Grimley-Evans@arm.com fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 117213118SEdmund.Grimley-Evans@arm.com 117313118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt) || 117413118SEdmund.Grimley-Evans@arm.com fp64_is_NaN(b_exp, b_mnt)) { 117513118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 117613118SEdmund.Grimley-Evans@arm.com return 0; 117713118SEdmund.Grimley-Evans@arm.com } 117813118SEdmund.Grimley-Evans@arm.com if (!a_mnt && !b_mnt) 117913118SEdmund.Grimley-Evans@arm.com return 0; 118013118SEdmund.Grimley-Evans@arm.com if (a_sgn != b_sgn) 118113118SEdmund.Grimley-Evans@arm.com return b_sgn; 118213118SEdmund.Grimley-Evans@arm.com if (a_exp != b_exp) 118313118SEdmund.Grimley-Evans@arm.com return a_sgn ^ (a_exp > b_exp); 118413118SEdmund.Grimley-Evans@arm.com if (a_mnt != b_mnt) 118513118SEdmund.Grimley-Evans@arm.com return a_sgn ^ (a_mnt > b_mnt); 118613118SEdmund.Grimley-Evans@arm.com return 0; 118713118SEdmund.Grimley-Evans@arm.com} 118813118SEdmund.Grimley-Evans@arm.com 118913118SEdmund.Grimley-Evans@arm.comstatic int 119013118SEdmund.Grimley-Evans@arm.comfp64_compare_un(uint64_t a, uint64_t b, int mode, int *flags) 119113118SEdmund.Grimley-Evans@arm.com{ 119213118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp; 119313118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt, b_mnt; 119413118SEdmund.Grimley-Evans@arm.com 119513118SEdmund.Grimley-Evans@arm.com fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 119613118SEdmund.Grimley-Evans@arm.com fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 119713118SEdmund.Grimley-Evans@arm.com 119813118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt) || 119913118SEdmund.Grimley-Evans@arm.com fp64_is_NaN(b_exp, b_mnt)) { 120013118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(a_exp, a_mnt) || 120113118SEdmund.Grimley-Evans@arm.com fp64_is_signalling_NaN(b_exp, b_mnt)) 120213118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 120313118SEdmund.Grimley-Evans@arm.com return 1; 120413118SEdmund.Grimley-Evans@arm.com } 120513118SEdmund.Grimley-Evans@arm.com return 0; 120613118SEdmund.Grimley-Evans@arm.com} 120713118SEdmund.Grimley-Evans@arm.com 120813118SEdmund.Grimley-Evans@arm.comstatic uint16_t 120913118SEdmund.Grimley-Evans@arm.comfp16_add(uint16_t a, uint16_t b, int neg, int mode, int *flags) 121013118SEdmund.Grimley-Evans@arm.com{ 121113118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 121213118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt, x, x_mnt; 121313118SEdmund.Grimley-Evans@arm.com 121413118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 121513118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 121613118SEdmund.Grimley-Evans@arm.com 121713118SEdmund.Grimley-Evans@arm.com if ((x = fp16_process_NaNs(a, b, mode, flags))) { 121813118SEdmund.Grimley-Evans@arm.com return x; 121913118SEdmund.Grimley-Evans@arm.com } 122013118SEdmund.Grimley-Evans@arm.com 122113118SEdmund.Grimley-Evans@arm.com b_sgn ^= neg; 122213118SEdmund.Grimley-Evans@arm.com 122313118SEdmund.Grimley-Evans@arm.com // Handle infinities and zeroes: 122413118SEdmund.Grimley-Evans@arm.com if (a_exp == FP16_EXP_INF && b_exp == FP16_EXP_INF && a_sgn != b_sgn) { 122513118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 122613118SEdmund.Grimley-Evans@arm.com return fp16_defaultNaN(); 122713118SEdmund.Grimley-Evans@arm.com } else if (a_exp == FP16_EXP_INF) { 122813118SEdmund.Grimley-Evans@arm.com return fp16_infinity(a_sgn); 122913118SEdmund.Grimley-Evans@arm.com } else if (b_exp == FP16_EXP_INF) { 123013118SEdmund.Grimley-Evans@arm.com return fp16_infinity(b_sgn); 123113118SEdmund.Grimley-Evans@arm.com } else if (!a_mnt && !b_mnt && a_sgn == b_sgn) { 123213118SEdmund.Grimley-Evans@arm.com return fp16_zero(a_sgn); 123313118SEdmund.Grimley-Evans@arm.com } 123413118SEdmund.Grimley-Evans@arm.com 123513118SEdmund.Grimley-Evans@arm.com a_mnt <<= 3; 123613118SEdmund.Grimley-Evans@arm.com b_mnt <<= 3; 123713118SEdmund.Grimley-Evans@arm.com if (a_exp >= b_exp) { 123813118SEdmund.Grimley-Evans@arm.com b_mnt = (lsr16(b_mnt, a_exp - b_exp) | 123913118SEdmund.Grimley-Evans@arm.com !!(b_mnt & (lsl16(1, a_exp - b_exp) - 1))); 124013118SEdmund.Grimley-Evans@arm.com b_exp = a_exp; 124113118SEdmund.Grimley-Evans@arm.com } else { 124213118SEdmund.Grimley-Evans@arm.com a_mnt = (lsr16(a_mnt, b_exp - a_exp) | 124313118SEdmund.Grimley-Evans@arm.com !!(a_mnt & (lsl16(1, b_exp - a_exp) - 1))); 124413118SEdmund.Grimley-Evans@arm.com a_exp = b_exp; 124513118SEdmund.Grimley-Evans@arm.com } 124613118SEdmund.Grimley-Evans@arm.com x_sgn = a_sgn; 124713118SEdmund.Grimley-Evans@arm.com x_exp = a_exp; 124813118SEdmund.Grimley-Evans@arm.com if (a_sgn == b_sgn) { 124913118SEdmund.Grimley-Evans@arm.com x_mnt = a_mnt + b_mnt; 125013118SEdmund.Grimley-Evans@arm.com } else if (a_mnt >= b_mnt) { 125113118SEdmund.Grimley-Evans@arm.com x_mnt = a_mnt - b_mnt; 125213118SEdmund.Grimley-Evans@arm.com } else { 125313118SEdmund.Grimley-Evans@arm.com x_sgn ^= 1; 125413118SEdmund.Grimley-Evans@arm.com x_mnt = b_mnt - a_mnt; 125513118SEdmund.Grimley-Evans@arm.com } 125613118SEdmund.Grimley-Evans@arm.com 125713118SEdmund.Grimley-Evans@arm.com if (!x_mnt) { 125813118SEdmund.Grimley-Evans@arm.com // Sign of exact zero result depends on rounding mode 125913118SEdmund.Grimley-Evans@arm.com return fp16_zero((mode & 3) == 2); 126013118SEdmund.Grimley-Evans@arm.com } 126113118SEdmund.Grimley-Evans@arm.com 126213118SEdmund.Grimley-Evans@arm.com x_mnt = fp16_normalise(x_mnt, &x_exp); 126313118SEdmund.Grimley-Evans@arm.com 126413118SEdmund.Grimley-Evans@arm.com return fp16_round(x_sgn, x_exp + FP16_EXP_BITS - 3, x_mnt << 1, 126513118SEdmund.Grimley-Evans@arm.com mode, flags); 126613118SEdmund.Grimley-Evans@arm.com} 126713118SEdmund.Grimley-Evans@arm.com 126810037SARM gem5 Developersstatic uint32_t 126910037SARM gem5 Developersfp32_add(uint32_t a, uint32_t b, int neg, int mode, int *flags) 127010037SARM gem5 Developers{ 127110037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 127210037SARM gem5 Developers uint32_t a_mnt, b_mnt, x, x_mnt; 127310037SARM gem5 Developers 127410037SARM gem5 Developers fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 127510037SARM gem5 Developers fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 127610037SARM gem5 Developers 127710037SARM gem5 Developers if ((x = fp32_process_NaNs(a, b, mode, flags))) { 127810037SARM gem5 Developers return x; 127910037SARM gem5 Developers } 128010037SARM gem5 Developers 128110037SARM gem5 Developers b_sgn ^= neg; 128210037SARM gem5 Developers 128310037SARM gem5 Developers // Handle infinities and zeroes: 128413118SEdmund.Grimley-Evans@arm.com if (a_exp == FP32_EXP_INF && b_exp == FP32_EXP_INF && a_sgn != b_sgn) { 128510037SARM gem5 Developers *flags |= FPLIB_IOC; 128610037SARM gem5 Developers return fp32_defaultNaN(); 128713118SEdmund.Grimley-Evans@arm.com } else if (a_exp == FP32_EXP_INF) { 128810037SARM gem5 Developers return fp32_infinity(a_sgn); 128913118SEdmund.Grimley-Evans@arm.com } else if (b_exp == FP32_EXP_INF) { 129010037SARM gem5 Developers return fp32_infinity(b_sgn); 129110037SARM gem5 Developers } else if (!a_mnt && !b_mnt && a_sgn == b_sgn) { 129210037SARM gem5 Developers return fp32_zero(a_sgn); 129310037SARM gem5 Developers } 129410037SARM gem5 Developers 129510037SARM gem5 Developers a_mnt <<= 3; 129610037SARM gem5 Developers b_mnt <<= 3; 129710037SARM gem5 Developers if (a_exp >= b_exp) { 129810037SARM gem5 Developers b_mnt = (lsr32(b_mnt, a_exp - b_exp) | 129910037SARM gem5 Developers !!(b_mnt & (lsl32(1, a_exp - b_exp) - 1))); 130010037SARM gem5 Developers b_exp = a_exp; 130110037SARM gem5 Developers } else { 130210037SARM gem5 Developers a_mnt = (lsr32(a_mnt, b_exp - a_exp) | 130310037SARM gem5 Developers !!(a_mnt & (lsl32(1, b_exp - a_exp) - 1))); 130410037SARM gem5 Developers a_exp = b_exp; 130510037SARM gem5 Developers } 130610037SARM gem5 Developers x_sgn = a_sgn; 130710037SARM gem5 Developers x_exp = a_exp; 130810037SARM gem5 Developers if (a_sgn == b_sgn) { 130910037SARM gem5 Developers x_mnt = a_mnt + b_mnt; 131010037SARM gem5 Developers } else if (a_mnt >= b_mnt) { 131110037SARM gem5 Developers x_mnt = a_mnt - b_mnt; 131210037SARM gem5 Developers } else { 131310037SARM gem5 Developers x_sgn ^= 1; 131410037SARM gem5 Developers x_mnt = b_mnt - a_mnt; 131510037SARM gem5 Developers } 131610037SARM gem5 Developers 131710037SARM gem5 Developers if (!x_mnt) { 131810037SARM gem5 Developers // Sign of exact zero result depends on rounding mode 131910037SARM gem5 Developers return fp32_zero((mode & 3) == 2); 132010037SARM gem5 Developers } 132110037SARM gem5 Developers 132210037SARM gem5 Developers x_mnt = fp32_normalise(x_mnt, &x_exp); 132310037SARM gem5 Developers 132413118SEdmund.Grimley-Evans@arm.com return fp32_round(x_sgn, x_exp + FP32_EXP_BITS - 3, x_mnt << 1, 132513118SEdmund.Grimley-Evans@arm.com mode, flags); 132610037SARM gem5 Developers} 132710037SARM gem5 Developers 132810037SARM gem5 Developersstatic uint64_t 132910037SARM gem5 Developersfp64_add(uint64_t a, uint64_t b, int neg, int mode, int *flags) 133010037SARM gem5 Developers{ 133110037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 133210037SARM gem5 Developers uint64_t a_mnt, b_mnt, x, x_mnt; 133310037SARM gem5 Developers 133410037SARM gem5 Developers fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 133510037SARM gem5 Developers fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 133610037SARM gem5 Developers 133710037SARM gem5 Developers if ((x = fp64_process_NaNs(a, b, mode, flags))) { 133810037SARM gem5 Developers return x; 133910037SARM gem5 Developers } 134010037SARM gem5 Developers 134110037SARM gem5 Developers b_sgn ^= neg; 134210037SARM gem5 Developers 134310037SARM gem5 Developers // Handle infinities and zeroes: 134413118SEdmund.Grimley-Evans@arm.com if (a_exp == FP64_EXP_INF && b_exp == FP64_EXP_INF && a_sgn != b_sgn) { 134510037SARM gem5 Developers *flags |= FPLIB_IOC; 134610037SARM gem5 Developers return fp64_defaultNaN(); 134713118SEdmund.Grimley-Evans@arm.com } else if (a_exp == FP64_EXP_INF) { 134810037SARM gem5 Developers return fp64_infinity(a_sgn); 134913118SEdmund.Grimley-Evans@arm.com } else if (b_exp == FP64_EXP_INF) { 135010037SARM gem5 Developers return fp64_infinity(b_sgn); 135110037SARM gem5 Developers } else if (!a_mnt && !b_mnt && a_sgn == b_sgn) { 135210037SARM gem5 Developers return fp64_zero(a_sgn); 135310037SARM gem5 Developers } 135410037SARM gem5 Developers 135510037SARM gem5 Developers a_mnt <<= 3; 135610037SARM gem5 Developers b_mnt <<= 3; 135710037SARM gem5 Developers if (a_exp >= b_exp) { 135810037SARM gem5 Developers b_mnt = (lsr64(b_mnt, a_exp - b_exp) | 135910037SARM gem5 Developers !!(b_mnt & (lsl64(1, a_exp - b_exp) - 1))); 136010037SARM gem5 Developers b_exp = a_exp; 136110037SARM gem5 Developers } else { 136210037SARM gem5 Developers a_mnt = (lsr64(a_mnt, b_exp - a_exp) | 136310037SARM gem5 Developers !!(a_mnt & (lsl64(1, b_exp - a_exp) - 1))); 136410037SARM gem5 Developers a_exp = b_exp; 136510037SARM gem5 Developers } 136610037SARM gem5 Developers x_sgn = a_sgn; 136710037SARM gem5 Developers x_exp = a_exp; 136810037SARM gem5 Developers if (a_sgn == b_sgn) { 136910037SARM gem5 Developers x_mnt = a_mnt + b_mnt; 137010037SARM gem5 Developers } else if (a_mnt >= b_mnt) { 137110037SARM gem5 Developers x_mnt = a_mnt - b_mnt; 137210037SARM gem5 Developers } else { 137310037SARM gem5 Developers x_sgn ^= 1; 137410037SARM gem5 Developers x_mnt = b_mnt - a_mnt; 137510037SARM gem5 Developers } 137610037SARM gem5 Developers 137710037SARM gem5 Developers if (!x_mnt) { 137810037SARM gem5 Developers // Sign of exact zero result depends on rounding mode 137910037SARM gem5 Developers return fp64_zero((mode & 3) == 2); 138010037SARM gem5 Developers } 138110037SARM gem5 Developers 138210037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 138310037SARM gem5 Developers 138413118SEdmund.Grimley-Evans@arm.com return fp64_round(x_sgn, x_exp + FP64_EXP_BITS - 3, x_mnt << 1, 138513118SEdmund.Grimley-Evans@arm.com mode, flags); 138613118SEdmund.Grimley-Evans@arm.com} 138713118SEdmund.Grimley-Evans@arm.com 138813118SEdmund.Grimley-Evans@arm.comstatic uint16_t 138913118SEdmund.Grimley-Evans@arm.comfp16_mul(uint16_t a, uint16_t b, int mode, int *flags) 139013118SEdmund.Grimley-Evans@arm.com{ 139113118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 139213118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt, x; 139313118SEdmund.Grimley-Evans@arm.com uint32_t x_mnt; 139413118SEdmund.Grimley-Evans@arm.com 139513118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 139613118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 139713118SEdmund.Grimley-Evans@arm.com 139813118SEdmund.Grimley-Evans@arm.com if ((x = fp16_process_NaNs(a, b, mode, flags))) { 139913118SEdmund.Grimley-Evans@arm.com return x; 140013118SEdmund.Grimley-Evans@arm.com } 140113118SEdmund.Grimley-Evans@arm.com 140213118SEdmund.Grimley-Evans@arm.com // Handle infinities and zeroes: 140313118SEdmund.Grimley-Evans@arm.com if ((a_exp == FP16_EXP_INF && !b_mnt) || 140413118SEdmund.Grimley-Evans@arm.com (b_exp == FP16_EXP_INF && !a_mnt)) { 140513118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 140613118SEdmund.Grimley-Evans@arm.com return fp16_defaultNaN(); 140713118SEdmund.Grimley-Evans@arm.com } else if (a_exp == FP16_EXP_INF || b_exp == FP16_EXP_INF) { 140813118SEdmund.Grimley-Evans@arm.com return fp16_infinity(a_sgn ^ b_sgn); 140913118SEdmund.Grimley-Evans@arm.com } else if (!a_mnt || !b_mnt) { 141013118SEdmund.Grimley-Evans@arm.com return fp16_zero(a_sgn ^ b_sgn); 141113118SEdmund.Grimley-Evans@arm.com } 141213118SEdmund.Grimley-Evans@arm.com 141313118SEdmund.Grimley-Evans@arm.com // Multiply and normalise: 141413118SEdmund.Grimley-Evans@arm.com x_sgn = a_sgn ^ b_sgn; 141513118SEdmund.Grimley-Evans@arm.com x_exp = a_exp + b_exp - FP16_EXP_BIAS + 2 * FP16_EXP_BITS + 1; 141613118SEdmund.Grimley-Evans@arm.com x_mnt = (uint32_t)a_mnt * b_mnt; 141713118SEdmund.Grimley-Evans@arm.com x_mnt = fp32_normalise(x_mnt, &x_exp); 141813118SEdmund.Grimley-Evans@arm.com 141913118SEdmund.Grimley-Evans@arm.com // Convert to FP16_BITS bits, collapsing error into bottom bit: 142013118SEdmund.Grimley-Evans@arm.com x_mnt = lsr32(x_mnt, FP16_BITS - 1) | !!lsl32(x_mnt, FP16_BITS + 1); 142113118SEdmund.Grimley-Evans@arm.com 142213118SEdmund.Grimley-Evans@arm.com return fp16_round(x_sgn, x_exp, x_mnt, mode, flags); 142310037SARM gem5 Developers} 142410037SARM gem5 Developers 142510037SARM gem5 Developersstatic uint32_t 142610037SARM gem5 Developersfp32_mul(uint32_t a, uint32_t b, int mode, int *flags) 142710037SARM gem5 Developers{ 142810037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 142910037SARM gem5 Developers uint32_t a_mnt, b_mnt, x; 143010037SARM gem5 Developers uint64_t x_mnt; 143110037SARM gem5 Developers 143210037SARM gem5 Developers fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 143310037SARM gem5 Developers fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 143410037SARM gem5 Developers 143510037SARM gem5 Developers if ((x = fp32_process_NaNs(a, b, mode, flags))) { 143610037SARM gem5 Developers return x; 143710037SARM gem5 Developers } 143810037SARM gem5 Developers 143910037SARM gem5 Developers // Handle infinities and zeroes: 144013118SEdmund.Grimley-Evans@arm.com if ((a_exp == FP32_EXP_INF && !b_mnt) || 144113118SEdmund.Grimley-Evans@arm.com (b_exp == FP32_EXP_INF && !a_mnt)) { 144210037SARM gem5 Developers *flags |= FPLIB_IOC; 144310037SARM gem5 Developers return fp32_defaultNaN(); 144413118SEdmund.Grimley-Evans@arm.com } else if (a_exp == FP32_EXP_INF || b_exp == FP32_EXP_INF) { 144510037SARM gem5 Developers return fp32_infinity(a_sgn ^ b_sgn); 144610037SARM gem5 Developers } else if (!a_mnt || !b_mnt) { 144710037SARM gem5 Developers return fp32_zero(a_sgn ^ b_sgn); 144810037SARM gem5 Developers } 144910037SARM gem5 Developers 145010037SARM gem5 Developers // Multiply and normalise: 145110037SARM gem5 Developers x_sgn = a_sgn ^ b_sgn; 145213118SEdmund.Grimley-Evans@arm.com x_exp = a_exp + b_exp - FP32_EXP_BIAS + 2 * FP32_EXP_BITS + 1; 145310037SARM gem5 Developers x_mnt = (uint64_t)a_mnt * b_mnt; 145410037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 145510037SARM gem5 Developers 145613118SEdmund.Grimley-Evans@arm.com // Convert to FP32_BITS bits, collapsing error into bottom bit: 145713118SEdmund.Grimley-Evans@arm.com x_mnt = lsr64(x_mnt, FP32_BITS - 1) | !!lsl64(x_mnt, FP32_BITS + 1); 145810037SARM gem5 Developers 145910037SARM gem5 Developers return fp32_round(x_sgn, x_exp, x_mnt, mode, flags); 146010037SARM gem5 Developers} 146110037SARM gem5 Developers 146210037SARM gem5 Developersstatic uint64_t 146310037SARM gem5 Developersfp64_mul(uint64_t a, uint64_t b, int mode, int *flags) 146410037SARM gem5 Developers{ 146510037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 146610037SARM gem5 Developers uint64_t a_mnt, b_mnt, x; 146710037SARM gem5 Developers uint64_t x0_mnt, x1_mnt; 146810037SARM gem5 Developers 146910037SARM gem5 Developers fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 147010037SARM gem5 Developers fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 147110037SARM gem5 Developers 147210037SARM gem5 Developers if ((x = fp64_process_NaNs(a, b, mode, flags))) { 147310037SARM gem5 Developers return x; 147410037SARM gem5 Developers } 147510037SARM gem5 Developers 147610037SARM gem5 Developers // Handle infinities and zeroes: 147713118SEdmund.Grimley-Evans@arm.com if ((a_exp == FP64_EXP_INF && !b_mnt) || 147813118SEdmund.Grimley-Evans@arm.com (b_exp == FP64_EXP_INF && !a_mnt)) { 147910037SARM gem5 Developers *flags |= FPLIB_IOC; 148010037SARM gem5 Developers return fp64_defaultNaN(); 148113118SEdmund.Grimley-Evans@arm.com } else if (a_exp == FP64_EXP_INF || b_exp == FP64_EXP_INF) { 148210037SARM gem5 Developers return fp64_infinity(a_sgn ^ b_sgn); 148310037SARM gem5 Developers } else if (!a_mnt || !b_mnt) { 148410037SARM gem5 Developers return fp64_zero(a_sgn ^ b_sgn); 148510037SARM gem5 Developers } 148610037SARM gem5 Developers 148710037SARM gem5 Developers // Multiply and normalise: 148810037SARM gem5 Developers x_sgn = a_sgn ^ b_sgn; 148913118SEdmund.Grimley-Evans@arm.com x_exp = a_exp + b_exp - FP64_EXP_BIAS + 2 * FP64_EXP_BITS + 1; 149010037SARM gem5 Developers mul62x62(&x0_mnt, &x1_mnt, a_mnt, b_mnt); 149110037SARM gem5 Developers fp128_normalise(&x0_mnt, &x1_mnt, &x_exp); 149210037SARM gem5 Developers 149313118SEdmund.Grimley-Evans@arm.com // Convert to FP64_BITS bits, collapsing error into bottom bit: 149410037SARM gem5 Developers x0_mnt = x1_mnt << 1 | !!x0_mnt; 149510037SARM gem5 Developers 149610037SARM gem5 Developers return fp64_round(x_sgn, x_exp, x0_mnt, mode, flags); 149710037SARM gem5 Developers} 149810037SARM gem5 Developers 149913118SEdmund.Grimley-Evans@arm.comstatic uint16_t 150013118SEdmund.Grimley-Evans@arm.comfp16_muladd(uint16_t a, uint16_t b, uint16_t c, int scale, 150113118SEdmund.Grimley-Evans@arm.com int mode, int *flags) 150213118SEdmund.Grimley-Evans@arm.com{ 150313118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp, c_sgn, c_exp, x_sgn, x_exp, y_sgn, y_exp; 150413118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt, c_mnt, x; 150513118SEdmund.Grimley-Evans@arm.com uint32_t x_mnt, y_mnt; 150613118SEdmund.Grimley-Evans@arm.com 150713118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 150813118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 150913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&c_sgn, &c_exp, &c_mnt, c, mode, flags); 151013118SEdmund.Grimley-Evans@arm.com 151113118SEdmund.Grimley-Evans@arm.com x = fp16_process_NaNs3(a, b, c, mode, flags); 151213118SEdmund.Grimley-Evans@arm.com 151313118SEdmund.Grimley-Evans@arm.com // Quiet NaN added to product of zero and infinity: 151413118SEdmund.Grimley-Evans@arm.com if (fp16_is_quiet_NaN(a_exp, a_mnt) && 151513118SEdmund.Grimley-Evans@arm.com ((!b_mnt && fp16_is_infinity(c_exp, c_mnt)) || 151613118SEdmund.Grimley-Evans@arm.com (!c_mnt && fp16_is_infinity(b_exp, b_mnt)))) { 151713118SEdmund.Grimley-Evans@arm.com x = fp16_defaultNaN(); 151813118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 151913118SEdmund.Grimley-Evans@arm.com } 152013118SEdmund.Grimley-Evans@arm.com 152113118SEdmund.Grimley-Evans@arm.com if (x) { 152213118SEdmund.Grimley-Evans@arm.com return x; 152313118SEdmund.Grimley-Evans@arm.com } 152413118SEdmund.Grimley-Evans@arm.com 152513118SEdmund.Grimley-Evans@arm.com // Handle infinities and zeroes: 152613118SEdmund.Grimley-Evans@arm.com if ((b_exp == FP16_EXP_INF && !c_mnt) || 152713118SEdmund.Grimley-Evans@arm.com (c_exp == FP16_EXP_INF && !b_mnt) || 152813118SEdmund.Grimley-Evans@arm.com (a_exp == FP16_EXP_INF && 152913118SEdmund.Grimley-Evans@arm.com (b_exp == FP16_EXP_INF || c_exp == FP16_EXP_INF) && 153013118SEdmund.Grimley-Evans@arm.com (a_sgn != (b_sgn ^ c_sgn)))) { 153113118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 153213118SEdmund.Grimley-Evans@arm.com return fp16_defaultNaN(); 153313118SEdmund.Grimley-Evans@arm.com } 153413118SEdmund.Grimley-Evans@arm.com if (a_exp == FP16_EXP_INF) 153513118SEdmund.Grimley-Evans@arm.com return fp16_infinity(a_sgn); 153613118SEdmund.Grimley-Evans@arm.com if (b_exp == FP16_EXP_INF || c_exp == FP16_EXP_INF) 153713118SEdmund.Grimley-Evans@arm.com return fp16_infinity(b_sgn ^ c_sgn); 153813118SEdmund.Grimley-Evans@arm.com if (!a_mnt && (!b_mnt || !c_mnt) && a_sgn == (b_sgn ^ c_sgn)) 153913118SEdmund.Grimley-Evans@arm.com return fp16_zero(a_sgn); 154013118SEdmund.Grimley-Evans@arm.com 154113118SEdmund.Grimley-Evans@arm.com x_sgn = a_sgn; 154213118SEdmund.Grimley-Evans@arm.com x_exp = a_exp + 2 * FP16_EXP_BITS - 3; 154313118SEdmund.Grimley-Evans@arm.com x_mnt = (uint32_t)a_mnt << (FP16_MANT_BITS + 4); 154413118SEdmund.Grimley-Evans@arm.com 154513118SEdmund.Grimley-Evans@arm.com // Multiply: 154613118SEdmund.Grimley-Evans@arm.com y_sgn = b_sgn ^ c_sgn; 154713118SEdmund.Grimley-Evans@arm.com y_exp = b_exp + c_exp - FP16_EXP_BIAS + 2 * FP16_EXP_BITS + 1 - 3; 154813118SEdmund.Grimley-Evans@arm.com y_mnt = (uint32_t)b_mnt * c_mnt << 3; 154913118SEdmund.Grimley-Evans@arm.com if (!y_mnt) { 155013118SEdmund.Grimley-Evans@arm.com y_exp = x_exp; 155113118SEdmund.Grimley-Evans@arm.com } 155213118SEdmund.Grimley-Evans@arm.com 155313118SEdmund.Grimley-Evans@arm.com // Add: 155413118SEdmund.Grimley-Evans@arm.com if (x_exp >= y_exp) { 155513118SEdmund.Grimley-Evans@arm.com y_mnt = (lsr32(y_mnt, x_exp - y_exp) | 155613118SEdmund.Grimley-Evans@arm.com !!(y_mnt & (lsl32(1, x_exp - y_exp) - 1))); 155713118SEdmund.Grimley-Evans@arm.com y_exp = x_exp; 155813118SEdmund.Grimley-Evans@arm.com } else { 155913118SEdmund.Grimley-Evans@arm.com x_mnt = (lsr32(x_mnt, y_exp - x_exp) | 156013118SEdmund.Grimley-Evans@arm.com !!(x_mnt & (lsl32(1, y_exp - x_exp) - 1))); 156113118SEdmund.Grimley-Evans@arm.com x_exp = y_exp; 156213118SEdmund.Grimley-Evans@arm.com } 156313118SEdmund.Grimley-Evans@arm.com if (x_sgn == y_sgn) { 156413118SEdmund.Grimley-Evans@arm.com x_mnt = x_mnt + y_mnt; 156513118SEdmund.Grimley-Evans@arm.com } else if (x_mnt >= y_mnt) { 156613118SEdmund.Grimley-Evans@arm.com x_mnt = x_mnt - y_mnt; 156713118SEdmund.Grimley-Evans@arm.com } else { 156813118SEdmund.Grimley-Evans@arm.com x_sgn ^= 1; 156913118SEdmund.Grimley-Evans@arm.com x_mnt = y_mnt - x_mnt; 157013118SEdmund.Grimley-Evans@arm.com } 157113118SEdmund.Grimley-Evans@arm.com 157213118SEdmund.Grimley-Evans@arm.com if (!x_mnt) { 157313118SEdmund.Grimley-Evans@arm.com // Sign of exact zero result depends on rounding mode 157413118SEdmund.Grimley-Evans@arm.com return fp16_zero((mode & 3) == 2); 157513118SEdmund.Grimley-Evans@arm.com } 157613118SEdmund.Grimley-Evans@arm.com 157713118SEdmund.Grimley-Evans@arm.com // Normalise into FP16_BITS bits, collapsing error into bottom bit: 157813118SEdmund.Grimley-Evans@arm.com x_mnt = fp32_normalise(x_mnt, &x_exp); 157913118SEdmund.Grimley-Evans@arm.com x_mnt = x_mnt >> (FP16_BITS - 1) | !!(uint16_t)(x_mnt << 1); 158013118SEdmund.Grimley-Evans@arm.com 158113118SEdmund.Grimley-Evans@arm.com return fp16_round(x_sgn, x_exp + scale, x_mnt, mode, flags); 158213118SEdmund.Grimley-Evans@arm.com} 158313118SEdmund.Grimley-Evans@arm.com 158410037SARM gem5 Developersstatic uint32_t 158510037SARM gem5 Developersfp32_muladd(uint32_t a, uint32_t b, uint32_t c, int scale, 158610037SARM gem5 Developers int mode, int *flags) 158710037SARM gem5 Developers{ 158810037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, c_sgn, c_exp, x_sgn, x_exp, y_sgn, y_exp; 158910037SARM gem5 Developers uint32_t a_mnt, b_mnt, c_mnt, x; 159010037SARM gem5 Developers uint64_t x_mnt, y_mnt; 159110037SARM gem5 Developers 159210037SARM gem5 Developers fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 159310037SARM gem5 Developers fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 159410037SARM gem5 Developers fp32_unpack(&c_sgn, &c_exp, &c_mnt, c, mode, flags); 159510037SARM gem5 Developers 159610037SARM gem5 Developers x = fp32_process_NaNs3(a, b, c, mode, flags); 159710037SARM gem5 Developers 159810037SARM gem5 Developers // Quiet NaN added to product of zero and infinity: 159913118SEdmund.Grimley-Evans@arm.com if (fp32_is_quiet_NaN(a_exp, a_mnt) && 160013118SEdmund.Grimley-Evans@arm.com ((!b_mnt && fp32_is_infinity(c_exp, c_mnt)) || 160113118SEdmund.Grimley-Evans@arm.com (!c_mnt && fp32_is_infinity(b_exp, b_mnt)))) { 160210037SARM gem5 Developers x = fp32_defaultNaN(); 160310037SARM gem5 Developers *flags |= FPLIB_IOC; 160410037SARM gem5 Developers } 160510037SARM gem5 Developers 160610037SARM gem5 Developers if (x) { 160710037SARM gem5 Developers return x; 160810037SARM gem5 Developers } 160910037SARM gem5 Developers 161010037SARM gem5 Developers // Handle infinities and zeroes: 161113118SEdmund.Grimley-Evans@arm.com if ((b_exp == FP32_EXP_INF && !c_mnt) || 161213118SEdmund.Grimley-Evans@arm.com (c_exp == FP32_EXP_INF && !b_mnt) || 161313118SEdmund.Grimley-Evans@arm.com (a_exp == FP32_EXP_INF && 161413118SEdmund.Grimley-Evans@arm.com (b_exp == FP32_EXP_INF || c_exp == FP32_EXP_INF) && 161510037SARM gem5 Developers (a_sgn != (b_sgn ^ c_sgn)))) { 161610037SARM gem5 Developers *flags |= FPLIB_IOC; 161710037SARM gem5 Developers return fp32_defaultNaN(); 161810037SARM gem5 Developers } 161913118SEdmund.Grimley-Evans@arm.com if (a_exp == FP32_EXP_INF) 162010037SARM gem5 Developers return fp32_infinity(a_sgn); 162113118SEdmund.Grimley-Evans@arm.com if (b_exp == FP32_EXP_INF || c_exp == FP32_EXP_INF) 162210037SARM gem5 Developers return fp32_infinity(b_sgn ^ c_sgn); 162310037SARM gem5 Developers if (!a_mnt && (!b_mnt || !c_mnt) && a_sgn == (b_sgn ^ c_sgn)) 162410037SARM gem5 Developers return fp32_zero(a_sgn); 162510037SARM gem5 Developers 162610037SARM gem5 Developers x_sgn = a_sgn; 162713118SEdmund.Grimley-Evans@arm.com x_exp = a_exp + 2 * FP32_EXP_BITS - 3; 162813118SEdmund.Grimley-Evans@arm.com x_mnt = (uint64_t)a_mnt << (FP32_MANT_BITS + 4); 162910037SARM gem5 Developers 163010037SARM gem5 Developers // Multiply: 163110037SARM gem5 Developers y_sgn = b_sgn ^ c_sgn; 163213118SEdmund.Grimley-Evans@arm.com y_exp = b_exp + c_exp - FP32_EXP_BIAS + 2 * FP32_EXP_BITS + 1 - 3; 163310037SARM gem5 Developers y_mnt = (uint64_t)b_mnt * c_mnt << 3; 163410037SARM gem5 Developers if (!y_mnt) { 163510037SARM gem5 Developers y_exp = x_exp; 163610037SARM gem5 Developers } 163710037SARM gem5 Developers 163810037SARM gem5 Developers // Add: 163910037SARM gem5 Developers if (x_exp >= y_exp) { 164010037SARM gem5 Developers y_mnt = (lsr64(y_mnt, x_exp - y_exp) | 164110037SARM gem5 Developers !!(y_mnt & (lsl64(1, x_exp - y_exp) - 1))); 164210037SARM gem5 Developers y_exp = x_exp; 164310037SARM gem5 Developers } else { 164410037SARM gem5 Developers x_mnt = (lsr64(x_mnt, y_exp - x_exp) | 164510037SARM gem5 Developers !!(x_mnt & (lsl64(1, y_exp - x_exp) - 1))); 164610037SARM gem5 Developers x_exp = y_exp; 164710037SARM gem5 Developers } 164810037SARM gem5 Developers if (x_sgn == y_sgn) { 164910037SARM gem5 Developers x_mnt = x_mnt + y_mnt; 165010037SARM gem5 Developers } else if (x_mnt >= y_mnt) { 165110037SARM gem5 Developers x_mnt = x_mnt - y_mnt; 165210037SARM gem5 Developers } else { 165310037SARM gem5 Developers x_sgn ^= 1; 165410037SARM gem5 Developers x_mnt = y_mnt - x_mnt; 165510037SARM gem5 Developers } 165610037SARM gem5 Developers 165710037SARM gem5 Developers if (!x_mnt) { 165810037SARM gem5 Developers // Sign of exact zero result depends on rounding mode 165910037SARM gem5 Developers return fp32_zero((mode & 3) == 2); 166010037SARM gem5 Developers } 166110037SARM gem5 Developers 166213118SEdmund.Grimley-Evans@arm.com // Normalise into FP32_BITS bits, collapsing error into bottom bit: 166310037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 166413118SEdmund.Grimley-Evans@arm.com x_mnt = x_mnt >> (FP32_BITS - 1) | !!(uint32_t)(x_mnt << 1); 166510037SARM gem5 Developers 166610037SARM gem5 Developers return fp32_round(x_sgn, x_exp + scale, x_mnt, mode, flags); 166710037SARM gem5 Developers} 166810037SARM gem5 Developers 166910037SARM gem5 Developersstatic uint64_t 167010037SARM gem5 Developersfp64_muladd(uint64_t a, uint64_t b, uint64_t c, int scale, 167110037SARM gem5 Developers int mode, int *flags) 167210037SARM gem5 Developers{ 167310037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, c_sgn, c_exp, x_sgn, x_exp, y_sgn, y_exp; 167410037SARM gem5 Developers uint64_t a_mnt, b_mnt, c_mnt, x; 167510037SARM gem5 Developers uint64_t x0_mnt, x1_mnt, y0_mnt, y1_mnt; 167610037SARM gem5 Developers 167710037SARM gem5 Developers fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 167810037SARM gem5 Developers fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 167910037SARM gem5 Developers fp64_unpack(&c_sgn, &c_exp, &c_mnt, c, mode, flags); 168010037SARM gem5 Developers 168110037SARM gem5 Developers x = fp64_process_NaNs3(a, b, c, mode, flags); 168210037SARM gem5 Developers 168310037SARM gem5 Developers // Quiet NaN added to product of zero and infinity: 168413118SEdmund.Grimley-Evans@arm.com if (fp64_is_quiet_NaN(a_exp, a_mnt) && 168513118SEdmund.Grimley-Evans@arm.com ((!b_mnt && fp64_is_infinity(c_exp, c_mnt)) || 168613118SEdmund.Grimley-Evans@arm.com (!c_mnt && fp64_is_infinity(b_exp, b_mnt)))) { 168710037SARM gem5 Developers x = fp64_defaultNaN(); 168810037SARM gem5 Developers *flags |= FPLIB_IOC; 168910037SARM gem5 Developers } 169010037SARM gem5 Developers 169110037SARM gem5 Developers if (x) { 169210037SARM gem5 Developers return x; 169310037SARM gem5 Developers } 169410037SARM gem5 Developers 169510037SARM gem5 Developers // Handle infinities and zeroes: 169613118SEdmund.Grimley-Evans@arm.com if ((b_exp == FP64_EXP_INF && !c_mnt) || 169713118SEdmund.Grimley-Evans@arm.com (c_exp == FP64_EXP_INF && !b_mnt) || 169813118SEdmund.Grimley-Evans@arm.com (a_exp == FP64_EXP_INF && 169913118SEdmund.Grimley-Evans@arm.com (b_exp == FP64_EXP_INF || c_exp == FP64_EXP_INF) && 170010037SARM gem5 Developers (a_sgn != (b_sgn ^ c_sgn)))) { 170110037SARM gem5 Developers *flags |= FPLIB_IOC; 170210037SARM gem5 Developers return fp64_defaultNaN(); 170310037SARM gem5 Developers } 170413118SEdmund.Grimley-Evans@arm.com if (a_exp == FP64_EXP_INF) 170510037SARM gem5 Developers return fp64_infinity(a_sgn); 170613118SEdmund.Grimley-Evans@arm.com if (b_exp == FP64_EXP_INF || c_exp == FP64_EXP_INF) 170710037SARM gem5 Developers return fp64_infinity(b_sgn ^ c_sgn); 170810037SARM gem5 Developers if (!a_mnt && (!b_mnt || !c_mnt) && a_sgn == (b_sgn ^ c_sgn)) 170910037SARM gem5 Developers return fp64_zero(a_sgn); 171010037SARM gem5 Developers 171110037SARM gem5 Developers x_sgn = a_sgn; 171213118SEdmund.Grimley-Evans@arm.com x_exp = a_exp + FP64_EXP_BITS; 171310037SARM gem5 Developers x0_mnt = 0; 171410037SARM gem5 Developers x1_mnt = a_mnt; 171510037SARM gem5 Developers 171610037SARM gem5 Developers // Multiply: 171710037SARM gem5 Developers y_sgn = b_sgn ^ c_sgn; 171813118SEdmund.Grimley-Evans@arm.com y_exp = b_exp + c_exp - FP64_EXP_BIAS + 2 * FP64_EXP_BITS + 1 - 3; 171910037SARM gem5 Developers mul62x62(&y0_mnt, &y1_mnt, b_mnt, c_mnt << 3); 172010037SARM gem5 Developers if (!y0_mnt && !y1_mnt) { 172110037SARM gem5 Developers y_exp = x_exp; 172210037SARM gem5 Developers } 172310037SARM gem5 Developers 172410037SARM gem5 Developers // Add: 172510037SARM gem5 Developers if (x_exp >= y_exp) { 172610037SARM gem5 Developers uint64_t t0, t1; 172710037SARM gem5 Developers lsl128(&t0, &t1, y0_mnt, y1_mnt, 172810037SARM gem5 Developers x_exp - y_exp < 128 ? 128 - (x_exp - y_exp) : 0); 172910037SARM gem5 Developers lsr128(&y0_mnt, &y1_mnt, y0_mnt, y1_mnt, x_exp - y_exp); 173010037SARM gem5 Developers y0_mnt |= !!(t0 | t1); 173110037SARM gem5 Developers y_exp = x_exp; 173210037SARM gem5 Developers } else { 173310037SARM gem5 Developers uint64_t t0, t1; 173410037SARM gem5 Developers lsl128(&t0, &t1, x0_mnt, x1_mnt, 173510037SARM gem5 Developers y_exp - x_exp < 128 ? 128 - (y_exp - x_exp) : 0); 173610037SARM gem5 Developers lsr128(&x0_mnt, &x1_mnt, x0_mnt, x1_mnt, y_exp - x_exp); 173710037SARM gem5 Developers x0_mnt |= !!(t0 | t1); 173810037SARM gem5 Developers x_exp = y_exp; 173910037SARM gem5 Developers } 174010037SARM gem5 Developers if (x_sgn == y_sgn) { 174110037SARM gem5 Developers add128(&x0_mnt, &x1_mnt, x0_mnt, x1_mnt, y0_mnt, y1_mnt); 174210037SARM gem5 Developers } else if (cmp128(x0_mnt, x1_mnt, y0_mnt, y1_mnt) >= 0) { 174310037SARM gem5 Developers sub128(&x0_mnt, &x1_mnt, x0_mnt, x1_mnt, y0_mnt, y1_mnt); 174410037SARM gem5 Developers } else { 174510037SARM gem5 Developers x_sgn ^= 1; 174610037SARM gem5 Developers sub128(&x0_mnt, &x1_mnt, y0_mnt, y1_mnt, x0_mnt, x1_mnt); 174710037SARM gem5 Developers } 174810037SARM gem5 Developers 174910037SARM gem5 Developers if (!x0_mnt && !x1_mnt) { 175010037SARM gem5 Developers // Sign of exact zero result depends on rounding mode 175110037SARM gem5 Developers return fp64_zero((mode & 3) == 2); 175210037SARM gem5 Developers } 175310037SARM gem5 Developers 175413118SEdmund.Grimley-Evans@arm.com // Normalise into FP64_BITS bits, collapsing error into bottom bit: 175510037SARM gem5 Developers fp128_normalise(&x0_mnt, &x1_mnt, &x_exp); 175610037SARM gem5 Developers x0_mnt = x1_mnt << 1 | !!x0_mnt; 175710037SARM gem5 Developers 175810037SARM gem5 Developers return fp64_round(x_sgn, x_exp + scale, x0_mnt, mode, flags); 175910037SARM gem5 Developers} 176010037SARM gem5 Developers 176113118SEdmund.Grimley-Evans@arm.comstatic uint16_t 176213118SEdmund.Grimley-Evans@arm.comfp16_div(uint16_t a, uint16_t b, int mode, int *flags) 176313118SEdmund.Grimley-Evans@arm.com{ 176413118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 176513118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, b_mnt, x; 176613118SEdmund.Grimley-Evans@arm.com uint32_t x_mnt; 176713118SEdmund.Grimley-Evans@arm.com 176813118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 176913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 177013118SEdmund.Grimley-Evans@arm.com 177113118SEdmund.Grimley-Evans@arm.com if ((x = fp16_process_NaNs(a, b, mode, flags))) 177213118SEdmund.Grimley-Evans@arm.com return x; 177313118SEdmund.Grimley-Evans@arm.com 177413118SEdmund.Grimley-Evans@arm.com // Handle infinities and zeroes: 177513118SEdmund.Grimley-Evans@arm.com if ((a_exp == FP16_EXP_INF && b_exp == FP16_EXP_INF) || 177613118SEdmund.Grimley-Evans@arm.com (!a_mnt && !b_mnt)) { 177713118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 177813118SEdmund.Grimley-Evans@arm.com return fp16_defaultNaN(); 177913118SEdmund.Grimley-Evans@arm.com } 178013118SEdmund.Grimley-Evans@arm.com if (a_exp == FP16_EXP_INF || !b_mnt) { 178113118SEdmund.Grimley-Evans@arm.com if (a_exp != FP16_EXP_INF) 178213118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_DZC; 178313118SEdmund.Grimley-Evans@arm.com return fp16_infinity(a_sgn ^ b_sgn); 178413118SEdmund.Grimley-Evans@arm.com } 178513118SEdmund.Grimley-Evans@arm.com if (!a_mnt || b_exp == FP16_EXP_INF) 178613118SEdmund.Grimley-Evans@arm.com return fp16_zero(a_sgn ^ b_sgn); 178713118SEdmund.Grimley-Evans@arm.com 178813118SEdmund.Grimley-Evans@arm.com // Divide, setting bottom bit if inexact: 178913118SEdmund.Grimley-Evans@arm.com a_mnt = fp16_normalise(a_mnt, &a_exp); 179013118SEdmund.Grimley-Evans@arm.com x_sgn = a_sgn ^ b_sgn; 179113118SEdmund.Grimley-Evans@arm.com x_exp = a_exp - b_exp + (FP16_EXP_BIAS + FP16_BITS + 2 * FP16_EXP_BITS - 3); 179213118SEdmund.Grimley-Evans@arm.com x_mnt = ((uint32_t)a_mnt << (FP16_MANT_BITS - FP16_EXP_BITS + 3)) / b_mnt; 179313118SEdmund.Grimley-Evans@arm.com x_mnt |= (x_mnt * b_mnt != 179413118SEdmund.Grimley-Evans@arm.com (uint32_t)a_mnt << (FP16_MANT_BITS - FP16_EXP_BITS + 3)); 179513118SEdmund.Grimley-Evans@arm.com 179613118SEdmund.Grimley-Evans@arm.com // Normalise into FP16_BITS bits, collapsing error into bottom bit: 179713118SEdmund.Grimley-Evans@arm.com x_mnt = fp32_normalise(x_mnt, &x_exp); 179813118SEdmund.Grimley-Evans@arm.com x_mnt = x_mnt >> (FP16_BITS - 1) | !!(uint16_t)(x_mnt << 1); 179913118SEdmund.Grimley-Evans@arm.com 180013118SEdmund.Grimley-Evans@arm.com return fp16_round(x_sgn, x_exp, x_mnt, mode, flags); 180113118SEdmund.Grimley-Evans@arm.com} 180213118SEdmund.Grimley-Evans@arm.com 180310037SARM gem5 Developersstatic uint32_t 180410037SARM gem5 Developersfp32_div(uint32_t a, uint32_t b, int mode, int *flags) 180510037SARM gem5 Developers{ 180610037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp; 180710037SARM gem5 Developers uint32_t a_mnt, b_mnt, x; 180810037SARM gem5 Developers uint64_t x_mnt; 180910037SARM gem5 Developers 181010037SARM gem5 Developers fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 181110037SARM gem5 Developers fp32_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 181210037SARM gem5 Developers 181310037SARM gem5 Developers if ((x = fp32_process_NaNs(a, b, mode, flags))) 181410037SARM gem5 Developers return x; 181510037SARM gem5 Developers 181610037SARM gem5 Developers // Handle infinities and zeroes: 181713118SEdmund.Grimley-Evans@arm.com if ((a_exp == FP32_EXP_INF && b_exp == FP32_EXP_INF) || 181813118SEdmund.Grimley-Evans@arm.com (!a_mnt && !b_mnt)) { 181910037SARM gem5 Developers *flags |= FPLIB_IOC; 182010037SARM gem5 Developers return fp32_defaultNaN(); 182110037SARM gem5 Developers } 182213118SEdmund.Grimley-Evans@arm.com if (a_exp == FP32_EXP_INF || !b_mnt) { 182313118SEdmund.Grimley-Evans@arm.com if (a_exp != FP32_EXP_INF) 182410037SARM gem5 Developers *flags |= FPLIB_DZC; 182510037SARM gem5 Developers return fp32_infinity(a_sgn ^ b_sgn); 182610037SARM gem5 Developers } 182713118SEdmund.Grimley-Evans@arm.com if (!a_mnt || b_exp == FP32_EXP_INF) 182810037SARM gem5 Developers return fp32_zero(a_sgn ^ b_sgn); 182910037SARM gem5 Developers 183010037SARM gem5 Developers // Divide, setting bottom bit if inexact: 183110037SARM gem5 Developers a_mnt = fp32_normalise(a_mnt, &a_exp); 183210037SARM gem5 Developers x_sgn = a_sgn ^ b_sgn; 183313118SEdmund.Grimley-Evans@arm.com x_exp = a_exp - b_exp + (FP32_EXP_BIAS + FP32_BITS + 2 * FP32_EXP_BITS - 3); 183413118SEdmund.Grimley-Evans@arm.com x_mnt = ((uint64_t)a_mnt << (FP32_MANT_BITS - FP32_EXP_BITS + 3)) / b_mnt; 183513118SEdmund.Grimley-Evans@arm.com x_mnt |= (x_mnt * b_mnt != 183613118SEdmund.Grimley-Evans@arm.com (uint64_t)a_mnt << (FP32_MANT_BITS - FP32_EXP_BITS + 3)); 183713118SEdmund.Grimley-Evans@arm.com 183813118SEdmund.Grimley-Evans@arm.com // Normalise into FP32_BITS bits, collapsing error into bottom bit: 183910037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 184013118SEdmund.Grimley-Evans@arm.com x_mnt = x_mnt >> (FP32_BITS - 1) | !!(uint32_t)(x_mnt << 1); 184110037SARM gem5 Developers 184210037SARM gem5 Developers return fp32_round(x_sgn, x_exp, x_mnt, mode, flags); 184310037SARM gem5 Developers} 184410037SARM gem5 Developers 184510037SARM gem5 Developersstatic uint64_t 184610037SARM gem5 Developersfp64_div(uint64_t a, uint64_t b, int mode, int *flags) 184710037SARM gem5 Developers{ 184810037SARM gem5 Developers int a_sgn, a_exp, b_sgn, b_exp, x_sgn, x_exp, c; 184910037SARM gem5 Developers uint64_t a_mnt, b_mnt, x, x_mnt, x0_mnt, x1_mnt; 185010037SARM gem5 Developers 185110037SARM gem5 Developers fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 185210037SARM gem5 Developers fp64_unpack(&b_sgn, &b_exp, &b_mnt, b, mode, flags); 185310037SARM gem5 Developers 185410037SARM gem5 Developers if ((x = fp64_process_NaNs(a, b, mode, flags))) 185510037SARM gem5 Developers return x; 185610037SARM gem5 Developers 185710037SARM gem5 Developers // Handle infinities and zeroes: 185813118SEdmund.Grimley-Evans@arm.com if ((a_exp == FP64_EXP_INF && b_exp == FP64_EXP_INF) || 185913118SEdmund.Grimley-Evans@arm.com (!a_mnt && !b_mnt)) { 186010037SARM gem5 Developers *flags |= FPLIB_IOC; 186110037SARM gem5 Developers return fp64_defaultNaN(); 186210037SARM gem5 Developers } 186313118SEdmund.Grimley-Evans@arm.com if (a_exp == FP64_EXP_INF || !b_mnt) { 186413118SEdmund.Grimley-Evans@arm.com if (a_exp != FP64_EXP_INF) 186510037SARM gem5 Developers *flags |= FPLIB_DZC; 186610037SARM gem5 Developers return fp64_infinity(a_sgn ^ b_sgn); 186710037SARM gem5 Developers } 186813118SEdmund.Grimley-Evans@arm.com if (!a_mnt || b_exp == FP64_EXP_INF) 186910037SARM gem5 Developers return fp64_zero(a_sgn ^ b_sgn); 187010037SARM gem5 Developers 187110037SARM gem5 Developers // Find reciprocal of divisor with Newton-Raphson: 187210037SARM gem5 Developers a_mnt = fp64_normalise(a_mnt, &a_exp); 187310037SARM gem5 Developers b_mnt = fp64_normalise(b_mnt, &b_exp); 187410037SARM gem5 Developers x_mnt = ~(uint64_t)0 / (b_mnt >> 31); 187510037SARM gem5 Developers mul64x32(&x0_mnt, &x1_mnt, b_mnt, x_mnt); 187610037SARM gem5 Developers sub128(&x0_mnt, &x1_mnt, 0, (uint64_t)1 << 32, x0_mnt, x1_mnt); 187710037SARM gem5 Developers lsr128(&x0_mnt, &x1_mnt, x0_mnt, x1_mnt, 32); 187810037SARM gem5 Developers mul64x32(&x0_mnt, &x1_mnt, x0_mnt, x_mnt); 187910037SARM gem5 Developers lsr128(&x0_mnt, &x1_mnt, x0_mnt, x1_mnt, 33); 188010037SARM gem5 Developers 188110037SARM gem5 Developers // Multiply by dividend: 188210037SARM gem5 Developers x_sgn = a_sgn ^ b_sgn; 188313118SEdmund.Grimley-Evans@arm.com x_exp = a_exp - b_exp + FP64_EXP_BIAS + 8; 188413118SEdmund.Grimley-Evans@arm.com mul62x62(&x0_mnt, &x1_mnt, x0_mnt, a_mnt >> 2); 188510037SARM gem5 Developers lsr128(&x0_mnt, &x1_mnt, x0_mnt, x1_mnt, 4); 188610037SARM gem5 Developers x_mnt = x1_mnt; 188710037SARM gem5 Developers 188810037SARM gem5 Developers // This is an underestimate, so try adding one: 188913118SEdmund.Grimley-Evans@arm.com mul62x62(&x0_mnt, &x1_mnt, b_mnt >> 2, x_mnt + 1); 189010037SARM gem5 Developers c = cmp128(x0_mnt, x1_mnt, 0, a_mnt >> 11); 189110037SARM gem5 Developers if (c <= 0) { 189210037SARM gem5 Developers ++x_mnt; 189310037SARM gem5 Developers } 189410037SARM gem5 Developers 189510037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 189610037SARM gem5 Developers 189710037SARM gem5 Developers return fp64_round(x_sgn, x_exp, x_mnt << 1 | !!c, mode, flags); 189810037SARM gem5 Developers} 189910037SARM gem5 Developers 190010037SARM gem5 Developersstatic void 190110037SARM gem5 Developersset_fpscr0(FPSCR &fpscr, int flags) 190210037SARM gem5 Developers{ 190310037SARM gem5 Developers if (flags & FPLIB_IDC) { 190410037SARM gem5 Developers fpscr.idc = 1; 190510037SARM gem5 Developers } 190610037SARM gem5 Developers if (flags & FPLIB_IOC) { 190710037SARM gem5 Developers fpscr.ioc = 1; 190810037SARM gem5 Developers } 190910037SARM gem5 Developers if (flags & FPLIB_DZC) { 191010037SARM gem5 Developers fpscr.dzc = 1; 191110037SARM gem5 Developers } 191210037SARM gem5 Developers if (flags & FPLIB_OFC) { 191310037SARM gem5 Developers fpscr.ofc = 1; 191410037SARM gem5 Developers } 191510037SARM gem5 Developers if (flags & FPLIB_UFC) { 191610037SARM gem5 Developers fpscr.ufc = 1; 191710037SARM gem5 Developers } 191810037SARM gem5 Developers if (flags & FPLIB_IXC) { 191910037SARM gem5 Developers fpscr.ixc = 1; 192010037SARM gem5 Developers } 192110037SARM gem5 Developers} 192210037SARM gem5 Developers 192313118SEdmund.Grimley-Evans@arm.comstatic uint16_t 192413118SEdmund.Grimley-Evans@arm.comfp16_scale(uint16_t a, int16_t b, int mode, int *flags) 192513118SEdmund.Grimley-Evans@arm.com{ 192613118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp; 192713118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt; 192813118SEdmund.Grimley-Evans@arm.com 192913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 193013118SEdmund.Grimley-Evans@arm.com 193113118SEdmund.Grimley-Evans@arm.com // Handle NaNs: 193213118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt)) { 193313118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(a, mode, flags); 193413118SEdmund.Grimley-Evans@arm.com } 193513118SEdmund.Grimley-Evans@arm.com 193613118SEdmund.Grimley-Evans@arm.com // Handle zeroes: 193713118SEdmund.Grimley-Evans@arm.com if (!a_mnt) { 193813118SEdmund.Grimley-Evans@arm.com return fp16_zero(a_sgn); 193913118SEdmund.Grimley-Evans@arm.com } 194013118SEdmund.Grimley-Evans@arm.com 194113118SEdmund.Grimley-Evans@arm.com // Handle infinities: 194213118SEdmund.Grimley-Evans@arm.com if (a_exp == FP16_EXP_INF) { 194313118SEdmund.Grimley-Evans@arm.com return fp16_infinity(a_sgn); 194413118SEdmund.Grimley-Evans@arm.com } 194513118SEdmund.Grimley-Evans@arm.com 194613118SEdmund.Grimley-Evans@arm.com b = b < -300 ? -300 : b; 194713118SEdmund.Grimley-Evans@arm.com b = b > 300 ? 300 : b; 194813118SEdmund.Grimley-Evans@arm.com a_exp += b; 194913118SEdmund.Grimley-Evans@arm.com a_mnt <<= 3; 195013118SEdmund.Grimley-Evans@arm.com 195113118SEdmund.Grimley-Evans@arm.com a_mnt = fp16_normalise(a_mnt, &a_exp); 195213118SEdmund.Grimley-Evans@arm.com 195313118SEdmund.Grimley-Evans@arm.com return fp16_round(a_sgn, a_exp + FP16_EXP_BITS - 3, a_mnt << 1, 195413118SEdmund.Grimley-Evans@arm.com mode, flags); 195513118SEdmund.Grimley-Evans@arm.com} 195613118SEdmund.Grimley-Evans@arm.com 195713118SEdmund.Grimley-Evans@arm.comstatic uint32_t 195813118SEdmund.Grimley-Evans@arm.comfp32_scale(uint32_t a, int32_t b, int mode, int *flags) 195913118SEdmund.Grimley-Evans@arm.com{ 196013118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp; 196113118SEdmund.Grimley-Evans@arm.com uint32_t a_mnt; 196213118SEdmund.Grimley-Evans@arm.com 196313118SEdmund.Grimley-Evans@arm.com fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 196413118SEdmund.Grimley-Evans@arm.com 196513118SEdmund.Grimley-Evans@arm.com // Handle NaNs: 196613118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt)) { 196713118SEdmund.Grimley-Evans@arm.com return fp32_process_NaN(a, mode, flags); 196813118SEdmund.Grimley-Evans@arm.com } 196913118SEdmund.Grimley-Evans@arm.com 197013118SEdmund.Grimley-Evans@arm.com // Handle zeroes: 197113118SEdmund.Grimley-Evans@arm.com if (!a_mnt) { 197213118SEdmund.Grimley-Evans@arm.com return fp32_zero(a_sgn); 197313118SEdmund.Grimley-Evans@arm.com } 197413118SEdmund.Grimley-Evans@arm.com 197513118SEdmund.Grimley-Evans@arm.com // Handle infinities: 197613118SEdmund.Grimley-Evans@arm.com if (a_exp == FP32_EXP_INF) { 197713118SEdmund.Grimley-Evans@arm.com return fp32_infinity(a_sgn); 197813118SEdmund.Grimley-Evans@arm.com } 197913118SEdmund.Grimley-Evans@arm.com 198013118SEdmund.Grimley-Evans@arm.com b = b < -300 ? -300 : b; 198113118SEdmund.Grimley-Evans@arm.com b = b > 300 ? 300 : b; 198213118SEdmund.Grimley-Evans@arm.com a_exp += b; 198313118SEdmund.Grimley-Evans@arm.com a_mnt <<= 3; 198413118SEdmund.Grimley-Evans@arm.com 198513118SEdmund.Grimley-Evans@arm.com a_mnt = fp32_normalise(a_mnt, &a_exp); 198613118SEdmund.Grimley-Evans@arm.com 198713118SEdmund.Grimley-Evans@arm.com return fp32_round(a_sgn, a_exp + FP32_EXP_BITS - 3, a_mnt << 1, 198813118SEdmund.Grimley-Evans@arm.com mode, flags); 198913118SEdmund.Grimley-Evans@arm.com} 199013118SEdmund.Grimley-Evans@arm.com 199113118SEdmund.Grimley-Evans@arm.comstatic uint64_t 199213118SEdmund.Grimley-Evans@arm.comfp64_scale(uint64_t a, int64_t b, int mode, int *flags) 199313118SEdmund.Grimley-Evans@arm.com{ 199413118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp; 199513118SEdmund.Grimley-Evans@arm.com uint64_t a_mnt; 199613118SEdmund.Grimley-Evans@arm.com 199713118SEdmund.Grimley-Evans@arm.com fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 199813118SEdmund.Grimley-Evans@arm.com 199913118SEdmund.Grimley-Evans@arm.com // Handle NaNs: 200013118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt)) { 200113118SEdmund.Grimley-Evans@arm.com return fp64_process_NaN(a, mode, flags); 200213118SEdmund.Grimley-Evans@arm.com } 200313118SEdmund.Grimley-Evans@arm.com 200413118SEdmund.Grimley-Evans@arm.com // Handle zeroes: 200513118SEdmund.Grimley-Evans@arm.com if (!a_mnt) { 200613118SEdmund.Grimley-Evans@arm.com return fp64_zero(a_sgn); 200713118SEdmund.Grimley-Evans@arm.com } 200813118SEdmund.Grimley-Evans@arm.com 200913118SEdmund.Grimley-Evans@arm.com // Handle infinities: 201013118SEdmund.Grimley-Evans@arm.com if (a_exp == FP64_EXP_INF) { 201113118SEdmund.Grimley-Evans@arm.com return fp64_infinity(a_sgn); 201213118SEdmund.Grimley-Evans@arm.com } 201313118SEdmund.Grimley-Evans@arm.com 201413118SEdmund.Grimley-Evans@arm.com b = b < -3000 ? -3000 : b; 201513118SEdmund.Grimley-Evans@arm.com b = b > 3000 ? 3000 : b; 201613118SEdmund.Grimley-Evans@arm.com a_exp += b; 201713118SEdmund.Grimley-Evans@arm.com a_mnt <<= 3; 201813118SEdmund.Grimley-Evans@arm.com 201913118SEdmund.Grimley-Evans@arm.com a_mnt = fp64_normalise(a_mnt, &a_exp); 202013118SEdmund.Grimley-Evans@arm.com 202113118SEdmund.Grimley-Evans@arm.com return fp64_round(a_sgn, a_exp + FP64_EXP_BITS - 3, a_mnt << 1, 202213118SEdmund.Grimley-Evans@arm.com mode, flags); 202313118SEdmund.Grimley-Evans@arm.com} 202413118SEdmund.Grimley-Evans@arm.com 202513118SEdmund.Grimley-Evans@arm.comstatic uint16_t 202613118SEdmund.Grimley-Evans@arm.comfp16_sqrt(uint16_t a, int mode, int *flags) 202713118SEdmund.Grimley-Evans@arm.com{ 202813118SEdmund.Grimley-Evans@arm.com int a_sgn, a_exp, x_sgn, x_exp; 202913118SEdmund.Grimley-Evans@arm.com uint16_t a_mnt, x_mnt; 203013118SEdmund.Grimley-Evans@arm.com uint32_t x, t0, t1; 203113118SEdmund.Grimley-Evans@arm.com 203213118SEdmund.Grimley-Evans@arm.com fp16_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 203313118SEdmund.Grimley-Evans@arm.com 203413118SEdmund.Grimley-Evans@arm.com // Handle NaNs: 203513118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(a_exp, a_mnt)) 203613118SEdmund.Grimley-Evans@arm.com return fp16_process_NaN(a, mode, flags); 203713118SEdmund.Grimley-Evans@arm.com 203813118SEdmund.Grimley-Evans@arm.com // Handle infinities and zeroes: 203913118SEdmund.Grimley-Evans@arm.com if (!a_mnt) 204013118SEdmund.Grimley-Evans@arm.com return fp16_zero(a_sgn); 204113118SEdmund.Grimley-Evans@arm.com if (a_exp == FP16_EXP_INF && !a_sgn) 204213118SEdmund.Grimley-Evans@arm.com return fp16_infinity(a_sgn); 204313118SEdmund.Grimley-Evans@arm.com if (a_sgn) { 204413118SEdmund.Grimley-Evans@arm.com *flags |= FPLIB_IOC; 204513118SEdmund.Grimley-Evans@arm.com return fp16_defaultNaN(); 204613118SEdmund.Grimley-Evans@arm.com } 204713118SEdmund.Grimley-Evans@arm.com 204813118SEdmund.Grimley-Evans@arm.com a_mnt = fp16_normalise(a_mnt, &a_exp); 204913118SEdmund.Grimley-Evans@arm.com if (a_exp & 1) { 205013118SEdmund.Grimley-Evans@arm.com ++a_exp; 205113118SEdmund.Grimley-Evans@arm.com a_mnt >>= 1; 205213118SEdmund.Grimley-Evans@arm.com } 205313118SEdmund.Grimley-Evans@arm.com 205413118SEdmund.Grimley-Evans@arm.com // x = (a * 3 + 5) / 8 205513118SEdmund.Grimley-Evans@arm.com x = ((uint32_t)a_mnt << 14) + ((uint32_t)a_mnt << 13) + ((uint32_t)5 << 28); 205613118SEdmund.Grimley-Evans@arm.com 205713118SEdmund.Grimley-Evans@arm.com // x = (a / x + x) / 2; // 8-bit accuracy 205813118SEdmund.Grimley-Evans@arm.com x = (((uint32_t)a_mnt << 16) / (x >> 15) + (x >> 16)) << 15; 205913118SEdmund.Grimley-Evans@arm.com 206013118SEdmund.Grimley-Evans@arm.com // x = (a / x + x) / 2; // 16-bit accuracy 206113118SEdmund.Grimley-Evans@arm.com x = (((uint32_t)a_mnt << 16) / (x >> 15) + (x >> 16)) << 15; 206213118SEdmund.Grimley-Evans@arm.com 206313118SEdmund.Grimley-Evans@arm.com x_sgn = 0; 206413118SEdmund.Grimley-Evans@arm.com x_exp = (a_exp + 27) >> 1; 206513118SEdmund.Grimley-Evans@arm.com x_mnt = ((x - (1 << 18)) >> 19) + 1; 206613118SEdmund.Grimley-Evans@arm.com t1 = (uint32_t)x_mnt * x_mnt; 206713118SEdmund.Grimley-Evans@arm.com t0 = (uint32_t)a_mnt << 9; 206813118SEdmund.Grimley-Evans@arm.com if (t1 > t0) { 206913118SEdmund.Grimley-Evans@arm.com --x_mnt; 207013118SEdmund.Grimley-Evans@arm.com } 207113118SEdmund.Grimley-Evans@arm.com 207213118SEdmund.Grimley-Evans@arm.com x_mnt = fp16_normalise(x_mnt, &x_exp); 207313118SEdmund.Grimley-Evans@arm.com 207413118SEdmund.Grimley-Evans@arm.com return fp16_round(x_sgn, x_exp, x_mnt << 1 | (t1 != t0), mode, flags); 207513118SEdmund.Grimley-Evans@arm.com} 207613118SEdmund.Grimley-Evans@arm.com 207710037SARM gem5 Developersstatic uint32_t 207810037SARM gem5 Developersfp32_sqrt(uint32_t a, int mode, int *flags) 207910037SARM gem5 Developers{ 208010037SARM gem5 Developers int a_sgn, a_exp, x_sgn, x_exp; 208110037SARM gem5 Developers uint32_t a_mnt, x, x_mnt; 208210037SARM gem5 Developers uint64_t t0, t1; 208310037SARM gem5 Developers 208410037SARM gem5 Developers fp32_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 208510037SARM gem5 Developers 208610037SARM gem5 Developers // Handle NaNs: 208713118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(a_exp, a_mnt)) 208810037SARM gem5 Developers return fp32_process_NaN(a, mode, flags); 208910037SARM gem5 Developers 209010037SARM gem5 Developers // Handle infinities and zeroes: 209113118SEdmund.Grimley-Evans@arm.com if (!a_mnt) 209210037SARM gem5 Developers return fp32_zero(a_sgn); 209313118SEdmund.Grimley-Evans@arm.com if (a_exp == FP32_EXP_INF && !a_sgn) 209410037SARM gem5 Developers return fp32_infinity(a_sgn); 209510037SARM gem5 Developers if (a_sgn) { 209610037SARM gem5 Developers *flags |= FPLIB_IOC; 209710037SARM gem5 Developers return fp32_defaultNaN(); 209810037SARM gem5 Developers } 209910037SARM gem5 Developers 210010037SARM gem5 Developers a_mnt = fp32_normalise(a_mnt, &a_exp); 210110037SARM gem5 Developers if (!(a_exp & 1)) { 210210037SARM gem5 Developers ++a_exp; 210310037SARM gem5 Developers a_mnt >>= 1; 210410037SARM gem5 Developers } 210510037SARM gem5 Developers 210610037SARM gem5 Developers // x = (a * 3 + 5) / 8 210713118SEdmund.Grimley-Evans@arm.com x = (a_mnt >> 2) + (a_mnt >> 3) + ((uint32_t)5 << 28); 210813118SEdmund.Grimley-Evans@arm.com 210913118SEdmund.Grimley-Evans@arm.com // x = (a / x + x) / 2; // 8-bit accuracy 211010037SARM gem5 Developers x = (a_mnt / (x >> 15) + (x >> 16)) << 15; 211110037SARM gem5 Developers 211210037SARM gem5 Developers // x = (a / x + x) / 2; // 16-bit accuracy 211310037SARM gem5 Developers x = (a_mnt / (x >> 15) + (x >> 16)) << 15; 211410037SARM gem5 Developers 211510037SARM gem5 Developers // x = (a / x + x) / 2; // 32-bit accuracy 211610037SARM gem5 Developers x = ((((uint64_t)a_mnt << 32) / x) >> 2) + (x >> 1); 211710037SARM gem5 Developers 211810037SARM gem5 Developers x_sgn = 0; 211910037SARM gem5 Developers x_exp = (a_exp + 147) >> 1; 212010037SARM gem5 Developers x_mnt = ((x - (1 << 5)) >> 6) + 1; 212110037SARM gem5 Developers t1 = (uint64_t)x_mnt * x_mnt; 212210037SARM gem5 Developers t0 = (uint64_t)a_mnt << 19; 212310037SARM gem5 Developers if (t1 > t0) { 212410037SARM gem5 Developers --x_mnt; 212510037SARM gem5 Developers } 212610037SARM gem5 Developers 212710037SARM gem5 Developers x_mnt = fp32_normalise(x_mnt, &x_exp); 212810037SARM gem5 Developers 212910037SARM gem5 Developers return fp32_round(x_sgn, x_exp, x_mnt << 1 | (t1 != t0), mode, flags); 213010037SARM gem5 Developers} 213110037SARM gem5 Developers 213210037SARM gem5 Developersstatic uint64_t 213310037SARM gem5 Developersfp64_sqrt(uint64_t a, int mode, int *flags) 213410037SARM gem5 Developers{ 213510037SARM gem5 Developers int a_sgn, a_exp, x_sgn, x_exp, c; 213610037SARM gem5 Developers uint64_t a_mnt, x_mnt, r, x0, x1; 213710037SARM gem5 Developers uint32_t x; 213810037SARM gem5 Developers 213910037SARM gem5 Developers fp64_unpack(&a_sgn, &a_exp, &a_mnt, a, mode, flags); 214010037SARM gem5 Developers 214110037SARM gem5 Developers // Handle NaNs: 214213118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(a_exp, a_mnt)) 214310037SARM gem5 Developers return fp64_process_NaN(a, mode, flags); 214410037SARM gem5 Developers 214510037SARM gem5 Developers // Handle infinities and zeroes: 214610037SARM gem5 Developers if (!a_mnt) 214710037SARM gem5 Developers return fp64_zero(a_sgn); 214813118SEdmund.Grimley-Evans@arm.com if (a_exp == FP64_EXP_INF && !a_sgn) 214910037SARM gem5 Developers return fp64_infinity(a_sgn); 215010037SARM gem5 Developers if (a_sgn) { 215110037SARM gem5 Developers *flags |= FPLIB_IOC; 215210037SARM gem5 Developers return fp64_defaultNaN(); 215310037SARM gem5 Developers } 215410037SARM gem5 Developers 215510037SARM gem5 Developers a_mnt = fp64_normalise(a_mnt, &a_exp); 215610037SARM gem5 Developers if (a_exp & 1) { 215710037SARM gem5 Developers ++a_exp; 215810037SARM gem5 Developers a_mnt >>= 1; 215910037SARM gem5 Developers } 216010037SARM gem5 Developers 216110037SARM gem5 Developers // x = (a * 3 + 5) / 8 216213118SEdmund.Grimley-Evans@arm.com x = (a_mnt >> 34) + (a_mnt >> 35) + ((uint32_t)5 << 28); 216313118SEdmund.Grimley-Evans@arm.com 216413118SEdmund.Grimley-Evans@arm.com // x = (a / x + x) / 2; // 8-bit accuracy 216510037SARM gem5 Developers x = ((a_mnt >> 32) / (x >> 15) + (x >> 16)) << 15; 216610037SARM gem5 Developers 216710037SARM gem5 Developers // x = (a / x + x) / 2; // 16-bit accuracy 216810037SARM gem5 Developers x = ((a_mnt >> 32) / (x >> 15) + (x >> 16)) << 15; 216910037SARM gem5 Developers 217010037SARM gem5 Developers // x = (a / x + x) / 2; // 32-bit accuracy 217110037SARM gem5 Developers x = ((a_mnt / x) >> 2) + (x >> 1); 217210037SARM gem5 Developers 217310037SARM gem5 Developers // r = 1 / x; // 32-bit accuracy 217410037SARM gem5 Developers r = ((uint64_t)1 << 62) / x; 217510037SARM gem5 Developers 217610037SARM gem5 Developers // r = r * (2 - x * r); // 64-bit accuracy 217710037SARM gem5 Developers mul64x32(&x0, &x1, -(uint64_t)x * r << 1, r); 217810037SARM gem5 Developers lsr128(&x0, &x1, x0, x1, 31); 217910037SARM gem5 Developers 218010037SARM gem5 Developers // x = (x + a * r) / 2; // 64-bit accuracy 218110037SARM gem5 Developers mul62x62(&x0, &x1, a_mnt >> 10, x0 >> 2); 218210037SARM gem5 Developers lsl128(&x0, &x1, x0, x1, 5); 218310037SARM gem5 Developers lsr128(&x0, &x1, x0, x1, 56); 218410037SARM gem5 Developers 218510037SARM gem5 Developers x0 = ((uint64_t)x << 31) + (x0 >> 1); 218610037SARM gem5 Developers 218710037SARM gem5 Developers x_sgn = 0; 218810037SARM gem5 Developers x_exp = (a_exp + 1053) >> 1; 218910037SARM gem5 Developers x_mnt = x0; 219010037SARM gem5 Developers x_mnt = ((x_mnt - (1 << 8)) >> 9) + 1; 219110037SARM gem5 Developers mul62x62(&x0, &x1, x_mnt, x_mnt); 219210037SARM gem5 Developers lsl128(&x0, &x1, x0, x1, 19); 219310037SARM gem5 Developers c = cmp128(x0, x1, 0, a_mnt); 219410037SARM gem5 Developers if (c > 0) 219510037SARM gem5 Developers --x_mnt; 219610037SARM gem5 Developers 219710037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 219810037SARM gem5 Developers 219910037SARM gem5 Developers return fp64_round(x_sgn, x_exp, x_mnt << 1 | !!c, mode, flags); 220010037SARM gem5 Developers} 220110037SARM gem5 Developers 220210037SARM gem5 Developersstatic int 220310037SARM gem5 DevelopersmodeConv(FPSCR fpscr) 220410037SARM gem5 Developers{ 220513118SEdmund.Grimley-Evans@arm.com uint32_t x = (uint32_t)fpscr; 220613118SEdmund.Grimley-Evans@arm.com return (x >> 22 & 0xf) | (x >> 19 & 1 ? FPLIB_FZ16 : 0); 220713118SEdmund.Grimley-Evans@arm.com // AHP bit is ignored. Only fplibConvert uses AHP. 220810037SARM gem5 Developers} 220910037SARM gem5 Developers 221010037SARM gem5 Developersstatic void 221110037SARM gem5 Developersset_fpscr(FPSCR &fpscr, int flags) 221210037SARM gem5 Developers{ 221310037SARM gem5 Developers // translate back to FPSCR 221410037SARM gem5 Developers bool underflow = false; 221510037SARM gem5 Developers if (flags & FPLIB_IDC) { 221610037SARM gem5 Developers fpscr.idc = 1; 221710037SARM gem5 Developers } 221810037SARM gem5 Developers if (flags & FPLIB_IOC) { 221910037SARM gem5 Developers fpscr.ioc = 1; 222010037SARM gem5 Developers } 222110037SARM gem5 Developers if (flags & FPLIB_DZC) { 222210037SARM gem5 Developers fpscr.dzc = 1; 222310037SARM gem5 Developers } 222410037SARM gem5 Developers if (flags & FPLIB_OFC) { 222510037SARM gem5 Developers fpscr.ofc = 1; 222610037SARM gem5 Developers } 222710037SARM gem5 Developers if (flags & FPLIB_UFC) { 222810037SARM gem5 Developers underflow = true; //xx Why is this required? 222910037SARM gem5 Developers fpscr.ufc = 1; 223010037SARM gem5 Developers } 223110037SARM gem5 Developers if ((flags & FPLIB_IXC) && !(underflow && fpscr.fz)) { 223210037SARM gem5 Developers fpscr.ixc = 1; 223310037SARM gem5 Developers } 223410037SARM gem5 Developers} 223510037SARM gem5 Developers 223610037SARM gem5 Developerstemplate <> 223710037SARM gem5 Developersbool 223813118SEdmund.Grimley-Evans@arm.comfplibCompareEQ(uint16_t a, uint16_t b, FPSCR &fpscr) 223913118SEdmund.Grimley-Evans@arm.com{ 224013118SEdmund.Grimley-Evans@arm.com int flags = 0; 224113118SEdmund.Grimley-Evans@arm.com int x = fp16_compare_eq(a, b, modeConv(fpscr), &flags); 224213118SEdmund.Grimley-Evans@arm.com set_fpscr(fpscr, flags); 224313118SEdmund.Grimley-Evans@arm.com return x; 224413118SEdmund.Grimley-Evans@arm.com} 224513118SEdmund.Grimley-Evans@arm.com 224613118SEdmund.Grimley-Evans@arm.comtemplate <> 224713118SEdmund.Grimley-Evans@arm.combool 224813118SEdmund.Grimley-Evans@arm.comfplibCompareGE(uint16_t a, uint16_t b, FPSCR &fpscr) 224913118SEdmund.Grimley-Evans@arm.com{ 225013118SEdmund.Grimley-Evans@arm.com int flags = 0; 225113118SEdmund.Grimley-Evans@arm.com int x = fp16_compare_ge(a, b, modeConv(fpscr), &flags); 225213118SEdmund.Grimley-Evans@arm.com set_fpscr(fpscr, flags); 225313118SEdmund.Grimley-Evans@arm.com return x; 225413118SEdmund.Grimley-Evans@arm.com} 225513118SEdmund.Grimley-Evans@arm.com 225613118SEdmund.Grimley-Evans@arm.comtemplate <> 225713118SEdmund.Grimley-Evans@arm.combool 225813118SEdmund.Grimley-Evans@arm.comfplibCompareGT(uint16_t a, uint16_t b, FPSCR &fpscr) 225913118SEdmund.Grimley-Evans@arm.com{ 226013118SEdmund.Grimley-Evans@arm.com int flags = 0; 226113118SEdmund.Grimley-Evans@arm.com int x = fp16_compare_gt(a, b, modeConv(fpscr), &flags); 226213118SEdmund.Grimley-Evans@arm.com set_fpscr(fpscr, flags); 226313118SEdmund.Grimley-Evans@arm.com return x; 226413118SEdmund.Grimley-Evans@arm.com} 226513118SEdmund.Grimley-Evans@arm.com 226613118SEdmund.Grimley-Evans@arm.comtemplate <> 226713118SEdmund.Grimley-Evans@arm.combool 226813118SEdmund.Grimley-Evans@arm.comfplibCompareUN(uint16_t a, uint16_t b, FPSCR &fpscr) 226913118SEdmund.Grimley-Evans@arm.com{ 227013118SEdmund.Grimley-Evans@arm.com int flags = 0; 227113118SEdmund.Grimley-Evans@arm.com int x = fp16_compare_un(a, b, modeConv(fpscr), &flags); 227213118SEdmund.Grimley-Evans@arm.com set_fpscr(fpscr, flags); 227313118SEdmund.Grimley-Evans@arm.com return x; 227413118SEdmund.Grimley-Evans@arm.com} 227513118SEdmund.Grimley-Evans@arm.com 227613118SEdmund.Grimley-Evans@arm.comtemplate <> 227713118SEdmund.Grimley-Evans@arm.combool 227810037SARM gem5 DevelopersfplibCompareEQ(uint32_t a, uint32_t b, FPSCR &fpscr) 227910037SARM gem5 Developers{ 228010037SARM gem5 Developers int flags = 0; 228110037SARM gem5 Developers int x = fp32_compare_eq(a, b, modeConv(fpscr), &flags); 228210037SARM gem5 Developers set_fpscr(fpscr, flags); 228310037SARM gem5 Developers return x; 228410037SARM gem5 Developers} 228510037SARM gem5 Developers 228610037SARM gem5 Developerstemplate <> 228710037SARM gem5 Developersbool 228810037SARM gem5 DevelopersfplibCompareGE(uint32_t a, uint32_t b, FPSCR &fpscr) 228910037SARM gem5 Developers{ 229010037SARM gem5 Developers int flags = 0; 229110037SARM gem5 Developers int x = fp32_compare_ge(a, b, modeConv(fpscr), &flags); 229210037SARM gem5 Developers set_fpscr(fpscr, flags); 229310037SARM gem5 Developers return x; 229410037SARM gem5 Developers} 229510037SARM gem5 Developers 229610037SARM gem5 Developerstemplate <> 229710037SARM gem5 Developersbool 229810037SARM gem5 DevelopersfplibCompareGT(uint32_t a, uint32_t b, FPSCR &fpscr) 229910037SARM gem5 Developers{ 230010037SARM gem5 Developers int flags = 0; 230110037SARM gem5 Developers int x = fp32_compare_gt(a, b, modeConv(fpscr), &flags); 230210037SARM gem5 Developers set_fpscr(fpscr, flags); 230310037SARM gem5 Developers return x; 230410037SARM gem5 Developers} 230510037SARM gem5 Developers 230610037SARM gem5 Developerstemplate <> 230710037SARM gem5 Developersbool 230813118SEdmund.Grimley-Evans@arm.comfplibCompareUN(uint32_t a, uint32_t b, FPSCR &fpscr) 230913118SEdmund.Grimley-Evans@arm.com{ 231013118SEdmund.Grimley-Evans@arm.com int flags = 0; 231113118SEdmund.Grimley-Evans@arm.com int x = fp32_compare_un(a, b, modeConv(fpscr), &flags); 231213118SEdmund.Grimley-Evans@arm.com set_fpscr(fpscr, flags); 231313118SEdmund.Grimley-Evans@arm.com return x; 231413118SEdmund.Grimley-Evans@arm.com} 231513118SEdmund.Grimley-Evans@arm.com 231613118SEdmund.Grimley-Evans@arm.comtemplate <> 231713118SEdmund.Grimley-Evans@arm.combool 231810037SARM gem5 DevelopersfplibCompareEQ(uint64_t a, uint64_t b, FPSCR &fpscr) 231910037SARM gem5 Developers{ 232010037SARM gem5 Developers int flags = 0; 232110037SARM gem5 Developers int x = fp64_compare_eq(a, b, modeConv(fpscr), &flags); 232210037SARM gem5 Developers set_fpscr(fpscr, flags); 232310037SARM gem5 Developers return x; 232410037SARM gem5 Developers} 232510037SARM gem5 Developers 232610037SARM gem5 Developerstemplate <> 232710037SARM gem5 Developersbool 232810037SARM gem5 DevelopersfplibCompareGE(uint64_t a, uint64_t b, FPSCR &fpscr) 232910037SARM gem5 Developers{ 233010037SARM gem5 Developers int flags = 0; 233110037SARM gem5 Developers int x = fp64_compare_ge(a, b, modeConv(fpscr), &flags); 233210037SARM gem5 Developers set_fpscr(fpscr, flags); 233310037SARM gem5 Developers return x; 233410037SARM gem5 Developers} 233510037SARM gem5 Developers 233610037SARM gem5 Developerstemplate <> 233710037SARM gem5 Developersbool 233810037SARM gem5 DevelopersfplibCompareGT(uint64_t a, uint64_t b, FPSCR &fpscr) 233910037SARM gem5 Developers{ 234010037SARM gem5 Developers int flags = 0; 234110037SARM gem5 Developers int x = fp64_compare_gt(a, b, modeConv(fpscr), &flags); 234210037SARM gem5 Developers set_fpscr(fpscr, flags); 234310037SARM gem5 Developers return x; 234410037SARM gem5 Developers} 234510037SARM gem5 Developers 234610037SARM gem5 Developerstemplate <> 234713118SEdmund.Grimley-Evans@arm.combool 234813118SEdmund.Grimley-Evans@arm.comfplibCompareUN(uint64_t a, uint64_t b, FPSCR &fpscr) 234913118SEdmund.Grimley-Evans@arm.com{ 235013118SEdmund.Grimley-Evans@arm.com int flags = 0; 235113118SEdmund.Grimley-Evans@arm.com int x = fp64_compare_un(a, b, modeConv(fpscr), &flags); 235213118SEdmund.Grimley-Evans@arm.com set_fpscr(fpscr, flags); 235313118SEdmund.Grimley-Evans@arm.com return x; 235413118SEdmund.Grimley-Evans@arm.com} 235513118SEdmund.Grimley-Evans@arm.com 235613118SEdmund.Grimley-Evans@arm.comtemplate <> 235713118SEdmund.Grimley-Evans@arm.comuint16_t 235813118SEdmund.Grimley-Evans@arm.comfplibAbs(uint16_t op) 235913118SEdmund.Grimley-Evans@arm.com{ 236013118SEdmund.Grimley-Evans@arm.com return op & ~(1ULL << (FP16_BITS - 1)); 236113118SEdmund.Grimley-Evans@arm.com} 236213118SEdmund.Grimley-Evans@arm.com 236313118SEdmund.Grimley-Evans@arm.comtemplate <> 236410037SARM gem5 Developersuint32_t 236510037SARM gem5 DevelopersfplibAbs(uint32_t op) 236610037SARM gem5 Developers{ 236713118SEdmund.Grimley-Evans@arm.com return op & ~(1ULL << (FP32_BITS - 1)); 236810037SARM gem5 Developers} 236910037SARM gem5 Developers 237010037SARM gem5 Developerstemplate <> 237110037SARM gem5 Developersuint64_t 237210037SARM gem5 DevelopersfplibAbs(uint64_t op) 237310037SARM gem5 Developers{ 237413118SEdmund.Grimley-Evans@arm.com return op & ~(1ULL << (FP64_BITS - 1)); 237513118SEdmund.Grimley-Evans@arm.com} 237613118SEdmund.Grimley-Evans@arm.com 237713118SEdmund.Grimley-Evans@arm.comtemplate <> 237813118SEdmund.Grimley-Evans@arm.comuint16_t 237913118SEdmund.Grimley-Evans@arm.comfplibAdd(uint16_t op1, uint16_t op2, FPSCR &fpscr) 238013118SEdmund.Grimley-Evans@arm.com{ 238113118SEdmund.Grimley-Evans@arm.com int flags = 0; 238213118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_add(op1, op2, 0, modeConv(fpscr), &flags); 238313118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 238413118SEdmund.Grimley-Evans@arm.com return result; 238510037SARM gem5 Developers} 238610037SARM gem5 Developers 238710037SARM gem5 Developerstemplate <> 238810037SARM gem5 Developersuint32_t 238910037SARM gem5 DevelopersfplibAdd(uint32_t op1, uint32_t op2, FPSCR &fpscr) 239010037SARM gem5 Developers{ 239110037SARM gem5 Developers int flags = 0; 239210037SARM gem5 Developers uint32_t result = fp32_add(op1, op2, 0, modeConv(fpscr), &flags); 239310037SARM gem5 Developers set_fpscr0(fpscr, flags); 239410037SARM gem5 Developers return result; 239510037SARM gem5 Developers} 239610037SARM gem5 Developers 239710037SARM gem5 Developerstemplate <> 239810037SARM gem5 Developersuint64_t 239910037SARM gem5 DevelopersfplibAdd(uint64_t op1, uint64_t op2, FPSCR &fpscr) 240010037SARM gem5 Developers{ 240110037SARM gem5 Developers int flags = 0; 240210037SARM gem5 Developers uint64_t result = fp64_add(op1, op2, 0, modeConv(fpscr), &flags); 240310037SARM gem5 Developers set_fpscr0(fpscr, flags); 240410037SARM gem5 Developers return result; 240510037SARM gem5 Developers} 240610037SARM gem5 Developers 240710037SARM gem5 Developerstemplate <> 240810037SARM gem5 Developersint 240913118SEdmund.Grimley-Evans@arm.comfplibCompare(uint16_t op1, uint16_t op2, bool signal_nans, FPSCR &fpscr) 241010037SARM gem5 Developers{ 241110037SARM gem5 Developers int mode = modeConv(fpscr); 241210037SARM gem5 Developers int flags = 0; 241310037SARM gem5 Developers int sgn1, exp1, sgn2, exp2, result; 241413118SEdmund.Grimley-Evans@arm.com uint16_t mnt1, mnt2; 241513118SEdmund.Grimley-Evans@arm.com 241613118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 241713118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 241813118SEdmund.Grimley-Evans@arm.com 241913118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp1, mnt1) || fp16_is_NaN(exp2, mnt2)) { 242010037SARM gem5 Developers result = 3; 242113118SEdmund.Grimley-Evans@arm.com if (fp16_is_signalling_NaN(exp1, mnt1) || 242213118SEdmund.Grimley-Evans@arm.com fp16_is_signalling_NaN(exp2, mnt2) || signal_nans) 242310037SARM gem5 Developers flags |= FPLIB_IOC; 242410037SARM gem5 Developers } else { 242510037SARM gem5 Developers if (op1 == op2 || (!mnt1 && !mnt2)) { 242610037SARM gem5 Developers result = 6; 242710037SARM gem5 Developers } else if (sgn1 != sgn2) { 242810037SARM gem5 Developers result = sgn1 ? 8 : 2; 242910037SARM gem5 Developers } else if (exp1 != exp2) { 243010037SARM gem5 Developers result = sgn1 ^ (exp1 < exp2) ? 8 : 2; 243110037SARM gem5 Developers } else { 243210037SARM gem5 Developers result = sgn1 ^ (mnt1 < mnt2) ? 8 : 2; 243310037SARM gem5 Developers } 243410037SARM gem5 Developers } 243510037SARM gem5 Developers 243610037SARM gem5 Developers set_fpscr0(fpscr, flags); 243710037SARM gem5 Developers 243810037SARM gem5 Developers return result; 243910037SARM gem5 Developers} 244010037SARM gem5 Developers 244110037SARM gem5 Developerstemplate <> 244210037SARM gem5 Developersint 244313118SEdmund.Grimley-Evans@arm.comfplibCompare(uint32_t op1, uint32_t op2, bool signal_nans, FPSCR &fpscr) 244410037SARM gem5 Developers{ 244510037SARM gem5 Developers int mode = modeConv(fpscr); 244610037SARM gem5 Developers int flags = 0; 244710037SARM gem5 Developers int sgn1, exp1, sgn2, exp2, result; 244813118SEdmund.Grimley-Evans@arm.com uint32_t mnt1, mnt2; 244913118SEdmund.Grimley-Evans@arm.com 245013118SEdmund.Grimley-Evans@arm.com fp32_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 245113118SEdmund.Grimley-Evans@arm.com fp32_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 245213118SEdmund.Grimley-Evans@arm.com 245313118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp1, mnt1) || fp32_is_NaN(exp2, mnt2)) { 245410037SARM gem5 Developers result = 3; 245513118SEdmund.Grimley-Evans@arm.com if (fp32_is_signalling_NaN(exp1, mnt1) || 245613118SEdmund.Grimley-Evans@arm.com fp32_is_signalling_NaN(exp2, mnt2) || signal_nans) 245710037SARM gem5 Developers flags |= FPLIB_IOC; 245810037SARM gem5 Developers } else { 245910037SARM gem5 Developers if (op1 == op2 || (!mnt1 && !mnt2)) { 246010037SARM gem5 Developers result = 6; 246110037SARM gem5 Developers } else if (sgn1 != sgn2) { 246210037SARM gem5 Developers result = sgn1 ? 8 : 2; 246310037SARM gem5 Developers } else if (exp1 != exp2) { 246410037SARM gem5 Developers result = sgn1 ^ (exp1 < exp2) ? 8 : 2; 246510037SARM gem5 Developers } else { 246610037SARM gem5 Developers result = sgn1 ^ (mnt1 < mnt2) ? 8 : 2; 246710037SARM gem5 Developers } 246810037SARM gem5 Developers } 246910037SARM gem5 Developers 247010037SARM gem5 Developers set_fpscr0(fpscr, flags); 247110037SARM gem5 Developers 247210037SARM gem5 Developers return result; 247310037SARM gem5 Developers} 247410037SARM gem5 Developers 247513118SEdmund.Grimley-Evans@arm.comtemplate <> 247613118SEdmund.Grimley-Evans@arm.comint 247713118SEdmund.Grimley-Evans@arm.comfplibCompare(uint64_t op1, uint64_t op2, bool signal_nans, FPSCR &fpscr) 247813118SEdmund.Grimley-Evans@arm.com{ 247913118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 248013118SEdmund.Grimley-Evans@arm.com int flags = 0; 248113118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2, result; 248213118SEdmund.Grimley-Evans@arm.com uint64_t mnt1, mnt2; 248313118SEdmund.Grimley-Evans@arm.com 248413118SEdmund.Grimley-Evans@arm.com fp64_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 248513118SEdmund.Grimley-Evans@arm.com fp64_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 248613118SEdmund.Grimley-Evans@arm.com 248713118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp1, mnt1) || fp64_is_NaN(exp2, mnt2)) { 248813118SEdmund.Grimley-Evans@arm.com result = 3; 248913118SEdmund.Grimley-Evans@arm.com if (fp64_is_signalling_NaN(exp1, mnt1) || 249013118SEdmund.Grimley-Evans@arm.com fp64_is_signalling_NaN(exp2, mnt2) || signal_nans) 249113118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_IOC; 249213118SEdmund.Grimley-Evans@arm.com } else { 249313118SEdmund.Grimley-Evans@arm.com if (op1 == op2 || (!mnt1 && !mnt2)) { 249413118SEdmund.Grimley-Evans@arm.com result = 6; 249513118SEdmund.Grimley-Evans@arm.com } else if (sgn1 != sgn2) { 249613118SEdmund.Grimley-Evans@arm.com result = sgn1 ? 8 : 2; 249713118SEdmund.Grimley-Evans@arm.com } else if (exp1 != exp2) { 249813118SEdmund.Grimley-Evans@arm.com result = sgn1 ^ (exp1 < exp2) ? 8 : 2; 249913118SEdmund.Grimley-Evans@arm.com } else { 250013118SEdmund.Grimley-Evans@arm.com result = sgn1 ^ (mnt1 < mnt2) ? 8 : 2; 250113118SEdmund.Grimley-Evans@arm.com } 250213118SEdmund.Grimley-Evans@arm.com } 250313118SEdmund.Grimley-Evans@arm.com 250413118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 250513118SEdmund.Grimley-Evans@arm.com 250613118SEdmund.Grimley-Evans@arm.com return result; 250713118SEdmund.Grimley-Evans@arm.com} 250813118SEdmund.Grimley-Evans@arm.com 250910037SARM gem5 Developersstatic uint16_t 251010037SARM gem5 Developersfp16_FPConvertNaN_32(uint32_t op) 251110037SARM gem5 Developers{ 251213118SEdmund.Grimley-Evans@arm.com return fp16_pack(op >> (FP32_BITS - 1), FP16_EXP_INF, 251313118SEdmund.Grimley-Evans@arm.com 1ULL << (FP16_MANT_BITS - 1) | 251413118SEdmund.Grimley-Evans@arm.com op >> (FP32_MANT_BITS - FP16_MANT_BITS)); 251510037SARM gem5 Developers} 251610037SARM gem5 Developers 251710037SARM gem5 Developersstatic uint16_t 251810037SARM gem5 Developersfp16_FPConvertNaN_64(uint64_t op) 251910037SARM gem5 Developers{ 252013118SEdmund.Grimley-Evans@arm.com return fp16_pack(op >> (FP64_BITS - 1), FP16_EXP_INF, 252113118SEdmund.Grimley-Evans@arm.com 1ULL << (FP16_MANT_BITS - 1) | 252213118SEdmund.Grimley-Evans@arm.com op >> (FP64_MANT_BITS - FP16_MANT_BITS)); 252310037SARM gem5 Developers} 252410037SARM gem5 Developers 252510037SARM gem5 Developersstatic uint32_t 252610037SARM gem5 Developersfp32_FPConvertNaN_16(uint16_t op) 252710037SARM gem5 Developers{ 252813118SEdmund.Grimley-Evans@arm.com return fp32_pack(op >> (FP16_BITS - 1), FP32_EXP_INF, 252913118SEdmund.Grimley-Evans@arm.com 1ULL << (FP32_MANT_BITS - 1) | 253013118SEdmund.Grimley-Evans@arm.com (uint32_t)op << (FP32_MANT_BITS - FP16_MANT_BITS)); 253110037SARM gem5 Developers} 253210037SARM gem5 Developers 253310037SARM gem5 Developersstatic uint32_t 253410037SARM gem5 Developersfp32_FPConvertNaN_64(uint64_t op) 253510037SARM gem5 Developers{ 253613118SEdmund.Grimley-Evans@arm.com return fp32_pack(op >> (FP64_BITS - 1), FP32_EXP_INF, 253713118SEdmund.Grimley-Evans@arm.com 1ULL << (FP32_MANT_BITS - 1) | 253813118SEdmund.Grimley-Evans@arm.com op >> (FP64_MANT_BITS - FP32_MANT_BITS)); 253910037SARM gem5 Developers} 254010037SARM gem5 Developers 254110037SARM gem5 Developersstatic uint64_t 254210037SARM gem5 Developersfp64_FPConvertNaN_16(uint16_t op) 254310037SARM gem5 Developers{ 254413118SEdmund.Grimley-Evans@arm.com return fp64_pack(op >> (FP16_BITS - 1), FP64_EXP_INF, 254513118SEdmund.Grimley-Evans@arm.com 1ULL << (FP64_MANT_BITS - 1) | 254613118SEdmund.Grimley-Evans@arm.com (uint64_t)op << (FP64_MANT_BITS - FP16_MANT_BITS)); 254710037SARM gem5 Developers} 254810037SARM gem5 Developers 254910037SARM gem5 Developersstatic uint64_t 255010037SARM gem5 Developersfp64_FPConvertNaN_32(uint32_t op) 255110037SARM gem5 Developers{ 255213118SEdmund.Grimley-Evans@arm.com return fp64_pack(op >> (FP32_BITS - 1), FP64_EXP_INF, 255313118SEdmund.Grimley-Evans@arm.com 1ULL << (FP64_MANT_BITS - 1) | 255413118SEdmund.Grimley-Evans@arm.com (uint64_t)op << (FP64_MANT_BITS - FP32_MANT_BITS)); 255513118SEdmund.Grimley-Evans@arm.com} 255613118SEdmund.Grimley-Evans@arm.com 255713118SEdmund.Grimley-Evans@arm.comstatic uint16_t 255813118SEdmund.Grimley-Evans@arm.comfp16_FPOnePointFive(int sgn) 255913118SEdmund.Grimley-Evans@arm.com{ 256013118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, FP16_EXP_BIAS, 1ULL << (FP16_MANT_BITS - 1)); 256110037SARM gem5 Developers} 256210037SARM gem5 Developers 256310037SARM gem5 Developersstatic uint32_t 256410037SARM gem5 Developersfp32_FPOnePointFive(int sgn) 256510037SARM gem5 Developers{ 256613118SEdmund.Grimley-Evans@arm.com return fp32_pack(sgn, FP32_EXP_BIAS, 1ULL << (FP32_MANT_BITS - 1)); 256710037SARM gem5 Developers} 256810037SARM gem5 Developers 256910037SARM gem5 Developersstatic uint64_t 257010037SARM gem5 Developersfp64_FPOnePointFive(int sgn) 257110037SARM gem5 Developers{ 257213118SEdmund.Grimley-Evans@arm.com return fp64_pack(sgn, FP64_EXP_BIAS, 1ULL << (FP64_MANT_BITS - 1)); 257313118SEdmund.Grimley-Evans@arm.com} 257413118SEdmund.Grimley-Evans@arm.com 257513118SEdmund.Grimley-Evans@arm.comstatic uint16_t 257613118SEdmund.Grimley-Evans@arm.comfp16_FPThree(int sgn) 257713118SEdmund.Grimley-Evans@arm.com{ 257813118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, FP16_EXP_BIAS + 1, 1ULL << (FP16_MANT_BITS - 1)); 257910037SARM gem5 Developers} 258010037SARM gem5 Developers 258110037SARM gem5 Developersstatic uint32_t 258210037SARM gem5 Developersfp32_FPThree(int sgn) 258310037SARM gem5 Developers{ 258413118SEdmund.Grimley-Evans@arm.com return fp32_pack(sgn, FP32_EXP_BIAS + 1, 1ULL << (FP32_MANT_BITS - 1)); 258510037SARM gem5 Developers} 258610037SARM gem5 Developers 258710037SARM gem5 Developersstatic uint64_t 258810037SARM gem5 Developersfp64_FPThree(int sgn) 258910037SARM gem5 Developers{ 259013118SEdmund.Grimley-Evans@arm.com return fp64_pack(sgn, FP64_EXP_BIAS + 1, 1ULL << (FP64_MANT_BITS - 1)); 259113118SEdmund.Grimley-Evans@arm.com} 259213118SEdmund.Grimley-Evans@arm.com 259313118SEdmund.Grimley-Evans@arm.comstatic uint16_t 259413118SEdmund.Grimley-Evans@arm.comfp16_FPTwo(int sgn) 259513118SEdmund.Grimley-Evans@arm.com{ 259613118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, FP16_EXP_BIAS + 1, 0); 259710037SARM gem5 Developers} 259810037SARM gem5 Developers 259910037SARM gem5 Developersstatic uint32_t 260010037SARM gem5 Developersfp32_FPTwo(int sgn) 260110037SARM gem5 Developers{ 260213118SEdmund.Grimley-Evans@arm.com return fp32_pack(sgn, FP32_EXP_BIAS + 1, 0); 260310037SARM gem5 Developers} 260410037SARM gem5 Developers 260510037SARM gem5 Developersstatic uint64_t 260610037SARM gem5 Developersfp64_FPTwo(int sgn) 260710037SARM gem5 Developers{ 260813118SEdmund.Grimley-Evans@arm.com return fp64_pack(sgn, FP64_EXP_BIAS + 1, 0); 260910037SARM gem5 Developers} 261010037SARM gem5 Developers 261110037SARM gem5 Developerstemplate <> 261210037SARM gem5 Developersuint16_t 261310037SARM gem5 DevelopersfplibConvert(uint32_t op, FPRounding rounding, FPSCR &fpscr) 261410037SARM gem5 Developers{ 261510037SARM gem5 Developers int mode = modeConv(fpscr); 261610037SARM gem5 Developers int flags = 0; 261710037SARM gem5 Developers int sgn, exp; 261810037SARM gem5 Developers uint32_t mnt; 261910037SARM gem5 Developers uint16_t result; 262010037SARM gem5 Developers 262110037SARM gem5 Developers // Unpack floating-point operand optionally with flush-to-zero: 262210037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, mode, &flags); 262310037SARM gem5 Developers 262410037SARM gem5 Developers bool alt_hp = fpscr.ahp; 262510037SARM gem5 Developers 262613118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 262710037SARM gem5 Developers if (alt_hp) { 262810037SARM gem5 Developers result = fp16_zero(sgn); 262910037SARM gem5 Developers } else if (fpscr.dn) { 263010037SARM gem5 Developers result = fp16_defaultNaN(); 263110037SARM gem5 Developers } else { 263210037SARM gem5 Developers result = fp16_FPConvertNaN_32(op); 263310037SARM gem5 Developers } 263413118SEdmund.Grimley-Evans@arm.com if (!(mnt >> (FP32_MANT_BITS - 1) & 1) || alt_hp) { 263510037SARM gem5 Developers flags |= FPLIB_IOC; 263610037SARM gem5 Developers } 263713118SEdmund.Grimley-Evans@arm.com } else if (exp == FP32_EXP_INF) { 263810037SARM gem5 Developers if (alt_hp) { 263913118SEdmund.Grimley-Evans@arm.com result = ((uint16_t)sgn << (FP16_BITS - 1) | 264013118SEdmund.Grimley-Evans@arm.com ((1ULL << (FP16_BITS - 1)) - 1)); 264110037SARM gem5 Developers flags |= FPLIB_IOC; 264210037SARM gem5 Developers } else { 264310037SARM gem5 Developers result = fp16_infinity(sgn); 264410037SARM gem5 Developers } 264510037SARM gem5 Developers } else if (!mnt) { 264610037SARM gem5 Developers result = fp16_zero(sgn); 264710037SARM gem5 Developers } else { 264813118SEdmund.Grimley-Evans@arm.com result = 264913118SEdmund.Grimley-Evans@arm.com fp16_round_(sgn, exp - FP32_EXP_BIAS + FP16_EXP_BIAS, 265013118SEdmund.Grimley-Evans@arm.com mnt >> (FP32_MANT_BITS - FP16_BITS) | 265113118SEdmund.Grimley-Evans@arm.com !!(mnt & ((1ULL << (FP32_MANT_BITS - FP16_BITS)) - 1)), 265213118SEdmund.Grimley-Evans@arm.com rounding, (mode & 0xf) | alt_hp << 4, &flags); 265310037SARM gem5 Developers } 265410037SARM gem5 Developers 265510037SARM gem5 Developers set_fpscr0(fpscr, flags); 265610037SARM gem5 Developers 265710037SARM gem5 Developers return result; 265810037SARM gem5 Developers} 265910037SARM gem5 Developers 266010037SARM gem5 Developerstemplate <> 266110037SARM gem5 Developersuint16_t 266210037SARM gem5 DevelopersfplibConvert(uint64_t op, FPRounding rounding, FPSCR &fpscr) 266310037SARM gem5 Developers{ 266410037SARM gem5 Developers int mode = modeConv(fpscr); 266510037SARM gem5 Developers int flags = 0; 266610037SARM gem5 Developers int sgn, exp; 266710037SARM gem5 Developers uint64_t mnt; 266810037SARM gem5 Developers uint16_t result; 266910037SARM gem5 Developers 267010037SARM gem5 Developers // Unpack floating-point operand optionally with flush-to-zero: 267110037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, mode, &flags); 267210037SARM gem5 Developers 267310037SARM gem5 Developers bool alt_hp = fpscr.ahp; 267410037SARM gem5 Developers 267513118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 267610037SARM gem5 Developers if (alt_hp) { 267710037SARM gem5 Developers result = fp16_zero(sgn); 267810037SARM gem5 Developers } else if (fpscr.dn) { 267910037SARM gem5 Developers result = fp16_defaultNaN(); 268010037SARM gem5 Developers } else { 268110037SARM gem5 Developers result = fp16_FPConvertNaN_64(op); 268210037SARM gem5 Developers } 268313118SEdmund.Grimley-Evans@arm.com if (!(mnt >> (FP64_MANT_BITS - 1) & 1) || alt_hp) { 268410037SARM gem5 Developers flags |= FPLIB_IOC; 268510037SARM gem5 Developers } 268613118SEdmund.Grimley-Evans@arm.com } else if (exp == FP64_EXP_INF) { 268710037SARM gem5 Developers if (alt_hp) { 268813118SEdmund.Grimley-Evans@arm.com result = ((uint16_t)sgn << (FP16_BITS - 1) | 268913118SEdmund.Grimley-Evans@arm.com ((1ULL << (FP16_BITS - 1)) - 1)); 269010037SARM gem5 Developers flags |= FPLIB_IOC; 269110037SARM gem5 Developers } else { 269210037SARM gem5 Developers result = fp16_infinity(sgn); 269310037SARM gem5 Developers } 269410037SARM gem5 Developers } else if (!mnt) { 269510037SARM gem5 Developers result = fp16_zero(sgn); 269610037SARM gem5 Developers } else { 269713118SEdmund.Grimley-Evans@arm.com result = 269813118SEdmund.Grimley-Evans@arm.com fp16_round_(sgn, exp - FP64_EXP_BIAS + FP16_EXP_BIAS, 269913118SEdmund.Grimley-Evans@arm.com mnt >> (FP64_MANT_BITS - FP16_BITS) | 270013118SEdmund.Grimley-Evans@arm.com !!(mnt & ((1ULL << (FP64_MANT_BITS - FP16_BITS)) - 1)), 270113118SEdmund.Grimley-Evans@arm.com rounding, (mode & 0xf) | alt_hp << 4, &flags); 270210037SARM gem5 Developers } 270310037SARM gem5 Developers 270410037SARM gem5 Developers set_fpscr0(fpscr, flags); 270510037SARM gem5 Developers 270610037SARM gem5 Developers return result; 270710037SARM gem5 Developers} 270810037SARM gem5 Developers 270910037SARM gem5 Developerstemplate <> 271010037SARM gem5 Developersuint32_t 271110037SARM gem5 DevelopersfplibConvert(uint16_t op, FPRounding rounding, FPSCR &fpscr) 271210037SARM gem5 Developers{ 271310037SARM gem5 Developers int mode = modeConv(fpscr); 271410037SARM gem5 Developers int flags = 0; 271510037SARM gem5 Developers int sgn, exp; 271610037SARM gem5 Developers uint16_t mnt; 271710037SARM gem5 Developers uint32_t result; 271810037SARM gem5 Developers 271910037SARM gem5 Developers // Unpack floating-point operand optionally with flush-to-zero: 272013118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, mode & 0xf, &flags); 272113118SEdmund.Grimley-Evans@arm.com 272213118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt) && !fpscr.ahp) { 272310037SARM gem5 Developers if (fpscr.dn) { 272410037SARM gem5 Developers result = fp32_defaultNaN(); 272510037SARM gem5 Developers } else { 272610037SARM gem5 Developers result = fp32_FPConvertNaN_16(op); 272710037SARM gem5 Developers } 272813118SEdmund.Grimley-Evans@arm.com if (!(mnt >> (FP16_MANT_BITS - 1) & 1)) { 272910037SARM gem5 Developers flags |= FPLIB_IOC; 273010037SARM gem5 Developers } 273113118SEdmund.Grimley-Evans@arm.com } else if (exp == FP16_EXP_INF && !fpscr.ahp) { 273210037SARM gem5 Developers result = fp32_infinity(sgn); 273310037SARM gem5 Developers } else if (!mnt) { 273410037SARM gem5 Developers result = fp32_zero(sgn); 273510037SARM gem5 Developers } else { 273610037SARM gem5 Developers mnt = fp16_normalise(mnt, &exp); 273713118SEdmund.Grimley-Evans@arm.com result = fp32_pack(sgn, (exp - FP16_EXP_BIAS + 273813118SEdmund.Grimley-Evans@arm.com FP32_EXP_BIAS + FP16_EXP_BITS), 273913118SEdmund.Grimley-Evans@arm.com (uint32_t)mnt << (FP32_MANT_BITS - FP16_BITS + 1)); 274010037SARM gem5 Developers } 274110037SARM gem5 Developers 274210037SARM gem5 Developers set_fpscr0(fpscr, flags); 274310037SARM gem5 Developers 274410037SARM gem5 Developers return result; 274510037SARM gem5 Developers} 274610037SARM gem5 Developers 274710037SARM gem5 Developerstemplate <> 274810037SARM gem5 Developersuint32_t 274910037SARM gem5 DevelopersfplibConvert(uint64_t op, FPRounding rounding, FPSCR &fpscr) 275010037SARM gem5 Developers{ 275110037SARM gem5 Developers int mode = modeConv(fpscr); 275210037SARM gem5 Developers int flags = 0; 275310037SARM gem5 Developers int sgn, exp; 275410037SARM gem5 Developers uint64_t mnt; 275510037SARM gem5 Developers uint32_t result; 275610037SARM gem5 Developers 275710037SARM gem5 Developers // Unpack floating-point operand optionally with flush-to-zero: 275810037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, mode, &flags); 275910037SARM gem5 Developers 276013118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 276110037SARM gem5 Developers if (fpscr.dn) { 276210037SARM gem5 Developers result = fp32_defaultNaN(); 276310037SARM gem5 Developers } else { 276410037SARM gem5 Developers result = fp32_FPConvertNaN_64(op); 276510037SARM gem5 Developers } 276613118SEdmund.Grimley-Evans@arm.com if (!(mnt >> (FP64_MANT_BITS - 1) & 1)) { 276710037SARM gem5 Developers flags |= FPLIB_IOC; 276810037SARM gem5 Developers } 276913118SEdmund.Grimley-Evans@arm.com } else if (exp == FP64_EXP_INF) { 277010037SARM gem5 Developers result = fp32_infinity(sgn); 277110037SARM gem5 Developers } else if (!mnt) { 277210037SARM gem5 Developers result = fp32_zero(sgn); 277310037SARM gem5 Developers } else { 277413118SEdmund.Grimley-Evans@arm.com result = 277513118SEdmund.Grimley-Evans@arm.com fp32_round_(sgn, exp - FP64_EXP_BIAS + FP32_EXP_BIAS, 277613118SEdmund.Grimley-Evans@arm.com mnt >> (FP64_MANT_BITS - FP32_BITS) | 277713118SEdmund.Grimley-Evans@arm.com !!(mnt & ((1ULL << (FP64_MANT_BITS - FP32_BITS)) - 1)), 277813118SEdmund.Grimley-Evans@arm.com rounding, mode, &flags); 277910037SARM gem5 Developers } 278010037SARM gem5 Developers 278110037SARM gem5 Developers set_fpscr0(fpscr, flags); 278210037SARM gem5 Developers 278310037SARM gem5 Developers return result; 278410037SARM gem5 Developers} 278510037SARM gem5 Developers 278610037SARM gem5 Developerstemplate <> 278710037SARM gem5 Developersuint64_t 278810037SARM gem5 DevelopersfplibConvert(uint16_t op, FPRounding rounding, FPSCR &fpscr) 278910037SARM gem5 Developers{ 279010037SARM gem5 Developers int mode = modeConv(fpscr); 279110037SARM gem5 Developers int flags = 0; 279210037SARM gem5 Developers int sgn, exp; 279310037SARM gem5 Developers uint16_t mnt; 279410037SARM gem5 Developers uint64_t result; 279510037SARM gem5 Developers 279610037SARM gem5 Developers // Unpack floating-point operand optionally with flush-to-zero: 279713118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, mode & 0xf, &flags); 279813118SEdmund.Grimley-Evans@arm.com 279913118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt) && !fpscr.ahp) { 280010037SARM gem5 Developers if (fpscr.dn) { 280110037SARM gem5 Developers result = fp64_defaultNaN(); 280210037SARM gem5 Developers } else { 280310037SARM gem5 Developers result = fp64_FPConvertNaN_16(op); 280410037SARM gem5 Developers } 280513118SEdmund.Grimley-Evans@arm.com if (!(mnt >> (FP16_MANT_BITS - 1) & 1)) { 280610037SARM gem5 Developers flags |= FPLIB_IOC; 280710037SARM gem5 Developers } 280813118SEdmund.Grimley-Evans@arm.com } else if (exp == FP16_EXP_INF && !fpscr.ahp) { 280910037SARM gem5 Developers result = fp64_infinity(sgn); 281010037SARM gem5 Developers } else if (!mnt) { 281110037SARM gem5 Developers result = fp64_zero(sgn); 281210037SARM gem5 Developers } else { 281310037SARM gem5 Developers mnt = fp16_normalise(mnt, &exp); 281413118SEdmund.Grimley-Evans@arm.com result = fp64_pack(sgn, (exp - FP16_EXP_BIAS + 281513118SEdmund.Grimley-Evans@arm.com FP64_EXP_BIAS + FP16_EXP_BITS), 281613118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP16_BITS + 1)); 281710037SARM gem5 Developers } 281810037SARM gem5 Developers 281910037SARM gem5 Developers set_fpscr0(fpscr, flags); 282010037SARM gem5 Developers 282110037SARM gem5 Developers return result; 282210037SARM gem5 Developers} 282310037SARM gem5 Developers 282410037SARM gem5 Developerstemplate <> 282510037SARM gem5 Developersuint64_t 282610037SARM gem5 DevelopersfplibConvert(uint32_t op, FPRounding rounding, FPSCR &fpscr) 282710037SARM gem5 Developers{ 282810037SARM gem5 Developers int mode = modeConv(fpscr); 282910037SARM gem5 Developers int flags = 0; 283010037SARM gem5 Developers int sgn, exp; 283110037SARM gem5 Developers uint32_t mnt; 283210037SARM gem5 Developers uint64_t result; 283310037SARM gem5 Developers 283410037SARM gem5 Developers // Unpack floating-point operand optionally with flush-to-zero: 283510037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, mode, &flags); 283610037SARM gem5 Developers 283713118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 283810037SARM gem5 Developers if (fpscr.dn) { 283910037SARM gem5 Developers result = fp64_defaultNaN(); 284010037SARM gem5 Developers } else { 284110037SARM gem5 Developers result = fp64_FPConvertNaN_32(op); 284210037SARM gem5 Developers } 284313118SEdmund.Grimley-Evans@arm.com if (!(mnt >> (FP32_MANT_BITS - 1) & 1)) { 284410037SARM gem5 Developers flags |= FPLIB_IOC; 284510037SARM gem5 Developers } 284613118SEdmund.Grimley-Evans@arm.com } else if (exp == FP32_EXP_INF) { 284710037SARM gem5 Developers result = fp64_infinity(sgn); 284810037SARM gem5 Developers } else if (!mnt) { 284910037SARM gem5 Developers result = fp64_zero(sgn); 285010037SARM gem5 Developers } else { 285110037SARM gem5 Developers mnt = fp32_normalise(mnt, &exp); 285213118SEdmund.Grimley-Evans@arm.com result = fp64_pack(sgn, (exp - FP32_EXP_BIAS + 285313118SEdmund.Grimley-Evans@arm.com FP64_EXP_BIAS + FP32_EXP_BITS), 285413118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP32_BITS + 1)); 285510037SARM gem5 Developers } 285610037SARM gem5 Developers 285710037SARM gem5 Developers set_fpscr0(fpscr, flags); 285810037SARM gem5 Developers 285910037SARM gem5 Developers return result; 286010037SARM gem5 Developers} 286110037SARM gem5 Developers 286210037SARM gem5 Developerstemplate <> 286313118SEdmund.Grimley-Evans@arm.comuint16_t 286413118SEdmund.Grimley-Evans@arm.comfplibMulAdd(uint16_t addend, uint16_t op1, uint16_t op2, FPSCR &fpscr) 286513118SEdmund.Grimley-Evans@arm.com{ 286613118SEdmund.Grimley-Evans@arm.com int flags = 0; 286713118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_muladd(addend, op1, op2, 0, modeConv(fpscr), &flags); 286813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 286913118SEdmund.Grimley-Evans@arm.com return result; 287013118SEdmund.Grimley-Evans@arm.com} 287113118SEdmund.Grimley-Evans@arm.com 287213118SEdmund.Grimley-Evans@arm.comtemplate <> 287310037SARM gem5 Developersuint32_t 287410037SARM gem5 DevelopersfplibMulAdd(uint32_t addend, uint32_t op1, uint32_t op2, FPSCR &fpscr) 287510037SARM gem5 Developers{ 287610037SARM gem5 Developers int flags = 0; 287710037SARM gem5 Developers uint32_t result = fp32_muladd(addend, op1, op2, 0, modeConv(fpscr), &flags); 287810037SARM gem5 Developers set_fpscr0(fpscr, flags); 287910037SARM gem5 Developers return result; 288010037SARM gem5 Developers} 288110037SARM gem5 Developers 288210037SARM gem5 Developerstemplate <> 288310037SARM gem5 Developersuint64_t 288410037SARM gem5 DevelopersfplibMulAdd(uint64_t addend, uint64_t op1, uint64_t op2, FPSCR &fpscr) 288510037SARM gem5 Developers{ 288610037SARM gem5 Developers int flags = 0; 288710037SARM gem5 Developers uint64_t result = fp64_muladd(addend, op1, op2, 0, modeConv(fpscr), &flags); 288810037SARM gem5 Developers set_fpscr0(fpscr, flags); 288910037SARM gem5 Developers return result; 289010037SARM gem5 Developers} 289110037SARM gem5 Developers 289210037SARM gem5 Developerstemplate <> 289313118SEdmund.Grimley-Evans@arm.comuint16_t 289413118SEdmund.Grimley-Evans@arm.comfplibDiv(uint16_t op1, uint16_t op2, FPSCR &fpscr) 289513118SEdmund.Grimley-Evans@arm.com{ 289613118SEdmund.Grimley-Evans@arm.com int flags = 0; 289713118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_div(op1, op2, modeConv(fpscr), &flags); 289813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 289913118SEdmund.Grimley-Evans@arm.com return result; 290013118SEdmund.Grimley-Evans@arm.com} 290113118SEdmund.Grimley-Evans@arm.com 290213118SEdmund.Grimley-Evans@arm.comtemplate <> 290310037SARM gem5 Developersuint32_t 290410037SARM gem5 DevelopersfplibDiv(uint32_t op1, uint32_t op2, FPSCR &fpscr) 290510037SARM gem5 Developers{ 290610037SARM gem5 Developers int flags = 0; 290710037SARM gem5 Developers uint32_t result = fp32_div(op1, op2, modeConv(fpscr), &flags); 290810037SARM gem5 Developers set_fpscr0(fpscr, flags); 290910037SARM gem5 Developers return result; 291010037SARM gem5 Developers} 291110037SARM gem5 Developers 291210037SARM gem5 Developerstemplate <> 291310037SARM gem5 Developersuint64_t 291410037SARM gem5 DevelopersfplibDiv(uint64_t op1, uint64_t op2, FPSCR &fpscr) 291510037SARM gem5 Developers{ 291610037SARM gem5 Developers int flags = 0; 291710037SARM gem5 Developers uint64_t result = fp64_div(op1, op2, modeConv(fpscr), &flags); 291810037SARM gem5 Developers set_fpscr0(fpscr, flags); 291910037SARM gem5 Developers return result; 292010037SARM gem5 Developers} 292110037SARM gem5 Developers 292213118SEdmund.Grimley-Evans@arm.comtemplate <> 292313118SEdmund.Grimley-Evans@arm.comuint16_t 292413118SEdmund.Grimley-Evans@arm.comfplibExpA(uint16_t op) 292513118SEdmund.Grimley-Evans@arm.com{ 292613118SEdmund.Grimley-Evans@arm.com static uint16_t coeff[32] = { 292713118SEdmund.Grimley-Evans@arm.com 0x0000, 292813118SEdmund.Grimley-Evans@arm.com 0x0016, 292913118SEdmund.Grimley-Evans@arm.com 0x002d, 293013118SEdmund.Grimley-Evans@arm.com 0x0045, 293113118SEdmund.Grimley-Evans@arm.com 0x005d, 293213118SEdmund.Grimley-Evans@arm.com 0x0075, 293313118SEdmund.Grimley-Evans@arm.com 0x008e, 293413118SEdmund.Grimley-Evans@arm.com 0x00a8, 293513118SEdmund.Grimley-Evans@arm.com 0x00c2, 293613118SEdmund.Grimley-Evans@arm.com 0x00dc, 293713118SEdmund.Grimley-Evans@arm.com 0x00f8, 293813118SEdmund.Grimley-Evans@arm.com 0x0114, 293913118SEdmund.Grimley-Evans@arm.com 0x0130, 294013118SEdmund.Grimley-Evans@arm.com 0x014d, 294113118SEdmund.Grimley-Evans@arm.com 0x016b, 294213118SEdmund.Grimley-Evans@arm.com 0x0189, 294313118SEdmund.Grimley-Evans@arm.com 0x01a8, 294413118SEdmund.Grimley-Evans@arm.com 0x01c8, 294513118SEdmund.Grimley-Evans@arm.com 0x01e8, 294613118SEdmund.Grimley-Evans@arm.com 0x0209, 294713118SEdmund.Grimley-Evans@arm.com 0x022b, 294813118SEdmund.Grimley-Evans@arm.com 0x024e, 294913118SEdmund.Grimley-Evans@arm.com 0x0271, 295013118SEdmund.Grimley-Evans@arm.com 0x0295, 295113118SEdmund.Grimley-Evans@arm.com 0x02ba, 295213118SEdmund.Grimley-Evans@arm.com 0x02e0, 295313118SEdmund.Grimley-Evans@arm.com 0x0306, 295413118SEdmund.Grimley-Evans@arm.com 0x032e, 295513118SEdmund.Grimley-Evans@arm.com 0x0356, 295613118SEdmund.Grimley-Evans@arm.com 0x037f, 295713118SEdmund.Grimley-Evans@arm.com 0x03a9, 295813118SEdmund.Grimley-Evans@arm.com 0x03d4 295913118SEdmund.Grimley-Evans@arm.com }; 296013118SEdmund.Grimley-Evans@arm.com return ((((op >> 5) & ((1 << FP16_EXP_BITS) - 1)) << FP16_MANT_BITS) | 296113118SEdmund.Grimley-Evans@arm.com coeff[op & ((1 << 5) - 1)]); 296213118SEdmund.Grimley-Evans@arm.com} 296313118SEdmund.Grimley-Evans@arm.com 296413118SEdmund.Grimley-Evans@arm.comtemplate <> 296513118SEdmund.Grimley-Evans@arm.comuint32_t 296613118SEdmund.Grimley-Evans@arm.comfplibExpA(uint32_t op) 296713118SEdmund.Grimley-Evans@arm.com{ 296813118SEdmund.Grimley-Evans@arm.com static uint32_t coeff[64] = { 296913118SEdmund.Grimley-Evans@arm.com 0x000000, 297013118SEdmund.Grimley-Evans@arm.com 0x0164d2, 297113118SEdmund.Grimley-Evans@arm.com 0x02cd87, 297213118SEdmund.Grimley-Evans@arm.com 0x043a29, 297313118SEdmund.Grimley-Evans@arm.com 0x05aac3, 297413118SEdmund.Grimley-Evans@arm.com 0x071f62, 297513118SEdmund.Grimley-Evans@arm.com 0x08980f, 297613118SEdmund.Grimley-Evans@arm.com 0x0a14d5, 297713118SEdmund.Grimley-Evans@arm.com 0x0b95c2, 297813118SEdmund.Grimley-Evans@arm.com 0x0d1adf, 297913118SEdmund.Grimley-Evans@arm.com 0x0ea43a, 298013118SEdmund.Grimley-Evans@arm.com 0x1031dc, 298113118SEdmund.Grimley-Evans@arm.com 0x11c3d3, 298213118SEdmund.Grimley-Evans@arm.com 0x135a2b, 298313118SEdmund.Grimley-Evans@arm.com 0x14f4f0, 298413118SEdmund.Grimley-Evans@arm.com 0x16942d, 298513118SEdmund.Grimley-Evans@arm.com 0x1837f0, 298613118SEdmund.Grimley-Evans@arm.com 0x19e046, 298713118SEdmund.Grimley-Evans@arm.com 0x1b8d3a, 298813118SEdmund.Grimley-Evans@arm.com 0x1d3eda, 298913118SEdmund.Grimley-Evans@arm.com 0x1ef532, 299013118SEdmund.Grimley-Evans@arm.com 0x20b051, 299113118SEdmund.Grimley-Evans@arm.com 0x227043, 299213118SEdmund.Grimley-Evans@arm.com 0x243516, 299313118SEdmund.Grimley-Evans@arm.com 0x25fed7, 299413118SEdmund.Grimley-Evans@arm.com 0x27cd94, 299513118SEdmund.Grimley-Evans@arm.com 0x29a15b, 299613118SEdmund.Grimley-Evans@arm.com 0x2b7a3a, 299713118SEdmund.Grimley-Evans@arm.com 0x2d583f, 299813118SEdmund.Grimley-Evans@arm.com 0x2f3b79, 299913118SEdmund.Grimley-Evans@arm.com 0x3123f6, 300013118SEdmund.Grimley-Evans@arm.com 0x3311c4, 300113118SEdmund.Grimley-Evans@arm.com 0x3504f3, 300213118SEdmund.Grimley-Evans@arm.com 0x36fd92, 300313118SEdmund.Grimley-Evans@arm.com 0x38fbaf, 300413118SEdmund.Grimley-Evans@arm.com 0x3aff5b, 300513118SEdmund.Grimley-Evans@arm.com 0x3d08a4, 300613118SEdmund.Grimley-Evans@arm.com 0x3f179a, 300713118SEdmund.Grimley-Evans@arm.com 0x412c4d, 300813118SEdmund.Grimley-Evans@arm.com 0x4346cd, 300913118SEdmund.Grimley-Evans@arm.com 0x45672a, 301013118SEdmund.Grimley-Evans@arm.com 0x478d75, 301113118SEdmund.Grimley-Evans@arm.com 0x49b9be, 301213118SEdmund.Grimley-Evans@arm.com 0x4bec15, 301313118SEdmund.Grimley-Evans@arm.com 0x4e248c, 301413118SEdmund.Grimley-Evans@arm.com 0x506334, 301513118SEdmund.Grimley-Evans@arm.com 0x52a81e, 301613118SEdmund.Grimley-Evans@arm.com 0x54f35b, 301713118SEdmund.Grimley-Evans@arm.com 0x5744fd, 301813118SEdmund.Grimley-Evans@arm.com 0x599d16, 301913118SEdmund.Grimley-Evans@arm.com 0x5bfbb8, 302013118SEdmund.Grimley-Evans@arm.com 0x5e60f5, 302113118SEdmund.Grimley-Evans@arm.com 0x60ccdf, 302213118SEdmund.Grimley-Evans@arm.com 0x633f89, 302313118SEdmund.Grimley-Evans@arm.com 0x65b907, 302413118SEdmund.Grimley-Evans@arm.com 0x68396a, 302513118SEdmund.Grimley-Evans@arm.com 0x6ac0c7, 302613118SEdmund.Grimley-Evans@arm.com 0x6d4f30, 302713118SEdmund.Grimley-Evans@arm.com 0x6fe4ba, 302813118SEdmund.Grimley-Evans@arm.com 0x728177, 302913118SEdmund.Grimley-Evans@arm.com 0x75257d, 303013118SEdmund.Grimley-Evans@arm.com 0x77d0df, 303113118SEdmund.Grimley-Evans@arm.com 0x7a83b3, 303213118SEdmund.Grimley-Evans@arm.com 0x7d3e0c 303313118SEdmund.Grimley-Evans@arm.com }; 303413118SEdmund.Grimley-Evans@arm.com return ((((op >> 6) & ((1 << FP32_EXP_BITS) - 1)) << FP32_MANT_BITS) | 303513118SEdmund.Grimley-Evans@arm.com coeff[op & ((1 << 6) - 1)]); 303613118SEdmund.Grimley-Evans@arm.com} 303713118SEdmund.Grimley-Evans@arm.com 303813118SEdmund.Grimley-Evans@arm.comtemplate <> 303913118SEdmund.Grimley-Evans@arm.comuint64_t 304013118SEdmund.Grimley-Evans@arm.comfplibExpA(uint64_t op) 304113118SEdmund.Grimley-Evans@arm.com{ 304213118SEdmund.Grimley-Evans@arm.com static uint64_t coeff[64] = { 304313118SEdmund.Grimley-Evans@arm.com 0x0000000000000ULL, 304413118SEdmund.Grimley-Evans@arm.com 0x02c9a3e778061ULL, 304513118SEdmund.Grimley-Evans@arm.com 0x059b0d3158574ULL, 304613118SEdmund.Grimley-Evans@arm.com 0x0874518759bc8ULL, 304713118SEdmund.Grimley-Evans@arm.com 0x0b5586cf9890fULL, 304813118SEdmund.Grimley-Evans@arm.com 0x0e3ec32d3d1a2ULL, 304913118SEdmund.Grimley-Evans@arm.com 0x11301d0125b51ULL, 305013118SEdmund.Grimley-Evans@arm.com 0x1429aaea92de0ULL, 305113118SEdmund.Grimley-Evans@arm.com 0x172b83c7d517bULL, 305213118SEdmund.Grimley-Evans@arm.com 0x1a35beb6fcb75ULL, 305313118SEdmund.Grimley-Evans@arm.com 0x1d4873168b9aaULL, 305413118SEdmund.Grimley-Evans@arm.com 0x2063b88628cd6ULL, 305513118SEdmund.Grimley-Evans@arm.com 0x2387a6e756238ULL, 305613118SEdmund.Grimley-Evans@arm.com 0x26b4565e27cddULL, 305713118SEdmund.Grimley-Evans@arm.com 0x29e9df51fdee1ULL, 305813118SEdmund.Grimley-Evans@arm.com 0x2d285a6e4030bULL, 305913118SEdmund.Grimley-Evans@arm.com 0x306fe0a31b715ULL, 306013118SEdmund.Grimley-Evans@arm.com 0x33c08b26416ffULL, 306113118SEdmund.Grimley-Evans@arm.com 0x371a7373aa9cbULL, 306213118SEdmund.Grimley-Evans@arm.com 0x3a7db34e59ff7ULL, 306313118SEdmund.Grimley-Evans@arm.com 0x3dea64c123422ULL, 306413118SEdmund.Grimley-Evans@arm.com 0x4160a21f72e2aULL, 306513118SEdmund.Grimley-Evans@arm.com 0x44e086061892dULL, 306613118SEdmund.Grimley-Evans@arm.com 0x486a2b5c13cd0ULL, 306713118SEdmund.Grimley-Evans@arm.com 0x4bfdad5362a27ULL, 306813118SEdmund.Grimley-Evans@arm.com 0x4f9b2769d2ca7ULL, 306913118SEdmund.Grimley-Evans@arm.com 0x5342b569d4f82ULL, 307013118SEdmund.Grimley-Evans@arm.com 0x56f4736b527daULL, 307113118SEdmund.Grimley-Evans@arm.com 0x5ab07dd485429ULL, 307213118SEdmund.Grimley-Evans@arm.com 0x5e76f15ad2148ULL, 307313118SEdmund.Grimley-Evans@arm.com 0x6247eb03a5585ULL, 307413118SEdmund.Grimley-Evans@arm.com 0x6623882552225ULL, 307513118SEdmund.Grimley-Evans@arm.com 0x6a09e667f3bcdULL, 307613118SEdmund.Grimley-Evans@arm.com 0x6dfb23c651a2fULL, 307713118SEdmund.Grimley-Evans@arm.com 0x71f75e8ec5f74ULL, 307813118SEdmund.Grimley-Evans@arm.com 0x75feb564267c9ULL, 307913118SEdmund.Grimley-Evans@arm.com 0x7a11473eb0187ULL, 308013118SEdmund.Grimley-Evans@arm.com 0x7e2f336cf4e62ULL, 308113118SEdmund.Grimley-Evans@arm.com 0x82589994cce13ULL, 308213118SEdmund.Grimley-Evans@arm.com 0x868d99b4492edULL, 308313118SEdmund.Grimley-Evans@arm.com 0x8ace5422aa0dbULL, 308413118SEdmund.Grimley-Evans@arm.com 0x8f1ae99157736ULL, 308513118SEdmund.Grimley-Evans@arm.com 0x93737b0cdc5e5ULL, 308613118SEdmund.Grimley-Evans@arm.com 0x97d829fde4e50ULL, 308713118SEdmund.Grimley-Evans@arm.com 0x9c49182a3f090ULL, 308813118SEdmund.Grimley-Evans@arm.com 0xa0c667b5de565ULL, 308913118SEdmund.Grimley-Evans@arm.com 0xa5503b23e255dULL, 309013118SEdmund.Grimley-Evans@arm.com 0xa9e6b5579fdbfULL, 309113118SEdmund.Grimley-Evans@arm.com 0xae89f995ad3adULL, 309213118SEdmund.Grimley-Evans@arm.com 0xb33a2b84f15fbULL, 309313118SEdmund.Grimley-Evans@arm.com 0xb7f76f2fb5e47ULL, 309413118SEdmund.Grimley-Evans@arm.com 0xbcc1e904bc1d2ULL, 309513118SEdmund.Grimley-Evans@arm.com 0xc199bdd85529cULL, 309613118SEdmund.Grimley-Evans@arm.com 0xc67f12e57d14bULL, 309713118SEdmund.Grimley-Evans@arm.com 0xcb720dcef9069ULL, 309813118SEdmund.Grimley-Evans@arm.com 0xd072d4a07897cULL, 309913118SEdmund.Grimley-Evans@arm.com 0xd5818dcfba487ULL, 310013118SEdmund.Grimley-Evans@arm.com 0xda9e603db3285ULL, 310113118SEdmund.Grimley-Evans@arm.com 0xdfc97337b9b5fULL, 310213118SEdmund.Grimley-Evans@arm.com 0xe502ee78b3ff6ULL, 310313118SEdmund.Grimley-Evans@arm.com 0xea4afa2a490daULL, 310413118SEdmund.Grimley-Evans@arm.com 0xefa1bee615a27ULL, 310513118SEdmund.Grimley-Evans@arm.com 0xf50765b6e4540ULL, 310613118SEdmund.Grimley-Evans@arm.com 0xfa7c1819e90d8ULL 310713118SEdmund.Grimley-Evans@arm.com }; 310813118SEdmund.Grimley-Evans@arm.com return ((((op >> 6) & ((1 << FP64_EXP_BITS) - 1)) << FP64_MANT_BITS) | 310913118SEdmund.Grimley-Evans@arm.com coeff[op & ((1 << 6) - 1)]); 311013118SEdmund.Grimley-Evans@arm.com} 311113118SEdmund.Grimley-Evans@arm.com 311213118SEdmund.Grimley-Evans@arm.comstatic uint16_t 311313118SEdmund.Grimley-Evans@arm.comfp16_repack(int sgn, int exp, uint16_t mnt) 311413118SEdmund.Grimley-Evans@arm.com{ 311513118SEdmund.Grimley-Evans@arm.com return fp16_pack(sgn, mnt >> FP16_MANT_BITS ? exp : 0, mnt); 311613118SEdmund.Grimley-Evans@arm.com} 311713118SEdmund.Grimley-Evans@arm.com 311810037SARM gem5 Developersstatic uint32_t 311910037SARM gem5 Developersfp32_repack(int sgn, int exp, uint32_t mnt) 312010037SARM gem5 Developers{ 312113118SEdmund.Grimley-Evans@arm.com return fp32_pack(sgn, mnt >> FP32_MANT_BITS ? exp : 0, mnt); 312210037SARM gem5 Developers} 312310037SARM gem5 Developers 312410037SARM gem5 Developersstatic uint64_t 312510037SARM gem5 Developersfp64_repack(int sgn, int exp, uint64_t mnt) 312610037SARM gem5 Developers{ 312713118SEdmund.Grimley-Evans@arm.com return fp64_pack(sgn, mnt >> FP64_MANT_BITS ? exp : 0, mnt); 312813118SEdmund.Grimley-Evans@arm.com} 312913118SEdmund.Grimley-Evans@arm.com 313013118SEdmund.Grimley-Evans@arm.comstatic void 313113118SEdmund.Grimley-Evans@arm.comfp16_minmaxnum(uint16_t *op1, uint16_t *op2, int sgn) 313213118SEdmund.Grimley-Evans@arm.com{ 313313118SEdmund.Grimley-Evans@arm.com // Treat a single quiet-NaN as +Infinity/-Infinity 313413118SEdmund.Grimley-Evans@arm.com if (!((uint16_t)~(*op1 << 1) >> FP16_MANT_BITS) && 313513118SEdmund.Grimley-Evans@arm.com (uint16_t)~(*op2 << 1) >> FP16_MANT_BITS) 313613118SEdmund.Grimley-Evans@arm.com *op1 = fp16_infinity(sgn); 313713118SEdmund.Grimley-Evans@arm.com if (!((uint16_t)~(*op2 << 1) >> FP16_MANT_BITS) && 313813118SEdmund.Grimley-Evans@arm.com (uint16_t)~(*op1 << 1) >> FP16_MANT_BITS) 313913118SEdmund.Grimley-Evans@arm.com *op2 = fp16_infinity(sgn); 314010037SARM gem5 Developers} 314110037SARM gem5 Developers 314210037SARM gem5 Developersstatic void 314310037SARM gem5 Developersfp32_minmaxnum(uint32_t *op1, uint32_t *op2, int sgn) 314410037SARM gem5 Developers{ 314510037SARM gem5 Developers // Treat a single quiet-NaN as +Infinity/-Infinity 314613118SEdmund.Grimley-Evans@arm.com if (!((uint32_t)~(*op1 << 1) >> FP32_MANT_BITS) && 314713118SEdmund.Grimley-Evans@arm.com (uint32_t)~(*op2 << 1) >> FP32_MANT_BITS) 314810037SARM gem5 Developers *op1 = fp32_infinity(sgn); 314913118SEdmund.Grimley-Evans@arm.com if (!((uint32_t)~(*op2 << 1) >> FP32_MANT_BITS) && 315013118SEdmund.Grimley-Evans@arm.com (uint32_t)~(*op1 << 1) >> FP32_MANT_BITS) 315110037SARM gem5 Developers *op2 = fp32_infinity(sgn); 315210037SARM gem5 Developers} 315310037SARM gem5 Developers 315410037SARM gem5 Developersstatic void 315510037SARM gem5 Developersfp64_minmaxnum(uint64_t *op1, uint64_t *op2, int sgn) 315610037SARM gem5 Developers{ 315710037SARM gem5 Developers // Treat a single quiet-NaN as +Infinity/-Infinity 315813118SEdmund.Grimley-Evans@arm.com if (!((uint64_t)~(*op1 << 1) >> FP64_MANT_BITS) && 315913118SEdmund.Grimley-Evans@arm.com (uint64_t)~(*op2 << 1) >> FP64_MANT_BITS) 316010037SARM gem5 Developers *op1 = fp64_infinity(sgn); 316113118SEdmund.Grimley-Evans@arm.com if (!((uint64_t)~(*op2 << 1) >> FP64_MANT_BITS) && 316213118SEdmund.Grimley-Evans@arm.com (uint64_t)~(*op1 << 1) >> FP64_MANT_BITS) 316310037SARM gem5 Developers *op2 = fp64_infinity(sgn); 316410037SARM gem5 Developers} 316510037SARM gem5 Developers 316610037SARM gem5 Developerstemplate <> 316713118SEdmund.Grimley-Evans@arm.comuint16_t 316813118SEdmund.Grimley-Evans@arm.comfplibMax(uint16_t op1, uint16_t op2, FPSCR &fpscr) 316913118SEdmund.Grimley-Evans@arm.com{ 317013118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 317113118SEdmund.Grimley-Evans@arm.com int flags = 0; 317213118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2; 317313118SEdmund.Grimley-Evans@arm.com uint16_t mnt1, mnt2, x, result; 317413118SEdmund.Grimley-Evans@arm.com 317513118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 317613118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 317713118SEdmund.Grimley-Evans@arm.com 317813118SEdmund.Grimley-Evans@arm.com if ((x = fp16_process_NaNs(op1, op2, mode, &flags))) { 317913118SEdmund.Grimley-Evans@arm.com result = x; 318013118SEdmund.Grimley-Evans@arm.com } else { 318113118SEdmund.Grimley-Evans@arm.com result = ((sgn1 != sgn2 ? sgn2 : sgn1 ^ (op1 > op2)) ? 318213118SEdmund.Grimley-Evans@arm.com fp16_repack(sgn1, exp1, mnt1) : 318313118SEdmund.Grimley-Evans@arm.com fp16_repack(sgn2, exp2, mnt2)); 318413118SEdmund.Grimley-Evans@arm.com } 318513118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 318613118SEdmund.Grimley-Evans@arm.com return result; 318713118SEdmund.Grimley-Evans@arm.com} 318813118SEdmund.Grimley-Evans@arm.com 318913118SEdmund.Grimley-Evans@arm.comtemplate <> 319010037SARM gem5 Developersuint32_t 319110037SARM gem5 DevelopersfplibMax(uint32_t op1, uint32_t op2, FPSCR &fpscr) 319210037SARM gem5 Developers{ 319310037SARM gem5 Developers int mode = modeConv(fpscr); 319410037SARM gem5 Developers int flags = 0; 319510037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 319610037SARM gem5 Developers uint32_t mnt1, mnt2, x, result; 319710037SARM gem5 Developers 319810037SARM gem5 Developers fp32_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 319910037SARM gem5 Developers fp32_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 320010037SARM gem5 Developers 320110037SARM gem5 Developers if ((x = fp32_process_NaNs(op1, op2, mode, &flags))) { 320210037SARM gem5 Developers result = x; 320310037SARM gem5 Developers } else { 320410037SARM gem5 Developers result = ((sgn1 != sgn2 ? sgn2 : sgn1 ^ (op1 > op2)) ? 320510037SARM gem5 Developers fp32_repack(sgn1, exp1, mnt1) : 320610037SARM gem5 Developers fp32_repack(sgn2, exp2, mnt2)); 320710037SARM gem5 Developers } 320810037SARM gem5 Developers set_fpscr0(fpscr, flags); 320910037SARM gem5 Developers return result; 321010037SARM gem5 Developers} 321110037SARM gem5 Developers 321210037SARM gem5 Developerstemplate <> 321310037SARM gem5 Developersuint64_t 321410037SARM gem5 DevelopersfplibMax(uint64_t op1, uint64_t op2, FPSCR &fpscr) 321510037SARM gem5 Developers{ 321610037SARM gem5 Developers int mode = modeConv(fpscr); 321710037SARM gem5 Developers int flags = 0; 321810037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 321910037SARM gem5 Developers uint64_t mnt1, mnt2, x, result; 322010037SARM gem5 Developers 322110037SARM gem5 Developers fp64_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 322210037SARM gem5 Developers fp64_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 322310037SARM gem5 Developers 322410037SARM gem5 Developers if ((x = fp64_process_NaNs(op1, op2, mode, &flags))) { 322510037SARM gem5 Developers result = x; 322610037SARM gem5 Developers } else { 322710037SARM gem5 Developers result = ((sgn1 != sgn2 ? sgn2 : sgn1 ^ (op1 > op2)) ? 322810037SARM gem5 Developers fp64_repack(sgn1, exp1, mnt1) : 322910037SARM gem5 Developers fp64_repack(sgn2, exp2, mnt2)); 323010037SARM gem5 Developers } 323110037SARM gem5 Developers set_fpscr0(fpscr, flags); 323210037SARM gem5 Developers return result; 323310037SARM gem5 Developers} 323410037SARM gem5 Developers 323510037SARM gem5 Developerstemplate <> 323613118SEdmund.Grimley-Evans@arm.comuint16_t 323713118SEdmund.Grimley-Evans@arm.comfplibMaxNum(uint16_t op1, uint16_t op2, FPSCR &fpscr) 323813118SEdmund.Grimley-Evans@arm.com{ 323913118SEdmund.Grimley-Evans@arm.com fp16_minmaxnum(&op1, &op2, 1); 324013118SEdmund.Grimley-Evans@arm.com return fplibMax<uint16_t>(op1, op2, fpscr); 324113118SEdmund.Grimley-Evans@arm.com} 324213118SEdmund.Grimley-Evans@arm.com 324313118SEdmund.Grimley-Evans@arm.comtemplate <> 324410037SARM gem5 Developersuint32_t 324510037SARM gem5 DevelopersfplibMaxNum(uint32_t op1, uint32_t op2, FPSCR &fpscr) 324610037SARM gem5 Developers{ 324710037SARM gem5 Developers fp32_minmaxnum(&op1, &op2, 1); 324810037SARM gem5 Developers return fplibMax<uint32_t>(op1, op2, fpscr); 324910037SARM gem5 Developers} 325010037SARM gem5 Developers 325110037SARM gem5 Developerstemplate <> 325210037SARM gem5 Developersuint64_t 325310037SARM gem5 DevelopersfplibMaxNum(uint64_t op1, uint64_t op2, FPSCR &fpscr) 325410037SARM gem5 Developers{ 325510037SARM gem5 Developers fp64_minmaxnum(&op1, &op2, 1); 325610037SARM gem5 Developers return fplibMax<uint64_t>(op1, op2, fpscr); 325710037SARM gem5 Developers} 325810037SARM gem5 Developers 325910037SARM gem5 Developerstemplate <> 326013118SEdmund.Grimley-Evans@arm.comuint16_t 326113118SEdmund.Grimley-Evans@arm.comfplibMin(uint16_t op1, uint16_t op2, FPSCR &fpscr) 326213118SEdmund.Grimley-Evans@arm.com{ 326313118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 326413118SEdmund.Grimley-Evans@arm.com int flags = 0; 326513118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2; 326613118SEdmund.Grimley-Evans@arm.com uint16_t mnt1, mnt2, x, result; 326713118SEdmund.Grimley-Evans@arm.com 326813118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 326913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 327013118SEdmund.Grimley-Evans@arm.com 327113118SEdmund.Grimley-Evans@arm.com if ((x = fp16_process_NaNs(op1, op2, mode, &flags))) { 327213118SEdmund.Grimley-Evans@arm.com result = x; 327313118SEdmund.Grimley-Evans@arm.com } else { 327413118SEdmund.Grimley-Evans@arm.com result = ((sgn1 != sgn2 ? sgn1 : sgn1 ^ (op1 < op2)) ? 327513118SEdmund.Grimley-Evans@arm.com fp16_repack(sgn1, exp1, mnt1) : 327613118SEdmund.Grimley-Evans@arm.com fp16_repack(sgn2, exp2, mnt2)); 327713118SEdmund.Grimley-Evans@arm.com } 327813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 327913118SEdmund.Grimley-Evans@arm.com return result; 328013118SEdmund.Grimley-Evans@arm.com} 328113118SEdmund.Grimley-Evans@arm.com 328213118SEdmund.Grimley-Evans@arm.comtemplate <> 328310037SARM gem5 Developersuint32_t 328410037SARM gem5 DevelopersfplibMin(uint32_t op1, uint32_t op2, FPSCR &fpscr) 328510037SARM gem5 Developers{ 328610037SARM gem5 Developers int mode = modeConv(fpscr); 328710037SARM gem5 Developers int flags = 0; 328810037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 328910037SARM gem5 Developers uint32_t mnt1, mnt2, x, result; 329010037SARM gem5 Developers 329110037SARM gem5 Developers fp32_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 329210037SARM gem5 Developers fp32_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 329310037SARM gem5 Developers 329410037SARM gem5 Developers if ((x = fp32_process_NaNs(op1, op2, mode, &flags))) { 329510037SARM gem5 Developers result = x; 329610037SARM gem5 Developers } else { 329710037SARM gem5 Developers result = ((sgn1 != sgn2 ? sgn1 : sgn1 ^ (op1 < op2)) ? 329810037SARM gem5 Developers fp32_repack(sgn1, exp1, mnt1) : 329910037SARM gem5 Developers fp32_repack(sgn2, exp2, mnt2)); 330010037SARM gem5 Developers } 330110037SARM gem5 Developers set_fpscr0(fpscr, flags); 330210037SARM gem5 Developers return result; 330310037SARM gem5 Developers} 330410037SARM gem5 Developers 330510037SARM gem5 Developerstemplate <> 330610037SARM gem5 Developersuint64_t 330710037SARM gem5 DevelopersfplibMin(uint64_t op1, uint64_t op2, FPSCR &fpscr) 330810037SARM gem5 Developers{ 330910037SARM gem5 Developers int mode = modeConv(fpscr); 331010037SARM gem5 Developers int flags = 0; 331110037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 331210037SARM gem5 Developers uint64_t mnt1, mnt2, x, result; 331310037SARM gem5 Developers 331410037SARM gem5 Developers fp64_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 331510037SARM gem5 Developers fp64_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 331610037SARM gem5 Developers 331710037SARM gem5 Developers if ((x = fp64_process_NaNs(op1, op2, mode, &flags))) { 331810037SARM gem5 Developers result = x; 331910037SARM gem5 Developers } else { 332010037SARM gem5 Developers result = ((sgn1 != sgn2 ? sgn1 : sgn1 ^ (op1 < op2)) ? 332110037SARM gem5 Developers fp64_repack(sgn1, exp1, mnt1) : 332210037SARM gem5 Developers fp64_repack(sgn2, exp2, mnt2)); 332310037SARM gem5 Developers } 332410037SARM gem5 Developers set_fpscr0(fpscr, flags); 332510037SARM gem5 Developers return result; 332610037SARM gem5 Developers} 332710037SARM gem5 Developers 332810037SARM gem5 Developerstemplate <> 332913118SEdmund.Grimley-Evans@arm.comuint16_t 333013118SEdmund.Grimley-Evans@arm.comfplibMinNum(uint16_t op1, uint16_t op2, FPSCR &fpscr) 333113118SEdmund.Grimley-Evans@arm.com{ 333213118SEdmund.Grimley-Evans@arm.com fp16_minmaxnum(&op1, &op2, 0); 333313118SEdmund.Grimley-Evans@arm.com return fplibMin<uint16_t>(op1, op2, fpscr); 333413118SEdmund.Grimley-Evans@arm.com} 333513118SEdmund.Grimley-Evans@arm.com 333613118SEdmund.Grimley-Evans@arm.comtemplate <> 333710037SARM gem5 Developersuint32_t 333810037SARM gem5 DevelopersfplibMinNum(uint32_t op1, uint32_t op2, FPSCR &fpscr) 333910037SARM gem5 Developers{ 334010037SARM gem5 Developers fp32_minmaxnum(&op1, &op2, 0); 334110037SARM gem5 Developers return fplibMin<uint32_t>(op1, op2, fpscr); 334210037SARM gem5 Developers} 334310037SARM gem5 Developers 334410037SARM gem5 Developerstemplate <> 334510037SARM gem5 Developersuint64_t 334610037SARM gem5 DevelopersfplibMinNum(uint64_t op1, uint64_t op2, FPSCR &fpscr) 334710037SARM gem5 Developers{ 334810037SARM gem5 Developers fp64_minmaxnum(&op1, &op2, 0); 334910037SARM gem5 Developers return fplibMin<uint64_t>(op1, op2, fpscr); 335010037SARM gem5 Developers} 335110037SARM gem5 Developers 335210037SARM gem5 Developerstemplate <> 335313118SEdmund.Grimley-Evans@arm.comuint16_t 335413118SEdmund.Grimley-Evans@arm.comfplibMul(uint16_t op1, uint16_t op2, FPSCR &fpscr) 335513118SEdmund.Grimley-Evans@arm.com{ 335613118SEdmund.Grimley-Evans@arm.com int flags = 0; 335713118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_mul(op1, op2, modeConv(fpscr), &flags); 335813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 335913118SEdmund.Grimley-Evans@arm.com return result; 336013118SEdmund.Grimley-Evans@arm.com} 336113118SEdmund.Grimley-Evans@arm.com 336213118SEdmund.Grimley-Evans@arm.comtemplate <> 336310037SARM gem5 Developersuint32_t 336410037SARM gem5 DevelopersfplibMul(uint32_t op1, uint32_t op2, FPSCR &fpscr) 336510037SARM gem5 Developers{ 336610037SARM gem5 Developers int flags = 0; 336710037SARM gem5 Developers uint32_t result = fp32_mul(op1, op2, modeConv(fpscr), &flags); 336810037SARM gem5 Developers set_fpscr0(fpscr, flags); 336910037SARM gem5 Developers return result; 337010037SARM gem5 Developers} 337110037SARM gem5 Developers 337210037SARM gem5 Developerstemplate <> 337310037SARM gem5 Developersuint64_t 337410037SARM gem5 DevelopersfplibMul(uint64_t op1, uint64_t op2, FPSCR &fpscr) 337510037SARM gem5 Developers{ 337610037SARM gem5 Developers int flags = 0; 337710037SARM gem5 Developers uint64_t result = fp64_mul(op1, op2, modeConv(fpscr), &flags); 337810037SARM gem5 Developers set_fpscr0(fpscr, flags); 337910037SARM gem5 Developers return result; 338010037SARM gem5 Developers} 338110037SARM gem5 Developers 338210037SARM gem5 Developerstemplate <> 338313118SEdmund.Grimley-Evans@arm.comuint16_t 338413118SEdmund.Grimley-Evans@arm.comfplibMulX(uint16_t op1, uint16_t op2, FPSCR &fpscr) 338513118SEdmund.Grimley-Evans@arm.com{ 338613118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 338713118SEdmund.Grimley-Evans@arm.com int flags = 0; 338813118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2; 338913118SEdmund.Grimley-Evans@arm.com uint16_t mnt1, mnt2, result; 339013118SEdmund.Grimley-Evans@arm.com 339113118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 339213118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 339313118SEdmund.Grimley-Evans@arm.com 339413118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaNs(op1, op2, mode, &flags); 339513118SEdmund.Grimley-Evans@arm.com if (!result) { 339613118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP16_EXP_INF && !mnt2) || 339713118SEdmund.Grimley-Evans@arm.com (exp2 == FP16_EXP_INF && !mnt1)) { 339813118SEdmund.Grimley-Evans@arm.com result = fp16_FPTwo(sgn1 ^ sgn2); 339913118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP16_EXP_INF || exp2 == FP16_EXP_INF) { 340013118SEdmund.Grimley-Evans@arm.com result = fp16_infinity(sgn1 ^ sgn2); 340113118SEdmund.Grimley-Evans@arm.com } else if (!mnt1 || !mnt2) { 340213118SEdmund.Grimley-Evans@arm.com result = fp16_zero(sgn1 ^ sgn2); 340313118SEdmund.Grimley-Evans@arm.com } else { 340413118SEdmund.Grimley-Evans@arm.com result = fp16_mul(op1, op2, mode, &flags); 340513118SEdmund.Grimley-Evans@arm.com } 340613118SEdmund.Grimley-Evans@arm.com } 340713118SEdmund.Grimley-Evans@arm.com 340813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 340913118SEdmund.Grimley-Evans@arm.com 341013118SEdmund.Grimley-Evans@arm.com return result; 341113118SEdmund.Grimley-Evans@arm.com} 341213118SEdmund.Grimley-Evans@arm.com 341313118SEdmund.Grimley-Evans@arm.comtemplate <> 341410037SARM gem5 Developersuint32_t 341510037SARM gem5 DevelopersfplibMulX(uint32_t op1, uint32_t op2, FPSCR &fpscr) 341610037SARM gem5 Developers{ 341710037SARM gem5 Developers int mode = modeConv(fpscr); 341810037SARM gem5 Developers int flags = 0; 341910037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 342010037SARM gem5 Developers uint32_t mnt1, mnt2, result; 342110037SARM gem5 Developers 342210037SARM gem5 Developers fp32_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 342310037SARM gem5 Developers fp32_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 342410037SARM gem5 Developers 342510037SARM gem5 Developers result = fp32_process_NaNs(op1, op2, mode, &flags); 342610037SARM gem5 Developers if (!result) { 342713118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP32_EXP_INF && !mnt2) || 342813118SEdmund.Grimley-Evans@arm.com (exp2 == FP32_EXP_INF && !mnt1)) { 342910037SARM gem5 Developers result = fp32_FPTwo(sgn1 ^ sgn2); 343013118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP32_EXP_INF || exp2 == FP32_EXP_INF) { 343110037SARM gem5 Developers result = fp32_infinity(sgn1 ^ sgn2); 343210037SARM gem5 Developers } else if (!mnt1 || !mnt2) { 343310037SARM gem5 Developers result = fp32_zero(sgn1 ^ sgn2); 343410037SARM gem5 Developers } else { 343510037SARM gem5 Developers result = fp32_mul(op1, op2, mode, &flags); 343610037SARM gem5 Developers } 343710037SARM gem5 Developers } 343810037SARM gem5 Developers 343910037SARM gem5 Developers set_fpscr0(fpscr, flags); 344010037SARM gem5 Developers 344110037SARM gem5 Developers return result; 344210037SARM gem5 Developers} 344310037SARM gem5 Developers 344410037SARM gem5 Developerstemplate <> 344510037SARM gem5 Developersuint64_t 344610037SARM gem5 DevelopersfplibMulX(uint64_t op1, uint64_t op2, FPSCR &fpscr) 344710037SARM gem5 Developers{ 344810037SARM gem5 Developers int mode = modeConv(fpscr); 344910037SARM gem5 Developers int flags = 0; 345010037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 345110037SARM gem5 Developers uint64_t mnt1, mnt2, result; 345210037SARM gem5 Developers 345310037SARM gem5 Developers fp64_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 345410037SARM gem5 Developers fp64_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 345510037SARM gem5 Developers 345610037SARM gem5 Developers result = fp64_process_NaNs(op1, op2, mode, &flags); 345710037SARM gem5 Developers if (!result) { 345813118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP64_EXP_INF && !mnt2) || 345913118SEdmund.Grimley-Evans@arm.com (exp2 == FP64_EXP_INF && !mnt1)) { 346010037SARM gem5 Developers result = fp64_FPTwo(sgn1 ^ sgn2); 346113118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP64_EXP_INF || exp2 == FP64_EXP_INF) { 346210037SARM gem5 Developers result = fp64_infinity(sgn1 ^ sgn2); 346310037SARM gem5 Developers } else if (!mnt1 || !mnt2) { 346410037SARM gem5 Developers result = fp64_zero(sgn1 ^ sgn2); 346510037SARM gem5 Developers } else { 346610037SARM gem5 Developers result = fp64_mul(op1, op2, mode, &flags); 346710037SARM gem5 Developers } 346810037SARM gem5 Developers } 346910037SARM gem5 Developers 347010037SARM gem5 Developers set_fpscr0(fpscr, flags); 347110037SARM gem5 Developers 347210037SARM gem5 Developers return result; 347310037SARM gem5 Developers} 347410037SARM gem5 Developers 347510037SARM gem5 Developerstemplate <> 347613118SEdmund.Grimley-Evans@arm.comuint16_t 347713118SEdmund.Grimley-Evans@arm.comfplibNeg(uint16_t op) 347813118SEdmund.Grimley-Evans@arm.com{ 347913118SEdmund.Grimley-Evans@arm.com return op ^ 1ULL << (FP16_BITS - 1); 348013118SEdmund.Grimley-Evans@arm.com} 348113118SEdmund.Grimley-Evans@arm.com 348213118SEdmund.Grimley-Evans@arm.comtemplate <> 348310037SARM gem5 Developersuint32_t 348410037SARM gem5 DevelopersfplibNeg(uint32_t op) 348510037SARM gem5 Developers{ 348613118SEdmund.Grimley-Evans@arm.com return op ^ 1ULL << (FP32_BITS - 1); 348710037SARM gem5 Developers} 348810037SARM gem5 Developers 348910037SARM gem5 Developerstemplate <> 349010037SARM gem5 Developersuint64_t 349110037SARM gem5 DevelopersfplibNeg(uint64_t op) 349210037SARM gem5 Developers{ 349313118SEdmund.Grimley-Evans@arm.com return op ^ 1ULL << (FP64_BITS - 1); 349410037SARM gem5 Developers} 349510037SARM gem5 Developers 349610037SARM gem5 Developersstatic const uint8_t recip_sqrt_estimate[256] = { 349710037SARM gem5 Developers 255, 253, 251, 249, 247, 245, 243, 242, 240, 238, 236, 234, 233, 231, 229, 228, 349810037SARM gem5 Developers 226, 224, 223, 221, 219, 218, 216, 215, 213, 212, 210, 209, 207, 206, 204, 203, 349910037SARM gem5 Developers 201, 200, 198, 197, 196, 194, 193, 192, 190, 189, 188, 186, 185, 184, 183, 181, 350010037SARM gem5 Developers 180, 179, 178, 176, 175, 174, 173, 172, 170, 169, 168, 167, 166, 165, 164, 163, 350110037SARM gem5 Developers 162, 160, 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 350210037SARM gem5 Developers 145, 144, 143, 142, 141, 140, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 350310037SARM gem5 Developers 131, 130, 129, 128, 127, 126, 126, 125, 124, 123, 122, 121, 121, 120, 119, 118, 350410037SARM gem5 Developers 118, 117, 116, 115, 114, 114, 113, 112, 111, 111, 110, 109, 109, 108, 107, 106, 350510037SARM gem5 Developers 105, 104, 103, 101, 100, 99, 97, 96, 95, 93, 92, 91, 90, 88, 87, 86, 350610037SARM gem5 Developers 85, 84, 82, 81, 80, 79, 78, 77, 76, 75, 74, 72, 71, 70, 69, 68, 350710037SARM gem5 Developers 67, 66, 65, 64, 63, 62, 61, 60, 60, 59, 58, 57, 56, 55, 54, 53, 350810037SARM gem5 Developers 52, 51, 51, 50, 49, 48, 47, 46, 46, 45, 44, 43, 42, 42, 41, 40, 350910037SARM gem5 Developers 39, 38, 38, 37, 36, 35, 35, 34, 33, 33, 32, 31, 30, 30, 29, 28, 351010037SARM gem5 Developers 28, 27, 26, 26, 25, 24, 24, 23, 22, 22, 21, 20, 20, 19, 19, 18, 351110037SARM gem5 Developers 17, 17, 16, 16, 15, 14, 14, 13, 13, 12, 11, 11, 10, 10, 9, 9, 351210037SARM gem5 Developers 8, 8, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0 351310037SARM gem5 Developers}; 351410037SARM gem5 Developers 351510037SARM gem5 Developerstemplate <> 351613118SEdmund.Grimley-Evans@arm.comuint16_t 351713118SEdmund.Grimley-Evans@arm.comfplibRSqrtEstimate(uint16_t op, FPSCR &fpscr) 351813118SEdmund.Grimley-Evans@arm.com{ 351913118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 352013118SEdmund.Grimley-Evans@arm.com int flags = 0; 352113118SEdmund.Grimley-Evans@arm.com int sgn, exp; 352213118SEdmund.Grimley-Evans@arm.com uint16_t mnt, result; 352313118SEdmund.Grimley-Evans@arm.com 352413118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, mode, &flags); 352513118SEdmund.Grimley-Evans@arm.com 352613118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 352713118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaN(op, mode, &flags); 352813118SEdmund.Grimley-Evans@arm.com } else if (!mnt) { 352913118SEdmund.Grimley-Evans@arm.com result = fp16_infinity(sgn); 353013118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_DZC; 353113118SEdmund.Grimley-Evans@arm.com } else if (sgn) { 353213118SEdmund.Grimley-Evans@arm.com result = fp16_defaultNaN(); 353313118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_IOC; 353413118SEdmund.Grimley-Evans@arm.com } else if (exp == FP16_EXP_INF) { 353513118SEdmund.Grimley-Evans@arm.com result = fp16_zero(0); 353613118SEdmund.Grimley-Evans@arm.com } else { 353713118SEdmund.Grimley-Evans@arm.com exp += FP16_EXP_BITS; 353813118SEdmund.Grimley-Evans@arm.com mnt = fp16_normalise(mnt, &exp); 353913118SEdmund.Grimley-Evans@arm.com mnt = recip_sqrt_estimate[(~exp & 1) << 7 | 354013118SEdmund.Grimley-Evans@arm.com (mnt >> (FP16_BITS - 8) & 127)]; 354113118SEdmund.Grimley-Evans@arm.com result = fp16_pack(0, (3 * FP16_EXP_BIAS - exp - 1) >> 1, 354213118SEdmund.Grimley-Evans@arm.com mnt << (FP16_MANT_BITS - 8)); 354313118SEdmund.Grimley-Evans@arm.com } 354413118SEdmund.Grimley-Evans@arm.com 354513118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 354613118SEdmund.Grimley-Evans@arm.com 354713118SEdmund.Grimley-Evans@arm.com return result; 354813118SEdmund.Grimley-Evans@arm.com} 354913118SEdmund.Grimley-Evans@arm.com 355013118SEdmund.Grimley-Evans@arm.comtemplate <> 355110037SARM gem5 Developersuint32_t 355210037SARM gem5 DevelopersfplibRSqrtEstimate(uint32_t op, FPSCR &fpscr) 355310037SARM gem5 Developers{ 355410037SARM gem5 Developers int mode = modeConv(fpscr); 355510037SARM gem5 Developers int flags = 0; 355610037SARM gem5 Developers int sgn, exp; 355710037SARM gem5 Developers uint32_t mnt, result; 355810037SARM gem5 Developers 355910037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, mode, &flags); 356010037SARM gem5 Developers 356113118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 356210037SARM gem5 Developers result = fp32_process_NaN(op, mode, &flags); 356310037SARM gem5 Developers } else if (!mnt) { 356410037SARM gem5 Developers result = fp32_infinity(sgn); 356510037SARM gem5 Developers flags |= FPLIB_DZC; 356610037SARM gem5 Developers } else if (sgn) { 356710037SARM gem5 Developers result = fp32_defaultNaN(); 356810037SARM gem5 Developers flags |= FPLIB_IOC; 356913118SEdmund.Grimley-Evans@arm.com } else if (exp == FP32_EXP_INF) { 357010037SARM gem5 Developers result = fp32_zero(0); 357110037SARM gem5 Developers } else { 357213118SEdmund.Grimley-Evans@arm.com exp += FP32_EXP_BITS; 357310037SARM gem5 Developers mnt = fp32_normalise(mnt, &exp); 357413118SEdmund.Grimley-Evans@arm.com mnt = recip_sqrt_estimate[(~exp & 1) << 7 | 357513118SEdmund.Grimley-Evans@arm.com (mnt >> (FP32_BITS - 8) & 127)]; 357613118SEdmund.Grimley-Evans@arm.com result = fp32_pack(0, (3 * FP32_EXP_BIAS - exp - 1) >> 1, 357713118SEdmund.Grimley-Evans@arm.com mnt << (FP32_MANT_BITS - 8)); 357810037SARM gem5 Developers } 357910037SARM gem5 Developers 358010037SARM gem5 Developers set_fpscr0(fpscr, flags); 358110037SARM gem5 Developers 358210037SARM gem5 Developers return result; 358310037SARM gem5 Developers} 358410037SARM gem5 Developers 358510037SARM gem5 Developerstemplate <> 358610037SARM gem5 Developersuint64_t 358710037SARM gem5 DevelopersfplibRSqrtEstimate(uint64_t op, FPSCR &fpscr) 358810037SARM gem5 Developers{ 358910037SARM gem5 Developers int mode = modeConv(fpscr); 359010037SARM gem5 Developers int flags = 0; 359110037SARM gem5 Developers int sgn, exp; 359210037SARM gem5 Developers uint64_t mnt, result; 359310037SARM gem5 Developers 359410037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, mode, &flags); 359510037SARM gem5 Developers 359613118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 359710037SARM gem5 Developers result = fp64_process_NaN(op, mode, &flags); 359810037SARM gem5 Developers } else if (!mnt) { 359910037SARM gem5 Developers result = fp64_infinity(sgn); 360010037SARM gem5 Developers flags |= FPLIB_DZC; 360110037SARM gem5 Developers } else if (sgn) { 360210037SARM gem5 Developers result = fp64_defaultNaN(); 360310037SARM gem5 Developers flags |= FPLIB_IOC; 360413118SEdmund.Grimley-Evans@arm.com } else if (exp == FP64_EXP_INF) { 360510037SARM gem5 Developers result = fp32_zero(0); 360610037SARM gem5 Developers } else { 360713118SEdmund.Grimley-Evans@arm.com exp += FP64_EXP_BITS; 360810037SARM gem5 Developers mnt = fp64_normalise(mnt, &exp); 360913118SEdmund.Grimley-Evans@arm.com mnt = recip_sqrt_estimate[(~exp & 1) << 7 | 361013118SEdmund.Grimley-Evans@arm.com (mnt >> (FP64_BITS - 8) & 127)]; 361113118SEdmund.Grimley-Evans@arm.com result = fp64_pack(0, (3 * FP64_EXP_BIAS - exp - 1) >> 1, 361213118SEdmund.Grimley-Evans@arm.com mnt << (FP64_MANT_BITS - 8)); 361313118SEdmund.Grimley-Evans@arm.com } 361413118SEdmund.Grimley-Evans@arm.com 361513118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 361613118SEdmund.Grimley-Evans@arm.com 361713118SEdmund.Grimley-Evans@arm.com return result; 361813118SEdmund.Grimley-Evans@arm.com} 361913118SEdmund.Grimley-Evans@arm.com 362013118SEdmund.Grimley-Evans@arm.comtemplate <> 362113118SEdmund.Grimley-Evans@arm.comuint16_t 362213118SEdmund.Grimley-Evans@arm.comfplibRSqrtStepFused(uint16_t op1, uint16_t op2, FPSCR &fpscr) 362313118SEdmund.Grimley-Evans@arm.com{ 362413118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 362513118SEdmund.Grimley-Evans@arm.com int flags = 0; 362613118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2; 362713118SEdmund.Grimley-Evans@arm.com uint16_t mnt1, mnt2, result; 362813118SEdmund.Grimley-Evans@arm.com 362913118SEdmund.Grimley-Evans@arm.com op1 = fplibNeg<uint16_t>(op1); 363013118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 363113118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 363213118SEdmund.Grimley-Evans@arm.com 363313118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaNs(op1, op2, mode, &flags); 363413118SEdmund.Grimley-Evans@arm.com if (!result) { 363513118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP16_EXP_INF && !mnt2) || 363613118SEdmund.Grimley-Evans@arm.com (exp2 == FP16_EXP_INF && !mnt1)) { 363713118SEdmund.Grimley-Evans@arm.com result = fp16_FPOnePointFive(0); 363813118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP16_EXP_INF || exp2 == FP16_EXP_INF) { 363913118SEdmund.Grimley-Evans@arm.com result = fp16_infinity(sgn1 ^ sgn2); 364013118SEdmund.Grimley-Evans@arm.com } else { 364113118SEdmund.Grimley-Evans@arm.com result = fp16_muladd(fp16_FPThree(0), op1, op2, -1, mode, &flags); 364213118SEdmund.Grimley-Evans@arm.com } 364310037SARM gem5 Developers } 364410037SARM gem5 Developers 364510037SARM gem5 Developers set_fpscr0(fpscr, flags); 364610037SARM gem5 Developers 364710037SARM gem5 Developers return result; 364810037SARM gem5 Developers} 364910037SARM gem5 Developers 365010037SARM gem5 Developerstemplate <> 365110037SARM gem5 Developersuint32_t 365210037SARM gem5 DevelopersfplibRSqrtStepFused(uint32_t op1, uint32_t op2, FPSCR &fpscr) 365310037SARM gem5 Developers{ 365410037SARM gem5 Developers int mode = modeConv(fpscr); 365510037SARM gem5 Developers int flags = 0; 365610037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 365710037SARM gem5 Developers uint32_t mnt1, mnt2, result; 365810037SARM gem5 Developers 365910037SARM gem5 Developers op1 = fplibNeg<uint32_t>(op1); 366010037SARM gem5 Developers fp32_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 366110037SARM gem5 Developers fp32_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 366210037SARM gem5 Developers 366310037SARM gem5 Developers result = fp32_process_NaNs(op1, op2, mode, &flags); 366410037SARM gem5 Developers if (!result) { 366513118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP32_EXP_INF && !mnt2) || 366613118SEdmund.Grimley-Evans@arm.com (exp2 == FP32_EXP_INF && !mnt1)) { 366710037SARM gem5 Developers result = fp32_FPOnePointFive(0); 366813118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP32_EXP_INF || exp2 == FP32_EXP_INF) { 366910037SARM gem5 Developers result = fp32_infinity(sgn1 ^ sgn2); 367010037SARM gem5 Developers } else { 367110037SARM gem5 Developers result = fp32_muladd(fp32_FPThree(0), op1, op2, -1, mode, &flags); 367210037SARM gem5 Developers } 367310037SARM gem5 Developers } 367410037SARM gem5 Developers 367510037SARM gem5 Developers set_fpscr0(fpscr, flags); 367610037SARM gem5 Developers 367710037SARM gem5 Developers return result; 367810037SARM gem5 Developers} 367910037SARM gem5 Developers 368010037SARM gem5 Developerstemplate <> 368110037SARM gem5 Developersuint64_t 368210037SARM gem5 DevelopersfplibRSqrtStepFused(uint64_t op1, uint64_t op2, FPSCR &fpscr) 368310037SARM gem5 Developers{ 368410037SARM gem5 Developers int mode = modeConv(fpscr); 368510037SARM gem5 Developers int flags = 0; 368610037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 368710037SARM gem5 Developers uint64_t mnt1, mnt2, result; 368810037SARM gem5 Developers 368910037SARM gem5 Developers op1 = fplibNeg<uint64_t>(op1); 369010037SARM gem5 Developers fp64_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 369110037SARM gem5 Developers fp64_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 369210037SARM gem5 Developers 369310037SARM gem5 Developers result = fp64_process_NaNs(op1, op2, mode, &flags); 369410037SARM gem5 Developers if (!result) { 369513118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP64_EXP_INF && !mnt2) || 369613118SEdmund.Grimley-Evans@arm.com (exp2 == FP64_EXP_INF && !mnt1)) { 369710037SARM gem5 Developers result = fp64_FPOnePointFive(0); 369813118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP64_EXP_INF || exp2 == FP64_EXP_INF) { 369910037SARM gem5 Developers result = fp64_infinity(sgn1 ^ sgn2); 370010037SARM gem5 Developers } else { 370110037SARM gem5 Developers result = fp64_muladd(fp64_FPThree(0), op1, op2, -1, mode, &flags); 370210037SARM gem5 Developers } 370310037SARM gem5 Developers } 370410037SARM gem5 Developers 370510037SARM gem5 Developers set_fpscr0(fpscr, flags); 370610037SARM gem5 Developers 370710037SARM gem5 Developers return result; 370810037SARM gem5 Developers} 370910037SARM gem5 Developers 371010037SARM gem5 Developerstemplate <> 371113118SEdmund.Grimley-Evans@arm.comuint16_t 371213118SEdmund.Grimley-Evans@arm.comfplibRecipEstimate(uint16_t op, FPSCR &fpscr) 371310037SARM gem5 Developers{ 371410037SARM gem5 Developers int mode = modeConv(fpscr); 371510037SARM gem5 Developers int flags = 0; 371613118SEdmund.Grimley-Evans@arm.com int sgn, exp; 371713118SEdmund.Grimley-Evans@arm.com uint16_t mnt, result; 371813118SEdmund.Grimley-Evans@arm.com 371913118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, mode, &flags); 372013118SEdmund.Grimley-Evans@arm.com 372113118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 372213118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaN(op, mode, &flags); 372313118SEdmund.Grimley-Evans@arm.com } else if (exp == FP16_EXP_INF) { 372413118SEdmund.Grimley-Evans@arm.com result = fp16_zero(sgn); 372513118SEdmund.Grimley-Evans@arm.com } else if (!mnt) { 372613118SEdmund.Grimley-Evans@arm.com result = fp16_infinity(sgn); 372713118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_DZC; 372813118SEdmund.Grimley-Evans@arm.com } else if (!((uint16_t)(op << 1) >> (FP16_MANT_BITS - 1))) { 372913118SEdmund.Grimley-Evans@arm.com bool overflow_to_inf = false; 373013118SEdmund.Grimley-Evans@arm.com switch (FPCRRounding(fpscr)) { 373113118SEdmund.Grimley-Evans@arm.com case FPRounding_TIEEVEN: 373213118SEdmund.Grimley-Evans@arm.com overflow_to_inf = true; 373313118SEdmund.Grimley-Evans@arm.com break; 373413118SEdmund.Grimley-Evans@arm.com case FPRounding_POSINF: 373513118SEdmund.Grimley-Evans@arm.com overflow_to_inf = !sgn; 373613118SEdmund.Grimley-Evans@arm.com break; 373713118SEdmund.Grimley-Evans@arm.com case FPRounding_NEGINF: 373813118SEdmund.Grimley-Evans@arm.com overflow_to_inf = sgn; 373913118SEdmund.Grimley-Evans@arm.com break; 374013118SEdmund.Grimley-Evans@arm.com case FPRounding_ZERO: 374113118SEdmund.Grimley-Evans@arm.com overflow_to_inf = false; 374213118SEdmund.Grimley-Evans@arm.com break; 374313118SEdmund.Grimley-Evans@arm.com default: 374413449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 374510037SARM gem5 Developers } 374613118SEdmund.Grimley-Evans@arm.com result = overflow_to_inf ? fp16_infinity(sgn) : fp16_max_normal(sgn); 374713118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_OFC | FPLIB_IXC; 374813118SEdmund.Grimley-Evans@arm.com } else if (fpscr.fz16 && exp >= 2 * FP16_EXP_BIAS - 1) { 374913118SEdmund.Grimley-Evans@arm.com result = fp16_zero(sgn); 375013118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_UFC; 375113118SEdmund.Grimley-Evans@arm.com } else { 375213118SEdmund.Grimley-Evans@arm.com exp += FP16_EXP_BITS; 375313118SEdmund.Grimley-Evans@arm.com mnt = fp16_normalise(mnt, &exp); 375413118SEdmund.Grimley-Evans@arm.com int result_exp = 2 * FP16_EXP_BIAS - 1 - exp; 375513118SEdmund.Grimley-Evans@arm.com uint16_t fraction = (((uint32_t)1 << 19) / 375613118SEdmund.Grimley-Evans@arm.com (mnt >> (FP16_BITS - 10) | 1) + 1) >> 1; 375713118SEdmund.Grimley-Evans@arm.com fraction <<= FP16_MANT_BITS - 8; 375813118SEdmund.Grimley-Evans@arm.com if (result_exp == 0) { 375913118SEdmund.Grimley-Evans@arm.com fraction >>= 1; 376013118SEdmund.Grimley-Evans@arm.com } else if (result_exp == -1) { 376113118SEdmund.Grimley-Evans@arm.com fraction >>= 2; 376213118SEdmund.Grimley-Evans@arm.com result_exp = 0; 376313118SEdmund.Grimley-Evans@arm.com } 376413118SEdmund.Grimley-Evans@arm.com result = fp16_pack(sgn, result_exp, fraction); 376510037SARM gem5 Developers } 376610037SARM gem5 Developers 376710037SARM gem5 Developers set_fpscr0(fpscr, flags); 376810037SARM gem5 Developers 376910037SARM gem5 Developers return result; 377010037SARM gem5 Developers} 377110037SARM gem5 Developers 377210037SARM gem5 Developerstemplate <> 377310037SARM gem5 Developersuint32_t 377410037SARM gem5 DevelopersfplibRecipEstimate(uint32_t op, FPSCR &fpscr) 377510037SARM gem5 Developers{ 377610037SARM gem5 Developers int mode = modeConv(fpscr); 377710037SARM gem5 Developers int flags = 0; 377810037SARM gem5 Developers int sgn, exp; 377910037SARM gem5 Developers uint32_t mnt, result; 378010037SARM gem5 Developers 378110037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, mode, &flags); 378210037SARM gem5 Developers 378313118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 378410037SARM gem5 Developers result = fp32_process_NaN(op, mode, &flags); 378513118SEdmund.Grimley-Evans@arm.com } else if (exp == FP32_EXP_INF) { 378610037SARM gem5 Developers result = fp32_zero(sgn); 378710037SARM gem5 Developers } else if (!mnt) { 378810037SARM gem5 Developers result = fp32_infinity(sgn); 378910037SARM gem5 Developers flags |= FPLIB_DZC; 379013118SEdmund.Grimley-Evans@arm.com } else if (!((uint32_t)(op << 1) >> (FP32_MANT_BITS - 1))) { 379110104Smitch.hayenga@arm.com bool overflow_to_inf = false; 379210037SARM gem5 Developers switch (FPCRRounding(fpscr)) { 379310037SARM gem5 Developers case FPRounding_TIEEVEN: 379410037SARM gem5 Developers overflow_to_inf = true; 379510037SARM gem5 Developers break; 379610037SARM gem5 Developers case FPRounding_POSINF: 379710037SARM gem5 Developers overflow_to_inf = !sgn; 379810037SARM gem5 Developers break; 379910037SARM gem5 Developers case FPRounding_NEGINF: 380010037SARM gem5 Developers overflow_to_inf = sgn; 380110037SARM gem5 Developers break; 380210037SARM gem5 Developers case FPRounding_ZERO: 380310037SARM gem5 Developers overflow_to_inf = false; 380410037SARM gem5 Developers break; 380510037SARM gem5 Developers default: 380613449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 380710037SARM gem5 Developers } 380810037SARM gem5 Developers result = overflow_to_inf ? fp32_infinity(sgn) : fp32_max_normal(sgn); 380910037SARM gem5 Developers flags |= FPLIB_OFC | FPLIB_IXC; 381013118SEdmund.Grimley-Evans@arm.com } else if (fpscr.fz && exp >= 2 * FP32_EXP_BIAS - 1) { 381110037SARM gem5 Developers result = fp32_zero(sgn); 381210037SARM gem5 Developers flags |= FPLIB_UFC; 381310037SARM gem5 Developers } else { 381413118SEdmund.Grimley-Evans@arm.com exp += FP32_EXP_BITS; 381510037SARM gem5 Developers mnt = fp32_normalise(mnt, &exp); 381613118SEdmund.Grimley-Evans@arm.com int result_exp = 2 * FP32_EXP_BIAS - 1 - exp; 381713118SEdmund.Grimley-Evans@arm.com uint32_t fraction = (((uint32_t)1 << 19) / 381813118SEdmund.Grimley-Evans@arm.com (mnt >> (FP32_BITS - 10) | 1) + 1) >> 1; 381913118SEdmund.Grimley-Evans@arm.com fraction <<= FP32_MANT_BITS - 8; 382010037SARM gem5 Developers if (result_exp == 0) { 382110037SARM gem5 Developers fraction >>= 1; 382210037SARM gem5 Developers } else if (result_exp == -1) { 382310037SARM gem5 Developers fraction >>= 2; 382410037SARM gem5 Developers result_exp = 0; 382510037SARM gem5 Developers } 382610037SARM gem5 Developers result = fp32_pack(sgn, result_exp, fraction); 382710037SARM gem5 Developers } 382810037SARM gem5 Developers 382910037SARM gem5 Developers set_fpscr0(fpscr, flags); 383010037SARM gem5 Developers 383110037SARM gem5 Developers return result; 383210037SARM gem5 Developers} 383310037SARM gem5 Developers 383410037SARM gem5 Developerstemplate <> 383510037SARM gem5 Developersuint64_t 383610037SARM gem5 DevelopersfplibRecipEstimate(uint64_t op, FPSCR &fpscr) 383710037SARM gem5 Developers{ 383810037SARM gem5 Developers int mode = modeConv(fpscr); 383910037SARM gem5 Developers int flags = 0; 384010037SARM gem5 Developers int sgn, exp; 384110037SARM gem5 Developers uint64_t mnt, result; 384210037SARM gem5 Developers 384310037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, mode, &flags); 384410037SARM gem5 Developers 384513118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 384610037SARM gem5 Developers result = fp64_process_NaN(op, mode, &flags); 384713118SEdmund.Grimley-Evans@arm.com } else if (exp == FP64_EXP_INF) { 384810037SARM gem5 Developers result = fp64_zero(sgn); 384910037SARM gem5 Developers } else if (!mnt) { 385010037SARM gem5 Developers result = fp64_infinity(sgn); 385110037SARM gem5 Developers flags |= FPLIB_DZC; 385213118SEdmund.Grimley-Evans@arm.com } else if (!((uint64_t)(op << 1) >> (FP64_MANT_BITS - 1))) { 385310104Smitch.hayenga@arm.com bool overflow_to_inf = false; 385410037SARM gem5 Developers switch (FPCRRounding(fpscr)) { 385510037SARM gem5 Developers case FPRounding_TIEEVEN: 385610037SARM gem5 Developers overflow_to_inf = true; 385710037SARM gem5 Developers break; 385810037SARM gem5 Developers case FPRounding_POSINF: 385910037SARM gem5 Developers overflow_to_inf = !sgn; 386010037SARM gem5 Developers break; 386110037SARM gem5 Developers case FPRounding_NEGINF: 386210037SARM gem5 Developers overflow_to_inf = sgn; 386310037SARM gem5 Developers break; 386410037SARM gem5 Developers case FPRounding_ZERO: 386510037SARM gem5 Developers overflow_to_inf = false; 386610037SARM gem5 Developers break; 386710037SARM gem5 Developers default: 386813449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 386910037SARM gem5 Developers } 387010037SARM gem5 Developers result = overflow_to_inf ? fp64_infinity(sgn) : fp64_max_normal(sgn); 387110037SARM gem5 Developers flags |= FPLIB_OFC | FPLIB_IXC; 387213118SEdmund.Grimley-Evans@arm.com } else if (fpscr.fz && exp >= 2 * FP64_EXP_BIAS - 1) { 387310037SARM gem5 Developers result = fp64_zero(sgn); 387410037SARM gem5 Developers flags |= FPLIB_UFC; 387510037SARM gem5 Developers } else { 387613118SEdmund.Grimley-Evans@arm.com exp += FP64_EXP_BITS; 387710037SARM gem5 Developers mnt = fp64_normalise(mnt, &exp); 387813118SEdmund.Grimley-Evans@arm.com int result_exp = 2 * FP64_EXP_BIAS - 1 - exp; 387913118SEdmund.Grimley-Evans@arm.com uint64_t fraction = (((uint32_t)1 << 19) / 388013118SEdmund.Grimley-Evans@arm.com (mnt >> (FP64_BITS - 10) | 1) + 1) >> 1; 388113118SEdmund.Grimley-Evans@arm.com fraction <<= FP64_MANT_BITS - 8; 388210037SARM gem5 Developers if (result_exp == 0) { 388310037SARM gem5 Developers fraction >>= 1; 388410037SARM gem5 Developers } else if (result_exp == -1) { 388510037SARM gem5 Developers fraction >>= 2; 388610037SARM gem5 Developers result_exp = 0; 388710037SARM gem5 Developers } 388810037SARM gem5 Developers result = fp64_pack(sgn, result_exp, fraction); 388910037SARM gem5 Developers } 389010037SARM gem5 Developers 389110037SARM gem5 Developers set_fpscr0(fpscr, flags); 389210037SARM gem5 Developers 389310037SARM gem5 Developers return result; 389410037SARM gem5 Developers} 389510037SARM gem5 Developers 389610037SARM gem5 Developerstemplate <> 389713118SEdmund.Grimley-Evans@arm.comuint16_t 389813118SEdmund.Grimley-Evans@arm.comfplibRecipStepFused(uint16_t op1, uint16_t op2, FPSCR &fpscr) 389913118SEdmund.Grimley-Evans@arm.com{ 390013118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 390113118SEdmund.Grimley-Evans@arm.com int flags = 0; 390213118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2; 390313118SEdmund.Grimley-Evans@arm.com uint16_t mnt1, mnt2, result; 390413118SEdmund.Grimley-Evans@arm.com 390513118SEdmund.Grimley-Evans@arm.com op1 = fplibNeg<uint16_t>(op1); 390613118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 390713118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 390813118SEdmund.Grimley-Evans@arm.com 390913118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaNs(op1, op2, mode, &flags); 391013118SEdmund.Grimley-Evans@arm.com if (!result) { 391113118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP16_EXP_INF && !mnt2) || 391213118SEdmund.Grimley-Evans@arm.com (exp2 == FP16_EXP_INF && !mnt1)) { 391313118SEdmund.Grimley-Evans@arm.com result = fp16_FPTwo(0); 391413118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP16_EXP_INF || exp2 == FP16_EXP_INF) { 391513118SEdmund.Grimley-Evans@arm.com result = fp16_infinity(sgn1 ^ sgn2); 391613118SEdmund.Grimley-Evans@arm.com } else { 391713118SEdmund.Grimley-Evans@arm.com result = fp16_muladd(fp16_FPTwo(0), op1, op2, 0, mode, &flags); 391813118SEdmund.Grimley-Evans@arm.com } 391913118SEdmund.Grimley-Evans@arm.com } 392013118SEdmund.Grimley-Evans@arm.com 392113118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 392213118SEdmund.Grimley-Evans@arm.com 392313118SEdmund.Grimley-Evans@arm.com return result; 392413118SEdmund.Grimley-Evans@arm.com} 392513118SEdmund.Grimley-Evans@arm.com 392613118SEdmund.Grimley-Evans@arm.comtemplate <> 392713118SEdmund.Grimley-Evans@arm.comuint32_t 392813118SEdmund.Grimley-Evans@arm.comfplibRecipStepFused(uint32_t op1, uint32_t op2, FPSCR &fpscr) 392913118SEdmund.Grimley-Evans@arm.com{ 393013118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 393113118SEdmund.Grimley-Evans@arm.com int flags = 0; 393213118SEdmund.Grimley-Evans@arm.com int sgn1, exp1, sgn2, exp2; 393313118SEdmund.Grimley-Evans@arm.com uint32_t mnt1, mnt2, result; 393413118SEdmund.Grimley-Evans@arm.com 393513118SEdmund.Grimley-Evans@arm.com op1 = fplibNeg<uint32_t>(op1); 393613118SEdmund.Grimley-Evans@arm.com fp32_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 393713118SEdmund.Grimley-Evans@arm.com fp32_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 393813118SEdmund.Grimley-Evans@arm.com 393913118SEdmund.Grimley-Evans@arm.com result = fp32_process_NaNs(op1, op2, mode, &flags); 394013118SEdmund.Grimley-Evans@arm.com if (!result) { 394113118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP32_EXP_INF && !mnt2) || 394213118SEdmund.Grimley-Evans@arm.com (exp2 == FP32_EXP_INF && !mnt1)) { 394313118SEdmund.Grimley-Evans@arm.com result = fp32_FPTwo(0); 394413118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP32_EXP_INF || exp2 == FP32_EXP_INF) { 394513118SEdmund.Grimley-Evans@arm.com result = fp32_infinity(sgn1 ^ sgn2); 394613118SEdmund.Grimley-Evans@arm.com } else { 394713118SEdmund.Grimley-Evans@arm.com result = fp32_muladd(fp32_FPTwo(0), op1, op2, 0, mode, &flags); 394813118SEdmund.Grimley-Evans@arm.com } 394913118SEdmund.Grimley-Evans@arm.com } 395013118SEdmund.Grimley-Evans@arm.com 395113118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 395213118SEdmund.Grimley-Evans@arm.com 395313118SEdmund.Grimley-Evans@arm.com return result; 395413118SEdmund.Grimley-Evans@arm.com} 395513118SEdmund.Grimley-Evans@arm.com 395613118SEdmund.Grimley-Evans@arm.comtemplate <> 395710037SARM gem5 Developersuint64_t 395810037SARM gem5 DevelopersfplibRecipStepFused(uint64_t op1, uint64_t op2, FPSCR &fpscr) 395910037SARM gem5 Developers{ 396010037SARM gem5 Developers int mode = modeConv(fpscr); 396110037SARM gem5 Developers int flags = 0; 396210037SARM gem5 Developers int sgn1, exp1, sgn2, exp2; 396310037SARM gem5 Developers uint64_t mnt1, mnt2, result; 396410037SARM gem5 Developers 396510037SARM gem5 Developers op1 = fplibNeg<uint64_t>(op1); 396610037SARM gem5 Developers fp64_unpack(&sgn1, &exp1, &mnt1, op1, mode, &flags); 396710037SARM gem5 Developers fp64_unpack(&sgn2, &exp2, &mnt2, op2, mode, &flags); 396810037SARM gem5 Developers 396910037SARM gem5 Developers result = fp64_process_NaNs(op1, op2, mode, &flags); 397010037SARM gem5 Developers if (!result) { 397113118SEdmund.Grimley-Evans@arm.com if ((exp1 == FP64_EXP_INF && !mnt2) || 397213118SEdmund.Grimley-Evans@arm.com (exp2 == FP64_EXP_INF && !mnt1)) { 397310037SARM gem5 Developers result = fp64_FPTwo(0); 397413118SEdmund.Grimley-Evans@arm.com } else if (exp1 == FP64_EXP_INF || exp2 == FP64_EXP_INF) { 397510037SARM gem5 Developers result = fp64_infinity(sgn1 ^ sgn2); 397610037SARM gem5 Developers } else { 397710037SARM gem5 Developers result = fp64_muladd(fp64_FPTwo(0), op1, op2, 0, mode, &flags); 397810037SARM gem5 Developers } 397910037SARM gem5 Developers } 398010037SARM gem5 Developers 398110037SARM gem5 Developers set_fpscr0(fpscr, flags); 398210037SARM gem5 Developers 398310037SARM gem5 Developers return result; 398410037SARM gem5 Developers} 398510037SARM gem5 Developers 398610037SARM gem5 Developerstemplate <> 398713118SEdmund.Grimley-Evans@arm.comuint16_t 398813118SEdmund.Grimley-Evans@arm.comfplibRecpX(uint16_t op, FPSCR &fpscr) 398913118SEdmund.Grimley-Evans@arm.com{ 399013118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 399113118SEdmund.Grimley-Evans@arm.com int flags = 0; 399213118SEdmund.Grimley-Evans@arm.com int sgn, exp; 399313118SEdmund.Grimley-Evans@arm.com uint16_t mnt, result; 399413118SEdmund.Grimley-Evans@arm.com 399513118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, mode, &flags); 399613118SEdmund.Grimley-Evans@arm.com 399713118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 399813118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaN(op, mode, &flags); 399913118SEdmund.Grimley-Evans@arm.com } 400013118SEdmund.Grimley-Evans@arm.com else { 400113118SEdmund.Grimley-Evans@arm.com if (!mnt) { // Zero and denormals 400213118SEdmund.Grimley-Evans@arm.com result = fp16_pack(sgn, FP16_EXP_INF - 1, 0); 400313118SEdmund.Grimley-Evans@arm.com } else { // Infinities and normals 400413118SEdmund.Grimley-Evans@arm.com result = fp16_pack(sgn, exp ^ FP16_EXP_INF, 0); 400513118SEdmund.Grimley-Evans@arm.com } 400613118SEdmund.Grimley-Evans@arm.com } 400713118SEdmund.Grimley-Evans@arm.com 400813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 400913118SEdmund.Grimley-Evans@arm.com 401013118SEdmund.Grimley-Evans@arm.com return result; 401113118SEdmund.Grimley-Evans@arm.com} 401213118SEdmund.Grimley-Evans@arm.com 401313118SEdmund.Grimley-Evans@arm.comtemplate <> 401410037SARM gem5 Developersuint32_t 401510037SARM gem5 DevelopersfplibRecpX(uint32_t op, FPSCR &fpscr) 401610037SARM gem5 Developers{ 401710037SARM gem5 Developers int mode = modeConv(fpscr); 401810037SARM gem5 Developers int flags = 0; 401910037SARM gem5 Developers int sgn, exp; 402010037SARM gem5 Developers uint32_t mnt, result; 402110037SARM gem5 Developers 402210037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, mode, &flags); 402310037SARM gem5 Developers 402413118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 402510037SARM gem5 Developers result = fp32_process_NaN(op, mode, &flags); 402610037SARM gem5 Developers } 402710037SARM gem5 Developers else { 402810037SARM gem5 Developers if (!mnt) { // Zero and denormals 402913118SEdmund.Grimley-Evans@arm.com result = fp32_pack(sgn, FP32_EXP_INF - 1, 0); 403010037SARM gem5 Developers } else { // Infinities and normals 403113118SEdmund.Grimley-Evans@arm.com result = fp32_pack(sgn, exp ^ FP32_EXP_INF, 0); 403210037SARM gem5 Developers } 403310037SARM gem5 Developers } 403410037SARM gem5 Developers 403510037SARM gem5 Developers set_fpscr0(fpscr, flags); 403610037SARM gem5 Developers 403710037SARM gem5 Developers return result; 403810037SARM gem5 Developers} 403910037SARM gem5 Developers 404010037SARM gem5 Developerstemplate <> 404110037SARM gem5 Developersuint64_t 404210037SARM gem5 DevelopersfplibRecpX(uint64_t op, FPSCR &fpscr) 404310037SARM gem5 Developers{ 404410037SARM gem5 Developers int mode = modeConv(fpscr); 404510037SARM gem5 Developers int flags = 0; 404610037SARM gem5 Developers int sgn, exp; 404710037SARM gem5 Developers uint64_t mnt, result; 404810037SARM gem5 Developers 404910037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, mode, &flags); 405010037SARM gem5 Developers 405113118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 405210037SARM gem5 Developers result = fp64_process_NaN(op, mode, &flags); 405310037SARM gem5 Developers } 405410037SARM gem5 Developers else { 405510037SARM gem5 Developers if (!mnt) { // Zero and denormals 405613118SEdmund.Grimley-Evans@arm.com result = fp64_pack(sgn, FP64_EXP_INF - 1, 0); 405710037SARM gem5 Developers } else { // Infinities and normals 405813118SEdmund.Grimley-Evans@arm.com result = fp64_pack(sgn, exp ^ FP64_EXP_INF, 0); 405910037SARM gem5 Developers } 406010037SARM gem5 Developers } 406110037SARM gem5 Developers 406210037SARM gem5 Developers set_fpscr0(fpscr, flags); 406310037SARM gem5 Developers 406410037SARM gem5 Developers return result; 406510037SARM gem5 Developers} 406610037SARM gem5 Developers 406710037SARM gem5 Developerstemplate <> 406813118SEdmund.Grimley-Evans@arm.comuint16_t 406913118SEdmund.Grimley-Evans@arm.comfplibRoundInt(uint16_t op, FPRounding rounding, bool exact, FPSCR &fpscr) 407013118SEdmund.Grimley-Evans@arm.com{ 407113118SEdmund.Grimley-Evans@arm.com int expint = FP16_EXP_BIAS + FP16_MANT_BITS; 407210037SARM gem5 Developers int mode = modeConv(fpscr); 407310037SARM gem5 Developers int flags = 0; 407410037SARM gem5 Developers int sgn, exp; 407513118SEdmund.Grimley-Evans@arm.com uint16_t mnt, result; 407610037SARM gem5 Developers 407710037SARM gem5 Developers // Unpack using FPCR to determine if subnormals are flushed-to-zero: 407813118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, mode, &flags); 407910037SARM gem5 Developers 408010037SARM gem5 Developers // Handle NaNs, infinities and zeroes: 408113118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 408213118SEdmund.Grimley-Evans@arm.com result = fp16_process_NaN(op, mode, &flags); 408313118SEdmund.Grimley-Evans@arm.com } else if (exp == FP16_EXP_INF) { 408413118SEdmund.Grimley-Evans@arm.com result = fp16_infinity(sgn); 408510037SARM gem5 Developers } else if (!mnt) { 408613118SEdmund.Grimley-Evans@arm.com result = fp16_zero(sgn); 408713118SEdmund.Grimley-Evans@arm.com } else if (exp >= expint) { 408810037SARM gem5 Developers // There are no fractional bits 408910037SARM gem5 Developers result = op; 409010037SARM gem5 Developers } else { 409110037SARM gem5 Developers // Truncate towards zero: 409213118SEdmund.Grimley-Evans@arm.com uint16_t x = expint - exp >= FP16_BITS ? 0 : mnt >> (expint - exp); 409313118SEdmund.Grimley-Evans@arm.com int err = exp < expint - FP16_BITS ? 1 : 409413118SEdmund.Grimley-Evans@arm.com ((mnt << 1 >> (expint - exp - 1) & 3) | 409513118SEdmund.Grimley-Evans@arm.com ((uint16_t)(mnt << 2 << (FP16_BITS + exp - expint)) != 0)); 409610037SARM gem5 Developers switch (rounding) { 409710037SARM gem5 Developers case FPRounding_TIEEVEN: 409810037SARM gem5 Developers x += (err == 3 || (err == 2 && (x & 1))); 409910037SARM gem5 Developers break; 410010037SARM gem5 Developers case FPRounding_POSINF: 410110037SARM gem5 Developers x += err && !sgn; 410210037SARM gem5 Developers break; 410310037SARM gem5 Developers case FPRounding_NEGINF: 410410037SARM gem5 Developers x += err && sgn; 410510037SARM gem5 Developers break; 410610037SARM gem5 Developers case FPRounding_ZERO: 410710037SARM gem5 Developers break; 410810037SARM gem5 Developers case FPRounding_TIEAWAY: 410910037SARM gem5 Developers x += err >> 1; 411010037SARM gem5 Developers break; 411110037SARM gem5 Developers default: 411213449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 411310037SARM gem5 Developers } 411410037SARM gem5 Developers 411510037SARM gem5 Developers if (x == 0) { 411613118SEdmund.Grimley-Evans@arm.com result = fp16_zero(sgn); 411710037SARM gem5 Developers } else { 411813118SEdmund.Grimley-Evans@arm.com exp = expint; 411913118SEdmund.Grimley-Evans@arm.com mnt = fp16_normalise(x, &exp); 412013118SEdmund.Grimley-Evans@arm.com result = fp16_pack(sgn, exp + FP16_EXP_BITS, mnt >> FP16_EXP_BITS); 412110037SARM gem5 Developers } 412210037SARM gem5 Developers 412310037SARM gem5 Developers if (err && exact) 412410037SARM gem5 Developers flags |= FPLIB_IXC; 412510037SARM gem5 Developers } 412610037SARM gem5 Developers 412710037SARM gem5 Developers set_fpscr0(fpscr, flags); 412810037SARM gem5 Developers 412910037SARM gem5 Developers return result; 413010037SARM gem5 Developers} 413110037SARM gem5 Developers 413210037SARM gem5 Developerstemplate <> 413313118SEdmund.Grimley-Evans@arm.comuint32_t 413413118SEdmund.Grimley-Evans@arm.comfplibRoundInt(uint32_t op, FPRounding rounding, bool exact, FPSCR &fpscr) 413513118SEdmund.Grimley-Evans@arm.com{ 413613118SEdmund.Grimley-Evans@arm.com int expint = FP32_EXP_BIAS + FP32_MANT_BITS; 413710037SARM gem5 Developers int mode = modeConv(fpscr); 413810037SARM gem5 Developers int flags = 0; 413910037SARM gem5 Developers int sgn, exp; 414013118SEdmund.Grimley-Evans@arm.com uint32_t mnt, result; 414110037SARM gem5 Developers 414210037SARM gem5 Developers // Unpack using FPCR to determine if subnormals are flushed-to-zero: 414313118SEdmund.Grimley-Evans@arm.com fp32_unpack(&sgn, &exp, &mnt, op, mode, &flags); 414410037SARM gem5 Developers 414510037SARM gem5 Developers // Handle NaNs, infinities and zeroes: 414613118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 414713118SEdmund.Grimley-Evans@arm.com result = fp32_process_NaN(op, mode, &flags); 414813118SEdmund.Grimley-Evans@arm.com } else if (exp == FP32_EXP_INF) { 414913118SEdmund.Grimley-Evans@arm.com result = fp32_infinity(sgn); 415010037SARM gem5 Developers } else if (!mnt) { 415113118SEdmund.Grimley-Evans@arm.com result = fp32_zero(sgn); 415213118SEdmund.Grimley-Evans@arm.com } else if (exp >= expint) { 415310037SARM gem5 Developers // There are no fractional bits 415410037SARM gem5 Developers result = op; 415510037SARM gem5 Developers } else { 415610037SARM gem5 Developers // Truncate towards zero: 415713118SEdmund.Grimley-Evans@arm.com uint32_t x = expint - exp >= FP32_BITS ? 0 : mnt >> (expint - exp); 415813118SEdmund.Grimley-Evans@arm.com int err = exp < expint - FP32_BITS ? 1 : 415913118SEdmund.Grimley-Evans@arm.com ((mnt << 1 >> (expint - exp - 1) & 3) | 416013118SEdmund.Grimley-Evans@arm.com ((uint32_t)(mnt << 2 << (FP32_BITS + exp - expint)) != 0)); 416110037SARM gem5 Developers switch (rounding) { 416210037SARM gem5 Developers case FPRounding_TIEEVEN: 416310037SARM gem5 Developers x += (err == 3 || (err == 2 && (x & 1))); 416410037SARM gem5 Developers break; 416510037SARM gem5 Developers case FPRounding_POSINF: 416610037SARM gem5 Developers x += err && !sgn; 416710037SARM gem5 Developers break; 416810037SARM gem5 Developers case FPRounding_NEGINF: 416910037SARM gem5 Developers x += err && sgn; 417010037SARM gem5 Developers break; 417110037SARM gem5 Developers case FPRounding_ZERO: 417210037SARM gem5 Developers break; 417310037SARM gem5 Developers case FPRounding_TIEAWAY: 417410037SARM gem5 Developers x += err >> 1; 417510037SARM gem5 Developers break; 417610037SARM gem5 Developers default: 417713449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 417810037SARM gem5 Developers } 417910037SARM gem5 Developers 418010037SARM gem5 Developers if (x == 0) { 418113118SEdmund.Grimley-Evans@arm.com result = fp32_zero(sgn); 418210037SARM gem5 Developers } else { 418313118SEdmund.Grimley-Evans@arm.com exp = expint; 418413118SEdmund.Grimley-Evans@arm.com mnt = fp32_normalise(x, &exp); 418513118SEdmund.Grimley-Evans@arm.com result = fp32_pack(sgn, exp + FP32_EXP_BITS, mnt >> FP32_EXP_BITS); 418610037SARM gem5 Developers } 418710037SARM gem5 Developers 418810037SARM gem5 Developers if (err && exact) 418910037SARM gem5 Developers flags |= FPLIB_IXC; 419010037SARM gem5 Developers } 419110037SARM gem5 Developers 419210037SARM gem5 Developers set_fpscr0(fpscr, flags); 419310037SARM gem5 Developers 419410037SARM gem5 Developers return result; 419510037SARM gem5 Developers} 419610037SARM gem5 Developers 419710037SARM gem5 Developerstemplate <> 419813118SEdmund.Grimley-Evans@arm.comuint64_t 419913118SEdmund.Grimley-Evans@arm.comfplibRoundInt(uint64_t op, FPRounding rounding, bool exact, FPSCR &fpscr) 420013118SEdmund.Grimley-Evans@arm.com{ 420113118SEdmund.Grimley-Evans@arm.com int expint = FP64_EXP_BIAS + FP64_MANT_BITS; 420213118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 420313118SEdmund.Grimley-Evans@arm.com int flags = 0; 420413118SEdmund.Grimley-Evans@arm.com int sgn, exp; 420513118SEdmund.Grimley-Evans@arm.com uint64_t mnt, result; 420613118SEdmund.Grimley-Evans@arm.com 420713118SEdmund.Grimley-Evans@arm.com // Unpack using FPCR to determine if subnormals are flushed-to-zero: 420813118SEdmund.Grimley-Evans@arm.com fp64_unpack(&sgn, &exp, &mnt, op, mode, &flags); 420913118SEdmund.Grimley-Evans@arm.com 421013118SEdmund.Grimley-Evans@arm.com // Handle NaNs, infinities and zeroes: 421113118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 421213118SEdmund.Grimley-Evans@arm.com result = fp64_process_NaN(op, mode, &flags); 421313118SEdmund.Grimley-Evans@arm.com } else if (exp == FP64_EXP_INF) { 421413118SEdmund.Grimley-Evans@arm.com result = fp64_infinity(sgn); 421513118SEdmund.Grimley-Evans@arm.com } else if (!mnt) { 421613118SEdmund.Grimley-Evans@arm.com result = fp64_zero(sgn); 421713118SEdmund.Grimley-Evans@arm.com } else if (exp >= expint) { 421813118SEdmund.Grimley-Evans@arm.com // There are no fractional bits 421913118SEdmund.Grimley-Evans@arm.com result = op; 422013118SEdmund.Grimley-Evans@arm.com } else { 422113118SEdmund.Grimley-Evans@arm.com // Truncate towards zero: 422213118SEdmund.Grimley-Evans@arm.com uint64_t x = expint - exp >= FP64_BITS ? 0 : mnt >> (expint - exp); 422313118SEdmund.Grimley-Evans@arm.com int err = exp < expint - FP64_BITS ? 1 : 422413118SEdmund.Grimley-Evans@arm.com ((mnt << 1 >> (expint - exp - 1) & 3) | 422513118SEdmund.Grimley-Evans@arm.com ((uint64_t)(mnt << 2 << (FP64_BITS + exp - expint)) != 0)); 422613118SEdmund.Grimley-Evans@arm.com switch (rounding) { 422713118SEdmund.Grimley-Evans@arm.com case FPRounding_TIEEVEN: 422813118SEdmund.Grimley-Evans@arm.com x += (err == 3 || (err == 2 && (x & 1))); 422913118SEdmund.Grimley-Evans@arm.com break; 423013118SEdmund.Grimley-Evans@arm.com case FPRounding_POSINF: 423113118SEdmund.Grimley-Evans@arm.com x += err && !sgn; 423213118SEdmund.Grimley-Evans@arm.com break; 423313118SEdmund.Grimley-Evans@arm.com case FPRounding_NEGINF: 423413118SEdmund.Grimley-Evans@arm.com x += err && sgn; 423513118SEdmund.Grimley-Evans@arm.com break; 423613118SEdmund.Grimley-Evans@arm.com case FPRounding_ZERO: 423713118SEdmund.Grimley-Evans@arm.com break; 423813118SEdmund.Grimley-Evans@arm.com case FPRounding_TIEAWAY: 423913118SEdmund.Grimley-Evans@arm.com x += err >> 1; 424013118SEdmund.Grimley-Evans@arm.com break; 424113118SEdmund.Grimley-Evans@arm.com default: 424213449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 424313118SEdmund.Grimley-Evans@arm.com } 424413118SEdmund.Grimley-Evans@arm.com 424513118SEdmund.Grimley-Evans@arm.com if (x == 0) { 424613118SEdmund.Grimley-Evans@arm.com result = fp64_zero(sgn); 424713118SEdmund.Grimley-Evans@arm.com } else { 424813118SEdmund.Grimley-Evans@arm.com exp = expint; 424913118SEdmund.Grimley-Evans@arm.com mnt = fp64_normalise(x, &exp); 425013118SEdmund.Grimley-Evans@arm.com result = fp64_pack(sgn, exp + FP64_EXP_BITS, mnt >> FP64_EXP_BITS); 425113118SEdmund.Grimley-Evans@arm.com } 425213118SEdmund.Grimley-Evans@arm.com 425313118SEdmund.Grimley-Evans@arm.com if (err && exact) 425413118SEdmund.Grimley-Evans@arm.com flags |= FPLIB_IXC; 425513118SEdmund.Grimley-Evans@arm.com } 425613118SEdmund.Grimley-Evans@arm.com 425713118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 425813118SEdmund.Grimley-Evans@arm.com 425913118SEdmund.Grimley-Evans@arm.com return result; 426013118SEdmund.Grimley-Evans@arm.com} 426113118SEdmund.Grimley-Evans@arm.com 426213118SEdmund.Grimley-Evans@arm.comtemplate <> 426313118SEdmund.Grimley-Evans@arm.comuint16_t 426413118SEdmund.Grimley-Evans@arm.comfplibScale(uint16_t op1, uint16_t op2, FPSCR &fpscr) 426513118SEdmund.Grimley-Evans@arm.com{ 426613118SEdmund.Grimley-Evans@arm.com int flags = 0; 426713118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_scale(op1, (int16_t)op2, modeConv(fpscr), &flags); 426813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 426913118SEdmund.Grimley-Evans@arm.com return result; 427013118SEdmund.Grimley-Evans@arm.com} 427113118SEdmund.Grimley-Evans@arm.com 427213118SEdmund.Grimley-Evans@arm.comtemplate <> 427313118SEdmund.Grimley-Evans@arm.comuint32_t 427413118SEdmund.Grimley-Evans@arm.comfplibScale(uint32_t op1, uint32_t op2, FPSCR &fpscr) 427513118SEdmund.Grimley-Evans@arm.com{ 427613118SEdmund.Grimley-Evans@arm.com int flags = 0; 427713118SEdmund.Grimley-Evans@arm.com uint32_t result = fp32_scale(op1, (int32_t)op2, modeConv(fpscr), &flags); 427813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 427913118SEdmund.Grimley-Evans@arm.com return result; 428013118SEdmund.Grimley-Evans@arm.com} 428113118SEdmund.Grimley-Evans@arm.com 428213118SEdmund.Grimley-Evans@arm.comtemplate <> 428313118SEdmund.Grimley-Evans@arm.comuint64_t 428413118SEdmund.Grimley-Evans@arm.comfplibScale(uint64_t op1, uint64_t op2, FPSCR &fpscr) 428513118SEdmund.Grimley-Evans@arm.com{ 428613118SEdmund.Grimley-Evans@arm.com int flags = 0; 428713118SEdmund.Grimley-Evans@arm.com uint64_t result = fp64_scale(op1, (int64_t)op2, modeConv(fpscr), &flags); 428813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 428913118SEdmund.Grimley-Evans@arm.com return result; 429013118SEdmund.Grimley-Evans@arm.com} 429113118SEdmund.Grimley-Evans@arm.com 429213118SEdmund.Grimley-Evans@arm.comtemplate <> 429313118SEdmund.Grimley-Evans@arm.comuint16_t 429413118SEdmund.Grimley-Evans@arm.comfplibSqrt(uint16_t op, FPSCR &fpscr) 429513118SEdmund.Grimley-Evans@arm.com{ 429613118SEdmund.Grimley-Evans@arm.com int flags = 0; 429713118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_sqrt(op, modeConv(fpscr), &flags); 429813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 429913118SEdmund.Grimley-Evans@arm.com return result; 430013118SEdmund.Grimley-Evans@arm.com} 430113118SEdmund.Grimley-Evans@arm.com 430213118SEdmund.Grimley-Evans@arm.comtemplate <> 430310037SARM gem5 Developersuint32_t 430410037SARM gem5 DevelopersfplibSqrt(uint32_t op, FPSCR &fpscr) 430510037SARM gem5 Developers{ 430610037SARM gem5 Developers int flags = 0; 430710037SARM gem5 Developers uint32_t result = fp32_sqrt(op, modeConv(fpscr), &flags); 430810037SARM gem5 Developers set_fpscr0(fpscr, flags); 430910037SARM gem5 Developers return result; 431010037SARM gem5 Developers} 431110037SARM gem5 Developers 431210037SARM gem5 Developerstemplate <> 431310037SARM gem5 Developersuint64_t 431410037SARM gem5 DevelopersfplibSqrt(uint64_t op, FPSCR &fpscr) 431510037SARM gem5 Developers{ 431610037SARM gem5 Developers int flags = 0; 431710037SARM gem5 Developers uint64_t result = fp64_sqrt(op, modeConv(fpscr), &flags); 431810037SARM gem5 Developers set_fpscr0(fpscr, flags); 431910037SARM gem5 Developers return result; 432010037SARM gem5 Developers} 432110037SARM gem5 Developers 432210037SARM gem5 Developerstemplate <> 432313118SEdmund.Grimley-Evans@arm.comuint16_t 432413118SEdmund.Grimley-Evans@arm.comfplibSub(uint16_t op1, uint16_t op2, FPSCR &fpscr) 432513118SEdmund.Grimley-Evans@arm.com{ 432613118SEdmund.Grimley-Evans@arm.com int flags = 0; 432713118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_add(op1, op2, 1, modeConv(fpscr), &flags); 432813118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 432913118SEdmund.Grimley-Evans@arm.com return result; 433013118SEdmund.Grimley-Evans@arm.com} 433113118SEdmund.Grimley-Evans@arm.com 433213118SEdmund.Grimley-Evans@arm.comtemplate <> 433310037SARM gem5 Developersuint32_t 433410037SARM gem5 DevelopersfplibSub(uint32_t op1, uint32_t op2, FPSCR &fpscr) 433510037SARM gem5 Developers{ 433610037SARM gem5 Developers int flags = 0; 433710037SARM gem5 Developers uint32_t result = fp32_add(op1, op2, 1, modeConv(fpscr), &flags); 433810037SARM gem5 Developers set_fpscr0(fpscr, flags); 433910037SARM gem5 Developers return result; 434010037SARM gem5 Developers} 434110037SARM gem5 Developers 434210037SARM gem5 Developerstemplate <> 434310037SARM gem5 Developersuint64_t 434410037SARM gem5 DevelopersfplibSub(uint64_t op1, uint64_t op2, FPSCR &fpscr) 434510037SARM gem5 Developers{ 434610037SARM gem5 Developers int flags = 0; 434710037SARM gem5 Developers uint64_t result = fp64_add(op1, op2, 1, modeConv(fpscr), &flags); 434810037SARM gem5 Developers set_fpscr0(fpscr, flags); 434910037SARM gem5 Developers return result; 435010037SARM gem5 Developers} 435110037SARM gem5 Developers 435213118SEdmund.Grimley-Evans@arm.comtemplate <> 435313118SEdmund.Grimley-Evans@arm.comuint16_t 435413118SEdmund.Grimley-Evans@arm.comfplibTrigMulAdd(uint8_t coeff_index, uint16_t op1, uint16_t op2, FPSCR &fpscr) 435513118SEdmund.Grimley-Evans@arm.com{ 435613118SEdmund.Grimley-Evans@arm.com static uint16_t coeff[2][8] = { 435713118SEdmund.Grimley-Evans@arm.com { 435813118SEdmund.Grimley-Evans@arm.com 0x3c00, 435913118SEdmund.Grimley-Evans@arm.com 0xb155, 436013118SEdmund.Grimley-Evans@arm.com 0x2030, 436113118SEdmund.Grimley-Evans@arm.com 0x0000, 436213118SEdmund.Grimley-Evans@arm.com 0x0000, 436313118SEdmund.Grimley-Evans@arm.com 0x0000, 436413118SEdmund.Grimley-Evans@arm.com 0x0000, 436513118SEdmund.Grimley-Evans@arm.com 0x0000, 436613118SEdmund.Grimley-Evans@arm.com }, 436713118SEdmund.Grimley-Evans@arm.com { 436813118SEdmund.Grimley-Evans@arm.com 0x3c00, 436913118SEdmund.Grimley-Evans@arm.com 0xb800, 437013118SEdmund.Grimley-Evans@arm.com 0x293a, 437113118SEdmund.Grimley-Evans@arm.com 0x0000, 437213118SEdmund.Grimley-Evans@arm.com 0x0000, 437313118SEdmund.Grimley-Evans@arm.com 0x0000, 437413118SEdmund.Grimley-Evans@arm.com 0x0000, 437513118SEdmund.Grimley-Evans@arm.com 0x0000 437613118SEdmund.Grimley-Evans@arm.com } 437713118SEdmund.Grimley-Evans@arm.com }; 437813118SEdmund.Grimley-Evans@arm.com int flags = 0; 437913118SEdmund.Grimley-Evans@arm.com uint16_t result = 438013118SEdmund.Grimley-Evans@arm.com fp16_muladd(coeff[op2 >> (FP16_BITS - 1)][coeff_index], op1, 438113118SEdmund.Grimley-Evans@arm.com fplibAbs(op2), 0, modeConv(fpscr), &flags); 438213118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 438313118SEdmund.Grimley-Evans@arm.com return result; 438413118SEdmund.Grimley-Evans@arm.com} 438513118SEdmund.Grimley-Evans@arm.com 438613118SEdmund.Grimley-Evans@arm.comtemplate <> 438713118SEdmund.Grimley-Evans@arm.comuint32_t 438813118SEdmund.Grimley-Evans@arm.comfplibTrigMulAdd(uint8_t coeff_index, uint32_t op1, uint32_t op2, FPSCR &fpscr) 438913118SEdmund.Grimley-Evans@arm.com{ 439013118SEdmund.Grimley-Evans@arm.com static uint32_t coeff[2][8] = { 439113118SEdmund.Grimley-Evans@arm.com { 439213118SEdmund.Grimley-Evans@arm.com 0x3f800000, 439313118SEdmund.Grimley-Evans@arm.com 0xbe2aaaab, 439413118SEdmund.Grimley-Evans@arm.com 0x3c088886, 439513118SEdmund.Grimley-Evans@arm.com 0xb95008b9, 439613118SEdmund.Grimley-Evans@arm.com 0x36369d6d, 439713118SEdmund.Grimley-Evans@arm.com 0x00000000, 439813118SEdmund.Grimley-Evans@arm.com 0x00000000, 439913118SEdmund.Grimley-Evans@arm.com 0x00000000 440013118SEdmund.Grimley-Evans@arm.com }, 440113118SEdmund.Grimley-Evans@arm.com { 440213118SEdmund.Grimley-Evans@arm.com 0x3f800000, 440313118SEdmund.Grimley-Evans@arm.com 0xbf000000, 440413118SEdmund.Grimley-Evans@arm.com 0x3d2aaaa6, 440513118SEdmund.Grimley-Evans@arm.com 0xbab60705, 440613118SEdmund.Grimley-Evans@arm.com 0x37cd37cc, 440713118SEdmund.Grimley-Evans@arm.com 0x00000000, 440813118SEdmund.Grimley-Evans@arm.com 0x00000000, 440913118SEdmund.Grimley-Evans@arm.com 0x00000000 441013118SEdmund.Grimley-Evans@arm.com } 441113118SEdmund.Grimley-Evans@arm.com }; 441213118SEdmund.Grimley-Evans@arm.com int flags = 0; 441313118SEdmund.Grimley-Evans@arm.com uint32_t result = 441413118SEdmund.Grimley-Evans@arm.com fp32_muladd(coeff[op2 >> (FP32_BITS - 1)][coeff_index], op1, 441513118SEdmund.Grimley-Evans@arm.com fplibAbs(op2), 0, modeConv(fpscr), &flags); 441613118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 441713118SEdmund.Grimley-Evans@arm.com return result; 441813118SEdmund.Grimley-Evans@arm.com} 441913118SEdmund.Grimley-Evans@arm.com 442013118SEdmund.Grimley-Evans@arm.comtemplate <> 442113118SEdmund.Grimley-Evans@arm.comuint64_t 442213118SEdmund.Grimley-Evans@arm.comfplibTrigMulAdd(uint8_t coeff_index, uint64_t op1, uint64_t op2, FPSCR &fpscr) 442313118SEdmund.Grimley-Evans@arm.com{ 442413118SEdmund.Grimley-Evans@arm.com static uint64_t coeff[2][8] = { 442513118SEdmund.Grimley-Evans@arm.com { 442613118SEdmund.Grimley-Evans@arm.com 0x3ff0000000000000ULL, 442713118SEdmund.Grimley-Evans@arm.com 0xbfc5555555555543ULL, 442813118SEdmund.Grimley-Evans@arm.com 0x3f8111111110f30cULL, 442913118SEdmund.Grimley-Evans@arm.com 0xbf2a01a019b92fc6ULL, 443013118SEdmund.Grimley-Evans@arm.com 0x3ec71de351f3d22bULL, 443113118SEdmund.Grimley-Evans@arm.com 0xbe5ae5e2b60f7b91ULL, 443213118SEdmund.Grimley-Evans@arm.com 0x3de5d8408868552fULL, 443313118SEdmund.Grimley-Evans@arm.com 0x0000000000000000ULL 443413118SEdmund.Grimley-Evans@arm.com }, 443513118SEdmund.Grimley-Evans@arm.com { 443613118SEdmund.Grimley-Evans@arm.com 0x3ff0000000000000ULL, 443713118SEdmund.Grimley-Evans@arm.com 0xbfe0000000000000ULL, 443813118SEdmund.Grimley-Evans@arm.com 0x3fa5555555555536ULL, 443913118SEdmund.Grimley-Evans@arm.com 0xbf56c16c16c13a0bULL, 444013118SEdmund.Grimley-Evans@arm.com 0x3efa01a019b1e8d8ULL, 444113118SEdmund.Grimley-Evans@arm.com 0xbe927e4f7282f468ULL, 444213118SEdmund.Grimley-Evans@arm.com 0x3e21ee96d2641b13ULL, 444313118SEdmund.Grimley-Evans@arm.com 0xbda8f76380fbb401ULL 444413118SEdmund.Grimley-Evans@arm.com } 444513118SEdmund.Grimley-Evans@arm.com }; 444613118SEdmund.Grimley-Evans@arm.com int flags = 0; 444713118SEdmund.Grimley-Evans@arm.com uint64_t result = 444813118SEdmund.Grimley-Evans@arm.com fp64_muladd(coeff[op2 >> (FP64_BITS - 1)][coeff_index], op1, 444913118SEdmund.Grimley-Evans@arm.com fplibAbs(op2), 0, modeConv(fpscr), &flags); 445013118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 445113118SEdmund.Grimley-Evans@arm.com return result; 445213118SEdmund.Grimley-Evans@arm.com} 445313118SEdmund.Grimley-Evans@arm.com 445413118SEdmund.Grimley-Evans@arm.comtemplate <> 445513118SEdmund.Grimley-Evans@arm.comuint16_t 445613118SEdmund.Grimley-Evans@arm.comfplibTrigSMul(uint16_t op1, uint16_t op2, FPSCR &fpscr) 445713118SEdmund.Grimley-Evans@arm.com{ 445813118SEdmund.Grimley-Evans@arm.com int flags = 0; 445913118SEdmund.Grimley-Evans@arm.com int sgn, exp; 446013118SEdmund.Grimley-Evans@arm.com uint16_t mnt; 446113118SEdmund.Grimley-Evans@arm.com 446213118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 446313118SEdmund.Grimley-Evans@arm.com uint16_t result = fp16_mul(op1, op1, mode, &flags); 446413118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 446513118SEdmund.Grimley-Evans@arm.com 446613118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, result, mode, &flags); 446713118SEdmund.Grimley-Evans@arm.com if (!fp16_is_NaN(exp, mnt)) { 446813118SEdmund.Grimley-Evans@arm.com result = (result & ~(1ULL << (FP16_BITS - 1))) | 446913118SEdmund.Grimley-Evans@arm.com op2 << (FP16_BITS - 1); 447013118SEdmund.Grimley-Evans@arm.com } 447113118SEdmund.Grimley-Evans@arm.com return result; 447213118SEdmund.Grimley-Evans@arm.com} 447313118SEdmund.Grimley-Evans@arm.com 447413118SEdmund.Grimley-Evans@arm.comtemplate <> 447513118SEdmund.Grimley-Evans@arm.comuint32_t 447613118SEdmund.Grimley-Evans@arm.comfplibTrigSMul(uint32_t op1, uint32_t op2, FPSCR &fpscr) 447713118SEdmund.Grimley-Evans@arm.com{ 447813118SEdmund.Grimley-Evans@arm.com int flags = 0; 447913118SEdmund.Grimley-Evans@arm.com int sgn, exp; 448013118SEdmund.Grimley-Evans@arm.com uint32_t mnt; 448113118SEdmund.Grimley-Evans@arm.com 448213118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 448313118SEdmund.Grimley-Evans@arm.com uint32_t result = fp32_mul(op1, op1, mode, &flags); 448413118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 448513118SEdmund.Grimley-Evans@arm.com 448613118SEdmund.Grimley-Evans@arm.com fp32_unpack(&sgn, &exp, &mnt, result, mode, &flags); 448713118SEdmund.Grimley-Evans@arm.com if (!fp32_is_NaN(exp, mnt)) { 448813118SEdmund.Grimley-Evans@arm.com result = (result & ~(1ULL << (FP32_BITS - 1))) | op2 << (FP32_BITS - 1); 448913118SEdmund.Grimley-Evans@arm.com } 449013118SEdmund.Grimley-Evans@arm.com return result; 449113118SEdmund.Grimley-Evans@arm.com} 449213118SEdmund.Grimley-Evans@arm.com 449313118SEdmund.Grimley-Evans@arm.comtemplate <> 449413118SEdmund.Grimley-Evans@arm.comuint64_t 449513118SEdmund.Grimley-Evans@arm.comfplibTrigSMul(uint64_t op1, uint64_t op2, FPSCR &fpscr) 449613118SEdmund.Grimley-Evans@arm.com{ 449713118SEdmund.Grimley-Evans@arm.com int flags = 0; 449813118SEdmund.Grimley-Evans@arm.com int sgn, exp; 449913118SEdmund.Grimley-Evans@arm.com uint64_t mnt; 450013118SEdmund.Grimley-Evans@arm.com 450113118SEdmund.Grimley-Evans@arm.com int mode = modeConv(fpscr); 450213118SEdmund.Grimley-Evans@arm.com uint64_t result = fp64_mul(op1, op1, mode, &flags); 450313118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 450413118SEdmund.Grimley-Evans@arm.com 450513118SEdmund.Grimley-Evans@arm.com fp64_unpack(&sgn, &exp, &mnt, result, mode, &flags); 450613118SEdmund.Grimley-Evans@arm.com if (!fp64_is_NaN(exp, mnt)) { 450713118SEdmund.Grimley-Evans@arm.com result = (result & ~(1ULL << (FP64_BITS - 1))) | op2 << (FP64_BITS - 1); 450813118SEdmund.Grimley-Evans@arm.com } 450913118SEdmund.Grimley-Evans@arm.com return result; 451013118SEdmund.Grimley-Evans@arm.com} 451113118SEdmund.Grimley-Evans@arm.com 451213118SEdmund.Grimley-Evans@arm.comtemplate <> 451313118SEdmund.Grimley-Evans@arm.comuint16_t 451413118SEdmund.Grimley-Evans@arm.comfplibTrigSSel(uint16_t op1, uint16_t op2, FPSCR &fpscr) 451513118SEdmund.Grimley-Evans@arm.com{ 451613118SEdmund.Grimley-Evans@arm.com static constexpr uint16_t fpOne = 451713118SEdmund.Grimley-Evans@arm.com (uint16_t)FP16_EXP_BIAS << FP16_MANT_BITS; // 1.0 451813118SEdmund.Grimley-Evans@arm.com if (op2 & 1) 451913118SEdmund.Grimley-Evans@arm.com op1 = fpOne; 452013118SEdmund.Grimley-Evans@arm.com return op1 ^ ((op2 >> 1) << (FP16_BITS - 1)); 452113118SEdmund.Grimley-Evans@arm.com} 452213118SEdmund.Grimley-Evans@arm.com 452313118SEdmund.Grimley-Evans@arm.comtemplate <> 452413118SEdmund.Grimley-Evans@arm.comuint32_t 452513118SEdmund.Grimley-Evans@arm.comfplibTrigSSel(uint32_t op1, uint32_t op2, FPSCR &fpscr) 452613118SEdmund.Grimley-Evans@arm.com{ 452713118SEdmund.Grimley-Evans@arm.com static constexpr uint32_t fpOne = 452813118SEdmund.Grimley-Evans@arm.com (uint32_t)FP32_EXP_BIAS << FP32_MANT_BITS; // 1.0 452913118SEdmund.Grimley-Evans@arm.com if (op2 & 1) 453013118SEdmund.Grimley-Evans@arm.com op1 = fpOne; 453113118SEdmund.Grimley-Evans@arm.com return op1 ^ ((op2 >> 1) << (FP32_BITS - 1)); 453213118SEdmund.Grimley-Evans@arm.com} 453313118SEdmund.Grimley-Evans@arm.com 453413118SEdmund.Grimley-Evans@arm.comtemplate <> 453513118SEdmund.Grimley-Evans@arm.comuint64_t 453613118SEdmund.Grimley-Evans@arm.comfplibTrigSSel(uint64_t op1, uint64_t op2, FPSCR &fpscr) 453713118SEdmund.Grimley-Evans@arm.com{ 453813118SEdmund.Grimley-Evans@arm.com static constexpr uint64_t fpOne = 453913118SEdmund.Grimley-Evans@arm.com (uint64_t)FP64_EXP_BIAS << FP64_MANT_BITS; // 1.0 454013118SEdmund.Grimley-Evans@arm.com if (op2 & 1) 454113118SEdmund.Grimley-Evans@arm.com op1 = fpOne; 454213118SEdmund.Grimley-Evans@arm.com return op1 ^ ((op2 >> 1) << (FP64_BITS - 1)); 454313118SEdmund.Grimley-Evans@arm.com} 454413118SEdmund.Grimley-Evans@arm.com 454510037SARM gem5 Developersstatic uint64_t 454610037SARM gem5 DevelopersFPToFixed_64(int sgn, int exp, uint64_t mnt, bool u, FPRounding rounding, 454710037SARM gem5 Developers int *flags) 454810037SARM gem5 Developers{ 454913118SEdmund.Grimley-Evans@arm.com int expmax = FP64_EXP_BIAS + FP64_BITS - 1; 455010037SARM gem5 Developers uint64_t x; 455110037SARM gem5 Developers int err; 455210037SARM gem5 Developers 455313118SEdmund.Grimley-Evans@arm.com if (exp > expmax) { 455410037SARM gem5 Developers *flags = FPLIB_IOC; 455513118SEdmund.Grimley-Evans@arm.com return ((uint64_t)!u << (FP64_BITS - 1)) - !sgn; 455610037SARM gem5 Developers } 455710037SARM gem5 Developers 455813118SEdmund.Grimley-Evans@arm.com x = lsr64(mnt << FP64_EXP_BITS, expmax - exp); 455913118SEdmund.Grimley-Evans@arm.com err = (exp > expmax - 2 ? 0 : 456013118SEdmund.Grimley-Evans@arm.com (lsr64(mnt << FP64_EXP_BITS, expmax - 2 - exp) & 3) | 456113118SEdmund.Grimley-Evans@arm.com !!(mnt << FP64_EXP_BITS & (lsl64(1, expmax - 2 - exp) - 1))); 456210037SARM gem5 Developers 456310037SARM gem5 Developers switch (rounding) { 456410037SARM gem5 Developers case FPRounding_TIEEVEN: 456510037SARM gem5 Developers x += (err == 3 || (err == 2 && (x & 1))); 456610037SARM gem5 Developers break; 456710037SARM gem5 Developers case FPRounding_POSINF: 456810037SARM gem5 Developers x += err && !sgn; 456910037SARM gem5 Developers break; 457010037SARM gem5 Developers case FPRounding_NEGINF: 457110037SARM gem5 Developers x += err && sgn; 457210037SARM gem5 Developers break; 457310037SARM gem5 Developers case FPRounding_ZERO: 457410037SARM gem5 Developers break; 457510037SARM gem5 Developers case FPRounding_TIEAWAY: 457610037SARM gem5 Developers x += err >> 1; 457710037SARM gem5 Developers break; 457810037SARM gem5 Developers default: 457913449Sgabeblack@google.com panic("Unrecognized FP rounding mode"); 458010037SARM gem5 Developers } 458110037SARM gem5 Developers 458213118SEdmund.Grimley-Evans@arm.com if (u ? sgn && x : x > (1ULL << (FP64_BITS - 1)) - !sgn) { 458310037SARM gem5 Developers *flags = FPLIB_IOC; 458413118SEdmund.Grimley-Evans@arm.com return ((uint64_t)!u << (FP64_BITS - 1)) - !sgn; 458510037SARM gem5 Developers } 458610037SARM gem5 Developers 458710037SARM gem5 Developers if (err) { 458810037SARM gem5 Developers *flags = FPLIB_IXC; 458910037SARM gem5 Developers } 459010037SARM gem5 Developers 459110037SARM gem5 Developers return sgn ? -x : x; 459210037SARM gem5 Developers} 459310037SARM gem5 Developers 459410037SARM gem5 Developersstatic uint32_t 459510037SARM gem5 DevelopersFPToFixed_32(int sgn, int exp, uint64_t mnt, bool u, FPRounding rounding, 459610037SARM gem5 Developers int *flags) 459710037SARM gem5 Developers{ 459810037SARM gem5 Developers uint64_t x = FPToFixed_64(sgn, exp, mnt, u, rounding, flags); 459913118SEdmund.Grimley-Evans@arm.com if (u ? x >= 1ULL << FP32_BITS : 460013118SEdmund.Grimley-Evans@arm.com !(x < 1ULL << (FP32_BITS - 1) || 460113118SEdmund.Grimley-Evans@arm.com (uint64_t)-x <= (uint64_t)1 << (FP32_BITS - 1))) { 460210037SARM gem5 Developers *flags = FPLIB_IOC; 460313118SEdmund.Grimley-Evans@arm.com x = ((uint32_t)!u << (FP32_BITS - 1)) - !sgn; 460410037SARM gem5 Developers } 460510037SARM gem5 Developers return x; 460610037SARM gem5 Developers} 460710037SARM gem5 Developers 460813118SEdmund.Grimley-Evans@arm.comstatic uint16_t 460913118SEdmund.Grimley-Evans@arm.comFPToFixed_16(int sgn, int exp, uint64_t mnt, bool u, FPRounding rounding, 461013118SEdmund.Grimley-Evans@arm.com int *flags) 461113118SEdmund.Grimley-Evans@arm.com{ 461213118SEdmund.Grimley-Evans@arm.com uint64_t x = FPToFixed_64(sgn, exp, mnt, u, rounding, flags); 461313118SEdmund.Grimley-Evans@arm.com if (u ? x >= 1ULL << FP16_BITS : 461413118SEdmund.Grimley-Evans@arm.com !(x < 1ULL << (FP16_BITS - 1) || 461513118SEdmund.Grimley-Evans@arm.com (uint64_t)-x <= (uint64_t)1 << (FP16_BITS - 1))) { 461613118SEdmund.Grimley-Evans@arm.com *flags = FPLIB_IOC; 461713118SEdmund.Grimley-Evans@arm.com x = ((uint16_t)!u << (FP16_BITS - 1)) - !sgn; 461813118SEdmund.Grimley-Evans@arm.com } 461913118SEdmund.Grimley-Evans@arm.com return x; 462013118SEdmund.Grimley-Evans@arm.com} 462113118SEdmund.Grimley-Evans@arm.com 462213118SEdmund.Grimley-Evans@arm.comtemplate <> 462313118SEdmund.Grimley-Evans@arm.comuint16_t 462413118SEdmund.Grimley-Evans@arm.comfplibFPToFixed(uint16_t op, int fbits, bool u, FPRounding rounding, 462513118SEdmund.Grimley-Evans@arm.com FPSCR &fpscr) 462613118SEdmund.Grimley-Evans@arm.com{ 462713118SEdmund.Grimley-Evans@arm.com int flags = 0; 462813118SEdmund.Grimley-Evans@arm.com int sgn, exp; 462913118SEdmund.Grimley-Evans@arm.com uint16_t mnt, result; 463013118SEdmund.Grimley-Evans@arm.com 463113118SEdmund.Grimley-Evans@arm.com // Unpack using FPCR to determine if subnormals are flushed-to-zero: 463213118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 463313118SEdmund.Grimley-Evans@arm.com 463413118SEdmund.Grimley-Evans@arm.com // If NaN, set cumulative flag or take exception: 463513118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 463613118SEdmund.Grimley-Evans@arm.com flags = FPLIB_IOC; 463713118SEdmund.Grimley-Evans@arm.com result = 0; 463813118SEdmund.Grimley-Evans@arm.com } else { 463913118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 464013118SEdmund.Grimley-Evans@arm.com // Infinity is treated as an ordinary normalised number that saturates. 464113118SEdmund.Grimley-Evans@arm.com result = 464213118SEdmund.Grimley-Evans@arm.com FPToFixed_16(sgn, exp + FP64_EXP_BIAS - FP16_EXP_BIAS + fbits, 464313118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP16_MANT_BITS), 464413118SEdmund.Grimley-Evans@arm.com u, rounding, &flags); 464513118SEdmund.Grimley-Evans@arm.com } 464613118SEdmund.Grimley-Evans@arm.com 464713118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 464813118SEdmund.Grimley-Evans@arm.com 464913118SEdmund.Grimley-Evans@arm.com return result; 465013118SEdmund.Grimley-Evans@arm.com} 465113118SEdmund.Grimley-Evans@arm.com 465213118SEdmund.Grimley-Evans@arm.comtemplate <> 465313118SEdmund.Grimley-Evans@arm.comuint32_t 465413118SEdmund.Grimley-Evans@arm.comfplibFPToFixed(uint16_t op, int fbits, bool u, FPRounding rounding, 465513118SEdmund.Grimley-Evans@arm.com FPSCR &fpscr) 465613118SEdmund.Grimley-Evans@arm.com{ 465713118SEdmund.Grimley-Evans@arm.com int flags = 0; 465813118SEdmund.Grimley-Evans@arm.com int sgn, exp; 465913118SEdmund.Grimley-Evans@arm.com uint16_t mnt; 466013118SEdmund.Grimley-Evans@arm.com uint32_t result; 466113118SEdmund.Grimley-Evans@arm.com 466213118SEdmund.Grimley-Evans@arm.com // Unpack using FPCR to determine if subnormals are flushed-to-zero: 466313118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 466413118SEdmund.Grimley-Evans@arm.com 466513118SEdmund.Grimley-Evans@arm.com // If NaN, set cumulative flag or take exception: 466613118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 466713118SEdmund.Grimley-Evans@arm.com flags = FPLIB_IOC; 466813118SEdmund.Grimley-Evans@arm.com result = 0; 466913118SEdmund.Grimley-Evans@arm.com } else { 467013118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 467113118SEdmund.Grimley-Evans@arm.com if (exp == FP16_EXP_INF) 467213118SEdmund.Grimley-Evans@arm.com exp = 255; // infinity: make it big enough to saturate 467313118SEdmund.Grimley-Evans@arm.com result = 467413118SEdmund.Grimley-Evans@arm.com FPToFixed_32(sgn, exp + FP64_EXP_BIAS - FP16_EXP_BIAS + fbits, 467513118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP16_MANT_BITS), 467613118SEdmund.Grimley-Evans@arm.com u, rounding, &flags); 467713118SEdmund.Grimley-Evans@arm.com } 467813118SEdmund.Grimley-Evans@arm.com 467913118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 468013118SEdmund.Grimley-Evans@arm.com 468113118SEdmund.Grimley-Evans@arm.com return result; 468213118SEdmund.Grimley-Evans@arm.com} 468313118SEdmund.Grimley-Evans@arm.com 468410037SARM gem5 Developerstemplate <> 468510037SARM gem5 Developersuint32_t 468610037SARM gem5 DevelopersfplibFPToFixed(uint32_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr) 468710037SARM gem5 Developers{ 468810037SARM gem5 Developers int flags = 0; 468910037SARM gem5 Developers int sgn, exp; 469010037SARM gem5 Developers uint32_t mnt, result; 469110037SARM gem5 Developers 469210037SARM gem5 Developers // Unpack using FPCR to determine if subnormals are flushed-to-zero: 469310037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 469410037SARM gem5 Developers 469510037SARM gem5 Developers // If NaN, set cumulative flag or take exception: 469613118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 469710037SARM gem5 Developers flags = FPLIB_IOC; 469810037SARM gem5 Developers result = 0; 469910037SARM gem5 Developers } else { 470013118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 470113118SEdmund.Grimley-Evans@arm.com // Infinity is treated as an ordinary normalised number that saturates. 470213118SEdmund.Grimley-Evans@arm.com result = 470313118SEdmund.Grimley-Evans@arm.com FPToFixed_32(sgn, exp + FP64_EXP_BIAS - FP32_EXP_BIAS + fbits, 470413118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP32_MANT_BITS), 470513118SEdmund.Grimley-Evans@arm.com u, rounding, &flags); 470610037SARM gem5 Developers } 470710037SARM gem5 Developers 470810037SARM gem5 Developers set_fpscr0(fpscr, flags); 470910037SARM gem5 Developers 471010037SARM gem5 Developers return result; 471110037SARM gem5 Developers} 471210037SARM gem5 Developers 471310037SARM gem5 Developerstemplate <> 471410037SARM gem5 Developersuint32_t 471510037SARM gem5 DevelopersfplibFPToFixed(uint64_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr) 471610037SARM gem5 Developers{ 471710037SARM gem5 Developers int flags = 0; 471810037SARM gem5 Developers int sgn, exp; 471910037SARM gem5 Developers uint64_t mnt; 472010037SARM gem5 Developers uint32_t result; 472110037SARM gem5 Developers 472210037SARM gem5 Developers // Unpack using FPCR to determine if subnormals are flushed-to-zero: 472310037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 472410037SARM gem5 Developers 472510037SARM gem5 Developers // If NaN, set cumulative flag or take exception: 472613118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 472710037SARM gem5 Developers flags = FPLIB_IOC; 472810037SARM gem5 Developers result = 0; 472910037SARM gem5 Developers } else { 473013118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 473113118SEdmund.Grimley-Evans@arm.com // Infinity is treated as an ordinary normalised number that saturates. 473210037SARM gem5 Developers result = FPToFixed_32(sgn, exp + fbits, mnt, u, rounding, &flags); 473310037SARM gem5 Developers } 473410037SARM gem5 Developers 473510037SARM gem5 Developers set_fpscr0(fpscr, flags); 473610037SARM gem5 Developers 473710037SARM gem5 Developers return result; 473810037SARM gem5 Developers} 473910037SARM gem5 Developers 474010037SARM gem5 Developerstemplate <> 474110037SARM gem5 Developersuint64_t 474213118SEdmund.Grimley-Evans@arm.comfplibFPToFixed(uint16_t op, int fbits, bool u, FPRounding rounding, 474313118SEdmund.Grimley-Evans@arm.com FPSCR &fpscr) 474413118SEdmund.Grimley-Evans@arm.com{ 474513118SEdmund.Grimley-Evans@arm.com int flags = 0; 474613118SEdmund.Grimley-Evans@arm.com int sgn, exp; 474713118SEdmund.Grimley-Evans@arm.com uint16_t mnt; 474813118SEdmund.Grimley-Evans@arm.com uint64_t result; 474913118SEdmund.Grimley-Evans@arm.com 475013118SEdmund.Grimley-Evans@arm.com // Unpack using FPCR to determine if subnormals are flushed-to-zero: 475113118SEdmund.Grimley-Evans@arm.com fp16_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 475213118SEdmund.Grimley-Evans@arm.com 475313118SEdmund.Grimley-Evans@arm.com // If NaN, set cumulative flag or take exception: 475413118SEdmund.Grimley-Evans@arm.com if (fp16_is_NaN(exp, mnt)) { 475513118SEdmund.Grimley-Evans@arm.com flags = FPLIB_IOC; 475613118SEdmund.Grimley-Evans@arm.com result = 0; 475713118SEdmund.Grimley-Evans@arm.com } else { 475813118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 475913118SEdmund.Grimley-Evans@arm.com if (exp == FP16_EXP_INF) 476013118SEdmund.Grimley-Evans@arm.com exp = 255; // infinity: make it big enough to saturate 476113118SEdmund.Grimley-Evans@arm.com result = 476213118SEdmund.Grimley-Evans@arm.com FPToFixed_64(sgn, exp + FP64_EXP_BIAS - FP16_EXP_BIAS + fbits, 476313118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP16_MANT_BITS), 476413118SEdmund.Grimley-Evans@arm.com u, rounding, &flags); 476513118SEdmund.Grimley-Evans@arm.com } 476613118SEdmund.Grimley-Evans@arm.com 476713118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 476813118SEdmund.Grimley-Evans@arm.com 476913118SEdmund.Grimley-Evans@arm.com return result; 477013118SEdmund.Grimley-Evans@arm.com} 477113118SEdmund.Grimley-Evans@arm.com 477213118SEdmund.Grimley-Evans@arm.comtemplate <> 477313118SEdmund.Grimley-Evans@arm.comuint64_t 477410037SARM gem5 DevelopersfplibFPToFixed(uint32_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr) 477510037SARM gem5 Developers{ 477610037SARM gem5 Developers int flags = 0; 477710037SARM gem5 Developers int sgn, exp; 477810037SARM gem5 Developers uint32_t mnt; 477910037SARM gem5 Developers uint64_t result; 478010037SARM gem5 Developers 478110037SARM gem5 Developers // Unpack using FPCR to determine if subnormals are flushed-to-zero: 478210037SARM gem5 Developers fp32_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 478310037SARM gem5 Developers 478410037SARM gem5 Developers // If NaN, set cumulative flag or take exception: 478513118SEdmund.Grimley-Evans@arm.com if (fp32_is_NaN(exp, mnt)) { 478610037SARM gem5 Developers flags = FPLIB_IOC; 478710037SARM gem5 Developers result = 0; 478810037SARM gem5 Developers } else { 478913118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 479013118SEdmund.Grimley-Evans@arm.com // Infinity is treated as an ordinary normalised number that saturates. 479113118SEdmund.Grimley-Evans@arm.com result = 479213118SEdmund.Grimley-Evans@arm.com FPToFixed_64(sgn, exp + FP64_EXP_BIAS - FP32_EXP_BIAS + fbits, 479313118SEdmund.Grimley-Evans@arm.com (uint64_t)mnt << (FP64_MANT_BITS - FP32_MANT_BITS), 479413118SEdmund.Grimley-Evans@arm.com u, rounding, &flags); 479510037SARM gem5 Developers } 479610037SARM gem5 Developers 479710037SARM gem5 Developers set_fpscr0(fpscr, flags); 479810037SARM gem5 Developers 479910037SARM gem5 Developers return result; 480010037SARM gem5 Developers} 480110037SARM gem5 Developers 480210037SARM gem5 Developerstemplate <> 480310037SARM gem5 Developersuint64_t 480410037SARM gem5 DevelopersfplibFPToFixed(uint64_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr) 480510037SARM gem5 Developers{ 480610037SARM gem5 Developers int flags = 0; 480710037SARM gem5 Developers int sgn, exp; 480810037SARM gem5 Developers uint64_t mnt, result; 480910037SARM gem5 Developers 481010037SARM gem5 Developers // Unpack using FPCR to determine if subnormals are flushed-to-zero: 481110037SARM gem5 Developers fp64_unpack(&sgn, &exp, &mnt, op, modeConv(fpscr), &flags); 481210037SARM gem5 Developers 481310037SARM gem5 Developers // If NaN, set cumulative flag or take exception: 481413118SEdmund.Grimley-Evans@arm.com if (fp64_is_NaN(exp, mnt)) { 481510037SARM gem5 Developers flags = FPLIB_IOC; 481610037SARM gem5 Developers result = 0; 481710037SARM gem5 Developers } else { 481813118SEdmund.Grimley-Evans@arm.com assert(fbits >= 0); 481913118SEdmund.Grimley-Evans@arm.com // Infinity is treated as an ordinary normalised number that saturates. 482010037SARM gem5 Developers result = FPToFixed_64(sgn, exp + fbits, mnt, u, rounding, &flags); 482110037SARM gem5 Developers } 482210037SARM gem5 Developers 482310037SARM gem5 Developers set_fpscr0(fpscr, flags); 482410037SARM gem5 Developers 482510037SARM gem5 Developers return result; 482610037SARM gem5 Developers} 482710037SARM gem5 Developers 482813118SEdmund.Grimley-Evans@arm.comstatic uint16_t 482913118SEdmund.Grimley-Evans@arm.comfp16_cvtf(uint64_t a, int fbits, int u, int mode, int *flags) 483013118SEdmund.Grimley-Evans@arm.com{ 483113118SEdmund.Grimley-Evans@arm.com int x_sgn = !u && a >> (FP64_BITS - 1); 483213118SEdmund.Grimley-Evans@arm.com int x_exp = FP16_EXP_BIAS + FP64_BITS - 1 - fbits; 483313118SEdmund.Grimley-Evans@arm.com uint64_t x_mnt = x_sgn ? -a : a; 483413118SEdmund.Grimley-Evans@arm.com 483513118SEdmund.Grimley-Evans@arm.com // Handle zero: 483613118SEdmund.Grimley-Evans@arm.com if (!x_mnt) { 483713118SEdmund.Grimley-Evans@arm.com return fp16_zero(0); 483813118SEdmund.Grimley-Evans@arm.com } 483913118SEdmund.Grimley-Evans@arm.com 484013118SEdmund.Grimley-Evans@arm.com // Normalise into FP16_BITS bits, collapsing error into bottom bit: 484113118SEdmund.Grimley-Evans@arm.com x_mnt = fp64_normalise(x_mnt, &x_exp); 484213118SEdmund.Grimley-Evans@arm.com x_mnt = (x_mnt >> (FP64_BITS - FP16_BITS - 1) | 484313118SEdmund.Grimley-Evans@arm.com !!(x_mnt & ((1ULL << (FP64_BITS - FP16_BITS - 1)) - 1))); 484413118SEdmund.Grimley-Evans@arm.com 484513118SEdmund.Grimley-Evans@arm.com return fp16_round(x_sgn, x_exp, x_mnt, mode, flags); 484613118SEdmund.Grimley-Evans@arm.com} 484713118SEdmund.Grimley-Evans@arm.com 484810037SARM gem5 Developersstatic uint32_t 484910037SARM gem5 Developersfp32_cvtf(uint64_t a, int fbits, int u, int mode, int *flags) 485010037SARM gem5 Developers{ 485113118SEdmund.Grimley-Evans@arm.com int x_sgn = !u && a >> (FP64_BITS - 1); 485213118SEdmund.Grimley-Evans@arm.com int x_exp = FP32_EXP_BIAS + FP64_BITS - 1 - fbits; 485310037SARM gem5 Developers uint64_t x_mnt = x_sgn ? -a : a; 485410037SARM gem5 Developers 485510037SARM gem5 Developers // Handle zero: 485610037SARM gem5 Developers if (!x_mnt) { 485710037SARM gem5 Developers return fp32_zero(0); 485810037SARM gem5 Developers } 485910037SARM gem5 Developers 486013118SEdmund.Grimley-Evans@arm.com // Normalise into FP32_BITS bits, collapsing error into bottom bit: 486110037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 486213118SEdmund.Grimley-Evans@arm.com x_mnt = (x_mnt >> (FP64_BITS - FP32_BITS - 1) | 486313118SEdmund.Grimley-Evans@arm.com !!(x_mnt & ((1ULL << (FP64_BITS - FP32_BITS - 1)) - 1))); 486410037SARM gem5 Developers 486510037SARM gem5 Developers return fp32_round(x_sgn, x_exp, x_mnt, mode, flags); 486610037SARM gem5 Developers} 486710037SARM gem5 Developers 486810037SARM gem5 Developersstatic uint64_t 486910037SARM gem5 Developersfp64_cvtf(uint64_t a, int fbits, int u, int mode, int *flags) 487010037SARM gem5 Developers{ 487113118SEdmund.Grimley-Evans@arm.com int x_sgn = !u && a >> (FP64_BITS - 1); 487213118SEdmund.Grimley-Evans@arm.com int x_exp = FP64_EXP_BIAS + FP64_BITS - 1 - fbits; 487310037SARM gem5 Developers uint64_t x_mnt = x_sgn ? -a : a; 487410037SARM gem5 Developers 487510037SARM gem5 Developers // Handle zero: 487610037SARM gem5 Developers if (!x_mnt) { 487710037SARM gem5 Developers return fp64_zero(0); 487810037SARM gem5 Developers } 487910037SARM gem5 Developers 488010037SARM gem5 Developers x_mnt = fp64_normalise(x_mnt, &x_exp); 488110037SARM gem5 Developers 488210037SARM gem5 Developers return fp64_round(x_sgn, x_exp, x_mnt << 1, mode, flags); 488310037SARM gem5 Developers} 488410037SARM gem5 Developers 488510037SARM gem5 Developerstemplate <> 488613118SEdmund.Grimley-Evans@arm.comuint16_t 488713118SEdmund.Grimley-Evans@arm.comfplibFixedToFP(uint64_t op, int fbits, bool u, FPRounding rounding, 488813118SEdmund.Grimley-Evans@arm.com FPSCR &fpscr) 488913118SEdmund.Grimley-Evans@arm.com{ 489013118SEdmund.Grimley-Evans@arm.com int flags = 0; 489113118SEdmund.Grimley-Evans@arm.com uint16_t res = fp16_cvtf(op, fbits, u, 489213118SEdmund.Grimley-Evans@arm.com (int)rounding | ((uint32_t)fpscr >> 22 & 12), 489313118SEdmund.Grimley-Evans@arm.com &flags); 489413118SEdmund.Grimley-Evans@arm.com set_fpscr0(fpscr, flags); 489513118SEdmund.Grimley-Evans@arm.com return res; 489613118SEdmund.Grimley-Evans@arm.com} 489713118SEdmund.Grimley-Evans@arm.com 489813118SEdmund.Grimley-Evans@arm.comtemplate <> 489910037SARM gem5 Developersuint32_t 490010037SARM gem5 DevelopersfplibFixedToFP(uint64_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr) 490110037SARM gem5 Developers{ 490210037SARM gem5 Developers int flags = 0; 490310037SARM gem5 Developers uint32_t res = fp32_cvtf(op, fbits, u, 490410037SARM gem5 Developers (int)rounding | ((uint32_t)fpscr >> 22 & 12), 490510037SARM gem5 Developers &flags); 490610037SARM gem5 Developers set_fpscr0(fpscr, flags); 490710037SARM gem5 Developers return res; 490810037SARM gem5 Developers} 490910037SARM gem5 Developers 491010037SARM gem5 Developerstemplate <> 491110037SARM gem5 Developersuint64_t 491210037SARM gem5 DevelopersfplibFixedToFP(uint64_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr) 491310037SARM gem5 Developers{ 491410037SARM gem5 Developers int flags = 0; 491510037SARM gem5 Developers uint64_t res = fp64_cvtf(op, fbits, u, 491610037SARM gem5 Developers (int)rounding | ((uint32_t)fpscr >> 22 & 12), 491710037SARM gem5 Developers &flags); 491810037SARM gem5 Developers set_fpscr0(fpscr, flags); 491910037SARM gem5 Developers return res; 492010037SARM gem5 Developers} 492110037SARM gem5 Developers 492213118SEdmund.Grimley-Evans@arm.comtemplate <> 492313118SEdmund.Grimley-Evans@arm.comuint16_t 492413118SEdmund.Grimley-Evans@arm.comfplibInfinity(int sgn) 492513118SEdmund.Grimley-Evans@arm.com{ 492613118SEdmund.Grimley-Evans@arm.com return fp16_infinity(sgn); 492713118SEdmund.Grimley-Evans@arm.com} 492813118SEdmund.Grimley-Evans@arm.com 492913118SEdmund.Grimley-Evans@arm.comtemplate <> 493013118SEdmund.Grimley-Evans@arm.comuint32_t 493113118SEdmund.Grimley-Evans@arm.comfplibInfinity(int sgn) 493213118SEdmund.Grimley-Evans@arm.com{ 493313118SEdmund.Grimley-Evans@arm.com return fp32_infinity(sgn); 493413118SEdmund.Grimley-Evans@arm.com} 493513118SEdmund.Grimley-Evans@arm.com 493613118SEdmund.Grimley-Evans@arm.comtemplate <> 493713118SEdmund.Grimley-Evans@arm.comuint64_t 493813118SEdmund.Grimley-Evans@arm.comfplibInfinity(int sgn) 493913118SEdmund.Grimley-Evans@arm.com{ 494013118SEdmund.Grimley-Evans@arm.com return fp64_infinity(sgn); 494113118SEdmund.Grimley-Evans@arm.com} 494213118SEdmund.Grimley-Evans@arm.com 494313118SEdmund.Grimley-Evans@arm.comtemplate <> 494413118SEdmund.Grimley-Evans@arm.comuint16_t 494513118SEdmund.Grimley-Evans@arm.comfplibDefaultNaN() 494613118SEdmund.Grimley-Evans@arm.com{ 494713118SEdmund.Grimley-Evans@arm.com return fp16_defaultNaN(); 494813118SEdmund.Grimley-Evans@arm.com} 494913118SEdmund.Grimley-Evans@arm.com 495013118SEdmund.Grimley-Evans@arm.comtemplate <> 495113118SEdmund.Grimley-Evans@arm.comuint32_t 495213118SEdmund.Grimley-Evans@arm.comfplibDefaultNaN() 495313118SEdmund.Grimley-Evans@arm.com{ 495413118SEdmund.Grimley-Evans@arm.com return fp32_defaultNaN(); 495513118SEdmund.Grimley-Evans@arm.com} 495613118SEdmund.Grimley-Evans@arm.com 495713118SEdmund.Grimley-Evans@arm.comtemplate <> 495813118SEdmund.Grimley-Evans@arm.comuint64_t 495913118SEdmund.Grimley-Evans@arm.comfplibDefaultNaN() 496013118SEdmund.Grimley-Evans@arm.com{ 496113118SEdmund.Grimley-Evans@arm.com return fp64_defaultNaN(); 496213118SEdmund.Grimley-Evans@arm.com} 496313118SEdmund.Grimley-Evans@arm.com 496413118SEdmund.Grimley-Evans@arm.com} 4965