qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] target-tilegx: Implement floating point tempora


From: Chen Gang
Subject: Re: [Qemu-devel] [PATCH] target-tilegx: Implement floating point temporarily
Date: Sun, 4 Oct 2015 19:48:42 +0800

After the temporary floating point patch, our tilegx qemu can test the
gcc testsuite successfully (no any unimplementation issues). The test
result is:

            === gcc Summary ===

  # of expected passes          77012
  # of unexpected failures      622
  # of unexpected successes     7
  # of expected failures        113
  # of unresolved testcases     143
  # of unsupported tests        1476


For the 622 left issues:

 - Maybe still tilegx implementation issue, e.g.

   the floating point single mul instruction cann't get the result which
   tilegx gcc expected (it is only related with calculating: float32_mul
   calculation result is not match tilegx gcc expected).

 - Maybe envorintments configuration issues, e.g.

   for gcc guality_check, it may call gdb outside, so I need config the
   related gdb correctlly.

 - Maybe tilegx gcc issues, e.g.

   for some UNKNOWN instructions, probably generated by incorrect jump
   instructions, one sample is "-fpic -mcmodel=large" for gcc nested-5
   test.

Next, I shall: 
 
 - continue to fix the left 622 issues, and send related patches to
   qemu-devel mailing list or gcc-patches mailing list.

 - then rewrite the floating point instructions implementation, and try
   to let the related code merged into qemu mainline with the qemu
   members' help.

 - at last, try to finish all left unimplemented instructions (there are
   still some unimplement insns left, but at present, gcc testsuite does
   not use them), and start tilegx qemu system mode, next.



Thanks
--
Chen Gang

Open, share, and attitude like air, water, and life which God blessed


----------------------------------------
> From: address@hidden
> To: address@hidden; address@hidden; address@hidden
> CC: address@hidden
> Subject: [PATCH] target-tilegx: Implement floating point temporarily
> Date: Sun, 4 Oct 2015 19:16:35 +0800
>
> From 4d12af14f361fb5e3a893fc68a599be9ea17d1dc Mon Sep 17 00:00:00 2001
> From: Chen Gang <address@hidden>
> Date: Sun, 4 Oct 2015 18:00:53 +0800
> Subject: [PATCH] target-tilegx: Implement floating point temporarily
>
> It is a temporary implementation, but it can pass gcc testsuite.
>
> Signed-off-by: Chen Gang <address@hidden>
> ---
> target-tilegx/Makefile.objs | 2 +-
> target-tilegx/cpu.h | 5 +-
> target-tilegx/fpu.h | 149 +++++++++++++++++++++++++
> target-tilegx/fpu_helper.c | 259 ++++++++++++++++++++++++++++++++++++++++++++
> target-tilegx/helper.h | 9 ++
> target-tilegx/translate.c | 70 +++++++++---
> 6 files changed, 479 insertions(+), 15 deletions(-)
> create mode 100644 target-tilegx/fpu.h
> create mode 100644 target-tilegx/fpu_helper.c
>
> diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs
> index 0db778f..1573c36 100644
> --- a/target-tilegx/Makefile.objs
> +++ b/target-tilegx/Makefile.objs
> @@ -1 +1 @@
> -obj-y += cpu.o translate.o helper.o simd_helper.o
> +obj-y += cpu.o translate.o helper.o simd_helper.o fpu_helper.o
> diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
> index 6c0fd53..b752ef3 100644
> --- a/target-tilegx/cpu.h
> +++ b/target-tilegx/cpu.h
> @@ -27,7 +27,7 @@
> #define CPUArchState struct CPUTLGState
>
> #include "exec/cpu-defs.h"
> -
> +#include "fpu.h"
>
> /* TILE-Gx common register alias */
> #define TILEGX_R_RE 0 /* 0 register, for function/syscall return value */
> @@ -77,6 +77,7 @@ typedef enum {
> TILEGX_EXCP_OPCODE_FETCHAND4 = 0x10c,
> TILEGX_EXCP_OPCODE_FETCHOR = 0x10d,
> TILEGX_EXCP_OPCODE_FETCHOR4 = 0x10e,
> + TILEGX_EXCP_OPCODE_INVALID_VALUE = 0x10f,
> TILEGX_EXCP_REG_IDN_ACCESS = 0x181,
> TILEGX_EXCP_REG_UDN_ACCESS = 0x182,
> TILEGX_EXCP_UNALIGNMENT = 0x201,
> @@ -88,6 +89,8 @@ typedef struct CPUTLGState {
> uint64_t spregs[TILEGX_SPR_COUNT]; /* Special used registers by outside */
> uint64_t pc; /* Current pc */
>
> + FPUTLGState fpu; /* fpu context */
> +
> #if defined(CONFIG_USER_ONLY)
> uint64_t excaddr; /* exception address */
> uint64_t atomic_srca; /* Arguments to atomic "exceptions" */
> diff --git a/target-tilegx/fpu.h b/target-tilegx/fpu.h
> new file mode 100644
> index 0000000..41076bd
> --- /dev/null
> +++ b/target-tilegx/fpu.h
> @@ -0,0 +1,149 @@
> +/*
> + * TILE-Gx virtual FPU header
> + *
> + * Copyright (c) 2015 Chen Gang
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> <http://www.gnu.org/licenses/>.
> + */
> +#ifndef FPU_TILEGX_H
> +#define FPU_TILEGX_H
> +
> +/*
> + * Single floaing point instructions decription.
> + *
> + * - fsingle_add1, fsingle_sub1, and fsingle_pack1/2 can be used 
> individually.
> + *
> + * - when fsingle_pack1/2 is used individually, it is for type cast.
> + *
> + * - the old 4Kth result is alrealy useless for caller.
> + *
> + * fsingle_add1 ; make context and calc result from rsrca and rsrcb.
> + * ; save result in roundup array, and add index to context.
> + * ; move context to rdst.
> + *
> + * fsingle_sub1 ; make context and calc result from rsrca and rsrcb.
> + * ; save result in roundup array, and add index to context.
> + * ; move context to rdst.
> + *
> + * fsingle_addsub2 ; skipped.
> + *
> + * fsingle_mul1 ; make context and calc result from rsrca and srcb.
> + * ; save result in roundup array, and add index to context.
> + * ; move context to rdst.
> + *
> + * fsingle_mul2 ; move rsrca to rdst.
> + *
> + * fsingle_pack1 ; skipped.
> + *
> + * fsingle_pack2 ; get context from rsrca (rsrca is context).
> + * ; if context for add/sub/mul
> + * ; get result from roundup array based on index.
> + * ; move result to rdst.
> + * ; else
> + * ; get (u)int32_t interger from context,
> + * ; (u)int32_to_float32.
> + */
> +
> +/*
> + * Double floating point instructions' description.
> + *
> + * - fdouble_add_flags, fdouble_sub_flags, and fdouble_pack1/2 can be used
> + * individually.
> + *
> + * - when fdouble_pack1/2 is used individually, it is for type cast.
> + *
> + * - the old 4Kth result is alrealy useless for caller.
> + *
> + * fdouble_unpack_max: ; skipped.
> + *
> + * fdouble_unpack_min: ; skipped.
> + *
> + * fdouble_add_flags: ; make context and calc result from rsrca and rsrcb.
> + * ; save result in roundup array, and add index to context.
> + * ; move context to rdst.
> + *
> + * fdouble_sub_flags: ; make context and calc result from rsrca and rsrcb.
> + * ; save result in roundup array, and add index to context.
> + * ; move context to rdst.
> + *
> + * fdouble_addsub: ; skipped.
> + *
> + * fdouble_mul_flags: ; make context and calc result from rsrca and rsrcb.
> + * ; save result in roundup array, and add index to context.
> + * ; move context to rdst.
> + *
> + * fdouble_pack1: ; get context from rsrcb.
> + * ; if context for add/sub/mul
> + * ; get result from roundup array based on index.
> + * ; move result to rdst.
> + * ; else
> + * ; get (u)int32_t interger from rsrca
> + * ; (u)int32_to_float64.
> + *
> + * fdouble_pack2: ; skipped.
> + */
> +
> +#define TILEGX_F_COUNT 0x1000 /* Maximized results count for fdouble */
> +
> +#define TILEGX_F_DUINT 0x21b00 /* exp is for uint32_t to double */
> +#define TILEGX_F_DINT 0xa1b00 /* exp is for int32_t to double */
> +#define TILEGX_F_SUINT 0x9e /* exp is for uint32_t to single */
> +#define TILEGX_F_SINT 0x29e /* exp is for int32_t to single */
> +
> +#define TILEGX_F_TCAST 0 /* Result type is for typecast, MUST BE 0 */
> +#define TILEGX_F_TCALC 1 /* Result type is for add/sub/mul */
> +
> +#pragma pack(push, 1)
> +typedef struct TileGXFPCtx {
> +
> + /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
> + uint64_t exp : 21; /* Exponent, for TILEGX_F_(D/S)(U)INT */
> +
> + /* Context type, defined and used by callee */
> + uint64_t type : 4; /* For TILEGX_F_T(CAST/CALC) */
> +
> + /* Come from TILE-Gx ISA document, Table 7-2 for floating point */
> + uint64_t unordered : 1; /* The two are unordered */
> + uint64_t lt : 1; /* 1st is less than 2nd */
> + uint64_t le : 1; /* 1st is less than or equal to 2nd */
> + uint64_t gt : 1; /* 1st is greater than 2nd */
> + uint64_t ge : 1; /* 1st is greater than or equal to 2nd */
> + uint64_t eq : 1; /* The two operands are equal */
> + uint64_t neq : 1; /* The two operands are not equal */
> +
> + /* Result data according to the context type */
> + uint64_t data : 32; /* The explanation is below */
> +#if 0
> + /* This is the explanation for 'data' above */
> + union {
> + uint32_t idx; /* Index for the add/sub/mul result */
> + uint32_t aint; /* Absolute input integer for fsingle typecast */
> + /*
> + * There is no input integer for fdouble typecast in context, it is in
> + * rsrca parameter of fdouble_pack1 instruction.
> + */
> + };
> +#endif
> +} TileGXFPCtx;
> +#pragma pack(pop)
> +
> +typedef struct FPUTLGState {
> + float_status fp_status; /* floating point status */
> + int pos32; /* Current position for fsingle result */
> + int pos64; /* Current position for fdouble result */
> + float32 val32s[TILEGX_F_COUNT]; /* results roudup array for fsingle */
> + float64 val64s[TILEGX_F_COUNT]; /* results roudup array for fdouble */
> +} FPUTLGState;
> +
> +#endif /* FPU_TILEGX_H */
> diff --git a/target-tilegx/fpu_helper.c b/target-tilegx/fpu_helper.c
> new file mode 100644
> index 0000000..daae570
> --- /dev/null
> +++ b/target-tilegx/fpu_helper.c
> @@ -0,0 +1,259 @@
> +/*
> + * QEMU TILE-Gx helpers
> + *
> + * Copyright (c) 2015 Chen Gang
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see
> + * <http://www.gnu.org/licenses/lgpl-2.1.html>
> + */
> +
> +#include "cpu.h"
> +#include "qemu-common.h"
> +#include "exec/helper-proto.h"
> +#include "fpu/softfloat.h"
> +
> +#define SIGNBIT32 0x80000000
> +#define FP_STATUS (fpu->fp_status)
> +
> +static void fdouble_ana(FPUTLGState *fpu,
> + float64 fsrc, float64 fsrcb, TileGXFPCtx *ctx)
> +{
> + if (float64_eq(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->eq = 1;
> + } else {
> + ctx->neq = 1;
> + }
> +
> + if (float64_lt(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->lt = 1;
> + }
> + if (float64_le(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->le = 1;
> + }
> +
> + if (float64_lt(fsrcb, fsrc, &FP_STATUS)) {
> + ctx->gt = 1;
> + }
> + if (float64_le(fsrcb, fsrc, &FP_STATUS)) {
> + ctx->ge = 1;
> + }
> +
> + if (float64_unordered(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->unordered = 1;
> + }
> +}
> +
> +static float64 t_to_float64(uint64_t a)
> +{
> + CPU_DoubleU r;
> + r.ll = a;
> + return r.d;
> +}
> +
> +static uint64_t float64_to_t(float64 fa)
> +{
> + CPU_DoubleU r;
> + r.d = fa;
> + return r.ll;
> +}
> +
> +static uint64_t ctx_to_uint64(TileGXFPCtx a)
> +{
> + union {
> + TileGXFPCtx a;
> + uint64_t v;
> + } t;
> + t.a = a;
> + return t.v;
> +}
> +
> +static TileGXFPCtx uint64_to_ctx(uint64 v)
> +{
> + union {
> + TileGXFPCtx a;
> + uint64_t v;
> + } t;
> + t.v = v;
> + return t.a;
> +}
> +
> +static uint64_t fdouble_calc(FPUTLGState *fpu,
> + float64 fsrc, float64 fsrcb,
> + float64 (*calc)(float64, float64, float_status *))
> +{
> + TileGXFPCtx ctx = {0};
> +
> + ctx.type = TILEGX_F_TCALC;
> + ctx.data = fpu->pos64;
> + fpu->val64s[fpu->pos64++] = calc(fsrc, fsrcb, &FP_STATUS);
> + if (fpu->pos64>= TILEGX_F_COUNT) {
> + fpu->pos64 = 0;
> + }
> + fdouble_ana(fpu, fsrc, fsrcb, &ctx);
> +
> + return ctx_to_uint64(ctx);
> +}
> +
> +uint64_t helper_fdouble_add_flags(CPUTLGState *env,
> + uint64_t rsrc, uint64_t rsrcb)
> +{
> + return fdouble_calc(&env->fpu, t_to_float64(rsrc), t_to_float64(rsrcb),
> + float64_add);
> +}
> +
> +uint64_t helper_fdouble_sub_flags(CPUTLGState *env,
> + uint64_t rsrc, uint64_t rsrcb)
> +{
> + return fdouble_calc(&env->fpu, t_to_float64(rsrc), t_to_float64(rsrcb),
> + float64_sub);
> +}
> +
> +uint64_t helper_fdouble_mul_flags(CPUTLGState *env,
> + uint64_t rsrc, uint64_t rsrcb)
> +{
> + return fdouble_calc(&env->fpu, t_to_float64(rsrc), t_to_float64(rsrcb),
> + float64_mul);
> +}
> +
> +uint64_t helper_fdouble_pack1(CPUTLGState *env,
> + uint64_t rsrc, uint64_t rsrcb)
> +{
> + FPUTLGState *fpu = &env->fpu;
> + TileGXFPCtx ctx = uint64_to_ctx(rsrcb);
> +
> + if (ctx.type == TILEGX_F_TCALC) {
> + if (ctx.data>= TILEGX_F_COUNT) {
> + helper_exception(env, TILEGX_EXCP_OPCODE_INVALID_VALUE);
> + }
> + return float64_to_t(fpu->val64s[ctx.data]);
> + }
> +
> + switch (ctx.exp) {
> + case 0x21b00:
> + return float64_to_t(uint32_to_float64(rsrc>> 4, &FP_STATUS));
> + case 0x121b00:
> + return float64_to_t(int32_to_float64((rsrc>> 4) | SIGNBIT32,
> + &FP_STATUS));
> + default:
> + fprintf(stderr, "\nUIMP: in helper_fdouble_pack2().\n");
> + helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED);
> + return 0;
> + }
> +}
> +
> +static void fsingle_ana(FPUTLGState *fpu,
> + float32 fsrc, float32 fsrcb, TileGXFPCtx *ctx)
> +{
> + if (float32_eq(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->eq = 1;
> + } else {
> + ctx->neq = 1;
> + }
> +
> + if (float32_lt(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->lt = 1;
> + }
> + if (float32_le(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->le = 1;
> + }
> +
> + if (float32_lt(fsrcb, fsrc, &FP_STATUS)) {
> + ctx->gt = 1;
> + }
> + if (float32_le(fsrcb, fsrc, &FP_STATUS)) {
> + ctx->ge = 1;
> + }
> +
> + if (float32_unordered(fsrc, fsrcb, &FP_STATUS)) {
> + ctx->unordered = 1;
> + }
> +}
> +
> +static uint64_t fsingle_calc(FPUTLGState *fpu,
> + float32 fsrc, float32 fsrcb,
> + float32 (*calc)(float32, float32, float_status *))
> +{
> + TileGXFPCtx ctx = {0};
> +
> + ctx.type = TILEGX_F_TCALC;
> + ctx.data = fpu->pos32;
> + fpu->val32s[fpu->pos32++] = calc(fsrc, fsrcb, &FP_STATUS);
> + if (fpu->pos32>= TILEGX_F_COUNT) {
> + fpu->pos32 = 0;
> + }
> + fsingle_ana(fpu, fsrc, fsrcb, &ctx);
> +
> + return ctx_to_uint64(ctx);
> +}
> +
> +uint64_t helper_fsingle_add1(CPUTLGState *env, uint64_t rsrc, uint64_t rsrcb)
> +{
> + FPUTLGState *fpu = &env->fpu;
> + return fsingle_calc(fpu, int64_to_float32(rsrc, &FP_STATUS),
> + int64_to_float32(rsrcb, &FP_STATUS),
> + float32_add);
> +}
> +
> +uint64_t helper_fsingle_sub1(CPUTLGState *env, uint64_t rsrc, uint64_t rsrcb)
> +{
> + FPUTLGState *fpu = &env->fpu;
> + return fsingle_calc(fpu, int64_to_float32(rsrc, &FP_STATUS),
> + int64_to_float32(rsrcb, &FP_STATUS),
> + float32_sub);
> +}
> +
> +uint64_t helper_fsingle_mul1(CPUTLGState *env, uint64_t rsrc, uint64_t rsrcb)
> +{
> + FPUTLGState *fpu = &env->fpu;
> +#if 0
> + {
> + float32 v;
> + fprintf(stderr, "\ncall helper_fsingle_mul1(), %lx, %lx\n", rsrc, rsrcb);
> + v = float32_mul(int64_to_float32(rsrc, &FP_STATUS),
> + int64_to_float32(rsrcb, &FP_STATUS),
> + &FP_STATUS);
> + fprintf(stderr, "result: %lx.\n", float32_to_int64(v, &FP_STATUS));
> + }
> +#endif
> + return fsingle_calc(fpu, int64_to_float32(rsrc, &FP_STATUS),
> + int64_to_float32(rsrcb, &FP_STATUS),
> + float32_mul);
> +}
> +
> +uint64_t helper_fsingle_pack2(CPUTLGState *env, uint64_t rsrc)
> +{
> + FPUTLGState *fpu = &env->fpu;
> + TileGXFPCtx ctx = uint64_to_ctx(rsrc);
> +
> + if (ctx.type == TILEGX_F_TCALC) {
> + if (ctx.data>= TILEGX_F_COUNT) {
> + helper_exception(env, TILEGX_EXCP_OPCODE_INVALID_VALUE);
> + }
> + return float32_to_int32(fpu->val32s[ctx.data], &FP_STATUS);
> + }
> +
> + switch (ctx.exp) {
> + case 0x9e:
> + return float32_to_int64(uint32_to_float32(ctx.data, &FP_STATUS),
> + &FP_STATUS);
> + case 0x49e:
> + return float32_to_int64(int32_to_float32(ctx.data | SIGNBIT32,
> + &FP_STATUS),
> + &FP_STATUS);
> + default:
> + fprintf(stderr, "\nUIMP: in helper_fsingle_pack2().\n");
> + helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED);
> + return 0;
> + }
> +}
> diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
> index 9281d0f..9f4fc8a 100644
> --- a/target-tilegx/helper.h
> +++ b/target-tilegx/helper.h
> @@ -24,3 +24,12 @@ DEF_HELPER_FLAGS_2(v1shrs, TCG_CALL_NO_RWG_SE, i64, i64, 
> i64)
> DEF_HELPER_FLAGS_2(v2shl, TCG_CALL_NO_RWG_SE, i64, i64, i64)
> DEF_HELPER_FLAGS_2(v2shru, TCG_CALL_NO_RWG_SE, i64, i64, i64)
> DEF_HELPER_FLAGS_2(v2shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64)
> +
> +DEF_HELPER_3(fsingle_add1, i64, env, i64, i64)
> +DEF_HELPER_3(fsingle_sub1, i64, env, i64, i64)
> +DEF_HELPER_3(fsingle_mul1, i64, env, i64, i64)
> +DEF_HELPER_2(fsingle_pack2, i64, env, i64)
> +DEF_HELPER_3(fdouble_add_flags, i64, env, i64, i64)
> +DEF_HELPER_3(fdouble_sub_flags, i64, env, i64, i64)
> +DEF_HELPER_3(fdouble_mul_flags, i64, env, i64, i64)
> +DEF_HELPER_3(fdouble_pack1, i64, env, i64, i64)
> diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
> index 2913902..c65e980 100644
> --- a/target-tilegx/translate.c
> +++ b/target-tilegx/translate.c
> @@ -616,6 +616,11 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
> opext,
> qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
> reg_names[dest], reg_names[srca]);
> return ret;
> +
> + case OE_RR_X0(FSINGLE_PACK1):
> + case OE_RR_Y0(FSINGLE_PACK1):
> + mnemonic = "fsingle_pack1";
> + goto done2;
> }
>
> tdest = dest_gr(dc, dest);
> @@ -632,9 +637,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
> opext,
> gen_helper_cnttz(tdest, tsrca);
> mnemonic = "cnttz";
> break;
> - case OE_RR_X0(FSINGLE_PACK1):
> - case OE_RR_Y0(FSINGLE_PACK1):
> - return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
> case OE_RR_X1(LD1S):
> memop = MO_SB;
> mnemonic = "ld1s"; /* prefetch_l1_fault */
> @@ -736,6 +738,7 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned 
> opext,
> return TILEGX_EXCP_OPCODE_UNKNOWN;
> }
>
> +done2:
> qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
> reg_names[dest], reg_names[srca]);
> return ret;
> @@ -744,13 +747,33 @@ static TileExcp gen_rr_opcode(DisasContext *dc, 
> unsigned opext,
> static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
> unsigned dest, unsigned srca, unsigned srcb)
> {
> - TCGv tdest = dest_gr(dc, dest);
> - TCGv tsrca = load_gr(dc, srca);
> - TCGv tsrcb = load_gr(dc, srcb);
> + TCGv tdest, tsrca, tsrcb;
> TCGv t0;
> const char *mnemonic;
>
> switch (opext) {
> + case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
> + mnemonic = "fsingle_addsub2";
> + goto done2;
> + case OE_RRR(FDOUBLE_ADDSUB, 0, X0):
> + mnemonic = "fdouble_addsub";
> + goto done2;
> + case OE_RRR(FDOUBLE_PACK2, 0, X0):
> + mnemonic = "fdouble_pack2";
> + goto done2;
> + case OE_RRR(FDOUBLE_UNPACK_MAX, 0, X0):
> + mnemonic = "fdouble_unpack_max";
> + goto done2;
> + case OE_RRR(FDOUBLE_UNPACK_MIN, 0, X0):
> + mnemonic = "fdouble_unpack_min";
> + goto done2;
> + }
> +
> + tdest = dest_gr(dc, dest);
> + tsrca = load_gr(dc, srca);
> + tsrcb = load_gr(dc, srcb);
> +
> + switch (opext) {
> case OE_RRR(ADDXSC, 0, X0):
> case OE_RRR(ADDXSC, 0, X1):
> gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_add_tl);
> @@ -907,15 +930,22 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, 
> unsigned opext,
> TILEGX_EXCP_OPCODE_EXCH);
> mnemonic = "exch";
> break;
> - case OE_RRR(FDOUBLE_ADDSUB, 0, X0):
> case OE_RRR(FDOUBLE_ADD_FLAGS, 0, X0):
> + gen_helper_fdouble_add_flags(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fdouble_add_flags";
> + break;
> case OE_RRR(FDOUBLE_MUL_FLAGS, 0, X0):
> + gen_helper_fdouble_mul_flags(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fdouble_mul_flags";
> + break;
> case OE_RRR(FDOUBLE_PACK1, 0, X0):
> - case OE_RRR(FDOUBLE_PACK2, 0, X0):
> + gen_helper_fdouble_pack1(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fdouble_pack1";
> + break;
> case OE_RRR(FDOUBLE_SUB_FLAGS, 0, X0):
> - case OE_RRR(FDOUBLE_UNPACK_MAX, 0, X0):
> - case OE_RRR(FDOUBLE_UNPACK_MIN, 0, X0):
> - return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
> + gen_helper_fdouble_sub_flags(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fdouble_sub_flags";
> + break;
> case OE_RRR(FETCHADD4, 0, X1):
> gen_atomic_excp(dc, dest, tdest, tsrca, tsrcb,
> TILEGX_EXCP_OPCODE_FETCHADD4);
> @@ -957,12 +987,25 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, 
> unsigned opext,
> mnemonic = "fetchor";
> break;
> case OE_RRR(FSINGLE_ADD1, 0, X0):
> - case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
> + gen_helper_fsingle_add1(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fsingle_add1";
> + break;
> case OE_RRR(FSINGLE_MUL1, 0, X0):
> + gen_helper_fsingle_mul1(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fsingle_mul1";
> + break;
> case OE_RRR(FSINGLE_MUL2, 0, X0):
> + tcg_gen_mov_i64(tdest, tsrca);
> + mnemonic = "fsingle_mul2";
> + break;
> case OE_RRR(FSINGLE_PACK2, 0, X0):
> + gen_helper_fsingle_pack2(tdest, cpu_env, tsrca);
> + mnemonic = "fsingle_pack2";
> + break;
> case OE_RRR(FSINGLE_SUB1, 0, X0):
> - return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
> + gen_helper_fsingle_sub1(tdest, cpu_env, tsrca, tsrcb);
> + mnemonic = "fsingle_sub1";
> + break;
> case OE_RRR(MNZ, 0, X0):
> case OE_RRR(MNZ, 0, X1):
> case OE_RRR(MNZ, 4, Y0):
> @@ -1466,6 +1509,7 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, 
> unsigned opext,
> return TILEGX_EXCP_OPCODE_UNKNOWN;
> }
>
> +done2:
> qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %s", mnemonic,
> reg_names[dest], reg_names[srca], reg_names[srcb]);
> return TILEGX_EXCP_NONE;
> --
> 1.9.3
>
>
                                          


reply via email to

[Prev in Thread] Current Thread [Next in Thread]