[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] target-tilegx: Implement floating point temporarily
From: |
Chen Gang |
Subject: |
[Qemu-devel] [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
0007-target-tilegx-Implement-floating-point-temporarily.patch
Description: Binary data
- [Qemu-devel] [PATCH] target-tilegx: Implement floating point temporarily,
Chen Gang <=