xref: /openbmc/qemu/target/hppa/helper.c (revision 20eee6cb3d3d75a471fbf200c68441893aa5491a)
161766fe9SRichard Henderson /*
261766fe9SRichard Henderson  *  HPPA emulation cpu helpers for qemu.
361766fe9SRichard Henderson  *
461766fe9SRichard Henderson  * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
561766fe9SRichard Henderson  *
661766fe9SRichard Henderson  * This library is free software; you can redistribute it and/or
761766fe9SRichard Henderson  * modify it under the terms of the GNU Lesser General Public
861766fe9SRichard Henderson  * License as published by the Free Software Foundation; either
9d6ea4236SChetan Pant  * version 2.1 of the License, or (at your option) any later version.
1061766fe9SRichard Henderson  *
1161766fe9SRichard Henderson  * This library is distributed in the hope that it will be useful,
1261766fe9SRichard Henderson  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1361766fe9SRichard Henderson  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1461766fe9SRichard Henderson  * Lesser General Public License for more details.
1561766fe9SRichard Henderson  *
1661766fe9SRichard Henderson  * You should have received a copy of the GNU Lesser General Public
1761766fe9SRichard Henderson  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1861766fe9SRichard Henderson  */
1961766fe9SRichard Henderson 
2061766fe9SRichard Henderson #include "qemu/osdep.h"
21cd617484SPhilippe Mathieu-Daudé #include "qemu/log.h"
2261766fe9SRichard Henderson #include "cpu.h"
2361766fe9SRichard Henderson #include "fpu/softfloat.h"
24d5de20bdSSven Schnelle #include "exec/exec-all.h"
2561766fe9SRichard Henderson #include "exec/helper-proto.h"
2690c84c56SMarkus Armbruster #include "qemu/qemu-print.h"
2761766fe9SRichard Henderson 
cpu_hppa_get_psw(CPUHPPAState * env)28c53e401eSRichard Henderson target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
2961766fe9SRichard Henderson {
30c53e401eSRichard Henderson     target_ulong psw;
31c53e401eSRichard Henderson     target_ulong mask1 = (target_ulong)-1 / 0xf;
32c53e401eSRichard Henderson     target_ulong maskf = (target_ulong)-1 / 0xffff * 0xf;
3361766fe9SRichard Henderson 
3461766fe9SRichard Henderson     /* Fold carry bits down to 8 consecutive bits.  */
35931adff3SRichard Henderson     /* ^^^b^^^c^^^d^^^e^^^f^^^g^^^h^^^i^^^j^^^k^^^l^^^m^^^n^^^o^^^p^^^^ */
36931adff3SRichard Henderson     psw = (env->psw_cb >> 4) & mask1;
37931adff3SRichard Henderson     /* .......b...c...d...e...f...g...h...i...j...k...l...m...n...o...p */
3861766fe9SRichard Henderson     psw |= psw >> 3;
39931adff3SRichard Henderson     /* .......b..bc..cd..de..ef..fg..gh..hi..ij..jk..kl..lm..mn..no..op */
40931adff3SRichard Henderson     psw |= psw >> 6;
41931adff3SRichard Henderson     psw &= maskf;
42931adff3SRichard Henderson     /* .............bcd............efgh............ijkl............mnop */
43931adff3SRichard Henderson     psw |= psw >> 12;
44931adff3SRichard Henderson     /* .............bcd.........bcdefgh........efghijkl........ijklmnop */
45c53e401eSRichard Henderson     psw |= env->psw_cb_msb << 39;
46931adff3SRichard Henderson     /* .............bcd........abcdefgh........efghijkl........ijklmnop */
47931adff3SRichard Henderson 
48931adff3SRichard Henderson     /* For hppa64, the two 8-bit fields are discontiguous. */
49931adff3SRichard Henderson     if (hppa_is_pa20(env)) {
50931adff3SRichard Henderson         psw = (psw & 0xff00000000ull) | ((psw & 0xff) << 8);
51931adff3SRichard Henderson     } else {
52fa57e327SRichard Henderson         psw = (psw & 0xff) << 8;
53931adff3SRichard Henderson     }
5461766fe9SRichard Henderson 
55fa57e327SRichard Henderson     psw |= env->psw_n * PSW_N;
56*20eee6cbSHelge Deller     psw |= ((env->psw_v >> 31) & 1) * PSW_V;
57ebc9401aSRichard Henderson     psw |= env->psw | env->psw_xb;
5861766fe9SRichard Henderson 
5961766fe9SRichard Henderson     return psw;
6061766fe9SRichard Henderson }
6161766fe9SRichard Henderson 
cpu_hppa_put_psw(CPUHPPAState * env,target_ulong psw)62c53e401eSRichard Henderson void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
6361766fe9SRichard Henderson {
64931adff3SRichard Henderson     uint64_t reserved;
65c53e401eSRichard Henderson     target_ulong cb = 0;
6661766fe9SRichard Henderson 
67931adff3SRichard Henderson     /* Do not allow reserved bits to be set. */
68931adff3SRichard Henderson     if (hppa_is_pa20(env)) {
69931adff3SRichard Henderson         reserved = MAKE_64BIT_MASK(40, 24) | MAKE_64BIT_MASK(28, 4);
70931adff3SRichard Henderson         reserved |= PSW_G;                  /* PA1.x only */
71931adff3SRichard Henderson         reserved |= PSW_E;                  /* not implemented */
72931adff3SRichard Henderson     } else {
73931adff3SRichard Henderson         reserved = MAKE_64BIT_MASK(32, 32) | MAKE_64BIT_MASK(28, 2);
74931adff3SRichard Henderson         reserved |= PSW_O | PSW_W;          /* PA2.0 only */
75931adff3SRichard Henderson         reserved |= PSW_E | PSW_Y | PSW_Z;  /* not implemented */
76931adff3SRichard Henderson     }
77931adff3SRichard Henderson     psw &= ~reserved;
78931adff3SRichard Henderson 
79ebc9401aSRichard Henderson     env->psw = psw & (uint32_t)~(PSW_B | PSW_N | PSW_V | PSW_X | PSW_CB);
80ebc9401aSRichard Henderson     env->psw_xb = psw & (PSW_X | PSW_B);
81fa57e327SRichard Henderson     env->psw_n = (psw / PSW_N) & 1;
82fa57e327SRichard Henderson     env->psw_v = -((psw / PSW_V) & 1);
8361766fe9SRichard Henderson 
84931adff3SRichard Henderson     env->psw_cb_msb = (psw >> 39) & 1;
85931adff3SRichard Henderson     cb |= ((psw >> 38) & 1) << 60;
86931adff3SRichard Henderson     cb |= ((psw >> 37) & 1) << 56;
87931adff3SRichard Henderson     cb |= ((psw >> 36) & 1) << 52;
88931adff3SRichard Henderson     cb |= ((psw >> 35) & 1) << 48;
89931adff3SRichard Henderson     cb |= ((psw >> 34) & 1) << 44;
90931adff3SRichard Henderson     cb |= ((psw >> 33) & 1) << 40;
91931adff3SRichard Henderson     cb |= ((psw >> 32) & 1) << 36;
92931adff3SRichard Henderson     cb |= ((psw >> 15) & 1) << 32;
9361766fe9SRichard Henderson     cb |= ((psw >> 14) & 1) << 28;
9461766fe9SRichard Henderson     cb |= ((psw >> 13) & 1) << 24;
9561766fe9SRichard Henderson     cb |= ((psw >> 12) & 1) << 20;
9661766fe9SRichard Henderson     cb |= ((psw >> 11) & 1) << 16;
9761766fe9SRichard Henderson     cb |= ((psw >> 10) & 1) << 12;
9861766fe9SRichard Henderson     cb |= ((psw >>  9) & 1) <<  8;
9961766fe9SRichard Henderson     cb |= ((psw >>  8) & 1) <<  4;
10061766fe9SRichard Henderson     env->psw_cb = cb;
10161766fe9SRichard Henderson }
10261766fe9SRichard Henderson 
hppa_cpu_dump_state(CPUState * cs,FILE * f,int flags)10390c84c56SMarkus Armbruster void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
10461766fe9SRichard Henderson {
105d2e22fdeSRichard Henderson #ifndef CONFIG_USER_ONLY
106d2e22fdeSRichard Henderson     static const char cr_name[32][5] = {
107d2e22fdeSRichard Henderson         "RC",    "CR1",   "CR2",   "CR3",
108d2e22fdeSRichard Henderson         "CR4",   "CR5",   "CR6",   "CR7",
109d2e22fdeSRichard Henderson         "PID1",  "PID2",  "CCR",   "SAR",
110d2e22fdeSRichard Henderson         "PID3",  "PID4",  "IVA",   "EIEM",
111d2e22fdeSRichard Henderson         "ITMR",  "ISQF",  "IOQF",  "IIR",
112d2e22fdeSRichard Henderson         "ISR",   "IOR",   "IPSW",  "EIRR",
113d2e22fdeSRichard Henderson         "TR0",   "TR1",   "TR2",   "TR3",
114d2e22fdeSRichard Henderson         "TR4",   "TR5",   "TR6",   "TR7",
115d2e22fdeSRichard Henderson     };
116d2e22fdeSRichard Henderson #endif
117d2e22fdeSRichard Henderson 
1185718fe4cSRichard Henderson     CPUHPPAState *env = cpu_env(cs);
119c53e401eSRichard Henderson     target_ulong psw = cpu_hppa_get_psw(env);
120c53e401eSRichard Henderson     target_ulong psw_cb;
121fa57e327SRichard Henderson     char psw_c[20];
1225718fe4cSRichard Henderson     int i, w;
1235718fe4cSRichard Henderson     uint64_t m;
1245718fe4cSRichard Henderson 
1255718fe4cSRichard Henderson     if (hppa_is_pa20(env)) {
1265718fe4cSRichard Henderson         w = 16;
1275718fe4cSRichard Henderson         m = UINT64_MAX;
1285718fe4cSRichard Henderson     } else {
1295718fe4cSRichard Henderson         w = 8;
1305718fe4cSRichard Henderson         m = UINT32_MAX;
1315718fe4cSRichard Henderson     }
13261766fe9SRichard Henderson 
133d2e22fdeSRichard Henderson     qemu_fprintf(f, "IA_F %08" PRIx64 ":%0*" PRIx64 " (" TARGET_FMT_lx ")\n"
134d2e22fdeSRichard Henderson                     "IA_B %08" PRIx64 ":%0*" PRIx64 " (" TARGET_FMT_lx ")\n",
135d2e22fdeSRichard Henderson                  env->iasq_f >> 32, w, m & env->iaoq_f,
136c301f34eSRichard Henderson                  hppa_form_gva_psw(psw, env->iasq_f, env->iaoq_f),
137d2e22fdeSRichard Henderson                  env->iasq_b >> 32, w, m & env->iaoq_b,
138d2e22fdeSRichard Henderson                  hppa_form_gva_psw(psw, env->iasq_b, env->iaoq_b));
139fa57e327SRichard Henderson 
140fa57e327SRichard Henderson     psw_c[0]  = (psw & PSW_W ? 'W' : '-');
141fa57e327SRichard Henderson     psw_c[1]  = (psw & PSW_E ? 'E' : '-');
142fa57e327SRichard Henderson     psw_c[2]  = (psw & PSW_S ? 'S' : '-');
143fa57e327SRichard Henderson     psw_c[3]  = (psw & PSW_T ? 'T' : '-');
144fa57e327SRichard Henderson     psw_c[4]  = (psw & PSW_H ? 'H' : '-');
145fa57e327SRichard Henderson     psw_c[5]  = (psw & PSW_L ? 'L' : '-');
146fa57e327SRichard Henderson     psw_c[6]  = (psw & PSW_N ? 'N' : '-');
147fa57e327SRichard Henderson     psw_c[7]  = (psw & PSW_X ? 'X' : '-');
148fa57e327SRichard Henderson     psw_c[8]  = (psw & PSW_B ? 'B' : '-');
149fa57e327SRichard Henderson     psw_c[9]  = (psw & PSW_C ? 'C' : '-');
150fa57e327SRichard Henderson     psw_c[10] = (psw & PSW_V ? 'V' : '-');
151fa57e327SRichard Henderson     psw_c[11] = (psw & PSW_M ? 'M' : '-');
152fa57e327SRichard Henderson     psw_c[12] = (psw & PSW_F ? 'F' : '-');
153fa57e327SRichard Henderson     psw_c[13] = (psw & PSW_R ? 'R' : '-');
154fa57e327SRichard Henderson     psw_c[14] = (psw & PSW_Q ? 'Q' : '-');
155fa57e327SRichard Henderson     psw_c[15] = (psw & PSW_P ? 'P' : '-');
156fa57e327SRichard Henderson     psw_c[16] = (psw & PSW_D ? 'D' : '-');
157fa57e327SRichard Henderson     psw_c[17] = (psw & PSW_I ? 'I' : '-');
158fa57e327SRichard Henderson     psw_c[18] = '\0';
159c53e401eSRichard Henderson     psw_cb = ((env->psw_cb >> 4) & 0x1111111111111111ull)
160c53e401eSRichard Henderson            | (env->psw_cb_msb << 60);
161fa57e327SRichard Henderson 
1625718fe4cSRichard Henderson     qemu_fprintf(f, "PSW  %0*" PRIx64 " CB   %0*" PRIx64 " %s\n",
1635718fe4cSRichard Henderson                  w, m & psw, w, m & psw_cb, psw_c);
164fa57e327SRichard Henderson 
165fa57e327SRichard Henderson     for (i = 0; i < 32; i++) {
1665718fe4cSRichard Henderson         qemu_fprintf(f, "GR%02d %0*" PRIx64 "%c",
1675718fe4cSRichard Henderson                      i, w, m & env->gr[i],
16833423472SRichard Henderson                      (i & 3) == 3 ? '\n' : ' ');
16961766fe9SRichard Henderson     }
17033423472SRichard Henderson #ifndef CONFIG_USER_ONLY
171d2e22fdeSRichard Henderson     for (i = 0; i < 32; i++) {
172d2e22fdeSRichard Henderson         qemu_fprintf(f, "%-4s %0*" PRIx64 "%c",
173d2e22fdeSRichard Henderson                      cr_name[i], w, m & env->cr[i],
174d2e22fdeSRichard Henderson                      (i & 3) == 3 ? '\n' : ' ');
175d2e22fdeSRichard Henderson     }
176d2e22fdeSRichard Henderson     qemu_fprintf(f, "ISQB %0*" PRIx64 " IOQB %0*" PRIx64 "\n",
177d2e22fdeSRichard Henderson                  w, m & env->cr_back[0], w, m & env->cr_back[1]);
17833423472SRichard Henderson     for (i = 0; i < 8; i++) {
17990c84c56SMarkus Armbruster         qemu_fprintf(f, "SR%02d %08x%c", i, (uint32_t)(env->sr[i] >> 32),
18033423472SRichard Henderson                      (i & 3) == 3 ? '\n' : ' ');
18161766fe9SRichard Henderson     }
18233423472SRichard Henderson #endif
18361766fe9SRichard Henderson 
184d2e22fdeSRichard Henderson     if (flags & CPU_DUMP_FPU) {
185d2e22fdeSRichard Henderson         static const char rm[4][4] = { "RN", "RZ", "R+", "R-" };
186d2e22fdeSRichard Henderson         char flg[6], ena[6];
187d2e22fdeSRichard Henderson         uint32_t fpsr = env->fr0_shadow;
188d2e22fdeSRichard Henderson 
189d2e22fdeSRichard Henderson         flg[0] = (fpsr & R_FPSR_FLG_V_MASK ? 'V' : '-');
190d2e22fdeSRichard Henderson         flg[1] = (fpsr & R_FPSR_FLG_Z_MASK ? 'Z' : '-');
191d2e22fdeSRichard Henderson         flg[2] = (fpsr & R_FPSR_FLG_O_MASK ? 'O' : '-');
192d2e22fdeSRichard Henderson         flg[3] = (fpsr & R_FPSR_FLG_U_MASK ? 'U' : '-');
193d2e22fdeSRichard Henderson         flg[4] = (fpsr & R_FPSR_FLG_I_MASK ? 'I' : '-');
194d2e22fdeSRichard Henderson         flg[5] = '\0';
195d2e22fdeSRichard Henderson 
196d2e22fdeSRichard Henderson         ena[0] = (fpsr & R_FPSR_ENA_V_MASK ? 'V' : '-');
197d2e22fdeSRichard Henderson         ena[1] = (fpsr & R_FPSR_ENA_Z_MASK ? 'Z' : '-');
198d2e22fdeSRichard Henderson         ena[2] = (fpsr & R_FPSR_ENA_O_MASK ? 'O' : '-');
199d2e22fdeSRichard Henderson         ena[3] = (fpsr & R_FPSR_ENA_U_MASK ? 'U' : '-');
200d2e22fdeSRichard Henderson         ena[4] = (fpsr & R_FPSR_ENA_I_MASK ? 'I' : '-');
201d2e22fdeSRichard Henderson         ena[5] = '\0';
202d2e22fdeSRichard Henderson 
203d2e22fdeSRichard Henderson         qemu_fprintf(f, "FPSR %08x flag    %s enable  %s %s\n",
204d2e22fdeSRichard Henderson                      fpsr, flg, ena, rm[FIELD_EX32(fpsr, FPSR, RM)]);
205d2e22fdeSRichard Henderson 
206d2e22fdeSRichard Henderson         for (i = 0; i < 32; i++) {
207d2e22fdeSRichard Henderson             qemu_fprintf(f, "FR%02d %016" PRIx64 "%c",
208d2e22fdeSRichard Henderson                      i, env->fr[i], (i & 3) == 3 ? '\n' : ' ');
209d2e22fdeSRichard Henderson         }
210d2e22fdeSRichard Henderson     }
211d2e22fdeSRichard Henderson 
212d2e22fdeSRichard Henderson     qemu_fprintf(f, "\n");
21361766fe9SRichard Henderson }
214