[PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS

Pierrick Bouvier posted 29 patches 1 month ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Peter Maydell <peter.maydell@linaro.org>, Michael Rolnik <mrolnik@gmail.com>, Brian Cain <brian.cain@oss.qualcomm.com>, Helge Deller <deller@gmx.de>, Zhao Liu <zhao1.liu@intel.com>, Eduardo Habkost <eduardo@habkost.net>, Song Gao <gaosong@loongson.cn>, Laurent Vivier <laurent@vivier.eu>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Aurelien Jarno <aurelien@aurel32.net>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <arikalo@gmail.com>, Stafford Horne <shorne@gmail.com>, Nicholas Piggin <npiggin@gmail.com>, Chinmay Rath <rathc@linux.ibm.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Yoshinori Sato <yoshinori.sato@nifty.com>, Ilya Leoshkevich <iii@linux.ibm.com>, David Hildenbrand <david@kernel.org>, Thomas Huth <thuth@redhat.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>, Bastian Koppelmann <kbastian@rumtueddeln.de>, Max Filippov <jcmvbkbc@gmail.com>
There is a newer version of this series
[PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Pierrick Bouvier 1 month ago
This define will be used to replace TARGET_LONG_BITS in tcg-op-*
headers. The goal here is to allow a compilation unit to set explicitely
which variant of the arch it's targeting (32 vs 64 bits).

By default, we simple let it defined as TARGET_LONG_BITS, so existing
code does not need to be changed, and we can progressively convert new
files.

target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
some TARGET_AARCH64 defines). For other arch, this is a work that will
have to be done before converting them.

Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
 include/tcg/tcg-op-address-bits.h | 21 +++++++++++++++++++++
 include/tcg/tcg-op-gvec.h         | 11 +++--------
 include/tcg/tcg-op.h              | 22 +++++++---------------
 3 files changed, 31 insertions(+), 23 deletions(-)
 create mode 100644 include/tcg/tcg-op-address-bits.h

diff --git a/include/tcg/tcg-op-address-bits.h b/include/tcg/tcg-op-address-bits.h
new file mode 100644
index 00000000000..71e9de65280
--- /dev/null
+++ b/include/tcg/tcg-op-address-bits.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TCG_OP_ADDRESS_BITS
+#define TCG_OP_ADDRESS_BITS
+
+#ifdef COMPILING_PER_TARGET
+ #include "exec/target_long.h"
+ #ifndef TARGET_ADDRESS_BITS
+  #define TARGET_ADDRESS_BITS TARGET_LONG_BITS
+ #endif
+#else
+ #ifndef TARGET_ADDRESS_BITS
+  #error TARGET_ADDRESS_BITS must be defined for current file
+ #endif
+#endif /* COMPILING_PER_TARGET */
+
+#if TARGET_ADDRESS_BITS != 32 && TARGET_ADDRESS_BITS != 64
+ #error TARGET_ADDRESS_BITS must be 32 or 64
+#endif
+
+#endif /* TCG_OP_ADDRESS_BITS */
diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
index b0a81ad4bf4..422a270b694 100644
--- a/include/tcg/tcg-op-gvec.h
+++ b/include/tcg/tcg-op-gvec.h
@@ -8,13 +8,10 @@
 #ifndef TCG_TCG_OP_GVEC_H
 #define TCG_TCG_OP_GVEC_H
 
+#include "tcg/tcg-op-address-bits.h"
 #include "tcg/tcg-op-gvec-common.h"
 
-#ifndef TARGET_LONG_BITS
-#error must include QEMU headers
-#endif
-
-#if TARGET_LONG_BITS == 64
+#if TARGET_ADDRESS_BITS == 64
 #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i64
 #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i64
 #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i64
@@ -28,7 +25,7 @@
 #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i64
 #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i64
 #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i64
-#elif TARGET_LONG_BITS == 32
+#elif TARGET_ADDRESS_BITS == 32
 #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i32
 #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i32
 #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i32
@@ -42,8 +39,6 @@
 #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i32
 #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i32
 #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i32
-#else
-# error
 #endif
 
 #endif
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index bf76749d1c5..9e4e58a2d4b 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -8,20 +8,14 @@
 #ifndef TCG_TCG_OP_H
 #define TCG_TCG_OP_H
 
+#include "tcg/tcg-op-address-bits.h"
 #include "tcg/tcg-op-common.h"
 #include "tcg/insn-start-words.h"
-#include "exec/target_long.h"
 
-#ifndef TARGET_LONG_BITS
-#error must include QEMU headers
-#endif
-
-#if TARGET_LONG_BITS == 32
+#if TARGET_ADDRESS_BITS == 32
 # define TCG_TYPE_TL  TCG_TYPE_I32
-#elif TARGET_LONG_BITS == 64
+#elif TARGET_ADDRESS_BITS == 64
 # define TCG_TYPE_TL  TCG_TYPE_I64
-#else
-# error
 #endif
 
 #if INSN_START_WORDS != 3
@@ -56,22 +50,20 @@ static inline void tcg_gen_insn_start2(uint64_t pc, uint64_t a1,
     tcg_set_insn_start_param(op, 2, a2);
 }
 
-#if TARGET_LONG_BITS == 32
+#if TARGET_ADDRESS_BITS == 32
 typedef TCGv_i32 TCGv;
 #define tcg_temp_new() tcg_temp_new_i32()
 #define tcg_global_mem_new tcg_global_mem_new_i32
 #define tcgv_tl_temp tcgv_i32_temp
 #define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
 #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
-#elif TARGET_LONG_BITS == 64
+#elif TARGET_ADDRESS_BITS == 64
 typedef TCGv_i64 TCGv;
 #define tcg_temp_new() tcg_temp_new_i64()
 #define tcg_global_mem_new tcg_global_mem_new_i64
 #define tcgv_tl_temp tcgv_i64_temp
 #define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i64
 #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i64
-#else
-#error Unhandled TARGET_LONG_BITS value
 #endif
 
 static inline void
@@ -171,7 +163,7 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
 #undef DEF_ATOMIC2
 #undef DEF_ATOMIC3
 
-#if TARGET_LONG_BITS == 64
+#if TARGET_ADDRESS_BITS == 64
 #define tcg_gen_movi_tl tcg_gen_movi_i64
 #define tcg_gen_mov_tl tcg_gen_mov_i64
 #define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
@@ -419,5 +411,5 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
         : (qemu_build_not_reached_always(), 0))                    \
      :  (target_long)dup_const(VECE, C))
 
-#endif /* TARGET_LONG_BITS == 64 */
+#endif /* TARGET_ADDRESS_BITS == 64 */
 #endif /* TCG_TCG_OP_H */
-- 
2.47.3
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Richard Henderson 1 month ago
On 1/9/26 16:31, Pierrick Bouvier wrote:
> This define will be used to replace TARGET_LONG_BITS in tcg-op-*
> headers. The goal here is to allow a compilation unit to set explicitely
> which variant of the arch it's targeting (32 vs 64 bits).
> 
> By default, we simple let it defined as TARGET_LONG_BITS, so existing
> code does not need to be changed, and we can progressively convert new
> files.
> 
> target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
> some TARGET_AARCH64 defines). For other arch, this is a work that will
> have to be done before converting them.
> 
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
>   include/tcg/tcg-op-address-bits.h | 21 +++++++++++++++++++++
>   include/tcg/tcg-op-gvec.h         | 11 +++--------
>   include/tcg/tcg-op.h              | 22 +++++++---------------
>   3 files changed, 31 insertions(+), 23 deletions(-)
>   create mode 100644 include/tcg/tcg-op-address-bits.h
> 
> diff --git a/include/tcg/tcg-op-address-bits.h b/include/tcg/tcg-op-address-bits.h
> new file mode 100644
> index 00000000000..71e9de65280
> --- /dev/null
> +++ b/include/tcg/tcg-op-address-bits.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#ifndef TCG_OP_ADDRESS_BITS
> +#define TCG_OP_ADDRESS_BITS
> +
> +#ifdef COMPILING_PER_TARGET
> + #include "exec/target_long.h"
> + #ifndef TARGET_ADDRESS_BITS
> +  #define TARGET_ADDRESS_BITS TARGET_LONG_BITS
> + #endif
> +#else
> + #ifndef TARGET_ADDRESS_BITS
> +  #error TARGET_ADDRESS_BITS must be defined for current file
> + #endif
> +#endif /* COMPILING_PER_TARGET */
> +
> +#if TARGET_ADDRESS_BITS != 32 && TARGET_ADDRESS_BITS != 64
> + #error TARGET_ADDRESS_BITS must be 32 or 64
> +#endif
> +
> +#endif /* TCG_OP_ADDRESS_BITS */
> diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
> index b0a81ad4bf4..422a270b694 100644
> --- a/include/tcg/tcg-op-gvec.h
> +++ b/include/tcg/tcg-op-gvec.h
> @@ -8,13 +8,10 @@
>   #ifndef TCG_TCG_OP_GVEC_H
>   #define TCG_TCG_OP_GVEC_H
>   
> +#include "tcg/tcg-op-address-bits.h"
>   #include "tcg/tcg-op-gvec-common.h"
>   
> -#ifndef TARGET_LONG_BITS
> -#error must include QEMU headers
> -#endif
> -
> -#if TARGET_LONG_BITS == 64
> +#if TARGET_ADDRESS_BITS == 64
>   #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i64
>   #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i64
>   #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i64
> @@ -28,7 +25,7 @@
>   #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i64
>   #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i64
>   #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i64
> -#elif TARGET_LONG_BITS == 32
> +#elif TARGET_ADDRESS_BITS == 32
>   #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i32
>   #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i32
>   #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i32
> @@ -42,8 +39,6 @@
>   #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i32
>   #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i32
>   #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i32
> -#else
> -# error
>   #endif

Not address related.  Not even close.


>   
>   #endif
> diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
> index bf76749d1c5..9e4e58a2d4b 100644
> --- a/include/tcg/tcg-op.h
> +++ b/include/tcg/tcg-op.h
> @@ -8,20 +8,14 @@
>   #ifndef TCG_TCG_OP_H
>   #define TCG_TCG_OP_H
>   
> +#include "tcg/tcg-op-address-bits.h"
>   #include "tcg/tcg-op-common.h"
>   #include "tcg/insn-start-words.h"
> -#include "exec/target_long.h"
>   
> -#ifndef TARGET_LONG_BITS
> -#error must include QEMU headers
> -#endif
> -
> -#if TARGET_LONG_BITS == 32
> +#if TARGET_ADDRESS_BITS == 32
>   # define TCG_TYPE_TL  TCG_TYPE_I32
> -#elif TARGET_LONG_BITS == 64
> +#elif TARGET_ADDRESS_BITS == 64
>   # define TCG_TYPE_TL  TCG_TYPE_I64
> -#else
> -# error
>   #endif

Ok, there's been a fundamental misunderstanding about what we discussed.

There should be *no* changes to target_long, TCGv or TCG_TYPE_TL.

There should be a *new* file, include/tcg/tcg-op-mem.h which deals with TCGv_va, 
TCG_TYPE_VA, and all of the tcg_gen_qemu_{ld,st}* helpers based on that.

The only thing that should happen in tcg-op.h is:

#define TARGET_ADDRESS_BITS  TARGET_LONG_BITS
#include "tcg-op-mem.h"


r~
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Pierrick Bouvier 1 month ago
On 1/9/26 2:02 PM, Richard Henderson wrote:
> On 1/9/26 16:31, Pierrick Bouvier wrote:
>> This define will be used to replace TARGET_LONG_BITS in tcg-op-*
>> headers. The goal here is to allow a compilation unit to set explicitely
>> which variant of the arch it's targeting (32 vs 64 bits).
>>
>> By default, we simple let it defined as TARGET_LONG_BITS, so existing
>> code does not need to be changed, and we can progressively convert new
>> files.
>>
>> target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
>> some TARGET_AARCH64 defines). For other arch, this is a work that will
>> have to be done before converting them.
>>
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>>    include/tcg/tcg-op-address-bits.h | 21 +++++++++++++++++++++
>>    include/tcg/tcg-op-gvec.h         | 11 +++--------
>>    include/tcg/tcg-op.h              | 22 +++++++---------------
>>    3 files changed, 31 insertions(+), 23 deletions(-)
>>    create mode 100644 include/tcg/tcg-op-address-bits.h
>>
>> diff --git a/include/tcg/tcg-op-address-bits.h b/include/tcg/tcg-op-address-bits.h
>> new file mode 100644
>> index 00000000000..71e9de65280
>> --- /dev/null
>> +++ b/include/tcg/tcg-op-address-bits.h
>> @@ -0,0 +1,21 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +
>> +#ifndef TCG_OP_ADDRESS_BITS
>> +#define TCG_OP_ADDRESS_BITS
>> +
>> +#ifdef COMPILING_PER_TARGET
>> + #include "exec/target_long.h"
>> + #ifndef TARGET_ADDRESS_BITS
>> +  #define TARGET_ADDRESS_BITS TARGET_LONG_BITS
>> + #endif
>> +#else
>> + #ifndef TARGET_ADDRESS_BITS
>> +  #error TARGET_ADDRESS_BITS must be defined for current file
>> + #endif
>> +#endif /* COMPILING_PER_TARGET */
>> +
>> +#if TARGET_ADDRESS_BITS != 32 && TARGET_ADDRESS_BITS != 64
>> + #error TARGET_ADDRESS_BITS must be 32 or 64
>> +#endif
>> +
>> +#endif /* TCG_OP_ADDRESS_BITS */
>> diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
>> index b0a81ad4bf4..422a270b694 100644
>> --- a/include/tcg/tcg-op-gvec.h
>> +++ b/include/tcg/tcg-op-gvec.h
>> @@ -8,13 +8,10 @@
>>    #ifndef TCG_TCG_OP_GVEC_H
>>    #define TCG_TCG_OP_GVEC_H
>>    
>> +#include "tcg/tcg-op-address-bits.h"
>>    #include "tcg/tcg-op-gvec-common.h"
>>    
>> -#ifndef TARGET_LONG_BITS
>> -#error must include QEMU headers
>> -#endif
>> -
>> -#if TARGET_LONG_BITS == 64
>> +#if TARGET_ADDRESS_BITS == 64
>>    #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i64
>>    #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i64
>>    #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i64
>> @@ -28,7 +25,7 @@
>>    #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i64
>>    #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i64
>>    #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i64
>> -#elif TARGET_LONG_BITS == 32
>> +#elif TARGET_ADDRESS_BITS == 32
>>    #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i32
>>    #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i32
>>    #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i32
>> @@ -42,8 +39,6 @@
>>    #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i32
>>    #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i32
>>    #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i32
>> -#else
>> -# error
>>    #endif
> 
> Not address related.  Not even close.
> 
> 
>>    
>>    #endif
>> diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
>> index bf76749d1c5..9e4e58a2d4b 100644
>> --- a/include/tcg/tcg-op.h
>> +++ b/include/tcg/tcg-op.h
>> @@ -8,20 +8,14 @@
>>    #ifndef TCG_TCG_OP_H
>>    #define TCG_TCG_OP_H
>>    
>> +#include "tcg/tcg-op-address-bits.h"
>>    #include "tcg/tcg-op-common.h"
>>    #include "tcg/insn-start-words.h"
>> -#include "exec/target_long.h"
>>    
>> -#ifndef TARGET_LONG_BITS
>> -#error must include QEMU headers
>> -#endif
>> -
>> -#if TARGET_LONG_BITS == 32
>> +#if TARGET_ADDRESS_BITS == 32
>>    # define TCG_TYPE_TL  TCG_TYPE_I32
>> -#elif TARGET_LONG_BITS == 64
>> +#elif TARGET_ADDRESS_BITS == 64
>>    # define TCG_TYPE_TL  TCG_TYPE_I64
>> -#else
>> -# error
>>    #endif
> 
> Ok, there's been a fundamental misunderstanding about what we discussed.
> 
> There should be *no* changes to target_long, TCGv or TCG_TYPE_TL.
> 
> There should be a *new* file, include/tcg/tcg-op-mem.h which deals with TCGv_va,
> TCG_TYPE_VA, and all of the tcg_gen_qemu_{ld,st}* helpers based on that.
> 
> The only thing that should happen in tcg-op.h is:
> 
> #define TARGET_ADDRESS_BITS  TARGET_LONG_BITS
> #include "tcg-op-mem.h"
> 

To be fair, I should have mentioned that I didn't understand why you 
were insisting to *only* deal with memory operations.
Yes, target/arm uses TCGv *only* for addresses, but it's very 
arm-centric to think about this.

So what's the benefit to split memory operations instead of parameterize 
TCGv directly?
In this case, I agree that TARGET_ADDRESS_BITS is definitely a bad name, 
but I wanted to stick to the one you said, I should not have though 
because the end result is not consistent.

> 
> r~
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Richard Henderson 1 month ago
On 1/10/26 09:11, Pierrick Bouvier wrote:
> Yes, target/arm uses TCGv *only* for addresses, but it's very arm-centric to think about 
> this.
> 
> So what's the benefit to split memory operations instead of parameterize TCGv directly?

Sure, but Arm has a unique set of circumstances.

The benefit is to leave the name "TCGv" to all other targets that don't have a clear 
separation of 32-bit and 64-bit mode.  By arranging for the name to not be defined for 
Arm, we avoid any use of it creeping back in.


r~
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Paolo Bonzini 1 month ago
On 1/9/26 06:31, Pierrick Bouvier wrote:
> This define will be used to replace TARGET_LONG_BITS in tcg-op-*
> headers. The goal here is to allow a compilation unit to set explicitely
> which variant of the arch it's targeting (32 vs 64 bits).
> 
> By default, we simple let it defined as TARGET_LONG_BITS, so existing
> code does not need to be changed, and we can progressively convert new
> files.
> 
> target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
> some TARGET_AARCH64 defines). For other arch, this is a work that will
> have to be done before converting them.

ARM is pretty special in this regard because it has separate registers 
arrays regs[] and xregs[].  The other five multi-size targets (i386, 
mips, ppc, riscv, sparc) probably will *not* use target_common_arch as 
much as ARM is doing, and will keep support two TCG _tl sizes: 32 for 
the 32-bit single-target binaries, 64 for the 64-bit single-target 
binaries and for the single multi-target binary.

For them, the death of target_long/target_ulong is not really possible, 
because they will have to reinvent include/exec/target_long.h for their 
CPUStates.

For the sake of this series, I would rename TARGET_ADDRESS_BITS to 
TCG_ADDRESS_BITS, add to include/tcg/tcg-op.h something like:

#if TCG_ADDRESS_BITS == 32
typedef TCGv_i32 TCGv_addr;
#define tcg_temp_new_addr() tcg_temp_new_i32()
#define tcg_global_mem_new_addr tcg_global_mem_new_i32
#define tcgv_addr_temp tcgv_i32_temp
#define tcg_gen_qemu_ld_addr tcg_gen_qemu_ld_i32
#define tcg_gen_qemu_st_addr tcg_gen_qemu_st_i32
#elif TCG_ADDRESS_BITS == 64
typedef TCGv_i64 TCGv_addr;
#define tcg_temp_new_addr() tcg_temp_new_i64()
#define tcg_global_mem_new_addr tcg_global_mem_new_i64
#define tcgv_addr_temp tcgv_i64_temp
#define tcg_gen_qemu_ld_addr tcg_gen_qemu_ld_i64
#define tcg_gen_qemu_st_addr tcg_gen_qemu_st_i64
#else
#error Unhandled TARGET_LONG_BITS value
#endif

and use TCGv_addr in tcg_gen_qemu_ld_i32 and friends.  This first step 
clearly separates (at least in the long run) target_long from TCG addresses.

 From the point of view of this is all I would like to see: 
TARGET_ADDRESS_BITS renamed to TCG_ADDRESS_BITS, and TCGv_addr 
introduced in include/tcg/tcg-op.h and tcg/tcg-op-ldst.c at the same 
time as TCG_ADDRESS_BITS.

In the rest of the message I'm going to describe why and what more I 
envision.

In the long run TCGv and _tl can become entirely optional, leaving the 
door open for single-size targets to use TCGv_{i32,i64,addr} 
exclusively.  For this reason, the second step (independent of this 
series) is for single-size targets, who have already mostly moved 
towards removing target_long, to remove TARGET_LONG_BITS from 
configs/targets/ altogether.  To this end I would create two files like 
this:

include/exec/target_long32.h
----------------------------
#ifndef TARGET_LONG_BITS
#define TARGET_LONG_BITS 32
#endif
#define TARGET_ADDRESS_BITS 32
#define TARGET_LONG_SIZE 4
typedef int32_t target_long;
typedef uint32_t target_ulong;
#define TARGET_FMT_lx "%08x"
#define TARGET_FMT_ld "%d"
#define TARGET_FMT_lu "%u"
#define MO_TL MO_32

include/exec/target_long64.h
----------------------------
#ifndef TARGET_LONG_BITS
#define TARGET_LONG_BITS 64
#endif
#define TARGET_ADDRESS_BITS 64
#define TARGET_LONG_SIZE 8
typedef int64_t target_long;
typedef uint64_t target_ulong;
#define TARGET_FMT_lx "%016" PRIx64
#define TARGET_FMT_ld "%" PRId64
#define TARGET_FMT_lu "%" PRIu64
#define MO_TL MO_64

... and use them in include/exec/target_long.h:

include/exec/target_long.h:
#ifndef TARGET_LONG_BITS
#error TARGET_LONG_BITS not defined
#elif TARGET_LONG_BITS == 32
#include "exec/target_long32.h"
#elif TARGET_LONG_BITS == 64
#include "exec/target_long64.h"
#endif

Then the single-size targets can replace TARGET_LONG_BITS with:
- a "#define TCG_ADDRESS_BITS" in their translate.c
- a #include "exec/target_longNN.h" in their cpu.h.

Dual-size targets, instead, can add to their cpu.h an initial stanza 
like this:

#ifdef TARGET_I386
#include "exec/target_long32.h"
#else
#include "exec/target_long64.h" // x86_64 or single binary
#endif

and keep using target_long.

And as a final third step, TCG should excise "_tl" definitions 
altogether if "!defined TARGET_LONG_BITS".  For targets that want to use 
exclusively TCGv_{i32,i64,addr}, this lets them stop including 
exec/target_longNN.h.

Thanks,

Paolo

> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
>   include/tcg/tcg-op-address-bits.h | 21 +++++++++++++++++++++
>   include/tcg/tcg-op-gvec.h         | 11 +++--------
>   include/tcg/tcg-op.h              | 22 +++++++---------------
>   3 files changed, 31 insertions(+), 23 deletions(-)
>   create mode 100644 include/tcg/tcg-op-address-bits.h
> 
> diff --git a/include/tcg/tcg-op-address-bits.h b/include/tcg/tcg-op-address-bits.h
> new file mode 100644
> index 00000000000..71e9de65280
> --- /dev/null
> +++ b/include/tcg/tcg-op-address-bits.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#ifndef TCG_OP_ADDRESS_BITS
> +#define TCG_OP_ADDRESS_BITS
> +
> +#ifdef COMPILING_PER_TARGET
> + #include "exec/target_long.h"
> + #ifndef TARGET_ADDRESS_BITS
> +  #define TARGET_ADDRESS_BITS TARGET_LONG_BITS
> + #endif
> +#else
> + #ifndef TARGET_ADDRESS_BITS
> +  #error TARGET_ADDRESS_BITS must be defined for current file
> + #endif
> +#endif /* COMPILING_PER_TARGET */
> +
> +#if TARGET_ADDRESS_BITS != 32 && TARGET_ADDRESS_BITS != 64
> + #error TARGET_ADDRESS_BITS must be 32 or 64
> +#endif
> +
> +#endif /* TCG_OP_ADDRESS_BITS */
> diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
> index b0a81ad4bf4..422a270b694 100644
> --- a/include/tcg/tcg-op-gvec.h
> +++ b/include/tcg/tcg-op-gvec.h
> @@ -8,13 +8,10 @@
>   #ifndef TCG_TCG_OP_GVEC_H
>   #define TCG_TCG_OP_GVEC_H
>   
> +#include "tcg/tcg-op-address-bits.h"
>   #include "tcg/tcg-op-gvec-common.h"
>   
> -#ifndef TARGET_LONG_BITS
> -#error must include QEMU headers
> -#endif
> -
> -#if TARGET_LONG_BITS == 64
> +#if TARGET_ADDRESS_BITS == 64
>   #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i64
>   #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i64
>   #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i64
> @@ -28,7 +25,7 @@
>   #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i64
>   #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i64
>   #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i64
> -#elif TARGET_LONG_BITS == 32
> +#elif TARGET_ADDRESS_BITS == 32
>   #define tcg_gen_gvec_dup_tl  tcg_gen_gvec_dup_i32
>   #define tcg_gen_vec_add8_tl  tcg_gen_vec_add8_i32
>   #define tcg_gen_vec_sub8_tl  tcg_gen_vec_sub8_i32
> @@ -42,8 +39,6 @@
>   #define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i32
>   #define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i32
>   #define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i32
> -#else
> -# error
>   #endif
>   
>   #endif
> diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
> index bf76749d1c5..9e4e58a2d4b 100644
> --- a/include/tcg/tcg-op.h
> +++ b/include/tcg/tcg-op.h
> @@ -8,20 +8,14 @@
>   #ifndef TCG_TCG_OP_H
>   #define TCG_TCG_OP_H
>   
> +#include "tcg/tcg-op-address-bits.h"
>   #include "tcg/tcg-op-common.h"
>   #include "tcg/insn-start-words.h"
> -#include "exec/target_long.h"
>   
> -#ifndef TARGET_LONG_BITS
> -#error must include QEMU headers
> -#endif
> -
> -#if TARGET_LONG_BITS == 32
> +#if TARGET_ADDRESS_BITS == 32
>   # define TCG_TYPE_TL  TCG_TYPE_I32
> -#elif TARGET_LONG_BITS == 64
> +#elif TARGET_ADDRESS_BITS == 64
>   # define TCG_TYPE_TL  TCG_TYPE_I64
> -#else
> -# error
>   #endif
>   
>   #if INSN_START_WORDS != 3
> @@ -56,22 +50,20 @@ static inline void tcg_gen_insn_start2(uint64_t pc, uint64_t a1,
>       tcg_set_insn_start_param(op, 2, a2);
>   }
>   
> -#if TARGET_LONG_BITS == 32
> +#if TARGET_ADDRESS_BITS == 32
>   typedef TCGv_i32 TCGv;
>   #define tcg_temp_new() tcg_temp_new_i32()
>   #define tcg_global_mem_new tcg_global_mem_new_i32
>   #define tcgv_tl_temp tcgv_i32_temp
>   #define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
>   #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
> -#elif TARGET_LONG_BITS == 64
> +#elif TARGET_ADDRESS_BITS == 64
>   typedef TCGv_i64 TCGv;
>   #define tcg_temp_new() tcg_temp_new_i64()
>   #define tcg_global_mem_new tcg_global_mem_new_i64
>   #define tcgv_tl_temp tcgv_i64_temp
>   #define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i64
>   #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i64
> -#else
> -#error Unhandled TARGET_LONG_BITS value
>   #endif
>   
>   static inline void
> @@ -171,7 +163,7 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
>   #undef DEF_ATOMIC2
>   #undef DEF_ATOMIC3
>   
> -#if TARGET_LONG_BITS == 64
> +#if TARGET_ADDRESS_BITS == 64
>   #define tcg_gen_movi_tl tcg_gen_movi_i64
>   #define tcg_gen_mov_tl tcg_gen_mov_i64
>   #define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
> @@ -419,5 +411,5 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
>           : (qemu_build_not_reached_always(), 0))                    \
>        :  (target_long)dup_const(VECE, C))
>   
> -#endif /* TARGET_LONG_BITS == 64 */
> +#endif /* TARGET_ADDRESS_BITS == 64 */
>   #endif /* TCG_TCG_OP_H */
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Richard Henderson 1 month ago
On 1/10/26 02:36, Paolo Bonzini wrote:
> 
> And as a final third step, TCG should excise "_tl" definitions altogether if "!defined 
> TARGET_LONG_BITS".  For targets that want to use exclusively TCGv_{i32,i64,addr}, this 
> lets them stop including exec/target_longNN.h.

FWIW, this is why tcg-op-common.h exists, for TCGv_{i32,i64} without TCGv and *_tl.
The tcg-op.h helper is "legacy" for the 100% of targets that still use it.

The new tcg-op-common.h is currently only used in specific cases, like plugins.


r~

Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Pierrick Bouvier 1 month ago
On 1/9/26 7:36 AM, Paolo Bonzini wrote:
> On 1/9/26 06:31, Pierrick Bouvier wrote:
>> This define will be used to replace TARGET_LONG_BITS in tcg-op-*
>> headers. The goal here is to allow a compilation unit to set explicitely
>> which variant of the arch it's targeting (32 vs 64 bits).
>>
>> By default, we simple let it defined as TARGET_LONG_BITS, so existing
>> code does not need to be changed, and we can progressively convert new
>> files.
>>
>> target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
>> some TARGET_AARCH64 defines). For other arch, this is a work that will
>> have to be done before converting them.
> 
> ARM is pretty special in this regard because it has separate registers
> arrays regs[] and xregs[].  The other five multi-size targets (i386,
> mips, ppc, riscv, sparc) probably will *not* use target_common_arch as
> much as ARM is doing, and will keep support two TCG _tl sizes: 32 for
> the 32-bit single-target binaries, 64 for the 64-bit single-target
> binaries and for the single multi-target binary.
>

That's a point we raised when talking about it with Richard. Indeed, 
some other arch will require further changes.

> For them, the death of target_long/target_ulong is not really possible,
> because they will have to reinvent include/exec/target_long.h for their
> CPUStates.
>

At this time, I don't have a simple solution to provide to workaround 
this. As long as compilation units are duplicated, you will have 
duplicated symbols for any extern symbol, thus preventing to link the 
final qemu-system binary. So duplication has to be eliminated, one way 
or another. And multiple type definitions is a barrier for this.

Any good idea is welcome.

> For the sake of this series, I would rename TARGET_ADDRESS_BITS to
> TCG_ADDRESS_BITS, add to include/tcg/tcg-op.h something like:
> 
> #if TCG_ADDRESS_BITS == 32
> typedef TCGv_i32 TCGv_addr;
> #define tcg_temp_new_addr() tcg_temp_new_i32()
> #define tcg_global_mem_new_addr tcg_global_mem_new_i32
> #define tcgv_addr_temp tcgv_i32_temp
> #define tcg_gen_qemu_ld_addr tcg_gen_qemu_ld_i32
> #define tcg_gen_qemu_st_addr tcg_gen_qemu_st_i32
> #elif TCG_ADDRESS_BITS == 64
> typedef TCGv_i64 TCGv_addr;
> #define tcg_temp_new_addr() tcg_temp_new_i64()
> #define tcg_global_mem_new_addr tcg_global_mem_new_i64
> #define tcgv_addr_temp tcgv_i64_temp
> #define tcg_gen_qemu_ld_addr tcg_gen_qemu_ld_i64
> #define tcg_gen_qemu_st_addr tcg_gen_qemu_st_i64
> #else
> #error Unhandled TARGET_LONG_BITS value
> #endif
> 
> and use TCGv_addr in tcg_gen_qemu_ld_i32 and friends.  This first step
> clearly separates (at least in the long run) target_long from TCG addresses.
>

Richard suggested to extract memory operations, of the rest, as you're 
suggesting now. So I'll do this for next version, and rename the define 
as well.

>   From the point of view of this is all I would like to see:
> TARGET_ADDRESS_BITS renamed to TCG_ADDRESS_BITS, and TCGv_addr
> introduced in include/tcg/tcg-op.h and tcg/tcg-op-ldst.c at the same
> time as TCG_ADDRESS_BITS.
> 
> In the rest of the message I'm going to describe why and what more I
> envision.
> 
> In the long run TCGv and _tl can become entirely optional, leaving the
> door open for single-size targets to use TCGv_{i32,i64,addr}
> exclusively.  For this reason, the second step (independent of this
> series) is for single-size targets, who have already mostly moved
> towards removing target_long, to remove TARGET_LONG_BITS from
> configs/targets/ altogether.  To this end I would create two files like
> this:
>

By making all files for an architecture "common", TARGET_LONG_BITS is 
eliminated by design, since it's a poisoned identifier.

> include/exec/target_long32.h
> ----------------------------
> #ifndef TARGET_LONG_BITS
> #define TARGET_LONG_BITS 32
> #endif
> #define TARGET_ADDRESS_BITS 32
> #define TARGET_LONG_SIZE 4
> typedef int32_t target_long;
> typedef uint32_t target_ulong;
> #define TARGET_FMT_lx "%08x"
> #define TARGET_FMT_ld "%d"
> #define TARGET_FMT_lu "%u"
> #define MO_TL MO_32
> 
> include/exec/target_long64.h
> ----------------------------
> #ifndef TARGET_LONG_BITS
> #define TARGET_LONG_BITS 64
> #endif
> #define TARGET_ADDRESS_BITS 64
> #define TARGET_LONG_SIZE 8
> typedef int64_t target_long;
> typedef uint64_t target_ulong;
> #define TARGET_FMT_lx "%016" PRIx64
> #define TARGET_FMT_ld "%" PRId64
> #define TARGET_FMT_lu "%" PRIu64
> #define MO_TL MO_64
> 
> ... and use them in include/exec/target_long.h:
> 
> include/exec/target_long.h:
> #ifndef TARGET_LONG_BITS
> #error TARGET_LONG_BITS not defined
> #elif TARGET_LONG_BITS == 32
> #include "exec/target_long32.h"
> #elif TARGET_LONG_BITS == 64
> #include "exec/target_long64.h"
> #endif
> 
> Then the single-size targets can replace TARGET_LONG_BITS with:
> - a "#define TCG_ADDRESS_BITS" in their translate.c
> - a #include "exec/target_longNN.h" in their cpu.h.
> 
> Dual-size targets, instead, can add to their cpu.h an initial stanza
> like this:
> 
> #ifdef TARGET_I386
> #include "exec/target_long32.h"
> #else
> #include "exec/target_long64.h" // x86_64 or single binary
> #endif
> 
> and keep using target_long.
>

I'm not sure what we gain from this header mechanics, wouldn't that be 
better to eradicate TARGET_LONG_BITS completely instead?

With Philippe, we introduced target-info.h, to precisely find this 
information at runtime, with target_long_bits().
As well, as you can see in codebase, target_long_bits() is not used in 
many places, and especially, it's not needed anywhere in target/arm. So 
it does not seem needed to keep it alive.

Thanks for the feedback,
Pierrick
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Paolo Bonzini 1 month ago
Il ven 9 gen 2026, 17:21 Pierrick Bouvier <pierrick.bouvier@linaro.org> ha
scritto:

> > For them, the death of target_long/target_ulong is not really possible,
> > because they will have to reinvent include/exec/target_long.h for their
> > CPUStates.
> >
>
> At this time, I don't have a simple solution to provide to workaround
> this. As long as compilation units are duplicated, you will have
> duplicated symbols for any extern symbol, thus preventing to link the
> final qemu-system binary. So duplication has to be eliminated, one way
> or another. And multiple type definitions is a barrier for this.
>

Yes, the idea is that if the "single binary" will include both i386 and
x86_64 targets, they will both use the TARGET_LONG_BITS==64 version (using
it also for the 32-bit target) of CPUState, of the TCG frontend and
helpers, etc.

IOW the single binary could build a third copy of target/i386, or reuse the
x86_64-softmmu one.

By making all files for an architecture "common", TARGET_LONG_BITS is
> eliminated by design, since it's a poisoned identifier.
>

Good point.

> include/exec/target_long32.h
> > ----------------------------
> > #ifndef TARGET_LONG_BITS
> > #define TARGET_LONG_BITS 32
> > #endif
> > #define TARGET_ADDRESS_BITS 32
> > #define TARGET_LONG_SIZE 4
> > typedef int32_t target_long;
> > typedef uint32_t target_ulong;
> > #define TARGET_FMT_lx "%08x"
> > #define TARGET_FMT_ld "%d"
> > #define TARGET_FMT_lu "%u"
> > #define MO_TL MO_32
> >
> > include/exec/target_long64.h
> > ----------------------------
> > #ifndef TARGET_LONG_BITS
> > #define TARGET_LONG_BITS 64
> > #endif
> > #define TARGET_ADDRESS_BITS 64
> > #define TARGET_LONG_SIZE 8
> > typedef int64_t target_long;
> > typedef uint64_t target_ulong;
> > #define TARGET_FMT_lx "%016" PRIx64
> > #define TARGET_FMT_ld "%" PRId64
> > #define TARGET_FMT_lu "%" PRIu64
> > #define MO_TL MO_64
> >
> > ... and use them in include/exec/target_long.h:
> >
> > include/exec/target_long.h:
> > #ifndef TARGET_LONG_BITS
> > #error TARGET_LONG_BITS not defined
> > #elif TARGET_LONG_BITS == 32
> > #include "exec/target_long32.h"
> > #elif TARGET_LONG_BITS == 64
> > #include "exec/target_long64.h"
> > #endif
> >
> > Then the single-size targets can replace TARGET_LONG_BITS with:
> > - a "#define TCG_ADDRESS_BITS" in their translate.c
> > - a #include "exec/target_longNN.h" in their cpu.h.
> >
> > Dual-size targets, instead, can add to their cpu.h an initial stanza
> > like this:
> >
> > #ifdef TARGET_I386
> > #include "exec/target_long32.h"
> > #else
> > #include "exec/target_long64.h" // x86_64 or single binary
> > #endif
> >
> > and keep using target_long.
> >
>
> I'm not sure what we gain from this header mechanics, wouldn't that be
> better to eradicate TARGET_LONG_BITS completely instead?
>

The problem is that dropping target_long in CPUState would be inefficient.
For example i386 registers occupy 32 bytes vs. 256 for x86_64. So I would
like to keep 32-bit registers for the 32-bit single-target binary.

Compared to the current mechanism, it decouples the choice of
TARGET_LONG_BITS from configs/targets/ and makes it possible for target/*/
to pick its preferred length when built for the single binary.

But anyway this was just a brain dump—we are in sync for what is needed for
this series.

With Philippe, we introduced target-info.h, to precisely find this
> information at runtime, with target_long_bits().
> As well, as you can see in codebase, target_long_bits() is not used in
> many places, and especially, it's not needed anywhere in target/arm. So
> it does not seem needed to keep it alive.
>

I agree that target_long_bits() should be needed almost nowhere (maybe it's
needed for VMSTATE_UINTTL migration but not much else) because ideally all
use of target_long/ulong would really be confined to target/ and not be in
common code.

It could be called like an x86_ulong, but it would have to be redone almost
the same across all the dual-size targets, hence it's easier to keep the
current name and provide a common mechanism.

Thanks,

Paolo

Thanks for the feedback,
> Pierrick
>
>
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Pierrick Bouvier 1 month ago
On 1/9/26 9:42 AM, Paolo Bonzini wrote:
> 
> 
> Il ven 9 gen 2026, 17:21 Pierrick Bouvier <pierrick.bouvier@linaro.org 
> <mailto:pierrick.bouvier@linaro.org>> ha scritto:
> 
>      > For them, the death of target_long/target_ulong is not really
>     possible,
>      > because they will have to reinvent include/exec/target_long.h for
>     their
>      > CPUStates.
>      >
> 
>     At this time, I don't have a simple solution to provide to workaround
>     this. As long as compilation units are duplicated, you will have
>     duplicated symbols for any extern symbol, thus preventing to link the
>     final qemu-system binary. So duplication has to be eliminated, one way
>     or another. And multiple type definitions is a barrier for this.
> 
> 
> Yes, the idea is that if the "single binary" will include both i386 and 
> x86_64 targets, they will both use the TARGET_LONG_BITS==64 version 
> (using it also for the 32-bit target) of CPUState, of the TCG frontend 
> and helpers, etc.
> 
> IOW the single binary could build a third copy of target/i386, or reuse 
> the x86_64-softmmu one.
> 
>     By making all files for an architecture "common", TARGET_LONG_BITS is
>     eliminated by design, since it's a poisoned identifier.
> 
> 
> Good point.
> 
>      > include/exec/target_long32.h
>      > ----------------------------
>      > #ifndef TARGET_LONG_BITS
>      > #define TARGET_LONG_BITS 32
>      > #endif
>      > #define TARGET_ADDRESS_BITS 32
>      > #define TARGET_LONG_SIZE 4
>      > typedef int32_t target_long;
>      > typedef uint32_t target_ulong;
>      > #define TARGET_FMT_lx "%08x"
>      > #define TARGET_FMT_ld "%d"
>      > #define TARGET_FMT_lu "%u"
>      > #define MO_TL MO_32
>      >
>      > include/exec/target_long64.h
>      > ----------------------------
>      > #ifndef TARGET_LONG_BITS
>      > #define TARGET_LONG_BITS 64
>      > #endif
>      > #define TARGET_ADDRESS_BITS 64
>      > #define TARGET_LONG_SIZE 8
>      > typedef int64_t target_long;
>      > typedef uint64_t target_ulong;
>      > #define TARGET_FMT_lx "%016" PRIx64
>      > #define TARGET_FMT_ld "%" PRId64
>      > #define TARGET_FMT_lu "%" PRIu64
>      > #define MO_TL MO_64
>      >
>      > ... and use them in include/exec/target_long.h:
>      >
>      > include/exec/target_long.h:
>      > #ifndef TARGET_LONG_BITS
>      > #error TARGET_LONG_BITS not defined
>      > #elif TARGET_LONG_BITS == 32
>      > #include "exec/target_long32.h"
>      > #elif TARGET_LONG_BITS == 64
>      > #include "exec/target_long64.h"
>      > #endif
>      >
>      > Then the single-size targets can replace TARGET_LONG_BITS with:
>      > - a "#define TCG_ADDRESS_BITS" in their translate.c
>      > - a #include "exec/target_longNN.h" in their cpu.h.
>      >
>      > Dual-size targets, instead, can add to their cpu.h an initial stanza
>      > like this:
>      >
>      > #ifdef TARGET_I386
>      > #include "exec/target_long32.h"
>      > #else
>      > #include "exec/target_long64.h" // x86_64 or single binary
>      > #endif
>      >
>      > and keep using target_long.
>      >
> 
>     I'm not sure what we gain from this header mechanics, wouldn't that be
>     better to eradicate TARGET_LONG_BITS completely instead?
> 
> 
> The problem is that dropping target_long in CPUState would be 
> inefficient. For example i386 registers occupy 32 bytes vs. 256 for 
> x86_64. So I would like to keep 32-bit registers for the 32-bit single- 
> target binary.
>

I agree, and that's why the current solution is not the final word on 
this question. My position on the single binary is that runtime 
compromises can be acceptable on our translation path (since it's not 
where we spend most of our time anyway), but definitely not on code 
generated by tcg, which has to be optimal.

In the first version of this series, I defined TCGv as an opaque type 
(i.e. not typedef to i32 or i64), and wrote wrappers for tcg_gen_* ops 
that were casting it to appropriate type and called the i32 or i64 
variants based on current context. After talking with Richard, I 
understood it was not useful for target/arm, since code has been cleanly 
splitted between 32/64 bits, so dropped it for the TCG_ADDRESS_BITS 
approach.

That said, I still think the opaque type + wrapper approach has its 
place for some architectures. It could be used for code where rewriting 
is too complicated, and still allow to generate efficient code. The 
downside is that we need some boilerplate in headers to generate this, 
but it's not something a macro can't help to deal with.

> Compared to the current mechanism, it decouples the choice of 
> TARGET_LONG_BITS from configs/targets/ and makes it possible for target/ 
> */ to pick its preferred length when built for the single binary.
> 
> But anyway this was just a brain dump—we are in sync for what is needed 
> for this series.
> 
>     With Philippe, we introduced target-info.h, to precisely find this
>     information at runtime, with target_long_bits().
>     As well, as you can see in codebase, target_long_bits() is not used in
>     many places, and especially, it's not needed anywhere in target/arm. So
>     it does not seem needed to keep it alive.
> 
> 
> I agree that target_long_bits() should be needed almost nowhere (maybe 
> it's needed for VMSTATE_UINTTL migration but not much else) because 
> ideally all use of target_long/ulong would really be confined to target/ 
> and not be in common code.
> 
> It could be called like an x86_ulong, but it would have to be redone 
> almost the same across all the dual-size targets, hence it's easier to 
> keep the current name and provide a common mechanism.
> 
> Thanks,
> 
> Paolo
> 
>     Thanks for the feedback,
>     Pierrick
> 


Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Paolo Bonzini 1 month ago
Il ven 9 gen 2026, 19:35 Pierrick Bouvier <pierrick.bouvier@linaro.org> ha
scritto:

> > The problem is that dropping target_long in CPUState would be
> > inefficient. For example i386 registers occupy 32 bytes vs. 256 for
> > x86_64. So I would like to keep 32-bit registers for the 32-bit single-
> > target binary.
> >
>
> I agree, and that's why the current solution is not the final word on
> this question. My position on the single binary is that runtime
> compromises can be acceptable on our translation path (since it's not
> where we spend most of our time anyway), but definitely not on code
> generated by tcg, which has to be optimal.
>

I think it's not that absolute for dual-size targets. For x86 I would be
okay if the i386 target used essentially the x86-64 CPUState and frontend
when compiled as part of the single binary, despite the extra space used by
registers. The only difference would be that the  64-bit CPU models are not
available (or their long-mode feature flag is masked) and therefore
entering 64-bit mode is not possible.

Anyhow, it's all food for later thought. But it explains why my first idea
was to isolate TARGET_LONG_BITS and yours was to abstract it.

Paolo


> In the first version of this series, I defined TCGv as an opaque type
> (i.e. not typedef to i32 or i64), and wrote wrappers for tcg_gen_* ops
> that were casting it to appropriate type and called the i32 or i64
> variants based on current context. After talking with Richard, I
> understood it was not useful for target/arm, since code has been cleanly
> splitted between 32/64 bits, so dropped it for the TCG_ADDRESS_BITS
> approach.
>
> That said, I still think the opaque type + wrapper approach has its
> place for some architectures. It could be used for code where rewriting
> is too complicated, and still allow to generate efficient code. The
> downside is that we need some boilerplate in headers to generate this,
> but it's not something a macro can't help to deal with.
>
> > Compared to the current mechanism, it decouples the choice of
> > TARGET_LONG_BITS from configs/targets/ and makes it possible for target/
> > */ to pick its preferred length when built for the single binary.
> >
> > But anyway this was just a brain dump—we are in sync for what is needed
> > for this series.
> >
> >     With Philippe, we introduced target-info.h, to precisely find this
> >     information at runtime, with target_long_bits().
> >     As well, as you can see in codebase, target_long_bits() is not used
> in
> >     many places, and especially, it's not needed anywhere in target/arm.
> So
> >     it does not seem needed to keep it alive.
> >
> >
> > I agree that target_long_bits() should be needed almost nowhere (maybe
> > it's needed for VMSTATE_UINTTL migration but not much else) because
> > ideally all use of target_long/ulong would really be confined to target/
> > and not be in common code.
> >
> > It could be called like an x86_ulong, but it would have to be redone
> > almost the same across all the dual-size targets, hence it's easier to
> > keep the current name and provide a common mechanism.
> >
> > Thanks,
> >
> > Paolo
> >
> >     Thanks for the feedback,
> >     Pierrick
> >
>
>
Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Philippe Mathieu-Daudé 1 month ago
On 9/1/26 06:31, Pierrick Bouvier wrote:
> This define will be used to replace TARGET_LONG_BITS in tcg-op-*
> headers. The goal here is to allow a compilation unit to set explicitely
> which variant of the arch it's targeting (32 vs 64 bits).
> 
> By default, we simple let it defined as TARGET_LONG_BITS, so existing
> code does not need to be changed, and we can progressively convert new
> files.
> 
> target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
> some TARGET_AARCH64 defines). For other arch, this is a work that will
> have to be done before converting them.
> 
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
>   include/tcg/tcg-op-address-bits.h | 21 +++++++++++++++++++++
>   include/tcg/tcg-op-gvec.h         | 11 +++--------
>   include/tcg/tcg-op.h              | 22 +++++++---------------
>   3 files changed, 31 insertions(+), 23 deletions(-)
>   create mode 100644 include/tcg/tcg-op-address-bits.h

Nice.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


Re: [PATCH 14/29] include/tcg/tcg-op.h: introduce TARGET_ADDRESS_BITS
Posted by Pierrick Bouvier 1 month ago
On 1/9/26 12:02 AM, Philippe Mathieu-Daudé wrote:
> On 9/1/26 06:31, Pierrick Bouvier wrote:
>> This define will be used to replace TARGET_LONG_BITS in tcg-op-*
>> headers. The goal here is to allow a compilation unit to set explicitely
>> which variant of the arch it's targeting (32 vs 64 bits).
>>
>> By default, we simple let it defined as TARGET_LONG_BITS, so existing
>> code does not need to be changed, and we can progressively convert new
>> files.
>>
>> target/arm/tcg/* files are cleanly splitted between 32 and 64 bits (with
>> some TARGET_AARCH64 defines). For other arch, this is a work that will
>> have to be done before converting them.
>>
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>>    include/tcg/tcg-op-address-bits.h | 21 +++++++++++++++++++++
>>    include/tcg/tcg-op-gvec.h         | 11 +++--------
>>    include/tcg/tcg-op.h              | 22 +++++++---------------
>>    3 files changed, 31 insertions(+), 23 deletions(-)
>>    create mode 100644 include/tcg/tcg-op-address-bits.h
> 
> Nice.
>

You can say thanks to our Richard here :).

> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>