hppa-linux target support
-----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJYhkNBAAoJEK0ScMxN0Cebf2oIAMf7xHHiG+KHKA+v/TCxwxa/ ezVw+cqkSiR6WSV2Hr0I+0edt9CGdVInJ9mgIYTKcLFvwieWywd5JffURddqbPK5 r0Hk0qLJLv4oKDkYv6wP37s96slnD8PGpLn292COhJwXo4oXhPtvyliRkP00Ge2/ PQAP/9vxtiUsWNFWiGMplqfYyTYCTNG/vUkYWjpvuEZRUQ3Rb/XPdCjkAd+dFM+U b/jB+cwoOSXs/DTNmDmmhpmiEP6hGwYhFsNeMlPr2EK0p3AfIF+UWR2RObven1zb LgyXyxEsRLimSyCmbyxiuQCXsMF7Ku5TQMvb5EKTKpMZzMbqmNnaAcEbqECQCuI= =PyRU -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-hppa-20170123' into staging hppa-linux target support # gpg: Signature made Mon 23 Jan 2017 17:54:09 GMT # gpg: using RSA key 0xAD1270CC4DD0279B # gpg: Good signature from "Richard Henderson <rth7680@gmail.com>" # gpg: aka "Richard Henderson <rth@redhat.com>" # gpg: aka "Richard Henderson <rth@twiddle.net>" # Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC 16A4 AD12 70CC 4DD0 279B * remotes/rth/tags/pull-hppa-20170123: (25 commits) target-hppa: Implement floating-point insns target-hppa: Implement system and memory-management insns target-hppa: Implement loads and stores target-hppa: Implement shifts and deposits target-hppa: Implement linux-user gateway page target-hppa: Implement branches target-hppa: Implement basic arithmetic target-hppa: Add nullification framework target-hppa: Add framework and enable compilation target-hppa: Add softfloat specializations linux-user: Add HPPA startup and main loop linux-user: Add HPPA signal handling linux-user: Add HPPA target_signal.h and target_cpu.h linux-user: Add HPPA target_structs.h linux-user: Add HPPA definitions to syscall_defs.h linux-user: Add HPPA target_syscall.h linux-user: Add HPPA termbits.h linux-user: Add HPPA syscall numbers linux-user: Add HPPA socket.h definitions linux-user: Add some hppa ioctls ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
48cef39bf3
@ -132,6 +132,12 @@ F: include/hw/cris/
|
||||
F: tests/tcg/cris/
|
||||
F: disas/cris.c
|
||||
|
||||
HPPA (PA-RISC)
|
||||
M: Richard Henderson <rth@twiddle.net>
|
||||
S: Maintained
|
||||
F: target/hppa/
|
||||
F: disas/hppa.c
|
||||
|
||||
LM32
|
||||
M: Michael Walle <michael@walle.cc>
|
||||
S: Maintained
|
||||
|
7
configure
vendored
7
configure
vendored
@ -5843,7 +5843,7 @@ target_name=$(echo $target | cut -d '-' -f 1)
|
||||
target_bigendian="no"
|
||||
|
||||
case "$target_name" in
|
||||
armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
|
||||
armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
|
||||
target_bigendian=yes
|
||||
;;
|
||||
esac
|
||||
@ -5906,6 +5906,8 @@ case "$target_name" in
|
||||
;;
|
||||
cris)
|
||||
;;
|
||||
hppa)
|
||||
;;
|
||||
lm32)
|
||||
;;
|
||||
m68k)
|
||||
@ -6114,6 +6116,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
|
||||
cris)
|
||||
disas_config "CRIS"
|
||||
;;
|
||||
hppa)
|
||||
disas_config "HPPA"
|
||||
;;
|
||||
i386|x86_64|x32)
|
||||
disas_config "I386"
|
||||
;;
|
||||
|
1
default-configs/hppa-linux-user.mak
Normal file
1
default-configs/hppa-linux-user.mak
Normal file
@ -0,0 +1 @@
|
||||
# Default configuration for hppa-linux-user
|
2
disas.c
2
disas.c
@ -310,6 +310,8 @@ void disas(FILE *out, void *code, unsigned long size)
|
||||
print_insn = print_insn_m68k;
|
||||
#elif defined(__s390__)
|
||||
print_insn = print_insn_s390;
|
||||
#elif defined(__hppa__)
|
||||
print_insn = print_insn_hppa;
|
||||
#elif defined(__ia64__)
|
||||
print_insn = print_insn_ia64;
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@ libvixldir = $(SRC_PATH)/disas/libvixl
|
||||
# versions do not.
|
||||
arm-a64.o-cflags := -I$(libvixldir) -Wno-sign-compare
|
||||
common-obj-$(CONFIG_CRIS_DIS) += cris.o
|
||||
common-obj-$(CONFIG_HPPA_DIS) += hppa.o
|
||||
common-obj-$(CONFIG_I386_DIS) += i386.o
|
||||
common-obj-$(CONFIG_IA64_DIS) += ia64.o
|
||||
common-obj-$(CONFIG_M68K_DIS) += m68k.o
|
||||
|
2832
disas/hppa.c
Normal file
2832
disas/hppa.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -116,6 +116,8 @@ float32 float32_default_nan(float_status *status)
|
||||
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
|
||||
defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE)
|
||||
return const_float32(0x7FC00000);
|
||||
#elif defined(TARGET_HPPA)
|
||||
return const_float32(0x7FA00000);
|
||||
#else
|
||||
if (status->snan_bit_is_one) {
|
||||
return const_float32(0x7FBFFFFF);
|
||||
@ -139,6 +141,8 @@ float64 float64_default_nan(float_status *status)
|
||||
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
|
||||
defined(TARGET_S390X)
|
||||
return const_float64(LIT64(0x7FF8000000000000));
|
||||
#elif defined(TARGET_HPPA)
|
||||
return const_float64(LIT64(0x7FF4000000000000));
|
||||
#else
|
||||
if (status->snan_bit_is_one) {
|
||||
return const_float64(LIT64(0x7FF7FFFFFFFFFFFF));
|
||||
@ -361,7 +365,14 @@ float32 float32_maybe_silence_nan(float32 a_, float_status *status)
|
||||
{
|
||||
if (float32_is_signaling_nan(a_, status)) {
|
||||
if (status->snan_bit_is_one) {
|
||||
#ifdef TARGET_HPPA
|
||||
uint32_t a = float32_val(a_);
|
||||
a &= ~0x00400000;
|
||||
a |= 0x00200000;
|
||||
return make_float32(a);
|
||||
#else
|
||||
return float32_default_nan(status);
|
||||
#endif
|
||||
} else {
|
||||
uint32_t a = float32_val(a_);
|
||||
a |= (1 << 22);
|
||||
@ -449,7 +460,7 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#elif defined(TARGET_MIPS)
|
||||
#elif defined(TARGET_MIPS) || defined(TARGET_HPPA)
|
||||
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
|
||||
flag aIsLargerSignificand)
|
||||
{
|
||||
@ -794,7 +805,14 @@ float64 float64_maybe_silence_nan(float64 a_, float_status *status)
|
||||
{
|
||||
if (float64_is_signaling_nan(a_, status)) {
|
||||
if (status->snan_bit_is_one) {
|
||||
#ifdef TARGET_HPPA
|
||||
uint64_t a = float64_val(a_);
|
||||
a &= ~0x0008000000000000ULL;
|
||||
a |= 0x0004000000000000ULL;
|
||||
return make_float64(a);
|
||||
#else
|
||||
return float64_default_nan(status);
|
||||
#endif
|
||||
} else {
|
||||
uint64_t a = float64_val(a_);
|
||||
a |= LIT64(0x0008000000000000);
|
||||
|
@ -235,6 +235,8 @@ struct target_pt_regs {
|
||||
#define TARGET_ENOTRECOVERABLE 137
|
||||
#undef TARGET_ERFKILL
|
||||
#define TARGET_ERFKILL 138
|
||||
#undef TARGET_EHWPOISON
|
||||
#define TARGET_EHWPOISON 139
|
||||
|
||||
// For sys_osf_getsysinfo
|
||||
#define TARGET_GSI_UACPROC 8
|
||||
|
@ -1215,6 +1215,30 @@ static inline void init_thread(struct target_pt_regs *regs,
|
||||
|
||||
#endif /* TARGET_TILEGX */
|
||||
|
||||
#ifdef TARGET_HPPA
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_PARISC
|
||||
#define ELF_PLATFORM "PARISC"
|
||||
#define STACK_GROWS_DOWN 0
|
||||
#define STACK_ALIGNMENT 64
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs,
|
||||
struct image_info *infop)
|
||||
{
|
||||
regs->iaoq[0] = infop->entry;
|
||||
regs->iaoq[1] = infop->entry + 4;
|
||||
regs->gr[23] = 0;
|
||||
regs->gr[24] = infop->arg_start;
|
||||
regs->gr[25] = (infop->arg_end - infop->arg_start) / sizeof(abi_ulong);
|
||||
/* The top-of-stack contains a linkage buffer. */
|
||||
regs->gr[30] = infop->start_stack + 64;
|
||||
regs->gr[31] = infop->entry;
|
||||
}
|
||||
|
||||
#endif /* TARGET_HPPA */
|
||||
|
||||
#ifndef ELF_PLATFORM
|
||||
#define ELF_PLATFORM (NULL)
|
||||
#endif
|
||||
@ -1231,6 +1255,14 @@ static inline void init_thread(struct target_pt_regs *regs,
|
||||
#define ELF_HWCAP 0
|
||||
#endif
|
||||
|
||||
#ifndef STACK_GROWS_DOWN
|
||||
#define STACK_GROWS_DOWN 1
|
||||
#endif
|
||||
|
||||
#ifndef STACK_ALIGNMENT
|
||||
#define STACK_ALIGNMENT 16
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
#undef ELF_CLASS
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
@ -1374,45 +1406,78 @@ static abi_ulong copy_elf_strings(int argc, char **argv, char *scratch,
|
||||
abi_ulong p, abi_ulong stack_limit)
|
||||
{
|
||||
char *tmp;
|
||||
int len, offset;
|
||||
int len, i;
|
||||
abi_ulong top = p;
|
||||
|
||||
if (!p) {
|
||||
return 0; /* bullet-proofing */
|
||||
}
|
||||
|
||||
offset = ((p - 1) % TARGET_PAGE_SIZE) + 1;
|
||||
if (STACK_GROWS_DOWN) {
|
||||
int offset = ((p - 1) % TARGET_PAGE_SIZE) + 1;
|
||||
for (i = argc - 1; i >= 0; --i) {
|
||||
tmp = argv[i];
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "VFS: argc is wrong");
|
||||
exit(-1);
|
||||
}
|
||||
len = strlen(tmp) + 1;
|
||||
tmp += len;
|
||||
|
||||
while (argc-- > 0) {
|
||||
tmp = argv[argc];
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "VFS: argc is wrong");
|
||||
exit(-1);
|
||||
}
|
||||
len = strlen(tmp) + 1;
|
||||
tmp += len;
|
||||
if (len > (p - stack_limit)) {
|
||||
return 0;
|
||||
}
|
||||
while (len) {
|
||||
int bytes_to_copy = (len > offset) ? offset : len;
|
||||
tmp -= bytes_to_copy;
|
||||
p -= bytes_to_copy;
|
||||
offset -= bytes_to_copy;
|
||||
len -= bytes_to_copy;
|
||||
|
||||
if (len > (p - stack_limit)) {
|
||||
return 0;
|
||||
}
|
||||
while (len) {
|
||||
int bytes_to_copy = (len > offset) ? offset : len;
|
||||
tmp -= bytes_to_copy;
|
||||
p -= bytes_to_copy;
|
||||
offset -= bytes_to_copy;
|
||||
len -= bytes_to_copy;
|
||||
memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);
|
||||
|
||||
memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);
|
||||
|
||||
if (offset == 0) {
|
||||
memcpy_to_target(p, scratch, top - p);
|
||||
top = p;
|
||||
offset = TARGET_PAGE_SIZE;
|
||||
if (offset == 0) {
|
||||
memcpy_to_target(p, scratch, top - p);
|
||||
top = p;
|
||||
offset = TARGET_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (offset) {
|
||||
memcpy_to_target(p, scratch + offset, top - p);
|
||||
if (p != top) {
|
||||
memcpy_to_target(p, scratch + offset, top - p);
|
||||
}
|
||||
} else {
|
||||
int remaining = TARGET_PAGE_SIZE - (p % TARGET_PAGE_SIZE);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
tmp = argv[i];
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "VFS: argc is wrong");
|
||||
exit(-1);
|
||||
}
|
||||
len = strlen(tmp) + 1;
|
||||
if (len > (stack_limit - p)) {
|
||||
return 0;
|
||||
}
|
||||
while (len) {
|
||||
int bytes_to_copy = (len > remaining) ? remaining : len;
|
||||
|
||||
memcpy_fromfs(scratch + (p - top), tmp, bytes_to_copy);
|
||||
|
||||
tmp += bytes_to_copy;
|
||||
remaining -= bytes_to_copy;
|
||||
p += bytes_to_copy;
|
||||
len -= bytes_to_copy;
|
||||
|
||||
if (remaining == 0) {
|
||||
memcpy_to_target(top, scratch, p - top);
|
||||
top = p;
|
||||
remaining = TARGET_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p != top) {
|
||||
memcpy_to_target(top, scratch, p - top);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
@ -1447,11 +1512,15 @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
|
||||
}
|
||||
|
||||
/* We reserve one extra page at the top of the stack as guard. */
|
||||
target_mprotect(error, guard, PROT_NONE);
|
||||
|
||||
info->stack_limit = error + guard;
|
||||
|
||||
return info->stack_limit + size - sizeof(void *);
|
||||
if (STACK_GROWS_DOWN) {
|
||||
target_mprotect(error, guard, PROT_NONE);
|
||||
info->stack_limit = error + guard;
|
||||
return info->stack_limit + size - sizeof(void *);
|
||||
} else {
|
||||
target_mprotect(error + size, guard, PROT_NONE);
|
||||
info->stack_limit = error + size;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map and zero the bss. We need to explicitly zero any fractional pages
|
||||
@ -1529,7 +1598,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
struct image_info *interp_info)
|
||||
{
|
||||
abi_ulong sp;
|
||||
abi_ulong sp_auxv;
|
||||
abi_ulong u_argc, u_argv, u_envp, u_auxv;
|
||||
int size;
|
||||
int i;
|
||||
abi_ulong u_rand_bytes;
|
||||
@ -1558,10 +1627,25 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
k_platform = ELF_PLATFORM;
|
||||
if (k_platform) {
|
||||
size_t len = strlen(k_platform) + 1;
|
||||
sp -= (len + n - 1) & ~(n - 1);
|
||||
u_platform = sp;
|
||||
/* FIXME - check return value of memcpy_to_target() for failure */
|
||||
memcpy_to_target(sp, k_platform, len);
|
||||
if (STACK_GROWS_DOWN) {
|
||||
sp -= (len + n - 1) & ~(n - 1);
|
||||
u_platform = sp;
|
||||
/* FIXME - check return value of memcpy_to_target() for failure */
|
||||
memcpy_to_target(sp, k_platform, len);
|
||||
} else {
|
||||
memcpy_to_target(sp, k_platform, len);
|
||||
u_platform = sp;
|
||||
sp += len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Provide 16 byte alignment for the PRNG, and basic alignment for
|
||||
* the argv and envp pointers.
|
||||
*/
|
||||
if (STACK_GROWS_DOWN) {
|
||||
sp = QEMU_ALIGN_DOWN(sp, 16);
|
||||
} else {
|
||||
sp = QEMU_ALIGN_UP(sp, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1571,15 +1655,17 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
for (i = 0; i < 16; i++) {
|
||||
k_rand_bytes[i] = rand();
|
||||
}
|
||||
sp -= 16;
|
||||
u_rand_bytes = sp;
|
||||
/* FIXME - check return value of memcpy_to_target() for failure */
|
||||
memcpy_to_target(sp, k_rand_bytes, 16);
|
||||
if (STACK_GROWS_DOWN) {
|
||||
sp -= 16;
|
||||
u_rand_bytes = sp;
|
||||
/* FIXME - check return value of memcpy_to_target() for failure */
|
||||
memcpy_to_target(sp, k_rand_bytes, 16);
|
||||
} else {
|
||||
memcpy_to_target(sp, k_rand_bytes, 16);
|
||||
u_rand_bytes = sp;
|
||||
sp += 16;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force 16 byte _final_ alignment here for generality.
|
||||
*/
|
||||
sp = sp &~ (abi_ulong)15;
|
||||
size = (DLINFO_ITEMS + 1) * 2;
|
||||
if (k_platform)
|
||||
size += 2;
|
||||
@ -1592,20 +1678,31 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
size += envc + argc + 2;
|
||||
size += 1; /* argc itself */
|
||||
size *= n;
|
||||
if (size & 15)
|
||||
sp -= 16 - (size & 15);
|
||||
|
||||
/* Allocate space and finalize stack alignment for entry now. */
|
||||
if (STACK_GROWS_DOWN) {
|
||||
u_argc = QEMU_ALIGN_DOWN(sp - size, STACK_ALIGNMENT);
|
||||
sp = u_argc;
|
||||
} else {
|
||||
u_argc = sp;
|
||||
sp = QEMU_ALIGN_UP(sp + size, STACK_ALIGNMENT);
|
||||
}
|
||||
|
||||
u_argv = u_argc + n;
|
||||
u_envp = u_argv + (argc + 1) * n;
|
||||
u_auxv = u_envp + (envc + 1) * n;
|
||||
info->saved_auxv = u_auxv;
|
||||
info->arg_start = u_argv;
|
||||
info->arg_end = u_argv + argc * n;
|
||||
|
||||
/* This is correct because Linux defines
|
||||
* elf_addr_t as Elf32_Off / Elf64_Off
|
||||
*/
|
||||
#define NEW_AUX_ENT(id, val) do { \
|
||||
sp -= n; put_user_ual(val, sp); \
|
||||
sp -= n; put_user_ual(id, sp); \
|
||||
put_user_ual(id, u_auxv); u_auxv += n; \
|
||||
put_user_ual(val, u_auxv); u_auxv += n; \
|
||||
} while(0)
|
||||
|
||||
sp_auxv = sp;
|
||||
NEW_AUX_ENT (AT_NULL, 0);
|
||||
|
||||
/* There must be exactly DLINFO_ITEMS entries here. */
|
||||
NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff));
|
||||
NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
|
||||
@ -1626,8 +1723,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
|
||||
#endif
|
||||
|
||||
if (k_platform)
|
||||
if (u_platform) {
|
||||
NEW_AUX_ENT(AT_PLATFORM, u_platform);
|
||||
}
|
||||
#ifdef ARCH_DLINFO
|
||||
/*
|
||||
* ARCH_DLINFO must come last so platform specific code can enforce
|
||||
@ -1635,14 +1733,29 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
*/
|
||||
ARCH_DLINFO;
|
||||
#endif
|
||||
NEW_AUX_ENT (AT_NULL, 0);
|
||||
#undef NEW_AUX_ENT
|
||||
|
||||
info->saved_auxv = sp;
|
||||
info->auxv_len = sp_auxv - sp;
|
||||
info->auxv_len = u_argv - info->saved_auxv;
|
||||
|
||||
put_user_ual(argc, u_argc);
|
||||
|
||||
p = info->arg_strings;
|
||||
for (i = 0; i < argc; ++i) {
|
||||
put_user_ual(p, u_argv);
|
||||
u_argv += n;
|
||||
p += target_strlen(p) + 1;
|
||||
}
|
||||
put_user_ual(0, u_argv);
|
||||
|
||||
p = info->env_strings;
|
||||
for (i = 0; i < envc; ++i) {
|
||||
put_user_ual(p, u_envp);
|
||||
u_envp += n;
|
||||
p += target_strlen(p) + 1;
|
||||
}
|
||||
put_user_ual(0, u_envp);
|
||||
|
||||
sp = loader_build_argptr(envc, argc, sp, p, 0);
|
||||
/* Check the right amount of stack was allocated for auxvec, envp & argv. */
|
||||
assert(sp_auxv - sp == size);
|
||||
return sp;
|
||||
}
|
||||
|
||||
@ -2213,12 +2326,28 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
|
||||
bprm->p = setup_arg_pages(bprm, info);
|
||||
|
||||
scratch = g_new0(char, TARGET_PAGE_SIZE);
|
||||
bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
if (STACK_GROWS_DOWN) {
|
||||
bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
info->file_string = bprm->p;
|
||||
bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
info->env_strings = bprm->p;
|
||||
bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
info->arg_strings = bprm->p;
|
||||
} else {
|
||||
info->arg_strings = bprm->p;
|
||||
bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
info->env_strings = bprm->p;
|
||||
bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
info->file_string = bprm->p;
|
||||
bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
|
||||
bprm->p, info->stack_limit);
|
||||
}
|
||||
|
||||
g_free(scratch);
|
||||
|
||||
if (!bprm->p) {
|
||||
|
@ -140,6 +140,9 @@
|
||||
#define TARGET_EOWNERDEAD 130 /* Owner died */
|
||||
#define TARGET_ENOTRECOVERABLE 131 /* State not recoverable */
|
||||
|
||||
#define TARGET_ERFKILL 132 /* Operation not possible due to RF-kill */
|
||||
#define TARGET_EHWPOISON 133 /* Memory page has hardware error */
|
||||
|
||||
/* QEMU internal, not visible to the guest. This is returned when a
|
||||
* system call should be restarted, to tell the main loop that it
|
||||
* should wind the guest PC backwards so it will re-execute the syscall
|
||||
|
97
linux-user/hppa/sockbits.h
Normal file
97
linux-user/hppa/sockbits.h
Normal file
@ -0,0 +1,97 @@
|
||||
#define TARGET_SOL_SOCKET 0xffff
|
||||
|
||||
#define TARGET_SO_DEBUG 0x0001
|
||||
#define TARGET_SO_REUSEADDR 0x0004
|
||||
#define TARGET_SO_KEEPALIVE 0x0008
|
||||
#define TARGET_SO_DONTROUTE 0x0010
|
||||
#define TARGET_SO_BROADCAST 0x0020
|
||||
#define TARGET_SO_LINGER 0x0080
|
||||
#define TARGET_SO_OOBINLINE 0x0100
|
||||
#define TARGET_SO_REUSEPORT 0x0200
|
||||
#define TARGET_SO_SNDBUF 0x1001
|
||||
#define TARGET_SO_RCVBUF 0x1002
|
||||
#define TARGET_SO_SNDBUFFORCE 0x100a
|
||||
#define TARGET_SO_RCVBUFFORCE 0x100b
|
||||
#define TARGET_SO_SNDLOWAT 0x1003
|
||||
#define TARGET_SO_RCVLOWAT 0x1004
|
||||
#define TARGET_SO_SNDTIMEO 0x1005
|
||||
#define TARGET_SO_RCVTIMEO 0x1006
|
||||
#define TARGET_SO_ERROR 0x1007
|
||||
#define TARGET_SO_TYPE 0x1008
|
||||
#define TARGET_SO_PROTOCOL 0x1028
|
||||
#define TARGET_SO_DOMAIN 0x1029
|
||||
#define TARGET_SO_PEERNAME 0x2000
|
||||
#define TARGET_SO_NO_CHECK 0x400b
|
||||
#define TARGET_SO_PRIORITY 0x400c
|
||||
#define TARGET_SO_BSDCOMPAT 0x400e
|
||||
#define TARGET_SO_PASSCRED 0x4010
|
||||
#define TARGET_SO_PEERCRED 0x4011
|
||||
#define TARGET_SO_TIMESTAMP 0x4012
|
||||
#define TARGET_SCM_TIMESTAMP TARGET_SO_TIMESTAMP
|
||||
#define TARGET_SO_TIMESTAMPNS 0x4013
|
||||
#define TARGET_SCM_TIMESTAMPNS TARGET_SO_TIMESTAMPNS
|
||||
|
||||
#define TARGET_SO_SECURITY_AUTHENTICATION 0x4016
|
||||
#define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 0x4017
|
||||
#define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 0x4018
|
||||
|
||||
#define TARGET_SO_BINDTODEVICE 0x4019
|
||||
#define TARGET_SO_ATTACH_FILTER 0x401a
|
||||
#define TARGET_SO_DETACH_FILTER 0x401b
|
||||
#define TARGET_SO_GET_FILTER TARGET_SO_ATTACH_FILTER
|
||||
#define TARGET_SO_ACCEPTCONN 0x401c
|
||||
#define TARGET_SO_PEERSEC 0x401d
|
||||
#define TARGET_SO_PASSSEC 0x401e
|
||||
#define TARGET_SO_MARK 0x401f
|
||||
#define TARGET_SO_TIMESTAMPING 0x4020
|
||||
#define TARGET_SCM_TIMESTAMPING TARGET_SO_TIMESTAMPING
|
||||
#define TARGET_SO_RXQ_OVFL 0x4021
|
||||
#define TARGET_SO_WIFI_STATUS 0x4022
|
||||
#define TARGET_SCM_WIFI_STATUS TARGET_SO_WIFI_STATUS
|
||||
#define TARGET_SO_PEEK_OFF 0x4023
|
||||
#define TARGET_SO_NOFCS 0x4024
|
||||
#define TARGET_SO_LOCK_FILTER 0x4025
|
||||
#define TARGET_SO_SELECT_ERR_QUEUE 0x4026
|
||||
#define TARGET_SO_BUSY_POLL 0x4027
|
||||
#define TARGET_SO_MAX_PACING_RATE 0x4028
|
||||
#define TARGET_SO_BPF_EXTENSIONS 0x4029
|
||||
#define TARGET_SO_INCOMING_CPU 0x402A
|
||||
#define TARGET_SO_ATTACH_BPF 0x402B
|
||||
#define TARGET_SO_DETACH_BPF TARGET_SO_DETACH_FILTER
|
||||
|
||||
#define TARGET_SO_ATTACH_REUSEPORT_CBPF 0x402C
|
||||
#define TARGET_SO_ATTACH_REUSEPORT_EBPF 0x402D
|
||||
|
||||
#define TARGET_SO_CNX_ADVICE 0x402E
|
||||
|
||||
/** sock_type - Socket types - default values
|
||||
*
|
||||
*
|
||||
* @SOCK_STREAM - stream (connection) socket
|
||||
* @SOCK_DGRAM - datagram (conn.less) socket
|
||||
* @SOCK_RAW - raw socket
|
||||
* @SOCK_RDM - reliably-delivered message
|
||||
* @SOCK_SEQPACKET - sequential packet socket
|
||||
* @SOCK_DCCP - Datagram Congestion Control Protocol socket
|
||||
* @SOCK_PACKET - linux specific way of getting packets at the dev level.
|
||||
* For writing rarp and other similar things on the user
|
||||
* level.
|
||||
* @SOCK_CLOEXEC - sets the close-on-exec (FD_CLOEXEC) flag.
|
||||
* @SOCK_NONBLOCK - sets the O_NONBLOCK file status flag.
|
||||
*/
|
||||
enum sock_type {
|
||||
TARGET_SOCK_STREAM = 1,
|
||||
TARGET_SOCK_DGRAM = 2,
|
||||
TARGET_SOCK_RAW = 3,
|
||||
TARGET_SOCK_RDM = 4,
|
||||
TARGET_SOCK_SEQPACKET = 5,
|
||||
TARGET_SOCK_DCCP = 6,
|
||||
TARGET_SOCK_PACKET = 10,
|
||||
TARGET_SOCK_CLOEXEC = 010000000,
|
||||
TARGET_SOCK_NONBLOCK = 0x40000000,
|
||||
};
|
||||
|
||||
#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
|
||||
#define TARGET_SOCK_TYPE_MASK 0xf /* Covers up to TARGET_SOCK_MAX-1. */
|
||||
|
||||
#define ARCH_HAS_SOCKET_TYPES 1
|
353
linux-user/hppa/syscall_nr.h
Normal file
353
linux-user/hppa/syscall_nr.h
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* This file contains the system call numbers.
|
||||
*/
|
||||
|
||||
#define TARGET_NR_restart_syscall 0
|
||||
#define TARGET_NR_exit 1
|
||||
#define TARGET_NR_fork 2
|
||||
#define TARGET_NR_read 3
|
||||
#define TARGET_NR_write 4
|
||||
#define TARGET_NR_open 5
|
||||
#define TARGET_NR_close 6
|
||||
#define TARGET_NR_waitpid 7
|
||||
#define TARGET_NR_creat 8
|
||||
#define TARGET_NR_link 9
|
||||
#define TARGET_NR_unlink 10
|
||||
#define TARGET_NR_execve 11
|
||||
#define TARGET_NR_chdir 12
|
||||
#define TARGET_NR_time 13
|
||||
#define TARGET_NR_mknod 14
|
||||
#define TARGET_NR_chmod 15
|
||||
#define TARGET_NR_lchown 16
|
||||
#define TARGET_NR_socket 17
|
||||
#define TARGET_NR_stat 18
|
||||
#define TARGET_NR_lseek 19
|
||||
#define TARGET_NR_getpid 20
|
||||
#define TARGET_NR_mount 21
|
||||
#define TARGET_NR_bind 22
|
||||
#define TARGET_NR_setuid 23
|
||||
#define TARGET_NR_getuid 24
|
||||
#define TARGET_NR_stime 25
|
||||
#define TARGET_NR_ptrace 26
|
||||
#define TARGET_NR_alarm 27
|
||||
#define TARGET_NR_fstat 28
|
||||
#define TARGET_NR_pause 29
|
||||
#define TARGET_NR_utime 30
|
||||
#define TARGET_NR_connect 31
|
||||
#define TARGET_NR_listen 32
|
||||
#define TARGET_NR_access 33
|
||||
#define TARGET_NR_nice 34
|
||||
#define TARGET_NR_accept 35
|
||||
#define TARGET_NR_sync 36
|
||||
#define TARGET_NR_kill 37
|
||||
#define TARGET_NR_rename 38
|
||||
#define TARGET_NR_mkdir 39
|
||||
#define TARGET_NR_rmdir 40
|
||||
#define TARGET_NR_dup 41
|
||||
#define TARGET_NR_pipe 42
|
||||
#define TARGET_NR_times 43
|
||||
#define TARGET_NR_getsockname 44
|
||||
#define TARGET_NR_brk 45
|
||||
#define TARGET_NR_setgid 46
|
||||
#define TARGET_NR_getgid 47
|
||||
#define TARGET_NR_signal 48
|
||||
#define TARGET_NR_geteuid 49
|
||||
#define TARGET_NR_getegid 50
|
||||
#define TARGET_NR_acct 51
|
||||
#define TARGET_NR_umount2 52
|
||||
#define TARGET_NR_getpeername 53
|
||||
#define TARGET_NR_ioctl 54
|
||||
#define TARGET_NR_fcntl 55
|
||||
#define TARGET_NR_socketpair 56
|
||||
#define TARGET_NR_setpgid 57
|
||||
#define TARGET_NR_send 58
|
||||
#define TARGET_NR_uname 59
|
||||
#define TARGET_NR_umask 60
|
||||
#define TARGET_NR_chroot 61
|
||||
#define TARGET_NR_ustat 62
|
||||
#define TARGET_NR_dup2 63
|
||||
#define TARGET_NR_getppid 64
|
||||
#define TARGET_NR_getpgrp 65
|
||||
#define TARGET_NR_setsid 66
|
||||
#define TARGET_NR_pivot_root 67
|
||||
#define TARGET_NR_sgetmask 68
|
||||
#define TARGET_NR_ssetmask 69
|
||||
#define TARGET_NR_setreuid 70
|
||||
#define TARGET_NR_setregid 71
|
||||
#define TARGET_NR_mincore 72
|
||||
#define TARGET_NR_sigpending 73
|
||||
#define TARGET_NR_sethostname 74
|
||||
#define TARGET_NR_setrlimit 75
|
||||
#define TARGET_NR_getrlimit 76
|
||||
#define TARGET_NR_getrusage 77
|
||||
#define TARGET_NR_gettimeofday 78
|
||||
#define TARGET_NR_settimeofday 79
|
||||
#define TARGET_NR_getgroups 80
|
||||
#define TARGET_NR_setgroups 81
|
||||
#define TARGET_NR_sendto 82
|
||||
#define TARGET_NR_symlink 83
|
||||
#define TARGET_NR_lstat 84
|
||||
#define TARGET_NR_readlink 85
|
||||
#define TARGET_NR_uselib 86
|
||||
#define TARGET_NR_swapon 87
|
||||
#define TARGET_NR_reboot 88
|
||||
#define TARGET_NR_mmap2 89
|
||||
#define TARGET_NR_mmap 90
|
||||
#define TARGET_NR_munmap 91
|
||||
#define TARGET_NR_truncate 92
|
||||
#define TARGET_NR_ftruncate 93
|
||||
#define TARGET_NR_fchmod 94
|
||||
#define TARGET_NR_fchown 95
|
||||
#define TARGET_NR_getpriority 96
|
||||
#define TARGET_NR_setpriority 97
|
||||
#define TARGET_NR_recv 98
|
||||
#define TARGET_NR_statfs 99
|
||||
#define TARGET_NR_fstatfs 100
|
||||
#define TARGET_NR_stat64 101
|
||||
#define TARGET_NR_socketcall 102
|
||||
#define TARGET_NR_syslog 103
|
||||
#define TARGET_NR_setitimer 104
|
||||
#define TARGET_NR_getitimer 105
|
||||
#define TARGET_NR_capget 106
|
||||
#define TARGET_NR_capset 107
|
||||
#define TARGET_NR_pread64 108
|
||||
#define TARGET_NR_pwrite64 109
|
||||
#define TARGET_NR_getcwd 110
|
||||
#define TARGET_NR_vhangup 111
|
||||
#define TARGET_NR_fstat64 112
|
||||
#define TARGET_NR_vfork 113
|
||||
#define TARGET_NR_wait4 114
|
||||
#define TARGET_NR_swapoff 115
|
||||
#define TARGET_NR_sysinfo 116
|
||||
#define TARGET_NR_shutdown 117
|
||||
#define TARGET_NR_fsync 118
|
||||
#define TARGET_NR_madvise 119
|
||||
#define TARGET_NR_clone 120
|
||||
#define TARGET_NR_setdomainname 121
|
||||
#define TARGET_NR_sendfile 122
|
||||
#define TARGET_NR_recvfrom 123
|
||||
#define TARGET_NR_adjtimex 124
|
||||
#define TARGET_NR_mprotect 125
|
||||
#define TARGET_NR_sigprocmask 126
|
||||
#define TARGET_NR_create_module 127
|
||||
#define TARGET_NR_init_module 128
|
||||
#define TARGET_NR_delete_module 129
|
||||
#define TARGET_NR_get_kernel_syms 130
|
||||
#define TARGET_NR_quotactl 131
|
||||
#define TARGET_NR_getpgid 132
|
||||
#define TARGET_NR_fchdir 133
|
||||
#define TARGET_NR_bdflush 134
|
||||
#define TARGET_NR_sysfs 135
|
||||
#define TARGET_NR_personality 136
|
||||
#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */
|
||||
#define TARGET_NR_setfsuid 138
|
||||
#define TARGET_NR_setfsgid 139
|
||||
#define TARGET_NR__llseek 140
|
||||
#define TARGET_NR_getdents 141
|
||||
#define TARGET_NR__newselect 142
|
||||
#define TARGET_NR_flock 143
|
||||
#define TARGET_NR_msync 144
|
||||
#define TARGET_NR_readv 145
|
||||
#define TARGET_NR_writev 146
|
||||
#define TARGET_NR_getsid 147
|
||||
#define TARGET_NR_fdatasync 148
|
||||
#define TARGET_NR__sysctl 149
|
||||
#define TARGET_NR_mlock 150
|
||||
#define TARGET_NR_munlock 151
|
||||
#define TARGET_NR_mlockall 152
|
||||
#define TARGET_NR_munlockall 153
|
||||
#define TARGET_NR_sched_setparam 154
|
||||
#define TARGET_NR_sched_getparam 155
|
||||
#define TARGET_NR_sched_setscheduler 156
|
||||
#define TARGET_NR_sched_getscheduler 157
|
||||
#define TARGET_NR_sched_yield 158
|
||||
#define TARGET_NR_sched_get_priority_max 159
|
||||
#define TARGET_NR_sched_get_priority_min 160
|
||||
#define TARGET_NR_sched_rr_get_interval 161
|
||||
#define TARGET_NR_nanosleep 162
|
||||
#define TARGET_NR_mremap 163
|
||||
#define TARGET_NR_setresuid 164
|
||||
#define TARGET_NR_getresuid 165
|
||||
#define TARGET_NR_sigaltstack 166
|
||||
#define TARGET_NR_query_module 167
|
||||
#define TARGET_NR_poll 168
|
||||
#define TARGET_NR_nfsservctl 169
|
||||
#define TARGET_NR_setresgid 170
|
||||
#define TARGET_NR_getresgid 171
|
||||
#define TARGET_NR_prctl 172
|
||||
#define TARGET_NR_rt_sigreturn 173
|
||||
#define TARGET_NR_rt_sigaction 174
|
||||
#define TARGET_NR_rt_sigprocmask 175
|
||||
#define TARGET_NR_rt_sigpending 176
|
||||
#define TARGET_NR_rt_sigtimedwait 177
|
||||
#define TARGET_NR_rt_sigqueueinfo 178
|
||||
#define TARGET_NR_rt_sigsuspend 179
|
||||
#define TARGET_NR_chown 180
|
||||
#define TARGET_NR_setsockopt 181
|
||||
#define TARGET_NR_getsockopt 182
|
||||
#define TARGET_NR_sendmsg 183
|
||||
#define TARGET_NR_recvmsg 184
|
||||
#define TARGET_NR_semop 185
|
||||
#define TARGET_NR_semget 186
|
||||
#define TARGET_NR_semctl 187
|
||||
#define TARGET_NR_msgsnd 188
|
||||
#define TARGET_NR_msgrcv 189
|
||||
#define TARGET_NR_msgget 190
|
||||
#define TARGET_NR_msgctl 191
|
||||
#define TARGET_NR_shmat 192
|
||||
#define TARGET_NR_shmdt 193
|
||||
#define TARGET_NR_shmget 194
|
||||
#define TARGET_NR_shmctl 195
|
||||
#define TARGET_NR_getpmsg 196
|
||||
#define TARGET_NR_putpmsg 197
|
||||
#define TARGET_NR_lstat64 198
|
||||
#define TARGET_NR_truncate64 199
|
||||
#define TARGET_NR_ftruncate64 200
|
||||
#define TARGET_NR_getdents64 201
|
||||
#define TARGET_NR_fcntl64 202
|
||||
#define TARGET_NR_attrctl 203
|
||||
#define TARGET_NR_acl_get 204
|
||||
#define TARGET_NR_acl_set 205
|
||||
#define TARGET_NR_gettid 206
|
||||
#define TARGET_NR_readahead 207
|
||||
#define TARGET_NR_tkill 208
|
||||
#define TARGET_NR_sendfile64 209
|
||||
#define TARGET_NR_futex 210
|
||||
#define TARGET_NR_sched_setaffinity 211
|
||||
#define TARGET_NR_sched_getaffinity 212
|
||||
#define TARGET_NR_set_thread_area 213
|
||||
#define TARGET_NR_get_thread_area 214
|
||||
#define TARGET_NR_io_setup 215
|
||||
#define TARGET_NR_io_destroy 216
|
||||
#define TARGET_NR_io_getevents 217
|
||||
#define TARGET_NR_io_submit 218
|
||||
#define TARGET_NR_io_cancel 219
|
||||
#define TARGET_NR_alloc_hugepages 220
|
||||
#define TARGET_NR_free_hugepages 221
|
||||
#define TARGET_NR_exit_group 222
|
||||
#define TARGET_NR_lookup_dcookie 223
|
||||
#define TARGET_NR_epoll_create 224
|
||||
#define TARGET_NR_epoll_ctl 225
|
||||
#define TARGET_NR_epill_wait 226
|
||||
#define TARGET_NR_remap_file_pages 227
|
||||
#define TARGET_NR_semtimedop 228
|
||||
#define TARGET_NR_mq_open 229
|
||||
#define TARGET_NR_mq_unlink 230
|
||||
#define TARGET_NR_mq_timedsend 231
|
||||
#define TARGET_NR_mq_timedreceive 232
|
||||
#define TARGET_NR_mq_notify 233
|
||||
#define TARGET_NR_mq_getsetattr 234
|
||||
#define TARGET_NR_waitid 235
|
||||
#define TARGET_NR_fadvise64_64 236
|
||||
#define TARGET_NR_set_tid_address 237
|
||||
#define TARGET_NR_setxattr 238
|
||||
#define TARGET_NR_lsetxattr 239
|
||||
#define TARGET_NR_fsetxattr 240
|
||||
#define TARGET_NR_getxattr 241
|
||||
#define TARGET_NR_lgetxattr 242
|
||||
#define TARGET_NR_fgetxattr 243
|
||||
#define TARGET_NR_listxattr 244
|
||||
#define TARGET_NR_llistxattr 245
|
||||
#define TARGET_NR_flistxattr 246
|
||||
#define TARGET_NR_removexattr 247
|
||||
#define TARGET_NR_lremovexattr 248
|
||||
#define TARGET_NR_fremovexattr 249
|
||||
#define TARGET_NR_timer_create 250
|
||||
#define TARGET_NR_timer_settime 251
|
||||
#define TARGET_NR_timer_gettime 252
|
||||
#define TARGET_NR_timer_getoverrun 253
|
||||
#define TARGET_NR_timer_delete 254
|
||||
#define TARGET_NR_clock_settime 255
|
||||
#define TARGET_NR_clock_gettime 256
|
||||
#define TARGET_NR_clock_getres 257
|
||||
#define TARGET_NR_clock_nanosleep 258
|
||||
#define TARGET_NR_tgkill 259
|
||||
#define TARGET_NR_mbind 260
|
||||
#define TARGET_NR_get_mempolicy 261
|
||||
#define TARGET_NR_set_mempolicy 262
|
||||
#define TARGET_NR_vserver 263
|
||||
#define TARGET_NR_add_key 264
|
||||
#define TARGET_NR_request_key 265
|
||||
#define TARGET_NR_keyctl 266
|
||||
#define TARGET_NR_ioprio_set 267
|
||||
#define TARGET_NR_ioprio_get 268
|
||||
#define TARGET_NR_inotify_init 269
|
||||
#define TARGET_NR_inotify_add_watch 270
|
||||
#define TARGET_NR_inotify_rm_watch 271
|
||||
#define TARGET_NR_migrate_pages 272
|
||||
#define TARGET_NR_pselect6 273
|
||||
#define TARGET_NR_ppoll 274
|
||||
#define TARGET_NR_openat 275
|
||||
#define TARGET_NR_mkdirat 276
|
||||
#define TARGET_NR_mknotat 277
|
||||
#define TARGET_NR_fchownat 278
|
||||
#define TARGET_NR_futimesat 279
|
||||
#define TARGET_NR_fstatat64 280
|
||||
#define TARGET_NR_unlinkat 281
|
||||
#define TARGET_NR_renameat 282
|
||||
#define TARGET_NR_linkat 283
|
||||
#define TARGET_NR_symlinkat 284
|
||||
#define TARGET_NR_readlinkat 285
|
||||
#define TARGET_NR_fchmodat 286
|
||||
#define TARGET_NR_faccessat 287
|
||||
#define TARGET_NR_unshare 288
|
||||
#define TARGET_NR_set_robust_list 289
|
||||
#define TARGET_NR_get_robust_list 290
|
||||
#define TARGET_NR_splice 291
|
||||
#define TARGET_NR_sync_file_range 292
|
||||
#define TARGET_NR_tee 293
|
||||
#define TARGET_NR_vmsplice 294
|
||||
#define TARGET_NR_move_pages 295
|
||||
#define TARGET_NR_getcpu 296
|
||||
#define TARGET_NR_epoll_pwait 297
|
||||
#define TARGET_NR_statfs64 298
|
||||
#define TARGET_NR_fstatfs64 299
|
||||
#define TARGET_NR_kexec_load 300
|
||||
#define TARGET_NR_utimensat 301
|
||||
#define TARGET_NR_signalfd 302
|
||||
#define TARGET_NR_timerfd 303
|
||||
#define TARGET_NR_eventfd 304
|
||||
#define TARGET_NR_fallocate 305
|
||||
#define TARGET_NR_timerfd_create 306
|
||||
#define TARGET_NR_timerfd_settime 307
|
||||
#define TARGET_NR_timerfd_gettime 308
|
||||
#define TARGET_NR_signalfd4 309
|
||||
#define TARGET_NR_eventfd2 310
|
||||
#define TARGET_NR_epoll_create1 311
|
||||
#define TARGET_NR_dup3 312
|
||||
#define TARGET_NR_pipe2 313
|
||||
#define TARGET_NR_inotify_init1 314
|
||||
#define TARGET_NR_preadv 315
|
||||
#define TARGET_NR_pwritev 316
|
||||
#define TARGET_NR_rt_tgsigqueueinfo 317
|
||||
#define TARGET_NR_perf_event_open 318
|
||||
#define TARGET_NR_recvmmsg 319
|
||||
#define TARGET_NR_accept4 320
|
||||
#define TARGET_NR_prlimit64 321
|
||||
#define TARGET_NR_fanotify_init 322
|
||||
#define TARGET_NR_fanotify_mark 323
|
||||
#define TARGET_NR_clock_adjtime 324
|
||||
#define TARGET_NR_name_to_handle_at 325
|
||||
#define TARGET_NR_open_by_handle_at 326
|
||||
#define TARGET_NR_syncfs 327
|
||||
#define TARGET_NR_setns 328
|
||||
#define TARGET_NR_sendmmsg 329
|
||||
#define TARGET_NR_process_vm_readv 330
|
||||
#define TARGET_NR_process_vm_writev 331
|
||||
#define TARGET_NR_kcmp 332
|
||||
#define TARGET_NR_finit_module 333
|
||||
#define TARGET_NR_sched_setattr 334
|
||||
#define TARGET_NR_sched_getattr 335
|
||||
#define TARGET_NR_utimes 336
|
||||
#define TARGET_NR_renameat2 337
|
||||
#define TARGET_NR_seccomp 338
|
||||
#define TARGET_NR_getrandom 339
|
||||
#define TARGET_NR_memfd_create 340
|
||||
#define TARGET_NR_bpf 341
|
||||
#define TARGET_NR_execveat 342
|
||||
#define TARGET_NR_membarrier 343
|
||||
#define TARGET_NR_userfaultfd 344
|
||||
#define TARGET_NR_mlock2 345
|
||||
#define TARGET_NR_copy_file_range 346
|
||||
#define TARGET_NR_preadv2 347
|
||||
#define TARGET_NR_pwritev2 348
|
35
linux-user/hppa/target_cpu.h
Normal file
35
linux-user/hppa/target_cpu.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* HPPA specific CPU ABI and functions for linux-user
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ALPHA_TARGET_CPU_H
|
||||
#define ALPHA_TARGET_CPU_H
|
||||
|
||||
static inline void cpu_clone_regs(CPUHPPAState *env, target_ulong newsp)
|
||||
{
|
||||
if (newsp) {
|
||||
env->gr[30] = newsp;
|
||||
}
|
||||
env->gr[28] = 0;
|
||||
}
|
||||
|
||||
static inline void cpu_set_tls(CPUHPPAState *env, target_ulong newtls)
|
||||
{
|
||||
env->cr27 = newtls;
|
||||
}
|
||||
|
||||
#endif
|
29
linux-user/hppa/target_signal.h
Normal file
29
linux-user/hppa/target_signal.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef HPPA_TARGET_SIGNAL_H
|
||||
#define HPPA_TARGET_SIGNAL_H
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
/* this struct defines a stack used during syscall handling */
|
||||
|
||||
typedef struct target_sigaltstack {
|
||||
abi_ulong ss_sp;
|
||||
int32_t ss_flags;
|
||||
abi_ulong ss_size;
|
||||
} target_stack_t;
|
||||
|
||||
|
||||
/*
|
||||
* sigaltstack controls
|
||||
*/
|
||||
#define TARGET_SS_ONSTACK 1
|
||||
#define TARGET_SS_DISABLE 2
|
||||
|
||||
#define TARGET_MINSIGSTKSZ 2048
|
||||
#define TARGET_SIGSTKSZ 8192
|
||||
|
||||
static inline abi_ulong get_sp_from_cpustate(CPUHPPAState *state)
|
||||
{
|
||||
return state->gr[30];
|
||||
}
|
||||
|
||||
#endif /* HPPA_TARGET_SIGNAL_H */
|
54
linux-user/hppa/target_structs.h
Normal file
54
linux-user/hppa/target_structs.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* HPPA specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef HPPA_TARGET_STRUCTS_H
|
||||
#define HPPA_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad2;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_uint __pad3;
|
||||
uint64_t __unused1;
|
||||
uint64_t __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_uint __pad1;
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
abi_uint __pad2;
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
abi_uint __pad3;
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
abi_uint __pad4;
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
#endif
|
237
linux-user/hppa/target_syscall.h
Normal file
237
linux-user/hppa/target_syscall.h
Normal file
@ -0,0 +1,237 @@
|
||||
#ifndef HPPA_TARGET_SYSCALL_H
|
||||
#define HPPA_TARGET_SYSCALL_H
|
||||
|
||||
struct target_pt_regs {
|
||||
target_ulong gr[32];
|
||||
uint64_t fr[32];
|
||||
target_ulong sr[8];
|
||||
target_ulong iasq[2];
|
||||
target_ulong iaoq[2];
|
||||
target_ulong cr27;
|
||||
target_ulong __pad0;
|
||||
target_ulong orig_r28;
|
||||
target_ulong ksp;
|
||||
target_ulong kpc;
|
||||
target_ulong sar;
|
||||
target_ulong iir;
|
||||
target_ulong isr;
|
||||
target_ulong ior;
|
||||
target_ulong ipsw;
|
||||
};
|
||||
|
||||
#define UNAME_MACHINE "hppa"
|
||||
#define UNAME_MINIMUM_RELEASE "2.6.32"
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
#define TARGET_MINSIGSTKSZ 2048
|
||||
#define TARGET_MLOCKALL_MCL_CURRENT 1
|
||||
#define TARGET_MLOCKALL_MCL_FUTURE 2
|
||||
|
||||
#undef TARGET_ENOMSG
|
||||
#define TARGET_ENOMSG 35
|
||||
#undef TARGET_EIDRM
|
||||
#define TARGET_EIDRM 36
|
||||
#undef TARGET_ECHRNG
|
||||
#define TARGET_ECHRNG 37
|
||||
#undef TARGET_EL2NSYNC
|
||||
#define TARGET_EL2NSYNC 38
|
||||
#undef TARGET_EL3HLT
|
||||
#define TARGET_EL3HLT 39
|
||||
#undef TARGET_EL3RST
|
||||
#define TARGET_EL3RST 40
|
||||
#undef TARGET_ELNRNG
|
||||
#define TARGET_ELNRNG 41
|
||||
#undef TARGET_EUNATCH
|
||||
#define TARGET_EUNATCH 42
|
||||
#undef TARGET_ENOCSI
|
||||
#define TARGET_ENOCSI 43
|
||||
#undef TARGET_EL2HLT
|
||||
#define TARGET_EL2HLT 44
|
||||
#undef TARGET_EDEADLK
|
||||
#define TARGET_EDEADLK 45
|
||||
#undef TARGET_ENOLCK
|
||||
#define TARGET_ENOLCK 46
|
||||
#undef TARGET_EILSEQ
|
||||
#define TARGET_EILSEQ 47
|
||||
|
||||
#undef TARGET_ENONET
|
||||
#define TARGET_ENONET 50
|
||||
#undef TARGET_ENODATA
|
||||
#define TARGET_ENODATA 51
|
||||
#undef TARGET_ETIME
|
||||
#define TARGET_ETIME 52
|
||||
#undef TARGET_ENOSR
|
||||
#define TARGET_ENOSR 53
|
||||
#undef TARGET_ENOSTR
|
||||
#define TARGET_ENOSTR 54
|
||||
#undef TARGET_ENOPKG
|
||||
#define TARGET_ENOPKG 55
|
||||
|
||||
#undef TARGET_ENOLINK
|
||||
#define TARGET_ENOLINK 57
|
||||
#undef TARGET_EADV
|
||||
#define TARGET_EADV 58
|
||||
#undef TARGET_ESRMNT
|
||||
#define TARGET_ESRMNT 59
|
||||
#undef TARGET_ECOMM
|
||||
#define TARGET_ECOMM 60
|
||||
#undef TARGET_EPROTO
|
||||
#define TARGET_EPROTO 61
|
||||
|
||||
#undef TARGET_EMULTIHOP
|
||||
#define TARGET_EMULTIHOP 64
|
||||
|
||||
#undef TARGET_EDOTDOT
|
||||
#define TARGET_EDOTDOT 66
|
||||
#undef TARGET_EBADMSG
|
||||
#define TARGET_EBADMSG 67
|
||||
#undef TARGET_EUSERS
|
||||
#define TARGET_EUSERS 68
|
||||
#undef TARGET_EDQUOT
|
||||
#define TARGET_EDQUOT 69
|
||||
#undef TARGET_ESTALE
|
||||
#define TARGET_ESTALE 70
|
||||
#undef TARGET_EREMOTE
|
||||
#define TARGET_EREMOTE 71
|
||||
#undef TARGET_EOVERFLOW
|
||||
#define TARGET_EOVERFLOW 72
|
||||
|
||||
#undef TARGET_EBADE
|
||||
#define TARGET_EBADE 160
|
||||
#undef TARGET_EBADR
|
||||
#define TARGET_EBADR 161
|
||||
#undef TARGET_EXFULL
|
||||
#define TARGET_EXFULL 162
|
||||
#undef TARGET_ENOANO
|
||||
#define TARGET_ENOANO 163
|
||||
#undef TARGET_EBADRQC
|
||||
#define TARGET_EBADRQC 164
|
||||
#undef TARGET_EBADSLT
|
||||
#define TARGET_EBADSLT 165
|
||||
#undef TARGET_EBFONT
|
||||
#define TARGET_EBFONT 166
|
||||
#undef TARGET_ENOTUNIQ
|
||||
#define TARGET_ENOTUNIQ 167
|
||||
#undef TARGET_EBADFD
|
||||
#define TARGET_EBADFD 168
|
||||
#undef TARGET_EREMCHG
|
||||
#define TARGET_EREMCHG 169
|
||||
#undef TARGET_ELIBACC
|
||||
#define TARGET_ELIBACC 170
|
||||
#undef TARGET_ELIBBAD
|
||||
#define TARGET_ELIBBAD 171
|
||||
#undef TARGET_ELIBSCN
|
||||
#define TARGET_ELIBSCN 172
|
||||
#undef TARGET_ELIBMAX
|
||||
#define TARGET_ELIBMAX 173
|
||||
#undef TARGET_ELIBEXEC
|
||||
#define TARGET_ELIBEXEC 174
|
||||
#undef TARGET_ERESTART
|
||||
#define TARGET_ERESTART 175
|
||||
#undef TARGET_ESTRPIPE
|
||||
#define TARGET_ESTRPIPE 176
|
||||
#undef TARGET_EUCLEAN
|
||||
#define TARGET_EUCLEAN 177
|
||||
#undef TARGET_ENOTNAM
|
||||
#define TARGET_ENOTNAM 178
|
||||
#undef TARGET_ENAVAIL
|
||||
#define TARGET_ENAVAIL 179
|
||||
#undef TARGET_EISNAM
|
||||
#define TARGET_EISNAM 180
|
||||
#undef TARGET_EREMOTEIO
|
||||
#define TARGET_EREMOTEIO 181
|
||||
#undef TARGET_ENOMEDIUM
|
||||
#define TARGET_ENOMEDIUM 182
|
||||
#undef TARGET_EMEDIUMTYPE
|
||||
#define TARGET_EMEDIUMTYPE 183
|
||||
#undef TARGET_ENOKEY
|
||||
#define TARGET_ENOKEY 184
|
||||
#undef TARGET_EKEYEXPIRED
|
||||
#define TARGET_EKEYEXPIRED 185
|
||||
#undef TARGET_EKEYREVOKED
|
||||
#define TARGET_EKEYREVOKED 186
|
||||
#undef TARGET_EKEYREJECTED
|
||||
#define TARGET_EKEYREJECTED 187
|
||||
|
||||
/* Never used in linux. */
|
||||
/* #define TARGET_ENOSYM 215 */
|
||||
#undef TARGET_ENOTSOCK
|
||||
#define TARGET_ENOTSOCK 216
|
||||
#undef TARGET_EDESTADDRREQ
|
||||
#define TARGET_EDESTADDRREQ 217
|
||||
#undef TARGET_EMSGSIZE
|
||||
#define TARGET_EMSGSIZE 218
|
||||
#undef TARGET_EPROTOTYPE
|
||||
#define TARGET_EPROTOTYPE 219
|
||||
#undef TARGET_ENOPROTOOPT
|
||||
#define TARGET_ENOPROTOOPT 220
|
||||
#undef TARGET_EPROTONOSUPPORT
|
||||
#define TARGET_EPROTONOSUPPORT 221
|
||||
#undef TARGET_ESOCKTNOSUPPORT
|
||||
#define TARGET_ESOCKTNOSUPPORT 222
|
||||
#undef TARGET_EOPNOTSUPP
|
||||
#define TARGET_EOPNOTSUPP 223
|
||||
#undef TARGET_EPFNOSUPPORT
|
||||
#define TARGET_EPFNOSUPPORT 224
|
||||
#undef TARGET_EAFNOSUPPORT
|
||||
#define TARGET_EAFNOSUPPORT 225
|
||||
#undef TARGET_EADDRINUSE
|
||||
#define TARGET_EADDRINUSE 226
|
||||
#undef TARGET_EADDRNOTAVAIL
|
||||
#define TARGET_EADDRNOTAVAIL 227
|
||||
#undef TARGET_ENETDOWN
|
||||
#define TARGET_ENETDOWN 228
|
||||
#undef TARGET_ENETUNREACH
|
||||
#define TARGET_ENETUNREACH 229
|
||||
#undef TARGET_ENETRESET
|
||||
#define TARGET_ENETRESET 230
|
||||
#undef TARGET_ECONNABORTED
|
||||
#define TARGET_ECONNABORTED 231
|
||||
#undef TARGET_ECONNRESET
|
||||
#define TARGET_ECONNRESET 232
|
||||
#undef TARGET_ENOBUFS
|
||||
#define TARGET_ENOBUFS 233
|
||||
#undef TARGET_EISCONN
|
||||
#define TARGET_EISCONN 234
|
||||
#undef TARGET_ENOTCONN
|
||||
#define TARGET_ENOTCONN 235
|
||||
#undef TARGET_ESHUTDOWN
|
||||
#define TARGET_ESHUTDOWN 236
|
||||
#undef TARGET_ETOOMANYREFS
|
||||
#define TARGET_ETOOMANYREFS 237
|
||||
#undef TARGET_ETIMEDOUT
|
||||
#define TARGET_ETIMEDOUT 238
|
||||
#undef TARGET_ECONNREFUSED
|
||||
#define TARGET_ECONNREFUSED 239
|
||||
#define TARGET_EREMOTERELEASE 240
|
||||
#undef TARGET_EHOSTDOWN
|
||||
#define TARGET_EHOSTDOWN 241
|
||||
#undef TARGET_EHOSTUNREACH
|
||||
#define TARGET_EHOSTUNREACH 242
|
||||
|
||||
#undef TARGET_EALREADY
|
||||
#define TARGET_EALREADY 244
|
||||
#undef TARGET_EINPROGRESS
|
||||
#define TARGET_EINPROGRESS 245
|
||||
#undef TARGET_ENOTEMPTY
|
||||
#define TARGET_ENOTEMPTY 247
|
||||
#undef TARGET_ENAMETOOLONG
|
||||
#define TARGET_ENAMETOOLONG 248
|
||||
#undef TARGET_ELOOP
|
||||
#define TARGET_ELOOP 249
|
||||
#undef TARGET_ENOSYS
|
||||
#define TARGET_ENOSYS 251
|
||||
|
||||
#undef TARGET_ECANCELED
|
||||
#define TARGET_ECANCELED 253
|
||||
|
||||
#undef TARGET_EOWNERDEAD
|
||||
#define TARGET_EOWNERDEAD 254
|
||||
#undef TARGET_ENOTRECOVERABLE
|
||||
#define TARGET_ENOTRECOVERABLE 255
|
||||
|
||||
#undef TARGET_ERFKILL
|
||||
#define TARGET_ERFKILL 256
|
||||
#undef TARGET_EHWPOISON
|
||||
#define TARGET_EHWPOISON 257
|
||||
|
||||
#endif /* HPPA_TARGET_SYSCALL_H */
|
219
linux-user/hppa/termbits.h
Normal file
219
linux-user/hppa/termbits.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* from asm/termbits.h */
|
||||
|
||||
#define TARGET_NCCS 19
|
||||
|
||||
struct target_termios {
|
||||
unsigned int c_iflag; /* input mode flags */
|
||||
unsigned int c_oflag; /* output mode flags */
|
||||
unsigned int c_cflag; /* control mode flags */
|
||||
unsigned int c_lflag; /* local mode flags */
|
||||
unsigned char c_line; /* line discipline */
|
||||
unsigned char c_cc[TARGET_NCCS]; /* control characters */
|
||||
};
|
||||
|
||||
/* c_iflag bits */
|
||||
#define TARGET_IGNBRK 0000001
|
||||
#define TARGET_BRKINT 0000002
|
||||
#define TARGET_IGNPAR 0000004
|
||||
#define TARGET_PARMRK 0000010
|
||||
#define TARGET_INPCK 0000020
|
||||
#define TARGET_ISTRIP 0000040
|
||||
#define TARGET_INLCR 0000100
|
||||
#define TARGET_IGNCR 0000200
|
||||
#define TARGET_ICRNL 0000400
|
||||
#define TARGET_IUCLC 0001000
|
||||
#define TARGET_IXON 0002000
|
||||
#define TARGET_IXANY 0004000
|
||||
#define TARGET_IXOFF 0010000
|
||||
#define TARGET_IMAXBEL 0040000
|
||||
#define TARGET_IUTF8 0100000
|
||||
|
||||
/* c_oflag bits */
|
||||
#define TARGET_OPOST 0000001
|
||||
#define TARGET_OLCUC 0000002
|
||||
#define TARGET_ONLCR 0000004
|
||||
#define TARGET_OCRNL 0000010
|
||||
#define TARGET_ONOCR 0000020
|
||||
#define TARGET_ONLRET 0000040
|
||||
#define TARGET_OFILL 0000100
|
||||
#define TARGET_OFDEL 0000200
|
||||
#define TARGET_NLDLY 0000400
|
||||
#define TARGET_NL0 0000000
|
||||
#define TARGET_NL1 0000400
|
||||
#define TARGET_CRDLY 0003000
|
||||
#define TARGET_CR0 0000000
|
||||
#define TARGET_CR1 0001000
|
||||
#define TARGET_CR2 0002000
|
||||
#define TARGET_CR3 0003000
|
||||
#define TARGET_TABDLY 0014000
|
||||
#define TARGET_TAB0 0000000
|
||||
#define TARGET_TAB1 0004000
|
||||
#define TARGET_TAB2 0010000
|
||||
#define TARGET_TAB3 0014000
|
||||
#define TARGET_XTABS 0014000
|
||||
#define TARGET_BSDLY 0020000
|
||||
#define TARGET_BS0 0000000
|
||||
#define TARGET_BS1 0020000
|
||||
#define TARGET_VTDLY 0040000
|
||||
#define TARGET_VT0 0000000
|
||||
#define TARGET_VT1 0040000
|
||||
#define TARGET_FFDLY 0100000
|
||||
#define TARGET_FF0 0000000
|
||||
#define TARGET_FF1 0100000
|
||||
|
||||
/* c_cflag bit meaning */
|
||||
#define TARGET_CBAUD 0010017
|
||||
#define TARGET_B0 0000000 /* hang up */
|
||||
#define TARGET_B50 0000001
|
||||
#define TARGET_B75 0000002
|
||||
#define TARGET_B110 0000003
|
||||
#define TARGET_B134 0000004
|
||||
#define TARGET_B150 0000005
|
||||
#define TARGET_B200 0000006
|
||||
#define TARGET_B300 0000007
|
||||
#define TARGET_B600 0000010
|
||||
#define TARGET_B1200 0000011
|
||||
#define TARGET_B1800 0000012
|
||||
#define TARGET_B2400 0000013
|
||||
#define TARGET_B4800 0000014
|
||||
#define TARGET_B9600 0000015
|
||||
#define TARGET_B19200 0000016
|
||||
#define TARGET_B38400 0000017
|
||||
#define TARGET_EXTA B19200
|
||||
#define TARGET_EXTB B38400
|
||||
#define TARGET_CSIZE 0000060
|
||||
#define TARGET_CS5 0000000
|
||||
#define TARGET_CS6 0000020
|
||||
#define TARGET_CS7 0000040
|
||||
#define TARGET_CS8 0000060
|
||||
#define TARGET_CSTOPB 0000100
|
||||
#define TARGET_CREAD 0000200
|
||||
#define TARGET_PARENB 0000400
|
||||
#define TARGET_PARODD 0001000
|
||||
#define TARGET_HUPCL 0002000
|
||||
#define TARGET_CLOCAL 0004000
|
||||
#define TARGET_CBAUDEX 0010000
|
||||
#define TARGET_B57600 0010001
|
||||
#define TARGET_B115200 0010002
|
||||
#define TARGET_B230400 0010003
|
||||
#define TARGET_B460800 0010004
|
||||
#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
|
||||
#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
|
||||
#define TARGET_CRTSCTS 020000000000 /* flow control */
|
||||
|
||||
/* c_lflag bits */
|
||||
#define TARGET_ISIG 0000001
|
||||
#define TARGET_ICANON 0000002
|
||||
#define TARGET_XCASE 0000004
|
||||
#define TARGET_ECHO 0000010
|
||||
#define TARGET_ECHOE 0000020
|
||||
#define TARGET_ECHOK 0000040
|
||||
#define TARGET_ECHONL 0000100
|
||||
#define TARGET_NOFLSH 0000200
|
||||
#define TARGET_TOSTOP 0000400
|
||||
#define TARGET_ECHOCTL 0001000
|
||||
#define TARGET_ECHOPRT 0002000
|
||||
#define TARGET_ECHOKE 0004000
|
||||
#define TARGET_FLUSHO 0010000
|
||||
#define TARGET_PENDIN 0040000
|
||||
#define TARGET_IEXTEN 0100000
|
||||
|
||||
/* c_cc character offsets */
|
||||
#define TARGET_VINTR 0
|
||||
#define TARGET_VQUIT 1
|
||||
#define TARGET_VERASE 2
|
||||
#define TARGET_VKILL 3
|
||||
#define TARGET_VEOF 4
|
||||
#define TARGET_VTIME 5
|
||||
#define TARGET_VMIN 6
|
||||
#define TARGET_VSWTC 7
|
||||
#define TARGET_VSTART 8
|
||||
#define TARGET_VSTOP 9
|
||||
#define TARGET_VSUSP 10
|
||||
#define TARGET_VEOL 11
|
||||
#define TARGET_VREPRINT 12
|
||||
#define TARGET_VDISCARD 13
|
||||
#define TARGET_VWERASE 14
|
||||
#define TARGET_VLNEXT 15
|
||||
#define TARGET_VEOL2 16
|
||||
|
||||
/* ioctls */
|
||||
|
||||
#define TARGET_TCGETS TARGET_IOR('T', 16, struct target_termios)
|
||||
#define TARGET_TCSETS TARGET_IOW('T', 17, struct target_termios)
|
||||
#define TARGET_TCSETSW TARGET_IOW('T', 18, struct target_termios)
|
||||
#define TARGET_TCSETSF TARGET_IOW('T', 19, struct target_termios)
|
||||
#define TARGET_TCGETA TARGET_IOR('T', 1, struct target_termios)
|
||||
#define TARGET_TCSETA TARGET_IOW('T', 2, struct target_termios)
|
||||
#define TARGET_TCSETAW TARGET_IOW('T', 3, struct target_termios)
|
||||
#define TARGET_TCSETAF TARGET_IOW('T', 4, struct target_termios)
|
||||
#define TARGET_TCSBRK TARGET_IO('T', 5)
|
||||
#define TARGET_TCXONC TARGET_IO('T', 6)
|
||||
#define TARGET_TCFLSH TARGET_IO('T', 7)
|
||||
|
||||
#define TARGET_TIOCEXCL 0x540C
|
||||
#define TARGET_TIOCNXCL 0x540D
|
||||
#define TARGET_TIOCSCTTY 0x540E
|
||||
#define TARGET_TIOCGPGRP TARGET_IOR('T', 30, int)
|
||||
#define TARGET_TIOCSPGRP TARGET_IOW('T', 29, int)
|
||||
#define TARGET_TIOCOUTQ 0x5411
|
||||
#define TARGET_TIOCSTI 0x5412
|
||||
#define TARGET_TIOCGWINSZ 0x5413
|
||||
#define TARGET_TIOCSWINSZ 0x5414
|
||||
#define TARGET_TIOCMGET 0x5415
|
||||
#define TARGET_TIOCMBIS 0x5416
|
||||
#define TARGET_TIOCMBIC 0x5417
|
||||
#define TARGET_TIOCMSET 0x5418
|
||||
#define TARGET_TIOCGSOFTCAR 0x5419
|
||||
#define TARGET_TIOCSSOFTCAR 0x541A
|
||||
#define TARGET_FIONREAD 0x541B
|
||||
#define TARGET_TIOCINQ TARGET_FIONREAD
|
||||
#define TARGET_TIOCLINUX 0x541C
|
||||
#define TARGET_TIOCCONS 0x541D
|
||||
#define TARGET_TIOCGSERIAL 0x541E
|
||||
#define TARGET_TIOCSSERIAL 0x541F
|
||||
#define TARGET_TIOCPKT 0x5420
|
||||
#define TARGET_FIONBIO 0x5421
|
||||
#define TARGET_TIOCNOTTY 0x5422
|
||||
#define TARGET_TIOCSETD 0x5423
|
||||
#define TARGET_TIOCGETD 0x5424
|
||||
#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
|
||||
#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */
|
||||
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
|
||||
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
|
||||
#define TARGET_TIOCGSID TARGET_IOR('T', 20, int)
|
||||
#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int)
|
||||
/* Get Pty Number (of pty-mux device) */
|
||||
#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int)
|
||||
/* Lock/unlock Pty */
|
||||
|
||||
#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
||||
#define TARGET_FIOCLEX 0x5451
|
||||
#define TARGET_FIOASYNC 0x5452
|
||||
#define TARGET_TIOCSERCONFIG 0x5453
|
||||
#define TARGET_TIOCSERGWILD 0x5454
|
||||
#define TARGET_TIOCSERSWILD 0x5455
|
||||
#define TARGET_TIOCGLCKTRMIOS 0x5456
|
||||
#define TARGET_TIOCSLCKTRMIOS 0x5457
|
||||
#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
|
||||
#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
|
||||
#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
|
||||
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
|
||||
|
||||
#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial */
|
||||
#define TARGET_TIOCGICOUNT 0x545D
|
||||
#define TARGET_FIOQSIZE 0x5460
|
||||
#define TARGET_TIOCSTART 0x5461
|
||||
#define TARGET_TIOCSTOP 0x5462
|
||||
#define TARGET_TIOCSLTC 0x5462
|
||||
|
||||
/* Used for packet mode */
|
||||
#define TARGET_TIOCPKT_DATA 0
|
||||
#define TARGET_TIOCPKT_FLUSHREAD 1
|
||||
#define TARGET_TIOCPKT_FLUSHWRITE 2
|
||||
#define TARGET_TIOCPKT_STOP 4
|
||||
#define TARGET_TIOCPKT_START 8
|
||||
#define TARGET_TIOCPKT_NOSTOP 16
|
||||
#define TARGET_TIOCPKT_DOSTOP 32
|
||||
|
||||
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
|
@ -164,6 +164,9 @@
|
||||
IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
|
||||
IOCTL(SIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) /* pid_t */
|
||||
IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval)))
|
||||
IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec)))
|
||||
|
||||
IOCTL(CDROMPAUSE, 0, TYPE_NULL)
|
||||
IOCTL(CDROMSTART, 0, TYPE_NULL)
|
||||
@ -422,3 +425,8 @@
|
||||
MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||
IOCTL_SPECIAL(SIOCDELRT, IOC_W, do_ioctl_rt,
|
||||
MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||
|
||||
#ifdef TARGET_TIOCSTART
|
||||
IOCTL_IGNORE(TIOCSTART)
|
||||
IOCTL_IGNORE(TIOCSTOP)
|
||||
#endif
|
||||
|
@ -3512,6 +3512,169 @@ void cpu_loop(CPUTLGState *env)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_HPPA
|
||||
|
||||
static abi_ulong hppa_lws(CPUHPPAState *env)
|
||||
{
|
||||
uint32_t which = env->gr[20];
|
||||
abi_ulong addr = env->gr[26];
|
||||
abi_ulong old = env->gr[25];
|
||||
abi_ulong new = env->gr[24];
|
||||
abi_ulong size, ret;
|
||||
|
||||
switch (which) {
|
||||
default:
|
||||
return -TARGET_ENOSYS;
|
||||
|
||||
case 0: /* elf32 atomic 32bit cmpxchg */
|
||||
if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
old = tswap32(old);
|
||||
new = tswap32(new);
|
||||
ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
|
||||
ret = tswap32(ret);
|
||||
break;
|
||||
|
||||
case 2: /* elf32 atomic "new" cmpxchg */
|
||||
size = env->gr[23];
|
||||
if (size >= 4) {
|
||||
return -TARGET_ENOSYS;
|
||||
}
|
||||
if (((addr | old | new) & ((1 << size) - 1))
|
||||
|| !access_ok(VERIFY_WRITE, addr, 1 << size)
|
||||
|| !access_ok(VERIFY_READ, old, 1 << size)
|
||||
|| !access_ok(VERIFY_READ, new, 1 << size)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
/* Note that below we use host-endian loads so that the cmpxchg
|
||||
can be host-endian as well. */
|
||||
switch (size) {
|
||||
case 0:
|
||||
old = *(uint8_t *)g2h(old);
|
||||
new = *(uint8_t *)g2h(new);
|
||||
ret = atomic_cmpxchg((uint8_t *)g2h(addr), old, new);
|
||||
ret = ret != old;
|
||||
break;
|
||||
case 1:
|
||||
old = *(uint16_t *)g2h(old);
|
||||
new = *(uint16_t *)g2h(new);
|
||||
ret = atomic_cmpxchg((uint16_t *)g2h(addr), old, new);
|
||||
ret = ret != old;
|
||||
break;
|
||||
case 2:
|
||||
old = *(uint32_t *)g2h(old);
|
||||
new = *(uint32_t *)g2h(new);
|
||||
ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
|
||||
ret = ret != old;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
uint64_t o64, n64, r64;
|
||||
o64 = *(uint64_t *)g2h(old);
|
||||
n64 = *(uint64_t *)g2h(new);
|
||||
#ifdef CONFIG_ATOMIC64
|
||||
r64 = atomic_cmpxchg__nocheck((uint64_t *)g2h(addr), o64, n64);
|
||||
ret = r64 != o64;
|
||||
#else
|
||||
start_exclusive();
|
||||
r64 = *(uint64_t *)g2h(addr);
|
||||
ret = 1;
|
||||
if (r64 == o64) {
|
||||
*(uint64_t *)g2h(addr) = n64;
|
||||
ret = 0;
|
||||
}
|
||||
end_exclusive();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
env->gr[28] = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cpu_loop(CPUHPPAState *env)
|
||||
{
|
||||
CPUState *cs = CPU(hppa_env_get_cpu(env));
|
||||
target_siginfo_t info;
|
||||
abi_ulong ret;
|
||||
int trapnr;
|
||||
|
||||
while (1) {
|
||||
cpu_exec_start(cs);
|
||||
trapnr = cpu_exec(cs);
|
||||
cpu_exec_end(cs);
|
||||
process_queued_cpu_work(cs);
|
||||
|
||||
switch (trapnr) {
|
||||
case EXCP_SYSCALL:
|
||||
ret = do_syscall(env, env->gr[20],
|
||||
env->gr[26], env->gr[25],
|
||||
env->gr[24], env->gr[23],
|
||||
env->gr[22], env->gr[21], 0, 0);
|
||||
switch (ret) {
|
||||
default:
|
||||
env->gr[28] = ret;
|
||||
/* We arrived here by faking the gateway page. Return. */
|
||||
env->iaoq_f = env->gr[31];
|
||||
env->iaoq_b = env->gr[31] + 4;
|
||||
break;
|
||||
case -TARGET_ERESTARTSYS:
|
||||
case -TARGET_QEMU_ESIGRETURN:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EXCP_SYSCALL_LWS:
|
||||
env->gr[21] = hppa_lws(env);
|
||||
/* We arrived here by faking the gateway page. Return. */
|
||||
env->iaoq_f = env->gr[31];
|
||||
env->iaoq_b = env->gr[31] + 4;
|
||||
break;
|
||||
case EXCP_SIGSEGV:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_ACCERR;
|
||||
info._sifields._sigfault._addr = env->ior;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_SIGILL:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->iaoq_f;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_SIGFPE:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
info._sifields._sigfault._addr = env->iaoq_f;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (trapnr) {
|
||||
info.si_signo = trapnr;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, trapnr, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
process_pending_signals(env);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TARGET_HPPA */
|
||||
|
||||
THREAD CPUState *thread_cpu;
|
||||
|
||||
bool qemu_cpu_is_self(CPUState *cpu)
|
||||
@ -4179,15 +4342,16 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
|
||||
qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
|
||||
qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
|
||||
info->start_code);
|
||||
qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
|
||||
info->start_data);
|
||||
qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n", info->start_code);
|
||||
qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n", info->start_data);
|
||||
qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
|
||||
qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
|
||||
info->start_stack);
|
||||
qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", info->start_stack);
|
||||
qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
|
||||
qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
|
||||
qemu_log("argv_start 0x" TARGET_ABI_FMT_lx "\n", info->arg_start);
|
||||
qemu_log("env_start 0x" TARGET_ABI_FMT_lx "\n",
|
||||
info->arg_end + (abi_ulong)sizeof(abi_ulong));
|
||||
qemu_log("auxv_start 0x" TARGET_ABI_FMT_lx "\n", info->saved_auxv);
|
||||
}
|
||||
|
||||
target_set_brk(info->brk);
|
||||
@ -4538,6 +4702,15 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
env->pc = regs->pc;
|
||||
}
|
||||
#elif defined(TARGET_HPPA)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 32; i++) {
|
||||
env->gr[i] = regs->gr[i];
|
||||
}
|
||||
env->iaoq_f = regs->iaoq[0];
|
||||
env->iaoq_b = regs->iaoq[1];
|
||||
}
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
@ -221,6 +221,11 @@ struct target_pt_regs {
|
||||
#undef TARGET_ENOTRECOVERABLE
|
||||
#define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
|
||||
|
||||
#undef TARGET_ERFKILL
|
||||
#define TARGET_ERFKILL 167
|
||||
#undef TARGET_EHWPOISON
|
||||
#define TARGET_EHWPOISON 168
|
||||
|
||||
#undef TARGET_EDQUOT
|
||||
#define TARGET_EDQUOT 1133 /* Quota exceeded */
|
||||
|
||||
|
@ -218,6 +218,11 @@ struct target_pt_regs {
|
||||
#undef TARGET_ENOTRECOVERABLE
|
||||
#define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
|
||||
|
||||
#undef TARGET_ERFKILL
|
||||
#define TARGET_ERFKILL 167
|
||||
#undef TARGET_EHWPOISON
|
||||
#define TARGET_EHWPOISON 168
|
||||
|
||||
#undef TARGET_EDQUOT
|
||||
#define TARGET_EDQUOT 1133 /* Quota exceeded */
|
||||
|
||||
|
@ -48,6 +48,9 @@ struct image_info {
|
||||
abi_ulong auxv_len;
|
||||
abi_ulong arg_start;
|
||||
abi_ulong arg_end;
|
||||
abi_ulong arg_strings;
|
||||
abi_ulong env_strings;
|
||||
abi_ulong file_string;
|
||||
uint32_t elf_flags;
|
||||
int personality;
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
|
@ -5888,6 +5888,195 @@ long do_rt_sigreturn(CPUTLGState *env)
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#elif defined(TARGET_HPPA)
|
||||
|
||||
struct target_sigcontext {
|
||||
abi_ulong sc_flags;
|
||||
abi_ulong sc_gr[32];
|
||||
uint64_t sc_fr[32];
|
||||
abi_ulong sc_iasq[2];
|
||||
abi_ulong sc_iaoq[2];
|
||||
abi_ulong sc_sar;
|
||||
};
|
||||
|
||||
struct target_ucontext {
|
||||
abi_uint tuc_flags;
|
||||
abi_ulong tuc_link;
|
||||
target_stack_t tuc_stack;
|
||||
abi_uint pad[1];
|
||||
struct target_sigcontext tuc_mcontext;
|
||||
target_sigset_t tuc_sigmask;
|
||||
};
|
||||
|
||||
struct target_rt_sigframe {
|
||||
abi_uint tramp[9];
|
||||
target_siginfo_t info;
|
||||
struct target_ucontext uc;
|
||||
/* hidden location of upper halves of pa2.0 64-bit gregs */
|
||||
};
|
||||
|
||||
static void setup_sigcontext(struct target_sigcontext *sc, CPUArchState *env)
|
||||
{
|
||||
int flags = 0;
|
||||
int i;
|
||||
|
||||
/* ??? if on_sig_stack, flags |= 1 (PARISC_SC_FLAG_ONSTACK). */
|
||||
|
||||
if (env->iaoq_f < TARGET_PAGE_SIZE) {
|
||||
/* In the gateway page, executing a syscall. */
|
||||
flags |= 2; /* PARISC_SC_FLAG_IN_SYSCALL */
|
||||
__put_user(env->gr[31], &sc->sc_iaoq[0]);
|
||||
__put_user(env->gr[31] + 4, &sc->sc_iaoq[1]);
|
||||
} else {
|
||||
__put_user(env->iaoq_f, &sc->sc_iaoq[0]);
|
||||
__put_user(env->iaoq_b, &sc->sc_iaoq[1]);
|
||||
}
|
||||
__put_user(0, &sc->sc_iasq[0]);
|
||||
__put_user(0, &sc->sc_iasq[1]);
|
||||
__put_user(flags, &sc->sc_flags);
|
||||
|
||||
__put_user(cpu_hppa_get_psw(env), &sc->sc_gr[0]);
|
||||
for (i = 1; i < 32; ++i) {
|
||||
__put_user(env->gr[i], &sc->sc_gr[i]);
|
||||
}
|
||||
|
||||
__put_user((uint64_t)env->fr0_shadow << 32, &sc->sc_fr[0]);
|
||||
for (i = 1; i < 32; ++i) {
|
||||
__put_user(env->fr[i], &sc->sc_fr[i]);
|
||||
}
|
||||
|
||||
__put_user(env->sar, &sc->sc_sar);
|
||||
}
|
||||
|
||||
static void restore_sigcontext(CPUArchState *env, struct target_sigcontext *sc)
|
||||
{
|
||||
target_ulong psw;
|
||||
int i;
|
||||
|
||||
__get_user(psw, &sc->sc_gr[0]);
|
||||
cpu_hppa_put_psw(env, psw);
|
||||
|
||||
for (i = 1; i < 32; ++i) {
|
||||
__get_user(env->gr[i], &sc->sc_gr[i]);
|
||||
}
|
||||
for (i = 0; i < 32; ++i) {
|
||||
__get_user(env->fr[i], &sc->sc_fr[i]);
|
||||
}
|
||||
cpu_hppa_loaded_fr0(env);
|
||||
|
||||
__get_user(env->iaoq_f, &sc->sc_iaoq[0]);
|
||||
__get_user(env->iaoq_b, &sc->sc_iaoq[1]);
|
||||
__get_user(env->sar, &sc->sc_sar);
|
||||
}
|
||||
|
||||
/* No, this doesn't look right, but it's copied straight from the kernel. */
|
||||
#define PARISC_RT_SIGFRAME_SIZE32 \
|
||||
((sizeof(struct target_rt_sigframe) + 48 + 64) & -64)
|
||||
|
||||
static void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
target_siginfo_t *info,
|
||||
target_sigset_t *set, CPUArchState *env)
|
||||
{
|
||||
abi_ulong frame_addr, sp, haddr;
|
||||
struct target_rt_sigframe *frame;
|
||||
int i;
|
||||
|
||||
sp = env->gr[30];
|
||||
if (ka->sa_flags & TARGET_SA_ONSTACK) {
|
||||
if (sas_ss_flags(sp) == 0) {
|
||||
sp = (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
|
||||
}
|
||||
}
|
||||
frame_addr = QEMU_ALIGN_UP(sp, 64);
|
||||
sp = frame_addr + PARISC_RT_SIGFRAME_SIZE32;
|
||||
|
||||
trace_user_setup_rt_frame(env, frame_addr);
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
tswap_siginfo(&frame->info, info);
|
||||
frame->uc.tuc_flags = 0;
|
||||
frame->uc.tuc_link = 0;
|
||||
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
|
||||
}
|
||||
|
||||
setup_sigcontext(&frame->uc.tuc_mcontext, env);
|
||||
|
||||
__put_user(0x34190000, frame->tramp + 0); /* ldi 0,%r25 */
|
||||
__put_user(0x3414015a, frame->tramp + 1); /* ldi __NR_rt_sigreturn,%r20 */
|
||||
__put_user(0xe4008200, frame->tramp + 2); /* be,l 0x100(%sr2,%r0) */
|
||||
__put_user(0x08000240, frame->tramp + 3); /* nop */
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
|
||||
env->gr[2] = h2g(frame->tramp);
|
||||
env->gr[30] = sp;
|
||||
env->gr[26] = sig;
|
||||
env->gr[25] = h2g(&frame->info);
|
||||
env->gr[24] = h2g(&frame->uc);
|
||||
|
||||
haddr = ka->_sa_handler;
|
||||
if (haddr & 2) {
|
||||
/* Function descriptor. */
|
||||
target_ulong *fdesc, dest;
|
||||
|
||||
haddr &= -4;
|
||||
if (!lock_user_struct(VERIFY_READ, fdesc, haddr, 1)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
__get_user(dest, fdesc);
|
||||
__get_user(env->gr[19], fdesc + 1);
|
||||
unlock_user_struct(fdesc, haddr, 1);
|
||||
haddr = dest;
|
||||
}
|
||||
env->iaoq_f = haddr;
|
||||
env->iaoq_b = haddr + 4;;
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUArchState *env)
|
||||
{
|
||||
abi_ulong frame_addr = env->gr[30] - PARISC_RT_SIGFRAME_SIZE32;
|
||||
struct target_rt_sigframe *frame;
|
||||
sigset_t set;
|
||||
|
||||
trace_user_do_rt_sigreturn(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
|
||||
goto badframe;
|
||||
}
|
||||
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
|
||||
set_sigmask(&set);
|
||||
|
||||
restore_sigcontext(env, &frame->uc.tuc_mcontext);
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
|
||||
uc.tuc_stack),
|
||||
0, env->gr[30]) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
@ -5989,7 +6178,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
|
||||
/* prepare the stack frame of the virtual CPU */
|
||||
#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \
|
||||
|| defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) \
|
||||
|| defined(TARGET_PPC64)
|
||||
|| defined(TARGET_PPC64) || defined(TARGET_HPPA)
|
||||
/* These targets do not have traditional signals. */
|
||||
setup_rt_frame(sig, sa, &k->info, &target_old_set, cpu_env);
|
||||
#else
|
||||
|
@ -205,6 +205,8 @@
|
||||
|
||||
#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
|
||||
#define TARGET_SOCK_TYPE_MASK 0xf /* Covers up to TARGET_SOCK_MAX-1. */
|
||||
#elif defined(TARGET_HPPA)
|
||||
#include <hppa/sockbits.h>
|
||||
#else
|
||||
|
||||
#if defined(TARGET_SPARC)
|
||||
|
@ -798,6 +798,12 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
|
||||
#ifdef ENOMSG
|
||||
[ENOMSG] = TARGET_ENOMSG,
|
||||
#endif
|
||||
#ifdef ERKFILL
|
||||
[ERFKILL] = TARGET_ERFKILL,
|
||||
#endif
|
||||
#ifdef EHWPOISON
|
||||
[EHWPOISON] = TARGET_EHWPOISON,
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int host_to_target_errno(int err)
|
||||
@ -5453,6 +5459,8 @@ static IOCTLEntry ioctl_entries[] = {
|
||||
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
|
||||
#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
|
||||
{ TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
|
||||
#define IOCTL_IGNORE(cmd) \
|
||||
{ TARGET_ ## cmd, 0, #cmd },
|
||||
#include "ioctls.h"
|
||||
{ 0, 0, },
|
||||
};
|
||||
@ -5484,6 +5492,10 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
|
||||
#endif
|
||||
if (ie->do_ioctl) {
|
||||
return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
|
||||
} else if (!ie->host_cmd) {
|
||||
/* Some architectures define BSD ioctls in their headers
|
||||
that are not implemented in Linux. */
|
||||
return -TARGET_ENOSYS;
|
||||
}
|
||||
|
||||
switch(arg_type[0]) {
|
||||
|
@ -90,6 +90,15 @@
|
||||
#define TARGET_IOC_READ 2U
|
||||
#define TARGET_IOC_WRITE 4U
|
||||
|
||||
#elif defined(TARGET_HPPA)
|
||||
|
||||
#define TARGET_IOC_SIZEBITS 14
|
||||
#define TARGET_IOC_DIRBITS 2
|
||||
|
||||
#define TARGET_IOC_NONE 0U
|
||||
#define TARGET_IOC_WRITE 2U
|
||||
#define TARGET_IOC_READ 1U
|
||||
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
@ -417,7 +426,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
|| defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
|
||||
|| defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
|
||||
|| defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
|
||||
|| defined(TARGET_TILEGX)
|
||||
|| defined(TARGET_TILEGX) || defined(TARGET_HPPA)
|
||||
|
||||
#if defined(TARGET_SPARC)
|
||||
#define TARGET_SA_NOCLDSTOP 8u
|
||||
@ -587,6 +596,46 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
#define TARGET_SIG_UNBLOCK 2 /* for unblocking signals */
|
||||
#define TARGET_SIG_SETMASK 3 /* for setting the signal mask */
|
||||
|
||||
#elif defined(TARGET_HPPA)
|
||||
|
||||
#define TARGET_SIGHUP 1
|
||||
#define TARGET_SIGINT 2
|
||||
#define TARGET_SIGQUIT 3
|
||||
#define TARGET_SIGILL 4
|
||||
#define TARGET_SIGTRAP 5
|
||||
#define TARGET_SIGABRT 6
|
||||
#define TARGET_SIGIOT 6
|
||||
#define TARGET_SIGSTKFLT 7
|
||||
#define TARGET_SIGFPE 8
|
||||
#define TARGET_SIGKILL 9
|
||||
#define TARGET_SIGBUS 10
|
||||
#define TARGET_SIGSEGV 11
|
||||
#define TARGET_SIGXCPU 12
|
||||
#define TARGET_SIGPIPE 13
|
||||
#define TARGET_SIGALRM 14
|
||||
#define TARGET_SIGTERM 15
|
||||
#define TARGET_SIGUSR1 16
|
||||
#define TARGET_SIGUSR2 17
|
||||
#define TARGET_SIGCHLD 18
|
||||
#define TARGET_SIGPWR 19
|
||||
#define TARGET_SIGVTALRM 20
|
||||
#define TARGET_SIGPROF 21
|
||||
#define TARGET_SIGIO 22
|
||||
#define TARGET_SIGPOLL TARGET_SIGIO
|
||||
#define TARGET_SIGWINCH 23
|
||||
#define TARGET_SIGSTOP 24
|
||||
#define TARGET_SIGTSTP 25
|
||||
#define TARGET_SIGCONT 26
|
||||
#define TARGET_SIGTTIN 27
|
||||
#define TARGET_SIGTTOU 28
|
||||
#define TARGET_SIGURG 29
|
||||
#define TARGET_SIGXFSZ 30
|
||||
#define TARGET_SIGSYS 31
|
||||
|
||||
#define TARGET_SIG_BLOCK 0
|
||||
#define TARGET_SIG_UNBLOCK 1
|
||||
#define TARGET_SIG_SETMASK 2
|
||||
|
||||
#else
|
||||
|
||||
/* OpenRISC Using the general signals */
|
||||
@ -930,9 +979,13 @@ struct target_pollfd {
|
||||
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4)
|
||||
#define TARGET_SIOCATMARK TARGET_IOR('s', 7, int)
|
||||
#define TARGET_SIOCGPGRP TARGET_IOR('s', 9, pid_t)
|
||||
#else
|
||||
#define TARGET_SIOCATMARK 0x8905
|
||||
#define TARGET_SIOCGPGRP 0x8904
|
||||
#endif
|
||||
#define TARGET_SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
|
||||
#define TARGET_SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
|
||||
|
||||
/* Networking ioctls */
|
||||
#define TARGET_SIOCADDRT 0x890B /* add routing table entry */
|
||||
@ -1275,6 +1328,16 @@ struct target_winsize {
|
||||
#define TARGET_MAP_NORESERVE 0x10000 /* no check for reservations */
|
||||
#define TARGET_MAP_POPULATE 0x20000 /* pop (prefault) pagetables */
|
||||
#define TARGET_MAP_NONBLOCK 0x40000 /* do not block on IO */
|
||||
#elif defined(TARGET_HPPA)
|
||||
#define TARGET_MAP_ANONYMOUS 0x10 /* don't use a file */
|
||||
#define TARGET_MAP_FIXED 0x04 /* Interpret addr exactly */
|
||||
#define TARGET_MAP_GROWSDOWN 0x08000 /* stack-like segment */
|
||||
#define TARGET_MAP_DENYWRITE 0x00800 /* ETXTBSY */
|
||||
#define TARGET_MAP_EXECUTABLE 0x01000 /* mark it as an executable */
|
||||
#define TARGET_MAP_LOCKED 0x02000 /* lock the mapping */
|
||||
#define TARGET_MAP_NORESERVE 0x04000 /* no check for reservations */
|
||||
#define TARGET_MAP_POPULATE 0x10000 /* pop (prefault) pagetables */
|
||||
#define TARGET_MAP_NONBLOCK 0x20000 /* do not block on IO */
|
||||
#else
|
||||
#define TARGET_MAP_FIXED 0x10 /* Interpret addr exactly */
|
||||
#define TARGET_MAP_ANONYMOUS 0x20 /* don't use a file */
|
||||
@ -2025,6 +2088,62 @@ struct target_stat64 {
|
||||
unsigned int __unused5;
|
||||
};
|
||||
|
||||
#elif defined(TARGET_HPPA)
|
||||
|
||||
struct target_stat {
|
||||
abi_uint st_dev;
|
||||
abi_uint st_ino;
|
||||
abi_ushort st_mode;
|
||||
abi_ushort st_nlink;
|
||||
abi_ushort _res1;
|
||||
abi_ushort _res2;
|
||||
abi_uint st_rdev;
|
||||
abi_int st_size;
|
||||
abi_int target_st_atime;
|
||||
abi_uint target_st_atime_nsec;
|
||||
abi_int target_st_mtime;
|
||||
abi_uint target_st_mtime_nsec;
|
||||
abi_int target_st_ctime;
|
||||
abi_uint target_st_ctime_nsec;
|
||||
abi_int st_blksize;
|
||||
abi_int st_blocks;
|
||||
abi_uint _unused1;
|
||||
abi_uint _unused2;
|
||||
abi_uint _unused3;
|
||||
abi_uint _unused4;
|
||||
abi_ushort _unused5;
|
||||
abi_short st_fstype;
|
||||
abi_uint st_realdev;
|
||||
abi_ushort st_basemode;
|
||||
abi_ushort _unused6;
|
||||
abi_uint st_uid;
|
||||
abi_uint st_gid;
|
||||
abi_uint _unused7[3];
|
||||
};
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
uint64_t st_dev;
|
||||
abi_uint _pad1;
|
||||
abi_uint _res1;
|
||||
abi_uint st_mode;
|
||||
abi_uint st_nlink;
|
||||
abi_uint st_uid;
|
||||
abi_uint st_gid;
|
||||
uint64_t st_rdev;
|
||||
abi_uint _pad2;
|
||||
int64_t st_size;
|
||||
abi_int st_blksize;
|
||||
int64_t st_blocks;
|
||||
abi_int target_st_atime;
|
||||
abi_uint target_st_atime_nsec;
|
||||
abi_int target_st_mtime;
|
||||
abi_uint target_st_mtime_nsec;
|
||||
abi_int target_st_ctime;
|
||||
abi_uint target_st_ctime_nsec;
|
||||
uint64_t st_ino;
|
||||
};
|
||||
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
@ -2195,6 +2314,12 @@ struct target_statfs64 {
|
||||
#define TARGET_F_SETLKW 7
|
||||
#define TARGET_F_SETOWN 24 /* for sockets. */
|
||||
#define TARGET_F_GETOWN 23 /* for sockets. */
|
||||
#elif defined(TARGET_HPPA)
|
||||
#define TARGET_F_GETLK 5
|
||||
#define TARGET_F_SETLK 6
|
||||
#define TARGET_F_SETLKW 7
|
||||
#define TARGET_F_GETOWN 11 /* for sockets. */
|
||||
#define TARGET_F_SETOWN 12 /* for sockets. */
|
||||
#else
|
||||
#define TARGET_F_GETLK 5
|
||||
#define TARGET_F_SETLK 6
|
||||
@ -2217,13 +2342,22 @@ struct target_statfs64 {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TARGET_HPPA)
|
||||
#define TARGET_F_SETSIG 13 /* for sockets. */
|
||||
#define TARGET_F_GETSIG 14 /* for sockets. */
|
||||
#else
|
||||
#define TARGET_F_SETSIG 10 /* for sockets. */
|
||||
#define TARGET_F_GETSIG 11 /* for sockets. */
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_MIPS)
|
||||
#define TARGET_F_GETLK64 33 /* using 'struct flock64' */
|
||||
#define TARGET_F_SETLK64 34
|
||||
#define TARGET_F_SETLKW64 35
|
||||
#elif defined(TARGET_HPPA)
|
||||
#define TARGET_F_GETLK64 8 /* using 'struct flock64' */
|
||||
#define TARGET_F_SETLK64 9
|
||||
#define TARGET_F_SETLKW64 10
|
||||
#else
|
||||
#define TARGET_F_GETLK64 12 /* using 'struct flock64' */
|
||||
#define TARGET_F_SETLK64 13
|
||||
@ -2254,6 +2388,20 @@ struct target_statfs64 {
|
||||
#define TARGET_O_CLOEXEC 010000000
|
||||
#define TARGET___O_SYNC 020000000
|
||||
#define TARGET_O_PATH 040000000
|
||||
#elif defined(TARGET_HPPA)
|
||||
#define TARGET_O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */
|
||||
#define TARGET_O_APPEND 000000010
|
||||
#define TARGET_O_CREAT 000000400 /* not fcntl */
|
||||
#define TARGET_O_EXCL 000002000 /* not fcntl */
|
||||
#define TARGET_O_NOCTTY 000400000 /* not fcntl */
|
||||
#define TARGET_O_DSYNC 001000000
|
||||
#define TARGET_O_LARGEFILE 000004000
|
||||
#define TARGET_O_DIRECTORY 000010000 /* must be a directory */
|
||||
#define TARGET_O_NOFOLLOW 000000200 /* don't follow links */
|
||||
#define TARGET_O_NOATIME 004000000
|
||||
#define TARGET_O_CLOEXEC 010000000
|
||||
#define TARGET___O_SYNC 000100000
|
||||
#define TARGET_O_PATH 020000000
|
||||
#elif defined(TARGET_ARM) || defined(TARGET_M68K)
|
||||
#define TARGET_O_DIRECTORY 040000 /* must be a directory */
|
||||
#define TARGET_O_NOFOLLOW 0100000 /* don't follow links */
|
||||
@ -2375,8 +2523,8 @@ struct target_flock {
|
||||
struct target_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
#if defined(TARGET_PPC) || defined(TARGET_X86_64) \
|
||||
|| defined(TARGET_MIPS) || defined(TARGET_SPARC) \
|
||||
#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) \
|
||||
|| defined(TARGET_SPARC) || defined(TARGET_HPPA) \
|
||||
|| defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX)
|
||||
int __pad;
|
||||
#endif
|
||||
|
@ -14,6 +14,12 @@ STRUCT(serial_icounter_struct,
|
||||
STRUCT(sockaddr,
|
||||
TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14))
|
||||
|
||||
STRUCT(timeval,
|
||||
MK_ARRAY(TYPE_LONG, 2))
|
||||
|
||||
STRUCT(timespec,
|
||||
MK_ARRAY(TYPE_LONG, 2))
|
||||
|
||||
STRUCT(rtentry,
|
||||
TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr),
|
||||
TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID,
|
||||
|
1
target/hppa/Makefile.objs
Normal file
1
target/hppa/Makefile.objs
Normal file
@ -0,0 +1 @@
|
||||
obj-y += translate.o helper.o cpu.o op_helper.o gdbstub.o
|
52
target/hppa/cpu-qom.h
Normal file
52
target/hppa/cpu-qom.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* QEMU HPPA CPU
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||
*/
|
||||
#ifndef QEMU_HPPA_CPU_QOM_H
|
||||
#define QEMU_HPPA_CPU_QOM_H
|
||||
|
||||
#include "qom/cpu.h"
|
||||
|
||||
#define TYPE_HPPA_CPU "hppa-cpu"
|
||||
|
||||
#define HPPA_CPU_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(HPPACPUClass, (klass), TYPE_HPPA_CPU)
|
||||
#define HPPA_CPU(obj) \
|
||||
OBJECT_CHECK(HPPACPU, (obj), TYPE_HPPA_CPU)
|
||||
#define HPPA_CPU_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(HPPACPUClass, (obj), TYPE_HPPA_CPU)
|
||||
|
||||
/**
|
||||
* HPPACPUClass:
|
||||
* @parent_realize: The parent class' realize handler.
|
||||
* @parent_reset: The parent class' reset handler.
|
||||
*
|
||||
* An HPPA CPU model.
|
||||
*/
|
||||
typedef struct HPPACPUClass {
|
||||
/*< private >*/
|
||||
CPUClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
} HPPACPUClass;
|
||||
|
||||
typedef struct HPPACPU HPPACPU;
|
||||
|
||||
#endif
|
164
target/hppa/cpu.c
Normal file
164
target/hppa/cpu.c
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* QEMU HPPA CPU
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "cpu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "exec/exec-all.h"
|
||||
|
||||
|
||||
static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
|
||||
cpu->env.iaoq_f = value;
|
||||
cpu->env.iaoq_b = value + 4;
|
||||
}
|
||||
|
||||
static void hppa_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
|
||||
cpu->env.iaoq_f = tb->pc;
|
||||
cpu->env.iaoq_b = tb->cs_base;
|
||||
cpu->env.psw_n = tb->flags & 1;
|
||||
}
|
||||
|
||||
static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
|
||||
{
|
||||
info->mach = bfd_mach_hppa20;
|
||||
info->print_insn = print_insn_hppa;
|
||||
}
|
||||
|
||||
static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
HPPACPUClass *acc = HPPA_CPU_GET_CLASS(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
acc->parent_realize(dev, errp);
|
||||
}
|
||||
|
||||
/* Sort hppabetically by type name. */
|
||||
static gint hppa_cpu_list_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
ObjectClass *class_a = (ObjectClass *)a;
|
||||
ObjectClass *class_b = (ObjectClass *)b;
|
||||
const char *name_a, *name_b;
|
||||
|
||||
name_a = object_class_get_name(class_a);
|
||||
name_b = object_class_get_name(class_b);
|
||||
return strcmp(name_a, name_b);
|
||||
}
|
||||
|
||||
static void hppa_cpu_list_entry(gpointer data, gpointer user_data)
|
||||
{
|
||||
ObjectClass *oc = data;
|
||||
CPUListState *s = user_data;
|
||||
|
||||
(*s->cpu_fprintf)(s->file, " %s\n", object_class_get_name(oc));
|
||||
}
|
||||
|
||||
void hppa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
||||
{
|
||||
CPUListState s = {
|
||||
.file = f,
|
||||
.cpu_fprintf = cpu_fprintf,
|
||||
};
|
||||
GSList *list;
|
||||
|
||||
list = object_class_get_list(TYPE_HPPA_CPU, false);
|
||||
list = g_slist_sort(list, hppa_cpu_list_compare);
|
||||
(*cpu_fprintf)(f, "Available CPUs:\n");
|
||||
g_slist_foreach(list, hppa_cpu_list_entry, &s);
|
||||
g_slist_free(list);
|
||||
}
|
||||
|
||||
static void hppa_cpu_initfn(Object *obj)
|
||||
{
|
||||
CPUState *cs = CPU(obj);
|
||||
HPPACPU *cpu = HPPA_CPU(obj);
|
||||
CPUHPPAState *env = &cpu->env;
|
||||
|
||||
cs->env_ptr = env;
|
||||
cpu_hppa_loaded_fr0(env);
|
||||
set_snan_bit_is_one(true, &env->fp_status);
|
||||
|
||||
hppa_translate_init();
|
||||
}
|
||||
|
||||
HPPACPU *cpu_hppa_init(const char *cpu_model)
|
||||
{
|
||||
HPPACPU *cpu;
|
||||
|
||||
cpu = HPPA_CPU(object_new(TYPE_HPPA_CPU));
|
||||
|
||||
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
static void hppa_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
HPPACPUClass *acc = HPPA_CPU_CLASS(oc);
|
||||
|
||||
acc->parent_realize = dc->realize;
|
||||
dc->realize = hppa_cpu_realizefn;
|
||||
|
||||
cc->do_interrupt = hppa_cpu_do_interrupt;
|
||||
cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
|
||||
cc->dump_state = hppa_cpu_dump_state;
|
||||
cc->set_pc = hppa_cpu_set_pc;
|
||||
cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
|
||||
cc->gdb_read_register = hppa_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = hppa_cpu_gdb_write_register;
|
||||
cc->handle_mmu_fault = hppa_cpu_handle_mmu_fault;
|
||||
cc->disas_set_info = hppa_cpu_disas_set_info;
|
||||
|
||||
cc->gdb_num_core_regs = 128;
|
||||
}
|
||||
|
||||
static const TypeInfo hppa_cpu_type_info = {
|
||||
.name = TYPE_HPPA_CPU,
|
||||
.parent = TYPE_CPU,
|
||||
.instance_size = sizeof(HPPACPU),
|
||||
.instance_init = hppa_cpu_initfn,
|
||||
.abstract = false,
|
||||
.class_size = sizeof(HPPACPUClass),
|
||||
.class_init = hppa_cpu_class_init,
|
||||
};
|
||||
|
||||
static void hppa_cpu_register_types(void)
|
||||
{
|
||||
type_register_static(&hppa_cpu_type_info);
|
||||
}
|
||||
|
||||
type_init(hppa_cpu_register_types)
|
144
target/hppa/cpu.h
Normal file
144
target/hppa/cpu.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* PA-RISC emulation cpu definitions for qemu.
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HPPA_CPU_H
|
||||
#define HPPA_CPU_H
|
||||
|
||||
#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 CPUArchState struct CPUHPPAState
|
||||
|
||||
#include "exec/cpu-defs.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
#define ALIGNED_ONLY
|
||||
#define NB_MMU_MODES 1
|
||||
#define MMU_USER_IDX 0
|
||||
#define TARGET_INSN_START_EXTRA_WORDS 1
|
||||
|
||||
#define EXCP_SYSCALL 1
|
||||
#define EXCP_SYSCALL_LWS 2
|
||||
#define EXCP_SIGSEGV 3
|
||||
#define EXCP_SIGILL 4
|
||||
#define EXCP_SIGFPE 5
|
||||
|
||||
typedef struct CPUHPPAState CPUHPPAState;
|
||||
|
||||
struct CPUHPPAState {
|
||||
target_ulong gr[32];
|
||||
uint64_t fr[32];
|
||||
|
||||
target_ulong sar;
|
||||
target_ulong cr26;
|
||||
target_ulong cr27;
|
||||
|
||||
target_ulong psw_n; /* boolean */
|
||||
target_long 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.
|
||||
* In addition, it's easier to compute carry-in for bit B+1 than it is to
|
||||
* compute carry-out for bit B (3 vs 4 insns for addition, assuming the
|
||||
* 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_ulong iaoq_f; /* front */
|
||||
target_ulong iaoq_b; /* back, aka next instruction */
|
||||
|
||||
target_ulong ior; /* interrupt offset register */
|
||||
|
||||
uint32_t fr0_shadow; /* flags, c, ca/cq, rm, d, enables */
|
||||
float_status fp_status;
|
||||
|
||||
/* Those resources are used only in QEMU core */
|
||||
CPU_COMMON
|
||||
};
|
||||
|
||||
/**
|
||||
* HPPACPU:
|
||||
* @env: #CPUHPPAState
|
||||
*
|
||||
* An HPPA CPU.
|
||||
*/
|
||||
struct HPPACPU {
|
||||
/*< private >*/
|
||||
CPUState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
CPUHPPAState env;
|
||||
};
|
||||
|
||||
static inline HPPACPU *hppa_env_get_cpu(CPUHPPAState *env)
|
||||
{
|
||||
return container_of(env, HPPACPU, env);
|
||||
}
|
||||
|
||||
#define ENV_GET_CPU(e) CPU(hppa_env_get_cpu(e))
|
||||
#define ENV_OFFSET offsetof(HPPACPU, env)
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hppa_translate_init(void);
|
||||
|
||||
HPPACPU *cpu_hppa_init(const char *cpu_model);
|
||||
|
||||
#define cpu_init(cpu_model) CPU(cpu_hppa_init(cpu_model))
|
||||
|
||||
void hppa_cpu_list(FILE *f, fprintf_function cpu_fprintf);
|
||||
|
||||
static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, target_ulong *pc,
|
||||
target_ulong *cs_base,
|
||||
uint32_t *pflags)
|
||||
{
|
||||
*pc = env->iaoq_f;
|
||||
*cs_base = env->iaoq_b;
|
||||
*pflags = env->psw_n;
|
||||
}
|
||||
|
||||
target_ulong cpu_hppa_get_psw(CPUHPPAState *env);
|
||||
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong);
|
||||
void cpu_hppa_loaded_fr0(CPUHPPAState *env);
|
||||
|
||||
#define cpu_signal_handler cpu_hppa_signal_handler
|
||||
|
||||
int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc);
|
||||
int hppa_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int midx);
|
||||
int hppa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
void hppa_cpu_do_interrupt(CPUState *cpu);
|
||||
bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
|
||||
void hppa_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function, int);
|
||||
|
||||
#endif /* HPPA_CPU_H */
|
111
target/hppa/gdbstub.c
Normal file
111
target/hppa/gdbstub.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* HPPA gdb server stub
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/gdbstub.h"
|
||||
|
||||
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;
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
val = cpu_hppa_get_psw(env);
|
||||
break;
|
||||
case 1 ... 31:
|
||||
val = env->gr[n];
|
||||
break;
|
||||
case 32:
|
||||
val = env->sar;
|
||||
break;
|
||||
case 33:
|
||||
val = env->iaoq_f;
|
||||
break;
|
||||
case 35:
|
||||
val = env->iaoq_b;
|
||||
break;
|
||||
case 59:
|
||||
val = env->cr26;
|
||||
break;
|
||||
case 60:
|
||||
val = env->cr27;
|
||||
break;
|
||||
case 64 ... 127:
|
||||
val = extract64(env->fr[(n - 64) / 2], (n & 1 ? 0 : 32), 32);
|
||||
break;
|
||||
default:
|
||||
if (n < 128) {
|
||||
val = 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return gdb_get_regl(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);
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
cpu_hppa_put_psw(env, val);
|
||||
break;
|
||||
case 1 ... 31:
|
||||
env->gr[n] = val;
|
||||
break;
|
||||
case 32:
|
||||
env->sar = val;
|
||||
break;
|
||||
case 33:
|
||||
env->iaoq_f = val;
|
||||
break;
|
||||
case 35:
|
||||
env->iaoq_b = val;
|
||||
case 59:
|
||||
env->cr26 = val;
|
||||
break;
|
||||
case 60:
|
||||
env->cr27 = val;
|
||||
break;
|
||||
case 64:
|
||||
env->fr[0] = deposit64(env->fr[0], 32, 32, val);
|
||||
cpu_hppa_loaded_fr0(env);
|
||||
break;
|
||||
case 65 ... 127:
|
||||
{
|
||||
uint64_t *fr = &env->fr[(n - 64) / 2];
|
||||
*fr = deposit64(*fr, val, (n & 1 ? 0 : 32), 32);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (n >= 128) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return sizeof(target_ulong);
|
||||
}
|
137
target/hppa/helper.c
Normal file
137
target/hppa/helper.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* HPPA emulation cpu helpers for qemu.
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "fpu/softfloat.h"
|
||||
#include "exec/helper-proto.h"
|
||||
|
||||
target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
|
||||
{
|
||||
target_ulong psw;
|
||||
|
||||
/* Fold carry bits down to 8 consecutive bits. */
|
||||
/* ??? Needs tweaking for hppa64. */
|
||||
/* .......b...c...d...e...f...g...h */
|
||||
psw = (env->psw_cb >> 4) & 0x01111111;
|
||||
/* .......b..bc..cd..de..ef..fg..gh */
|
||||
psw |= psw >> 3;
|
||||
/* .............bcd............efgh */
|
||||
psw |= (psw >> 6) & 0x000f000f;
|
||||
/* .........................bcdefgh */
|
||||
psw |= (psw >> 12) & 0xf;
|
||||
psw |= env->psw_cb_msb << 7;
|
||||
psw <<= 8;
|
||||
|
||||
psw |= env->psw_n << 21;
|
||||
psw |= (env->psw_v < 0) << 17;
|
||||
|
||||
return psw;
|
||||
}
|
||||
|
||||
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
|
||||
{
|
||||
target_ulong cb = 0;
|
||||
|
||||
env->psw_n = (psw >> 21) & 1;
|
||||
env->psw_v = -((psw >> 17) & 1);
|
||||
env->psw_cb_msb = (psw >> 15) & 1;
|
||||
|
||||
cb |= ((psw >> 14) & 1) << 28;
|
||||
cb |= ((psw >> 13) & 1) << 24;
|
||||
cb |= ((psw >> 12) & 1) << 20;
|
||||
cb |= ((psw >> 11) & 1) << 16;
|
||||
cb |= ((psw >> 10) & 1) << 12;
|
||||
cb |= ((psw >> 9) & 1) << 8;
|
||||
cb |= ((psw >> 8) & 1) << 4;
|
||||
env->psw_cb = cb;
|
||||
}
|
||||
|
||||
int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
|
||||
int rw, int mmu_idx)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
|
||||
cs->exception_index = EXCP_SIGSEGV;
|
||||
cpu->env.ior = address;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hppa_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
CPUHPPAState *env = &cpu->env;
|
||||
int i = cs->exception_index;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_INT)) {
|
||||
static int count;
|
||||
const char *name = "<unknown>";
|
||||
|
||||
switch (i) {
|
||||
case EXCP_SYSCALL:
|
||||
name = "syscall";
|
||||
break;
|
||||
case EXCP_SIGSEGV:
|
||||
name = "sigsegv";
|
||||
break;
|
||||
case EXCP_SIGILL:
|
||||
name = "sigill";
|
||||
break;
|
||||
case EXCP_SIGFPE:
|
||||
name = "sigfpe";
|
||||
break;
|
||||
}
|
||||
qemu_log("INT %6d: %s ia_f=" TARGET_FMT_lx "\n",
|
||||
++count, name, env->iaoq_f);
|
||||
}
|
||||
cs->exception_index = -1;
|
||||
}
|
||||
|
||||
bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
void hppa_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
fprintf_function cpu_fprintf, int flags)
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
CPUHPPAState *env = &cpu->env;
|
||||
int i;
|
||||
|
||||
cpu_fprintf(f, "IA_F " TARGET_FMT_lx
|
||||
" IA_B " TARGET_FMT_lx
|
||||
" PSW " TARGET_FMT_lx
|
||||
" [N:" TARGET_FMT_ld " V:%d"
|
||||
" CB:" TARGET_FMT_lx "]\n ",
|
||||
env->iaoq_f, env->iaoq_b, cpu_hppa_get_psw(env),
|
||||
env->psw_n, env->psw_v < 0,
|
||||
((env->psw_cb >> 4) & 0x01111111) | (env->psw_cb_msb << 28));
|
||||
for (i = 1; i < 32; i++) {
|
||||
cpu_fprintf(f, "GR%02d " TARGET_FMT_lx " ", i, env->gr[i]);
|
||||
if ((i % 4) == 3) {
|
||||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* ??? FR */
|
||||
}
|
66
target/hppa/helper.h
Normal file
66
target/hppa/helper.h
Normal file
@ -0,0 +1,66 @@
|
||||
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_3(stby_b, 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_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(loaded_fr0, TCG_CALL_NO_RWG, void, env)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fsqrt_s, TCG_CALL_NO_RWG, f32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(frnd_s, TCG_CALL_NO_RWG, f32, env, f32)
|
||||
DEF_HELPER_FLAGS_3(fadd_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fsub_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fmpy_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(fdiv_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fsqrt_d, TCG_CALL_NO_RWG, f64, env, f64)
|
||||
DEF_HELPER_FLAGS_2(frnd_d, TCG_CALL_NO_RWG, f64, env, f64)
|
||||
DEF_HELPER_FLAGS_3(fadd_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fsub_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fmpy_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
DEF_HELPER_FLAGS_3(fdiv_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_s_d, TCG_CALL_NO_RWG, f64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_d_s, TCG_CALL_NO_RWG, f32, env, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_w_s, TCG_CALL_NO_RWG, f32, env, s32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_dw_s, TCG_CALL_NO_RWG, f32, env, s64)
|
||||
DEF_HELPER_FLAGS_2(fcnv_w_d, TCG_CALL_NO_RWG, f64, env, s32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_dw_d, TCG_CALL_NO_RWG, f64, env, s64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_s_w, TCG_CALL_NO_RWG, s32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_d_w, TCG_CALL_NO_RWG, s32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fcnv_s_dw, TCG_CALL_NO_RWG, s64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_d_dw, TCG_CALL_NO_RWG, s64, env, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_s_w, TCG_CALL_NO_RWG, s32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_d_w, TCG_CALL_NO_RWG, s32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_s_dw, TCG_CALL_NO_RWG, s64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_d_dw, TCG_CALL_NO_RWG, s64, env, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_uw_s, TCG_CALL_NO_RWG, f32, env, i32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_udw_s, TCG_CALL_NO_RWG, f32, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcnv_uw_d, TCG_CALL_NO_RWG, f64, env, i32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_udw_d, TCG_CALL_NO_RWG, f64, env, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_s_uw, TCG_CALL_NO_RWG, i32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_d_uw, TCG_CALL_NO_RWG, i32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fcnv_s_udw, TCG_CALL_NO_RWG, i64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_d_udw, TCG_CALL_NO_RWG, i64, env, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_s_uw, TCG_CALL_NO_RWG, i32, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_d_uw, TCG_CALL_NO_RWG, i32, env, f64)
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_s_udw, TCG_CALL_NO_RWG, i64, env, f32)
|
||||
DEF_HELPER_FLAGS_2(fcnv_t_d_udw, TCG_CALL_NO_RWG, i64, env, f64)
|
||||
|
||||
DEF_HELPER_FLAGS_5(fcmp_s, TCG_CALL_NO_RWG, void, env, f32, f32, i32, i32)
|
||||
DEF_HELPER_FLAGS_5(fcmp_d, TCG_CALL_NO_RWG, void, env, f64, f64, i32, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(fmpyfadd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_4(fmpynfadd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_4(fmpyfadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_4(fmpynfadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
|
570
target/hppa/op_helper.c
Normal file
570
target/hppa/op_helper.c
Normal file
@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Helpers for HPPA instructions.
|
||||
*
|
||||
* Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exec/cpu_ldst.h"
|
||||
|
||||
void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp)
|
||||
{
|
||||
HPPACPU *cpu = hppa_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
cs->exception_index = excp;
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
||||
static void QEMU_NORETURN dynexcp(CPUHPPAState *env, int excp, uintptr_t ra)
|
||||
{
|
||||
HPPACPU *cpu = hppa_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
cs->exception_index = excp;
|
||||
cpu_loop_exit_restore(cs, ra);
|
||||
}
|
||||
|
||||
void HELPER(tsv)(CPUHPPAState *env, target_ulong cond)
|
||||
{
|
||||
if (unlikely((target_long)cond < 0)) {
|
||||
dynexcp(env, EXCP_SIGFPE, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
|
||||
{
|
||||
if (unlikely(cond)) {
|
||||
dynexcp(env, EXCP_SIGFPE, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val,
|
||||
uint32_t mask, uintptr_t ra)
|
||||
{
|
||||
uint32_t old, new, cmp;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
uint32_t *haddr = g2h(addr - 1);
|
||||
old = *haddr;
|
||||
while (1) {
|
||||
new = (old & ~mask) | (val & mask);
|
||||
cmp = atomic_cmpxchg(haddr, old, new);
|
||||
if (cmp == old) {
|
||||
return;
|
||||
}
|
||||
old = cmp;
|
||||
}
|
||||
#else
|
||||
#error "Not implemented."
|
||||
#endif
|
||||
}
|
||||
|
||||
void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ulong val)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
|
||||
switch (addr & 3) {
|
||||
case 3:
|
||||
cpu_stb_data_ra(env, addr, val, ra);
|
||||
break;
|
||||
case 2:
|
||||
cpu_stw_data_ra(env, addr, val, ra);
|
||||
break;
|
||||
case 1:
|
||||
/* The 3 byte store must appear atomic. */
|
||||
if (parallel_cpus) {
|
||||
atomic_store_3(env, addr, val, 0x00ffffffu, ra);
|
||||
} else {
|
||||
cpu_stb_data_ra(env, addr, val >> 16, ra);
|
||||
cpu_stw_data_ra(env, addr + 1, val, ra);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cpu_stl_data_ra(env, addr, val, ra);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ulong val)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
|
||||
switch (addr & 3) {
|
||||
case 3:
|
||||
/* The 3 byte store must appear atomic. */
|
||||
if (parallel_cpus) {
|
||||
atomic_store_3(env, addr - 3, val, 0xffffff00u, ra);
|
||||
} else {
|
||||
cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
|
||||
cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
|
||||
break;
|
||||
case 1:
|
||||
cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
|
||||
break;
|
||||
default:
|
||||
/* Nothing is stored, but protection is checked and the
|
||||
cacheline is marked dirty. */
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
probe_write(env, addr, cpu_mmu_index(env, 0), ra);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
target_ulong HELPER(probe_r)(target_ulong addr)
|
||||
{
|
||||
return page_check_range(addr, 1, PAGE_READ);
|
||||
}
|
||||
|
||||
target_ulong HELPER(probe_w)(target_ulong addr)
|
||||
{
|
||||
return page_check_range(addr, 1, PAGE_WRITE);
|
||||
}
|
||||
|
||||
void HELPER(loaded_fr0)(CPUHPPAState *env)
|
||||
{
|
||||
uint32_t shadow = env->fr[0] >> 32;
|
||||
int rm, d;
|
||||
|
||||
env->fr0_shadow = shadow;
|
||||
|
||||
switch (extract32(shadow, 9, 2)) {
|
||||
default:
|
||||
rm = float_round_nearest_even;
|
||||
break;
|
||||
case 1:
|
||||
rm = float_round_to_zero;
|
||||
break;
|
||||
case 2:
|
||||
rm = float_round_up;
|
||||
break;
|
||||
case 3:
|
||||
rm = float_round_down;
|
||||
break;
|
||||
}
|
||||
set_float_rounding_mode(rm, &env->fp_status);
|
||||
|
||||
d = extract32(shadow, 5, 1);
|
||||
set_flush_to_zero(d, &env->fp_status);
|
||||
set_flush_inputs_to_zero(d, &env->fp_status);
|
||||
}
|
||||
|
||||
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
|
||||
{
|
||||
helper_loaded_fr0(env);
|
||||
}
|
||||
|
||||
#define CONVERT_BIT(X, SRC, DST) \
|
||||
((SRC) > (DST) \
|
||||
? (X) / ((SRC) / (DST)) & (DST) \
|
||||
: ((X) & (SRC)) * ((DST) / (SRC)))
|
||||
|
||||
static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
|
||||
{
|
||||
uint32_t soft_exp = get_float_exception_flags(&env->fp_status);
|
||||
uint32_t hard_exp = 0;
|
||||
uint32_t shadow = env->fr0_shadow;
|
||||
|
||||
if (likely(soft_exp == 0)) {
|
||||
env->fr[0] = (uint64_t)shadow << 32;
|
||||
return;
|
||||
}
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact, 1u << 0);
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, 1u << 1);
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, 1u << 2);
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, 1u << 3);
|
||||
hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, 1u << 4);
|
||||
shadow |= hard_exp << (32 - 5);
|
||||
env->fr0_shadow = shadow;
|
||||
env->fr[0] = (uint64_t)shadow << 32;
|
||||
|
||||
if (hard_exp & shadow) {
|
||||
dynexcp(env, EXCP_SIGFPE, ra);
|
||||
}
|
||||
}
|
||||
|
||||
float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
float32 ret = float32_sqrt(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(frnd_s)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
float32 ret = float32_round_to_int(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fadd_s)(CPUHPPAState *env, float32 a, float32 b)
|
||||
{
|
||||
float32 ret = float32_add(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fsub_s)(CPUHPPAState *env, float32 a, float32 b)
|
||||
{
|
||||
float32 ret = float32_sub(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fmpy_s)(CPUHPPAState *env, float32 a, float32 b)
|
||||
{
|
||||
float32 ret = float32_mul(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fdiv_s)(CPUHPPAState *env, float32 a, float32 b)
|
||||
{
|
||||
float32 ret = float32_div(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fsqrt_d)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
float64 ret = float64_sqrt(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(frnd_d)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
float64 ret = float64_round_to_int(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fadd_d)(CPUHPPAState *env, float64 a, float64 b)
|
||||
{
|
||||
float64 ret = float64_add(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fsub_d)(CPUHPPAState *env, float64 a, float64 b)
|
||||
{
|
||||
float64 ret = float64_sub(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fmpy_d)(CPUHPPAState *env, float64 a, float64 b)
|
||||
{
|
||||
float64 ret = float64_mul(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fdiv_d)(CPUHPPAState *env, float64 a, float64 b)
|
||||
{
|
||||
float64 ret = float64_div(a, b, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fcnv_s_d)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
float64 ret = float32_to_float64(arg, &env->fp_status);
|
||||
ret = float64_maybe_silence_nan(ret, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fcnv_d_s)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
float32 ret = float64_to_float32(arg, &env->fp_status);
|
||||
ret = float32_maybe_silence_nan(ret, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fcnv_w_s)(CPUHPPAState *env, int32_t arg)
|
||||
{
|
||||
float32 ret = int32_to_float32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fcnv_dw_s)(CPUHPPAState *env, int64_t arg)
|
||||
{
|
||||
float32 ret = int64_to_float32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fcnv_w_d)(CPUHPPAState *env, int32_t arg)
|
||||
{
|
||||
float64 ret = int32_to_float64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fcnv_dw_d)(CPUHPPAState *env, int64_t arg)
|
||||
{
|
||||
float64 ret = int64_to_float64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HELPER(fcnv_s_w)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
int32_t ret = float32_to_int32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HELPER(fcnv_d_w)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
int32_t ret = float64_to_int32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t HELPER(fcnv_s_dw)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
int64_t ret = float32_to_int64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t HELPER(fcnv_d_dw)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
int64_t ret = float64_to_int64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HELPER(fcnv_t_s_w)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
int32_t ret = float32_to_int32_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HELPER(fcnv_t_d_w)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
int32_t ret = float64_to_int32_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t HELPER(fcnv_t_s_dw)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
int64_t ret = float32_to_int64_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t HELPER(fcnv_t_d_dw)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
int64_t ret = float64_to_int64_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fcnv_uw_s)(CPUHPPAState *env, uint32_t arg)
|
||||
{
|
||||
float32 ret = uint32_to_float32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fcnv_udw_s)(CPUHPPAState *env, uint64_t arg)
|
||||
{
|
||||
float32 ret = uint64_to_float32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fcnv_uw_d)(CPUHPPAState *env, uint32_t arg)
|
||||
{
|
||||
float64 ret = uint32_to_float64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fcnv_udw_d)(CPUHPPAState *env, uint64_t arg)
|
||||
{
|
||||
float64 ret = uint64_to_float64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t HELPER(fcnv_s_uw)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
uint32_t ret = float32_to_uint32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t HELPER(fcnv_d_uw)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
uint32_t ret = float64_to_uint32(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t HELPER(fcnv_s_udw)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
uint64_t ret = float32_to_uint64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t HELPER(fcnv_d_udw)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
uint64_t ret = float64_to_uint64(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t HELPER(fcnv_t_s_uw)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
uint32_t ret = float32_to_uint32_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t HELPER(fcnv_t_d_uw)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
uint32_t ret = float64_to_uint32_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t HELPER(fcnv_t_s_udw)(CPUHPPAState *env, float32 arg)
|
||||
{
|
||||
uint64_t ret = float32_to_uint64_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t HELPER(fcnv_t_d_udw)(CPUHPPAState *env, float64 arg)
|
||||
{
|
||||
uint64_t ret = float64_to_uint64_round_to_zero(arg, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void update_fr0_cmp(CPUHPPAState *env, uint32_t y, uint32_t c, int r)
|
||||
{
|
||||
uint32_t shadow = env->fr0_shadow;
|
||||
|
||||
switch (r) {
|
||||
case float_relation_greater:
|
||||
c = extract32(c, 4, 1);
|
||||
break;
|
||||
case float_relation_less:
|
||||
c = extract32(c, 3, 1);
|
||||
break;
|
||||
case float_relation_equal:
|
||||
c = extract32(c, 2, 1);
|
||||
break;
|
||||
case float_relation_unordered:
|
||||
c = extract32(c, 1, 1);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if (y) {
|
||||
/* targeted comparison */
|
||||
/* set fpsr[ca[y - 1]] to current compare */
|
||||
shadow = deposit32(shadow, 21 - (y - 1), 1, c);
|
||||
} else {
|
||||
/* queued comparison */
|
||||
/* shift cq right by one place */
|
||||
shadow = deposit32(shadow, 11, 10, extract32(shadow, 12, 10));
|
||||
/* move fpsr[c] to fpsr[cq[0]] */
|
||||
shadow = deposit32(shadow, 21, 1, extract32(shadow, 26, 1));
|
||||
/* set fpsr[c] to current compare */
|
||||
shadow = deposit32(shadow, 26, 1, c);
|
||||
}
|
||||
|
||||
env->fr0_shadow = shadow;
|
||||
env->fr[0] = (uint64_t)shadow << 32;
|
||||
}
|
||||
|
||||
void HELPER(fcmp_s)(CPUHPPAState *env, float32 a, float32 b,
|
||||
uint32_t y, uint32_t c)
|
||||
{
|
||||
int r;
|
||||
if (c & 1) {
|
||||
r = float32_compare(a, b, &env->fp_status);
|
||||
} else {
|
||||
r = float32_compare_quiet(a, b, &env->fp_status);
|
||||
}
|
||||
update_fr0_op(env, GETPC());
|
||||
update_fr0_cmp(env, y, c, r);
|
||||
}
|
||||
|
||||
void HELPER(fcmp_d)(CPUHPPAState *env, float64 a, float64 b,
|
||||
uint32_t y, uint32_t c)
|
||||
{
|
||||
int r;
|
||||
if (c & 1) {
|
||||
r = float64_compare(a, b, &env->fp_status);
|
||||
} else {
|
||||
r = float64_compare_quiet(a, b, &env->fp_status);
|
||||
}
|
||||
update_fr0_op(env, GETPC());
|
||||
update_fr0_cmp(env, y, c, r);
|
||||
}
|
||||
|
||||
float32 HELPER(fmpyfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c)
|
||||
{
|
||||
float32 ret = float32_muladd(a, b, c, 0, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float32 HELPER(fmpynfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c)
|
||||
{
|
||||
float32 ret = float32_muladd(a, b, c, float_muladd_negate_product,
|
||||
&env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fmpyfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c)
|
||||
{
|
||||
float64 ret = float64_muladd(a, b, c, 0, &env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c)
|
||||
{
|
||||
float64 ret = float64_muladd(a, b, c, float_muladd_negate_product,
|
||||
&env->fp_status);
|
||||
update_fr0_op(env, GETPC());
|
||||
return ret;
|
||||
}
|
3946
target/hppa/translate.c
Normal file
3946
target/hppa/translate.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user