target/hppa: Split address size from register size
For system mode, we will need 64-bit virtual addresses even when we have 32-bit register sizes. Since the rest of QEMU equates TARGET_LONG_BITS with the address size, redefine everything related to register size in terms of a new TARGET_REGISTER_BITS. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
2986721df7
commit
eaa3783b68
@ -23,10 +23,10 @@
|
||||
#include "qemu-common.h"
|
||||
#include "cpu-qom.h"
|
||||
|
||||
/* We only support hppa-linux-user at present, so 32-bit only. */
|
||||
#define TARGET_LONG_BITS 32
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 32
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#define TARGET_LONG_BITS 32
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#define TARGET_REGISTER_BITS 32
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 32
|
||||
|
||||
#define CPUArchState struct CPUHPPAState
|
||||
|
||||
@ -123,17 +123,29 @@
|
||||
|
||||
typedef struct CPUHPPAState CPUHPPAState;
|
||||
|
||||
#if TARGET_REGISTER_BITS == 32
|
||||
typedef uint32_t target_ureg;
|
||||
typedef int32_t target_sreg;
|
||||
#define TREG_FMT_lx "%08"PRIx32
|
||||
#define TREG_FMT_ld "%"PRId32
|
||||
#else
|
||||
typedef uint64_t target_ureg;
|
||||
typedef int64_t target_sreg;
|
||||
#define TREG_FMT_lx "%016"PRIx64
|
||||
#define TREG_FMT_ld "%"PRId64
|
||||
#endif
|
||||
|
||||
struct CPUHPPAState {
|
||||
target_ulong gr[32];
|
||||
target_ureg gr[32];
|
||||
uint64_t fr[32];
|
||||
|
||||
target_ulong sar;
|
||||
target_ulong cr26;
|
||||
target_ulong cr27;
|
||||
target_ureg sar;
|
||||
target_ureg cr26;
|
||||
target_ureg cr27;
|
||||
|
||||
target_long psw; /* All psw bits except the following: */
|
||||
target_ulong psw_n; /* boolean */
|
||||
target_long psw_v; /* in most significant bit */
|
||||
target_ureg psw; /* All psw bits except the following: */
|
||||
target_ureg psw_n; /* boolean */
|
||||
target_sreg psw_v; /* in most significant bit */
|
||||
|
||||
/* Splitting the carry-borrow field into the MSB and "the rest", allows
|
||||
* for "the rest" to be deleted when it is unused, but the MSB is in use.
|
||||
@ -142,13 +154,13 @@ struct CPUHPPAState {
|
||||
* host has the appropriate add-with-carry insn to compute the msb).
|
||||
* Therefore the carry bits are stored as: cb_msb : cb & 0x11111110.
|
||||
*/
|
||||
target_ulong psw_cb; /* in least significant bit of next nibble */
|
||||
target_ulong psw_cb_msb; /* boolean */
|
||||
target_ureg psw_cb; /* in least significant bit of next nibble */
|
||||
target_ureg psw_cb_msb; /* boolean */
|
||||
|
||||
target_ulong iaoq_f; /* front */
|
||||
target_ulong iaoq_b; /* back, aka next instruction */
|
||||
target_ureg iaoq_f; /* front */
|
||||
target_ureg iaoq_b; /* back, aka next instruction */
|
||||
|
||||
target_ulong ior; /* interrupt offset register */
|
||||
target_ureg ior; /* interrupt offset register */
|
||||
|
||||
uint32_t fr0_shadow; /* flags, c, ca/cq, rm, d, enables */
|
||||
float_status fp_status;
|
||||
@ -201,8 +213,8 @@ static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, target_ulong *pc,
|
||||
*pflags = env->psw_n;
|
||||
}
|
||||
|
||||
target_ulong cpu_hppa_get_psw(CPUHPPAState *env);
|
||||
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong);
|
||||
target_ureg cpu_hppa_get_psw(CPUHPPAState *env);
|
||||
void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg);
|
||||
void cpu_hppa_loaded_fr0(CPUHPPAState *env);
|
||||
|
||||
#define cpu_signal_handler cpu_hppa_signal_handler
|
||||
|
@ -26,7 +26,7 @@ int hppa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
CPUHPPAState *env = &cpu->env;
|
||||
target_ulong val;
|
||||
target_ureg val;
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
@ -61,14 +61,25 @@ int hppa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
}
|
||||
break;
|
||||
}
|
||||
return gdb_get_regl(mem_buf, val);
|
||||
|
||||
if (TARGET_REGISTER_BITS == 64) {
|
||||
return gdb_get_reg64(mem_buf, val);
|
||||
} else {
|
||||
return gdb_get_reg32(mem_buf, val);
|
||||
}
|
||||
}
|
||||
|
||||
int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
CPUHPPAState *env = &cpu->env;
|
||||
target_ulong val = ldtul_p(mem_buf);
|
||||
target_ureg val;
|
||||
|
||||
if (TARGET_REGISTER_BITS == 64) {
|
||||
val = ldq_p(mem_buf);
|
||||
} else {
|
||||
val = ldl_p(mem_buf);
|
||||
}
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
@ -108,5 +119,5 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
}
|
||||
break;
|
||||
}
|
||||
return sizeof(target_ulong);
|
||||
return sizeof(target_ureg);
|
||||
}
|
||||
|
@ -24,9 +24,9 @@
|
||||
#include "fpu/softfloat.h"
|
||||
#include "exec/helper-proto.h"
|
||||
|
||||
target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
|
||||
target_ureg cpu_hppa_get_psw(CPUHPPAState *env)
|
||||
{
|
||||
target_ulong psw;
|
||||
target_ureg psw;
|
||||
|
||||
/* Fold carry bits down to 8 consecutive bits. */
|
||||
/* ??? Needs tweaking for hppa64. */
|
||||
@ -48,9 +48,9 @@ target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
|
||||
return psw;
|
||||
}
|
||||
|
||||
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
|
||||
void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw)
|
||||
{
|
||||
target_ulong cb = 0;
|
||||
target_ureg cb = 0;
|
||||
|
||||
env->psw = psw & ~(PSW_N | PSW_V | PSW_CB);
|
||||
env->psw_n = (psw / PSW_N) & 1;
|
||||
@ -135,13 +135,13 @@ void hppa_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
CPUHPPAState *env = &cpu->env;
|
||||
target_ulong psw = cpu_hppa_get_psw(env);
|
||||
target_ulong psw_cb;
|
||||
target_ureg psw = cpu_hppa_get_psw(env);
|
||||
target_ureg psw_cb;
|
||||
char psw_c[20];
|
||||
int i;
|
||||
|
||||
cpu_fprintf(f, "IA_F " TARGET_FMT_lx " IA_B " TARGET_FMT_lx "\n",
|
||||
env->iaoq_f, env->iaoq_b);
|
||||
(target_ulong)env->iaoq_f, (target_ulong)env->iaoq_b);
|
||||
|
||||
psw_c[0] = (psw & PSW_W ? 'W' : '-');
|
||||
psw_c[1] = (psw & PSW_E ? 'E' : '-');
|
||||
@ -164,11 +164,11 @@ void hppa_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
psw_c[18] = '\0';
|
||||
psw_cb = ((env->psw_cb >> 4) & 0x01111111) | (env->psw_cb_msb << 28);
|
||||
|
||||
cpu_fprintf(f, "PSW " TARGET_FMT_lx " CB " TARGET_FMT_lx " %s\n",
|
||||
cpu_fprintf(f, "PSW " TREG_FMT_lx " CB " TREG_FMT_lx " %s\n",
|
||||
psw, psw_cb, psw_c);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
cpu_fprintf(f, "GR%02d " TARGET_FMT_lx " ", i, env->gr[i]);
|
||||
cpu_fprintf(f, "GR%02d " TREG_FMT_lx " ", i, env->gr[i]);
|
||||
if ((i % 4) == 3) {
|
||||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
|
@ -1,14 +1,24 @@
|
||||
#if TARGET_REGISTER_BITS == 64
|
||||
# define dh_alias_tr i64
|
||||
# define dh_is_64bit_tr 1
|
||||
#else
|
||||
# define dh_alias_tr i32
|
||||
# define dh_is_64bit_tr 0
|
||||
#endif
|
||||
#define dh_ctype_tr target_ureg
|
||||
#define dh_is_signed_tr 0
|
||||
|
||||
DEF_HELPER_2(excp, noreturn, env, int)
|
||||
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tr)
|
||||
DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tr)
|
||||
|
||||
DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tl)
|
||||
DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tl)
|
||||
DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tl)
|
||||
DEF_HELPER_FLAGS_3(stby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tl)
|
||||
DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tr)
|
||||
DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tr)
|
||||
DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tr)
|
||||
DEF_HELPER_FLAGS_3(stby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tr)
|
||||
|
||||
DEF_HELPER_FLAGS_1(probe_r, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
DEF_HELPER_FLAGS_1(probe_w, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
DEF_HELPER_FLAGS_1(probe_r, TCG_CALL_NO_RWG_SE, tr, tl)
|
||||
DEF_HELPER_FLAGS_1(probe_w, TCG_CALL_NO_RWG_SE, tr, tl)
|
||||
|
||||
DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
|
||||
|
||||
|
@ -41,14 +41,14 @@ static void QEMU_NORETURN dynexcp(CPUHPPAState *env, int excp, uintptr_t ra)
|
||||
cpu_loop_exit_restore(cs, ra);
|
||||
}
|
||||
|
||||
void HELPER(tsv)(CPUHPPAState *env, target_ulong cond)
|
||||
void HELPER(tsv)(CPUHPPAState *env, target_ureg cond)
|
||||
{
|
||||
if (unlikely((target_long)cond < 0)) {
|
||||
if (unlikely((target_sreg)cond < 0)) {
|
||||
dynexcp(env, EXCP_OVERFLOW, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
|
||||
void HELPER(tcond)(CPUHPPAState *env, target_ureg cond)
|
||||
{
|
||||
if (unlikely(cond)) {
|
||||
dynexcp(env, EXCP_COND, GETPC());
|
||||
@ -77,7 +77,7 @@ static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ulong val,
|
||||
static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ureg val,
|
||||
bool parallel)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
@ -104,18 +104,18 @@ static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ulong val,
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ulong val)
|
||||
void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ureg val)
|
||||
{
|
||||
do_stby_b(env, addr, val, false);
|
||||
}
|
||||
|
||||
void HELPER(stby_b_parallel)(CPUHPPAState *env, target_ulong addr,
|
||||
target_ulong val)
|
||||
target_ureg val)
|
||||
{
|
||||
do_stby_b(env, addr, val, true);
|
||||
}
|
||||
|
||||
static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ulong val,
|
||||
static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ureg val,
|
||||
bool parallel)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
@ -146,18 +146,18 @@ static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ulong val,
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ulong val)
|
||||
void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ureg val)
|
||||
{
|
||||
do_stby_e(env, addr, val, false);
|
||||
}
|
||||
|
||||
void HELPER(stby_e_parallel)(CPUHPPAState *env, target_ulong addr,
|
||||
target_ulong val)
|
||||
target_ureg val)
|
||||
{
|
||||
do_stby_e(env, addr, val, true);
|
||||
}
|
||||
|
||||
target_ulong HELPER(probe_r)(target_ulong addr)
|
||||
target_ureg HELPER(probe_r)(target_ulong addr)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return page_check_range(addr, 1, PAGE_READ);
|
||||
@ -166,7 +166,7 @@ target_ulong HELPER(probe_r)(target_ulong addr)
|
||||
#endif
|
||||
}
|
||||
|
||||
target_ulong HELPER(probe_w)(target_ulong addr)
|
||||
target_ureg HELPER(probe_w)(target_ulong addr)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return page_check_range(addr, 1, PAGE_WRITE);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user