2 * HPPA emulation cpu helpers for qemu.
4 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
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.1 of the License, or (at your option) any later version.
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.
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/>.
20 #include "qemu/osdep.h"
23 #include "fpu/softfloat.h"
24 #include "exec/exec-all.h"
25 #include "exec/helper-proto.h"
26 #include "qemu/qemu-print.h"
28 target_ulong
cpu_hppa_get_psw(CPUHPPAState
*env
)
31 target_ulong mask1
= (target_ulong
)-1 / 0xf;
32 target_ulong maskf
= (target_ulong
)-1 / 0xffff * 0xf;
34 /* Fold carry bits down to 8 consecutive bits. */
35 /* ^^^b^^^c^^^d^^^e^^^f^^^g^^^h^^^i^^^j^^^k^^^l^^^m^^^n^^^o^^^p^^^^ */
36 psw
= (env
->psw_cb
>> 4) & mask1
;
37 /* .......b...c...d...e...f...g...h...i...j...k...l...m...n...o...p */
39 /* .......b..bc..cd..de..ef..fg..gh..hi..ij..jk..kl..lm..mn..no..op */
42 /* .............bcd............efgh............ijkl............mnop */
44 /* .............bcd.........bcdefgh........efghijkl........ijklmnop */
45 psw
|= env
->psw_cb_msb
<< 39;
46 /* .............bcd........abcdefgh........efghijkl........ijklmnop */
48 /* For hppa64, the two 8-bit fields are discontiguous. */
49 if (hppa_is_pa20(env
)) {
50 psw
= (psw
& 0xff00000000ull
) | ((psw
& 0xff) << 8);
52 psw
= (psw
& 0xff) << 8;
55 psw
|= env
->psw_n
* PSW_N
;
56 psw
|= ((env
->psw_v
>> 31) & 1) * PSW_V
;
57 psw
|= env
->psw
| env
->psw_xb
;
62 void cpu_hppa_put_psw(CPUHPPAState
*env
, target_ulong psw
)
67 /* Do not allow reserved bits to be set. */
68 if (hppa_is_pa20(env
)) {
69 reserved
= MAKE_64BIT_MASK(40, 24) | MAKE_64BIT_MASK(28, 4);
70 reserved
|= PSW_G
; /* PA1.x only */
71 reserved
|= PSW_E
; /* not implemented */
73 reserved
= MAKE_64BIT_MASK(32, 32) | MAKE_64BIT_MASK(28, 2);
74 reserved
|= PSW_O
| PSW_W
; /* PA2.0 only */
75 reserved
|= PSW_E
| PSW_Y
| PSW_Z
; /* not implemented */
79 env
->psw
= psw
& (uint32_t)~(PSW_B
| PSW_N
| PSW_V
| PSW_X
| PSW_CB
);
80 env
->psw_xb
= psw
& (PSW_X
| PSW_B
);
81 env
->psw_n
= (psw
/ PSW_N
) & 1;
82 env
->psw_v
= -((psw
/ PSW_V
) & 1);
84 env
->psw_cb_msb
= (psw
>> 39) & 1;
85 cb
|= ((psw
>> 38) & 1) << 60;
86 cb
|= ((psw
>> 37) & 1) << 56;
87 cb
|= ((psw
>> 36) & 1) << 52;
88 cb
|= ((psw
>> 35) & 1) << 48;
89 cb
|= ((psw
>> 34) & 1) << 44;
90 cb
|= ((psw
>> 33) & 1) << 40;
91 cb
|= ((psw
>> 32) & 1) << 36;
92 cb
|= ((psw
>> 15) & 1) << 32;
93 cb
|= ((psw
>> 14) & 1) << 28;
94 cb
|= ((psw
>> 13) & 1) << 24;
95 cb
|= ((psw
>> 12) & 1) << 20;
96 cb
|= ((psw
>> 11) & 1) << 16;
97 cb
|= ((psw
>> 10) & 1) << 12;
98 cb
|= ((psw
>> 9) & 1) << 8;
99 cb
|= ((psw
>> 8) & 1) << 4;
103 void hppa_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
105 #ifndef CONFIG_USER_ONLY
106 static const char cr_name
[32][5] = {
107 "RC", "CR1", "CR2", "CR3",
108 "CR4", "CR5", "CR6", "CR7",
109 "PID1", "PID2", "CCR", "SAR",
110 "PID3", "PID4", "IVA", "EIEM",
111 "ITMR", "ISQF", "IOQF", "IIR",
112 "ISR", "IOR", "IPSW", "EIRR",
113 "TR0", "TR1", "TR2", "TR3",
114 "TR4", "TR5", "TR6", "TR7",
118 CPUHPPAState
*env
= cpu_env(cs
);
119 target_ulong psw
= cpu_hppa_get_psw(env
);
125 if (hppa_is_pa20(env
)) {
133 qemu_fprintf(f
, "IA_F %08" PRIx64
":%0*" PRIx64
" (" TARGET_FMT_lx
")\n"
134 "IA_B %08" PRIx64
":%0*" PRIx64
" (" TARGET_FMT_lx
")\n",
135 env
->iasq_f
>> 32, w
, m
& env
->iaoq_f
,
136 hppa_form_gva_psw(psw
, env
->iasq_f
, env
->iaoq_f
),
137 env
->iasq_b
>> 32, w
, m
& env
->iaoq_b
,
138 hppa_form_gva_psw(psw
, env
->iasq_b
, env
->iaoq_b
));
140 psw_c
[0] = (psw
& PSW_W
? 'W' : '-');
141 psw_c
[1] = (psw
& PSW_E
? 'E' : '-');
142 psw_c
[2] = (psw
& PSW_S
? 'S' : '-');
143 psw_c
[3] = (psw
& PSW_T
? 'T' : '-');
144 psw_c
[4] = (psw
& PSW_H
? 'H' : '-');
145 psw_c
[5] = (psw
& PSW_L
? 'L' : '-');
146 psw_c
[6] = (psw
& PSW_N
? 'N' : '-');
147 psw_c
[7] = (psw
& PSW_X
? 'X' : '-');
148 psw_c
[8] = (psw
& PSW_B
? 'B' : '-');
149 psw_c
[9] = (psw
& PSW_C
? 'C' : '-');
150 psw_c
[10] = (psw
& PSW_V
? 'V' : '-');
151 psw_c
[11] = (psw
& PSW_M
? 'M' : '-');
152 psw_c
[12] = (psw
& PSW_F
? 'F' : '-');
153 psw_c
[13] = (psw
& PSW_R
? 'R' : '-');
154 psw_c
[14] = (psw
& PSW_Q
? 'Q' : '-');
155 psw_c
[15] = (psw
& PSW_P
? 'P' : '-');
156 psw_c
[16] = (psw
& PSW_D
? 'D' : '-');
157 psw_c
[17] = (psw
& PSW_I
? 'I' : '-');
159 psw_cb
= ((env
->psw_cb
>> 4) & 0x1111111111111111ull
)
160 | (env
->psw_cb_msb
<< 60);
162 qemu_fprintf(f
, "PSW %0*" PRIx64
" CB %0*" PRIx64
" %s\n",
163 w
, m
& psw
, w
, m
& psw_cb
, psw_c
);
165 for (i
= 0; i
< 32; i
++) {
166 qemu_fprintf(f
, "GR%02d %0*" PRIx64
"%c",
167 i
, w
, m
& env
->gr
[i
],
168 (i
& 3) == 3 ? '\n' : ' ');
170 #ifndef CONFIG_USER_ONLY
171 for (i
= 0; i
< 32; i
++) {
172 qemu_fprintf(f
, "%-4s %0*" PRIx64
"%c",
173 cr_name
[i
], w
, m
& env
->cr
[i
],
174 (i
& 3) == 3 ? '\n' : ' ');
176 qemu_fprintf(f
, "ISQB %0*" PRIx64
" IOQB %0*" PRIx64
"\n",
177 w
, m
& env
->cr_back
[0], w
, m
& env
->cr_back
[1]);
178 for (i
= 0; i
< 8; i
++) {
179 qemu_fprintf(f
, "SR%02d %08x%c", i
, (uint32_t)(env
->sr
[i
] >> 32),
180 (i
& 3) == 3 ? '\n' : ' ');
184 if (flags
& CPU_DUMP_FPU
) {
185 static const char rm
[4][4] = { "RN", "RZ", "R+", "R-" };
187 uint32_t fpsr
= env
->fr0_shadow
;
189 flg
[0] = (fpsr
& R_FPSR_FLG_V_MASK
? 'V' : '-');
190 flg
[1] = (fpsr
& R_FPSR_FLG_Z_MASK
? 'Z' : '-');
191 flg
[2] = (fpsr
& R_FPSR_FLG_O_MASK
? 'O' : '-');
192 flg
[3] = (fpsr
& R_FPSR_FLG_U_MASK
? 'U' : '-');
193 flg
[4] = (fpsr
& R_FPSR_FLG_I_MASK
? 'I' : '-');
196 ena
[0] = (fpsr
& R_FPSR_ENA_V_MASK
? 'V' : '-');
197 ena
[1] = (fpsr
& R_FPSR_ENA_Z_MASK
? 'Z' : '-');
198 ena
[2] = (fpsr
& R_FPSR_ENA_O_MASK
? 'O' : '-');
199 ena
[3] = (fpsr
& R_FPSR_ENA_U_MASK
? 'U' : '-');
200 ena
[4] = (fpsr
& R_FPSR_ENA_I_MASK
? 'I' : '-');
203 qemu_fprintf(f
, "FPSR %08x flag %s enable %s %s\n",
204 fpsr
, flg
, ena
, rm
[FIELD_EX32(fpsr
, FPSR
, RM
)]);
206 for (i
= 0; i
< 32; i
++) {
207 qemu_fprintf(f
, "FR%02d %016" PRIx64
"%c",
208 i
, env
->fr
[i
], (i
& 3) == 3 ? '\n' : ' ');
212 qemu_fprintf(f
, "\n");