xref: /qemu/target/hppa/helper.c (revision 644ce5df2ea7b0fe34c56ab414182dd7ecd009dc)
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"
27*644ce5dfSHelge Deller #include "hw/hppa/hppa_hardware.h"
2861766fe9SRichard Henderson 
29c53e401eSRichard Henderson target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
3061766fe9SRichard Henderson {
31c53e401eSRichard Henderson     target_ulong psw;
32c53e401eSRichard Henderson     target_ulong mask1 = (target_ulong)-1 / 0xf;
33c53e401eSRichard Henderson     target_ulong maskf = (target_ulong)-1 / 0xffff * 0xf;
3461766fe9SRichard Henderson 
3561766fe9SRichard Henderson     /* Fold carry bits down to 8 consecutive bits.  */
36931adff3SRichard Henderson     /* ^^^b^^^c^^^d^^^e^^^f^^^g^^^h^^^i^^^j^^^k^^^l^^^m^^^n^^^o^^^p^^^^ */
37931adff3SRichard Henderson     psw = (env->psw_cb >> 4) & mask1;
38931adff3SRichard Henderson     /* .......b...c...d...e...f...g...h...i...j...k...l...m...n...o...p */
3961766fe9SRichard Henderson     psw |= psw >> 3;
40931adff3SRichard Henderson     /* .......b..bc..cd..de..ef..fg..gh..hi..ij..jk..kl..lm..mn..no..op */
41931adff3SRichard Henderson     psw |= psw >> 6;
42931adff3SRichard Henderson     psw &= maskf;
43931adff3SRichard Henderson     /* .............bcd............efgh............ijkl............mnop */
44931adff3SRichard Henderson     psw |= psw >> 12;
45931adff3SRichard Henderson     /* .............bcd.........bcdefgh........efghijkl........ijklmnop */
46c53e401eSRichard Henderson     psw |= env->psw_cb_msb << 39;
47931adff3SRichard Henderson     /* .............bcd........abcdefgh........efghijkl........ijklmnop */
48931adff3SRichard Henderson 
49931adff3SRichard Henderson     /* For hppa64, the two 8-bit fields are discontiguous. */
50931adff3SRichard Henderson     if (hppa_is_pa20(env)) {
51931adff3SRichard Henderson         psw = (psw & 0xff00000000ull) | ((psw & 0xff) << 8);
52931adff3SRichard Henderson     } else {
53fa57e327SRichard Henderson         psw = (psw & 0xff) << 8;
54931adff3SRichard Henderson     }
5561766fe9SRichard Henderson 
56fa57e327SRichard Henderson     psw |= env->psw_n * PSW_N;
57ead5078cSHelge Deller     psw |= ((env->psw_v >> 31) & 1) * PSW_V;
58ebc9401aSRichard Henderson     psw |= env->psw | env->psw_xb;
5961766fe9SRichard Henderson 
6061766fe9SRichard Henderson     return psw;
6161766fe9SRichard Henderson }
6261766fe9SRichard Henderson 
63*644ce5dfSHelge Deller void update_gva_offset_mask(CPUHPPAState *env)
64*644ce5dfSHelge Deller {
65*644ce5dfSHelge Deller     uint64_t gom;
66*644ce5dfSHelge Deller 
67*644ce5dfSHelge Deller     if (env->psw & PSW_W) {
68*644ce5dfSHelge Deller         gom = (env->dr[2] & HPPA64_DIAG_SPHASH_ENABLE)
69*644ce5dfSHelge Deller             ? MAKE_64BIT_MASK(0, 62) &
70*644ce5dfSHelge Deller                 ~((uint64_t)HPPA64_PDC_CACHE_RET_SPID_VAL << 48)
71*644ce5dfSHelge Deller             : MAKE_64BIT_MASK(0, 62);
72*644ce5dfSHelge Deller     } else {
73*644ce5dfSHelge Deller         gom = MAKE_64BIT_MASK(0, 32);
74*644ce5dfSHelge Deller     }
75*644ce5dfSHelge Deller 
76*644ce5dfSHelge Deller     env->gva_offset_mask = gom;
77*644ce5dfSHelge Deller }
78*644ce5dfSHelge Deller 
79c53e401eSRichard Henderson void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
8061766fe9SRichard Henderson {
81931adff3SRichard Henderson     uint64_t reserved;
82c53e401eSRichard Henderson     target_ulong cb = 0;
8361766fe9SRichard Henderson 
84931adff3SRichard Henderson     /* Do not allow reserved bits to be set. */
85931adff3SRichard Henderson     if (hppa_is_pa20(env)) {
86931adff3SRichard Henderson         reserved = MAKE_64BIT_MASK(40, 24) | MAKE_64BIT_MASK(28, 4);
87931adff3SRichard Henderson         reserved |= PSW_G;                  /* PA1.x only */
88931adff3SRichard Henderson         reserved |= PSW_E;                  /* not implemented */
89931adff3SRichard Henderson     } else {
90931adff3SRichard Henderson         reserved = MAKE_64BIT_MASK(32, 32) | MAKE_64BIT_MASK(28, 2);
91931adff3SRichard Henderson         reserved |= PSW_O | PSW_W;          /* PA2.0 only */
92931adff3SRichard Henderson         reserved |= PSW_E | PSW_Y | PSW_Z;  /* not implemented */
93931adff3SRichard Henderson     }
94931adff3SRichard Henderson     psw &= ~reserved;
95931adff3SRichard Henderson 
96ebc9401aSRichard Henderson     env->psw = psw & (uint32_t)~(PSW_B | PSW_N | PSW_V | PSW_X | PSW_CB);
97ebc9401aSRichard Henderson     env->psw_xb = psw & (PSW_X | PSW_B);
98fa57e327SRichard Henderson     env->psw_n = (psw / PSW_N) & 1;
99fa57e327SRichard Henderson     env->psw_v = -((psw / PSW_V) & 1);
10061766fe9SRichard Henderson 
101931adff3SRichard Henderson     env->psw_cb_msb = (psw >> 39) & 1;
102931adff3SRichard Henderson     cb |= ((psw >> 38) & 1) << 60;
103931adff3SRichard Henderson     cb |= ((psw >> 37) & 1) << 56;
104931adff3SRichard Henderson     cb |= ((psw >> 36) & 1) << 52;
105931adff3SRichard Henderson     cb |= ((psw >> 35) & 1) << 48;
106931adff3SRichard Henderson     cb |= ((psw >> 34) & 1) << 44;
107931adff3SRichard Henderson     cb |= ((psw >> 33) & 1) << 40;
108931adff3SRichard Henderson     cb |= ((psw >> 32) & 1) << 36;
109931adff3SRichard Henderson     cb |= ((psw >> 15) & 1) << 32;
11061766fe9SRichard Henderson     cb |= ((psw >> 14) & 1) << 28;
11161766fe9SRichard Henderson     cb |= ((psw >> 13) & 1) << 24;
11261766fe9SRichard Henderson     cb |= ((psw >> 12) & 1) << 20;
11361766fe9SRichard Henderson     cb |= ((psw >> 11) & 1) << 16;
11461766fe9SRichard Henderson     cb |= ((psw >> 10) & 1) << 12;
11561766fe9SRichard Henderson     cb |= ((psw >>  9) & 1) <<  8;
11661766fe9SRichard Henderson     cb |= ((psw >>  8) & 1) <<  4;
11761766fe9SRichard Henderson     env->psw_cb = cb;
118*644ce5dfSHelge Deller 
119*644ce5dfSHelge Deller     update_gva_offset_mask(env);
12061766fe9SRichard Henderson }
12161766fe9SRichard Henderson 
12290c84c56SMarkus Armbruster void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
12361766fe9SRichard Henderson {
124d2e22fdeSRichard Henderson #ifndef CONFIG_USER_ONLY
125d2e22fdeSRichard Henderson     static const char cr_name[32][5] = {
126d2e22fdeSRichard Henderson         "RC",    "CR1",   "CR2",   "CR3",
127d2e22fdeSRichard Henderson         "CR4",   "CR5",   "CR6",   "CR7",
128d2e22fdeSRichard Henderson         "PID1",  "PID2",  "CCR",   "SAR",
129d2e22fdeSRichard Henderson         "PID3",  "PID4",  "IVA",   "EIEM",
130d2e22fdeSRichard Henderson         "ITMR",  "ISQF",  "IOQF",  "IIR",
131d2e22fdeSRichard Henderson         "ISR",   "IOR",   "IPSW",  "EIRR",
132d2e22fdeSRichard Henderson         "TR0",   "TR1",   "TR2",   "TR3",
133d2e22fdeSRichard Henderson         "TR4",   "TR5",   "TR6",   "TR7",
134d2e22fdeSRichard Henderson     };
135d2e22fdeSRichard Henderson #endif
136d2e22fdeSRichard Henderson 
1375718fe4cSRichard Henderson     CPUHPPAState *env = cpu_env(cs);
138c53e401eSRichard Henderson     target_ulong psw = cpu_hppa_get_psw(env);
139c53e401eSRichard Henderson     target_ulong psw_cb;
140fa57e327SRichard Henderson     char psw_c[20];
1415718fe4cSRichard Henderson     int i, w;
1425718fe4cSRichard Henderson     uint64_t m;
1435718fe4cSRichard Henderson 
1445718fe4cSRichard Henderson     if (hppa_is_pa20(env)) {
1455718fe4cSRichard Henderson         w = 16;
1465718fe4cSRichard Henderson         m = UINT64_MAX;
1475718fe4cSRichard Henderson     } else {
1485718fe4cSRichard Henderson         w = 8;
1495718fe4cSRichard Henderson         m = UINT32_MAX;
1505718fe4cSRichard Henderson     }
15161766fe9SRichard Henderson 
152d2e22fdeSRichard Henderson     qemu_fprintf(f, "IA_F %08" PRIx64 ":%0*" PRIx64 " (" TARGET_FMT_lx ")\n"
153d2e22fdeSRichard Henderson                     "IA_B %08" PRIx64 ":%0*" PRIx64 " (" TARGET_FMT_lx ")\n",
154d2e22fdeSRichard Henderson                  env->iasq_f >> 32, w, m & env->iaoq_f,
155*644ce5dfSHelge Deller                  hppa_form_gva_mask(env->gva_offset_mask, env->iasq_f,
156*644ce5dfSHelge Deller 				    env->iaoq_f),
157d2e22fdeSRichard Henderson                  env->iasq_b >> 32, w, m & env->iaoq_b,
158*644ce5dfSHelge Deller                  hppa_form_gva_mask(env->gva_offset_mask, env->iasq_b,
159*644ce5dfSHelge Deller 				    env->iaoq_b));
160fa57e327SRichard Henderson 
161fa57e327SRichard Henderson     psw_c[0]  = (psw & PSW_W ? 'W' : '-');
162fa57e327SRichard Henderson     psw_c[1]  = (psw & PSW_E ? 'E' : '-');
163fa57e327SRichard Henderson     psw_c[2]  = (psw & PSW_S ? 'S' : '-');
164fa57e327SRichard Henderson     psw_c[3]  = (psw & PSW_T ? 'T' : '-');
165fa57e327SRichard Henderson     psw_c[4]  = (psw & PSW_H ? 'H' : '-');
166fa57e327SRichard Henderson     psw_c[5]  = (psw & PSW_L ? 'L' : '-');
167fa57e327SRichard Henderson     psw_c[6]  = (psw & PSW_N ? 'N' : '-');
168fa57e327SRichard Henderson     psw_c[7]  = (psw & PSW_X ? 'X' : '-');
169fa57e327SRichard Henderson     psw_c[8]  = (psw & PSW_B ? 'B' : '-');
170fa57e327SRichard Henderson     psw_c[9]  = (psw & PSW_C ? 'C' : '-');
171fa57e327SRichard Henderson     psw_c[10] = (psw & PSW_V ? 'V' : '-');
172fa57e327SRichard Henderson     psw_c[11] = (psw & PSW_M ? 'M' : '-');
173fa57e327SRichard Henderson     psw_c[12] = (psw & PSW_F ? 'F' : '-');
174fa57e327SRichard Henderson     psw_c[13] = (psw & PSW_R ? 'R' : '-');
175fa57e327SRichard Henderson     psw_c[14] = (psw & PSW_Q ? 'Q' : '-');
176fa57e327SRichard Henderson     psw_c[15] = (psw & PSW_P ? 'P' : '-');
177fa57e327SRichard Henderson     psw_c[16] = (psw & PSW_D ? 'D' : '-');
178fa57e327SRichard Henderson     psw_c[17] = (psw & PSW_I ? 'I' : '-');
179fa57e327SRichard Henderson     psw_c[18] = '\0';
180c53e401eSRichard Henderson     psw_cb = ((env->psw_cb >> 4) & 0x1111111111111111ull)
181c53e401eSRichard Henderson            | (env->psw_cb_msb << 60);
182fa57e327SRichard Henderson 
1835718fe4cSRichard Henderson     qemu_fprintf(f, "PSW  %0*" PRIx64 " CB   %0*" PRIx64 " %s\n",
1845718fe4cSRichard Henderson                  w, m & psw, w, m & psw_cb, psw_c);
185fa57e327SRichard Henderson 
186fa57e327SRichard Henderson     for (i = 0; i < 32; i++) {
1875718fe4cSRichard Henderson         qemu_fprintf(f, "GR%02d %0*" PRIx64 "%c",
1885718fe4cSRichard Henderson                      i, w, m & env->gr[i],
18933423472SRichard Henderson                      (i & 3) == 3 ? '\n' : ' ');
19061766fe9SRichard Henderson     }
19133423472SRichard Henderson #ifndef CONFIG_USER_ONLY
192d2e22fdeSRichard Henderson     for (i = 0; i < 32; i++) {
193d2e22fdeSRichard Henderson         qemu_fprintf(f, "%-4s %0*" PRIx64 "%c",
194d2e22fdeSRichard Henderson                      cr_name[i], w, m & env->cr[i],
195d2e22fdeSRichard Henderson                      (i & 3) == 3 ? '\n' : ' ');
196d2e22fdeSRichard Henderson     }
197d2e22fdeSRichard Henderson     qemu_fprintf(f, "ISQB %0*" PRIx64 " IOQB %0*" PRIx64 "\n",
198d2e22fdeSRichard Henderson                  w, m & env->cr_back[0], w, m & env->cr_back[1]);
19933423472SRichard Henderson     for (i = 0; i < 8; i++) {
20090c84c56SMarkus Armbruster         qemu_fprintf(f, "SR%02d %08x%c", i, (uint32_t)(env->sr[i] >> 32),
20133423472SRichard Henderson                      (i & 3) == 3 ? '\n' : ' ');
20261766fe9SRichard Henderson     }
20333423472SRichard Henderson #endif
20461766fe9SRichard Henderson 
205d2e22fdeSRichard Henderson     if (flags & CPU_DUMP_FPU) {
206d2e22fdeSRichard Henderson         static const char rm[4][4] = { "RN", "RZ", "R+", "R-" };
207d2e22fdeSRichard Henderson         char flg[6], ena[6];
208d2e22fdeSRichard Henderson         uint32_t fpsr = env->fr0_shadow;
209d2e22fdeSRichard Henderson 
210d2e22fdeSRichard Henderson         flg[0] = (fpsr & R_FPSR_FLG_V_MASK ? 'V' : '-');
211d2e22fdeSRichard Henderson         flg[1] = (fpsr & R_FPSR_FLG_Z_MASK ? 'Z' : '-');
212d2e22fdeSRichard Henderson         flg[2] = (fpsr & R_FPSR_FLG_O_MASK ? 'O' : '-');
213d2e22fdeSRichard Henderson         flg[3] = (fpsr & R_FPSR_FLG_U_MASK ? 'U' : '-');
214d2e22fdeSRichard Henderson         flg[4] = (fpsr & R_FPSR_FLG_I_MASK ? 'I' : '-');
215d2e22fdeSRichard Henderson         flg[5] = '\0';
216d2e22fdeSRichard Henderson 
217d2e22fdeSRichard Henderson         ena[0] = (fpsr & R_FPSR_ENA_V_MASK ? 'V' : '-');
218d2e22fdeSRichard Henderson         ena[1] = (fpsr & R_FPSR_ENA_Z_MASK ? 'Z' : '-');
219d2e22fdeSRichard Henderson         ena[2] = (fpsr & R_FPSR_ENA_O_MASK ? 'O' : '-');
220d2e22fdeSRichard Henderson         ena[3] = (fpsr & R_FPSR_ENA_U_MASK ? 'U' : '-');
221d2e22fdeSRichard Henderson         ena[4] = (fpsr & R_FPSR_ENA_I_MASK ? 'I' : '-');
222d2e22fdeSRichard Henderson         ena[5] = '\0';
223d2e22fdeSRichard Henderson 
224d2e22fdeSRichard Henderson         qemu_fprintf(f, "FPSR %08x flag    %s enable  %s %s\n",
225d2e22fdeSRichard Henderson                      fpsr, flg, ena, rm[FIELD_EX32(fpsr, FPSR, RM)]);
226d2e22fdeSRichard Henderson 
227d2e22fdeSRichard Henderson         for (i = 0; i < 32; i++) {
228d2e22fdeSRichard Henderson             qemu_fprintf(f, "FR%02d %016" PRIx64 "%c",
229d2e22fdeSRichard Henderson                      i, env->fr[i], (i & 3) == 3 ? '\n' : ' ');
230d2e22fdeSRichard Henderson         }
231d2e22fdeSRichard Henderson     }
232d2e22fdeSRichard Henderson 
233d2e22fdeSRichard Henderson     qemu_fprintf(f, "\n");
23461766fe9SRichard Henderson }
235