* [Qemu-devel] [PULL 0/9] tricore patches
@ 2014-12-10 11:36 Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 1/9] target-tricore: Add instructions of BOL opcode format Bastian Koppelmann
` (9 more replies)
0 siblings, 10 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Hi,
here is my first round of TriCore patches for 2.3.
Cheers,
Bastian
The following changes since commit 7fb8da2b8861795e0013e6ee97acd0363d868a35:
Open 2.3 development tree (2014-12-09 21:48:34 +0000)
are available in the git repository at:
https://github.com/bkoppelmann/qemu-tricore-upstream.git tags/pull-tricore-20141210
for you to fetch changes up to 328f1f0f08f1aa303eef7493bd7c3d97a8d9636a:
target-tricore: Add instructions of RCR opcode format (2014-12-10 11:13:45 +0000)
----------------------------------------------------------------
TriCore BOL, BRC, BRN, BRR, RC, RCPW, RCRR, RCR, RLC and RCR insn added
----------------------------------------------------------------
Bastian Koppelmann (9):
target-tricore: Add instructions of BOL opcode format
target-tricore: Add instructions of BRC opcode format
target-tricore: Add instructions of BRN opcode format
target-tricore: Add instructions of BRR opcode format
target-tricore: Add instructions of RC opcode format
target-tricore: Make TRICORE_FEATURES implying others.
target-tricore: Add instructions of RCPW, RCRR and RCRW opcode format
target-tricore: Add instructions of RLC opcode format
target-tricore: Add instructions of RCR opcode format
target-tricore/cpu.c | 9 +
target-tricore/csfr.def | 124 +++
target-tricore/helper.h | 17 +
target-tricore/op_helper.c | 278 +++++++
target-tricore/translate.c | 1644 +++++++++++++++++++++++++++++++++++++-
target-tricore/tricore-opcodes.h | 17 +-
6 files changed, 2074 insertions(+), 15 deletions(-)
create mode 100644 target-tricore/csfr.def
--
2.1.3
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 1/9] target-tricore: Add instructions of BOL opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 2/9] target-tricore: Add instructions of BRC " Bastian Koppelmann
` (8 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of BOL opcode format.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/translate.c | 48 ++++++++++++++++++++++++++++++++++++++++
target-tricore/tricore-opcodes.h | 4 +++-
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d5a9596..28e268e 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -2279,6 +2279,46 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
tcg_temp_free(temp3);
}
+static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
+{
+ int r1, r2;
+ int32_t address;
+ TCGv temp;
+
+ r1 = MASK_OP_BOL_S1D(ctx->opcode);
+ r2 = MASK_OP_BOL_S2(ctx->opcode);
+ address = MASK_OP_BOL_OFF16_SEXT(ctx->opcode);
+
+ switch (op1) {
+ case OPC1_32_BOL_LD_A_LONGOFF:
+ temp = tcg_temp_new();
+ tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
+ tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);
+ tcg_temp_free(temp);
+ break;
+ case OPC1_32_BOL_LD_W_LONFOFF:
+ temp = tcg_temp_new();
+ tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
+ tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);
+ tcg_temp_free(temp);
+ break;
+ case OPC1_32_BOL_LEA_LONGOFF:
+ tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address);
+ break;
+ case OPC1_32_BOL_ST_A_LONGOFF:
+ if (tricore_feature(env, TRICORE_FEATURE_16)) {
+ gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
+ } else {
+ /* raise illegal opcode trap */
+ }
+ break;
+ case OPC1_32_BOL_ST_W_LONGOFF:
+ gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
+ break;
+ }
+
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
@@ -2405,6 +2445,14 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR:
decode_bo_addrmode_ldmst_bitreverse_circular(env, ctx);
break;
+/* BOL-format */
+ case OPC1_32_BOL_LD_A_LONGOFF:
+ case OPC1_32_BOL_LD_W_LONFOFF:
+ case OPC1_32_BOL_LEA_LONGOFF:
+ case OPC1_32_BOL_ST_W_LONGOFF:
+ case OPC1_32_BOL_ST_A_LONGOFF:
+ decode_bol_opc(env, ctx, op1);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 7e6f33b..ba07d85 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -115,7 +115,9 @@
#define MASK_OP_BOL_OFF16(op) ((MASK_BITS_SHIFT(op, 16, 21) + \
(MASK_BITS_SHIFT(op, 28, 31) << 6)) + \
(MASK_BITS_SHIFT(op, 22, 27) >> 10))
-
+#define MASK_OP_BOL_OFF16_SEXT(op) ((MASK_BITS_SHIFT(op, 16, 21) + \
+ (MASK_BITS_SHIFT(op, 28, 31) << 6)) + \
+ (MASK_BITS_SHIFT_SEXT(op, 22, 27) << 10))
#define MASK_OP_BOL_S2(op) MASK_BITS_SHIFT(op, 12, 15)
#define MASK_OP_BOL_S1D(op) MASK_BITS_SHIFT(op, 8, 11)
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 2/9] target-tricore: Add instructions of BRC opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 1/9] target-tricore: Add instructions of BOL opcode format Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 3/9] target-tricore: Add instructions of BRN " Bastian Koppelmann
` (7 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of BRC opcode format.
Fixed OP2_BRC_JGE -> OP2_32_BRC_JGE
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/translate.c | 53 +++++++++++++++++++++++++++++++++++++++-
target-tricore/tricore-opcodes.h | 6 +++--
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 28e268e..789f005 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -665,6 +665,47 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
break;
+/* BOL format */
+ case OPCM_32_BRC_EQ_NEQ:
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JEQ) {
+ gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], constant, offset);
+ } else {
+ gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], constant, offset);
+ }
+ break;
+ case OPCM_32_BRC_GE:
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OP2_32_BRC_JGE) {
+ gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], constant, offset);
+ } else {
+ constant = MASK_OP_BRC_CONST4(ctx->opcode);
+ gen_branch_condi(ctx, TCG_COND_GEU, cpu_gpr_d[r1], constant,
+ offset);
+ }
+ break;
+ case OPCM_32_BRC_JLT:
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JLT) {
+ gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], constant, offset);
+ } else {
+ constant = MASK_OP_BRC_CONST4(ctx->opcode);
+ gen_branch_condi(ctx, TCG_COND_LTU, cpu_gpr_d[r1], constant,
+ offset);
+ }
+ break;
+ case OPCM_32_BRC_JNE:
+ temp = tcg_temp_new();
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JNED) {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* subi is unconditional */
+ tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
+ } else {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* addi is unconditional */
+ tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
+ }
+ tcg_temp_free(temp);
+ break;
default:
printf("Branch Error at %x\n", ctx->pc);
}
@@ -2324,7 +2365,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
int op1;
int32_t r1;
int32_t address;
- int8_t b;
+ int8_t b, const4;
int32_t bpos;
TCGv temp, temp2;
@@ -2453,6 +2494,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPC1_32_BOL_ST_A_LONGOFF:
decode_bol_opc(env, ctx, op1);
break;
+/* BRC Format */
+ case OPCM_32_BRC_EQ_NEQ:
+ case OPCM_32_BRC_GE:
+ case OPCM_32_BRC_JLT:
+ case OPCM_32_BRC_JNE:
+ const4 = MASK_OP_BRC_CONST4_SEXT(ctx->opcode);
+ address = MASK_OP_BRC_DISP15_SEXT(ctx->opcode);
+ r1 = MASK_OP_BRC_S1(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, 0, const4, address);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index ba07d85..2d18624 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -124,7 +124,9 @@
/* BRC Format */
#define MASK_OP_BRC_OP2(op) MASK_BITS_SHIFT(op, 31, 31)
#define MASK_OP_BRC_DISP15(op) MASK_BITS_SHIFT(op, 16, 30)
+#define MASK_OP_BRC_DISP15_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 16, 30)
#define MASK_OP_BRC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_BRC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
#define MASK_OP_BRC_S1(op) MASK_BITS_SHIFT(op, 8, 11)
/* BRN Format */
@@ -765,8 +767,8 @@ enum {
};
/* OPCM_32_BRC_GE */
enum {
- OP2_BRC_JGE = 0x00,
- OPC_BRC_JGE_U = 0x01,
+ OP2_32_BRC_JGE = 0x00,
+ OPC_32_BRC_JGE_U = 0x01,
};
/* OPCM_32_BRC_JLT */
enum {
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 3/9] target-tricore: Add instructions of BRN opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 1/9] target-tricore: Add instructions of BOL opcode format Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 2/9] target-tricore: Add instructions of BRC " Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 4/9] target-tricore: Add instructions of BRR " Bastian Koppelmann
` (6 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of BRN opcode format.
Add MASK_OP_BRN_DISP15_SEXT.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/translate.c | 26 ++++++++++++++++++++++++++
target-tricore/tricore-opcodes.h | 1 +
2 files changed, 27 insertions(+)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 789f005..428a41e 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -568,6 +568,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
{
TCGv temp;
+ int n;
switch (opc) {
/* SB-format jumps */
@@ -706,6 +707,20 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
}
tcg_temp_free(temp);
break;
+/* BRN format */
+ case OPCM_32_BRN_JTT:
+ n = MASK_OP_BRN_N(ctx->opcode);
+
+ temp = tcg_temp_new();
+ tcg_gen_andi_tl(temp, cpu_gpr_d[r1], (1 << n));
+
+ if (MASK_OP_BRN_OP2(ctx->opcode) == OPC2_32_BRN_JNZ_T) {
+ gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
+ } else {
+ gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
+ }
+ tcg_temp_free(temp);
+ break;
default:
printf("Branch Error at %x\n", ctx->pc);
}
@@ -2371,6 +2386,11 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
op1 = MASK_OP_MAJOR(ctx->opcode);
+ /* handle JNZ.T opcode only being 6 bit long */
+ if (unlikely((op1 & 0x3f) == OPCM_32_BRN_JTT)) {
+ op1 = OPCM_32_BRN_JTT;
+ }
+
switch (op1) {
/* ABS-format */
case OPCM_32_ABS_LDW:
@@ -2504,6 +2524,12 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
r1 = MASK_OP_BRC_S1(ctx->opcode);
gen_compute_branch(ctx, op1, r1, 0, const4, address);
break;
+/* BRN Format */
+ case OPCM_32_BRN_JTT:
+ address = MASK_OP_BRN_DISP15_SEXT(ctx->opcode);
+ r1 = MASK_OP_BRN_S1(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, 0, 0, address);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 2d18624..3622d38 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -132,6 +132,7 @@
/* BRN Format */
#define MASK_OP_BRN_OP2(op) MASK_BITS_SHIFT(op, 31, 31)
#define MASK_OP_BRN_DISP15(op) MASK_BITS_SHIFT(op, 16, 30)
+#define MASK_OP_BRN_DISP15_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 16, 30)
#define MASK_OP_BRN_N(op) (MASK_BITS_SHIFT(op, 12, 15) + \
(MASK_BITS_SHIFT(op, 7, 7) << 4))
#define MASK_OP_BRN_S1(op) MASK_BITS_SHIFT(op, 8, 11)
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 4/9] target-tricore: Add instructions of BRR opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (2 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 3/9] target-tricore: Add instructions of BRN " Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 5/9] target-tricore: Add instructions of RC " Bastian Koppelmann
` (5 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of BRR opcode format.
Add MASK_OP_BRR_DISP15_SEXT.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/translate.c | 90 +++++++++++++++++++++++++++++++++++++++-
target-tricore/tricore-opcodes.h | 1 +
2 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 428a41e..84dd47d 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -567,7 +567,7 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
{
- TCGv temp;
+ TCGv temp, temp2;
int n;
switch (opc) {
@@ -721,6 +721,79 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
}
tcg_temp_free(temp);
break;
+/* BRR Format */
+ case OPCM_32_BRR_EQ_NEQ:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ) {
+ gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_ADDR_EQ_NEQ:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ_A) {
+ gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_a[r1], cpu_gpr_a[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_a[r1], cpu_gpr_a[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_GE:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JGE) {
+ gen_branch_cond(ctx, TCG_COND_GE, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_GEU, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_JLT:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JLT) {
+ gen_branch_cond(ctx, TCG_COND_LT, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ } else {
+ gen_branch_cond(ctx, TCG_COND_LTU, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ offset);
+ }
+ break;
+ case OPCM_32_BRR_LOOP:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_LOOP) {
+ gen_loop(ctx, r1, offset * 2);
+ } else {
+ /* OPC2_32_BRR_LOOPU */
+ gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+ }
+ break;
+ case OPCM_32_BRR_JNE:
+ temp = tcg_temp_new();
+ temp2 = tcg_temp_new();
+ if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRR_JNED) {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* also save r2, in case of r1 == r2, so r2 is not decremented */
+ tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
+ /* subi is unconditional */
+ tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
+ } else {
+ tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+ /* also save r2, in case of r1 == r2, so r2 is not decremented */
+ tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
+ /* addi is unconditional */
+ tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
+ gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
+ }
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ break;
+ case OPCM_32_BRR_JNZ:
+ if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JNZ_A) {
+ gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
+ } else {
+ gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
+ }
+ break;
default:
printf("Branch Error at %x\n", ctx->pc);
}
@@ -2378,7 +2451,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
- int32_t r1;
+ int32_t r1, r2;
int32_t address;
int8_t b, const4;
int32_t bpos;
@@ -2530,6 +2603,19 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
r1 = MASK_OP_BRN_S1(ctx->opcode);
gen_compute_branch(ctx, op1, r1, 0, 0, address);
break;
+/* BRR Format */
+ case OPCM_32_BRR_EQ_NEQ:
+ case OPCM_32_BRR_ADDR_EQ_NEQ:
+ case OPCM_32_BRR_GE:
+ case OPCM_32_BRR_JLT:
+ case OPCM_32_BRR_JNE:
+ case OPCM_32_BRR_JNZ:
+ case OPCM_32_BRR_LOOP:
+ address = MASK_OP_BRR_DISP15_SEXT(ctx->opcode);
+ r2 = MASK_OP_BRR_S2(ctx->opcode);
+ r1 = MASK_OP_BRR_S1(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, r2, 0, address);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 3622d38..7d35e3e 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -139,6 +139,7 @@
/* BRR Format */
#define MASK_OP_BRR_OP2(op) MASK_BITS_SHIFT(op, 31, 31)
#define MASK_OP_BRR_DISP15(op) MASK_BITS_SHIFT(op, 16, 30)
+#define MASK_OP_BRR_DISP15_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 16, 30)
#define MASK_OP_BRR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
#define MASK_OP_BRR_S1(op) MASK_BITS_SHIFT(op, 8, 11)
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 5/9] target-tricore: Add instructions of RC opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (3 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 4/9] target-tricore: Add instructions of BRR " Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 6/9] target-tricore: Make TRICORE_FEATURES implying others Bastian Koppelmann
` (4 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of RC opcode format.
Add helper for mul, sha, absdif with signed saturation on overflow.
Add helper for add, sub, mul with unsigned saturation on overflow.
Add microcode generator functions:
* gen_add_CC, which calculates the carry bit.
* gen_addc_CC, which adds the carry bit to the add and calculates the carry bit.
* gen_absdif, which calculates the absolute difference.
* gen_mul_i64s/u, which mul two 32 bits val into one 64bit reg.
* gen_sh_hi, which shifts two 16bit words in one reg.
* gen_sha_hi, which does a arithmetic shift on two 16bit words.
* gen_sh_cond, which shifts left a reg by one and writes the result of cond into the lsb.
* gen_accumulating_cond, which ands/ors/xors the result of cond of the lsbs
with the lsb of the result.
* gen_eqany_bi/hi, which checks ever byte/hword on equality.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/helper.h | 6 +
target-tricore/op_helper.c | 99 ++++++
target-tricore/translate.c | 693 +++++++++++++++++++++++++++++++++++++++
target-tricore/tricore-opcodes.h | 1 +
4 files changed, 799 insertions(+)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index b3fc33c..4893060 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -17,7 +17,13 @@
/* Arithmetic */
DEF_HELPER_3(add_ssov, i32, env, i32, i32)
+DEF_HELPER_3(add_suov, i32, env, i32, i32)
DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
+DEF_HELPER_3(sub_suov, i32, env, i32, i32)
+DEF_HELPER_3(mul_ssov, i32, env, i32, i32)
+DEF_HELPER_3(mul_suov, i32, env, i32, i32)
+DEF_HELPER_3(sha_ssov, i32, env, i32, i32)
+DEF_HELPER_3(absdif_ssov, i32, env, i32, i32)
/* CSA */
DEF_HELPER_2(call, void, env, i32)
DEF_HELPER_1(ret, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index a36988a..d8d57b0 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -77,6 +77,27 @@ uint32_t helper_circ_update(uint32_t reg, uint32_t off)
env->PSW_USB_SAV |= env->PSW_USB_AV; \
} while (0)
+#define SUOV(env, ret, arg, len) do { \
+ int64_t max_pos = UINT##len ##_MAX; \
+ if (arg > max_pos) { \
+ env->PSW_USB_V = (1 << 31); \
+ env->PSW_USB_SV = (1 << 31); \
+ ret = (target_ulong)max_pos; \
+ } else { \
+ if (arg < 0) { \
+ env->PSW_USB_V = (1 << 31); \
+ env->PSW_USB_SV = (1 << 31); \
+ ret = 0; \
+ } else { \
+ env->PSW_USB_V = 0; \
+ ret = (target_ulong)arg; \
+ } \
+ } \
+ env->PSW_USB_AV = arg ^ arg * 2u; \
+ env->PSW_USB_SAV |= env->PSW_USB_AV; \
+} while (0)
+
+
target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
target_ulong r2)
{
@@ -88,6 +109,17 @@ target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
return ret;
}
+target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t result = t1 + t2;
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
target_ulong r2)
{
@@ -99,6 +131,73 @@ target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
return ret;
}
+target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t result = t1 - t2;
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t result = t1 * t2;
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t result = t1 * t2;
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int32_t t2 = sextract64(r2, 0, 6);
+ int64_t result;
+ if (t2 == 0) {
+ result = t1;
+ } else if (t2 > 0) {
+ result = t1 << t2;
+ } else {
+ result = t1 >> -t2;
+ }
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t result;
+
+ if (t1 > t2) {
+ result = t1 - t2;
+ } else {
+ result = t2 - t1;
+ }
+ SSOV(env, ret, result, 32);
+ return ret;
+}
/* context save area (CSA) related helpers */
static int cdc_increment(target_ulong *psw)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 84dd47d..1daf26d 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -265,6 +265,76 @@ static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
gen_add_d(ret, r1, temp);
tcg_temp_free(temp);
}
+/* calculate the carry bit too */
+static inline void gen_add_CC(TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv t0 = tcg_temp_new_i32();
+ TCGv result = tcg_temp_new_i32();
+
+ tcg_gen_movi_tl(t0, 0);
+ /* Addition and set C/V/SV bits */
+ tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, r2, t0);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+ tcg_gen_xor_tl(t0, r1, r2);
+ tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, result, result);
+ tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_tl(ret, result);
+
+ tcg_temp_free(result);
+ tcg_temp_free(t0);
+}
+
+static inline void gen_addi_CC(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_add_CC(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_addc_CC(TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv carry = tcg_temp_new_i32();
+ TCGv t0 = tcg_temp_new_i32();
+ TCGv result = tcg_temp_new_i32();
+
+ tcg_gen_movi_tl(t0, 0);
+ tcg_gen_setcondi_tl(TCG_COND_NE, carry, cpu_PSW_C, 0);
+ /* Addition, carry and set C/V/SV bits */
+ tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, carry, t0);
+ tcg_gen_add2_i32(result, cpu_PSW_C, result, cpu_PSW_C, r2, t0);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+ tcg_gen_xor_tl(t0, r1, r2);
+ tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, result, result);
+ tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_tl(ret, result);
+
+ tcg_temp_free(result);
+ tcg_temp_free(t0);
+ tcg_temp_free(carry);
+}
+
+static inline void gen_addci_CC(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_addc_CC(ret, r1, temp);
+ tcg_temp_free(temp);
+}
static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
TCGv r4)
@@ -337,6 +407,49 @@ static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(result);
}
+static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv temp = tcg_temp_new_i32();
+ TCGv result = tcg_temp_new_i32();
+
+ tcg_gen_sub_tl(result, r1, r2);
+ tcg_gen_sub_tl(temp, r2, r1);
+ tcg_gen_movcond_tl(TCG_COND_GT, result, r1, r2, result, temp);
+
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+ tcg_gen_xor_tl(temp, result, r2);
+ tcg_gen_movcond_tl(TCG_COND_GT, cpu_PSW_V, r1, r2, cpu_PSW_V, temp);
+ tcg_gen_xor_tl(temp, r1, r2);
+ tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV bit */
+ tcg_gen_add_tl(cpu_PSW_AV, result, result);
+ tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
+ /* calc SAV bit */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_tl(ret, result);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(result);
+}
+
+static inline void gen_absdifi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_absdif(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_absdifsi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_absdif_ssov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
{
TCGv high = tcg_temp_new();
@@ -360,6 +473,71 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(low);
}
+static inline void gen_muli_i32s(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_mul_i32s(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mul_i64s(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
+{
+ tcg_gen_muls2_tl(ret_low, ret_high, r1, r2);
+ /* clear V bit */
+ tcg_gen_movi_tl(cpu_PSW_V, 0);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV bit */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV bit */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+}
+
+static inline void gen_muli_i64s(TCGv ret_low, TCGv ret_high, TCGv r1,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_mul_i64s(ret_low, ret_high, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mul_i64u(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
+{
+ tcg_gen_mulu2_tl(ret_low, ret_high, r1, r2);
+ /* clear V bit */
+ tcg_gen_movi_tl(cpu_PSW_V, 0);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV bit */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV bit */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+}
+
+static inline void gen_muli_i64u(TCGv ret_low, TCGv ret_high, TCGv r1,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_mul_i64u(ret_low, ret_high, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mulsi_i32(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_mul_ssov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_mulsui_i32(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_mul_suov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
{
TCGv sat_neg = tcg_const_i32(low);
@@ -394,6 +572,27 @@ static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
}
}
+static void gen_sh_hi(TCGv ret, TCGv r1, int32_t shiftcount)
+{
+ TCGv temp_low, temp_high;
+
+ if (shiftcount == -16) {
+ tcg_gen_movi_tl(ret, 0);
+ } else {
+ temp_high = tcg_temp_new();
+ temp_low = tcg_temp_new();
+
+ tcg_gen_andi_tl(temp_low, r1, 0xffff);
+ tcg_gen_andi_tl(temp_high, r1, 0xffff0000);
+ gen_shi(temp_low, temp_low, shiftcount);
+ gen_shi(ret, temp_high, shiftcount);
+ tcg_gen_deposit_tl(ret, ret, temp_low, 0, 16);
+
+ tcg_temp_free(temp_low);
+ tcg_temp_free(temp_high);
+ }
+}
+
static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
{
uint32_t msk, msk_start;
@@ -453,16 +652,100 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
tcg_temp_free(t_0);
}
+static void gen_shas(TCGv ret, TCGv r1, TCGv r2)
+{
+ gen_helper_sha_ssov(ret, cpu_env, r1, r2);
+}
+
+static void gen_shasi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_shas(ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static void gen_sha_hi(TCGv ret, TCGv r1, int32_t shift_count)
+{
+ TCGv low, high;
+
+ if (shift_count == 0) {
+ tcg_gen_mov_tl(ret, r1);
+ } else if (shift_count > 0) {
+ low = tcg_temp_new();
+ high = tcg_temp_new();
+
+ tcg_gen_andi_tl(high, r1, 0xffff0000);
+ tcg_gen_shli_tl(low, r1, shift_count);
+ tcg_gen_shli_tl(ret, high, shift_count);
+ tcg_gen_deposit_tl(ret, ret, low, 0, 16);
+
+ tcg_temp_free(low);
+ tcg_temp_free(high);
+ } else {
+ low = tcg_temp_new();
+ high = tcg_temp_new();
+
+ tcg_gen_ext16s_tl(low, r1);
+ tcg_gen_sari_tl(low, low, -shift_count);
+ tcg_gen_sari_tl(ret, r1, -shift_count);
+ tcg_gen_deposit_tl(ret, ret, low, 0, 16);
+
+ tcg_temp_free(low);
+ tcg_temp_free(high);
+ }
+
+}
+
+/* ret = {ret[30:0], (r1 cond r2)}; */
+static void gen_sh_cond(int cond, TCGv ret, TCGv r1, TCGv r2)
+{
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+
+ tcg_gen_shli_tl(temp, ret, 1);
+ tcg_gen_setcond_tl(cond, temp2, r1, r2);
+ tcg_gen_or_tl(ret, temp, temp2);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+static void gen_sh_condi(int cond, TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_sh_cond(cond, ret, r1, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
{
gen_helper_add_ssov(ret, cpu_env, r1, r2);
}
+static inline void gen_addsi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_add_ssov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_addsui(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_add_suov(ret, cpu_env, r1, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
{
gen_helper_sub_ssov(ret, cpu_env, r1, r2);
}
+static inline void gen_subsu(TCGv ret, TCGv r1, TCGv r2)
+{
+ gen_helper_sub_suov(ret, cpu_env, r1, r2);
+}
+
static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2,
int pos1, int pos2,
void(*op1)(TCGv, TCGv, TCGv),
@@ -506,6 +789,88 @@ static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
tcg_temp_free(temp2);
}
+static inline void gen_accumulating_cond(int cond, TCGv ret, TCGv r1, TCGv r2,
+ void(*op)(TCGv, TCGv, TCGv))
+{
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+ /* temp = (arg1 cond arg2 )*/
+ tcg_gen_setcond_tl(cond, temp, r1, r2);
+ /* temp2 = ret[0]*/
+ tcg_gen_andi_tl(temp2, ret, 0x1);
+ /* temp = temp insn temp2 */
+ (*op)(temp, temp, temp2);
+ /* ret = {ret[31:1], temp} */
+ tcg_gen_deposit_tl(ret, ret, temp, 0, 1);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+static inline void
+gen_accumulating_condi(int cond, TCGv ret, TCGv r1, int32_t con,
+ void(*op)(TCGv, TCGv, TCGv))
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_accumulating_cond(cond, ret, r1, temp, op);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv b0 = tcg_temp_new();
+ TCGv b1 = tcg_temp_new();
+ TCGv b2 = tcg_temp_new();
+ TCGv b3 = tcg_temp_new();
+
+ /* byte 0 */
+ tcg_gen_andi_tl(b0, r1, 0xff);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b0, b0, con & 0xff);
+
+ /* byte 1 */
+ tcg_gen_andi_tl(b1, r1, 0xff00);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b1, b1, con & 0xff00);
+
+ /* byte 2 */
+ tcg_gen_andi_tl(b2, r1, 0xff0000);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b2, b2, con & 0xff0000);
+
+ /* byte 3 */
+ tcg_gen_andi_tl(b3, r1, 0xff000000);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, b3, b3, con & 0xff000000);
+
+ /* combine them */
+ tcg_gen_or_tl(ret, b0, b1);
+ tcg_gen_or_tl(ret, ret, b2);
+ tcg_gen_or_tl(ret, ret, b3);
+
+ tcg_temp_free(b0);
+ tcg_temp_free(b1);
+ tcg_temp_free(b2);
+ tcg_temp_free(b3);
+}
+
+static inline void gen_eqany_hi(TCGv ret, TCGv r1, int32_t con)
+{
+ TCGv h0 = tcg_temp_new();
+ TCGv h1 = tcg_temp_new();
+
+ /* halfword 0 */
+ tcg_gen_andi_tl(h0, r1, 0xffff);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, h0, h0, con & 0xffff);
+
+ /* halfword 1 */
+ tcg_gen_andi_tl(h1, r1, 0xffff0000);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, h1, h1, con & 0xffff0000);
+
+ /* combine them */
+ tcg_gen_or_tl(ret, h0, h1);
+
+ tcg_temp_free(h0);
+ tcg_temp_free(h1);
+}
+
+
/* helpers for generating program flow micro-ops */
static inline void gen_save_pc(target_ulong pc)
@@ -2448,6 +2813,321 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
}
+/* RC format */
+static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int32_t const9;
+ TCGv temp;
+
+ r2 = MASK_OP_RC_D(ctx->opcode);
+ r1 = MASK_OP_RC_S1(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+
+ temp = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_RC_AND:
+ tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ANDN:
+ tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
+ break;
+ case OPC2_32_RC_NAND:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_nand_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_NOR:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_nor_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_OR:
+ tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ORN:
+ tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
+ break;
+ case OPC2_32_RC_SH:
+ const9 = sextract32(const9, 0, 6);
+ gen_shi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_H:
+ const9 = sextract32(const9, 0, 5);
+ gen_sh_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SHA:
+ const9 = sextract32(const9, 0, 6);
+ gen_shaci(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SHA_H:
+ const9 = sextract32(const9, 0, 5);
+ gen_sha_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SHAS:
+ gen_shasi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_XNOR:
+ tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ tcg_gen_not_tl(cpu_gpr_d[r2], cpu_gpr_d[r2]);
+ break;
+ case OPC2_32_RC_XOR:
+ tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ }
+ tcg_temp_free(temp);
+}
+
+static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int16_t const9;
+
+ TCGv temp;
+
+ r2 = MASK_OP_RC_D(ctx->opcode);
+ r1 = MASK_OP_RC_S1(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
+
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+
+ temp = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_RC_ABSDIF:
+ gen_absdifi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ABSDIFS:
+ gen_absdifsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADD:
+ gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDC:
+ gen_addci_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDS:
+ gen_addsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDS_U:
+ gen_addsui(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_ADDX:
+ gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_AND_EQ:
+ gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_GE:
+ gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_LT:
+ gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_AND_NE:
+ gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_RC_EQ:
+ tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_EQANY_B:
+ gen_eqany_bi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_EQANY_H:
+ gen_eqany_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_GE:
+ tcg_gen_setcondi_tl(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_LT:
+ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MAX:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_MAX_U:
+ tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
+ tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_MIN:
+ tcg_gen_movi_tl(temp, const9);
+ tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_MIN_U:
+ tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
+ tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
+ cpu_gpr_d[r1], temp);
+ break;
+ case OPC2_32_RC_NE:
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_OR_EQ:
+ gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_GE:
+ gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_LT:
+ gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_OR_NE:
+ gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_RC_RSUB:
+ tcg_gen_movi_tl(temp, const9);
+ gen_sub_d(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RC_RSUBS:
+ tcg_gen_movi_tl(temp, const9);
+ gen_subs(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RC_RSUBS_U:
+ tcg_gen_movi_tl(temp, const9);
+ gen_subsu(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RC_SH_EQ:
+ gen_sh_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_GE:
+ gen_sh_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_sh_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_LT:
+ gen_sh_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_sh_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_SH_NE:
+ gen_sh_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_XOR_EQ:
+ gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_GE:
+ gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_GE_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_LT:
+ gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_LT_U:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ case OPC2_32_RC_XOR_NE:
+ gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
+ const9, &tcg_gen_xor_tl);
+ break;
+ }
+ tcg_temp_free(temp);
+}
+
+static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ uint32_t const9;
+
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RC_BISR:
+ gen_helper_1arg(bisr, const9);
+ break;
+ case OPC2_32_RC_SYSCALL:
+ /* TODO: Add exception generation */
+ break;
+ }
+}
+
+static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int16_t const9;
+
+ r2 = MASK_OP_RC_D(ctx->opcode);
+ r1 = MASK_OP_RC_S1(ctx->opcode);
+ const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
+
+ op2 = MASK_OP_RC_OP2(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RC_MUL_32:
+ gen_muli_i32s(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MUL_64:
+ gen_muli_i64s(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MULS_32:
+ gen_mulsi_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MUL_U_64:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_muli_i64u(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
+ break;
+ case OPC2_32_RC_MULS_U_32:
+ const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ gen_mulsui_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
+ break;
+ }
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
@@ -2616,6 +3296,19 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
r1 = MASK_OP_BRR_S1(ctx->opcode);
gen_compute_branch(ctx, op1, r1, r2, 0, address);
break;
+/* RC Format */
+ case OPCM_32_RC_LOGICAL_SHIFT:
+ decode_rc_logical_shift(env, ctx);
+ break;
+ case OPCM_32_RC_ACCUMULATOR:
+ decode_rc_accumulator(env, ctx);
+ break;
+ case OPCM_32_RC_SERVICEROUTINE:
+ decode_rc_serviceroutine(env, ctx);
+ break;
+ case OPCM_32_RC_MUL:
+ decode_rc_mul(env, ctx);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 7d35e3e..9b042e4 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -151,6 +151,7 @@
#define MASK_OP_RC_D(op) MASK_OP_META_D(op)
#define MASK_OP_RC_OP2(op) MASK_BITS_SHIFT(op, 21, 27)
#define MASK_OP_RC_CONST9(op) MASK_BITS_SHIFT(op, 12, 20)
+#define MASK_OP_RC_CONST9_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 20)
#define MASK_OP_RC_S1(op) MASK_OP_META_S1(op)
/* RCPW Format */
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 6/9] target-tricore: Make TRICORE_FEATURES implying others.
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (4 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 5/9] target-tricore: Add instructions of RC " Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 7/9] target-tricore: Add instructions of RCPW, RCRR and RCRW opcode format Bastian Koppelmann
` (3 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Since all the TriCore instructionsets are subsets of each other (1.3 C 1.3.1 C 1.6),
make the features implying each other, e.g 1.6 also has 1.3.1 and 1.3. This way
we only need to check our features for the instructionset, where a instruction was first introduced.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/cpu.c | 9 +++++++++
target-tricore/translate.c | 6 +++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index 7bf041a..abe16fa 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -63,8 +63,17 @@ static bool tricore_cpu_has_work(CPUState *cs)
static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
+ TriCoreCPU *cpu = TRICORE_CPU(dev);
TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(dev);
+ CPUTriCoreState *env = &cpu->env;
+ /* Some features automatically imply others */
+ if (tricore_feature(env, TRICORE_FEATURE_16)) {
+ set_feature(env, TRICORE_FEATURE_131);
+ }
+ if (tricore_feature(env, TRICORE_FEATURE_131)) {
+ set_feature(env, TRICORE_FEATURE_13);
+ }
cpu_reset(cs);
qemu_init_vcpu(cs);
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 1daf26d..3775374 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -2206,17 +2206,17 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
case OPC2_32_BO_CACHEI_WI_SHORTOFF:
case OPC2_32_BO_CACHEI_W_SHORTOFF:
/* TODO: Raise illegal opcode trap,
- if tricore_feature(TRICORE_FEATURE_13) */
+ if !tricore_feature(TRICORE_FEATURE_131) */
break;
case OPC2_32_BO_CACHEI_W_POSTINC:
case OPC2_32_BO_CACHEI_WI_POSTINC:
- if (!tricore_feature(env, TRICORE_FEATURE_13)) {
+ if (tricore_feature(env, TRICORE_FEATURE_131)) {
tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10);
} /* TODO: else raise illegal opcode trap */
break;
case OPC2_32_BO_CACHEI_W_PREINC:
case OPC2_32_BO_CACHEI_WI_PREINC:
- if (!tricore_feature(env, TRICORE_FEATURE_13)) {
+ if (tricore_feature(env, TRICORE_FEATURE_131)) {
tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10);
} /* TODO: else raise illegal opcode trap */
break;
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 7/9] target-tricore: Add instructions of RCPW, RCRR and RCRW opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (5 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 6/9] target-tricore: Make TRICORE_FEATURES implying others Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 8/9] target-tricore: Add instructions of RLC " Bastian Koppelmann
` (2 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of RCPW, RCRR and RCRW opcode format.
Add microcode generator function gen_insert.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/translate.c | 132 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 129 insertions(+), 3 deletions(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 3775374..689596f 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -869,7 +869,28 @@ static inline void gen_eqany_hi(TCGv ret, TCGv r1, int32_t con)
tcg_temp_free(h0);
tcg_temp_free(h1);
}
+/* mask = ((1 << width) -1) << pos;
+ ret = (r1 & ~mask) | (r2 << pos) & mask); */
+static inline void gen_insert(TCGv ret, TCGv r1, TCGv r2, TCGv width, TCGv pos)
+{
+ TCGv mask = tcg_temp_new();
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+ tcg_gen_movi_tl(mask, 1);
+ tcg_gen_shl_tl(mask, mask, width);
+ tcg_gen_subi_tl(mask, mask, 1);
+ tcg_gen_shl_tl(mask, mask, pos);
+
+ tcg_gen_shl_tl(temp, r2, pos);
+ tcg_gen_and_tl(temp, temp, mask);
+ tcg_gen_andc_tl(temp2, r1, mask);
+ tcg_gen_or_tl(ret, temp, temp2);
+
+ tcg_temp_free(mask);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
/* helpers for generating program flow micro-ops */
@@ -3128,14 +3149,92 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
}
}
+/* RCPW format */
+static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r2;
+ int32_t pos, width, const4;
+
+ TCGv temp;
+
+ op2 = MASK_OP_RCPW_OP2(ctx->opcode);
+ r1 = MASK_OP_RCPW_S1(ctx->opcode);
+ r2 = MASK_OP_RCPW_D(ctx->opcode);
+ const4 = MASK_OP_RCPW_CONST4(ctx->opcode);
+ width = MASK_OP_RCPW_WIDTH(ctx->opcode);
+ pos = MASK_OP_RCPW_POS(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCPW_IMASK:
+ /* if pos + width > 31 undefined result */
+ if (pos + width <= 31) {
+ tcg_gen_movi_tl(cpu_gpr_d[r2+1], ((1u << width) - 1) << pos);
+ tcg_gen_movi_tl(cpu_gpr_d[r2], (const4 << pos));
+ }
+ break;
+ case OPC2_32_RCPW_INSERT:
+ /* if pos + width > 32 undefined result */
+ if (pos + width <= 32) {
+ temp = tcg_const_i32(const4);
+ tcg_gen_deposit_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, pos, width);
+ tcg_temp_free(temp);
+ }
+ break;
+ }
+}
+
+/* RCRW format */
+
+static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t width, const4;
+
+ TCGv temp, temp2, temp3;
+
+ op2 = MASK_OP_RCRW_OP2(ctx->opcode);
+ r1 = MASK_OP_RCRW_S1(ctx->opcode);
+ r3 = MASK_OP_RCRW_S3(ctx->opcode);
+ r4 = MASK_OP_RCRW_D(ctx->opcode);
+ width = MASK_OP_RCRW_WIDTH(ctx->opcode);
+ const4 = MASK_OP_RCRW_CONST4(ctx->opcode);
+
+ temp = tcg_temp_new();
+ temp2 = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_RCRW_IMASK:
+ tcg_gen_andi_tl(temp, cpu_gpr_d[r4], 0x1f);
+ tcg_gen_movi_tl(temp2, (1 << width) - 1);
+ tcg_gen_shl_tl(cpu_gpr_d[r3 + 1], temp2, temp);
+ tcg_gen_movi_tl(temp2, const4);
+ tcg_gen_shl_tl(cpu_gpr_d[r3], temp2, temp);
+ break;
+ case OPC2_32_RCRW_INSERT:
+ temp3 = tcg_temp_new();
+
+ tcg_gen_movi_tl(temp, width);
+ tcg_gen_movi_tl(temp2, const4);
+ tcg_gen_andi_tl(temp3, cpu_gpr_d[r4], 0x1f);
+ gen_insert(cpu_gpr_d[r3], cpu_gpr_d[r1], temp2, temp, temp3);
+
+ tcg_temp_free(temp3);
+ break;
+ }
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
- int32_t r1, r2;
- int32_t address;
+ int32_t r1, r2, r3;
+ int32_t address, const16;
int8_t b, const4;
int32_t bpos;
- TCGv temp, temp2;
+ TCGv temp, temp2, temp3;
op1 = MASK_OP_MAJOR(ctx->opcode);
@@ -3309,6 +3408,33 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPCM_32_RC_MUL:
decode_rc_mul(env, ctx);
break;
+/* RCPW Format */
+ case OPCM_32_RCPW_MASK_INSERT:
+ decode_rcpw_insert(env, ctx);
+ break;
+/* RCRR Format */
+ case OPC1_32_RCRR_INSERT:
+ r1 = MASK_OP_RCRR_S1(ctx->opcode);
+ r2 = MASK_OP_RCRR_S3(ctx->opcode);
+ r3 = MASK_OP_RCRR_D(ctx->opcode);
+ const16 = MASK_OP_RCRR_CONST4(ctx->opcode);
+ temp = tcg_const_i32(const16);
+ temp2 = tcg_temp_new(); /* width*/
+ temp3 = tcg_temp_new(); /* pos */
+
+ tcg_gen_andi_tl(temp2, cpu_gpr_d[r3+1], 0x1f);
+ tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
+
+ gen_insert(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, temp2, temp3);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ tcg_temp_free(temp3);
+ break;
+/* RCRW Format */
+ case OPCM_32_RCRW_MASK_INSERT:
+ decode_rcrw_insert(env, ctx);
+ break;
}
}
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 8/9] target-tricore: Add instructions of RLC opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (6 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 7/9] target-tricore: Add instructions of RCPW, RCRR and RCRW opcode format Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 9/9] target-tricore: Add instructions of RCR " Bastian Koppelmann
2014-12-11 12:07 ` [Qemu-devel] [PULL 0/9] tricore patches Peter Maydell
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of RLC opcode format.
Add helper psw_write/read.
Add microcode generator gen_mtcr/mfcr, which loads/stores a value to a core special function register, which are defined in csfr.def
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/csfr.def | 124 +++++++++++++++++++++++++++++++++++++++
target-tricore/helper.h | 3 +
target-tricore/op_helper.c | 11 ++++
target-tricore/translate.c | 113 +++++++++++++++++++++++++++++++++++
target-tricore/tricore-opcodes.h | 1 +
5 files changed, 252 insertions(+)
create mode 100644 target-tricore/csfr.def
diff --git a/target-tricore/csfr.def b/target-tricore/csfr.def
new file mode 100644
index 0000000..5b219b4
--- /dev/null
+++ b/target-tricore/csfr.def
@@ -0,0 +1,124 @@
+/* A(ll) access permited
+ R(ead only) access
+ E(nd init protected) access
+
+ A|R|E(offset, register, feature introducing reg)
+
+ NOTE: PSW is handled as a special case in gen_mtcr/mfcr */
+
+A(0xfe00, PCXI, TRICORE_FEATURE_13)
+A(0xfe08, PC, TRICORE_FEATURE_13)
+A(0xfe14, SYSCON, TRICORE_FEATURE_13)
+R(0xfe18, CPU_ID, TRICORE_FEATURE_13)
+E(0xfe20, BIV, TRICORE_FEATURE_13)
+E(0xfe24, BTV, TRICORE_FEATURE_13)
+E(0xfe28, ISP, TRICORE_FEATURE_13)
+A(0xfe2c, ICR, TRICORE_FEATURE_13)
+A(0xfe38, FCX, TRICORE_FEATURE_13)
+A(0xfe3c, LCX, TRICORE_FEATURE_13)
+E(0x9400, COMPAT, TRICORE_FEATURE_131)
+/* memory protection register */
+A(0xC000, DPR0_0L, TRICORE_FEATURE_13)
+A(0xC004, DPR0_0U, TRICORE_FEATURE_13)
+A(0xC008, DPR0_1L, TRICORE_FEATURE_13)
+A(0xC00C, DPR0_1U, TRICORE_FEATURE_13)
+A(0xC010, DPR0_2L, TRICORE_FEATURE_13)
+A(0xC014, DPR0_2U, TRICORE_FEATURE_13)
+A(0xC018, DPR0_3L, TRICORE_FEATURE_13)
+A(0xC01C, DPR0_3U, TRICORE_FEATURE_13)
+A(0xC400, DPR1_0L, TRICORE_FEATURE_13)
+A(0xC404, DPR1_0U, TRICORE_FEATURE_13)
+A(0xC408, DPR1_1L, TRICORE_FEATURE_13)
+A(0xC40C, DPR1_1U, TRICORE_FEATURE_13)
+A(0xC410, DPR1_2L, TRICORE_FEATURE_13)
+A(0xC414, DPR1_2U, TRICORE_FEATURE_13)
+A(0xC418, DPR1_3L, TRICORE_FEATURE_13)
+A(0xC41C, DPR1_3U, TRICORE_FEATURE_13)
+A(0xC800, DPR2_0L, TRICORE_FEATURE_13)
+A(0xC804, DPR2_0U, TRICORE_FEATURE_13)
+A(0xC808, DPR2_1L, TRICORE_FEATURE_13)
+A(0xC80C, DPR2_1U, TRICORE_FEATURE_13)
+A(0xC810, DPR2_2L, TRICORE_FEATURE_13)
+A(0xC814, DPR2_2U, TRICORE_FEATURE_13)
+A(0xC818, DPR2_3L, TRICORE_FEATURE_13)
+A(0xC81C, DPR2_3U, TRICORE_FEATURE_13)
+A(0xCC00, DPR3_0L, TRICORE_FEATURE_13)
+A(0xCC04, DPR3_0U, TRICORE_FEATURE_13)
+A(0xCC08, DPR3_1L, TRICORE_FEATURE_13)
+A(0xCC0C, DPR3_1U, TRICORE_FEATURE_13)
+A(0xCC10, DPR3_2L, TRICORE_FEATURE_13)
+A(0xCC14, DPR3_2U, TRICORE_FEATURE_13)
+A(0xCC18, DPR3_3L, TRICORE_FEATURE_13)
+A(0xCC1C, DPR3_3U, TRICORE_FEATURE_13)
+A(0xD000, CPR0_0L, TRICORE_FEATURE_13)
+A(0xD004, CPR0_0U, TRICORE_FEATURE_13)
+A(0xD008, CPR0_1L, TRICORE_FEATURE_13)
+A(0xD00C, CPR0_1U, TRICORE_FEATURE_13)
+A(0xD010, CPR0_2L, TRICORE_FEATURE_13)
+A(0xD014, CPR0_2U, TRICORE_FEATURE_13)
+A(0xD018, CPR0_3L, TRICORE_FEATURE_13)
+A(0xD01C, CPR0_3U, TRICORE_FEATURE_13)
+A(0xD400, CPR1_0L, TRICORE_FEATURE_13)
+A(0xD404, CPR1_0U, TRICORE_FEATURE_13)
+A(0xD408, CPR1_1L, TRICORE_FEATURE_13)
+A(0xD40C, CPR1_1U, TRICORE_FEATURE_13)
+A(0xD410, CPR1_2L, TRICORE_FEATURE_13)
+A(0xD414, CPR1_2U, TRICORE_FEATURE_13)
+A(0xD418, CPR1_3L, TRICORE_FEATURE_13)
+A(0xD41C, CPR1_3U, TRICORE_FEATURE_13)
+A(0xD800, CPR2_0L, TRICORE_FEATURE_13)
+A(0xD804, CPR2_0U, TRICORE_FEATURE_13)
+A(0xD808, CPR2_1L, TRICORE_FEATURE_13)
+A(0xD80C, CPR2_1U, TRICORE_FEATURE_13)
+A(0xD810, CPR2_2L, TRICORE_FEATURE_13)
+A(0xD814, CPR2_2U, TRICORE_FEATURE_13)
+A(0xD818, CPR2_3L, TRICORE_FEATURE_13)
+A(0xD81C, CPR2_3U, TRICORE_FEATURE_13)
+A(0xDC00, CPR3_0L, TRICORE_FEATURE_13)
+A(0xDC04, CPR3_0U, TRICORE_FEATURE_13)
+A(0xDC08, CPR3_1L, TRICORE_FEATURE_13)
+A(0xDC0C, CPR3_1U, TRICORE_FEATURE_13)
+A(0xDC10, CPR3_2L, TRICORE_FEATURE_13)
+A(0xDC14, CPR3_2U, TRICORE_FEATURE_13)
+A(0xDC18, CPR3_3L, TRICORE_FEATURE_13)
+A(0xDC1C, CPR3_3U, TRICORE_FEATURE_13)
+A(0xE000, DPM0, TRICORE_FEATURE_13)
+A(0xE080, DPM1, TRICORE_FEATURE_13)
+A(0xE100, DPM2, TRICORE_FEATURE_13)
+A(0xE180, DPM3, TRICORE_FEATURE_13)
+A(0xE200, CPM0, TRICORE_FEATURE_13)
+A(0xE280, CPM1, TRICORE_FEATURE_13)
+A(0xE300, CPM2, TRICORE_FEATURE_13)
+A(0xE380, CPM3, TRICORE_FEATURE_13)
+/* memory Managment Registers */
+A(0x8000, MMU_CON, TRICORE_FEATURE_13)
+A(0x8004, MMU_ASI, TRICORE_FEATURE_13)
+A(0x800C, MMU_TVA, TRICORE_FEATURE_13)
+A(0x8010, MMU_TPA, TRICORE_FEATURE_13)
+A(0x8014, MMU_TPX, TRICORE_FEATURE_13)
+A(0x8018, MMU_TFA, TRICORE_FEATURE_13)
+E(0x9004, BMACON, TRICORE_FEATURE_131)
+E(0x900C, SMACON, TRICORE_FEATURE_131)
+A(0x9020, DIEAR, TRICORE_FEATURE_131)
+A(0x9024, DIETR, TRICORE_FEATURE_131)
+A(0x9028, CCDIER, TRICORE_FEATURE_131)
+E(0x9044, MIECON, TRICORE_FEATURE_131)
+A(0x9210, PIEAR, TRICORE_FEATURE_131)
+A(0x9214, PIETR, TRICORE_FEATURE_131)
+A(0x9218, CCPIER, TRICORE_FEATURE_131)
+/* debug registers */
+A(0xFD00, DBGSR, TRICORE_FEATURE_13)
+A(0xFD08, EXEVT, TRICORE_FEATURE_13)
+A(0xFD0C, CREVT, TRICORE_FEATURE_13)
+A(0xFD10, SWEVT, TRICORE_FEATURE_13)
+A(0xFD20, TR0EVT, TRICORE_FEATURE_13)
+A(0xFD24, TR1EVT, TRICORE_FEATURE_13)
+A(0xFD40, DMS, TRICORE_FEATURE_13)
+A(0xFD44, DCX, TRICORE_FEATURE_13)
+A(0xFD48, DBGTCR, TRICORE_FEATURE_131)
+A(0xFC00, CCTRL, TRICORE_FEATURE_131)
+A(0xFC04, CCNT, TRICORE_FEATURE_131)
+A(0xFC08, ICNT, TRICORE_FEATURE_131)
+A(0xFC0C, M1CNT, TRICORE_FEATURE_131)
+A(0xFC10, M2CNT, TRICORE_FEATURE_131)
+A(0xFC14, M3CNT, TRICORE_FEATURE_131)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 4893060..2eb33ea 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -36,3 +36,6 @@ DEF_HELPER_2(stucx, void, env, i32)
/* Address mode helper */
DEF_HELPER_1(br_update, i32, i32)
DEF_HELPER_2(circ_update, i32, i32, i32)
+/* PSW cache helper */
+DEF_HELPER_2(psw_write, void, env, i32)
+DEF_HELPER_1(psw_read, i32, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index d8d57b0..0b6b471 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -536,6 +536,17 @@ void helper_stucx(CPUTriCoreState *env, uint32_t ea)
save_context_upper(env, ea);
}
+void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
+{
+ psw_write(env, arg);
+}
+
+uint32_t helper_psw_read(CPUTriCoreState *env)
+{
+ return psw_read(env);
+}
+
+
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
uint32_t exception,
int error_code,
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 689596f..fdc9ade 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -233,6 +233,63 @@ static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
tcg_temp_free(temp);
}
+/* We generate loads and store to core special function register (csfr) through
+ the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
+ makros R, A and E, which allow read-only, all and endinit protected access.
+ These makros also specify in which ISA version the csfr was introduced. */
+#define R(ADDRESS, REG, FEATURE) \
+ case ADDRESS: \
+ if (tricore_feature(env, FEATURE)) { \
+ tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \
+ } \
+ break;
+#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
+#define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
+static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
+{
+ /* since we're caching PSW make this a special case */
+ if (offset == 0xfe04) {
+ gen_helper_psw_read(ret, cpu_env);
+ } else {
+ switch (offset) {
+#include "csfr.def"
+ }
+ }
+}
+#undef R
+#undef A
+#undef E
+
+#define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
+ since no execption occurs */
+#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
+ case ADDRESS: \
+ if (tricore_feature(env, FEATURE)) { \
+ tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG)); \
+ } \
+ break;
+/* Endinit protected registers
+ TODO: Since the endinit bit is in a register of a not yet implemented
+ watchdog device, we handle endinit protected registers like
+ all-access registers for now. */
+#define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
+static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1,
+ int32_t offset)
+{
+ if (ctx->hflags & TRICORE_HFLAG_SM) {
+ /* since we're caching PSW make this a special case */
+ if (offset == 0xfe04) {
+ gen_helper_psw_write(cpu_env, r1);
+ } else {
+ switch (offset) {
+#include "csfr.def"
+ }
+ }
+ } else {
+ /* generate privilege trap */
+ }
+}
+
/* Functions for arithmetic instructions */
static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
@@ -3227,6 +3284,50 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp2);
}
+/* RLC format */
+
+static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
+ uint32_t op1)
+{
+ int32_t const16;
+ int r1, r2;
+
+ const16 = MASK_OP_RLC_CONST16_SEXT(ctx->opcode);
+ r1 = MASK_OP_RLC_S1(ctx->opcode);
+ r2 = MASK_OP_RLC_D(ctx->opcode);
+
+ switch (op1) {
+ case OPC1_32_RLC_ADDI:
+ gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const16);
+ break;
+ case OPC1_32_RLC_ADDIH:
+ gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const16 << 16);
+ break;
+ case OPC1_32_RLC_ADDIH_A:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r1], const16 << 16);
+ break;
+ case OPC1_32_RLC_MFCR:
+ gen_mfcr(env, cpu_gpr_d[r2], const16);
+ break;
+ case OPC1_32_RLC_MOV:
+ tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
+ break;
+ case OPC1_32_RLC_MOV_U:
+ const16 = MASK_OP_RLC_CONST16(ctx->opcode);
+ tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
+ break;
+ case OPC1_32_RLC_MOV_H:
+ tcg_gen_movi_tl(cpu_gpr_d[r2], const16 << 16);
+ break;
+ case OPC1_32_RLC_MOVH_A:
+ tcg_gen_movi_tl(cpu_gpr_a[r2], const16 << 16);
+ break;
+ case OPC1_32_RLC_MTCR:
+ gen_mtcr(env, ctx, cpu_gpr_d[r2], const16);
+ break;
+ }
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
@@ -3435,6 +3536,18 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPCM_32_RCRW_MASK_INSERT:
decode_rcrw_insert(env, ctx);
break;
+/* RLC Format */
+ case OPC1_32_RLC_ADDI:
+ case OPC1_32_RLC_ADDIH:
+ case OPC1_32_RLC_ADDIH_A:
+ case OPC1_32_RLC_MFCR:
+ case OPC1_32_RLC_MOV:
+ case OPC1_32_RLC_MOV_U:
+ case OPC1_32_RLC_MOV_H:
+ case OPC1_32_RLC_MOVH_A:
+ case OPC1_32_RLC_MTCR:
+ decode_rlc_opc(env, ctx, op1);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 9b042e4..bafc8fb 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -192,6 +192,7 @@
#define MASK_OP_RLC_D(op) MASK_OP_META_D(op)
#define MASK_OP_RLC_CONST16(op) MASK_BITS_SHIFT(op, 12, 27)
+#define MASK_OP_RLC_CONST16_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 27)
#define MASK_OP_RLC_S1(op) MASK_OP_META_S1(op)
/* RR Format */
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 9/9] target-tricore: Add instructions of RCR opcode format
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (7 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 8/9] target-tricore: Add instructions of RLC " Bastian Koppelmann
@ 2014-12-10 11:36 ` Bastian Koppelmann
2014-12-11 12:07 ` [Qemu-devel] [PULL 0/9] tricore patches Peter Maydell
9 siblings, 0 replies; 15+ messages in thread
From: Bastian Koppelmann @ 2014-12-10 11:36 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of RCR opcode format.
Add helper for madd32/64_ssov and madd32/64_suov.
Add helper for msub32/64_ssov and msub32/64_suov.
Add microcode generator function madd/msub for 32bit and 64bit, which calculate a mul and a add/sub.
OPC2_32_RCR_MSUB_U_32 -> OPC2_32_RCR_MSUB_U_32.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
target-tricore/helper.h | 8 +
target-tricore/op_helper.c | 168 ++++++++++++++
target-tricore/translate.c | 479 +++++++++++++++++++++++++++++++++++++++
target-tricore/tricore-opcodes.h | 3 +-
4 files changed, 657 insertions(+), 1 deletion(-)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 2eb33ea..6c07bd7 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -24,6 +24,14 @@ DEF_HELPER_3(mul_ssov, i32, env, i32, i32)
DEF_HELPER_3(mul_suov, i32, env, i32, i32)
DEF_HELPER_3(sha_ssov, i32, env, i32, i32)
DEF_HELPER_3(absdif_ssov, i32, env, i32, i32)
+DEF_HELPER_4(madd32_ssov, i32, env, i32, i32, i32)
+DEF_HELPER_4(madd32_suov, i32, env, i32, i32, i32)
+DEF_HELPER_4(madd64_ssov, i64, env, i32, i64, i32)
+DEF_HELPER_4(madd64_suov, i64, env, i32, i64, i32)
+DEF_HELPER_4(msub32_ssov, i32, env, i32, i32, i32)
+DEF_HELPER_4(msub32_suov, i32, env, i32, i32, i32)
+DEF_HELPER_4(msub64_ssov, i64, env, i32, i64, i32)
+DEF_HELPER_4(msub64_suov, i64, env, i32, i64, i32)
/* CSA */
DEF_HELPER_2(call, void, env, i32)
DEF_HELPER_1(ret, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 0b6b471..4da76ff 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -198,6 +198,174 @@ target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
SSOV(env, ret, result, 32);
return ret;
}
+
+target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 + (t1 * t3);
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ uint64_t t1 = extract64(r1, 0, 32);
+ uint64_t t2 = extract64(r2, 0, 32);
+ uint64_t t3 = extract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 + (t1 * t3);
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, ovf;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t mul;
+
+ mul = t1 * t3;
+ ret = mul + r2;
+ ovf = (ret ^ mul) & ~(mul ^ r2);
+
+ if ((int64_t)ovf < 0) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* ext_ret > MAX_INT */
+ if (mul >= 0) {
+ ret = INT64_MAX;
+ /* ext_ret < MIN_INT */
+ } else {
+ ret = INT64_MIN;
+ }
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+
+ return ret;
+}
+
+uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, mul;
+ uint64_t t1 = extract64(r1, 0, 32);
+ uint64_t t3 = extract64(r3, 0, 32);
+
+ mul = t1 * t3;
+ ret = mul + r2;
+
+ if (ret < r2) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* saturate */
+ ret = UINT64_MAX;
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ return ret;
+}
+
+target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t2 = sextract64(r2, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 - (t1 * t3);
+ SSOV(env, ret, result, 32);
+ return ret;
+}
+
+target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
+ target_ulong r2, target_ulong r3)
+{
+ target_ulong ret;
+ int64_t t1 = extract64(r1, 0, 32);
+ int64_t t2 = extract64(r2, 0, 32);
+ int64_t t3 = extract64(r3, 0, 32);
+ int64_t result;
+
+ result = t2 - (t1 * t3);
+ SUOV(env, ret, result, 32);
+ return ret;
+}
+
+uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, ovf;
+ int64_t t1 = sextract64(r1, 0, 32);
+ int64_t t3 = sextract64(r3, 0, 32);
+ int64_t mul;
+
+ mul = t1 * t3;
+ ret = r2 - mul;
+ ovf = (ret ^ r2) & (mul ^ r2);
+
+ if ((int64_t)ovf < 0) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* ext_ret > MAX_INT */
+ if (mul < 0) {
+ ret = INT64_MAX;
+ /* ext_ret < MIN_INT */
+ } else {
+ ret = INT64_MIN;
+ }
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ return ret;
+}
+
+uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
+ uint64_t r2, target_ulong r3)
+{
+ uint64_t ret, mul;
+ uint64_t t1 = extract64(r1, 0, 32);
+ uint64_t t3 = extract64(r3, 0, 32);
+
+ mul = t1 * t3;
+ ret = r2 - mul;
+
+ if (ret > r2) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* saturate */
+ ret = 0;
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ t1 = ret >> 32;
+ env->PSW_USB_AV = t1 ^ t1 * 2u;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ return ret;
+}
+
/* context save area (CSA) related helpers */
static int cdc_increment(target_ulong *psw)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index fdc9ade..65abf45 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -316,6 +316,261 @@ static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(t0);
}
+/* ret = r2 + (r1 * r3); */
+static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_i32_i64(t1, r1);
+ tcg_gen_ext_i32_i64(t2, r2);
+ tcg_gen_ext_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_add_i64(t1, t2, t1);
+
+ tcg_gen_trunc_i64_i32(ret, t1);
+ /* calc V
+ t1 > 0x7fffffff */
+ tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
+ /* t1 < -0x80000000 */
+ tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
+ tcg_gen_or_i64(t2, t2, t3);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void gen_maddi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_madd32_d(ret, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_madd64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ TCGv t4 = tcg_temp_new();
+
+ tcg_gen_muls2_tl(t1, t2, r1, r3);
+ /* only the add can overflow */
+ tcg_gen_add2_tl(t3, t4, r2_low, r2_high, t1, t2);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
+ tcg_gen_xor_tl(t1, r2_high, t2);
+ tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t1);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
+ tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back the result */
+ tcg_gen_mov_tl(ret_low, t3);
+ tcg_gen_mov_tl(ret_high, t4);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
+ tcg_temp_free(t3);
+ tcg_temp_free(t4);
+}
+
+static inline void
+gen_maddu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_extu_i32_i64(t1, r1);
+ tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
+ tcg_gen_extu_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_add_i64(t2, t2, t1);
+ /* write back result */
+ tcg_gen_extr_i64_i32(ret_low, ret_high, t2);
+ /* only the add overflows, if t2 < t1
+ calc V bit */
+ tcg_gen_setcond_i64(TCG_COND_LTU, t2, t2, t1);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void
+gen_maddi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_maddui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
+/* ret = r2 - (r1 * r3); */
+static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_i32_i64(t1, r1);
+ tcg_gen_ext_i32_i64(t2, r2);
+ tcg_gen_ext_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_sub_i64(t1, t2, t1);
+
+ tcg_gen_trunc_i64_i32(ret, t1);
+ /* calc V
+ t2 > 0x7fffffff */
+ tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
+ /* result < -0x80000000 */
+ tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
+ tcg_gen_or_i64(t2, t2, t3);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void gen_msubi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_msub32_d(ret, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_msub64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ TCGv t4 = tcg_temp_new();
+
+ tcg_gen_muls2_tl(t1, t2, r1, r3);
+ /* only the sub can overflow */
+ tcg_gen_sub2_tl(t3, t4, r2_low, r2_high, t1, t2);
+ /* calc V bit */
+ tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
+ tcg_gen_xor_tl(t1, r2_high, t2);
+ tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, t1);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
+ tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back the result */
+ tcg_gen_mov_tl(ret_low, t3);
+ tcg_gen_mov_tl(ret_high, t4);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
+ tcg_temp_free(t3);
+ tcg_temp_free(t4);
+}
+
+static inline void
+gen_msubi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_msubu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ TCGv r3)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_extu_i32_i64(t1, r1);
+ tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
+ tcg_gen_extu_i32_i64(t3, r3);
+
+ tcg_gen_mul_i64(t1, t1, t3);
+ tcg_gen_sub_i64(t3, t2, t1);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, t3);
+ /* calc V bit, only the sub can overflow, if t1 > t2 */
+ tcg_gen_setcond_i64(TCG_COND_GTU, t1, t1, t2);
+ tcg_gen_trunc_i64_i32(cpu_PSW_V, t1);
+ tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+ /* Calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* Calc AV/SAV bits */
+ tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+ tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t3);
+}
+
+static inline void
+gen_msubui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+ tcg_temp_free(temp);
+}
+
static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
{
TCGv temp = tcg_const_i32(r2);
@@ -594,6 +849,86 @@ static inline void gen_mulsui_i32(TCGv ret, TCGv r1, int32_t con)
gen_helper_mul_suov(ret, cpu_env, r1, temp);
tcg_temp_free(temp);
}
+/* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
+static inline void gen_maddsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_madd32_ssov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_maddsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_madd32_suov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_maddsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_madd64_ssov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_maddsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_madd64_suov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void gen_msubsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_msub32_ssov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void gen_msubsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ gen_helper_msub32_suov(ret, cpu_env, r1, r2, temp);
+ tcg_temp_free(temp);
+}
+
+static inline void
+gen_msubsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_msub64_ssov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+ int32_t con)
+{
+ TCGv temp = tcg_const_i32(con);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+ gen_helper_msub64_suov(temp64, cpu_env, r1, temp64, temp);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
{
@@ -3284,6 +3619,140 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp2);
}
+/* RCR format */
+
+static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t const9;
+
+ TCGv temp, temp2;
+
+ op2 = MASK_OP_RCR_OP2(ctx->opcode);
+ r1 = MASK_OP_RCR_S1(ctx->opcode);
+ const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+ r3 = MASK_OP_RCR_S3(ctx->opcode);
+ r4 = MASK_OP_RCR_D(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCR_CADD:
+ gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const9, cpu_gpr_d[r3],
+ cpu_gpr_d[r4]);
+ break;
+ case OPC2_32_RCR_CADDN:
+ gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const9, cpu_gpr_d[r3],
+ cpu_gpr_d[r4]);
+ break;
+ case OPC2_32_RCR_SEL:
+ temp = tcg_const_i32(0);
+ temp2 = tcg_const_i32(const9);
+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r4], temp,
+ cpu_gpr_d[r1], temp2);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ break;
+ case OPC2_32_RCR_SELN:
+ temp = tcg_const_i32(0);
+ temp2 = tcg_const_i32(const9);
+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r4], temp,
+ cpu_gpr_d[r1], temp2);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ break;
+ }
+}
+
+static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t const9;
+
+
+ op2 = MASK_OP_RCR_OP2(ctx->opcode);
+ r1 = MASK_OP_RCR_S1(ctx->opcode);
+ const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+ r3 = MASK_OP_RCR_S3(ctx->opcode);
+ r4 = MASK_OP_RCR_D(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCR_MADD_32:
+ gen_maddi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MADD_64:
+ gen_maddi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MADDS_32:
+ gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MADDS_64:
+ gen_maddsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MADD_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_maddui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MADDS_U_32:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_maddsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MADDS_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_maddsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ }
+}
+
+static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ int r1, r3, r4;
+ int32_t const9;
+
+
+ op2 = MASK_OP_RCR_OP2(ctx->opcode);
+ r1 = MASK_OP_RCR_S1(ctx->opcode);
+ const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+ r3 = MASK_OP_RCR_S3(ctx->opcode);
+ r4 = MASK_OP_RCR_D(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RCR_MSUB_32:
+ gen_msubi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MSUB_64:
+ gen_msubi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_32:
+ gen_msubsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_64:
+ gen_msubsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MSUB_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_msubui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_U_32:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_msubsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+ break;
+ case OPC2_32_RCR_MSUBS_U_64:
+ const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+ gen_msubsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+ break;
+ }
+}
+
/* RLC format */
static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
@@ -3536,6 +4005,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPCM_32_RCRW_MASK_INSERT:
decode_rcrw_insert(env, ctx);
break;
+/* RCR Format */
+ case OPCM_32_RCR_COND_SELECT:
+ decode_rcr_cond_select(env, ctx);
+ break;
+ case OPCM_32_RCR_MADD:
+ decode_rcr_madd(env, ctx);
+ break;
+ case OPCM_32_RCR_MSUB:
+ decode_rcr_msub(env, ctx);
+ break;
/* RLC Format */
case OPC1_32_RLC_ADDI:
case OPC1_32_RLC_ADDIH:
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index bafc8fb..0a9122c 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -169,6 +169,7 @@
#define MASK_OP_RCR_S3(op) MASK_BITS_SHIFT(op, 24, 27)
#define MASK_OP_RCR_OP2(op) MASK_BITS_SHIFT(op, 21, 23)
#define MASK_OP_RCR_CONST9(op) MASK_BITS_SHIFT(op, 12, 20)
+#define MASK_OP_RCR_CONST9_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 20)
#define MASK_OP_RCR_S1(op) MASK_OP_META_S1(op)
/* RCRR Format */
@@ -945,7 +946,7 @@ enum {
OPC2_32_RCR_MSUB_64 = 0x03,
OPC2_32_RCR_MSUBS_32 = 0x05,
OPC2_32_RCR_MSUBS_64 = 0x07,
- OPC2_32_RCR_MSUB_U_32 = 0x02,
+ OPC2_32_RCR_MSUB_U_64 = 0x02,
OPC2_32_RCR_MSUBS_U_32 = 0x04,
OPC2_32_RCR_MSUBS_U_64 = 0x06,
};
--
2.1.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/9] tricore patches
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
` (8 preceding siblings ...)
2014-12-10 11:36 ` [Qemu-devel] [PULL 9/9] target-tricore: Add instructions of RCR " Bastian Koppelmann
@ 2014-12-11 12:07 ` Peter Maydell
9 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2014-12-11 12:07 UTC (permalink / raw)
To: Bastian Koppelmann; +Cc: QEMU Developers, Richard Henderson
On 10 December 2014 at 11:36, Bastian Koppelmann
<kbastian@mail.uni-paderborn.de> wrote:
> Hi,
>
> here is my first round of TriCore patches for 2.3.
>
> Cheers,
> Bastian
>
> The following changes since commit 7fb8da2b8861795e0013e6ee97acd0363d868a35:
>
> Open 2.3 development tree (2014-12-09 21:48:34 +0000)
>
> are available in the git repository at:
>
> https://github.com/bkoppelmann/qemu-tricore-upstream.git tags/pull-tricore-20141210
>
> for you to fetch changes up to 328f1f0f08f1aa303eef7493bd7c3d97a8d9636a:
>
> target-tricore: Add instructions of RCR opcode format (2014-12-10 11:13:45 +0000)
>
> ----------------------------------------------------------------
> TriCore BOL, BRC, BRN, BRR, RC, RCPW, RCRR, RCR, RLC and RCR insn added
>
> ----------------------------------------------------------------
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 0/9] tricore patches
@ 2015-01-26 20:03 Bastian Koppelmann
2015-01-27 10:40 ` Peter Maydell
0 siblings, 1 reply; 15+ messages in thread
From: Bastian Koppelmann @ 2015-01-26 20:03 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
The following changes since commit 1ac0206b2ae1ffaeec564f110664a3a77bafafd2:
qemu-timer.c: Trim list of included headers (2015-01-26 18:15:54 +0000)
are available in the git repository at:
https://github.com/bkoppelmann/qemu-tricore-upstream.git tags/pull-tricore20150126-2
for you to fetch changes up to 24c3bf03341ada63a0728f2bdfd2b7c226ad958e:
target-tricore: Add instructions of RRR opcode format (2015-01-26 19:56:46 +0000)
----------------------------------------------------------------
tricore bugfixes and RR1, RR2, RRPW and RRR insn
----------------------------------------------------------------
Bastian Koppelmann (8):
target-tricore: Several translator and cpu model fixes
target-tricore: calculate av bits before saturation
target-tricore: Fix bugs found by coverity
target-tricore: split up suov32 into suov32_pos and suov32_neg
target-tricore: target-tricore: Add instructions of RR1 opcode format, that have 0x93 as first opcode
target-tricore: Add instructions of RR2 opcode format
target-tricore: Add instructions of RRPW opcode format
target-tricore: Add instructions of RRR opcode format
Peter Maydell (1):
target-tricore: Add missing ULL suffix on 64 bit constant
target-tricore/cpu.c | 2 +-
target-tricore/cpu.h | 1 +
target-tricore/helper.h | 8 +
target-tricore/op_helper.c | 232 +++++++++++++++++---
target-tricore/translate.c | 448 ++++++++++++++++++++++++++++++++++++++-
target-tricore/tricore-opcodes.h | 2 +-
6 files changed, 659 insertions(+), 34 deletions(-)
--
2.2.2
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/9] tricore patches
2015-01-26 20:03 Bastian Koppelmann
@ 2015-01-27 10:40 ` Peter Maydell
2015-01-27 11:45 ` Bastian Koppelmann
0 siblings, 1 reply; 15+ messages in thread
From: Peter Maydell @ 2015-01-27 10:40 UTC (permalink / raw)
To: Bastian Koppelmann; +Cc: QEMU Developers
On 26 January 2015 at 20:03, Bastian Koppelmann
<kbastian@mail.uni-paderborn.de> wrote:
> The following changes since commit 1ac0206b2ae1ffaeec564f110664a3a77bafafd2:
>
> qemu-timer.c: Trim list of included headers (2015-01-26 18:15:54 +0000)
>
> are available in the git repository at:
>
> https://github.com/bkoppelmann/qemu-tricore-upstream.git tags/pull-tricore20150126-2
>
> for you to fetch changes up to 24c3bf03341ada63a0728f2bdfd2b7c226ad958e:
>
> target-tricore: Add instructions of RRR opcode format (2015-01-26 19:56:46 +0000)
>
> ----------------------------------------------------------------
> tricore bugfixes and RR1, RR2, RRPW and RRR insn
>
> ----------------------------------------------------------------
Looks like this would introduce a new clang warning:
/home/petmay01/linaro/qemu-for-merges/target-tricore/translate.c:1049:23:
warning: equality
comparison with extraneous parentheses [-Wparentheses-equality]
if ((up_shift == 32)) {
~~~~~~~~~^~~~~
/home/petmay01/linaro/qemu-for-merges/target-tricore/translate.c:1049:23:
note: remove extraneous
parentheses around the comparison to silence this warning
if ((up_shift == 32)) {
~ ^ ~
/home/petmay01/linaro/qemu-for-merges/target-tricore/translate.c:1049:23:
note: use '=' to turn
this equality comparison into an assignment
if ((up_shift == 32)) {
^~
=
We've nearly managed to eradicate all our clang warnings so I
don't want to add more at this point -- could you fix this
and resend the pullreq, please?
thanks
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/9] tricore patches
2015-01-27 11:45 ` Bastian Koppelmann
@ 2015-01-27 11:23 ` Peter Maydell
0 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2015-01-27 11:23 UTC (permalink / raw)
To: Bastian Koppelmann; +Cc: QEMU Developers
On 27 January 2015 at 11:45, Bastian Koppelmann
<kbastian@mail.uni-paderborn.de> wrote:
> Sure thing. With this many clang warning, I think I should also build with
> clang on my machine too.
You don't have to (though of course you can if you like): I
build pull requests with a pretty wide set of target configs
which I don't expect every submaintainer to have convenient
access to. (I don't even run my own pull requests through the
full set of config builds before sending them :-))
I recommend configuring with '--cc=clang' '--cxx=clang++'
'--extra-cflags=-fsanitize=undefined'
(and do use separate build directories so it doesn't get
mixed up with the gcc build objects). The undefined
sanitizer will print warnings at runtime about things that
are undefined behaviour in C, so it's worth exercising your
code under that build occasionally to see what falls out.
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/9] tricore patches
2015-01-27 10:40 ` Peter Maydell
@ 2015-01-27 11:45 ` Bastian Koppelmann
2015-01-27 11:23 ` Peter Maydell
0 siblings, 1 reply; 15+ messages in thread
From: Bastian Koppelmann @ 2015-01-27 11:45 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers
On 01/27/2015 10:40 AM, Peter Maydell wrote:
> On 26 January 2015 at 20:03, Bastian Koppelmann
> <kbastian@mail.uni-paderborn.de> wrote:
>> The following changes since commit 1ac0206b2ae1ffaeec564f110664a3a77bafafd2:
>>
>> qemu-timer.c: Trim list of included headers (2015-01-26 18:15:54 +0000)
>>
>> are available in the git repository at:
>>
>> https://github.com/bkoppelmann/qemu-tricore-upstream.git tags/pull-tricore20150126-2
>>
>> for you to fetch changes up to 24c3bf03341ada63a0728f2bdfd2b7c226ad958e:
>>
>> target-tricore: Add instructions of RRR opcode format (2015-01-26 19:56:46 +0000)
>>
>> ----------------------------------------------------------------
>> tricore bugfixes and RR1, RR2, RRPW and RRR insn
>>
>> ----------------------------------------------------------------
> Looks like this would introduce a new clang warning:
>
> /home/petmay01/linaro/qemu-for-merges/target-tricore/translate.c:1049:23:
> warning: equality
> comparison with extraneous parentheses [-Wparentheses-equality]
> if ((up_shift == 32)) {
> ~~~~~~~~~^~~~~
> /home/petmay01/linaro/qemu-for-merges/target-tricore/translate.c:1049:23:
> note: remove extraneous
> parentheses around the comparison to silence this warning
> if ((up_shift == 32)) {
> ~ ^ ~
> /home/petmay01/linaro/qemu-for-merges/target-tricore/translate.c:1049:23:
> note: use '=' to turn
> this equality comparison into an assignment
> if ((up_shift == 32)) {
> ^~
> =
>
> We've nearly managed to eradicate all our clang warnings so I
> don't want to add more at this point -- could you fix this
> and resend the pullreq, please?
Sure thing. With this many clang warning, I think I should also build
with clang on my machine too.
Cheers,
Bastian
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-01-27 11:24 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-10 11:36 [Qemu-devel] [PULL 0/9] tricore patches Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 1/9] target-tricore: Add instructions of BOL opcode format Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 2/9] target-tricore: Add instructions of BRC " Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 3/9] target-tricore: Add instructions of BRN " Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 4/9] target-tricore: Add instructions of BRR " Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 5/9] target-tricore: Add instructions of RC " Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 6/9] target-tricore: Make TRICORE_FEATURES implying others Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 7/9] target-tricore: Add instructions of RCPW, RCRR and RCRW opcode format Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 8/9] target-tricore: Add instructions of RLC " Bastian Koppelmann
2014-12-10 11:36 ` [Qemu-devel] [PULL 9/9] target-tricore: Add instructions of RCR " Bastian Koppelmann
2014-12-11 12:07 ` [Qemu-devel] [PULL 0/9] tricore patches Peter Maydell
-- strict thread matches above, loose matches on Subject: below --
2015-01-26 20:03 Bastian Koppelmann
2015-01-27 10:40 ` Peter Maydell
2015-01-27 11:45 ` Bastian Koppelmann
2015-01-27 11:23 ` Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).