--- /dev/null
+# Copyright (C) 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an AArch64 target.
+if ![istarget aarch64*-*-*] then {
+ return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+ "" ""
+
+# All done.
+dg-finish
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/boolean-1.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-final { scan-file "temp.json" "\"non_exec_costs_exec\": false" } } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "insn_extra_cost": {
+ "alu": {
+ "non_exec_costs_exec": false
+ }
+ }
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/boolean-2.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-error "key .* expected to be a boolean" "" { target *-*-* } 0 } */
+/* { dg-error "validation failed for the provided JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "insn_extra_cost": {
+ "alu": {
+ "non_exec_costs_exec": 0
+ }
+ }
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-warning "key 'tune_params' not found in JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/empty.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-error "expected a JSON value but got EOF" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/enum-1.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-final { scan-file "temp.json" "\"autoprefetcher_model\": \"AUTOPREFETCHER_OFF\"" } } */
+/* { dg-final { scan-file "temp.json" "\"ldp_policy_model\": \"AARCH64_LDP_STP_POLICY_NEVER\"" } } */
+/* { dg-final { scan-file "temp.json" "\"stp_policy_model\": \"AARCH64_LDP_STP_POLICY_DEFAULT\"" } } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "autoprefetcher_model": "AUTOPREFETCHER_OFF",
+ "ldp_policy_model": "AARCH64_LDP_STP_POLICY_NEVER",
+ "stp_policy_model": "AARCH64_LDP_STP_POLICY_DEFAULT"
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/enum-2.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-warning "autoprefetcher_model not recognized, defaulting to 'AUTOPREFETCHER_OFF'" "" { target *-*-* } 0 } */
+/* { dg-warning "ldp_policy_model not recognized, defaulting to 'AARCH64_LDP_STP_POLICY_DEFAULT'" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "autoprefetcher_model": "null",
+ "ldp_policy_model": "null",
+ "stp_policy_model": "AARCH64_LDP_STP_POLICY_DEFAULT"
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-1.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-final { scan-file "temp.json" "\"sve_width\": 256" } } */
+/* { dg-final { scan-file "temp.json" "\"issue_rate\": 4" } } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "sve_width": 256,
+ "issue_rate": 4
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-error "key .* value .* is out of range for 'int' type" "" { target *-*-* } 0 } */
+/* { dg-error "validation failed for the provided JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "int_reassoc_width": 12097307449014
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-3.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-error "key .* expected to be an integer" "" { target *-*-* } 0 } */
+/* { dg-error "validation failed for the provided JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "issue_rate": "10"
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/string-1.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-final { scan-file "temp.json" "\"function_align\": \"16\"" } } */
+/* { dg-final { scan-file "temp.json" "\"jump_align\": \"2\"" } } */
+/* { dg-final { scan-file "temp.json" "\"loop_align\": \"8\"" } } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "function_align": "16",
+ "jump_align": "2",
+ "loop_align": "8"
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/string-2.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-error "key .* expected to be a string" "" { target *-*-* } 0 } */
+/* { dg-error "validation failed for the provided JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "function_align": 16
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/test-all.json -fdump-tuning-model=temp.json" } */
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+
+/* Test round-trip parsing: load JSON, dump it, verify key values are preserved */
+
+/* Check basic structure values */
+/* { dg-final { scan-file "temp.json" "\"issue_rate\": 3" } } */
+/* { dg-final { scan-file "temp.json" "\"fusible_ops\": 48" } } */
+/* { dg-final { scan-file "temp.json" "\"function_align\": \"32:16\"" } } */
+
+/* Check alu costs */
+/* { dg-final { scan-file "temp.json" "\"arith\": 0" } } */
+/* { dg-final { scan-file "temp.json" "\"logical\": 0" } } */
+/* { dg-final { scan-file "temp.json" "\"shift\": 0" } } */
+/* { dg-final { scan-file "temp.json" "\"arith_shift\": 4" } } */
+
+/* Check load/store costs */
+/* { dg-final { scan-file "temp.json" "\"load\": 12" } } */
+/* { dg-final { scan-file "temp.json" "\"store\": 0" } } */
+/* { dg-final { scan-file "temp.json" "\"loadf\": 16" } } */
+/* { dg-final { scan-file "temp.json" "\"storef\": 0" } } */
+
+/* Check regmove costs */
+/* { dg-final { scan-file "temp.json" "\"GP2GP\": 1" } } */
+/* { dg-final { scan-file "temp.json" "\"GP2FP\": 5" } } */
+/* { dg-final { scan-file "temp.json" "\"FP2GP\": 5" } } */
+/* { dg-final { scan-file "temp.json" "\"FP2FP\": 2" } } */
+
+/* Check vec_costs scalar fields */
+/* { dg-final { scan-file "temp.json" "\"scalar_int_stmt_cost\": 1" } } */
+/* { dg-final { scan-file "temp.json" "\"scalar_fp_stmt_cost\": 1" } } */
+/* { dg-final { scan-file "temp.json" "\"cond_taken_branch_cost\": 3" } } */
+
+/* Check vec_costs advsimd nested fields */
+/* { dg-final { scan-file "temp.json" "\"int_stmt_cost\": 1" } } */
+/* { dg-final { scan-file "temp.json" "\"fp_stmt_cost\": 1" } } */
+/* { dg-final { scan-file "temp.json" "\"permute_cost\": 2" } } */
+/* { dg-final { scan-file "temp.json" "\"vec_to_scalar_cost\": 2" } } */
+
+/* Check vec_costs sve nested fields */
+/* { dg-final { scan-file "temp.json" "\"clast_cost\": 2" } } */
+/* { dg-final { scan-file "temp.json" "\"fadda_f32_cost\": 2" } } */
+/* { dg-final { scan-file "temp.json" "\"gather_load_x32_cost\": 4" } } */
+
+/* Check enum values */
+/* { dg-final { scan-file "temp.json" "\"autoprefetcher_model\": \"AUTOPREFETCHER_WEAK\"" } } */
+/* { dg-final { scan-file "temp.json" "\"ldp_policy_model\": \"AARCH64_LDP_STP_POLICY_ALWAYS\"" } } */
+/* { dg-final { scan-file "temp.json" "\"stp_policy_model\": \"AARCH64_LDP_STP_POLICY_ALWAYS\"" } } */
+
+/* Check boolean values */
+/* { dg-final { scan-file "temp.json" "\"non_exec_costs_exec\": true" } } */
+/* { dg-final { scan-file "temp.json" "\"prefetch_dynamic_strides\": true" } } */
+
+/* Check nested array values (mult costs) */
+/* { dg-final { scan-file "temp.json" "\"simple\": 4" } } */
+/* { dg-final { scan-file "temp.json" "\"idiv\": 24" } } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "insn_extra_cost": {
+ "alu": {
+ "arith": 0,
+ "logical": 0,
+ "shift": 0,
+ "arith_shift": 4
+ },
+ "mult": [
+ {
+ "simple": 4,
+ "idiv": 24
+ }
+ ],
+ "ldst": {
+ "load": 12,
+ "store": 0,
+ "loadf": 16,
+ "storef": 0
+ }
+ },
+ "regmove_cost": {
+ "GP2GP": 1,
+ "GP2FP": 5,
+ "FP2GP": 5,
+ "FP2FP": 2
+ },
+ "issue_rate": 3,
+ "fusible_ops": 48,
+ "function_align": "32:16",
+ "autoprefetcher_model": "AUTOPREFETCHER_WEAK",
+ "ldp_policy_model": "AARCH64_LDP_STP_POLICY_ALWAYS",
+ "stp_policy_model": "AARCH64_LDP_STP_POLICY_ALWAYS",
+ "prefetch": {
+ "prefetch_dynamic_strides": true
+ }
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-warning "key .* is not a tuning parameter, skipping" "" { target *-*-* } 0 } */
+
+int main () {}
\ No newline at end of file
--- /dev/null
+{
+ "tune_params": {
+ "unidentified_key": "10"
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-1.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-final { scan-file "temp.json" "\"sve_width\": 512" } } */
+/* { dg-final { scan-file "temp.json" "\"extra_tuning_flags\": 16" } } */
+
+int main () {}
--- /dev/null
+{
+ "tune_params": {
+ "sve_width": 512,
+ "extra_tuning_flags": 16
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-error "key .* value .* is out of range for 'uint' type" "" { target *-*-* } 0 } */
+/* { dg-error "validation failed for the provided JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
--- /dev/null
+{
+ "tune_params": {
+ "sve_width": -128,
+ "extra_tuning_flags": 0
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json -fdump-tuning-model=temp.json" } */
+
+/* { dg-warning "JSON tuning file does not contain version information" "" { target *-*-* } 0 } */
+/* { dg-error "key .* value .* is out of range for 'uint' type" "" { target *-*-* } 0 } */
+/* { dg-error "validation failed for the provided JSON data" "" { target *-*-* } 0 } */
+
+int main () {}
--- /dev/null
+{
+ "tune_params": {
+ "sve_width": 5000000000
+ }
+}