Re: [Qemu-devel] [PATCH 17/23] target-tricore: Remove the dummy interrupt boilerplate

2014-09-20 Thread Bastian Koppelmann
Thanks for the effort cleaning up the cpu-exec file. This looks good to 
me. I'll add it again, in the next TriCore patchset.


Reviewed-by: Bastian Koppelmann 

On 09/13/2014 05:45 PM, Richard Henderson wrote:

It can go back in when it actually does something.

Cc: Bastian Koppelmann 
Signed-off-by: Richard Henderson 
---
  cpu-exec.c   | 5 -
  target-tricore/cpu-qom.h | 1 -
  target-tricore/cpu.c | 1 -
  target-tricore/cpu.h | 2 --
  target-tricore/helper.c  | 4 
  5 files changed, 13 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 81441e7..7e9f4cd 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -523,11 +523,6 @@ int cpu_exec(CPUArchState *env)
  cc->do_interrupt(cpu);
  next_tb = 0;
  }
-#elif defined(TARGET_TRICORE)
-if ((interrupt_request & CPU_INTERRUPT_HARD)) {
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
  #endif
  /* The target hook has 3 exit conditions:
 False when the interrupt isn't processed,
diff --git a/target-tricore/cpu-qom.h b/target-tricore/cpu-qom.h
index 470215a..66c9664 100644
--- a/target-tricore/cpu-qom.h
+++ b/target-tricore/cpu-qom.h
@@ -63,7 +63,6 @@ static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState 
*env)
  #define ENV_OFFSET offsetof(TriCoreCPU, env)
  
  hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);

-void tricore_cpu_do_interrupt(CPUState *cpu);
  void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
  fprintf_function cpu_fprintf, int flags);
  
diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c

index db9f404..7bf041a 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -145,7 +145,6 @@ static void tricore_cpu_class_init(ObjectClass *c, void 
*data)
  cc->class_by_name = tricore_cpu_class_by_name;
  cc->has_work = tricore_cpu_has_work;
  
-cc->do_interrupt = tricore_cpu_do_interrupt;

  cc->dump_state = tricore_cpu_dump_state;
  cc->set_pc = tricore_cpu_set_pc;
  cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index b036ff1..7555b70 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -400,6 +400,4 @@ static inline void cpu_pc_from_tb(CPUTriCoreState *env, 
TranslationBlock *tb)
  env->PC = tb->pc;
  }
  
-void do_interrupt(CPUTriCoreState *env);

-
  #endif /*__TRICORE_CPU_H__ */
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index e4af6f1..f52504c 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -82,10 +82,6 @@ int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong 
address,
  return ret;
  }
  
-void tricore_cpu_do_interrupt(CPUState *cs)

-{
-}
-
  TriCoreCPU *cpu_tricore_init(const char *cpu_model)
  {
  return TRICORE_CPU(cpu_generic_init(TYPE_TRICORE_CPU, cpu_model));





[Qemu-devel] [PATCH v2] arch_init: Setting QEMU_ARCH enum straight

2014-09-21 Thread Bastian Koppelmann
Every QEMU_ARCH is now in (1 << n) notation, instead of a mixture of decimal 
and hexadecimal.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- As Michael suggested it is now in (1 << n) notation.

 include/sysemu/arch_init.h | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 8939233..42a99bc 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -7,22 +7,22 @@
 enum {
 QEMU_ARCH_ALL = -1,
 QEMU_ARCH_ALPHA = 1,
-QEMU_ARCH_ARM = 2,
-QEMU_ARCH_CRIS = 4,
-QEMU_ARCH_I386 = 8,
-QEMU_ARCH_M68K = 16,
-QEMU_ARCH_LM32 = 32,
-QEMU_ARCH_MICROBLAZE = 64,
-QEMU_ARCH_MIPS = 128,
-QEMU_ARCH_PPC = 256,
-QEMU_ARCH_S390X = 512,
-QEMU_ARCH_SH4 = 1024,
-QEMU_ARCH_SPARC = 2048,
-QEMU_ARCH_XTENSA = 4096,
-QEMU_ARCH_OPENRISC = 8192,
-QEMU_ARCH_UNICORE32 = 0x4000,
-QEMU_ARCH_MOXIE = 0x8000,
-QEMU_ARCH_TRICORE = 0x1,
+QEMU_ARCH_ARM = (1 << 1),
+QEMU_ARCH_CRIS = (1 << 2),
+QEMU_ARCH_I386 = (1 << 3),
+QEMU_ARCH_M68K = (1 << 4),
+QEMU_ARCH_LM32 = (1 << 5),
+QEMU_ARCH_MICROBLAZE = (1 << 6),
+QEMU_ARCH_MIPS = (1 << 7),
+QEMU_ARCH_PPC = (1 << 8),
+QEMU_ARCH_S390X = (1 << 9),
+QEMU_ARCH_SH4 = (1 << 10),
+QEMU_ARCH_SPARC = (1 << 11),
+QEMU_ARCH_XTENSA = (1 << 12),
+QEMU_ARCH_OPENRISC = (1 << 13),
+QEMU_ARCH_UNICORE32 = (1 << 14),
+QEMU_ARCH_MOXIE = (1 << 15),
+QEMU_ARCH_TRICORE = (1 << 16),
 };

 extern const uint32_t arch_type;
--
2.1.0




[Qemu-devel] [PATCH 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions

2014-09-27 Thread Bastian Koppelmann
Hi guys,

here is the next round of TriCore patches. The first patch addresses a clang 
issue mentioned by Peter Maydell and
some bugfixes. And the other four add instructions of the ABS, ABSB, B, BIT and 
BO opcode format.

Thanks,

Bastian

Bastian Koppelmann (5):
  target-tricore: Cleanup and Bugfixes
  target-tricore: Add instructions of ABS, ABSB opcode format
  target-tricore: Add instructions of B opcode format
  target-tricore: Add instructions of BIT opcode format
  target-tricore: Add instructions of BO opcode format

 target-tricore/helper.h  |   46 ++
 target-tricore/op_helper.c   |  575 -
 target-tricore/translate.c   | 1261 ++
 target-tricore/tricore-opcodes.h |4 +-
 4 files changed, 1859 insertions(+), 27 deletions(-)

--
2.1.1




[Qemu-devel] [PATCH 1/5] target-tricore: Cleanup and Bugfixes

2014-09-27 Thread Bastian Koppelmann
Move FCX loading of save_context_ to caller functions, for STLCX, STUCX insn to 
use those functions.
Move FCX storing of restore_context_ to caller functions, for LDLCX, LDUCX insn 
to use those functions.
Remove do_raise_exception function, which caused clang to emit a warning.
Fix: save_context_lower now saves a[11] instead of PSW.
Fix: MASK_OP_ABSB_BPOS starting at wrong offset.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/op_helper.c   | 47 ++--
 target-tricore/tricore-opcodes.h |  2 +-
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 6376f07..f2a5cbc 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -114,10 +114,8 @@ static bool cdc_zero(target_ulong *psw)
 return count == 0;
 }
 
-static void save_context_upper(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_upper(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
 cpu_stl_data(env, ea+4, env->PSW);
 cpu_stl_data(env, ea+8, env->gpr_a[10]);
@@ -134,15 +132,12 @@ static void save_context_upper(CPUTriCoreState *env, int 
ea,
 cpu_stl_data(env, ea+52, env->gpr_d[13]);
 cpu_stl_data(env, ea+56, env->gpr_d[14]);
 cpu_stl_data(env, ea+60, env->gpr_d[15]);
-
 }
 
-static void save_context_lower(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_lower(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
-cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+4, env->gpr_a[11]);
 cpu_stl_data(env, ea+8, env->gpr_a[2]);
 cpu_stl_data(env, ea+12, env->gpr_a[3]);
 cpu_stl_data(env, ea+16, env->gpr_d[0]);
@@ -178,7 +173,6 @@ static void restore_context_upper(CPUTriCoreState *env, int 
ea,
 env->gpr_d[13] = cpu_ldl_data(env, ea+52);
 env->gpr_d[14] = cpu_ldl_data(env, ea+56);
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
-cpu_stl_data(env, ea, env->FCX);
 }
 
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
@@ -206,11 +200,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
 ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
  ((env->FCX & MASK_FCX_FCXO) << 6);
-/* new_FCX = M(EA, word);
-   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
-  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
-  D[15]}; */
-save_context_upper(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+   A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+   D[15]}; */
+save_context_upper(env, ea);
 
 /* PCXI.PCPN = ICR.CCPN; */
 env->PCXI = (env->PCXI & 0xff) +
@@ -263,9 +258,10 @@ void helper_ret(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-M(EA, word) = FCX; */
+A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* M(EA, word) = FCX; */
+cpu_stl_data(env, ea, env->FCX);
 /* FCX[19: 0] = PCXI[19: 0]; */
 env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
 /* PCXI = new_PCXI; */
@@ -293,7 +289,12 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
 tmp_FCX = env->FCX;
 ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
 
-save_context_lower(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], 
A[4]
+   , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
+save_context_lower(env, ea);
+
 
 /* PCXI.PCPN = ICR.CCPN */
 env->PCXI = (env->PCXI & 0xff) +
@@ -343,9 +344,10 @@ void helper_rfe(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-  M(EA, word) = FCX;*/
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
 r

[Qemu-devel] [PATCH 4/5] target-tricore: Add instructions of BIT opcode format

2014-09-27 Thread Bastian Koppelmann
Add instructions of BIT opcode format.
Add microcode generator functions gen_bit_1/2op to do 1/2 bit operations on the 
last bit.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c | 349 +
 1 file changed, 349 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 871c3cd..34375a9 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -427,6 +427,56 @@ static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
 gen_helper_sub_ssov(ret, cpu_env, r1, r2);
 }
 
+/* D[c] = D[c][0] op1 (D[a][pos1] op2 D[b][pos2]);*/
+static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2, TCGv r3,
+   int pos1, int pos2,
+   void(*op1)(TCGv, TCGv, TCGv),
+   void(*op2)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2, temp3;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+temp3 = tcg_temp_new();
+
+tcg_gen_andi_tl(temp3, r3, 0x1);
+
+tcg_gen_andi_tl(temp2, r2 , (0x1u << pos2));
+tcg_gen_shri_tl(temp2, temp2, pos2);
+
+tcg_gen_andi_tl(temp1, r1, (0x1u << pos1));
+tcg_gen_shri_tl(temp1, temp1, pos1);
+
+(*op1)(temp1, temp1, temp2);
+(*op2)(ret , temp3, temp1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+tcg_temp_free(temp3);
+}
+
+/* result = D[a][pos1] op1 D[b][pos2]; */
+static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
+   int pos1, int pos2,
+   void(*op1)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_andi_tl(temp2, r2, (0x1u << pos2));
+tcg_gen_shri_tl(temp2, temp2, pos2);
+
+tcg_gen_andi_tl(temp1, r1, (0x1u << pos1));
+tcg_gen_shri_tl(temp1, temp1, pos1);
+
+(*op1)(ret, temp1, temp2);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
 /* helpers for generating program flow micro-ops */
 
 static inline void gen_save_pc(target_ulong pc)
@@ -1347,6 +1397,283 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }
 
+/* Bit-format */
+
+static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+TCGv temp;
+
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+temp = tcg_temp_new();
+
+switch (op2) {
+case OPC2_32_BIT_AND_AND_T:
+gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_ANDN_T:
+gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_NOR_T:
+gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
+break;
+case OPC2_32_BIT_AND_OR_T:
+gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
+break;
+}
+tcg_gen_andi_tl(temp, temp, 0x1);
+tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0xfffe);
+tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
+tcg_temp_free(temp);
+}
+
+static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+switch (op2) {
+case OPC2_32_BIT_AND_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_ANDN_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl);
+break;
+case OPC2_32_BIT_NOR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl);
+tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0x1);
+break;
+case OPC2_32_BIT_OR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl);
+break;
+}
+}
+
+static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1

[Qemu-devel] [PATCH 2/5] target-tricore: Add instructions of ABS, ABSB opcode format

2014-09-27 Thread Bastian Koppelmann
Add instructions of ABS, ABSB opcode format.
Add microcode generator functions for ld/st of two 32bit reg as one 64bit value.
Add microcode generator functions for ldmst and swap.
Add helper ldlcx, lducx, stlcx and stucx.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/helper.h|   4 +
 target-tricore/op_helper.c |  45 +++
 target-tricore/translate.c | 303 +
 3 files changed, 352 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 7b7d74b..fbabbd5 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -23,3 +23,7 @@ DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
 DEF_HELPER_1(rfe, void, env)
+DEF_HELPER_2(ldlcx, void, env, i32)
+DEF_HELPER_2(lducx, void, env, i32)
+DEF_HELPER_2(stlcx, void, env, i32)
+DEF_HELPER_2(stucx, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index f2a5cbc..7a33afd 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -175,6 +175,27 @@ static void restore_context_upper(CPUTriCoreState *env, 
int ea,
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
 }
 
+static void restore_context_lower(CPUTriCoreState *env, int ea,
+  target_ulong *ra, target_ulong *pcxi)
+{
+*pcxi = cpu_ldl_data(env, ea);
+*ra = cpu_ldl_data(env, ea+4);
+env->gpr_a[2] = cpu_ldl_data(env, ea+8);
+env->gpr_a[3] = cpu_ldl_data(env, ea+12);
+env->gpr_d[0]  = cpu_ldl_data(env, ea+16);
+env->gpr_d[1]  = cpu_ldl_data(env, ea+20);
+env->gpr_d[2] = cpu_ldl_data(env, ea+24);
+env->gpr_d[3] = cpu_ldl_data(env, ea+28);
+env->gpr_a[4] = cpu_ldl_data(env, ea+32);
+env->gpr_a[5] = cpu_ldl_data(env, ea+36);
+env->gpr_a[6] = cpu_ldl_data(env, ea+40);
+env->gpr_a[7] = cpu_ldl_data(env, ea+44);
+env->gpr_d[4] = cpu_ldl_data(env, ea+48);
+env->gpr_d[5] = cpu_ldl_data(env, ea+52);
+env->gpr_d[6] = cpu_ldl_data(env, ea+56);
+env->gpr_d[7] = cpu_ldl_data(env, ea+60);
+}
+
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 {
 target_ulong tmp_FCX;
@@ -356,6 +377,30 @@ void helper_rfe(CPUTriCoreState *env)
 psw_write(env, new_PSW);
 }
 
+void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and RA */
+restore_context_lower(env, ea, &dummy, &dummy);
+}
+
+void helper_lducx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and PSW */
+restore_context_upper(env, ea, &dummy, &dummy);
+}
+
+void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_lower(env, ea);
+}
+
+void helper_stucx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_upper(env, ea);
+}
+
 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 4f654de..3ec5ca7 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -115,6 +115,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 tcg_temp_free_i32(helper_tmp);\
 } while (0)
 
+#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+
 /* Functions for load/save to/from memory */
 
 static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
@@ -135,6 +137,64 @@ static inline void gen_offset_st(DisasContext *ctx, TCGv 
r1, TCGv r2,
 tcg_temp_free(temp);
 }
 
+static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_concat_i32_i64(temp, rl, rh);
+tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
+
+tcg_temp_free_i64(temp);
+}
+
+static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
+/* write back to two 32 bit regs */
+tcg_gen_trunc_i64_i32(rl, temp);
+tcg_gen_shri_i64(temp, temp, 32);
+tcg_gen_trunc_i64_i32(rh, temp);
+
+tcg_temp_free_i64(temp);
+}
+
+/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
+static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+
+/* temp = (M(EA, word) */
+tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
+/* temp = temp & ~E[a][63:32]) */
+tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
+/* temp2 = (E[a][31:0] & E[a][63:32]); */
+tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]);
+/* temp = temp | temp2; */
+tcg_gen_or

[Qemu-devel] [PATCH 3/5] target-tricore: Add instructions of B opcode format

2014-09-27 Thread Bastian Koppelmann
Add instructions of B opcode format.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 3ec5ca7..871c3cd 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -116,6 +116,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 } while (0)
 
 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+#define EA_B_FORMAT(con) (((offset & 0xf0) << 8) | \
+ ((offset & 0x0f) << 1))
 
 /* Functions for load/save to/from memory */
 
@@ -494,6 +496,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_32_B_J:
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
 break;
+case OPC1_32_B_CALL:
 case OPC1_16_SB_CALL:
 gen_helper_1arg(call, ctx->next_pc);
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
@@ -569,6 +572,20 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_helper_ret(cpu_env);
 tcg_gen_exit_tb(0);
 break;
+/* B-format */
+case OPC1_32_B_CALLA:
+gen_helper_1arg(call, ctx->next_pc);
+gen_goto_tb(ctx, 0, EA_B_FORMAT(offset));
+break;
+case OPC1_32_B_JLA:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+case OPC1_32_B_JA:
+gen_goto_tb(ctx, 0, EA_B_FORMAT(offset));
+break;
+case OPC1_32_B_JL:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -1403,6 +1420,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
 break;
+/* B-format */
+case OPC1_32_B_CALL:
+case OPC1_32_B_CALLA:
+case OPC1_32_B_J:
+case OPC1_32_B_JA:
+case OPC1_32_B_JL:
+case OPC1_32_B_JLA:
+address = MASK_OP_B_DISP24(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, 0, address);
+break;
 }
 }
 
-- 
2.1.1




[Qemu-devel] [PATCH 5/5] target-tricore: Add instructions of BO opcode format

2014-09-27 Thread Bastian Koppelmann
Add instructions of BO opcode format.
Add microcode generator functions gen_swap, gen_ldmst.
Add helper for loading/storing byte, halfword, upper halfword word, dword in 
circular and bit reverse addr mode
Add sign extended bitmask for BO_OFF10 field.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/helper.h  |  42 +++
 target-tricore/op_helper.c   | 483 
 target-tricore/translate.c   | 582 +++
 target-tricore/tricore-opcodes.h |   2 +
 4 files changed, 1109 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index fbabbd5..ee8c9a7 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -27,3 +27,45 @@ DEF_HELPER_2(ldlcx, void, env, i32)
 DEF_HELPER_2(lducx, void, env, i32)
 DEF_HELPER_2(stlcx, void, env, i32)
 DEF_HELPER_2(stucx, void, env, i32)
+/* ld circ */
+DEF_HELPER_4(ld_b_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_bu_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_h_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_hu_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_q_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ldmst_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_a_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_w_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_d_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_da_circ, void, env, i32, i32, int)
+/* st circ */
+DEF_HELPER_4(st_a_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_b_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_d_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_da_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_h_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_q_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_w_circ, void, env, i32, i32, int)
+DEF_HELPER_4(swap_circ, void, env, i32, i32, int)
+DEF_HELPER_3(empty_circ, void, env, i32, int)
+/* ld br */
+DEF_HELPER_3(ld_b_br, void, env, i32, i32)
+DEF_HELPER_3(ld_bu_br, void, env, i32, i32)
+DEF_HELPER_3(ld_h_br, void, env, i32, i32)
+DEF_HELPER_3(ld_hu_br, void, env, i32, i32)
+DEF_HELPER_3(ld_q_br, void, env, i32, i32)
+DEF_HELPER_3(ldmst_br, void, env, i32, i32)
+DEF_HELPER_3(ld_a_br, void, env, i32, i32)
+DEF_HELPER_3(ld_w_br, void, env, i32, i32)
+DEF_HELPER_3(ld_d_br, void, env, i32, i32)
+DEF_HELPER_3(ld_da_br, void, env, i32, i32)
+/* st br */
+DEF_HELPER_3(st_a_br, void, env, i32, i32)
+DEF_HELPER_3(st_b_br, void, env, i32, i32)
+DEF_HELPER_3(st_d_br, void, env, i32, i32)
+DEF_HELPER_3(st_da_br, void, env, i32, i32)
+DEF_HELPER_3(st_h_br, void, env, i32, i32)
+DEF_HELPER_3(st_q_br, void, env, i32, i32)
+DEF_HELPER_3(st_w_br, void, env, i32, i32)
+DEF_HELPER_3(swap_br, void, env, i32, i32)
+DEF_HELPER_2(empty_br, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 7a33afd..c965a46 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,489 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+/* Addressing mode helper */
+
+#define CIRC_BR_DEFINES(reg)   \
+uint32_t index = env->gpr_a[reg+1] & 0x;   \
+uint32_t length_incr = (env->gpr_a[reg+1] & 0x) >> 16; \
+
+static uint16_t reverse16(uint16_t val)
+{
+uint8_t high = (uint8_t)(val >> 8);
+uint8_t low  = (uint8_t)(val & 0xff);
+
+uint16_t rh, rl;
+
+rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+
+return (rh << 8) | rl;
+}
+
+#define BR_CALC_INDEX(reg, index, incr) do {   \
+int32_t new_index = reverse16(reverse16(index) + reverse16(incr)); \
+env->gpr_a[reg+1] = (incr << 16) | new_index;  \
+} while (0)
+
+#define CIRC_CALC_INDEX(reg, off, len) do { \
+int32_t new_index = index + off;\
+if (new_index < 0) {\
+new_index = new_index + len;\
+} else {\
+new_index = new_index % len;\
+}   \
+env->gpr_a[reg+1] = (len << 16) | new_index; \
+} while (0)
+
+void helper_ld_b_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int 
off10)
+{
+CIRC_BR_DEFINES(r2)
+
+uint32_t ea = env->gpr_a[r2] + index;
+
+env->gpr_d[r1] = cpu_ldsb_data(env, ea);
+
+CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_bu_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
+   int off10)
+{
+CIRC_BR_DEFINES(r2)
+
+uint32_t ea = env->gpr_a[r2] + index;
+
+env->gpr_d[r1] = cpu_ldub_data(env, ea);
+
+CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_h_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int 
off

Re: [Qemu-devel] [PATCH 4/5] target-tricore: Add instructions of BIT opcode format

2014-09-28 Thread Bastian Koppelmann


On 09/28/2014 06:22 AM, Richard Henderson wrote:

+case OPC2_32_BIT_XNOR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_xor_tl);

tcg_gen_eqv_tl

I often don't use the optimal tcg-frontend operation, since the 
documentation I mostly use is 
http://wiki.qemu.org/Documentation/TCG/frontend-ops, which is outdated. 
That said, I'm willing to update the documentation to include all the 
latest tcg-ops. Richard, would you be willing to review those changes?


Thanks,

Bastian



[Qemu-devel] [PATCH v2 1/5] target-tricore: Cleanup and Bugfixes

2014-10-01 Thread Bastian Koppelmann
Move FCX loading of save_context_ to caller functions, for STLCX, STUCX insn to 
use those functions.
Move FCX storing of restore_context_ to caller functions, for LDLCX, LDUCX insn 
to use those functions.
Remove do_raise_exception function, which caused clang to emit a warning.
Fix: save_context_lower now saves a[11] instead of PSW.
Fix: MASK_OP_ABSB_BPOS starting at wrong offset.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/op_helper.c   | 47 ++--
 target-tricore/tricore-opcodes.h |  2 +-
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 6376f07..f2a5cbc 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -114,10 +114,8 @@ static bool cdc_zero(target_ulong *psw)
 return count == 0;
 }

-static void save_context_upper(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_upper(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
 cpu_stl_data(env, ea+4, env->PSW);
 cpu_stl_data(env, ea+8, env->gpr_a[10]);
@@ -134,15 +132,12 @@ static void save_context_upper(CPUTriCoreState *env, int 
ea,
 cpu_stl_data(env, ea+52, env->gpr_d[13]);
 cpu_stl_data(env, ea+56, env->gpr_d[14]);
 cpu_stl_data(env, ea+60, env->gpr_d[15]);
-
 }

-static void save_context_lower(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_lower(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
-cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+4, env->gpr_a[11]);
 cpu_stl_data(env, ea+8, env->gpr_a[2]);
 cpu_stl_data(env, ea+12, env->gpr_a[3]);
 cpu_stl_data(env, ea+16, env->gpr_d[0]);
@@ -178,7 +173,6 @@ static void restore_context_upper(CPUTriCoreState *env, int 
ea,
 env->gpr_d[13] = cpu_ldl_data(env, ea+52);
 env->gpr_d[14] = cpu_ldl_data(env, ea+56);
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
-cpu_stl_data(env, ea, env->FCX);
 }

 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
@@ -206,11 +200,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
 ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
  ((env->FCX & MASK_FCX_FCXO) << 6);
-/* new_FCX = M(EA, word);
-   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
-  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
-  D[15]}; */
-save_context_upper(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+   A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+   D[15]}; */
+save_context_upper(env, ea);

 /* PCXI.PCPN = ICR.CCPN; */
 env->PCXI = (env->PCXI & 0xff) +
@@ -263,9 +258,10 @@ void helper_ret(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-M(EA, word) = FCX; */
+A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* M(EA, word) = FCX; */
+cpu_stl_data(env, ea, env->FCX);
 /* FCX[19: 0] = PCXI[19: 0]; */
 env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
 /* PCXI = new_PCXI; */
@@ -293,7 +289,12 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
 tmp_FCX = env->FCX;
 ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);

-save_context_lower(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], 
A[4]
+   , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
+save_context_lower(env, ea);
+

 /* PCXI.PCPN = ICR.CCPN */
 env->PCXI = (env->PCXI & 0xff) +
@@ -343,9 +344,10 @@ void helper_rfe(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-  M(EA, word) = FCX;*/
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16

[Qemu-devel] [PATCH v2 3/5] target-tricore: Add instructions of B opcode format

2014-10-01 Thread Bastian Koppelmann
Add instructions of B opcode format.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index fc89a43..830bcd0 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -116,6 +116,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 } while (0)

 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+#define EA_B_ABSOLUT(con) (((offset & 0xf0) << 8) | \
+   ((offset & 0x0f) << 1))

 /* Functions for load/save to/from memory */

@@ -492,6 +494,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_32_B_J:
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
 break;
+case OPC1_32_B_CALL:
 case OPC1_16_SB_CALL:
 gen_helper_1arg(call, ctx->next_pc);
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
@@ -567,6 +570,20 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_helper_ret(cpu_env);
 tcg_gen_exit_tb(0);
 break;
+/* B-format */
+case OPC1_32_B_CALLA:
+gen_helper_1arg(call, ctx->next_pc);
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
+case OPC1_32_B_JLA:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+case OPC1_32_B_JA:
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
+case OPC1_32_B_JL:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -1403,6 +1420,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
 break;
+/* B-format */
+case OPC1_32_B_CALL:
+case OPC1_32_B_CALLA:
+case OPC1_32_B_J:
+case OPC1_32_B_JA:
+case OPC1_32_B_JL:
+case OPC1_32_B_JLA:
+address = MASK_OP_B_DISP24(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, 0, address);
+break;
 }
 }

--
2.1.1




[Qemu-devel] [PATCH v2 2/5] target-tricore: Add instructions of ABS, ABSB opcode format

2014-10-01 Thread Bastian Koppelmann
Add instructions of ABS, ABSB opcode format.
Add microcode generator functions for ld/st of two 32bit reg as one 64bit value.
Add microcode generator functions for ldmst and swap.
Add helper ldlcx, lducx, stlcx and stucx.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- Fix whitespaces
- gen_ld_2regs_64: replace three tcg-ops to write back 64bit result with 
tcg_gen_extr
- decode32Bit: move declaration of b and bpos to the top of the function.

 target-tricore/helper.h|   4 +
 target-tricore/op_helper.c |  45 +++
 target-tricore/translate.c | 303 +
 3 files changed, 352 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 7b7d74b..fbabbd5 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -23,3 +23,7 @@ DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
 DEF_HELPER_1(rfe, void, env)
+DEF_HELPER_2(ldlcx, void, env, i32)
+DEF_HELPER_2(lducx, void, env, i32)
+DEF_HELPER_2(stlcx, void, env, i32)
+DEF_HELPER_2(stucx, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index f2a5cbc..94b5d8e 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -175,6 +175,27 @@ static void restore_context_upper(CPUTriCoreState *env, 
int ea,
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
 }

+static void restore_context_lower(CPUTriCoreState *env, int ea,
+  target_ulong *ra, target_ulong *pcxi)
+{
+*pcxi = cpu_ldl_data(env, ea);
+*ra = cpu_ldl_data(env, ea+4);
+env->gpr_a[2] = cpu_ldl_data(env, ea+8);
+env->gpr_a[3] = cpu_ldl_data(env, ea+12);
+env->gpr_d[0] = cpu_ldl_data(env, ea+16);
+env->gpr_d[1] = cpu_ldl_data(env, ea+20);
+env->gpr_d[2] = cpu_ldl_data(env, ea+24);
+env->gpr_d[3] = cpu_ldl_data(env, ea+28);
+env->gpr_a[4] = cpu_ldl_data(env, ea+32);
+env->gpr_a[5] = cpu_ldl_data(env, ea+36);
+env->gpr_a[6] = cpu_ldl_data(env, ea+40);
+env->gpr_a[7] = cpu_ldl_data(env, ea+44);
+env->gpr_d[4] = cpu_ldl_data(env, ea+48);
+env->gpr_d[5] = cpu_ldl_data(env, ea+52);
+env->gpr_d[6] = cpu_ldl_data(env, ea+56);
+env->gpr_d[7] = cpu_ldl_data(env, ea+60);
+}
+
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 {
 target_ulong tmp_FCX;
@@ -356,6 +377,30 @@ void helper_rfe(CPUTriCoreState *env)
 psw_write(env, new_PSW);
 }

+void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and RA */
+restore_context_lower(env, ea, &dummy, &dummy);
+}
+
+void helper_lducx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and PSW */
+restore_context_upper(env, ea, &dummy, &dummy);
+}
+
+void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_lower(env, ea);
+}
+
+void helper_stucx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_upper(env, ea);
+}
+
 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 4f654de..fc89a43 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -115,6 +115,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 tcg_temp_free_i32(helper_tmp);\
 } while (0)

+#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+
 /* Functions for load/save to/from memory */

 static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
@@ -135,6 +137,62 @@ static inline void gen_offset_st(DisasContext *ctx, TCGv 
r1, TCGv r2,
 tcg_temp_free(temp);
 }

+static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_concat_i32_i64(temp, rl, rh);
+tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
+
+tcg_temp_free_i64(temp);
+}
+
+static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
+/* write back to two 32 bit regs */
+tcg_gen_extr_i64_i32(rl, rh, temp);
+
+tcg_temp_free_i64(temp);
+}
+
+/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
+static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+
+/* temp = (M(EA, word) */
+tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
+/* temp = temp & ~E[a][63:32]) */
+tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
+/* temp2 = (E[a][31:0] &

[Qemu-devel] [PATCH v2 4/5] target-tricore: Add instructions of BIT opcode format

2014-10-01 Thread Bastian Koppelmann
Add instructions of BIT opcode format.
Add microcode generator functions gen_bit_1/2op to do 1/2 bit operations on the 
last bit.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- gen_bit_2op: Now uses deposit and two shifts.
- gen_bit_1op: Now masks output instead of inputs and eliminates special 
cases for NOR.
- Remove depositing into r3 from decode_bit_andacc/orand, since gen_bit_2op 
does it.
- decode_bit_insert: Now uses shift + deposit.
- BIT_AND_NOR_T, BIT_XNOR_T and BIT_OR_NOR_T now use conditionalization.
- BIT_XNOR_T and BIT_SH_XNOR_T now use tcg_gen_eqv_tl.

 target-tricore/translate.c | 312 +
 1 file changed, 312 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 830bcd0..0cede7e 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -425,6 +425,49 @@ static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
 gen_helper_sub_ssov(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),
+   void(*op2)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_shri_tl(temp2, r2, pos2);
+tcg_gen_shri_tl(temp1, r1, pos1);
+
+(*op1)(temp1, temp1, temp2);
+(*op2)(temp1 , ret, temp1);
+
+tcg_gen_deposit_tl(ret, ret, temp1, 0, 1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
+/* ret = r1[pos1] op1 r2[pos2]; */
+static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
+   int pos1, int pos2,
+   void(*op1)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_shri_tl(temp2, r2, pos2);
+tcg_gen_shri_tl(temp1, r1, pos1);
+
+(*op1)(ret, temp1, temp2);
+
+tcg_gen_andi_tl(ret, ret, 0x1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
 /* helpers for generating program flow micro-ops */

 static inline void gen_save_pc(target_ulong pc)
@@ -1345,6 +1388,253 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }

+/* Bit-format */
+
+static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+
+switch (op2) {
+case OPC2_32_BIT_AND_AND_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_ANDN_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_NOR_T:
+#if defined TCG_TARGET_HAS_nor_i32
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
+#else
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
+#endif
+break;
+case OPC2_32_BIT_AND_OR_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
+break;
+}
+}
+
+static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+switch (op2) {
+case OPC2_32_BIT_AND_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_ANDN_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl);
+break;
+case OPC2_32_BIT_NOR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl);
+break;
+case OPC2_32_BIT_OR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl);
+break;
+}
+}
+
+static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+TCG

[Qemu-devel] [PATCH v2 5/5] target-tricore: Add instructions of BO opcode format

2014-10-01 Thread Bastian Koppelmann
Add instructions of BO opcode format.
Add microcode generator functions gen_swap, gen_ldmst.
Add helper for circular and bit reverse addr mode calculation.
Add sign extended bitmask for BO_OFF10 field.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- Replace helper for every ld/st_bitreverse/circular instruction with a 
general helper + tcg-op.

 target-tricore/helper.h  |   3 +
 target-tricore/op_helper.c   |  36 +++
 target-tricore/translate.c   | 652 +++
 target-tricore/tricore-opcodes.h |   2 +
 4 files changed, 693 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index fbabbd5..b3fc33c 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -27,3 +27,6 @@ DEF_HELPER_2(ldlcx, void, env, i32)
 DEF_HELPER_2(lducx, void, env, i32)
 DEF_HELPER_2(stlcx, void, env, i32)
 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)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 94b5d8e..a36988a 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,42 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"

+/* Addressing mode helper */
+
+static uint16_t reverse16(uint16_t val)
+{
+uint8_t high = (uint8_t)(val >> 8);
+uint8_t low  = (uint8_t)(val & 0xff);
+
+uint16_t rh, rl;
+
+rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+
+return (rh << 8) | rl;
+}
+
+uint32_t helper_br_update(uint32_t reg)
+{
+uint32_t index = reg & 0x;
+uint32_t incr  = reg >> 16;
+uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
+return reg - index + new_index;
+}
+
+uint32_t helper_circ_update(uint32_t reg, uint32_t off)
+{
+uint32_t index = reg & 0x;
+uint32_t length = reg >> 16;
+int32_t new_index = index + off;
+if (new_index < 0) {
+new_index += length;
+} else {
+new_index %= length;
+}
+return reg - index + new_index;
+}
+
 #define SSOV(env, ret, arg, len) do {   \
 int64_t max_pos = INT##len ##_MAX;  \
 int64_t max_neg = INT##len ##_MIN;  \
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 0cede7e..28697aa 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -149,6 +149,15 @@ static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv 
address, DisasContext *ctx)
 tcg_temp_free_i64(temp);
 }

+static void gen_offset_st_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
+DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, base, con);
+gen_st_2regs_64(rh, rl, temp, ctx);
+tcg_temp_free(temp);
+}
+
 static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
 {
 TCGv_i64 temp = tcg_temp_new_i64();
@@ -160,6 +169,15 @@ static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv 
address, DisasContext *ctx)
 tcg_temp_free_i64(temp);
 }

+static void gen_offset_ld_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
+DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, base, con);
+gen_ld_2regs_64(rh, rl, temp, ctx);
+tcg_temp_free(temp);
+}
+
 /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
 static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
 {
@@ -1635,6 +1653,621 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }

+/* BO-format */
+
+
+static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
+ DisasContext *ctx)
+{
+uint32_t op2;
+uint32_t off10;
+int32_t r1, r2;
+TCGv temp;
+
+r1 = MASK_OP_BO_S1D(ctx->opcode);
+r2  = MASK_OP_BO_S2(ctx->opcode);
+off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
+op2 = MASK_OP_BO_OP2(ctx->opcode);
+
+switch (op2) {
+case OPC2_32_BO_CACHEA_WI_SHORTOFF:
+case OPC2_32_BO_CACHEA_W_SHORTOFF:
+case OPC2_32_BO_CACHEA_I_SHORTOFF:
+/* instruction to access the cache */
+break;
+case OPC2_32_BO_CACHEA_WI_POSTINC:
+case OPC2_32_BO_CACHEA_W_POSTINC:
+case OPC2_32_BO_CACHEA_I_POSTINC:
+/* instruction to access the cache, but we still need to handle
+   the addressing mode */
+tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10);
+break;
+case OPC2_32_BO_CACHEA_WI_PREINC:
+case OPC2_32_BO_CACHEA_W_PREINC:
+case OPC2_32_BO_CACHEA_I_PREINC:
+/* instruction to access the cache, but we still need to handle
+   the addressing mode */
+tcg_gen_addi_tl(cpu_gpr_d[r2],

[Qemu-devel] [PATCH v2 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions

2014-10-01 Thread Bastian Koppelmann
Hi guys,

here is the next round of TriCore patches. The first patch addresses a clang 
issue mentioned by Peter Maydell and
some bugfixes. And the other four add instructions of the ABS, ABSB, B, BIT and 
BO opcode format.

Thanks,

Bastian

v1 -> v2:
- Fix whitespaces
- gen_ld_2regs_64: replace three tcg-ops to write back 64bit result with 
tcg_gen_extr
- decode32Bit: move declaration of b and bpos to the top of the function.
- gen_bit_2op: Now uses deposit and two shifts.
- gen_bit_1op: Now masks output instead of inputs and eliminates special 
cases for NOR.
- Remove depositing into r3 from decode_bit_andacc/orand, since gen_bit_2op 
does it.
- decode_bit_insert: Now uses shift + deposit.
- BIT_AND_NOR_T, BIT_XNOR_T and BIT_OR_NOR_T now use conditionalization.
- BIT_XNOR_T and BIT_SH_XNOR_T now use tcg_gen_eqv_tl.
- Replace helper for every ld/st_bitreverse/circular instruction with a 
general helper + tcg-op.

Bastian Koppelmann (5):
  target-tricore: Cleanup and Bugfixes
  target-tricore: Add instructions of ABS, ABSB opcode format
  target-tricore: Add instructions of B opcode format
  target-tricore: Add instructions of BIT opcode format
  target-tricore: Add instructions of BO opcode format

 target-tricore/helper.h  |7 +
 target-tricore/op_helper.c   |  128 +++-
 target-tricore/translate.c   | 1294 ++
 target-tricore/tricore-opcodes.h |4 +-
 4 files changed, 1406 insertions(+), 27 deletions(-)

--
2.1.1




Re: [Qemu-devel] [PATCH v4 01/15] target-tricore: Add target stubs and qom-cpu

2014-08-11 Thread Bastian Koppelmann


On 08/08/2014 03:28 AM, Richard Henderson wrote:

On 08/07/2014 04:34 AM, Bastian Koppelmann wrote:

+/* PSW flag cache for faster execution
+   if flag != 0 then flag is set. Else flag is not set.
+*/
+target_ulong PSW_USB_C;
+target_ulong PSW_USB_V;
+target_ulong PSW_USB_SV;
+target_ulong PSW_USB_AV;  /* Only if bit 31 set, then flag is set. */
+target_ulong PSW_USB_SAV; /* Only if bit 31 set, then flag is set. */

V and SV are also only set if bit 31 is set, the way we're computing overflow
from addition.  Of course, overflow from saturation or multiplication isn't
being computed into bit 31, so there is a decision to make.

Depending on how important it is for ADDX+ADDC to be implemented efficiently,
vs how important is for SHA to be quick, you may wish to have C already set to
0/1 only.


Since I don't have data, which instructions are more common, I would 
choose the SHA instructions to be fast, because the manual states, that 
the most commen instructions are also implemented as 16 bit instructions 
and SHA is part of those. So I would leave the carry bit as is, unless 
you are sure, that there is a benefit for ADDX+ADDC to be fast.





r~





[Qemu-devel] [PATCH v5 07/15] target-tricore: Add instructions of SRR opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SRR opcode format.
Add helper for add/sub_ssov.

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- gen_sub_d now saves result of substraction into tcg temp to handle ret = 
r1 cases.
- gen_mul_i32s now calculates V, SV bits in bit 31.
- SSOV makro now computes V, SV bits in bit 31.
- Negate conditions of 16_SRR_CMOV and 16_SRR_CMOVN insns.
- MOV_AA: Switch r1 and r2 arguments.

 target-tricore/helper.h|   4 ++
 target-tricore/op_helper.c |  43 
 target-tricore/translate.c | 164 +
 3 files changed, 211 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 5884240..299bd77 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -14,3 +14,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+
+/* Arithmetic */
+DEF_HELPER_3(add_ssov, i32, env, i32, i32)
+DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 2e5981f..3c83945 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,49 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+#define SSOV(env, ret, arg, len) do {   \
+int64_t max_pos = INT##len ##_MAX;  \
+int64_t max_neg = INT##len ##_MIN;  \
+if (arg > max_pos) {\
+env->PSW_USB_V = (1 << 31); \
+env->PSW_USB_SV = (1 << 31);\
+ret = (target_ulong)max_pos;\
+} else {\
+if (arg < max_neg) {\
+env->PSW_USB_V = (1 << 31); \
+env->PSW_USB_SV = (1 << 31);\
+ret = (target_ulong)max_neg;\
+} 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)
+{
+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_sub_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;
+}
+
 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 fbaba9e..054d08c 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -187,6 +187,53 @@ static inline void gen_condi_add(TCGCond cond, TCGv r1, 
int32_t r2,
 tcg_temp_free(temp);
 }
 
+static inline void gen_sub_d(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);
+/* calc V bit */
+tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+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_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
+{
+TCGv high = tcg_temp_new();
+TCGv low = tcg_temp_new();
+
+tcg_gen_muls2_tl(low, high, r1, r2);
+tcg_gen_mov_tl(ret, low);
+/* calc V bit */
+tcg_gen_sari_tl(low, low, 31);
+tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
+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 bit */
+tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+/* calc SAV bit */
+tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+tcg_temp_free(high);
+t

[Qemu-devel] [PATCH v5 04/15] target-tricore: Add initialization for translation and activate target

2014-08-13 Thread Bastian Koppelmann
Add tcg and cpu model initialization.
Add gen_intermediate_code function.
Activate target in configure and add softmmu config.

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- gen_intermediate_code_internal: Move calculation of next_pc after the ifs 
for singlestep and long tbs.

 configure   |   5 ++
 default-configs/tricore-softmmu.mak |   3 +
 target-tricore/translate.c  | 165 
 3 files changed, 173 insertions(+)
 create mode 100644 default-configs/tricore-softmmu.mak

diff --git a/configure b/configure
index f7685b5..5003e28 100755
--- a/configure
+++ b/configure
@@ -4965,6 +4965,9 @@ case "$target_name" in
 TARGET_BASE_ARCH=mips
 echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
   ;;
+  tricore)
+target_phys_bits=32
+  ;;
   moxie)
   ;;
   or32)
@@ -5162,6 +5165,8 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
 echo "CONFIG_MIPS_DIS=y"  >> $config_target_mak
 echo "CONFIG_MIPS_DIS=y"  >> config-all-disas.mak
   ;;
+  tricore*)
+  ;;
   moxie*)
 echo "CONFIG_MOXIE_DIS=y"  >> $config_target_mak
 echo "CONFIG_MOXIE_DIS=y"  >> config-all-disas.mak
diff --git a/default-configs/tricore-softmmu.mak 
b/default-configs/tricore-softmmu.mak
new file mode 100644
index 000..48ccd12
--- /dev/null
+++ b/default-configs/tricore-softmmu.mak
@@ -0,0 +1,3 @@
+include pci.mak
+CONFIG_PFLASH_CFI01=y
+CONFIG_SMC91C111=y
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 5bb212d..431968b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,26 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+/*
+ * TCG registers
+ */
+static TCGv cpu_PC;
+static TCGv cpu_PCXI;
+static TCGv cpu_PSW;
+static TCGv cpu_ICR;
+/* GPR registers */
+static TCGv cpu_gpr_a[16];
+static TCGv cpu_gpr_d[16];
+/* PSW Flag cache */
+static TCGv cpu_PSW_C;
+static TCGv cpu_PSW_V;
+static TCGv cpu_PSW_SV;
+static TCGv cpu_PSW_AV;
+static TCGv cpu_PSW_SAV;
+/* CPU env */
+static TCGv_ptr cpu_env;
+
+#include "exec/gen-icount.h"
 
 static const char *regnames_a[] = {
   "a0"  , "a1"  , "a2"  , "a3" , "a4"  , "a5" ,
@@ -39,6 +59,25 @@ static const char *regnames_d[] = {
   "d12" , "d13" , "d14" , "d15",
 };
 
+typedef struct DisasContext {
+struct TranslationBlock *tb;
+target_ulong pc, saved_pc, next_pc;
+uint32_t opcode;
+int singlestep_enabled;
+/* Routine used to access memory */
+int mem_idx;
+uint32_t hflags, saved_hflags;
+int bstate;
+} DisasContext;
+
+enum {
+
+BS_NONE   = 0,
+BS_STOP   = 1,
+BS_BRANCH = 2,
+BS_EXCP   = 3,
+};
+
 void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 fprintf_function cpu_fprintf, int flags)
 {
@@ -62,10 +101,88 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 
 }
 
+static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
+{
+}
+
+static void decode_32Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
+{
+}
+
+static void decode_opc(CPUTRICOREState *env, DisasContext *ctx, int *is_branch)
+{
+/* 16-Bit Instruction */
+if ((ctx->opcode & 0x1) == 0) {
+ctx->next_pc = ctx->pc + 2;
+decode_16Bit_opc(env, ctx);
+/* 32-Bit Instruction */
+} else {
+ctx->next_pc = ctx->pc + 4;
+decode_32Bit_opc(env, ctx);
+}
+}
+
 static inline void
 gen_intermediate_code_internal(TRICORECPU *cpu, struct TranslationBlock *tb,
   int search_pc)
 {
+CPUState *cs = CPU(cpu);
+CPUTRICOREState *env = &cpu->env;
+DisasContext ctx;
+target_ulong pc_start;
+int num_insns;
+uint16_t *gen_opc_end;
+
+if (search_pc) {
+qemu_log("search pc %d\n", search_pc);
+}
+
+num_insns = 0;
+pc_start = tb->pc;
+gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
+ctx.pc = pc_start;
+ctx.saved_pc = -1;
+ctx.tb = tb;
+ctx.singlestep_enabled = cs->singlestep_enabled;
+ctx.bstate = BS_NONE;
+ctx.mem_idx = cpu_mmu_index(env);
+
+tcg_clear_temp_count();
+gen_tb_start();
+while (ctx.bstate == BS_NONE) {
+ctx.opcode = cpu_ldl_code(env, ctx.pc);
+decode_opc(env, &ctx, 0);
+
+num_insns++;
+
+if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
+break;
+}
+if (singlestep) {
+break;
+}
+ctx.pc = ctx.next_pc;
+}
+
+gen_tb_end(tb, num_insns);
+*tcg_ctx.gen_opc_ptr = INDEX_op_end;
+if (search_pc) {
+printf("done_generating search pc\n");
+} else {
+tb->size = ctx.pc - pc_start;
+tb->icount = num_insns;
+}
+if (tcg_check_temp_count

[Qemu-devel] [PATCH v5 13/15] target-tricore: Add instructions of SC opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SC opcode format.
Add helper for begin interrupt service routine.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h|  1 +
 target-tricore/op_helper.c | 59 ++
 target-tricore/translate.c | 48 +
 3 files changed, 108 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index adf5b26..3c73234 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -21,3 +21,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 /* CSA */
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
+DEF_HELPER_2(bisr, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index bdcb2c4..4ea94d8 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -122,6 +122,28 @@ static void save_context_upper(CPUTRICOREState *env, int 
ea,
 
 }
 
+static void save_context_lower(CPUTRICOREState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[2]);
+cpu_stl_data(env, ea+12, env->gpr_a[3]);
+cpu_stl_data(env, ea+16, env->gpr_d[0]);
+cpu_stl_data(env, ea+20, env->gpr_d[1]);
+cpu_stl_data(env, ea+24, env->gpr_d[2]);
+cpu_stl_data(env, ea+28, env->gpr_d[3]);
+cpu_stl_data(env, ea+32, env->gpr_a[4]);
+cpu_stl_data(env, ea+36, env->gpr_a[5]);
+cpu_stl_data(env, ea+40, env->gpr_a[6]);
+cpu_stl_data(env, ea+44, env->gpr_a[7]);
+cpu_stl_data(env, ea+48, env->gpr_d[4]);
+cpu_stl_data(env, ea+52, env->gpr_d[5]);
+cpu_stl_data(env, ea+56, env->gpr_d[6]);
+cpu_stl_data(env, ea+60, env->gpr_d[7]);
+}
+
 static void restore_context_upper(CPUTRICOREState *env, int ea,
   target_ulong *new_PCXI, target_ulong 
*new_PSW)
 {
@@ -243,6 +265,43 @@ void helper_ret(CPUTRICOREState *env)
 }
 }
 
+void helper_bisr(CPUTRICOREState *env, uint32_t const9)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+
+if (env->FCX == 0) {
+/* FCU trap */
+}
+
+tmp_FCX = env->FCX;
+ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
+
+save_context_lower(env, ea, &new_FCX);
+
+/* PCXI.PCPN = ICR.CCPN */
+env->PCXI = (env->PCXI & 0xff) +
+ ((env->ICR & MASK_ICR_CCPN) << 24);
+/* PCXI.PIE  = ICR.IE */
+env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
+ ((env->ICR & MASK_ICR_IE) << 15));
+/* PCXI.UL = 0 */
+env->PCXI &= ~(MASK_PCXI_UL);
+/* PCXI[19: 0] = FCX[19: 0] */
+env->PCXI = (env->PCXI & 0xfff0) + (env->FCX & 0xf);
+/* FXC[19: 0] = new_FCX[19: 0] */
+env->FCX = (env->FCX & 0xfff0) + (new_FCX & 0xf);
+/* ICR.IE = 1 */
+env->ICR |= MASK_ICR_IE;
+
+env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
+
+if (tmp_FCX == env->LCX) {
+/* FCD trap */
+}
+}
+
 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 8e468bd..40459b5 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -678,6 +678,42 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 }
 }
 
+static void decode_sc_opc(DisasContext *ctx, int op1)
+{
+int32_t const16;
+
+const16 = MASK_OP_SC_CONST8(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SC_AND:
+tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_BISR:
+gen_helper_1arg(bisr, const16 & 0xff);
+break;
+case OPC1_16_SC_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_MOV:
+tcg_gen_movi_tl(cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_OR:
+tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_SUB_A:
+tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
+break;
+}
+}
 static void decode_16Bit_opc(CPUTRICOREStat

[Qemu-devel] [PATCH v5 05/15] target-tricore: Add masks and opcodes for decoding

2014-08-13 Thread Bastian Koppelmann
Add masks and opcodes for decoding TriCore instructions.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c   |1 +
 target-tricore/tricore-opcodes.h | 1406 ++
 2 files changed, 1407 insertions(+)
 create mode 100644 target-tricore/tricore-opcodes.h

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 431968b..ec4d80b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,7 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+#include "tricore-opcodes.h"
 /*
  * TCG registers
  */
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
new file mode 100644
index 000..9c6ec01
--- /dev/null
+++ b/target-tricore/tricore-opcodes.h
@@ -0,0 +1,1406 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Opcode Masks for Tricore
+ * Format MASK_OP_InstrFormatName_Field
+ */
+
+/* This creates a mask with bits start .. end set to 1 and applies it to op */
+#define MASK_BITS_SHIFT(op, start, end) (extract32(op, (start), \
+(end) - (start) + 1))
+#define MASK_BITS_SHIFT_SEXT(op, start, end) (sextract32(op, (start),\
+ (end) - (start) + 1))
+
+/* new opcode masks */
+
+#define MASK_OP_MAJOR(op)  MASK_BITS_SHIFT(op, 0, 7)
+
+/* 16-Bit Formats */
+#define MASK_OP_SB_DISP8(op)   MASK_BITS_SHIFT(op, 8, 15)
+#define MASK_OP_SB_DISP8_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 8, 15)
+
+#define MASK_OP_SBC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
+#define MASK_OP_SBC_DISP4(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SBR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBR_DISP4(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SBRN_N(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBRN_DISP4(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SC_CONST8(op)  MASK_BITS_SHIFT(op, 8, 15)
+
+#define MASK_OP_SLR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SLR_D(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SLRO_OFF4(op)  MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SLRO_D(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SR_OP2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SR_S1D(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
+#define MASK_OP_SRC_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRO_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRO_OFF4(op)   MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRR_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRRS_S2(op)MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRRS_S1D(op)   MASK_BITS_SHIFT(op, 8, 11)
+#define MASK_OP_SRRS_N(op) MASK_BITS_SHIFT(op, 6, 7)
+
+#define MASK_OP_SSR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SSR_S1(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SSRO_OFF4(op)  MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SSRO_S1(op)MASK_BITS_SHIFT(op, 8, 11)
+
+/* 32-Bit Formats */
+
+/* ABS Format */
+#define MASK_OP_ABS_OFF18(op)  (MASK_BITS_SHIFT(op, 16, 21) +   \
+   (MASK_BITS_SHIFT(op, 28, 31) << 6) + \
+   (MASK_BITS_SHIFT(op, 22, 25) << 10) +\
+   (MASK_BITS_SHIFT(op, 12, 15) << 14))
+#define MASK_OP_ABS_OP2(op)MASK_BITS_SHIFT(op, 26, 27)
+#define MASK_OP_ABS_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+/* ABSB Format */
+#define MASK_OP_ABSB_OFF18(op) MASK_OP_ABS_OFF18(op)
+#define MASK_OP_ABSB_OP2(op)   MASK_BITS_SHIFT(op, 26, 27)
+#define MASK_OP_ABSB_B(op) MASK_BITS_SHIFT(op, 11, 11)
+#define MASK_OP_ABSB_BPOS(op)  MASK_BITS_SHIFT(op, 7, 10)
+
+/* B Format   */
+#define MASK_OP_B_DISP24(op)   (MASK_BITS_SHIFT(op, 16, 31) + \
+   (MASK_BITS_SHIFT(op, 8, 15) << 16))
+/* BIT Format */
+#define MASK_OP_BIT_D(op)  MASK_BITS_SHIFT(op, 28, 31)
+#define MASK_OP_BIT_POS2(op)   MASK_BITS_SHIFT(op

[Qemu-devel] [PATCH v5 14/15] target-tricore: Add instructions of SLR, SSRO and SRO opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SLR, SSRO and SRO opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 121 +
 1 file changed, 121 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 40459b5..5efa022 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -714,6 +714,84 @@ static void decode_sc_opc(DisasContext *ctx, int op1)
 break;
 }
 }
+
+static void decode_slr_opc(DisasContext *ctx, int op1)
+{
+int r1, r2;
+
+r1 = MASK_OP_SLR_D(ctx->opcode);
+r2 = MASK_OP_SLR_S2(ctx->opcode);
+
+switch (op1) {
+/* SLR-format */
+case OPC1_16_SLR_LD_A:
+tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESL);
+break;
+case OPC1_16_SLR_LD_A_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+case OPC1_16_SLR_LD_BU:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+break;
+case OPC1_16_SLR_LD_BU_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
+break;
+case OPC1_16_SLR_LD_H:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+break;
+case OPC1_16_SLR_LD_H_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
+break;
+case OPC1_16_SLR_LD_W:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+break;
+case OPC1_16_SLR_LD_W_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+}
+}
+
+static void decode_sro_opc(DisasContext *ctx, int op1)
+{
+int r2;
+int32_t address;
+
+r2 = MASK_OP_SRO_S2(ctx->opcode);
+address = MASK_OP_SRO_OFF4(ctx->opcode);
+
+/* SRO-format */
+switch (op1) {
+case OPC1_16_SRO_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_LD_BU:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
+break;
+case OPC1_16_SRO_LD_H:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW);
+break;
+case OPC1_16_SRO_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_ST_B:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
+break;
+case OPC1_16_SRO_ST_H:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
+break;
+case OPC1_16_SRO_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+}
+}
+
 static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
 {
 int op1;
@@ -862,6 +940,49 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 case OPC1_16_SC_SUB_A:
 decode_sc_opc(ctx, op1);
 break;
+/* SLR-format */
+case OPC1_16_SLR_LD_A:
+case OPC1_16_SLR_LD_A_POSTINC:
+case OPC1_16_SLR_LD_BU:
+case OPC1_16_SLR_LD_BU_POSTINC:
+case OPC1_16_SLR_LD_H:
+case OPC1_16_SLR_LD_H_POSTINC:
+case OPC1_16_SLR_LD_W:
+case OPC1_16_SLR_LD_W_POSTINC:
+decode_slr_opc(ctx, op1);
+break;
+/* SRO-format */
+case OPC1_16_SRO_LD_A:
+case OPC1_16_SRO_LD_BU:
+case OPC1_16_SRO_LD_H:
+case OPC1_16_SRO_LD_W:
+case OPC1_16_SRO_ST_A:
+case OPC1_16_SRO_ST_B:
+case OPC1_16_SRO_ST_H:
+case OPC1_16_SRO_ST_W:
+decode_sro_opc(ctx, op1);
+break;
+/* SSRO-format */
+case OPC1_16_SSRO_ST_A:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SSRO_ST_B:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
+break;
+case OPC1_16_SSRO_ST_H:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
+break;
+case OPC1_16_SSRO_ST_W:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr

[Qemu-devel] [PATCH v5 10/15] target-tricore: Add instructions of SB opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SB opcode format.
Add helper call/ret.
Add micro-op generator functions for branches.
Add makro to generate helper functions.

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- Change int cond to TCGCond in functions gen_branch_cond, gen_branch_condi.
- gen_intermediate_code_internal: Add gen_goto_tb so qemu finds new tb on 
singlestep and after long tbs without branch.

 target-tricore/helper.h|   3 +
 target-tricore/op_helper.c | 180 +
 target-tricore/translate.c |  91 +++
 3 files changed, 274 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 299bd77..adf5b26 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -18,3 +18,6 @@
 /* Arithmetic */
 DEF_HELPER_3(add_ssov, i32, env, i32, i32)
 DEF_HELPER_3(sub_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 3c83945..bdcb2c4 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -63,6 +63,186 @@ target_ulong helper_sub_ssov(CPUTRICOREState *env, 
target_ulong r1,
 return ret;
 }
 
+/* context save area (CSA) related helpers */
+
+static int cdc_increment(target_ulong *psw)
+{
+if ((*psw & MASK_PSW_CDC) == 0x7f) {
+return 0;
+}
+
+(*psw)++;
+/* check for overflow */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+if (count == 0) {
+(*psw)--;
+return 1;
+}
+return 0;
+}
+
+static int cdc_decrement(target_ulong *psw)
+{
+if ((*psw & MASK_PSW_CDC) == 0x7f) {
+return 0;
+}
+/* check for underflow */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+if (count == 0) {
+return 1;
+}
+(*psw)--;
+return 0;
+}
+
+static void save_context_upper(CPUTRICOREState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[10]);
+cpu_stl_data(env, ea+12, env->gpr_a[11]);
+cpu_stl_data(env, ea+16, env->gpr_d[8]);
+cpu_stl_data(env, ea+20, env->gpr_d[9]);
+cpu_stl_data(env, ea+24, env->gpr_d[10]);
+cpu_stl_data(env, ea+28, env->gpr_d[11]);
+cpu_stl_data(env, ea+32, env->gpr_a[12]);
+cpu_stl_data(env, ea+36, env->gpr_a[13]);
+cpu_stl_data(env, ea+40, env->gpr_a[14]);
+cpu_stl_data(env, ea+44, env->gpr_a[15]);
+cpu_stl_data(env, ea+48, env->gpr_d[12]);
+cpu_stl_data(env, ea+52, env->gpr_d[13]);
+cpu_stl_data(env, ea+56, env->gpr_d[14]);
+cpu_stl_data(env, ea+60, env->gpr_d[15]);
+
+}
+
+static void restore_context_upper(CPUTRICOREState *env, int ea,
+  target_ulong *new_PCXI, target_ulong 
*new_PSW)
+{
+*new_PCXI = cpu_ldl_data(env, ea);
+*new_PSW = cpu_ldl_data(env, ea+4);
+env->gpr_a[10] = cpu_ldl_data(env, ea+8);
+env->gpr_a[11] = cpu_ldl_data(env, ea+12);
+env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
+env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
+env->gpr_d[10] = cpu_ldl_data(env, ea+24);
+env->gpr_d[11] = cpu_ldl_data(env, ea+28);
+env->gpr_a[12] = cpu_ldl_data(env, ea+32);
+env->gpr_a[13] = cpu_ldl_data(env, ea+36);
+env->gpr_a[14] = cpu_ldl_data(env, ea+40);
+env->gpr_a[15] = cpu_ldl_data(env, ea+44);
+env->gpr_d[12] = cpu_ldl_data(env, ea+48);
+env->gpr_d[13] = cpu_ldl_data(env, ea+52);
+env->gpr_d[14] = cpu_ldl_data(env, ea+56);
+env->gpr_d[15] = cpu_ldl_data(env, ea+60);
+cpu_stl_data(env, ea, env->FCX);
+}
+
+void helper_call(CPUTRICOREState *env, uint32_t next_pc)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+target_ulong psw;
+
+psw = psw_read(env);
+/* if (FCX == 0) trap(FCU); */
+if (env->FCX == 0) {
+/* FCU trap */
+}
+/* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
+if (psw & MASK_PSW_CDE) {
+if (cdc_increment(&psw)) {
+/* CDO trap */
+}
+}
+/* PSW.CDE = 1;*/
+psw |= MASK_PSW_CDE;
+/* tmp_FCX = FCX; */
+tmp_FCX = env->FCX;
+/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
+ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
+ ((env->FCX & MASK_FCX_FCXO) << 6);
+/* new_FCX = M(EA, word);
+   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+  D[15]}; */
+

[Qemu-devel] [PATCH v5 06/15] target-tricore: Add instructions of SRC opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SRC opcode format.
Add micro-op generator functions for add, conditional add/sub and shi/shai.

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- gen_shaci: Change case of shift_count == 32 to shift_count == -32 and add 
the clear of V bit.
- gen_shaci: Move creation and freeing of t_max, t_min to case shift_count 
> 0.
- gen_shaci: Add cast to int32_t to the creation of t_min.
- gen_shaci: Now msk is 1 bit longer and uses a positive value of 
shift_count in the else case.
- gen_shaci: now computes V bit in bit 31.
- gen_shaci: Move computation of shift after the computation of PSW bits to 
handle the case of ret = r1.
- gen_shaci: Add clear of V bit for cases shift_count = 0 / = -32 / < 0.
- gen_add_d now saves result of addition into tcg temp to handle ret = r1 
cases.
- gen_cond_add now sets SV, SAV bits conditionally.
- gen_cond_add now writes result after PSW bit computations, to handle ret 
= r1 cases.
- Change int cond to TCGCond on function gen_cond_add, gen_condi_add.
- Switched source and destination register of SRC_ADD_A15 and SRC_ADD_15A 
insns.
- Negate conditions of 16_SRC_CMOV and 16_SRC_CMOVN insns.
- SRC_MOV_A loads const4 zero extended. (Googled alot to find a manual 
saying it should be sign extended, but couldn't)
- RSUB now computes V bit in bit 31.

 target-tricore/helper.h|  16 +++
 target-tricore/translate.c | 249 +
 2 files changed, 265 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index e69de29..5884240 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index ec4d80b..fbaba9e 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -27,6 +27,7 @@
 #include "exec/helper-gen.h"
 
 #include "tricore-opcodes.h"
+
 /*
  * TCG registers
  */
@@ -102,8 +103,256 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 
 }
 
+/*
+ * Functions to generate micro-ops
+ */
+
+/* Functions for arithmetic instructions  */
+
+static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
+{
+TCGv t0 = tcg_temp_new_i32();
+TCGv result = tcg_temp_new_i32();
+/* Addition and set V/SV bits */
+tcg_gen_add_tl(result, r1, r2);
+/* 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_d(TCGv ret, TCGv r1, target_ulong r2)
+{
+TCGv temp = tcg_const_i32(r2);
+gen_add_d(ret, r1, temp);
+tcg_temp_free(temp);
+}
+
+static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
+TCGv r4)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+TCGv result = tcg_temp_new();
+TCGv mask = tcg_temp_new();
+TCGv t0 = tcg_const_i32(0);
+
+/* create mask for sticky bits */
+tcg_gen_setcond_tl(cond, mask, r4, t0);
+tcg_gen_shli_tl(mask, mask, 31);
+
+tcg_gen_add_tl(result, r1, r2);
+/* Calc PSW_V */
+tcg_gen_xor_tl(temp, result, r1);
+tcg_gen_xor_tl(temp2, r1, r2);
+tcg_gen_andc_tl(temp, temp, temp2);
+tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
+/* Set PSW_SV */
+tcg_gen_and_tl(temp, temp, mask);
+tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
+/* calc AV bit */
+tcg_gen_add_tl(temp, result, result);
+tcg_gen_xor_tl(temp, temp, result);
+tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
+/* calc SAV bit */
+tcg_gen_and_tl(temp, temp, mask);
+tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
+/* write back result */
+tcg_gen

[Qemu-devel] [PATCH v5 01/15] target-tricore: Add target stubs and qom-cpu

2014-08-13 Thread Bastian Koppelmann
Add TriCore target stubs, and QOM cpu.

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- Change documentation of S, SV bits to use bit 31.
- psw_read/_write now uses only bit 31 of S, SV bits.

 arch_init.c   |   2 +
 cpu-exec.c|  11 +-
 cpus.c|   6 +
 include/elf.h |   2 +
 include/sysemu/arch_init.h|   1 +
 target-tricore/Makefile.objs  |   1 +
 target-tricore/cpu-qom.h  |  71 
 target-tricore/cpu.c  | 191 
 target-tricore/cpu.h  | 400 ++
 target-tricore/helper.c   |  92 ++
 target-tricore/helper.h   |   0
 target-tricore/op_helper.c|  27 +++
 target-tricore/translate.c| 100 +++
 target-tricore/tricore-defs.h |  28 +++
 14 files changed, 931 insertions(+), 1 deletion(-)
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 100644 target-tricore/helper.h
 create mode 100644 target-tricore/op_helper.c
 create mode 100644 target-tricore/translate.c
 create mode 100644 target-tricore/tricore-defs.h

diff --git a/arch_init.c b/arch_init.c
index 8ddaf35..29a5821 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -104,6 +104,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_XTENSA
 #elif defined(TARGET_UNICORE32)
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
+#elif defined(TARGET_TRICORE)
+#define QEMU_ARCH QEMU_ARCH_TRICORE
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/cpu-exec.c b/cpu-exec.c
index cbc8067..6fbf5a6 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -382,6 +382,7 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
 #elif defined(TARGET_XTENSA)
+#elif defined(TARGET_TRICORE)
 /* X */
 #else
 #error unsupported target CPU
@@ -439,7 +440,8 @@ int cpu_exec(CPUArchState *env)
 }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
-defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || 
defined(TARGET_UNICORE32)
+defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) ||   \
+defined(TARGET_UNICORE32) || defined(TARGET_TRICORE)
 if (interrupt_request & CPU_INTERRUPT_HALT) {
 cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
 cpu->halted = 1;
@@ -555,6 +557,12 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
+#elif defined(TARGET_TRICORE)
+if ((interrupt_request & CPU_INTERRUPT_HARD)) {
+cc->do_interrupt(cpu);
+next_tb = 0;
+}
+
 #elif defined(TARGET_OPENRISC)
 {
 int idx = -1;
@@ -840,6 +848,7 @@ int cpu_exec(CPUArchState *env)
   | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_TRICORE)
 #elif defined(TARGET_MOXIE)
 #elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
diff --git a/cpus.c b/cpus.c
index 2b5c0bd..c740890 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1409,6 +1409,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 MIPSCPU *mips_cpu = MIPS_CPU(cpu);
 CPUMIPSState *env = &mips_cpu->env;
+#elif defined(TARGET_TRICORE)
+TRICORECPU *tricore_cpu = TRICORE_CPU(cpu);
+CPUTRICOREState *env = &tricore_cpu->env;
 #endif
 
 cpu_synchronize_state(cpu);
@@ -1433,6 +1436,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 info->value->has_PC = true;
 info->value->PC = env->active_tc.PC;
+#elif defined(TARGET_TRICORE)
+info->value->has_PC = true;
+info->value->PC = env->PC;
 #endif
 
 /* XXX: waiting for the qapi to support GSList */
diff --git a/include/elf.h b/include/elf.h
index e88d52f..70107f0 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -92,6 +92,8 @@ typedef int64_t  Elf64_Sxword;
 
 #define EM_SPARCV9 43  /* SPARC v9 64-bit */
 
+#define EM_TRICORE  44  /* Infineon TriCore */
+
 #define EM_IA_64   50  /* HP/Intel IA-64 */
 
 #define EM_X86_64  62  /* AMD x86-64 */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 182d48d..8939233 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -22,6 +22,7 @@ enum {
 QEMU_ARCH_OPENRISC = 8192,
 QEMU_ARCH_UNICORE32 = 0x4000,
 QEMU_ARCH_MOXIE = 0x8000,
+QEMU_ARCH_TRICORE = 0x1,
 };
 
 extern c

[Qemu-devel] [PATCH v5 12/15] target-tricore: Add instructions of SBR opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SBR opcode format.
Add gen_loop micro-op generator function.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 66 +-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 87b5ad3..8e468bd 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -386,6 +386,18 @@ static inline void gen_branch_condi(DisasContext *ctx, 
TCGCond 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_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
+gen_goto_tb(ctx, 1, ctx->pc + offset);
+gen_set_label(l1);
+gen_goto_tb(ctx, 0, ctx->next_pc);
+}
+
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
@@ -427,8 +439,44 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, 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, offset * 2 - 32);
+break;
 default:
-printf("Branch Error at %x\n", ctx->pc);
+printf("Branch Error at %x\n", ctx->pc);
 }
 ctx->bstate = BS_BRANCH;
 }
@@ -750,6 +798,22 @@ 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;
 }
 }
 
-- 
2.0.4




[Qemu-devel] [PATCH v5 11/15] target-tricore: Add instructions of SBC and SBRN opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SBC and SBRN opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index b06f856..87b5ad3 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -389,6 +389,8 @@ static inline void gen_branch_condi(DisasContext *ctx, 
TCGCond cond, TCGv r1,
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
+TCGv temp;
+
 switch (opc) {
 /* SB-format jumps */
 case OPC1_16_SB_J:
@@ -405,6 +407,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_16_SB_JNZ:
 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
 break;
+/* SBC-format jumps */
+case OPC1_16_SBC_JEQ:
+gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
+break;
+case OPC1_16_SBC_JNE:
+gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
+break;
+/* SBRN-format jumps */
+case OPC1_16_SBRN_JZ_T:
+temp = tcg_temp_new();
+tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
+gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
+tcg_temp_free(temp);
+break;
+case OPC1_16_SBRN_JNZ_T:
+temp = tcg_temp_new();
+tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
+gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
+tcg_temp_free(temp);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -714,6 +736,20 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
 gen_compute_branch(ctx, op1, 0, 0, 0, address);
 break;
+/* SBC-format */
+case OPC1_16_SBC_JEQ:
+case OPC1_16_SBC_JNE:
+address = MASK_OP_SBC_DISP4(ctx->opcode);
+const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+break;
+/* SBRN-format */
+case OPC1_16_SBRN_JNZ_T:
+case OPC1_16_SBRN_JZ_T:
+address = MASK_OP_SBRN_DISP4(ctx->opcode);
+const16 = MASK_OP_SBRN_N(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+break;
 }
 }
 
-- 
2.0.4




[Qemu-devel] [PATCH v5 09/15] target-tricore: Add instructions of SRRS and SLRO opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SSRS and SLRO opcode format.
Add micro-op generator functions for offset loads.

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- decode_16Bit_opc: Add if to handle ADDSC.A opcode being 6 bit instead of 
7 bit long

 target-tricore/translate.c | 59 ++
 1 file changed, 59 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 674ef9c..ad30c3d 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -107,6 +107,26 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
  * Functions to generate micro-ops
  */
 
+/* Functions for load/save to/from memory */
+
+static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
+ int16_t con, TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, con);
+tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
+tcg_temp_free(temp);
+}
+
+static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2,
+ int16_t con, TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, con);
+tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
+tcg_temp_free(temp);
+}
+
 /* Functions for arithmetic instructions  */
 
 static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
@@ -511,9 +531,17 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
 {
 int op1;
+int r1, r2;
+int32_t const16;
+TCGv temp;
 
 op1 = MASK_OP_MAJOR(ctx->opcode);
 
+/* handle ADDSC.A opcode only being 6 bit long */
+if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
+op1 = OPC1_16_SRRS_ADDSC_A;
+}
+
 switch (op1) {
 case OPC1_16_SRC_ADD:
 case OPC1_16_SRC_ADD_A15:
@@ -566,6 +594,37 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 case OPC1_16_SSR_ST_W_POSTINC:
 decode_ssr_opc(ctx, op1);
 break;
+/* SRRS-format */
+case OPC1_16_SRRS_ADDSC_A:
+r2 = MASK_OP_SRRS_S2(ctx->opcode);
+r1 = MASK_OP_SRRS_S1D(ctx->opcode);
+const16 = MASK_OP_SRRS_N(ctx->opcode);
+temp = tcg_temp_new();
+tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
+tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
+tcg_temp_free(temp);
+break;
+/* SLRO-format */
+case OPC1_16_SLRO_LD_A:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SLRO_LD_BU:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
+break;
+case OPC1_16_SLRO_LD_H:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
+break;
+case OPC1_16_SLRO_LD_W:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
 }
 }
 
-- 
2.0.4




[Qemu-devel] [PATCH v5 08/15] target-tricore: Add instructions of SSR opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SSR opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 054d08c..674ef9c 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -469,6 +469,45 @@ static void decode_srr_opc(DisasContext *ctx, int op1)
 }
 }
 
+static void decode_ssr_opc(DisasContext *ctx, int op1)
+{
+int r1, r2;
+
+r1 = MASK_OP_SSR_S1(ctx->opcode);
+r2 = MASK_OP_SSR_S2(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SSR_ST_A:
+tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+break;
+case OPC1_16_SSR_ST_A_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+case OPC1_16_SSR_ST_B:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+break;
+case OPC1_16_SSR_ST_B_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
+break;
+case OPC1_16_SSR_ST_H:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUW);
+break;
+case OPC1_16_SSR_ST_H_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
+break;
+case OPC1_16_SSR_ST_W:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+break;
+case OPC1_16_SSR_ST_W_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+}
+}
+
 static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
 {
 int op1;
@@ -516,6 +555,17 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 case OPC1_16_SRR_XOR:
 decode_srr_opc(ctx, op1);
 break;
+/* SSR-format */
+case OPC1_16_SSR_ST_A:
+case OPC1_16_SSR_ST_A_POSTINC:
+case OPC1_16_SSR_ST_B:
+case OPC1_16_SSR_ST_B_POSTINC:
+case OPC1_16_SSR_ST_H:
+case OPC1_16_SSR_ST_H_POSTINC:
+case OPC1_16_SSR_ST_W:
+case OPC1_16_SSR_ST_W_POSTINC:
+decode_ssr_opc(ctx, op1);
+break;
 }
 }
 
-- 
2.0.4




[Qemu-devel] [PATCH v5 02/15] target-tricore: Add board for systemmode

2014-08-13 Thread Bastian Koppelmann
Add basic board to allow systemmode emulation

Signed-off-by: Bastian Koppelmann 
---
 hw/tricore/Makefile.objs   |   1 +
 hw/tricore/tricore_testboard.c | 129 +
 include/hw/tricore/tricore.h   |  54 +
 3 files changed, 184 insertions(+)
 create mode 100644 hw/tricore/Makefile.objs
 create mode 100644 hw/tricore/tricore_testboard.c
 create mode 100644 include/hw/tricore/tricore.h

diff --git a/hw/tricore/Makefile.objs b/hw/tricore/Makefile.objs
new file mode 100644
index 000..435e095
--- /dev/null
+++ b/hw/tricore/Makefile.objs
@@ -0,0 +1 @@
+obj-y += tricore_testboard.o
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
new file mode 100644
index 000..fee67b1
--- /dev/null
+++ b/hw/tricore/tricore_testboard.c
@@ -0,0 +1,129 @@
+/*
+ * TriCore Baseboard System emulation.
+ *
+ * Copyright (c) 2014 Bastian Koppelmann
+ *
+ * This code is licensed under the GPL.
+ */
+
+#include "hw/hw.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "sysemu/blockdev.h"
+#include "exec/address-spaces.h"
+#include "hw/block/flash.h"
+#include "elf.h"
+#include "hw/tricore/tricore.h"
+
+#define TRICORE_FLASH_ADDR 0xa000
+#define TRICORE_FLASH_SIZE (2 * 1024 * 1024)
+#define TRICORE_FLASH_SECT_SIZE (256 * 1024)
+
+
+/* Board init.  */
+
+static struct tricore_boot_info tricoretb_binfo;
+
+static void tricore_load_kernel(CPUTRICOREState *env)
+{
+int64_t entry;
+long kernel_size;
+
+kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL,
+   NULL, (uint64_t *)&entry, NULL,
+   NULL, 0,
+   ELF_MACHINE, 1);
+if (kernel_size <= 0) {
+fprintf(stderr, "qemu: no kernel file '%s'\n",
+tricoretb_binfo.kernel_filename);
+exit(1);
+}
+env->PC = entry;
+
+}
+
+static void tricore_testboard_init(MachineState *machine, int board_id)
+{
+TRICORECPU *cpu;
+CPUTRICOREState *env;
+
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ext_cram = g_new(MemoryRegion, 1);
+MemoryRegion *ext_dram = g_new(MemoryRegion, 1);
+MemoryRegion *int_cram = g_new(MemoryRegion, 1);
+MemoryRegion *int_dram = g_new(MemoryRegion, 1);
+MemoryRegion *pcp_data = g_new(MemoryRegion, 1);
+MemoryRegion *pcp_text = g_new(MemoryRegion, 1);
+DriveInfo *dinfo;
+
+if (!machine->cpu_model) {
+machine->cpu_model = "tc1796";
+}
+cpu = cpu_tricore_init(machine->cpu_model);
+env = &cpu->env;
+if (!cpu) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram", 2*1024*1024);
+vmstate_register_ram_global(ext_cram);
+memory_region_init_ram(ext_dram, NULL, "powerlink_ext_d.ram", 4*1024*1024);
+vmstate_register_ram_global(ext_dram);
+memory_region_init_ram(int_cram, NULL, "powerlink_int_c.ram", 48*1024);
+vmstate_register_ram_global(int_cram);
+memory_region_init_ram(int_dram, NULL, "powerlink_int_d.ram", 48*1024);
+vmstate_register_ram_global(int_dram);
+memory_region_init_ram(pcp_data, NULL, "powerlink_pcp_data.ram", 16*1024);
+vmstate_register_ram_global(pcp_data);
+memory_region_init_ram(pcp_text, NULL, "powerlink_pcp_text.ram", 32*1024);
+vmstate_register_ram_global(pcp_text);
+
+memory_region_add_subregion(sysmem, 0x8000, ext_cram);
+memory_region_add_subregion(sysmem, 0xa100, ext_dram);
+memory_region_add_subregion(sysmem, 0xd400, int_cram);
+memory_region_add_subregion(sysmem, 0xd000, int_dram);
+memory_region_add_subregion(sysmem, 0xf005, pcp_data);
+memory_region_add_subregion(sysmem, 0xf006, pcp_text);
+
+dinfo = drive_get(IF_PFLASH, 0, 0);
+if (!pflash_cfi01_register(TRICORE_FLASH_ADDR, NULL,
+  "tricore_testboard.flash",
+  TRICORE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+  TRICORE_FLASH_SECT_SIZE,
+  TRICORE_FLASH_SIZE / TRICORE_FLASH_SECT_SIZE,
+  2, 0x00, 0x00, 0x, 0x0, 0)) {
+
+fprintf(stderr, "qemu: Error registering flash memory.\n");
+} else {
+env->PC = TRICORE_FLASH_ADDR;
+}
+
+tricoretb_binfo.ram_size = machine->ram_size;
+tricoretb_binfo.kernel_filename = machine->kernel_filename;
+
+if (machine->kernel_filename) {
+tricore_load_kernel(env);
+}
+}
+
+static void tricoreboard_init(MachineState *machine)
+{
+tricore_testboard_init(machin

[Qemu-devel] [PATCH v5 15/15] target-tricore: Add instructions of SR opcode format

2014-08-13 Thread Bastian Koppelmann
Add instructions of SR opcode format.
Add micro-op generator functions for saturate.
Add helper return from exception (rfe).

Signed-off-by: Bastian Koppelmann 
---
v4 -> v5:
- Switched sat_neg and arg in first movcond in function gen_saturate.
- SR_NOT: Remove if checking OP2.

 target-tricore/helper.h|   1 +
 target-tricore/op_helper.c |  52 +
 target-tricore/translate.c | 111 +
 3 files changed, 164 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 3c73234..7b7d74b 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -22,3 +22,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
+DEF_HELPER_1(rfe, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 4ea94d8..4174ef9 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -99,6 +99,21 @@ static int cdc_decrement(target_ulong *psw)
 return 0;
 }
 
+static bool cdc_zero(target_ulong *psw)
+{
+int cdc = *psw & MASK_PSW_CDC;
+/* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
+   7'b111, otherwise returns FALSE. */
+if (cdc == 0x7f) {
+return true;
+}
+/* find CDC.COUNT */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+return count == 0;
+}
+
 static void save_context_upper(CPUTRICOREState *env, int ea,
target_ulong *new_FCX)
 {
@@ -302,6 +317,43 @@ void helper_bisr(CPUTRICOREState *env, uint32_t const9)
 }
 }
 
+void helper_rfe(CPUTRICOREState *env)
+{
+target_ulong ea;
+target_ulong new_PCXI;
+target_ulong new_PSW;
+/* if (PCXI[19: 0] == 0) then trap(CSU); */
+if ((env->PCXI & 0xf) == 0) {
+/* raise csu trap */
+}
+/* if (PCXI.UL == 0) then trap(CTYP); */
+if ((env->PCXI & MASK_PCXI_UL) == 0) {
+/* raise CTYP trap */
+}
+/* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
+if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
+/* raise MNG trap */
+}
+/* ICR.IE = PCXI.PIE; */
+env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
+/* ICR.CCPN = PCXI.PCPN; */
+env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
+   ((env->PCXI & MASK_PCXI_PCPN) >> 24);
+/*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
+ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
+ ((env->PCXI & MASK_PCXI_PCXO) << 6);
+/*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
+  M(EA, word) = FCX;*/
+restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* FCX[19: 0] = PCXI[19: 0]; */
+env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
+/* PCXI = new_PCXI; */
+env->PCXI = new_PCXI;
+/* write psw */
+psw_write(env, new_PSW);
+}
+
 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 5efa022..7466c21 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -262,6 +262,29 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
 tcg_temp_free(low);
 }
 
+static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
+{
+TCGv sat_neg = tcg_const_i32(low);
+TCGv temp = tcg_const_i32(up);
+
+/* sat_neg = (arg < low ) ? low : arg; */
+tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
+
+/* ret = (sat_neg > up ) ? up  : sat_neg; */
+tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+
+tcg_temp_free(sat_neg);
+tcg_temp_free(temp);
+}
+
+static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
+{
+TCGv temp = tcg_const_i32(up);
+/* sat_neg = (arg > up ) ? up : arg; */
+tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+tcg_temp_free(temp);
+}
+
 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
 {
 if (shift_count == -32) {
@@ -475,6 +498,15 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_16_SBR_LOOP:
 gen_loop(ctx, r1, offset * 2 - 32);
 break;
+/* SR-format jumps */
+case OPC1_16_SR_JI:
+tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffe);
+tcg_gen_exit_tb(0);
+break;
+case OPC2_16_SR_RET:
+gen_helper_ret(cpu_env);
+tcg_gen_exit_tb

[Qemu-devel] [PATCH v5 03/15] target-tricore: Add softmmu support

2014-08-13 Thread Bastian Koppelmann
Add basic softmmu support for TriCore

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/helper.c| 54 +-
 target-tricore/op_helper.c | 33 +++-
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index 7d8fc30..9176add 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -24,10 +24,62 @@
 
 #include "cpu.h"
 
+enum {
+TLBRET_DIRTY = -4,
+TLBRET_INVALID = -3,
+TLBRET_NOMATCH = -2,
+TLBRET_BADADDR = -1,
+TLBRET_MATCH = 0
+};
+
+#if defined(CONFIG_SOFTMMU)
+static int get_physical_address(CPUTRICOREState *env, hwaddr *physical,
+int *prot, target_ulong address,
+int rw, int access_type)
+{
+int ret = TLBRET_MATCH;
+
+*physical = address & 0x;
+*prot = PAGE_READ | PAGE_WRITE;
+
+return ret;
+}
+#endif
+
+/* TODO: Add exeption support*/
+static void raise_mmu_exception(CPUTRICOREState *env, target_ulong address,
+int rw, int tlb_error)
+{
+}
+
 int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address,
  int rw, int mmu_idx)
 {
-return 0;
+TRICORECPU *cpu = TRICORE_CPU(cs);
+CPUTRICOREState *env = &cpu->env;
+hwaddr physical;
+int prot;
+int access_type;
+int ret = 0;
+
+rw &= 1;
+access_type = ACCESS_INT;
+ret = get_physical_address(env, &physical, &prot,
+   address, rw, access_type);
+qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx
+ " prot %d\n", __func__, address, ret, physical, prot);
+
+if (ret == TLBRET_MATCH) {
+tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ mmu_idx, TARGET_PAGE_SIZE);
+ret = 0;
+} else if (ret < 0) {
+raise_mmu_exception(env, address, rw, ret);
+ret = 1;
+}
+
+return ret;
 }
 
 void tricore_cpu_do_interrupt(CPUState *cs)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 275790b..2e5981f 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,8 +20,39 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env,
+uint32_t exception,
+int error_code,
+uintptr_t pc)
+{
+CPUState *cs = CPU(tricore_env_get_cpu(env));
+cs->exception_index = exception;
+env->error_code = error_code;
+
+if (pc) {
+/* now we have a real cpu fault */
+cpu_restore_state(cs, pc);
+}
+
+cpu_loop_exit(cs);
+}
+
+static inline void QEMU_NORETURN do_raise_exception(CPUTRICOREState *env,
+uint32_t exception,
+uintptr_t pc)
+{
+do_raise_exception_err(env, exception, 0, pc);
+}
+
 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
   uintptr_t retaddr)
 {
+int ret;
+ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
+if (ret) {
+TRICORECPU *cpu = TRICORE_CPU(cs);
+CPUTRICOREState *env = &cpu->env;
+do_raise_exception_err(env, cs->exception_index,
+   env->error_code, retaddr);
+}
 }
-
-- 
2.0.4




[Qemu-devel] [PATCH v5 00/15] TriCore architecture guest implementation

2014-08-13 Thread Bastian Koppelmann
Hi,

my aim is to add Infineon's TriCore architecture to QEMU. This series of 
patches adds the target stubs, a basic testboard and a softmmu for system mode 
emulation. Furthermore it adds all the 16 bit long instructions of the 
architecture grouped by opcode format.

After this series of patches. Another one will follow, which adds a lot of the 
32 bit long instructions.

All the best

Bastian

v4 -> v5:
- Change documentation of S, SV bits to use bit 31.
- psw_read/_write now uses only bit 31 of S, SV bits.
- gen_intermediate_code_internal: Move calculation of next_pc after the ifs 
for singlestep and long tbs.
- gen_shaci: Change case of shift_count == 32 to shift_count == -32 and add 
the clear of V bit.
- gen_shaci: Move creation and freeing of t_max, t_min to case shift_count 
> 0.
- gen_shaci: Add cast to int32_t to the creation of t_min.
- gen_shaci: Now msk is 1 bit longer and uses a positive value of 
shift_count in the else case.
- gen_shaci: now computes V bit in bit 31.
- gen_shaci: Move computation of shift after the computation of PSW bits to 
handle the case of ret = r1.
- gen_shaci: Add clear of V bit for cases shift_count = 0 / = -32 / < 0.
- gen_add_d now saves result of addition into tcg temp to handle ret = r1 
cases.
- gen_cond_add now sets SV, SAV bits conditionally.
- gen_cond_add now writes result after PSW bit computations, to handle ret 
= r1 cases.
- Change int cond to TCGCond on function gen_cond_add, gen_condi_add.
- Switched source and destination register of SRC_ADD_A15 and SRC_ADD_15A 
insns.
- Negate conditions of 16_SRC_CMOV and 16_SRC_CMOVN insns.
- SRC_MOV_A loads const4 zero extended. (Googled alot to find a manual 
saying it should be sign extended, but couldn't. 1.3 and 1.6 manual state sign 
extension)
- RSUB now computes V bit in bit 31.
- gen_sub_d now saves result of substraction into tcg temp to handle ret = 
r1 cases.
- gen_mul_i32s now calculates V, SV bits in bit 31.
- SSOV makro now computes V, SV bits in bit 31.
- Negate conditions of 16_SRR_CMOV and 16_SRR_CMOVN insns.
- MOV_AA: Switch r1 and r2 arguments.
- decode_16Bit_opc: Add if to handle ADDSC.A opcode being 6 bit instead of 
7 bit long.
- Change int cond to TCGCond in functions gen_branch_cond, gen_branch_condi.
- gen_intermediate_code_internal: Add gen_goto_tb so qemu finds new tb on 
singlestep and after long tbs without branch.
- Switched sat_neg and arg in first movcond in function gen_saturate.
- SR_NOT: Remove if checking OP2.


Bastian Koppelmann (15):
  target-tricore: Add target stubs and qom-cpu
  target-tricore: Add board for systemmode
  target-tricore: Add softmmu support
  target-tricore: Add initialization for translation and activate target
  target-tricore: Add masks and opcodes for decoding
  target-tricore: Add instructions of SRC opcode format
  target-tricore: Add instructions of SRR opcode format
  target-tricore: Add instructions of SSR opcode format
  target-tricore: Add instructions of SRRS and SLRO opcode format
  target-tricore: Add instructions of SB opcode format
  target-tricore: Add instructions of SBC and SBRN opcode format
  target-tricore: Add instructions of SBR opcode format
  target-tricore: Add instructions of SC opcode format
  target-tricore: Add instructions of SLR, SSRO and SRO opcode format
  target-tricore: Add instructions of SR opcode format

 arch_init.c |2 +
 configure   |5 +
 cpu-exec.c  |   11 +-
 cpus.c  |6 +
 default-configs/tricore-softmmu.mak |3 +
 hw/tricore/Makefile.objs|1 +
 hw/tricore/tricore_testboard.c  |  129 
 include/elf.h   |2 +
 include/hw/tricore/tricore.h|   54 ++
 include/sysemu/arch_init.h  |1 +
 target-tricore/Makefile.objs|1 +
 target-tricore/cpu-qom.h|   71 ++
 target-tricore/cpu.c|  191 +
 target-tricore/cpu.h|  400 ++
 target-tricore/helper.c |  144 
 target-tricore/helper.h |   25 +
 target-tricore/op_helper.c  |  392 ++
 target-tricore/translate.c  | 1259 +++
 target-tricore/tricore-defs.h   |   28 +
 target-tricore/tricore-opcodes.h| 1406 +++
 20 files changed, 4130 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/tricore-softmmu.mak
 create mode 100644 hw/tricore/Makefile.objs
 create mode 100644 hw/tricore/tricore_testboard.c
 create mode 100644 include/hw/tricore/tricore.h
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 10

Re: [Qemu-devel] [PATCH v5 00/15] TriCore architecture guest implementation

2014-08-20 Thread Bastian Koppelmann

ping, anyone?

Patchwork links:

01: https://patchwork.ozlabs.org/patch/379594/
02: https://patchwork.ozlabs.org/patch/379598/
03: https://patchwork.ozlabs.org/patch/379600/
04: https://patchwork.ozlabs.org/patch/379588/
05: https://patchwork.ozlabs.org/patch/379589/
06: https://patchwork.ozlabs.org/patch/379591/
07: https://patchwork.ozlabs.org/patch/379587/
08: https://patchwork.ozlabs.org/patch/379596/
09: https://patchwork.ozlabs.org/patch/379597/
10: https://patchwork.ozlabs.org/patch/379592/
11: https://patchwork.ozlabs.org/patch/379593/
12: https://patchwork.ozlabs.org/patch/379595/
13: https://patchwork.ozlabs.org/patch/379586/
14: https://patchwork.ozlabs.org/patch/379590/
15: https://patchwork.ozlabs.org/patch/379599/

Thanks,

Bastian

On 08/13/2014 01:07 PM, Bastian Koppelmann wrote:

Hi,

my aim is to add Infineon's TriCore architecture to QEMU. This series of 
patches adds the target stubs, a basic testboard and a softmmu for system mode 
emulation. Furthermore it adds all the 16 bit long instructions of the 
architecture grouped by opcode format.

After this series of patches. Another one will follow, which adds a lot of the 
32 bit long instructions.

All the best

Bastian

v4 -> v5:
 - Change documentation of S, SV bits to use bit 31.
 - psw_read/_write now uses only bit 31 of S, SV bits.
 - gen_intermediate_code_internal: Move calculation of next_pc after the 
ifs for singlestep and long tbs.
 - gen_shaci: Change case of shift_count == 32 to shift_count == -32 and 
add the clear of V bit.
 - gen_shaci: Move creation and freeing of t_max, t_min to case shift_count 
> 0.
 - gen_shaci: Add cast to int32_t to the creation of t_min.
 - gen_shaci: Now msk is 1 bit longer and uses a positive value of 
shift_count in the else case.
 - gen_shaci: now computes V bit in bit 31.
 - gen_shaci: Move computation of shift after the computation of PSW bits 
to handle the case of ret = r1.
 - gen_shaci: Add clear of V bit for cases shift_count = 0 / = -32 / < 0.
 - gen_add_d now saves result of addition into tcg temp to handle ret = r1 
cases.
 - gen_cond_add now sets SV, SAV bits conditionally.
 - gen_cond_add now writes result after PSW bit computations, to handle ret 
= r1 cases.
 - Change int cond to TCGCond on function gen_cond_add, gen_condi_add.
 - Switched source and destination register of SRC_ADD_A15 and SRC_ADD_15A 
insns.
 - Negate conditions of 16_SRC_CMOV and 16_SRC_CMOVN insns.
 - SRC_MOV_A loads const4 zero extended. (Googled alot to find a manual 
saying it should be sign extended, but couldn't. 1.3 and 1.6 manual state sign 
extension)
 - RSUB now computes V bit in bit 31.
 - gen_sub_d now saves result of substraction into tcg temp to handle ret = 
r1 cases.
 - gen_mul_i32s now calculates V, SV bits in bit 31.
 - SSOV makro now computes V, SV bits in bit 31.
 - Negate conditions of 16_SRR_CMOV and 16_SRR_CMOVN insns.
 - MOV_AA: Switch r1 and r2 arguments.
 - decode_16Bit_opc: Add if to handle ADDSC.A opcode being 6 bit instead of 
7 bit long.
 - Change int cond to TCGCond in functions gen_branch_cond, 
gen_branch_condi.
 - gen_intermediate_code_internal: Add gen_goto_tb so qemu finds new tb on 
singlestep and after long tbs without branch.
 - Switched sat_neg and arg in first movcond in function gen_saturate.
 - SR_NOT: Remove if checking OP2.


Bastian Koppelmann (15):
   target-tricore: Add target stubs and qom-cpu
   target-tricore: Add board for systemmode
   target-tricore: Add softmmu support
   target-tricore: Add initialization for translation and activate target
   target-tricore: Add masks and opcodes for decoding
   target-tricore: Add instructions of SRC opcode format
   target-tricore: Add instructions of SRR opcode format
   target-tricore: Add instructions of SSR opcode format
   target-tricore: Add instructions of SRRS and SLRO opcode format
   target-tricore: Add instructions of SB opcode format
   target-tricore: Add instructions of SBC and SBRN opcode format
   target-tricore: Add instructions of SBR opcode format
   target-tricore: Add instructions of SC opcode format
   target-tricore: Add instructions of SLR, SSRO and SRO opcode format
   target-tricore: Add instructions of SR opcode format

  arch_init.c |2 +
  configure   |5 +
  cpu-exec.c  |   11 +-
  cpus.c  |6 +
  default-configs/tricore-softmmu.mak |3 +
  hw/tricore/Makefile.objs|1 +
  hw/tricore/tricore_testboard.c  |  129 
  include/elf.h   |2 +
  include/hw/tricore/tricore.h|   54 ++
  include/sysemu/arch_init.h  |1 +
  target-tricore/Makefile.objs|1 +
  target-tricore/cpu-qom.h|   71 ++
  target-tricore/cpu.c   

Re: [Qemu-devel] [PATCH v5 00/15] TriCore architecture guest implementation

2014-08-20 Thread Bastian Koppelmann

Hi Andreas,

On 08/20/2014 02:17 PM, Andreas Färber wrote:

Hi,

Am 13.08.2014 14:07, schrieb Bastian Koppelmann:

  arch_init.c |2 +
  configure   |5 +
  cpu-exec.c  |   11 +-
  cpus.c  |6 +
  default-configs/tricore-softmmu.mak |3 +
  hw/tricore/Makefile.objs|1 +
  hw/tricore/tricore_testboard.c  |  129 
  include/elf.h   |2 +
  include/hw/tricore/tricore.h|   54 ++
  include/sysemu/arch_init.h  |1 +
  target-tricore/Makefile.objs|1 +
  target-tricore/cpu-qom.h|   71 ++
  target-tricore/cpu.c|  191 +
  target-tricore/cpu.h|  400 ++
  target-tricore/helper.c |  144 
  target-tricore/helper.h |   25 +
  target-tricore/op_helper.c  |  392 ++
  target-tricore/translate.c  | 1259 +++
  target-tricore/tricore-defs.h   |   28 +
  target-tricore/tricore-opcodes.h| 1406 +++
  20 files changed, 4130 insertions(+), 1 deletion(-)
  create mode 100644 default-configs/tricore-softmmu.mak
  create mode 100644 hw/tricore/Makefile.objs
  create mode 100644 hw/tricore/tricore_testboard.c
  create mode 100644 include/hw/tricore/tricore.h
  create mode 100644 target-tricore/Makefile.objs
  create mode 100644 target-tricore/cpu-qom.h
  create mode 100644 target-tricore/cpu.c
  create mode 100644 target-tricore/cpu.h
  create mode 100644 target-tricore/helper.c
  create mode 100644 target-tricore/helper.h
  create mode 100644 target-tricore/op_helper.c
  create mode 100644 target-tricore/translate.c
  create mode 100644 target-tricore/tricore-defs.h
  create mode 100644 target-tricore/tricore-opcodes.h

I still haven't really looked at the CPU QOM parts yet (and won't get to
that shortly, no blocker), in this diffstat I am missing a MAINTAINERS
entry that names and CCs someone (you?) to take care of all those new
target-tricore/, hw/tricore/ and hw/include/tricore/ files in the future.

I can definitly do that.


Have you tested your new machine using "make check V=1"? Just wondering
whether qom-test passes. (Sorry if I already asked earlier.)
I just tried that now and the test fails, because I have a whitespace in 
the machine name. I'll fix that as soon as I get review on the 
translation patches.


Regards,
Andreas


Thanks,

Bastian



Re: [Qemu-devel] [PATCH v5 15/15] target-tricore: Add instructions of SR opcode format

2014-08-22 Thread Bastian Koppelmann


On 08/21/2014 09:48 PM, Richard Henderson wrote:

On 08/13/2014 05:07 AM, Bastian Koppelmann wrote:

+/* SR-format */
+case OPCM_16_SR_SYSTEM:
+decode_sr_system(env, ctx);
+ break;
+case OPCM_16_SR_ACCU:
+decode_sr_accu(env, ctx);
+ break;

Formatting is off; checkpatch should have caught this.



I ran checkpatch again and oddly it does not find that error, so I've 
put Blue Swirl into cc.



r~






[Qemu-devel] [PATCH v6 00/15] TriCore architecture guest implementation

2014-08-22 Thread Bastian Koppelmann
Hi,

my aim is to add Infineon's TriCore architecture to QEMU. This series of 
patches adds the target stubs, a basic testboard and a softmmu for system mode 
emulation. Furthermore it adds all the 16 bit long instructions of the 
architecture grouped by opcode format.

After this series of patches. Another one will follow, which adds a lot of the 
32 bit long instructions.

All the best

Bastian

Richard Henderson: Thanks alot for the great feedback, I really appreciate it.

v5 -> v6:
- Add myself to MAINTAINERS
- tricore_testboard: Fix machine name containing blanks.
- get_physical_address: Add PAGE_EXEC permission.
- gen_shaci: Add calculation of PSW.C to shift_count = -32 case.
- gen_intermediate_code_internal: Replace gen_goto_tb with setting of 
next_pc and exit_tb(0).
- SBC/SBR_JEQ: Negate condition.
- Formating fixes.

Bastian Koppelmann (15):
  target-tricore: Add target stubs and qom-cpu
  target-tricore: Add board for systemmode
  target-tricore: Add softmmu support
  target-tricore: Add initialization for translation and activate target
  target-tricore: Add masks and opcodes for decoding
  target-tricore: Add instructions of SRC opcode format
  target-tricore: Add instructions of SRR opcode format
  target-tricore: Add instructions of SSR opcode format
  target-tricore: Add instructions of SRRS and SLRO opcode format
  target-tricore: Add instructions of SB opcode format
  target-tricore: Add instructions of SBC and SBRN opcode format
  target-tricore: Add instructions of SBR opcode format
  target-tricore: Add instructions of SC opcode format
  target-tricore: Add instructions of SLR, SSRO and SRO opcode format
  target-tricore: Add instructions of SR opcode format

 MAINTAINERS |6 +
 arch_init.c |2 +
 configure   |5 +
 cpu-exec.c  |   11 +-
 cpus.c  |6 +
 default-configs/tricore-softmmu.mak |3 +
 hw/tricore/Makefile.objs|1 +
 hw/tricore/tricore_testboard.c  |  129 
 include/elf.h   |2 +
 include/hw/tricore/tricore.h|   54 ++
 include/sysemu/arch_init.h  |1 +
 target-tricore/Makefile.objs|1 +
 target-tricore/cpu-qom.h|   71 ++
 target-tricore/cpu.c|  191 +
 target-tricore/cpu.h|  400 ++
 target-tricore/helper.c |  144 
 target-tricore/helper.h |   25 +
 target-tricore/op_helper.c  |  392 ++
 target-tricore/translate.c  | 1263 +++
 target-tricore/tricore-defs.h   |   28 +
 target-tricore/tricore-opcodes.h| 1406 +++
 21 files changed, 4140 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/tricore-softmmu.mak
 create mode 100644 hw/tricore/Makefile.objs
 create mode 100644 hw/tricore/tricore_testboard.c
 create mode 100644 include/hw/tricore/tricore.h
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 100644 target-tricore/helper.h
 create mode 100644 target-tricore/op_helper.c
 create mode 100644 target-tricore/translate.c
 create mode 100644 target-tricore/tricore-defs.h
 create mode 100644 target-tricore/tricore-opcodes.h

-- 
2.1.0




[Qemu-devel] [PATCH v6 01/15] target-tricore: Add target stubs and qom-cpu

2014-08-22 Thread Bastian Koppelmann
Add TriCore target stubs, and QOM cpu, and Maintainer

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- Add myself to MAINTAINERS

 MAINTAINERS   |   6 +
 arch_init.c   |   2 +
 cpu-exec.c|  11 +-
 cpus.c|   6 +
 include/elf.h |   2 +
 include/sysemu/arch_init.h|   1 +
 target-tricore/Makefile.objs  |   1 +
 target-tricore/cpu-qom.h  |  71 
 target-tricore/cpu.c  | 191 
 target-tricore/cpu.h  | 400 ++
 target-tricore/helper.c   |  92 ++
 target-tricore/helper.h   |   0
 target-tricore/op_helper.c|  27 +++
 target-tricore/translate.c| 100 +++
 target-tricore/tricore-defs.h |  28 +++
 15 files changed, 937 insertions(+), 1 deletion(-)
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 100644 target-tricore/helper.h
 create mode 100644 target-tricore/op_helper.c
 create mode 100644 target-tricore/translate.c
 create mode 100644 target-tricore/tricore-defs.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 59940f9..70b2c88 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -161,6 +161,12 @@ S: Maintained
 F: target-xtensa/
 F: hw/xtensa/
 
+TriCore
+M: Bastian Koppelmann 
+S: Maintained
+F: target-tricore/
+F: hw/tricore/
+
 Guest CPU Cores (KVM):
 --
 
diff --git a/arch_init.c b/arch_init.c
index 28ece76..c974f3f 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -104,6 +104,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_XTENSA
 #elif defined(TARGET_UNICORE32)
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
+#elif defined(TARGET_TRICORE)
+#define QEMU_ARCH QEMU_ARCH_TRICORE
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/cpu-exec.c b/cpu-exec.c
index c6aad74..7b5d2e2 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -387,6 +387,7 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
 #elif defined(TARGET_XTENSA)
+#elif defined(TARGET_TRICORE)
 /* X */
 #else
 #error unsupported target CPU
@@ -444,7 +445,8 @@ int cpu_exec(CPUArchState *env)
 }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
-defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || 
defined(TARGET_UNICORE32)
+defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) ||   \
+defined(TARGET_UNICORE32) || defined(TARGET_TRICORE)
 if (interrupt_request & CPU_INTERRUPT_HALT) {
 cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
 cpu->halted = 1;
@@ -560,6 +562,12 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
+#elif defined(TARGET_TRICORE)
+if ((interrupt_request & CPU_INTERRUPT_HARD)) {
+cc->do_interrupt(cpu);
+next_tb = 0;
+}
+
 #elif defined(TARGET_OPENRISC)
 {
 int idx = -1;
@@ -846,6 +854,7 @@ int cpu_exec(CPUArchState *env)
   | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_TRICORE)
 #elif defined(TARGET_MOXIE)
 #elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
diff --git a/cpus.c b/cpus.c
index 2b5c0bd..c740890 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1409,6 +1409,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 MIPSCPU *mips_cpu = MIPS_CPU(cpu);
 CPUMIPSState *env = &mips_cpu->env;
+#elif defined(TARGET_TRICORE)
+TRICORECPU *tricore_cpu = TRICORE_CPU(cpu);
+CPUTRICOREState *env = &tricore_cpu->env;
 #endif
 
 cpu_synchronize_state(cpu);
@@ -1433,6 +1436,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 info->value->has_PC = true;
 info->value->PC = env->active_tc.PC;
+#elif defined(TARGET_TRICORE)
+info->value->has_PC = true;
+info->value->PC = env->PC;
 #endif
 
 /* XXX: waiting for the qapi to support GSList */
diff --git a/include/elf.h b/include/elf.h
index e88d52f..70107f0 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -92,6 +92,8 @@ typedef int64_t  Elf64_Sxword;
 
 #define EM_SPARCV9 43  /* SPARC v9 64-bit */
 
+#define EM_TRICORE  44  /* Infineon TriCore */
+
 #define EM_IA_64   50  /* HP/Intel IA-64 */
 
 #define EM_X86_64  62  /* AMD x86-64 */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_

[Qemu-devel] [PATCH v6 05/15] target-tricore: Add masks and opcodes for decoding

2014-08-22 Thread Bastian Koppelmann
Add masks and opcodes for decoding TriCore instructions.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c   |1 +
 target-tricore/tricore-opcodes.h | 1406 ++
 2 files changed, 1407 insertions(+)
 create mode 100644 target-tricore/tricore-opcodes.h

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 431968b..ec4d80b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,7 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+#include "tricore-opcodes.h"
 /*
  * TCG registers
  */
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
new file mode 100644
index 000..9c6ec01
--- /dev/null
+++ b/target-tricore/tricore-opcodes.h
@@ -0,0 +1,1406 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Opcode Masks for Tricore
+ * Format MASK_OP_InstrFormatName_Field
+ */
+
+/* This creates a mask with bits start .. end set to 1 and applies it to op */
+#define MASK_BITS_SHIFT(op, start, end) (extract32(op, (start), \
+(end) - (start) + 1))
+#define MASK_BITS_SHIFT_SEXT(op, start, end) (sextract32(op, (start),\
+ (end) - (start) + 1))
+
+/* new opcode masks */
+
+#define MASK_OP_MAJOR(op)  MASK_BITS_SHIFT(op, 0, 7)
+
+/* 16-Bit Formats */
+#define MASK_OP_SB_DISP8(op)   MASK_BITS_SHIFT(op, 8, 15)
+#define MASK_OP_SB_DISP8_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 8, 15)
+
+#define MASK_OP_SBC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
+#define MASK_OP_SBC_DISP4(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SBR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBR_DISP4(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SBRN_N(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBRN_DISP4(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SC_CONST8(op)  MASK_BITS_SHIFT(op, 8, 15)
+
+#define MASK_OP_SLR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SLR_D(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SLRO_OFF4(op)  MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SLRO_D(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SR_OP2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SR_S1D(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
+#define MASK_OP_SRC_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRO_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRO_OFF4(op)   MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRR_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRRS_S2(op)MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRRS_S1D(op)   MASK_BITS_SHIFT(op, 8, 11)
+#define MASK_OP_SRRS_N(op) MASK_BITS_SHIFT(op, 6, 7)
+
+#define MASK_OP_SSR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SSR_S1(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SSRO_OFF4(op)  MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SSRO_S1(op)MASK_BITS_SHIFT(op, 8, 11)
+
+/* 32-Bit Formats */
+
+/* ABS Format */
+#define MASK_OP_ABS_OFF18(op)  (MASK_BITS_SHIFT(op, 16, 21) +   \
+   (MASK_BITS_SHIFT(op, 28, 31) << 6) + \
+   (MASK_BITS_SHIFT(op, 22, 25) << 10) +\
+   (MASK_BITS_SHIFT(op, 12, 15) << 14))
+#define MASK_OP_ABS_OP2(op)MASK_BITS_SHIFT(op, 26, 27)
+#define MASK_OP_ABS_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+/* ABSB Format */
+#define MASK_OP_ABSB_OFF18(op) MASK_OP_ABS_OFF18(op)
+#define MASK_OP_ABSB_OP2(op)   MASK_BITS_SHIFT(op, 26, 27)
+#define MASK_OP_ABSB_B(op) MASK_BITS_SHIFT(op, 11, 11)
+#define MASK_OP_ABSB_BPOS(op)  MASK_BITS_SHIFT(op, 7, 10)
+
+/* B Format   */
+#define MASK_OP_B_DISP24(op)   (MASK_BITS_SHIFT(op, 16, 31) + \
+   (MASK_BITS_SHIFT(op, 8, 15) << 16))
+/* BIT Format */
+#define MASK_OP_BIT_D(op)  MASK_BITS_SHIFT(op, 28, 31)
+#define

[Qemu-devel] [PATCH v6 04/15] target-tricore: Add initialization for translation and activate target

2014-08-22 Thread Bastian Koppelmann
Add tcg and cpu model initialization.
Add gen_intermediate_code function.
Activate target in configure and add softmmu config.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 configure   |   5 ++
 default-configs/tricore-softmmu.mak |   3 +
 target-tricore/translate.c  | 165 
 3 files changed, 173 insertions(+)
 create mode 100644 default-configs/tricore-softmmu.mak

diff --git a/configure b/configure
index 283c71c..009aac8 100755
--- a/configure
+++ b/configure
@@ -5008,6 +5008,9 @@ case "$target_name" in
 TARGET_BASE_ARCH=mips
 echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
   ;;
+  tricore)
+target_phys_bits=32
+  ;;
   moxie)
   ;;
   or32)
@@ -5205,6 +5208,8 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
 echo "CONFIG_MIPS_DIS=y"  >> $config_target_mak
 echo "CONFIG_MIPS_DIS=y"  >> config-all-disas.mak
   ;;
+  tricore*)
+  ;;
   moxie*)
 echo "CONFIG_MOXIE_DIS=y"  >> $config_target_mak
 echo "CONFIG_MOXIE_DIS=y"  >> config-all-disas.mak
diff --git a/default-configs/tricore-softmmu.mak 
b/default-configs/tricore-softmmu.mak
new file mode 100644
index 000..48ccd12
--- /dev/null
+++ b/default-configs/tricore-softmmu.mak
@@ -0,0 +1,3 @@
+include pci.mak
+CONFIG_PFLASH_CFI01=y
+CONFIG_SMC91C111=y
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 5bb212d..431968b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,26 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+/*
+ * TCG registers
+ */
+static TCGv cpu_PC;
+static TCGv cpu_PCXI;
+static TCGv cpu_PSW;
+static TCGv cpu_ICR;
+/* GPR registers */
+static TCGv cpu_gpr_a[16];
+static TCGv cpu_gpr_d[16];
+/* PSW Flag cache */
+static TCGv cpu_PSW_C;
+static TCGv cpu_PSW_V;
+static TCGv cpu_PSW_SV;
+static TCGv cpu_PSW_AV;
+static TCGv cpu_PSW_SAV;
+/* CPU env */
+static TCGv_ptr cpu_env;
+
+#include "exec/gen-icount.h"
 
 static const char *regnames_a[] = {
   "a0"  , "a1"  , "a2"  , "a3" , "a4"  , "a5" ,
@@ -39,6 +59,25 @@ static const char *regnames_d[] = {
   "d12" , "d13" , "d14" , "d15",
 };
 
+typedef struct DisasContext {
+struct TranslationBlock *tb;
+target_ulong pc, saved_pc, next_pc;
+uint32_t opcode;
+int singlestep_enabled;
+/* Routine used to access memory */
+int mem_idx;
+uint32_t hflags, saved_hflags;
+int bstate;
+} DisasContext;
+
+enum {
+
+BS_NONE   = 0,
+BS_STOP   = 1,
+BS_BRANCH = 2,
+BS_EXCP   = 3,
+};
+
 void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 fprintf_function cpu_fprintf, int flags)
 {
@@ -62,10 +101,88 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 
 }
 
+static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
+{
+}
+
+static void decode_32Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
+{
+}
+
+static void decode_opc(CPUTRICOREState *env, DisasContext *ctx, int *is_branch)
+{
+/* 16-Bit Instruction */
+if ((ctx->opcode & 0x1) == 0) {
+ctx->next_pc = ctx->pc + 2;
+decode_16Bit_opc(env, ctx);
+/* 32-Bit Instruction */
+} else {
+ctx->next_pc = ctx->pc + 4;
+decode_32Bit_opc(env, ctx);
+}
+}
+
 static inline void
 gen_intermediate_code_internal(TRICORECPU *cpu, struct TranslationBlock *tb,
   int search_pc)
 {
+CPUState *cs = CPU(cpu);
+CPUTRICOREState *env = &cpu->env;
+DisasContext ctx;
+target_ulong pc_start;
+int num_insns;
+uint16_t *gen_opc_end;
+
+if (search_pc) {
+qemu_log("search pc %d\n", search_pc);
+}
+
+num_insns = 0;
+pc_start = tb->pc;
+gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
+ctx.pc = pc_start;
+ctx.saved_pc = -1;
+ctx.tb = tb;
+ctx.singlestep_enabled = cs->singlestep_enabled;
+ctx.bstate = BS_NONE;
+ctx.mem_idx = cpu_mmu_index(env);
+
+tcg_clear_temp_count();
+gen_tb_start();
+while (ctx.bstate == BS_NONE) {
+ctx.opcode = cpu_ldl_code(env, ctx.pc);
+decode_opc(env, &ctx, 0);
+
+num_insns++;
+
+if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
+break;
+}
+if (singlestep) {
+break;
+}
+ctx.pc = ctx.next_pc;
+}
+
+gen_tb_end(tb, num_insns);
+*tcg_ctx.gen_opc_ptr = INDEX_op_end;
+if (search_pc) {
+printf("done_generating search pc\n");
+} else {
+tb->size = ctx.pc - pc_start;
+tb->icount = num_insns;
+}
+if (tcg_check_temp_count()) {
+printf("LEAK at %08x\n", env->PC);
+}
+
+#if

[Qemu-devel] [PATCH v6 03/15] target-tricore: Add softmmu support

2014-08-22 Thread Bastian Koppelmann
Add basic softmmu support for TriCore

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- get_physical_address: Add PAGE_EXEC permission.

 target-tricore/helper.c| 54 +-
 target-tricore/op_helper.c | 33 +++-
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index 7d8fc30..24fabf3 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -24,10 +24,62 @@
 
 #include "cpu.h"
 
+enum {
+TLBRET_DIRTY = -4,
+TLBRET_INVALID = -3,
+TLBRET_NOMATCH = -2,
+TLBRET_BADADDR = -1,
+TLBRET_MATCH = 0
+};
+
+#if defined(CONFIG_SOFTMMU)
+static int get_physical_address(CPUTRICOREState *env, hwaddr *physical,
+int *prot, target_ulong address,
+int rw, int access_type)
+{
+int ret = TLBRET_MATCH;
+
+*physical = address & 0x;
+*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+
+return ret;
+}
+#endif
+
+/* TODO: Add exeption support*/
+static void raise_mmu_exception(CPUTRICOREState *env, target_ulong address,
+int rw, int tlb_error)
+{
+}
+
 int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address,
  int rw, int mmu_idx)
 {
-return 0;
+TRICORECPU *cpu = TRICORE_CPU(cs);
+CPUTRICOREState *env = &cpu->env;
+hwaddr physical;
+int prot;
+int access_type;
+int ret = 0;
+
+rw &= 1;
+access_type = ACCESS_INT;
+ret = get_physical_address(env, &physical, &prot,
+   address, rw, access_type);
+qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx
+ " prot %d\n", __func__, address, ret, physical, prot);
+
+if (ret == TLBRET_MATCH) {
+tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ mmu_idx, TARGET_PAGE_SIZE);
+ret = 0;
+} else if (ret < 0) {
+raise_mmu_exception(env, address, rw, ret);
+ret = 1;
+}
+
+return ret;
 }
 
 void tricore_cpu_do_interrupt(CPUState *cs)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 275790b..2e5981f 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,8 +20,39 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env,
+uint32_t exception,
+int error_code,
+uintptr_t pc)
+{
+CPUState *cs = CPU(tricore_env_get_cpu(env));
+cs->exception_index = exception;
+env->error_code = error_code;
+
+if (pc) {
+/* now we have a real cpu fault */
+cpu_restore_state(cs, pc);
+}
+
+cpu_loop_exit(cs);
+}
+
+static inline void QEMU_NORETURN do_raise_exception(CPUTRICOREState *env,
+uint32_t exception,
+uintptr_t pc)
+{
+do_raise_exception_err(env, exception, 0, pc);
+}
+
 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
   uintptr_t retaddr)
 {
+int ret;
+ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
+if (ret) {
+TRICORECPU *cpu = TRICORE_CPU(cs);
+CPUTRICOREState *env = &cpu->env;
+do_raise_exception_err(env, cs->exception_index,
+   env->error_code, retaddr);
+}
 }
-
-- 
2.1.0




[Qemu-devel] [PATCH v6 02/15] target-tricore: Add board for systemmode

2014-08-22 Thread Bastian Koppelmann
Add basic board to allow systemmode emulation

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- tricore_testboard: Fix machine name containing blanks.

 hw/tricore/Makefile.objs   |   1 +
 hw/tricore/tricore_testboard.c | 129 +
 include/hw/tricore/tricore.h   |  54 +
 3 files changed, 184 insertions(+)
 create mode 100644 hw/tricore/Makefile.objs
 create mode 100644 hw/tricore/tricore_testboard.c
 create mode 100644 include/hw/tricore/tricore.h

diff --git a/hw/tricore/Makefile.objs b/hw/tricore/Makefile.objs
new file mode 100644
index 000..435e095
--- /dev/null
+++ b/hw/tricore/Makefile.objs
@@ -0,0 +1 @@
+obj-y += tricore_testboard.o
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
new file mode 100644
index 000..04c0f89
--- /dev/null
+++ b/hw/tricore/tricore_testboard.c
@@ -0,0 +1,129 @@
+/*
+ * TriCore Baseboard System emulation.
+ *
+ * Copyright (c) 2014 Bastian Koppelmann
+ *
+ * This code is licensed under the GPL.
+ */
+
+#include "hw/hw.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "sysemu/blockdev.h"
+#include "exec/address-spaces.h"
+#include "hw/block/flash.h"
+#include "elf.h"
+#include "hw/tricore/tricore.h"
+
+#define TRICORE_FLASH_ADDR 0xa000
+#define TRICORE_FLASH_SIZE (2 * 1024 * 1024)
+#define TRICORE_FLASH_SECT_SIZE (256 * 1024)
+
+
+/* Board init.  */
+
+static struct tricore_boot_info tricoretb_binfo;
+
+static void tricore_load_kernel(CPUTRICOREState *env)
+{
+int64_t entry;
+long kernel_size;
+
+kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL,
+   NULL, (uint64_t *)&entry, NULL,
+   NULL, 0,
+   ELF_MACHINE, 1);
+if (kernel_size <= 0) {
+fprintf(stderr, "qemu: no kernel file '%s'\n",
+tricoretb_binfo.kernel_filename);
+exit(1);
+}
+env->PC = entry;
+
+}
+
+static void tricore_testboard_init(MachineState *machine, int board_id)
+{
+TRICORECPU *cpu;
+CPUTRICOREState *env;
+
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ext_cram = g_new(MemoryRegion, 1);
+MemoryRegion *ext_dram = g_new(MemoryRegion, 1);
+MemoryRegion *int_cram = g_new(MemoryRegion, 1);
+MemoryRegion *int_dram = g_new(MemoryRegion, 1);
+MemoryRegion *pcp_data = g_new(MemoryRegion, 1);
+MemoryRegion *pcp_text = g_new(MemoryRegion, 1);
+DriveInfo *dinfo;
+
+if (!machine->cpu_model) {
+machine->cpu_model = "tc1796";
+}
+cpu = cpu_tricore_init(machine->cpu_model);
+env = &cpu->env;
+if (!cpu) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram", 2*1024*1024);
+vmstate_register_ram_global(ext_cram);
+memory_region_init_ram(ext_dram, NULL, "powerlink_ext_d.ram", 4*1024*1024);
+vmstate_register_ram_global(ext_dram);
+memory_region_init_ram(int_cram, NULL, "powerlink_int_c.ram", 48*1024);
+vmstate_register_ram_global(int_cram);
+memory_region_init_ram(int_dram, NULL, "powerlink_int_d.ram", 48*1024);
+vmstate_register_ram_global(int_dram);
+memory_region_init_ram(pcp_data, NULL, "powerlink_pcp_data.ram", 16*1024);
+vmstate_register_ram_global(pcp_data);
+memory_region_init_ram(pcp_text, NULL, "powerlink_pcp_text.ram", 32*1024);
+vmstate_register_ram_global(pcp_text);
+
+memory_region_add_subregion(sysmem, 0x8000, ext_cram);
+memory_region_add_subregion(sysmem, 0xa100, ext_dram);
+memory_region_add_subregion(sysmem, 0xd400, int_cram);
+memory_region_add_subregion(sysmem, 0xd000, int_dram);
+memory_region_add_subregion(sysmem, 0xf005, pcp_data);
+memory_region_add_subregion(sysmem, 0xf006, pcp_text);
+
+dinfo = drive_get(IF_PFLASH, 0, 0);
+if (!pflash_cfi01_register(TRICORE_FLASH_ADDR, NULL,
+  "tricore_testboard.flash",
+  TRICORE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+  TRICORE_FLASH_SECT_SIZE,
+  TRICORE_FLASH_SIZE / TRICORE_FLASH_SECT_SIZE,
+  2, 0x00, 0x00, 0x, 0x0, 0)) {
+
+fprintf(stderr, "qemu: Error registering flash memory.\n");
+} else {
+env->PC = TRICORE_FLASH_ADDR;
+}
+
+tricoretb_binfo.ram_size = machine->ram_size;
+tricoretb_binfo.kernel_filename = machine->kernel_filename;
+
+if (machine->kernel_filename) {
+tricore_load_kernel(env);
+}
+}
+
+static 

[Qemu-devel] [PATCH v6 06/15] target-tricore: Add instructions of SRC opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SRC opcode format.
Add micro-op generator functions for add, conditional add/sub and shi/shai.

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- gen_shaci: Add calculation of PSW.C to shift_count = -32 case.
- Remove useless parenthesis.

 target-tricore/helper.h|  16 +++
 target-tricore/translate.c | 251 +
 2 files changed, 267 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index e69de29..5884240 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index ec4d80b..12d8277 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -27,6 +27,7 @@
 #include "exec/helper-gen.h"
 
 #include "tricore-opcodes.h"
+
 /*
  * TCG registers
  */
@@ -102,8 +103,258 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 
 }
 
+/*
+ * Functions to generate micro-ops
+ */
+
+/* Functions for arithmetic instructions  */
+
+static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
+{
+TCGv t0 = tcg_temp_new_i32();
+TCGv result = tcg_temp_new_i32();
+/* Addition and set V/SV bits */
+tcg_gen_add_tl(result, r1, r2);
+/* 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_d(TCGv ret, TCGv r1, target_ulong r2)
+{
+TCGv temp = tcg_const_i32(r2);
+gen_add_d(ret, r1, temp);
+tcg_temp_free(temp);
+}
+
+static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
+TCGv r4)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+TCGv result = tcg_temp_new();
+TCGv mask = tcg_temp_new();
+TCGv t0 = tcg_const_i32(0);
+
+/* create mask for sticky bits */
+tcg_gen_setcond_tl(cond, mask, r4, t0);
+tcg_gen_shli_tl(mask, mask, 31);
+
+tcg_gen_add_tl(result, r1, r2);
+/* Calc PSW_V */
+tcg_gen_xor_tl(temp, result, r1);
+tcg_gen_xor_tl(temp2, r1, r2);
+tcg_gen_andc_tl(temp, temp, temp2);
+tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
+/* Set PSW_SV */
+tcg_gen_and_tl(temp, temp, mask);
+tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
+/* calc AV bit */
+tcg_gen_add_tl(temp, result, result);
+tcg_gen_xor_tl(temp, temp, result);
+tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
+/* calc SAV bit */
+tcg_gen_and_tl(temp, temp, mask);
+tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
+/* write back result */
+tcg_gen_movcond_tl(cond, r3, r4, t0, result, r3);
+
+tcg_temp_free(t0);
+tcg_temp_free(temp);
+tcg_temp_free(temp2);
+tcg_temp_free(result);
+tcg_temp_free(mask);
+}
+
+static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2,
+ TCGv r3, TCGv r4)
+{
+TCGv temp = tcg_const_i32(r2);
+gen_cond_add(cond, r1, temp, r3, r4);
+tcg_temp_free(temp);
+}
+
+static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
+{
+if (shift_count == -32) {
+tcg_gen_movi_tl(ret, 0);
+} else if (shift_count >= 0) {
+tcg_gen_shli_tl(ret, r1, shift_count);
+} else {
+tcg_gen_shri_tl(ret, r1, -shift_count);
+}
+}
+
+static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
+{
+uint32_t msk, msk_start;
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+TCGv t_0 = tcg_const_i32(0);
+
+if (shift_count == 0) {
+/* Clear PSW.C and PSW.V */
+tcg_gen_movi_tl(cpu_PSW_C, 0);
+tcg_gen_mov_tl(cpu_PSW_V, cpu_PSW_C);
+tcg_gen_mov_tl(ret, r1);
+} else if (shift_count

[Qemu-devel] [PATCH v6 11/15] target-tricore: Add instructions of SBC and SBRN opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SBC and SBRN opcode format.

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- SBC_JEQ: Negate condition.

 target-tricore/translate.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 008aa43..3ca3211 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -391,6 +391,8 @@ static inline void gen_branch_condi(DisasContext *ctx, 
TCGCond cond, TCGv r1,
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
+TCGv temp;
+
 switch (opc) {
 /* SB-format jumps */
 case OPC1_16_SB_J:
@@ -407,6 +409,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_16_SB_JNZ:
 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
 break;
+/* SBC-format jumps */
+case OPC1_16_SBC_JEQ:
+gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
+break;
+case OPC1_16_SBC_JNE:
+gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
+break;
+/* SBRN-format jumps */
+case OPC1_16_SBRN_JZ_T:
+temp = tcg_temp_new();
+tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
+gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
+tcg_temp_free(temp);
+break;
+case OPC1_16_SBRN_JNZ_T:
+temp = tcg_temp_new();
+tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
+gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
+tcg_temp_free(temp);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -716,6 +738,20 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
 gen_compute_branch(ctx, op1, 0, 0, 0, address);
 break;
+/* SBC-format */
+case OPC1_16_SBC_JEQ:
+case OPC1_16_SBC_JNE:
+address = MASK_OP_SBC_DISP4(ctx->opcode);
+const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+break;
+/* SBRN-format */
+case OPC1_16_SBRN_JNZ_T:
+case OPC1_16_SBRN_JZ_T:
+address = MASK_OP_SBRN_DISP4(ctx->opcode);
+const16 = MASK_OP_SBRN_N(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+break;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v6 10/15] target-tricore: Add instructions of SB opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SB opcode format.
Add helper call/ret.
Add micro-op generator functions for branches.
Add makro to generate helper functions.

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- gen_intermediate_code_internal: Replace gen_goto_tb with setting of 
next_pc and exit_tb(0).

 target-tricore/helper.h|   3 +
 target-tricore/op_helper.c | 180 +
 target-tricore/translate.c |  93 +++
 3 files changed, 276 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 299bd77..adf5b26 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -18,3 +18,6 @@
 /* Arithmetic */
 DEF_HELPER_3(add_ssov, i32, env, i32, i32)
 DEF_HELPER_3(sub_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 3c83945..bdcb2c4 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -63,6 +63,186 @@ target_ulong helper_sub_ssov(CPUTRICOREState *env, 
target_ulong r1,
 return ret;
 }
 
+/* context save area (CSA) related helpers */
+
+static int cdc_increment(target_ulong *psw)
+{
+if ((*psw & MASK_PSW_CDC) == 0x7f) {
+return 0;
+}
+
+(*psw)++;
+/* check for overflow */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+if (count == 0) {
+(*psw)--;
+return 1;
+}
+return 0;
+}
+
+static int cdc_decrement(target_ulong *psw)
+{
+if ((*psw & MASK_PSW_CDC) == 0x7f) {
+return 0;
+}
+/* check for underflow */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+if (count == 0) {
+return 1;
+}
+(*psw)--;
+return 0;
+}
+
+static void save_context_upper(CPUTRICOREState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[10]);
+cpu_stl_data(env, ea+12, env->gpr_a[11]);
+cpu_stl_data(env, ea+16, env->gpr_d[8]);
+cpu_stl_data(env, ea+20, env->gpr_d[9]);
+cpu_stl_data(env, ea+24, env->gpr_d[10]);
+cpu_stl_data(env, ea+28, env->gpr_d[11]);
+cpu_stl_data(env, ea+32, env->gpr_a[12]);
+cpu_stl_data(env, ea+36, env->gpr_a[13]);
+cpu_stl_data(env, ea+40, env->gpr_a[14]);
+cpu_stl_data(env, ea+44, env->gpr_a[15]);
+cpu_stl_data(env, ea+48, env->gpr_d[12]);
+cpu_stl_data(env, ea+52, env->gpr_d[13]);
+cpu_stl_data(env, ea+56, env->gpr_d[14]);
+cpu_stl_data(env, ea+60, env->gpr_d[15]);
+
+}
+
+static void restore_context_upper(CPUTRICOREState *env, int ea,
+  target_ulong *new_PCXI, target_ulong 
*new_PSW)
+{
+*new_PCXI = cpu_ldl_data(env, ea);
+*new_PSW = cpu_ldl_data(env, ea+4);
+env->gpr_a[10] = cpu_ldl_data(env, ea+8);
+env->gpr_a[11] = cpu_ldl_data(env, ea+12);
+env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
+env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
+env->gpr_d[10] = cpu_ldl_data(env, ea+24);
+env->gpr_d[11] = cpu_ldl_data(env, ea+28);
+env->gpr_a[12] = cpu_ldl_data(env, ea+32);
+env->gpr_a[13] = cpu_ldl_data(env, ea+36);
+env->gpr_a[14] = cpu_ldl_data(env, ea+40);
+env->gpr_a[15] = cpu_ldl_data(env, ea+44);
+env->gpr_d[12] = cpu_ldl_data(env, ea+48);
+env->gpr_d[13] = cpu_ldl_data(env, ea+52);
+env->gpr_d[14] = cpu_ldl_data(env, ea+56);
+env->gpr_d[15] = cpu_ldl_data(env, ea+60);
+cpu_stl_data(env, ea, env->FCX);
+}
+
+void helper_call(CPUTRICOREState *env, uint32_t next_pc)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+target_ulong psw;
+
+psw = psw_read(env);
+/* if (FCX == 0) trap(FCU); */
+if (env->FCX == 0) {
+/* FCU trap */
+}
+/* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
+if (psw & MASK_PSW_CDE) {
+if (cdc_increment(&psw)) {
+/* CDO trap */
+}
+}
+/* PSW.CDE = 1;*/
+psw |= MASK_PSW_CDE;
+/* tmp_FCX = FCX; */
+tmp_FCX = env->FCX;
+/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
+ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
+ ((env->FCX & MASK_FCX_FCXO) << 6);
+/* new_FCX = M(EA, word);
+   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+  D[15]}; */
+save_context_upper(env, ea, &new_FCX);
+
+/* PCXI.PCPN = ICR.CCPN; */
+env->PCXI = (env

[Qemu-devel] [PATCH v6 09/15] target-tricore: Add instructions of SRRS and SLRO opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SSRS and SLRO opcode format.
Add micro-op generator functions for offset loads.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 59 ++
 1 file changed, 59 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 9ba90c4..64ad4ec 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -107,6 +107,26 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
  * Functions to generate micro-ops
  */
 
+/* Functions for load/save to/from memory */
+
+static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
+ int16_t con, TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, con);
+tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
+tcg_temp_free(temp);
+}
+
+static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2,
+ int16_t con, TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, con);
+tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
+tcg_temp_free(temp);
+}
+
 /* Functions for arithmetic instructions  */
 
 static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
@@ -513,9 +533,17 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
 {
 int op1;
+int r1, r2;
+int32_t const16;
+TCGv temp;
 
 op1 = MASK_OP_MAJOR(ctx->opcode);
 
+/* handle ADDSC.A opcode only being 6 bit long */
+if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
+op1 = OPC1_16_SRRS_ADDSC_A;
+}
+
 switch (op1) {
 case OPC1_16_SRC_ADD:
 case OPC1_16_SRC_ADD_A15:
@@ -568,6 +596,37 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 case OPC1_16_SSR_ST_W_POSTINC:
 decode_ssr_opc(ctx, op1);
 break;
+/* SRRS-format */
+case OPC1_16_SRRS_ADDSC_A:
+r2 = MASK_OP_SRRS_S2(ctx->opcode);
+r1 = MASK_OP_SRRS_S1D(ctx->opcode);
+const16 = MASK_OP_SRRS_N(ctx->opcode);
+temp = tcg_temp_new();
+tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
+tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
+tcg_temp_free(temp);
+break;
+/* SLRO-format */
+case OPC1_16_SLRO_LD_A:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SLRO_LD_BU:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
+break;
+case OPC1_16_SLRO_LD_H:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
+break;
+case OPC1_16_SLRO_LD_W:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v6 07/15] target-tricore: Add instructions of SRR opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SRR opcode format.
Add helper for add/sub_ssov.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h|   4 ++
 target-tricore/op_helper.c |  43 
 target-tricore/translate.c | 164 +
 3 files changed, 211 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 5884240..299bd77 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -14,3 +14,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+
+/* Arithmetic */
+DEF_HELPER_3(add_ssov, i32, env, i32, i32)
+DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 2e5981f..3c83945 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,49 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+#define SSOV(env, ret, arg, len) do {   \
+int64_t max_pos = INT##len ##_MAX;  \
+int64_t max_neg = INT##len ##_MIN;  \
+if (arg > max_pos) {\
+env->PSW_USB_V = (1 << 31); \
+env->PSW_USB_SV = (1 << 31);\
+ret = (target_ulong)max_pos;\
+} else {\
+if (arg < max_neg) {\
+env->PSW_USB_V = (1 << 31); \
+env->PSW_USB_SV = (1 << 31);\
+ret = (target_ulong)max_neg;\
+} 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)
+{
+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_sub_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;
+}
+
 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 12d8277..eab2d6c 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -187,6 +187,53 @@ static inline void gen_condi_add(TCGCond cond, TCGv r1, 
int32_t r2,
 tcg_temp_free(temp);
 }
 
+static inline void gen_sub_d(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);
+/* calc V bit */
+tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+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_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
+{
+TCGv high = tcg_temp_new();
+TCGv low = tcg_temp_new();
+
+tcg_gen_muls2_tl(low, high, r1, r2);
+tcg_gen_mov_tl(ret, low);
+/* calc V bit */
+tcg_gen_sari_tl(low, low, 31);
+tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
+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 bit */
+tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+/* calc SAV bit */
+tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+tcg_temp_free(high);
+tcg_temp_free(low);
+}
+
 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
 {
 if (shift_count == -32) {
@@ -257,6 +304,16 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t 
shift_count)
 tcg_temp_free(t_0);
 }
 
+static inline void gen_adds(TCGv ret, TCGv r1, TCGv

[Qemu-devel] [PATCH v6 15/15] target-tricore: Add instructions of SR opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SR opcode format.
Add micro-op generator functions for saturate.
Add helper return from exception (rfe).

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- Fix formating.

 target-tricore/helper.h|   1 +
 target-tricore/op_helper.c |  52 +
 target-tricore/translate.c | 111 +
 3 files changed, 164 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 3c73234..7b7d74b 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -22,3 +22,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
+DEF_HELPER_1(rfe, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 4ea94d8..4174ef9 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -99,6 +99,21 @@ static int cdc_decrement(target_ulong *psw)
 return 0;
 }
 
+static bool cdc_zero(target_ulong *psw)
+{
+int cdc = *psw & MASK_PSW_CDC;
+/* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
+   7'b111, otherwise returns FALSE. */
+if (cdc == 0x7f) {
+return true;
+}
+/* find CDC.COUNT */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+return count == 0;
+}
+
 static void save_context_upper(CPUTRICOREState *env, int ea,
target_ulong *new_FCX)
 {
@@ -302,6 +317,43 @@ void helper_bisr(CPUTRICOREState *env, uint32_t const9)
 }
 }
 
+void helper_rfe(CPUTRICOREState *env)
+{
+target_ulong ea;
+target_ulong new_PCXI;
+target_ulong new_PSW;
+/* if (PCXI[19: 0] == 0) then trap(CSU); */
+if ((env->PCXI & 0xf) == 0) {
+/* raise csu trap */
+}
+/* if (PCXI.UL == 0) then trap(CTYP); */
+if ((env->PCXI & MASK_PCXI_UL) == 0) {
+/* raise CTYP trap */
+}
+/* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
+if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
+/* raise MNG trap */
+}
+/* ICR.IE = PCXI.PIE; */
+env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
+/* ICR.CCPN = PCXI.PCPN; */
+env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
+   ((env->PCXI & MASK_PCXI_PCPN) >> 24);
+/*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
+ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
+ ((env->PCXI & MASK_PCXI_PCXO) << 6);
+/*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
+  M(EA, word) = FCX;*/
+restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* FCX[19: 0] = PCXI[19: 0]; */
+env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
+/* PCXI = new_PCXI; */
+env->PCXI = new_PCXI;
+/* write psw */
+psw_write(env, new_PSW);
+}
+
 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 40d41c5..0124f99 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -262,6 +262,29 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
 tcg_temp_free(low);
 }
 
+static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
+{
+TCGv sat_neg = tcg_const_i32(low);
+TCGv temp = tcg_const_i32(up);
+
+/* sat_neg = (arg < low ) ? low : arg; */
+tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
+
+/* ret = (sat_neg > up ) ? up  : sat_neg; */
+tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+
+tcg_temp_free(sat_neg);
+tcg_temp_free(temp);
+}
+
+static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
+{
+TCGv temp = tcg_const_i32(up);
+/* sat_neg = (arg > up ) ? up : arg; */
+tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+tcg_temp_free(temp);
+}
+
 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
 {
 if (shift_count == -32) {
@@ -477,6 +500,15 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_16_SBR_LOOP:
 gen_loop(ctx, r1, offset * 2 - 32);
 break;
+/* SR-format jumps */
+case OPC1_16_SR_JI:
+tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffe);
+tcg_gen_exit_tb(0);
+break;
+case OPC2_16_SR_RET:
+gen_helper_ret(cpu_env);
+tcg_gen_exit_tb(0);
+break;
 default:
 printf("Branch Error at %x\n",

[Qemu-devel] [PATCH v6 08/15] target-tricore: Add instructions of SSR opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SSR opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index eab2d6c..9ba90c4 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -471,6 +471,45 @@ static void decode_srr_opc(DisasContext *ctx, int op1)
 }
 }
 
+static void decode_ssr_opc(DisasContext *ctx, int op1)
+{
+int r1, r2;
+
+r1 = MASK_OP_SSR_S1(ctx->opcode);
+r2 = MASK_OP_SSR_S2(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SSR_ST_A:
+tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+break;
+case OPC1_16_SSR_ST_A_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+case OPC1_16_SSR_ST_B:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+break;
+case OPC1_16_SSR_ST_B_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
+break;
+case OPC1_16_SSR_ST_H:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUW);
+break;
+case OPC1_16_SSR_ST_H_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
+break;
+case OPC1_16_SSR_ST_W:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+break;
+case OPC1_16_SSR_ST_W_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+}
+}
+
 static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
 {
 int op1;
@@ -518,6 +557,17 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 case OPC1_16_SRR_XOR:
 decode_srr_opc(ctx, op1);
 break;
+/* SSR-format */
+case OPC1_16_SSR_ST_A:
+case OPC1_16_SSR_ST_A_POSTINC:
+case OPC1_16_SSR_ST_B:
+case OPC1_16_SSR_ST_B_POSTINC:
+case OPC1_16_SSR_ST_H:
+case OPC1_16_SSR_ST_H_POSTINC:
+case OPC1_16_SSR_ST_W:
+case OPC1_16_SSR_ST_W_POSTINC:
+decode_ssr_opc(ctx, op1);
+break;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v6 14/15] target-tricore: Add instructions of SLR, SSRO and SRO opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SLR, SSRO and SRO opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 121 +
 1 file changed, 121 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index e0674fa..40d41c5 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -716,6 +716,84 @@ static void decode_sc_opc(DisasContext *ctx, int op1)
 break;
 }
 }
+
+static void decode_slr_opc(DisasContext *ctx, int op1)
+{
+int r1, r2;
+
+r1 = MASK_OP_SLR_D(ctx->opcode);
+r2 = MASK_OP_SLR_S2(ctx->opcode);
+
+switch (op1) {
+/* SLR-format */
+case OPC1_16_SLR_LD_A:
+tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESL);
+break;
+case OPC1_16_SLR_LD_A_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+case OPC1_16_SLR_LD_BU:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+break;
+case OPC1_16_SLR_LD_BU_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
+break;
+case OPC1_16_SLR_LD_H:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+break;
+case OPC1_16_SLR_LD_H_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
+break;
+case OPC1_16_SLR_LD_W:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+break;
+case OPC1_16_SLR_LD_W_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+}
+}
+
+static void decode_sro_opc(DisasContext *ctx, int op1)
+{
+int r2;
+int32_t address;
+
+r2 = MASK_OP_SRO_S2(ctx->opcode);
+address = MASK_OP_SRO_OFF4(ctx->opcode);
+
+/* SRO-format */
+switch (op1) {
+case OPC1_16_SRO_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_LD_BU:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
+break;
+case OPC1_16_SRO_LD_H:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW);
+break;
+case OPC1_16_SRO_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_ST_B:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
+break;
+case OPC1_16_SRO_ST_H:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
+break;
+case OPC1_16_SRO_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+}
+}
+
 static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
 {
 int op1;
@@ -864,6 +942,49 @@ static void decode_16Bit_opc(CPUTRICOREState *env, 
DisasContext *ctx)
 case OPC1_16_SC_SUB_A:
 decode_sc_opc(ctx, op1);
 break;
+/* SLR-format */
+case OPC1_16_SLR_LD_A:
+case OPC1_16_SLR_LD_A_POSTINC:
+case OPC1_16_SLR_LD_BU:
+case OPC1_16_SLR_LD_BU_POSTINC:
+case OPC1_16_SLR_LD_H:
+case OPC1_16_SLR_LD_H_POSTINC:
+case OPC1_16_SLR_LD_W:
+case OPC1_16_SLR_LD_W_POSTINC:
+decode_slr_opc(ctx, op1);
+break;
+/* SRO-format */
+case OPC1_16_SRO_LD_A:
+case OPC1_16_SRO_LD_BU:
+case OPC1_16_SRO_LD_H:
+case OPC1_16_SRO_LD_W:
+case OPC1_16_SRO_ST_A:
+case OPC1_16_SRO_ST_B:
+case OPC1_16_SRO_ST_H:
+case OPC1_16_SRO_ST_W:
+decode_sro_opc(ctx, op1);
+break;
+/* SSRO-format */
+case OPC1_16_SSRO_ST_A:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SSRO_ST_B:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
+break;
+case OPC1_16_SSRO_ST_H:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
+break;
+case OPC1_16_SSRO_ST_W:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr

[Qemu-devel] [PATCH v6 13/15] target-tricore: Add instructions of SC opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SC opcode format.
Add helper for begin interrupt service routine.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h|  1 +
 target-tricore/op_helper.c | 59 ++
 target-tricore/translate.c | 48 +
 3 files changed, 108 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index adf5b26..3c73234 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -21,3 +21,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 /* CSA */
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
+DEF_HELPER_2(bisr, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index bdcb2c4..4ea94d8 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -122,6 +122,28 @@ static void save_context_upper(CPUTRICOREState *env, int 
ea,
 
 }
 
+static void save_context_lower(CPUTRICOREState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[2]);
+cpu_stl_data(env, ea+12, env->gpr_a[3]);
+cpu_stl_data(env, ea+16, env->gpr_d[0]);
+cpu_stl_data(env, ea+20, env->gpr_d[1]);
+cpu_stl_data(env, ea+24, env->gpr_d[2]);
+cpu_stl_data(env, ea+28, env->gpr_d[3]);
+cpu_stl_data(env, ea+32, env->gpr_a[4]);
+cpu_stl_data(env, ea+36, env->gpr_a[5]);
+cpu_stl_data(env, ea+40, env->gpr_a[6]);
+cpu_stl_data(env, ea+44, env->gpr_a[7]);
+cpu_stl_data(env, ea+48, env->gpr_d[4]);
+cpu_stl_data(env, ea+52, env->gpr_d[5]);
+cpu_stl_data(env, ea+56, env->gpr_d[6]);
+cpu_stl_data(env, ea+60, env->gpr_d[7]);
+}
+
 static void restore_context_upper(CPUTRICOREState *env, int ea,
   target_ulong *new_PCXI, target_ulong 
*new_PSW)
 {
@@ -243,6 +265,43 @@ void helper_ret(CPUTRICOREState *env)
 }
 }
 
+void helper_bisr(CPUTRICOREState *env, uint32_t const9)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+
+if (env->FCX == 0) {
+/* FCU trap */
+}
+
+tmp_FCX = env->FCX;
+ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
+
+save_context_lower(env, ea, &new_FCX);
+
+/* PCXI.PCPN = ICR.CCPN */
+env->PCXI = (env->PCXI & 0xff) +
+ ((env->ICR & MASK_ICR_CCPN) << 24);
+/* PCXI.PIE  = ICR.IE */
+env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
+ ((env->ICR & MASK_ICR_IE) << 15));
+/* PCXI.UL = 0 */
+env->PCXI &= ~(MASK_PCXI_UL);
+/* PCXI[19: 0] = FCX[19: 0] */
+env->PCXI = (env->PCXI & 0xfff0) + (env->FCX & 0xf);
+/* FXC[19: 0] = new_FCX[19: 0] */
+env->FCX = (env->FCX & 0xfff0) + (new_FCX & 0xf);
+/* ICR.IE = 1 */
+env->ICR |= MASK_ICR_IE;
+
+env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
+
+if (tmp_FCX == env->LCX) {
+/* FCD trap */
+}
+}
+
 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 d2419ba..e0674fa 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -680,6 +680,42 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 }
 }
 
+static void decode_sc_opc(DisasContext *ctx, int op1)
+{
+int32_t const16;
+
+const16 = MASK_OP_SC_CONST8(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SC_AND:
+tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_BISR:
+gen_helper_1arg(bisr, const16 & 0xff);
+break;
+case OPC1_16_SC_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_MOV:
+tcg_gen_movi_tl(cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_OR:
+tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_SUB_A:
+tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
+break;
+}
+}
 static void decode_16Bit_opc(CPUTRICOREStat

[Qemu-devel] [PATCH v6 12/15] target-tricore: Add instructions of SBR opcode format

2014-08-22 Thread Bastian Koppelmann
Add instructions of SBR opcode format.
Add gen_loop micro-op generator function.

Signed-off-by: Bastian Koppelmann 
---
v5 -> v6:
- SBR_JEQ: Negate condition.

 target-tricore/translate.c | 66 +-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 3ca3211..d2419ba 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -388,6 +388,18 @@ static inline void gen_branch_condi(DisasContext *ctx, 
TCGCond 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_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
+gen_goto_tb(ctx, 1, ctx->pc + offset);
+gen_set_label(l1);
+gen_goto_tb(ctx, 0, ctx->next_pc);
+}
+
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
@@ -429,8 +441,44 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
 tcg_temp_free(temp);
 break;
+/* SBR-format jumps */
+case OPC1_16_SBR_JEQ:
+gen_branch_cond(ctx, TCG_COND_EQ, 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, offset * 2 - 32);
+break;
 default:
-printf("Branch Error at %x\n", ctx->pc);
+printf("Branch Error at %x\n", ctx->pc);
 }
 ctx->bstate = BS_BRANCH;
 }
@@ -752,6 +800,22 @@ 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;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v3 1/5] target-tricore: Cleanup and Bugfixes

2014-10-13 Thread Bastian Koppelmann
Move FCX loading of save_context_ to caller functions, for STLCX, STUCX insn to 
use those functions.
Move FCX storing of restore_context_ to caller functions, for LDLCX, LDUCX insn 
to use those functions.
Remove do_raise_exception function, which caused clang to emit a warning.
Fix: save_context_lower now saves a[11] instead of PSW.
Fix: MASK_OP_ABSB_BPOS starting at wrong offset.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/op_helper.c   | 47 ++--
 target-tricore/tricore-opcodes.h |  2 +-
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 6376f07..f2a5cbc 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -114,10 +114,8 @@ static bool cdc_zero(target_ulong *psw)
 return count == 0;
 }
 
-static void save_context_upper(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_upper(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
 cpu_stl_data(env, ea+4, env->PSW);
 cpu_stl_data(env, ea+8, env->gpr_a[10]);
@@ -134,15 +132,12 @@ static void save_context_upper(CPUTriCoreState *env, int 
ea,
 cpu_stl_data(env, ea+52, env->gpr_d[13]);
 cpu_stl_data(env, ea+56, env->gpr_d[14]);
 cpu_stl_data(env, ea+60, env->gpr_d[15]);
-
 }
 
-static void save_context_lower(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_lower(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
-cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+4, env->gpr_a[11]);
 cpu_stl_data(env, ea+8, env->gpr_a[2]);
 cpu_stl_data(env, ea+12, env->gpr_a[3]);
 cpu_stl_data(env, ea+16, env->gpr_d[0]);
@@ -178,7 +173,6 @@ static void restore_context_upper(CPUTriCoreState *env, int 
ea,
 env->gpr_d[13] = cpu_ldl_data(env, ea+52);
 env->gpr_d[14] = cpu_ldl_data(env, ea+56);
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
-cpu_stl_data(env, ea, env->FCX);
 }
 
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
@@ -206,11 +200,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
 ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
  ((env->FCX & MASK_FCX_FCXO) << 6);
-/* new_FCX = M(EA, word);
-   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
-  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
-  D[15]}; */
-save_context_upper(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+   A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+   D[15]}; */
+save_context_upper(env, ea);
 
 /* PCXI.PCPN = ICR.CCPN; */
 env->PCXI = (env->PCXI & 0xff) +
@@ -263,9 +258,10 @@ void helper_ret(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-M(EA, word) = FCX; */
+A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* M(EA, word) = FCX; */
+cpu_stl_data(env, ea, env->FCX);
 /* FCX[19: 0] = PCXI[19: 0]; */
 env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
 /* PCXI = new_PCXI; */
@@ -293,7 +289,12 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
 tmp_FCX = env->FCX;
 ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
 
-save_context_lower(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], 
A[4]
+   , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
+save_context_lower(env, ea);
+
 
 /* PCXI.PCPN = ICR.CCPN */
 env->PCXI = (env->PCXI & 0xff) +
@@ -343,9 +344,10 @@ void helper_rfe(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-  M(EA, word) = FCX;*/
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = 

[Qemu-devel] [PATCH v3 2/5] target-tricore: Add instructions of ABS, ABSB opcode format

2014-10-13 Thread Bastian Koppelmann
Add instructions of ABS, ABSB opcode format.
Add microcode generator functions for ld/st of two 32bit reg as one 64bit value.
Add microcode generator functions for ldmst and swap.
Add helper ldlcx, lducx, stlcx and stucx.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h|   4 +
 target-tricore/op_helper.c |  45 +++
 target-tricore/translate.c | 303 +
 3 files changed, 352 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 7b7d74b..fbabbd5 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -23,3 +23,7 @@ DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
 DEF_HELPER_1(rfe, void, env)
+DEF_HELPER_2(ldlcx, void, env, i32)
+DEF_HELPER_2(lducx, void, env, i32)
+DEF_HELPER_2(stlcx, void, env, i32)
+DEF_HELPER_2(stucx, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index f2a5cbc..94b5d8e 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -175,6 +175,27 @@ static void restore_context_upper(CPUTriCoreState *env, 
int ea,
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
 }
 
+static void restore_context_lower(CPUTriCoreState *env, int ea,
+  target_ulong *ra, target_ulong *pcxi)
+{
+*pcxi = cpu_ldl_data(env, ea);
+*ra = cpu_ldl_data(env, ea+4);
+env->gpr_a[2] = cpu_ldl_data(env, ea+8);
+env->gpr_a[3] = cpu_ldl_data(env, ea+12);
+env->gpr_d[0] = cpu_ldl_data(env, ea+16);
+env->gpr_d[1] = cpu_ldl_data(env, ea+20);
+env->gpr_d[2] = cpu_ldl_data(env, ea+24);
+env->gpr_d[3] = cpu_ldl_data(env, ea+28);
+env->gpr_a[4] = cpu_ldl_data(env, ea+32);
+env->gpr_a[5] = cpu_ldl_data(env, ea+36);
+env->gpr_a[6] = cpu_ldl_data(env, ea+40);
+env->gpr_a[7] = cpu_ldl_data(env, ea+44);
+env->gpr_d[4] = cpu_ldl_data(env, ea+48);
+env->gpr_d[5] = cpu_ldl_data(env, ea+52);
+env->gpr_d[6] = cpu_ldl_data(env, ea+56);
+env->gpr_d[7] = cpu_ldl_data(env, ea+60);
+}
+
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 {
 target_ulong tmp_FCX;
@@ -356,6 +377,30 @@ void helper_rfe(CPUTriCoreState *env)
 psw_write(env, new_PSW);
 }
 
+void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and RA */
+restore_context_lower(env, ea, &dummy, &dummy);
+}
+
+void helper_lducx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and PSW */
+restore_context_upper(env, ea, &dummy, &dummy);
+}
+
+void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_lower(env, ea);
+}
+
+void helper_stucx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_upper(env, ea);
+}
+
 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 4f654de..fc89a43 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -115,6 +115,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 tcg_temp_free_i32(helper_tmp);\
 } while (0)
 
+#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+
 /* Functions for load/save to/from memory */
 
 static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
@@ -135,6 +137,62 @@ static inline void gen_offset_st(DisasContext *ctx, TCGv 
r1, TCGv r2,
 tcg_temp_free(temp);
 }
 
+static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_concat_i32_i64(temp, rl, rh);
+tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
+
+tcg_temp_free_i64(temp);
+}
+
+static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
+/* write back to two 32 bit regs */
+tcg_gen_extr_i64_i32(rl, rh, temp);
+
+tcg_temp_free_i64(temp);
+}
+
+/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
+static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+
+/* temp = (M(EA, word) */
+tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
+/* temp = temp & ~E[a][63:32]) */
+tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
+/* temp2 = (E[a][31:0] & E[a][63:32]); */
+tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]);
+/* temp = temp | temp2; */
+tcg_gen_or_tl(temp, temp, temp2);
+   

[Qemu-devel] [PATCH v3 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions

2014-10-13 Thread Bastian Koppelmann
Hi guys,

here is the next round of TriCore patches. The first patch addresses a clang 
issue mentioned by Peter Maydell and
some bugfixes. And the other four add instructions of the ABS, ABSB, B, BIT and 
BO opcode format.

Thanks,

Bastian

v2 -> v3:
- OR_NOR_T, AND_NOR_T: Now uses normal conditionals instead of preprocessor.
- Add microcode generator functions gen_st/ld_preincr, which write back the
  address after the memory access.
- ST/LD_PREINC insn now use gen_st/ld_preincr or write back the address 
after
  after the memory access.

Bastian Koppelmann (5):
  target-tricore: Cleanup and Bugfixes
  target-tricore: Add instructions of ABS, ABSB opcode format
  target-tricore: Add instructions of B opcode format
  target-tricore: Add instructions of BIT opcode format
  target-tricore: Add instructions of BO opcode format

 target-tricore/helper.h  |7 +
 target-tricore/op_helper.c   |  128 +++-
 target-tricore/translate.c   | 1305 ++
 target-tricore/tricore-opcodes.h |4 +-
 4 files changed, 1417 insertions(+), 27 deletions(-)

--
2.1.2




[Qemu-devel] [PATCH v3 3/5] target-tricore: Add instructions of B opcode format

2014-10-13 Thread Bastian Koppelmann
Add instructions of B opcode format.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index fc89a43..830bcd0 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -116,6 +116,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 } while (0)
 
 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+#define EA_B_ABSOLUT(con) (((offset & 0xf0) << 8) | \
+   ((offset & 0x0f) << 1))
 
 /* Functions for load/save to/from memory */
 
@@ -492,6 +494,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_32_B_J:
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
 break;
+case OPC1_32_B_CALL:
 case OPC1_16_SB_CALL:
 gen_helper_1arg(call, ctx->next_pc);
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
@@ -567,6 +570,20 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_helper_ret(cpu_env);
 tcg_gen_exit_tb(0);
 break;
+/* B-format */
+case OPC1_32_B_CALLA:
+gen_helper_1arg(call, ctx->next_pc);
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
+case OPC1_32_B_JLA:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+case OPC1_32_B_JA:
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
+case OPC1_32_B_JL:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -1403,6 +1420,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
 break;
+/* B-format */
+case OPC1_32_B_CALL:
+case OPC1_32_B_CALLA:
+case OPC1_32_B_J:
+case OPC1_32_B_JA:
+case OPC1_32_B_JL:
+case OPC1_32_B_JLA:
+address = MASK_OP_B_DISP24(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, 0, address);
+break;
 }
 }
 
-- 
2.1.2




[Qemu-devel] [PATCH v3 4/5] target-tricore: Add instructions of BIT opcode format

2014-10-13 Thread Bastian Koppelmann
Add instructions of BIT opcode format.
Add microcode generator functions gen_bit_1/2op to do 1/2 bit operations on the 
last bit.

Signed-off-by: Bastian Koppelmann 
---
v2 -> v3:
- OR_NOR_T, AND_NOR_T: Now uses normal conditionals instead of preprocessor.

 target-tricore/translate.c | 312 +
 1 file changed, 312 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 830bcd0..ddbabc4 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -425,6 +425,49 @@ static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
 gen_helper_sub_ssov(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),
+   void(*op2)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_shri_tl(temp2, r2, pos2);
+tcg_gen_shri_tl(temp1, r1, pos1);
+
+(*op1)(temp1, temp1, temp2);
+(*op2)(temp1 , ret, temp1);
+
+tcg_gen_deposit_tl(ret, ret, temp1, 0, 1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
+/* ret = r1[pos1] op1 r2[pos2]; */
+static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
+   int pos1, int pos2,
+   void(*op1)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_shri_tl(temp2, r2, pos2);
+tcg_gen_shri_tl(temp1, r1, pos1);
+
+(*op1)(ret, temp1, temp2);
+
+tcg_gen_andi_tl(ret, ret, 0x1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
 /* helpers for generating program flow micro-ops */

 static inline void gen_save_pc(target_ulong pc)
@@ -1345,6 +1388,253 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }

+/* Bit-format */
+
+static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+
+switch (op2) {
+case OPC2_32_BIT_AND_AND_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_ANDN_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_NOR_T:
+if (TCG_TARGET_HAS_andc_i32) {
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
+} else {
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
+}
+break;
+case OPC2_32_BIT_AND_OR_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
+break;
+}
+}
+
+static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+switch (op2) {
+case OPC2_32_BIT_AND_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_ANDN_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl);
+break;
+case OPC2_32_BIT_NOR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl);
+break;
+case OPC2_32_BIT_OR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl);
+break;
+}
+}
+
+static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+TCGv temp;
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+
+temp = tcg_temp_new();
+
+tcg

[Qemu-devel] [PATCH v3 5/5] target-tricore: Add instructions of BO opcode format

2014-10-13 Thread Bastian Koppelmann
Add instructions of BO opcode format.
Add microcode generator functions gen_swap, gen_ldmst.
Add microcode generator functions gen_st/ld_preincr, which write back the 
address after the memory access.
Add helper for circular and bit reverse addr mode calculation.
Add sign extended bitmask for BO_OFF10 field.

Signed-off-by: Bastian Koppelmann 
---
v2 -> v3:
- Add microcode generator functions gen_st/ld_preincr, which write back the
  address after the memory access.
- ST/LD_PREINC insn now use gen_st/ld_preincr or write back the address 
after
  after the memory access.

 target-tricore/helper.h  |   3 +
 target-tricore/op_helper.c   |  36 +++
 target-tricore/translate.c   | 663 +++
 target-tricore/tricore-opcodes.h |   2 +
 4 files changed, 704 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index fbabbd5..b3fc33c 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -27,3 +27,6 @@ DEF_HELPER_2(ldlcx, void, env, i32)
 DEF_HELPER_2(lducx, void, env, i32)
 DEF_HELPER_2(stlcx, void, env, i32)
 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)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 94b5d8e..a36988a 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,42 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"

+/* Addressing mode helper */
+
+static uint16_t reverse16(uint16_t val)
+{
+uint8_t high = (uint8_t)(val >> 8);
+uint8_t low  = (uint8_t)(val & 0xff);
+
+uint16_t rh, rl;
+
+rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+
+return (rh << 8) | rl;
+}
+
+uint32_t helper_br_update(uint32_t reg)
+{
+uint32_t index = reg & 0x;
+uint32_t incr  = reg >> 16;
+uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
+return reg - index + new_index;
+}
+
+uint32_t helper_circ_update(uint32_t reg, uint32_t off)
+{
+uint32_t index = reg & 0x;
+uint32_t length = reg >> 16;
+int32_t new_index = index + off;
+if (new_index < 0) {
+new_index += length;
+} else {
+new_index %= length;
+}
+return reg - index + new_index;
+}
+
 #define SSOV(env, ret, arg, len) do {   \
 int64_t max_pos = INT##len ##_MAX;  \
 int64_t max_neg = INT##len ##_MIN;  \
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index ddbabc4..d5a9596 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -149,6 +149,15 @@ static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv 
address, DisasContext *ctx)
 tcg_temp_free_i64(temp);
 }

+static void gen_offset_st_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
+DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, base, con);
+gen_st_2regs_64(rh, rl, temp, ctx);
+tcg_temp_free(temp);
+}
+
 static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
 {
 TCGv_i64 temp = tcg_temp_new_i64();
@@ -160,6 +169,35 @@ static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv 
address, DisasContext *ctx)
 tcg_temp_free_i64(temp);
 }

+static void gen_offset_ld_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
+DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, base, con);
+gen_ld_2regs_64(rh, rl, temp, ctx);
+tcg_temp_free(temp);
+}
+
+static void gen_st_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
+   TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, off);
+tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
+tcg_gen_mov_tl(r2, temp);
+tcg_temp_free(temp);
+}
+
+static void gen_ld_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
+   TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, off);
+tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
+tcg_gen_mov_tl(r2, temp);
+tcg_temp_free(temp);
+}
+
 /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
 static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
 {
@@ -1635,6 +1673,612 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }

+/* BO-format */
+
+
+static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
+ DisasContext *ctx)
+{
+uint32_t op2;
+uint32_t off10;
+int32_t r1, r2;
+TCGv temp;
+
+r1 = MASK_OP_BO_S1D(ctx->opcode);
+r2  = MASK_OP_BO_S2(ctx->opcod

Re: [Qemu-devel] [PATCH v3 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions

2014-10-14 Thread Bastian Koppelmann
Peter, how do I go on from here? Do you apply the patches or do I send a 
pull-request?


Thanks,
Bastian

On 10/13/2014 05:26 PM, Bastian Koppelmann wrote:

Hi guys,

here is the next round of TriCore patches. The first patch addresses a clang 
issue mentioned by Peter Maydell and
some bugfixes. And the other four add instructions of the ABS, ABSB, B, BIT and 
BO opcode format.

Thanks,

Bastian

v2 -> v3:
 - OR_NOR_T, AND_NOR_T: Now uses normal conditionals instead of 
preprocessor.
 - Add microcode generator functions gen_st/ld_preincr, which write back the
   address after the memory access.
 - ST/LD_PREINC insn now use gen_st/ld_preincr or write back the address 
after
   after the memory access.

Bastian Koppelmann (5):
   target-tricore: Cleanup and Bugfixes
   target-tricore: Add instructions of ABS, ABSB opcode format
   target-tricore: Add instructions of B opcode format
   target-tricore: Add instructions of BIT opcode format
   target-tricore: Add instructions of BO opcode format

  target-tricore/helper.h  |7 +
  target-tricore/op_helper.c   |  128 +++-
  target-tricore/translate.c   | 1305 ++
  target-tricore/tricore-opcodes.h |4 +-
  4 files changed, 1417 insertions(+), 27 deletions(-)

--
2.1.2







[Qemu-devel] [PULL 4/5] target-tricore: Add instructions of BIT opcode format

2014-10-21 Thread Bastian Koppelmann
Add instructions of BIT opcode format.
Add microcode generator functions gen_bit_1/2op to do 1/2 bit operations on the 
last bit.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 312 +
 1 file changed, 312 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 830bcd0..ddbabc4 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -425,6 +425,49 @@ static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
 gen_helper_sub_ssov(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),
+   void(*op2)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_shri_tl(temp2, r2, pos2);
+tcg_gen_shri_tl(temp1, r1, pos1);
+
+(*op1)(temp1, temp1, temp2);
+(*op2)(temp1 , ret, temp1);
+
+tcg_gen_deposit_tl(ret, ret, temp1, 0, 1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
+/* ret = r1[pos1] op1 r2[pos2]; */
+static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
+   int pos1, int pos2,
+   void(*op1)(TCGv, TCGv, TCGv))
+{
+TCGv temp1, temp2;
+
+temp1 = tcg_temp_new();
+temp2 = tcg_temp_new();
+
+tcg_gen_shri_tl(temp2, r2, pos2);
+tcg_gen_shri_tl(temp1, r1, pos1);
+
+(*op1)(ret, temp1, temp2);
+
+tcg_gen_andi_tl(ret, ret, 0x1);
+
+tcg_temp_free(temp1);
+tcg_temp_free(temp2);
+}
+
 /* helpers for generating program flow micro-ops */
 
 static inline void gen_save_pc(target_ulong pc)
@@ -1345,6 +1388,253 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }
 
+/* Bit-format */
+
+static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+
+switch (op2) {
+case OPC2_32_BIT_AND_AND_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_ANDN_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_AND_NOR_T:
+if (TCG_TARGET_HAS_andc_i32) {
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
+} else {
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
+}
+break;
+case OPC2_32_BIT_AND_OR_T:
+gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
+break;
+}
+}
+
+static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+
+switch (op2) {
+case OPC2_32_BIT_AND_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_and_tl);
+break;
+case OPC2_32_BIT_ANDN_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_andc_tl);
+break;
+case OPC2_32_BIT_NOR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_nor_tl);
+break;
+case OPC2_32_BIT_OR_T:
+gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+pos1, pos2, &tcg_gen_or_tl);
+break;
+}
+}
+
+static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int pos1, pos2;
+TCGv temp;
+op2 = MASK_OP_BIT_OP2(ctx->opcode);
+r1 = MASK_OP_BIT_S1(ctx->opcode);
+r2 = MASK_OP_BIT_S2(ctx->opcode);
+r3 = MASK_OP_BIT_D(ctx->opcode);
+pos1 = MASK_OP_BIT_POS1(ctx->opcode);
+pos2 = MASK_OP_BIT_POS2(ctx->opcode);
+
+temp = tcg_temp_new();
+
+tcg_gen_shri_tl(temp, cpu_gpr_d[r2], pos2);
+if (op2 == OPC2

[Qemu-devel] [PULL 0/5] target-tricore patches

2014-10-21 Thread Bastian Koppelmann
The following changes since commit 5f77ef69a195098baddfdc6d189f1b4a94587378:

  glib: add compatibility interface for g_strcmp0() (2014-10-16 23:02:31 +0100)

are available in the git repository at:

  https://github.com/bkoppelmann/qemu-tricore-upstream.git 
tags/pull-tricore-20141021

for you to fetch changes up to 3a16ecb06355d0bfc8b547eba094ebaa44dce39f:

  target-tricore: Add instructions of BO opcode format (2014-10-20 12:25:07 
+0100)


TriCore ABS, ABSB, B, BIT, BO instructions added


Bastian Koppelmann (5):
  target-tricore: Cleanup and Bugfixes
  target-tricore: Add instructions of ABS, ABSB opcode format
  target-tricore: Add instructions of B opcode format
  target-tricore: Add instructions of BIT opcode format
  target-tricore: Add instructions of BO opcode format

 target-tricore/helper.h  |7 +
 target-tricore/op_helper.c   |  128 +++-
 target-tricore/translate.c   | 1305 ++
 target-tricore/tricore-opcodes.h |4 +-
 4 files changed, 1417 insertions(+), 27 deletions(-)



[Qemu-devel] [PULL 1/5] target-tricore: Cleanup and Bugfixes

2014-10-21 Thread Bastian Koppelmann
Move FCX loading of save_context_ to caller functions, for STLCX, STUCX insn to 
use those functions.
Move FCX storing of restore_context_ to caller functions, for LDLCX, LDUCX insn 
to use those functions.
Remove do_raise_exception function, which caused clang to emit a warning.
Fix: save_context_lower now saves a[11] instead of PSW.
Fix: MASK_OP_ABSB_BPOS starting at wrong offset.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/op_helper.c   | 47 ++--
 target-tricore/tricore-opcodes.h |  2 +-
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 6376f07..f2a5cbc 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -114,10 +114,8 @@ static bool cdc_zero(target_ulong *psw)
 return count == 0;
 }
 
-static void save_context_upper(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_upper(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
 cpu_stl_data(env, ea+4, env->PSW);
 cpu_stl_data(env, ea+8, env->gpr_a[10]);
@@ -134,15 +132,12 @@ static void save_context_upper(CPUTriCoreState *env, int 
ea,
 cpu_stl_data(env, ea+52, env->gpr_d[13]);
 cpu_stl_data(env, ea+56, env->gpr_d[14]);
 cpu_stl_data(env, ea+60, env->gpr_d[15]);
-
 }
 
-static void save_context_lower(CPUTriCoreState *env, int ea,
-   target_ulong *new_FCX)
+static void save_context_lower(CPUTriCoreState *env, int ea)
 {
-*new_FCX = cpu_ldl_data(env, ea);
 cpu_stl_data(env, ea, env->PCXI);
-cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+4, env->gpr_a[11]);
 cpu_stl_data(env, ea+8, env->gpr_a[2]);
 cpu_stl_data(env, ea+12, env->gpr_a[3]);
 cpu_stl_data(env, ea+16, env->gpr_d[0]);
@@ -178,7 +173,6 @@ static void restore_context_upper(CPUTriCoreState *env, int 
ea,
 env->gpr_d[13] = cpu_ldl_data(env, ea+52);
 env->gpr_d[14] = cpu_ldl_data(env, ea+56);
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
-cpu_stl_data(env, ea, env->FCX);
 }
 
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
@@ -206,11 +200,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
 ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
  ((env->FCX & MASK_FCX_FCXO) << 6);
-/* new_FCX = M(EA, word);
-   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
-  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
-  D[15]}; */
-save_context_upper(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+   A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+   D[15]}; */
+save_context_upper(env, ea);
 
 /* PCXI.PCPN = ICR.CCPN; */
 env->PCXI = (env->PCXI & 0xff) +
@@ -263,9 +258,10 @@ void helper_ret(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-M(EA, word) = FCX; */
+A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* M(EA, word) = FCX; */
+cpu_stl_data(env, ea, env->FCX);
 /* FCX[19: 0] = PCXI[19: 0]; */
 env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
 /* PCXI = new_PCXI; */
@@ -293,7 +289,12 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
 tmp_FCX = env->FCX;
 ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
 
-save_context_lower(env, ea, &new_FCX);
+/* new_FCX = M(EA, word); */
+new_FCX = cpu_ldl_data(env, ea);
+/* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], 
A[4]
+   , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
+save_context_lower(env, ea);
+
 
 /* PCXI.PCPN = ICR.CCPN */
 env->PCXI = (env->PCXI & 0xff) +
@@ -343,9 +344,10 @@ void helper_rfe(CPUTriCoreState *env)
 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
  ((env->PCXI & MASK_PCXI_PCXO) << 6);
 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
-  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
-  M(EA, word) = FCX;*/
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = 

[Qemu-devel] [PULL 2/5] target-tricore: Add instructions of ABS, ABSB opcode format

2014-10-21 Thread Bastian Koppelmann
Add instructions of ABS, ABSB opcode format.
Add microcode generator functions for ld/st of two 32bit reg as one 64bit value.
Add microcode generator functions for ldmst and swap.
Add helper ldlcx, lducx, stlcx and stucx.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h|   4 +
 target-tricore/op_helper.c |  45 +++
 target-tricore/translate.c | 303 +
 3 files changed, 352 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 7b7d74b..fbabbd5 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -23,3 +23,7 @@ DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
 DEF_HELPER_1(rfe, void, env)
+DEF_HELPER_2(ldlcx, void, env, i32)
+DEF_HELPER_2(lducx, void, env, i32)
+DEF_HELPER_2(stlcx, void, env, i32)
+DEF_HELPER_2(stucx, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index f2a5cbc..94b5d8e 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -175,6 +175,27 @@ static void restore_context_upper(CPUTriCoreState *env, 
int ea,
 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
 }
 
+static void restore_context_lower(CPUTriCoreState *env, int ea,
+  target_ulong *ra, target_ulong *pcxi)
+{
+*pcxi = cpu_ldl_data(env, ea);
+*ra = cpu_ldl_data(env, ea+4);
+env->gpr_a[2] = cpu_ldl_data(env, ea+8);
+env->gpr_a[3] = cpu_ldl_data(env, ea+12);
+env->gpr_d[0] = cpu_ldl_data(env, ea+16);
+env->gpr_d[1] = cpu_ldl_data(env, ea+20);
+env->gpr_d[2] = cpu_ldl_data(env, ea+24);
+env->gpr_d[3] = cpu_ldl_data(env, ea+28);
+env->gpr_a[4] = cpu_ldl_data(env, ea+32);
+env->gpr_a[5] = cpu_ldl_data(env, ea+36);
+env->gpr_a[6] = cpu_ldl_data(env, ea+40);
+env->gpr_a[7] = cpu_ldl_data(env, ea+44);
+env->gpr_d[4] = cpu_ldl_data(env, ea+48);
+env->gpr_d[5] = cpu_ldl_data(env, ea+52);
+env->gpr_d[6] = cpu_ldl_data(env, ea+56);
+env->gpr_d[7] = cpu_ldl_data(env, ea+60);
+}
+
 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 {
 target_ulong tmp_FCX;
@@ -356,6 +377,30 @@ void helper_rfe(CPUTriCoreState *env)
 psw_write(env, new_PSW);
 }
 
+void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and RA */
+restore_context_lower(env, ea, &dummy, &dummy);
+}
+
+void helper_lducx(CPUTriCoreState *env, uint32_t ea)
+{
+uint32_t dummy;
+/* insn doesn't load PCXI and PSW */
+restore_context_upper(env, ea, &dummy, &dummy);
+}
+
+void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_lower(env, ea);
+}
+
+void helper_stucx(CPUTriCoreState *env, uint32_t ea)
+{
+save_context_upper(env, ea);
+}
+
 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 4f654de..fc89a43 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -115,6 +115,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 tcg_temp_free_i32(helper_tmp);\
 } while (0)
 
+#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+
 /* Functions for load/save to/from memory */
 
 static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
@@ -135,6 +137,62 @@ static inline void gen_offset_st(DisasContext *ctx, TCGv 
r1, TCGv r2,
 tcg_temp_free(temp);
 }
 
+static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_concat_i32_i64(temp, rl, rh);
+tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
+
+tcg_temp_free_i64(temp);
+}
+
+static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
+{
+TCGv_i64 temp = tcg_temp_new_i64();
+
+tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
+/* write back to two 32 bit regs */
+tcg_gen_extr_i64_i32(rl, rh, temp);
+
+tcg_temp_free_i64(temp);
+}
+
+/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
+static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+
+/* temp = (M(EA, word) */
+tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
+/* temp = temp & ~E[a][63:32]) */
+tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
+/* temp2 = (E[a][31:0] & E[a][63:32]); */
+tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]);
+/* temp = temp | temp2; */
+tcg_gen_or_tl(temp, temp, temp2);
+   

[Qemu-devel] [PULL 3/5] target-tricore: Add instructions of B opcode format

2014-10-21 Thread Bastian Koppelmann
Add instructions of B opcode format.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index fc89a43..830bcd0 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -116,6 +116,8 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 } while (0)
 
 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
+#define EA_B_ABSOLUT(con) (((offset & 0xf0) << 8) | \
+   ((offset & 0x0f) << 1))
 
 /* Functions for load/save to/from memory */
 
@@ -492,6 +494,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_32_B_J:
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
 break;
+case OPC1_32_B_CALL:
 case OPC1_16_SB_CALL:
 gen_helper_1arg(call, ctx->next_pc);
 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
@@ -567,6 +570,20 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_helper_ret(cpu_env);
 tcg_gen_exit_tb(0);
 break;
+/* B-format */
+case OPC1_32_B_CALLA:
+gen_helper_1arg(call, ctx->next_pc);
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
+case OPC1_32_B_JLA:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+case OPC1_32_B_JA:
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
+case OPC1_32_B_JL:
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -1403,6 +1420,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
 break;
+/* B-format */
+case OPC1_32_B_CALL:
+case OPC1_32_B_CALLA:
+case OPC1_32_B_J:
+case OPC1_32_B_JA:
+case OPC1_32_B_JL:
+case OPC1_32_B_JLA:
+address = MASK_OP_B_DISP24(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, 0, address);
+break;
 }
 }
 
-- 
2.1.2




[Qemu-devel] [PULL 5/5] target-tricore: Add instructions of BO opcode format

2014-10-21 Thread Bastian Koppelmann
Add instructions of BO opcode format.
Add microcode generator functions gen_swap, gen_ldmst.
Add microcode generator functions gen_st/ld_preincr, which write back the 
address after the memory access.
Add helper for circular and bit reverse addr mode calculation.
Add sign extended bitmask for BO_OFF10 field.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h  |   3 +
 target-tricore/op_helper.c   |  36 +++
 target-tricore/translate.c   | 663 +++
 target-tricore/tricore-opcodes.h |   2 +
 4 files changed, 704 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index fbabbd5..b3fc33c 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -27,3 +27,6 @@ DEF_HELPER_2(ldlcx, void, env, i32)
 DEF_HELPER_2(lducx, void, env, i32)
 DEF_HELPER_2(stlcx, void, env, i32)
 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)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 94b5d8e..a36988a 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,42 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"

+/* Addressing mode helper */
+
+static uint16_t reverse16(uint16_t val)
+{
+uint8_t high = (uint8_t)(val >> 8);
+uint8_t low  = (uint8_t)(val & 0xff);
+
+uint16_t rh, rl;
+
+rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+
+return (rh << 8) | rl;
+}
+
+uint32_t helper_br_update(uint32_t reg)
+{
+uint32_t index = reg & 0x;
+uint32_t incr  = reg >> 16;
+uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
+return reg - index + new_index;
+}
+
+uint32_t helper_circ_update(uint32_t reg, uint32_t off)
+{
+uint32_t index = reg & 0x;
+uint32_t length = reg >> 16;
+int32_t new_index = index + off;
+if (new_index < 0) {
+new_index += length;
+} else {
+new_index %= length;
+}
+return reg - index + new_index;
+}
+
 #define SSOV(env, ret, arg, len) do {   \
 int64_t max_pos = INT##len ##_MAX;  \
 int64_t max_neg = INT##len ##_MIN;  \
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index ddbabc4..d5a9596 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -149,6 +149,15 @@ static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv 
address, DisasContext *ctx)
 tcg_temp_free_i64(temp);
 }

+static void gen_offset_st_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
+DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, base, con);
+gen_st_2regs_64(rh, rl, temp, ctx);
+tcg_temp_free(temp);
+}
+
 static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
 {
 TCGv_i64 temp = tcg_temp_new_i64();
@@ -160,6 +169,35 @@ static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv 
address, DisasContext *ctx)
 tcg_temp_free_i64(temp);
 }

+static void gen_offset_ld_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
+DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, base, con);
+gen_ld_2regs_64(rh, rl, temp, ctx);
+tcg_temp_free(temp);
+}
+
+static void gen_st_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
+   TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, off);
+tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
+tcg_gen_mov_tl(r2, temp);
+tcg_temp_free(temp);
+}
+
+static void gen_ld_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
+   TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, off);
+tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
+tcg_gen_mov_tl(r2, temp);
+tcg_temp_free(temp);
+}
+
 /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
 static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
 {
@@ -1635,6 +1673,612 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp);
 }

+/* BO-format */
+
+
+static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
+ DisasContext *ctx)
+{
+uint32_t op2;
+uint32_t off10;
+int32_t r1, r2;
+TCGv temp;
+
+r1 = MASK_OP_BO_S1D(ctx->opcode);
+r2  = MASK_OP_BO_S2(ctx->opcode);
+off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
+op2 = MASK_OP_BO_OP2(ctx->opcode);
+
+switch (op2) {
+case OPC2_32_BO_CACHEA_WI_SHORTOFF:
+case OPC2_32_BO_CACHEA_W_SHORTOFF:
+case OPC2_32_B

[Qemu-devel] [PATCH 4/5] target-tricore: Add instructions of BRR opcode format

2014-10-29 Thread Bastian Koppelmann
Add instructions of BRR opcode format.
Add MASK_OP_BRR_DISP15_SEXT.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c   | 89 +++-
 target-tricore/tricore-opcodes.h |  1 +
 2 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 0c69f1f..17eb8a7 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 l1, n;
 
 switch (opc) {
@@ -725,6 +725,78 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_goto_tb(ctx, 1, ctx->pc + offset * 2);
 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 {
+gen_save_pc(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);
 }
@@ -2382,7 +2454,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;
@@ -2534,6 +2606,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);
+br

[Qemu-devel] [PATCH 2/5] target-tricore: Add instructions of BRC opcode format

2014-10-29 Thread Bastian Koppelmann
Add instructions of BRC opcode format.
Fixed OP2_BRC_JGE -> OP2_32_BRC_JGE.

Signed-off-by: Bastian Koppelmann 
---
 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.2




[Qemu-devel] [PATCH 1/5] target-tricore: Add instructions of BOL opcode format

2014-10-29 Thread Bastian Koppelmann
Add instructions of BOL opcode format.

Signed-off-by: Bastian Koppelmann 
---
 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.2




[Qemu-devel] [PATCH 5/5] target-tricore: Add instructions of RC opcode format

2014-10-29 Thread Bastian Koppelmann
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 
---
 target-tricore/helper.h  |   6 +
 target-tricore/op_helper.c   |  99 ++
 target-tricore/translate.c   | 695 +++
 target-tricore/tricore-opcodes.h |   1 +
 4 files changed, 801 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 r

[Qemu-devel] [PATCH 3/5] target-tricore: Add instructions of BRN opcode format

2014-10-29 Thread Bastian Koppelmann
Add instructions of BRN opcode format.
Add MASK_OP_BRN_DISP15_SEXT.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c   | 30 ++
 target-tricore/tricore-opcodes.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 789f005..0c69f1f 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 l1, n;

 switch (opc) {
 /* SB-format jumps */
@@ -706,6 +707,24 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 }
 tcg_temp_free(temp);
 break;
+/* BRN format */
+case OPCM_32_BRN_JTT:
+l1 = gen_new_label();
+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) {
+tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
+} else {
+tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+}
+gen_goto_tb(ctx, 0, ctx->next_pc);
+gen_set_label(l1);
+gen_goto_tb(ctx, 1, ctx->pc + offset * 2);
+tcg_temp_free(temp);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -2371,6 +2390,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 +2528,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.2




[Qemu-devel] [PATCH 0/5] Add TriCore BOL, BRC, BRN, BRR and RC instructions

2014-10-29 Thread Bastian Koppelmann
Hi,

this is the next round of TriCore patches, which adds BOL, BRC, BRN, BRR and RC 
instructions.
I'm not quite sure about the softfreeze. Since this patch has not been 
announced after
the softfreeze, do I have to wait with a pull-request to after the release of 
2.2?

thanks,
Bastian

Bastian Koppelmann (5):
  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/helper.h  |   6 +
 target-tricore/op_helper.c   |  99 +
 target-tricore/translate.c   | 913 ++-
 target-tricore/tricore-opcodes.h |  13 +-
 4 files changed, 1025 insertions(+), 6 deletions(-)

--
2.1.2




Re: [Qemu-devel] [PATCH] target-tricore: check return value before using it

2014-10-30 Thread Bastian Koppelmann

Geez, thanks. I wonder how I missed that.

Reviewed-by: Bastian Koppelmann 

On 10/30/2014 02:03 AM, zhanghailiang wrote:

We reference the return value of cpu before checking whether it is NULL,
The checking code is after that which violates code style.

It makes no difference if the cpu is NULL, qemu process will terminate.
But one will be 'Segmentation fault' and the other will report a error
which is what we want.

Signed-off-by: zhanghailiang 
---
  hw/tricore/tricore_testboard.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index eeb4922..a059a20 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -71,11 +71,11 @@ static void tricore_testboard_init(MachineState *machine, 
int board_id)
  machine->cpu_model = "tc1796";
  }
  cpu = cpu_tricore_init(machine->cpu_model);
-env = &cpu->env;
  if (!cpu) {
  error_report("Unable to find CPU definition");
  exit(1);
  }
+env = &cpu->env;
  memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram", 2*1024*1024, 
&error_abort);
  vmstate_register_ram_global(ext_cram);
  memory_region_init_ram(ext_dram, NULL, "powerlink_ext_d.ram", 4*1024*1024, 
&error_abort);





[Qemu-devel] [PATCH v2 0/5] Add TriCore BOL, BRC, BRN, BRR and RC instructions

2014-10-31 Thread Bastian Koppelmann
Hi,

this is the next round of TriCore patches, which adds BOL, BRC, BRN, BRR and RC 
instructions.
I'm not quite sure about the softfreeze. Since this patch has not been 
announced after
the softfreeze, do I have to wait with a pull-request to after the release of 
2.2?

Thanks,
Bastian

v1 -> v2:
- OPC2_32_BRN_JNZ_T now uses gen_branch_condi.
- OPC2_32_BRR_LOOPU now uses gen_goto_tb.
- else of OPC2_32_BRR_LOOPU now has comment identifying it.
- gen_sha_hi: Remove mask for low in case shift_count > 0, since deposit 
handles that.
- gen_sha_hi: Remove mask for high in case shift <= 0, since deposit 
handles that.

Bastian Koppelmann (5):
  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/helper.h  |   6 +
 target-tricore/op_helper.c   |  99 +
 target-tricore/translate.c   | 910 ++-
 target-tricore/tricore-opcodes.h |  13 +-
 4 files changed, 1022 insertions(+), 6 deletions(-)

--
2.1.2




[Qemu-devel] [PATCH v2 1/5] target-tricore: Add instructions of BOL opcode format

2014-10-31 Thread Bastian Koppelmann
Add instructions of BOL opcode format.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 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.2




[Qemu-devel] [PATCH v2 3/5] target-tricore: Add instructions of BRN opcode format

2014-10-31 Thread Bastian Koppelmann
Add instructions of BRN opcode format.
Add MASK_OP_BRN_DISP15_SEXT.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- OPC2_32_BRN_JNZ_T now uses gen_branch_condi.

 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.2




[Qemu-devel] [PATCH v2 4/5] target-tricore: Add instructions of BRR opcode format

2014-10-31 Thread Bastian Koppelmann
Add instructions of BRR opcode format.
Add MASK_OP_BRR_DISP15_SEXT.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- OPC2_32_BRR_LOOPU now uses gen_goto_tb.
- else of OPC2_32_BRR_LOOPU now has comment identifying it.

 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->

[Qemu-devel] [PATCH v2 5/5] target-tricore: Add instructions of RC opcode format

2014-10-31 Thread Bastian Koppelmann
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 
---
v1 -> v2:
- gen_sha_hi: Remove mask for low in case shift_count > 0, since deposit 
handles that.
- gen_sha_hi: Remove mask for high in case shift <= 0, since deposit 
handles that.

 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;

[Qemu-devel] [PATCH v2 2/5] target-tricore: Add instructions of BRC opcode format

2014-10-31 Thread Bastian Koppelmann
Add instructions of BRC opcode format.
Fixed OP2_BRC_JGE -> OP2_32_BRC_JGE

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 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.2




Re: [Qemu-devel] [PATCH v6 02/15] target-tricore: Add board for systemmode

2014-08-29 Thread Bastian Koppelmann

Hi Peter,

On 08/29/2014 03:30 PM, Peter Maydell wrote:



+
+dinfo = drive_get(IF_PFLASH, 0, 0);
+if (!pflash_cfi01_register(TRICORE_FLASH_ADDR, NULL,
+  "tricore_testboard.flash",
+  TRICORE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+  TRICORE_FLASH_SECT_SIZE,
+  TRICORE_FLASH_SIZE / TRICORE_FLASH_SECT_SIZE,
+  2, 0x00, 0x00, 0x, 0x0, 0)) {

Don't use pflash_cfi01_register() in new code, it gives you a
weird not-like-hardware flash device that we only have for
backwards compatibility with existing board models. Instantiate
and configure the flash device directly (compare vexpress.c's
ve_pflash_cfi01_register(), but use the correct config for the
hardware you're modelling, which might not be two parallel
16 bit wide flash chips).


This board does not exists. It's purpose is just to be able to run 
TriCore binaries. So I rather just get rid of the flash drive.

+}
+
+tricoretb_binfo.ram_size = machine->ram_size;
+tricoretb_binfo.kernel_filename = machine->kernel_filename;
+
+if (machine->kernel_filename) {
+tricore_load_kernel(env);
+}
+}
+
+static void tricoreboard_init(MachineState *machine)
+{
+tricore_testboard_init(machine, 0x183);
+}
+
+static QEMUMachine ttb_machine = {
+.name = "tricore_testboard",
+.desc = "Just for testing",
+.init = tricoreboard_init,
+.is_default = 1,
+};

The .desc text here appears in the user-visible help output, so
can we have something slightly more useful to them, please?

$ ./build/all/tricore-softmmu/qemu-system-tricore -M help
Supported machines are:
tricore_testboardJust for testing (default)
none empty machine


Same as above. The description shows exactly the board's purpose. It is 
just for testing and not a real board. How about I change it to "a 
minimal TriCore board"?
I see your point about the default. For now I would leave it as is, 
since there are not other boards and qemu would give an error, when 
launched without -M.



Also, think about whether you really want to set the
is_default flag. Will all users of TriCore based boards
always want the test board?


+++ b/include/hw/tricore/tricore.h
@@ -0,0 +1,54 @@
+#ifndef TRICORE_MISC_H
+#define TRICORE_MISC_H 1
+
+#include "exec/memory.h"
+#include "hw/irq.h"
+
+struct tricore_boot_info {
+uint64_t ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+const char *dtb_filename;
+hwaddr loader_start;
+/* multicore boards that use the default secondary core boot functions
+ * need to put the address of the secondary boot code, the boot reg,
+ * and the GIC address in the next 3 values, respectively. boards that
+ * have their own boot functions can use these values as they want.
+ */
+hwaddr smp_loader_start;
+hwaddr smp_bootreg_addr;
+hwaddr gic_cpu_if_addr;
+int nb_cpus;
+int board_id;
+int (*atag_board)(const struct tricore_boot_info *info, void *p);
+/* multicore boards that use the default secondary core boot functions
+ * can ignore these two function calls. If the default functions won't
+ * work, then write_secondary_boot() should write a suitable blob of
+ * code mimicking the secondary CPU startup process used by the board's
+ * boot loader/boot ROM code, and secondary_cpu_reset_hook() should
+ * perform any necessary CPU reset handling and set the PC for the
+ * secondary CPUs to point at this boot blob.
+ */
+void (*write_secondary_boot)(TRICORECPU *cpu,
+ const struct tricore_boot_info *info);
+void (*secondary_cpu_reset_hook)(TRICORECPU *cpu,
+ const struct tricore_boot_info *info);
+/* if a board is able to create a dtb without a dtb file then it
+ * sets get_dtb. This will only be used if no dtb file is provided
+ * by the user. On success, sets *size to the length of the created
+ * dtb, and returns a pointer to it. (The caller must free this memory
+ * with g_free() when it has finished with it.) On failure, returns NULL.
+ */
+void *(*get_dtb)(const struct tricore_boot_info *info, int *size);
+/* if a board needs to be able to modify a device tree provided by
+ * the user it should implement this hook.
+ */
+void (*modify_dtb)(const struct tricore_boot_info *info, void *fdt);
+/* Used internally by arm_boot.c */
+int is_linux;
+hwaddr initrd_start;
+hwaddr initrd_size;
+hwaddr entry;
+};

This looks pretty obviously like you just copied it wholesale from
the ARM board support code. Please only include struct fields
you actually use.

thanks
-- PMM



Thanks,
Bastian



[Qemu-devel] [PATCH v7 02/15] target-tricore: Add board for systemmode

2014-09-01 Thread Bastian Koppelmann
Add basic board to allow systemmode emulation

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- TRICORECPU -> TriCoreCPU.
- CPUTRICOREState -> CPUTriCoreState.
- tricore_testboard.c: Change Licence to GPL v2.
- fprintf(stderr, ..) -> error_report(..).
- tricore_boot_info: Remove unused fields.
- tricore_testboard.c: Remove flash drive.
- tricore_testboard.c: Is not default anymore, change desc.

 hw/tricore/Makefile.objs   |   1 +
 hw/tricore/tricore_testboard.c | 124 +
 include/hw/tricore/tricore.h   |  11 
 3 files changed, 136 insertions(+)
 create mode 100644 hw/tricore/Makefile.objs
 create mode 100644 hw/tricore/tricore_testboard.c
 create mode 100644 include/hw/tricore/tricore.h

diff --git a/hw/tricore/Makefile.objs b/hw/tricore/Makefile.objs
new file mode 100644
index 000..435e095
--- /dev/null
+++ b/hw/tricore/Makefile.objs
@@ -0,0 +1 @@
+obj-y += tricore_testboard.o
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
new file mode 100644
index 000..f412e27
--- /dev/null
+++ b/hw/tricore/tricore_testboard.c
@@ -0,0 +1,124 @@
+/*
+ * TriCore Baseboard System emulation.
+ *
+ * Copyright (c) 2013-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "hw/hw.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "sysemu/blockdev.h"
+#include "exec/address-spaces.h"
+#include "hw/block/flash.h"
+#include "elf.h"
+#include "hw/tricore/tricore.h"
+#include "qemu/error-report.h"
+
+
+/* Board init.  */
+
+static struct tricore_boot_info tricoretb_binfo;
+
+static void tricore_load_kernel(CPUTriCoreState *env)
+{
+uint64_t entry;
+long kernel_size;
+
+kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL,
+   NULL, (uint64_t *)&entry, NULL,
+   NULL, 0,
+   ELF_MACHINE, 1);
+if (kernel_size <= 0) {
+error_report("qemu: no kernel file '%s'",
+tricoretb_binfo.kernel_filename);
+exit(1);
+}
+env->PC = entry;
+
+}
+
+static void tricore_testboard_init(MachineState *machine, int board_id)
+{
+TriCoreCPU *cpu;
+CPUTriCoreState *env;
+
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ext_cram = g_new(MemoryRegion, 1);
+MemoryRegion *ext_dram = g_new(MemoryRegion, 1);
+MemoryRegion *int_cram = g_new(MemoryRegion, 1);
+MemoryRegion *int_dram = g_new(MemoryRegion, 1);
+MemoryRegion *pcp_data = g_new(MemoryRegion, 1);
+MemoryRegion *pcp_text = g_new(MemoryRegion, 1);
+
+if (!machine->cpu_model) {
+machine->cpu_model = "tc1796";
+}
+cpu = cpu_tricore_init(machine->cpu_model);
+env = &cpu->env;
+if (!cpu) {
+error_report("Unable to find CPU definition");
+exit(1);
+}
+memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram", 2*1024*1024);
+vmstate_register_ram_global(ext_cram);
+memory_region_init_ram(ext_dram, NULL, "powerlink_ext_d.ram", 4*1024*1024);
+vmstate_register_ram_global(ext_dram);
+memory_region_init_ram(int_cram, NULL, "powerlink_int_c.ram", 48*1024);
+vmstate_register_ram_global(int_cram);
+memory_region_init_ram(int_dram, NULL, "powerlink_int_d.ram", 48*1024);
+vmstate_register_ram_global(int_dram);
+memory_region_init_ram(pcp_data, NULL, "powerlink_pcp_data.ram", 16*1024);
+vmstate_register_ram_global(pcp_data);
+memory_region_init_ram(pcp_text, NULL, "powerlink_pcp_text.ram", 32*1024);
+vmstate_register_ram_global(pcp_text);
+
+memory_region_add_subregion(sysmem, 0x8000, ext_cram);
+memory_region_add_subregion(sysmem, 0xa100, ext_dram);
+memory_region_add_subregion(sysmem, 0xd400, int_cram);
+memory_region_add_subregion(sysmem, 0xd000, int_dram);
+memory_region_add_subregion(sysmem, 0xf005, pcp_data);
+memory_region_add_subregion(sysmem, 0xf006

[Qemu-devel] [PATCH v7 01/15] target-tricore: Add target stubs and qom-cpu

2014-09-01 Thread Bastian Koppelmann
Add TriCore target stubs, and QOM cpu, and Maintainer

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- TRICORECPU -> TriCoreCPU.
- TRICORECPUClass -> TriCoreCPUClass.
- CPUTRICOREState -> CPUTriCoreState.
- TRICORECPUInfo: Add terminator.
- TRICORECPUInfo -> TriCoreCPUInfo.
- Remove ARM-style IRQ and FIQ lines.
- CPUTRICOREState: target_ulong -> uint32_t.
- CPUTRICOREState: Move mask defines below the struct.

 MAINTAINERS   |   6 +
 arch_init.c   |   2 +
 cpu-exec.c|  11 +-
 cpus.c|   6 +
 include/elf.h |   2 +
 include/sysemu/arch_init.h|   1 +
 target-tricore/Makefile.objs  |   1 +
 target-tricore/cpu-qom.h  |  71 
 target-tricore/cpu.c  | 192 
 target-tricore/cpu.h  | 405 ++
 target-tricore/helper.c   |  92 ++
 target-tricore/helper.h   |   0
 target-tricore/op_helper.c|  27 +++
 target-tricore/translate.c| 100 +++
 target-tricore/tricore-defs.h |  28 +++
 15 files changed, 943 insertions(+), 1 deletion(-)
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 100644 target-tricore/helper.h
 create mode 100644 target-tricore/op_helper.c
 create mode 100644 target-tricore/translate.c
 create mode 100644 target-tricore/tricore-defs.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a74c04c..142f68a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -161,6 +161,12 @@ S: Maintained
 F: target-xtensa/
 F: hw/xtensa/
 
+TriCore
+M: Bastian Koppelmann 
+S: Maintained
+F: target-tricore/
+F: hw/tricore/
+
 Guest CPU Cores (KVM):
 --
 
diff --git a/arch_init.c b/arch_init.c
index 28ece76..c974f3f 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -104,6 +104,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_XTENSA
 #elif defined(TARGET_UNICORE32)
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
+#elif defined(TARGET_TRICORE)
+#define QEMU_ARCH QEMU_ARCH_TRICORE
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/cpu-exec.c b/cpu-exec.c
index c6aad74..7b5d2e2 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -387,6 +387,7 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
 #elif defined(TARGET_XTENSA)
+#elif defined(TARGET_TRICORE)
 /* X */
 #else
 #error unsupported target CPU
@@ -444,7 +445,8 @@ int cpu_exec(CPUArchState *env)
 }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
-defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || 
defined(TARGET_UNICORE32)
+defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) ||   \
+defined(TARGET_UNICORE32) || defined(TARGET_TRICORE)
 if (interrupt_request & CPU_INTERRUPT_HALT) {
 cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
 cpu->halted = 1;
@@ -560,6 +562,12 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
+#elif defined(TARGET_TRICORE)
+if ((interrupt_request & CPU_INTERRUPT_HARD)) {
+cc->do_interrupt(cpu);
+next_tb = 0;
+}
+
 #elif defined(TARGET_OPENRISC)
 {
 int idx = -1;
@@ -846,6 +854,7 @@ int cpu_exec(CPUArchState *env)
   | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_TRICORE)
 #elif defined(TARGET_MOXIE)
 #elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
diff --git a/cpus.c b/cpus.c
index eb1ac85..0f7d0ea 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1410,6 +1410,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 MIPSCPU *mips_cpu = MIPS_CPU(cpu);
 CPUMIPSState *env = &mips_cpu->env;
+#elif defined(TARGET_TRICORE)
+TriCoreCPU *tricore_cpu = TRICORE_CPU(cpu);
+CPUTriCoreState *env = &tricore_cpu->env;
 #endif
 
 cpu_synchronize_state(cpu);
@@ -1434,6 +1437,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 info->value->has_PC = true;
 info->value->PC = env->active_tc.PC;
+#elif defined(TARGET_TRICORE)
+info->value->has_PC = true;
+info->value->PC = env->PC;
 #endif
 
 /* XXX: waiting for the qapi to support GSList */
diff --git a/include/elf.h b/include/elf.h
index e88d52f..70107f0 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ 

[Qemu-devel] [PATCH v7 05/15] target-tricore: Add masks and opcodes for decoding

2014-09-01 Thread Bastian Koppelmann
Add masks and opcodes for decoding TriCore instructions.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c   |1 +
 target-tricore/tricore-opcodes.h | 1406 ++
 2 files changed, 1407 insertions(+)
 create mode 100644 target-tricore/tricore-opcodes.h

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 7691b11..e06cf41 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,7 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+#include "tricore-opcodes.h"
 /*
  * TCG registers
  */
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
new file mode 100644
index 000..9c6ec01
--- /dev/null
+++ b/target-tricore/tricore-opcodes.h
@@ -0,0 +1,1406 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Opcode Masks for Tricore
+ * Format MASK_OP_InstrFormatName_Field
+ */
+
+/* This creates a mask with bits start .. end set to 1 and applies it to op */
+#define MASK_BITS_SHIFT(op, start, end) (extract32(op, (start), \
+(end) - (start) + 1))
+#define MASK_BITS_SHIFT_SEXT(op, start, end) (sextract32(op, (start),\
+ (end) - (start) + 1))
+
+/* new opcode masks */
+
+#define MASK_OP_MAJOR(op)  MASK_BITS_SHIFT(op, 0, 7)
+
+/* 16-Bit Formats */
+#define MASK_OP_SB_DISP8(op)   MASK_BITS_SHIFT(op, 8, 15)
+#define MASK_OP_SB_DISP8_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 8, 15)
+
+#define MASK_OP_SBC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
+#define MASK_OP_SBC_DISP4(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SBR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBR_DISP4(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SBRN_N(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SBRN_DISP4(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SC_CONST8(op)  MASK_BITS_SHIFT(op, 8, 15)
+
+#define MASK_OP_SLR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SLR_D(op)  MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SLRO_OFF4(op)  MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SLRO_D(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SR_OP2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SR_S1D(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRC_CONST4(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRC_CONST4_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 15)
+#define MASK_OP_SRC_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRO_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRO_OFF4(op)   MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRR_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SRRS_S2(op)MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SRRS_S1D(op)   MASK_BITS_SHIFT(op, 8, 11)
+#define MASK_OP_SRRS_N(op) MASK_BITS_SHIFT(op, 6, 7)
+
+#define MASK_OP_SSR_S2(op) MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SSR_S1(op) MASK_BITS_SHIFT(op, 8, 11)
+
+#define MASK_OP_SSRO_OFF4(op)  MASK_BITS_SHIFT(op, 12, 15)
+#define MASK_OP_SSRO_S1(op)MASK_BITS_SHIFT(op, 8, 11)
+
+/* 32-Bit Formats */
+
+/* ABS Format */
+#define MASK_OP_ABS_OFF18(op)  (MASK_BITS_SHIFT(op, 16, 21) +   \
+   (MASK_BITS_SHIFT(op, 28, 31) << 6) + \
+   (MASK_BITS_SHIFT(op, 22, 25) << 10) +\
+   (MASK_BITS_SHIFT(op, 12, 15) << 14))
+#define MASK_OP_ABS_OP2(op)MASK_BITS_SHIFT(op, 26, 27)
+#define MASK_OP_ABS_S1D(op)MASK_BITS_SHIFT(op, 8, 11)
+
+/* ABSB Format */
+#define MASK_OP_ABSB_OFF18(op) MASK_OP_ABS_OFF18(op)
+#define MASK_OP_ABSB_OP2(op)   MASK_BITS_SHIFT(op, 26, 27)
+#define MASK_OP_ABSB_B(op) MASK_BITS_SHIFT(op, 11, 11)
+#define MASK_OP_ABSB_BPOS(op)  MASK_BITS_SHIFT(op, 7, 10)
+
+/* B Format   */
+#define MASK_OP_B_DISP24(op)   (MASK_BITS_SHIFT(op, 16, 31) + \
+   (MASK_BITS_SHIFT(op, 8, 15) << 16))
+/* BIT Format */
+#define MASK_OP_BIT_D(op)  MASK_BITS_SHIFT(op, 28, 31)
+#define

[Qemu-devel] [PATCH v7 00/15] TriCore architecture guest implementation

2014-09-01 Thread Bastian Koppelmann
Hi,

my aim is to add Infineon's TriCore architecture to QEMU. This series of 
patches adds the target stubs, a basic testboard and a softmmu for system mode 
emulation. Furthermore it adds all the 16 bit long instructions of the 
architecture grouped by opcode format.

After this series of patches. Another one will follow, which adds a lot of the 
32 bit long instructions.

All the best

Bastian

v6 -> v7:
- TRICORECPU -> TriCoreCPU.
- TRICORECPUClass -> TriCoreCPUClass.
- CPUTRICOREState -> CPUTriCoreState.
- TRICORECPUInfo: Add terminator.
- TRICORECPUInfo -> TriCoreCPUInfo.
- Remove ARM-style IRQ and FIQ lines.
- CPUTRICOREState: target_ulong -> uint32_t.
- CPUTRICOREState: Move mask defines below the struct.
- tricore_testboard.c: Change Licence to GPL v2.
- fprintf(stderr, ..) -> error_report(..).
- tricore_boot_info: Remove unused fields.
- tricore_testboard.c: Remove flash drive.
- tricore_testboard.c: Is not default anymore, change desc.
- configure: Remove empty disas case. Remove target_phys_bits=32.
- tricore-softmmu.mak: Remove pci, SMC91C111 and PFLASH_CFI01.


Bastian Koppelmann (15):
  target-tricore: Add target stubs and qom-cpu
  target-tricore: Add board for systemmode
  target-tricore: Add softmmu support
  target-tricore: Add initialization for translation and activate target
  target-tricore: Add masks and opcodes for decoding
  target-tricore: Add instructions of SRC opcode format
  target-tricore: Add instructions of SRR opcode format
  target-tricore: Add instructions of SSR opcode format
  target-tricore: Add instructions of SRRS and SLRO opcode format
  target-tricore: Add instructions of SB opcode format
  target-tricore: Add instructions of SBC and SBRN opcode format
  target-tricore: Add instructions of SBR opcode format
  target-tricore: Add instructions of SC opcode format
  target-tricore: Add instructions of SLR, SSRO and SRO opcode format
  target-tricore: Add instructions of SR opcode format

 MAINTAINERS |6 +
 arch_init.c |2 +
 configure   |2 +
 cpu-exec.c  |   11 +-
 cpus.c  |6 +
 default-configs/tricore-softmmu.mak |0
 hw/tricore/Makefile.objs|1 +
 hw/tricore/tricore_testboard.c  |  124 +++
 include/elf.h   |2 +
 include/hw/tricore/tricore.h|   11 +
 include/sysemu/arch_init.h  |1 +
 target-tricore/Makefile.objs|1 +
 target-tricore/cpu-qom.h|   71 ++
 target-tricore/cpu.c|  192 +
 target-tricore/cpu.h|  405 ++
 target-tricore/helper.c |  144 
 target-tricore/helper.h |   25 +
 target-tricore/op_helper.c  |  392 ++
 target-tricore/translate.c  | 1263 +++
 target-tricore/tricore-defs.h   |   28 +
 target-tricore/tricore-opcodes.h| 1406 +++
 21 files changed, 4092 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/tricore-softmmu.mak
 create mode 100644 hw/tricore/Makefile.objs
 create mode 100644 hw/tricore/tricore_testboard.c
 create mode 100644 include/hw/tricore/tricore.h
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 100644 target-tricore/helper.h
 create mode 100644 target-tricore/op_helper.c
 create mode 100644 target-tricore/translate.c
 create mode 100644 target-tricore/tricore-defs.h
 create mode 100644 target-tricore/tricore-opcodes.h

-- 
2.1.0




[Qemu-devel] [PATCH v7 11/15] target-tricore: Add instructions of SBC and SBRN opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SBC and SBRN opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index e13fba7..1bd2642 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -391,6 +391,8 @@ static inline void gen_branch_condi(DisasContext *ctx, 
TCGCond cond, TCGv r1,
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
+TCGv temp;
+
 switch (opc) {
 /* SB-format jumps */
 case OPC1_16_SB_J:
@@ -407,6 +409,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_16_SB_JNZ:
 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
 break;
+/* SBC-format jumps */
+case OPC1_16_SBC_JEQ:
+gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
+break;
+case OPC1_16_SBC_JNE:
+gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
+break;
+/* SBRN-format jumps */
+case OPC1_16_SBRN_JZ_T:
+temp = tcg_temp_new();
+tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
+gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
+tcg_temp_free(temp);
+break;
+case OPC1_16_SBRN_JNZ_T:
+temp = tcg_temp_new();
+tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
+gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
+tcg_temp_free(temp);
+break;
 default:
 printf("Branch Error at %x\n", ctx->pc);
 }
@@ -716,6 +738,20 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
 gen_compute_branch(ctx, op1, 0, 0, 0, address);
 break;
+/* SBC-format */
+case OPC1_16_SBC_JEQ:
+case OPC1_16_SBC_JNE:
+address = MASK_OP_SBC_DISP4(ctx->opcode);
+const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+break;
+/* SBRN-format */
+case OPC1_16_SBRN_JNZ_T:
+case OPC1_16_SBRN_JZ_T:
+address = MASK_OP_SBRN_DISP4(ctx->opcode);
+const16 = MASK_OP_SBRN_N(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+break;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v7 06/15] target-tricore: Add instructions of SRC opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SRC opcode format.
Add micro-op generator functions for add, conditional add/sub and shi/shai.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h|  16 +++
 target-tricore/translate.c | 251 +
 2 files changed, 267 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index e69de29..5884240 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index e06cf41..607a066 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -27,6 +27,7 @@
 #include "exec/helper-gen.h"
 
 #include "tricore-opcodes.h"
+
 /*
  * TCG registers
  */
@@ -102,8 +103,258 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 
 }
 
+/*
+ * Functions to generate micro-ops
+ */
+
+/* Functions for arithmetic instructions  */
+
+static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
+{
+TCGv t0 = tcg_temp_new_i32();
+TCGv result = tcg_temp_new_i32();
+/* Addition and set V/SV bits */
+tcg_gen_add_tl(result, r1, r2);
+/* 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_d(TCGv ret, TCGv r1, target_ulong r2)
+{
+TCGv temp = tcg_const_i32(r2);
+gen_add_d(ret, r1, temp);
+tcg_temp_free(temp);
+}
+
+static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
+TCGv r4)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+TCGv result = tcg_temp_new();
+TCGv mask = tcg_temp_new();
+TCGv t0 = tcg_const_i32(0);
+
+/* create mask for sticky bits */
+tcg_gen_setcond_tl(cond, mask, r4, t0);
+tcg_gen_shli_tl(mask, mask, 31);
+
+tcg_gen_add_tl(result, r1, r2);
+/* Calc PSW_V */
+tcg_gen_xor_tl(temp, result, r1);
+tcg_gen_xor_tl(temp2, r1, r2);
+tcg_gen_andc_tl(temp, temp, temp2);
+tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
+/* Set PSW_SV */
+tcg_gen_and_tl(temp, temp, mask);
+tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
+/* calc AV bit */
+tcg_gen_add_tl(temp, result, result);
+tcg_gen_xor_tl(temp, temp, result);
+tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
+/* calc SAV bit */
+tcg_gen_and_tl(temp, temp, mask);
+tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
+/* write back result */
+tcg_gen_movcond_tl(cond, r3, r4, t0, result, r3);
+
+tcg_temp_free(t0);
+tcg_temp_free(temp);
+tcg_temp_free(temp2);
+tcg_temp_free(result);
+tcg_temp_free(mask);
+}
+
+static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2,
+ TCGv r3, TCGv r4)
+{
+TCGv temp = tcg_const_i32(r2);
+gen_cond_add(cond, r1, temp, r3, r4);
+tcg_temp_free(temp);
+}
+
+static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
+{
+if (shift_count == -32) {
+tcg_gen_movi_tl(ret, 0);
+} else if (shift_count >= 0) {
+tcg_gen_shli_tl(ret, r1, shift_count);
+} else {
+tcg_gen_shri_tl(ret, r1, -shift_count);
+}
+}
+
+static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
+{
+uint32_t msk, msk_start;
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+TCGv t_0 = tcg_const_i32(0);
+
+if (shift_count == 0) {
+/* Clear PSW.C and PSW.V */
+tcg_gen_movi_tl(cpu_PSW_C, 0);
+tcg_gen_mov_tl(cpu_PSW_V, cpu_PSW_C);
+tcg_gen_mov_tl(ret, r1);
+} else if (shift_count == -32) {
+/* set PSW.C */
+tcg_gen_mov_tl(cpu_PSW_C, r1);
+/* fil

[Qemu-devel] [PATCH v7 03/15] target-tricore: Add softmmu support

2014-09-01 Thread Bastian Koppelmann
Add basic softmmu support for TriCore

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- TRICORECPU -> TriCoreCPU.
- CPUTRICOREState -> CPUTriCoreState.

 target-tricore/helper.c| 54 +-
 target-tricore/op_helper.c | 33 +++-
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index ee7f007..e4af6f1 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -24,10 +24,62 @@
 
 #include "cpu.h"
 
+enum {
+TLBRET_DIRTY = -4,
+TLBRET_INVALID = -3,
+TLBRET_NOMATCH = -2,
+TLBRET_BADADDR = -1,
+TLBRET_MATCH = 0
+};
+
+#if defined(CONFIG_SOFTMMU)
+static int get_physical_address(CPUTriCoreState *env, hwaddr *physical,
+int *prot, target_ulong address,
+int rw, int access_type)
+{
+int ret = TLBRET_MATCH;
+
+*physical = address & 0x;
+*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+
+return ret;
+}
+#endif
+
+/* TODO: Add exeption support*/
+static void raise_mmu_exception(CPUTriCoreState *env, target_ulong address,
+int rw, int tlb_error)
+{
+}
+
 int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address,
  int rw, int mmu_idx)
 {
-return 0;
+TriCoreCPU *cpu = TRICORE_CPU(cs);
+CPUTriCoreState *env = &cpu->env;
+hwaddr physical;
+int prot;
+int access_type;
+int ret = 0;
+
+rw &= 1;
+access_type = ACCESS_INT;
+ret = get_physical_address(env, &physical, &prot,
+   address, rw, access_type);
+qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx
+ " prot %d\n", __func__, address, ret, physical, prot);
+
+if (ret == TLBRET_MATCH) {
+tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ mmu_idx, TARGET_PAGE_SIZE);
+ret = 0;
+} else if (ret < 0) {
+raise_mmu_exception(env, address, rw, ret);
+ret = 1;
+}
+
+return ret;
 }
 
 void tricore_cpu_do_interrupt(CPUState *cs)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 275790b..c1342e9 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,8 +20,39 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
+uint32_t exception,
+int error_code,
+uintptr_t pc)
+{
+CPUState *cs = CPU(tricore_env_get_cpu(env));
+cs->exception_index = exception;
+env->error_code = error_code;
+
+if (pc) {
+/* now we have a real cpu fault */
+cpu_restore_state(cs, pc);
+}
+
+cpu_loop_exit(cs);
+}
+
+static inline void QEMU_NORETURN do_raise_exception(CPUTriCoreState *env,
+uint32_t exception,
+uintptr_t pc)
+{
+do_raise_exception_err(env, exception, 0, pc);
+}
+
 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
   uintptr_t retaddr)
 {
+int ret;
+ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
+if (ret) {
+TriCoreCPU *cpu = TRICORE_CPU(cs);
+CPUTriCoreState *env = &cpu->env;
+do_raise_exception_err(env, cs->exception_index,
+   env->error_code, retaddr);
+}
 }
-
-- 
2.1.0




[Qemu-devel] [PATCH v7 04/15] target-tricore: Add initialization for translation and activate target

2014-09-01 Thread Bastian Koppelmann
Add tcg and cpu model initialization.
Add gen_intermediate_code function.
Activate target in configure and add softmmu config.

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- configure: Remove empty disas case. Remove target_phys_bits=32.
- tricore-softmmu.mak: Remove pci, SMC91C111 and PFLASH_CFI01
- CPUTRICOREState -> CPUTriCoreState.

 configure   |   2 +
 default-configs/tricore-softmmu.mak |   0
 target-tricore/translate.c  | 165 
 3 files changed, 167 insertions(+)
 create mode 100644 default-configs/tricore-softmmu.mak

diff --git a/configure b/configure
index 2063cf6..021b3cf 100755
--- a/configure
+++ b/configure
@@ -5045,6 +5045,8 @@ case "$target_name" in
 TARGET_BASE_ARCH=mips
 echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
   ;;
+  tricore)
+  ;;
   moxie)
   ;;
   or32)
diff --git a/default-configs/tricore-softmmu.mak 
b/default-configs/tricore-softmmu.mak
new file mode 100644
index 000..e69de29
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index fae1b1a..7691b11 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,26 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+/*
+ * TCG registers
+ */
+static TCGv cpu_PC;
+static TCGv cpu_PCXI;
+static TCGv cpu_PSW;
+static TCGv cpu_ICR;
+/* GPR registers */
+static TCGv cpu_gpr_a[16];
+static TCGv cpu_gpr_d[16];
+/* PSW Flag cache */
+static TCGv cpu_PSW_C;
+static TCGv cpu_PSW_V;
+static TCGv cpu_PSW_SV;
+static TCGv cpu_PSW_AV;
+static TCGv cpu_PSW_SAV;
+/* CPU env */
+static TCGv_ptr cpu_env;
+
+#include "exec/gen-icount.h"
 
 static const char *regnames_a[] = {
   "a0"  , "a1"  , "a2"  , "a3" , "a4"  , "a5" ,
@@ -39,6 +59,25 @@ static const char *regnames_d[] = {
   "d12" , "d13" , "d14" , "d15",
 };
 
+typedef struct DisasContext {
+struct TranslationBlock *tb;
+target_ulong pc, saved_pc, next_pc;
+uint32_t opcode;
+int singlestep_enabled;
+/* Routine used to access memory */
+int mem_idx;
+uint32_t hflags, saved_hflags;
+int bstate;
+} DisasContext;
+
+enum {
+
+BS_NONE   = 0,
+BS_STOP   = 1,
+BS_BRANCH = 2,
+BS_EXCP   = 3,
+};
+
 void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 fprintf_function cpu_fprintf, int flags)
 {
@@ -62,10 +101,88 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 
 }
 
+static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
+{
+}
+
+static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
+{
+}
+
+static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
+{
+/* 16-Bit Instruction */
+if ((ctx->opcode & 0x1) == 0) {
+ctx->next_pc = ctx->pc + 2;
+decode_16Bit_opc(env, ctx);
+/* 32-Bit Instruction */
+} else {
+ctx->next_pc = ctx->pc + 4;
+decode_32Bit_opc(env, ctx);
+}
+}
+
 static inline void
 gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,
   int search_pc)
 {
+CPUState *cs = CPU(cpu);
+CPUTriCoreState *env = &cpu->env;
+DisasContext ctx;
+target_ulong pc_start;
+int num_insns;
+uint16_t *gen_opc_end;
+
+if (search_pc) {
+qemu_log("search pc %d\n", search_pc);
+}
+
+num_insns = 0;
+pc_start = tb->pc;
+gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
+ctx.pc = pc_start;
+ctx.saved_pc = -1;
+ctx.tb = tb;
+ctx.singlestep_enabled = cs->singlestep_enabled;
+ctx.bstate = BS_NONE;
+ctx.mem_idx = cpu_mmu_index(env);
+
+tcg_clear_temp_count();
+gen_tb_start();
+while (ctx.bstate == BS_NONE) {
+ctx.opcode = cpu_ldl_code(env, ctx.pc);
+decode_opc(env, &ctx, 0);
+
+num_insns++;
+
+if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
+break;
+}
+if (singlestep) {
+break;
+}
+ctx.pc = ctx.next_pc;
+}
+
+gen_tb_end(tb, num_insns);
+*tcg_ctx.gen_opc_ptr = INDEX_op_end;
+if (search_pc) {
+printf("done_generating search pc\n");
+} else {
+tb->size = ctx.pc - pc_start;
+tb->icount = num_insns;
+}
+if (tcg_check_temp_count()) {
+printf("LEAK at %08x\n", env->PC);
+}
+
+#ifdef DEBUG_DISAS
+if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+qemu_log("IN: %s\n", lookup_symbol(pc_start));
+log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
+qemu_log("\n");
+}
+#endif
 }
 
 void
@@ -93,8 +210,56 @@ restore_state_to_opc(CPUTriCoreState *env, TranslationBlock 
*tb, int pc_pos)
 
 void cpu_state_reset(CPU

[Qemu-devel] [PATCH v7 10/15] target-tricore: Add instructions of SB opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SB opcode format.
Add helper call/ret.
Add micro-op generator functions for branches.
Add makro to generate helper functions.

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- CPUTRICOREState -> CPUTriCoreState.

 target-tricore/helper.h|   3 +
 target-tricore/op_helper.c | 180 +
 target-tricore/translate.c |  93 +++
 3 files changed, 276 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 299bd77..adf5b26 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -18,3 +18,6 @@
 /* Arithmetic */
 DEF_HELPER_3(add_ssov, i32, env, i32, i32)
 DEF_HELPER_3(sub_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 664a100..990d463 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -63,6 +63,186 @@ target_ulong helper_sub_ssov(CPUTriCoreState *env, 
target_ulong r1,
 return ret;
 }
 
+/* context save area (CSA) related helpers */
+
+static int cdc_increment(target_ulong *psw)
+{
+if ((*psw & MASK_PSW_CDC) == 0x7f) {
+return 0;
+}
+
+(*psw)++;
+/* check for overflow */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+if (count == 0) {
+(*psw)--;
+return 1;
+}
+return 0;
+}
+
+static int cdc_decrement(target_ulong *psw)
+{
+if ((*psw & MASK_PSW_CDC) == 0x7f) {
+return 0;
+}
+/* check for underflow */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+if (count == 0) {
+return 1;
+}
+(*psw)--;
+return 0;
+}
+
+static void save_context_upper(CPUTriCoreState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[10]);
+cpu_stl_data(env, ea+12, env->gpr_a[11]);
+cpu_stl_data(env, ea+16, env->gpr_d[8]);
+cpu_stl_data(env, ea+20, env->gpr_d[9]);
+cpu_stl_data(env, ea+24, env->gpr_d[10]);
+cpu_stl_data(env, ea+28, env->gpr_d[11]);
+cpu_stl_data(env, ea+32, env->gpr_a[12]);
+cpu_stl_data(env, ea+36, env->gpr_a[13]);
+cpu_stl_data(env, ea+40, env->gpr_a[14]);
+cpu_stl_data(env, ea+44, env->gpr_a[15]);
+cpu_stl_data(env, ea+48, env->gpr_d[12]);
+cpu_stl_data(env, ea+52, env->gpr_d[13]);
+cpu_stl_data(env, ea+56, env->gpr_d[14]);
+cpu_stl_data(env, ea+60, env->gpr_d[15]);
+
+}
+
+static void restore_context_upper(CPUTriCoreState *env, int ea,
+  target_ulong *new_PCXI, target_ulong 
*new_PSW)
+{
+*new_PCXI = cpu_ldl_data(env, ea);
+*new_PSW = cpu_ldl_data(env, ea+4);
+env->gpr_a[10] = cpu_ldl_data(env, ea+8);
+env->gpr_a[11] = cpu_ldl_data(env, ea+12);
+env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
+env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
+env->gpr_d[10] = cpu_ldl_data(env, ea+24);
+env->gpr_d[11] = cpu_ldl_data(env, ea+28);
+env->gpr_a[12] = cpu_ldl_data(env, ea+32);
+env->gpr_a[13] = cpu_ldl_data(env, ea+36);
+env->gpr_a[14] = cpu_ldl_data(env, ea+40);
+env->gpr_a[15] = cpu_ldl_data(env, ea+44);
+env->gpr_d[12] = cpu_ldl_data(env, ea+48);
+env->gpr_d[13] = cpu_ldl_data(env, ea+52);
+env->gpr_d[14] = cpu_ldl_data(env, ea+56);
+env->gpr_d[15] = cpu_ldl_data(env, ea+60);
+cpu_stl_data(env, ea, env->FCX);
+}
+
+void helper_call(CPUTriCoreState *env, uint32_t next_pc)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+target_ulong psw;
+
+psw = psw_read(env);
+/* if (FCX == 0) trap(FCU); */
+if (env->FCX == 0) {
+/* FCU trap */
+}
+/* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
+if (psw & MASK_PSW_CDE) {
+if (cdc_increment(&psw)) {
+/* CDO trap */
+}
+}
+/* PSW.CDE = 1;*/
+psw |= MASK_PSW_CDE;
+/* tmp_FCX = FCX; */
+tmp_FCX = env->FCX;
+/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
+ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
+ ((env->FCX & MASK_FCX_FCXO) << 6);
+/* new_FCX = M(EA, word);
+   M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+  A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+  D[15]}; */
+save_context_upper(env, ea, &new_FCX);
+
+/* PCXI.PCPN = ICR.CCPN; */
+env->PCXI = (env->PCXI & 0xff) +
+((env->

[Qemu-devel] [PATCH v7 09/15] target-tricore: Add instructions of SRRS and SLRO opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SSRS and SLRO opcode format.
Add micro-op generator functions for offset loads.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 59 ++
 1 file changed, 59 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d8e23fc..258f4e4 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -107,6 +107,26 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
  * Functions to generate micro-ops
  */
 
+/* Functions for load/save to/from memory */
+
+static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
+ int16_t con, TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, con);
+tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
+tcg_temp_free(temp);
+}
+
+static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2,
+ int16_t con, TCGMemOp mop)
+{
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, r2, con);
+tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
+tcg_temp_free(temp);
+}
+
 /* Functions for arithmetic instructions  */
 
 static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
@@ -513,9 +533,17 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
 int op1;
+int r1, r2;
+int32_t const16;
+TCGv temp;
 
 op1 = MASK_OP_MAJOR(ctx->opcode);
 
+/* handle ADDSC.A opcode only being 6 bit long */
+if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
+op1 = OPC1_16_SRRS_ADDSC_A;
+}
+
 switch (op1) {
 case OPC1_16_SRC_ADD:
 case OPC1_16_SRC_ADD_A15:
@@ -568,6 +596,37 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC1_16_SSR_ST_W_POSTINC:
 decode_ssr_opc(ctx, op1);
 break;
+/* SRRS-format */
+case OPC1_16_SRRS_ADDSC_A:
+r2 = MASK_OP_SRRS_S2(ctx->opcode);
+r1 = MASK_OP_SRRS_S1D(ctx->opcode);
+const16 = MASK_OP_SRRS_N(ctx->opcode);
+temp = tcg_temp_new();
+tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
+tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
+tcg_temp_free(temp);
+break;
+/* SLRO-format */
+case OPC1_16_SLRO_LD_A:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SLRO_LD_BU:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
+break;
+case OPC1_16_SLRO_LD_H:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
+break;
+case OPC1_16_SLRO_LD_W:
+r1 = MASK_OP_SLRO_D(ctx->opcode);
+const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
+gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v7 08/15] target-tricore: Add instructions of SSR opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SSR opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 717a42d..d8e23fc 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -471,6 +471,45 @@ static void decode_srr_opc(DisasContext *ctx, int op1)
 }
 }
 
+static void decode_ssr_opc(DisasContext *ctx, int op1)
+{
+int r1, r2;
+
+r1 = MASK_OP_SSR_S1(ctx->opcode);
+r2 = MASK_OP_SSR_S2(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SSR_ST_A:
+tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+break;
+case OPC1_16_SSR_ST_A_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+case OPC1_16_SSR_ST_B:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+break;
+case OPC1_16_SSR_ST_B_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
+break;
+case OPC1_16_SSR_ST_H:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUW);
+break;
+case OPC1_16_SSR_ST_H_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
+break;
+case OPC1_16_SSR_ST_W:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+break;
+case OPC1_16_SSR_ST_W_POSTINC:
+tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LEUL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+}
+}
+
 static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
 int op1;
@@ -518,6 +557,17 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC1_16_SRR_XOR:
 decode_srr_opc(ctx, op1);
 break;
+/* SSR-format */
+case OPC1_16_SSR_ST_A:
+case OPC1_16_SSR_ST_A_POSTINC:
+case OPC1_16_SSR_ST_B:
+case OPC1_16_SSR_ST_B_POSTINC:
+case OPC1_16_SSR_ST_H:
+case OPC1_16_SSR_ST_H_POSTINC:
+case OPC1_16_SSR_ST_W:
+case OPC1_16_SSR_ST_W_POSTINC:
+decode_ssr_opc(ctx, op1);
+break;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v7 12/15] target-tricore: Add instructions of SBR opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SBR opcode format.
Add gen_loop micro-op generator function.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 66 +-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 1bd2642..74db70d 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -388,6 +388,18 @@ static inline void gen_branch_condi(DisasContext *ctx, 
TCGCond 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_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
+gen_goto_tb(ctx, 1, ctx->pc + offset);
+gen_set_label(l1);
+gen_goto_tb(ctx, 0, ctx->next_pc);
+}
+
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
@@ -429,8 +441,44 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
 tcg_temp_free(temp);
 break;
+/* SBR-format jumps */
+case OPC1_16_SBR_JEQ:
+gen_branch_cond(ctx, TCG_COND_EQ, 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, offset * 2 - 32);
+break;
 default:
-printf("Branch Error at %x\n", ctx->pc);
+printf("Branch Error at %x\n", ctx->pc);
 }
 ctx->bstate = BS_BRANCH;
 }
@@ -752,6 +800,22 @@ 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;
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v7 14/15] target-tricore: Add instructions of SLR, SSRO and SRO opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SLR, SSRO and SRO opcode format.

Signed-off-by: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 121 +
 1 file changed, 121 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 5298712..e24479d 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -716,6 +716,84 @@ static void decode_sc_opc(DisasContext *ctx, int op1)
 break;
 }
 }
+
+static void decode_slr_opc(DisasContext *ctx, int op1)
+{
+int r1, r2;
+
+r1 = MASK_OP_SLR_D(ctx->opcode);
+r2 = MASK_OP_SLR_S2(ctx->opcode);
+
+switch (op1) {
+/* SLR-format */
+case OPC1_16_SLR_LD_A:
+tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESL);
+break;
+case OPC1_16_SLR_LD_A_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESL);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+case OPC1_16_SLR_LD_BU:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+break;
+case OPC1_16_SLR_LD_BU_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
+break;
+case OPC1_16_SLR_LD_H:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+break;
+case OPC1_16_SLR_LD_H_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
+break;
+case OPC1_16_SLR_LD_W:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+break;
+case OPC1_16_SLR_LD_W_POSTINC:
+tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, 
MO_LESW);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
+break;
+}
+}
+
+static void decode_sro_opc(DisasContext *ctx, int op1)
+{
+int r2;
+int32_t address;
+
+r2 = MASK_OP_SRO_S2(ctx->opcode);
+address = MASK_OP_SRO_OFF4(ctx->opcode);
+
+/* SRO-format */
+switch (op1) {
+case OPC1_16_SRO_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_LD_BU:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
+break;
+case OPC1_16_SRO_LD_H:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW);
+break;
+case OPC1_16_SRO_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+case OPC1_16_SRO_ST_B:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
+break;
+case OPC1_16_SRO_ST_H:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
+break;
+case OPC1_16_SRO_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
+break;
+}
+}
+
 static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
 int op1;
@@ -864,6 +942,49 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC1_16_SC_SUB_A:
 decode_sc_opc(ctx, op1);
 break;
+/* SLR-format */
+case OPC1_16_SLR_LD_A:
+case OPC1_16_SLR_LD_A_POSTINC:
+case OPC1_16_SLR_LD_BU:
+case OPC1_16_SLR_LD_BU_POSTINC:
+case OPC1_16_SLR_LD_H:
+case OPC1_16_SLR_LD_H_POSTINC:
+case OPC1_16_SLR_LD_W:
+case OPC1_16_SLR_LD_W_POSTINC:
+decode_slr_opc(ctx, op1);
+break;
+/* SRO-format */
+case OPC1_16_SRO_LD_A:
+case OPC1_16_SRO_LD_BU:
+case OPC1_16_SRO_LD_H:
+case OPC1_16_SRO_LD_W:
+case OPC1_16_SRO_ST_A:
+case OPC1_16_SRO_ST_B:
+case OPC1_16_SRO_ST_H:
+case OPC1_16_SRO_ST_W:
+decode_sro_opc(ctx, op1);
+break;
+/* SSRO-format */
+case OPC1_16_SSRO_ST_A:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SSRO_ST_B:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
+break;
+case OPC1_16_SSRO_ST_H:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
+break;
+case OPC1_16_SSRO_ST_W:
+r1 = MASK_OP_SSRO_S1(ctx->opcode);
+const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
+gen_offset_st(ctx, cpu_gpr

[Qemu-devel] [PATCH v7 07/15] target-tricore: Add instructions of SRR opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SRR opcode format.
Add helper for add/sub_ssov.

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- CPUTRICOREState -> CPUTriCoreState.

 target-tricore/helper.h|   4 ++
 target-tricore/op_helper.c |  43 
 target-tricore/translate.c | 164 +
 3 files changed, 211 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 5884240..299bd77 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -14,3 +14,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+
+/* Arithmetic */
+DEF_HELPER_3(add_ssov, i32, env, i32, i32)
+DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index c1342e9..664a100 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,49 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 
+#define SSOV(env, ret, arg, len) do {   \
+int64_t max_pos = INT##len ##_MAX;  \
+int64_t max_neg = INT##len ##_MIN;  \
+if (arg > max_pos) {\
+env->PSW_USB_V = (1 << 31); \
+env->PSW_USB_SV = (1 << 31);\
+ret = (target_ulong)max_pos;\
+} else {\
+if (arg < max_neg) {\
+env->PSW_USB_V = (1 << 31); \
+env->PSW_USB_SV = (1 << 31);\
+ret = (target_ulong)max_neg;\
+} 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)
+{
+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_sub_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;
+}
+
 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 607a066..717a42d 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -187,6 +187,53 @@ static inline void gen_condi_add(TCGCond cond, TCGv r1, 
int32_t r2,
 tcg_temp_free(temp);
 }
 
+static inline void gen_sub_d(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);
+/* calc V bit */
+tcg_gen_xor_tl(cpu_PSW_V, result, r1);
+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_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
+{
+TCGv high = tcg_temp_new();
+TCGv low = tcg_temp_new();
+
+tcg_gen_muls2_tl(low, high, r1, r2);
+tcg_gen_mov_tl(ret, low);
+/* calc V bit */
+tcg_gen_sari_tl(low, low, 31);
+tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
+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 bit */
+tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+/* calc SAV bit */
+tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+tcg_temp_free(high);
+tcg_temp_free(low);
+}
+
 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
 {
 if (shift_count == -32) {
@@ -257,6 +304,16 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t 
shift_count)
 tcg_temp_free(t_0);
 }
 
+static inline void

[Qemu-devel] [PATCH v7 15/15] target-tricore: Add instructions of SR opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SR opcode format.
Add micro-op generator functions for saturate.
Add helper return from exception (rfe).

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- CPUTRICOREState -> CPUTriCoreState.

 target-tricore/helper.h|   1 +
 target-tricore/op_helper.c |  52 +
 target-tricore/translate.c | 111 +
 3 files changed, 164 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 3c73234..7b7d74b 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -22,3 +22,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
 DEF_HELPER_2(bisr, void, env, i32)
+DEF_HELPER_1(rfe, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index bb55a49..6376f07 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -99,6 +99,21 @@ static int cdc_decrement(target_ulong *psw)
 return 0;
 }
 
+static bool cdc_zero(target_ulong *psw)
+{
+int cdc = *psw & MASK_PSW_CDC;
+/* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
+   7'b111, otherwise returns FALSE. */
+if (cdc == 0x7f) {
+return true;
+}
+/* find CDC.COUNT */
+int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+int mask = (1u << (7 - lo)) - 1;
+int count = *psw & mask;
+return count == 0;
+}
+
 static void save_context_upper(CPUTriCoreState *env, int ea,
target_ulong *new_FCX)
 {
@@ -302,6 +317,43 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
 }
 }
 
+void helper_rfe(CPUTriCoreState *env)
+{
+target_ulong ea;
+target_ulong new_PCXI;
+target_ulong new_PSW;
+/* if (PCXI[19: 0] == 0) then trap(CSU); */
+if ((env->PCXI & 0xf) == 0) {
+/* raise csu trap */
+}
+/* if (PCXI.UL == 0) then trap(CTYP); */
+if ((env->PCXI & MASK_PCXI_UL) == 0) {
+/* raise CTYP trap */
+}
+/* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
+if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
+/* raise MNG trap */
+}
+/* ICR.IE = PCXI.PIE; */
+env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
+/* ICR.CCPN = PCXI.PCPN; */
+env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
+   ((env->PCXI & MASK_PCXI_PCPN) >> 24);
+/*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
+ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
+ ((env->PCXI & MASK_PCXI_PCXO) << 6);
+/*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
+  A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
+  M(EA, word) = FCX;*/
+restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+/* FCX[19: 0] = PCXI[19: 0]; */
+env->FCX = (env->FCX & 0xfff0) + (env->PCXI & 0x000f);
+/* PCXI = new_PCXI; */
+env->PCXI = new_PCXI;
+/* write psw */
+psw_write(env, new_PSW);
+}
+
 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 e24479d..4f654de 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -262,6 +262,29 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
 tcg_temp_free(low);
 }
 
+static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
+{
+TCGv sat_neg = tcg_const_i32(low);
+TCGv temp = tcg_const_i32(up);
+
+/* sat_neg = (arg < low ) ? low : arg; */
+tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
+
+/* ret = (sat_neg > up ) ? up  : sat_neg; */
+tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+
+tcg_temp_free(sat_neg);
+tcg_temp_free(temp);
+}
+
+static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
+{
+TCGv temp = tcg_const_i32(up);
+/* sat_neg = (arg > up ) ? up : arg; */
+tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+tcg_temp_free(temp);
+}
+
 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
 {
 if (shift_count == -32) {
@@ -477,6 +500,15 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t 
opc, int r1,
 case OPC1_16_SBR_LOOP:
 gen_loop(ctx, r1, offset * 2 - 32);
 break;
+/* SR-format jumps */
+case OPC1_16_SR_JI:
+tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffe);
+tcg_gen_exit_tb(0);
+break;
+case OPC2_16_SR_RET:
+gen_helper_ret(cpu_env);
+tcg_gen_exit_tb(0);
+break;
 default:
 printf("Br

[Qemu-devel] [PATCH v7 13/15] target-tricore: Add instructions of SC opcode format

2014-09-01 Thread Bastian Koppelmann
Add instructions of SC opcode format.
Add helper for begin interrupt service routine.

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
- CPUTRICOREState -> CPUTriCoreState.

 target-tricore/helper.h|  1 +
 target-tricore/op_helper.c | 59 ++
 target-tricore/translate.c | 48 +
 3 files changed, 108 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index adf5b26..3c73234 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -21,3 +21,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 /* CSA */
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
+DEF_HELPER_2(bisr, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 990d463..bb55a49 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -122,6 +122,28 @@ static void save_context_upper(CPUTriCoreState *env, int 
ea,
 
 }
 
+static void save_context_lower(CPUTriCoreState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[2]);
+cpu_stl_data(env, ea+12, env->gpr_a[3]);
+cpu_stl_data(env, ea+16, env->gpr_d[0]);
+cpu_stl_data(env, ea+20, env->gpr_d[1]);
+cpu_stl_data(env, ea+24, env->gpr_d[2]);
+cpu_stl_data(env, ea+28, env->gpr_d[3]);
+cpu_stl_data(env, ea+32, env->gpr_a[4]);
+cpu_stl_data(env, ea+36, env->gpr_a[5]);
+cpu_stl_data(env, ea+40, env->gpr_a[6]);
+cpu_stl_data(env, ea+44, env->gpr_a[7]);
+cpu_stl_data(env, ea+48, env->gpr_d[4]);
+cpu_stl_data(env, ea+52, env->gpr_d[5]);
+cpu_stl_data(env, ea+56, env->gpr_d[6]);
+cpu_stl_data(env, ea+60, env->gpr_d[7]);
+}
+
 static void restore_context_upper(CPUTriCoreState *env, int ea,
   target_ulong *new_PCXI, target_ulong 
*new_PSW)
 {
@@ -243,6 +265,43 @@ void helper_ret(CPUTriCoreState *env)
 }
 }
 
+void helper_bisr(CPUTriCoreState *env, uint32_t const9)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+
+if (env->FCX == 0) {
+/* FCU trap */
+}
+
+tmp_FCX = env->FCX;
+ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
+
+save_context_lower(env, ea, &new_FCX);
+
+/* PCXI.PCPN = ICR.CCPN */
+env->PCXI = (env->PCXI & 0xff) +
+ ((env->ICR & MASK_ICR_CCPN) << 24);
+/* PCXI.PIE  = ICR.IE */
+env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
+ ((env->ICR & MASK_ICR_IE) << 15));
+/* PCXI.UL = 0 */
+env->PCXI &= ~(MASK_PCXI_UL);
+/* PCXI[19: 0] = FCX[19: 0] */
+env->PCXI = (env->PCXI & 0xfff0) + (env->FCX & 0xf);
+/* FXC[19: 0] = new_FCX[19: 0] */
+env->FCX = (env->FCX & 0xfff0) + (new_FCX & 0xf);
+/* ICR.IE = 1 */
+env->ICR |= MASK_ICR_IE;
+
+env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
+
+if (tmp_FCX == env->LCX) {
+/* FCD trap */
+}
+}
+
 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 74db70d..5298712 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -680,6 +680,42 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 }
 }
 
+static void decode_sc_opc(DisasContext *ctx, int op1)
+{
+int32_t const16;
+
+const16 = MASK_OP_SC_CONST8(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SC_AND:
+tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_BISR:
+gen_helper_1arg(bisr, const16 & 0xff);
+break;
+case OPC1_16_SC_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_MOV:
+tcg_gen_movi_tl(cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_OR:
+tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_SUB_A:
+tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
+break;
+}
+}
 static void decode_16Bit_opc(

Re: [Qemu-devel] [PATCH v7 02/15] target-tricore: Add board for systemmode

2014-09-01 Thread Bastian Koppelmann

Hi Peter,

On 09/01/2014 01:48 PM, Peter Maydell wrote:

On 1 September 2014 12:59, Bastian Koppelmann
 wrote:

Add basic board to allow systemmode emulation

Signed-off-by: Bastian Koppelmann 
---
v6 -> v7:
 - TRICORECPU -> TriCoreCPU.
 - CPUTRICOREState -> CPUTriCoreState.
 - tricore_testboard.c: Change Licence to GPL v2.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.


yep, LGPL 2+ is fine for me. Thanks for check :).


...the text you've actually used is LGPL 2+, not GPL2+. That's
fine if that's what you wanted, but I thought I'd check given the
difference between changelog and change.

thanks
-- PMM






[Qemu-devel] [PATCH] arch_init: Setting QEMU_ARCH enum straight

2014-09-08 Thread Bastian Koppelmann
Every QEMU_ARCH is now hexadecimal instead of a mixture of decimal and 
hexadecimal.

Signed-off-by: Bastian Koppelmann 
---
 include/sysemu/arch_init.h | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 8939233..e1ec025 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -5,21 +5,21 @@
 #include "qemu/option.h"
 
 enum {
-QEMU_ARCH_ALL = -1,
-QEMU_ARCH_ALPHA = 1,
-QEMU_ARCH_ARM = 2,
-QEMU_ARCH_CRIS = 4,
-QEMU_ARCH_I386 = 8,
-QEMU_ARCH_M68K = 16,
-QEMU_ARCH_LM32 = 32,
-QEMU_ARCH_MICROBLAZE = 64,
-QEMU_ARCH_MIPS = 128,
-QEMU_ARCH_PPC = 256,
-QEMU_ARCH_S390X = 512,
-QEMU_ARCH_SH4 = 1024,
-QEMU_ARCH_SPARC = 2048,
-QEMU_ARCH_XTENSA = 4096,
-QEMU_ARCH_OPENRISC = 8192,
+QEMU_ARCH_ALL = -0x1,
+QEMU_ARCH_ALPHA = 0x1,
+QEMU_ARCH_ARM = 0x2,
+QEMU_ARCH_CRIS = 0x4,
+QEMU_ARCH_I386 = 0x8,
+QEMU_ARCH_M68K = 0x10,
+QEMU_ARCH_LM32 = 0x20,
+QEMU_ARCH_MICROBLAZE = 0x40,
+QEMU_ARCH_MIPS = 0x80,
+QEMU_ARCH_PPC = 0x100,
+QEMU_ARCH_S390X = 0x200,
+QEMU_ARCH_SH4 = 0x400,
+QEMU_ARCH_SPARC = 0x800,
+QEMU_ARCH_XTENSA = 0x1000,
+QEMU_ARCH_OPENRISC = 0x2000,
 QEMU_ARCH_UNICORE32 = 0x4000,
 QEMU_ARCH_MOXIE = 0x8000,
 QEMU_ARCH_TRICORE = 0x1,
-- 
2.1.0




[Qemu-devel] [PATCH v2 06/15] target-tricore: Add instructions of SRC opcode format

2014-07-14 Thread Bastian Koppelmann
Add instructions of SRC opcode format.
Add helper for sh arithmetic carry.
Add micro-op generator functions for conditional add/sub and shi.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- helper_shac uses sextract32 for the constant and add len parameter.
- Replace else case with signed right shift in helper_shac.
- Remove sign_extend function and use sextract32 instead.
- Replace branches in OP_COND makro with movcond.
- Remove gen_cond_mov and use tcg_gen_movcond_tl instead.
- Remove gen_sh and and change gen_shi to a special case.
- Moved all SRC instructions to one decode function.

 target-tricore/helper.h|  19 ++
 target-tricore/op_helper.c |  32 +
 target-tricore/translate.c | 162 +
 3 files changed, 213 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index e69de29..87c423c 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -0,0 +1,19 @@
+/*
+ *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Arithmetic */
+DEF_HELPER_4(shac, i32, env, i32, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 2e5981f..1d1c9d8 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,38 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"

+
+target_ulong helper_shac(CPUTRICOREState *env, target_ulong r1,
+ target_ulong r2, target_ulong len)
+{
+target_ulong carry_out, msk, msk_start, msk_len, ret;
+int32_t shift_count;
+int const6;
+const6 = sextract32(r2, 0, len);
+
+if (const6 >= 0) {
+if (const6 != 0) {
+msk_start = 32 - const6;
+msk_len = 31-msk_start;
+msk = ((1 << msk_len) - 1) << msk_start;
+carry_out = ((r1 & msk) != 0);
+} else {
+carry_out = 0;
+}
+ret = r1 << const6;
+} else {
+
+shift_count = 0 - const6;
+ret = (int32_t)r1 >> shift_count;
+msk = (1 << (shift_count - 1)) - 1;
+carry_out = ((r1 & msk) != 0);
+}
+if (carry_out) {
+/* TODO: carry out */
+}
+return ret;
+}
+
 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 19250e1..3d59709 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -27,6 +27,7 @@
 #include "exec/helper-gen.h"

 #include "tricore-opcodes.h"
+
 /*
  * TCG registers
  */
@@ -94,8 +95,169 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,

 }

+/*
+ * Functions to generate micro-ops
+ */
+/* Functions for arithmetic instructions  */
+
+#define OP_COND(insn)\
+static inline void gen_cond_##insn(int cond, TCGv r1, TCGv r2, TCGv r3, \
+   TCGv r4) \
+{   \
+TCGv temp = tcg_temp_new(); \
+TCGv temp2 = tcg_const_tl(0);   \
+\
+tcg_gen_##insn ## _tl(temp, r1, r2);\
+tcg_gen_movcond_tl(cond, r3, r4, temp2, temp, r3);  \
+\
+tcg_temp_free(temp);\
+tcg_temp_free(temp2);   \
+}   \
+\
+static inline void gen_condi_##insn(int cond, TCGv r1, int32_t r2,  \
+TCGv r3, TCGv r4)   \
+{   \
+TCGv temp = tcg_const_i32(r2);  \
+gen

[Qemu-devel] [PATCH v2 13/15] target-tricore: Add instructions of SC opcode format

2014-07-14 Thread Bastian Koppelmann
Add instructions of SC opcode format.
Add helper for begin interrupt service routine.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- Add save_context_lower. (see patch v2 10/15)
- Remove printfs in helper_bisr.
- Add one decode function for all SC instructions.

 target-tricore/helper.h|  1 +
 target-tricore/op_helper.c | 59 ++
 target-tricore/translate.c | 48 +
 3 files changed, 108 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 7593b92..ce64dc2 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -22,3 +22,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
 /* CSA */
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
+DEF_HELPER_2(bisr, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 24acbd7..862b255 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -148,6 +148,28 @@ static void save_context_upper(CPUTRICOREState *env, int 
ea,

 }

+static void save_context_lower(CPUTRICOREState *env, int ea,
+   target_ulong *new_FCX)
+{
+*new_FCX = cpu_ldl_data(env, ea);
+cpu_stl_data(env, ea, env->PCXI);
+cpu_stl_data(env, ea+4, env->PSW);
+cpu_stl_data(env, ea+8, env->gpr_a[2]);
+cpu_stl_data(env, ea+12, env->gpr_a[3]);
+cpu_stl_data(env, ea+16, env->gpr_d[0]);
+cpu_stl_data(env, ea+20, env->gpr_d[1]);
+cpu_stl_data(env, ea+24, env->gpr_d[2]);
+cpu_stl_data(env, ea+28, env->gpr_d[3]);
+cpu_stl_data(env, ea+32, env->gpr_a[4]);
+cpu_stl_data(env, ea+36, env->gpr_a[5]);
+cpu_stl_data(env, ea+40, env->gpr_a[6]);
+cpu_stl_data(env, ea+44, env->gpr_a[7]);
+cpu_stl_data(env, ea+48, env->gpr_d[4]);
+cpu_stl_data(env, ea+52, env->gpr_d[5]);
+cpu_stl_data(env, ea+56, env->gpr_d[6]);
+cpu_stl_data(env, ea+60, env->gpr_d[7]);
+}
+
 static void restore_context_upper(CPUTRICOREState *env, int ea,
   target_ulong *new_PCXI, target_ulong 
*new_PSW)
 {
@@ -256,6 +278,43 @@ void helper_ret(CPUTRICOREState *env)
 env->PCXI = new_PCXI;
 }

+void helper_bisr(CPUTRICOREState *env, uint32_t const9)
+{
+target_ulong tmp_FCX;
+target_ulong ea;
+target_ulong new_FCX;
+
+if (env->FCX == 0) {
+/* FCU trap */
+}
+
+tmp_FCX = env->FCX;
+ea = ((env->FCX & 0xf) << 12) + ((env->FCX & 0x) << 6);
+
+save_context_lower(env, ea, &new_FCX);
+
+/* PCXI.PCPN = ICR.CCPN */
+env->PCXI = (env->PCXI & 0xff) +
+ ((env->ICR & MASK_ICR_CCPN) << 24);
+/* PCXI.PIE  = ICR.IE */
+env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
+ ((env->ICR & MASK_ICR_IE) << 15));
+/* PCXI.UL = 0 */
+env->PCXI &= ~(MASK_PCXI_UL);
+/* PCXI[19: 0] = FCX[19: 0] */
+env->PCXI = (env->PCXI & 0xfff0) + (env->FCX & 0xf);
+/* FXC[19: 0] = new_FCX[19: 0] */
+env->FCX = (env->FCX & 0xfff0) + (new_FCX & 0xf);
+/* ICR.IE = 1 */
+env->ICR |= MASK_ICR_IE;
+
+env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
+
+if (tmp_FCX == env->LCX) {
+/* FCD trap */
+}
+}
+
 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 a4f1419..ec98c15 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -538,6 +538,42 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
 }
 }

+static void decode_sc_opc(DisasContext *ctx, int op1)
+{
+int32_t const16;
+
+const16 = MASK_OP_SC_CONST8(ctx->opcode);
+
+switch (op1) {
+case OPC1_16_SC_AND:
+tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_BISR:
+gen_helper_1arg(bisr, const16 & 0xff);
+break;
+case OPC1_16_SC_LD_A:
+gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_LD_W:
+gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_MOV:
+tcg_gen_movi_tl(cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_OR:
+tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
+break;
+case OPC1_16_SC_ST_A:
+gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_ST_W:
+gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
+break;
+case OPC1_16_SC_SUB_A:
+ 

[Qemu-devel] [PATCH v2 01/15] target-tricore: Add target stubs and qom-cpu

2014-07-14 Thread Bastian Koppelmann
Add TriCore target stubs, and QOM cpu.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- Move activation of target patch1->patch4.
- Remove host related in configure.
- Remove host related code in user-exec.
- Remove active_tc struct.
- Change define GPR first, then CSFR.
- Fixed QEMU_ARCH_TRICORE using the right number.

 arch_init.c |   2 +
 cpu-exec.c  |  11 +-
 cpus.c  |   6 +
 include/elf.h   |   2 +
 include/sysemu/arch_init.h  |   1 +
 target-tricore/Makefile.objs|   1 +
 target-tricore/cpu-qom.h|  71 
 target-tricore/cpu.c| 121 +
 target-tricore/cpu.h| 372 
 target-tricore/helper.c |  36 
 target-tricore/helper.h |   0
 target-tricore/op_helper.c  |  27 +++
 target-tricore/translate.c  | 106 
 target-tricore/translate_init.c |  21 +++
 target-tricore/tricore-defs.h   |  28 +++
 15 files changed, 804 insertions(+), 1 deletion(-)
 create mode 100644 target-tricore/Makefile.objs
 create mode 100644 target-tricore/cpu-qom.h
 create mode 100644 target-tricore/cpu.c
 create mode 100644 target-tricore/cpu.h
 create mode 100644 target-tricore/helper.c
 create mode 100644 target-tricore/helper.h
 create mode 100644 target-tricore/op_helper.c
 create mode 100644 target-tricore/translate.c
 create mode 100644 target-tricore/translate_init.c
 create mode 100644 target-tricore/tricore-defs.h

diff --git a/arch_init.c b/arch_init.c
index 8ddaf35..29a5821 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -104,6 +104,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_XTENSA
 #elif defined(TARGET_UNICORE32)
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
+#elif defined(TARGET_TRICORE)
+#define QEMU_ARCH QEMU_ARCH_TRICORE
 #endif

 const uint32_t arch_type = QEMU_ARCH;
diff --git a/cpu-exec.c b/cpu-exec.c
index 38e5f02..bcfa943 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -277,6 +277,7 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
 #elif defined(TARGET_XTENSA)
+#elif defined(TARGET_TRICORE)
 /* X */
 #else
 #error unsupported target CPU
@@ -327,7 +328,8 @@ int cpu_exec(CPUArchState *env)
 }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
-defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || 
defined(TARGET_UNICORE32)
+defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) ||   \
+defined(TARGET_UNICORE32) || defined(TARGET_TRICORE)
 if (interrupt_request & CPU_INTERRUPT_HALT) {
 cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
 cpu->halted = 1;
@@ -443,6 +445,12 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
+#elif defined(TARGET_TRICORE)
+if ((interrupt_request & CPU_INTERRUPT_HARD)) {
+cc->do_interrupt(cpu);
+next_tb = 0;
+}
+
 #elif defined(TARGET_OPENRISC)
 {
 int idx = -1;
@@ -724,6 +732,7 @@ int cpu_exec(CPUArchState *env)
   | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_TRICORE)
 #elif defined(TARGET_MOXIE)
 #elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
diff --git a/cpus.c b/cpus.c
index 5e7f2cf..3262c6b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1342,6 +1342,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 MIPSCPU *mips_cpu = MIPS_CPU(cpu);
 CPUMIPSState *env = &mips_cpu->env;
+#elif defined(TARGET_TRICORE)
+TRICORECPU *tricore_cpu = TRICORE_CPU(cpu);
+CPUTRICOREState *env = &tricore_cpu->env;
 #endif

 cpu_synchronize_state(cpu);
@@ -1366,6 +1369,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_MIPS)
 info->value->has_PC = true;
 info->value->PC = env->active_tc.PC;
+#elif defined(TARGET_TRICORE)
+info->value->has_PC = true;
+info->value->PC = env->PC;
 #endif

 /* XXX: waiting for the qapi to support GSList */
diff --git a/include/elf.h b/include/elf.h
index e88d52f..70107f0 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -92,6 +92,8 @@ typedef int64_t  Elf64_Sxword;

 #define EM_SPARCV9 43  /* SPARC v9 64-bit */

+#define EM_TRICORE  44  /* Infineon TriCore */
+
 #define EM_IA_64   50  /* HP/Intel IA-64 */

 #define EM_X86_64  62  /* AMD x86-64 */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 182d48d..8939233 1

[Qemu-devel] [PATCH v2 04/15] target-tricore: Add initialization for translation and activate target

2014-07-14 Thread Bastian Koppelmann
Add tcg and cpu model initialization.
Add gen_intermediate_code function.
Activate target in configure and add softmmu config.

Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- Add next_pc to DisasContext and change pc calculation.
- Remove insn_bytes.

 configure   |   5 ++
 default-configs/tricore-softmmu.mak |   3 +
 target-tricore/translate.c  | 156 +++-
 target-tricore/translate_init.c |  30 +++
 4 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/tricore-softmmu.mak

diff --git a/configure b/configure
index f7685b5..5003e28 100755
--- a/configure
+++ b/configure
@@ -4965,6 +4965,9 @@ case "$target_name" in
 TARGET_BASE_ARCH=mips
 echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
   ;;
+  tricore)
+target_phys_bits=32
+  ;;
   moxie)
   ;;
   or32)
@@ -5162,6 +5165,8 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
 echo "CONFIG_MIPS_DIS=y"  >> $config_target_mak
 echo "CONFIG_MIPS_DIS=y"  >> config-all-disas.mak
   ;;
+  tricore*)
+  ;;
   moxie*)
 echo "CONFIG_MOXIE_DIS=y"  >> $config_target_mak
 echo "CONFIG_MOXIE_DIS=y"  >> config-all-disas.mak
diff --git a/default-configs/tricore-softmmu.mak 
b/default-configs/tricore-softmmu.mak
new file mode 100644
index 000..48ccd12
--- /dev/null
+++ b/default-configs/tricore-softmmu.mak
@@ -0,0 +1,3 @@
+include pci.mak
+CONFIG_PFLASH_CFI01=y
+CONFIG_SMC91C111=y
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index ab6b452..f420a9b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -26,6 +26,18 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"

+/*
+ * TCG registers
+ */
+static TCGv cpu_PC;
+static TCGv cpu_PCXI;
+static TCGv cpu_PSW;
+static TCGv cpu_ICR;
+/* GPR registers */
+static TCGv cpu_gpr_a[16];
+static TCGv cpu_gpr_d[16];
+static TCGv_ptr cpu_env;
+#include "exec/gen-icount.h"

 static const char *regnames_a[] = {
   "a0"  , "a1"  , "a2"  , "a3" , "a4"  , "a5" ,
@@ -39,6 +51,25 @@ static const char *regnames_d[] = {
   "d12" , "d13" , "d14" , "d15",
 };

+typedef struct DisasContext {
+struct TranslationBlock *tb;
+target_ulong pc, saved_pc, next_pc;
+uint32_t opcode;
+int singlestep_enabled;
+/* Routine used to access memory */
+int mem_idx;
+uint32_t hflags, saved_hflags;
+int bstate;
+} DisasContext;
+
+enum {
+
+BS_NONE   = 0,
+BS_STOP   = 1,
+BS_BRANCH = 2,
+BS_EXCP   = 3,
+};
+
 void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 fprintf_function cpu_fprintf, int flags)
 {
@@ -62,10 +93,88 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,

 }

+static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
+{
+}
+
+static void decode_32Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
+{
+}
+
+static void decode_opc(CPUTRICOREState *env, DisasContext *ctx, int *is_branch)
+{
+/* 16-Bit Instruction */
+if ((ctx->opcode & 0x1) == 0) {
+ctx->next_pc = ctx->pc + 2;
+decode_16Bit_opc(env, ctx);
+/* 32-Bit Instruction */
+} else {
+ctx->next_pc = ctx->pc + 4;
+decode_32Bit_opc(env, ctx);
+}
+}
+
 static inline void
 gen_intermediate_code_internal(TRICORECPU *cpu, struct TranslationBlock *tb,
   int search_pc)
 {
+CPUState *cs = CPU(cpu);
+CPUTRICOREState *env = &cpu->env;
+DisasContext ctx;
+target_ulong pc_start;
+int num_insns;
+uint16_t *gen_opc_end;
+
+if (search_pc) {
+qemu_log("search pc %d\n", search_pc);
+}
+
+num_insns = 0;
+pc_start = tb->pc;
+gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
+ctx.pc = pc_start;
+ctx.saved_pc = -1;
+ctx.tb = tb;
+ctx.singlestep_enabled = cs->singlestep_enabled;
+ctx.bstate = BS_NONE;
+ctx.mem_idx = cpu_mmu_index(env);
+
+tcg_clear_temp_count();
+gen_tb_start();
+while (ctx.bstate == BS_NONE) {
+ctx.opcode = cpu_ldl_code(env, ctx.pc);
+decode_opc(env, &ctx, 0);
+
+num_insns++;
+
+ctx.pc = ctx.next_pc;
+if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
+break;
+}
+if (singlestep) {
+break;
+}
+}
+
+gen_tb_end(tb, num_insns);
+*tcg_ctx.gen_opc_ptr = INDEX_op_end;
+if (search_pc) {
+printf("done_generating search pc\n");
+} else {
+tb->size = ctx.pc - pc_start;
+tb->icount = num_insns;
+}
+if (tcg_check_temp_count()) {
+printf("LEAK at %08x\n", env->PC);
+}
+
+#ifdef DEBUG_DISAS
+if (qemu_loglevel_m

  1   2   3   4   5   6   7   8   9   10   >