1# Copyright (C) 2011-2020 Free Software Foundation, Inc.
2#
3# This file is part of GCC.
4#
5# GCC is free software; you can redistribute it and/or modify it under
6# the terms of the GNU General Public License as published by the Free
7# Software Foundation; either version 3, or (at your option) any later
8# version.
9#
10# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11# WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with GCC; see the file COPYING3.  If not see
17# <http://www.gnu.org/licenses/>.
18
19##################################################################
20#  
21# Transform Core/Device Information from avr-mcus.def to a
22# Representation that is understood by GCC's multilib Machinery.
23#
24# The Script works as a Filter from STDIN to STDOUT.
25# It generates a Makefile Snippet that sets some
26# MULTILIB_* Variables as needed.
27#
28##################################################################
29
30BEGIN {
31    FS ="[(, \t]+"
32    option[""] = ""
33    comment = 1
34
35    dir_tiny = "tiny-stack"
36    opt_tiny = "msp8"
37
38    dir_rcall = "short-calls"
39    opt_rcall = "mshort-calls"
40
41    #    awk Variable         Makefile Variable  
42    #  ------------------------------------------
43    #    m_options     <->    MULTILIB_OPTIONS
44    #    m_dirnames    <->    MULTILIB_DIRNAMES
45    #    m_required    <->    MULTILIB_REQUIRED
46    #    m_reuse       <->    MULTILIB_REUSE
47    m_sep = ""
48    m_options    = "\nMULTILIB_OPTIONS = "
49    m_dirnames   = "\nMULTILIB_DIRNAMES ="
50    m_required   = "\nMULTILIB_REQUIRED ="
51    m_reuse      = "\nMULTILIB_REUSE ="
52
53    have_long_double_is_double = (HAVE_LONG_DOUBLE_IS_DOUBLE \
54				  == "HAVE_LONG_DOUBLE_IS_DOUBLE")
55    have_double32 = (HAVE_DOUBLE32 == "HAVE_DOUBLE32")
56    have_double64 = (HAVE_DOUBLE64 == "HAVE_DOUBLE64")
57    have_long_double32 = (HAVE_LONG_DOUBLE32 == "HAVE_LONG_DOUBLE32")
58    have_long_double64 = (HAVE_LONG_DOUBLE64 == "HAVE_LONG_DOUBLE64")
59
60    have_double_multi = (have_double32 && have_double64)
61    have_long_double_multi = (! have_long_double_is_double \
62			      && have_long_double32 && have_long_double64)
63
64    # How to switch away from the default.
65    dir_double = "double"   (96 - with_double)
66    opt_double = "mdouble=" (96 - with_double)
67
68    dir_long_double = "long-double"   (96 - with_long_double)
69    opt_long_double = "mlong-double=" (96 - with_long_double)
70}
71
72##################################################################
73# Add some Comments to the generated Files and copy-paste
74# Copyright Notice from above.
75##################################################################
76
77/^#/ {
78    if (!comment)
79	next
80    else if (comment == 1)
81    {
82	print "# Auto-generated Makefile Snip"
83	print "# Generated by    : ./gcc/config/avr/genmultilib.awk"
84	print "# Generated from  : ./gcc/config/avr/avr-mcus.def"
85	print "# Used by         : tmake_file from Makefile and genmultilib"
86	print ""
87    }
88
89    comment = 2;
90
91    print
92}
93
94/^$/ {
95    # The first empty line stops copy-pasting the GPL comments
96    # from this file to the generated file.
97
98    if (comment)
99    {
100	print
101
102	if (have_double_multi)
103	{
104	    print "# dir_double = " dir_double
105	    print "# opt_double = -" opt_double
106	}
107	else
108	    print "# No multilib for double."
109
110	if (have_long_double_multi)
111	{
112	    print "# dir_long_double = " dir_long_double
113	    print "# opt_long_double = -" opt_long_double
114	}
115	else
116	    print "# No multilib for long double."
117    }
118    comment = 0
119}
120
121##################################################################
122# Run over all AVR_MCU Lines.  If we encounter a required multilib
123# variant, add according combination of options to m_required,
124# but onyl once.  Add encountered cores to m_dirnames and
125# according -mmcu= options to m_options.
126##################################################################
127
128/^AVR_MCU/ {
129    name = $2
130    gsub ("\"", "", name)
131
132    if ($5 == "NULL")
133    {
134	core = name
135
136	# avr1 is supported for Assembler only:  It gets no multilib
137	if (core == "avr1")
138	    next
139
140	option[core] = "mmcu=" core
141
142	m_options  = m_options m_sep option[core]
143	m_dirnames = m_dirnames " " core
144	m_sep = "/"
145
146	next
147    }
148
149    # avr1 is supported for Assembler only:  Its Devices are ignored
150    if (core == "avr1")
151	next
152
153    opts = option[core]
154
155    # split device specific feature list
156    n = split($4,dev_attribute,"|")
157
158    for (i=1; i <= n; i++)
159    {
160      if (dev_attribute[i] == "AVR_SHORT_SP")
161        opts = opts "/" opt_tiny
162      if (dev_attribute[i] == "AVR_ISA_RCALL")
163        opts = opts "/" opt_rcall
164    }
165
166    if (!have[opts])
167    {
168	have[opts] = 1
169	# Some special handling for the default mmcu: Remove a
170	# leading "mmcu=avr2/" in order not to confuse genmultilib.
171	gsub (/^mmcu=avr2\//, "", opts)
172	if (opts != "mmcu=avr2")
173	{
174	    m_required = m_required " \\\n\t" opts
175	    if (have_double_multi && have_long_double_multi)
176	    {
177		m_required = m_required " \\\n\t" opts "/" opt_double
178		m_required = m_required " \\\n\t" opts "/" opt_long_double
179
180		# We have only 3 different combinations because -mdouble=64
181		# implies -mlong-double=64, and -mlong-double=32 implies
182		# -mdouble=32, hence add respective reuses.  The reuse is
183		# not needed in the case with_double != with_long_double
184		# which means with_double=32 with_long_double=64 because
185		# the driver will rectify combining -mdouble=64 and
186		# -mlong-double=32.
187		if (with_double == with_long_double)
188		{
189		    d_opts = with_double == 32 ? opt_double : opt_long_double
190		    d_opts  = opts "/" d_opts
191		    d_reuse = opts "/" opt_double "/" opt_long_double
192		    gsub (/=/, ".", d_opts)
193		    gsub (/=/, ".", d_reuse)
194		    m_reuse = m_reuse " \\\n\t" d_opts "=" d_reuse
195		}
196	    }
197	    else if (have_double_multi)
198		m_required = m_required " \\\n\t" opts "/" opt_double
199	    else if (have_long_double_multi)
200		m_required = m_required " \\\n\t" opts "/" opt_long_double
201	}
202    }
203}
204
205##################################################################
206# 
207##################################################################
208
209END {
210    ############################################################
211    # Output that Stuff
212    ############################################################
213
214    # Intended Target: $(top_builddir)/gcc/t-multilib-avr
215
216    if (have_double_multi && have_long_double_multi)
217    {
218	print m_options  " " opt_tiny " " opt_rcall " " opt_double "/" opt_long_double
219	print m_dirnames " " dir_tiny " " dir_rcall " " dir_double " " dir_long_double
220	# Notice that the ./double* and ./long-double* variants cannot
221	# be copied by t-avrlibc because the . default multilib is built
222	# after all the others.
223	m_required = m_required " \\\n\t" opt_double
224	m_required = m_required " \\\n\t" opt_long_double
225	if (with_double == with_long_double)
226	{
227	    d_opts  = with_double == 32 ? opt_double : opt_long_double
228	    d_reuse = opt_double "/" opt_long_double
229	    gsub (/=/, ".", d_opts)
230	    gsub (/=/, ".", d_reuse)
231	    m_reuse = m_reuse " \\\n\t" d_opts "=" d_reuse
232
233	}
234    }
235    else if (have_double_multi)
236    {
237	print m_options  " " opt_tiny " " opt_rcall " " opt_double
238	print m_dirnames " " dir_tiny " " dir_rcall " " dir_double
239	m_required = m_required " \\\n\t" opt_double
240    }
241    else if (have_long_double_multi)
242    {
243	print m_options  " " opt_tiny " " opt_rcall " " opt_long_double
244	print m_dirnames " " dir_tiny " " dir_rcall " " dir_long_double
245	m_required = m_required " \\\n\t" opt_long_double
246    }
247    else
248    {
249	print m_options  " " opt_tiny " " opt_rcall
250	print m_dirnames " " dir_tiny " " dir_rcall
251    }
252
253    print m_required
254    print m_reuse
255}
256