Blame mpn/asm-defs.m4

Packit 5c3484
divert(-1)
Packit 5c3484
dnl
Packit 5c3484
dnl  m4 macros for gmp assembly code, shared by all CPUs.
Packit 5c3484
Packit 5c3484
dnl  Copyright 1999-2006, 2011 Free Software Foundation, Inc.
Packit 5c3484
Packit 5c3484
dnl  This file is part of the GNU MP Library.
Packit 5c3484
dnl
Packit 5c3484
dnl  The GNU MP Library is free software; you can redistribute it and/or modify
Packit 5c3484
dnl  it under the terms of either:
Packit 5c3484
dnl
Packit 5c3484
dnl    * the GNU Lesser General Public License as published by the Free
Packit 5c3484
dnl      Software Foundation; either version 3 of the License, or (at your
Packit 5c3484
dnl      option) any later version.
Packit 5c3484
dnl
Packit 5c3484
dnl  or
Packit 5c3484
dnl
Packit 5c3484
dnl    * the GNU General Public License as published by the Free Software
Packit 5c3484
dnl      Foundation; either version 2 of the License, or (at your option) any
Packit 5c3484
dnl      later version.
Packit 5c3484
dnl
Packit 5c3484
dnl  or both in parallel, as here.
Packit 5c3484
dnl
Packit 5c3484
dnl  The GNU MP Library is distributed in the hope that it will be useful, but
Packit 5c3484
dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 5c3484
dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit 5c3484
dnl  for more details.
Packit 5c3484
dnl
Packit 5c3484
dnl  You should have received copies of the GNU General Public License and the
Packit 5c3484
dnl  GNU Lesser General Public License along with the GNU MP Library.  If not,
Packit 5c3484
dnl  see https://www.gnu.org/licenses/.
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  These macros are designed for use with any m4 and have been used on
Packit 5c3484
dnl  GNU, FreeBSD, NetBSD, OpenBSD and SysV.
Packit 5c3484
dnl
Packit 5c3484
dnl  GNU m4 and OpenBSD 2.7 m4 will give filenames and line numbers in error
Packit 5c3484
dnl  messages.
Packit 5c3484
dnl
Packit 5c3484
dnl
Packit 5c3484
dnl  Macros:
Packit 5c3484
dnl
Packit 5c3484
dnl  Most new m4 specific macros have an "m4_" prefix to emphasise they're
Packit 5c3484
dnl  m4 expansions.  But new defining things like deflit() and defreg() are
Packit 5c3484
dnl  named like the builtin define(), and forloop() is named following the
Packit 5c3484
dnl  GNU m4 example on which it's based.
Packit 5c3484
dnl
Packit 5c3484
dnl  GNU m4 with the -P option uses "m4_" as a prefix for builtins, but that
Packit 5c3484
dnl  option isn't going to be used, so there's no conflict or confusion.
Packit 5c3484
dnl
Packit 5c3484
dnl
Packit 5c3484
dnl  Comments in output:
Packit 5c3484
dnl
Packit 5c3484
dnl  The m4 comment delimiters are left at # and \n, the normal assembler
Packit 5c3484
dnl  commenting for most CPUs.  m4 passes comment text through without
Packit 5c3484
dnl  expanding macros in it, which is generally a good thing since it stops
Packit 5c3484
dnl  unexpected expansions and possible resultant errors.
Packit 5c3484
dnl
Packit 5c3484
dnl  But note that when a quoted string is being read, a # isn't special, so
Packit 5c3484
dnl  apostrophes in comments in quoted strings must be avoided or they'll be
Packit 5c3484
dnl  interpreted as a closing quote mark.  But when the quoted text is
Packit 5c3484
dnl  re-read # will still act like a normal comment, suppressing macro
Packit 5c3484
dnl  expansion.
Packit 5c3484
dnl
Packit 5c3484
dnl  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl          # apostrophes in comments that're outside quotes are ok
Packit 5c3484
dnl          # and using macro names like PROLOGUE is ok too
Packit 5c3484
dnl          ...
Packit 5c3484
dnl          ifdef(`PIC',`
Packit 5c3484
dnl                  # but apostrophes aren't ok inside quotes
Packit 5c3484
dnl                  #                     ^--wrong
Packit 5c3484
dnl                  ...
Packit 5c3484
dnl                  # though macro names like PROLOGUE are still ok
Packit 5c3484
dnl                  ...
Packit 5c3484
dnl          ')
Packit 5c3484
dnl
Packit 5c3484
dnl  If macro expansion in a comment is wanted, use `#' in the .asm (ie. a
Packit 5c3484
dnl  quoted hash symbol), which will turn into # in the .s but get
Packit 5c3484
dnl  expansions done on that line.  This can make the .s more readable to
Packit 5c3484
dnl  humans, but it won't make a blind bit of difference to the assembler.
Packit 5c3484
dnl
Packit 5c3484
dnl  All the above applies, mutatis mutandis, when changecom() is used to
Packit 5c3484
dnl  select @ ! ; or whatever other commenting.
Packit 5c3484
dnl
Packit 5c3484
dnl
Packit 5c3484
dnl  Variations in m4 affecting gmp:
Packit 5c3484
dnl
Packit 5c3484
dnl  $# - When a macro is called as "foo" with no brackets, BSD m4 sets $#
Packit 5c3484
dnl       to 1, whereas GNU or SysV m4 set it to 0.  In all cases though
Packit 5c3484
dnl       "foo()" sets $# to 1.  This is worked around in various places.
Packit 5c3484
dnl
Packit 5c3484
dnl  len() - When "len()" is given an empty argument, BSD m4 evaluates to
Packit 5c3484
dnl       nothing, whereas GNU, SysV, and the new OpenBSD, evaluate to 0.
Packit 5c3484
dnl       See m4_length() below which works around this.
Packit 5c3484
dnl
Packit 5c3484
dnl  translit() - GNU m4 accepts character ranges like A-Z, and the new
Packit 5c3484
dnl       OpenBSD m4 does under option -g, but basic BSD and SysV don't.
Packit 5c3484
dnl
Packit 5c3484
dnl  popdef() - in BSD and SysV m4 popdef() takes multiple arguments and
Packit 5c3484
dnl       pops each, but GNU m4 only takes one argument.
Packit 5c3484
dnl
Packit 5c3484
dnl  push back - BSD m4 has some limits on the amount of text that can be
Packit 5c3484
dnl       pushed back.  The limit is reasonably big and so long as macros
Packit 5c3484
dnl       don't gratuitously duplicate big arguments it isn't a problem.
Packit 5c3484
dnl       Normally an error message is given, but sometimes it just hangs.
Packit 5c3484
dnl
Packit 5c3484
dnl  eval() &,|,^ - GNU and SysV m4 have bitwise operators &,|,^ available,
Packit 5c3484
dnl       but BSD m4 doesn't (contrary to what the man page suggests) and
Packit 5c3484
dnl       instead ^ is exponentiation.
Packit 5c3484
dnl
Packit 5c3484
dnl  eval() ?: - The C ternary operator "?:" is available in BSD m4, but not
Packit 5c3484
dnl       in SysV or GNU m4 (as of GNU m4 1.4 and betas of 1.5).
Packit 5c3484
dnl
Packit 5c3484
dnl  eval() -2^31 - BSD m4 has a bug where an eval() resulting in -2^31
Packit 5c3484
dnl       (ie. -2147483648) gives "-(".  Using -2147483648 within an
Packit 5c3484
dnl       expression is ok, it just can't be a final result.  "-(" will of
Packit 5c3484
dnl       course upset parsing, with all sorts of strange effects.
Packit 5c3484
dnl
Packit 5c3484
dnl  eval() <<,>> - SysV m4 doesn't support shift operators in eval() (on
Packit 5c3484
dnl       Solaris 7 /usr/xpg4/m4 has them but /usr/ccs/m4 doesn't).  See
Packit 5c3484
dnl       m4_lshift() and m4_rshift() below for workarounds.
Packit 5c3484
dnl
Packit 5c3484
dnl  ifdef() - OSF 4.0 m4 considers a macro defined to a zero value `0' or
Packit 5c3484
dnl       `00' etc as not defined.  See m4_ifdef below for a workaround.
Packit 5c3484
dnl
Packit 5c3484
dnl  m4wrap() sequence - in BSD m4, m4wrap() replaces any previous m4wrap()
Packit 5c3484
dnl       string, in SysV m4 it appends to it, and in GNU m4 it prepends.
Packit 5c3484
dnl       See m4wrap_prepend() below which brings uniformity to this.
Packit 5c3484
dnl
Packit 5c3484
dnl  m4wrap() 0xFF - old versions of BSD m4 store EOF in a C "char" under an
Packit 5c3484
dnl       m4wrap() and on systems where char is unsigned by default a
Packit 5c3484
dnl       spurious 0xFF is output.  This has been observed on recent Cray
Packit 5c3484
dnl       Unicos Alpha, Apple MacOS X, and HPUX 11 systems.  An autoconf
Packit 5c3484
dnl       test is used to check for this, see the m4wrap handling below.  It
Packit 5c3484
dnl       might work to end the m4wrap string with a dnl to consume the
Packit 5c3484
dnl       0xFF, but that probably induces the offending m4's to read from an
Packit 5c3484
dnl       already closed "FILE *", which could be bad on a glibc style
Packit 5c3484
dnl       stdio.
Packit 5c3484
dnl
Packit 5c3484
dnl  __file__,__line__ - GNU m4 and OpenBSD 2.7 m4 provide these, and
Packit 5c3484
dnl       they're used here to make error messages more informative.  GNU m4
Packit 5c3484
dnl       gives an unhelpful "NONE 0" in an m4wrap(), but that's worked
Packit 5c3484
dnl       around.
Packit 5c3484
dnl
Packit 5c3484
dnl  __file__ quoting - OpenBSD m4, unlike GNU m4, doesn't quote the
Packit 5c3484
dnl       filename in __file__, so care should be taken that no macro has
Packit 5c3484
dnl       the same name as a file, or an unwanted expansion will occur when
Packit 5c3484
dnl       printing an error or warning.
Packit 5c3484
dnl
Packit 5c3484
dnl  changecom() - BSD m4 changecom doesn't quite work like the man page
Packit 5c3484
dnl       suggests, in particular "changecom" or "changecom()" doesn't
Packit 5c3484
dnl       disable the comment feature, and multi-character comment sequences
Packit 5c3484
dnl       don't seem to work.  If the default `#' and newline aren't
Packit 5c3484
dnl       suitable it's necessary to change it to something else,
Packit 5c3484
dnl       eg. changecom(;).
Packit 5c3484
dnl
Packit 5c3484
dnl  OpenBSD 2.6 m4 - in this m4, eval() rejects decimal constants containing
Packit 5c3484
dnl       an 8 or 9, making it pretty much unusable.  The bug is confined to
Packit 5c3484
dnl       version 2.6 (it's not in 2.5, and was fixed in 2.7).
Packit 5c3484
dnl
Packit 5c3484
dnl  SunOS /usr/bin/m4 - this m4 lacks a number of desired features,
Packit 5c3484
dnl       including $# and $@, defn(), m4exit(), m4wrap(), pushdef(),
Packit 5c3484
dnl       popdef().  /usr/5bin/m4 is a SysV style m4 which should always be
Packit 5c3484
dnl       available, and "configure" will reject /usr/bin/m4 in favour of
Packit 5c3484
dnl       /usr/5bin/m4 (if necessary).
Packit 5c3484
dnl
Packit 5c3484
dnl       The sparc code actually has modest m4 requirements currently and
Packit 5c3484
dnl       could manage with /usr/bin/m4, but there's no reason to put our
Packit 5c3484
dnl       macros through contortions when /usr/5bin/m4 is available or GNU
Packit 5c3484
dnl       m4 can be installed.
Packit 5c3484
Packit 5c3484
Packit 5c3484
ifdef(`__ASM_DEFS_M4_INCLUDED__',
Packit 5c3484
`m4_error(`asm-defs.m4 already included, dont include it twice
Packit 5c3484
')m4exit(1)')
Packit 5c3484
define(`__ASM_DEFS_M4_INCLUDED__')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Detect and give a message about the unsuitable OpenBSD 2.6 m4.
Packit 5c3484
Packit 5c3484
ifelse(eval(89),89,,
Packit 5c3484
`errprint(
Packit 5c3484
`This m4 doesnt accept 8 and/or 9 in constants in eval(), making it unusable.
Packit 5c3484
This is probably OpenBSD 2.6 m4 (September 1999).  Upgrade to OpenBSD 2.7,
Packit 5c3484
or get a bug fix from the CVS (expr.c rev 1.9), or get GNU m4.  Dont forget
Packit 5c3484
to configure with M4=/wherever/m4 if you install one of these in a directory
Packit 5c3484
not in $PATH.
Packit 5c3484
')m4exit(1)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Detect and give a message about the unsuitable SunOS /usr/bin/m4.
Packit 5c3484
dnl
Packit 5c3484
dnl  Unfortunately this test doesn't work when m4 is run in the normal way
Packit 5c3484
dnl  from mpn/Makefile with "m4 -DOPERATION_foo foo.asm", since the bad m4
Packit 5c3484
dnl  takes "-" in "-D..." to mean read stdin, so it will look like it just
Packit 5c3484
dnl  hangs.  But running "m4 asm-defs.m4" to try it out will work.
Packit 5c3484
dnl
Packit 5c3484
dnl  We'd like to abort immediately on finding a problem, but unfortunately
Packit 5c3484
dnl  the bad m4 doesn't have an m4exit(), nor does an invalid eval() kill
Packit 5c3484
dnl  it.  Unexpanded $#'s in some m4_assert_numargs() later on will comment
Packit 5c3484
dnl  out some closing parentheses and kill it with "m4: arg stack overflow".
Packit 5c3484
Packit 5c3484
define(m4_dollarhash_works_test,``$#'')
Packit 5c3484
ifelse(m4_dollarhash_works_test(x),1,,
Packit 5c3484
`errprint(
Packit 5c3484
`This m4 doesnt support $# and cant be used for GMP asm processing.
Packit 5c3484
If this is on SunOS, ./configure should choose /usr/5bin/m4 if you have that
Packit 5c3484
or can get it, otherwise install GNU m4.  Dont forget to configure with
Packit 5c3484
M4=/wherever/m4 if you install in a directory not in $PATH.
Packit 5c3484
')')
Packit 5c3484
undefine(`m4_dollarhash_works_test')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  --------------------------------------------------------------------------
Packit 5c3484
dnl  Basic error handling things.
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_dollarhash_1_if_noparen_p
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to 1 if a call "foo" gives $# set to 1 (as opposed to 0 like GNU
Packit 5c3484
dnl  and SysV m4 give).
Packit 5c3484
Packit 5c3484
define(m4_dollarhash_1_if_noparen_test,`$#')
Packit 5c3484
define(m4_dollarhash_1_if_noparen_p,
Packit 5c3484
eval(m4_dollarhash_1_if_noparen_test==1))
Packit 5c3484
undefine(`m4_dollarhash_1_if_noparen_test')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4wrap_prepend(string)
Packit 5c3484
dnl
Packit 5c3484
dnl  Prepend the given string to what will be expanded under m4wrap at the
Packit 5c3484
dnl  end of input.
Packit 5c3484
dnl
Packit 5c3484
dnl  This macro exists to work around variations in m4wrap() behaviour in
Packit 5c3484
dnl  the various m4s (notes at the start of this file).  Don't use m4wrap()
Packit 5c3484
dnl  directly since it will interfere with this scheme.
Packit 5c3484
Packit 5c3484
define(m4wrap_prepend,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`define(`m4wrap_string',`$1'defn(`m4wrap_string'))')
Packit 5c3484
Packit 5c3484
define(m4wrap_string,`')
Packit 5c3484
Packit 5c3484
define(m4wrap_works_p,
Packit 5c3484
`ifelse(M4WRAP_SPURIOUS,yes,0,1)')
Packit 5c3484
Packit 5c3484
ifelse(m4wrap_works_p,1,
Packit 5c3484
`m4wrap(`m4wrap_string')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_file_and_line
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to the current file and line number, if the GNU m4 extensions
Packit 5c3484
dnl  __file__ and __line__ are available.
Packit 5c3484
dnl
Packit 5c3484
dnl  In GNU m4 1.4 at the end of input when m4wrap text is expanded,
Packit 5c3484
dnl  __file__ is NONE and __line__ is 0, which is not a helpful thing to
Packit 5c3484
dnl  print.  If m4_file_seen() has been called to note the last file seen,
Packit 5c3484
dnl  then that file at a big line number is used, otherwise "end of input"
Packit 5c3484
dnl  is used (although "end of input" won't parse as an error message).
Packit 5c3484
Packit 5c3484
define(m4_file_and_line,
Packit 5c3484
`ifdef(`__file__',
Packit 5c3484
`ifelse(__file__`'__line__,`NONE0',
Packit 5c3484
`ifdef(`m4_file_seen_last',`m4_file_seen_last: 999999: ',`end of input: ')',
Packit 5c3484
`__file__: __line__: ')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_errprint_commas(arg,...)
Packit 5c3484
dnl
Packit 5c3484
dnl  The same as errprint(), but commas are printed between arguments
Packit 5c3484
dnl  instead of spaces.
Packit 5c3484
Packit 5c3484
define(m4_errprint_commas,
Packit 5c3484
`errprint(`$1')dnl
Packit 5c3484
ifelse(eval($#>1),1,`errprint(`,')m4_errprint_commas(shift($@))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_error(args...)
Packit 5c3484
dnl         m4_warning(args...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Print an error message, using m4_errprint_commas, prefixed with the
Packit 5c3484
dnl  current filename and line number (if available).  m4_error sets up to
Packit 5c3484
dnl  give an error exit at the end of processing, m4_warning just prints.
Packit 5c3484
dnl  These macros are the recommended way to print errors.
Packit 5c3484
dnl
Packit 5c3484
dnl  The arguments here should be quoted in the usual way to prevent them
Packit 5c3484
dnl  being expanded when the macro call is read.  (m4_error takes care not
Packit 5c3484
dnl  to do any further expansion.)
Packit 5c3484
dnl
Packit 5c3484
dnl  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         m4_error(`some error message
Packit 5c3484
dnl         ')
Packit 5c3484
dnl
Packit 5c3484
dnl  which prints
Packit 5c3484
dnl
Packit 5c3484
dnl         foo.asm:123: some error message
Packit 5c3484
dnl
Packit 5c3484
dnl  or if __file__ and __line__ aren't available
Packit 5c3484
dnl
Packit 5c3484
dnl         some error message
Packit 5c3484
dnl
Packit 5c3484
dnl  The "file:line:" format is a basic style, used by gcc and GNU m4, so
Packit 5c3484
dnl  emacs and other editors will recognise it in their normal error message
Packit 5c3484
dnl  parsing.
Packit 5c3484
Packit 5c3484
define(m4_warning,
Packit 5c3484
`m4_errprint_commas(m4_file_and_line`'$@)')
Packit 5c3484
Packit 5c3484
define(m4_error,
Packit 5c3484
`define(`m4_error_occurred',1)m4_warning($@)dnl
Packit 5c3484
ifelse(m4wrap_works_p,0,`m4exit(1)')')
Packit 5c3484
Packit 5c3484
define(`m4_error_occurred',0)
Packit 5c3484
Packit 5c3484
dnl  This m4wrap_prepend() is first, so it'll be executed last.
Packit 5c3484
m4wrap_prepend(
Packit 5c3484
`ifelse(m4_error_occurred,1,
Packit 5c3484
`m4_error(`Errors occurred during m4 processing
Packit 5c3484
')m4exit(1)')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_assert_numargs(num)
Packit 5c3484
dnl
Packit 5c3484
dnl  Put this unquoted on a line on its own at the start of a macro
Packit 5c3484
dnl  definition to add some code to check that num many arguments get passed
Packit 5c3484
dnl  to the macro.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         define(foo,
Packit 5c3484
dnl         m4_assert_numargs(2)
Packit 5c3484
dnl         `something `$1' and `$2' blah blah')
Packit 5c3484
dnl
Packit 5c3484
dnl  Then a call like foo(one,two,three) will provoke an error like
Packit 5c3484
dnl
Packit 5c3484
dnl         file:10: foo expected 2 arguments, got 3 arguments
Packit 5c3484
dnl
Packit 5c3484
dnl  Here are some calls and how many arguments they're interpreted as passing.
Packit 5c3484
dnl
Packit 5c3484
dnl         foo(abc,def)  2
Packit 5c3484
dnl         foo(xyz)      1
Packit 5c3484
dnl         foo()         0
Packit 5c3484
dnl         foo          -1
Packit 5c3484
dnl
Packit 5c3484
dnl  The -1 for no parentheses at all means a macro that's meant to be used
Packit 5c3484
dnl  that way can be checked with m4_assert_numargs(-1).  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         define(SPECIAL_SUFFIX,
Packit 5c3484
dnl         m4_assert_numargs(-1)
Packit 5c3484
dnl         `ifdef(`FOO',`_foo',`_bar')')
Packit 5c3484
dnl
Packit 5c3484
dnl  But as an alternative see also deflit() below where parenthesized
Packit 5c3484
dnl  expressions following a macro are passed through to the output.
Packit 5c3484
dnl
Packit 5c3484
dnl  Note that in BSD m4 there's no way to differentiate calls "foo" and
Packit 5c3484
dnl  "foo()", so in BSD m4 the distinction between the two isn't enforced.
Packit 5c3484
dnl  (In GNU and SysV m4 it can be checked, and is.)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  m4_assert_numargs is able to check its own arguments by calling
Packit 5c3484
dnl  assert_numargs_internal directly.
Packit 5c3484
dnl
Packit 5c3484
dnl  m4_doublequote($`'0) expands to ``$0'', whereas ``$`'0'' would expand
Packit 5c3484
dnl  to `$`'0' and do the wrong thing, and likewise for $1.  The same is
Packit 5c3484
dnl  done in other assert macros.
Packit 5c3484
dnl
Packit 5c3484
dnl  $`#' leaves $# in the new macro being defined, and stops # being
Packit 5c3484
dnl  interpreted as a comment character.
Packit 5c3484
dnl
Packit 5c3484
dnl  `dnl ' means an explicit dnl isn't necessary when m4_assert_numargs is
Packit 5c3484
dnl  used.  The space means that if there is a dnl it'll still work.
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_doublequote(x) expands to ``x''
Packit 5c3484
define(m4_doublequote,
Packit 5c3484
`m4_assert_numargs_internal(`$0',1,$#,len(`$1'))``$1''')
Packit 5c3484
Packit 5c3484
define(m4_assert_numargs,
Packit 5c3484
`m4_assert_numargs_internal(`$0',1,$#,len(`$1'))dnl
Packit 5c3484
`m4_assert_numargs_internal'(m4_doublequote($`'0),$1,$`#',`len'(m4_doublequote($`'1)))`dnl '')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_assert_numargs_internal(`macroname',wantargs,$#,len(`$1'))
Packit 5c3484
define(m4_assert_numargs_internal,
Packit 5c3484
`m4_assert_numargs_internal_check(`$1',`$2',m4_numargs_count(`$3',`$4'))')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_assert_numargs_internal_check(`macroname',wantargs,gotargs)
Packit 5c3484
dnl
Packit 5c3484
dnl  If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
Packit 5c3484
dnl  should be -1.  If wantargs is -1 but gotargs is 0 and the two can't be
Packit 5c3484
dnl  distinguished then it's allowed to pass.
Packit 5c3484
dnl
Packit 5c3484
define(m4_assert_numargs_internal_check,
Packit 5c3484
`ifelse(eval($2 == $3
Packit 5c3484
             || ($2==-1 && $3==0 && m4_dollarhash_1_if_noparen_p)),0,
Packit 5c3484
`m4_error(`$1 expected 'm4_Narguments(`$2')`, got 'm4_Narguments(`$3')
Packit 5c3484
)')')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_numargs_count($#,len(`$1'))
Packit 5c3484
dnl  If $#==0 then -1 args, if $#==1 but len(`$1')==0 then 0 args, otherwise
Packit 5c3484
dnl  $# args.
Packit 5c3484
define(m4_numargs_count,
Packit 5c3484
`ifelse($1,0, -1,
Packit 5c3484
`ifelse(eval($1==1 && $2-0==0),1, 0, $1)')')
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_Narguments(N)
Packit 5c3484
dnl  "$1 argument" or "$1 arguments" with the plural according to $1.
Packit 5c3484
define(m4_Narguments,
Packit 5c3484
`$1 argument`'ifelse(`$1',1,,s)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  --------------------------------------------------------------------------
Packit 5c3484
dnl  Additional error checking things.
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_file_seen()
Packit 5c3484
dnl
Packit 5c3484
dnl  Record __file__ for the benefit of m4_file_and_line in m4wrap text.
Packit 5c3484
dnl
Packit 5c3484
dnl  The basic __file__ macro comes out quoted in GNU m4, like `foo.asm',
Packit 5c3484
dnl  and m4_file_seen_last is defined like that too.
Packit 5c3484
dnl
Packit 5c3484
dnl  This is used by PROLOGUE, since that's normally in the main .asm file,
Packit 5c3484
dnl  and in particular it sets up m4wrap error checks for missing EPILOGUE.
Packit 5c3484
Packit 5c3484
define(m4_file_seen,
Packit 5c3484
m4_assert_numargs(0)
Packit 5c3484
`ifelse(__file__,`NONE',,
Packit 5c3484
`define(`m4_file_seen_last',m4_doublequote(__file__))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_assert_onearg()
Packit 5c3484
dnl
Packit 5c3484
dnl  Put this, unquoted, at the start of a macro definition to add some code
Packit 5c3484
dnl  to check that one argument is passed to the macro, but with that
Packit 5c3484
dnl  argument allowed to be empty.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl          define(foo,
Packit 5c3484
dnl          m4_assert_onearg()
Packit 5c3484
dnl          `blah blah $1 blah blah')
Packit 5c3484
dnl
Packit 5c3484
dnl  Calls "foo(xyz)" or "foo()" are accepted.  A call "foo(xyz,abc)" fails.
Packit 5c3484
dnl  A call "foo" fails too, but BSD m4 can't detect this case (GNU and SysV
Packit 5c3484
dnl  m4 can).
Packit 5c3484
Packit 5c3484
define(m4_assert_onearg,
Packit 5c3484
m4_assert_numargs(0)
Packit 5c3484
`m4_assert_onearg_internal'(m4_doublequote($`'0),$`#')`dnl ')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_assert_onearg(`macroname',$#)
Packit 5c3484
define(m4_assert_onearg_internal,
Packit 5c3484
`ifelse($2,1,,
Packit 5c3484
`m4_error(`$1 expected 1 argument, got 'm4_Narguments(`$2')
Packit 5c3484
)')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_assert_numargs_range(low,high)
Packit 5c3484
dnl
Packit 5c3484
dnl  Put this, unquoted, at the start of a macro definition to add some code
Packit 5c3484
dnl  to check that between low and high many arguments get passed to the
Packit 5c3484
dnl  macro.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         define(foo,
Packit 5c3484
dnl         m4_assert_numargs_range(3,5)
Packit 5c3484
dnl         `mandatory $1 $2 $3 optional $4 $5 end')
Packit 5c3484
dnl
Packit 5c3484
dnl  See m4_assert_numargs() for more info.
Packit 5c3484
Packit 5c3484
define(m4_assert_numargs_range,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
``m4_assert_numargs_range_internal'(m4_doublequote($`'0),$1,$2,$`#',`len'(m4_doublequote($`'1)))`dnl '')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_assert_numargs_range_internal(`name',low,high,$#,len(`$1'))
Packit 5c3484
define(m4_assert_numargs_range_internal,
Packit 5c3484
m4_assert_numargs(5)
Packit 5c3484
`m4_assert_numargs_range_check(`$1',`$2',`$3',m4_numargs_count(`$4',`$5'))')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_assert_numargs_range_check(`name',low,high,gotargs)
Packit 5c3484
dnl
Packit 5c3484
dnl  If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
Packit 5c3484
dnl  should be -1.  To ensure a `high' of -1 works, a fudge is applied to
Packit 5c3484
dnl  gotargs if it's 0 and the 0 and -1 cases can't be distinguished.
Packit 5c3484
dnl
Packit 5c3484
define(m4_assert_numargs_range_check,
Packit 5c3484
m4_assert_numargs(4)
Packit 5c3484
`ifelse(eval($2 <= $4 &&
Packit 5c3484
             ($4 - ($4==0 && m4_dollarhash_1_if_noparen_p) <= $3)),0,
Packit 5c3484
`m4_error(`$1 expected $2 to $3 arguments, got 'm4_Narguments(`$4')
Packit 5c3484
)')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_assert_defined(symbol)
Packit 5c3484
dnl
Packit 5c3484
dnl  Put this unquoted on a line of its own at the start of a macro
Packit 5c3484
dnl  definition to add some code to check that the given symbol is defined
Packit 5c3484
dnl  when the macro is used.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl          define(foo,
Packit 5c3484
dnl          m4_assert_defined(`FOO_PREFIX')
Packit 5c3484
dnl          `FOO_PREFIX whatever')
Packit 5c3484
dnl
Packit 5c3484
dnl  This is a convenient way to check that the user or ./configure or
Packit 5c3484
dnl  whatever has defined the things needed by a macro, as opposed to
Packit 5c3484
dnl  silently generating garbage.
Packit 5c3484
Packit 5c3484
define(m4_assert_defined,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
``m4_assert_defined_internal'(m4_doublequote($`'0),``$1'')`dnl '')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_assert_defined_internal(`macroname',`define_required')
Packit 5c3484
define(m4_assert_defined_internal,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`m4_ifdef(`$2',,
Packit 5c3484
`m4_error(`$1 needs $2 defined
Packit 5c3484
')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_not_for_expansion(`SYMBOL')
Packit 5c3484
dnl         define_not_for_expansion(`SYMBOL')
Packit 5c3484
dnl
Packit 5c3484
dnl  m4_not_for_expansion turns SYMBOL, if defined, into something which
Packit 5c3484
dnl  will give an error if expanded.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         m4_not_for_expansion(`PIC')
Packit 5c3484
dnl
Packit 5c3484
dnl  define_not_for_expansion is the same, but always makes a definition.
Packit 5c3484
dnl
Packit 5c3484
dnl  These are for symbols that should be tested with ifdef(`FOO',...)
Packit 5c3484
dnl  rather than be expanded as such.  They guard against accidentally
Packit 5c3484
dnl  omitting the quotes, as in ifdef(FOO,...).  Note though that they only
Packit 5c3484
dnl  catches this when FOO is defined, so be sure to test code both with and
Packit 5c3484
dnl  without each definition.
Packit 5c3484
Packit 5c3484
define(m4_not_for_expansion,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`ifdef(`$1',`define_not_for_expansion(`$1')')')
Packit 5c3484
Packit 5c3484
define(define_not_for_expansion,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`ifelse(defn(`$1'),,,
Packit 5c3484
`m4_error(``$1' has a non-empty value, maybe it shouldnt be munged with m4_not_for_expansion()
Packit 5c3484
')')dnl
Packit 5c3484
define(`$1',`m4_not_for_expansion_internal(`$1')')')
Packit 5c3484
Packit 5c3484
define(m4_not_for_expansion_internal,
Packit 5c3484
`m4_error(``$1' is not meant to be expanded, perhaps you mean `ifdef(`$1',...)'
Packit 5c3484
')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  --------------------------------------------------------------------------
Packit 5c3484
dnl  Various generic m4 things.
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_unquote(macro)
Packit 5c3484
dnl
Packit 5c3484
dnl  Allow the argument text to be re-evaluated.  This is useful for "token
Packit 5c3484
dnl  pasting" like m4_unquote(foo`'bar).
Packit 5c3484
Packit 5c3484
define(m4_unquote,
Packit 5c3484
m4_assert_onearg()
Packit 5c3484
`$1')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_ifdef(name,yes[,no])
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to the yes argument if name is defined, or to the no argument if
Packit 5c3484
dnl  not.
Packit 5c3484
dnl
Packit 5c3484
dnl  This is the same as the builtin "ifdef", but avoids an OSF 4.0 m4 bug
Packit 5c3484
dnl  in which a macro with a zero value `0' or `00' etc is considered not
Packit 5c3484
dnl  defined.
Packit 5c3484
dnl
Packit 5c3484
dnl  There's no particular need to use this everywhere, only if there might
Packit 5c3484
dnl  be a zero value.
Packit 5c3484
Packit 5c3484
define(m4_ifdef,
Packit 5c3484
m4_assert_numargs_range(2,3)
Packit 5c3484
`ifelse(eval(ifdef(`$1',1,0)+m4_length(defn(`$1'))),0,
Packit 5c3484
`$3',`$2')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_ifdef_anyof_p(`symbol',...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to 1 if any of the symbols in the argument list are defined, or
Packit 5c3484
dnl  to 0 if not.
Packit 5c3484
Packit 5c3484
define(m4_ifdef_anyof_p,
Packit 5c3484
`ifelse(eval($#<=1 && m4_length(`$1')==0),1, 0,
Packit 5c3484
`ifdef(`$1', 1,
Packit 5c3484
`m4_ifdef_anyof_p(shift($@))')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_length(string)
Packit 5c3484
dnl
Packit 5c3484
dnl  Determine the length of a string.  This is the same as len(), but
Packit 5c3484
dnl  always expands to a number, working around the BSD len() which
Packit 5c3484
dnl  evaluates to nothing given an empty argument.
Packit 5c3484
Packit 5c3484
define(m4_length,
Packit 5c3484
m4_assert_onearg()
Packit 5c3484
`eval(len(`$1')-0)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_stringequal_p(x,y)
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to 1 or 0 according as strings x and y are equal or not.
Packit 5c3484
Packit 5c3484
define(m4_stringequal_p,
Packit 5c3484
`ifelse(`$1',`$2',1,0)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_incr_or_decr(n,last)
Packit 5c3484
dnl
Packit 5c3484
dnl  Do an incr(n) or decr(n), whichever is in the direction of "last".
Packit 5c3484
dnl  Both n and last must be numbers of course.
Packit 5c3484
Packit 5c3484
define(m4_incr_or_decr,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`ifelse(eval($1<$2),1,incr($1),decr($1))')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: forloop(i, first, last, statement)
Packit 5c3484
dnl
Packit 5c3484
dnl  Based on GNU m4 examples/forloop.m4, but extended.
Packit 5c3484
dnl
Packit 5c3484
dnl  statement is expanded repeatedly, with i successively defined as
Packit 5c3484
dnl
Packit 5c3484
dnl         first, first+1, ..., last-1, last
Packit 5c3484
dnl
Packit 5c3484
dnl  Or if first > last, then it's
Packit 5c3484
dnl
Packit 5c3484
dnl         first, first-1, ..., last+1, last
Packit 5c3484
dnl
Packit 5c3484
dnl  If first == last, then one expansion is done.
Packit 5c3484
dnl
Packit 5c3484
dnl  A pushdef/popdef of i is done to preserve any previous definition (or
Packit 5c3484
dnl  lack of definition).  first and last are eval()ed and so can be
Packit 5c3484
dnl  expressions.
Packit 5c3484
dnl
Packit 5c3484
dnl  forloop_first is defined to 1 on the first iteration, 0 on the rest.
Packit 5c3484
dnl  forloop_last is defined to 1 on the last iteration, 0 on the others.
Packit 5c3484
dnl  Nested forloops are allowed, in which case forloop_first and
Packit 5c3484
dnl  forloop_last apply to the innermost loop that's open.
Packit 5c3484
dnl
Packit 5c3484
dnl  A simple example,
Packit 5c3484
dnl
Packit 5c3484
dnl         forloop(i, 1, 2*2+1, `dnl
Packit 5c3484
dnl         iteration number i ... ifelse(forloop_first,1,FIRST)
Packit 5c3484
dnl         ')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  "i" and "statement" are carefully quoted, but "first" and "last" are
Packit 5c3484
dnl  just plain numbers once eval()ed.
Packit 5c3484
Packit 5c3484
define(`forloop',
Packit 5c3484
m4_assert_numargs(4)
Packit 5c3484
`pushdef(`$1',eval(`$2'))dnl
Packit 5c3484
pushdef(`forloop_first',1)dnl
Packit 5c3484
pushdef(`forloop_last',0)dnl
Packit 5c3484
forloop_internal(`$1',eval(`$3'),`$4')`'dnl
Packit 5c3484
popdef(`forloop_first')dnl
Packit 5c3484
popdef(`forloop_last')dnl
Packit 5c3484
popdef(`$1')')
Packit 5c3484
Packit 5c3484
dnl  Called: forloop_internal(`var',last,statement)
Packit 5c3484
define(`forloop_internal',
Packit 5c3484
m4_assert_numargs(3)
Packit 5c3484
`ifelse($1,$2,
Packit 5c3484
`define(`forloop_last',1)$3',
Packit 5c3484
`$3`'dnl
Packit 5c3484
define(`forloop_first',0)dnl
Packit 5c3484
define(`$1',m4_incr_or_decr($1,$2))dnl
Packit 5c3484
forloop_internal(`$1',$2,`$3')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: foreach(var,body, item1,item2,...,itemN)
Packit 5c3484
dnl
Packit 5c3484
dnl  For each "item" argument, define "var" to that value and expand "body".
Packit 5c3484
dnl  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         foreach(i, `something i
Packit 5c3484
dnl         ', one, two)
Packit 5c3484
dnl  gives
Packit 5c3484
dnl         something one
Packit 5c3484
dnl         something two
Packit 5c3484
dnl
Packit 5c3484
dnl  Any previous definition of "var", or lack thereof, is saved and
Packit 5c3484
dnl  restored.  Empty "item"s are not allowed.
Packit 5c3484
Packit 5c3484
define(foreach,
Packit 5c3484
m4_assert_numargs_range(2,1000)
Packit 5c3484
`ifelse(`$3',,,
Packit 5c3484
`pushdef(`$1',`$3')$2`'popdef(`$1')dnl
Packit 5c3484
foreach(`$1',`$2',shift(shift(shift($@))))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_toupper(x)
Packit 5c3484
dnl         m4_tolower(x)
Packit 5c3484
dnl
Packit 5c3484
dnl  Convert the argument string to upper or lower case, respectively.
Packit 5c3484
dnl  Only one argument accepted.
Packit 5c3484
dnl
Packit 5c3484
dnl  BSD m4 doesn't take ranges like a-z in translit(), so the full alphabet
Packit 5c3484
dnl  is written out.
Packit 5c3484
Packit 5c3484
define(m4_alphabet_lower, `abcdefghijklmnopqrstuvwxyz')
Packit 5c3484
define(m4_alphabet_upper, `ABCDEFGHIJKLMNOPQRSTUVWXYZ')
Packit 5c3484
Packit 5c3484
define(m4_toupper,
Packit 5c3484
m4_assert_onearg()
Packit 5c3484
`translit(`$1', m4_alphabet_lower, m4_alphabet_upper)')
Packit 5c3484
Packit 5c3484
define(m4_tolower,
Packit 5c3484
m4_assert_onearg()
Packit 5c3484
`translit(`$1', m4_alphabet_upper, m4_alphabet_lower)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_empty_if_zero(x)
Packit 5c3484
dnl
Packit 5c3484
dnl  Evaluate to x, or to nothing if x is 0.  x is eval()ed and so can be an
Packit 5c3484
dnl  expression.
Packit 5c3484
dnl
Packit 5c3484
dnl  This is useful for x86 addressing mode displacements since forms like
Packit 5c3484
dnl  (%ebx) are one byte shorter than 0(%ebx).  A macro `foo' for use as
Packit 5c3484
dnl  foo(%ebx) could be defined with the following so it'll be empty if the
Packit 5c3484
dnl  expression comes out zero.
Packit 5c3484
dnl
Packit 5c3484
dnl	   deflit(`foo', `m4_empty_if_zero(a+b*4-c)')
Packit 5c3484
dnl
Packit 5c3484
dnl  Naturally this shouldn't be done if, say, a computed jump depends on
Packit 5c3484
dnl  the code being a particular size.
Packit 5c3484
Packit 5c3484
define(m4_empty_if_zero,
Packit 5c3484
m4_assert_onearg()
Packit 5c3484
`ifelse(eval($1),0,,eval($1))')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_log2(x)
Packit 5c3484
dnl
Packit 5c3484
dnl  Calculate a logarithm to base 2.
Packit 5c3484
dnl  x must be an integral power of 2, between 2**0 and 2**30.
Packit 5c3484
dnl  x is eval()ed, so it can be an expression.
Packit 5c3484
dnl  An error results if x is invalid.
Packit 5c3484
dnl
Packit 5c3484
dnl  2**31 isn't supported, because an unsigned 2147483648 is out of range
Packit 5c3484
dnl  of a 32-bit signed int.  Also, the bug in BSD m4 where an eval()
Packit 5c3484
dnl  resulting in 2147483648 (or -2147483648 as the case may be) gives `-('
Packit 5c3484
dnl  means tests like eval(1<<31==(x)) would be necessary, but that then
Packit 5c3484
dnl  gives an unattractive explosion of eval() error messages if x isn't
Packit 5c3484
dnl  numeric.
Packit 5c3484
Packit 5c3484
define(m4_log2,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`m4_log2_internal(0,1,eval(`$1'))')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_log2_internal(n,2**n,target)
Packit 5c3484
define(m4_log2_internal,
Packit 5c3484
m4_assert_numargs(3)
Packit 5c3484
`ifelse($2,$3,$1,
Packit 5c3484
`ifelse($1,30,
Packit 5c3484
`m4_error(`m4_log2() argument too big or not a power of two: $3
Packit 5c3484
')',
Packit 5c3484
`m4_log2_internal(incr($1),eval(2*$2),$3)')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage:  m4_div2_towards_zero
Packit 5c3484
dnl
Packit 5c3484
dnl  m4 division is probably whatever a C signed division is, and C doesn't
Packit 5c3484
dnl  specify what rounding gets used on negatives, so this expression forces
Packit 5c3484
dnl  a rounding towards zero.
Packit 5c3484
Packit 5c3484
define(m4_div2_towards_zero,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`eval((($1) + ((($1)<0) & ($1))) / 2)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_lshift(n,count)
Packit 5c3484
dnl         m4_rshift(n,count)
Packit 5c3484
dnl
Packit 5c3484
dnl  Calculate n shifted left or right by count many bits.  Both n and count
Packit 5c3484
dnl  are eval()ed and so can be expressions.
Packit 5c3484
dnl
Packit 5c3484
dnl  Negative counts are allowed and mean a shift in the opposite direction.
Packit 5c3484
dnl  Negative n is allowed and right shifts will be arithmetic (meaning
Packit 5c3484
dnl  divide by 2**count, rounding towards zero, also meaning the sign bit is
Packit 5c3484
dnl  duplicated).
Packit 5c3484
dnl
Packit 5c3484
dnl  Use these macros instead of << and >> in eval() since the basic ccs
Packit 5c3484
dnl  SysV m4 doesn't have those operators.
Packit 5c3484
Packit 5c3484
define(m4_rshift,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`m4_lshift(`$1',-(`$2'))')
Packit 5c3484
Packit 5c3484
define(m4_lshift,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`m4_lshift_internal(eval(`$1'),eval(`$2'))')
Packit 5c3484
Packit 5c3484
define(m4_lshift_internal,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`ifelse(eval($2-0==0),1,$1,
Packit 5c3484
`ifelse(eval($2>0),1,
Packit 5c3484
`m4_lshift_internal(eval($1*2),decr($2))',
Packit 5c3484
`m4_lshift_internal(m4_div2_towards_zero($1),incr($2))')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_popcount(n)
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to the number 1 bits in n.
Packit 5c3484
Packit 5c3484
define(m4_popcount,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`m4_popcount_internal(0,eval(`$1'))')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_popcount_internal(count,rem)
Packit 5c3484
define(m4_popcount_internal,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`ifelse($2,0,$1,
Packit 5c3484
`m4_popcount_internal(eval($1+($2%2)),eval($2/2))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_count_trailing_zeros(N)
Packit 5c3484
dnl
Packit 5c3484
dnl  Determine the number of trailing zero bits on N.  N is eval()ed and so
Packit 5c3484
dnl  can be an expression.  If N is zero an error is generated.
Packit 5c3484
Packit 5c3484
define(m4_count_trailing_zeros,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`m4_count_trailing_zeros_internal(eval(`$1'),0)')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_count_trailing_zeros_internal(val,count)
Packit 5c3484
define(m4_count_trailing_zeros_internal,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`ifelse($1,0,
Packit 5c3484
`m4_error(`m4_count_trailing_zeros() given a zero value')',
Packit 5c3484
`ifelse(eval(($1)%2),1,`$2',
Packit 5c3484
`m4_count_trailing_zeros_internal(eval($1/2),incr($2))')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: deflit(name,value)
Packit 5c3484
dnl
Packit 5c3484
dnl  Like define(), but "name" expands like a literal, rather than taking
Packit 5c3484
dnl  arguments.  For example "name(%eax)" expands to "value(%eax)".
Packit 5c3484
dnl
Packit 5c3484
dnl  Limitations:
Packit 5c3484
dnl
Packit 5c3484
dnl  $ characters in the value part must have quotes to stop them looking
Packit 5c3484
dnl  like macro parameters.  For example, deflit(reg,`123+$`'4+567').  See
Packit 5c3484
dnl  defreg() below for handling simple register definitions like $7 etc.
Packit 5c3484
dnl
Packit 5c3484
dnl  "name()" is turned into "name", unfortunately.  In GNU and SysV m4 an
Packit 5c3484
dnl  error is generated when this happens, but in BSD m4 it will happen
Packit 5c3484
dnl  silently.  The problem is that in BSD m4 $# is 1 in both "name" or
Packit 5c3484
dnl  "name()", so there's no way to differentiate them.  Because we want
Packit 5c3484
dnl  plain "name" to turn into plain "value", we end up with "name()"
Packit 5c3484
dnl  turning into plain "value" too.
Packit 5c3484
dnl
Packit 5c3484
dnl  "name(foo)" will lose any whitespace after commas in "foo", for example
Packit 5c3484
dnl  "disp(%eax, %ecx)" would become "128(%eax,%ecx)".
Packit 5c3484
dnl
Packit 5c3484
dnl  These parentheses oddities shouldn't matter in assembler text, but if
Packit 5c3484
dnl  they do the suggested workaround is to write "name ()" or "name (foo)"
Packit 5c3484
dnl  to stop the parentheses looking like a macro argument list.  If a space
Packit 5c3484
dnl  isn't acceptable in the output, then write "name`'()" or "name`'(foo)".
Packit 5c3484
dnl  The `' is stripped when read, but again stops the parentheses looking
Packit 5c3484
dnl  like parameters.
Packit 5c3484
Packit 5c3484
dnl  Quoting for deflit_emptyargcheck is similar to m4_assert_numargs.  The
Packit 5c3484
dnl  stuff in the ifelse gives a $#, $1 and $@ evaluated in the new macro
Packit 5c3484
dnl  created, not in deflit.
Packit 5c3484
define(deflit,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`define(`$1',
Packit 5c3484
`deflit_emptyargcheck'(``$1'',$`#',m4_doublequote($`'1))`dnl
Packit 5c3484
$2`'dnl
Packit 5c3484
ifelse(eval($'`#>1 || m4_length('m4_doublequote($`'1)`)!=0),1,($'`@))')')
Packit 5c3484
Packit 5c3484
dnl  Called: deflit_emptyargcheck(macroname,$#,`$1')
Packit 5c3484
define(deflit_emptyargcheck,
Packit 5c3484
`ifelse(eval($2==1 && !m4_dollarhash_1_if_noparen_p && m4_length(`$3')==0),1,
Packit 5c3484
`m4_error(`dont use a deflit as $1() because it loses the brackets (see deflit in asm-defs.m4 for more information)
Packit 5c3484
')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_assert(`expr')
Packit 5c3484
dnl
Packit 5c3484
dnl  Test a compile-time requirement with an m4 expression.  The expression
Packit 5c3484
dnl  should be quoted, and will be eval()ed and expected to be non-zero.
Packit 5c3484
dnl  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         m4_assert(`FOO*2+6 < 14')
Packit 5c3484
Packit 5c3484
define(m4_assert,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`ifelse(eval($1),1,,
Packit 5c3484
`m4_error(`assertion failed: $1
Packit 5c3484
')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_repeat(count,text)
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to the given repetitions of the given text.  A zero count is
Packit 5c3484
dnl  allowed, and expands to nothing.
Packit 5c3484
Packit 5c3484
define(m4_repeat,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`m4_repeat_internal(eval($1),`$2')')
Packit 5c3484
Packit 5c3484
define(m4_repeat_internal,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`ifelse(`$1',0,,
Packit 5c3484
`forloop(m4_repeat_internal_counter,1,$1,``$2'')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_hex_lowmask(bits)
Packit 5c3484
dnl
Packit 5c3484
dnl  Generate a hex constant which is a low mask of the given number of
Packit 5c3484
dnl  bits.  For example m4_hex_lowmask(10) would give 0x3ff.
Packit 5c3484
Packit 5c3484
define(m4_hex_lowmask,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`m4_cpu_hex_constant(m4_hex_lowmask_internal1(eval(`$1')))')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_hex_lowmask_internal1(bits)
Packit 5c3484
define(m4_hex_lowmask_internal1,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`ifelse($1,0,`0',
Packit 5c3484
`m4_hex_lowmask_internal2(eval(($1)%4),eval(($1)/4))')')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_hex_lowmask_internal(remainder,digits)
Packit 5c3484
define(m4_hex_lowmask_internal2,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`ifelse($1,1,`1',
Packit 5c3484
`ifelse($1,2,`3',
Packit 5c3484
`ifelse($1,3,`7')')')dnl
Packit 5c3484
m4_repeat($2,`f')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  --------------------------------------------------------------------------
Packit 5c3484
dnl  The following m4_list functions take a list as multiple arguments.
Packit 5c3484
dnl  Arguments are evaluated multiple times, there's no attempt at strict
Packit 5c3484
dnl  quoting.  Empty list elements are not allowed, since an empty final
Packit 5c3484
dnl  argument is ignored.  These restrictions don't affect the current uses,
Packit 5c3484
dnl  and make the implementation easier.
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_list_quote(list,...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Produce a list with quoted commas, so it can be a single argument
Packit 5c3484
dnl  string.  For instance m4_list_quote(a,b,c) gives
Packit 5c3484
dnl
Packit 5c3484
dnl         a`,'b`,'c`,'
Packit 5c3484
dnl
Packit 5c3484
dnl  This can be used to put a list in a define,
Packit 5c3484
dnl
Packit 5c3484
dnl         define(foolist, m4_list_quote(a,b,c))
Packit 5c3484
dnl
Packit 5c3484
dnl  Which can then be used for instance as
Packit 5c3484
dnl
Packit 5c3484
dnl         m4_list_find(target, foolist)
Packit 5c3484
Packit 5c3484
define(m4_list_quote,
Packit 5c3484
`ifelse(`$1',,,
Packit 5c3484
`$1`,'m4_list_quote(shift($@))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_list_find(key,list,...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Evaluate to 1 or 0 according to whether key is in the list elements.
Packit 5c3484
Packit 5c3484
define(m4_list_find,
Packit 5c3484
m4_assert_numargs_range(1,1000)
Packit 5c3484
`ifelse(`$2',,0,
Packit 5c3484
`ifelse(`$1',`$2',1,
Packit 5c3484
`m4_list_find(`$1',shift(shift($@)))')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_list_remove(key,list,...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Evaluate to the given list with `key' removed (if present).
Packit 5c3484
Packit 5c3484
define(m4_list_remove,
Packit 5c3484
m4_assert_numargs_range(1,1000)
Packit 5c3484
`ifelse(`$2',,,
Packit 5c3484
`ifelse(`$1',`$2',,`$2,')dnl
Packit 5c3484
m4_list_remove(`$1',shift(shift($@)))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_list_first(list,...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Evaluate to the first element of the list (if any).
Packit 5c3484
Packit 5c3484
define(m4_list_first,`$1')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_list_count(list,...)
Packit 5c3484
dnl
Packit 5c3484
dnl  Evaluate to the number of elements in the list.  This can't just use $#
Packit 5c3484
dnl  because the last element might be empty.
Packit 5c3484
Packit 5c3484
define(m4_list_count,
Packit 5c3484
`m4_list_count_internal(0,$@)')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_list_internal(count,list,...)
Packit 5c3484
define(m4_list_count_internal,
Packit 5c3484
m4_assert_numargs_range(1,1000)
Packit 5c3484
`ifelse(`$2',,$1,
Packit 5c3484
`m4_list_count_internal(eval($1+1),shift(shift($@)))')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  --------------------------------------------------------------------------
Packit 5c3484
dnl  Various assembler things, not specific to any particular CPU.
Packit 5c3484
dnl
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: include_mpn(`filename')
Packit 5c3484
dnl
Packit 5c3484
dnl  Like include(), but adds a path to the mpn source directory.  For
Packit 5c3484
dnl  example,
Packit 5c3484
dnl
Packit 5c3484
dnl         include_mpn(`sparc64/addmul_1h.asm')
Packit 5c3484
Packit 5c3484
define(include_mpn,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
m4_assert_defined(`CONFIG_TOP_SRCDIR')
Packit 5c3484
`include(CONFIG_TOP_SRCDIR`/mpn/$1')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: C comment ...
Packit 5c3484
dnl
Packit 5c3484
dnl  This works like a FORTRAN-style comment character.  It can be used for
Packit 5c3484
dnl  comments to the right of assembly instructions, where just dnl would
Packit 5c3484
dnl  remove the newline and concatenate adjacent lines.
Packit 5c3484
dnl
Packit 5c3484
dnl  C and/or dnl are useful when an assembler doesn't support comments, or
Packit 5c3484
dnl  where different assemblers for a particular CPU need different styles.
Packit 5c3484
dnl  The intermediate ".s" files will end up with no comments, just code.
Packit 5c3484
dnl
Packit 5c3484
dnl  Using C is not intended to cause offence to anyone who doesn't like
Packit 5c3484
dnl  FORTRAN; but if that happens it's an unexpected bonus.
Packit 5c3484
dnl
Packit 5c3484
dnl  During development, if comments are wanted in the .s files to help see
Packit 5c3484
dnl  what's expanding where, C can be redefined with something like
Packit 5c3484
dnl
Packit 5c3484
dnl         define(`C',`#')
Packit 5c3484
Packit 5c3484
define(C, `
Packit 5c3484
dnl')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Normally PIC is defined (or not) by libtool, but it doesn't set it on
Packit 5c3484
dnl  systems which are always PIC.  PIC_ALWAYS established in config.m4
Packit 5c3484
dnl  identifies these for us.
Packit 5c3484
Packit 5c3484
ifelse(`PIC_ALWAYS',`yes',`define(`PIC')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Various possible defines passed from the Makefile that are to be tested
Packit 5c3484
dnl  with ifdef() rather than be expanded.
Packit 5c3484
Packit 5c3484
m4_not_for_expansion(`PIC')
Packit 5c3484
m4_not_for_expansion(`DLL_EXPORT')
Packit 5c3484
Packit 5c3484
dnl  aors_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_add_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_sub_n')
Packit 5c3484
Packit 5c3484
dnl  aors_err1_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_add_err1_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_sub_err1_n')
Packit 5c3484
Packit 5c3484
dnl  aors_err2_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_add_err2_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_sub_err2_n')
Packit 5c3484
Packit 5c3484
dnl  aors_err3_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_add_err3_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_sub_err3_n')
Packit 5c3484
Packit 5c3484
dnl  aorsmul_1
Packit 5c3484
m4_not_for_expansion(`OPERATION_addmul_1')
Packit 5c3484
m4_not_for_expansion(`OPERATION_submul_1')
Packit 5c3484
Packit 5c3484
dnl  logops_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_and_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_andn_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_nand_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_ior_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_iorn_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_nior_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_xor_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_xnor_n')
Packit 5c3484
Packit 5c3484
dnl  popham
Packit 5c3484
m4_not_for_expansion(`OPERATION_popcount')
Packit 5c3484
m4_not_for_expansion(`OPERATION_hamdist')
Packit 5c3484
Packit 5c3484
dnl  lorrshift
Packit 5c3484
m4_not_for_expansion(`OPERATION_lshift')
Packit 5c3484
m4_not_for_expansion(`OPERATION_rshift')
Packit 5c3484
Packit 5c3484
dnl  aorslsh1_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_addlsh1_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_sublsh1_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_rsblsh1_n')
Packit 5c3484
Packit 5c3484
dnl  aorslsh2_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_addlsh2_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_sublsh2_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_rsblsh2_n')
Packit 5c3484
Packit 5c3484
dnl  rsh1aors_n
Packit 5c3484
m4_not_for_expansion(`OPERATION_rsh1add_n')
Packit 5c3484
m4_not_for_expansion(`OPERATION_rsh1sub_n')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_config_gmp_mparam(`symbol')
Packit 5c3484
dnl
Packit 5c3484
dnl  Check that `symbol' is defined.  If it isn't, issue an error and
Packit 5c3484
dnl  terminate immediately.  The error message explains that the symbol
Packit 5c3484
dnl  should be in config.m4, copied from gmp-mparam.h.
Packit 5c3484
dnl
Packit 5c3484
dnl  Termination is immediate since missing say SQR_TOOM2_THRESHOLD can
Packit 5c3484
dnl  lead to infinite loops and endless error messages.
Packit 5c3484
Packit 5c3484
define(m4_config_gmp_mparam,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`ifdef(`$1',,
Packit 5c3484
`m4_error(`$1 is not defined.
Packit 5c3484
	"configure" should have extracted this from gmp-mparam.h and put it
Packit 5c3484
	in config.m4 (or in <cpu>_<file>.asm for a fat binary), but somehow
Packit 5c3484
        this has failed.
Packit 5c3484
')m4exit(1)')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: defreg(name,reg)
Packit 5c3484
dnl
Packit 5c3484
dnl  Give a name to a $ style register.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         defreg(foo,$12)
Packit 5c3484
dnl
Packit 5c3484
dnl  defreg() inserts an extra pair of quotes after the $ so that it's not
Packit 5c3484
dnl  interpreted as an m4 macro parameter, ie. foo is actually $`'12.  m4
Packit 5c3484
dnl  strips those quotes when foo is expanded.
Packit 5c3484
dnl
Packit 5c3484
dnl  deflit() is used to make the new definition, so it will expand
Packit 5c3484
dnl  literally even if followed by parentheses ie. foo(99) will become
Packit 5c3484
dnl  $12(99).  (But there's nowhere that would be used is there?)
Packit 5c3484
dnl
Packit 5c3484
dnl  When making further definitions from existing defreg() macros, remember
Packit 5c3484
dnl  to use defreg() again to protect the $ in the new definitions too.  For
Packit 5c3484
dnl  example,
Packit 5c3484
dnl
Packit 5c3484
dnl         defreg(a0,$4)
Packit 5c3484
dnl         defreg(a1,$5)
Packit 5c3484
dnl         ...
Packit 5c3484
dnl
Packit 5c3484
dnl         defreg(PARAM_DST,a0)
Packit 5c3484
dnl
Packit 5c3484
dnl  This is only because a0 is expanding at the time the PARAM_DST
Packit 5c3484
dnl  definition is made, leaving a literal $4 that must be re-quoted.  On
Packit 5c3484
dnl  the other hand in something like the following ra is only expanded when
Packit 5c3484
dnl  ret is used and its $`'31 protection will have its desired effect at
Packit 5c3484
dnl  that time.
Packit 5c3484
dnl
Packit 5c3484
dnl         defreg(ra,$31)
Packit 5c3484
dnl         ...
Packit 5c3484
dnl         define(ret,`j ra')
Packit 5c3484
dnl
Packit 5c3484
dnl  Note that only $n forms are meant to be used here, and something like
Packit 5c3484
dnl  128($30) doesn't get protected and will come out wrong.
Packit 5c3484
Packit 5c3484
define(defreg,
Packit 5c3484
m4_assert_numargs(2)
Packit 5c3484
`deflit(`$1',
Packit 5c3484
substr(`$2',0,1)``''substr(`$2',1))')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_instruction_wrapper()
Packit 5c3484
dnl
Packit 5c3484
dnl  Put this, unquoted, on a line on its own, at the start of a macro
Packit 5c3484
dnl  that's a wrapper around an assembler instruction.  It adds code to give
Packit 5c3484
dnl  a descriptive error message if the macro is invoked without arguments.
Packit 5c3484
dnl
Packit 5c3484
dnl  For example, suppose jmp needs to be wrapped,
Packit 5c3484
dnl
Packit 5c3484
dnl         define(jmp,
Packit 5c3484
dnl         m4_instruction_wrapper()
Packit 5c3484
dnl         m4_assert_numargs(1)
Packit 5c3484
dnl                 `.byte 0x42
Packit 5c3484
dnl                 .long  $1
Packit 5c3484
dnl                 nop')
Packit 5c3484
dnl
Packit 5c3484
dnl  The point of m4_instruction_wrapper is to get a better error message
Packit 5c3484
dnl  than m4_assert_numargs would give if jmp is accidentally used as plain
Packit 5c3484
dnl  "jmp foo" instead of the intended "jmp( foo)".  "jmp()" with no
Packit 5c3484
dnl  argument also provokes the error message.
Packit 5c3484
dnl
Packit 5c3484
dnl  m4_instruction_wrapper should only be used with wrapped instructions
Packit 5c3484
dnl  that take arguments, since obviously something meant to be used as say
Packit 5c3484
dnl  plain "ret" doesn't want to give an error when used that way.
Packit 5c3484
Packit 5c3484
define(m4_instruction_wrapper,
Packit 5c3484
m4_assert_numargs(0)
Packit 5c3484
``m4_instruction_wrapper_internal'(m4_doublequote($`'0),dnl
Packit 5c3484
ifdef(`__file__',`m4_doublequote(__file__)',``the m4 sources''),dnl
Packit 5c3484
$`#',m4_doublequote($`'1))`dnl'')
Packit 5c3484
Packit 5c3484
dnl  Called: m4_instruction_wrapper_internal($0,`filename',$#,$1)
Packit 5c3484
define(m4_instruction_wrapper_internal,
Packit 5c3484
`ifelse(eval($3<=1 && m4_length(`$4')==0),1,
Packit 5c3484
`m4_error(`$1 is a macro replacing that instruction and needs arguments, see $2 for details
Packit 5c3484
')')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4_cpu_hex_constant(string)
Packit 5c3484
dnl
Packit 5c3484
dnl  Expand to the string prefixed by a suitable `0x' hex marker.  This
Packit 5c3484
dnl  should be redefined as necessary for CPUs with different conventions.
Packit 5c3484
Packit 5c3484
define(m4_cpu_hex_constant,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`0x`$1'')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: UNROLL_LOG2, UNROLL_MASK, UNROLL_BYTES
Packit 5c3484
dnl         CHUNK_LOG2, CHUNK_MASK, CHUNK_BYTES
Packit 5c3484
dnl
Packit 5c3484
dnl  When code supports a variable amount of loop unrolling, the convention
Packit 5c3484
dnl  is to define UNROLL_COUNT to the number of limbs processed per loop.
Packit 5c3484
dnl  When testing code this can be varied to see how much the loop overhead
Packit 5c3484
dnl  is costing.  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         deflit(UNROLL_COUNT, 32)
Packit 5c3484
dnl
Packit 5c3484
dnl  If the forloop() generating the unrolled loop has a pattern processing
Packit 5c3484
dnl  more than one limb, the convention is to express this with CHUNK_COUNT.
Packit 5c3484
dnl  For example,
Packit 5c3484
dnl
Packit 5c3484
dnl         deflit(CHUNK_COUNT, 2)
Packit 5c3484
dnl
Packit 5c3484
dnl  The LOG2, MASK and BYTES definitions below are derived from these COUNT
Packit 5c3484
dnl  definitions.  If COUNT is redefined, the LOG2, MASK and BYTES follow
Packit 5c3484
dnl  the new definition automatically.
Packit 5c3484
dnl
Packit 5c3484
dnl  LOG2 is the log base 2 of COUNT.  MASK is COUNT-1, which can be used as
Packit 5c3484
dnl  a bit mask.  BYTES is GMP_LIMB_BYTES*COUNT, the number of bytes
Packit 5c3484
dnl  processed in each unrolled loop.
Packit 5c3484
dnl
Packit 5c3484
dnl  GMP_LIMB_BYTES is defined in a CPU specific m4 include file.  It
Packit 5c3484
dnl  exists only so the BYTES definitions here can be common to all CPUs.
Packit 5c3484
dnl  In the actual code for a given CPU, an explicit 4 or 8 may as well be
Packit 5c3484
dnl  used because the code is only for a particular CPU, it doesn't need to
Packit 5c3484
dnl  be general.
Packit 5c3484
dnl
Packit 5c3484
dnl  Note that none of these macros do anything except give conventional
Packit 5c3484
dnl  names to commonly used things.  You still have to write your own
Packit 5c3484
dnl  expressions for a forloop() and the resulting address displacements.
Packit 5c3484
dnl  Something like the following would be typical for 4 bytes per limb.
Packit 5c3484
dnl
Packit 5c3484
dnl         forloop(`i',0,UNROLL_COUNT-1,`
Packit 5c3484
dnl                 deflit(`disp',eval(i*4))
Packit 5c3484
dnl                 ...
Packit 5c3484
dnl         ')
Packit 5c3484
dnl
Packit 5c3484
dnl  Or when using CHUNK_COUNT,
Packit 5c3484
dnl
Packit 5c3484
dnl         forloop(`i',0,UNROLL_COUNT/CHUNK_COUNT-1,`
Packit 5c3484
dnl                 deflit(`disp0',eval(i*CHUNK_COUNT*4))
Packit 5c3484
dnl                 deflit(`disp1',eval(disp0+4))
Packit 5c3484
dnl                 ...
Packit 5c3484
dnl         ')
Packit 5c3484
dnl
Packit 5c3484
dnl  Clearly `i' can be run starting from 1, or from high to low or whatever
Packit 5c3484
dnl  best suits.
Packit 5c3484
Packit 5c3484
deflit(UNROLL_LOG2,
Packit 5c3484
m4_assert_defined(`UNROLL_COUNT')
Packit 5c3484
`m4_log2(UNROLL_COUNT)')
Packit 5c3484
Packit 5c3484
deflit(UNROLL_MASK,
Packit 5c3484
m4_assert_defined(`UNROLL_COUNT')
Packit 5c3484
`eval(UNROLL_COUNT-1)')
Packit 5c3484
Packit 5c3484
deflit(UNROLL_BYTES,
Packit 5c3484
m4_assert_defined(`UNROLL_COUNT')
Packit 5c3484
m4_assert_defined(`GMP_LIMB_BYTES')
Packit 5c3484
`eval(UNROLL_COUNT * GMP_LIMB_BYTES)')
Packit 5c3484
Packit 5c3484
deflit(CHUNK_LOG2,
Packit 5c3484
m4_assert_defined(`CHUNK_COUNT')
Packit 5c3484
`m4_log2(CHUNK_COUNT)')
Packit 5c3484
Packit 5c3484
deflit(CHUNK_MASK,
Packit 5c3484
m4_assert_defined(`CHUNK_COUNT')
Packit 5c3484
`eval(CHUNK_COUNT-1)')
Packit 5c3484
Packit 5c3484
deflit(CHUNK_BYTES,
Packit 5c3484
m4_assert_defined(`CHUNK_COUNT')
Packit 5c3484
m4_assert_defined(`GMP_LIMB_BYTES')
Packit 5c3484
`eval(CHUNK_COUNT * GMP_LIMB_BYTES)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: MPN(name)
Packit 5c3484
dnl
Packit 5c3484
dnl  Add MPN_PREFIX to a name.
Packit 5c3484
dnl  MPN_PREFIX defaults to "__gmpn_" if not defined.
Packit 5c3484
dnl
Packit 5c3484
dnl  m4_unquote is used in MPN so that when it expands to say __gmpn_foo,
Packit 5c3484
dnl  that identifier will be subject to further macro expansion.  This is
Packit 5c3484
dnl  used by some of the fat binary support for renaming symbols.
Packit 5c3484
Packit 5c3484
ifdef(`MPN_PREFIX',,
Packit 5c3484
`define(`MPN_PREFIX',`__gmpn_')')
Packit 5c3484
Packit 5c3484
define(MPN,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`m4_unquote(MPN_PREFIX`'$1)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: mpn_add_n, etc
Packit 5c3484
dnl
Packit 5c3484
dnl  Convenience definitions using MPN(), like the #defines in gmp.h.  Each
Packit 5c3484
dnl  function that might be implemented in assembler is here.
Packit 5c3484
Packit 5c3484
define(define_mpn,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`deflit(`mpn_$1',`MPN(`$1')')')
Packit 5c3484
Packit 5c3484
define_mpn(add)
Packit 5c3484
define_mpn(add_1)
Packit 5c3484
define_mpn(add_err1_n)
Packit 5c3484
define_mpn(add_err2_n)
Packit 5c3484
define_mpn(add_err3_n)
Packit 5c3484
define_mpn(add_n)
Packit 5c3484
define_mpn(add_nc)
Packit 5c3484
define_mpn(addlsh1_n)
Packit 5c3484
define_mpn(addlsh1_nc)
Packit 5c3484
define_mpn(addlsh2_n)
Packit 5c3484
define_mpn(addlsh2_nc)
Packit 5c3484
define_mpn(addlsh_n)
Packit 5c3484
define_mpn(addlsh_nc)
Packit 5c3484
define_mpn(addlsh1_n_ip1)
Packit 5c3484
define_mpn(addlsh1_nc_ip1)
Packit 5c3484
define_mpn(addlsh2_n_ip1)
Packit 5c3484
define_mpn(addlsh2_nc_ip1)
Packit 5c3484
define_mpn(addlsh_n_ip1)
Packit 5c3484
define_mpn(addlsh_nc_ip1)
Packit 5c3484
define_mpn(addlsh1_n_ip2)
Packit 5c3484
define_mpn(addlsh1_nc_ip2)
Packit 5c3484
define_mpn(addlsh2_n_ip2)
Packit 5c3484
define_mpn(addlsh2_nc_ip2)
Packit 5c3484
define_mpn(addlsh_n_ip2)
Packit 5c3484
define_mpn(addlsh_nc_ip2)
Packit 5c3484
define_mpn(addmul_1)
Packit 5c3484
define_mpn(addmul_1c)
Packit 5c3484
define_mpn(addmul_2)
Packit 5c3484
define_mpn(addmul_3)
Packit 5c3484
define_mpn(addmul_4)
Packit 5c3484
define_mpn(addmul_5)
Packit 5c3484
define_mpn(addmul_6)
Packit 5c3484
define_mpn(addmul_7)
Packit 5c3484
define_mpn(addmul_8)
Packit 5c3484
define_mpn(addmul_2s)
Packit 5c3484
define_mpn(add_n_sub_n)
Packit 5c3484
define_mpn(add_n_sub_nc)
Packit 5c3484
define_mpn(addaddmul_1msb0)
Packit 5c3484
define_mpn(and_n)
Packit 5c3484
define_mpn(andn_n)
Packit 5c3484
define_mpn(bdiv_q_1)
Packit 5c3484
define_mpn(pi1_bdiv_q_1)
Packit 5c3484
define_mpn(bdiv_dbm1c)
Packit 5c3484
define_mpn(cmp)
Packit 5c3484
define_mpn(cnd_add_n)
Packit 5c3484
define_mpn(cnd_sub_n)
Packit 5c3484
define_mpn(com)
Packit 5c3484
define_mpn(copyd)
Packit 5c3484
define_mpn(copyi)
Packit 5c3484
define_mpn(count_leading_zeros)
Packit 5c3484
define_mpn(count_trailing_zeros)
Packit 5c3484
define_mpn(div_qr_1n_pi1)
Packit 5c3484
define_mpn(div_qr_2)
Packit 5c3484
define_mpn(div_qr_2n_pi1)
Packit 5c3484
define_mpn(div_qr_2u_pi1)
Packit 5c3484
define_mpn(div_qr_2n_pi2)
Packit 5c3484
define_mpn(div_qr_2u_pi2)
Packit 5c3484
define_mpn(divexact_1)
Packit 5c3484
define_mpn(divexact_by3c)
Packit 5c3484
define_mpn(divrem)
Packit 5c3484
define_mpn(divrem_1)
Packit 5c3484
define_mpn(divrem_1c)
Packit 5c3484
define_mpn(divrem_2)
Packit 5c3484
define_mpn(divrem_classic)
Packit 5c3484
define_mpn(divrem_newton)
Packit 5c3484
define_mpn(dump)
Packit 5c3484
define_mpn(gcd)
Packit 5c3484
define_mpn(gcd_1)
Packit 5c3484
define_mpn(gcdext)
Packit 5c3484
define_mpn(get_str)
Packit 5c3484
define_mpn(hamdist)
Packit 5c3484
define_mpn(invert_limb)
Packit 5c3484
define_mpn(invert_limb_table)
Packit 5c3484
define_mpn(ior_n)
Packit 5c3484
define_mpn(iorn_n)
Packit 5c3484
define_mpn(lshift)
Packit 5c3484
define_mpn(lshiftc)
Packit 5c3484
define_mpn(mod_1_1p)
Packit 5c3484
define_mpn(mod_1_1p_cps)
Packit 5c3484
define_mpn(mod_1s_2p)
Packit 5c3484
define_mpn(mod_1s_2p_cps)
Packit 5c3484
define_mpn(mod_1s_3p)
Packit 5c3484
define_mpn(mod_1s_3p_cps)
Packit 5c3484
define_mpn(mod_1s_4p)
Packit 5c3484
define_mpn(mod_1s_4p_cps)
Packit 5c3484
define_mpn(mod_1)
Packit 5c3484
define_mpn(mod_1c)
Packit 5c3484
define_mpn(mod_34lsub1)
Packit 5c3484
define_mpn(modexact_1_odd)
Packit 5c3484
define_mpn(modexact_1c_odd)
Packit 5c3484
define_mpn(mul)
Packit 5c3484
define_mpn(mul_1)
Packit 5c3484
define_mpn(mul_1c)
Packit 5c3484
define_mpn(mul_2)
Packit 5c3484
define_mpn(mul_3)
Packit 5c3484
define_mpn(mul_4)
Packit 5c3484
define_mpn(mul_5)
Packit 5c3484
define_mpn(mul_6)
Packit 5c3484
define_mpn(mul_basecase)
Packit 5c3484
define_mpn(mul_n)
Packit 5c3484
define_mpn(mullo_basecase)
Packit 5c3484
define_mpn(mulmid_basecase)
Packit 5c3484
define_mpn(perfect_square_p)
Packit 5c3484
define_mpn(popcount)
Packit 5c3484
define_mpn(preinv_divrem_1)
Packit 5c3484
define_mpn(preinv_mod_1)
Packit 5c3484
define_mpn(nand_n)
Packit 5c3484
define_mpn(neg)
Packit 5c3484
define_mpn(nior_n)
Packit 5c3484
define_mpn(powm)
Packit 5c3484
define_mpn(powlo)
Packit 5c3484
define_mpn(random)
Packit 5c3484
define_mpn(random2)
Packit 5c3484
define_mpn(redc_1)
Packit 5c3484
define_mpn(redc_2)
Packit 5c3484
define_mpn(rsblsh1_n)
Packit 5c3484
define_mpn(rsblsh1_nc)
Packit 5c3484
define_mpn(rsblsh2_n)
Packit 5c3484
define_mpn(rsblsh2_nc)
Packit 5c3484
define_mpn(rsblsh_n)
Packit 5c3484
define_mpn(rsblsh_nc)
Packit 5c3484
define_mpn(rsh1add_n)
Packit 5c3484
define_mpn(rsh1add_nc)
Packit 5c3484
define_mpn(rsh1sub_n)
Packit 5c3484
define_mpn(rsh1sub_nc)
Packit 5c3484
define_mpn(rshift)
Packit 5c3484
define_mpn(rshiftc)
Packit 5c3484
define_mpn(scan0)
Packit 5c3484
define_mpn(scan1)
Packit 5c3484
define_mpn(set_str)
Packit 5c3484
define_mpn(sqr_basecase)
Packit 5c3484
define_mpn(sqr_diagonal)
Packit 5c3484
define_mpn(sqr_diag_addlsh1)
Packit 5c3484
define_mpn(sub_n)
Packit 5c3484
define_mpn(sublsh1_n)
Packit 5c3484
define_mpn(sublsh1_nc)
Packit 5c3484
define_mpn(sublsh1_n_ip1)
Packit 5c3484
define_mpn(sublsh1_nc_ip1)
Packit 5c3484
define_mpn(sublsh2_n)
Packit 5c3484
define_mpn(sublsh2_nc)
Packit 5c3484
define_mpn(sublsh2_n_ip1)
Packit 5c3484
define_mpn(sublsh2_nc_ip1)
Packit 5c3484
define_mpn(sublsh_n)
Packit 5c3484
define_mpn(sublsh_nc)
Packit 5c3484
define_mpn(sublsh_n_ip1)
Packit 5c3484
define_mpn(sublsh_nc_ip1)
Packit 5c3484
define_mpn(sqrtrem)
Packit 5c3484
define_mpn(sub)
Packit 5c3484
define_mpn(sub_1)
Packit 5c3484
define_mpn(sub_err1_n)
Packit 5c3484
define_mpn(sub_err2_n)
Packit 5c3484
define_mpn(sub_err3_n)
Packit 5c3484
define_mpn(sub_n)
Packit 5c3484
define_mpn(sub_nc)
Packit 5c3484
define_mpn(submul_1)
Packit 5c3484
define_mpn(submul_1c)
Packit 5c3484
define_mpn(sec_tabselect)
Packit 5c3484
define_mpn(umul_ppmm)
Packit 5c3484
define_mpn(umul_ppmm_r)
Packit 5c3484
define_mpn(udiv_qrnnd)
Packit 5c3484
define_mpn(udiv_qrnnd_r)
Packit 5c3484
define_mpn(xnor_n)
Packit 5c3484
define_mpn(xor_n)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Defines for C global arrays and variables, with names matching what's
Packit 5c3484
dnl  used in the C code.
Packit 5c3484
dnl
Packit 5c3484
dnl  Notice that GSYM_PREFIX is included, unlike with the function defines
Packit 5c3484
dnl  above.  Also, "deflit" is used so that something like __clz_tab(%ebx)
Packit 5c3484
dnl  comes out as __gmpn_clz_tab(%ebx), for the benefit of CPUs with that
Packit 5c3484
dnl  style assembler syntax.
Packit 5c3484
Packit 5c3484
deflit(__clz_tab,
Packit 5c3484
m4_assert_defined(`GSYM_PREFIX')
Packit 5c3484
`GSYM_PREFIX`'MPN(`clz_tab')')
Packit 5c3484
Packit 5c3484
deflit(binvert_limb_table,
Packit 5c3484
m4_assert_defined(`GSYM_PREFIX')
Packit 5c3484
`GSYM_PREFIX`'__gmp_binvert_limb_table')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: ASM_START()
Packit 5c3484
dnl
Packit 5c3484
dnl  Emit any directives needed once at the start of an assembler file, like
Packit 5c3484
dnl  ".set noreorder" or whatever.  The default for this is nothing, but
Packit 5c3484
dnl  it's redefined by CPU specific m4 files.
Packit 5c3484
Packit 5c3484
define(ASM_START)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: ASM_END()
Packit 5c3484
dnl
Packit 5c3484
dnl  Emit any directives needed once at the end of an assembler file.  The
Packit 5c3484
dnl  default for this is nothing, but it's redefined by CPU specific m4 files.
Packit 5c3484
Packit 5c3484
define(ASM_END)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: PROLOGUE(foo[,param])
Packit 5c3484
dnl         EPILOGUE(foo)
Packit 5c3484
dnl
Packit 5c3484
dnl  Emit directives to start or end a function.  GSYM_PREFIX is added by
Packit 5c3484
dnl  these macros if necessary, so the given "foo" is what the function will
Packit 5c3484
dnl  be called in C.
Packit 5c3484
dnl
Packit 5c3484
dnl  The second parameter to PROLOGUE is used only for some CPUs and should
Packit 5c3484
dnl  be omitted if not required.
Packit 5c3484
dnl
Packit 5c3484
dnl  Nested or overlapping PROLOGUE/EPILOGUE pairs are allowed, if that
Packit 5c3484
dnl  makes sense for the system.  The name given to EPILOGUE must be a
Packit 5c3484
dnl  currently open PROLOGUE.
Packit 5c3484
dnl
Packit 5c3484
dnl  If only one PROLOGUE is open then the name can be omitted from
Packit 5c3484
dnl  EPILOGUE.  This is encouraged, since it means the name only has to
Packit 5c3484
dnl  appear in one place, not two.
Packit 5c3484
dnl
Packit 5c3484
dnl  The given name "foo" is not fully quoted here, it will be macro
Packit 5c3484
dnl  expanded more than once.  This is the way the m4_list macros work, and
Packit 5c3484
dnl  it also helps the tune/many.pl program do a renaming like
Packit 5c3484
dnl  -D__gmpn_add_n=mpn_add_n_foo when GSYM_PREFIX is not empty.
Packit 5c3484
Packit 5c3484
define(PROLOGUE,
Packit 5c3484
m4_assert_numargs_range(1,2)
Packit 5c3484
`m4_file_seen()dnl
Packit 5c3484
define(`PROLOGUE_list',m4_list_quote($1,PROLOGUE_list))dnl
Packit 5c3484
ifelse(`$2',,
Packit 5c3484
`PROLOGUE_cpu(GSYM_PREFIX`'$1)',
Packit 5c3484
`PROLOGUE_cpu(GSYM_PREFIX`'$1,`$2')')')
Packit 5c3484
Packit 5c3484
define(EPILOGUE,
Packit 5c3484
m4_assert_numargs_range(0,1)
Packit 5c3484
`ifelse(`$1',,
Packit 5c3484
`ifelse(m4_list_count(PROLOGUE_list),0,
Packit 5c3484
`m4_error(`no open functions for EPILOGUE
Packit 5c3484
')',
Packit 5c3484
`ifelse(m4_list_count(PROLOGUE_list),1,
Packit 5c3484
`EPILOGUE_internal(PROLOGUE_current_function)',
Packit 5c3484
`m4_error(`more than one open function for EPILOGUE
Packit 5c3484
')')')',
Packit 5c3484
`EPILOGUE_internal(`$1')')')
Packit 5c3484
Packit 5c3484
define(EPILOGUE_internal,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
m4_assert_defined(`EPILOGUE_cpu')
Packit 5c3484
`ifelse(m4_list_find($1,PROLOGUE_list),0,
Packit 5c3484
`m4_error(`EPILOGUE without PROLOGUE: $1
Packit 5c3484
')')dnl
Packit 5c3484
define(`PROLOGUE_list',m4_list_quote(m4_list_remove($1,PROLOGUE_list)))dnl
Packit 5c3484
EPILOGUE_cpu(GSYM_PREFIX`$1')')
Packit 5c3484
Packit 5c3484
dnl  Currently open PROLOGUEs, as a comma-separated list.
Packit 5c3484
define(PROLOGUE_list)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Called: PROLOGUE_check(list,...)
Packit 5c3484
dnl  Check there's no remaining open PROLOGUEs at the end of input.
Packit 5c3484
define(PROLOGUE_check,
Packit 5c3484
`ifelse($1,,,
Packit 5c3484
`m4_error(`no EPILOGUE for: $1
Packit 5c3484
')dnl
Packit 5c3484
PROLOGUE_check(shift($@))')')
Packit 5c3484
Packit 5c3484
m4wrap_prepend(`PROLOGUE_check(PROLOGUE_list)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: PROLOGUE_current_function
Packit 5c3484
dnl
Packit 5c3484
dnl  This macro expands to the current PROLOGUE/EPILOGUE function, or the
Packit 5c3484
dnl  most recent PROLOGUE if such pairs are nested or overlapped.
Packit 5c3484
Packit 5c3484
define(PROLOGUE_current_function,
Packit 5c3484
m4_assert_numargs(-1)
Packit 5c3484
`m4_list_first(PROLOGUE_list)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: PROLOGUE_cpu(GSYM_PREFIX`'foo[,param])
Packit 5c3484
dnl         EPILOGUE_cpu(GSYM_PREFIX`'foo)
Packit 5c3484
dnl
Packit 5c3484
dnl  These macros hold the CPU-specific parts of PROLOGUE and EPILOGUE.
Packit 5c3484
dnl  Both are called with the function name, with GSYM_PREFIX already
Packit 5c3484
dnl  prepended.
Packit 5c3484
dnl
Packit 5c3484
dnl  The definitions here are something typical and sensible, but CPU or
Packit 5c3484
dnl  system specific m4 files should redefine them as necessary.  The
Packit 5c3484
dnl  optional extra parameter to PROLOGUE_cpu is not expected and not
Packit 5c3484
dnl  accepted here.
Packit 5c3484
Packit 5c3484
define(PROLOGUE_cpu,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`	TEXT
Packit 5c3484
	ALIGN(8)
Packit 5c3484
	GLOBL	`$1' GLOBL_ATTR
Packit 5c3484
	TYPE(`$1',`function')
Packit 5c3484
`$1'LABEL_SUFFIX')
Packit 5c3484
Packit 5c3484
define(EPILOGUE_cpu,
Packit 5c3484
`	SIZE(`$1',.-`$1')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: L(name)
Packit 5c3484
dnl
Packit 5c3484
dnl  Generate a local label with the given name.  This is simply a
Packit 5c3484
dnl  convenient way to add LSYM_PREFIX.
Packit 5c3484
dnl
Packit 5c3484
dnl  LSYM_PREFIX might be L$, so defn() must be used to quote it or the L
Packit 5c3484
dnl  will expand again as the L macro, making an infinite recursion.
Packit 5c3484
Packit 5c3484
define(`L',
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`defn(`LSYM_PREFIX')$1')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: LDEF(name)
Packit 5c3484
dnl
Packit 5c3484
dnl  Generate a directive to define a local label.
Packit 5c3484
dnl
Packit 5c3484
dnl  On systems with a fixed syntax for defining labels there's no need to
Packit 5c3484
dnl  use this macro, it's only meant for systems where the syntax varies,
Packit 5c3484
dnl  like hppa which is "L(foo):" with gas, but just "L(foo)" in column 0
Packit 5c3484
dnl  with the system `as'.
Packit 5c3484
dnl
Packit 5c3484
dnl  The extra `' after LABEL_SUFFIX avoids any chance of a following
Packit 5c3484
dnl  "(...)"  being interpreted as an argument list.  Not that it'd be
Packit 5c3484
dnl  sensible to write anything like that after an LDEF(), but just in case.
Packit 5c3484
Packit 5c3484
define(LDEF,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
m4_assert_defined(`LABEL_SUFFIX')
Packit 5c3484
`L(`$1')`'LABEL_SUFFIX`'')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: INT32(label,value)
Packit 5c3484
dnl         INT64(label,first,second)
Packit 5c3484
Packit 5c3484
define(`INT32',
Packit 5c3484
m4_assert_defined(`W32')
Packit 5c3484
`	ALIGN(4)
Packit 5c3484
LDEF(`$1')
Packit 5c3484
	W32	$2')
Packit 5c3484
Packit 5c3484
define(`INT64',
Packit 5c3484
m4_assert_defined(`W32')
Packit 5c3484
`	ALIGN(8)
Packit 5c3484
LDEF(`$1')
Packit 5c3484
	W32	$2
Packit 5c3484
	W32	$3')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: ALIGN(bytes)
Packit 5c3484
dnl
Packit 5c3484
dnl  Emit a ".align" directive.  The alignment is specified in bytes, and
Packit 5c3484
dnl  will normally need to be a power of 2.  The actual ".align" generated
Packit 5c3484
dnl  is either bytes or logarithmic according to what ./configure finds the
Packit 5c3484
dnl  assembler needs.
Packit 5c3484
dnl
Packit 5c3484
dnl  If ALIGN_FILL_0x90 is defined and equal to "yes", then ", 0x90" is
Packit 5c3484
dnl  appended.  This is for x86, see mpn/x86/README.
Packit 5c3484
Packit 5c3484
define(ALIGN,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
m4_assert_defined(`ALIGN_LOGARITHMIC')
Packit 5c3484
`.align	ifelse(ALIGN_LOGARITHMIC,yes,`m4_log2($1)',`eval($1)')dnl
Packit 5c3484
ifelse(ALIGN_FILL_0x90,yes,`, 0x90')')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: MULFUNC_PROLOGUE(function function...)
Packit 5c3484
dnl
Packit 5c3484
dnl  A dummy macro which is grepped for by ./configure to know what
Packit 5c3484
dnl  functions a multi-function file is providing.  Use this if there aren't
Packit 5c3484
dnl  explicit PROLOGUE()s for each possible function.
Packit 5c3484
dnl
Packit 5c3484
dnl  Multiple MULFUNC_PROLOGUEs can be used, or just one with the function
Packit 5c3484
dnl  names separated by spaces.
Packit 5c3484
Packit 5c3484
define(`MULFUNC_PROLOGUE',
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: NAILS_SUPPORT(spec spec ...)
Packit 5c3484
dnl
Packit 5c3484
dnl  A dummy macro which is grepped for by ./configure to know what nails
Packit 5c3484
dnl  are supported in an asm file.
Packit 5c3484
dnl
Packit 5c3484
dnl  Ranges can be given, or just individual values.  Multiple values or
Packit 5c3484
dnl  ranges can be given, separated by spaces.  Multiple NAILS_SUPPORT
Packit 5c3484
dnl  declarations work too.  Some examples,
Packit 5c3484
dnl
Packit 5c3484
dnl         NAILS_SUPPORT(1-20)
Packit 5c3484
dnl         NAILS_SUPPORT(1 6 9-12)
Packit 5c3484
dnl         NAILS_SUPPORT(1-10 16-20)
Packit 5c3484
Packit 5c3484
define(NAILS_SUPPORT,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: ABI_SUPPORT(abi)
Packit 5c3484
dnl
Packit 5c3484
dnl  A dummy macro which is grepped for by ./configure to know what ABIs
Packit 5c3484
dnl  are supported in an asm file.
Packit 5c3484
dnl
Packit 5c3484
dnl  If multiple non-standard ABIs are supported, several ABI_SUPPORT
Packit 5c3484
dnl  declarations should be used:
Packit 5c3484
dnl
Packit 5c3484
dnl         ABI_SUPPORT(FOOABI)
Packit 5c3484
dnl         ABI_SUPPORT(BARABI)
Packit 5c3484
Packit 5c3484
define(ABI_SUPPORT,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
)
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: GMP_NUMB_MASK
Packit 5c3484
dnl
Packit 5c3484
dnl  A bit mask for the number part of a limb.  Eg. with 6 bit nails in a
Packit 5c3484
dnl  32 bit limb, GMP_NUMB_MASK would be 0x3ffffff.
Packit 5c3484
Packit 5c3484
define(GMP_NUMB_MASK,
Packit 5c3484
m4_assert_numargs(-1)
Packit 5c3484
m4_assert_defined(`GMP_NUMB_BITS')
Packit 5c3484
`m4_hex_lowmask(GMP_NUMB_BITS)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Usage: m4append(`variable',`value-to-append')
Packit 5c3484
Packit 5c3484
define(`m4append',
Packit 5c3484
`define(`$1',  defn(`$1')`$2')
Packit 5c3484
'
Packit 5c3484
)
Packit 5c3484
Packit 5c3484
divert`'dnl