From 1a9d04ec725523bbdd8a600dbea295ed21e4c233 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 11 Feb 2024 18:21:46 +0000 Subject: [PATCH 01/61] make SymQEMU Dockerfile rely on SymCC Dockerfile --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 8a529d93ce..e005b1ecf8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +FROM symcc AS symcc + FROM ubuntu:22.04 RUN apt update From 18fc98c28bb4eaf989fb8111189445281c86ddea Mon Sep 17 00:00:00 2001 From: Aurelien Francillon Date: Thu, 15 Feb 2024 22:36:27 +0100 Subject: [PATCH 02/61] Add some documentation, fix typos in doc, and wrap to 80 columns --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cce352e45a..f071816eaa 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Fedora 33: $ ../configure \ --audio-drv-list= \ - --disable-sdl \ +s --disable-sdl \ --disable-gtk \ --disable-vte \ --disable-opengl \ From c434dfd18c9039effba2a2b1980ea0c25257e1ca Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:36:56 +0000 Subject: [PATCH 03/61] remove unncessary line in Dockerfile --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index e005b1ecf8..8a529d93ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,3 @@ -FROM symcc AS symcc - FROM ubuntu:22.04 RUN apt update From a9cbdff25c45632b0fd588453987713fdfbe72c7 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:46:28 +0000 Subject: [PATCH 04/61] write a wrong test expected output to demonstrate that this makes the tests fail --- tests/symqemu/binaries/simple/expected_outputs/000001 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/symqemu/binaries/simple/expected_outputs/000001 b/tests/symqemu/binaries/simple/expected_outputs/000001 index 2afdfd6872..afed563b62 100644 --- a/tests/symqemu/binaries/simple/expected_outputs/000001 +++ b/tests/symqemu/binaries/simple/expected_outputs/000001 @@ -1 +1 @@ -zbzzzzzzz +zizzzzzzz From 40ffbc2a901c307865aa5d202f7cda1d9b3c27e4 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:48:58 +0000 Subject: [PATCH 05/61] revert previous commit --- tests/symqemu/binaries/simple/expected_outputs/000001 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/symqemu/binaries/simple/expected_outputs/000001 b/tests/symqemu/binaries/simple/expected_outputs/000001 index afed563b62..2afdfd6872 100644 --- a/tests/symqemu/binaries/simple/expected_outputs/000001 +++ b/tests/symqemu/binaries/simple/expected_outputs/000001 @@ -1 +1 @@ -zizzzzzzz +zbzzzzzzz From 6f6df2f9b23b5dca73c6328358b2393cbb8b9cc5 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:38:00 +0000 Subject: [PATCH 06/61] add util function for vec expr --- include/tcg/tcg.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index fc0be635dd..e92bf56cd4 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -742,6 +742,11 @@ static inline TCGv_i64 tcgv_i64_expr_num(TCGv_i64 v) return temp_tcgv_i64(temp_expr(tcgv_i64_temp(v))); } +static inline TCGv_i64 tcgv_vec_expr_num(TCGv_vec v) +{ + return temp_tcgv_i64(temp_expr(tcgv_vec_temp(v))); +} + static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg) { From 0e5af2e9d58f86a7aa76453624cd80329b9018cc Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:40:04 +0000 Subject: [PATCH 07/61] instrument tcg_gen_mov_vec --- tcg/tcg-op-vec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index ad8ee08a7e..5298d2e5b7 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -214,6 +214,7 @@ static void vec_gen_op3(TCGOpcode opc, unsigned vece, void tcg_gen_mov_vec(TCGv_vec r, TCGv_vec a) { if (r != a) { + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcgv_vec_expr_num(a)); vec_gen_op2(INDEX_op_mov_vec, 0, r, a); } } From 39899929b36658f01269dfce2fa7e09bf9544a93 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:18:17 +0000 Subject: [PATCH 08/61] instumented tcg_gen_ld_vec --- accel/tcg/tcg-runtime-sym.c | 5 +++++ accel/tcg/tcg-runtime-sym.h | 1 + tcg/tcg-op-vec.c | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 25a9aa7ae9..8c2089d0f7 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -392,6 +392,11 @@ void *HELPER(sym_load_host_i64)(void *addr, uint64_t offset, uint64_t length) return sym_load_host_internal(addr, offset, length, 8); } +void *HELPER(sym_load_host_v)(void *addr, uint64_t offset, uint64_t length) +{ + return sym_load_host_internal(addr, offset, length, length); +} + void HELPER(sym_store_host_i32)(uint32_t value, void *value_expr, void *addr, uint64_t offset, uint64_t length) diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 1c4f7c5caf..68ed62fac0 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -97,6 +97,7 @@ DEF_HELPER_FLAGS_7(sym_store_guest_i64, TCG_CALL_NO_RWG, void, env, i64, ptr, /* Host memory */ DEF_HELPER_FLAGS_3(sym_load_host_i32, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_load_host_i64, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_3(sym_load_host_v, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_5(sym_store_host_i32, TCG_CALL_NO_RWG, void, i32, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_5(sym_store_host_i64, TCG_CALL_NO_RWG, void, i64, ptr, ptr, diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 5298d2e5b7..e86a000926 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -277,6 +277,24 @@ static void vec_gen_ldst(TCGOpcode opc, TCGv_vec r, TCGv_ptr b, TCGArg o) void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) { + uint64_t length; + + switch(tcgv_vec_temp(r)->base_type) { + case TCG_TYPE_V64: + length = 8; + break; + case TCG_TYPE_V128: + length = 16; + break; + case TCG_TYPE_V256: + length = 32; + break; + default: + g_assert_not_reached(); + } + + gen_helper_sym_load_host_v(tcgv_vec_expr(r), b, tcg_constant_i64(o), tcg_constant_i64(length)); + vec_gen_ldst(INDEX_op_ld_vec, r, b, o); } From af8fa7b718fec9b5dd4a12ed6b5863dfce23a694 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:18:43 +0000 Subject: [PATCH 09/61] add tcgv_vec_expr util function --- include/tcg/tcg.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index e92bf56cd4..f581028b76 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -729,6 +729,11 @@ static inline TCGv_ptr tcgv_i64_expr(TCGv_i64 v) return temp_tcgv_ptr(temp_expr(tcgv_i64_temp(v))); } +static inline TCGv_ptr tcgv_vec_expr(TCGv_vec v) +{ + return temp_tcgv_ptr(temp_expr(tcgv_vec_temp(v))); +} + /* Expression pointers as (64-bit) numbers for code simplification. This assumes * that we're running on a 64-bit architecture! */ From 0165c3fdce1f9857492fbd8b734add92f6b5eb7c Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:25:38 +0000 Subject: [PATCH 10/61] simplify sym_store_host helper --- accel/tcg/tcg-runtime-sym.c | 10 +--------- accel/tcg/tcg-runtime-sym.h | 4 +--- tcg/tcg-op.c | 8 ++++---- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 8c2089d0f7..127e75efac 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -397,15 +397,7 @@ void *HELPER(sym_load_host_v)(void *addr, uint64_t offset, uint64_t length) return sym_load_host_internal(addr, offset, length, length); } -void HELPER(sym_store_host_i32)(uint32_t value, void *value_expr, - void *addr, - uint64_t offset, uint64_t length) -{ - _sym_write_memory((uint8_t*)addr + offset, length, value_expr, true); -} - -void HELPER(sym_store_host_i64)(uint64_t value, void *value_expr, - void *addr, +void HELPER(sym_store_host)(void *value_expr, void *addr, uint64_t offset, uint64_t length) { _sym_write_memory((uint8_t*)addr + offset, length, value_expr, true); diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 68ed62fac0..bce194a788 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -98,9 +98,7 @@ DEF_HELPER_FLAGS_7(sym_store_guest_i64, TCG_CALL_NO_RWG, void, env, i64, ptr, DEF_HELPER_FLAGS_3(sym_load_host_i32, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_load_host_i64, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_load_host_v, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_5(sym_store_host_i32, TCG_CALL_NO_RWG, void, i32, ptr, ptr, - i64, i64) -DEF_HELPER_FLAGS_5(sym_store_host_i64, TCG_CALL_NO_RWG, void, i64, ptr, ptr, +DEF_HELPER_FLAGS_4(sym_store_host, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i64) /* Bit fields */ diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 414c8a6dcf..c8bf78c679 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -122,8 +122,8 @@ void tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val, case INDEX_op_st8_i32: case INDEX_op_st16_i32: case INDEX_op_st_i32: - gen_helper_sym_store_host_i32( - val, tcgv_i32_expr(val), + gen_helper_sym_store_host( + tcgv_i32_expr(val), base, tcg_constant_i64(offset), tcg_constant_i64(data_size) ); break; @@ -180,8 +180,8 @@ void tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val, case INDEX_op_st16_i64: case INDEX_op_st32_i64: case INDEX_op_st_i64: - gen_helper_sym_store_host_i64( - val, tcgv_i64_expr(val), + gen_helper_sym_store_host( + tcgv_i64_expr(val), base, tcg_constant_i64(offset), tcg_constant_i64(data_size) ); break; From 1437949b1cf784b358a4fc184030ecc944906a68 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:37:22 +0000 Subject: [PATCH 11/61] instrumented tcg_gen_st_vec --- tcg/tcg-op-vec.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index e86a000926..1a1bebff0b 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -300,6 +300,24 @@ void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) { + uint64_t length; + + switch(tcgv_vec_temp(r)->base_type) { + case TCG_TYPE_V64: + length = 8; + break; + case TCG_TYPE_V128: + length = 16; + break; + case TCG_TYPE_V256: + length = 32; + break; + default: + g_assert_not_reached(); + } + + gen_helper_sym_store_host(tcgv_vec_expr(r), b, tcg_constant_i64(o), tcg_constant_i64(length) ); + vec_gen_ldst(INDEX_op_st_vec, r, b, o); } From a338746de658027226ccd6ed5c9cd5796c21b859 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 29 Nov 2023 22:12:48 +0000 Subject: [PATCH 12/61] instrument tcg_gen_stl_vec --- tcg/tcg-op-vec.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 1a1bebff0b..583b507e61 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -330,6 +330,25 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr b, TCGArg o, TCGType low_type) tcg_debug_assert(low_type >= TCG_TYPE_V64); tcg_debug_assert(low_type <= type); + + uint64_t length; + + switch (low_type) { + case TCG_TYPE_V64: + length = 8; + break; + case TCG_TYPE_V128: + length = 16; + break; + case TCG_TYPE_V256: + length = 32; + break; + default: + g_assert_not_reached(); + } + + gen_helper_sym_store_host(tcgv_vec_expr(r), b, tcg_constant_i64(o), tcg_constant_i64(length)); + vec_gen_3(INDEX_op_st_vec, low_type, 0, ri, bi, o); } From 29ec563ffd24c1a35e17c2113dd6b7560a0ce1f6 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:30:23 +0000 Subject: [PATCH 13/61] add malloc and free helper functions --- accel/tcg/tcg-runtime-sym.c | 8 ++++++++ accel/tcg/tcg-runtime-sym.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 127e75efac..38332e9abb 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -658,3 +658,11 @@ void HELPER(sym_collect_garbage)(void) { _sym_collect_garbage(); } + +void *HELPER(malloc)(uint64_t size){ + return malloc(size); +} + +void HELPER(free)(void *ptr){ + free(ptr); +} \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index bce194a788..3ed456d576 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -123,6 +123,10 @@ DEF_HELPER_FLAGS_1(sym_notify_block, TCG_CALL_NO_RWG, void, i64) /* Garbage collection */ DEF_HELPER_FLAGS_0(sym_collect_garbage, TCG_CALL_NO_RWG, void) + +DEF_HELPER_FLAGS_1(malloc, TCG_CALL_NO_RWG, ptr, i64) +DEF_HELPER_FLAGS_1(free, TCG_CALL_NO_RWG, void, ptr) + /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ /* The extrl and extrh instructions aren't emitted on 64-bit hosts. If we ever From 64f19e6f28aaa726fadb21dfd5b184995c942ecc Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:40:10 +0000 Subject: [PATCH 14/61] util functions for vector intrumentation --- tcg/tcg-op-vec.c | 75 +++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 583b507e61..4a0d9f7d44 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -24,6 +24,36 @@ #include "tcg/tcg-mo.h" #include "tcg-internal.h" +static int tcg_vec_length_bytes(TCGv_vec vector){ + switch(tcgv_vec_temp(vector)->base_type) { + case TCG_TYPE_V64: + return 8; + case TCG_TYPE_V128: + return 16; + case TCG_TYPE_V256: + return 32; + default: + g_assert_not_reached(); + } +} + +static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ + TCGv_ptr buffer_address = tcg_temp_new_ptr(); + gen_helper_malloc(buffer_address, tcg_constant_i64(tcg_vec_length_bytes(vector))); + + /* store vec at a buffer_address */ + vec_gen_3( + INDEX_op_st_vec, + tcgv_vec_temp(vector)->base_type, + 0, + tcgv_vec_arg(vector), + tcgv_ptr_arg(buffer_address), + 0 + ); + + return buffer_address; +} + /* * Vector optional opcode tracking. * Except for the basic logical operations (and, or, xor), and @@ -277,46 +307,25 @@ static void vec_gen_ldst(TCGOpcode opc, TCGv_vec r, TCGv_ptr b, TCGArg o) void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) { - uint64_t length; - switch(tcgv_vec_temp(r)->base_type) { - case TCG_TYPE_V64: - length = 8; - break; - case TCG_TYPE_V128: - length = 16; - break; - case TCG_TYPE_V256: - length = 32; - break; - default: - g_assert_not_reached(); - } - - gen_helper_sym_load_host_v(tcgv_vec_expr(r), b, tcg_constant_i64(o), tcg_constant_i64(length)); + gen_helper_sym_load_host_v( + tcgv_vec_expr(r), + b, + tcg_constant_i64(o), + tcg_constant_i64(tcg_vec_length_bytes(r)) + ); vec_gen_ldst(INDEX_op_ld_vec, r, b, o); } void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) { - uint64_t length; - - switch(tcgv_vec_temp(r)->base_type) { - case TCG_TYPE_V64: - length = 8; - break; - case TCG_TYPE_V128: - length = 16; - break; - case TCG_TYPE_V256: - length = 32; - break; - default: - g_assert_not_reached(); - } - - gen_helper_sym_store_host(tcgv_vec_expr(r), b, tcg_constant_i64(o), tcg_constant_i64(length) ); + gen_helper_sym_store_host( + tcgv_vec_expr(r), + b, + tcg_constant_i64(o), + tcg_constant_i64(tcg_vec_length_bytes(r)) + ); vec_gen_ldst(INDEX_op_st_vec, r, b, o); } From ab6b435023fe6f976b77096cc3f35a73ebc2d5ca Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:40:18 +0000 Subject: [PATCH 15/61] instrumented tcg_gen_and_vec --- accel/tcg/tcg-runtime-sym.c | 4 ++++ accel/tcg/tcg-runtime-sym.h | 2 ++ tcg/tcg-op-vec.c | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 38332e9abb..774f56a0b7 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -665,4 +665,8 @@ void *HELPER(malloc)(uint64_t size){ void HELPER(free)(void *ptr){ free(ptr); +} + +void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size){ + return NULL; } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 3ed456d576..01d10934e4 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -127,6 +127,8 @@ DEF_HELPER_FLAGS_0(sym_collect_garbage, TCG_CALL_NO_RWG, void) DEF_HELPER_FLAGS_1(malloc, TCG_CALL_NO_RWG, ptr, i64) DEF_HELPER_FLAGS_1(free, TCG_CALL_NO_RWG, void, ptr) +DEF_HELPER_FLAGS_5(sym_and_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64) + /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ /* The extrl and extrh instructions aren't emitted on 64-bit hosts. If we ever diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 4a0d9f7d44..694a768080 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -363,6 +363,26 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr b, TCGArg o, TCGType low_type) void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + TCGv_ptr buffer_address_a = store_vector_in_memory(a); + TCGv_ptr buffer_address_b = store_vector_in_memory(b); + int length_a = tcg_vec_length_bytes(a); + int length_b = tcg_vec_length_bytes(b); + int length_r = tcg_vec_length_bytes(r); + + g_assert(length_a == length_b && length_b == length_r); + + gen_helper_sym_and_vec( + tcgv_vec_expr(r), + buffer_address_a, + tcgv_vec_expr(a), + buffer_address_b, + tcgv_vec_expr(b), + tcg_constant_i64(length_a) + ); + + gen_helper_free(buffer_address_a); + gen_helper_free(buffer_address_b); + vec_gen_op3(INDEX_op_and_vec, 0, r, a, b); } From 45b07f51de89e93e2e14afaecc8e48acbec270c4 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:30:43 +0000 Subject: [PATCH 16/61] implemented sym helper for and vec --- accel/tcg/tcg-runtime-sym.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 774f56a0b7..49bd33175a 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -668,5 +668,23 @@ void HELPER(free)(void *ptr){ } void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size){ - return NULL; + + if (arg1_expr == NULL && arg2_expr == NULL) { + return NULL; + } + + if (arg1_expr == NULL) { + /* _sym_build_integer_arbitrary_length expects arg1 to be an uint64_t array */ + g_assert(size % 8 == 0); + arg1_expr = _sym_build_integer_arbitrary_length(size * 8, size, arg1); + } + + if (arg2_expr == NULL) { + g_assert(size % 8 == 0); + arg2_expr = _sym_build_integer_arbitrary_length(size * 8, size, arg2); + } + + g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr)); + + return _sym_build_and(arg1_expr, arg2_expr); } \ No newline at end of file From 035012434343aacce595d0d9769448c55f6a62f0 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:13:52 +0000 Subject: [PATCH 17/61] generalized sym_and_vec implementation --- accel/tcg/tcg-runtime-sym.c | 17 +++++++++++++++-- accel/tcg/tcg-runtime-sym.h | 2 +- tcg/tcg-op-vec.c | 3 ++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 49bd33175a..1ae06cf7ac 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -667,7 +667,7 @@ void HELPER(free)(void *ptr){ free(ptr); } -void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size){ +void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ if (arg1_expr == NULL && arg2_expr == NULL) { return NULL; @@ -686,5 +686,18 @@ void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_ex g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr)); - return _sym_build_and(arg1_expr, arg2_expr); + uint64_t symbol_count = size * 8 / vece; + void* intermediate_symbols[symbol_count]; + for(uint64_t i = 0; i < symbol_count; i++){ + void *arg1_vec = _sym_extract_helper(arg1_expr, i * vece, (i + 1) * vece - 1); + void *arg2_vec = _sym_extract_helper(arg2_expr, i * vece, (i + 1) * vece - 1); + intermediate_symbols[i] = _sym_build_and(arg1_vec, arg2_vec); + } + + void* final_symbol = intermediate_symbols[0]; + for(uint64_t i = 1; i < symbol_count; i++){ + final_symbol = _sym_concat_helper(final_symbol, intermediate_symbols[i]); + } + + return final_symbol; } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 01d10934e4..9688abbb67 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -127,7 +127,7 @@ DEF_HELPER_FLAGS_0(sym_collect_garbage, TCG_CALL_NO_RWG, void) DEF_HELPER_FLAGS_1(malloc, TCG_CALL_NO_RWG, ptr, i64) DEF_HELPER_FLAGS_1(free, TCG_CALL_NO_RWG, void, ptr) -DEF_HELPER_FLAGS_5(sym_and_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64) +DEF_HELPER_FLAGS_6(sym_and_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 694a768080..5a7b7493c2 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -377,7 +377,8 @@ void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) tcgv_vec_expr(a), buffer_address_b, tcgv_vec_expr(b), - tcg_constant_i64(length_a) + tcg_constant_i64(length_a), + tcg_constant_i64(vece) ); gen_helper_free(buffer_address_a); From 62d1019ec21a35bd689e973d4bcdbd5dfd023967 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:18:46 +0000 Subject: [PATCH 18/61] refactor --- accel/tcg/tcg-runtime-sym.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 1ae06cf7ac..f082ac6302 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -667,8 +667,7 @@ void HELPER(free)(void *ptr){ free(ptr); } -void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - +static void* build_symbol_for_vector_binary_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece, void* (*sym_build_op)(void*, void*)){ if (arg1_expr == NULL && arg2_expr == NULL) { return NULL; } @@ -691,7 +690,7 @@ void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_ex for(uint64_t i = 0; i < symbol_count; i++){ void *arg1_vec = _sym_extract_helper(arg1_expr, i * vece, (i + 1) * vece - 1); void *arg2_vec = _sym_extract_helper(arg2_expr, i * vece, (i + 1) * vece - 1); - intermediate_symbols[i] = _sym_build_and(arg1_vec, arg2_vec); + intermediate_symbols[i] = sym_build_op(arg1_vec, arg2_vec); } void* final_symbol = intermediate_symbols[0]; @@ -700,4 +699,10 @@ void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_ex } return final_symbol; +} + + +void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + + return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); } \ No newline at end of file From da2ee3657d93d4a72f8de405d9ce5e63ee5c9bbe Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:25:49 +0000 Subject: [PATCH 19/61] refactor --- tcg/tcg-op-vec.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 5a7b7493c2..1cdc74c327 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -54,6 +54,29 @@ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ return buffer_address; } +static void binary_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i64)){ + TCGv_ptr buffer_address_a = store_vector_in_memory(a); + TCGv_ptr buffer_address_b = store_vector_in_memory(b); + int length_a = tcg_vec_length_bytes(a); + int length_b = tcg_vec_length_bytes(b); + int length_r = tcg_vec_length_bytes(r); + + g_assert(length_a == length_b && length_b == length_r); + + sym_helper( + tcgv_vec_expr(r), + buffer_address_a, + tcgv_vec_expr(a), + buffer_address_b, + tcgv_vec_expr(b), + tcg_constant_i64(length_a), + tcg_constant_i64(vece) + ); + + gen_helper_free(buffer_address_a); + gen_helper_free(buffer_address_b); +} + /* * Vector optional opcode tracking. * Except for the basic logical operations (and, or, xor), and @@ -363,27 +386,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr b, TCGArg o, TCGType low_type) void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - TCGv_ptr buffer_address_a = store_vector_in_memory(a); - TCGv_ptr buffer_address_b = store_vector_in_memory(b); - int length_a = tcg_vec_length_bytes(a); - int length_b = tcg_vec_length_bytes(b); - int length_r = tcg_vec_length_bytes(r); - - g_assert(length_a == length_b && length_b == length_r); - - gen_helper_sym_and_vec( - tcgv_vec_expr(r), - buffer_address_a, - tcgv_vec_expr(a), - buffer_address_b, - tcgv_vec_expr(b), - tcg_constant_i64(length_a), - tcg_constant_i64(vece) - ); - - gen_helper_free(buffer_address_a); - gen_helper_free(buffer_address_b); - + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_and_vec); vec_gen_op3(INDEX_op_and_vec, 0, r, a, b); } From 0a1f32b6299cd576d833448f174ce01437641206 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:31:20 +0000 Subject: [PATCH 20/61] fix free temp --- tcg/tcg-op-vec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 1cdc74c327..f3d60cd37c 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -75,6 +75,9 @@ static void binary_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, gen_helper_free(buffer_address_a); gen_helper_free(buffer_address_b); + + tcg_temp_free_ptr(buffer_address_a); + tcg_temp_free_ptr(buffer_address_b); } /* From 73a618aecededba55735fa14547ae78671c5a769 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:52:05 +0000 Subject: [PATCH 21/61] instrumented vec or,xor,add,sub,mul --- accel/tcg/tcg-runtime-sym.c | 22 ++++++++++++++++++++-- accel/tcg/tcg-runtime-sym.h | 5 +++++ tcg/tcg-op-vec.c | 5 +++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index f082ac6302..cf2e3a0e8d 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -701,8 +701,26 @@ static void* build_symbol_for_vector_binary_op(void *arg1, void *arg1_expr, void return final_symbol; } - void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); +} + +void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); +} + +void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); +} + +void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); +} + +void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); +} + +void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 9688abbb67..ac42cf742a 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -128,6 +128,11 @@ DEF_HELPER_FLAGS_1(malloc, TCG_CALL_NO_RWG, ptr, i64) DEF_HELPER_FLAGS_1(free, TCG_CALL_NO_RWG, void, ptr) DEF_HELPER_FLAGS_6(sym_and_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_or_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_xor_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_mul_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index f3d60cd37c..62bc18193c 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -395,11 +395,13 @@ void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_or_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_or_vec); vec_gen_op3(INDEX_op_or_vec, 0, r, a, b); } void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_xor_vec); vec_gen_op3(INDEX_op_xor_vec, 0, r, a, b); } @@ -658,16 +660,19 @@ static void do_op3_nofail(unsigned vece, TCGv_vec r, TCGv_vec a, void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_add_vec); do_op3_nofail(vece, r, a, b, INDEX_op_add_vec); } void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_sub_vec); do_op3_nofail(vece, r, a, b, INDEX_op_sub_vec); } void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_mul_vec); do_op3_nofail(vece, r, a, b, INDEX_op_mul_vec); } From ad3e1ee2f8668eb12625c9376580efc399ae6617 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 1 Dec 2023 01:00:47 +0000 Subject: [PATCH 22/61] typo --- tcg/tcg-op-vec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 62bc18193c..79fc24b91b 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -41,7 +41,7 @@ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ TCGv_ptr buffer_address = tcg_temp_new_ptr(); gen_helper_malloc(buffer_address, tcg_constant_i64(tcg_vec_length_bytes(vector))); - /* store vec at a buffer_address */ + /* store vec at buffer_address */ vec_gen_3( INDEX_op_st_vec, tcgv_vec_temp(vector)->base_type, From bd8f5a536e874b82aaf586a0fc78894b0bed3eca Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:02:15 +0000 Subject: [PATCH 23/61] make vector operations andc,orc,nand,nor,eqv be built with instrumented operations --- tcg/tcg-op-vec.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 79fc24b91b..20c8bcbdde 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -407,56 +407,56 @@ void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - if (TCG_TARGET_HAS_andc_vec) { + /* if (TCG_TARGET_HAS_andc_vec) { vec_gen_op3(INDEX_op_andc_vec, 0, r, a, b); - } else { + } else { */ TCGv_vec t = tcg_temp_new_vec_matching(r); tcg_gen_not_vec(0, t, b); tcg_gen_and_vec(0, r, a, t); tcg_temp_free_vec(t); - } + /* } */ } void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - if (TCG_TARGET_HAS_orc_vec) { + /* if (TCG_TARGET_HAS_orc_vec) { vec_gen_op3(INDEX_op_orc_vec, 0, r, a, b); - } else { + } else { */ TCGv_vec t = tcg_temp_new_vec_matching(r); tcg_gen_not_vec(0, t, b); tcg_gen_or_vec(0, r, a, t); tcg_temp_free_vec(t); - } + /* } */ } void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - if (TCG_TARGET_HAS_nand_vec) { + /* if (TCG_TARGET_HAS_nand_vec) { vec_gen_op3(INDEX_op_nand_vec, 0, r, a, b); - } else { + } else { */ tcg_gen_and_vec(0, r, a, b); tcg_gen_not_vec(0, r, r); - } + /* } */ } void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - if (TCG_TARGET_HAS_nor_vec) { + /* if (TCG_TARGET_HAS_nor_vec) { vec_gen_op3(INDEX_op_nor_vec, 0, r, a, b); - } else { + } else { */ tcg_gen_or_vec(0, r, a, b); tcg_gen_not_vec(0, r, r); - } + /* } */ } void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - if (TCG_TARGET_HAS_eqv_vec) { + /* if (TCG_TARGET_HAS_eqv_vec) { vec_gen_op3(INDEX_op_eqv_vec, 0, r, a, b); - } else { + } else { */ tcg_gen_xor_vec(0, r, a, b); tcg_gen_not_vec(0, r, r); - } + /* } */ } static bool do_op2(unsigned vece, TCGv_vec r, TCGv_vec a, TCGOpcode opc) From 197924f9b7492167ba72830357f60a41d737eeb3 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:32:20 +0000 Subject: [PATCH 24/61] make vector operations not and neg be built with instrumented operations --- tcg/tcg-op-vec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 20c8bcbdde..3983b7263d 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -487,9 +487,9 @@ void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a) { const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); - if (!TCG_TARGET_HAS_not_vec || !do_op2(vece, r, a, INDEX_op_not_vec)) { + /*if (!TCG_TARGET_HAS_not_vec || !do_op2(vece, r, a, INDEX_op_not_vec)) {*/ tcg_gen_xor_vec(0, r, a, tcg_constant_vec_matching(r, 0, -1)); - } + /*}*/ tcg_swap_vecop_list(hold_list); } @@ -500,9 +500,9 @@ void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a) tcg_assert_listed_vecop(INDEX_op_neg_vec); hold_list = tcg_swap_vecop_list(NULL); - if (!TCG_TARGET_HAS_neg_vec || !do_op2(vece, r, a, INDEX_op_neg_vec)) { + /*if (!TCG_TARGET_HAS_neg_vec || !do_op2(vece, r, a, INDEX_op_neg_vec)) {*/ tcg_gen_sub_vec(vece, r, tcg_constant_vec_matching(r, vece, 0), a); - } + /*}*/ tcg_swap_vecop_list(hold_list); } From b4d10cf43bc4b77efcaa5e57bba1042936e8b2e3 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:49:08 +0000 Subject: [PATCH 25/61] make vector operations abs be built with instrumented operations --- tcg/tcg-op-vec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 3983b7263d..c68b0f196c 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -513,7 +513,7 @@ void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a) tcg_assert_listed_vecop(INDEX_op_abs_vec); hold_list = tcg_swap_vecop_list(NULL); - if (!do_op2(vece, r, a, INDEX_op_abs_vec)) { + /*if (!do_op2(vece, r, a, INDEX_op_abs_vec)) {*/ TCGType type = tcgv_vec_temp(r)->base_type; TCGv_vec t = tcg_temp_new_vec(type); @@ -533,7 +533,7 @@ void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a) } tcg_temp_free_vec(t); - } + /*}*/ tcg_swap_vecop_list(hold_list); } From 4647e1a03c2b08cf0a73c2bbe9bed67daf082995 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 16:22:44 +0000 Subject: [PATCH 26/61] refactor --- accel/tcg/tcg-runtime-sym.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index cf2e3a0e8d..d4098d4f03 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -667,7 +667,7 @@ void HELPER(free)(void *ptr){ free(ptr); } -static void* build_symbol_for_vector_binary_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece, void* (*sym_build_op)(void*, void*)){ +static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece, void* (*sym_build_op)(void*, void*)){ if (arg1_expr == NULL && arg2_expr == NULL) { return NULL; } @@ -702,25 +702,25 @@ static void* build_symbol_for_vector_binary_op(void *arg1, void *arg1_expr, void } void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); } void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); } void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); } void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); } void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); } void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_binary_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); } \ No newline at end of file From 8186dd696cf8eb9ec24d720b12f946f53e564357 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 18:20:24 +0000 Subject: [PATCH 27/61] refactor --- accel/tcg/tcg-runtime-sym.c | 54 +++++++++++++++++++++++-------------- tcg/tcg-op-vec.c | 24 ++++++++--------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index d4098d4f03..2abacd5771 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -667,38 +667,52 @@ void HELPER(free)(void *ptr){ free(ptr); } -static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece, void* (*sym_build_op)(void*, void*)){ +static void split_symbol(void* symbol, uint64_t element_count, void* result[]){ + g_assert(_sym_bits_helper(symbol) % element_count == 0); + for(uint64_t i = 0; i < element_count; i++){ + result[i] = _sym_extract_helper(symbol, i * 8, (i + 1) * 8 - 1); + } +} + +static void *apply_op_and_merge(void* (*op)(void*, void*), void* arg1[], void* arg2[], uint64_t element_count){ + void* merged_result = op(arg1[0], arg2[0]); + for(uint64_t i = 1; i < element_count; i++){ + merged_result = _sym_concat_helper(merged_result, op(arg1[i], arg2[i])); + } + return merged_result; +} + +static uint64_t vece_element_size(uint64_t vece){ + /* see definition of vece here https://www.qemu.org/docs/master/devel/tcg-ops.html#host-vector-operations */ + return 8 << vece; +} + +static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + if (arg1_expr == NULL && arg2_expr == NULL) { return NULL; } if (arg1_expr == NULL) { - /* _sym_build_integer_arbitrary_length expects arg1 to be an uint64_t array */ - g_assert(size % 8 == 0); - arg1_expr = _sym_build_integer_arbitrary_length(size * 8, size, arg1); + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); } if (arg2_expr == NULL) { - g_assert(size % 8 == 0); - arg2_expr = _sym_build_integer_arbitrary_length(size * 8, size, arg2); + arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); } - g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr)); + g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); - uint64_t symbol_count = size * 8 / vece; - void* intermediate_symbols[symbol_count]; - for(uint64_t i = 0; i < symbol_count; i++){ - void *arg1_vec = _sym_extract_helper(arg1_expr, i * vece, (i + 1) * vece - 1); - void *arg2_vec = _sym_extract_helper(arg2_expr, i * vece, (i + 1) * vece - 1); - intermediate_symbols[i] = sym_build_op(arg1_vec, arg2_vec); - } - - void* final_symbol = intermediate_symbols[0]; - for(uint64_t i = 1; i < symbol_count; i++){ - final_symbol = _sym_concat_helper(final_symbol, intermediate_symbols[i]); - } + uint64_t element_count = vector_size / element_size; + void* arg1_elements[element_count]; + void* arg2_elements[element_count]; + split_symbol(arg1_expr, element_count, arg1_elements); + split_symbol(arg2_expr, element_count, arg2_elements); - return final_symbol; + return apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); } void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index c68b0f196c..c76635560f 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -24,14 +24,14 @@ #include "tcg/tcg-mo.h" #include "tcg-internal.h" -static int tcg_vec_length_bytes(TCGv_vec vector){ +static int vec_size(TCGv_vec vector){ switch(tcgv_vec_temp(vector)->base_type) { case TCG_TYPE_V64: - return 8; + return 64; case TCG_TYPE_V128: - return 16; + return 128; case TCG_TYPE_V256: - return 32; + return 256; default: g_assert_not_reached(); } @@ -39,7 +39,7 @@ static int tcg_vec_length_bytes(TCGv_vec vector){ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ TCGv_ptr buffer_address = tcg_temp_new_ptr(); - gen_helper_malloc(buffer_address, tcg_constant_i64(tcg_vec_length_bytes(vector))); + gen_helper_malloc(buffer_address, tcg_constant_i64(vec_size(vector) / 8)); /* store vec at buffer_address */ vec_gen_3( @@ -57,11 +57,11 @@ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ static void binary_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i64)){ TCGv_ptr buffer_address_a = store_vector_in_memory(a); TCGv_ptr buffer_address_b = store_vector_in_memory(b); - int length_a = tcg_vec_length_bytes(a); - int length_b = tcg_vec_length_bytes(b); - int length_r = tcg_vec_length_bytes(r); + int size_a = vec_size(a); + int size_b = vec_size(b); + int size_r = vec_size(r); - g_assert(length_a == length_b && length_b == length_r); + g_assert(size_a == size_b && size_b == size_r); sym_helper( tcgv_vec_expr(r), @@ -69,7 +69,7 @@ static void binary_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, tcgv_vec_expr(a), buffer_address_b, tcgv_vec_expr(b), - tcg_constant_i64(length_a), + tcg_constant_i64(size_a), tcg_constant_i64(vece) ); @@ -338,7 +338,7 @@ void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) tcgv_vec_expr(r), b, tcg_constant_i64(o), - tcg_constant_i64(tcg_vec_length_bytes(r)) + tcg_constant_i64(vec_size(r)) ); vec_gen_ldst(INDEX_op_ld_vec, r, b, o); @@ -350,7 +350,7 @@ void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) tcgv_vec_expr(r), b, tcg_constant_i64(o), - tcg_constant_i64(tcg_vec_length_bytes(r)) + tcg_constant_i64(vec_size(r)) ); vec_gen_ldst(INDEX_op_st_vec, r, b, o); From eb45cd6580b558af6275be8f632319d320ef669b Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 18:34:58 +0000 Subject: [PATCH 28/61] add build_symbol_for_vector_int32_op function --- accel/tcg/tcg-runtime-sym.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 2abacd5771..6a34ee37a0 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -715,6 +715,37 @@ static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void return apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); } +static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_expr == NULL && arg2_expr == NULL) { + return NULL; + } + + if (arg1_expr == NULL) { + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + } + + if (arg2_expr == NULL) { + arg2_expr = _sym_build_integer(arg2, 32); + } + + g_assert(_sym_bits_helper(arg1_expr) == vector_size); + g_assert(_sym_bits_helper(arg2_expr) == 32); + + uint64_t element_count = vector_size / element_size; + void* arg1_elements[element_count]; + void* arg2_elements[element_count]; + split_symbol(arg1_expr, element_count, arg1_elements); + for(uint64_t i = 0; i < element_count; i++){ + arg2_elements[i] = arg2_expr; + } + + return apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); +} + void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); } From 50251f92cf8bd87ba79214eddb90a7547e045183 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 19:10:06 +0000 Subject: [PATCH 29/61] instrumented vec vec shifts and rotates ops --- accel/tcg/tcg-runtime-sym.c | 20 ++++++++++++++++++++ accel/tcg/tcg-runtime-sym.h | 5 +++++ tcg/tcg-op-vec.c | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 6a34ee37a0..9174452361 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -768,4 +768,24 @@ void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_ex void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); +} + +void *HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); +} + +void *HELPER(sym_logical_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); +} + +void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); +} + +void *HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); +} + +void *HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index ac42cf742a..7dd621769d 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -133,6 +133,11 @@ DEF_HELPER_FLAGS_6(sym_xor_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i DEF_HELPER_FLAGS_6(sym_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_mul_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_shift_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index c76635560f..150ae67924 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -749,26 +749,31 @@ void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_shift_left_vec); do_op3_nofail(vece, r, a, b, INDEX_op_shlv_vec); } void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_logical_shift_right_vec); do_op3_nofail(vece, r, a, b, INDEX_op_shrv_vec); } void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_arithmetic_shift_right_vec); do_op3_nofail(vece, r, a, b, INDEX_op_sarv_vec); } void tcg_gen_rotlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_rotate_left_vec); do_op3_nofail(vece, r, a, b, INDEX_op_rotlv_vec); } void tcg_gen_rotrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_rotate_right_vec); do_op3_nofail(vece, r, a, b, INDEX_op_rotrv_vec); } From 1636af2ff89a318a199ee8bdd6160626de95e02f Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 20:08:52 +0000 Subject: [PATCH 30/61] instrumented vec i32 shifts and rotates ops --- accel/tcg/tcg-runtime-sym.c | 20 +++++++++++++++ accel/tcg/tcg-runtime-sym.h | 5 ++++ tcg/tcg-op-vec.c | 50 ++++++++++++++++++++++++++++--------- 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 9174452361..7738803729 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -788,4 +788,24 @@ void *HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void void *HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); +} + +void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); +} + +void *HELPER(sym_logical_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); +} + +void *HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); +} + +void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); +} + +void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 7dd621769d..be3d65bf32 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -138,6 +138,11 @@ DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_shift_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 150ae67924..e6ce19c346 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -54,7 +54,7 @@ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ return buffer_address; } -static void binary_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i64)){ +static void vec_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i64)){ TCGv_ptr buffer_address_a = store_vector_in_memory(a); TCGv_ptr buffer_address_b = store_vector_in_memory(b); int size_a = vec_size(a); @@ -80,6 +80,28 @@ static void binary_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, tcg_temp_free_ptr(buffer_address_b); } +static void vec_int32_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32, TCGv_ptr, TCGv_i64, TCGv_i64)){ + TCGv_ptr buffer_address_a = store_vector_in_memory(a); + int size_a = vec_size(a); + int size_r = vec_size(r); + + g_assert(size_a == size_r); + + sym_helper( + tcgv_vec_expr(r), + buffer_address_a, + tcgv_vec_expr(a), + b, + tcgv_i32_expr(b), + tcg_constant_i64(size_a), + tcg_constant_i64(vece) + ); + + gen_helper_free(buffer_address_a); + + tcg_temp_free_ptr(buffer_address_a); +} + /* * Vector optional opcode tracking. * Except for the basic logical operations (and, or, xor), and @@ -389,19 +411,19 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr b, TCGArg o, TCGType low_type) void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_and_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_and_vec); vec_gen_op3(INDEX_op_and_vec, 0, r, a, b); } void tcg_gen_or_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_or_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_or_vec); vec_gen_op3(INDEX_op_or_vec, 0, r, a, b); } void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_xor_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_xor_vec); vec_gen_op3(INDEX_op_xor_vec, 0, r, a, b); } @@ -660,19 +682,19 @@ static void do_op3_nofail(unsigned vece, TCGv_vec r, TCGv_vec a, void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_add_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_add_vec); do_op3_nofail(vece, r, a, b, INDEX_op_add_vec); } void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_sub_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_sub_vec); do_op3_nofail(vece, r, a, b, INDEX_op_sub_vec); } void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_mul_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_mul_vec); do_op3_nofail(vece, r, a, b, INDEX_op_mul_vec); } @@ -749,31 +771,31 @@ void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_shift_left_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_shift_left_vec); do_op3_nofail(vece, r, a, b, INDEX_op_shlv_vec); } void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_logical_shift_right_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_logical_shift_right_vec); do_op3_nofail(vece, r, a, b, INDEX_op_shrv_vec); } void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_arithmetic_shift_right_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_arithmetic_shift_right_vec); do_op3_nofail(vece, r, a, b, INDEX_op_sarv_vec); } void tcg_gen_rotlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_rotate_left_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_rotate_left_vec); do_op3_nofail(vece, r, a, b, INDEX_op_rotlv_vec); } void tcg_gen_rotrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - binary_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_rotate_right_vec); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_rotate_right_vec); do_op3_nofail(vece, r, a, b, INDEX_op_rotrv_vec); } @@ -805,21 +827,25 @@ static void do_shifts(unsigned vece, TCGv_vec r, TCGv_vec a, void tcg_gen_shls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 b) { + vec_int32_op_instrumentation(vece, r, a, b, gen_helper_sym_shift_left_vec_int32); do_shifts(vece, r, a, b, INDEX_op_shls_vec); } void tcg_gen_shrs_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 b) { + vec_int32_op_instrumentation(vece, r, a, b, gen_helper_sym_logical_shift_right_vec_int32); do_shifts(vece, r, a, b, INDEX_op_shrs_vec); } void tcg_gen_sars_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 b) { + vec_int32_op_instrumentation(vece, r, a, b, gen_helper_sym_arithmetic_shift_right_vec_int32); do_shifts(vece, r, a, b, INDEX_op_sars_vec); } void tcg_gen_rotls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s) { + vec_int32_op_instrumentation(vece, r, a, s, gen_helper_sym_rotate_left_vec_int32); do_shifts(vece, r, a, s, INDEX_op_rotls_vec); } From 0ec22e4d315a55f15f07697d930f4e56dd915c6d Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 2 Dec 2023 20:13:10 +0000 Subject: [PATCH 31/61] instrumented vec immediate shifts and rotates ops --- tcg/tcg-op-vec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index e6ce19c346..fe18da0d8f 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -594,21 +594,25 @@ static void do_shifti(TCGOpcode opc, unsigned vece, void tcg_gen_shli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i) { + vec_int32_op_instrumentation(vece, r, a, tcg_constant_i32(i), gen_helper_sym_shift_left_vec_int32); do_shifti(INDEX_op_shli_vec, vece, r, a, i); } void tcg_gen_shri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i) { + vec_int32_op_instrumentation(vece, r, a, tcg_constant_i32(i), gen_helper_sym_logical_shift_right_vec_int32); do_shifti(INDEX_op_shri_vec, vece, r, a, i); } void tcg_gen_sari_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i) { + vec_int32_op_instrumentation(vece, r, a, tcg_constant_i32(i), gen_helper_sym_arithmetic_shift_right_vec_int32); do_shifti(INDEX_op_sari_vec, vece, r, a, i); } void tcg_gen_rotli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i) { + vec_int32_op_instrumentation(vece, r, a, tcg_constant_i32(i), gen_helper_sym_rotate_left_vec_int32); do_shifti(INDEX_op_rotli_vec, vece, r, a, i); } @@ -616,6 +620,7 @@ void tcg_gen_rotri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i) { int bits = 8 << vece; tcg_debug_assert(i >= 0 && i < bits); + vec_int32_op_instrumentation(vece, r, a, tcg_constant_i32(i), gen_helper_sym_rotate_right_vec_int32); do_shifti(INDEX_op_rotli_vec, vece, r, a, -i & (bits - 1)); } From 55f9de426ef24b9a551ebb9a3fdc00a014393f6e Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 13:39:49 +0000 Subject: [PATCH 32/61] refactor --- accel/tcg/tcg-runtime-sym.c | 94 ++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 7738803729..be5534687e 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -569,74 +569,80 @@ void *HELPER(sym_deposit_i64)(uint64_t arg1, void *arg1_expr, _sym_build_integer(ofs, 64))); } +static void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, int32_t comparison_operator, uint64_t is_taken){ + void *(*handler)(void *, void*); + switch (comparison_operator) { + case TCG_COND_EQ: + handler = _sym_build_equal; + break; + case TCG_COND_NE: + handler = _sym_build_not_equal; + break; + case TCG_COND_LT: + handler = _sym_build_signed_less_than; + break; + case TCG_COND_GE: + handler = _sym_build_signed_greater_equal; + break; + case TCG_COND_LE: + handler = _sym_build_signed_less_equal; + break; + case TCG_COND_GT: + handler = _sym_build_signed_greater_than; + break; + case TCG_COND_LTU: + handler = _sym_build_unsigned_less_than; + break; + case TCG_COND_GEU: + handler = _sym_build_unsigned_greater_equal; + break; + case TCG_COND_LEU: + handler = _sym_build_unsigned_less_equal; + break; + case TCG_COND_GTU: + handler = _sym_build_unsigned_greater_than; + break; + default: + g_assert_not_reached(); + } + + void *condition_symbol = handler(arg1_expr, arg2_expr); + _sym_push_path_constraint(condition_symbol, is_taken, get_pc(env)); + + return condition_symbol; +} + static void *sym_setcond_internal(CPUArchState *env, uint64_t arg1, void *arg1_expr, uint64_t arg2, void *arg2_expr, - int32_t cond, uint64_t result, + int32_t comparison_operator, uint64_t is_taken, uint8_t result_bits) { BINARY_HELPER_ENSURE_EXPRESSIONS; - void *(*handler)(void *, void*); - switch (cond) { - case TCG_COND_EQ: - handler = _sym_build_equal; - break; - case TCG_COND_NE: - handler = _sym_build_not_equal; - break; - case TCG_COND_LT: - handler = _sym_build_signed_less_than; - break; - case TCG_COND_GE: - handler = _sym_build_signed_greater_equal; - break; - case TCG_COND_LE: - handler = _sym_build_signed_less_equal; - break; - case TCG_COND_GT: - handler = _sym_build_signed_greater_than; - break; - case TCG_COND_LTU: - handler = _sym_build_unsigned_less_than; - break; - case TCG_COND_GEU: - handler = _sym_build_unsigned_greater_equal; - break; - case TCG_COND_LEU: - handler = _sym_build_unsigned_less_equal; - break; - case TCG_COND_GTU: - handler = _sym_build_unsigned_greater_than; - break; - default: - g_assert_not_reached(); - } - - void *condition = handler(arg1_expr, arg2_expr); - _sym_push_path_constraint(condition, result, get_pc(env)); + void *condition_symbol = build_and_push_path_constraint(env, arg1_expr, arg2_expr, comparison_operator, is_taken); assert(result_bits > 1); - return _sym_build_zext(_sym_build_bool_to_bit(condition), + return _sym_build_zext(_sym_build_bool_to_bit(condition_symbol), result_bits - 1); } void *HELPER(sym_setcond_i32)(CPUArchState *env, uint32_t arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, - int32_t cond, uint32_t result) + int32_t comparison_operator, uint32_t is_taken) { return sym_setcond_internal( - env, arg1, arg1_expr, arg2, arg2_expr, cond, result, 32); + env, arg1, arg1_expr, arg2, arg2_expr, comparison_operator, is_taken, 32); } void *HELPER(sym_setcond_i64)(CPUArchState *env, uint64_t arg1, void *arg1_expr, uint64_t arg2, void *arg2_expr, - int32_t cond, uint64_t result) + int32_t comparison_operator, uint64_t is_taken) { return sym_setcond_internal( - env, arg1, arg1_expr, arg2, arg2_expr, cond, result, 64); + env, arg1, arg1_expr, arg2, arg2_expr, comparison_operator, is_taken, 64); } void HELPER(sym_notify_call)(uint64_t return_address) From d8074f5ce52cdd4be8084a8931ebefd23c932e49 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 14:42:23 +0000 Subject: [PATCH 33/61] add support of helper functions with 8 and 9 args --- include/exec/helper-gen.h.inc | 30 ++++++++++++++++++++++++++++++ include/exec/helper-info.c.inc | 25 +++++++++++++++++++++++++ include/exec/helper-proto.h.inc | 14 ++++++++++++++ include/tcg/tcg.h | 4 ++++ tcg/tcg.c | 16 ++++++++++++++++ 5 files changed, 89 insertions(+) diff --git a/include/exec/helper-gen.h.inc b/include/exec/helper-gen.h.inc index c009641517..0739933ada 100644 --- a/include/exec/helper-gen.h.inc +++ b/include/exec/helper-gen.h.inc @@ -90,6 +90,34 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \ dh_arg(t7, 7)); \ } +#define DEF_HELPER_FLAGS_8(name, flags, ret, t1, t2, t3, t4, t5, t6, t7, \ + t8) \ +extern TCGHelperInfo glue(helper_info_, name); \ +static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \ + dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \ + dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \ + dh_arg_decl(t7, 7), dh_arg_decl(t8, 8)) \ +{ \ + tcg_gen_call8(&glue(helper_info_, name), dh_retvar(ret), \ + dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \ + dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \ + dh_arg(t7, 7), dh_arg(t8, 8)); \ +} + +#define DEF_HELPER_FLAGS_9(name, flags, ret, t1, t2, t3, t4, t5, t6, t7, \ + t8, t9) \ +extern TCGHelperInfo glue(helper_info_, name); \ +static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \ + dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \ + dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \ + dh_arg_decl(t7, 7), dh_arg_decl(t8, 8), dh_arg_decl(t9, 9)) \ +{ \ + tcg_gen_call9(&glue(helper_info_, name), dh_retvar(ret), \ + dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \ + dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \ + dh_arg(t7, 7), dh_arg(t8, 8), dh_arg(t9, 9)); \ +} + #include HELPER_H #undef DEF_HELPER_FLAGS_0 @@ -100,3 +128,5 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \ #undef DEF_HELPER_FLAGS_5 #undef DEF_HELPER_FLAGS_6 #undef DEF_HELPER_FLAGS_7 +#undef DEF_HELPER_FLAGS_8 +#undef DEF_HELPER_FLAGS_9 diff --git a/include/exec/helper-info.c.inc b/include/exec/helper-info.c.inc index 530d2e6d35..273fcbe2a3 100644 --- a/include/exec/helper-info.c.inc +++ b/include/exec/helper-info.c.inc @@ -83,6 +83,29 @@ | dh_typemask(T6, 6) | dh_typemask(T7, 7) \ }; +#define DEF_HELPER_FLAGS_8(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6, T7, T8) \ + TCGHelperInfo glue(helper_info_, NAME) = { \ + .func = HELPER(NAME), .name = str(NAME), \ + .flags = FLAGS | dh_callflag(RET), \ + .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \ + | dh_typemask(T2, 2) | dh_typemask(T3, 3) \ + | dh_typemask(T4, 4) | dh_typemask(T5, 5) \ + | dh_typemask(T6, 6) | dh_typemask(T7, 7) \ + | dh_typemask(T8, 8) \ + }; + +#define DEF_HELPER_FLAGS_9(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6, T7, T8, T9) \ + TCGHelperInfo glue(helper_info_, NAME) = { \ + .func = HELPER(NAME), .name = str(NAME), \ + .flags = FLAGS | dh_callflag(RET), \ + .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \ + | dh_typemask(T2, 2) | dh_typemask(T3, 3) \ + | dh_typemask(T4, 4) | dh_typemask(T5, 5) \ + | dh_typemask(T6, 6) | dh_typemask(T7, 7) \ + | dh_typemask(T8, 8) | dh_typemask(T9, 9) \ + }; + + #include HELPER_H #undef str @@ -94,3 +117,5 @@ #undef DEF_HELPER_FLAGS_5 #undef DEF_HELPER_FLAGS_6 #undef DEF_HELPER_FLAGS_7 +#undef DEF_HELPER_FLAGS_8 +#undef DEF_HELPER_FLAGS_9 diff --git a/include/exec/helper-proto.h.inc b/include/exec/helper-proto.h.inc index c3aa666929..c615cea5d4 100644 --- a/include/exec/helper-proto.h.inc +++ b/include/exec/helper-proto.h.inc @@ -51,6 +51,18 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \ dh_ctype(t7)) DEF_HELPER_ATTR; +# define DEF_HELPER_FLAGS_8(name, flags, ret, t1, t2, t3, t4, t5, t6, t7, t8) \ +dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ + dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \ + dh_ctype(t7), dh_ctype(t8)) DEF_HELPER_ATTR; + +#define DEF_HELPER_FLAGS_9(name, flags, ret, t1, t2, t3, t4, t5, t6, t7, t8, \ + t9) \ +dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ + dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \ + dh_ctype(t7), dh_ctype(t8), dh_ctype(t9)) \ + DEF_HELPER_ATTR; + #define IN_HELPER_PROTO #include HELPER_H @@ -65,4 +77,6 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ #undef DEF_HELPER_FLAGS_5 #undef DEF_HELPER_FLAGS_6 #undef DEF_HELPER_FLAGS_7 +#undef DEF_HELPER_FLAGS_8 +#undef DEF_HELPER_FLAGS_9 #undef DEF_HELPER_ATTR diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index f581028b76..0d3b1a475d 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -963,6 +963,10 @@ void tcg_gen_call6(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *); void tcg_gen_call7(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *); +void tcg_gen_call8(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *, + TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *); +void tcg_gen_call9(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *, + TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *); TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs); void tcg_op_remove(TCGContext *s, TCGOp *op); diff --git a/tcg/tcg.c b/tcg/tcg.c index 1a5562d6c6..c3582865be 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -2345,6 +2345,22 @@ void tcg_gen_call7(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, tcg_gen_callN(info, ret, args); } +void tcg_gen_call8(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, TCGTemp *t2, + TCGTemp *t3, TCGTemp *t4, TCGTemp *t5, TCGTemp *t6, + TCGTemp *t7, TCGTemp *t8) +{ + TCGTemp *args[8] = { t1, t2, t3, t4, t5, t6, t7, t8 }; + tcg_gen_callN(info, ret, args); +} + +void tcg_gen_call9(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, TCGTemp *t2, + TCGTemp *t3, TCGTemp *t4, TCGTemp *t5, TCGTemp *t6, + TCGTemp *t7, TCGTemp *t8, TCGTemp *t9) +{ + TCGTemp *args[9] = { t1, t2, t3, t4, t5, t6, t7, t8, t9 }; + tcg_gen_callN(info, ret, args); +} + static void tcg_reg_alloc_start(TCGContext *s) { int i, n; From 0f9e96147ac0517be767fce10c729ed57bbb7c0c Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 15:09:40 +0000 Subject: [PATCH 34/61] instrumented tcg_gen_cmp_vec --- accel/tcg/tcg-runtime-sym.c | 55 +++++++++++++++++++++++++++++++++---- accel/tcg/tcg-runtime-sym.h | 1 + tcg/tcg-op-vec.c | 38 +++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index be5534687e..51371bfe01 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -569,7 +569,7 @@ void *HELPER(sym_deposit_i64)(uint64_t arg1, void *arg1_expr, _sym_build_integer(ofs, 64))); } -static void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, int32_t comparison_operator, uint64_t is_taken){ +static void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, uint32_t comparison_operator, uint8_t is_taken){ void *(*handler)(void *, void*); switch (comparison_operator) { case TCG_COND_EQ: @@ -673,10 +673,10 @@ void HELPER(free)(void *ptr){ free(ptr); } -static void split_symbol(void* symbol, uint64_t element_count, void* result[]){ +static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_size, void* result[]){ g_assert(_sym_bits_helper(symbol) % element_count == 0); for(uint64_t i = 0; i < element_count; i++){ - result[i] = _sym_extract_helper(symbol, i * 8, (i + 1) * 8 - 1); + result[i] = _sym_extract_helper(symbol, i * element_size, (i + 1) * element_size - 1); } } @@ -715,8 +715,8 @@ static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void uint64_t element_count = vector_size / element_size; void* arg1_elements[element_count]; void* arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, arg1_elements); - split_symbol(arg2_expr, element_count, arg2_elements); + split_symbol(arg1_expr, element_count, element_size, arg1_elements); + split_symbol(arg2_expr, element_count, element_size, arg2_elements); return apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); } @@ -744,7 +744,7 @@ static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint3 uint64_t element_count = vector_size / element_size; void* arg1_elements[element_count]; void* arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, arg1_elements); + split_symbol(arg1_expr, element_count, element_size, arg1_elements); for(uint64_t i = 0; i < element_count; i++){ arg2_elements[i] = arg2_expr; } @@ -814,4 +814,47 @@ void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t ar void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); +} + +void HELPER(sym_cmp_vec)( + CPUArchState *env, + void *arg1, void *arg1_expr, + void *arg2, void *arg2_expr, + uint32_t comparison_operator, void *concrete_result, + uint64_t vector_size, uint64_t vece +) { + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_expr == NULL && arg2_expr == NULL) { + return; + } + + if (arg1_expr == NULL) { + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + } + + if (arg2_expr == NULL) { + arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); + } + + g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); + + uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; + void *arg2_elements[element_count]; + split_symbol(arg1_expr, element_count, element_size, arg1_elements); + split_symbol(arg2_expr, element_count, element_size, arg2_elements); + + for (uint64_t i = 0; i < element_count; i++) { + uint8_t is_taken = * (uint8_t*) (concrete_result + i * element_size / 8); + build_and_push_path_constraint( + env, + arg1_elements[i], + arg2_elements[i], + comparison_operator, + is_taken + ); + } } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index be3d65bf32..c50d79790f 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -143,6 +143,7 @@ DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index fe18da0d8f..ff3302cc20 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -636,6 +636,14 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGType type = rt->base_type; int can; + /* gen_helper_sym_cmp_vec below needs the concrete value of a and b. + * However, if r designates the same TCGTemp as a or b, the execution of the concrete cmp operation + * will overwrite the value of a or b. Therefore, we need to store the values of a and b + * *before* the concrete cmp operation is executed. + */ + TCGv_ptr buffer_address_a = store_vector_in_memory(a); + TCGv_ptr buffer_address_b = store_vector_in_memory(b); + tcg_debug_assert(at->base_type >= type); tcg_debug_assert(bt->base_type >= type); tcg_assert_listed_vecop(INDEX_op_cmp_vec); @@ -648,6 +656,36 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, tcg_expand_vec_op(INDEX_op_cmp_vec, type, vece, ri, ai, bi, cond); tcg_swap_vecop_list(hold_list); } + + TCGv_ptr buffer_address_r = store_vector_in_memory(r); + int size_a = vec_size(a); + int size_b = vec_size(b); + int size_r = vec_size(r); + + g_assert(size_a == size_b && size_b == size_r); + + gen_helper_sym_cmp_vec( + cpu_env, + buffer_address_a, + tcgv_vec_expr(a), + buffer_address_b, + tcgv_vec_expr(b), + tcg_constant_i32(cond), + buffer_address_r, + tcg_constant_i64(size_a), + tcg_constant_i64(vece) + ); + + gen_helper_free(buffer_address_a); + gen_helper_free(buffer_address_b); + gen_helper_free(buffer_address_r); + + tcg_temp_free_ptr(buffer_address_a); + tcg_temp_free_ptr(buffer_address_b); + tcg_temp_free_ptr(buffer_address_r); + + /* Concretize r */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); } static bool do_op3(unsigned vece, TCGv_vec r, TCGv_vec a, From f9cf587d480e32962f38f870519f1cf81091aed5 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 15:16:27 +0000 Subject: [PATCH 35/61] concretize not yet instrumented vec ops results to avoid crash --- tcg/tcg-op-vec.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index ff3302cc20..08a74d2278 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -743,11 +743,15 @@ void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_op3_nofail(vece, r, a, b, INDEX_op_ssadd_vec); } void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); if (!do_op3(vece, r, a, b, INDEX_op_usadd_vec)) { const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); TCGv_vec t = tcg_temp_new_vec_matching(r); @@ -764,11 +768,15 @@ void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_op3_nofail(vece, r, a, b, INDEX_op_sssub_vec); } void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); if (!do_op3(vece, r, a, b, INDEX_op_ussub_vec)) { const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); TCGv_vec t = tcg_temp_new_vec_matching(r); @@ -794,21 +802,29 @@ static void do_minmax(unsigned vece, TCGv_vec r, TCGv_vec a, void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_smin_vec, TCG_COND_LT); } void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_umin_vec, TCG_COND_LTU); } void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_smax_vec, TCG_COND_GT); } void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_umax_vec, TCG_COND_GTU); } @@ -920,6 +936,8 @@ void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a, void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, TCGv_vec c, TCGv_vec d) { + /* TODO instrument */ + tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); TCGTemp *rt = tcgv_vec_temp(r); TCGTemp *at = tcgv_vec_temp(a); TCGTemp *bt = tcgv_vec_temp(b); From eaea5864a3b0531ef18e90690aad8dadcabb0810 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:33:05 +0000 Subject: [PATCH 36/61] fix bux related to expr version of constants and add assert to avoid future regression --- tcg/tcg.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index c3582865be..73ae67d268 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1509,6 +1509,16 @@ void tcg_func_start(TCGContext *s) static TCGTemp *tcg_temp_alloc(TCGContext *s) { + int last_temp_idx = s->nb_temps - 1; + if (last_temp_idx > 0) { + if (last_temp_idx % 2 == 0) { + g_assert(!(s->temps[last_temp_idx].symbolic_expression)); + } else { + g_assert((s->temps[last_temp_idx].symbolic_expression)); + } + } + + int n = s->nb_temps++; if (n >= TCG_MAX_TEMPS) { @@ -1843,14 +1853,15 @@ TCGTemp *tcg_constant_internal(TCGType type, int64_t val) val_ptr = &ts->val; } g_hash_table_insert(h, val_ptr, ts); + + ts_expr = tcg_temp_alloc(s); + ts_expr->base_type = TCG_TYPE_PTR; + ts_expr->type = TCG_TYPE_PTR; + ts_expr->kind = TEMP_CONST; + ts_expr->temp_allocated = 1; + ts_expr->symbolic_expression = 1; + ts_expr->val = 0; } - ts_expr = tcg_temp_alloc(s); - ts_expr->base_type = TCG_TYPE_PTR; - ts_expr->type = TCG_TYPE_PTR; - ts_expr->kind = TEMP_CONST; - ts_expr->temp_allocated = 1; - ts_expr->symbolic_expression = 1; - ts_expr->val = 0; return ts; } From 8aa48d693acb0ecb646bbb7b4d6c159968cf6192 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 17:20:51 +0000 Subject: [PATCH 37/61] fix vector load bug --- tcg/tcg-op-vec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 08a74d2278..1e25e6d952 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -360,7 +360,7 @@ void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) tcgv_vec_expr(r), b, tcg_constant_i64(o), - tcg_constant_i64(vec_size(r)) + tcg_constant_i64(vec_size(r) / 8) ); vec_gen_ldst(INDEX_op_ld_vec, r, b, o); @@ -372,7 +372,7 @@ void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) tcgv_vec_expr(r), b, tcg_constant_i64(o), - tcg_constant_i64(vec_size(r)) + tcg_constant_i64(vec_size(r) / 8) ); vec_gen_ldst(INDEX_op_st_vec, r, b, o); From 49a0157c7f4fc5ee38697a0e83dc767afdaad9d9 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:55:44 +0000 Subject: [PATCH 38/61] fix split_symbol function, add asserts --- accel/tcg/tcg-runtime-sym.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 51371bfe01..7667d28745 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -676,7 +676,7 @@ void HELPER(free)(void *ptr){ static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_size, void* result[]){ g_assert(_sym_bits_helper(symbol) % element_count == 0); for(uint64_t i = 0; i < element_count; i++){ - result[i] = _sym_extract_helper(symbol, i * element_size, (i + 1) * element_size - 1); + result[i] = _sym_build_extract(symbol, i * element_size / 8, element_size / 8, false); } } @@ -694,6 +694,7 @@ static uint64_t vece_element_size(uint64_t vece){ } static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); @@ -718,10 +719,13 @@ static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void split_symbol(arg1_expr, element_count, element_size, arg1_elements); split_symbol(arg2_expr, element_count, element_size, arg2_elements); - return apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); + void* result = apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); + g_assert(_sym_bits_helper(result) == vector_size); + return result; } static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); @@ -749,7 +753,9 @@ static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint3 arg2_elements[i] = arg2_expr; } - return apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); + void* result = apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); + g_assert(_sym_bits_helper(result) == vector_size); + return result; } void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ From 89cc56251eb3b1e5795809ffe13575f61649f24c Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Mon, 4 Dec 2023 18:10:00 +0000 Subject: [PATCH 39/61] fix extract symbol logic --- accel/tcg/tcg-runtime-sym.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 7667d28745..d7212df356 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -676,7 +676,7 @@ void HELPER(free)(void *ptr){ static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_size, void* result[]){ g_assert(_sym_bits_helper(symbol) % element_count == 0); for(uint64_t i = 0; i < element_count; i++){ - result[i] = _sym_build_extract(symbol, i * element_size / 8, element_size / 8, false); + result[i] = _sym_extract_helper(symbol, (i + 1) * element_size - 1, i * element_size); } } From 82a67928b5c803ea65e14f24d6c5d8e810fe9e8d Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:06:26 +0000 Subject: [PATCH 40/61] fix endianess issue in apply_op_and_merge function --- accel/tcg/tcg-runtime-sym.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index d7212df356..db64d4d313 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -683,7 +683,7 @@ static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_ static void *apply_op_and_merge(void* (*op)(void*, void*), void* arg1[], void* arg2[], uint64_t element_count){ void* merged_result = op(arg1[0], arg2[0]); for(uint64_t i = 1; i < element_count; i++){ - merged_result = _sym_concat_helper(merged_result, op(arg1[i], arg2[i])); + merged_result = _sym_concat_helper(op(arg1[i], arg2[i]), merged_result); } return merged_result; } From d3b03860bf995d2785460647af7f0cb33b0065a4 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:32:10 +0000 Subject: [PATCH 41/61] instrumented saturating signed/unsigned sub/add vec instructions --- accel/tcg/tcg-runtime-sym.c | 18 ++++++++++++++++++ accel/tcg/tcg-runtime-sym.h | 4 ++++ tcg/tcg-op-vec.c | 14 ++++++-------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index db64d4d313..e8d935b9b3 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -782,6 +782,22 @@ void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_ex return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); } +void *HELPER(sym_signed_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sadd_sat); +} + +void *HELPER(sym_signed_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_ssub_sat); +} + +void *HELPER(sym_unsigned_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_uadd_sat); +} + +void *HELPER(sym_unsigned_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_usub_sat); +} + void *HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); } @@ -822,6 +838,8 @@ void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t a return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } + + void HELPER(sym_cmp_vec)( CPUArchState *env, void *arg1, void *arg1_expr, diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index c50d79790f..3e12e53b2c 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -133,6 +133,10 @@ DEF_HELPER_FLAGS_6(sym_xor_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i DEF_HELPER_FLAGS_6(sym_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_mul_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_signed_saturating_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_signed_saturating_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_unsigned_saturating_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_unsigned_saturating_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_shift_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 1e25e6d952..7c8ce8b81b 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -743,15 +743,14 @@ void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_signed_saturating_add_vec); do_op3_nofail(vece, r, a, b, INDEX_op_ssadd_vec); } void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_unsigned_saturating_add_vec); + if (!do_op3(vece, r, a, b, INDEX_op_usadd_vec)) { const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); TCGv_vec t = tcg_temp_new_vec_matching(r); @@ -768,15 +767,14 @@ void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_signed_saturating_sub_vec); do_op3_nofail(vece, r, a, b, INDEX_op_sssub_vec); } void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); + vec_vec_op_instrumentation(vece, r, a, b, gen_helper_sym_unsigned_saturating_sub_vec); + if (!do_op3(vece, r, a, b, INDEX_op_ussub_vec)) { const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); TCGv_vec t = tcg_temp_new_vec_matching(r); From ff7406b90d682623dd9c621103e6476aa419e1b4 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:43:27 +0000 Subject: [PATCH 42/61] make sure cmpsel and bitsel instructions are generated using already instrumented instructions --- tcg/tcg-op-vec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 7c8ce8b81b..8f5390d384 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -919,16 +919,16 @@ void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a, tcg_debug_assert(bt->base_type >= type); tcg_debug_assert(ct->base_type >= type); - if (TCG_TARGET_HAS_bitsel_vec) { + /* if (TCG_TARGET_HAS_bitsel_vec) { vec_gen_4(INDEX_op_bitsel_vec, type, MO_8, temp_arg(rt), temp_arg(at), temp_arg(bt), temp_arg(ct)); - } else { + } else { */ TCGv_vec t = tcg_temp_new_vec(type); tcg_gen_and_vec(MO_8, t, a, b); tcg_gen_andc_vec(MO_8, r, c, a); tcg_gen_or_vec(MO_8, r, r, t); tcg_temp_free_vec(t); - } + /* } */ } void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r, @@ -959,16 +959,16 @@ void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r, hold_list = tcg_swap_vecop_list(NULL); can = tcg_can_emit_vec_op(INDEX_op_cmpsel_vec, type, vece); - if (can > 0) { + /* if (can > 0) { vec_gen_6(INDEX_op_cmpsel_vec, type, vece, ri, ai, bi, ci, di, cond); } else if (can < 0) { tcg_expand_vec_op(INDEX_op_cmpsel_vec, type, vece, ri, ai, bi, ci, di, cond); - } else { + } else { */ TCGv_vec t = tcg_temp_new_vec(type); tcg_gen_cmp_vec(cond, vece, t, a, b); tcg_gen_bitsel_vec(vece, r, t, c, d); tcg_temp_free_vec(t); - } + /* } */ tcg_swap_vecop_list(hold_list); } From 065eee4b6b84a36935c85a5256574e9bc64a0de2 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:46:27 +0000 Subject: [PATCH 43/61] remove forgotten concretization --- tcg/tcg-op-vec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 8f5390d384..3269314698 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -934,8 +934,6 @@ void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a, void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, TCGv_vec c, TCGv_vec d) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); TCGTemp *rt = tcgv_vec_temp(r); TCGTemp *at = tcgv_vec_temp(a); TCGTemp *bt = tcgv_vec_temp(b); From f7d04472e43fa19533d05d7f2ddfd4a7dbc2212a Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:08:28 +0000 Subject: [PATCH 44/61] instrumented tcg_gen_dup_i64_vec,tcg_gen_dup_i32_vec functions --- accel/tcg/tcg-runtime-sym.c | 31 +++++++++++++++++++++++++++++++ accel/tcg/tcg-runtime-sym.h | 1 + tcg/tcg-op-vec.c | 4 ++++ 3 files changed, 36 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index e8d935b9b3..faabfbe47e 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -838,6 +838,37 @@ void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t a return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } +void *HELPER(sym_duplicate_value_into_vec)(void *value_expr, uint64_t vector_size, uint64_t vece){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (value_expr == NULL) { + return NULL; + } + + g_assert(_sym_bits_helper(value_expr) == 32 || _sym_bits_helper(value_expr) == 64); + + void *resized_value_expr; + + if (_sym_bits_helper(value_expr) == element_size) { + resized_value_expr = value_expr; + } else if (_sym_bits_helper(value_expr) < element_size) { + resized_value_expr = _sym_build_zext(value_expr, element_size); + } else { + resized_value_expr = _sym_extract_helper(value_expr, element_size - 1, 0); + } + + uint64_t element_count = vector_size / element_size; + void *result_symbol = resized_value_expr; + for(uint64_t i = 1; i < element_count; i++){ + result_symbol = _sym_concat_helper(resized_value_expr, result_symbol); + } + g_assert(_sym_bits_helper(result_symbol) == vector_size); + return result_symbol; +} + void HELPER(sym_cmp_vec)( diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 3e12e53b2c..c74e5c9d9e 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -148,6 +148,7 @@ DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, p DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 3269314698..e88f2e8527 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -305,6 +305,8 @@ void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a) void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a) { + gen_helper_sym_duplicate_value_into_vec(tcgv_vec_expr(r), tcgv_i64_expr(a), tcg_constant_i64(vece), tcg_constant_i64(vec_size(r))); + TCGArg ri = tcgv_vec_arg(r); TCGTemp *rt = arg_temp(ri); TCGType type = rt->base_type; @@ -324,6 +326,8 @@ void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a) void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec r, TCGv_i32 a) { + gen_helper_sym_duplicate_value_into_vec(tcgv_vec_expr(r), tcgv_i32_expr(a), tcg_constant_i64(vece), tcg_constant_i64(vec_size(r))); + TCGArg ri = tcgv_vec_arg(r); TCGArg ai = tcgv_i32_arg(a); TCGTemp *rt = arg_temp(ri); From 6f5b31205d0f3da36c67a2c6bb6420772b781293 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:33:53 +0000 Subject: [PATCH 45/61] instrumented min max functions --- accel/tcg/tcg-runtime-sym.c | 64 +++++++++++++++++++++++++++++++++++-- accel/tcg/tcg-runtime-sym.h | 1 + tcg/tcg-op-vec.c | 51 ++++++++++++++++++++++++----- 3 files changed, 106 insertions(+), 10 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index faabfbe47e..6e748b1055 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -869,7 +869,11 @@ void *HELPER(sym_duplicate_value_into_vec)(void *value_expr, uint64_t vector_siz return result_symbol; } - +static void *element_address(void *concrete_vector, uint64_t element_index, uint64_t element_size, uint64_t vector_size){ + void* result = concrete_vector + element_index * element_size / 8; + g_assert(result + element_size <= concrete_vector + vector_size); + return result; +} void HELPER(sym_cmp_vec)( CPUArchState *env, @@ -903,7 +907,7 @@ void HELPER(sym_cmp_vec)( split_symbol(arg2_expr, element_count, element_size, arg2_elements); for (uint64_t i = 0; i < element_count; i++) { - uint8_t is_taken = * (uint8_t*) (concrete_result + i * element_size / 8); + uint8_t is_taken = * (uint8_t*) element_address(concrete_result, i, element_size, vector_size); build_and_push_path_constraint( env, arg1_elements[i], @@ -912,4 +916,60 @@ void HELPER(sym_cmp_vec)( is_taken ); } +} + +void *HELPER(sym_minmax_vec)( + CPUArchState *env, + void *arg1, void *arg1_expr, + void *arg2, void *arg2_expr, + uint32_t comparison_operator, void *concrete_result, + uint64_t vector_size, uint64_t vece +){ + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_expr == NULL && arg2_expr == NULL) { + return NULL; + } + + if (arg1_expr == NULL) { + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + } + + if (arg2_expr == NULL) { + arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); + } + + g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); + + uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; + void *arg2_elements[element_count]; + int is_taken[element_count]; + split_symbol(arg1_expr, element_count, element_size, arg1_elements); + split_symbol(arg2_expr, element_count, element_size, arg2_elements); + for (int i = 0; i < element_count; i++) { + void *result_element_ptr = element_address(concrete_result, i, element_size, vector_size); + void *arg1_element_ptr = element_address(arg1, i, element_size, vector_size); + is_taken[i] = memcmp(result_element_ptr, arg1_element_ptr, element_size / 8) == 0; + } + + for (int i = 0; i < element_count; i++) { + build_and_push_path_constraint( + env, + arg1_elements[i], + arg2_elements[i], + comparison_operator, + is_taken[i] + ); + } + + void *result_symbol = is_taken[0] ? arg1_elements[0] : arg2_elements[0]; + for (int i = 1; i < element_count; i++) { + result_symbol = _sym_concat_helper(is_taken[i] ? arg1_elements[i] : arg2_elements[i], result_symbol); + } + + g_assert(_sym_bits_helper(result_symbol) == vector_size); + return result_symbol; } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index c74e5c9d9e..a6adc1eda5 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -148,6 +148,7 @@ DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, p DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_9(sym_minmax_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index e88f2e8527..192586befe 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -795,38 +795,73 @@ void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) static void do_minmax(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, TCGOpcode opc, TCGCond cond) { + /* + * gen_helper_sym_minmax_vec below needs the concrete value of a and b. + * However, if r designates the same TCGTemp as a or b, the execution of the concrete min/max operation + * will overwrite the value of a or b. Therefore, we need to store the values of a and b + * *before* the concrete cmp operation is executed. + */ + TCGv_ptr buffer_address_a = store_vector_in_memory(a); + TCGv_ptr buffer_address_b = store_vector_in_memory(b); + + /* Note that, if the if below is entered, an infinite recursion occurs. + * This is due to the fact that tcg_expand_vec_op, which is called by several functions in the present file, + * internally leads to calls to min / max functions. + * For this reason, here we have to provide an explicit instrumentation of the min / max functions instead + * of forcing the instruction to be generated with other instrumented functions, as done in several other cases. + */ if (!do_op3(vece, r, a, b, opc)) { const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL); tcg_gen_cmpsel_vec(cond, vece, r, a, b, a, b); tcg_swap_vecop_list(hold_list); } + + TCGv_ptr buffer_address_r = store_vector_in_memory(r); + int size_a = vec_size(a); + int size_b = vec_size(b); + int size_r = vec_size(r); + + g_assert(size_a == size_b && size_b == size_r); + + gen_helper_sym_minmax_vec( + tcgv_vec_expr(r), + cpu_env, + buffer_address_a, + tcgv_vec_expr(a), + buffer_address_b, + tcgv_vec_expr(b), + tcg_constant_i32(cond), + buffer_address_r, + tcg_constant_i64(size_a), + tcg_constant_i64(vece) + ); + + gen_helper_free(buffer_address_a); + gen_helper_free(buffer_address_b); + gen_helper_free(buffer_address_r); + + tcg_temp_free_ptr(buffer_address_a); + tcg_temp_free_ptr(buffer_address_b); + tcg_temp_free_ptr(buffer_address_r); } void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_smin_vec, TCG_COND_LT); } void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_umin_vec, TCG_COND_LTU); } void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_smax_vec, TCG_COND_GT); } void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { - /* TODO instrument */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); do_minmax(vece, r, a, b, INDEX_op_umax_vec, TCG_COND_GTU); } From c5419d085c1e52ecbb7cf00b986f1f2ae93fdb6a Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:59:39 +0000 Subject: [PATCH 46/61] instrumented tcg_gen_dup_mem_vec --- accel/tcg/tcg-runtime-sym.c | 12 ++++++++++++ accel/tcg/tcg-runtime-sym.h | 1 + tcg/tcg-op-vec.c | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 6e748b1055..0ba1061e65 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -869,6 +869,18 @@ void *HELPER(sym_duplicate_value_into_vec)(void *value_expr, uint64_t vector_siz return result_symbol; } +void *HELPER(sym_load_and_duplicate_into_vec)(void *addr, uint64_t offset, uint64_t vector_size, uint64_t vece){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + void *value_expr = helper_sym_load_host_v(addr, offset, element_size / 8); + g_assert(_sym_bits_helper(value_expr) == element_size); + + return helper_sym_duplicate_value_into_vec(value_expr, vector_size, vece); +} + static void *element_address(void *concrete_vector, uint64_t element_index, uint64_t element_size, uint64_t vector_size){ void* result = concrete_vector + element_index * element_size / 8; g_assert(result + element_size <= concrete_vector + vector_size); diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index a6adc1eda5..0b7d1ea366 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -150,6 +150,7 @@ DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_9(sym_minmax_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_4(sym_load_and_duplicate_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64, i64) /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 192586befe..548e9bc958 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -339,6 +339,14 @@ void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec r, TCGv_i32 a) void tcg_gen_dup_mem_vec(unsigned vece, TCGv_vec r, TCGv_ptr b, tcg_target_long ofs) { + gen_helper_sym_load_and_duplicate_into_vec( + tcgv_vec_expr(r), + b, + tcg_constant_i64(ofs), + tcg_constant_i64(vec_size(r)), + tcg_constant_i64(vece) + ); + TCGArg ri = tcgv_vec_arg(r); TCGArg bi = tcgv_ptr_arg(b); TCGTemp *rt = arg_temp(ri); From 01b0b10fcc34f5ee079e908cdfc33fb4d4cc429c Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:27:42 +0000 Subject: [PATCH 47/61] fix wront assert in sym_load_and_duplicate_into_vec --- accel/tcg/tcg-runtime-sym.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 0ba1061e65..7880f27424 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -876,7 +876,7 @@ void *HELPER(sym_load_and_duplicate_into_vec)(void *addr, uint64_t offset, uint6 g_assert(vector_size % element_size == 0); void *value_expr = helper_sym_load_host_v(addr, offset, element_size / 8); - g_assert(_sym_bits_helper(value_expr) == element_size); + g_assert(value_expr == NULL || _sym_bits_helper(value_expr) == element_size); return helper_sym_duplicate_value_into_vec(value_expr, vector_size, vece); } From 37491b2543ba4d4d45ae81d4103634bc3cecefab Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sat, 16 Dec 2023 16:46:51 +0000 Subject: [PATCH 48/61] refactor : put vec helpers in separate file --- accel/tcg/meson.build | 2 + accel/tcg/tcg-runtime-sym-common.c | 68 ++++++ accel/tcg/tcg-runtime-sym-common.h | 2 + accel/tcg/tcg-runtime-sym-vec.c | 352 +++++++++++++++++++++++++++ accel/tcg/tcg-runtime-sym-vec.h | 27 +++ accel/tcg/tcg-runtime-sym.c | 377 +---------------------------- accel/tcg/tcg-runtime-sym.h | 28 --- include/exec/helper-gen-common.h | 4 + include/exec/helper-proto-common.h | 4 + 9 files changed, 461 insertions(+), 403 deletions(-) create mode 100644 accel/tcg/tcg-runtime-sym-common.c create mode 100644 accel/tcg/tcg-runtime-sym-common.h create mode 100644 accel/tcg/tcg-runtime-sym-vec.c create mode 100644 accel/tcg/tcg-runtime-sym-vec.h diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index 00aeac9e53..782ae0a7a1 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -7,6 +7,8 @@ tcg_ss.add(files( 'tcg-runtime-gvec.c', 'tcg-runtime.c', 'tcg-runtime-sym.c', + 'tcg-runtime-sym-vec.c', + 'tcg-runtime-sym-common.c', 'translate-all.c', 'translator.c', )) diff --git a/accel/tcg/tcg-runtime-sym-common.c b/accel/tcg/tcg-runtime-sym-common.c new file mode 100644 index 0000000000..6c3aeba9f6 --- /dev/null +++ b/accel/tcg/tcg-runtime-sym-common.c @@ -0,0 +1,68 @@ +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/cpu_ldst.h" +#include "qemu/qemu-print.h" +#include "tcg/tcg.h" +#include "exec/translation-block.h" + +#include "accel/tcg/tcg-runtime-sym-common.h" + +/* Include the symbolic backend, using void* as expression type. */ + +#define SymExpr void* +#include "RuntimeCommon.h" + +void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, uint32_t comparison_operator, uint8_t is_taken){ + void *(*handler)(void *, void*); + switch (comparison_operator) { + case TCG_COND_EQ: + handler = _sym_build_equal; + break; + case TCG_COND_NE: + handler = _sym_build_not_equal; + break; + case TCG_COND_LT: + handler = _sym_build_signed_less_than; + break; + case TCG_COND_GE: + handler = _sym_build_signed_greater_equal; + break; + case TCG_COND_LE: + handler = _sym_build_signed_less_equal; + break; + case TCG_COND_GT: + handler = _sym_build_signed_greater_than; + break; + case TCG_COND_LTU: + handler = _sym_build_unsigned_less_than; + break; + case TCG_COND_GEU: + handler = _sym_build_unsigned_greater_equal; + break; + case TCG_COND_LEU: + handler = _sym_build_unsigned_less_equal; + break; + case TCG_COND_GTU: + handler = _sym_build_unsigned_greater_than; + break; + default: + g_assert_not_reached(); + } + + void *condition_symbol = handler(arg1_expr, arg2_expr); + _sym_push_path_constraint(condition_symbol, is_taken, get_pc(env)); + + return condition_symbol; +} + +/* Architecture-independent way to get the program counter */ +target_ulong get_pc(CPUArchState *env) +{ + target_ulong pc, cs_base; + uint32_t flags; + + cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); + + return pc; +} \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym-common.h b/accel/tcg/tcg-runtime-sym-common.h new file mode 100644 index 0000000000..9e090b01ee --- /dev/null +++ b/accel/tcg/tcg-runtime-sym-common.h @@ -0,0 +1,2 @@ +void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, uint32_t comparison_operator, uint8_t is_taken); +target_ulong get_pc(CPUArchState *env); \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c new file mode 100644 index 0000000000..2b7d8eaeff --- /dev/null +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -0,0 +1,352 @@ +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/translation-block.h" +#include "accel/tcg/tcg-runtime-sym-common.h" + +#define HELPER_H "accel/tcg/tcg-runtime-sym-vec.h" +#include "exec/helper-info.c.inc" +#undef HELPER_H + +/* Include the symbolic backend, using void* as expression type. */ + +#define SymExpr void* +#include "RuntimeCommon.h" + +void *HELPER(malloc)(uint64_t size){ + return malloc(size); +} + +void HELPER(free)(void *ptr){ + free(ptr); +} + +static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_size, void* result[]){ + g_assert(_sym_bits_helper(symbol) % element_count == 0); + for(uint64_t i = 0; i < element_count; i++){ + result[i] = _sym_extract_helper(symbol, (i + 1) * element_size - 1, i * element_size); + } +} + +static void *apply_op_and_merge(void* (*op)(void*, void*), void* arg1[], void* arg2[], uint64_t element_count){ + void* merged_result = op(arg1[0], arg2[0]); + for(uint64_t i = 1; i < element_count; i++){ + merged_result = _sym_concat_helper(op(arg1[i], arg2[i]), merged_result); + } + return merged_result; +} + +static uint64_t vece_element_size(uint64_t vece){ + /* see definition of vece here https://www.qemu.org/docs/master/devel/tcg-ops.html#host-vector-operations */ + return 8 << vece; +} + +/* + * Builds a symbolic expression for an SIMD operation on two vector operands. + * Args + * arg1_concrete, arg2_concrete : concrete values of the input vector operands + * arg1_symbolic, arg2_symbolic : symbolic expressions of the input vector operands + * vector_size : size of the vectors in bits + * vece : element size in bits = 8 * 2^vece + * symbolic_operation : function for the symbolic operation applied on each element of the vectors + * Returns + * A symbol that represents the output of the SIMD operation + */ +static void *build_symbol_for_vector_vector_op( + void *arg1_concrete, void *arg1_symbolic, + void *arg2_concrete, void *arg2_symbolic, + uint64_t vector_size, uint64_t vece, + void *(*symbolic_operation)(void *, void *) +) { + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_symbolic == NULL && arg2_symbolic == NULL) { + return NULL; + } + + if (arg1_symbolic == NULL) { + arg1_symbolic = _sym_build_integer_from_buffer(arg1_concrete, vector_size); + } + + if (arg2_symbolic == NULL) { + arg2_symbolic = _sym_build_integer_from_buffer(arg2_concrete, vector_size); + } + + g_assert(_sym_bits_helper(arg1_symbolic) == _sym_bits_helper(arg2_symbolic) && + _sym_bits_helper(arg1_symbolic) == vector_size); + + uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; + void *arg2_elements[element_count]; + split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); + split_symbol(arg2_symbolic, element_count, element_size, arg2_elements); + + void *result = apply_op_and_merge(symbolic_operation, arg1_elements, arg2_elements, element_count); + g_assert(_sym_bits_helper(result) == vector_size); + return result; +} + +static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_expr == NULL && arg2_expr == NULL) { + return NULL; + } + + if (arg1_expr == NULL) { + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + } + + if (arg2_expr == NULL) { + arg2_expr = _sym_build_integer(arg2, 32); + } + + g_assert(_sym_bits_helper(arg1_expr) == vector_size); + g_assert(_sym_bits_helper(arg2_expr) == 32); + + uint64_t element_count = vector_size / element_size; + void* arg1_elements[element_count]; + void* arg2_elements[element_count]; + split_symbol(arg1_expr, element_count, element_size, arg1_elements); + for(uint64_t i = 0; i < element_count; i++){ + arg2_elements[i] = arg2_expr; + } + + void* result = apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); + g_assert(_sym_bits_helper(result) == vector_size); + return result; +} + +void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); +} + +void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); +} + +void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); +} + +void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); +} + +void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); +} + +void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); +} + +void *HELPER(sym_signed_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sadd_sat); +} + +void *HELPER(sym_signed_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_ssub_sat); +} + +void *HELPER(sym_unsigned_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_uadd_sat); +} + +void *HELPER(sym_unsigned_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_usub_sat); +} + +void *HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); +} + +void *HELPER(sym_logical_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); +} + +void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); +} + +void *HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); +} + +void *HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); +} + +void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); +} + +void *HELPER(sym_logical_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); +} + +void *HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); +} + +void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); +} + +void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); +} + +void *HELPER(sym_duplicate_value_into_vec)(void *value_expr, uint64_t vector_size, uint64_t vece){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (value_expr == NULL) { + return NULL; + } + + g_assert(_sym_bits_helper(value_expr) == 32 || _sym_bits_helper(value_expr) == 64); + + void *resized_value_expr; + + if (_sym_bits_helper(value_expr) == element_size) { + resized_value_expr = value_expr; + } else if (_sym_bits_helper(value_expr) < element_size) { + resized_value_expr = _sym_build_zext(value_expr, element_size); + } else { + resized_value_expr = _sym_extract_helper(value_expr, element_size - 1, 0); + } + + uint64_t element_count = vector_size / element_size; + void *result_symbol = resized_value_expr; + for(uint64_t i = 1; i < element_count; i++){ + result_symbol = _sym_concat_helper(resized_value_expr, result_symbol); + } + g_assert(_sym_bits_helper(result_symbol) == vector_size); + return result_symbol; +} + +void *HELPER(sym_load_and_duplicate_into_vec)(void *addr, uint64_t offset, uint64_t vector_size, uint64_t vece){ + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + void *value_expr = helper_sym_load_host_v(addr, offset, element_size / 8); + g_assert(value_expr == NULL || _sym_bits_helper(value_expr) == element_size); + + return helper_sym_duplicate_value_into_vec(value_expr, vector_size, vece); +} + +static void *element_address(void *concrete_vector, uint64_t element_index, uint64_t element_size, uint64_t vector_size){ + void* result = concrete_vector + element_index * element_size / 8; + g_assert(result + element_size <= concrete_vector + vector_size); + return result; +} + +void HELPER(sym_cmp_vec)( + CPUArchState *env, + void *arg1, void *arg1_expr, + void *arg2, void *arg2_expr, + uint32_t comparison_operator, void *concrete_result, + uint64_t vector_size, uint64_t vece +) { + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_expr == NULL && arg2_expr == NULL) { + return; + } + + if (arg1_expr == NULL) { + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + } + + if (arg2_expr == NULL) { + arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); + } + + g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); + + uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; + void *arg2_elements[element_count]; + split_symbol(arg1_expr, element_count, element_size, arg1_elements); + split_symbol(arg2_expr, element_count, element_size, arg2_elements); + + for (uint64_t i = 0; i < element_count; i++) { + uint8_t is_taken = * (uint8_t*) element_address(concrete_result, i, element_size, vector_size); + build_and_push_path_constraint( + env, + arg1_elements[i], + arg2_elements[i], + comparison_operator, + is_taken + ); + } +} + +void *HELPER(sym_minmax_vec)( + CPUArchState *env, + void *arg1, void *arg1_expr, + void *arg2, void *arg2_expr, + uint32_t comparison_operator, void *concrete_result, + uint64_t vector_size, uint64_t vece +){ + uint64_t element_size = vece_element_size(vece); + g_assert(element_size <= vector_size); + g_assert(vector_size % element_size == 0); + + if (arg1_expr == NULL && arg2_expr == NULL) { + return NULL; + } + + if (arg1_expr == NULL) { + arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + } + + if (arg2_expr == NULL) { + arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); + } + + g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); + + uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; + void *arg2_elements[element_count]; + int is_taken[element_count]; + split_symbol(arg1_expr, element_count, element_size, arg1_elements); + split_symbol(arg2_expr, element_count, element_size, arg2_elements); + for (int i = 0; i < element_count; i++) { + void *result_element_ptr = element_address(concrete_result, i, element_size, vector_size); + void *arg1_element_ptr = element_address(arg1, i, element_size, vector_size); + is_taken[i] = memcmp(result_element_ptr, arg1_element_ptr, element_size / 8) == 0; + } + + for (int i = 0; i < element_count; i++) { + build_and_push_path_constraint( + env, + arg1_elements[i], + arg2_elements[i], + comparison_operator, + is_taken[i] + ); + } + + void *result_symbol = is_taken[0] ? arg1_elements[0] : arg2_elements[0]; + for (int i = 1; i < element_count; i++) { + result_symbol = _sym_concat_helper(is_taken[i] ? arg1_elements[i] : arg2_elements[i], result_symbol); + } + + g_assert(_sym_bits_helper(result_symbol) == vector_size); + return result_symbol; +} \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym-vec.h b/accel/tcg/tcg-runtime-sym-vec.h new file mode 100644 index 0000000000..0b8be48b30 --- /dev/null +++ b/accel/tcg/tcg-runtime-sym-vec.h @@ -0,0 +1,27 @@ +DEF_HELPER_FLAGS_1(malloc, TCG_CALL_NO_RWG, ptr, i64) +DEF_HELPER_FLAGS_1(free, TCG_CALL_NO_RWG, void, ptr) + +DEF_HELPER_FLAGS_6(sym_and_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_or_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_xor_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_mul_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_signed_saturating_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_signed_saturating_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_unsigned_saturating_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_unsigned_saturating_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_shift_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_shift_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_9(sym_minmax_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_4(sym_load_and_duplicate_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64, i64) \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index 7880f27424..cbdc8a7e94 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -20,6 +20,8 @@ #include "exec/cpu_ldst.h" #include "qemu/qemu-print.h" #include "tcg/tcg.h" +#include "exec/translation-block.h" +#include "accel/tcg/tcg-runtime-sym-common.h" #define HELPER_H "accel/tcg/tcg-runtime-sym.h" #include "exec/helper-info.c.inc" @@ -92,18 +94,6 @@ } -/* Architecture-independent way to get the program counter */ -static target_ulong get_pc(CPUArchState *env) -{ - target_ulong pc, cs_base; - uint32_t flags; - - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); - - return pc; -} - - /* The binary helpers */ DEF_HELPER_BINARY(add, add) @@ -569,49 +559,6 @@ void *HELPER(sym_deposit_i64)(uint64_t arg1, void *arg1_expr, _sym_build_integer(ofs, 64))); } -static void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, uint32_t comparison_operator, uint8_t is_taken){ - void *(*handler)(void *, void*); - switch (comparison_operator) { - case TCG_COND_EQ: - handler = _sym_build_equal; - break; - case TCG_COND_NE: - handler = _sym_build_not_equal; - break; - case TCG_COND_LT: - handler = _sym_build_signed_less_than; - break; - case TCG_COND_GE: - handler = _sym_build_signed_greater_equal; - break; - case TCG_COND_LE: - handler = _sym_build_signed_less_equal; - break; - case TCG_COND_GT: - handler = _sym_build_signed_greater_than; - break; - case TCG_COND_LTU: - handler = _sym_build_unsigned_less_than; - break; - case TCG_COND_GEU: - handler = _sym_build_unsigned_greater_equal; - break; - case TCG_COND_LEU: - handler = _sym_build_unsigned_less_equal; - break; - case TCG_COND_GTU: - handler = _sym_build_unsigned_greater_than; - break; - default: - g_assert_not_reached(); - } - - void *condition_symbol = handler(arg1_expr, arg2_expr); - _sym_push_path_constraint(condition_symbol, is_taken, get_pc(env)); - - return condition_symbol; -} - static void *sym_setcond_internal(CPUArchState *env, uint64_t arg1, void *arg1_expr, uint64_t arg2, void *arg2_expr, @@ -665,323 +612,3 @@ void HELPER(sym_collect_garbage)(void) _sym_collect_garbage(); } -void *HELPER(malloc)(uint64_t size){ - return malloc(size); -} - -void HELPER(free)(void *ptr){ - free(ptr); -} - -static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_size, void* result[]){ - g_assert(_sym_bits_helper(symbol) % element_count == 0); - for(uint64_t i = 0; i < element_count; i++){ - result[i] = _sym_extract_helper(symbol, (i + 1) * element_size - 1, i * element_size); - } -} - -static void *apply_op_and_merge(void* (*op)(void*, void*), void* arg1[], void* arg2[], uint64_t element_count){ - void* merged_result = op(arg1[0], arg2[0]); - for(uint64_t i = 1; i < element_count; i++){ - merged_result = _sym_concat_helper(op(arg1[i], arg2[i]), merged_result); - } - return merged_result; -} - -static uint64_t vece_element_size(uint64_t vece){ - /* see definition of vece here https://www.qemu.org/docs/master/devel/tcg-ops.html#host-vector-operations */ - return 8 << vece; -} - -static void* build_symbol_for_vector_vector_op(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ - g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); - uint64_t element_size = vece_element_size(vece); - g_assert(element_size <= vector_size); - g_assert(vector_size % element_size == 0); - - if (arg1_expr == NULL && arg2_expr == NULL) { - return NULL; - } - - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); - } - - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); - } - - g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); - - uint64_t element_count = vector_size / element_size; - void* arg1_elements[element_count]; - void* arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - split_symbol(arg2_expr, element_count, element_size, arg2_elements); - - void* result = apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); - g_assert(_sym_bits_helper(result) == vector_size); - return result; -} - -static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ - g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); - uint64_t element_size = vece_element_size(vece); - g_assert(element_size <= vector_size); - g_assert(vector_size % element_size == 0); - - if (arg1_expr == NULL && arg2_expr == NULL) { - return NULL; - } - - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); - } - - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer(arg2, 32); - } - - g_assert(_sym_bits_helper(arg1_expr) == vector_size); - g_assert(_sym_bits_helper(arg2_expr) == 32); - - uint64_t element_count = vector_size / element_size; - void* arg1_elements[element_count]; - void* arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - for(uint64_t i = 0; i < element_count; i++){ - arg2_elements[i] = arg2_expr; - } - - void* result = apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); - g_assert(_sym_bits_helper(result) == vector_size); - return result; -} - -void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); -} - -void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); -} - -void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); -} - -void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); -} - -void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); -} - -void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); -} - -void *HELPER(sym_signed_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sadd_sat); -} - -void *HELPER(sym_signed_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_ssub_sat); -} - -void *HELPER(sym_unsigned_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_uadd_sat); -} - -void *HELPER(sym_unsigned_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_usub_sat); -} - -void *HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); -} - -void *HELPER(sym_logical_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); -} - -void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); -} - -void *HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); -} - -void *HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); -} - -void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); -} - -void *HELPER(sym_logical_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); -} - -void *HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); -} - -void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); -} - -void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); -} - -void *HELPER(sym_duplicate_value_into_vec)(void *value_expr, uint64_t vector_size, uint64_t vece){ - g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); - uint64_t element_size = vece_element_size(vece); - g_assert(element_size <= vector_size); - g_assert(vector_size % element_size == 0); - - if (value_expr == NULL) { - return NULL; - } - - g_assert(_sym_bits_helper(value_expr) == 32 || _sym_bits_helper(value_expr) == 64); - - void *resized_value_expr; - - if (_sym_bits_helper(value_expr) == element_size) { - resized_value_expr = value_expr; - } else if (_sym_bits_helper(value_expr) < element_size) { - resized_value_expr = _sym_build_zext(value_expr, element_size); - } else { - resized_value_expr = _sym_extract_helper(value_expr, element_size - 1, 0); - } - - uint64_t element_count = vector_size / element_size; - void *result_symbol = resized_value_expr; - for(uint64_t i = 1; i < element_count; i++){ - result_symbol = _sym_concat_helper(resized_value_expr, result_symbol); - } - g_assert(_sym_bits_helper(result_symbol) == vector_size); - return result_symbol; -} - -void *HELPER(sym_load_and_duplicate_into_vec)(void *addr, uint64_t offset, uint64_t vector_size, uint64_t vece){ - g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); - uint64_t element_size = vece_element_size(vece); - g_assert(element_size <= vector_size); - g_assert(vector_size % element_size == 0); - - void *value_expr = helper_sym_load_host_v(addr, offset, element_size / 8); - g_assert(value_expr == NULL || _sym_bits_helper(value_expr) == element_size); - - return helper_sym_duplicate_value_into_vec(value_expr, vector_size, vece); -} - -static void *element_address(void *concrete_vector, uint64_t element_index, uint64_t element_size, uint64_t vector_size){ - void* result = concrete_vector + element_index * element_size / 8; - g_assert(result + element_size <= concrete_vector + vector_size); - return result; -} - -void HELPER(sym_cmp_vec)( - CPUArchState *env, - void *arg1, void *arg1_expr, - void *arg2, void *arg2_expr, - uint32_t comparison_operator, void *concrete_result, - uint64_t vector_size, uint64_t vece -) { - uint64_t element_size = vece_element_size(vece); - g_assert(element_size <= vector_size); - g_assert(vector_size % element_size == 0); - - if (arg1_expr == NULL && arg2_expr == NULL) { - return; - } - - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); - } - - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); - } - - g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); - - uint64_t element_count = vector_size / element_size; - void *arg1_elements[element_count]; - void *arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - split_symbol(arg2_expr, element_count, element_size, arg2_elements); - - for (uint64_t i = 0; i < element_count; i++) { - uint8_t is_taken = * (uint8_t*) element_address(concrete_result, i, element_size, vector_size); - build_and_push_path_constraint( - env, - arg1_elements[i], - arg2_elements[i], - comparison_operator, - is_taken - ); - } -} - -void *HELPER(sym_minmax_vec)( - CPUArchState *env, - void *arg1, void *arg1_expr, - void *arg2, void *arg2_expr, - uint32_t comparison_operator, void *concrete_result, - uint64_t vector_size, uint64_t vece -){ - uint64_t element_size = vece_element_size(vece); - g_assert(element_size <= vector_size); - g_assert(vector_size % element_size == 0); - - if (arg1_expr == NULL && arg2_expr == NULL) { - return NULL; - } - - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); - } - - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); - } - - g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); - - uint64_t element_count = vector_size / element_size; - void *arg1_elements[element_count]; - void *arg2_elements[element_count]; - int is_taken[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - split_symbol(arg2_expr, element_count, element_size, arg2_elements); - for (int i = 0; i < element_count; i++) { - void *result_element_ptr = element_address(concrete_result, i, element_size, vector_size); - void *arg1_element_ptr = element_address(arg1, i, element_size, vector_size); - is_taken[i] = memcmp(result_element_ptr, arg1_element_ptr, element_size / 8) == 0; - } - - for (int i = 0; i < element_count; i++) { - build_and_push_path_constraint( - env, - arg1_elements[i], - arg2_elements[i], - comparison_operator, - is_taken[i] - ); - } - - void *result_symbol = is_taken[0] ? arg1_elements[0] : arg2_elements[0]; - for (int i = 1; i < element_count; i++) { - result_symbol = _sym_concat_helper(is_taken[i] ? arg1_elements[i] : arg2_elements[i], result_symbol); - } - - g_assert(_sym_bits_helper(result_symbol) == vector_size); - return result_symbol; -} \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 0b7d1ea366..692c10d3c9 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -124,34 +124,6 @@ DEF_HELPER_FLAGS_1(sym_notify_block, TCG_CALL_NO_RWG, void, i64) DEF_HELPER_FLAGS_0(sym_collect_garbage, TCG_CALL_NO_RWG, void) -DEF_HELPER_FLAGS_1(malloc, TCG_CALL_NO_RWG, ptr, i64) -DEF_HELPER_FLAGS_1(free, TCG_CALL_NO_RWG, void, ptr) - -DEF_HELPER_FLAGS_6(sym_and_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_or_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_xor_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_mul_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_signed_saturating_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_signed_saturating_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_unsigned_saturating_add_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_unsigned_saturating_sub_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_shift_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_rotate_left_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_rotate_right_vec, TCG_CALL_NO_RWG, ptr, ptr, ptr, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_shift_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_9(sym_minmax_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_4(sym_load_and_duplicate_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64, i64) - /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ /* The extrl and extrh instructions aren't emitted on 64-bit hosts. If we ever diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h index 927044e3ab..3cff276c8a 100644 --- a/include/exec/helper-gen-common.h +++ b/include/exec/helper-gen-common.h @@ -15,6 +15,10 @@ #include "exec/helper-gen.h.inc" #undef HELPER_H +#define HELPER_H "accel/tcg/tcg-runtime-sym-vec.h" +#include "exec/helper-gen.h.inc" +#undef HELPER_H + #define HELPER_H "accel/tcg/plugin-helpers.h" #include "exec/helper-gen.h.inc" #undef HELPER_H diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h index 108bdf1853..893f4026d3 100644 --- a/include/exec/helper-proto-common.h +++ b/include/exec/helper-proto-common.h @@ -17,6 +17,10 @@ #include "exec/helper-proto.h.inc" #undef HELPER_H +#define HELPER_H "accel/tcg/tcg-runtime-sym-vec.h" +#include "exec/helper-proto.h.inc" +#undef HELPER_H + #define HELPER_H "accel/tcg/plugin-helpers.h" #include "exec/helper-proto.h.inc" #undef HELPER_H From 877692f1da41f2dc3c4745571e5a88af99216136 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 17 Dec 2023 22:00:24 +0000 Subject: [PATCH 49/61] documentation and refactoring --- accel/tcg/tcg-runtime-sym-vec.c | 323 ++++++++++++++++++++++---------- accel/tcg/tcg-runtime-sym-vec.h | 4 +- accel/tcg/tcg-runtime-sym.c | 2 +- accel/tcg/tcg-runtime-sym.h | 2 +- tcg/tcg-op-vec.c | 62 +++--- 5 files changed, 274 insertions(+), 119 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c index 2b7d8eaeff..8429ccaea5 100644 --- a/accel/tcg/tcg-runtime-sym-vec.c +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -5,38 +5,71 @@ #include "accel/tcg/tcg-runtime-sym-common.h" #define HELPER_H "accel/tcg/tcg-runtime-sym-vec.h" + #include "exec/helper-info.c.inc" + #undef HELPER_H /* Include the symbolic backend, using void* as expression type. */ #define SymExpr void* + #include "RuntimeCommon.h" -void *HELPER(malloc)(uint64_t size){ +void *HELPER(malloc)(uint64_t size) { return malloc(size); } -void HELPER(free)(void *ptr){ +void HELPER(free)(void *ptr) { free(ptr); } -static void split_symbol(void* symbol, uint64_t element_count, uint64_t element_size, void* result[]){ +/* + * Splits a symbol into multiple symbols of equal size. + * + * The symbols are stored in little endian order : result[0] is the least significant element of the original symbol, + * result[element_count - 1] is the most significant element. + * + * Args + * symbol : the symbol to split + * element_count : number of symbols to split into + * element_size : size of each result symbol in bits + * result : array of size element_count to store the result + */ +static void split_symbol(void *symbol, uint64_t element_count, uint64_t element_size, void *result[]) { g_assert(_sym_bits_helper(symbol) % element_count == 0); - for(uint64_t i = 0; i < element_count; i++){ + for (uint64_t i = 0; i < element_count; i++) { result[i] = _sym_extract_helper(symbol, (i + 1) * element_size - 1, i * element_size); } } -static void *apply_op_and_merge(void* (*op)(void*, void*), void* arg1[], void* arg2[], uint64_t element_count){ - void* merged_result = op(arg1[0], arg2[0]); - for(uint64_t i = 1; i < element_count; i++){ - merged_result = _sym_concat_helper(op(arg1[i], arg2[i]), merged_result); +/* Pairwise applies a binary operation on two arrays of symbols and concatenates the result into a single symbol. + * + * The concatenation is done in little endian order : symbolic_operation(args1[0], args2[0]) is the least significant + * element of the result, symbolic_operation(args1[element_count - 1], args2[element_count - 1]) is the most significant. + * + * Args + * symbolic_operation : function for the symbolic operation applied on each pair of elements + * args1 : first array of symbols + * args2 : second array of symbols + * element_count : number of elements in each array + * Returns + * A symbol that represents the concatenated results + */ +static void *apply_op_and_merge( + void *(*symbolic_operation)(void *, void *), + void *args1[], void *args2[], + uint64_t element_count +) { + void *merged_result = symbolic_operation(args1[0], args2[0]); + for (uint64_t i = 1; i < element_count; i++) { + g_assert(_sym_bits_helper(args1[0]) == _sym_bits_helper(args1[i])); + merged_result = _sym_concat_helper(symbolic_operation(args1[i], args2[i]), merged_result); } return merged_result; } -static uint64_t vece_element_size(uint64_t vece){ +static uint64_t vece_element_size(uint64_t vece) { /* see definition of vece here https://www.qemu.org/docs/master/devel/tcg-ops.html#host-vector-operations */ return 8 << vece; } @@ -44,7 +77,7 @@ static uint64_t vece_element_size(uint64_t vece){ /* * Builds a symbolic expression for an SIMD operation on two vector operands. * Args - * arg1_concrete, arg2_concrete : concrete values of the input vector operands + * arg1_concrete, arg2_concrete : pointers to buffers that store the concrete values of the input vector operands * arg1_symbolic, arg2_symbolic : symbolic expressions of the input vector operands * vector_size : size of the vectors in bits * vece : element size in bits = 8 * 2^vece @@ -89,202 +122,271 @@ static void *build_symbol_for_vector_vector_op( return result; } -static void* build_symbol_for_vector_int32_op(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t vector_size, uint64_t vece, void* (*op)(void*, void*)){ +/* + * Builds a symbolic expression for an SIMD operation on a vector operand and an integer operand. + * + * The operation is performed like if arg2 was duplicated into a vector of the same size as arg1. + * + * Args + * arg1_concrete : pointer to a buffer that stores the concrete value of the input vector operand + * arg1_symbolic : symbolic expression of the input vector operand + * arg2_concrete: concrete value of the input integer operand + * arg2_symbolic : symbolic expression of the input integer operand + * vector_size : size of the vector in bits + * vece: element size in bits = 8 * 2^vece + * symbolic_operation : function for the symbolic operation applied on each element of the vector + */ +static void * +build_symbol_for_vector_int32_op( + void *arg1_concrete, void *arg1_symbolic, + uint32_t arg2_concrete, void *arg2_symbolic, + uint64_t vector_size, uint64_t vece, + void *(*symbolic_operation)(void *, void *) +) { g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); - if (arg1_expr == NULL && arg2_expr == NULL) { + if (arg1_symbolic == NULL && arg2_symbolic == NULL) { return NULL; } - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + if (arg1_symbolic == NULL) { + arg1_symbolic = _sym_build_integer_from_buffer(arg1_concrete, vector_size); } - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer(arg2, 32); + if (arg2_symbolic == NULL) { + arg2_symbolic = _sym_build_integer(arg2_concrete, 32); } - g_assert(_sym_bits_helper(arg1_expr) == vector_size); - g_assert(_sym_bits_helper(arg2_expr) == 32); + g_assert(_sym_bits_helper(arg1_symbolic) == vector_size); + g_assert(_sym_bits_helper(arg2_symbolic) == 32); + + if (element_size != 32) { + arg2_symbolic = _sym_build_zext(arg2_symbolic, element_size - 32); + } uint64_t element_count = vector_size / element_size; - void* arg1_elements[element_count]; - void* arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - for(uint64_t i = 0; i < element_count; i++){ - arg2_elements[i] = arg2_expr; + void *arg1_elements[element_count]; + void *arg2_elements[element_count]; + split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); + for (uint64_t i = 0; i < element_count; i++) { + arg2_elements[i] = arg2_symbolic; } - void* result = apply_op_and_merge(op, arg1_elements, arg2_elements, element_count); + void *result = apply_op_and_merge(symbolic_operation, arg1_elements, arg2_elements, element_count); g_assert(_sym_bits_helper(result) == vector_size); return result; } -void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); } -void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); } -void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); } -void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); } -void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); } -void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); } -void *HELPER(sym_signed_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_signed_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sadd_sat); } -void *HELPER(sym_signed_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_signed_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_ssub_sat); } -void *HELPER(sym_unsigned_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_unsigned_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_uadd_sat); } -void *HELPER(sym_unsigned_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_unsigned_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_usub_sat); } -void *HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ +void * +HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); } -void *HELPER(sym_logical_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); +void *HELPER(sym_logical_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_logical_shift_right); } -void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece){ - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); +void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { + return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_arithmetic_shift_right); } -void *HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void * +HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); } -void *HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void * +HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } -void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); } -void *HELPER(sym_logical_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_logical_shift_right); +void * +HELPER(sym_logical_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_logical_shift_right); } -void *HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_arithmetic_shift_right); +void * +HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { + return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_arithmetic_shift_right); } -void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); } -void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { +void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, + uint64_t vece) { return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } -void *HELPER(sym_duplicate_value_into_vec)(void *value_expr, uint64_t vector_size, uint64_t vece){ +/* + * Symbolic equivalent of creating a vector by duplicating a value. + * + * value_symbol is resized to match vece before being duplicated. + */ +void *HELPER(sym_duplicate_value_into_vec)(void *value_symbol, uint64_t vector_size, uint64_t vece) { g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); - if (value_expr == NULL) { + if (value_symbol == NULL) { return NULL; } - g_assert(_sym_bits_helper(value_expr) == 32 || _sym_bits_helper(value_expr) == 64); + g_assert(_sym_bits_helper(value_symbol) == 32 || _sym_bits_helper(value_symbol) == 64); void *resized_value_expr; - if (_sym_bits_helper(value_expr) == element_size) { - resized_value_expr = value_expr; - } else if (_sym_bits_helper(value_expr) < element_size) { - resized_value_expr = _sym_build_zext(value_expr, element_size); + if (_sym_bits_helper(value_symbol) == element_size) { + resized_value_expr = value_symbol; + } else if (_sym_bits_helper(value_symbol) < element_size) { + resized_value_expr = _sym_build_zext(value_symbol, element_size); } else { - resized_value_expr = _sym_extract_helper(value_expr, element_size - 1, 0); + resized_value_expr = _sym_extract_helper(value_symbol, element_size - 1, 0); } uint64_t element_count = vector_size / element_size; void *result_symbol = resized_value_expr; - for(uint64_t i = 1; i < element_count; i++){ + for (uint64_t i = 1; i < element_count; i++) { result_symbol = _sym_concat_helper(resized_value_expr, result_symbol); } + g_assert(_sym_bits_helper(result_symbol) == vector_size); return result_symbol; } -void *HELPER(sym_load_and_duplicate_into_vec)(void *addr, uint64_t offset, uint64_t vector_size, uint64_t vece){ +/* + * Symbolic equivalent of a loading a value from memory and duplicating it into a vector. + */ +void *HELPER(sym_load_and_duplicate_into_vec)( + void *load_address, + uint64_t address_offset, + uint64_t vector_size, uint64_t vece +) { g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); - void *value_expr = helper_sym_load_host_v(addr, offset, element_size / 8); + void *value_expr = helper_sym_load_host_vec(load_address, address_offset, element_size / 8); g_assert(value_expr == NULL || _sym_bits_helper(value_expr) == element_size); return helper_sym_duplicate_value_into_vec(value_expr, vector_size, vece); } -static void *element_address(void *concrete_vector, uint64_t element_index, uint64_t element_size, uint64_t vector_size){ - void* result = concrete_vector + element_index * element_size / 8; +/* + * Computes the address of an element in a vector. + */ +static void *element_address( + void *concrete_vector, + uint64_t element_index, + uint64_t element_size, + uint64_t vector_size +) { + void *result = concrete_vector + element_index * element_size / 8; g_assert(result + element_size <= concrete_vector + vector_size); return result; } -void HELPER(sym_cmp_vec)( +void *HELPER(sym_cmp_vec)( CPUArchState *env, - void *arg1, void *arg1_expr, - void *arg2, void *arg2_expr, - uint32_t comparison_operator, void *concrete_result, + void *arg1_concrete, void *arg1_symbolic, + void *arg2_concrete, void *arg2_symbolic, + TCGCond comparison_operator, void *result_concrete, uint64_t vector_size, uint64_t vece ) { + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); - if (arg1_expr == NULL && arg2_expr == NULL) { - return; + if (arg1_symbolic == NULL && arg2_symbolic == NULL) { + return NULL; } - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + if (arg1_symbolic == NULL) { + arg1_symbolic = _sym_build_integer_from_buffer(arg1_concrete, vector_size); } - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); + if (arg2_symbolic == NULL) { + arg2_symbolic = _sym_build_integer_from_buffer(arg2_concrete, vector_size); } - g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); + g_assert(_sym_bits_helper(arg1_symbolic) == _sym_bits_helper(arg2_symbolic) && + _sym_bits_helper(arg1_symbolic) == vector_size); uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; void *arg2_elements[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - split_symbol(arg2_expr, element_count, element_size, arg2_elements); + + split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); + split_symbol(arg2_symbolic, element_count, element_size, arg2_elements); for (uint64_t i = 0; i < element_count; i++) { - uint8_t is_taken = * (uint8_t*) element_address(concrete_result, i, element_size, vector_size); + uint8_t is_taken = *(uint8_t *) element_address(result_concrete, i, element_size, vector_size); build_and_push_path_constraint( env, arg1_elements[i], @@ -292,44 +394,76 @@ void HELPER(sym_cmp_vec)( comparison_operator, is_taken ); + } + + return NULL; } -void *HELPER(sym_minmax_vec)( +/* + * Symbolic equivalent of an SIMD ternary operation. + * + * This function performs the symbolic equivalent of computing an output vector of the form : + * result[i] = arg1[i] arg2[i] ? arg1[i] : arg2[i] + * where [i] denotes the ith element of the vector . + * + * For each element, the concrete result is used to determine if the ternary condition was true or false, + * and path constraints are pushed accordingly. + * + * Args + * arg1_concrete, arg2_concrete : pointers to buffers that store the concrete values of the input vector operands + * arg1_symbolic, arg2_symbolic : symbolic expressions of the input vector operands + * comparison_operator : enum value that represents a comparison operator like <, >, ==, etc. + * concrete_result : pointer to a buffer that stores the concrete value of the result vector, as computed by the + * concrete execution of the SIMD operation + * vector_size : size of the vectors in bits + * vece : element size in bits = 8 * 2^vece + * Returns + * A symbol that corresponds to the symbolic result of the SIMD operation + */ +void *HELPER(sym_ternary_vec)( CPUArchState *env, - void *arg1, void *arg1_expr, - void *arg2, void *arg2_expr, - uint32_t comparison_operator, void *concrete_result, + void *arg1_concrete, void *arg1_symbolic, + void *arg2_concrete, void *arg2_symbolic, + TCGCond comparison_operator, void *concrete_result, uint64_t vector_size, uint64_t vece -){ +) { + g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); - if (arg1_expr == NULL && arg2_expr == NULL) { + if (arg1_symbolic == NULL && arg2_symbolic == NULL) { return NULL; } - if (arg1_expr == NULL) { - arg1_expr = _sym_build_integer_from_buffer(arg1, vector_size); + if (arg1_symbolic == NULL) { + arg1_symbolic = _sym_build_integer_from_buffer(arg1_concrete, vector_size); } - if (arg2_expr == NULL) { - arg2_expr = _sym_build_integer_from_buffer(arg2, vector_size); + if (arg2_symbolic == NULL) { + arg2_symbolic = _sym_build_integer_from_buffer(arg2_concrete, vector_size); } - g_assert(_sym_bits_helper(arg1_expr) == _sym_bits_helper(arg2_expr) && _sym_bits_helper(arg1_expr) == vector_size); + g_assert(_sym_bits_helper(arg1_symbolic) == _sym_bits_helper(arg2_symbolic) && + _sym_bits_helper(arg1_symbolic) == vector_size); uint64_t element_count = vector_size / element_size; + void *arg1_elements[element_count]; void *arg2_elements[element_count]; - int is_taken[element_count]; - split_symbol(arg1_expr, element_count, element_size, arg1_elements); - split_symbol(arg2_expr, element_count, element_size, arg2_elements); + + split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); + split_symbol(arg2_symbolic, element_count, element_size, arg2_elements); + + /* For each element, the condition of the ternary was true iff the element of the result is equal to the element + * of arg1. */ + int concrete_condition_was_true[element_count]; + for (int i = 0; i < element_count; i++) { void *result_element_ptr = element_address(concrete_result, i, element_size, vector_size); - void *arg1_element_ptr = element_address(arg1, i, element_size, vector_size); - is_taken[i] = memcmp(result_element_ptr, arg1_element_ptr, element_size / 8) == 0; + void *arg1_element_ptr = element_address(arg1_concrete, i, element_size, vector_size); + concrete_condition_was_true[i] = memcmp(result_element_ptr, arg1_element_ptr, element_size / 8) == 0; } for (int i = 0; i < element_count; i++) { @@ -338,13 +472,14 @@ void *HELPER(sym_minmax_vec)( arg1_elements[i], arg2_elements[i], comparison_operator, - is_taken[i] + concrete_condition_was_true[i] ); } - void *result_symbol = is_taken[0] ? arg1_elements[0] : arg2_elements[0]; + void *result_symbol = concrete_condition_was_true[0] ? arg1_elements[0] : arg2_elements[0]; for (int i = 1; i < element_count; i++) { - result_symbol = _sym_concat_helper(is_taken[i] ? arg1_elements[i] : arg2_elements[i], result_symbol); + result_symbol = _sym_concat_helper(concrete_condition_was_true[i] ? arg1_elements[i] : arg2_elements[i], + result_symbol); } g_assert(_sym_bits_helper(result_symbol) == vector_size); diff --git a/accel/tcg/tcg-runtime-sym-vec.h b/accel/tcg/tcg-runtime-sym-vec.h index 0b8be48b30..f159e7afa7 100644 --- a/accel/tcg/tcg-runtime-sym-vec.h +++ b/accel/tcg/tcg-runtime-sym-vec.h @@ -21,7 +21,7 @@ DEF_HELPER_FLAGS_6(sym_logical_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, DEF_HELPER_FLAGS_6(sym_arithmetic_shift_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_left_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, void, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) -DEF_HELPER_FLAGS_9(sym_minmax_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) +DEF_HELPER_FLAGS_9(sym_ternary_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_4(sym_load_and_duplicate_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64, i64) \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym.c b/accel/tcg/tcg-runtime-sym.c index cbdc8a7e94..288d673fd4 100644 --- a/accel/tcg/tcg-runtime-sym.c +++ b/accel/tcg/tcg-runtime-sym.c @@ -382,7 +382,7 @@ void *HELPER(sym_load_host_i64)(void *addr, uint64_t offset, uint64_t length) return sym_load_host_internal(addr, offset, length, 8); } -void *HELPER(sym_load_host_v)(void *addr, uint64_t offset, uint64_t length) +void *HELPER(sym_load_host_vec)(void *addr, uint64_t offset, uint64_t length) { return sym_load_host_internal(addr, offset, length, length); } diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 692c10d3c9..4092daf1c4 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -97,7 +97,7 @@ DEF_HELPER_FLAGS_7(sym_store_guest_i64, TCG_CALL_NO_RWG, void, env, i64, ptr, /* Host memory */ DEF_HELPER_FLAGS_3(sym_load_host_i32, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_load_host_i64, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_3(sym_load_host_v, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) +DEF_HELPER_FLAGS_3(sym_load_host_vec, TCG_CALL_NO_RWG_SE, ptr, ptr, i64, i64) DEF_HELPER_FLAGS_4(sym_store_host, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i64) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 548e9bc958..3f13a3aba3 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -37,11 +37,18 @@ static int vec_size(TCGv_vec vector){ } } +/* Adds TCG ops for storing a vector TCG variable in a heap buffer. + * + * The caller must add TCG ops for freeing the buffer. + * + * Returns + * A TCG variable that will contain the buffer address at run time. + */ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ TCGv_ptr buffer_address = tcg_temp_new_ptr(); gen_helper_malloc(buffer_address, tcg_constant_i64(vec_size(vector) / 8)); - /* store vec at buffer_address */ + /* store vector at buffer_address */ vec_gen_3( INDEX_op_st_vec, tcgv_vec_temp(vector)->base_type, @@ -54,7 +61,20 @@ static TCGv_ptr store_vector_in_memory(TCGv_vec vector){ return buffer_address; } -static void vec_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i64)){ +/* Adds instrumentation TCG ops for an instruction of the form vec = vec vec. + * + * Args + * vece: element size in bits = 8 * 2^vece + * r: output operand + * a: first input operand + * b: second input operand + * sym_helper: function for calling the symbolic helper + */ +static void vec_vec_op_instrumentation( + unsigned vece, + TCGv_vec r, TCGv_vec a, TCGv_vec b, + void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i64) +) { TCGv_ptr buffer_address_a = store_vector_in_memory(a); TCGv_ptr buffer_address_b = store_vector_in_memory(b); int size_a = vec_size(a); @@ -75,12 +95,23 @@ static void vec_vec_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TC gen_helper_free(buffer_address_a); gen_helper_free(buffer_address_b); - - tcg_temp_free_ptr(buffer_address_a); - tcg_temp_free_ptr(buffer_address_b); } -static void vec_int32_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 b, void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32, TCGv_ptr, TCGv_i64, TCGv_i64)){ +/* + * Adds instrumentation TCG ops for an instruction of the form vec = vec i32. + * + * Args + * vece: element size in bits = 8 * 2^vece + * r: output operand + * a: first input operand + * b: second input operand + * sym_helper: function for calling the symbolic helper + */ +static void vec_int32_op_instrumentation( + unsigned vece, + TCGv_vec r, TCGv_vec a, TCGv_i32 b, + void (*sym_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32, TCGv_ptr, TCGv_i64, TCGv_i64) +) { TCGv_ptr buffer_address_a = store_vector_in_memory(a); int size_a = vec_size(a); int size_r = vec_size(r); @@ -98,8 +129,6 @@ static void vec_int32_op_instrumentation(unsigned vece, TCGv_vec r, TCGv_vec a, ); gen_helper_free(buffer_address_a); - - tcg_temp_free_ptr(buffer_address_a); } /* @@ -368,7 +397,7 @@ static void vec_gen_ldst(TCGOpcode opc, TCGv_vec r, TCGv_ptr b, TCGArg o) void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) { - gen_helper_sym_load_host_v( + gen_helper_sym_load_host_vec( tcgv_vec_expr(r), b, tcg_constant_i64(o), @@ -677,6 +706,7 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, g_assert(size_a == size_b && size_b == size_r); gen_helper_sym_cmp_vec( + tcgv_vec_expr(r), cpu_env, buffer_address_a, tcgv_vec_expr(a), @@ -692,12 +722,6 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, gen_helper_free(buffer_address_b); gen_helper_free(buffer_address_r); - tcg_temp_free_ptr(buffer_address_a); - tcg_temp_free_ptr(buffer_address_b); - tcg_temp_free_ptr(buffer_address_r); - - /* Concretize r */ - tcg_gen_op2_i64(INDEX_op_mov_i64, tcgv_vec_expr_num(r), tcg_constant_i64(0)); } static bool do_op3(unsigned vece, TCGv_vec r, TCGv_vec a, @@ -804,7 +828,7 @@ static void do_minmax(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b, TCGOpcode opc, TCGCond cond) { /* - * gen_helper_sym_minmax_vec below needs the concrete value of a and b. + * gen_helper_sym_ternary_vec below needs the concrete values of a and b. * However, if r designates the same TCGTemp as a or b, the execution of the concrete min/max operation * will overwrite the value of a or b. Therefore, we need to store the values of a and b * *before* the concrete cmp operation is executed. @@ -831,7 +855,7 @@ static void do_minmax(unsigned vece, TCGv_vec r, TCGv_vec a, g_assert(size_a == size_b && size_b == size_r); - gen_helper_sym_minmax_vec( + gen_helper_sym_ternary_vec( tcgv_vec_expr(r), cpu_env, buffer_address_a, @@ -847,10 +871,6 @@ static void do_minmax(unsigned vece, TCGv_vec r, TCGv_vec a, gen_helper_free(buffer_address_a); gen_helper_free(buffer_address_b); gen_helper_free(buffer_address_r); - - tcg_temp_free_ptr(buffer_address_a); - tcg_temp_free_ptr(buffer_address_b); - tcg_temp_free_ptr(buffer_address_r); } void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) From d9796f9704416af8227e4540f6a86ca3eaf013b0 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:29:15 +0000 Subject: [PATCH 50/61] refactor --- accel/tcg/tcg-runtime-sym-vec.c | 155 +++++++++++++++++++------------- 1 file changed, 92 insertions(+), 63 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c index 8429ccaea5..1e2b62f6b7 100644 --- a/accel/tcg/tcg-runtime-sym-vec.c +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -1,3 +1,8 @@ +/* + * This file is part of SymQEMU. + * It contains symbolic helper functions for vector operations. + */ + #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" @@ -25,25 +30,25 @@ void HELPER(free)(void *ptr) { } /* - * Splits a symbol into multiple symbols of equal size. + * Splits an expression into multiple expressions of equal size. * - * The symbols are stored in little endian order : result[0] is the least significant element of the original symbol, + * The expressions are stored in little endian order : result[0] is the least significant element of the original expression, * result[element_count - 1] is the most significant element. * * Args - * symbol : the symbol to split - * element_count : number of symbols to split into - * element_size : size of each result symbol in bits + * expression : the expression to split + * element_count : number of expressions to split into + * element_size : size of each result expression in bits * result : array of size element_count to store the result */ -static void split_symbol(void *symbol, uint64_t element_count, uint64_t element_size, void *result[]) { - g_assert(_sym_bits_helper(symbol) % element_count == 0); +static void split_expression(void *expression, uint64_t element_count, uint64_t element_size, void *result[]) { + g_assert(_sym_bits_helper(expression) % element_count == 0); for (uint64_t i = 0; i < element_count; i++) { - result[i] = _sym_extract_helper(symbol, (i + 1) * element_size - 1, i * element_size); + result[i] = _sym_extract_helper(expression, (i + 1) * element_size - 1, i * element_size); } } -/* Pairwise applies a binary operation on two arrays of symbols and concatenates the result into a single symbol. +/* Pairwise applies a binary operation on two arrays of expressions and concatenates the result into a single expression. * * The concatenation is done in little endian order : symbolic_operation(args1[0], args2[0]) is the least significant * element of the result, symbolic_operation(args1[element_count - 1], args2[element_count - 1]) is the most significant. @@ -54,7 +59,7 @@ static void split_symbol(void *symbol, uint64_t element_count, uint64_t element_ * args2 : second array of symbols * element_count : number of elements in each array * Returns - * A symbol that represents the concatenated results + * An expression that represents the concatenated results */ static void *apply_op_and_merge( void *(*symbolic_operation)(void *, void *), @@ -83,9 +88,9 @@ static uint64_t vece_element_size(uint64_t vece) { * vece : element size in bits = 8 * 2^vece * symbolic_operation : function for the symbolic operation applied on each element of the vectors * Returns - * A symbol that represents the output of the SIMD operation + * A symbol expression that represents the output of the SIMD operation */ -static void *build_symbol_for_vector_vector_op( +static void *build_expression_for_vector_vector_op( void *arg1_concrete, void *arg1_symbolic, void *arg2_concrete, void *arg2_symbolic, uint64_t vector_size, uint64_t vece, @@ -114,8 +119,8 @@ static void *build_symbol_for_vector_vector_op( uint64_t element_count = vector_size / element_size; void *arg1_elements[element_count]; void *arg2_elements[element_count]; - split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); - split_symbol(arg2_symbolic, element_count, element_size, arg2_elements); + split_expression(arg1_symbolic, element_count, element_size, arg1_elements); + split_expression(arg2_symbolic, element_count, element_size, arg2_elements); void *result = apply_op_and_merge(symbolic_operation, arg1_elements, arg2_elements, element_count); g_assert(_sym_bits_helper(result) == vector_size); @@ -135,9 +140,11 @@ static void *build_symbol_for_vector_vector_op( * vector_size : size of the vector in bits * vece: element size in bits = 8 * 2^vece * symbolic_operation : function for the symbolic operation applied on each element of the vector + * Returns + * A symbol expression that represents the output of the SIMD operation */ static void * -build_symbol_for_vector_int32_op( +build_expression_for_vector_int32_op( void *arg1_concrete, void *arg1_symbolic, uint32_t arg2_concrete, void *arg2_symbolic, uint64_t vector_size, uint64_t vece, @@ -170,7 +177,7 @@ build_symbol_for_vector_int32_op( uint64_t element_count = vector_size / element_size; void *arg1_elements[element_count]; void *arg2_elements[element_count]; - split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); + split_expression(arg1_symbolic, element_count, element_size, arg1_elements); for (uint64_t i = 0; i < element_count; i++) { arg2_elements[i] = arg2_symbolic; } @@ -181,140 +188,140 @@ build_symbol_for_vector_int32_op( } void *HELPER(sym_and_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_and); } void *HELPER(sym_or_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_or); } void *HELPER(sym_xor_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_xor); } void *HELPER(sym_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_add); } void *HELPER(sym_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sub); } void *HELPER(sym_mul_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_mul); } void *HELPER(sym_signed_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sadd_sat); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_sadd_sat); } void *HELPER(sym_signed_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_ssub_sat); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_ssub_sat); } void *HELPER(sym_unsigned_saturating_add_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_uadd_sat); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_uadd_sat); } void *HELPER(sym_unsigned_saturating_sub_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_usub_sat); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_usub_sat); } void * HELPER(sym_shift_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); } void *HELPER(sym_logical_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, - _sym_build_logical_shift_right); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_logical_shift_right); } void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, - _sym_build_arithmetic_shift_right); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_arithmetic_shift_right); } void * HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); } void * HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_shift_left); } void * HELPER(sym_logical_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, - _sym_build_logical_shift_right); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_logical_shift_right); } void * HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, - _sym_build_arithmetic_shift_right); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, + _sym_build_arithmetic_shift_right); } void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); } void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_symbol_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); } /* * Symbolic equivalent of creating a vector by duplicating a value. * - * value_symbol is resized to match vece before being duplicated. + * value_expression is resized to match vece before being duplicated. */ -void *HELPER(sym_duplicate_value_into_vec)(void *value_symbol, uint64_t vector_size, uint64_t vece) { +void *HELPER(sym_duplicate_value_into_vec)(void *value_expression, uint64_t vector_size, uint64_t vece) { g_assert(vector_size == 64 || vector_size == 128 || vector_size == 256); uint64_t element_size = vece_element_size(vece); g_assert(element_size <= vector_size); g_assert(vector_size % element_size == 0); - if (value_symbol == NULL) { + if (value_expression == NULL) { return NULL; } - g_assert(_sym_bits_helper(value_symbol) == 32 || _sym_bits_helper(value_symbol) == 64); + g_assert(_sym_bits_helper(value_expression) == 32 || _sym_bits_helper(value_expression) == 64); void *resized_value_expr; - if (_sym_bits_helper(value_symbol) == element_size) { - resized_value_expr = value_symbol; - } else if (_sym_bits_helper(value_symbol) < element_size) { - resized_value_expr = _sym_build_zext(value_symbol, element_size); + if (_sym_bits_helper(value_expression) == element_size) { + resized_value_expr = value_expression; + } else if (_sym_bits_helper(value_expression) < element_size) { + resized_value_expr = _sym_build_zext(value_expression, element_size); } else { - resized_value_expr = _sym_extract_helper(value_symbol, element_size - 1, 0); + resized_value_expr = _sym_extract_helper(value_expression, element_size - 1, 0); } uint64_t element_count = vector_size / element_size; - void *result_symbol = resized_value_expr; + void *result_expression = resized_value_expr; for (uint64_t i = 1; i < element_count; i++) { - result_symbol = _sym_concat_helper(resized_value_expr, result_symbol); + result_expression = _sym_concat_helper(resized_value_expr, result_expression); } - g_assert(_sym_bits_helper(result_symbol) == vector_size); - return result_symbol; + g_assert(_sym_bits_helper(result_expression) == vector_size); + return result_expression; } /* @@ -350,6 +357,25 @@ static void *element_address( return result; } +/* + * Symbolic equivalent of an SIMD comparison operation, where true is represented by -1 and false by 0. + * + * This function performs the symbolic equivalent of computing an output vector of the form : + * result[i] = arg1[i] arg2[i] ? -1 : 0 + * + * For each element, the concrete result is used to determine if the comparison was true or false, + * and path constraints are pushed accordingly. + * + * Args + * arg1_concrete, arg2_concrete : pointers to buffers that store the concrete values of the input vector operands + * arg1_symbolic, arg2_symbolic : symbolic expressions of the input vector operands + * comparison_operator : enum value that represents a comparison operator like <, >, ==, etc. + * result_concrete : pointer to a buffer that stores the concrete value of the result vector, as computed by the + * concrete execution of the SIMD operation + * vector_size : size of the vectors in bits + * vece : element size in bits = 8 * 2^vece + * + */ void *HELPER(sym_cmp_vec)( CPUArchState *env, void *arg1_concrete, void *arg1_symbolic, @@ -382,10 +408,12 @@ void *HELPER(sym_cmp_vec)( void *arg1_elements[element_count]; void *arg2_elements[element_count]; - split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); - split_symbol(arg2_symbolic, element_count, element_size, arg2_elements); + split_expression(arg1_symbolic, element_count, element_size, arg1_elements); + split_expression(arg2_symbolic, element_count, element_size, arg2_elements); for (uint64_t i = 0; i < element_count; i++) { + /* For each element, the comparison was true iff the element of the result is equal to -1. + * Here it is ok to take the first byte of the element, because the result is either -1 or 0. */ uint8_t is_taken = *(uint8_t *) element_address(result_concrete, i, element_size, vector_size); build_and_push_path_constraint( env, @@ -397,6 +425,7 @@ void *HELPER(sym_cmp_vec)( } + /* Concretize the result, as path constraints for its value have been pushed. */ return NULL; } @@ -419,7 +448,7 @@ void *HELPER(sym_cmp_vec)( * vector_size : size of the vectors in bits * vece : element size in bits = 8 * 2^vece * Returns - * A symbol that corresponds to the symbolic result of the SIMD operation + * An expression that corresponds to the symbolic result of the SIMD operation */ void *HELPER(sym_ternary_vec)( CPUArchState *env, @@ -453,8 +482,8 @@ void *HELPER(sym_ternary_vec)( void *arg1_elements[element_count]; void *arg2_elements[element_count]; - split_symbol(arg1_symbolic, element_count, element_size, arg1_elements); - split_symbol(arg2_symbolic, element_count, element_size, arg2_elements); + split_expression(arg1_symbolic, element_count, element_size, arg1_elements); + split_expression(arg2_symbolic, element_count, element_size, arg2_elements); /* For each element, the condition of the ternary was true iff the element of the result is equal to the element * of arg1. */ @@ -476,12 +505,12 @@ void *HELPER(sym_ternary_vec)( ); } - void *result_symbol = concrete_condition_was_true[0] ? arg1_elements[0] : arg2_elements[0]; + void *result_expression = concrete_condition_was_true[0] ? arg1_elements[0] : arg2_elements[0]; for (int i = 1; i < element_count; i++) { - result_symbol = _sym_concat_helper(concrete_condition_was_true[i] ? arg1_elements[i] : arg2_elements[i], - result_symbol); + result_expression = _sym_concat_helper(concrete_condition_was_true[i] ? arg1_elements[i] : arg2_elements[i], + result_expression); } - g_assert(_sym_bits_helper(result_symbol) == vector_size); - return result_symbol; + g_assert(_sym_bits_helper(result_expression) == vector_size); + return result_expression; } \ No newline at end of file From b29f504a62f30c730b01c1acc26ab174a3426b7b Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 4 Feb 2024 21:38:55 +0000 Subject: [PATCH 51/61] fix rotate functions for PR --- accel/tcg/tcg-runtime-sym-common.c | 27 +++++++++++++++++++++++++++ accel/tcg/tcg-runtime-sym-common.h | 4 +++- accel/tcg/tcg-runtime-sym-vec.c | 8 ++++---- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym-common.c b/accel/tcg/tcg-runtime-sym-common.c index 6c3aeba9f6..06c98aea27 100644 --- a/accel/tcg/tcg-runtime-sym-common.c +++ b/accel/tcg/tcg-runtime-sym-common.c @@ -65,4 +65,31 @@ target_ulong get_pc(CPUArchState *env) cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); return pc; +} + +void *sym_rotate_left(void *arg1_expr, void *arg2_expr) { + /* The implementation follows the alternative implementation of + * tcg_gen_rotl_i64 in tcg-op.c (which handles architectures that don't + * support rotl directly). */ + + uint8_t bits = _sym_bits_helper(arg1_expr); + return _sym_build_or( + _sym_build_shift_left(arg1_expr, arg2_expr), + _sym_build_logical_shift_right( + arg1_expr, + _sym_build_sub(_sym_build_integer(bits, bits), arg2_expr))); +} + +void *sym_rotate_right(void *arg1_expr, void *arg2_expr) { + + /* The implementation follows the alternative implementation of + * tcg_gen_rotr_i64 in tcg-op.c (which handles architectures that don't + * support rotr directly). */ + + uint8_t bits = _sym_bits_helper(arg1_expr); + return _sym_build_or( + _sym_build_logical_shift_right(arg1_expr, arg2_expr), + _sym_build_shift_left( + arg1_expr, + _sym_build_sub(_sym_build_integer(bits, bits), arg2_expr))); } \ No newline at end of file diff --git a/accel/tcg/tcg-runtime-sym-common.h b/accel/tcg/tcg-runtime-sym-common.h index 9e090b01ee..dfe998d8c5 100644 --- a/accel/tcg/tcg-runtime-sym-common.h +++ b/accel/tcg/tcg-runtime-sym-common.h @@ -1,2 +1,4 @@ void *build_and_push_path_constraint(CPUArchState *env, void *arg1_expr, void *arg2_expr, uint32_t comparison_operator, uint8_t is_taken); -target_ulong get_pc(CPUArchState *env); \ No newline at end of file +target_ulong get_pc(CPUArchState *env); +void *sym_rotate_left(void *arg1_expr, void *arg2_expr); +void *sym_rotate_right(void *arg1_expr, void *arg2_expr); diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c index 1e2b62f6b7..c86db98cbf 100644 --- a/accel/tcg/tcg-runtime-sym-vec.c +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -250,12 +250,12 @@ void *HELPER(sym_arithmetic_shift_right_vec)(void *arg1, void *arg1_expr, void * void * HELPER(sym_rotate_left_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, sym_rotate_left); } void * HELPER(sym_rotate_right_vec)(void *arg1, void *arg1_expr, void *arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); + return build_expression_for_vector_vector_op(arg1, arg1_expr, arg2, arg2_expr, size, vece,sym_rotate_right); } void *HELPER(sym_shift_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, @@ -279,12 +279,12 @@ HELPER(sym_arithmetic_shift_right_vec_int32)(void *arg1, void *arg1_expr, uint32 void *HELPER(sym_rotate_left_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_left); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece,sym_rotate_left); } void *HELPER(sym_rotate_right_vec_int32)(void *arg1, void *arg1_expr, uint32_t arg2, void *arg2_expr, uint64_t size, uint64_t vece) { - return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, _sym_build_rotate_right); + return build_expression_for_vector_int32_op(arg1, arg1_expr, arg2, arg2_expr, size, vece, sym_rotate_right); } /* From 0529b3b13a097b7c0eee754a685ebd1d2dfa681c Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 11 Feb 2024 11:06:33 +0000 Subject: [PATCH 52/61] added todo comments to clarify situation for indirectly instrumented instructions --- tcg/tcg-op-vec.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 3f13a3aba3..57911ee57d 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -470,6 +470,14 @@ void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (TCG_TARGET_HAS_andc_vec) { vec_gen_op3(INDEX_op_andc_vec, 0, r, a, b); } else { */ @@ -482,6 +490,14 @@ void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (TCG_TARGET_HAS_orc_vec) { vec_gen_op3(INDEX_op_orc_vec, 0, r, a, b); } else { */ @@ -494,6 +510,14 @@ void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (TCG_TARGET_HAS_nand_vec) { vec_gen_op3(INDEX_op_nand_vec, 0, r, a, b); } else { */ @@ -504,6 +528,14 @@ void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (TCG_TARGET_HAS_nor_vec) { vec_gen_op3(INDEX_op_nor_vec, 0, r, a, b); } else { */ @@ -514,6 +546,14 @@ void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) { + + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (TCG_TARGET_HAS_eqv_vec) { vec_gen_op3(INDEX_op_eqv_vec, 0, r, a, b); } else { */ @@ -563,6 +603,13 @@ void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a) tcg_assert_listed_vecop(INDEX_op_neg_vec); hold_list = tcg_swap_vecop_list(NULL); + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /*if (!TCG_TARGET_HAS_neg_vec || !do_op2(vece, r, a, INDEX_op_neg_vec)) {*/ tcg_gen_sub_vec(vece, r, tcg_constant_vec_matching(r, vece, 0), a); /*}*/ @@ -576,6 +623,13 @@ void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a) tcg_assert_listed_vecop(INDEX_op_abs_vec); hold_list = tcg_swap_vecop_list(NULL); + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /*if (!do_op2(vece, r, a, INDEX_op_abs_vec)) {*/ TCGType type = tcgv_vec_temp(r)->base_type; TCGv_vec t = tcg_temp_new_vec(type); @@ -986,6 +1040,13 @@ void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a, tcg_debug_assert(bt->base_type >= type); tcg_debug_assert(ct->base_type >= type); + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (TCG_TARGET_HAS_bitsel_vec) { vec_gen_4(INDEX_op_bitsel_vec, type, MO_8, temp_arg(rt), temp_arg(at), temp_arg(bt), temp_arg(ct)); @@ -1024,6 +1085,13 @@ void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r, hold_list = tcg_swap_vecop_list(NULL); can = tcg_can_emit_vec_op(INDEX_op_cmpsel_vec, type, vece); + /* + TODO (SymQEMU): + This instruction is not instrumented yet. + For now, we make sure that alternative instructions below, which are instrumented, are always used. + Directly instrumenting this instruction would improve performance of SymQEMU. + */ + /* if (can > 0) { vec_gen_6(INDEX_op_cmpsel_vec, type, vece, ri, ai, bi, ci, di, cond); } else if (can < 0) { From 1ea43b512824106f61a706c729e32cd79aae76ca Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 11 Feb 2024 11:34:23 +0000 Subject: [PATCH 53/61] add todo for returning expressions instad of pushing path constraints --- accel/tcg/tcg-runtime-sym-vec.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c index c86db98cbf..59dbc41299 100644 --- a/accel/tcg/tcg-runtime-sym-vec.c +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -357,6 +357,13 @@ static void *element_address( return result; } +/* +TODO: + Currently, `helper_sym_cmp_vec` pushes path constraints and concretizes its result. + Returning an expression that represents the result of the comparison, instead of pushing path constraints, + may give better results. +/* + /* * Symbolic equivalent of an SIMD comparison operation, where true is represented by -1 and false by 0. * @@ -429,6 +436,13 @@ void *HELPER(sym_cmp_vec)( return NULL; } +/* +TODO: + Currently, `helper_sym_ternary_vec` pushes path constraints and concretizes its result. + Returning an expression that represents the result of the comparison, instead of pushing path constraints, + may give better results. +/* + /* * Symbolic equivalent of an SIMD ternary operation. * From 569f996129fb7f66e67f9c8924c497fe9b42f88b Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:49:02 +0000 Subject: [PATCH 54/61] mention files related to vec instructions in README --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f071816eaa..11b61b34ab 100644 --- a/README.md +++ b/README.md @@ -112,13 +112,15 @@ docker run -it --rm symqemu ## Documentation -The [paper](http://www.s3.eurecom.fr/tools/symbolic_execution/symqemu.html) -contains details on how SymQEMU works. A large part of the implementation is the -run-time support in `accel/tcg/tcg-runtime-sym.{c,h}` (which delegates any -actual symbolic computation to SymCC's symbolic backend), and we have modified -most code-generating functions in `tcg/tcg-op.c` to emit calls to the runtime. -For development, configure with `--enable-debug` for run-time assertions; there -are tests for the symbolic run-time support in `tests/check-sym-runtime.c`. +The [paper](http://www.s3.eurecom.fr/tools/symbolic_execution/symqemu.html) contains +details on how SymQEMU works. A large part of the implementation is the run-time support +in `accel/tcg/tcg-runtime-sym.{c,h}` and `accel/tcg/tcg-runtime-sym-vec.{c,h}` (which +delegates any actual symbolic computation to SymCC's symbolic backend), and we have +modified most code-generating functions in `tcg/tcg-op.c`, `tcg/tcg-op-vec.c` and +`include/tcg/tcg-op-common.h` to emit calls to the runtime. + +For development, configure with `--enable-debug` for run-time assertions; there are tests +for the symbolic run-time support in `tests/check-sym-runtime.c`. More information about the port to QEMU 8 and internals of (Sym)QEMU can be found in the QEMU 8 merge commit message From 3c35a2ebd57fb67f2e413ada5a6268181e781cf4 Mon Sep 17 00:00:00 2001 From: Damien Maier <91182145+damienmaier@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:04:50 +0000 Subject: [PATCH 55/61] Add asprintf test program This target program resulted on incorrect results before vector instructions were instrumented --- tests/symqemu/binaries/printf/Makefile | 6 +++++ tests/symqemu/binaries/printf/args | 1 + tests/symqemu/binaries/printf/binary | Bin 0 -> 900480 bytes tests/symqemu/binaries/printf/binary.c | 24 ++++++++++++++++++ .../binaries/printf/expected_outputs/000000 | 2 ++ .../binaries/printf/expected_outputs/000001 | 2 ++ .../binaries/printf/expected_outputs/000002 | 2 ++ .../binaries/printf/expected_outputs/000003 | 2 ++ .../binaries/printf/expected_outputs/000004 | 2 ++ .../binaries/printf/expected_outputs/000005 | 2 ++ .../binaries/printf/expected_outputs/000006 | 2 ++ .../binaries/printf/expected_outputs/000007 | 1 + .../binaries/printf/expected_outputs/000008 | 1 + .../binaries/printf/expected_outputs/000009 | 1 + .../binaries/printf/expected_outputs/000010 | 1 + .../binaries/printf/expected_outputs/000011 | 1 + .../binaries/printf/expected_outputs/000012 | 1 + .../binaries/printf/expected_outputs/000013 | 1 + .../binaries/printf/expected_outputs/000014 | Bin 0 -> 24 bytes .../binaries/printf/expected_outputs/000015 | 1 + .../binaries/printf/expected_outputs/000016 | 1 + .../binaries/printf/expected_outputs/000017 | 1 + .../binaries/printf/expected_outputs/000018 | Bin 0 -> 24 bytes .../binaries/printf/expected_outputs/000019 | Bin 0 -> 24 bytes .../printf/expected_outputs/000020-optimistic | Bin 0 -> 24 bytes .../binaries/printf/expected_outputs/000021 | 1 + .../binaries/printf/expected_outputs/000022 | 1 + .../printf/expected_outputs/000023-optimistic | 1 + .../printf/expected_outputs/000024-optimistic | 1 + .../printf/expected_outputs/000025-optimistic | 1 + .../printf/expected_outputs/000026-optimistic | 1 + .../printf/expected_outputs/000027-optimistic | 1 + .../printf/expected_outputs/000028-optimistic | 1 + .../printf/expected_outputs/000029-optimistic | 1 + .../printf/expected_outputs/000030-optimistic | 1 + .../printf/expected_outputs/000031-optimistic | 1 + .../printf/expected_outputs/000032-optimistic | Bin 0 -> 24 bytes .../printf/expected_outputs/000033-optimistic | Bin 0 -> 24 bytes .../binaries/printf/expected_outputs/000034 | 1 + .../binaries/printf/expected_outputs/000035 | 1 + .../printf/expected_outputs/000036-optimistic | 1 + .../printf/expected_outputs/000037-optimistic | 1 + .../printf/expected_outputs/000038-optimistic | 1 + .../printf/expected_outputs/000039-optimistic | 1 + .../printf/expected_outputs/000040-optimistic | 1 + .../printf/expected_outputs/000041-optimistic | 1 + .../printf/expected_outputs/000042-optimistic | Bin 0 -> 24 bytes .../binaries/printf/expected_outputs/000043 | 1 + .../binaries/printf/expected_outputs/000044 | 1 + .../printf/expected_outputs/000045-optimistic | 1 + .../printf/expected_outputs/000046-optimistic | 1 + .../printf/expected_outputs/000047-optimistic | 1 + .../printf/expected_outputs/000048-optimistic | Bin 0 -> 24 bytes .../binaries/printf/expected_outputs/000049 | 1 + .../binaries/printf/expected_outputs/000050 | 1 + .../printf/expected_outputs/000051-optimistic | 1 + .../printf/expected_outputs/000052-optimistic | 1 + .../printf/expected_outputs/000053-optimistic | 1 + tests/symqemu/binaries/printf/input | 1 + tests/symqemu/test.py | 3 +++ 60 files changed, 88 insertions(+) create mode 100644 tests/symqemu/binaries/printf/Makefile create mode 100644 tests/symqemu/binaries/printf/args create mode 100755 tests/symqemu/binaries/printf/binary create mode 100644 tests/symqemu/binaries/printf/binary.c create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000000 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000001 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000002 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000003 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000004 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000005 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000006 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000007 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000008 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000009 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000010 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000011 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000012 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000013 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000014 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000015 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000016 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000017 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000018 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000019 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000020-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000021 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000022 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000023-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000024-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000025-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000026-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000027-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000028-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000029-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000030-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000031-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000032-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000033-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000034 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000035 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000036-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000037-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000038-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000039-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000040-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000041-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000042-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000043 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000044 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000045-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000046-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000047-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000048-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000049 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000050 create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000051-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000052-optimistic create mode 100644 tests/symqemu/binaries/printf/expected_outputs/000053-optimistic create mode 100644 tests/symqemu/binaries/printf/input diff --git a/tests/symqemu/binaries/printf/Makefile b/tests/symqemu/binaries/printf/Makefile new file mode 100644 index 0000000000..d844058ebc --- /dev/null +++ b/tests/symqemu/binaries/printf/Makefile @@ -0,0 +1,6 @@ +LDFLAGS = -static + +binary: + +clean: + rm binary diff --git a/tests/symqemu/binaries/printf/args b/tests/symqemu/binaries/printf/args new file mode 100644 index 0000000000..028281573c --- /dev/null +++ b/tests/symqemu/binaries/printf/args @@ -0,0 +1 @@ +@@ diff --git a/tests/symqemu/binaries/printf/binary b/tests/symqemu/binaries/printf/binary new file mode 100755 index 0000000000000000000000000000000000000000..07ff142202ef7c2546e9b398567423d07643dba2 GIT binary patch literal 900480 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

J2+Nxip$wCjC>? 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ξ!1M-w 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%0A~$GLo=+V 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 |@KFgZVcMK2iRVC;CkHkTb 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 literal 0 HcmV?d00001 diff --git a/tests/symqemu/binaries/printf/binary.c b/tests/symqemu/binaries/printf/binary.c new file mode 100644 index 0000000000..32f4feb926 --- /dev/null +++ b/tests/symqemu/binaries/printf/binary.c @@ -0,0 +1,24 @@ +#define _GNU_SOURCE +#include + +int main(int argc, char *argv[]) { + + if (argc != 2) { + puts("ERROR: You need one argument."); + return 1; + } + + FILE* file_stream = fopen(argv[1], "r"); + + if (!file_stream) { + puts("ERROR: Could not open file."); + return 1; + } + + char format_string[100]; + + fgets(format_string, 100, file_stream); + + char *formatted_string; + asprintf(&formatted_string, format_string, 1, 2, 3, 4); +} diff --git a/tests/symqemu/binaries/printf/expected_outputs/000000 b/tests/symqemu/binaries/printf/expected_outputs/000000 new file mode 100644 index 0000000000..3203734bc7 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000000 @@ -0,0 +1,2 @@ + +aaaa %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000001 b/tests/symqemu/binaries/printf/expected_outputs/000001 new file mode 100644 index 0000000000..7da797c958 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000001 @@ -0,0 +1,2 @@ +a +aaa %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000002 b/tests/symqemu/binaries/printf/expected_outputs/000002 new file mode 100644 index 0000000000..d87178ebbf --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000002 @@ -0,0 +1,2 @@ +aa +aa %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000003 b/tests/symqemu/binaries/printf/expected_outputs/000003 new file mode 100644 index 0000000000..f4921ff94b --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000003 @@ -0,0 +1,2 @@ +aaa +a %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000004 b/tests/symqemu/binaries/printf/expected_outputs/000004 new file mode 100644 index 0000000000..966695ca06 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000004 @@ -0,0 +1,2 @@ +aaaaa +%d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000005 b/tests/symqemu/binaries/printf/expected_outputs/000005 new file mode 100644 index 0000000000..b8f6589390 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000005 @@ -0,0 +1,2 @@ +aaaaa %d +d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000006 b/tests/symqemu/binaries/printf/expected_outputs/000006 new file mode 100644 index 0000000000..2c47f93eca --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000006 @@ -0,0 +1,2 @@ +aaaaa %d %d %d %d +aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000007 b/tests/symqemu/binaries/printf/expected_outputs/000007 new file mode 100644 index 0000000000..eef038c86e --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000007 @@ -0,0 +1 @@ +aaaaa %d %d %d %d aaaaaõ \ No newline at end of file diff --git a/tests/symqemu/binaries/printf/expected_outputs/000008 b/tests/symqemu/binaries/printf/expected_outputs/000008 new file mode 100644 index 0000000000..73ef5fde6d --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000008 @@ -0,0 +1 @@ +%aaaa %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000009 b/tests/symqemu/binaries/printf/expected_outputs/000009 new file mode 100644 index 0000000000..beae6f0f55 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000009 @@ -0,0 +1 @@ +a%aaa %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000010 b/tests/symqemu/binaries/printf/expected_outputs/000010 new file mode 100644 index 0000000000..958c098b93 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000010 @@ -0,0 +1 @@ +aa%aa %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000011 b/tests/symqemu/binaries/printf/expected_outputs/000011 new file mode 100644 index 0000000000..1b027d0155 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000011 @@ -0,0 +1 @@ +aaaa% %d %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000012 b/tests/symqemu/binaries/printf/expected_outputs/000012 new file mode 100644 index 0000000000..0e41ca7152 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000012 @@ -0,0 +1 @@ +aaaaa 'd %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000013 b/tests/symqemu/binaries/printf/expected_outputs/000013 new file mode 100644 index 0000000000..b519e8c530 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000013 @@ -0,0 +1 @@ +aaaaa %% %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000014 b/tests/symqemu/binaries/printf/expected_outputs/000014 new file mode 100644 index 0000000000000000000000000000000000000000..04cc99b510cc58da5d769892c4273bd67b653ded GIT binary patch literal 24 XcmYdH1Of%s6a|J95D7#efkZ9? literal 0 HcmV?d00001 diff --git a/tests/symqemu/binaries/printf/expected_outputs/000019 b/tests/symqemu/binaries/printf/expected_outputs/000019 new file mode 100644 index 0000000000000000000000000000000000000000..0d5e42731f45d610a050f3cd23fd9b791dff0762 GIT binary patch literal 24 VcmYdH1Of%s6c}Pq00|^=0RU0D1~mWx literal 0 HcmV?d00001 diff --git a/tests/symqemu/binaries/printf/expected_outputs/000020-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000020-optimistic new file mode 100644 index 0000000000000000000000000000000000000000..b480e58efb7fa13bcf2ba21eb9178b0d6e916a82 GIT binary patch literal 24 VcmYdH1Of$y6a`fn0tqB?0RU1!26O-b literal 0 HcmV?d00001 diff --git a/tests/symqemu/binaries/printf/expected_outputs/000021 b/tests/symqemu/binaries/printf/expected_outputs/000021 new file mode 100644 index 0000000000..844bfb3a85 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000021 @@ -0,0 +1 @@ +aaaaa %ð %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000022 b/tests/symqemu/binaries/printf/expected_outputs/000022 new file mode 100644 index 0000000000..610352f716 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000022 @@ -0,0 +1 @@ +aaaaa %o %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000023-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000023-optimistic new file mode 100644 index 0000000000..afa944593a --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000023-optimistic @@ -0,0 +1 @@ +aaaaa %X %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000024-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000024-optimistic new file mode 100644 index 0000000000..afa944593a --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000024-optimistic @@ -0,0 +1 @@ +aaaaa %X %d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000025-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000025-optimistic new file mode 100644 index 0000000000..bc5caa701d --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000025-optimistic @@ -0,0 +1 @@ +aaaaa %d%%d %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000026-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000026-optimistic new file mode 100644 index 0000000000..42c60e9ea3 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000026-optimistic @@ -0,0 +1 @@ +aaaaa %d Úd %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000027-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000027-optimistic new file mode 100644 index 0000000000..a737ba1d8a --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000027-optimistic @@ -0,0 +1 @@ +aaaaa %d %% %d %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000028-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000028-optimistic new file mode 100644 index 0000000000..acc07b9595 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000028-optimistic @@ -0,0 +1 @@ +aaaaa %d %d Úd %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000029-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000029-optimistic new file mode 100644 index 0000000000..f17725fedb --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000029-optimistic @@ -0,0 +1 @@ +aaaaa %d %d %% %d aaaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000030-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000030-optimistic new file mode 100644 index 0000000000..68ea7d095f --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000030-optimistic @@ -0,0 +1 @@ +aaaaa %d %d %d %d %aaaa diff --git a/tests/symqemu/binaries/printf/expected_outputs/000031-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000031-optimistic new file mode 100644 index 0000000000..16e27336b7 --- /dev/null +++ b/tests/symqemu/binaries/printf/expected_outputs/000031-optimistic @@ -0,0 +1 @@ +aaaaa %d %d %d %d aaaa% diff --git a/tests/symqemu/binaries/printf/expected_outputs/000032-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000032-optimistic new file mode 100644 index 0000000000000000000000000000000000000000..94e74dc8eb3ec8cec592d96e15bc1a41aa849364 GIT binary patch literal 24 VcmYdH1Of%s6bNDfGC%@}TmVy=26+Gg literal 0 HcmV?d00001 diff --git a/tests/symqemu/binaries/printf/expected_outputs/000033-optimistic b/tests/symqemu/binaries/printf/expected_outputs/000033-optimistic new file mode 100644 index 0000000000000000000000000000000000000000..04cc99b510cc58da5d769892c4273bd67b653ded GIT binary patch literal 24 XcmYdH1Of%s6a|J95D7#efkZ9 Date: Sat, 17 Feb 2024 20:52:26 +0100 Subject: [PATCH 56/61] typo fixes in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 11b61b34ab..c5e0c727c7 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Fedora 33: $ ../configure \ --audio-drv-list= \ -s --disable-sdl \ + --disable-sdl \ --disable-gtk \ --disable-vte \ --disable-opengl \ @@ -117,7 +117,7 @@ details on how SymQEMU works. A large part of the implementation is the run-time in `accel/tcg/tcg-runtime-sym.{c,h}` and `accel/tcg/tcg-runtime-sym-vec.{c,h}` (which delegates any actual symbolic computation to SymCC's symbolic backend), and we have modified most code-generating functions in `tcg/tcg-op.c`, `tcg/tcg-op-vec.c` and -`include/tcg/tcg-op-common.h` to emit calls to the runtime. +`include/tcg/tcg-op-common.h` to emit calls to the runtime. For development, configure with `--enable-debug` for run-time assertions; there are tests for the symbolic run-time support in `tests/check-sym-runtime.c`. From 51bbf363a41b53a536b355e3078fdd1c3c5c04e6 Mon Sep 17 00:00:00 2001 From: Aurelien Francillon Date: Sat, 17 Feb 2024 21:23:14 +0100 Subject: [PATCH 57/61] Minor formatting fixes --- accel/tcg/tcg-runtime-sym-common.c | 2 +- accel/tcg/tcg-runtime-sym-vec.c | 2 +- accel/tcg/tcg-runtime-sym-vec.h | 2 +- accel/tcg/tcg-runtime-sym.h | 1 - tcg/tcg.c | 1 - 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym-common.c b/accel/tcg/tcg-runtime-sym-common.c index 06c98aea27..b7fa4a88aa 100644 --- a/accel/tcg/tcg-runtime-sym-common.c +++ b/accel/tcg/tcg-runtime-sym-common.c @@ -92,4 +92,4 @@ void *sym_rotate_right(void *arg1_expr, void *arg2_expr) { _sym_build_shift_left( arg1_expr, _sym_build_sub(_sym_build_integer(bits, bits), arg2_expr))); -} \ No newline at end of file +} diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c index 59dbc41299..2545b08b07 100644 --- a/accel/tcg/tcg-runtime-sym-vec.c +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -527,4 +527,4 @@ void *HELPER(sym_ternary_vec)( g_assert(_sym_bits_helper(result_expression) == vector_size); return result_expression; -} \ No newline at end of file +} diff --git a/accel/tcg/tcg-runtime-sym-vec.h b/accel/tcg/tcg-runtime-sym-vec.h index f159e7afa7..fa66cca7c5 100644 --- a/accel/tcg/tcg-runtime-sym-vec.h +++ b/accel/tcg/tcg-runtime-sym-vec.h @@ -24,4 +24,4 @@ DEF_HELPER_FLAGS_6(sym_rotate_right_vec_int32, TCG_CALL_NO_RWG, ptr, ptr, ptr, i DEF_HELPER_FLAGS_9(sym_cmp_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_9(sym_ternary_vec, TCG_CALL_NO_RWG, ptr, env, ptr, ptr, ptr, ptr, i32, ptr, i64, i64) DEF_HELPER_FLAGS_3(sym_duplicate_value_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64) -DEF_HELPER_FLAGS_4(sym_load_and_duplicate_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64, i64) \ No newline at end of file +DEF_HELPER_FLAGS_4(sym_load_and_duplicate_into_vec, TCG_CALL_NO_RWG, ptr, ptr, i64, i64, i64) diff --git a/accel/tcg/tcg-runtime-sym.h b/accel/tcg/tcg-runtime-sym.h index 4092daf1c4..363d22af76 100644 --- a/accel/tcg/tcg-runtime-sym.h +++ b/accel/tcg/tcg-runtime-sym.h @@ -123,7 +123,6 @@ DEF_HELPER_FLAGS_1(sym_notify_block, TCG_CALL_NO_RWG, void, i64) /* Garbage collection */ DEF_HELPER_FLAGS_0(sym_collect_garbage, TCG_CALL_NO_RWG, void) - /* TODO clz, ctz, clrsb, ctpop; vector operations; helpers for atomic operations (?) */ /* The extrl and extrh instructions aren't emitted on 64-bit hosts. If we ever diff --git a/tcg/tcg.c b/tcg/tcg.c index 73ae67d268..d501e3f2f4 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1518,7 +1518,6 @@ static TCGTemp *tcg_temp_alloc(TCGContext *s) } } - int n = s->nb_temps++; if (n >= TCG_MAX_TEMPS) { From 5945bd785267c4d1efe67064211fb916d7271b98 Mon Sep 17 00:00:00 2001 From: aurelf Date: Thu, 22 Feb 2024 15:59:39 +0100 Subject: [PATCH 58/61] Update tcg-runtime-sym-vec.c Minor typos --- accel/tcg/tcg-runtime-sym-vec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accel/tcg/tcg-runtime-sym-vec.c b/accel/tcg/tcg-runtime-sym-vec.c index 2545b08b07..0cff8b6251 100644 --- a/accel/tcg/tcg-runtime-sym-vec.c +++ b/accel/tcg/tcg-runtime-sym-vec.c @@ -362,7 +362,7 @@ static void *element_address( Currently, `helper_sym_cmp_vec` pushes path constraints and concretizes its result. Returning an expression that represents the result of the comparison, instead of pushing path constraints, may give better results. -/* +*/ /* * Symbolic equivalent of an SIMD comparison operation, where true is represented by -1 and false by 0. @@ -441,7 +441,7 @@ void *HELPER(sym_cmp_vec)( Currently, `helper_sym_ternary_vec` pushes path constraints and concretizes its result. Returning an expression that represents the result of the comparison, instead of pushing path constraints, may give better results. -/* +*/ /* * Symbolic equivalent of an SIMD ternary operation. From 772c202110c653060ef4e768d749d6269b548df6 Mon Sep 17 00:00:00 2001 From: aurelf Date: Mon, 19 Feb 2024 12:33:44 +0300 Subject: [PATCH 59/61] Adding QEMU own checks to Dockerfile (CI) and improve README.md (#43) --- Dockerfile | 3 +++ README.md | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8a529d93ce..ab8333a32e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,5 +35,8 @@ RUN ./configure \ RUN make -j +# Run QEMU base checks +RUN make check + WORKDIR /symqemu_source/tests/symqemu RUN python3 -m unittest test.py diff --git a/README.md b/README.md index c5e0c727c7..95bbed1ccf 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,8 @@ and binaries. The following invocation is known to work on Debian 10, Arch and Fedora 33: ``` shell - +$ mkdir build +$ cd build $ ../configure \ --audio-drv-list= \ --disable-sdl \ @@ -42,15 +43,14 @@ $ ../configure \ --disable-virglrenderer \ --disable-werror \ --target-list=x86_64-linux-user \ - --symcc-source=/sources \ - --symcc-build=/build - -$ make + --symcc-source=../symcc \ + --symcc-build=../symcc/build +$ make -j ``` This will build a relatively stripped-down emulator targeting 64-bit x86 binaries. We also have experimental support for AARCH64. Working with 32-bit -target architectures are possible in principle but will require a bit of work +target architectures is possible in principle but will require a bit of work because the current implementation assumes that we can pass around host pointers in guest registers. From 393104f693f97ed09d518a88aebce9c66cd55a4c Mon Sep 17 00:00:00 2001 From: aurelf Date: Thu, 22 Feb 2024 14:03:40 +0300 Subject: [PATCH 60/61] Adding SymQEMU unit test suite to CI (#44) * Moved check-sym-runtime.c to unit tests and updated to work with QEMU8 * Build and run check-sym-runtime test with meson.build * Improve Dockerfile * Added documentation about test suites --- Dockerfile | 7 ++++-- README.md | 36 +++++++++++++++++++++++++++- tests/{ => unit}/check-sym-runtime.c | 4 +++- tests/unit/meson.build | 28 +++++++++++++++++++++- 4 files changed, 70 insertions(+), 5 deletions(-) rename tests/{ => unit}/check-sym-runtime.c (99%) diff --git a/Dockerfile b/Dockerfile index ab8333a32e..d0d4ec9548 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM ubuntu:22.04 +# prepare machine +FROM ubuntu:22.04 as builder RUN apt update RUN apt install -y \ @@ -9,6 +10,9 @@ RUN apt install -y \ python3 \ python3-pip +# +FROM builder as symqemu + COPY . /symqemu_source WORKDIR /symqemu_source @@ -35,7 +39,6 @@ RUN ./configure \ RUN make -j -# Run QEMU base checks RUN make check WORKDIR /symqemu_source/tests/symqemu diff --git a/README.md b/README.md index 95bbed1ccf..2e49ef53c6 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ cd .. Then build the SymQEMU image with (this will also run the tests): ```shell -docker build -t symqemu . +docker build -t symqemu . ``` You can use the docker with: @@ -110,6 +110,40 @@ You can use the docker with: docker run -it --rm symqemu ``` +## Contributing + +Use the GitHub project for reporting issues, and proposing changes. + +### Issues + +Please try to provide a minimal test case that demonstrates the problem, or ways +to reproduce the behavior. If possible provide a precise line number if +referring to some code. Ideally, make a PR with the test case demonstrating the +failure (see next point). + +### Pull Requests + +Pull requests are very welcome. Pull requests will only be merged if all tests +pass, and ideally with a new test case to validate the correctness of the +proposed modifications. QEMU tests that are not specific to SymQEMU should pass +(no regression). + +It is very valuable to also make a PR to add a test case for a known bug, this +will facilitate correcting the issue. + +Current SymQEMU tests are run by the CI from the Docker container, the following +test suites are currently in place: +- [Unit tests](tests/unit/check-sym-runtime.c): Those tests are made to validate + specific instrumentation. +- [Integration tests](tests/symqemu/): Those tests are running SymQEMU on a set + of binaries and compare the results to expected results. Note that those test + cases can legitimately fail if some changes are made to SymQEMU (because for + example, an improvement leads to generating new test cases). In that case, + update the relevant files in `expected_outputs` folders. It would be nice to + also validate those changes with a new test case. + +Also, refer to [QEMU's own tests suite documentation](https://www.qemu.org/docs/master/devel/testing.html). + ## Documentation The [paper](http://www.s3.eurecom.fr/tools/symbolic_execution/symqemu.html) contains diff --git a/tests/check-sym-runtime.c b/tests/unit/check-sym-runtime.c similarity index 99% rename from tests/check-sym-runtime.c rename to tests/unit/check-sym-runtime.c index 2169960af3..db4d89a8e8 100644 --- a/tests/check-sym-runtime.c +++ b/tests/unit/check-sym-runtime.c @@ -15,7 +15,9 @@ */ #include "qemu/osdep.h" -#include "tcg.h" +#include "tcg/tcg.h" +#include "hw/i386/topology.h" +#include "target/i386/cpu.h" #include "exec/helper-proto.h" #define SymExpr void* diff --git a/tests/unit/meson.build b/tests/unit/meson.build index 93977cc32d..061ef5548f 100644 --- a/tests/unit/meson.build +++ b/tests/unit/meson.build @@ -50,6 +50,7 @@ tests = { 'test-qapi-util': [], 'test-interval-tree': [], 'test-xs-node': [qom], + 'check-sym-runtime' : [qemuutil, qom, hwcore], } if have_system or have_tools @@ -184,7 +185,32 @@ foreach test_name, extra: tests src += test_ss.all_sources() deps += test_ss.all_dependencies() endif - exe = executable(test_name, src, genh, dependencies: deps) + args = [] + lwith = [] + + # SymQEMU unit tests executable construction is a bit more complicated + if test_name == 'check-sym-runtime' + # lookup the libSymRuntime.so and add it as a dependence + libdir = meson.current_build_dir() / '../../' / config_host['SYMCC_BUILD'] + symcc_runtime = cc.find_library('SymRuntime', dirs : libdir) + deps += [symcc_runtime] + + # embeds most of qemu objects, including SymQEMU + lwith += [lib] + args += ['-I../target/i386/', + '-I../../symcc/runtime/', + '-DCONFIG_TARGET="x86_64-linux-user-config-target.h"', + '-DNEED_CPU_H', + '-Ix86_64-linux-user'] + + # Create the output file for symcc results + symcc_output=meson.current_build_dir() / 'symcc-tests-output' + test_env.append('SYMCC_OUTPUT_DIR', symcc_output) + r = run_command('mkdir', symcc_output, check : false) + endif + + exe = executable(test_name, src, genh, dependencies: deps, + c_args : args, link_with: lwith) test(test_name, exe, depends: test_deps.get(test_name, []), From 087b98dc04664a6b854394825d19ed79e006002e Mon Sep 17 00:00:00 2001 From: Aurelien Francillon Date: Thu, 22 Feb 2024 16:23:27 +0100 Subject: [PATCH 61/61] Update SymQEMU unit tests (check-sym-runtime.c) "helper_sym_store_host_i64" and "helper_sym_store_host_i32" were replaced by helper_sym_store_host, adjusting the unit tests accordingly --- tests/unit/check-sym-runtime.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/check-sym-runtime.c b/tests/unit/check-sym-runtime.c index db4d89a8e8..8d1505e83f 100644 --- a/tests/unit/check-sym-runtime.c +++ b/tests/unit/check-sym-runtime.c @@ -328,12 +328,12 @@ static void load_store_host_test(void) /* Store some symbolic data in the middle of the buffer. */ *((uint32_t*)&memory[16]) = 0x11223344; - helper_sym_store_host_i64(0x11223344, _sym_build_integer(0x11223344, 64), - memory, 16, 4); + helper_sym_store_host(_sym_build_integer(0x11223344, 64), + memory, 16, 4); *((uint16_t*)&memory[20]) = 0x5566; - helper_sym_store_host_i32(0x5566, _sym_build_integer(0x5566, 32), - memory, 20, 2); + helper_sym_store_host(_sym_build_integer(0x5566, 32), + memory, 20, 2); /* Buffer: [AA...AA 44 33 22 11 66 55 BB...BB] */