11.8Smatt/* $NetBSD: fpsetround.c,v 1.8 2013/02/03 01:50:54 matt Exp $ */ 21.1Sbjh21 31.7Smatt/*- 41.7Smatt * Copyright (c) 2013 The NetBSD Foundation, Inc. 51.1Sbjh21 * All rights reserved. 61.1Sbjh21 * 71.7Smatt * This code is derived from software contributed to The NetBSD Foundation 81.7Smatt * by Matt Thomas of 3am Software Foundry. 91.7Smatt * 101.1Sbjh21 * Redistribution and use in source and binary forms, with or without 111.1Sbjh21 * modification, are permitted provided that the following conditions 121.1Sbjh21 * are met: 131.1Sbjh21 * 1. Redistributions of source code must retain the above copyright 141.1Sbjh21 * notice, this list of conditions and the following disclaimer. 151.1Sbjh21 * 2. Redistributions in binary form must reproduce the above copyright 161.1Sbjh21 * notice, this list of conditions and the following disclaimer in the 171.1Sbjh21 * documentation and/or other materials provided with the distribution. 181.1Sbjh21 * 191.7Smatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.7Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.7Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.7Smatt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.7Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.7Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.7Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.7Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.7Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.7Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.7Smatt * POSSIBILITY OF SUCH DAMAGE. 301.1Sbjh21 */ 311.1Sbjh21 321.7Smatt#ifndef __VFP_FP__ 331.7Smatt#error FPA is not supported anymore 341.7Smatt#endif 351.7Smatt 361.2Sthorpej#include <sys/cdefs.h> 371.5Slukem#if defined(LIBC_SCCS) && !defined(lint) 381.8Smatt__RCSID("$NetBSD: fpsetround.c,v 1.8 2013/02/03 01:50:54 matt Exp $"); 391.5Slukem#endif /* LIBC_SCCS and not lint */ 401.2Sthorpej 411.2Sthorpej#include "namespace.h" 421.2Sthorpej 431.1Sbjh21#include <sys/types.h> 441.1Sbjh21#include <ieeefp.h> 451.2Sthorpej 461.8Smatt#include <arm/vfpreg.h> 471.8Smatt 481.2Sthorpej#ifdef __weak_alias 491.2Sthorpej__weak_alias(fpsetround,_fpsetround) 501.2Sthorpej#endif 511.1Sbjh21 521.1Sbjh21/* 531.1Sbjh21 * Return the current FP rounding mode 541.1Sbjh21 */ 551.1Sbjh21 561.1Sbjh21fp_rnd 571.7Smattfpsetround(fp_rnd new_rnd) 581.1Sbjh21{ 591.7Smatt __CTASSERT(__SHIFTOUT(VFP_FPSCR_RN, VFP_FPSCR_RMODE) == FP_RN); 601.7Smatt __CTASSERT(__SHIFTOUT(VFP_FPSCR_RP, VFP_FPSCR_RMODE) == FP_RP); 611.7Smatt __CTASSERT(__SHIFTOUT(VFP_FPSCR_RM, VFP_FPSCR_RMODE) == FP_RM); 621.7Smatt __CTASSERT(__SHIFTOUT(VFP_FPSCR_RZ, VFP_FPSCR_RMODE) == FP_RZ); 631.7Smatt uint32_t fpscr; 641.7Smatt __asm __volatile("vmrs %0, fpscr" : "=r" (fpscr)); 651.7Smatt fp_rnd old_rnd = __SHIFTOUT(fpscr, VFP_FPSCR_RMODE); 661.7Smatt fpscr ^= __SHIFTIN(new_rnd ^ old_rnd, VFP_FPSCR_RMODE); 671.7Smatt __asm __volatile("vmsr fpscr, %0" :: "r" (fpscr)); 681.7Smatt return old_rnd; 691.1Sbjh21} 70