Skip to content

Commit

Permalink
LoongArch: Define builtin macros for ISA evolutions
Browse files Browse the repository at this point in the history
Detailed description of these definitions can be found at
https://github.com/loongson/la-toolchain-conventions, which
the LoongArch GCC port aims to conform to.

gcc/ChangeLog:

	* config.gcc: Add loongarch-evolution.o.
	* config/loongarch/genopts/genstr.sh: Enable generation of
	loongarch-evolution.[cc,h].
	* config/loongarch/t-loongarch: Likewise.
	* config/loongarch/genopts/gen-evolution.awk: New file.
	* config/loongarch/genopts/isa-evolution.in: Mark ISA version
	of introduction for each ISA evolution feature.
	* config/loongarch/loongarch-c.cc (loongarch_cpu_cpp_builtins):
	Define builtin macros for enabled ISA evolutions and the ISA
	version.
	* config/loongarch/loongarch-cpu.cc: Use loongarch-evolution.h.
	* config/loongarch/loongarch.h: Likewise.
	* config/loongarch/loongarch-cpucfg-map.h: Delete.
	* config/loongarch/loongarch-evolution.cc: New file.
	* config/loongarch/loongarch-evolution.h: New file.
	* config/loongarch/loongarch-opts.h (ISA_HAS_FRECIPE): Define.
	(ISA_HAS_DIV32): Likewise.
	(ISA_HAS_LAM_BH): Likewise.
	(ISA_HAS_LAMCAS): Likewise.
	(ISA_HAS_LD_SEQ_SA): Likewise.
  • Loading branch information
scylaac authored and chenglulu326 committed Apr 23, 2024
1 parent b4ebdd1 commit 77e114b
Show file tree
Hide file tree
Showing 11 changed files with 398 additions and 95 deletions.
2 changes: 1 addition & 1 deletion gcc/config.gcc
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ loongarch*-*-*)
cpu_type=loongarch
d_target_objs="loongarch-d.o"
extra_headers="larchintrin.h lsxintrin.h lasxintrin.h"
extra_objs="loongarch-c.o loongarch-builtins.o loongarch-cpu.o loongarch-opts.o loongarch-def.o"
extra_objs="loongarch-c.o loongarch-builtins.o loongarch-cpu.o loongarch-opts.o loongarch-def.o loongarch-evolution.o"
extra_gcc_objs="loongarch-driver.o loongarch-cpu.o loongarch-opts.o loongarch-def.o"
extra_options="${extra_options} g.opt fused-madd.opt"
;;
Expand Down
230 changes: 230 additions & 0 deletions gcc/config/loongarch/genopts/gen-evolution.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
#!/usr/bin/gawk
#
# A simple script that generates loongarch-evolution.h
# from genopts/isa-evolution.in
#
# Copyright (C) 2021-2024 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC 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, or (at your option) any later
# version.
#
# GCC 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/>.

BEGIN {
# isa_version_major[]
# isa_version_minor[]
# cpucfg_word[]
# cpucfg_bit_in_word[]
# name_capitalized[]
# comment[]
}

{
cpucfg_word[NR] = $1
cpucfg_bit_in_word[NR] = $2
name[NR] = gensub(/-/, "_", "g", $3)
name_capitalized[NR] = toupper(name[NR])
isa_version_major[NR] = gensub(/^([1-9][0-9]*)\.([0-9]+)$/, "\\1", 1, $4)
isa_version_minor[NR] = gensub(/^([1-9][0-9]*)\.([0-9]+)$/, "\\2", 1, $4)

$1 = $2 = $3 = $4 = ""
sub (/^\s*/, "")
comment[NR] = $0
}

function copyright_header(from_year,to_year)
{
print " Copyright (C) " from_year "-" to_year \
" Free Software Foundation, Inc."
print ""
print "This file is part of GCC."
print ""
print "GCC is free software; you can redistribute it and/or modify"
print "it under the terms of the GNU General Public License as published by"
print "the Free Software Foundation; either version 3, or (at your option)"
print "any later version."
print ""
print "GCC is distributed in the hope that it will be useful,"
print "but WITHOUT ANY WARRANTY; without even the implied warranty of"
print "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
print "GNU General Public License for more details."
print ""
print "You should have received a copy of the GNU General Public License"
print "along with GCC; see the file COPYING3. If not see"
print "<http://www.gnu.org/licenses/>."
}

function gen_cpucfg_map()
{
print "static constexpr struct {"
print " int cpucfg_word;"
print " unsigned int cpucfg_bit;"
print " HOST_WIDE_INT isa_evolution_bit;"
print "} cpucfg_map[] = {"

for (i = 1; i <= NR; i++)
printf (" { %d, 1u << %d, OPTION_MASK_ISA_%s },\n",
cpucfg_word[i], cpucfg_bit_in_word[i], name_capitalized[i])

print "};"
}

function gen_cpucfg_useful_idx()
{
split("0 1 2 16 17 18 19", init_useful_idx)

delete idx_bucket

for (i in init_useful_idx)
idx_bucket[init_useful_idx[i]] = 1
delete init_useful_idx

for (i in cpucfg_word)
idx_bucket[cpucfg_word[i]] = 1

delete idx_list
for (i in idx_bucket)
idx_list[length(idx_list)-1] = i+0
delete idx_bucket

asort (idx_list)

print "static constexpr int cpucfg_useful_idx[] = {"
for (i in idx_list)
printf(" %d,\n", idx_list[i])
print "};"

print ""

printf ("static constexpr int N_CPUCFG_WORDS = %d;\n",
idx_list[length(idx_list)] + 1)

delete idx_list
}

function gen_evolution_decl()
{
print "/* ISA evolution features */"
print "enum {"

for (i = 1; i <= NR; i++)
print " EVO_" name_capitalized[i] " = " i - 1 ","

print " N_EVO_FEATURES = " NR
print "};"
print ""

print "/* Condition macros */"
for (i = 1; i <= NR; i++)
printf ("#define ISA_HAS_%s \\\n" \
" (la_target.isa.evolution & OPTION_MASK_ISA_%s)\n",
name_capitalized[i], name_capitalized[i])
print ""

print "/* Bitmasks on la_target.isa.evolution. */"
print "extern int la_evo_feature_masks[N_EVO_FEATURES];"
print ""
print "/* Builtin macro names for the evolution features. */"
print "extern const char* la_evo_macro_name[N_EVO_FEATURES];"
print ""
print "/* The ISA version where a specific feature is introduced. */"
print "extern int la_evo_version_major[N_EVO_FEATURES];"
print "extern int la_evo_version_minor[N_EVO_FEATURES];"
}

function gen_full_header()
{
print "/* Generated automatically by \"genstr\" from \"isa-evolution.in\"."
print " Please do not edit this file directly."
print ""

copyright_header(2023, 2024)

print "*/"
print ""

print "#ifndef LOONGARCH_EVOLUTION_H"
print "#define LOONGARCH_EVOLUTION_H"
print ""
print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)"
print ""
print "#include \"options.h\""
print ""

gen_cpucfg_map()

print ""

gen_cpucfg_useful_idx()

print ""

gen_evolution_decl()

print ""
print "#endif"
print ""
print "#endif /* LOONGARCH_EVOLUTION_H */"
}


function gen_full_source()
{
print "/* Generated automatically by \"genstr\" from \"isa-evolution.in\"."
print " Please do not edit this file directly."
print ""

copyright_header(2023, 2024)

print "*/"
print ""
print "#include \"config.h\""
print "#include \"system.h\""
print "#include \"coretypes.h\""
print "#include \"options.h\""
print ""
print "#include \"loongarch-evolution.h\""
print ""

print "int la_evo_feature_masks[] = {";
for (i = 1; i <= NR; i++)
print " OPTION_MASK_ISA_" name_capitalized[i] ","
print "};"
print ""

print "const char* la_evo_macro_name[] = {";
for (i = 1; i <= NR; i++)
print " \"__loongarch_" name[i] "\","
print "};"
print ""


print "int la_evo_version_major[] = {"
for (i = 1; i <= NR; i++)
print " " isa_version_major[i] ", /* " name_capitalized[i] " */"
print "};"
print ""

print "int la_evo_version_minor[] = {"
for (i = 1; i <= NR; i++)
print " " isa_version_minor[i] ", /* " name_capitalized[i] " */"
print "};"
}

END {
if (header_p)
gen_full_header()
else
gen_full_source()
}
82 changes: 17 additions & 65 deletions gcc/config/loongarch/genopts/genstr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -108,78 +108,30 @@ EOF
print("m"$3)
gsub(/-/, "_", $3)
print("Target Mask(ISA_"toupper($3)") Var(la_isa_evolution)")
$1=""; $2=""; $3=""
$1=""; $2=""; $3=""; $4=""
sub(/^ */, "", $0)
print($0)
}' isa-evolution.in
}

gen_cpucfg_map() {
cat <<EOF
/* Generated automatically by "genstr" from "isa-evolution.in".
Please do not edit this file directly.
Copyright (C) 2023-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC 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, or (at your option)
any later version.
GCC 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/>. */
#ifndef LOONGARCH_CPUCFG_MAP_H
#define LOONGARCH_CPUCFG_MAP_H
#include "options.h"
static constexpr struct {
int cpucfg_word;
unsigned int cpucfg_bit;
HOST_WIDE_INT isa_evolution_bit;
} cpucfg_map[] = {
EOF

# Generate the strings from isa-evolution.in.
awk '{
gsub(/-/, "_", $3)
print(" { "$1", 1u << "$2", OPTION_MASK_ISA_"toupper($3)" },")
}' isa-evolution.in

echo "};"
echo
echo "static constexpr int cpucfg_useful_idx[] = {"

awk 'BEGIN { print(" 0,\n 1,\n 2,\n 16,\n 17,\n 18,\n 19,") }
{if ($1+0 > max+0) max=$1; print(" "$1",")}' \
isa-evolution.in | sort -n | uniq

echo "};"
echo ""

awk 'BEGIN { max=19 }
{ if ($1+0 > max+0) max=$1 }
END { print "static constexpr int N_CPUCFG_WORDS = "1+max";" }' \
isa-evolution.in

echo "#endif /* LOONGARCH_CPUCFG_MAP_H */"
}

main() {
case "$1" in
cpucfg-map) gen_cpucfg_map;;
header) gen_defines;;
opt) gen_options;;
*) echo "Unknown Command: \"$1\". Available: cpucfg-map, header, opt"; exit 1;;
evolution_h)
awk -v header_p=1 -f gen-evolution.awk isa-evolution.in
;;
evolution_c)
awk -v header_p=0 -f gen-evolution.awk isa-evolution.in
;;
header)
gen_defines
;;
opt)
gen_options
;;
*)
echo "Unknown Command: \"$1\". Available: header, opt, evolution_h, evolution_c"
exit 1
;;
esac
}

Expand Down
10 changes: 5 additions & 5 deletions gcc/config/loongarch/genopts/isa-evolution.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
2 25 frecipe Support frecipe.{s/d} and frsqrte.{s/d} instructions.
2 26 div32 Support div.w[u] and mod.w[u] instructions with inputs not sign-extended.
2 27 lam-bh Support am{swap/add}[_db].{b/h} instructions.
2 28 lamcas Support amcas[_db].{b/h/w/d} instructions.
3 23 ld-seq-sa Do not need load-load barriers (dbar 0x700).
2 25 frecipe 1.1 Support frecipe.{s/d} and frsqrte.{s/d} instructions.
2 26 div32 1.1 Support div.w[u] and mod.w[u] instructions with inputs not sign-extended.
2 27 lam-bh 1.1 Support am{swap/add}[_db].{b/h} instructions.
2 28 lamcas 1.1 Support amcas[_db].{b/h/w/d} instructions.
3 23 ld-seq-sa 1.1 Do not need load-load barriers (dbar 0x700).
23 changes: 23 additions & 0 deletions gcc/config/loongarch/loongarch-c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,29 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
builtin_define ("__loongarch_simd_width=256");
}

/* ISA evolution features */
int max_v_major = 1, max_v_minor = 0;

for (int i = 0; i < N_EVO_FEATURES; i++)
if (la_target.isa.evolution & la_evo_feature_masks[i])
{
builtin_define (la_evo_macro_name[i]);

int major = la_evo_version_major[i],
minor = la_evo_version_minor[i];

max_v_major = major > max_v_major ? major : max_v_major;
max_v_minor = major == max_v_major
? (minor > max_v_minor ? minor : max_v_minor): max_v_minor;
}

/* Find the minimum ISA version required to run the target program. */
if (!(max_v_major == 1 && max_v_minor <= 1 && ISA_HAS_LASX))
{
builtin_define_with_int_value ("__loongarch_version_major", max_v_major);
builtin_define_with_int_value ("__loongarch_version_minor", max_v_minor);
}

/* Add support for FLOAT128_TYPE on the LoongArch architecture. */
builtin_define ("__FLOAT128_TYPE__");

Expand Down
2 changes: 1 addition & 1 deletion gcc/config/loongarch/loongarch-cpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "loongarch-def.h"
#include "loongarch-opts.h"
#include "loongarch-cpu.h"
#include "loongarch-cpucfg-map.h"
#include "loongarch-str.h"
#include "loongarch-evolution.h"


/* Native CPU detection with "cpucfg" */
Expand Down

0 comments on commit 77e114b

Please sign in to comment.