Skip to content

Commit

Permalink
include/exec: Provide the tswap() functions for target independent co…
Browse files Browse the repository at this point in the history
…de, too

In some cases of target independent code, it would be useful to have access
to the functions that swap endianess in case it differs between guest and
host. Thus re-implement the tswapXX() functions in a new header that can be
included separately. The check whether the swapping is needed continues to
be done at compile-time for target specific code, while it is done at
run-time in target-independent code.

Message-Id: <20230411183418.1640500-3-thuth@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 24be336)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(trivial change needed for the next commit 058096f
 "hw/char/riscv_htif: Fix the console syscall on big endian hosts")
  • Loading branch information
huth authored and Michael Tokarev committed Sep 20, 2023
1 parent 3af03de commit aeb931d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 63 deletions.
64 changes: 1 addition & 63 deletions include/exec/cpu-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "exec/cpu-common.h"
#include "exec/memory.h"
#include "exec/tswap.h"
#include "qemu/thread.h"
#include "hw/core/cpu.h"
#include "qemu/rcu.h"
Expand All @@ -44,69 +45,6 @@
#define BSWAP_NEEDED
#endif

#ifdef BSWAP_NEEDED

static inline uint16_t tswap16(uint16_t s)
{
return bswap16(s);
}

static inline uint32_t tswap32(uint32_t s)
{
return bswap32(s);
}

static inline uint64_t tswap64(uint64_t s)
{
return bswap64(s);
}

static inline void tswap16s(uint16_t *s)
{
*s = bswap16(*s);
}

static inline void tswap32s(uint32_t *s)
{
*s = bswap32(*s);
}

static inline void tswap64s(uint64_t *s)
{
*s = bswap64(*s);
}

#else

static inline uint16_t tswap16(uint16_t s)
{
return s;
}

static inline uint32_t tswap32(uint32_t s)
{
return s;
}

static inline uint64_t tswap64(uint64_t s)
{
return s;
}

static inline void tswap16s(uint16_t *s)
{
}

static inline void tswap32s(uint32_t *s)
{
}

static inline void tswap64s(uint64_t *s)
{
}

#endif

#if TARGET_LONG_SIZE == 4
#define tswapl(s) tswap32(s)
#define tswapls(s) tswap32s((uint32_t *)(s))
Expand Down
72 changes: 72 additions & 0 deletions include/exec/tswap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Macros for swapping a value if the endianness is different
* between the target and the host.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#ifndef TSWAP_H
#define TSWAP_H

#include "hw/core/cpu.h"
#include "qemu/bswap.h"

/*
* If we're in target-specific code, we can hard-code the swapping
* condition, otherwise we have to do (slower) run-time checks.
*/
#ifdef NEED_CPU_H
#define target_needs_bswap() (HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN)
#else
#define target_needs_bswap() (target_words_bigendian() != HOST_BIG_ENDIAN)
#endif

static inline uint16_t tswap16(uint16_t s)
{
if (target_needs_bswap()) {
return bswap16(s);
} else {
return s;
}
}

static inline uint32_t tswap32(uint32_t s)
{
if (target_needs_bswap()) {
return bswap32(s);
} else {
return s;
}
}

static inline uint64_t tswap64(uint64_t s)
{
if (target_needs_bswap()) {
return bswap64(s);
} else {
return s;
}
}

static inline void tswap16s(uint16_t *s)
{
if (target_needs_bswap()) {
*s = bswap16(*s);
}
}

static inline void tswap32s(uint32_t *s)
{
if (target_needs_bswap()) {
*s = bswap32(*s);
}
}

static inline void tswap64s(uint64_t *s)
{
if (target_needs_bswap()) {
*s = bswap64(*s);
}
}

#endif /* TSWAP_H */

0 comments on commit aeb931d

Please sign in to comment.