blob: 7b7e53e41798757f6c0a6e241563138f1c10d548 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001divert(-1)
2dnl
3dnl m4 macros for gmp assembly code, shared by all CPUs.
4
5dnl Copyright 1999-2006, 2011 Free Software Foundation, Inc.
6
7dnl This file is part of the GNU MP Library.
8dnl
9dnl The GNU MP Library is free software; you can redistribute it and/or modify
10dnl it under the terms of either:
11dnl
12dnl * the GNU Lesser General Public License as published by the Free
13dnl Software Foundation; either version 3 of the License, or (at your
14dnl option) any later version.
15dnl
16dnl or
17dnl
18dnl * the GNU General Public License as published by the Free Software
19dnl Foundation; either version 2 of the License, or (at your option) any
20dnl later version.
21dnl
22dnl or both in parallel, as here.
23dnl
24dnl The GNU MP Library is distributed in the hope that it will be useful, but
25dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27dnl for more details.
28dnl
29dnl You should have received copies of the GNU General Public License and the
30dnl GNU Lesser General Public License along with the GNU MP Library. If not,
31dnl see https://www.gnu.org/licenses/.
32
33
34dnl These macros are designed for use with any m4 and have been used on
35dnl GNU, FreeBSD, NetBSD, OpenBSD and SysV.
36dnl
37dnl GNU m4 and OpenBSD 2.7 m4 will give filenames and line numbers in error
38dnl messages.
39dnl
40dnl
41dnl Macros:
42dnl
43dnl Most new m4 specific macros have an "m4_" prefix to emphasise they're
44dnl m4 expansions. But new defining things like deflit() and defreg() are
45dnl named like the builtin define(), and forloop() is named following the
46dnl GNU m4 example on which it's based.
47dnl
48dnl GNU m4 with the -P option uses "m4_" as a prefix for builtins, but that
49dnl option isn't going to be used, so there's no conflict or confusion.
50dnl
51dnl
52dnl Comments in output:
53dnl
54dnl The m4 comment delimiters are left at # and \n, the normal assembler
55dnl commenting for most CPUs. m4 passes comment text through without
56dnl expanding macros in it, which is generally a good thing since it stops
57dnl unexpected expansions and possible resultant errors.
58dnl
59dnl But note that when a quoted string is being read, a # isn't special, so
60dnl apostrophes in comments in quoted strings must be avoided or they'll be
61dnl interpreted as a closing quote mark. But when the quoted text is
62dnl re-read # will still act like a normal comment, suppressing macro
63dnl expansion.
64dnl
65dnl For example,
66dnl
67dnl # apostrophes in comments that're outside quotes are ok
68dnl # and using macro names like PROLOGUE is ok too
69dnl ...
70dnl ifdef(`PIC',`
71dnl # but apostrophes aren't ok inside quotes
72dnl # ^--wrong
73dnl ...
74dnl # though macro names like PROLOGUE are still ok
75dnl ...
76dnl ')
77dnl
78dnl If macro expansion in a comment is wanted, use `#' in the .asm (ie. a
79dnl quoted hash symbol), which will turn into # in the .s but get
80dnl expansions done on that line. This can make the .s more readable to
81dnl humans, but it won't make a blind bit of difference to the assembler.
82dnl
83dnl All the above applies, mutatis mutandis, when changecom() is used to
84dnl select @ ! ; or whatever other commenting.
85dnl
86dnl
87dnl Variations in m4 affecting gmp:
88dnl
89dnl $# - When a macro is called as "foo" with no brackets, BSD m4 sets $#
90dnl to 1, whereas GNU or SysV m4 set it to 0. In all cases though
91dnl "foo()" sets $# to 1. This is worked around in various places.
92dnl
93dnl len() - When "len()" is given an empty argument, BSD m4 evaluates to
94dnl nothing, whereas GNU, SysV, and the new OpenBSD, evaluate to 0.
95dnl See m4_length() below which works around this.
96dnl
97dnl translit() - GNU m4 accepts character ranges like A-Z, and the new
98dnl OpenBSD m4 does under option -g, but basic BSD and SysV don't.
99dnl
100dnl popdef() - in BSD and SysV m4 popdef() takes multiple arguments and
101dnl pops each, but GNU m4 only takes one argument.
102dnl
103dnl push back - BSD m4 has some limits on the amount of text that can be
104dnl pushed back. The limit is reasonably big and so long as macros
105dnl don't gratuitously duplicate big arguments it isn't a problem.
106dnl Normally an error message is given, but sometimes it just hangs.
107dnl
108dnl eval() &,|,^ - GNU and SysV m4 have bitwise operators &,|,^ available,
109dnl but BSD m4 doesn't (contrary to what the man page suggests) and
110dnl instead ^ is exponentiation.
111dnl
112dnl eval() ?: - The C ternary operator "?:" is available in BSD m4, but not
113dnl in SysV or GNU m4 (as of GNU m4 1.4 and betas of 1.5).
114dnl
115dnl eval() -2^31 - BSD m4 has a bug where an eval() resulting in -2^31
116dnl (ie. -2147483648) gives "-(". Using -2147483648 within an
117dnl expression is ok, it just can't be a final result. "-(" will of
118dnl course upset parsing, with all sorts of strange effects.
119dnl
120dnl eval() <<,>> - SysV m4 doesn't support shift operators in eval() (on
121dnl Solaris 7 /usr/xpg4/m4 has them but /usr/ccs/m4 doesn't). See
122dnl m4_lshift() and m4_rshift() below for workarounds.
123dnl
124dnl ifdef() - OSF 4.0 m4 considers a macro defined to a zero value `0' or
125dnl `00' etc as not defined. See m4_ifdef below for a workaround.
126dnl
127dnl m4wrap() sequence - in BSD m4, m4wrap() replaces any previous m4wrap()
128dnl string, in SysV m4 it appends to it, and in GNU m4 it prepends.
129dnl See m4wrap_prepend() below which brings uniformity to this.
130dnl
131dnl m4wrap() 0xFF - old versions of BSD m4 store EOF in a C "char" under an
132dnl m4wrap() and on systems where char is unsigned by default a
133dnl spurious 0xFF is output. This has been observed on recent Cray
134dnl Unicos Alpha, Apple MacOS X, and HPUX 11 systems. An autoconf
135dnl test is used to check for this, see the m4wrap handling below. It
136dnl might work to end the m4wrap string with a dnl to consume the
137dnl 0xFF, but that probably induces the offending m4's to read from an
138dnl already closed "FILE *", which could be bad on a glibc style
139dnl stdio.
140dnl
141dnl __file__,__line__ - GNU m4 and OpenBSD 2.7 m4 provide these, and
142dnl they're used here to make error messages more informative. GNU m4
143dnl gives an unhelpful "NONE 0" in an m4wrap(), but that's worked
144dnl around.
145dnl
146dnl __file__ quoting - OpenBSD m4, unlike GNU m4, doesn't quote the
147dnl filename in __file__, so care should be taken that no macro has
148dnl the same name as a file, or an unwanted expansion will occur when
149dnl printing an error or warning.
150dnl
151dnl changecom() - BSD m4 changecom doesn't quite work like the man page
152dnl suggests, in particular "changecom" or "changecom()" doesn't
153dnl disable the comment feature, and multi-character comment sequences
154dnl don't seem to work. If the default `#' and newline aren't
155dnl suitable it's necessary to change it to something else,
156dnl eg. changecom(;).
157dnl
158dnl OpenBSD 2.6 m4 - in this m4, eval() rejects decimal constants containing
159dnl an 8 or 9, making it pretty much unusable. The bug is confined to
160dnl version 2.6 (it's not in 2.5, and was fixed in 2.7).
161dnl
162dnl SunOS /usr/bin/m4 - this m4 lacks a number of desired features,
163dnl including $# and $@, defn(), m4exit(), m4wrap(), pushdef(),
164dnl popdef(). /usr/5bin/m4 is a SysV style m4 which should always be
165dnl available, and "configure" will reject /usr/bin/m4 in favour of
166dnl /usr/5bin/m4 (if necessary).
167dnl
168dnl The sparc code actually has modest m4 requirements currently and
169dnl could manage with /usr/bin/m4, but there's no reason to put our
170dnl macros through contortions when /usr/5bin/m4 is available or GNU
171dnl m4 can be installed.
172
173
174ifdef(`__ASM_DEFS_M4_INCLUDED__',
175`m4_error(`asm-defs.m4 already included, dont include it twice
176')m4exit(1)')
177define(`__ASM_DEFS_M4_INCLUDED__')
178
179
180dnl Detect and give a message about the unsuitable OpenBSD 2.6 m4.
181
182ifelse(eval(89),89,,
183`errprint(
184`This m4 doesnt accept 8 and/or 9 in constants in eval(), making it unusable.
185This is probably OpenBSD 2.6 m4 (September 1999). Upgrade to OpenBSD 2.7,
186or get a bug fix from the CVS (expr.c rev 1.9), or get GNU m4. Dont forget
187to configure with M4=/wherever/m4 if you install one of these in a directory
188not in $PATH.
189')m4exit(1)')
190
191
192dnl Detect and give a message about the unsuitable SunOS /usr/bin/m4.
193dnl
194dnl Unfortunately this test doesn't work when m4 is run in the normal way
195dnl from mpn/Makefile with "m4 -DOPERATION_foo foo.asm", since the bad m4
196dnl takes "-" in "-D..." to mean read stdin, so it will look like it just
197dnl hangs. But running "m4 asm-defs.m4" to try it out will work.
198dnl
199dnl We'd like to abort immediately on finding a problem, but unfortunately
200dnl the bad m4 doesn't have an m4exit(), nor does an invalid eval() kill
201dnl it. Unexpanded $#'s in some m4_assert_numargs() later on will comment
202dnl out some closing parentheses and kill it with "m4: arg stack overflow".
203
204define(m4_dollarhash_works_test,``$#'')
205ifelse(m4_dollarhash_works_test(x),1,,
206`errprint(
207`This m4 doesnt support $# and cant be used for GMP asm processing.
208If this is on SunOS, ./configure should choose /usr/5bin/m4 if you have that
209or can get it, otherwise install GNU m4. Dont forget to configure with
210M4=/wherever/m4 if you install in a directory not in $PATH.
211')')
212undefine(`m4_dollarhash_works_test')
213
214
215dnl --------------------------------------------------------------------------
216dnl Basic error handling things.
217
218
219dnl Usage: m4_dollarhash_1_if_noparen_p
220dnl
221dnl Expand to 1 if a call "foo" gives $# set to 1 (as opposed to 0 like GNU
222dnl and SysV m4 give).
223
224define(m4_dollarhash_1_if_noparen_test,`$#')
225define(m4_dollarhash_1_if_noparen_p,
226eval(m4_dollarhash_1_if_noparen_test==1))
227undefine(`m4_dollarhash_1_if_noparen_test')
228
229
230dnl Usage: m4wrap_prepend(string)
231dnl
232dnl Prepend the given string to what will be expanded under m4wrap at the
233dnl end of input.
234dnl
235dnl This macro exists to work around variations in m4wrap() behaviour in
236dnl the various m4s (notes at the start of this file). Don't use m4wrap()
237dnl directly since it will interfere with this scheme.
238
239define(m4wrap_prepend,
240m4_assert_numargs(1)
241`define(`m4wrap_string',`$1'defn(`m4wrap_string'))')
242
243define(m4wrap_string,`')
244
245define(m4wrap_works_p,
246`ifelse(M4WRAP_SPURIOUS,yes,0,1)')
247
248ifelse(m4wrap_works_p,1,
249`m4wrap(`m4wrap_string')')
250
251
252dnl Usage: m4_file_and_line
253dnl
254dnl Expand to the current file and line number, if the GNU m4 extensions
255dnl __file__ and __line__ are available.
256dnl
257dnl In GNU m4 1.4 at the end of input when m4wrap text is expanded,
258dnl __file__ is NONE and __line__ is 0, which is not a helpful thing to
259dnl print. If m4_file_seen() has been called to note the last file seen,
260dnl then that file at a big line number is used, otherwise "end of input"
261dnl is used (although "end of input" won't parse as an error message).
262
263define(m4_file_and_line,
264`ifdef(`__file__',
265`ifelse(__file__`'__line__,`NONE0',
266`ifdef(`m4_file_seen_last',`m4_file_seen_last: 999999: ',`end of input: ')',
267`__file__: __line__: ')')')
268
269
270dnl Usage: m4_errprint_commas(arg,...)
271dnl
272dnl The same as errprint(), but commas are printed between arguments
273dnl instead of spaces.
274
275define(m4_errprint_commas,
276`errprint(`$1')dnl
277ifelse(eval($#>1),1,`errprint(`,')m4_errprint_commas(shift($@))')')
278
279
280dnl Usage: m4_error(args...)
281dnl m4_warning(args...)
282dnl
283dnl Print an error message, using m4_errprint_commas, prefixed with the
284dnl current filename and line number (if available). m4_error sets up to
285dnl give an error exit at the end of processing, m4_warning just prints.
286dnl These macros are the recommended way to print errors.
287dnl
288dnl The arguments here should be quoted in the usual way to prevent them
289dnl being expanded when the macro call is read. (m4_error takes care not
290dnl to do any further expansion.)
291dnl
292dnl For example,
293dnl
294dnl m4_error(`some error message
295dnl ')
296dnl
297dnl which prints
298dnl
299dnl foo.asm:123: some error message
300dnl
301dnl or if __file__ and __line__ aren't available
302dnl
303dnl some error message
304dnl
305dnl The "file:line:" format is a basic style, used by gcc and GNU m4, so
306dnl emacs and other editors will recognise it in their normal error message
307dnl parsing.
308
309define(m4_warning,
310`m4_errprint_commas(m4_file_and_line`'$@)')
311
312define(m4_error,
313`define(`m4_error_occurred',1)m4_warning($@)dnl
314ifelse(m4wrap_works_p,0,`m4exit(1)')')
315
316define(`m4_error_occurred',0)
317
318dnl This m4wrap_prepend() is first, so it'll be executed last.
319m4wrap_prepend(
320`ifelse(m4_error_occurred,1,
321`m4_error(`Errors occurred during m4 processing
322')m4exit(1)')')
323
324
325dnl Usage: m4_assert_numargs(num)
326dnl
327dnl Put this unquoted on a line on its own at the start of a macro
328dnl definition to add some code to check that num many arguments get passed
329dnl to the macro. For example,
330dnl
331dnl define(foo,
332dnl m4_assert_numargs(2)
333dnl `something `$1' and `$2' blah blah')
334dnl
335dnl Then a call like foo(one,two,three) will provoke an error like
336dnl
337dnl file:10: foo expected 2 arguments, got 3 arguments
338dnl
339dnl Here are some calls and how many arguments they're interpreted as passing.
340dnl
341dnl foo(abc,def) 2
342dnl foo(xyz) 1
343dnl foo() 0
344dnl foo -1
345dnl
346dnl The -1 for no parentheses at all means a macro that's meant to be used
347dnl that way can be checked with m4_assert_numargs(-1). For example,
348dnl
349dnl define(SPECIAL_SUFFIX,
350dnl m4_assert_numargs(-1)
351dnl `ifdef(`FOO',`_foo',`_bar')')
352dnl
353dnl But as an alternative see also deflit() below where parenthesized
354dnl expressions following a macro are passed through to the output.
355dnl
356dnl Note that in BSD m4 there's no way to differentiate calls "foo" and
357dnl "foo()", so in BSD m4 the distinction between the two isn't enforced.
358dnl (In GNU and SysV m4 it can be checked, and is.)
359
360
361dnl m4_assert_numargs is able to check its own arguments by calling
362dnl assert_numargs_internal directly.
363dnl
364dnl m4_doublequote($`'0) expands to ``$0'', whereas ``$`'0'' would expand
365dnl to `$`'0' and do the wrong thing, and likewise for $1. The same is
366dnl done in other assert macros.
367dnl
368dnl $`#' leaves $# in the new macro being defined, and stops # being
369dnl interpreted as a comment character.
370dnl
371dnl `dnl ' means an explicit dnl isn't necessary when m4_assert_numargs is
372dnl used. The space means that if there is a dnl it'll still work.
373
374dnl Usage: m4_doublequote(x) expands to ``x''
375define(m4_doublequote,
376`m4_assert_numargs_internal(`$0',1,$#,len(`$1'))``$1''')
377
378define(m4_assert_numargs,
379`m4_assert_numargs_internal(`$0',1,$#,len(`$1'))dnl
380`m4_assert_numargs_internal'(m4_doublequote($`'0),$1,$`#',`len'(m4_doublequote($`'1)))`dnl '')
381
382dnl Called: m4_assert_numargs_internal(`macroname',wantargs,$#,len(`$1'))
383define(m4_assert_numargs_internal,
384`m4_assert_numargs_internal_check(`$1',`$2',m4_numargs_count(`$3',`$4'))')
385
386dnl Called: m4_assert_numargs_internal_check(`macroname',wantargs,gotargs)
387dnl
388dnl If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
389dnl should be -1. If wantargs is -1 but gotargs is 0 and the two can't be
390dnl distinguished then it's allowed to pass.
391dnl
392define(m4_assert_numargs_internal_check,
393`ifelse(eval($2 == $3
394 || ($2==-1 && $3==0 && m4_dollarhash_1_if_noparen_p)),0,
395`m4_error(`$1 expected 'm4_Narguments(`$2')`, got 'm4_Narguments(`$3')
396)')')
397
398dnl Called: m4_numargs_count($#,len(`$1'))
399dnl If $#==0 then -1 args, if $#==1 but len(`$1')==0 then 0 args, otherwise
400dnl $# args.
401define(m4_numargs_count,
402`ifelse($1,0, -1,
403`ifelse(eval($1==1 && $2-0==0),1, 0, $1)')')
404
405dnl Usage: m4_Narguments(N)
406dnl "$1 argument" or "$1 arguments" with the plural according to $1.
407define(m4_Narguments,
408`$1 argument`'ifelse(`$1',1,,s)')
409
410
411dnl --------------------------------------------------------------------------
412dnl Additional error checking things.
413
414
415dnl Usage: m4_file_seen()
416dnl
417dnl Record __file__ for the benefit of m4_file_and_line in m4wrap text.
418dnl
419dnl The basic __file__ macro comes out quoted in GNU m4, like `foo.asm',
420dnl and m4_file_seen_last is defined like that too.
421dnl
422dnl This is used by PROLOGUE, since that's normally in the main .asm file,
423dnl and in particular it sets up m4wrap error checks for missing EPILOGUE.
424
425define(m4_file_seen,
426m4_assert_numargs(0)
427`ifelse(__file__,`NONE',,
428`define(`m4_file_seen_last',m4_doublequote(__file__))')')
429
430
431dnl Usage: m4_assert_onearg()
432dnl
433dnl Put this, unquoted, at the start of a macro definition to add some code
434dnl to check that one argument is passed to the macro, but with that
435dnl argument allowed to be empty. For example,
436dnl
437dnl define(foo,
438dnl m4_assert_onearg()
439dnl `blah blah $1 blah blah')
440dnl
441dnl Calls "foo(xyz)" or "foo()" are accepted. A call "foo(xyz,abc)" fails.
442dnl A call "foo" fails too, but BSD m4 can't detect this case (GNU and SysV
443dnl m4 can).
444
445define(m4_assert_onearg,
446m4_assert_numargs(0)
447`m4_assert_onearg_internal'(m4_doublequote($`'0),$`#')`dnl ')
448
449dnl Called: m4_assert_onearg(`macroname',$#)
450define(m4_assert_onearg_internal,
451`ifelse($2,1,,
452`m4_error(`$1 expected 1 argument, got 'm4_Narguments(`$2')
453)')')
454
455
456dnl Usage: m4_assert_numargs_range(low,high)
457dnl
458dnl Put this, unquoted, at the start of a macro definition to add some code
459dnl to check that between low and high many arguments get passed to the
460dnl macro. For example,
461dnl
462dnl define(foo,
463dnl m4_assert_numargs_range(3,5)
464dnl `mandatory $1 $2 $3 optional $4 $5 end')
465dnl
466dnl See m4_assert_numargs() for more info.
467
468define(m4_assert_numargs_range,
469m4_assert_numargs(2)
470``m4_assert_numargs_range_internal'(m4_doublequote($`'0),$1,$2,$`#',`len'(m4_doublequote($`'1)))`dnl '')
471
472dnl Called: m4_assert_numargs_range_internal(`name',low,high,$#,len(`$1'))
473define(m4_assert_numargs_range_internal,
474m4_assert_numargs(5)
475`m4_assert_numargs_range_check(`$1',`$2',`$3',m4_numargs_count(`$4',`$5'))')
476
477dnl Called: m4_assert_numargs_range_check(`name',low,high,gotargs)
478dnl
479dnl If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
480dnl should be -1. To ensure a `high' of -1 works, a fudge is applied to
481dnl gotargs if it's 0 and the 0 and -1 cases can't be distinguished.
482dnl
483define(m4_assert_numargs_range_check,
484m4_assert_numargs(4)
485`ifelse(eval($2 <= $4 &&
486 ($4 - ($4==0 && m4_dollarhash_1_if_noparen_p) <= $3)),0,
487`m4_error(`$1 expected $2 to $3 arguments, got 'm4_Narguments(`$4')
488)')')
489
490
491dnl Usage: m4_assert_defined(symbol)
492dnl
493dnl Put this unquoted on a line of its own at the start of a macro
494dnl definition to add some code to check that the given symbol is defined
495dnl when the macro is used. For example,
496dnl
497dnl define(foo,
498dnl m4_assert_defined(`FOO_PREFIX')
499dnl `FOO_PREFIX whatever')
500dnl
501dnl This is a convenient way to check that the user or ./configure or
502dnl whatever has defined the things needed by a macro, as opposed to
503dnl silently generating garbage.
504
505define(m4_assert_defined,
506m4_assert_numargs(1)
507``m4_assert_defined_internal'(m4_doublequote($`'0),``$1'')`dnl '')
508
509dnl Called: m4_assert_defined_internal(`macroname',`define_required')
510define(m4_assert_defined_internal,
511m4_assert_numargs(2)
512`m4_ifdef(`$2',,
513`m4_error(`$1 needs $2 defined
514')')')
515
516
517dnl Usage: m4_not_for_expansion(`SYMBOL')
518dnl define_not_for_expansion(`SYMBOL')
519dnl
520dnl m4_not_for_expansion turns SYMBOL, if defined, into something which
521dnl will give an error if expanded. For example,
522dnl
523dnl m4_not_for_expansion(`PIC')
524dnl
525dnl define_not_for_expansion is the same, but always makes a definition.
526dnl
527dnl These are for symbols that should be tested with ifdef(`FOO',...)
528dnl rather than be expanded as such. They guard against accidentally
529dnl omitting the quotes, as in ifdef(FOO,...). Note though that they only
530dnl catches this when FOO is defined, so be sure to test code both with and
531dnl without each definition.
532
533define(m4_not_for_expansion,
534m4_assert_numargs(1)
535`ifdef(`$1',`define_not_for_expansion(`$1')')')
536
537define(define_not_for_expansion,
538m4_assert_numargs(1)
539`ifelse(defn(`$1'),,,
540`m4_error(``$1' has a non-empty value, maybe it shouldnt be munged with m4_not_for_expansion()
541')')dnl
542define(`$1',`m4_not_for_expansion_internal(`$1')')')
543
544define(m4_not_for_expansion_internal,
545`m4_error(``$1' is not meant to be expanded, perhaps you mean `ifdef(`$1',...)'
546')')
547
548
549dnl --------------------------------------------------------------------------
550dnl Various generic m4 things.
551
552
553dnl Usage: m4_unquote(macro)
554dnl
555dnl Allow the argument text to be re-evaluated. This is useful for "token
556dnl pasting" like m4_unquote(foo`'bar).
557
558define(m4_unquote,
559m4_assert_onearg()
560`$1')
561
562
563dnl Usage: m4_ifdef(name,yes[,no])
564dnl
565dnl Expand to the yes argument if name is defined, or to the no argument if
566dnl not.
567dnl
568dnl This is the same as the builtin "ifdef", but avoids an OSF 4.0 m4 bug
569dnl in which a macro with a zero value `0' or `00' etc is considered not
570dnl defined.
571dnl
572dnl There's no particular need to use this everywhere, only if there might
573dnl be a zero value.
574
575define(m4_ifdef,
576m4_assert_numargs_range(2,3)
577`ifelse(eval(ifdef(`$1',1,0)+m4_length(defn(`$1'))),0,
578`$3',`$2')')
579
580
581dnl Usage: m4_ifdef_anyof_p(`symbol',...)
582dnl
583dnl Expand to 1 if any of the symbols in the argument list are defined, or
584dnl to 0 if not.
585
586define(m4_ifdef_anyof_p,
587`ifelse(eval($#<=1 && m4_length(`$1')==0),1, 0,
588`ifdef(`$1', 1,
589`m4_ifdef_anyof_p(shift($@))')')')
590
591
592dnl Usage: m4_length(string)
593dnl
594dnl Determine the length of a string. This is the same as len(), but
595dnl always expands to a number, working around the BSD len() which
596dnl evaluates to nothing given an empty argument.
597
598define(m4_length,
599m4_assert_onearg()
600`eval(len(`$1')-0)')
601
602
603dnl Usage: m4_stringequal_p(x,y)
604dnl
605dnl Expand to 1 or 0 according as strings x and y are equal or not.
606
607define(m4_stringequal_p,
608`ifelse(`$1',`$2',1,0)')
609
610
611dnl Usage: m4_incr_or_decr(n,last)
612dnl
613dnl Do an incr(n) or decr(n), whichever is in the direction of "last".
614dnl Both n and last must be numbers of course.
615
616define(m4_incr_or_decr,
617m4_assert_numargs(2)
618`ifelse(eval($1<$2),1,incr($1),decr($1))')
619
620
621dnl Usage: forloop(i, first, last, statement)
622dnl
623dnl Based on GNU m4 examples/forloop.m4, but extended.
624dnl
625dnl statement is expanded repeatedly, with i successively defined as
626dnl
627dnl first, first+1, ..., last-1, last
628dnl
629dnl Or if first > last, then it's
630dnl
631dnl first, first-1, ..., last+1, last
632dnl
633dnl If first == last, then one expansion is done.
634dnl
635dnl A pushdef/popdef of i is done to preserve any previous definition (or
636dnl lack of definition). first and last are eval()ed and so can be
637dnl expressions.
638dnl
639dnl forloop_first is defined to 1 on the first iteration, 0 on the rest.
640dnl forloop_last is defined to 1 on the last iteration, 0 on the others.
641dnl Nested forloops are allowed, in which case forloop_first and
642dnl forloop_last apply to the innermost loop that's open.
643dnl
644dnl A simple example,
645dnl
646dnl forloop(i, 1, 2*2+1, `dnl
647dnl iteration number i ... ifelse(forloop_first,1,FIRST)
648dnl ')
649
650
651dnl "i" and "statement" are carefully quoted, but "first" and "last" are
652dnl just plain numbers once eval()ed.
653
654define(`forloop',
655m4_assert_numargs(4)
656`pushdef(`$1',eval(`$2'))dnl
657pushdef(`forloop_first',1)dnl
658pushdef(`forloop_last',0)dnl
659forloop_internal(`$1',eval(`$3'),`$4')`'dnl
660popdef(`forloop_first')dnl
661popdef(`forloop_last')dnl
662popdef(`$1')')
663
664dnl Called: forloop_internal(`var',last,statement)
665define(`forloop_internal',
666m4_assert_numargs(3)
667`ifelse($1,$2,
668`define(`forloop_last',1)$3',
669`$3`'dnl
670define(`forloop_first',0)dnl
671define(`$1',m4_incr_or_decr($1,$2))dnl
672forloop_internal(`$1',$2,`$3')')')
673
674
675dnl Usage: foreach(var,body, item1,item2,...,itemN)
676dnl
677dnl For each "item" argument, define "var" to that value and expand "body".
678dnl For example,
679dnl
680dnl foreach(i, `something i
681dnl ', one, two)
682dnl gives
683dnl something one
684dnl something two
685dnl
686dnl Any previous definition of "var", or lack thereof, is saved and
687dnl restored. Empty "item"s are not allowed.
688
689define(foreach,
690m4_assert_numargs_range(2,1000)
691`ifelse(`$3',,,
692`pushdef(`$1',`$3')$2`'popdef(`$1')dnl
693foreach(`$1',`$2',shift(shift(shift($@))))')')
694
695
696dnl Usage: m4_toupper(x)
697dnl m4_tolower(x)
698dnl
699dnl Convert the argument string to upper or lower case, respectively.
700dnl Only one argument accepted.
701dnl
702dnl BSD m4 doesn't take ranges like a-z in translit(), so the full alphabet
703dnl is written out.
704
705define(m4_alphabet_lower, `abcdefghijklmnopqrstuvwxyz')
706define(m4_alphabet_upper, `ABCDEFGHIJKLMNOPQRSTUVWXYZ')
707
708define(m4_toupper,
709m4_assert_onearg()
710`translit(`$1', m4_alphabet_lower, m4_alphabet_upper)')
711
712define(m4_tolower,
713m4_assert_onearg()
714`translit(`$1', m4_alphabet_upper, m4_alphabet_lower)')
715
716
717dnl Usage: m4_empty_if_zero(x)
718dnl
719dnl Evaluate to x, or to nothing if x is 0. x is eval()ed and so can be an
720dnl expression.
721dnl
722dnl This is useful for x86 addressing mode displacements since forms like
723dnl (%ebx) are one byte shorter than 0(%ebx). A macro `foo' for use as
724dnl foo(%ebx) could be defined with the following so it'll be empty if the
725dnl expression comes out zero.
726dnl
727dnl deflit(`foo', `m4_empty_if_zero(a+b*4-c)')
728dnl
729dnl Naturally this shouldn't be done if, say, a computed jump depends on
730dnl the code being a particular size.
731
732define(m4_empty_if_zero,
733m4_assert_onearg()
734`ifelse(eval($1),0,,eval($1))')
735
736
737dnl Usage: m4_log2(x)
738dnl
739dnl Calculate a logarithm to base 2.
740dnl x must be an integral power of 2, between 2**0 and 2**30.
741dnl x is eval()ed, so it can be an expression.
742dnl An error results if x is invalid.
743dnl
744dnl 2**31 isn't supported, because an unsigned 2147483648 is out of range
745dnl of a 32-bit signed int. Also, the bug in BSD m4 where an eval()
746dnl resulting in 2147483648 (or -2147483648 as the case may be) gives `-('
747dnl means tests like eval(1<<31==(x)) would be necessary, but that then
748dnl gives an unattractive explosion of eval() error messages if x isn't
749dnl numeric.
750
751define(m4_log2,
752m4_assert_numargs(1)
753`m4_log2_internal(0,1,eval(`$1'))')
754
755dnl Called: m4_log2_internal(n,2**n,target)
756define(m4_log2_internal,
757m4_assert_numargs(3)
758`ifelse($2,$3,$1,
759`ifelse($1,30,
760`m4_error(`m4_log2() argument too big or not a power of two: $3
761')',
762`m4_log2_internal(incr($1),eval(2*$2),$3)')')')
763
764
765dnl Usage: m4_div2_towards_zero
766dnl
767dnl m4 division is probably whatever a C signed division is, and C doesn't
768dnl specify what rounding gets used on negatives, so this expression forces
769dnl a rounding towards zero.
770
771define(m4_div2_towards_zero,
772m4_assert_numargs(1)
773`eval((($1) + ((($1)<0) & ($1))) / 2)')
774
775
776dnl Usage: m4_lshift(n,count)
777dnl m4_rshift(n,count)
778dnl
779dnl Calculate n shifted left or right by count many bits. Both n and count
780dnl are eval()ed and so can be expressions.
781dnl
782dnl Negative counts are allowed and mean a shift in the opposite direction.
783dnl Negative n is allowed and right shifts will be arithmetic (meaning
784dnl divide by 2**count, rounding towards zero, also meaning the sign bit is
785dnl duplicated).
786dnl
787dnl Use these macros instead of << and >> in eval() since the basic ccs
788dnl SysV m4 doesn't have those operators.
789
790define(m4_rshift,
791m4_assert_numargs(2)
792`m4_lshift(`$1',-(`$2'))')
793
794define(m4_lshift,
795m4_assert_numargs(2)
796`m4_lshift_internal(eval(`$1'),eval(`$2'))')
797
798define(m4_lshift_internal,
799m4_assert_numargs(2)
800`ifelse(eval($2-0==0),1,$1,
801`ifelse(eval($2>0),1,
802`m4_lshift_internal(eval($1*2),decr($2))',
803`m4_lshift_internal(m4_div2_towards_zero($1),incr($2))')')')
804
805
806dnl Usage: m4_popcount(n)
807dnl
808dnl Expand to the number 1 bits in n.
809
810define(m4_popcount,
811m4_assert_numargs(1)
812`m4_popcount_internal(0,eval(`$1'))')
813
814dnl Called: m4_popcount_internal(count,rem)
815define(m4_popcount_internal,
816m4_assert_numargs(2)
817`ifelse($2,0,$1,
818`m4_popcount_internal(eval($1+($2%2)),eval($2/2))')')
819
820
821dnl Usage: m4_count_trailing_zeros(N)
822dnl
823dnl Determine the number of trailing zero bits on N. N is eval()ed and so
824dnl can be an expression. If N is zero an error is generated.
825
826define(m4_count_trailing_zeros,
827m4_assert_numargs(1)
828`m4_count_trailing_zeros_internal(eval(`$1'),0)')
829
830dnl Called: m4_count_trailing_zeros_internal(val,count)
831define(m4_count_trailing_zeros_internal,
832m4_assert_numargs(2)
833`ifelse($1,0,
834`m4_error(`m4_count_trailing_zeros() given a zero value')',
835`ifelse(eval(($1)%2),1,`$2',
836`m4_count_trailing_zeros_internal(eval($1/2),incr($2))')')')
837
838
839dnl Usage: deflit(name,value)
840dnl
841dnl Like define(), but "name" expands like a literal, rather than taking
842dnl arguments. For example "name(%eax)" expands to "value(%eax)".
843dnl
844dnl Limitations:
845dnl
846dnl $ characters in the value part must have quotes to stop them looking
847dnl like macro parameters. For example, deflit(reg,`123+$`'4+567'). See
848dnl defreg() below for handling simple register definitions like $7 etc.
849dnl
850dnl "name()" is turned into "name", unfortunately. In GNU and SysV m4 an
851dnl error is generated when this happens, but in BSD m4 it will happen
852dnl silently. The problem is that in BSD m4 $# is 1 in both "name" or
853dnl "name()", so there's no way to differentiate them. Because we want
854dnl plain "name" to turn into plain "value", we end up with "name()"
855dnl turning into plain "value" too.
856dnl
857dnl "name(foo)" will lose any whitespace after commas in "foo", for example
858dnl "disp(%eax, %ecx)" would become "128(%eax,%ecx)".
859dnl
860dnl These parentheses oddities shouldn't matter in assembler text, but if
861dnl they do the suggested workaround is to write "name ()" or "name (foo)"
862dnl to stop the parentheses looking like a macro argument list. If a space
863dnl isn't acceptable in the output, then write "name`'()" or "name`'(foo)".
864dnl The `' is stripped when read, but again stops the parentheses looking
865dnl like parameters.
866
867dnl Quoting for deflit_emptyargcheck is similar to m4_assert_numargs. The
868dnl stuff in the ifelse gives a $#, $1 and $@ evaluated in the new macro
869dnl created, not in deflit.
870define(deflit,
871m4_assert_numargs(2)
872`define(`$1',
873`deflit_emptyargcheck'(``$1'',$`#',m4_doublequote($`'1))`dnl
874$2`'dnl
875ifelse(eval($'`#>1 || m4_length('m4_doublequote($`'1)`)!=0),1,($'`@))')')
876
877dnl Called: deflit_emptyargcheck(macroname,$#,`$1')
878define(deflit_emptyargcheck,
879`ifelse(eval($2==1 && !m4_dollarhash_1_if_noparen_p && m4_length(`$3')==0),1,
880`m4_error(`dont use a deflit as $1() because it loses the brackets (see deflit in asm-defs.m4 for more information)
881')')')
882
883
884dnl Usage: m4_assert(`expr')
885dnl
886dnl Test a compile-time requirement with an m4 expression. The expression
887dnl should be quoted, and will be eval()ed and expected to be non-zero.
888dnl For example,
889dnl
890dnl m4_assert(`FOO*2+6 < 14')
891
892define(m4_assert,
893m4_assert_numargs(1)
894`ifelse(eval($1),1,,
895`m4_error(`assertion failed: $1
896')')')
897
898
899dnl Usage: m4_repeat(count,text)
900dnl
901dnl Expand to the given repetitions of the given text. A zero count is
902dnl allowed, and expands to nothing.
903
904define(m4_repeat,
905m4_assert_numargs(2)
906`m4_repeat_internal(eval($1),`$2')')
907
908define(m4_repeat_internal,
909m4_assert_numargs(2)
910`ifelse(`$1',0,,
911`forloop(m4_repeat_internal_counter,1,$1,``$2'')')')
912
913
914dnl Usage: m4_hex_lowmask(bits)
915dnl
916dnl Generate a hex constant which is a low mask of the given number of
917dnl bits. For example m4_hex_lowmask(10) would give 0x3ff.
918
919define(m4_hex_lowmask,
920m4_assert_numargs(1)
921`m4_cpu_hex_constant(m4_hex_lowmask_internal1(eval(`$1')))')
922
923dnl Called: m4_hex_lowmask_internal1(bits)
924define(m4_hex_lowmask_internal1,
925m4_assert_numargs(1)
926`ifelse($1,0,`0',
927`m4_hex_lowmask_internal2(eval(($1)%4),eval(($1)/4))')')
928
929dnl Called: m4_hex_lowmask_internal(remainder,digits)
930define(m4_hex_lowmask_internal2,
931m4_assert_numargs(2)
932`ifelse($1,1,`1',
933`ifelse($1,2,`3',
934`ifelse($1,3,`7')')')dnl
935m4_repeat($2,`f')')
936
937
938dnl --------------------------------------------------------------------------
939dnl The following m4_list functions take a list as multiple arguments.
940dnl Arguments are evaluated multiple times, there's no attempt at strict
941dnl quoting. Empty list elements are not allowed, since an empty final
942dnl argument is ignored. These restrictions don't affect the current uses,
943dnl and make the implementation easier.
944
945
946dnl Usage: m4_list_quote(list,...)
947dnl
948dnl Produce a list with quoted commas, so it can be a single argument
949dnl string. For instance m4_list_quote(a,b,c) gives
950dnl
951dnl a`,'b`,'c`,'
952dnl
953dnl This can be used to put a list in a define,
954dnl
955dnl define(foolist, m4_list_quote(a,b,c))
956dnl
957dnl Which can then be used for instance as
958dnl
959dnl m4_list_find(target, foolist)
960
961define(m4_list_quote,
962`ifelse(`$1',,,
963`$1`,'m4_list_quote(shift($@))')')
964
965
966dnl Usage: m4_list_find(key,list,...)
967dnl
968dnl Evaluate to 1 or 0 according to whether key is in the list elements.
969
970define(m4_list_find,
971m4_assert_numargs_range(1,1000)
972`ifelse(`$2',,0,
973`ifelse(`$1',`$2',1,
974`m4_list_find(`$1',shift(shift($@)))')')')
975
976
977dnl Usage: m4_list_remove(key,list,...)
978dnl
979dnl Evaluate to the given list with `key' removed (if present).
980
981define(m4_list_remove,
982m4_assert_numargs_range(1,1000)
983`ifelse(`$2',,,
984`ifelse(`$1',`$2',,`$2,')dnl
985m4_list_remove(`$1',shift(shift($@)))')')
986
987
988dnl Usage: m4_list_first(list,...)
989dnl
990dnl Evaluate to the first element of the list (if any).
991
992define(m4_list_first,`$1')
993
994
995dnl Usage: m4_list_count(list,...)
996dnl
997dnl Evaluate to the number of elements in the list. This can't just use $#
998dnl because the last element might be empty.
999
1000define(m4_list_count,
1001`m4_list_count_internal(0,$@)')
1002
1003dnl Called: m4_list_internal(count,list,...)
1004define(m4_list_count_internal,
1005m4_assert_numargs_range(1,1000)
1006`ifelse(`$2',,$1,
1007`m4_list_count_internal(eval($1+1),shift(shift($@)))')')
1008
1009
1010dnl --------------------------------------------------------------------------
1011dnl Various assembler things, not specific to any particular CPU.
1012dnl
1013
1014
1015dnl Usage: include_mpn(`filename')
1016dnl
1017dnl Like include(), but adds a path to the mpn source directory. For
1018dnl example,
1019dnl
1020dnl include_mpn(`sparc64/addmul_1h.asm')
1021
1022define(include_mpn,
1023m4_assert_numargs(1)
1024m4_assert_defined(`CONFIG_TOP_SRCDIR')
1025`include(CONFIG_TOP_SRCDIR`/mpn/$1')')
1026
1027
1028dnl Usage: C comment ...
1029dnl
1030dnl This works like a FORTRAN-style comment character. It can be used for
1031dnl comments to the right of assembly instructions, where just dnl would
1032dnl remove the newline and concatenate adjacent lines.
1033dnl
1034dnl C and/or dnl are useful when an assembler doesn't support comments, or
1035dnl where different assemblers for a particular CPU need different styles.
1036dnl The intermediate ".s" files will end up with no comments, just code.
1037dnl
1038dnl Using C is not intended to cause offence to anyone who doesn't like
1039dnl FORTRAN; but if that happens it's an unexpected bonus.
1040dnl
1041dnl During development, if comments are wanted in the .s files to help see
1042dnl what's expanding where, C can be redefined with something like
1043dnl
1044dnl define(`C',`#')
1045
1046define(C, `
1047dnl')
1048
1049
1050dnl Normally PIC is defined (or not) by libtool, but it doesn't set it on
1051dnl systems which are always PIC. PIC_ALWAYS established in config.m4
1052dnl identifies these for us.
1053
1054ifelse(`PIC_ALWAYS',`yes',`define(`PIC')')
1055
1056
1057dnl Various possible defines passed from the Makefile that are to be tested
1058dnl with ifdef() rather than be expanded.
1059
1060m4_not_for_expansion(`PIC')
1061m4_not_for_expansion(`DLL_EXPORT')
1062
1063dnl aors_n
1064m4_not_for_expansion(`OPERATION_add_n')
1065m4_not_for_expansion(`OPERATION_sub_n')
1066
1067dnl aors_err1_n
1068m4_not_for_expansion(`OPERATION_add_err1_n')
1069m4_not_for_expansion(`OPERATION_sub_err1_n')
1070
1071dnl aors_err2_n
1072m4_not_for_expansion(`OPERATION_add_err2_n')
1073m4_not_for_expansion(`OPERATION_sub_err2_n')
1074
1075dnl aors_err3_n
1076m4_not_for_expansion(`OPERATION_add_err3_n')
1077m4_not_for_expansion(`OPERATION_sub_err3_n')
1078
1079dnl aorsmul_1
1080m4_not_for_expansion(`OPERATION_addmul_1')
1081m4_not_for_expansion(`OPERATION_submul_1')
1082
1083dnl logops_n
1084m4_not_for_expansion(`OPERATION_and_n')
1085m4_not_for_expansion(`OPERATION_andn_n')
1086m4_not_for_expansion(`OPERATION_nand_n')
1087m4_not_for_expansion(`OPERATION_ior_n')
1088m4_not_for_expansion(`OPERATION_iorn_n')
1089m4_not_for_expansion(`OPERATION_nior_n')
1090m4_not_for_expansion(`OPERATION_xor_n')
1091m4_not_for_expansion(`OPERATION_xnor_n')
1092
1093dnl popham
1094m4_not_for_expansion(`OPERATION_popcount')
1095m4_not_for_expansion(`OPERATION_hamdist')
1096
1097dnl lorrshift
1098m4_not_for_expansion(`OPERATION_lshift')
1099m4_not_for_expansion(`OPERATION_rshift')
1100
1101dnl aorslsh1_n
1102m4_not_for_expansion(`OPERATION_addlsh1_n')
1103m4_not_for_expansion(`OPERATION_sublsh1_n')
1104m4_not_for_expansion(`OPERATION_rsblsh1_n')
1105
1106dnl aorslsh2_n
1107m4_not_for_expansion(`OPERATION_addlsh2_n')
1108m4_not_for_expansion(`OPERATION_sublsh2_n')
1109m4_not_for_expansion(`OPERATION_rsblsh2_n')
1110
1111dnl rsh1aors_n
1112m4_not_for_expansion(`OPERATION_rsh1add_n')
1113m4_not_for_expansion(`OPERATION_rsh1sub_n')
1114
1115
1116dnl Usage: m4_config_gmp_mparam(`symbol')
1117dnl
1118dnl Check that `symbol' is defined. If it isn't, issue an error and
1119dnl terminate immediately. The error message explains that the symbol
1120dnl should be in config.m4, copied from gmp-mparam.h.
1121dnl
1122dnl Termination is immediate since missing say SQR_TOOM2_THRESHOLD can
1123dnl lead to infinite loops and endless error messages.
1124
1125define(m4_config_gmp_mparam,
1126m4_assert_numargs(1)
1127`ifdef(`$1',,
1128`m4_error(`$1 is not defined.
1129 "configure" should have extracted this from gmp-mparam.h and put it
1130 in config.m4 (or in <cpu>_<file>.asm for a fat binary), but somehow
1131 this has failed.
1132')m4exit(1)')')
1133
1134
1135dnl Usage: defreg(name,reg)
1136dnl
1137dnl Give a name to a $ style register. For example,
1138dnl
1139dnl defreg(foo,$12)
1140dnl
1141dnl defreg() inserts an extra pair of quotes after the $ so that it's not
1142dnl interpreted as an m4 macro parameter, ie. foo is actually $`'12. m4
1143dnl strips those quotes when foo is expanded.
1144dnl
1145dnl deflit() is used to make the new definition, so it will expand
1146dnl literally even if followed by parentheses ie. foo(99) will become
1147dnl $12(99). (But there's nowhere that would be used is there?)
1148dnl
1149dnl When making further definitions from existing defreg() macros, remember
1150dnl to use defreg() again to protect the $ in the new definitions too. For
1151dnl example,
1152dnl
1153dnl defreg(a0,$4)
1154dnl defreg(a1,$5)
1155dnl ...
1156dnl
1157dnl defreg(PARAM_DST,a0)
1158dnl
1159dnl This is only because a0 is expanding at the time the PARAM_DST
1160dnl definition is made, leaving a literal $4 that must be re-quoted. On
1161dnl the other hand in something like the following ra is only expanded when
1162dnl ret is used and its $`'31 protection will have its desired effect at
1163dnl that time.
1164dnl
1165dnl defreg(ra,$31)
1166dnl ...
1167dnl define(ret,`j ra')
1168dnl
1169dnl Note that only $n forms are meant to be used here, and something like
1170dnl 128($30) doesn't get protected and will come out wrong.
1171
1172define(defreg,
1173m4_assert_numargs(2)
1174`deflit(`$1',
1175substr(`$2',0,1)``''substr(`$2',1))')
1176
1177
1178dnl Usage: m4_instruction_wrapper()
1179dnl
1180dnl Put this, unquoted, on a line on its own, at the start of a macro
1181dnl that's a wrapper around an assembler instruction. It adds code to give
1182dnl a descriptive error message if the macro is invoked without arguments.
1183dnl
1184dnl For example, suppose jmp needs to be wrapped,
1185dnl
1186dnl define(jmp,
1187dnl m4_instruction_wrapper()
1188dnl m4_assert_numargs(1)
1189dnl `.byte 0x42
1190dnl .long $1
1191dnl nop')
1192dnl
1193dnl The point of m4_instruction_wrapper is to get a better error message
1194dnl than m4_assert_numargs would give if jmp is accidentally used as plain
1195dnl "jmp foo" instead of the intended "jmp( foo)". "jmp()" with no
1196dnl argument also provokes the error message.
1197dnl
1198dnl m4_instruction_wrapper should only be used with wrapped instructions
1199dnl that take arguments, since obviously something meant to be used as say
1200dnl plain "ret" doesn't want to give an error when used that way.
1201
1202define(m4_instruction_wrapper,
1203m4_assert_numargs(0)
1204``m4_instruction_wrapper_internal'(m4_doublequote($`'0),dnl
1205ifdef(`__file__',`m4_doublequote(__file__)',``the m4 sources''),dnl
1206$`#',m4_doublequote($`'1))`dnl'')
1207
1208dnl Called: m4_instruction_wrapper_internal($0,`filename',$#,$1)
1209define(m4_instruction_wrapper_internal,
1210`ifelse(eval($3<=1 && m4_length(`$4')==0),1,
1211`m4_error(`$1 is a macro replacing that instruction and needs arguments, see $2 for details
1212')')')
1213
1214
1215dnl Usage: m4_cpu_hex_constant(string)
1216dnl
1217dnl Expand to the string prefixed by a suitable `0x' hex marker. This
1218dnl should be redefined as necessary for CPUs with different conventions.
1219
1220define(m4_cpu_hex_constant,
1221m4_assert_numargs(1)
1222`0x`$1'')
1223
1224
1225dnl Usage: UNROLL_LOG2, UNROLL_MASK, UNROLL_BYTES
1226dnl CHUNK_LOG2, CHUNK_MASK, CHUNK_BYTES
1227dnl
1228dnl When code supports a variable amount of loop unrolling, the convention
1229dnl is to define UNROLL_COUNT to the number of limbs processed per loop.
1230dnl When testing code this can be varied to see how much the loop overhead
1231dnl is costing. For example,
1232dnl
1233dnl deflit(UNROLL_COUNT, 32)
1234dnl
1235dnl If the forloop() generating the unrolled loop has a pattern processing
1236dnl more than one limb, the convention is to express this with CHUNK_COUNT.
1237dnl For example,
1238dnl
1239dnl deflit(CHUNK_COUNT, 2)
1240dnl
1241dnl The LOG2, MASK and BYTES definitions below are derived from these COUNT
1242dnl definitions. If COUNT is redefined, the LOG2, MASK and BYTES follow
1243dnl the new definition automatically.
1244dnl
1245dnl LOG2 is the log base 2 of COUNT. MASK is COUNT-1, which can be used as
1246dnl a bit mask. BYTES is GMP_LIMB_BYTES*COUNT, the number of bytes
1247dnl processed in each unrolled loop.
1248dnl
1249dnl GMP_LIMB_BYTES is defined in a CPU specific m4 include file. It
1250dnl exists only so the BYTES definitions here can be common to all CPUs.
1251dnl In the actual code for a given CPU, an explicit 4 or 8 may as well be
1252dnl used because the code is only for a particular CPU, it doesn't need to
1253dnl be general.
1254dnl
1255dnl Note that none of these macros do anything except give conventional
1256dnl names to commonly used things. You still have to write your own
1257dnl expressions for a forloop() and the resulting address displacements.
1258dnl Something like the following would be typical for 4 bytes per limb.
1259dnl
1260dnl forloop(`i',0,UNROLL_COUNT-1,`
1261dnl deflit(`disp',eval(i*4))
1262dnl ...
1263dnl ')
1264dnl
1265dnl Or when using CHUNK_COUNT,
1266dnl
1267dnl forloop(`i',0,UNROLL_COUNT/CHUNK_COUNT-1,`
1268dnl deflit(`disp0',eval(i*CHUNK_COUNT*4))
1269dnl deflit(`disp1',eval(disp0+4))
1270dnl ...
1271dnl ')
1272dnl
1273dnl Clearly `i' can be run starting from 1, or from high to low or whatever
1274dnl best suits.
1275
1276deflit(UNROLL_LOG2,
1277m4_assert_defined(`UNROLL_COUNT')
1278`m4_log2(UNROLL_COUNT)')
1279
1280deflit(UNROLL_MASK,
1281m4_assert_defined(`UNROLL_COUNT')
1282`eval(UNROLL_COUNT-1)')
1283
1284deflit(UNROLL_BYTES,
1285m4_assert_defined(`UNROLL_COUNT')
1286m4_assert_defined(`GMP_LIMB_BYTES')
1287`eval(UNROLL_COUNT * GMP_LIMB_BYTES)')
1288
1289deflit(CHUNK_LOG2,
1290m4_assert_defined(`CHUNK_COUNT')
1291`m4_log2(CHUNK_COUNT)')
1292
1293deflit(CHUNK_MASK,
1294m4_assert_defined(`CHUNK_COUNT')
1295`eval(CHUNK_COUNT-1)')
1296
1297deflit(CHUNK_BYTES,
1298m4_assert_defined(`CHUNK_COUNT')
1299m4_assert_defined(`GMP_LIMB_BYTES')
1300`eval(CHUNK_COUNT * GMP_LIMB_BYTES)')
1301
1302
1303dnl Usage: MPN(name)
1304dnl
1305dnl Add MPN_PREFIX to a name.
1306dnl MPN_PREFIX defaults to "__gmpn_" if not defined.
1307dnl
1308dnl m4_unquote is used in MPN so that when it expands to say __gmpn_foo,
1309dnl that identifier will be subject to further macro expansion. This is
1310dnl used by some of the fat binary support for renaming symbols.
1311
1312ifdef(`MPN_PREFIX',,
1313`define(`MPN_PREFIX',`__gmpn_')')
1314
1315define(MPN,
1316m4_assert_numargs(1)
1317`m4_unquote(MPN_PREFIX`'$1)')
1318
1319
1320dnl Usage: mpn_add_n, etc
1321dnl
1322dnl Convenience definitions using MPN(), like the #defines in gmp.h. Each
1323dnl function that might be implemented in assembler is here.
1324
1325define(define_mpn,
1326m4_assert_numargs(1)
1327`deflit(`mpn_$1',`MPN(`$1')')')
1328
1329define_mpn(add)
1330define_mpn(add_1)
1331define_mpn(add_err1_n)
1332define_mpn(add_err2_n)
1333define_mpn(add_err3_n)
1334define_mpn(add_n)
1335define_mpn(add_nc)
1336define_mpn(addlsh1_n)
1337define_mpn(addlsh1_nc)
1338define_mpn(addlsh2_n)
1339define_mpn(addlsh2_nc)
1340define_mpn(addlsh_n)
1341define_mpn(addlsh_nc)
1342define_mpn(addlsh1_n_ip1)
1343define_mpn(addlsh1_nc_ip1)
1344define_mpn(addlsh2_n_ip1)
1345define_mpn(addlsh2_nc_ip1)
1346define_mpn(addlsh_n_ip1)
1347define_mpn(addlsh_nc_ip1)
1348define_mpn(addlsh1_n_ip2)
1349define_mpn(addlsh1_nc_ip2)
1350define_mpn(addlsh2_n_ip2)
1351define_mpn(addlsh2_nc_ip2)
1352define_mpn(addlsh_n_ip2)
1353define_mpn(addlsh_nc_ip2)
1354define_mpn(addmul_1)
1355define_mpn(addmul_1c)
1356define_mpn(addmul_2)
1357define_mpn(addmul_3)
1358define_mpn(addmul_4)
1359define_mpn(addmul_5)
1360define_mpn(addmul_6)
1361define_mpn(addmul_7)
1362define_mpn(addmul_8)
1363define_mpn(addmul_2s)
1364define_mpn(add_n_sub_n)
1365define_mpn(add_n_sub_nc)
1366define_mpn(addaddmul_1msb0)
1367define_mpn(and_n)
1368define_mpn(andn_n)
1369define_mpn(bdiv_q_1)
1370define_mpn(pi1_bdiv_q_1)
1371define_mpn(bdiv_dbm1c)
1372define_mpn(cmp)
1373define_mpn(cnd_add_n)
1374define_mpn(cnd_sub_n)
1375define_mpn(com)
1376define_mpn(copyd)
1377define_mpn(copyi)
1378define_mpn(count_leading_zeros)
1379define_mpn(count_trailing_zeros)
1380define_mpn(div_qr_1n_pi1)
1381define_mpn(div_qr_2)
1382define_mpn(div_qr_2n_pi1)
1383define_mpn(div_qr_2u_pi1)
1384define_mpn(div_qr_2n_pi2)
1385define_mpn(div_qr_2u_pi2)
1386define_mpn(divexact_1)
1387define_mpn(divexact_by3c)
1388define_mpn(divrem)
1389define_mpn(divrem_1)
1390define_mpn(divrem_1c)
1391define_mpn(divrem_2)
1392define_mpn(divrem_classic)
1393define_mpn(divrem_newton)
1394define_mpn(dump)
1395define_mpn(gcd)
1396define_mpn(gcd_1)
1397define_mpn(gcd_11)
1398define_mpn(gcd_22)
1399define_mpn(gcdext)
1400define_mpn(get_str)
1401define_mpn(hamdist)
1402define_mpn(invert_limb)
1403define_mpn(invert_limb_table)
1404define_mpn(ior_n)
1405define_mpn(iorn_n)
1406define_mpn(lshift)
1407define_mpn(lshiftc)
1408define_mpn(mod_1_1p)
1409define_mpn(mod_1_1p_cps)
1410define_mpn(mod_1s_2p)
1411define_mpn(mod_1s_2p_cps)
1412define_mpn(mod_1s_3p)
1413define_mpn(mod_1s_3p_cps)
1414define_mpn(mod_1s_4p)
1415define_mpn(mod_1s_4p_cps)
1416define_mpn(mod_1)
1417define_mpn(mod_1c)
1418define_mpn(mod_34lsub1)
1419define_mpn(modexact_1_odd)
1420define_mpn(modexact_1c_odd)
1421define_mpn(mul)
1422define_mpn(mul_1)
1423define_mpn(mul_1c)
1424define_mpn(mul_2)
1425define_mpn(mul_3)
1426define_mpn(mul_4)
1427define_mpn(mul_5)
1428define_mpn(mul_6)
1429define_mpn(mul_basecase)
1430define_mpn(mul_n)
1431define_mpn(mullo_basecase)
1432define_mpn(mulmid_basecase)
1433define_mpn(perfect_square_p)
1434define_mpn(popcount)
1435define_mpn(preinv_divrem_1)
1436define_mpn(preinv_mod_1)
1437define_mpn(nand_n)
1438define_mpn(neg)
1439define_mpn(nior_n)
1440define_mpn(powm)
1441define_mpn(powlo)
1442define_mpn(random)
1443define_mpn(random2)
1444define_mpn(redc_1)
1445define_mpn(redc_2)
1446define_mpn(rsblsh1_n)
1447define_mpn(rsblsh1_nc)
1448define_mpn(rsblsh2_n)
1449define_mpn(rsblsh2_nc)
1450define_mpn(rsblsh_n)
1451define_mpn(rsblsh_nc)
1452define_mpn(rsh1add_n)
1453define_mpn(rsh1add_nc)
1454define_mpn(rsh1sub_n)
1455define_mpn(rsh1sub_nc)
1456define_mpn(rshift)
1457define_mpn(rshiftc)
1458define_mpn(sbpi1_bdiv_q)
1459define_mpn(sbpi1_bdiv_qr)
1460define_mpn(sbpi1_bdiv_r)
1461define_mpn(scan0)
1462define_mpn(scan1)
1463define_mpn(set_str)
1464define_mpn(sqr_basecase)
1465define_mpn(sqr_diagonal)
1466define_mpn(sqr_diag_addlsh1)
1467define_mpn(sub_n)
1468define_mpn(sublsh1_n)
1469define_mpn(sublsh1_nc)
1470define_mpn(sublsh1_n_ip1)
1471define_mpn(sublsh1_nc_ip1)
1472define_mpn(sublsh2_n)
1473define_mpn(sublsh2_nc)
1474define_mpn(sublsh2_n_ip1)
1475define_mpn(sublsh2_nc_ip1)
1476define_mpn(sublsh_n)
1477define_mpn(sublsh_nc)
1478define_mpn(sublsh_n_ip1)
1479define_mpn(sublsh_nc_ip1)
1480define_mpn(sqrtrem)
1481define_mpn(sub)
1482define_mpn(sub_1)
1483define_mpn(sub_err1_n)
1484define_mpn(sub_err2_n)
1485define_mpn(sub_err3_n)
1486define_mpn(sub_n)
1487define_mpn(sub_nc)
1488define_mpn(submul_1)
1489define_mpn(submul_1c)
1490define_mpn(sec_tabselect)
1491define_mpn(umul_ppmm)
1492define_mpn(umul_ppmm_r)
1493define_mpn(udiv_qrnnd)
1494define_mpn(udiv_qrnnd_r)
1495define_mpn(xnor_n)
1496define_mpn(xor_n)
1497
1498
1499dnl Defines for C global arrays and variables, with names matching what's
1500dnl used in the C code.
1501dnl
1502dnl Notice that GSYM_PREFIX is included, unlike with the function defines
1503dnl above. Also, "deflit" is used so that something like __clz_tab(%ebx)
1504dnl comes out as __gmpn_clz_tab(%ebx), for the benefit of CPUs with that
1505dnl style assembler syntax.
1506
1507deflit(__clz_tab,
1508m4_assert_defined(`GSYM_PREFIX')
1509`GSYM_PREFIX`'MPN(`clz_tab')')
1510
1511deflit(binvert_limb_table,
1512m4_assert_defined(`GSYM_PREFIX')
1513`GSYM_PREFIX`'__gmp_binvert_limb_table')
1514
1515
1516dnl Usage: ASM_START()
1517dnl
1518dnl Emit any directives needed once at the start of an assembler file, like
1519dnl ".set noreorder" or whatever. The default for this is nothing, but
1520dnl it's redefined by CPU specific m4 files.
1521
1522define(ASM_START)
1523
1524
1525dnl Usage: ASM_END()
1526dnl
1527dnl Emit any directives needed once at the end of an assembler file. The
1528dnl default for this is nothing, but it's redefined by CPU specific m4 files.
1529
1530define(ASM_END)
1531
1532
1533dnl Usage: PROLOGUE(foo[,param])
1534dnl EPILOGUE(foo)
1535dnl
1536dnl Emit directives to start or end a function. GSYM_PREFIX is added by
1537dnl these macros if necessary, so the given "foo" is what the function will
1538dnl be called in C.
1539dnl
1540dnl The second parameter to PROLOGUE is used only for some CPUs and should
1541dnl be omitted if not required.
1542dnl
1543dnl Nested or overlapping PROLOGUE/EPILOGUE pairs are allowed, if that
1544dnl makes sense for the system. The name given to EPILOGUE must be a
1545dnl currently open PROLOGUE.
1546dnl
1547dnl If only one PROLOGUE is open then the name can be omitted from
1548dnl EPILOGUE. This is encouraged, since it means the name only has to
1549dnl appear in one place, not two.
1550dnl
1551dnl The given name "foo" is not fully quoted here, it will be macro
1552dnl expanded more than once. This is the way the m4_list macros work, and
1553dnl it also helps the tune/many.pl program do a renaming like
1554dnl -D__gmpn_add_n=mpn_add_n_foo when GSYM_PREFIX is not empty.
1555
1556define(PROLOGUE,
1557m4_assert_numargs_range(1,2)
1558`m4_file_seen()dnl
1559define(`PROLOGUE_list',m4_list_quote($1,PROLOGUE_list))dnl
1560ifelse(`$2',,
1561`PROLOGUE_cpu(GSYM_PREFIX`'$1)',
1562`PROLOGUE_cpu(GSYM_PREFIX`'$1,`$2')')')
1563
1564define(EPILOGUE,
1565m4_assert_numargs_range(0,1)
1566`ifelse(`$1',,
1567`ifelse(m4_list_count(PROLOGUE_list),0,
1568`m4_error(`no open functions for EPILOGUE
1569')',
1570`ifelse(m4_list_count(PROLOGUE_list),1,
1571`EPILOGUE_internal(PROLOGUE_current_function)',
1572`m4_error(`more than one open function for EPILOGUE
1573')')')',
1574`EPILOGUE_internal(`$1')')')
1575
1576define(EPILOGUE_internal,
1577m4_assert_numargs(1)
1578m4_assert_defined(`EPILOGUE_cpu')
1579`ifelse(m4_list_find($1,PROLOGUE_list),0,
1580`m4_error(`EPILOGUE without PROLOGUE: $1
1581')')dnl
1582define(`PROLOGUE_list',m4_list_quote(m4_list_remove($1,PROLOGUE_list)))dnl
1583EPILOGUE_cpu(GSYM_PREFIX`$1')')
1584
1585dnl Currently open PROLOGUEs, as a comma-separated list.
1586define(PROLOGUE_list)
1587
1588
1589dnl Called: PROLOGUE_check(list,...)
1590dnl Check there's no remaining open PROLOGUEs at the end of input.
1591define(PROLOGUE_check,
1592`ifelse($1,,,
1593`m4_error(`no EPILOGUE for: $1
1594')dnl
1595PROLOGUE_check(shift($@))')')
1596
1597m4wrap_prepend(`PROLOGUE_check(PROLOGUE_list)')
1598
1599
1600dnl Usage: PROLOGUE_current_function
1601dnl
1602dnl This macro expands to the current PROLOGUE/EPILOGUE function, or the
1603dnl most recent PROLOGUE if such pairs are nested or overlapped.
1604
1605define(PROLOGUE_current_function,
1606m4_assert_numargs(-1)
1607`m4_list_first(PROLOGUE_list)')
1608
1609
1610dnl Usage: PROLOGUE_cpu(GSYM_PREFIX`'foo[,param])
1611dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
1612dnl
1613dnl These macros hold the CPU-specific parts of PROLOGUE and EPILOGUE.
1614dnl Both are called with the function name, with GSYM_PREFIX already
1615dnl prepended.
1616dnl
1617dnl The definitions here are something typical and sensible, but CPU or
1618dnl system specific m4 files should redefine them as necessary. The
1619dnl optional extra parameter to PROLOGUE_cpu is not expected and not
1620dnl accepted here.
1621
1622define(PROLOGUE_cpu,
1623m4_assert_numargs(1)
1624` TEXT
1625 ALIGN(8)
1626 GLOBL `$1' GLOBL_ATTR
1627 TYPE(`$1',`function')
1628`$1'LABEL_SUFFIX')
1629
1630define(EPILOGUE_cpu,
1631` SIZE(`$1',.-`$1')')
1632
1633
1634dnl Usage: L(name)
1635dnl
1636dnl Generate a local label with the given name. This is simply a
1637dnl convenient way to add LSYM_PREFIX.
1638dnl
1639dnl LSYM_PREFIX might be L$, so defn() must be used to quote it or the L
1640dnl will expand again as the L macro, making an infinite recursion.
1641
1642define(`L',
1643m4_assert_numargs(1)
1644`defn(`LSYM_PREFIX')$1')
1645
1646
1647dnl Usage: LDEF(name)
1648dnl
1649dnl Generate a directive to define a local label.
1650dnl
1651dnl On systems with a fixed syntax for defining labels there's no need to
1652dnl use this macro, it's only meant for systems where the syntax varies,
1653dnl like hppa which is "L(foo):" with gas, but just "L(foo)" in column 0
1654dnl with the system `as'.
1655dnl
1656dnl The extra `' after LABEL_SUFFIX avoids any chance of a following
1657dnl "(...)" being interpreted as an argument list. Not that it'd be
1658dnl sensible to write anything like that after an LDEF(), but just in case.
1659
1660define(LDEF,
1661m4_assert_numargs(1)
1662m4_assert_defined(`LABEL_SUFFIX')
1663`L(`$1')`'LABEL_SUFFIX`'')
1664
1665
1666dnl Usage: INT32(label,value)
1667dnl INT64(label,first,second)
1668
1669define(`INT32',
1670m4_assert_defined(`W32')
1671` ALIGN(4)
1672LDEF(`$1')
1673 W32 $2')
1674
1675define(`INT64',
1676m4_assert_defined(`W32')
1677` ALIGN(8)
1678LDEF(`$1')
1679 W32 $2
1680 W32 $3')
1681
1682
1683dnl Usage: ALIGN(bytes)
1684dnl
1685dnl Emit a ".align" directive. The alignment is specified in bytes, and
1686dnl will normally need to be a power of 2. The actual ".align" generated
1687dnl is either bytes or logarithmic according to what ./configure finds the
1688dnl assembler needs.
1689dnl
1690dnl If ALIGN_FILL_0x90 is defined and equal to "yes", then ", 0x90" is
1691dnl appended. This is for x86, see mpn/x86/README.
1692
1693define(ALIGN,
1694m4_assert_numargs(1)
1695m4_assert_defined(`ALIGN_LOGARITHMIC')
1696`.align ifelse(ALIGN_LOGARITHMIC,yes,`m4_log2($1)',`eval($1)')dnl
1697ifelse(ALIGN_FILL_0x90,yes,`, 0x90')')
1698
1699
1700dnl Usage: MULFUNC_PROLOGUE(function function...)
1701dnl
1702dnl A dummy macro which is grepped for by ./configure to know what
1703dnl functions a multi-function file is providing. Use this if there aren't
1704dnl explicit PROLOGUE()s for each possible function.
1705dnl
1706dnl Multiple MULFUNC_PROLOGUEs can be used, or just one with the function
1707dnl names separated by spaces.
1708
1709define(`MULFUNC_PROLOGUE',
1710m4_assert_numargs(1)
1711)
1712
1713
1714dnl Usage: NAILS_SUPPORT(spec spec ...)
1715dnl
1716dnl A dummy macro which is grepped for by ./configure to know what nails
1717dnl are supported in an asm file.
1718dnl
1719dnl Ranges can be given, or just individual values. Multiple values or
1720dnl ranges can be given, separated by spaces. Multiple NAILS_SUPPORT
1721dnl declarations work too. Some examples,
1722dnl
1723dnl NAILS_SUPPORT(1-20)
1724dnl NAILS_SUPPORT(1 6 9-12)
1725dnl NAILS_SUPPORT(1-10 16-20)
1726
1727define(NAILS_SUPPORT,
1728m4_assert_numargs(1)
1729)
1730
1731
1732dnl Usage: ABI_SUPPORT(abi)
1733dnl
1734dnl A dummy macro which is grepped for by ./configure to know what ABIs
1735dnl are supported in an asm file.
1736dnl
1737dnl If multiple non-standard ABIs are supported, several ABI_SUPPORT
1738dnl declarations should be used:
1739dnl
1740dnl ABI_SUPPORT(FOOABI)
1741dnl ABI_SUPPORT(BARABI)
1742
1743define(ABI_SUPPORT,
1744m4_assert_numargs(1)
1745)
1746
1747
1748dnl Usage: GMP_NUMB_MASK
1749dnl
1750dnl A bit mask for the number part of a limb. Eg. with 6 bit nails in a
1751dnl 32 bit limb, GMP_NUMB_MASK would be 0x3ffffff.
1752
1753define(GMP_NUMB_MASK,
1754m4_assert_numargs(-1)
1755m4_assert_defined(`GMP_NUMB_BITS')
1756`m4_hex_lowmask(GMP_NUMB_BITS)')
1757
1758
1759dnl Usage: m4append(`variable',`value-to-append')
1760
1761define(`m4append',
1762`define(`$1', defn(`$1')`$2')
1763'
1764)
1765
1766divert`'dnl