[PATCH 13/29] include/tcg/tcg-op.h: eradicate TARGET_INSN_START_EXTRA_WORDS

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 13/29] include/tcg/tcg-op.h: eradicate TARGET_INSN_START_EXTRA_WORDS
Posted by Pierrick Bouvier 1 month ago
We simply define the 3 variants and call the correct one per arch.
Since all arch have a single call site (in translate.c), this is as
good documentation as having a single define.

The notable exception is target/arm, which has two different translate
files for 32/64 bits. Since it's the only one, we accept to have two
call sites for this.

This is much simpler and safer than trying to define a common functions
with variadic or unused parameters. The only risk is calling two
different variants for a single arch, but as mentioned in first
paragraph, there is no real reason for this to happen.

Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
 include/tcg/tcg-op.h             | 16 ++++++----------
 target/alpha/cpu-param.h         |  2 --
 target/arm/cpu-param.h           |  7 -------
 target/avr/cpu-param.h           |  2 --
 target/hexagon/cpu-param.h       |  2 --
 target/hppa/cpu-param.h          |  2 --
 target/i386/cpu-param.h          |  2 --
 target/loongarch/cpu-param.h     |  2 --
 target/m68k/cpu-param.h          |  2 --
 target/microblaze/cpu-param.h    |  2 --
 target/mips/cpu-param.h          |  2 --
 target/openrisc/cpu-param.h      |  2 --
 target/ppc/cpu-param.h           |  2 --
 target/riscv/cpu-param.h         |  7 -------
 target/rx/cpu-param.h            |  2 --
 target/s390x/cpu-param.h         |  2 --
 target/sh4/cpu-param.h           |  2 --
 target/sparc/cpu-param.h         |  2 --
 target/tricore/cpu-param.h       |  2 --
 target/xtensa/cpu-param.h        |  2 --
 target/alpha/translate.c         |  4 ++--
 target/arm/tcg/translate-a64.c   |  2 +-
 target/arm/tcg/translate.c       |  2 +-
 target/avr/translate.c           |  2 +-
 target/hexagon/translate.c       |  2 +-
 target/hppa/translate.c          |  2 +-
 target/i386/tcg/translate.c      |  2 +-
 target/loongarch/tcg/translate.c |  2 +-
 target/m68k/translate.c          |  2 +-
 target/microblaze/translate.c    |  2 +-
 target/mips/tcg/translate.c      |  4 ++--
 target/openrisc/translate.c      |  4 ++--
 target/ppc/translate.c           |  2 +-
 target/riscv/translate.c         |  2 +-
 target/rx/translate.c            |  2 +-
 target/s390x/tcg/translate.c     |  2 +-
 target/sh4/translate.c           |  4 ++--
 target/sparc/translate.c         |  2 +-
 target/tricore/translate.c       |  2 +-
 target/xtensa/translate.c        |  2 +-
 40 files changed, 30 insertions(+), 82 deletions(-)

diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index f3fe2d9386a..bf76749d1c5 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -28,8 +28,7 @@
 # error Mismatch with insn-start-words.h
 #endif
 
-#if TARGET_INSN_START_EXTRA_WORDS == 0
-static inline void tcg_gen_insn_start(uint64_t pc)
+static inline void tcg_gen_insn_start0(uint64_t pc)
 {
     TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
                             INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
@@ -37,8 +36,8 @@ static inline void tcg_gen_insn_start(uint64_t pc)
     tcg_set_insn_start_param(op, 1, 0);
     tcg_set_insn_start_param(op, 2, 0);
 }
-#elif TARGET_INSN_START_EXTRA_WORDS == 1
-static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1)
+
+static inline void tcg_gen_insn_start1(uint64_t pc, uint64_t a1)
 {
     TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
                             INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
@@ -46,9 +45,9 @@ static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1)
     tcg_set_insn_start_param(op, 1, a1);
     tcg_set_insn_start_param(op, 2, 0);
 }
-#elif TARGET_INSN_START_EXTRA_WORDS == 2
-static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1,
-                                      uint64_t a2)
+
+static inline void tcg_gen_insn_start2(uint64_t pc, uint64_t a1,
+                                       uint64_t a2)
 {
     TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
                             INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
@@ -56,9 +55,6 @@ static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1,
     tcg_set_insn_start_param(op, 1, a1);
     tcg_set_insn_start_param(op, 2, a2);
 }
-#else
-#error Unhandled TARGET_INSN_START_EXTRA_WORDS value
-#endif
 
 #if TARGET_LONG_BITS == 32
 typedef TCGv_i32 TCGv;
diff --git a/target/alpha/cpu-param.h b/target/alpha/cpu-param.h
index a799f42db31..c9da620ab3e 100644
--- a/target/alpha/cpu-param.h
+++ b/target/alpha/cpu-param.h
@@ -24,6 +24,4 @@
 # define TARGET_VIRT_ADDR_SPACE_BITS  (30 + TARGET_PAGE_BITS)
 #endif
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 8b46c7c5708..7de0099cbfa 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -32,11 +32,4 @@
 # define TARGET_PAGE_BITS_LEGACY 10
 #endif /* !CONFIG_USER_ONLY */
 
-/*
- * ARM-specific extra insn start words:
- * 1: Conditional execution bits
- * 2: Partial exception syndrome for data aborts
- */
-#define TARGET_INSN_START_EXTRA_WORDS 2
-
 #endif
diff --git a/target/avr/cpu-param.h b/target/avr/cpu-param.h
index f74bfc25804..ea7887919a7 100644
--- a/target/avr/cpu-param.h
+++ b/target/avr/cpu-param.h
@@ -25,6 +25,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 24
 #define TARGET_VIRT_ADDR_SPACE_BITS 24
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/hexagon/cpu-param.h b/target/hexagon/cpu-param.h
index 635d509e743..45ee7b46409 100644
--- a/target/hexagon/cpu-param.h
+++ b/target/hexagon/cpu-param.h
@@ -23,6 +23,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 36
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h
index 9bf7ac76d0c..e0b2c7c9157 100644
--- a/target/hppa/cpu-param.h
+++ b/target/hppa/cpu-param.h
@@ -19,6 +19,4 @@
 
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_INSN_START_EXTRA_WORDS 2
-
 #endif
diff --git a/target/i386/cpu-param.h b/target/i386/cpu-param.h
index ebb844bcc83..909bc027923 100644
--- a/target/i386/cpu-param.h
+++ b/target/i386/cpu-param.h
@@ -22,6 +22,4 @@
 #endif
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
 #endif
diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
index 58cc45a377e..071567712b3 100644
--- a/target/loongarch/cpu-param.h
+++ b/target/loongarch/cpu-param.h
@@ -13,6 +13,4 @@
 
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/m68k/cpu-param.h b/target/m68k/cpu-param.h
index 256a2b5f8b2..7afbf6d302d 100644
--- a/target/m68k/cpu-param.h
+++ b/target/m68k/cpu-param.h
@@ -17,6 +17,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
 #endif
diff --git a/target/microblaze/cpu-param.h b/target/microblaze/cpu-param.h
index e0a37945136..6a0714bb3d7 100644
--- a/target/microblaze/cpu-param.h
+++ b/target/microblaze/cpu-param.h
@@ -27,6 +27,4 @@
 /* FIXME: MB uses variable pages down to 1K but linux only uses 4k.  */
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
 #endif
diff --git a/target/mips/cpu-param.h b/target/mips/cpu-param.h
index 58f450827f7..a71e7383d24 100644
--- a/target/mips/cpu-param.h
+++ b/target/mips/cpu-param.h
@@ -20,6 +20,4 @@
 #endif
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_INSN_START_EXTRA_WORDS 2
-
 #endif
diff --git a/target/openrisc/cpu-param.h b/target/openrisc/cpu-param.h
index b4f57bbe692..3011bf5fcca 100644
--- a/target/openrisc/cpu-param.h
+++ b/target/openrisc/cpu-param.h
@@ -12,6 +12,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
 #endif
diff --git a/target/ppc/cpu-param.h b/target/ppc/cpu-param.h
index e4ed9080ee9..ca7602d8983 100644
--- a/target/ppc/cpu-param.h
+++ b/target/ppc/cpu-param.h
@@ -37,6 +37,4 @@
 # define TARGET_PAGE_BITS 12
 #endif
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h
index cfdc67c258c..039e877891a 100644
--- a/target/riscv/cpu-param.h
+++ b/target/riscv/cpu-param.h
@@ -17,13 +17,6 @@
 #endif
 #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
 
-/*
- * RISC-V-specific extra insn start words:
- * 1: Original instruction opcode
- * 2: more information about instruction
- */
-#define TARGET_INSN_START_EXTRA_WORDS 2
-
 /*
  * The current MMU Modes are:
  *  - U mode 0b000
diff --git a/target/rx/cpu-param.h b/target/rx/cpu-param.h
index 84934f3bcaf..ef1970a09e9 100644
--- a/target/rx/cpu-param.h
+++ b/target/rx/cpu-param.h
@@ -24,6 +24,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/s390x/cpu-param.h b/target/s390x/cpu-param.h
index abfae3bedfb..a5f798eeae7 100644
--- a/target/s390x/cpu-param.h
+++ b/target/s390x/cpu-param.h
@@ -12,6 +12,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 64
 #define TARGET_VIRT_ADDR_SPACE_BITS 64
 
-#define TARGET_INSN_START_EXTRA_WORDS 2
-
 #endif
diff --git a/target/sh4/cpu-param.h b/target/sh4/cpu-param.h
index f328715ee86..2b6e11dd0ac 100644
--- a/target/sh4/cpu-param.h
+++ b/target/sh4/cpu-param.h
@@ -16,6 +16,4 @@
 # define TARGET_VIRT_ADDR_SPACE_BITS 32
 #endif
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
 #endif
diff --git a/target/sparc/cpu-param.h b/target/sparc/cpu-param.h
index 45eea9d6bac..6e8e2a51469 100644
--- a/target/sparc/cpu-param.h
+++ b/target/sparc/cpu-param.h
@@ -21,6 +21,4 @@
 # define TARGET_VIRT_ADDR_SPACE_BITS 32
 #endif
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
 #endif
diff --git a/target/tricore/cpu-param.h b/target/tricore/cpu-param.h
index eb33a67c419..790242ef3d2 100644
--- a/target/tricore/cpu-param.h
+++ b/target/tricore/cpu-param.h
@@ -12,6 +12,4 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/xtensa/cpu-param.h b/target/xtensa/cpu-param.h
index 7a0c22c9005..06d85218b84 100644
--- a/target/xtensa/cpu-param.h
+++ b/target/xtensa/cpu-param.h
@@ -16,6 +16,4 @@
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 #endif
 
-#define TARGET_INSN_START_EXTRA_WORDS 0
-
 #endif
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index b1d8a4eb80a..75808795e52 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2895,9 +2895,9 @@ static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
     if (ctx->pcrel) {
-        tcg_gen_insn_start(dcbase->pc_next & ~TARGET_PAGE_MASK);
+        tcg_gen_insn_start0(dcbase->pc_next & ~TARGET_PAGE_MASK);
     } else {
-        tcg_gen_insn_start(dcbase->pc_next);
+        tcg_gen_insn_start0(dcbase->pc_next);
     }
 }
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index b066da37891..b7a8e94b937 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -10764,7 +10764,7 @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
     if (tb_cflags(dcbase->tb) & CF_PCREL) {
         pc_arg &= ~TARGET_PAGE_MASK;
     }
-    tcg_gen_insn_start(pc_arg, 0, 0);
+    tcg_gen_insn_start2(pc_arg, 0, 0);
     dc->insn_start_updated = false;
 }
 
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 79b111a228b..5c496f42c55 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -6453,7 +6453,7 @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
     } else {
         condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
     }
-    tcg_gen_insn_start(pc_arg, condexec_bits, 0);
+    tcg_gen_insn_start2(pc_arg, condexec_bits, 0);
     dc->insn_start_updated = false;
 }
 
diff --git a/target/avr/translate.c b/target/avr/translate.c
index ef6f655a458..29de249342e 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2689,7 +2689,7 @@ static void avr_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->npc);
+    tcg_gen_insn_start0(ctx->npc);
 }
 
 static void avr_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 3762faec4d8..c61ddc85b6f 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -977,7 +977,7 @@ static void hexagon_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->base.pc_next);
+    tcg_gen_insn_start0(ctx->base.pc_next);
 }
 
 static bool pkt_crosses_page(CPUHexagonState *env, DisasContext *ctx)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 853cba2ba4f..2a9eafacda7 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -4716,7 +4716,7 @@ static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
         tcg_debug_assert(diff != INT32_MIN);
     }
 
-    tcg_gen_insn_start(iaoq_f & ~TARGET_PAGE_MASK, diff, 0);
+    tcg_gen_insn_start2(iaoq_f & ~TARGET_PAGE_MASK, diff, 0);
     ctx->insn_start_updated = false;
 }
 
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 7c444d5006d..207cd541152 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -3527,7 +3527,7 @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
     if (tb_cflags(dcbase->tb) & CF_PCREL) {
         pc_arg &= ~TARGET_PAGE_MASK;
     }
-    tcg_gen_insn_start(pc_arg, dc->cc_op);
+    tcg_gen_insn_start1(pc_arg, dc->cc_op);
 }
 
 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
index 055f6fb6046..120411eda1e 100644
--- a/target/loongarch/tcg/translate.c
+++ b/target/loongarch/tcg/translate.c
@@ -159,7 +159,7 @@ static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->base.pc_next);
+    tcg_gen_insn_start0(ctx->base.pc_next);
 }
 
 /*
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index eb1ba150745..2abcbae879b 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -6028,7 +6028,7 @@ static void m68k_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
 static void m68k_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
-    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
+    tcg_gen_insn_start1(dc->base.pc_next, dc->cc_op);
 }
 
 static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index fefe5cb552a..3407cfbdb1d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1630,7 +1630,7 @@ static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
 {
     DisasContext *dc = container_of(dcb, DisasContext, base);
 
-    tcg_gen_insn_start(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
+    tcg_gen_insn_start1(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
 }
 
 static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 54849e9ff1a..3000e09e241 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -15133,8 +15133,8 @@ static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
-                       ctx->btarget);
+    tcg_gen_insn_start2(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
+                        ctx->btarget);
 }
 
 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 6fa4d6cfa70..7c2d6979bc6 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -1551,8 +1551,8 @@ static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
-                       | (dc->base.num_insns > 1 ? 2 : 0));
+    tcg_gen_insn_start1(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
+                        | (dc->base.num_insns > 1 ? 2 : 0));
 }
 
 static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 17e6d07c8c2..9eca4043daa 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -6574,7 +6574,7 @@ static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs)
 
 static void ppc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
-    tcg_gen_insn_start(dcbase->pc_next);
+    tcg_gen_insn_start0(dcbase->pc_next);
 }
 
 static bool is_prefix_insn(DisasContext *ctx, uint32_t insn)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index e1f4dc5ffd0..da3e6606871 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1351,7 +1351,7 @@ static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
         pc_next &= ~TARGET_PAGE_MASK;
     }
 
-    tcg_gen_insn_start(pc_next, 0, 0);
+    tcg_gen_insn_start2(pc_next, 0, 0);
     ctx->insn_start_updated = false;
 }
 
diff --git a/target/rx/translate.c b/target/rx/translate.c
index ef865f14bf5..1a4ed4de31b 100644
--- a/target/rx/translate.c
+++ b/target/rx/translate.c
@@ -2215,7 +2215,7 @@ static void rx_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->base.pc_next);
+    tcg_gen_insn_start0(ctx->base.pc_next);
 }
 
 static void rx_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index e38607ee18c..111a5e2cb54 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -6402,7 +6402,7 @@ static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
     DisasContext *dc = container_of(dcbase, DisasContext, base);
 
     /* Delay the set of ilen until we've read the insn. */
-    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 0);
+    tcg_gen_insn_start2(dc->base.pc_next, dc->cc_op, 0);
 }
 
 static target_ulong get_next_pc(CPUS390XState *env, DisasContext *s,
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index b3ae0a3814c..78f606f4a4f 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -2181,7 +2181,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
      * tb->icount * insn_start.
      */
     for (i = 1; i < max_insns; ++i) {
-        tcg_gen_insn_start(pc + i * 2, ctx->envflags);
+        tcg_gen_insn_start1(pc + i * 2, ctx->envflags);
         ctx->base.insn_start = tcg_last_op();
     }
 }
@@ -2241,7 +2241,7 @@ static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
+    tcg_gen_insn_start1(ctx->base.pc_next, ctx->envflags);
 }
 
 static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index d6b599b71fe..bca9c7a0c1e 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5735,7 +5735,7 @@ static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
             g_assert_not_reached();
         }
     }
-    tcg_gen_insn_start(dc->pc, npc);
+    tcg_gen_insn_start1(dc->pc, npc);
 }
 
 static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index fbe05a93a8a..cee7fedc9db 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -8410,7 +8410,7 @@ static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
 {
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-    tcg_gen_insn_start(ctx->base.pc_next);
+    tcg_gen_insn_start0(ctx->base.pc_next);
 }
 
 static bool insn_crosses_page(DisasContext *ctx, CPUTriCoreState *env)
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index bb8d2ed86cf..7851a5f0371 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -1159,7 +1159,7 @@ static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
 
 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
 {
-    tcg_gen_insn_start(dcbase->pc_next);
+    tcg_gen_insn_start0(dcbase->pc_next);
 }
 
 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
-- 
2.47.3
Re: [PATCH 13/29] include/tcg/tcg-op.h: eradicate TARGET_INSN_START_EXTRA_WORDS
Posted by Richard Henderson 1 month ago
On 1/9/26 16:31, Pierrick Bouvier wrote:
> We simply define the 3 variants and call the correct one per arch.
> Since all arch have a single call site (in translate.c), this is as
> good documentation as having a single define.
> 
> The notable exception is target/arm, which has two different translate
> files for 32/64 bits. Since it's the only one, we accept to have two
> call sites for this.
> 
> This is much simpler and safer than trying to define a common functions
> with variadic or unused parameters. The only risk is calling two
> different variants for a single arch, but as mentioned in first
> paragraph, there is no real reason for this to happen.
> 
> Signed-off-by: Pierrick Bouvier<pierrick.bouvier@linaro.org>
> ---
>   include/tcg/tcg-op.h             | 16 ++++++----------
>   target/alpha/cpu-param.h         |  2 --
>   target/arm/cpu-param.h           |  7 -------
>   target/avr/cpu-param.h           |  2 --
>   target/hexagon/cpu-param.h       |  2 --
>   target/hppa/cpu-param.h          |  2 --
>   target/i386/cpu-param.h          |  2 --
>   target/loongarch/cpu-param.h     |  2 --
>   target/m68k/cpu-param.h          |  2 --
>   target/microblaze/cpu-param.h    |  2 --
>   target/mips/cpu-param.h          |  2 --
>   target/openrisc/cpu-param.h      |  2 --
>   target/ppc/cpu-param.h           |  2 --
>   target/riscv/cpu-param.h         |  7 -------
>   target/rx/cpu-param.h            |  2 --
>   target/s390x/cpu-param.h         |  2 --
>   target/sh4/cpu-param.h           |  2 --
>   target/sparc/cpu-param.h         |  2 --
>   target/tricore/cpu-param.h       |  2 --
>   target/xtensa/cpu-param.h        |  2 --
>   target/alpha/translate.c         |  4 ++--
>   target/arm/tcg/translate-a64.c   |  2 +-
>   target/arm/tcg/translate.c       |  2 +-
>   target/avr/translate.c           |  2 +-
>   target/hexagon/translate.c       |  2 +-
>   target/hppa/translate.c          |  2 +-
>   target/i386/tcg/translate.c      |  2 +-
>   target/loongarch/tcg/translate.c |  2 +-
>   target/m68k/translate.c          |  2 +-
>   target/microblaze/translate.c    |  2 +-
>   target/mips/tcg/translate.c      |  4 ++--
>   target/openrisc/translate.c      |  4 ++--
>   target/ppc/translate.c           |  2 +-
>   target/riscv/translate.c         |  2 +-
>   target/rx/translate.c            |  2 +-
>   target/s390x/tcg/translate.c     |  2 +-
>   target/sh4/translate.c           |  4 ++--
>   target/sparc/translate.c         |  2 +-
>   target/tricore/translate.c       |  2 +-
>   target/xtensa/translate.c        |  2 +-
>   40 files changed, 30 insertions(+), 82 deletions(-)
> 
> diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
> index f3fe2d9386a..bf76749d1c5 100644
> --- a/include/tcg/tcg-op.h
> +++ b/include/tcg/tcg-op.h
> @@ -28,8 +28,7 @@
>   # error Mismatch with insn-start-words.h
>   #endif
>   
> -#if TARGET_INSN_START_EXTRA_WORDS == 0
> -static inline void tcg_gen_insn_start(uint64_t pc)
> +static inline void tcg_gen_insn_start0(uint64_t pc)
>   {
>       TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
>                               INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
> @@ -37,8 +36,8 @@ static inline void tcg_gen_insn_start(uint64_t pc)
>       tcg_set_insn_start_param(op, 1, 0);
>       tcg_set_insn_start_param(op, 2, 0);
>   }
> -#elif TARGET_INSN_START_EXTRA_WORDS == 1
> -static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1)
> +
> +static inline void tcg_gen_insn_start1(uint64_t pc, uint64_t a1)
>   {
>       TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
>                               INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
> @@ -46,9 +45,9 @@ static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1)
>       tcg_set_insn_start_param(op, 1, a1);
>       tcg_set_insn_start_param(op, 2, 0);
>   }
> -#elif TARGET_INSN_START_EXTRA_WORDS == 2
> -static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1,
> -                                      uint64_t a2)
> +
> +static inline void tcg_gen_insn_start2(uint64_t pc, uint64_t a1,
> +                                       uint64_t a2)
>   {
>       TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
>                               INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
> @@ -56,9 +55,6 @@ static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1,
>       tcg_set_insn_start_param(op, 1, a1);
>       tcg_set_insn_start_param(op, 2, a2);
>   }
> -#else
> -#error Unhandled TARGET_INSN_START_EXTRA_WORDS value
> -#endif
>   

Eh.  If you're going to change anything here, we might as well force the targets to supply 
zeros for the unused parameters and move the last 3-argument tcg_gen_insn_start to 
tcg-op-common.h.


r~
Re: [PATCH 13/29] include/tcg/tcg-op.h: eradicate TARGET_INSN_START_EXTRA_WORDS
Posted by Pierrick Bouvier 1 month ago
On 1/9/26 1:51 PM, Richard Henderson wrote:
> On 1/9/26 16:31, Pierrick Bouvier wrote:
>> We simply define the 3 variants and call the correct one per arch.
>> Since all arch have a single call site (in translate.c), this is as
>> good documentation as having a single define.
>>
>> The notable exception is target/arm, which has two different translate
>> files for 32/64 bits. Since it's the only one, we accept to have two
>> call sites for this.
>>
>> This is much simpler and safer than trying to define a common functions
>> with variadic or unused parameters. The only risk is calling two
>> different variants for a single arch, but as mentioned in first
>> paragraph, there is no real reason for this to happen.
>>
>> Signed-off-by: Pierrick Bouvier<pierrick.bouvier@linaro.org>
>> ---
>>    include/tcg/tcg-op.h             | 16 ++++++----------
>>    target/alpha/cpu-param.h         |  2 --
>>    target/arm/cpu-param.h           |  7 -------
>>    target/avr/cpu-param.h           |  2 --
>>    target/hexagon/cpu-param.h       |  2 --
>>    target/hppa/cpu-param.h          |  2 --
>>    target/i386/cpu-param.h          |  2 --
>>    target/loongarch/cpu-param.h     |  2 --
>>    target/m68k/cpu-param.h          |  2 --
>>    target/microblaze/cpu-param.h    |  2 --
>>    target/mips/cpu-param.h          |  2 --
>>    target/openrisc/cpu-param.h      |  2 --
>>    target/ppc/cpu-param.h           |  2 --
>>    target/riscv/cpu-param.h         |  7 -------
>>    target/rx/cpu-param.h            |  2 --
>>    target/s390x/cpu-param.h         |  2 --
>>    target/sh4/cpu-param.h           |  2 --
>>    target/sparc/cpu-param.h         |  2 --
>>    target/tricore/cpu-param.h       |  2 --
>>    target/xtensa/cpu-param.h        |  2 --
>>    target/alpha/translate.c         |  4 ++--
>>    target/arm/tcg/translate-a64.c   |  2 +-
>>    target/arm/tcg/translate.c       |  2 +-
>>    target/avr/translate.c           |  2 +-
>>    target/hexagon/translate.c       |  2 +-
>>    target/hppa/translate.c          |  2 +-
>>    target/i386/tcg/translate.c      |  2 +-
>>    target/loongarch/tcg/translate.c |  2 +-
>>    target/m68k/translate.c          |  2 +-
>>    target/microblaze/translate.c    |  2 +-
>>    target/mips/tcg/translate.c      |  4 ++--
>>    target/openrisc/translate.c      |  4 ++--
>>    target/ppc/translate.c           |  2 +-
>>    target/riscv/translate.c         |  2 +-
>>    target/rx/translate.c            |  2 +-
>>    target/s390x/tcg/translate.c     |  2 +-
>>    target/sh4/translate.c           |  4 ++--
>>    target/sparc/translate.c         |  2 +-
>>    target/tricore/translate.c       |  2 +-
>>    target/xtensa/translate.c        |  2 +-
>>    40 files changed, 30 insertions(+), 82 deletions(-)
>>
>> diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
>> index f3fe2d9386a..bf76749d1c5 100644
>> --- a/include/tcg/tcg-op.h
>> +++ b/include/tcg/tcg-op.h
>> @@ -28,8 +28,7 @@
>>    # error Mismatch with insn-start-words.h
>>    #endif
>>    
>> -#if TARGET_INSN_START_EXTRA_WORDS == 0
>> -static inline void tcg_gen_insn_start(uint64_t pc)
>> +static inline void tcg_gen_insn_start0(uint64_t pc)
>>    {
>>        TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
>>                                INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
>> @@ -37,8 +36,8 @@ static inline void tcg_gen_insn_start(uint64_t pc)
>>        tcg_set_insn_start_param(op, 1, 0);
>>        tcg_set_insn_start_param(op, 2, 0);
>>    }
>> -#elif TARGET_INSN_START_EXTRA_WORDS == 1
>> -static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1)
>> +
>> +static inline void tcg_gen_insn_start1(uint64_t pc, uint64_t a1)
>>    {
>>        TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
>>                                INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
>> @@ -46,9 +45,9 @@ static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1)
>>        tcg_set_insn_start_param(op, 1, a1);
>>        tcg_set_insn_start_param(op, 2, 0);
>>    }
>> -#elif TARGET_INSN_START_EXTRA_WORDS == 2
>> -static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1,
>> -                                      uint64_t a2)
>> +
>> +static inline void tcg_gen_insn_start2(uint64_t pc, uint64_t a1,
>> +                                       uint64_t a2)
>>    {
>>        TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
>>                                INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
>> @@ -56,9 +55,6 @@ static inline void tcg_gen_insn_start(uint64_t pc, uint64_t a1,
>>        tcg_set_insn_start_param(op, 1, a1);
>>        tcg_set_insn_start_param(op, 2, a2);
>>    }
>> -#else
>> -#error Unhandled TARGET_INSN_START_EXTRA_WORDS value
>> -#endif
>>    
> 
> Eh.  If you're going to change anything here, we might as well force the targets to supply
> zeros for the unused parameters and move the last 3-argument tcg_gen_insn_start to
> tcg-op-common.h.
>

Ok, back to having a constant and check it at runtime then...

> 
> r~
Re: [PATCH 13/29] include/tcg/tcg-op.h: eradicate TARGET_INSN_START_EXTRA_WORDS
Posted by Philippe Mathieu-Daudé 1 month ago
On 9/1/26 06:31, Pierrick Bouvier wrote:
> We simply define the 3 variants and call the correct one per arch.
> Since all arch have a single call site (in translate.c), this is as
> good documentation as having a single define.

Just wondering, if we define a per-target @inst_start_words
constant in TCGCPUOps instead of the INSN_START_WORDS definition,
could we 1/ ensure we call the correct tcg_gen_insn_start()
in cpu_restore_state_from_tb() and 2/ "optimize" the loop in
cpu_unwind_data_from_tb()? Surely not worth it =)

> The notable exception is target/arm, which has two different translate
> files for 32/64 bits. Since it's the only one, we accept to have two
> call sites for this.
> 
> This is much simpler and safer than trying to define a common functions
> with variadic or unused parameters. The only risk is calling two
> different variants for a single arch, but as mentioned in first
> paragraph, there is no real reason for this to happen.
> 
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
>   include/tcg/tcg-op.h             | 16 ++++++----------
>   target/alpha/cpu-param.h         |  2 --
>   target/arm/cpu-param.h           |  7 -------
>   target/avr/cpu-param.h           |  2 --
>   target/hexagon/cpu-param.h       |  2 --
>   target/hppa/cpu-param.h          |  2 --
>   target/i386/cpu-param.h          |  2 --
>   target/loongarch/cpu-param.h     |  2 --
>   target/m68k/cpu-param.h          |  2 --
>   target/microblaze/cpu-param.h    |  2 --
>   target/mips/cpu-param.h          |  2 --
>   target/openrisc/cpu-param.h      |  2 --
>   target/ppc/cpu-param.h           |  2 --
>   target/riscv/cpu-param.h         |  7 -------
>   target/rx/cpu-param.h            |  2 --
>   target/s390x/cpu-param.h         |  2 --
>   target/sh4/cpu-param.h           |  2 --
>   target/sparc/cpu-param.h         |  2 --
>   target/tricore/cpu-param.h       |  2 --
>   target/xtensa/cpu-param.h        |  2 --
>   target/alpha/translate.c         |  4 ++--
>   target/arm/tcg/translate-a64.c   |  2 +-
>   target/arm/tcg/translate.c       |  2 +-
>   target/avr/translate.c           |  2 +-
>   target/hexagon/translate.c       |  2 +-
>   target/hppa/translate.c          |  2 +-
>   target/i386/tcg/translate.c      |  2 +-
>   target/loongarch/tcg/translate.c |  2 +-
>   target/m68k/translate.c          |  2 +-
>   target/microblaze/translate.c    |  2 +-
>   target/mips/tcg/translate.c      |  4 ++--
>   target/openrisc/translate.c      |  4 ++--
>   target/ppc/translate.c           |  2 +-
>   target/riscv/translate.c         |  2 +-
>   target/rx/translate.c            |  2 +-
>   target/s390x/tcg/translate.c     |  2 +-
>   target/sh4/translate.c           |  4 ++--
>   target/sparc/translate.c         |  2 +-
>   target/tricore/translate.c       |  2 +-
>   target/xtensa/translate.c        |  2 +-
>   40 files changed, 30 insertions(+), 82 deletions(-)
Re: [PATCH 13/29] include/tcg/tcg-op.h: eradicate TARGET_INSN_START_EXTRA_WORDS
Posted by Pierrick Bouvier 1 month ago
On 1/9/26 12:00 AM, Philippe Mathieu-Daudé wrote:
> On 9/1/26 06:31, Pierrick Bouvier wrote:
>> We simply define the 3 variants and call the correct one per arch.
>> Since all arch have a single call site (in translate.c), this is as
>> good documentation as having a single define.
> 
> Just wondering, if we define a per-target @inst_start_words
> constant in TCGCPUOps instead of the INSN_START_WORDS definition,
> could we 1/ ensure we call the correct tcg_gen_insn_start()
> in cpu_restore_state_from_tb() and 2/ "optimize" the loop in
> cpu_unwind_data_from_tb()? Surely not worth it =)
>

I'm not sure. The point of INSN_START_WORDS was to have a constant 
definition, not target specific.
Now, could we poke the constant at runtime and optimize. Maybe, but I'm 
not sure there is a real performance benefit, and surely more complexity 
since we would need to reflect this through all targets.

As said in commit description, it's not really possible to call the 
wrong tcg_gen_insn_start() because there is a single call site anyway. 
Making it a constant or a function call with a specific name has the 
same benefit, so I would stick to the simpler (latter) solution.

>> The notable exception is target/arm, which has two different translate
>> files for 32/64 bits. Since it's the only one, we accept to have two
>> call sites for this.
>>
>> This is much simpler and safer than trying to define a common functions
>> with variadic or unused parameters. The only risk is calling two
>> different variants for a single arch, but as mentioned in first
>> paragraph, there is no real reason for this to happen.
>>
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>>    include/tcg/tcg-op.h             | 16 ++++++----------
>>    target/alpha/cpu-param.h         |  2 --
>>    target/arm/cpu-param.h           |  7 -------
>>    target/avr/cpu-param.h           |  2 --
>>    target/hexagon/cpu-param.h       |  2 --
>>    target/hppa/cpu-param.h          |  2 --
>>    target/i386/cpu-param.h          |  2 --
>>    target/loongarch/cpu-param.h     |  2 --
>>    target/m68k/cpu-param.h          |  2 --
>>    target/microblaze/cpu-param.h    |  2 --
>>    target/mips/cpu-param.h          |  2 --
>>    target/openrisc/cpu-param.h      |  2 --
>>    target/ppc/cpu-param.h           |  2 --
>>    target/riscv/cpu-param.h         |  7 -------
>>    target/rx/cpu-param.h            |  2 --
>>    target/s390x/cpu-param.h         |  2 --
>>    target/sh4/cpu-param.h           |  2 --
>>    target/sparc/cpu-param.h         |  2 --
>>    target/tricore/cpu-param.h       |  2 --
>>    target/xtensa/cpu-param.h        |  2 --
>>    target/alpha/translate.c         |  4 ++--
>>    target/arm/tcg/translate-a64.c   |  2 +-
>>    target/arm/tcg/translate.c       |  2 +-
>>    target/avr/translate.c           |  2 +-
>>    target/hexagon/translate.c       |  2 +-
>>    target/hppa/translate.c          |  2 +-
>>    target/i386/tcg/translate.c      |  2 +-
>>    target/loongarch/tcg/translate.c |  2 +-
>>    target/m68k/translate.c          |  2 +-
>>    target/microblaze/translate.c    |  2 +-
>>    target/mips/tcg/translate.c      |  4 ++--
>>    target/openrisc/translate.c      |  4 ++--
>>    target/ppc/translate.c           |  2 +-
>>    target/riscv/translate.c         |  2 +-
>>    target/rx/translate.c            |  2 +-
>>    target/s390x/tcg/translate.c     |  2 +-
>>    target/sh4/translate.c           |  4 ++--
>>    target/sparc/translate.c         |  2 +-
>>    target/tricore/translate.c       |  2 +-
>>    target/xtensa/translate.c        |  2 +-
>>    40 files changed, 30 insertions(+), 82 deletions(-)
>