tcg/optimize: Remove in-flight mask data from OptContext

fpu: Add float*_muladd_scalbn
 fpu: Remove float_muladd_halve_result
 fpu: Add float_round_nearest_even_max
 fpu: Add float_muladd_suppress_add_product_zero
 target/hexagon: Use float32_muladd
 accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmdrE7QdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+l2Qf/aECUfMn07wns7WjX
 ebWxzIRKp//ktsIJg9InL8zrCStyRqrBj0VQE9LUfO2Vhvqf8faUdh+uh2ek/Ewa
 f1hfo0kDK7e7oWnCicSbHmdC0FQIrKpg2i+YXIsbd4XWOkmFAhkNenISuQfCrL3k
 3UYAA12seK9uCls+fljvhK6iid3h+4ReDFW7DPg7mumFCCz6CwzYYW/4cnhcAmOn
 qVehtts8W+6SFMjTE04S8NV8OBaMisf8AbCcZf2PedRl1cHGSumLOjvjOxcQU8Hw
 nGUjL8/hYWkEetzU4YzJyfHOe6F9lPJBMnDattwIswwYrTOD/Sq7VbBWFbW0EwUy
 7XIZ8Q==
 =DZgo
 -----END PGP SIGNATURE-----

Merge tag 'pull-tcg-20241224' of https://gitlab.com/rth7680/qemu into staging

tcg/optimize: Remove in-flight mask data from OptContext
fpu: Add float*_muladd_scalbn
fpu: Remove float_muladd_halve_result
fpu: Add float_round_nearest_even_max
fpu: Add float_muladd_suppress_add_product_zero
target/hexagon: Use float32_muladd
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmdrE7QdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+l2Qf/aECUfMn07wns7WjX
# ebWxzIRKp//ktsIJg9InL8zrCStyRqrBj0VQE9LUfO2Vhvqf8faUdh+uh2ek/Ewa
# f1hfo0kDK7e7oWnCicSbHmdC0FQIrKpg2i+YXIsbd4XWOkmFAhkNenISuQfCrL3k
# 3UYAA12seK9uCls+fljvhK6iid3h+4ReDFW7DPg7mumFCCz6CwzYYW/4cnhcAmOn
# qVehtts8W+6SFMjTE04S8NV8OBaMisf8AbCcZf2PedRl1cHGSumLOjvjOxcQU8Hw
# nGUjL8/hYWkEetzU4YzJyfHOe6F9lPJBMnDattwIswwYrTOD/Sq7VbBWFbW0EwUy
# 7XIZ8Q==
# =DZgo
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 24 Dec 2024 15:04:04 EST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-tcg-20241224' of https://gitlab.com/rth7680/qemu: (72 commits)
  accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core
  target/hexagon: Simplify internal_mpyhh setup
  target/hexagon: Use mulu64 for int128_mul_6464
  target/hexagon: Remove Double
  target/hexagon: Remove Float
  target/hexagon: Expand GEN_XF_ROUND
  target/hexagon: Remove internal_fmafx
  target/hexagon: Use float32_muladd for helper_sffm[as]_lib
  target/hexagon: Use float32_muladd_scalbn for helper_sffma_sc
  target/hexagon: Use float32_muladd for helper_sffms
  target/hexagon: Use float32_muladd for helper_sffma
  target/hexagon: Use float32_mul in helper_sfmpy
  softfloat: Add float_muladd_suppress_add_product_zero
  softfloat: Add float_round_nearest_even_max
  softfloat: Remove float_muladd_halve_result
  target/sparc: Use float*_muladd_scalbn
  target/arm: Use float*_muladd_scalbn
  softfloat: Add float{16,32,64}_muladd_scalbn
  tcg/optimize: Move fold_cmp_vec, fold_cmpsel_vec into alphabetic sort
  tcg/optimize: Move fold_bitsel_vec into alphabetic sort
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2024-12-25 08:33:33 -05:00
commit a7f77545d4
75 changed files with 866 additions and 1009 deletions

View File

@ -1088,11 +1088,13 @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
if (!tcg_target_initialized) { if (!tcg_target_initialized) {
/* Check mandatory TCGCPUOps handlers */ /* Check mandatory TCGCPUOps handlers */
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
assert(cpu->cc->tcg_ops->cpu_exec_halt); assert(tcg_ops->cpu_exec_halt);
assert(cpu->cc->tcg_ops->cpu_exec_interrupt); assert(tcg_ops->cpu_exec_interrupt);
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
cpu->cc->tcg_ops->initialize(); assert(tcg_ops->translate_code);
tcg_ops->initialize();
tcg_target_initialized = true; tcg_target_initialized = true;
} }

View File

@ -102,6 +102,15 @@ static void gen_disable_mem_helper(void)
static TCGv_i32 gen_cpu_index(void) static TCGv_i32 gen_cpu_index(void)
{ {
/*
* Optimize when we run with a single vcpu. All values using cpu_index,
* including scoreboard index, will be optimized out.
* User-mode calls tb_flush when setting this flag. In system-mode, all
* vcpus are created before generating code.
*/
if (!tcg_cflags_has(current_cpu, CF_PARALLEL)) {
return tcg_constant_i32(current_cpu->cpu_index);
}
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32(); TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
tcg_gen_ld_i32(cpu_index, tcg_env, tcg_gen_ld_i32(cpu_index, tcg_env,
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index)); -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));

View File

@ -276,8 +276,10 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
tcg_func_start(tcg_ctx); tcg_func_start(tcg_ctx);
tcg_ctx->cpu = env_cpu(env); CPUState *cs = env_cpu(env);
gen_intermediate_code(env_cpu(env), tb, max_insns, pc, host_pc); tcg_ctx->cpu = cs;
cs->cc->tcg_ops->translate_code(cs, tb, max_insns, pc, host_pc);
assert(tb->size != 0); assert(tb->size != 0);
tcg_ctx->cpu = NULL; tcg_ctx->cpu = NULL;
*max_insns = tb->icount; *max_insns = tb->icount;
@ -364,7 +366,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
/* /*
* Overflow of code_gen_buffer, or the current slice of it. * Overflow of code_gen_buffer, or the current slice of it.
* *
* TODO: We don't need to re-do gen_intermediate_code, nor * TODO: We don't need to re-do tcg_ops->translate_code, nor
* should we re-do the tcg optimization currently hidden * should we re-do the tcg optimization currently hidden
* inside tcg_gen_code. All that should be required is to * inside tcg_gen_code. All that should be required is to
* flush the TBs, allocate a new TB, re-initialize it per * flush the TBs, allocate a new TB, re-initialize it per

View File

@ -241,6 +241,9 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
int exp, flags = 0; int exp, flags = 0;
switch (s->float_rounding_mode) { switch (s->float_rounding_mode) {
case float_round_nearest_even_max:
overflow_norm = true;
/* fall through */
case float_round_nearest_even: case float_round_nearest_even:
if (N > 64 && frac_lsb == 0) { if (N > 64 && frac_lsb == 0) {
inc = ((p->frac_hi & 1) || (p->frac_lo & round_mask) != frac_lsbm1 inc = ((p->frac_hi & 1) || (p->frac_lo & round_mask) != frac_lsbm1
@ -562,8 +565,9 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
* Requires A and C extracted into a double-sized structure to provide the * Requires A and C extracted into a double-sized structure to provide the
* extra space for the widening multiply. * extra space for the widening multiply.
*/ */
static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b, static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
FloatPartsN *c, int flags, float_status *s) FloatPartsN *c, int scale,
int flags, float_status *s)
{ {
int ab_mask, abc_mask; int ab_mask, abc_mask;
FloatPartsW p_widen, c_widen; FloatPartsW p_widen, c_widen;
@ -611,7 +615,9 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
goto return_normal; goto return_normal;
} }
if (c->cls == float_class_zero) { if (c->cls == float_class_zero) {
if (a->sign != c->sign) { if (flags & float_muladd_suppress_add_product_zero) {
a->sign = c->sign;
} else if (a->sign != c->sign) {
goto return_sub_zero; goto return_sub_zero;
} }
goto return_zero; goto return_zero;
@ -652,9 +658,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
a->exp = p_widen.exp; a->exp = p_widen.exp;
return_normal: return_normal:
if (flags & float_muladd_halve_result) { a->exp += scale;
a->exp -= 1;
}
finish_sign: finish_sign:
if (flags & float_muladd_negate_result) { if (flags & float_muladd_negate_result) {
a->sign ^= 1; a->sign ^= 1;

View File

@ -789,15 +789,15 @@ static FloatParts128 *parts128_mul(FloatParts128 *a, FloatParts128 *b,
#define parts_mul(A, B, S) \ #define parts_mul(A, B, S) \
PARTS_GENERIC_64_128(mul, A)(A, B, S) PARTS_GENERIC_64_128(mul, A)(A, B, S)
static FloatParts64 *parts64_muladd(FloatParts64 *a, FloatParts64 *b, static FloatParts64 *parts64_muladd_scalbn(FloatParts64 *a, FloatParts64 *b,
FloatParts64 *c, int flags, FloatParts64 *c, int scale,
float_status *s); int flags, float_status *s);
static FloatParts128 *parts128_muladd(FloatParts128 *a, FloatParts128 *b, static FloatParts128 *parts128_muladd_scalbn(FloatParts128 *a, FloatParts128 *b,
FloatParts128 *c, int flags, FloatParts128 *c, int scale,
float_status *s); int flags, float_status *s);
#define parts_muladd(A, B, C, Z, S) \ #define parts_muladd_scalbn(A, B, C, Z, Y, S) \
PARTS_GENERIC_64_128(muladd, A)(A, B, C, Z, S) PARTS_GENERIC_64_128(muladd_scalbn, A)(A, B, C, Z, Y, S)
static FloatParts64 *parts64_div(FloatParts64 *a, FloatParts64 *b, static FloatParts64 *parts64_div(FloatParts64 *a, FloatParts64 *b,
float_status *s); float_status *s);
@ -2212,43 +2212,50 @@ floatx80_mul(floatx80 a, floatx80 b, float_status *status)
* Fused multiply-add * Fused multiply-add
*/ */
float16 QEMU_FLATTEN float16_muladd(float16 a, float16 b, float16 c, float16 QEMU_FLATTEN
int flags, float_status *status) float16_muladd_scalbn(float16 a, float16 b, float16 c,
int scale, int flags, float_status *status)
{ {
FloatParts64 pa, pb, pc, *pr; FloatParts64 pa, pb, pc, *pr;
float16_unpack_canonical(&pa, a, status); float16_unpack_canonical(&pa, a, status);
float16_unpack_canonical(&pb, b, status); float16_unpack_canonical(&pb, b, status);
float16_unpack_canonical(&pc, c, status); float16_unpack_canonical(&pc, c, status);
pr = parts_muladd(&pa, &pb, &pc, flags, status); pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
return float16_round_pack_canonical(pr, status); return float16_round_pack_canonical(pr, status);
} }
static float32 QEMU_SOFTFLOAT_ATTR float16 float16_muladd(float16 a, float16 b, float16 c,
soft_f32_muladd(float32 a, float32 b, float32 c, int flags, int flags, float_status *status)
float_status *status) {
return float16_muladd_scalbn(a, b, c, 0, flags, status);
}
float32 QEMU_SOFTFLOAT_ATTR
float32_muladd_scalbn(float32 a, float32 b, float32 c,
int scale, int flags, float_status *status)
{ {
FloatParts64 pa, pb, pc, *pr; FloatParts64 pa, pb, pc, *pr;
float32_unpack_canonical(&pa, a, status); float32_unpack_canonical(&pa, a, status);
float32_unpack_canonical(&pb, b, status); float32_unpack_canonical(&pb, b, status);
float32_unpack_canonical(&pc, c, status); float32_unpack_canonical(&pc, c, status);
pr = parts_muladd(&pa, &pb, &pc, flags, status); pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
return float32_round_pack_canonical(pr, status); return float32_round_pack_canonical(pr, status);
} }
static float64 QEMU_SOFTFLOAT_ATTR float64 QEMU_SOFTFLOAT_ATTR
soft_f64_muladd(float64 a, float64 b, float64 c, int flags, float64_muladd_scalbn(float64 a, float64 b, float64 c,
float_status *status) int scale, int flags, float_status *status)
{ {
FloatParts64 pa, pb, pc, *pr; FloatParts64 pa, pb, pc, *pr;
float64_unpack_canonical(&pa, a, status); float64_unpack_canonical(&pa, a, status);
float64_unpack_canonical(&pb, b, status); float64_unpack_canonical(&pb, b, status);
float64_unpack_canonical(&pc, c, status); float64_unpack_canonical(&pc, c, status);
pr = parts_muladd(&pa, &pb, &pc, flags, status); pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
return float64_round_pack_canonical(pr, status); return float64_round_pack_canonical(pr, status);
} }
@ -2267,7 +2274,7 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
if (unlikely(!can_use_fpu(s))) { if (unlikely(!can_use_fpu(s))) {
goto soft; goto soft;
} }
if (unlikely(flags & float_muladd_halve_result)) { if (unlikely(flags & float_muladd_suppress_add_product_zero)) {
goto soft; goto soft;
} }
@ -2323,7 +2330,7 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
return ur.s; return ur.s;
soft: soft:
return soft_f32_muladd(ua.s, ub.s, uc.s, flags, s); return float32_muladd_scalbn(ua.s, ub.s, uc.s, 0, flags, s);
} }
float64 QEMU_FLATTEN float64 QEMU_FLATTEN
@ -2338,9 +2345,6 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
if (unlikely(!can_use_fpu(s))) { if (unlikely(!can_use_fpu(s))) {
goto soft; goto soft;
} }
if (unlikely(flags & float_muladd_halve_result)) {
goto soft;
}
float64_input_flush3(&ua.s, &ub.s, &uc.s, s); float64_input_flush3(&ua.s, &ub.s, &uc.s, s);
if (unlikely(!f64_is_zon3(ua, ub, uc))) { if (unlikely(!f64_is_zon3(ua, ub, uc))) {
@ -2394,7 +2398,7 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
return ur.s; return ur.s;
soft: soft:
return soft_f64_muladd(ua.s, ub.s, uc.s, flags, s); return float64_muladd_scalbn(ua.s, ub.s, uc.s, 0, flags, s);
} }
float64 float64r32_muladd(float64 a, float64 b, float64 c, float64 float64r32_muladd(float64 a, float64 b, float64 c,
@ -2405,7 +2409,7 @@ float64 float64r32_muladd(float64 a, float64 b, float64 c,
float64_unpack_canonical(&pa, a, status); float64_unpack_canonical(&pa, a, status);
float64_unpack_canonical(&pb, b, status); float64_unpack_canonical(&pb, b, status);
float64_unpack_canonical(&pc, c, status); float64_unpack_canonical(&pc, c, status);
pr = parts_muladd(&pa, &pb, &pc, flags, status); pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
return float64r32_round_pack_canonical(pr, status); return float64r32_round_pack_canonical(pr, status);
} }
@ -2418,7 +2422,7 @@ bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
bfloat16_unpack_canonical(&pa, a, status); bfloat16_unpack_canonical(&pa, a, status);
bfloat16_unpack_canonical(&pb, b, status); bfloat16_unpack_canonical(&pb, b, status);
bfloat16_unpack_canonical(&pc, c, status); bfloat16_unpack_canonical(&pc, c, status);
pr = parts_muladd(&pa, &pb, &pc, flags, status); pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
return bfloat16_round_pack_canonical(pr, status); return bfloat16_round_pack_canonical(pr, status);
} }
@ -2431,7 +2435,7 @@ float128 QEMU_FLATTEN float128_muladd(float128 a, float128 b, float128 c,
float128_unpack_canonical(&pa, a, status); float128_unpack_canonical(&pa, a, status);
float128_unpack_canonical(&pb, b, status); float128_unpack_canonical(&pb, b, status);
float128_unpack_canonical(&pc, c, status); float128_unpack_canonical(&pc, c, status);
pr = parts_muladd(&pa, &pb, &pc, flags, status); pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
return float128_round_pack_canonical(pr, status); return float128_round_pack_canonical(pr, status);
} }
@ -5249,8 +5253,9 @@ float32 float32_exp2(float32 a, float_status *status)
float64_unpack_canonical(&rp, float64_one, status); float64_unpack_canonical(&rp, float64_one, status);
for (i = 0 ; i < 15 ; i++) { for (i = 0 ; i < 15 ; i++) {
float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status); float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
rp = *parts_muladd(&tp, &xnp, &rp, 0, status); rp = *parts_muladd_scalbn(&tp, &xnp, &rp, 0, 0, status);
xnp = *parts_mul(&xnp, &xp, status); xnp = *parts_mul(&xnp, &xp, status);
} }

View File

@ -21,20 +21,6 @@
#include "qemu/bswap.h" #include "qemu/bswap.h"
#include "exec/vaddr.h" #include "exec/vaddr.h"
/**
* gen_intermediate_code
* @cpu: cpu context
* @tb: translation block
* @max_insns: max number of instructions to translate
* @pc: guest virtual program counter address
* @host_pc: host physical program counter address
*
* This function must be provided by the target, which should create
* the target-specific DisasContext, and then invoke translator_loop.
*/
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
vaddr pc, void *host_pc);
/** /**
* DisasJumpType: * DisasJumpType:
* @DISAS_NEXT: Next instruction in program order. * @DISAS_NEXT: Next instruction in program order.

View File

@ -140,6 +140,8 @@ typedef enum __attribute__((__packed__)) {
float_round_to_odd = 5, float_round_to_odd = 5,
/* Not an IEEE rounding mode: round to closest odd, overflow to inf */ /* Not an IEEE rounding mode: round to closest odd, overflow to inf */
float_round_to_odd_inf = 6, float_round_to_odd_inf = 6,
/* Not an IEEE rounding mode: round to nearest even, overflow to max */
float_round_nearest_even_max = 7,
} FloatRoundMode; } FloatRoundMode;
/* /*

View File

@ -120,14 +120,16 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
| Using these differs from negating an input or output before calling | Using these differs from negating an input or output before calling
| the muladd function in that this means that a NaN doesn't have its | the muladd function in that this means that a NaN doesn't have its
| sign bit inverted before it is propagated. | sign bit inverted before it is propagated.
| We also support halving the result before rounding, as a special |
| case to support the ARM fused-sqrt-step instruction FRSQRTS. | With float_muladd_suppress_add_product_zero, if A or B is zero
| such that the product is a true zero, then return C without addition.
| This preserves the sign of C when C is +/- 0. Used for Hexagon.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
enum { enum {
float_muladd_negate_c = 1, float_muladd_negate_c = 1,
float_muladd_negate_product = 2, float_muladd_negate_product = 2,
float_muladd_negate_result = 4, float_muladd_negate_result = 4,
float_muladd_halve_result = 8, float_muladd_suppress_add_product_zero = 8,
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -238,6 +240,8 @@ float16 float16_add(float16, float16, float_status *status);
float16 float16_sub(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status);
float16 float16_mul(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status);
float16 float16_muladd(float16, float16, float16, int, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *status);
float16 float16_muladd_scalbn(float16, float16, float16,
int, int, float_status *status);
float16 float16_div(float16, float16, float_status *status); float16 float16_div(float16, float16, float_status *status);
float16 float16_scalbn(float16, int, float_status *status); float16 float16_scalbn(float16, int, float_status *status);
float16 float16_min(float16, float16, float_status *status); float16 float16_min(float16, float16, float_status *status);
@ -597,6 +601,8 @@ float32 float32_mul(float32, float32, float_status *status);
float32 float32_div(float32, float32, float_status *status); float32 float32_div(float32, float32, float_status *status);
float32 float32_rem(float32, float32, float_status *status); float32 float32_rem(float32, float32, float_status *status);
float32 float32_muladd(float32, float32, float32, int, float_status *status); float32 float32_muladd(float32, float32, float32, int, float_status *status);
float32 float32_muladd_scalbn(float32, float32, float32,
int, int, float_status *status);
float32 float32_sqrt(float32, float_status *status); float32 float32_sqrt(float32, float_status *status);
float32 float32_exp2(float32, float_status *status); float32 float32_exp2(float32, float_status *status);
float32 float32_log2(float32, float_status *status); float32 float32_log2(float32, float_status *status);
@ -792,6 +798,8 @@ float64 float64_mul(float64, float64, float_status *status);
float64 float64_div(float64, float64, float_status *status); float64 float64_div(float64, float64, float_status *status);
float64 float64_rem(float64, float64, float_status *status); float64 float64_rem(float64, float64, float_status *status);
float64 float64_muladd(float64, float64, float64, int, float_status *status); float64 float64_muladd(float64, float64, float64, int, float_status *status);
float64 float64_muladd_scalbn(float64, float64, float64,
int, int, float_status *status);
float64 float64_sqrt(float64, float_status *status); float64 float64_sqrt(float64, float_status *status);
float64 float64_log2(float64, float_status *status); float64 float64_log2(float64, float_status *status);
FloatRelation float64_compare(float64, float64, float_status *status); FloatRelation float64_compare(float64, float64, float_status *status);

View File

@ -24,6 +24,19 @@ struct TCGCPUOps {
* Called when the first CPU is realized. * Called when the first CPU is realized.
*/ */
void (*initialize)(void); void (*initialize)(void);
/**
* @translate_code: Translate guest instructions to TCGOps
* @cpu: cpu context
* @tb: translation block
* @max_insns: max number of instructions to translate
* @pc: guest virtual program counter address
* @host_pc: host physical program counter address
*
* This function must be provided by the target, which should create
* the target-specific DisasContext, and then invoke translator_loop.
*/
void (*translate_code)(CPUState *cpu, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
/** /**
* @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock * @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock
* *

View File

@ -224,6 +224,7 @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
static const TCGCPUOps alpha_tcg_ops = { static const TCGCPUOps alpha_tcg_ops = {
.initialize = alpha_translate_init, .initialize = alpha_translate_init,
.translate_code = alpha_translate_code,
.synchronize_from_tb = alpha_cpu_synchronize_from_tb, .synchronize_from_tb = alpha_cpu_synchronize_from_tb,
.restore_state_to_opc = alpha_restore_state_to_opc, .restore_state_to_opc = alpha_restore_state_to_opc,

View File

@ -431,6 +431,8 @@ enum {
}; };
void alpha_translate_init(void); void alpha_translate_init(void);
void alpha_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
#define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU

View File

@ -2955,8 +2955,8 @@ static const TranslatorOps alpha_tr_ops = {
.tb_stop = alpha_tr_tb_stop, .tb_stop = alpha_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, void alpha_translate_code(CPUState *cpu, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc; DisasContext dc;
translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base); translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);

View File

@ -2682,6 +2682,7 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
#ifdef CONFIG_TCG #ifdef CONFIG_TCG
static const TCGCPUOps arm_tcg_ops = { static const TCGCPUOps arm_tcg_ops = {
.initialize = arm_translate_init, .initialize = arm_translate_init,
.translate_code = arm_translate_code,
.synchronize_from_tb = arm_cpu_synchronize_from_tb, .synchronize_from_tb = arm_cpu_synchronize_from_tb,
.debug_excp_handler = arm_debug_excp_handler, .debug_excp_handler = arm_debug_excp_handler,
.restore_state_to_opc = arm_restore_state_to_opc, .restore_state_to_opc = arm_restore_state_to_opc,

View File

@ -357,6 +357,8 @@ void init_cpreg_list(ARMCPU *cpu);
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu); void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
void arm_translate_init(void); void arm_translate_init(void);
void arm_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void arm_cpu_register_gdb_commands(ARMCPU *cpu); void arm_cpu_register_gdb_commands(ARMCPU *cpu);
void aarch64_cpu_register_gdb_commands(ARMCPU *cpu, GString *, void aarch64_cpu_register_gdb_commands(ARMCPU *cpu, GString *,

View File

@ -234,6 +234,7 @@ static void cortex_m55_initfn(Object *obj)
static const TCGCPUOps arm_v7m_tcg_ops = { static const TCGCPUOps arm_v7m_tcg_ops = {
.initialize = arm_translate_init, .initialize = arm_translate_init,
.translate_code = arm_translate_code,
.synchronize_from_tb = arm_cpu_synchronize_from_tb, .synchronize_from_tb = arm_cpu_synchronize_from_tb,
.debug_excp_handler = arm_debug_excp_handler, .debug_excp_handler = arm_debug_excp_handler,
.restore_state_to_opc = arm_restore_state_to_opc, .restore_state_to_opc = arm_restore_state_to_opc,

View File

@ -262,7 +262,7 @@ uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, float_status *fpst)
(float16_is_infinity(b) && float16_is_zero(a))) { (float16_is_infinity(b) && float16_is_zero(a))) {
return float16_one_point_five; return float16_one_point_five;
} }
return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst); return float16_muladd_scalbn(a, b, float16_three, -1, 0, fpst);
} }
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst) float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
@ -275,7 +275,7 @@ float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
(float32_is_infinity(b) && float32_is_zero(a))) { (float32_is_infinity(b) && float32_is_zero(a))) {
return float32_one_point_five; return float32_one_point_five;
} }
return float32_muladd(a, b, float32_three, float_muladd_halve_result, fpst); return float32_muladd_scalbn(a, b, float32_three, -1, 0, fpst);
} }
float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst) float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
@ -288,7 +288,7 @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
(float64_is_infinity(b) && float64_is_zero(a))) { (float64_is_infinity(b) && float64_is_zero(a))) {
return float64_one_point_five; return float64_one_point_five;
} }
return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst); return float64_muladd_scalbn(a, b, float64_three, -1, 0, fpst);
} }
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */ /* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */

View File

@ -8093,9 +8093,8 @@ static const TranslatorOps thumb_translator_ops = {
.tb_stop = arm_tr_tb_stop, .tb_stop = arm_tr_tb_stop,
}; };
/* generate intermediate code for basic block 'tb'. */ void arm_translate_code(CPUState *cpu, TranslationBlock *tb,
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, int *max_insns, vaddr pc, void *host_pc)
vaddr pc, void *host_pc)
{ {
DisasContext dc = { }; DisasContext dc = { };
const TranslatorOps *ops = &arm_translator_ops; const TranslatorOps *ops = &arm_translator_ops;

View File

@ -207,6 +207,7 @@ static const struct SysemuCPUOps avr_sysemu_ops = {
static const TCGCPUOps avr_tcg_ops = { static const TCGCPUOps avr_tcg_ops = {
.initialize = avr_cpu_tcg_init, .initialize = avr_cpu_tcg_init,
.translate_code = avr_cpu_translate_code,
.synchronize_from_tb = avr_cpu_synchronize_from_tb, .synchronize_from_tb = avr_cpu_synchronize_from_tb,
.restore_state_to_opc = avr_restore_state_to_opc, .restore_state_to_opc = avr_restore_state_to_opc,
.cpu_exec_interrupt = avr_cpu_exec_interrupt, .cpu_exec_interrupt = avr_cpu_exec_interrupt,

View File

@ -183,6 +183,8 @@ static inline void set_avr_feature(CPUAVRState *env, int feature)
} }
void avr_cpu_tcg_init(void); void avr_cpu_tcg_init(void);
void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
int cpu_avr_exec(CPUState *cpu); int cpu_avr_exec(CPUState *cpu);

View File

@ -2599,7 +2599,7 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
* *
* - translate() * - translate()
* - canonicalize_skip() * - canonicalize_skip()
* - gen_intermediate_code() * - translate_code()
* - restore_state_to_opc() * - restore_state_to_opc()
* *
*/ */
@ -2795,8 +2795,8 @@ static const TranslatorOps avr_tr_ops = {
.tb_stop = avr_tr_tb_stop, .tb_stop = avr_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc = { }; DisasContext dc = { };
translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base); translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);

View File

@ -325,6 +325,7 @@ static void hexagon_cpu_init(Object *obj)
static const TCGCPUOps hexagon_tcg_ops = { static const TCGCPUOps hexagon_tcg_ops = {
.initialize = hexagon_translate_init, .initialize = hexagon_translate_init,
.translate_code = hexagon_translate_code,
.synchronize_from_tb = hexagon_cpu_synchronize_from_tb, .synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
.restore_state_to_opc = hexagon_restore_state_to_opc, .restore_state_to_opc = hexagon_restore_state_to_opc,
}; };

View File

@ -150,6 +150,8 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
typedef HexagonCPU ArchCPU; typedef HexagonCPU ArchCPU;
void hexagon_translate_init(void); void hexagon_translate_init(void);
void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
#include "exec/cpu-all.h" #include "exec/cpu-all.h"

View File

@ -43,112 +43,51 @@
#define WAY_BIG_EXP 4096 #define WAY_BIG_EXP 4096
typedef union {
double f;
uint64_t i;
struct {
uint64_t mant:52;
uint64_t exp:11;
uint64_t sign:1;
};
} Double;
typedef union {
float f;
uint32_t i;
struct {
uint32_t mant:23;
uint32_t exp:8;
uint32_t sign:1;
};
} Float;
static uint64_t float64_getmant(float64 f64) static uint64_t float64_getmant(float64 f64)
{ {
Double a = { .i = f64 }; uint64_t mant = extract64(f64, 0, 52);
if (float64_is_normal(f64)) { if (float64_is_normal(f64)) {
return a.mant | 1ULL << 52; return mant | 1ULL << 52;
} }
if (float64_is_zero(f64)) { if (float64_is_zero(f64)) {
return 0; return 0;
} }
if (float64_is_denormal(f64)) { if (float64_is_denormal(f64)) {
return a.mant; return mant;
} }
return ~0ULL; return ~0ULL;
} }
int32_t float64_getexp(float64 f64) int32_t float64_getexp(float64 f64)
{ {
Double a = { .i = f64 }; int exp = extract64(f64, 52, 11);
if (float64_is_normal(f64)) { if (float64_is_normal(f64)) {
return a.exp; return exp;
} }
if (float64_is_denormal(f64)) { if (float64_is_denormal(f64)) {
return a.exp + 1; return exp + 1;
} }
return -1; return -1;
} }
static uint64_t float32_getmant(float32 f32)
{
Float a = { .i = f32 };
if (float32_is_normal(f32)) {
return a.mant | 1ULL << 23;
}
if (float32_is_zero(f32)) {
return 0;
}
if (float32_is_denormal(f32)) {
return a.mant;
}
return ~0ULL;
}
int32_t float32_getexp(float32 f32) int32_t float32_getexp(float32 f32)
{ {
Float a = { .i = f32 }; int exp = float32_getexp_raw(f32);
if (float32_is_normal(f32)) { if (float32_is_normal(f32)) {
return a.exp; return exp;
} }
if (float32_is_denormal(f32)) { if (float32_is_denormal(f32)) {
return a.exp + 1; return exp + 1;
} }
return -1; return -1;
} }
static uint32_t int128_getw0(Int128 x)
{
return int128_getlo(x);
}
static uint32_t int128_getw1(Int128 x)
{
return int128_getlo(x) >> 32;
}
static Int128 int128_mul_6464(uint64_t ai, uint64_t bi) static Int128 int128_mul_6464(uint64_t ai, uint64_t bi)
{ {
Int128 a, b; uint64_t l, h;
uint64_t pp0, pp1a, pp1b, pp1s, pp2;
a = int128_make64(ai); mulu64(&l, &h, ai, bi);
b = int128_make64(bi); return int128_make128(l, h);
pp0 = (uint64_t)int128_getw0(a) * (uint64_t)int128_getw0(b);
pp1a = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw0(b);
pp1b = (uint64_t)int128_getw1(b) * (uint64_t)int128_getw0(a);
pp2 = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw1(b);
pp1s = pp1a + pp1b;
if ((pp1s < pp1a) || (pp1s < pp1b)) {
pp2 += (1ULL << 32);
}
uint64_t ret_low = pp0 + (pp1s << 32);
if ((ret_low < pp0) || (ret_low < (pp1s << 32))) {
pp2 += 1;
}
return int128_make128(ret_low, pp2 + (pp1s >> 32));
} }
static Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow) static Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow)
@ -369,298 +308,129 @@ float32 infinite_float32(uint8_t sign)
} }
/* Return a maximum finite value with the requested sign */ /* Return a maximum finite value with the requested sign */
static float32 maxfinite_float32(uint8_t sign) static float64 accum_round_float64(Accum a, float_status *fp_status)
{ {
if (sign) { uint64_t ret;
return make_float32(SF_MINUS_MAXF);
if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0)
&& ((a.guard | a.round | a.sticky) == 0)) {
/* result zero */
switch (fp_status->float_rounding_mode) {
case float_round_down:
return zero_float64(1);
default:
return zero_float64(0);
}
}
/*
* Normalize right
* We want DF_MANTBITS bits of mantissa plus the leading one.
* That means that we want DF_MANTBITS+1 bits, or 0x000000000000FF_FFFF
* So we need to normalize right while the high word is non-zero and
* while the low word is nonzero when masked with 0xffe0_0000_0000_0000
*/
while ((int128_gethi(a.mant) != 0) ||
((int128_getlo(a.mant) >> (DF_MANTBITS + 1)) != 0)) {
a = accum_norm_right(a, 1);
}
/*
* OK, now normalize left
* We want to normalize left until we have a leading one in bit 24
* Theoretically, we only need to shift a maximum of one to the left if we
* shifted out lots of bits from B, or if we had no shift / 1 shift sticky
* should be 0
*/
while ((int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) == 0) {
a = accum_norm_left(a);
}
/*
* OK, now we might need to denormalize because of potential underflow.
* We need to do this before rounding, and rounding might make us normal
* again
*/
while (a.exp <= 0) {
a = accum_norm_right(a, 1 - a.exp);
/*
* Do we have underflow?
* That's when we get an inexact answer because we ran out of bits
* in a denormal.
*/
if (a.guard || a.round || a.sticky) {
float_raise(float_flag_underflow, fp_status);
}
}
/* OK, we're relatively canonical... now we need to round */
if (a.guard || a.round || a.sticky) {
float_raise(float_flag_inexact, fp_status);
switch (fp_status->float_rounding_mode) {
case float_round_to_zero:
/* Chop and we're done */
break;
case float_round_up:
if (a.sign == 0) {
a.mant = int128_add(a.mant, int128_one());
}
break;
case float_round_down:
if (a.sign != 0) {
a.mant = int128_add(a.mant, int128_one());
}
break;
default:
if (a.round || a.sticky) {
/* round up if guard is 1, down if guard is zero */
a.mant = int128_add(a.mant, int128_make64(a.guard));
} else if (a.guard) {
/* exactly .5, round up if odd */
a.mant = int128_add(a.mant, int128_and(a.mant, int128_one()));
}
break;
}
}
/*
* OK, now we might have carried all the way up.
* So we might need to shr once
* at least we know that the lsb should be zero if we rounded and
* got a carry out...
*/
if ((int128_getlo(a.mant) >> (DF_MANTBITS + 1)) != 0) {
a = accum_norm_right(a, 1);
}
/* Overflow? */
if (a.exp >= DF_INF_EXP) {
/* Yep, inf result */
float_raise(float_flag_overflow, fp_status);
float_raise(float_flag_inexact, fp_status);
switch (fp_status->float_rounding_mode) {
case float_round_to_zero:
return maxfinite_float64(a.sign);
case float_round_up:
if (a.sign == 0) {
return infinite_float64(a.sign);
} else { } else {
return make_float32(SF_MAXF); return maxfinite_float64(a.sign);
} }
} case float_round_down:
if (a.sign != 0) {
/* Return a zero value with requested sign */ return infinite_float64(a.sign);
static float32 zero_float32(uint8_t sign)
{
if (sign) {
return make_float32(0x80000000);
} else { } else {
return float32_zero; return maxfinite_float64(a.sign);
} }
} default:
return infinite_float64(a.sign);
#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
{ \
if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) \
&& ((a.guard | a.round | a.sticky) == 0)) { \
/* result zero */ \
switch (fp_status->float_rounding_mode) { \
case float_round_down: \
return zero_##SUFFIX(1); \
default: \
return zero_##SUFFIX(0); \
} \
} \
/* Normalize right */ \
/* We want MANTBITS bits of mantissa plus the leading one. */ \
/* That means that we want MANTBITS+1 bits, or 0x000000000000FF_FFFF */ \
/* So we need to normalize right while the high word is non-zero and \
* while the low word is nonzero when masked with 0xffe0_0000_0000_0000 */ \
while ((int128_gethi(a.mant) != 0) || \
((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0)) { \
a = accum_norm_right(a, 1); \
} \
/* \
* OK, now normalize left \
* We want to normalize left until we have a leading one in bit 24 \
* Theoretically, we only need to shift a maximum of one to the left if we \
* shifted out lots of bits from B, or if we had no shift / 1 shift sticky \
* should be 0 \
*/ \
while ((int128_getlo(a.mant) & (1ULL << MANTBITS)) == 0) { \
a = accum_norm_left(a); \
} \
/* \
* OK, now we might need to denormalize because of potential underflow. \
* We need to do this before rounding, and rounding might make us normal \
* again \
*/ \
while (a.exp <= 0) { \
a = accum_norm_right(a, 1 - a.exp); \
/* \
* Do we have underflow? \
* That's when we get an inexact answer because we ran out of bits \
* in a denormal. \
*/ \
if (a.guard || a.round || a.sticky) { \
float_raise(float_flag_underflow, fp_status); \
} \
} \
/* OK, we're relatively canonical... now we need to round */ \
if (a.guard || a.round || a.sticky) { \
float_raise(float_flag_inexact, fp_status); \
switch (fp_status->float_rounding_mode) { \
case float_round_to_zero: \
/* Chop and we're done */ \
break; \
case float_round_up: \
if (a.sign == 0) { \
a.mant = int128_add(a.mant, int128_one()); \
} \
break; \
case float_round_down: \
if (a.sign != 0) { \
a.mant = int128_add(a.mant, int128_one()); \
} \
break; \
default: \
if (a.round || a.sticky) { \
/* round up if guard is 1, down if guard is zero */ \
a.mant = int128_add(a.mant, int128_make64(a.guard)); \
} else if (a.guard) { \
/* exactly .5, round up if odd */ \
a.mant = int128_add(a.mant, int128_and(a.mant, int128_one())); \
} \
break; \
} \
} \
/* \
* OK, now we might have carried all the way up. \
* So we might need to shr once \
* at least we know that the lsb should be zero if we rounded and \
* got a carry out... \
*/ \
if ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0) { \
a = accum_norm_right(a, 1); \
} \
/* Overflow? */ \
if (a.exp >= INF_EXP) { \
/* Yep, inf result */ \
float_raise(float_flag_overflow, fp_status); \
float_raise(float_flag_inexact, fp_status); \
switch (fp_status->float_rounding_mode) { \
case float_round_to_zero: \
return maxfinite_##SUFFIX(a.sign); \
case float_round_up: \
if (a.sign == 0) { \
return infinite_##SUFFIX(a.sign); \
} else { \
return maxfinite_##SUFFIX(a.sign); \
} \
case float_round_down: \
if (a.sign != 0) { \
return infinite_##SUFFIX(a.sign); \
} else { \
return maxfinite_##SUFFIX(a.sign); \
} \
default: \
return infinite_##SUFFIX(a.sign); \
} \
} \
/* Underflow? */ \
if (int128_getlo(a.mant) & (1ULL << MANTBITS)) { \
/* Leading one means: No, we're normal. So, we should be done... */ \
INTERNAL_TYPE ret; \
ret.i = 0; \
ret.sign = a.sign; \
ret.exp = a.exp; \
ret.mant = int128_getlo(a.mant); \
return ret.i; \
} \
assert(a.exp == 1); \
INTERNAL_TYPE ret; \
ret.i = 0; \
ret.sign = a.sign; \
ret.exp = 0; \
ret.mant = int128_getlo(a.mant); \
return ret.i; \
}
GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double)
GEN_XF_ROUND(float32, SF_MANTBITS, SF_INF_EXP, Float)
static bool is_inf_prod(float64 a, float64 b)
{
return ((float64_is_infinity(a) && float64_is_infinity(b)) ||
(float64_is_infinity(a) && is_finite(b) && (!float64_is_zero(b))) ||
(float64_is_infinity(b) && is_finite(a) && (!float64_is_zero(a))));
}
static float64 special_fma(float64 a, float64 b, float64 c,
float_status *fp_status)
{
float64 ret = make_float64(0);
/*
* If A multiplied by B is an exact infinity and C is also an infinity
* but with the opposite sign, FMA returns NaN and raises invalid.
*/
uint8_t a_sign = float64_is_neg(a);
uint8_t b_sign = float64_is_neg(b);
uint8_t c_sign = float64_is_neg(c);
if (is_inf_prod(a, b) && float64_is_infinity(c)) {
if ((a_sign ^ b_sign) != c_sign) {
ret = make_float64(DF_NAN);
float_raise(float_flag_invalid, fp_status);
return ret;
} }
} }
if ((float64_is_infinity(a) && float64_is_zero(b)) || /* Underflow? */
(float64_is_zero(a) && float64_is_infinity(b))) { ret = int128_getlo(a.mant);
ret = make_float64(DF_NAN); if (ret & (1ULL << DF_MANTBITS)) {
float_raise(float_flag_invalid, fp_status); /* Leading one means: No, we're normal. So, we should be done... */
return ret; ret = deposit64(ret, 52, 11, a.exp);
}
/*
* If none of the above checks are true and C is a NaN,
* a NaN shall be returned
* If A or B are NaN, a NAN shall be returned.
*/
if (float64_is_any_nan(a) ||
float64_is_any_nan(b) ||
float64_is_any_nan(c)) {
if (float64_is_any_nan(a) && (fGETBIT(51, a) == 0)) {
float_raise(float_flag_invalid, fp_status);
}
if (float64_is_any_nan(b) && (fGETBIT(51, b) == 0)) {
float_raise(float_flag_invalid, fp_status);
}
if (float64_is_any_nan(c) && (fGETBIT(51, c) == 0)) {
float_raise(float_flag_invalid, fp_status);
}
ret = make_float64(DF_NAN);
return ret;
}
/*
* We have checked for adding opposite-signed infinities.
* Other infinities return infinity with the correct sign
*/
if (float64_is_infinity(c)) {
ret = infinite_float64(c_sign);
return ret;
}
if (float64_is_infinity(a) || float64_is_infinity(b)) {
ret = infinite_float64(a_sign ^ b_sign);
return ret;
}
g_assert_not_reached();
}
static float32 special_fmaf(float32 a, float32 b, float32 c,
float_status *fp_status)
{
float64 aa, bb, cc;
aa = float32_to_float64(a, fp_status);
bb = float32_to_float64(b, fp_status);
cc = float32_to_float64(c, fp_status);
return float64_to_float32(special_fma(aa, bb, cc, fp_status), fp_status);
}
float32 internal_fmafx(float32 a, float32 b, float32 c, int scale,
float_status *fp_status)
{
Accum prod;
Accum acc;
Accum result;
accum_init(&prod);
accum_init(&acc);
accum_init(&result);
uint8_t a_sign = float32_is_neg(a);
uint8_t b_sign = float32_is_neg(b);
uint8_t c_sign = float32_is_neg(c);
if (float32_is_infinity(a) ||
float32_is_infinity(b) ||
float32_is_infinity(c)) {
return special_fmaf(a, b, c, fp_status);
}
if (float32_is_any_nan(a) ||
float32_is_any_nan(b) ||
float32_is_any_nan(c)) {
return special_fmaf(a, b, c, fp_status);
}
if ((scale == 0) && (float32_is_zero(a) || float32_is_zero(b))) {
float32 tmp = float32_mul(a, b, fp_status);
tmp = float32_add(tmp, c, fp_status);
return tmp;
}
/* (a * 2**b) * (c * 2**d) == a*c * 2**(b+d) */
prod.mant = int128_mul_6464(float32_getmant(a), float32_getmant(b));
/*
* Note: extracting the mantissa into an int is multiplying by
* 2**23, so adjust here
*/
prod.exp = float32_getexp(a) + float32_getexp(b) - SF_BIAS - 23;
prod.sign = a_sign ^ b_sign;
if (float32_is_zero(a) || float32_is_zero(b)) {
prod.exp = -2 * WAY_BIG_EXP;
}
if ((scale > 0) && float32_is_denormal(c)) {
acc.mant = int128_mul_6464(0, 0);
acc.exp = -WAY_BIG_EXP;
acc.sign = c_sign;
acc.sticky = 1;
result = accum_add(prod, acc);
} else if (!float32_is_zero(c)) {
acc.mant = int128_mul_6464(float32_getmant(c), 1);
acc.exp = float32_getexp(c);
acc.sign = c_sign;
result = accum_add(prod, acc);
} else { } else {
result = prod; assert(a.exp == 1);
ret = deposit64(ret, 52, 11, 0);
} }
result.exp += scale; ret = deposit64(ret, 63, 1, a.sign);
return accum_round_float32(result, fp_status); return ret;
}
float32 internal_mpyf(float32 a, float32 b, float_status *fp_status)
{
if (float32_is_zero(a) || float32_is_zero(b)) {
return float32_mul(a, b, fp_status);
}
return internal_fmafx(a, b, float32_zero, 0, fp_status);
} }
float64 internal_mpyhh(float64 a, float64 b, float64 internal_mpyhh(float64 a, float64 b,
@ -685,7 +455,7 @@ float64 internal_mpyhh(float64 a, float64 b,
float64_is_infinity(b)) { float64_is_infinity(b)) {
return float64_mul(a, b, fp_status); return float64_mul(a, b, fp_status);
} }
x.mant = int128_mul_6464(accumulated, 1); x.mant = int128_make64(accumulated);
x.sticky = sticky; x.sticky = sticky;
prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b)); prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b));
x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL)); x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL));

View File

@ -30,9 +30,6 @@ static inline uint32_t float32_getexp_raw(float32 f32)
} }
int32_t float32_getexp(float32 f32); int32_t float32_getexp(float32 f32);
float32 infinite_float32(uint8_t sign); float32 infinite_float32(uint8_t sign);
float32 internal_fmafx(float32 a, float32 b, float32 c,
int scale, float_status *fp_status);
float32 internal_mpyf(float32 a, float32 b, float_status *fp_status);
float64 internal_mpyhh(float64 a, float64 b, float64 internal_mpyhh(float64 a, float64 b,
unsigned long long int accumulated, unsigned long long int accumulated,
float_status *fp_status); float_status *fp_status);

View File

@ -1045,7 +1045,7 @@ float32 HELPER(sfmpy)(CPUHexagonState *env, float32 RsV, float32 RtV)
{ {
float32 RdV; float32 RdV;
arch_fpop_start(env); arch_fpop_start(env);
RdV = internal_mpyf(RsV, RtV, &env->fp_status); RdV = float32_mul(RsV, RtV, &env->fp_status);
arch_fpop_end(env); arch_fpop_end(env);
return RdV; return RdV;
} }
@ -1054,41 +1054,18 @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
float32 RsV, float32 RtV) float32 RsV, float32 RtV)
{ {
arch_fpop_start(env); arch_fpop_start(env);
RxV = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status); RxV = float32_muladd(RsV, RtV, RxV, 0, &env->fp_status);
arch_fpop_end(env); arch_fpop_end(env);
return RxV; return RxV;
} }
static bool is_zero_prod(float32 a, float32 b)
{
return ((float32_is_zero(a) && is_finite(b)) ||
(float32_is_zero(b) && is_finite(a)));
}
static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
{
float32 ret = dst;
if (float32_is_any_nan(x)) {
if (extract32(x, 22, 1) == 0) {
float_raise(float_flag_invalid, fp_status);
}
ret = make_float32(0xffffffff); /* nan */
}
return ret;
}
float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV, float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
float32 RsV, float32 RtV, float32 PuV) float32 RsV, float32 RtV, float32 PuV)
{ {
size4s_t tmp;
arch_fpop_start(env); arch_fpop_start(env);
RxV = check_nan(RxV, RxV, &env->fp_status); RxV = float32_muladd_scalbn(RsV, RtV, RxV, fSXTN(8, 64, PuV),
RxV = check_nan(RxV, RsV, &env->fp_status); float_muladd_suppress_add_product_zero,
RxV = check_nan(RxV, RtV, &env->fp_status); &env->fp_status);
tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status);
if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
RxV = tmp;
}
arch_fpop_end(env); arch_fpop_end(env);
return RxV; return RxV;
} }
@ -1096,86 +1073,50 @@ float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV, float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
float32 RsV, float32 RtV) float32 RsV, float32 RtV)
{ {
float32 neg_RsV;
arch_fpop_start(env); arch_fpop_start(env);
neg_RsV = float32_set_sign(RsV, float32_is_neg(RsV) ? 0 : 1); RxV = float32_muladd(RsV, RtV, RxV, float_muladd_negate_product,
RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status); &env->fp_status);
arch_fpop_end(env); arch_fpop_end(env);
return RxV; return RxV;
} }
static bool is_inf_prod(int32_t a, int32_t b) static float32 do_sffma_lib(CPUHexagonState *env, float32 RxV,
float32 RsV, float32 RtV, int negate)
{ {
return (float32_is_infinity(a) && float32_is_infinity(b)) || int flags;
(float32_is_infinity(a) && is_finite(b) && !float32_is_zero(b)) ||
(float32_is_infinity(b) && is_finite(a) && !float32_is_zero(a)); arch_fpop_start(env);
set_float_rounding_mode(float_round_nearest_even_max, &env->fp_status);
RxV = float32_muladd(RsV, RtV, RxV,
negate | float_muladd_suppress_add_product_zero,
&env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
if (flags) {
/* Flags are suppressed by this instruction. */
set_float_exception_flags(0, &env->fp_status);
/* Return 0 for Inf - Inf. */
if (flags & float_flag_invalid_isi) {
RxV = 0;
}
}
arch_fpop_end(env);
return RxV;
} }
float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV, float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV,
float32 RsV, float32 RtV) float32 RsV, float32 RtV)
{ {
bool infinp; return do_sffma_lib(env, RxV, RsV, RtV, 0);
bool infminusinf;
float32 tmp;
arch_fpop_start(env);
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
infminusinf = float32_is_infinity(RxV) &&
is_inf_prod(RsV, RtV) &&
(fGETBIT(31, RsV ^ RxV ^ RtV) != 0);
infinp = float32_is_infinity(RxV) ||
float32_is_infinity(RtV) ||
float32_is_infinity(RsV);
RxV = check_nan(RxV, RxV, &env->fp_status);
RxV = check_nan(RxV, RsV, &env->fp_status);
RxV = check_nan(RxV, RtV, &env->fp_status);
tmp = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
RxV = tmp;
}
set_float_exception_flags(0, &env->fp_status);
if (float32_is_infinity(RxV) && !infinp) {
RxV = RxV - 1;
}
if (infminusinf) {
RxV = 0;
}
arch_fpop_end(env);
return RxV;
} }
float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV, float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV,
float32 RsV, float32 RtV) float32 RsV, float32 RtV)
{ {
bool infinp; return do_sffma_lib(env, RxV, RsV, RtV, float_muladd_negate_product);
bool infminusinf;
float32 tmp;
arch_fpop_start(env);
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
infminusinf = float32_is_infinity(RxV) &&
is_inf_prod(RsV, RtV) &&
(fGETBIT(31, RsV ^ RxV ^ RtV) == 0);
infinp = float32_is_infinity(RxV) ||
float32_is_infinity(RtV) ||
float32_is_infinity(RsV);
RxV = check_nan(RxV, RxV, &env->fp_status);
RxV = check_nan(RxV, RsV, &env->fp_status);
RxV = check_nan(RxV, RtV, &env->fp_status);
float32 minus_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
tmp = internal_fmafx(minus_RsV, RtV, RxV, 0, &env->fp_status);
if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
RxV = tmp;
}
set_float_exception_flags(0, &env->fp_status);
if (float32_is_infinity(RxV) && !infinp) {
RxV = RxV - 1;
}
if (infminusinf) {
RxV = 0;
}
arch_fpop_end(env);
return RxV;
} }
float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV) float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV)

View File

@ -1026,8 +1026,8 @@ static const TranslatorOps hexagon_tr_ops = {
.tb_stop = hexagon_tr_tb_stop, .tb_stop = hexagon_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -223,6 +223,7 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
static const TCGCPUOps hppa_tcg_ops = { static const TCGCPUOps hppa_tcg_ops = {
.initialize = hppa_translate_init, .initialize = hppa_translate_init,
.translate_code = hppa_translate_code,
.synchronize_from_tb = hppa_cpu_synchronize_from_tb, .synchronize_from_tb = hppa_cpu_synchronize_from_tb,
.restore_state_to_opc = hppa_restore_state_to_opc, .restore_state_to_opc = hppa_restore_state_to_opc,

View File

@ -303,6 +303,8 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
} }
void hppa_translate_init(void); void hppa_translate_init(void);
void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU

View File

@ -4869,8 +4869,8 @@ static const TranslatorOps hppa_tr_ops = {
#endif #endif
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx = { }; DisasContext ctx = { };
translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base); translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);

View File

@ -59,6 +59,8 @@ static inline target_long lshift(target_long x, int n)
/* translate.c */ /* translate.c */
void tcg_x86_init(void); void tcg_x86_init(void);
void x86_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
/* excp_helper.c */ /* excp_helper.c */
G_NORETURN void raise_exception(CPUX86State *env, int exception_index); G_NORETURN void raise_exception(CPUX86State *env, int exception_index);

View File

@ -109,6 +109,7 @@ static bool x86_debug_check_breakpoint(CPUState *cs)
static const TCGCPUOps x86_tcg_ops = { static const TCGCPUOps x86_tcg_ops = {
.initialize = tcg_x86_init, .initialize = tcg_x86_init,
.translate_code = x86_translate_code,
.synchronize_from_tb = x86_cpu_synchronize_from_tb, .synchronize_from_tb = x86_cpu_synchronize_from_tb,
.restore_state_to_opc = x86_restore_state_to_opc, .restore_state_to_opc = x86_restore_state_to_opc,
.cpu_exec_enter = x86_cpu_exec_enter, .cpu_exec_enter = x86_cpu_exec_enter,

View File

@ -3814,9 +3814,8 @@ static const TranslatorOps i386_tr_ops = {
.tb_stop = i386_tr_tb_stop, .tb_stop = i386_tr_tb_stop,
}; };
/* generate intermediate code for basic block 'tb'. */ void x86_translate_code(CPUState *cpu, TranslationBlock *tb,
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, int *max_insns, vaddr pc, void *host_pc)
vaddr pc, void *host_pc)
{ {
DisasContext dc; DisasContext dc;

View File

@ -795,6 +795,7 @@ static void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
static const TCGCPUOps loongarch_tcg_ops = { static const TCGCPUOps loongarch_tcg_ops = {
.initialize = loongarch_translate_init, .initialize = loongarch_translate_init,
.translate_code = loongarch_translate_code,
.synchronize_from_tb = loongarch_cpu_synchronize_from_tb, .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
.restore_state_to_opc = loongarch_restore_state_to_opc, .restore_state_to_opc = loongarch_restore_state_to_opc,

View File

@ -17,6 +17,8 @@
#define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS) #define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS)
void loongarch_translate_init(void); void loongarch_translate_init(void);
void loongarch_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void G_NORETURN do_raise_exception(CPULoongArchState *env, void G_NORETURN do_raise_exception(CPULoongArchState *env,
uint32_t exception, uint32_t exception,

View File

@ -333,8 +333,8 @@ static const TranslatorOps loongarch_tr_ops = {
.tb_stop = loongarch_tr_tb_stop, .tb_stop = loongarch_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void loongarch_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -551,6 +551,7 @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
static const TCGCPUOps m68k_tcg_ops = { static const TCGCPUOps m68k_tcg_ops = {
.initialize = m68k_tcg_init, .initialize = m68k_tcg_init,
.translate_code = m68k_translate_code,
.restore_state_to_opc = m68k_restore_state_to_opc, .restore_state_to_opc = m68k_restore_state_to_opc,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY

View File

@ -193,6 +193,8 @@ int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void m68k_tcg_init(void); void m68k_tcg_init(void);
void m68k_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void m68k_cpu_init_gdb(M68kCPU *cpu); void m68k_cpu_init_gdb(M68kCPU *cpu);
uint32_t cpu_m68k_get_ccr(CPUM68KState *env); uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t); void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);

View File

@ -6118,8 +6118,8 @@ static const TranslatorOps m68k_tr_ops = {
.tb_stop = m68k_tr_tb_stop, .tb_stop = m68k_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, void m68k_translate_code(CPUState *cpu, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc; DisasContext dc;
translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base); translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);

View File

@ -423,6 +423,7 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
static const TCGCPUOps mb_tcg_ops = { static const TCGCPUOps mb_tcg_ops = {
.initialize = mb_tcg_init, .initialize = mb_tcg_init,
.translate_code = mb_translate_code,
.synchronize_from_tb = mb_cpu_synchronize_from_tb, .synchronize_from_tb = mb_cpu_synchronize_from_tb,
.restore_state_to_opc = mb_restore_state_to_opc, .restore_state_to_opc = mb_restore_state_to_opc,

View File

@ -398,6 +398,8 @@ static inline void mb_cpu_write_msr(CPUMBState *env, uint32_t val)
} }
void mb_tcg_init(void); void mb_tcg_init(void);
void mb_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
#define CPU_RESOLVING_TYPE TYPE_MICROBLAZE_CPU #define CPU_RESOLVING_TYPE TYPE_MICROBLAZE_CPU

View File

@ -1779,8 +1779,8 @@ static const TranslatorOps mb_tr_ops = {
.tb_stop = mb_tr_tb_stop, .tb_stop = mb_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, void mb_translate_code(CPUState *cpu, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc; DisasContext dc;
translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base); translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);

View File

@ -547,6 +547,7 @@ static const Property mips_cpu_properties[] = {
#include "hw/core/tcg-cpu-ops.h" #include "hw/core/tcg-cpu-ops.h"
static const TCGCPUOps mips_tcg_ops = { static const TCGCPUOps mips_tcg_ops = {
.initialize = mips_tcg_init, .initialize = mips_tcg_init,
.translate_code = mips_translate_code,
.synchronize_from_tb = mips_cpu_synchronize_from_tb, .synchronize_from_tb = mips_cpu_synchronize_from_tb,
.restore_state_to_opc = mips_restore_state_to_opc, .restore_state_to_opc = mips_restore_state_to_opc,

View File

@ -16,6 +16,8 @@
#include "cpu.h" #include "cpu.h"
void mips_tcg_init(void); void mips_tcg_init(void);
void mips_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb); void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
G_NORETURN void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, G_NORETURN void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,

View File

@ -15231,8 +15231,8 @@ static const TranslatorOps mips_tr_ops = {
.tb_stop = mips_tr_tb_stop, .tb_stop = mips_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void mips_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -236,6 +236,7 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
static const TCGCPUOps openrisc_tcg_ops = { static const TCGCPUOps openrisc_tcg_ops = {
.initialize = openrisc_translate_init, .initialize = openrisc_translate_init,
.translate_code = openrisc_translate_code,
.synchronize_from_tb = openrisc_cpu_synchronize_from_tb, .synchronize_from_tb = openrisc_cpu_synchronize_from_tb,
.restore_state_to_opc = openrisc_restore_state_to_opc, .restore_state_to_opc = openrisc_restore_state_to_opc,

View File

@ -301,6 +301,8 @@ void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void openrisc_translate_init(void); void openrisc_translate_init(void);
void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
int print_insn_or1k(bfd_vma addr, disassemble_info *info); int print_insn_or1k(bfd_vma addr, disassemble_info *info);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY

View File

@ -1646,8 +1646,8 @@ static const TranslatorOps openrisc_tr_ops = {
.tb_stop = openrisc_tr_tb_stop, .tb_stop = openrisc_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -1581,6 +1581,8 @@ extern const VMStateDescription vmstate_ppc_cpu;
/*****************************************************************************/ /*****************************************************************************/
void ppc_translate_init(void); void ppc_translate_init(void);
void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
void ppc_store_sdr1(CPUPPCState *env, target_ulong value); void ppc_store_sdr1(CPUPPCState *env, target_ulong value);

View File

@ -7431,6 +7431,7 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
static const TCGCPUOps ppc_tcg_ops = { static const TCGCPUOps ppc_tcg_ops = {
.initialize = ppc_translate_init, .initialize = ppc_translate_init,
.translate_code = ppc_translate_code,
.restore_state_to_opc = ppc_restore_state_to_opc, .restore_state_to_opc = ppc_restore_state_to_opc,
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY

View File

@ -6669,8 +6669,8 @@ static const TranslatorOps ppc_tr_ops = {
.tb_stop = ppc_tr_tb_stop, .tb_stop = ppc_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -602,6 +602,9 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en); void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
void riscv_translate_init(void); void riscv_translate_init(void);
void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
G_NORETURN void riscv_raise_exception(CPURISCVState *env, G_NORETURN void riscv_raise_exception(CPURISCVState *env,
uint32_t exception, uintptr_t pc); uint32_t exception, uintptr_t pc);

View File

@ -135,6 +135,7 @@ static void riscv_restore_state_to_opc(CPUState *cs,
static const TCGCPUOps riscv_tcg_ops = { static const TCGCPUOps riscv_tcg_ops = {
.initialize = riscv_translate_init, .initialize = riscv_translate_init,
.translate_code = riscv_translate_code,
.synchronize_from_tb = riscv_cpu_synchronize_from_tb, .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
.restore_state_to_opc = riscv_restore_state_to_opc, .restore_state_to_opc = riscv_restore_state_to_opc,

View File

@ -1346,8 +1346,8 @@ static const TranslatorOps riscv_tr_ops = {
.tb_stop = riscv_tr_tb_stop, .tb_stop = riscv_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -196,6 +196,7 @@ static const struct SysemuCPUOps rx_sysemu_ops = {
static const TCGCPUOps rx_tcg_ops = { static const TCGCPUOps rx_tcg_ops = {
.initialize = rx_translate_init, .initialize = rx_translate_init,
.translate_code = rx_translate_code,
.synchronize_from_tb = rx_cpu_synchronize_from_tb, .synchronize_from_tb = rx_cpu_synchronize_from_tb,
.restore_state_to_opc = rx_restore_state_to_opc, .restore_state_to_opc = rx_restore_state_to_opc,
.tlb_fill = rx_cpu_tlb_fill, .tlb_fill = rx_cpu_tlb_fill,

View File

@ -139,6 +139,8 @@ int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void rx_translate_init(void); void rx_translate_init(void);
void rx_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte); void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte);
#include "exec/cpu-all.h" #include "exec/cpu-all.h"

View File

@ -2258,8 +2258,8 @@ static const TranslatorOps rx_tr_ops = {
.tb_stop = rx_tr_tb_stop, .tb_stop = rx_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void rx_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc; DisasContext dc;

View File

@ -362,6 +362,7 @@ void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc,
static const TCGCPUOps s390_tcg_ops = { static const TCGCPUOps s390_tcg_ops = {
.initialize = s390x_translate_init, .initialize = s390x_translate_init,
.translate_code = s390x_translate_code,
.restore_state_to_opc = s390x_restore_state_to_opc, .restore_state_to_opc = s390x_restore_state_to_opc,
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY

View File

@ -399,6 +399,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3,
/* translate.c */ /* translate.c */
void s390x_translate_init(void); void s390x_translate_init(void);
void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void s390x_restore_state_to_opc(CPUState *cs, void s390x_restore_state_to_opc(CPUState *cs,
const TranslationBlock *tb, const TranslationBlock *tb,
const uint64_t *data); const uint64_t *data);

View File

@ -6481,8 +6481,8 @@ static const TranslatorOps s390x_tr_ops = {
.disas_log = s390x_tr_disas_log, .disas_log = s390x_tr_disas_log,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc; DisasContext dc;

View File

@ -251,6 +251,7 @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
static const TCGCPUOps superh_tcg_ops = { static const TCGCPUOps superh_tcg_ops = {
.initialize = sh4_translate_init, .initialize = sh4_translate_init,
.translate_code = sh4_translate_code,
.synchronize_from_tb = superh_cpu_synchronize_from_tb, .synchronize_from_tb = superh_cpu_synchronize_from_tb,
.restore_state_to_opc = superh_restore_state_to_opc, .restore_state_to_opc = superh_restore_state_to_opc,

View File

@ -248,6 +248,8 @@ G_NORETURN void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
uintptr_t retaddr); uintptr_t retaddr);
void sh4_translate_init(void); void sh4_translate_init(void);
void sh4_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);

View File

@ -2318,8 +2318,8 @@ static const TranslatorOps sh4_tr_ops = {
.tb_stop = sh4_tr_tb_stop, .tb_stop = sh4_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void sh4_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;

View File

@ -996,6 +996,7 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
static const TCGCPUOps sparc_tcg_ops = { static const TCGCPUOps sparc_tcg_ops = {
.initialize = sparc_tcg_init, .initialize = sparc_tcg_init,
.translate_code = sparc_translate_code,
.synchronize_from_tb = sparc_cpu_synchronize_from_tb, .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
.restore_state_to_opc = sparc_restore_state_to_opc, .restore_state_to_opc = sparc_restore_state_to_opc,

View File

@ -609,6 +609,8 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
/* translate.c */ /* translate.c */
void sparc_tcg_init(void); void sparc_tcg_init(void);
void sparc_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
/* fop_helper.c */ /* fop_helper.c */
target_ulong cpu_get_fsr(CPUSPARCState *); target_ulong cpu_get_fsr(CPUSPARCState *);

View File

@ -344,17 +344,17 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
} }
float32 helper_fmadds(CPUSPARCState *env, float32 s1, float32 helper_fmadds(CPUSPARCState *env, float32 s1,
float32 s2, float32 s3, uint32_t op) float32 s2, float32 s3, int32_t sc, uint32_t op)
{ {
float32 ret = float32_muladd(s1, s2, s3, op, &env->fp_status); float32 ret = float32_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
check_ieee_exceptions(env, GETPC()); check_ieee_exceptions(env, GETPC());
return ret; return ret;
} }
float64 helper_fmaddd(CPUSPARCState *env, float64 s1, float64 helper_fmaddd(CPUSPARCState *env, float64 s1,
float64 s2, float64 s3, uint32_t op) float64 s2, float64 s3, int32_t sc, uint32_t op)
{ {
float64 ret = float64_muladd(s1, s2, s3, op, &env->fp_status); float64 ret = float64_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
check_ieee_exceptions(env, GETPC()); check_ieee_exceptions(env, GETPC());
return ret; return ret;
} }

View File

@ -59,7 +59,7 @@ DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_5(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, i32) DEF_HELPER_FLAGS_6(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, s32, i32)
DEF_HELPER_FLAGS_3(fnaddd, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_3(fnaddd, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fnmuld, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_3(fnmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
@ -72,7 +72,7 @@ DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32) DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32) DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32) DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_5(fmadds, TCG_CALL_NO_WG, f32, env, f32, f32, f32, i32) DEF_HELPER_FLAGS_6(fmadds, TCG_CALL_NO_WG, f32, env, f32, f32, f32, s32, i32)
DEF_HELPER_FLAGS_3(fnadds, TCG_CALL_NO_WG, f32, env, f32, f32) DEF_HELPER_FLAGS_3(fnadds, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fnmuls, TCG_CALL_NO_WG, f32, env, f32, f32) DEF_HELPER_FLAGS_3(fnmuls, TCG_CALL_NO_WG, f32, env, f32, f32)

View File

@ -1359,93 +1359,109 @@ static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
static void gen_op_fmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3) static void gen_op_fmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
{ {
gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(0)); TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, z);
} }
static void gen_op_fmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3) static void gen_op_fmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
{ {
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(0)); TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, z);
} }
static void gen_op_fmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3) static void gen_op_fmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
{ {
int op = float_muladd_negate_c; TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, op);
} }
static void gen_op_fmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3) static void gen_op_fmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
{ {
int op = float_muladd_negate_c; TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, op);
} }
static void gen_op_fnmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3) static void gen_op_fnmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
{ {
int op = float_muladd_negate_c | float_muladd_negate_result; TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c |
float_muladd_negate_result);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, op);
} }
static void gen_op_fnmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3) static void gen_op_fnmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
{ {
int op = float_muladd_negate_c | float_muladd_negate_result; TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c |
float_muladd_negate_result);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, op);
} }
static void gen_op_fnmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3) static void gen_op_fnmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
{ {
int op = float_muladd_negate_result; TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, op);
} }
static void gen_op_fnmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3) static void gen_op_fnmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
{ {
int op = float_muladd_negate_result; TCGv_i32 z = tcg_constant_i32(0);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, op);
} }
/* Use muladd to compute (1 * src1) + src2 / 2 with one rounding. */ /* Use muladd to compute (1 * src1) + src2 / 2 with one rounding. */
static void gen_op_fhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2) static void gen_op_fhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
{ {
TCGv_i32 one = tcg_constant_i32(float32_one); TCGv_i32 fone = tcg_constant_i32(float32_one);
int op = float_muladd_halve_result; TCGv_i32 mone = tcg_constant_i32(-1);
gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(0);
gen_helper_fmadds(d, tcg_env, fone, s1, s2, mone, op);
} }
static void gen_op_fhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2) static void gen_op_fhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
{ {
TCGv_i64 one = tcg_constant_i64(float64_one); TCGv_i64 fone = tcg_constant_i64(float64_one);
int op = float_muladd_halve_result; TCGv_i32 mone = tcg_constant_i32(-1);
gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(0);
gen_helper_fmaddd(d, tcg_env, fone, s1, s2, mone, op);
} }
/* Use muladd to compute (1 * src1) - src2 / 2 with one rounding. */ /* Use muladd to compute (1 * src1) - src2 / 2 with one rounding. */
static void gen_op_fhsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2) static void gen_op_fhsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
{ {
TCGv_i32 one = tcg_constant_i32(float32_one); TCGv_i32 fone = tcg_constant_i32(float32_one);
int op = float_muladd_negate_c | float_muladd_halve_result; TCGv_i32 mone = tcg_constant_i32(-1);
gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
gen_helper_fmadds(d, tcg_env, fone, s1, s2, mone, op);
} }
static void gen_op_fhsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2) static void gen_op_fhsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
{ {
TCGv_i64 one = tcg_constant_i64(float64_one); TCGv_i64 fone = tcg_constant_i64(float64_one);
int op = float_muladd_negate_c | float_muladd_halve_result; TCGv_i32 mone = tcg_constant_i32(-1);
gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
gen_helper_fmaddd(d, tcg_env, fone, s1, s2, mone, op);
} }
/* Use muladd to compute -((1 * src1) + src2 / 2) with one rounding. */ /* Use muladd to compute -((1 * src1) + src2 / 2) with one rounding. */
static void gen_op_fnhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2) static void gen_op_fnhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
{ {
TCGv_i32 one = tcg_constant_i32(float32_one); TCGv_i32 fone = tcg_constant_i32(float32_one);
int op = float_muladd_negate_result | float_muladd_halve_result; TCGv_i32 mone = tcg_constant_i32(-1);
gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
gen_helper_fmadds(d, tcg_env, fone, s1, s2, mone, op);
} }
static void gen_op_fnhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2) static void gen_op_fnhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
{ {
TCGv_i64 one = tcg_constant_i64(float64_one); TCGv_i64 fone = tcg_constant_i64(float64_one);
int op = float_muladd_negate_result | float_muladd_halve_result; TCGv_i32 mone = tcg_constant_i32(-1);
gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op)); TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
gen_helper_fmaddd(d, tcg_env, fone, s1, s2, mone, op);
} }
static void gen_op_fpexception_im(DisasContext *dc, int ftt) static void gen_op_fpexception_im(DisasContext *dc, int ftt)
@ -5803,8 +5819,8 @@ static const TranslatorOps sparc_tr_ops = {
.tb_stop = sparc_tr_tb_stop, .tb_stop = sparc_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, void sparc_translate_code(CPUState *cs, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc = {}; DisasContext dc = {};

View File

@ -172,6 +172,7 @@ static const struct SysemuCPUOps tricore_sysemu_ops = {
static const TCGCPUOps tricore_tcg_ops = { static const TCGCPUOps tricore_tcg_ops = {
.initialize = tricore_tcg_init, .initialize = tricore_tcg_init,
.translate_code = tricore_translate_code,
.synchronize_from_tb = tricore_cpu_synchronize_from_tb, .synchronize_from_tb = tricore_cpu_synchronize_from_tb,
.restore_state_to_opc = tricore_restore_state_to_opc, .restore_state_to_opc = tricore_restore_state_to_opc,
.tlb_fill = tricore_cpu_tlb_fill, .tlb_fill = tricore_cpu_tlb_fill,

View File

@ -252,6 +252,8 @@ FIELD(TB_FLAGS, PRIV, 0, 2)
void cpu_state_reset(CPUTriCoreState *s); void cpu_state_reset(CPUTriCoreState *s);
void tricore_tcg_init(void); void tricore_tcg_init(void);
void tricore_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc, static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *flags) uint64_t *cs_base, uint32_t *flags)

View File

@ -8460,9 +8460,8 @@ static const TranslatorOps tricore_tr_ops = {
.tb_stop = tricore_tr_tb_stop, .tb_stop = tricore_tr_tb_stop,
}; };
void tricore_translate_code(CPUState *cs, TranslationBlock *tb,
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, int *max_insns, vaddr pc, void *host_pc)
vaddr pc, void *host_pc)
{ {
DisasContext ctx; DisasContext ctx;
translator_loop(cs, tb, max_insns, pc, host_pc, translator_loop(cs, tb, max_insns, pc, host_pc,

View File

@ -232,6 +232,7 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
static const TCGCPUOps xtensa_tcg_ops = { static const TCGCPUOps xtensa_tcg_ops = {
.initialize = xtensa_translate_init, .initialize = xtensa_translate_init,
.translate_code = xtensa_translate_code,
.debug_excp_handler = xtensa_breakpoint_handler, .debug_excp_handler = xtensa_breakpoint_handler,
.restore_state_to_opc = xtensa_restore_state_to_opc, .restore_state_to_opc = xtensa_restore_state_to_opc,

View File

@ -617,6 +617,8 @@ G_NORETURN void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
void xtensa_collect_sr_names(const XtensaConfig *config); void xtensa_collect_sr_names(const XtensaConfig *config);
void xtensa_translate_init(void); void xtensa_translate_init(void);
void xtensa_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
void **xtensa_get_regfile_by_name(const char *name, int entries, int bits); void **xtensa_get_regfile_by_name(const char *name, int entries, int bits);
void xtensa_breakpoint_handler(CPUState *cs); void xtensa_breakpoint_handler(CPUState *cs);
void xtensa_register_core(XtensaConfigList *node); void xtensa_register_core(XtensaConfigList *node);

View File

@ -1228,8 +1228,8 @@ static const TranslatorOps xtensa_translator_ops = {
.tb_stop = xtensa_tr_tb_stop, .tb_stop = xtensa_tr_tb_stop,
}; };
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns, void xtensa_translate_code(CPUState *cpu, TranslationBlock *tb,
vaddr pc, void *host_pc) int *max_insns, vaddr pc, void *host_pc)
{ {
DisasContext dc = {}; DisasContext dc = {};
translator_loop(cpu, tb, max_insns, pc, host_pc, translator_loop(cpu, tb, max_insns, pc, host_pc,

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <inttypes.h>
#include <minilib.h> #include <minilib.h>
#ifndef CHECK_UNALIGNED #ifndef CHECK_UNALIGNED
@ -511,8 +510,8 @@ int main(void)
int i; int i;
bool ok = true; bool ok = true;
ml_printf("Test data start: 0x%"PRIxPTR"\n", &test_data[0]); ml_printf("Test data start: 0x%lx\n", (unsigned long)&test_data[0]);
ml_printf("Test data end: 0x%"PRIxPTR"\n", &test_data[TEST_SIZE]); ml_printf("Test data end: 0x%lx\n", (unsigned long)&test_data[TEST_SIZE]);
/* Run through the unsigned tests first */ /* Run through the unsigned tests first */
for (i = 0; i < ARRAY_SIZE(init_ufns) && ok; i++) { for (i = 0; i < ARRAY_SIZE(init_ufns) && ok; i++) {
@ -529,8 +528,8 @@ int main(void)
ok = do_signed_reads(true); ok = do_signed_reads(true);
} }
ml_printf("Test data read: %"PRId32"\n", test_read_count); ml_printf("Test data read: %lu\n", (unsigned long)test_read_count);
ml_printf("Test data write: %"PRId32"\n", test_write_count); ml_printf("Test data write: %lu\n", (unsigned long)test_write_count);
ml_printf("Test complete: %s\n", ok ? "PASSED" : "FAILED"); ml_printf("Test complete: %s\n", ok ? "PASSED" : "FAILED");
return ok ? 0 : -1; return ok ? 0 : -1;
} }