xref: /qemu/target/hppa/helper.c (revision 6402cbbb)
1 /*
2  *  HPPA emulation cpu helpers for qemu.
3  *
4  * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "fpu/softfloat.h"
25 #include "exec/helper-proto.h"
26 
27 target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
28 {
29     target_ulong psw;
30 
31     /* Fold carry bits down to 8 consecutive bits.  */
32     /* ??? Needs tweaking for hppa64.  */
33     /* .......b...c...d...e...f...g...h */
34     psw = (env->psw_cb >> 4) & 0x01111111;
35     /* .......b..bc..cd..de..ef..fg..gh */
36     psw |= psw >> 3;
37     /* .............bcd............efgh */
38     psw |= (psw >> 6) & 0x000f000f;
39     /* .........................bcdefgh */
40     psw |= (psw >> 12) & 0xf;
41     psw |= env->psw_cb_msb << 7;
42     psw <<= 8;
43 
44     psw |= env->psw_n << 21;
45     psw |= (env->psw_v < 0) << 17;
46 
47     return psw;
48 }
49 
50 void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
51 {
52     target_ulong cb = 0;
53 
54     env->psw_n = (psw >> 21) & 1;
55     env->psw_v = -((psw >> 17) & 1);
56     env->psw_cb_msb = (psw >> 15) & 1;
57 
58     cb |= ((psw >> 14) & 1) << 28;
59     cb |= ((psw >> 13) & 1) << 24;
60     cb |= ((psw >> 12) & 1) << 20;
61     cb |= ((psw >> 11) & 1) << 16;
62     cb |= ((psw >> 10) & 1) << 12;
63     cb |= ((psw >>  9) & 1) <<  8;
64     cb |= ((psw >>  8) & 1) <<  4;
65     env->psw_cb = cb;
66 }
67 
68 int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
69                               int rw, int mmu_idx)
70 {
71     HPPACPU *cpu = HPPA_CPU(cs);
72 
73     cs->exception_index = EXCP_SIGSEGV;
74     cpu->env.ior = address;
75     return 1;
76 }
77 
78 void hppa_cpu_do_interrupt(CPUState *cs)
79 {
80     HPPACPU *cpu = HPPA_CPU(cs);
81     CPUHPPAState *env = &cpu->env;
82     int i = cs->exception_index;
83 
84     if (qemu_loglevel_mask(CPU_LOG_INT)) {
85         static int count;
86         const char *name = "<unknown>";
87 
88         switch (i) {
89         case EXCP_SYSCALL:
90             name = "syscall";
91             break;
92         case EXCP_SIGSEGV:
93             name = "sigsegv";
94             break;
95         case EXCP_SIGILL:
96             name = "sigill";
97             break;
98         case EXCP_SIGFPE:
99             name = "sigfpe";
100             break;
101         }
102         qemu_log("INT %6d: %s ia_f=" TARGET_FMT_lx "\n",
103                  ++count, name, env->iaoq_f);
104     }
105     cs->exception_index = -1;
106 }
107 
108 bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
109 {
110     abort();
111     return false;
112 }
113 
114 void hppa_cpu_dump_state(CPUState *cs, FILE *f,
115                          fprintf_function cpu_fprintf, int flags)
116 {
117     HPPACPU *cpu = HPPA_CPU(cs);
118     CPUHPPAState *env = &cpu->env;
119     int i;
120 
121     cpu_fprintf(f, "IA_F " TARGET_FMT_lx
122                    " IA_B " TARGET_FMT_lx
123                    " PSW  " TARGET_FMT_lx
124                    " [N:" TARGET_FMT_ld " V:%d"
125                    " CB:" TARGET_FMT_lx "]\n              ",
126                 env->iaoq_f, env->iaoq_b, cpu_hppa_get_psw(env),
127                 env->psw_n, env->psw_v < 0,
128                 ((env->psw_cb >> 4) & 0x01111111) | (env->psw_cb_msb << 28));
129     for (i = 1; i < 32; i++) {
130         cpu_fprintf(f, "GR%02d " TARGET_FMT_lx " ", i, env->gr[i]);
131         if ((i % 4) == 3) {
132             cpu_fprintf(f, "\n");
133         }
134     }
135 
136     /* ??? FR */
137 }
138