[PATCH] plugin: Fixes compiling errors on OSX

2020-10-26 Thread Peer Adelt
Removed the following entries
 - "qemu_plugin_register_vcpu_mem_haddr_cb"
 - "qemu_plugin_ram_addr_from_host"
 - "qemu_plugin_hwaddr_to_raddr"
from file "plugins/qemu-plugins.symbols".

The exported symbols do not seem to be defined anywhere and cause
errors when linking under OSX Mojave and Big Sur.

Signed-off-by: Peer Adelt 
---
 plugins/qemu-plugins.symbols | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
index 4bdb381f48..40b4ff3821 100644
--- a/plugins/qemu-plugins.symbols
+++ b/plugins/qemu-plugins.symbols
@@ -8,9 +8,7 @@
   qemu_plugin_register_vcpu_insn_exec_cb;
   qemu_plugin_register_vcpu_insn_exec_inline;
   qemu_plugin_register_vcpu_mem_cb;
-  qemu_plugin_register_vcpu_mem_haddr_cb;
   qemu_plugin_register_vcpu_mem_inline;
-  qemu_plugin_ram_addr_from_host;
   qemu_plugin_register_vcpu_tb_trans_cb;
   qemu_plugin_register_vcpu_tb_exec_cb;
   qemu_plugin_register_vcpu_tb_exec_inline;
@@ -32,7 +30,6 @@
   qemu_plugin_mem_is_store;
   qemu_plugin_get_hwaddr;
   qemu_plugin_hwaddr_is_io;
-  qemu_plugin_hwaddr_to_raddr;
   qemu_plugin_vcpu_for_each;
   qemu_plugin_n_vcpus;
   qemu_plugin_n_max_vcpus;
-- 
2.29.1




Re: HTIF tohost symbol size check always fails

2020-10-16 Thread Peer Adelt
The solution was even easier: I forgot to load the proxy kernel. As soon as I 
replaced the command-line parameter "-kernel " with "-kernel  -append 
", everything was working as expected. 

Without your hint about my possibly misconfigured toolchain I would have 
probably continued to search for the error in the QEMU HTIF device. But in fact 
it was due to the wrong binary.

Thanks a lot! :-)

> On 16. Oct 2020, at 20:03, Alistair Francis  wrote:
> 
> On Fri, Oct 16, 2020 at 7:59 AM Peer Adelt  wrote:
>> 
>> Hi,
>> 
>> I have a problem with the RISC-V HTIF device.
>> 
>> Every binary I have compiled for Spike on riscv32 fails with the following 
>> error message: "HTIF tohost must be 8 bytes"
>> 
>> This happens regardless of which program I have translated for Spike. This 
>> is also the case with the official riscv-compliance tests, for example.
>> 
>> The query "if (st_size != 8)" in the HTIF device always fails, because 
>> st_size seems to be always 0.
>> 
>> To be able to reproduce it:
>> - QEMU GIT Hash: d0ed6a69d399ae193959225cdeaa9382746c91cc (tag "v5.1.0")
> 
> I just checked with this hash and with the current master and on both
> I can run a ELF executable on the Spike machine for RV32.
> 
>> - System: Mac OS 10.14.6 (Darwin Kernel Version 18.7.0)
>> - Compiler: Latest SiFive Build for GCC under OSX
> 
> Maybe try using an official toolchain instead of a vendor fork.
> 
> Alistair
> 
>> - Command: qemu-system-riscv32 -M spike -nographic -bios none -kernel 
>> 
>> 
>> Best regards,
>> Peer Adelt




HTIF tohost symbol size check always fails

2020-10-16 Thread Peer Adelt
Hi,

I have a problem with the RISC-V HTIF device. 

Every binary I have compiled for Spike on riscv32 fails with the following 
error message: "HTIF tohost must be 8 bytes"

This happens regardless of which program I have translated for Spike. This is 
also the case with the official riscv-compliance tests, for example.

The query "if (st_size != 8)" in the HTIF device always fails, because st_size 
seems to be always 0.

To be able to reproduce it:
- QEMU GIT Hash: d0ed6a69d399ae193959225cdeaa9382746c91cc (tag "v5.1.0")
- System: Mac OS 10.14.6 (Darwin Kernel Version 18.7.0)
- Compiler: Latest SiFive Build for GCC under OSX
- Command: qemu-system-riscv32 -M spike -nographic -bios none -kernel 


Best regards,
Peer Adelt


[Qemu-devel] [PATCH v3 2/4] target-tricore: Added MADD.F and MSUB.F instructions

2016-06-07 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Multiplies D[a] and D[b] and adds/subtracts the result to/from D[d].
The result is put in D[c]. All operands are floating-point numbers.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/fpu_helper.c | 80 +
 target-tricore/helper.h |  2 ++
 target-tricore/translate.c  |  8 +
 3 files changed, 90 insertions(+)

diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 16f274c..a4b0973 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -21,6 +21,7 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 
+#define QUIET_NAN 0x7fc0
 #define ADD_NAN   0x7cf1
 #define DIV_NAN   0x7fc8
 #define MUL_NAN   0x7fc2
@@ -47,6 +48,39 @@ static inline bool f_is_denormal(float32 arg)
 return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
 }
 
+static inline int f_is_pos_infinity(float32 a)
+{
+return !float32_is_neg(a) && float32_is_infinity(a);
+}
+
+static inline int f_is_neg_infinity(float32 a)
+{
+return float32_is_neg(a) && float32_is_infinity(a);
+}
+
+static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
+   float32 arg3, float32 result)
+{
+if (float32_is_any_nan(arg1) ||
+float32_is_any_nan(arg2) ||
+float32_is_any_nan(arg3)) {
+return QUIET_NAN;
+} else if (float32_is_infinity(arg1) && float32_is_zero(arg2)) {
+return MUL_NAN;
+} else if (float32_is_zero(arg1) && float32_is_infinity(arg2)) {
+return MUL_NAN;
+} else if (((f_is_neg_infinity(arg1) && f_is_neg_infinity(arg2)) ||
+(f_is_pos_infinity(arg1) && f_is_pos_infinity(arg2))) &&
+ f_is_neg_infinity(arg3)) {
+return ADD_NAN;
+} else if (((f_is_neg_infinity(arg1) && f_is_pos_infinity(arg2)) ||
+(f_is_pos_infinity(arg1) && f_is_neg_infinity(arg2))) &&
+ f_is_pos_infinity(arg3)) {
+return ADD_NAN;
+}
+return result;
+}
+
 static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
 {
 uint8_t some_excp = 0;
@@ -159,6 +193,52 @@ uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, 
uint32_t r2)
 return (uint32_t)f_result;
 }
 
+uint32_t helper_fmadd(CPUTriCoreState *env, uint32_t r1,
+  uint32_t r2, uint32_t r3)
+{
+uint32_t flags;
+float32 arg1 = make_float32(r1);
+float32 arg2 = make_float32(r2);
+float32 arg3 = make_float32(r3);
+float32 f_result;
+
+f_result = float32_muladd(arg1, arg2, arg3, 0, >fp_status);
+
+flags = f_get_excp_flags(env);
+if (flags) {
+if (flags & float_flag_invalid) {
+f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result);
+}
+f_update_psw_flags(env, flags);
+} else {
+env->FPU_FS = 0;
+}
+return (uint32_t)f_result;
+}
+
+uint32_t helper_fmsub(CPUTriCoreState *env, uint32_t r1,
+  uint32_t r2, uint32_t r3)
+{
+uint32_t flags;
+float32 arg1 = make_float32(r1);
+float32 arg2 = make_float32(r2);
+float32 arg3 = make_float32(r3);
+float32 f_result;
+
+f_result = float32_muladd(arg1, arg2, arg3, float_muladd_negate_product, 
>fp_status);
+
+flags = f_get_excp_flags(env);
+if (flags) {
+if (flags & float_flag_invalid) {
+f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result);
+}
+f_update_psw_flags(env, flags);
+} else {
+env->FPU_FS = 0;
+}
+return (uint32_t)f_result;
+}
+
 uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 {
 uint32_t result, flags;
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 467c880..c897a44 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -109,6 +109,8 @@ DEF_HELPER_3(fadd, i32, env, i32, i32)
 DEF_HELPER_3(fsub, i32, env, i32, i32)
 DEF_HELPER_3(fmul, i32, env, i32, i32)
 DEF_HELPER_3(fdiv, i32, env, i32, i32)
+DEF_HELPER_4(fmadd, i32, env, i32, i32, i32)
+DEF_HELPER_4(fmsub, i32, env, i32, i32, i32)
 DEF_HELPER_3(fcmp, i32, env, i32, i32)
 DEF_HELPER_2(ftoi, i32, env, i32)
 DEF_HELPER_2(itof, i32, env, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index b888b64..07b0a8b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -7096,6 +7096,14 @@ static void decode_rrr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RRR_SUB_F:
 gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
 break;
+case OPC2_32_RRR_MADD_F:
+gen_helper_fmadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
+ cpu_gpr_d[r2], cpu_gpr_d[r3]);
+break;
+case OPC2_32_RRR_MSUB

[Qemu-devel] [PATCH v3 3/4] target-tricore: Added new MOV instruction variant

2016-06-07 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Puts the content of data register D[a] into E[c][63:32] and the
content of data register D[b] into E[c][31:0].

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/translate.c   | 15 +++
 target-tricore/tricore-opcodes.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 07b0a8b..0e970c6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6034,11 +6034,15 @@ static void decode_rr_accumulator(CPUTriCoreState *env, 
DisasContext *ctx)
 uint32_t op2;
 int r3, r2, r1;
 
+TCGv temp;
+
 r3 = MASK_OP_RR_D(ctx->opcode);
 r2 = MASK_OP_RR_S2(ctx->opcode);
 r1 = MASK_OP_RR_S1(ctx->opcode);
 op2 = MASK_OP_RR_OP2(ctx->opcode);
 
+temp = tcg_temp_new();
+
 switch (op2) {
 case OPC2_32_RR_ABS:
 gen_abs(cpu_gpr_d[r3], cpu_gpr_d[r2]);
@@ -6224,6 +6228,16 @@ static void decode_rr_accumulator(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RR_MOV:
 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
 break;
+case OPC2_32_RR_MOV_64:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+CHECK_REG_PAIR(r3);
+tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
+tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp);
+} else {
+generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+}
+break;
 case OPC2_32_RR_NE:
 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
@@ -6344,6 +6358,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, 
DisasContext *ctx)
 default:
 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
 }
+tcg_temp_free(temp);
 }
 
 static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index df666b0..78ba338 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1062,6 +1062,7 @@ enum {
 OPC2_32_RR_MIN_H = 0x78,
 OPC2_32_RR_MIN_HU= 0x79,
 OPC2_32_RR_MOV   = 0x1f,
+OPC2_32_RR_MOV_64= 0x81,
 OPC2_32_RR_NE= 0x11,
 OPC2_32_RR_OR_EQ = 0x27,
 OPC2_32_RR_OR_GE = 0x2b,
-- 
2.7.4




[Qemu-devel] [PATCH v3 0/4] Added 5 instructions to the tricore target

2016-06-07 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

This patch set contains 5 new instructions:
 - FTOUZ (converts float to unsigned int, rounds towards zero)
 - MADD.F / MSUB.F (multiplies two floats and adds/subtracts result
to/from the third operand)
 - MOV (new variant in RR format - see ISA v1.6 for details)
 - JNE (new variant in SBC format - see ISA v1.6 for details)

v3:
  PATCH 1/4: target-tricore: Added FTOUZ instruction
  - Removed unnecessary cast

  PATCH 2/4: target-tricore: Added MADD.F and MSUB.F instructions
  - Provided correct negation options for float32_muladd()
instead of negating one of the input arguments
  - Calculate NaN results as required in the datasheet

  PATCH 3/4: target-tricore: Added new MOV instruction variant
  - Removed unnecessary parentheses
  - Used temp register to avoid losing the value of r1
  - Checks that r3+1:r3 for a valid 64 Bit extended register

  PATCH 4/4: target-tricore: Added new JNE instruction variant
  - gen_compute_branch() now calculates the displacement value

v2:
  PATCH 3/4: target-tricore: Added new MOV instruction variant
  - Checks TriCore ISA version requirement

  PATCH 4/4: target-tricore: Added new JNE instruction variant
  - Checks TriCore ISA version requirement


Peer Adelt (4):
  target-tricore: Added FTOUZ instruction
  target-tricore: Added MADD.F and MSUB.F instructions
  target-tricore: Added new MOV instruction variant
  target-tricore: Added new JNE instruction variant

 target-tricore/fpu_helper.c  | 77 
 target-tricore/helper.h  |  3 ++
 target-tricore/translate.c   | 42 ++
 target-tricore/tricore-opcodes.h |  3 ++
 4 files changed, 125 insertions(+)

-- 
2.7.4




[Qemu-devel] [PATCH v3 1/4] target-tricore: Added FTOUZ instruction

2016-06-07 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Converts a 32-bit floating point number to an unsigned int. The
result is rounded towards zero.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>

Reviewed-by: Bastian Koppelmann <kbast...@mail.uni-paderborn.de>
---
 target-tricore/fpu_helper.c | 20 
 target-tricore/helper.h |  1 +
 target-tricore/translate.c  |  3 +++
 3 files changed, 24 insertions(+)

diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 98fe947..16f274c 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -215,3 +215,23 @@ uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg)
 }
 return (uint32_t)f_result;
 }
+
+uint32_t helper_ftouz(CPUTriCoreState *env, uint32_t arg)
+{
+float32 f_arg = make_float32(arg);
+uint32_t result;
+int32_t flags;
+
+result = float32_to_uint32_round_to_zero(f_arg, >fp_status);
+
+flags = f_get_excp_flags(env);
+if (flags) {
+if (float32_is_any_nan(f_arg)) {
+result = 0;
+}
+f_update_psw_flags(env, flags);
+} else {
+env->FPU_FS = 0;
+}
+return result;
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 9333e16..467c880 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -112,6 +112,7 @@ DEF_HELPER_3(fdiv, i32, env, i32, i32)
 DEF_HELPER_3(fcmp, i32, env, i32, i32)
 DEF_HELPER_2(ftoi, i32, env, i32)
 DEF_HELPER_2(itof, i32, env, i32)
+DEF_HELPER_2(ftouz, i32, env, i32)
 /* dvinit */
 DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index eb3deac..b888b64 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6698,6 +6698,9 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RR_ITOF:
 gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
 break;
+case OPC2_32_RR_FTOUZ:
+gen_helper_ftouz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+break;
 default:
 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
 }
-- 
2.7.4




[Qemu-devel] [PATCH v3 4/4] target-tricore: Added new JNE instruction variant

2016-06-07 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

If D[15] is != sign_ext(const4) then PC will be set to (PC +
zero_ext(disp4 + 16)).

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/translate.c   | 16 
 target-tricore/tricore-opcodes.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 0e970c6..8fb8bf1 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3362,9 +3362,15 @@ static void gen_compute_branch(DisasContext *ctx, 
uint32_t opc, int r1,
 case OPC1_16_SBC_JEQ:
 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
 break;
+case OPC1_16_SBC_JEQ2:
+gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset + 
16);
+break;
 case OPC1_16_SBC_JNE:
 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
 break;
+case OPC1_16_SBC_JNE2:
+gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset + 
16);
+break;
 /* SBRN-format jumps */
 case OPC1_16_SBRN_JZ_T:
 temp = tcg_temp_new();
@@ -4097,6 +4103,16 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
 gen_compute_branch(ctx, op1, 0, 0, const16, address);
 break;
+case OPC1_16_SBC_JEQ2:
+case OPC1_16_SBC_JNE2:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+address = MASK_OP_SBC_DISP4(ctx->opcode);
+const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address);
+} else {
+generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+}
+break;
 /* SBRN-format */
 case OPC1_16_SBRN_JNZ_T:
 case OPC1_16_SBRN_JZ_T:
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 78ba338..08394b8 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -311,6 +311,7 @@ enum {
 OPC1_16_SRR_EQ   = 0x3a,
 OPC1_16_SB_J = 0x3c,
 OPC1_16_SBC_JEQ  = 0x1e,
+OPC1_16_SBC_JEQ2 = 0x9e,
 OPC1_16_SBR_JEQ  = 0x3e,
 OPC1_16_SBR_JGEZ = 0xce,
 OPC1_16_SBR_JGTZ = 0x4e,
@@ -318,6 +319,7 @@ enum {
 OPC1_16_SBR_JLEZ = 0x8e,
 OPC1_16_SBR_JLTZ = 0x0e,
 OPC1_16_SBC_JNE  = 0x5e,
+OPC1_16_SBC_JNE2 = 0xde,
 OPC1_16_SBR_JNE  = 0x7e,
 OPC1_16_SB_JNZ   = 0xee,
 OPC1_16_SBR_JNZ  = 0xf6,
-- 
2.7.4




[Qemu-devel] [PATCH v2 4/4] target-tricore: Added new JNE instruction variant

2016-05-30 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

If D[15] is != sign_ext(const4) then PC will be set to (PC +
zero_ext(disp4 + 16)).

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/translate.c   | 11 +++
 target-tricore/tricore-opcodes.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 960ee33..21732f8 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3363,6 +3363,7 @@ static void gen_compute_branch(DisasContext *ctx, 
uint32_t opc, int r1,
 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
 break;
 case OPC1_16_SBC_JNE:
+case OPC1_16_SBC_JNE16:
 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
 break;
 /* SBRN-format jumps */
@@ -4097,6 +4098,16 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
 gen_compute_branch(ctx, op1, 0, 0, const16, address);
 break;
+case OPC1_16_SBC_JEQ16:
+case OPC1_16_SBC_JNE16:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+address = MASK_OP_SBC_DISP4(ctx->opcode);
+const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
+gen_compute_branch(ctx, op1, 0, 0, const16, address + 16);
+} else {
+generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+}
+break;
 /* SBRN-format */
 case OPC1_16_SBRN_JNZ_T:
 case OPC1_16_SBRN_JZ_T:
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 2f25613..7925354 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -318,6 +318,7 @@ enum {
 OPC1_16_SBR_JLEZ = 0x8e,
 OPC1_16_SBR_JLTZ = 0x0e,
 OPC1_16_SBC_JNE  = 0x5e,
+OPC1_16_SBC_JNE16= 0xde,
 OPC1_16_SBR_JNE  = 0x7e,
 OPC1_16_SB_JNZ   = 0xee,
 OPC1_16_SBR_JNZ  = 0xf6,
-- 
2.7.4




[Qemu-devel] [PATCH v2 3/4] target-tricore: Added new MOV instruction variant

2016-05-30 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Puts the content of data register D[a] into E[c][63:32] and the
content of data register D[b] into E[c][31:0].

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/translate.c   | 8 
 target-tricore/tricore-opcodes.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index e66b433..960ee33 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6224,6 +6224,14 @@ static void decode_rr_accumulator(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RR_MOV:
 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
 break;
+case OPC2_32_RR_MOV_EXT:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+tcg_gen_mov_tl(cpu_gpr_d[(r3+1)], cpu_gpr_d[r2]);
+} else {
+generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+}
+break;
 case OPC2_32_RR_NE:
 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index df666b0..2f25613 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1062,6 +1062,7 @@ enum {
 OPC2_32_RR_MIN_H = 0x78,
 OPC2_32_RR_MIN_HU= 0x79,
 OPC2_32_RR_MOV   = 0x1f,
+OPC2_32_RR_MOV_EXT   = 0x81,
 OPC2_32_RR_NE= 0x11,
 OPC2_32_RR_OR_EQ = 0x27,
 OPC2_32_RR_OR_GE = 0x2b,
-- 
2.7.4




[Qemu-devel] [PATCH 4/4] target-tricore: Added new JNE instruction variant

2016-05-29 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

If D[15] is != sign_ext(const4) then PC will be set to (PC +
zero_ext(disp4 + 16)).

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/translate.c   | 1 +
 target-tricore/tricore-opcodes.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 2145f64..9ad9fcc 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3363,6 +3363,7 @@ static void gen_compute_branch(DisasContext *ctx, 
uint32_t opc, int r1,
 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
 break;
 case OPC1_16_SBC_JNE:
+case OPC1_16_SBC_JNE16:
 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
 break;
 /* SBRN-format jumps */
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 2f25613..7925354 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -318,6 +318,7 @@ enum {
 OPC1_16_SBR_JLEZ = 0x8e,
 OPC1_16_SBR_JLTZ = 0x0e,
 OPC1_16_SBC_JNE  = 0x5e,
+OPC1_16_SBC_JNE16= 0xde,
 OPC1_16_SBR_JNE  = 0x7e,
 OPC1_16_SB_JNZ   = 0xee,
 OPC1_16_SBR_JNZ  = 0xf6,
-- 
2.7.4 (Apple Git-66)




[Qemu-devel] [PATCH 0/4] Added 5 instructions to the tricore target

2016-05-29 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

This patch set contains 5 new instructions:
- FTOUZ (converts float to unsigned int, rounds towards zero)
- MADD.F / MSUB.F (multiplies two floats and adds/subtracts result
   to/from the third operand)
- MOV (new variant in RR format - see ISA v1.6 for details)
- JNE (new variant in SBC format - see ISA v1.6 for details) 

Peer Adelt (4):
  target-tricore: Added FTOUZ instruction
  target-tricore: Added MADD.F and MSUB.F instructions
  target-tricore: Added new MOV instruction variant
  target-tricore: Added new JNE instruction variant

 target-tricore/fpu_helper.c  | 74 
 target-tricore/helper.h  |  3 ++
 target-tricore/translate.c   | 16 +
 target-tricore/tricore-opcodes.h |  2 ++
 4 files changed, 95 insertions(+)

-- 
2.7.4 (Apple Git-66)




[Qemu-devel] [PATCH 1/4] target-tricore: Added FTOUZ instruction

2016-05-29 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Converts a 32-bit floating point number to an unsigned int. The
result is rounded towards zero.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/fpu_helper.c | 20 
 target-tricore/helper.h |  1 +
 target-tricore/translate.c  |  3 +++
 3 files changed, 24 insertions(+)

diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 98fe947..ccaa6b0 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -215,3 +215,23 @@ uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg)
 }
 return (uint32_t)f_result;
 }
+
+uint32_t helper_ftouz(CPUTriCoreState *env, uint32_t arg)
+{
+float32 f_arg = make_float32(arg);
+uint32_t result;
+int32_t flags;
+
+result = float32_to_uint32_round_to_zero(f_arg, >fp_status);
+
+flags = f_get_excp_flags(env);
+if (flags) {
+if (float32_is_any_nan(f_arg)) {
+result = 0;
+}
+f_update_psw_flags(env, flags);
+} else {
+env->FPU_FS = 0;
+}
+return (uint32_t)result;
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 9333e16..467c880 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -112,6 +112,7 @@ DEF_HELPER_3(fdiv, i32, env, i32, i32)
 DEF_HELPER_3(fcmp, i32, env, i32, i32)
 DEF_HELPER_2(ftoi, i32, env, i32)
 DEF_HELPER_2(itof, i32, env, i32)
+DEF_HELPER_2(ftouz, i32, env, i32)
 /* dvinit */
 DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 83fa4fc..a109c15 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6698,6 +6698,9 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RR_ITOF:
 gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
 break;
+case OPC2_32_RR_FTOUZ:
+gen_helper_ftouz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+break;
 default:
 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
 }
-- 
2.7.4 (Apple Git-66)




[Qemu-devel] [PATCH 2/4] target-tricore: Added MADD.F and MSUB.F instructions

2016-05-29 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Multiplies D[a] and D[b] and adds/subtracts the result to/from D[d].
The result is put in D[c]. All operands are floating-point numbers.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/fpu_helper.c | 54 +
 target-tricore/helper.h |  2 ++
 target-tricore/translate.c  |  8 +++
 3 files changed, 64 insertions(+)

diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index ccaa6b0..3207818 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -159,6 +159,60 @@ uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, 
uint32_t r2)
 return (uint32_t)f_result;
 }
 
+uint32_t helper_fmadd(CPUTriCoreState *env, uint32_t r1,
+  uint32_t r2, uint32_t r3)
+{
+uint32_t flags;
+float32 arg1 = make_float32(r1);
+float32 arg2 = make_float32(r2);
+float32 arg3 = make_float32(r3);
+float32 f_result;
+
+flags = f_get_excp_flags(env);
+f_result = float32_muladd(arg1, arg2, arg3, flags, >fp_status);
+
+if (flags) {
+/* If the output is a NaN, but the inputs aren't,
+   we return a unique value.  */
+if ((flags & float_flag_invalid)
+&& !float32_is_any_nan(arg1)
+&& !float32_is_any_nan(arg2)) {
+f_result = MUL_NAN;
+}
+f_update_psw_flags(env, flags);
+} else {
+env->FPU_FS = 0;
+}
+return (uint32_t)f_result;
+}
+
+uint32_t helper_fmsub(CPUTriCoreState *env, uint32_t r1,
+  uint32_t r2, uint32_t r3)
+{
+uint32_t flags;
+float32 arg1 = make_float32(r1);
+float32 arg2 = make_float32(r2);
+float32 arg3 = make_float32(r3);
+float32 f_result;
+
+flags = f_get_excp_flags(env);
+f_result = float32_muladd(-arg1, arg2, arg3, flags, >fp_status);
+
+if (flags) {
+/* If the output is a NaN, but the inputs aren't,
+   we return a unique value.  */
+if ((flags & float_flag_invalid)
+&& !float32_is_any_nan(arg1)
+&& !float32_is_any_nan(arg2)) {
+f_result = MUL_NAN;
+}
+f_update_psw_flags(env, flags);
+} else {
+env->FPU_FS = 0;
+}
+return (uint32_t)f_result;
+}
+
 uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 {
 uint32_t result, flags;
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 467c880..c897a44 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -109,6 +109,8 @@ DEF_HELPER_3(fadd, i32, env, i32, i32)
 DEF_HELPER_3(fsub, i32, env, i32, i32)
 DEF_HELPER_3(fmul, i32, env, i32, i32)
 DEF_HELPER_3(fdiv, i32, env, i32, i32)
+DEF_HELPER_4(fmadd, i32, env, i32, i32, i32)
+DEF_HELPER_4(fmsub, i32, env, i32, i32, i32)
 DEF_HELPER_3(fcmp, i32, env, i32, i32)
 DEF_HELPER_2(ftoi, i32, env, i32)
 DEF_HELPER_2(itof, i32, env, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index a109c15..e66b433 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -7096,6 +7096,14 @@ static void decode_rrr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RRR_SUB_F:
 gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
 break;
+case OPC2_32_RRR_MADD_F:
+gen_helper_fmadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
+ cpu_gpr_d[r2], cpu_gpr_d[r3]);
+break;
+case OPC2_32_RRR_MSUB_F:
+gen_helper_fmsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
+ cpu_gpr_d[r2], cpu_gpr_d[r3]);
+break;
 default:
 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
 }
-- 
2.7.4 (Apple Git-66)




[Qemu-devel] [PATCH 3/4] target-tricore: Added new MOV instruction variant

2016-05-29 Thread peer . adelt
From: Peer Adelt <peer.ad...@c-lab.de>

Puts the content of data register D[a] into E[c][63:32] and the
content of data register D[b] into E[c][31:0].

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 target-tricore/translate.c   | 4 
 target-tricore/tricore-opcodes.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index e66b433..2145f64 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6224,6 +6224,10 @@ static void decode_rr_accumulator(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RR_MOV:
 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
 break;
+case OPC2_32_RR_MOV_EXT:
+tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+tcg_gen_mov_tl(cpu_gpr_d[(r3 + 1)], cpu_gpr_d[r2]);
+break;
 case OPC2_32_RR_NE:
 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index df666b0..2f25613 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1062,6 +1062,7 @@ enum {
 OPC2_32_RR_MIN_H = 0x78,
 OPC2_32_RR_MIN_HU= 0x79,
 OPC2_32_RR_MOV   = 0x1f,
+OPC2_32_RR_MOV_EXT   = 0x81,
 OPC2_32_RR_NE= 0x11,
 OPC2_32_RR_OR_EQ = 0x27,
 OPC2_32_RR_OR_GE = 0x2b,
-- 
2.7.4 (Apple Git-66)




[Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser

2016-01-14 Thread Peer Adelt
The XML file contains a control flow graph, where each edge
is annotated with a context-dependent value. The parser reads
this information into a data structure within CPUState.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 include/qom/cpu.h|   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +
 include/tb-annotation/tb-annotation.h|  64 ++
 tb-annotation/tb-annotation-parser.c | 174 +++
 4 files changed, 276 insertions(+)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/tb-annotation-parser.c

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 51a1323..afc532b 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -30,6 +30,10 @@
 #include "qemu/thread.h"
 #include "qemu/typedefs.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
  void *opaque);
 
@@ -329,6 +333,11 @@ struct CPUState {
  */
 bool throttle_thread_scheduled;
 
+#ifdef CONFIG_TB_ANNOTATION
+/* Used to annotate cpu state during tb execution */
+TbAnnotation *tb_annotation;
+#endif
+
 /* Note that this is accessed at the start of every TB via a negative
offset from AREG0.  Leave this field at the end so as to make the
(absolute value) offset as small as possible.  This reduces code
diff --git a/include/tb-annotation/tb-annotation-parser.h 
b/include/tb-annotation/tb-annotation-parser.h
new file mode 100644
index 000..aacab8e
--- /dev/null
+++ b/include/tb-annotation/tb-annotation-parser.h
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *  Peer Adelt
+ *  C-Lab/Paderborn University
+ *
+ * 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/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_PARSER_H_
+#define INCLUDE_TB_ANNOTATION_PARSER_H_
+
+#include "tb-annotation/tb-annotation.h"
+
+void tb_annotation_xml_init(const char *filename);
+void tb_annotation_xml_close(void);
+TbAnnotation *tb_annotation_parse(const char *filename);
+
+#endif /* INCLUDE_TB_ANNOTATION_PARSER_H_ */
diff --git a/include/tb-annotation/tb-annotation.h 
b/include/tb-annotation/tb-annotation.h
new file mode 100644
index 000..e1093b2
--- /dev/null
+++ b/include/tb-annotation/tb-annotation.h
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *  Peer Adelt
+ *  C-Lab/Paderborn University
+ *
+ * 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/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_H_
+#define INCLUDE_TB_ANNOTATION_H_
+
+#include 
+
+typedef struct tb_leaving_edge_tuple TbAnnotationLeavingEdgeTuple;
+typedef struct tb_annotation_block TbAnnotationBlock;
+typedef struct tb_annotation_edge TbAnnotationEdge;
+typedef struct tb_annotation TbAnnotation;
+
+struct tb_leaving_edge_tuple {
+TbAnnotationEdge *out1;
+TbAnnotationEdge *out2;
+};
+
+struct tb_annotation_block {
+uint8_t is_end_block;
+const char *id;
+unsigned int address;
+/* This hashtable points to all pairs of leaving edges
+ * from all source contexts.
+ * Note: string -> tb_leaving_edge_tuple
+ */
+GHashTable *out_edges_hash_table;
+};
+
+struct tb_annotation_edge {
+TbAnnotationBlock *source;
+TbAnnotationBlock *target;
+const char *source_context;
+const char *target_context;
+unsigned int value;
+};
+
+struct tb_annotation {
+
+TbAnnotationBlock *

Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism

2016-01-14 Thread Peer Adelt

On 14.01.2016 11:55, Peer Adelt wrote:

Hey guys :)

We have developed a generic concept to annotate TranslationBlocks during
runtime. The initial idea was to use it for time annotation with data from
static analysis tools. However, we have kept this approach as generic as
possible to allow other kinds of annotation (e.g. power consumption, etc.).

Our extension expects an XML file specifying the CFG of the program (similar
to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
with the data, that QEMU ought to accumulate during program execution. Each
edge has a source and target context in which it is executed.
For example: a for-loop that runs several times has its own context dependent
edge for each iteration. We plan on making this more flexible by allowing
to specify iterative context edges, i.e. from context n to context n+1.

This approach is not limited to one target architecture but we only tested
it for ARM and TriCore so far.

To show the current state of this patch we have attached a very small example
consisting of an ARM STM32F205 program and a timing annotation XML file (see
reply to this letter). You can provide the XML file to QEMU with the
"-annotation " option. During execution, the "value_sum" field of
the CPUState data structure will accumulate a total value of 70 (cycles).

Are there any comments? Is this in general a good idea to be added to upstream
QEMU?

All the best,
Peer

Peer Adelt (3):
   tb-annotation: Added annotation XML file parser
   tb-annotation: Add control flow graph mapper
   tb-annotation: Activate annotation extension

  Makefile |   5 +-
  Makefile.objs|   4 +
  Makefile.target  |   4 +-
  configure|  13 ++
  include/exec/gen-icount.h|  18 +++
  include/qom/cpu.h|   9 ++
  include/tb-annotation/tb-annotation-parser.h |  29 +
  include/tb-annotation/tb-annotation.h|  64 ++
  qemu-options.hx  |   8 ++
  tb-annotation/Makefile.objs  |   1 +
  tb-annotation/tb-annotation-parser.c | 174 +++
  tcg-runtime.c|  99 +++
  tcg/tcg-runtime.h|   4 +
  vl.c |  25 
  14 files changed, 454 insertions(+), 3 deletions(-)
  create mode 100644 include/tb-annotation/tb-annotation-parser.h
  create mode 100644 include/tb-annotation/tb-annotation.h
  create mode 100644 tb-annotation/Makefile.objs
  create mode 100644 tb-annotation/tb-annotation-parser.c


See attachment


annotation-example-project.tar.bz2
Description: application/bzip


[Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension

2016-01-14 Thread Peer Adelt
This changeset activates the TranslationBlock annotation
mechanism for the QEMU system mode.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 Makefile|  5 +++--
 Makefile.objs   |  4 
 Makefile.target |  4 +++-
 configure   | 13 +
 qemu-options.hx |  8 
 tb-annotation/Makefile.objs |  1 +
 vl.c| 25 +
 7 files changed, 57 insertions(+), 3 deletions(-)
 create mode 100644 tb-annotation/Makefile.objs

diff --git a/Makefile b/Makefile
index 82b2fc8..c351b31 100644
--- a/Makefile
+++ b/Makefile
@@ -161,7 +161,8 @@ dummy := $(call unnest-vars,, \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
-common-obj-m)
+common-obj-m \
+   annotation-obj-y)
 
 ifneq ($(wildcard config-host.mak),)
 include $(SRC_PATH)/tests/Makefile
@@ -204,7 +205,7 @@ subdir-dtc:dtc/libfdt dtc/tests
 dtc/%:
mkdir -p $@
 
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) 
$(crypto-aes-obj-$(CONFIG_USER_ONLY))
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) 
$(crypto-aes-obj-$(CONFIG_USER_ONLY)) $(annotation-obj-$(CONFIG_TB_ANNOTATION))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 romsubdir-%:
diff --git a/Makefile.objs b/Makefile.objs
index dac2c02..9b64358 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -116,3 +116,7 @@ qga-vss-dll-obj-y = qga/
 # contrib
 ivshmem-client-obj-y = contrib/ivshmem-client/
 ivshmem-server-obj-y = contrib/ivshmem-server/
+
+##
+# annotation
+annotation-obj-y = tb-annotation/
\ No newline at end of file
diff --git a/Makefile.target b/Makefile.target
index 34ddb7e..50a969d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -178,7 +178,8 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
-   common-obj-m)
+   common-obj-m \
+   annotation-obj-y)
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
@@ -187,6 +188,7 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
+all-obj-$(CONFIG_TB_ANNOTATION) += $(annotation-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
 
diff --git a/configure b/configure
index 83b40fc..5e72e06 100755
--- a/configure
+++ b/configure
@@ -345,6 +345,7 @@ vhdx=""
 numa=""
 tcmalloc="no"
 jemalloc="no"
+tbannotation="no"
 
 # parse CC options first
 for opt do
@@ -1169,6 +1170,10 @@ for opt do
   ;;
   --enable-jemalloc) jemalloc="yes"
   ;;
+  --disable-tbannotation) tbannotation="no"
+  ;;
+  --enable-tbannotation) tbannotation="yes"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1391,6 +1396,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   numalibnuma support
   tcmalloctcmalloc support
   jemallocjemalloc support
+  tbannotationTB annotation support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -4855,6 +4861,7 @@ echo "bzip2 support $bzip2"
 echo "NUMA host support $numa"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
+echo "TB annotation support $tbannotation"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5400,6 +5407,12 @@ if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi
 
+if test "$tbannotation" = "yes" ; then
+  echo "CONFIG_TB_ANNOTATION=y" >> $config_host_mak
+  echo "LIBS+=-lxml2" >> $config_host_mak
+  QEMU_CFLAGS="-I/usr/include/libxml2 $QEMU_CFLAGS"
+fi
+
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 # a thread we have a handle to
diff --git a/qemu-options.hx b/qemu-options.hx
index 215d00d..e3d9df9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2737,6 +2737,14 @@ Use @var{bzImage} as kernel image. The kernel can be 
either a Linux kernel
 or in multiboot format.
 ETEXI
 
+DEF("annotation", HAS_ARG, QEMU_OPTION_annotation, \
+"-annotation tbAnnotation use 'tbAnnotation' as annotation file\n", 
QEMU_ARCH_ALL)
+STEXI
+@item -annotation @var{tbAnnotation}
+@findex -annotation
+Use @var{tbAnnotation} as annotation file. TODO: spec

[Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism

2016-01-14 Thread Peer Adelt
Hey guys :)

We have developed a generic concept to annotate TranslationBlocks during
runtime. The initial idea was to use it for time annotation with data from
static analysis tools. However, we have kept this approach as generic as
possible to allow other kinds of annotation (e.g. power consumption, etc.).

Our extension expects an XML file specifying the CFG of the program (similar
to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
with the data, that QEMU ought to accumulate during program execution. Each
edge has a source and target context in which it is executed.
For example: a for-loop that runs several times has its own context dependent
edge for each iteration. We plan on making this more flexible by allowing
to specify iterative context edges, i.e. from context n to context n+1.

This approach is not limited to one target architecture but we only tested
it for ARM and TriCore so far.

To show the current state of this patch we have attached a very small example
consisting of an ARM STM32F205 program and a timing annotation XML file (see
reply to this letter). You can provide the XML file to QEMU with the 
"-annotation " option. During execution, the "value_sum" field of
the CPUState data structure will accumulate a total value of 70 (cycles).

Are there any comments? Is this in general a good idea to be added to upstream
QEMU?

All the best,
Peer

Peer Adelt (3):
  tb-annotation: Added annotation XML file parser
  tb-annotation: Add control flow graph mapper
  tb-annotation: Activate annotation extension

 Makefile |   5 +-
 Makefile.objs|   4 +
 Makefile.target  |   4 +-
 configure|  13 ++
 include/exec/gen-icount.h|  18 +++
 include/qom/cpu.h|   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +
 include/tb-annotation/tb-annotation.h|  64 ++
 qemu-options.hx  |   8 ++
 tb-annotation/Makefile.objs  |   1 +
 tb-annotation/tb-annotation-parser.c | 174 +++
 tcg-runtime.c|  99 +++
 tcg/tcg-runtime.h|   4 +
 vl.c |  25 
 14 files changed, 454 insertions(+), 3 deletions(-)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/Makefile.objs
 create mode 100644 tb-annotation/tb-annotation-parser.c

-- 
2.5.0




[Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper

2016-01-14 Thread Peer Adelt
Added helper function at the start of every TranslationBlock
that maps the sequence of static basic blocks (obtained from
the XML file) to the current TranslationBlock. The helper also
accumulates the values that are annotated on the corresponding
edges of the control flow graph.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 include/exec/gen-icount.h | 18 +
 tcg-runtime.c | 99 +++
 tcg/tcg-runtime.h |  4 ++
 3 files changed, 121 insertions(+)

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 05d89d3..0b8821b 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -14,6 +14,11 @@ static inline void gen_tb_start(TranslationBlock *tb)
 TCGv_i32 count, flag, imm;
 int i;
 
+#ifdef CONFIG_TB_ANNOTATION
+TCGv_ptr annotation_ptr;
+TCGv_i64 pc;
+#endif
+
 exitreq_label = gen_new_label();
 flag = tcg_temp_new_i32();
 tcg_gen_ld_i32(flag, cpu_env,
@@ -21,6 +26,17 @@ static inline void gen_tb_start(TranslationBlock *tb)
 tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
 tcg_temp_free_i32(flag);
 
+#ifdef CONFIG_TB_ANNOTATION
+pc = tcg_const_i64(tb->pc);
+annotation_ptr = tcg_temp_new_ptr();
+tcg_gen_ld_ptr(annotation_ptr, cpu_env,
+   -ENV_OFFSET + offsetof(CPUState, tb_annotation));
+
+gen_helper_annotation(pc, annotation_ptr);
+tcg_temp_free_i64(pc);
+tcg_temp_free_ptr(annotation_ptr);
+#endif
+
 if (!(tb->cflags & CF_USE_ICOUNT)) {
 return;
 }
@@ -45,6 +61,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
 tcg_gen_st16_i32(count, cpu_env,
  -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
 tcg_temp_free_i32(count);
+
+
 }
 
 static void gen_tb_end(TranslationBlock *tb, int num_insns)
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 9daba69..fc2526c 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -29,6 +29,10 @@
 
 #include "exec/helper-head.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
   dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 
@@ -107,3 +111,98 @@ int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2)
 muls64(, , arg1, arg2);
 return h;
 }
+
+#ifdef CONFIG_TB_ANNOTATION
+static inline void take_final_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+/* Store current context and block */
+env->last_ctx = edge->target_context;
+env->last_block = edge->target;
+/* Accumulate value */
+env->value_sum += edge->value;
+}
+
+static inline void take_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+TbAnnotationLeavingEdgeTuple *out;
+
+/* Store current context and block */
+env->last_ctx = edge->target_context;
+env->last_block = edge->target;
+/* Accumulate value */
+env->value_sum += edge->value;
+
+/* Check whether we are at the end of our analysis... */
+if (env->last_block->out_edges_hash_table != NULL) {
+out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+  env->last_ctx);
+if (out != NULL && out->out1->target->is_end_block) {
+take_final_edge(env, out->out1);
+}
+}
+}
+
+void HELPER(annotation)(uint64_t pc, void *opaque)
+{
+TbAnnotation *env = (TbAnnotation *) opaque;
+TbAnnotationBlock *b;
+TbAnnotationLeavingEdgeTuple *out;
+
+if (!env) {
+return;
+}
+
+/* does the block corresponding to pc exist? */
+if (!g_hash_table_contains(env->tb_annotation_blocks, )) {
+return;
+}
+/* if last_block == NULL we're in the first block */
+if (env->last_block == NULL) {
+
+b = (TbAnnotationBlock *)g_hash_table_lookup(env->tb_annotation_blocks,
+ );
+env->last_block = b;
+
+} else {
+/* while not reached block with current pc (target)
+ * take the next distinct edge if it exists
+ * otherwise we're one edge away from the target and
+ * take the edge directly leading to the target
+ */
+out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+  env->last_ctx);
+
+while (out != NULL && out->out2 == NULL) {
+/* We found a distinct path to "out1" */
+take_edge(env, out->out1);
+
+/* Have we reached our target? */
+if (env->last_block->address == pc) {
+return;
+}
+
+/* Get the current out edge tuple */
+out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+  env->last_ctx

[Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser

2016-01-08 Thread Peer Adelt
The XML file contains a control flow graph, where each edge
is annotated with a context-dependent value. The parser reads
this information into a data structure within CPUState.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 include/qom/cpu.h|   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +
 include/tb-annotation/tb-annotation.h|  64 ++
 tb-annotation/tb-annotation-parser.c | 174 +++
 4 files changed, 276 insertions(+)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/tb-annotation-parser.c

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 51a1323..afc532b 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -30,6 +30,10 @@
 #include "qemu/thread.h"
 #include "qemu/typedefs.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
  void *opaque);
 
@@ -329,6 +333,11 @@ struct CPUState {
  */
 bool throttle_thread_scheduled;
 
+#ifdef CONFIG_TB_ANNOTATION
+/* Used to annotate cpu state during tb execution */
+TbAnnotation *tb_annotation;
+#endif
+
 /* Note that this is accessed at the start of every TB via a negative
offset from AREG0.  Leave this field at the end so as to make the
(absolute value) offset as small as possible.  This reduces code
diff --git a/include/tb-annotation/tb-annotation-parser.h 
b/include/tb-annotation/tb-annotation-parser.h
new file mode 100644
index 000..aacab8e
--- /dev/null
+++ b/include/tb-annotation/tb-annotation-parser.h
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *  Peer Adelt
+ *  C-Lab/Paderborn University
+ *
+ * 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/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_PARSER_H_
+#define INCLUDE_TB_ANNOTATION_PARSER_H_
+
+#include "tb-annotation/tb-annotation.h"
+
+void tb_annotation_xml_init(const char *filename);
+void tb_annotation_xml_close(void);
+TbAnnotation *tb_annotation_parse(const char *filename);
+
+#endif /* INCLUDE_TB_ANNOTATION_PARSER_H_ */
diff --git a/include/tb-annotation/tb-annotation.h 
b/include/tb-annotation/tb-annotation.h
new file mode 100644
index 000..e1093b2
--- /dev/null
+++ b/include/tb-annotation/tb-annotation.h
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *  Peer Adelt
+ *  C-Lab/Paderborn University
+ *
+ * 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/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_H_
+#define INCLUDE_TB_ANNOTATION_H_
+
+#include 
+
+typedef struct tb_leaving_edge_tuple TbAnnotationLeavingEdgeTuple;
+typedef struct tb_annotation_block TbAnnotationBlock;
+typedef struct tb_annotation_edge TbAnnotationEdge;
+typedef struct tb_annotation TbAnnotation;
+
+struct tb_leaving_edge_tuple {
+TbAnnotationEdge *out1;
+TbAnnotationEdge *out2;
+};
+
+struct tb_annotation_block {
+uint8_t is_end_block;
+const char *id;
+unsigned int address;
+/* This hashtable points to all pairs of leaving edges
+ * from all source contexts.
+ * Note: string -> tb_leaving_edge_tuple
+ */
+GHashTable *out_edges_hash_table;
+};
+
+struct tb_annotation_edge {
+TbAnnotationBlock *source;
+TbAnnotationBlock *target;
+const char *source_context;
+const char *target_context;
+unsigned int value;
+};
+
+struct tb_annotation {
+
+TbAnnotationBlock *

[Qemu-devel] [RFC PATCH 0/3] TranslationBlock annotation mechanism

2016-01-08 Thread Peer Adelt

Hey guys

We have developed a generic concept to annotate TranslationBlocks during
runtime. The initial idea was to use it for time annotation with data from
static analysis tools. However, we have kept this approach as generic as
possible to allow other kinds of annotation (e.g. power consumption, etc.).

Our extension expects an XML file specifying the CFG of the program (similar
to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
with the data, that QEMU ought to accumulate during program execution. Each
edge has a source and target context in which it is executed.
For example: a for-loop that runs several times has its own context dependent
edge for each iteration. We plan on making this more flexible by allowing
to specify iterative context edges, i.e. from context n to context n+1.

This approach is not limited to one target architecture but we only tested
it for ARM and TriCore so far.

To show the current state of this patch we have attached a very small example
consisting of an ARM STM32F205 program and a timing annotation XML file. You
can provide the XML file to QEMU with the "-annotation " option.
During execution, the "value_sum" field of the CPUState data structure will
accumulate a total value of 70 (cycles).

Are there any comments? Is this in general a good idea to be added to upstream
QEMU?

All the best,
Peer

 Peer Adelt (3):
  tb-annotation: Added annotation XML file parser
  tb-annotation: Add control flow graph mapper
  tb-annotation: Activate annotation extension

 Makefile |   5 +-
 Makefile.objs|   4 +
 Makefile.target  |   4 +-
 configure|  13 ++
 include/exec/gen-icount.h|  18 +++
 include/qom/cpu.h|   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +
 include/tb-annotation/tb-annotation.h|  64 ++
 qemu-options.hx  |   8 ++
 tb-annotation/Makefile.objs  |   1 +
 tb-annotation/tb-annotation-parser.c | 174 +++
 tcg-runtime.c|  99 +++
 tcg/tcg-runtime.h|   4 +
 vl.c |  25 
 14 files changed, 454 insertions(+), 3 deletions(-)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/Makefile.objs
 create mode 100644 tb-annotation/tb-annotation-parser.c

-- 2.5.0



annotation-example-project.tar.bz2
Description: application/bzip


[Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension

2016-01-08 Thread Peer Adelt
This changeset activates the TranslationBlock annotation
mechanism for the QEMU system mode.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 Makefile|  5 +++--
 Makefile.objs   |  4 
 Makefile.target |  4 +++-
 configure   | 13 +
 qemu-options.hx |  8 
 tb-annotation/Makefile.objs |  1 +
 vl.c| 25 +
 7 files changed, 57 insertions(+), 3 deletions(-)
 create mode 100644 tb-annotation/Makefile.objs

diff --git a/Makefile b/Makefile
index 82b2fc8..c351b31 100644
--- a/Makefile
+++ b/Makefile
@@ -161,7 +161,8 @@ dummy := $(call unnest-vars,, \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
-common-obj-m)
+common-obj-m \
+   annotation-obj-y)
 
 ifneq ($(wildcard config-host.mak),)
 include $(SRC_PATH)/tests/Makefile
@@ -204,7 +205,7 @@ subdir-dtc:dtc/libfdt dtc/tests
 dtc/%:
mkdir -p $@
 
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) 
$(crypto-aes-obj-$(CONFIG_USER_ONLY))
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) 
$(crypto-aes-obj-$(CONFIG_USER_ONLY)) $(annotation-obj-$(CONFIG_TB_ANNOTATION))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 romsubdir-%:
diff --git a/Makefile.objs b/Makefile.objs
index dac2c02..9b64358 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -116,3 +116,7 @@ qga-vss-dll-obj-y = qga/
 # contrib
 ivshmem-client-obj-y = contrib/ivshmem-client/
 ivshmem-server-obj-y = contrib/ivshmem-server/
+
+##
+# annotation
+annotation-obj-y = tb-annotation/
\ No newline at end of file
diff --git a/Makefile.target b/Makefile.target
index 34ddb7e..50a969d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -178,7 +178,8 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
-   common-obj-m)
+   common-obj-m \
+   annotation-obj-y)
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
@@ -187,6 +188,7 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
+all-obj-$(CONFIG_TB_ANNOTATION) += $(annotation-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
 
diff --git a/configure b/configure
index 83b40fc..5e72e06 100755
--- a/configure
+++ b/configure
@@ -345,6 +345,7 @@ vhdx=""
 numa=""
 tcmalloc="no"
 jemalloc="no"
+tbannotation="no"
 
 # parse CC options first
 for opt do
@@ -1169,6 +1170,10 @@ for opt do
   ;;
   --enable-jemalloc) jemalloc="yes"
   ;;
+  --disable-tbannotation) tbannotation="no"
+  ;;
+  --enable-tbannotation) tbannotation="yes"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1391,6 +1396,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   numalibnuma support
   tcmalloctcmalloc support
   jemallocjemalloc support
+  tbannotationTB annotation support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -4855,6 +4861,7 @@ echo "bzip2 support $bzip2"
 echo "NUMA host support $numa"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
+echo "TB annotation support $tbannotation"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5400,6 +5407,12 @@ if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi
 
+if test "$tbannotation" = "yes" ; then
+  echo "CONFIG_TB_ANNOTATION=y" >> $config_host_mak
+  echo "LIBS+=-lxml2" >> $config_host_mak
+  QEMU_CFLAGS="-I/usr/include/libxml2 $QEMU_CFLAGS"
+fi
+
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 # a thread we have a handle to
diff --git a/qemu-options.hx b/qemu-options.hx
index 215d00d..e3d9df9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2737,6 +2737,14 @@ Use @var{bzImage} as kernel image. The kernel can be 
either a Linux kernel
 or in multiboot format.
 ETEXI
 
+DEF("annotation", HAS_ARG, QEMU_OPTION_annotation, \
+"-annotation tbAnnotation use 'tbAnnotation' as annotation file\n", 
QEMU_ARCH_ALL)
+STEXI
+@item -annotation @var{tbAnnotation}
+@findex -annotation
+Use @var{tbAnnotation} as annotation file. TODO: spec

[Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper

2016-01-08 Thread Peer Adelt
Added helper function at the start of every TranslationBlock
that maps the sequence of static basic blocks (obtained from
the XML file) to the current TranslationBlock. The helper also
accumulates the values that are annotated on the corresponding
edges of the control flow graph.

Signed-off-by: Peer Adelt <peer.ad...@c-lab.de>
---
 include/exec/gen-icount.h | 18 +
 tcg-runtime.c | 99 +++
 tcg/tcg-runtime.h |  4 ++
 3 files changed, 121 insertions(+)

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 05d89d3..0b8821b 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -14,6 +14,11 @@ static inline void gen_tb_start(TranslationBlock *tb)
 TCGv_i32 count, flag, imm;
 int i;
 
+#ifdef CONFIG_TB_ANNOTATION
+TCGv_ptr annotation_ptr;
+TCGv_i64 pc;
+#endif
+
 exitreq_label = gen_new_label();
 flag = tcg_temp_new_i32();
 tcg_gen_ld_i32(flag, cpu_env,
@@ -21,6 +26,17 @@ static inline void gen_tb_start(TranslationBlock *tb)
 tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
 tcg_temp_free_i32(flag);
 
+#ifdef CONFIG_TB_ANNOTATION
+pc = tcg_const_i64(tb->pc);
+annotation_ptr = tcg_temp_new_ptr();
+tcg_gen_ld_ptr(annotation_ptr, cpu_env,
+   -ENV_OFFSET + offsetof(CPUState, tb_annotation));
+
+gen_helper_annotation(pc, annotation_ptr);
+tcg_temp_free_i64(pc);
+tcg_temp_free_ptr(annotation_ptr);
+#endif
+
 if (!(tb->cflags & CF_USE_ICOUNT)) {
 return;
 }
@@ -45,6 +61,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
 tcg_gen_st16_i32(count, cpu_env,
  -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
 tcg_temp_free_i32(count);
+
+
 }
 
 static void gen_tb_end(TranslationBlock *tb, int num_insns)
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 9daba69..fc2526c 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -29,6 +29,10 @@
 
 #include "exec/helper-head.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
   dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 
@@ -107,3 +111,98 @@ int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2)
 muls64(, , arg1, arg2);
 return h;
 }
+
+#ifdef CONFIG_TB_ANNOTATION
+static inline void take_final_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+/* Store current context and block */
+env->last_ctx = edge->target_context;
+env->last_block = edge->target;
+/* Accumulate value */
+env->value_sum += edge->value;
+}
+
+static inline void take_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+TbAnnotationLeavingEdgeTuple *out;
+
+/* Store current context and block */
+env->last_ctx = edge->target_context;
+env->last_block = edge->target;
+/* Accumulate value */
+env->value_sum += edge->value;
+
+/* Check whether we are at the end of our analysis... */
+if (env->last_block->out_edges_hash_table != NULL) {
+out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+  env->last_ctx);
+if (out != NULL && out->out1->target->is_end_block) {
+take_final_edge(env, out->out1);
+}
+}
+}
+
+void HELPER(annotation)(uint64_t pc, void *opaque)
+{
+TbAnnotation *env = (TbAnnotation *) opaque;
+TbAnnotationBlock *b;
+TbAnnotationLeavingEdgeTuple *out;
+
+if (!env) {
+return;
+}
+
+/* does the block corresponding to pc exist? */
+if (!g_hash_table_contains(env->tb_annotation_blocks, )) {
+return;
+}
+/* if last_block == NULL we're in the first block */
+if (env->last_block == NULL) {
+
+b = (TbAnnotationBlock *)g_hash_table_lookup(env->tb_annotation_blocks,
+ );
+env->last_block = b;
+
+} else {
+/* while not reached block with current pc (target)
+ * take the next distinct edge if it exists
+ * otherwise we're one edge away from the target and
+ * take the edge directly leading to the target
+ */
+out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+  env->last_ctx);
+
+while (out != NULL && out->out2 == NULL) {
+/* We found a distinct path to "out1" */
+take_edge(env, out->out1);
+
+/* Have we reached our target? */
+if (env->last_block->address == pc) {
+return;
+}
+
+/* Get the current out edge tuple */
+out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+  env->last_ctx