]> Git Repo - qemu.git/blobdiff - target-alpha/helper.c
target-alpha: Fixes for alpha-linux syscalls.
[qemu.git] / target-alpha / helper.c
index 5a8955d0292b73aa5927b41a8d6cdabd858c6a0e..a658f9782ac2071a847c672969ec7e2eeb66fafc 100644 (file)
@@ -14,8 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <stdint.h>
 
 #include "cpu.h"
 #include "exec-all.h"
+#include "softfloat.h"
+
+uint64_t cpu_alpha_load_fpcr (CPUState *env)
+{
+    uint64_t ret = 0;
+    int flags, mask;
+
+    flags = env->fp_status.float_exception_flags;
+    ret |= (uint64_t) flags << 52;
+    if (flags)
+        ret |= FPCR_SUM;
+    env->ipr[IPR_EXC_SUM] &= ~0x3E;
+    env->ipr[IPR_EXC_SUM] |= flags << 1;
+
+    mask = env->fp_status.float_exception_mask;
+    if (mask & float_flag_invalid)
+        ret |= FPCR_INVD;
+    if (mask & float_flag_divbyzero)
+        ret |= FPCR_DZED;
+    if (mask & float_flag_overflow)
+        ret |= FPCR_OVFD;
+    if (mask & float_flag_underflow)
+        ret |= FPCR_UNFD;
+    if (mask & float_flag_inexact)
+        ret |= FPCR_INED;
+
+    switch (env->fp_status.float_rounding_mode) {
+    case float_round_nearest_even:
+        ret |= 2ULL << FPCR_DYN_SHIFT;
+        break;
+    case float_round_down:
+        ret |= 1ULL << FPCR_DYN_SHIFT;
+        break;
+    case float_round_up:
+        ret |= 3ULL << FPCR_DYN_SHIFT;
+        break;
+    case float_round_to_zero:
+        break;
+    }
+    return ret;
+}
+
+void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
+{
+    int round_mode, mask;
+
+    set_float_exception_flags((val >> 52) & 0x3F, &env->fp_status);
+
+    mask = 0;
+    if (val & FPCR_INVD)
+        mask |= float_flag_invalid;
+    if (val & FPCR_DZED)
+        mask |= float_flag_divbyzero;
+    if (val & FPCR_OVFD)
+        mask |= float_flag_overflow;
+    if (val & FPCR_UNFD)
+        mask |= float_flag_underflow;
+    if (val & FPCR_INED)
+        mask |= float_flag_inexact;
+    env->fp_status.float_exception_mask = mask;
+
+    switch ((val >> FPCR_DYN_SHIFT) & 3) {
+    case 0:
+        round_mode = float_round_to_zero;
+        break;
+    case 1:
+        round_mode = float_round_down;
+        break;
+    case 2:
+        round_mode = float_round_nearest_even;
+        break;
+    case 3:
+        round_mode = float_round_up;
+        break;
+    }
+    set_float_rounding_mode(round_mode, &env->fp_status);
+}
 
 #if defined(CONFIG_USER_ONLY)
 
This page took 0.026803 seconds and 4 git commands to generate.