diff mbox

[12/15] target-tricore: Add instructions of SBR opcode format

Message ID 1404756822-3253-13-git-send-email-kbastian@mail.uni-paderborn.de
State New
Headers show

Commit Message

Bastian Koppelmann July 7, 2014, 6:13 p.m. UTC
Add instructions of SBR opcode format.
Add gen_loop micro-op generator function.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
 target-tricore/translate.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

Comments

Richard Henderson July 8, 2014, 5:26 a.m. UTC | #1
On 07/07/2014 11:13 AM, Bastian Koppelmann wrote:
> Add instructions of SBR opcode format.
> Add gen_loop micro-op generator function.
> 
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> ---
>  target-tricore/translate.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 69 insertions(+)
> 
> diff --git a/target-tricore/translate.c b/target-tricore/translate.c
> index 69d99d3..5b11396 100644
> --- a/target-tricore/translate.c
> +++ b/target-tricore/translate.c
> @@ -281,6 +281,22 @@ static inline void gen_branch_condi(DisasContext *ctx, int cond, TCGv r1,
>      tcg_temp_free(temp);
>  }
>  
> +static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
> +{
> +    int l1;
> +    l1 = gen_new_label();
> +
> +    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], 0, l1);
> +    gen_save_pc(ctx->pc+offset);
> +    tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
> +    tcg_gen_exit_tb(0);
> +    gen_set_label(l1);
> +    gen_save_pc(ctx->pc+insn_bytes);
> +    tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
> +    tcg_gen_exit_tb(0);

Given that TCG does not register allocate over blocks, you're probably better
off subtracting first and comparing against -1, that way you don't need to keep
re-loading a[r1] from memory.

Again, goto_tb.

> +        gen_loop(ctx, r1, 0xffffffe0+(offset<<1));
> +        break;

I'd be happier seeing offset * 2 - 32.


r~
diff mbox

Patch

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 69d99d3..5b11396 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -281,6 +281,22 @@  static inline void gen_branch_condi(DisasContext *ctx, int cond, TCGv r1,
     tcg_temp_free(temp);
 }
 
+static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
+{
+    int l1;
+    l1 = gen_new_label();
+
+    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], 0, l1);
+    gen_save_pc(ctx->pc+offset);
+    tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
+    tcg_gen_exit_tb(0);
+    gen_set_label(l1);
+    gen_save_pc(ctx->pc+insn_bytes);
+    tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
+    tcg_gen_exit_tb(0);
+}
+
+
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
                    int r1, int r2 , int32_t constant , int32_t offset)
 {
@@ -323,6 +339,42 @@  static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
         gen_branch_condi(ctx, TCG_COND_EQ, temp, 0x1 << constant, offset);
         tcg_temp_free(temp);
         break;
+/* SBR-format jumps */
+    case OPC1_16_SBR_JEQ:
+        gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
+                        offset);
+        break;
+    case OPC1_16_SBR_JNE:
+        gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
+                        offset);
+        break;
+    case OPC1_16_SBR_JNZ:
+        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JNZ_A:
+        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JGEZ:
+        gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JGTZ:
+        gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JLEZ:
+        gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JLTZ:
+        gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JZ:
+        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_JZ_A:
+        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
+        break;
+    case OPC1_16_SBR_LOOP:
+        gen_loop(ctx, r1, 0xffffffe0+(offset<<1));
+        break;
     default:
             printf("Branch Error at %x\n", ctx->pc);
     }
@@ -669,6 +721,23 @@  static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
         const16 = MASK_OP_SBRN_N(ctx->opcode);
         gen_compute_branch(ctx, op1, 0, 0, const16, address);
         break;
+/* SBR-format */
+    case OPC1_16_SBR_JEQ:
+    case OPC1_16_SBR_JGEZ:
+    case OPC1_16_SBR_JGTZ:
+    case OPC1_16_SBR_JLEZ:
+    case OPC1_16_SBR_JLTZ:
+    case OPC1_16_SBR_JNE:
+    case OPC1_16_SBR_JNZ:
+    case OPC1_16_SBR_JNZ_A:
+    case OPC1_16_SBR_JZ:
+    case OPC1_16_SBR_JZ_A:
+    case OPC1_16_SBR_LOOP:
+        r1 = MASK_OP_SBR_S2(ctx->opcode);
+        address = MASK_OP_SBR_DISP4(ctx->opcode);
+        gen_compute_branch(ctx, op1, r1, 0, 0, address);
+        break;
+
    }
 }