14c9649a9Sj_mayer /* 24c9649a9Sj_mayer * Alpha emulation cpu helpers for qemu. 34c9649a9Sj_mayer * 44c9649a9Sj_mayer * Copyright (c) 2007 Jocelyn Mayer 54c9649a9Sj_mayer * 64c9649a9Sj_mayer * This library is free software; you can redistribute it and/or 74c9649a9Sj_mayer * modify it under the terms of the GNU Lesser General Public 84c9649a9Sj_mayer * License as published by the Free Software Foundation; either 94c9649a9Sj_mayer * version 2 of the License, or (at your option) any later version. 104c9649a9Sj_mayer * 114c9649a9Sj_mayer * This library is distributed in the hope that it will be useful, 124c9649a9Sj_mayer * but WITHOUT ANY WARRANTY; without even the implied warranty of 134c9649a9Sj_mayer * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 144c9649a9Sj_mayer * Lesser General Public License for more details. 154c9649a9Sj_mayer * 164c9649a9Sj_mayer * You should have received a copy of the GNU Lesser General Public 178167ee88SBlue Swirl * License along with this library; if not, see <http://www.gnu.org/licenses/>. 184c9649a9Sj_mayer */ 194c9649a9Sj_mayer 204c9649a9Sj_mayer #include <stdint.h> 214c9649a9Sj_mayer #include <stdlib.h> 224c9649a9Sj_mayer #include <stdio.h> 234c9649a9Sj_mayer 244c9649a9Sj_mayer #include "cpu.h" 254c9649a9Sj_mayer #include "exec-all.h" 26ba0e276dSRichard Henderson #include "softfloat.h" 27ba0e276dSRichard Henderson 28ba0e276dSRichard Henderson uint64_t cpu_alpha_load_fpcr (CPUState *env) 29ba0e276dSRichard Henderson { 308443effbSRichard Henderson uint64_t r = 0; 318443effbSRichard Henderson uint8_t t; 32ba0e276dSRichard Henderson 338443effbSRichard Henderson t = env->fpcr_exc_status; 348443effbSRichard Henderson if (t) { 358443effbSRichard Henderson r = FPCR_SUM; 368443effbSRichard Henderson if (t & float_flag_invalid) { 378443effbSRichard Henderson r |= FPCR_INV; 388443effbSRichard Henderson } 398443effbSRichard Henderson if (t & float_flag_divbyzero) { 408443effbSRichard Henderson r |= FPCR_DZE; 418443effbSRichard Henderson } 428443effbSRichard Henderson if (t & float_flag_overflow) { 438443effbSRichard Henderson r |= FPCR_OVF; 448443effbSRichard Henderson } 458443effbSRichard Henderson if (t & float_flag_underflow) { 468443effbSRichard Henderson r |= FPCR_UNF; 478443effbSRichard Henderson } 488443effbSRichard Henderson if (t & float_flag_inexact) { 498443effbSRichard Henderson r |= FPCR_INE; 508443effbSRichard Henderson } 518443effbSRichard Henderson } 52ba0e276dSRichard Henderson 538443effbSRichard Henderson t = env->fpcr_exc_mask; 548443effbSRichard Henderson if (t & float_flag_invalid) { 558443effbSRichard Henderson r |= FPCR_INVD; 568443effbSRichard Henderson } 578443effbSRichard Henderson if (t & float_flag_divbyzero) { 588443effbSRichard Henderson r |= FPCR_DZED; 598443effbSRichard Henderson } 608443effbSRichard Henderson if (t & float_flag_overflow) { 618443effbSRichard Henderson r |= FPCR_OVFD; 628443effbSRichard Henderson } 638443effbSRichard Henderson if (t & float_flag_underflow) { 648443effbSRichard Henderson r |= FPCR_UNFD; 658443effbSRichard Henderson } 668443effbSRichard Henderson if (t & float_flag_inexact) { 678443effbSRichard Henderson r |= FPCR_INED; 688443effbSRichard Henderson } 69ba0e276dSRichard Henderson 708443effbSRichard Henderson switch (env->fpcr_dyn_round) { 71ba0e276dSRichard Henderson case float_round_nearest_even: 728443effbSRichard Henderson r |= FPCR_DYN_NORMAL; 73ba0e276dSRichard Henderson break; 74ba0e276dSRichard Henderson case float_round_down: 758443effbSRichard Henderson r |= FPCR_DYN_MINUS; 76ba0e276dSRichard Henderson break; 77ba0e276dSRichard Henderson case float_round_up: 788443effbSRichard Henderson r |= FPCR_DYN_PLUS; 79ba0e276dSRichard Henderson break; 80ba0e276dSRichard Henderson case float_round_to_zero: 818443effbSRichard Henderson r |= FPCR_DYN_CHOPPED; 82ba0e276dSRichard Henderson break; 83ba0e276dSRichard Henderson } 848443effbSRichard Henderson 858443effbSRichard Henderson if (env->fpcr_dnz) { 868443effbSRichard Henderson r |= FPCR_DNZ; 878443effbSRichard Henderson } 888443effbSRichard Henderson if (env->fpcr_dnod) { 898443effbSRichard Henderson r |= FPCR_DNOD; 908443effbSRichard Henderson } 918443effbSRichard Henderson if (env->fpcr_undz) { 928443effbSRichard Henderson r |= FPCR_UNDZ; 938443effbSRichard Henderson } 948443effbSRichard Henderson 958443effbSRichard Henderson return r; 96ba0e276dSRichard Henderson } 97ba0e276dSRichard Henderson 98ba0e276dSRichard Henderson void cpu_alpha_store_fpcr (CPUState *env, uint64_t val) 99ba0e276dSRichard Henderson { 1008443effbSRichard Henderson uint8_t t; 101ba0e276dSRichard Henderson 1028443effbSRichard Henderson t = 0; 1038443effbSRichard Henderson if (val & FPCR_INV) { 1048443effbSRichard Henderson t |= float_flag_invalid; 1058443effbSRichard Henderson } 1068443effbSRichard Henderson if (val & FPCR_DZE) { 1078443effbSRichard Henderson t |= float_flag_divbyzero; 1088443effbSRichard Henderson } 1098443effbSRichard Henderson if (val & FPCR_OVF) { 1108443effbSRichard Henderson t |= float_flag_overflow; 1118443effbSRichard Henderson } 1128443effbSRichard Henderson if (val & FPCR_UNF) { 1138443effbSRichard Henderson t |= float_flag_underflow; 1148443effbSRichard Henderson } 1158443effbSRichard Henderson if (val & FPCR_INE) { 1168443effbSRichard Henderson t |= float_flag_inexact; 1178443effbSRichard Henderson } 1188443effbSRichard Henderson env->fpcr_exc_status = t; 119ba0e276dSRichard Henderson 1208443effbSRichard Henderson t = 0; 1218443effbSRichard Henderson if (val & FPCR_INVD) { 1228443effbSRichard Henderson t |= float_flag_invalid; 1238443effbSRichard Henderson } 1248443effbSRichard Henderson if (val & FPCR_DZED) { 1258443effbSRichard Henderson t |= float_flag_divbyzero; 1268443effbSRichard Henderson } 1278443effbSRichard Henderson if (val & FPCR_OVFD) { 1288443effbSRichard Henderson t |= float_flag_overflow; 1298443effbSRichard Henderson } 1308443effbSRichard Henderson if (val & FPCR_UNFD) { 1318443effbSRichard Henderson t |= float_flag_underflow; 1328443effbSRichard Henderson } 1338443effbSRichard Henderson if (val & FPCR_INED) { 1348443effbSRichard Henderson t |= float_flag_inexact; 1358443effbSRichard Henderson } 1368443effbSRichard Henderson env->fpcr_exc_mask = t; 137ba0e276dSRichard Henderson 1388443effbSRichard Henderson switch (val & FPCR_DYN_MASK) { 1398443effbSRichard Henderson case FPCR_DYN_CHOPPED: 1408443effbSRichard Henderson t = float_round_to_zero; 141ba0e276dSRichard Henderson break; 1428443effbSRichard Henderson case FPCR_DYN_MINUS: 1438443effbSRichard Henderson t = float_round_down; 144ba0e276dSRichard Henderson break; 1458443effbSRichard Henderson case FPCR_DYN_NORMAL: 1468443effbSRichard Henderson t = float_round_nearest_even; 147ba0e276dSRichard Henderson break; 1488443effbSRichard Henderson case FPCR_DYN_PLUS: 1498443effbSRichard Henderson t = float_round_up; 150ba0e276dSRichard Henderson break; 151ba0e276dSRichard Henderson } 1528443effbSRichard Henderson env->fpcr_dyn_round = t; 1538443effbSRichard Henderson 1548443effbSRichard Henderson env->fpcr_flush_to_zero 1558443effbSRichard Henderson = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD); 1568443effbSRichard Henderson 1578443effbSRichard Henderson env->fpcr_dnz = (val & FPCR_DNZ) != 0; 1588443effbSRichard Henderson env->fpcr_dnod = (val & FPCR_DNOD) != 0; 1598443effbSRichard Henderson env->fpcr_undz = (val & FPCR_UNDZ) != 0; 160ba0e276dSRichard Henderson } 1614c9649a9Sj_mayer 1624c9649a9Sj_mayer #if defined(CONFIG_USER_ONLY) 1634c9649a9Sj_mayer 1644c9649a9Sj_mayer int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 1656ebbf390Sj_mayer int mmu_idx, int is_softmmu) 1664c9649a9Sj_mayer { 1674c9649a9Sj_mayer if (rw == 2) 1684c9649a9Sj_mayer env->exception_index = EXCP_ITB_MISS; 1694c9649a9Sj_mayer else 1704c9649a9Sj_mayer env->exception_index = EXCP_DFAULT; 171129d8aa5SRichard Henderson env->trap_arg0 = address; 1724c9649a9Sj_mayer return 1; 1734c9649a9Sj_mayer } 1744c9649a9Sj_mayer 1754c9649a9Sj_mayer void do_interrupt (CPUState *env) 1764c9649a9Sj_mayer { 1774c9649a9Sj_mayer env->exception_index = -1; 1784c9649a9Sj_mayer } 1794c9649a9Sj_mayer 1804c9649a9Sj_mayer #else 1814c9649a9Sj_mayer 182c227f099SAnthony Liguori target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) 1834c9649a9Sj_mayer { 1844c9649a9Sj_mayer return -1; 1854c9649a9Sj_mayer } 1864c9649a9Sj_mayer 1874c9649a9Sj_mayer int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 1886ebbf390Sj_mayer int mmu_idx, int is_softmmu) 1894c9649a9Sj_mayer { 190129d8aa5SRichard Henderson return 0; 1914c9649a9Sj_mayer } 1924c9649a9Sj_mayer 1934c9649a9Sj_mayer void do_interrupt (CPUState *env) 1944c9649a9Sj_mayer { 195352e48b0SRichard Henderson abort(); 1964c9649a9Sj_mayer } 1974c9649a9Sj_mayer #endif 1984c9649a9Sj_mayer 1999a78eeadSStefan Weil void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, 2004c9649a9Sj_mayer int flags) 2014c9649a9Sj_mayer { 202b55266b5Sblueswir1 static const char *linux_reg_names[] = { 2034c9649a9Sj_mayer "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ", 2044c9649a9Sj_mayer "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ", 2054c9649a9Sj_mayer "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ", 2064c9649a9Sj_mayer "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero", 2074c9649a9Sj_mayer }; 2084c9649a9Sj_mayer int i; 2094c9649a9Sj_mayer 210129d8aa5SRichard Henderson cpu_fprintf(f, " PC " TARGET_FMT_lx " PS %02x\n", 2114c9649a9Sj_mayer env->pc, env->ps); 2124c9649a9Sj_mayer for (i = 0; i < 31; i++) { 2134c9649a9Sj_mayer cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i, 2144c9649a9Sj_mayer linux_reg_names[i], env->ir[i]); 2154c9649a9Sj_mayer if ((i % 3) == 2) 2164c9649a9Sj_mayer cpu_fprintf(f, "\n"); 2174c9649a9Sj_mayer } 2186910b8f6SRichard Henderson 2196910b8f6SRichard Henderson cpu_fprintf(f, "lock_a " TARGET_FMT_lx " lock_v " TARGET_FMT_lx "\n", 2206910b8f6SRichard Henderson env->lock_addr, env->lock_value); 2216910b8f6SRichard Henderson 2224c9649a9Sj_mayer for (i = 0; i < 31; i++) { 2234c9649a9Sj_mayer cpu_fprintf(f, "FIR%02d " TARGET_FMT_lx " ", i, 2244c9649a9Sj_mayer *((uint64_t *)(&env->fir[i]))); 2254c9649a9Sj_mayer if ((i % 3) == 2) 2264c9649a9Sj_mayer cpu_fprintf(f, "\n"); 2274c9649a9Sj_mayer } 2286910b8f6SRichard Henderson cpu_fprintf(f, "\n"); 2294c9649a9Sj_mayer } 230