[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 10/10] target-tricore: add RR_DIV and RR_DIV_U instru
From: |
Bastian Koppelmann |
Subject: |
[Qemu-devel] [PULL 10/10] target-tricore: add RR_DIV and RR_DIV_U instructions of the v1.6 ISA |
Date: |
Fri, 22 May 2015 17:06:08 +0200 |
Signed-off-by: Bastian Koppelmann <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
---
target-tricore/helper.h | 2 ++
target-tricore/op_helper.c | 49 ++++++++++++++++++++++++++++++++++++++++
target-tricore/translate.c | 21 +++++++++++++++++
target-tricore/tricore-opcodes.h | 2 ++
4 files changed, 74 insertions(+)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 842506c..cc221f1 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -113,6 +113,8 @@ DEF_HELPER_3(dvinit_h_131, i64, env, i32, i32)
DEF_HELPER_FLAGS_2(dvadj, TCG_CALL_NO_RWG_SE, i64, i64, i32)
DEF_HELPER_FLAGS_2(dvstep, TCG_CALL_NO_RWG_SE, i64, i64, i32)
DEF_HELPER_FLAGS_2(dvstep_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
+DEF_HELPER_3(divide, i64, env, i32, i32)
+DEF_HELPER_3(divide_u, i64, env, i32, i32)
/* mulh */
DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 7aa1f8e..10ed541 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -2094,6 +2094,55 @@ uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
}
+uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ int32_t quotient, remainder;
+ int32_t dividend = (int32_t)r1;
+ int32_t divisor = (int32_t)r2;
+
+ if (divisor == 0) {
+ if (dividend >= 0) {
+ quotient = 0x7fffffff;
+ remainder = 0;
+ } else {
+ quotient = 0x80000000;
+ remainder = 0;
+ }
+ env->PSW_USB_V = (1 << 31);
+ } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
+ quotient = 0x7fffffff;
+ remainder = 0;
+ env->PSW_USB_V = (1 << 31);
+ } else {
+ remainder = dividend % divisor;
+ quotient = (dividend - remainder)/divisor;
+ env->PSW_USB_V = 0;
+ }
+ env->PSW_USB_SV |= env->PSW_USB_V;
+ env->PSW_USB_AV = 0;
+ return ((uint64_t)remainder << 32) | (uint32_t)quotient;
+}
+
+uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ uint32_t quotient, remainder;
+ uint32_t dividend = r1;
+ uint32_t divisor = r2;
+
+ if (divisor == 0) {
+ quotient = 0xffffffff;
+ remainder = 0;
+ env->PSW_USB_V = (1 << 31);
+ } else {
+ remainder = dividend % divisor;
+ quotient = (dividend - remainder)/divisor;
+ env->PSW_USB_V = 0;
+ }
+ env->PSW_USB_SV |= env->PSW_USB_V;
+ env->PSW_USB_AV = 0;
+ return ((uint64_t)remainder << 32) | quotient;
+}
+
uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
uint32_t arg10, uint32_t arg11, uint32_t n)
{
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d4e4226..5f8eff0 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -201,6 +201,15 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
tcg_temp_free_i64(arg1); \
} while (0)
+#define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do { \
+ TCGv_i64 ret = tcg_temp_new_i64(); \
+ \
+ gen_helper_##name(ret, cpu_env, arg1, arg2); \
+ tcg_gen_extr_i64_i32(rl, rh, ret); \
+ \
+ tcg_temp_free_i64(ret); \
+} while (0)
+
#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
#define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
((offset & 0x0fffff) << 1))
@@ -6494,6 +6503,18 @@ static void decode_rr_divide(CPUTriCoreState *env,
DisasContext *ctx)
gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
} /* TODO: else raise illegal opcode trap */
break;
+ case OPC2_32_RR_DIV:
+ if (tricore_feature(env, TRICORE_FEATURE_16)) {
+ GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1],
+ cpu_gpr_d[r2]);
+ } /* TODO: else raise illegal opcode trap */
+ break;
+ case OPC2_32_RR_DIV_U:
+ if (tricore_feature(env, TRICORE_FEATURE_16)) {
+ GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
+ cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ } /* TODO: else raise illegal opcode trap */
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 22c79f5..1bfed0c 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1124,6 +1124,8 @@ enum {
OPC2_32_RR_PARITY = 0x02,
OPC2_32_RR_UNPACK = 0x08,
OPC2_32_RR_CRC32 = 0x03,
+ OPC2_32_RR_DIV = 0x20,
+ OPC2_32_RR_DIV_U = 0x21,
};
/* OPCM_32_RR_IDIRECT */
enum {
--
2.4.1
- [Qemu-devel] [PULL 00/10] tricore-patches, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 03/10] target-tricore: Add SRC_MOV_E instruction of the v1.6 ISA, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 08/10] target-tricore: add FCALL instructions of the v1.6 ISA, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 02/10] target-tricore: introduce ISA v1.6.1 feature, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 04/10] target-tricore: add CMPSWP instructions of the v1.6.1 ISA, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 06/10] target-tricore: add RR_CRC32 instruction of the v1.6.1 ISA, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 01/10] target-tricore: Add ISA v1.3.1 cpu and fix tc1796 to using v1.3, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 05/10] target-tricore: add SWAPMSK instructions of the v1.6.1 ISA, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 10/10] target-tricore: add RR_DIV and RR_DIV_U instructions of the v1.6 ISA,
Bastian Koppelmann <=
- [Qemu-devel] [PULL 07/10] target-tricore: add SYS_RESTORE instruction of the v1.6 ISA, Bastian Koppelmann, 2015/05/22
- [Qemu-devel] [PULL 09/10] target-tricore: add FRET instructions of the v1.6 ISA, Bastian Koppelmann, 2015/05/22
- Re: [Qemu-devel] [PULL 00/10] tricore-patches, Peter Maydell, 2015/05/22