|
@@ -17,11 +17,9 @@
|
|
#include "qemu/main-loop.h"
|
|
#include "qemu/main-loop.h"
|
|
#include "qemu/timer.h"
|
|
#include "qemu/timer.h"
|
|
#include "qemu/bitops.h"
|
|
#include "qemu/bitops.h"
|
|
-#include "qemu/crc32c.h"
|
|
|
|
#include "qemu/qemu-print.h"
|
|
#include "qemu/qemu-print.h"
|
|
#include "exec/exec-all.h"
|
|
#include "exec/exec-all.h"
|
|
#include "exec/translation-block.h"
|
|
#include "exec/translation-block.h"
|
|
-#include <zlib.h> /* for crc32 */
|
|
|
|
#include "hw/irq.h"
|
|
#include "hw/irq.h"
|
|
#include "system/cpu-timers.h"
|
|
#include "system/cpu-timers.h"
|
|
#include "system/kvm.h"
|
|
#include "system/kvm.h"
|
|
@@ -10984,289 +10982,6 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * Note that signed overflow is undefined in C. The following routines are
|
|
|
|
- * careful to use unsigned types where modulo arithmetic is required.
|
|
|
|
- * Failure to do so _will_ break on newer gcc.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-/* Signed saturating arithmetic. */
|
|
|
|
-
|
|
|
|
-/* Perform 16-bit signed saturating addition. */
|
|
|
|
-static inline uint16_t add16_sat(uint16_t a, uint16_t b)
|
|
|
|
-{
|
|
|
|
- uint16_t res;
|
|
|
|
-
|
|
|
|
- res = a + b;
|
|
|
|
- if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
|
|
|
|
- if (a & 0x8000) {
|
|
|
|
- res = 0x8000;
|
|
|
|
- } else {
|
|
|
|
- res = 0x7fff;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Perform 8-bit signed saturating addition. */
|
|
|
|
-static inline uint8_t add8_sat(uint8_t a, uint8_t b)
|
|
|
|
-{
|
|
|
|
- uint8_t res;
|
|
|
|
-
|
|
|
|
- res = a + b;
|
|
|
|
- if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
|
|
|
|
- if (a & 0x80) {
|
|
|
|
- res = 0x80;
|
|
|
|
- } else {
|
|
|
|
- res = 0x7f;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Perform 16-bit signed saturating subtraction. */
|
|
|
|
-static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
|
|
|
|
-{
|
|
|
|
- uint16_t res;
|
|
|
|
-
|
|
|
|
- res = a - b;
|
|
|
|
- if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
|
|
|
|
- if (a & 0x8000) {
|
|
|
|
- res = 0x8000;
|
|
|
|
- } else {
|
|
|
|
- res = 0x7fff;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Perform 8-bit signed saturating subtraction. */
|
|
|
|
-static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
|
|
|
|
-{
|
|
|
|
- uint8_t res;
|
|
|
|
-
|
|
|
|
- res = a - b;
|
|
|
|
- if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
|
|
|
|
- if (a & 0x80) {
|
|
|
|
- res = 0x80;
|
|
|
|
- } else {
|
|
|
|
- res = 0x7f;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
|
|
|
|
-#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
|
|
|
|
-#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
|
|
|
|
-#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
|
|
|
|
-#define PFX q
|
|
|
|
-
|
|
|
|
-#include "op_addsub.h"
|
|
|
|
-
|
|
|
|
-/* Unsigned saturating arithmetic. */
|
|
|
|
-static inline uint16_t add16_usat(uint16_t a, uint16_t b)
|
|
|
|
-{
|
|
|
|
- uint16_t res;
|
|
|
|
- res = a + b;
|
|
|
|
- if (res < a) {
|
|
|
|
- res = 0xffff;
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
|
|
|
|
-{
|
|
|
|
- if (a > b) {
|
|
|
|
- return a - b;
|
|
|
|
- } else {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline uint8_t add8_usat(uint8_t a, uint8_t b)
|
|
|
|
-{
|
|
|
|
- uint8_t res;
|
|
|
|
- res = a + b;
|
|
|
|
- if (res < a) {
|
|
|
|
- res = 0xff;
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
|
|
|
|
-{
|
|
|
|
- if (a > b) {
|
|
|
|
- return a - b;
|
|
|
|
- } else {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
|
|
|
|
-#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
|
|
|
|
-#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
|
|
|
|
-#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
|
|
|
|
-#define PFX uq
|
|
|
|
-
|
|
|
|
-#include "op_addsub.h"
|
|
|
|
-
|
|
|
|
-/* Signed modulo arithmetic. */
|
|
|
|
-#define SARITH16(a, b, n, op) do { \
|
|
|
|
- int32_t sum; \
|
|
|
|
- sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
|
|
|
|
- RESULT(sum, n, 16); \
|
|
|
|
- if (sum >= 0) \
|
|
|
|
- ge |= 3 << (n * 2); \
|
|
|
|
- } while (0)
|
|
|
|
-
|
|
|
|
-#define SARITH8(a, b, n, op) do { \
|
|
|
|
- int32_t sum; \
|
|
|
|
- sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
|
|
|
|
- RESULT(sum, n, 8); \
|
|
|
|
- if (sum >= 0) \
|
|
|
|
- ge |= 1 << n; \
|
|
|
|
- } while (0)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-#define ADD16(a, b, n) SARITH16(a, b, n, +)
|
|
|
|
-#define SUB16(a, b, n) SARITH16(a, b, n, -)
|
|
|
|
-#define ADD8(a, b, n) SARITH8(a, b, n, +)
|
|
|
|
-#define SUB8(a, b, n) SARITH8(a, b, n, -)
|
|
|
|
-#define PFX s
|
|
|
|
-#define ARITH_GE
|
|
|
|
-
|
|
|
|
-#include "op_addsub.h"
|
|
|
|
-
|
|
|
|
-/* Unsigned modulo arithmetic. */
|
|
|
|
-#define ADD16(a, b, n) do { \
|
|
|
|
- uint32_t sum; \
|
|
|
|
- sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
|
|
|
|
- RESULT(sum, n, 16); \
|
|
|
|
- if ((sum >> 16) == 1) \
|
|
|
|
- ge |= 3 << (n * 2); \
|
|
|
|
- } while (0)
|
|
|
|
-
|
|
|
|
-#define ADD8(a, b, n) do { \
|
|
|
|
- uint32_t sum; \
|
|
|
|
- sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
|
|
|
|
- RESULT(sum, n, 8); \
|
|
|
|
- if ((sum >> 8) == 1) \
|
|
|
|
- ge |= 1 << n; \
|
|
|
|
- } while (0)
|
|
|
|
-
|
|
|
|
-#define SUB16(a, b, n) do { \
|
|
|
|
- uint32_t sum; \
|
|
|
|
- sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
|
|
|
|
- RESULT(sum, n, 16); \
|
|
|
|
- if ((sum >> 16) == 0) \
|
|
|
|
- ge |= 3 << (n * 2); \
|
|
|
|
- } while (0)
|
|
|
|
-
|
|
|
|
-#define SUB8(a, b, n) do { \
|
|
|
|
- uint32_t sum; \
|
|
|
|
- sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
|
|
|
|
- RESULT(sum, n, 8); \
|
|
|
|
- if ((sum >> 8) == 0) \
|
|
|
|
- ge |= 1 << n; \
|
|
|
|
- } while (0)
|
|
|
|
-
|
|
|
|
-#define PFX u
|
|
|
|
-#define ARITH_GE
|
|
|
|
-
|
|
|
|
-#include "op_addsub.h"
|
|
|
|
-
|
|
|
|
-/* Halved signed arithmetic. */
|
|
|
|
-#define ADD16(a, b, n) \
|
|
|
|
- RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
|
|
|
|
-#define SUB16(a, b, n) \
|
|
|
|
- RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
|
|
|
|
-#define ADD8(a, b, n) \
|
|
|
|
- RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
|
|
|
|
-#define SUB8(a, b, n) \
|
|
|
|
- RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
|
|
|
|
-#define PFX sh
|
|
|
|
-
|
|
|
|
-#include "op_addsub.h"
|
|
|
|
-
|
|
|
|
-/* Halved unsigned arithmetic. */
|
|
|
|
-#define ADD16(a, b, n) \
|
|
|
|
- RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
|
|
|
|
-#define SUB16(a, b, n) \
|
|
|
|
- RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
|
|
|
|
-#define ADD8(a, b, n) \
|
|
|
|
- RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
|
|
|
|
-#define SUB8(a, b, n) \
|
|
|
|
- RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
|
|
|
|
-#define PFX uh
|
|
|
|
-
|
|
|
|
-#include "op_addsub.h"
|
|
|
|
-
|
|
|
|
-static inline uint8_t do_usad(uint8_t a, uint8_t b)
|
|
|
|
-{
|
|
|
|
- if (a > b) {
|
|
|
|
- return a - b;
|
|
|
|
- } else {
|
|
|
|
- return b - a;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Unsigned sum of absolute byte differences. */
|
|
|
|
-uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
|
|
|
|
-{
|
|
|
|
- uint32_t sum;
|
|
|
|
- sum = do_usad(a, b);
|
|
|
|
- sum += do_usad(a >> 8, b >> 8);
|
|
|
|
- sum += do_usad(a >> 16, b >> 16);
|
|
|
|
- sum += do_usad(a >> 24, b >> 24);
|
|
|
|
- return sum;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* For ARMv6 SEL instruction. */
|
|
|
|
-uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
|
|
|
|
-{
|
|
|
|
- uint32_t mask;
|
|
|
|
-
|
|
|
|
- mask = 0;
|
|
|
|
- if (flags & 1) {
|
|
|
|
- mask |= 0xff;
|
|
|
|
- }
|
|
|
|
- if (flags & 2) {
|
|
|
|
- mask |= 0xff00;
|
|
|
|
- }
|
|
|
|
- if (flags & 4) {
|
|
|
|
- mask |= 0xff0000;
|
|
|
|
- }
|
|
|
|
- if (flags & 8) {
|
|
|
|
- mask |= 0xff000000;
|
|
|
|
- }
|
|
|
|
- return (a & mask) | (b & ~mask);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * CRC helpers.
|
|
|
|
- * The upper bytes of val (above the number specified by 'bytes') must have
|
|
|
|
- * been zeroed out by the caller.
|
|
|
|
- */
|
|
|
|
-uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
|
|
|
|
-{
|
|
|
|
- uint8_t buf[4];
|
|
|
|
-
|
|
|
|
- stl_le_p(buf, val);
|
|
|
|
-
|
|
|
|
- /* zlib crc32 converts the accumulator and output to one's complement. */
|
|
|
|
- return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
|
|
|
|
-{
|
|
|
|
- uint8_t buf[4];
|
|
|
|
-
|
|
|
|
- stl_le_p(buf, val);
|
|
|
|
-
|
|
|
|
- /* Linux crc32c converts the output to one's complement. */
|
|
|
|
- return crc32c(acc, buf, bytes) ^ 0xffffffff;
|
|
|
|
-}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Return the exception level to which FP-disabled exceptions should
|
|
* Return the exception level to which FP-disabled exceptions should
|