[BACK]Return to asm-defs.m4 CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn

Annotation of OpenXM_contrib/gmp/mpn/asm-defs.m4, Revision 1.1

1.1     ! maekawa     1: divert(-1)
        !             2: dnl
        !             3: dnl  m4 macros for gmp assembly code, shared by all CPUs.
        !             4: dnl
        !             5: dnl  These macros are designed for use with any m4 and have been used on
        !             6: dnl  GNU, FreeBSD, OpenBSD and SysV.
        !             7: dnl
        !             8: dnl  GNU m4 and OpenBSD 2.7 m4 will give filenames and line numbers in error
        !             9: dnl  messages.
        !            10:
        !            11:
        !            12: dnl  Copyright (C) 1999, 2000 Free Software Foundation, Inc.
        !            13: dnl
        !            14: dnl  This file is part of the GNU MP Library.
        !            15: dnl
        !            16: dnl  The GNU MP Library is free software; you can redistribute it and/or
        !            17: dnl  modify it under the terms of the GNU Lesser General Public License as
        !            18: dnl  published by the Free Software Foundation; either version 2.1 of the
        !            19: dnl  License, or (at your option) any later version.
        !            20: dnl
        !            21: dnl  The GNU MP Library is distributed in the hope that it will be useful,
        !            22: dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            23: dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            24: dnl  Lesser General Public License for more details.
        !            25: dnl
        !            26: dnl  You should have received a copy of the GNU Lesser General Public
        !            27: dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
        !            28: dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
        !            29: dnl  Suite 330, Boston, MA 02111-1307, USA.
        !            30:
        !            31:
        !            32: dnl  Macros:
        !            33: dnl
        !            34: dnl  Most new m4 specific macros have an "m4_" prefix to emphasise they're
        !            35: dnl  m4 expansions.  But new defining things like deflit() and defreg() are
        !            36: dnl  named like the builtin define(), and forloop() is named following the
        !            37: dnl  GNU m4 example on which it's based.
        !            38: dnl
        !            39: dnl  GNU m4 with the -P option uses "m4_" as a prefix for builtins, but that
        !            40: dnl  option isn't going to be used, so there's no conflict or confusion.
        !            41: dnl
        !            42: dnl
        !            43: dnl  Comments in output:
        !            44: dnl
        !            45: dnl  The m4 comment delimiters are left at # and \n, the normal assembler
        !            46: dnl  commenting for most CPUs.  m4 passes comment text through without
        !            47: dnl  expanding macros in it, which is generally a good thing since it stops
        !            48: dnl  unexpected expansions and possible resultant errors.
        !            49: dnl
        !            50: dnl  But note that when a quoted string is being read, a # isn't special, so
        !            51: dnl  apostrophes in comments in quoted strings must be avoided or they'll be
        !            52: dnl  interpreted as a closing quote mark.  But when the quoted text is
        !            53: dnl  re-read # will still act like a normal comment, supressing macro
        !            54: dnl  expansion.
        !            55: dnl
        !            56: dnl  For example,
        !            57: dnl
        !            58: dnl          # apostrophes in comments that're outside quotes are ok
        !            59: dnl          # and using macro names like PROLOGUE is ok too
        !            60: dnl          ...
        !            61: dnl          ifdef(`PIC',`
        !            62: dnl                  # but apostrophes aren't ok inside quotes
        !            63: dnl                  #                     ^--wrong
        !            64: dnl                  ...
        !            65: dnl                  # though macro names like PROLOGUE are still ok
        !            66: dnl                  ...
        !            67: dnl          ')
        !            68: dnl
        !            69: dnl  If macro expansion in a comment is wanted, use `#' in the .asm (ie. a
        !            70: dnl  quoted hash symbol), which will turn into # in the .s but get
        !            71: dnl  expansions done on that line.  This can make the .s more readable to
        !            72: dnl  humans, but it won't make a blind bit of difference to the assembler.
        !            73: dnl
        !            74: dnl  All the above applies, mutatis mutandis, when changecom() is used to
        !            75: dnl  select @ ! ; or whatever other commenting.
        !            76: dnl
        !            77: dnl
        !            78: dnl  Variations in m4 affecting gmp:
        !            79: dnl
        !            80: dnl  $# - When a macro is called as "foo" with no brackets, BSD m4 sets $#
        !            81: dnl       to 1, whereas GNU or SysV m4 set it to 0.  In all cases though
        !            82: dnl       "foo()" sets $# to 1.  This is worked around in various places.
        !            83: dnl
        !            84: dnl  len() - When "len()" is given an empty argument, BSD m4 evaluates to
        !            85: dnl       nothing, whereas GNU, SysV, and the new OpenBSD, evaluate to 0.
        !            86: dnl       See m4_length() below which works around this.
        !            87: dnl
        !            88: dnl  translit() - GNU m4 accepts character ranges like A-Z, and the new
        !            89: dnl       OpenBSD m4 does under option -g, but basic BSD and SysV don't.
        !            90: dnl
        !            91: dnl  popdef() - in BSD and SysV m4 popdef() takes multiple arguments and
        !            92: dnl       pops each, but GNU m4 only takes one argument.
        !            93: dnl
        !            94: dnl  push back - BSD m4 has some limits on the amount of text that can be
        !            95: dnl       pushed back.  The limit is reasonably big and so long as macros
        !            96: dnl       don't gratuitously duplicate big arguments it isn't a problem.
        !            97: dnl       Normally an error message is given, but sometimes it just hangs.
        !            98: dnl
        !            99: dnl  eval() &,|,^ - GNU and SysV m4 have bitwise operators &,|,^ available,
        !           100: dnl       but BSD m4 doesn't (contrary to what the man page suggests) and
        !           101: dnl       instead ^ is exponentiation.
        !           102: dnl
        !           103: dnl  eval() ?: - The C ternary operator "?:" is available in BSD m4, but not
        !           104: dnl       in SysV or GNU m4 (as of GNU m4 1.4 and betas of 1.5).
        !           105: dnl
        !           106: dnl  eval() -2^31 - BSD m4 has a bug where an eval() resulting in -2^31
        !           107: dnl       (ie. -2147483648) gives "-(".  Using -2147483648 within an
        !           108: dnl       expression is ok, it just can't be a final result.  "-(" will of
        !           109: dnl       course upset parsing, with all sorts of strange effects.
        !           110: dnl
        !           111: dnl  eval() <<,>> - SysV m4 doesn't support shift operators in eval() (on
        !           112: dnl       SunOS 5.7 /usr/xpg4/m4 has them but /usr/ccs/m4 doesn't).  See
        !           113: dnl       m4_lshift() and m4_rshift() below for workarounds.
        !           114: dnl
        !           115: dnl  m4wrap() - in BSD m4, m4wrap() replaces any previous m4wrap() string,
        !           116: dnl       in SysV m4 it appends to it, and in GNU m4 it prepends.  See
        !           117: dnl       m4wrap_prepend() below which brings uniformity to this.
        !           118: dnl
        !           119: dnl  __file__,__line__ - GNU m4 and OpenBSD 2.7 m4 provide these, and
        !           120: dnl       they're used here to make error messages more informative.  GNU m4
        !           121: dnl       gives an unhelpful "NONE 0" in an m4wrap(), but that's worked
        !           122: dnl       around.
        !           123: dnl
        !           124: dnl  __file__ quoting - OpenBSD m4, unlike GNU m4, doesn't quote the
        !           125: dnl       filename in __file__, so care should be taken that no macro has
        !           126: dnl       the same name as a file, or an unwanted expansion will occur when
        !           127: dnl       printing an error or warning.
        !           128: dnl
        !           129: dnl  OpenBSD 2.6 m4 - this m4 rejects decimal constants containing an 8 or 9
        !           130: dnl       in eval(), making it pretty much unusable.  This bug is confined
        !           131: dnl       to version 2.6 (it's not in 2.5, and has been fixed in 2.7).
        !           132: dnl
        !           133: dnl  SunOS /usr/bin/m4 - this m4 lacks a number of desired features,
        !           134: dnl       including $# and $@, defn(), m4exit(), m4wrap(), pushdef(),
        !           135: dnl       popdef().  /usr/5bin/m4 is a SysV style m4 which should always be
        !           136: dnl       available, and "configure" will reject /usr/bin/m4 in favour of
        !           137: dnl       /usr/5bin/m4 (if necessary).
        !           138: dnl
        !           139: dnl       The sparc code actually has modest m4 requirements currently and
        !           140: dnl       could manage with /usr/bin/m4, but there's no reason to put our
        !           141: dnl       macros through contortions when /usr/5bin/m4 is available or GNU
        !           142: dnl       m4 can be installed.
        !           143:
        !           144:
        !           145: ifdef(`__ASM_DEFS_M4_INCLUDED__',
        !           146: `m4_error(`asm-defs.m4 already included, dont include it twice
        !           147: ')m4exit(1)')
        !           148: define(`__ASM_DEFS_M4_INCLUDED__')
        !           149:
        !           150:
        !           151: dnl  Detect and give a message about the unsuitable OpenBSD 2.6 m4.
        !           152:
        !           153: ifelse(eval(89),89,,
        !           154: `errprint(
        !           155: `This m4 doesnt accept 8 and/or 9 in constants in eval(), making it unusable.
        !           156: This is probably OpenBSD 2.6 m4 (September 1999).  Upgrade to OpenBSD 2.7,
        !           157: or get a bug fix from the CVS (expr.c rev 1.9), or get GNU m4.  Dont forget
        !           158: to configure with M4=/wherever/m4 if you install one of these in a directory
        !           159: not in $PATH.
        !           160: ')m4exit(1)')
        !           161:
        !           162:
        !           163: dnl  Detect and give a message about the unsuitable SunOS /usr/bin/m4.
        !           164: dnl
        !           165: dnl  Unfortunately this test doesn't work when m4 is run in the normal way
        !           166: dnl  from mpn/Makefile with "m4 -DOPERATION_foo foo.asm", since the bad m4
        !           167: dnl  takes "-" in "-D..." to mean read stdin, so it will look like it just
        !           168: dnl  hangs.  But running "m4 asm-defs.m4" to try it out will work.
        !           169: dnl
        !           170: dnl  We'd like to abort immediately on finding a problem, but unfortunately
        !           171: dnl  the bad m4 doesn't have an m4exit(), nor does an invalid eval() kill
        !           172: dnl  it.  Unexpanded $#'s in some m4_assert_numargs() later on will comment
        !           173: dnl  out some closing parentheses and kill it with "m4: arg stack overflow".
        !           174:
        !           175: define(m4_dollarhash_works_test,``$#'')
        !           176: ifelse(m4_dollarhash_works_test(x),1,,
        !           177: `errprint(
        !           178: `This m4 doesnt support $# and cant be used for GMP asm processing.
        !           179: If this is on SunOS, ./configure should choose /usr/5bin/m4 if you have that
        !           180: or can get it, otherwise install GNU m4.  Dont forget to configure with
        !           181: M4=/wherever/m4 if you install in a directory not in $PATH.
        !           182: ')')
        !           183: undefine(`m4_dollarhash_works_test')
        !           184:
        !           185:
        !           186: dnl  --------------------------------------------------------------------------
        !           187: dnl  Basic error handling things.
        !           188:
        !           189:
        !           190: dnl  Usage: m4_dollarhash_1_if_noparen_p
        !           191: dnl
        !           192: dnl  Expand to 1 if a call "foo" gives $# set to 1 (as opposed to 0 like GNU
        !           193: dnl  and SysV m4 give).
        !           194:
        !           195: define(m4_dollarhash_1_if_noparen_test,`$#')
        !           196: define(m4_dollarhash_1_if_noparen_p,
        !           197: eval(m4_dollarhash_1_if_noparen_test==1))
        !           198: undefine(`m4_dollarhash_1_if_noparen_test')
        !           199:
        !           200:
        !           201: dnl  Usage: m4wrap_prepend(string)
        !           202: dnl
        !           203: dnl  Prepend the given string to what will be exapanded under m4wrap at the
        !           204: dnl  end of input.
        !           205: dnl
        !           206: dnl  This macro exists to work around variations in m4wrap() behaviour in
        !           207: dnl  the various m4s (notes at the start of this file).  Don't use m4wrap()
        !           208: dnl  directly since it will interfere with this scheme.
        !           209:
        !           210: define(m4wrap_prepend,
        !           211: m4_assert_numargs(1)
        !           212: `define(`m4wrap_string',`$1'defn(`m4wrap_string'))')
        !           213:
        !           214: m4wrap(`m4wrap_string')
        !           215: define(m4wrap_string,`')
        !           216:
        !           217:
        !           218: dnl  Usage: m4_file_and_line
        !           219: dnl
        !           220: dnl  Expand to the current file and line number, if the GNU m4 extensions
        !           221: dnl  __file__ and __line__ are available.
        !           222: dnl
        !           223: dnl  In GNU m4 1.4 at the end of input when m4wrap text is expanded,
        !           224: dnl  __file__ is NONE and __line__ is 0, which is not a helpful thing to
        !           225: dnl  print.  If m4_file_seen() has been called to note the last file seen,
        !           226: dnl  then that file at a big line number is used, otherwise "end of input"
        !           227: dnl  is used (although "end of input" won't parse as an error message).
        !           228:
        !           229: define(m4_file_and_line,
        !           230: `ifdef(`__file__',
        !           231: `ifelse(__file__`'__line__,`NONE0',
        !           232: `ifdef(`m4_file_seen_last',`m4_file_seen_last: 999999: ',`end of input: ')',
        !           233: `__file__: __line__: ')')')
        !           234:
        !           235:
        !           236: dnl  Usage: m4_errprint_commas(arg,...)
        !           237: dnl
        !           238: dnl  The same as errprint(), but commas are printed between arguments
        !           239: dnl  instead of spaces.
        !           240:
        !           241: define(m4_errprint_commas,
        !           242: `errprint(`$1')dnl
        !           243: ifelse(eval($#>1),1,`errprint(`,')m4_errprint_commas(shift($@))')')
        !           244:
        !           245:
        !           246: dnl  Usage: m4_error(args...)
        !           247: dnl         m4_warning(args...)
        !           248: dnl
        !           249: dnl  Print an error message, using m4_errprint_commas, prefixed with the
        !           250: dnl  current filename and line number (if available).  m4_error sets up to
        !           251: dnl  give an error exit at the end of processing, m4_warning just prints.
        !           252: dnl  These macros are the recommended way to print errors.
        !           253: dnl
        !           254: dnl  The arguments here should be quoted in the usual way to prevent them
        !           255: dnl  being expanded when the macro call is read.  (m4_error takes care not
        !           256: dnl  to do any further expansion.)
        !           257: dnl
        !           258: dnl  For example,
        !           259: dnl
        !           260: dnl         m4_error(`some error message
        !           261: dnl         ')
        !           262: dnl
        !           263: dnl  which prints
        !           264: dnl
        !           265: dnl         foo.asm:123: some error message
        !           266: dnl
        !           267: dnl  or if __file__ and __line__ aren't available
        !           268: dnl
        !           269: dnl         some error message
        !           270: dnl
        !           271: dnl  The "file:line:" format is a basic style, used by gcc and GNU m4, so
        !           272: dnl  emacs and other editors will recognise it in their normal error message
        !           273: dnl  parsing.
        !           274:
        !           275: define(m4_warning,
        !           276: `m4_errprint_commas(m4_file_and_line`'$@)')
        !           277:
        !           278: define(m4_error,
        !           279: `define(`m4_error_occurred',1)m4_warning($@)')
        !           280:
        !           281: define(`m4_error_occurred',0)
        !           282:
        !           283: dnl  This m4wrap_prepend() is first, so it'll be executed last.
        !           284: m4wrap_prepend(
        !           285: `ifelse(m4_error_occurred,1,
        !           286: `m4_error(`Errors occurred during m4 processing
        !           287: ')m4exit(1)')')
        !           288:
        !           289:
        !           290: dnl  Usage: m4_assert_numargs(num)
        !           291: dnl
        !           292: dnl  Put this unquoted on a line on its own at the start of a macro
        !           293: dnl  definition to add some code to check that num many arguments get passed
        !           294: dnl  to the macro.  For example,
        !           295: dnl
        !           296: dnl         define(foo,
        !           297: dnl         m4_assert_numargs(2)
        !           298: dnl         `something `$1' and `$2' blah blah')
        !           299: dnl
        !           300: dnl  Then a call like foo(one,two,three) will provoke an error like
        !           301: dnl
        !           302: dnl         file:10: foo expected 2 arguments, got 3 arguments
        !           303: dnl
        !           304: dnl  Here are some calls and how many arguments they're interpreted as passing.
        !           305: dnl
        !           306: dnl         foo(abc,def)  2
        !           307: dnl         foo(xyz)      1
        !           308: dnl         foo()         0
        !           309: dnl         foo          -1
        !           310: dnl
        !           311: dnl  The -1 for no parentheses at all means a macro that's meant to be used
        !           312: dnl  that way can be checked with m4_assert_numargs(-1).  For example,
        !           313: dnl
        !           314: dnl         define(SPECIAL_SUFFIX,
        !           315: dnl         m4_assert_numargs(-1)
        !           316: dnl         `ifdef(`FOO',`_foo',`_bar')')
        !           317: dnl
        !           318: dnl  But as an alternative see also deflit() below where parenthesized
        !           319: dnl  expressions following a macro are passed through to the output.
        !           320: dnl
        !           321: dnl  Note that in BSD m4 there's no way to differentiate calls "foo" and
        !           322: dnl  "foo()", so in BSD m4 the distinction between the two isn't enforced.
        !           323: dnl  (In GNU and SysV m4 it can be checked, and is.)
        !           324:
        !           325:
        !           326: dnl  m4_assert_numargs is able to check its own arguments by calling
        !           327: dnl  assert_numargs_internal directly.
        !           328: dnl
        !           329: dnl  m4_doublequote($`'0) expands to ``$0'', whereas ``$`'0'' would expand
        !           330: dnl  to `$`'0' and do the wrong thing, and likewise for $1.  The same is
        !           331: dnl  done in other assert macros.
        !           332: dnl
        !           333: dnl  $`#' leaves $# in the new macro being defined, and stops # being
        !           334: dnl  interpreted as a comment character.
        !           335: dnl
        !           336: dnl  `dnl ' means an explicit dnl isn't necessary when m4_assert_numargs is
        !           337: dnl  used.  The space means that if there is a dnl it'll still work.
        !           338:
        !           339: dnl  Usage: m4_doublequote(x) expands to ``x''
        !           340: define(m4_doublequote,
        !           341: `m4_assert_numargs_internal(`$0',1,$#,len(`$1'))``$1''')
        !           342:
        !           343: define(m4_assert_numargs,
        !           344: `m4_assert_numargs_internal(`$0',1,$#,len(`$1'))dnl
        !           345: `m4_assert_numargs_internal'(m4_doublequote($`'0),$1,$`#',`len'(m4_doublequote($`'1)))`dnl '')
        !           346:
        !           347: dnl  Called: m4_assert_numargs_internal(`macroname',wantargs,$#,len(`$1'))
        !           348: define(m4_assert_numargs_internal,
        !           349: `m4_assert_numargs_internal_check(`$1',`$2',m4_numargs_count(`$3',`$4'))')
        !           350:
        !           351: dnl  Called: m4_assert_numargs_internal_check(`macroname',wantargs,gotargs)
        !           352: dnl
        !           353: dnl  If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
        !           354: dnl  should be -1.  If wantargs is -1 but gotargs is 0 and the two can't be
        !           355: dnl  distinguished then it's allowed to pass.
        !           356: dnl
        !           357: define(m4_assert_numargs_internal_check,
        !           358: `ifelse(eval($2 == $3
        !           359:              || ($2==-1 && $3==0 && m4_dollarhash_1_if_noparen_p)),0,
        !           360: `m4_error(`$1 expected 'm4_Narguments(`$2')`, got 'm4_Narguments(`$3')
        !           361: )')')
        !           362:
        !           363: dnl  Called: m4_numargs_count($#,len(`$1'))
        !           364: dnl  If $#==0 then -1 args, if $#==1 but len(`$1')==0 then 0 args, otherwise
        !           365: dnl  $# args.
        !           366: define(m4_numargs_count,
        !           367: `ifelse($1,0, -1,
        !           368: `ifelse(eval($1==1 && $2-0==0),1, 0, $1)')')
        !           369:
        !           370: dnl  Usage: m4_Narguments(N)
        !           371: dnl  "$1 argument" or "$1 arguments" with the plural according to $1.
        !           372: define(m4_Narguments,
        !           373: `$1 argument`'ifelse(`$1',1,,s)')
        !           374:
        !           375:
        !           376: dnl  --------------------------------------------------------------------------
        !           377: dnl  Additional error checking things.
        !           378:
        !           379:
        !           380: dnl  Usage: m4_file_seen()
        !           381: dnl
        !           382: dnl  Record __file__ for the benefit of m4_file_and_line in m4wrap text.
        !           383: dnl  The basic __file__ macro comes out quoted, like `foo.asm', and
        !           384: dnl  m4_file_seen_last is defined like that too.
        !           385: dnl
        !           386: dnl  This only needs to be used with something that could generate an error
        !           387: dnl  message in m4wrap text.  The x86 PROLOGUE is the only such at the
        !           388: dnl  moment (at end of input its m4wrap checks for missing EPILOGUE).  A few
        !           389: dnl  include()s can easily trick this scheme, but you'd expect an EPILOGUE
        !           390: dnl  in the same file as the PROLOGUE.
        !           391:
        !           392: define(m4_file_seen,
        !           393: m4_assert_numargs(0)
        !           394: `ifelse(__file__,`NONE',,
        !           395: `define(`m4_file_seen_last',m4_doublequote(__file__))')')
        !           396:
        !           397:
        !           398: dnl  Usage: m4_assert_onearg()
        !           399: dnl
        !           400: dnl  Put this, unquoted, at the start of a macro definition to add some code
        !           401: dnl  to check that one argument is passed to the macro, but with that
        !           402: dnl  argument allowed to be empty.  For example,
        !           403: dnl
        !           404: dnl          define(foo,
        !           405: dnl          m4_assert_onearg()
        !           406: dnl          `blah blah $1 blah blah')
        !           407: dnl
        !           408: dnl  Calls "foo(xyz)" or "foo()" are accepted.  A call "foo(xyz,abc)" fails.
        !           409: dnl  A call "foo" fails too, but BSD m4 can't detect this case (GNU and SysV
        !           410: dnl  m4 can).
        !           411:
        !           412: define(m4_assert_onearg,
        !           413: m4_assert_numargs(0)
        !           414: `m4_assert_onearg_internal'(m4_doublequote($`'0),$`#')`dnl ')
        !           415:
        !           416: dnl  Called: m4_assert_onearg(`macroname',$#)
        !           417: define(m4_assert_onearg_internal,
        !           418: `ifelse($2,1,,
        !           419: `m4_error(`$1 expected 1 argument, got 'm4_Narguments(`$2')
        !           420: )')')
        !           421:
        !           422:
        !           423: dnl  Usage: m4_assert_numargs_range(low,high)
        !           424: dnl
        !           425: dnl  Put this, unquoted, at the start of a macro definition to add some code
        !           426: dnl  to check that between low and high many arguments get passed to the
        !           427: dnl  macro.  For example,
        !           428: dnl
        !           429: dnl         define(foo,
        !           430: dnl         m4_assert_numargs_range(3,5)
        !           431: dnl         `mandatory $1 $2 $3 optional $4 $5 end')
        !           432: dnl
        !           433: dnl  See m4_assert_numargs() for more info.
        !           434:
        !           435: define(m4_assert_numargs_range,
        !           436: m4_assert_numargs(2)
        !           437: ``m4_assert_numargs_range_internal'(m4_doublequote($`'0),$1,$2,$`#',`len'(m4_doublequote($`'1)))`dnl '')
        !           438:
        !           439: dnl  Called: m4_assert_numargs_range_internal(`name',low,high,$#,len(`$1'))
        !           440: define(m4_assert_numargs_range_internal,
        !           441: m4_assert_numargs(5)
        !           442: `m4_assert_numargs_range_check(`$1',`$2',`$3',m4_numargs_count(`$4',`$5'))')
        !           443:
        !           444: dnl  Called: m4_assert_numargs_range_check(`name',low,high,gotargs)
        !           445: dnl
        !           446: dnl  If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
        !           447: dnl  should be -1.  To ensure a `high' of -1 works, a fudge is applied to
        !           448: dnl  gotargs if it's 0 and the 0 and -1 cases can't be distinguished.
        !           449: dnl
        !           450: define(m4_assert_numargs_range_check,
        !           451: m4_assert_numargs(4)
        !           452: `ifelse(eval($2 <= $4 &&
        !           453:              ($4 - ($4==0 && m4_dollarhash_1_if_noparen_p) <= $3)),0,
        !           454: `m4_error(`$1 expected $2 to $3 arguments, got 'm4_Narguments(`$4')
        !           455: )')')
        !           456:
        !           457:
        !           458: dnl  Usage: m4_assert_defined(symbol)
        !           459: dnl
        !           460: dnl  Put this unquoted on a line of its own at the start of a macro
        !           461: dnl  definition to add some code to check that the given symbol is defined
        !           462: dnl  when the macro is used.  For example,
        !           463: dnl
        !           464: dnl          define(foo,
        !           465: dnl          m4_assert_defined(`FOO_PREFIX')
        !           466: dnl          `FOO_PREFIX whatever')
        !           467: dnl
        !           468: dnl  This is a convenient way to check that the user or ./configure or
        !           469: dnl  whatever has defined the things needed by a macro, as opposed to
        !           470: dnl  silently generating garbage.
        !           471:
        !           472: define(m4_assert_defined,
        !           473: m4_assert_numargs(1)
        !           474: ``m4_assert_defined_internal'(m4_doublequote($`'0),``$1'')`dnl '')
        !           475:
        !           476: dnl  Called: m4_assert_defined_internal(`macroname',`define_required')
        !           477: define(m4_assert_defined_internal,
        !           478: m4_assert_numargs(2)
        !           479: `ifdef(`$2',,
        !           480: `m4_error(`$1 needs $2 defined
        !           481: ')')')
        !           482:
        !           483:
        !           484: dnl  Usage: m4_not_for_expansion(`SYMBOL')
        !           485: dnl         define_not_for_expansion(`SYMBOL')
        !           486: dnl
        !           487: dnl  m4_not_for_expansion turns SYMBOL, if defined, into something which
        !           488: dnl  will give an error if expanded.  For example,
        !           489: dnl
        !           490: dnl         m4_not_for_expansion(`PIC')
        !           491: dnl
        !           492: dnl  define_not_for_expansion is the same, but always makes a definition.
        !           493: dnl
        !           494: dnl  These are for symbols that should be tested with ifdef(`FOO',...)
        !           495: dnl  rather than be expanded as such.  They guard against accidentally
        !           496: dnl  omitting the quotes, as in ifdef(FOO,...).  Note though that they only
        !           497: dnl  catches this when FOO is defined, so be sure to test code both with and
        !           498: dnl  without each definition.
        !           499:
        !           500: define(m4_not_for_expansion,
        !           501: m4_assert_numargs(1)
        !           502: `ifdef(`$1',`define_not_for_expansion(`$1')')')
        !           503:
        !           504: define(define_not_for_expansion,
        !           505: m4_assert_numargs(1)
        !           506: `ifelse(defn(`$1'),,,
        !           507: `m4_error(``$1' has a non-empty value, maybe it shouldnt be munged with m4_not_for_expansion()
        !           508: ')')dnl
        !           509: define(`$1',`m4_not_for_expansion_internal(`$1')')')
        !           510:
        !           511: define(m4_not_for_expansion_internal,
        !           512: `m4_error(``$1' is not meant to be expanded, perhaps you mean `ifdef(`$1',...)'
        !           513: ')')
        !           514:
        !           515:
        !           516: dnl  --------------------------------------------------------------------------
        !           517: dnl  Various generic m4 things.
        !           518:
        !           519:
        !           520: dnl  Usage: m4_ifdef_anyof_p(`symbol',...)
        !           521: dnl
        !           522: dnl  Expand to 1 if any of the symbols in the argument list are defined, or
        !           523: dnl  to 0 if not.
        !           524:
        !           525: define(m4_ifdef_anyof_p,
        !           526: `ifelse(eval($#<=1 && m4_length(`$1')==0),1, 0,
        !           527: `ifdef(`$1', 1,
        !           528: `m4_ifdef_anyof_p(shift($@))')')')
        !           529:
        !           530:
        !           531: dnl  Usage: m4_length(string)
        !           532: dnl
        !           533: dnl  Determine the length of a string.  This is the same as len(), but
        !           534: dnl  always expands to a number, working around the BSD len() which
        !           535: dnl  evaluates to nothing given an empty argument.
        !           536:
        !           537: define(m4_length,
        !           538: m4_assert_onearg()
        !           539: `eval(len(`$1')-0)')
        !           540:
        !           541:
        !           542: dnl  Usage: m4_stringequal_p(x,y)
        !           543: dnl
        !           544: dnl  Expand to 1 or 0 according as strings x and y are equal or not.
        !           545:
        !           546: define(m4_stringequal_p,
        !           547: `ifelse(`$1',`$2',1,0)')
        !           548:
        !           549:
        !           550: dnl  Usage: m4_incr_or_decr(n,last)
        !           551: dnl
        !           552: dnl  Do an incr(n) or decr(n), whichever is in the direction of "last".
        !           553: dnl  Both n and last must be numbers of course.
        !           554:
        !           555: define(m4_incr_or_decr,
        !           556: m4_assert_numargs(2)
        !           557: `ifelse(eval($1<$2),1,incr($1),decr($1))')
        !           558:
        !           559:
        !           560: dnl  Usage: forloop(i, first, last, statement)
        !           561: dnl
        !           562: dnl  Based on GNU m4 examples/forloop.m4, but extended.
        !           563: dnl
        !           564: dnl  statement is expanded repeatedly, with i successively defined as
        !           565: dnl
        !           566: dnl         first, first+1, ..., last-1, last
        !           567: dnl
        !           568: dnl  Or if first > last, then it's
        !           569: dnl
        !           570: dnl         first, first-1, ..., last+1, last
        !           571: dnl
        !           572: dnl  If first == last, then one expansion is done.
        !           573: dnl
        !           574: dnl  A pushdef/popdef of i is done to preserve any previous definition (or
        !           575: dnl  lack of definition).  first and last are eval()ed and so can be
        !           576: dnl  expressions.
        !           577: dnl
        !           578: dnl  forloop_first is defined to 1 on the first iteration, 0 on the rest.
        !           579: dnl  forloop_last is defined to 1 on the last iteration, 0 on the others.
        !           580: dnl  Nested forloops are allowed, in which case forloop_first and
        !           581: dnl  forloop_last apply to the innermost loop that's open.
        !           582: dnl
        !           583: dnl  A simple example,
        !           584: dnl
        !           585: dnl         forloop(i, 1, 2*2+1, `dnl
        !           586: dnl         iteration number i ... ifelse(forloop_first,1,FIRST)
        !           587: dnl         ')
        !           588:
        !           589:
        !           590: dnl  "i" and "statement" are carefully quoted, but "first" and "last" are
        !           591: dnl  just plain numbers once eval()ed.
        !           592:
        !           593: define(`forloop',
        !           594: m4_assert_numargs(4)
        !           595: `pushdef(`$1',eval(`$2'))dnl
        !           596: pushdef(`forloop_first',1)dnl
        !           597: pushdef(`forloop_last',0)dnl
        !           598: forloop_internal(`$1',eval(`$3'),`$4')`'dnl
        !           599: popdef(`forloop_first')dnl
        !           600: popdef(`forloop_last')dnl
        !           601: popdef(`$1')')
        !           602:
        !           603: dnl  Called: forloop_internal(`var',last,statement)
        !           604: define(`forloop_internal',
        !           605: m4_assert_numargs(3)
        !           606: `ifelse($1,$2,
        !           607: `define(`forloop_last',1)$3',
        !           608: `$3`'dnl
        !           609: define(`forloop_first',0)dnl
        !           610: define(`$1',m4_incr_or_decr($1,$2))dnl
        !           611: forloop_internal(`$1',$2,`$3')')')
        !           612:
        !           613:
        !           614: dnl  Usage: m4_toupper(x)
        !           615: dnl         m4_tolower(x)
        !           616: dnl
        !           617: dnl  Convert the argument string to upper or lower case, respectively.
        !           618: dnl  Only one argument accepted.
        !           619: dnl
        !           620: dnl  BSD m4 doesn't take ranges like a-z in translit(), so the full alphabet
        !           621: dnl  is written out.
        !           622:
        !           623: define(m4_alphabet_lower, `abcdefghijklmnopqrstuvwxyz')
        !           624: define(m4_alphabet_upper, `ABCDEFGHIJKLMNOPQRSTUVWXYZ')
        !           625:
        !           626: define(m4_toupper,
        !           627: m4_assert_onearg()
        !           628: `translit(`$1', m4_alphabet_lower, m4_alphabet_upper)')
        !           629:
        !           630: define(m4_tolower,
        !           631: m4_assert_onearg()
        !           632: `translit(`$1', m4_alphabet_upper, m4_alphabet_lower)')
        !           633:
        !           634:
        !           635: dnl  Usage: m4_empty_if_zero(x)
        !           636: dnl
        !           637: dnl  Evaluate to x, or to nothing if x is 0.  x is eval()ed and so can be an
        !           638: dnl  expression.
        !           639: dnl
        !           640: dnl  This is useful for x86 addressing mode displacements since forms like
        !           641: dnl  (%ebx) are one byte shorter than 0(%ebx).  A macro `foo' for use as
        !           642: dnl  foo(%ebx) could be defined with the following so it'll be empty if the
        !           643: dnl  expression comes out zero.
        !           644: dnl
        !           645: dnl       deflit(`foo', `m4_empty_if_zero(a+b*4-c)')
        !           646: dnl
        !           647: dnl  Naturally this shouldn't be done if, say, a computed jump depends on
        !           648: dnl  the code being a particular size.
        !           649:
        !           650: define(m4_empty_if_zero,
        !           651: m4_assert_onearg()
        !           652: `ifelse(eval($1),0,,eval($1))')
        !           653:
        !           654:
        !           655: dnl  Usage: m4_log2(x)
        !           656: dnl
        !           657: dnl  Calculate a logarithm to base 2.
        !           658: dnl  x must be an integral power of 2, between 2**0 and 2**30.
        !           659: dnl  x is eval()ed, so it can be an expression.
        !           660: dnl  An error results if x is invalid.
        !           661: dnl
        !           662: dnl  2**31 isn't supported, because an unsigned 2147483648 is out of range
        !           663: dnl  of a 32-bit signed int.  Also, the bug in BSD m4 where an eval()
        !           664: dnl  resulting in 2147483648 (or -2147483648 as the case may be) gives `-('
        !           665: dnl  means tests like eval(1<<31==(x)) would be necessary, but that then
        !           666: dnl  gives an unattractive explosion of eval() error messages if x isn't
        !           667: dnl  numeric.
        !           668:
        !           669: define(m4_log2,
        !           670: m4_assert_numargs(1)
        !           671: `m4_log2_internal(0,1,eval(`$1'))')
        !           672:
        !           673: dnl  Called: m4_log2_internal(n,2**n,target)
        !           674: define(m4_log2_internal,
        !           675: m4_assert_numargs(3)
        !           676: `ifelse($2,$3,$1,
        !           677: `ifelse($1,30,
        !           678: `m4_error(`m4_log2() argument too big or not a power of two: $3
        !           679: ')',
        !           680: `m4_log2_internal(incr($1),eval(2*$2),$3)')')')
        !           681:
        !           682:
        !           683: dnl  Usage:  m4_div2_towards_zero
        !           684: dnl
        !           685: dnl  m4 division is probably whatever a C signed division is, and C doesn't
        !           686: dnl  specify what rounding gets used on negatives, so this expression forces
        !           687: dnl  a rounding towards zero.
        !           688:
        !           689: define(m4_div2_towards_zero,
        !           690: m4_assert_numargs(1)
        !           691: `eval((($1) + ((($1)<0) & ($1))) / 2)')
        !           692:
        !           693:
        !           694: dnl  Usage: m4_lshift(n,count)
        !           695: dnl         m4_rshift(n,count)
        !           696: dnl
        !           697: dnl  Calculate n shifted left or right by count many bits.  Both n and count
        !           698: dnl  are eval()ed and so can be expressions.
        !           699: dnl
        !           700: dnl  Negative counts are allowed and mean a shift in the opposite direction.
        !           701: dnl  Negative n is allowed and right shifts will be arithmetic (meaning
        !           702: dnl  divide by 2**count, rounding towards zero, also meaning the sign bit is
        !           703: dnl  duplicated).
        !           704: dnl
        !           705: dnl  Use these macros instead of << and >> in eval() since the basic ccs
        !           706: dnl  SysV m4 doesn't have those operators.
        !           707:
        !           708: define(m4_rshift,
        !           709: m4_assert_numargs(2)
        !           710: `m4_lshift(`$1',-(`$2'))')
        !           711:
        !           712: define(m4_lshift,
        !           713: m4_assert_numargs(2)
        !           714: `m4_lshift_internal(eval(`$1'),eval(`$2'))')
        !           715:
        !           716: define(m4_lshift_internal,
        !           717: m4_assert_numargs(2)
        !           718: `ifelse(eval($2-0==0),1,$1,
        !           719: `ifelse(eval($2>0),1,
        !           720: `m4_lshift_internal(eval($1*2),decr($2))',
        !           721: `m4_lshift_internal(m4_div2_towards_zero($1),incr($2))')')')
        !           722:
        !           723:
        !           724: dnl  Usage: deflit(name,value)
        !           725: dnl
        !           726: dnl  Like define(), but "name" expands like a literal, rather than taking
        !           727: dnl  arguments.  For example "name(%eax)" expands to "value(%eax)".
        !           728: dnl
        !           729: dnl  Limitations:
        !           730: dnl
        !           731: dnl  $ characters in the value part must have quotes to stop them looking
        !           732: dnl  like macro parameters.  For example, deflit(reg,`123+$`'4+567').  See
        !           733: dnl  defreg() below for handling simple register definitions like $7 etc.
        !           734: dnl
        !           735: dnl  "name()" is turned into "name", unfortunately.  In GNU and SysV m4 an
        !           736: dnl  error is generated when this happens, but in BSD m4 it will happen
        !           737: dnl  silently.  The problem is that in BSD m4 $# is 1 in both "name" or
        !           738: dnl  "name()", so there's no way to differentiate them.  Because we want
        !           739: dnl  plain "name" to turn into plain "value", we end up with "name()"
        !           740: dnl  turning into plain "value" too.
        !           741: dnl
        !           742: dnl  "name(foo)" will lose any whitespace after commas in "foo", for example
        !           743: dnl  "disp(%eax, %ecx)" would become "128(%eax,%ecx)".
        !           744: dnl
        !           745: dnl  These parentheses oddities shouldn't matter in assembler text, but if
        !           746: dnl  they do the suggested workaround is to write "name ()" or "name (foo)"
        !           747: dnl  to stop the parentheses looking like a macro argument list.  If a space
        !           748: dnl  isn't acceptable in the output, then write "name`'()" or "name`'(foo)".
        !           749: dnl  The `' is stripped when read, but again stops the parentheses looking
        !           750: dnl  like parameters.
        !           751:
        !           752: dnl  Quoting for deflit_emptyargcheck is similar to m4_assert_numargs.  The
        !           753: dnl  stuff in the ifelse gives a $#, $1 and $@ evaluated in the new macro
        !           754: dnl  created, not in deflit.
        !           755: define(deflit,
        !           756: m4_assert_numargs(2)
        !           757: `define(`$1',
        !           758: `deflit_emptyargcheck'(``$1'',$`#',m4_doublequote($`'1))`dnl
        !           759: $2`'dnl
        !           760: ifelse(eval($'`#>1 || m4_length('m4_doublequote($`'1)`)!=0),1,($'`@))')')
        !           761:
        !           762: dnl  Called: deflit_emptyargcheck(macroname,$#,`$1')
        !           763: define(deflit_emptyargcheck,
        !           764: `ifelse(eval($2==1 && !m4_dollarhash_1_if_noparen_p && m4_length(`$3')==0),1,
        !           765: `m4_error(`dont use a deflit as $1() because it loses the brackets (see deflit in asm-incl.m4 for more information)
        !           766: ')')')
        !           767:
        !           768:
        !           769: dnl  Usage: m4_assert(`expr')
        !           770: dnl
        !           771: dnl  Test a compile-time requirement with an m4 expression.  The expression
        !           772: dnl  should be quoted, and will be eval()ed and expected to be non-zero.
        !           773: dnl  For example,
        !           774: dnl
        !           775: dnl         m4_assert(`FOO*2+6 < 14')
        !           776:
        !           777: define(m4_assert,
        !           778: m4_assert_numargs(1)
        !           779: `ifelse(eval($1),1,,
        !           780: `m4_error(`assertion failed: $1
        !           781: ')')')
        !           782:
        !           783:
        !           784: dnl  --------------------------------------------------------------------------
        !           785: dnl  Various assembler things, not specific to any particular CPU.
        !           786: dnl
        !           787:
        !           788:
        !           789: dnl  Usage: include_mpn(`filename')
        !           790: dnl
        !           791: dnl  Like include(), but adds a path to the mpn source directory.  For
        !           792: dnl  example,
        !           793: dnl
        !           794: dnl         include_mpn(`sparc64/addmul_1h.asm')
        !           795:
        !           796: define(include_mpn,
        !           797: m4_assert_numargs(1)
        !           798: m4_assert_defined(`CONFIG_TOP_SRCDIR')
        !           799: `include(CONFIG_TOP_SRCDIR`/mpn/$1')')
        !           800:
        !           801:
        !           802: dnl  Usage: C comment ...
        !           803: dnl
        !           804: dnl  "C" works like a FORTRAN-style comment character.  This can be used for
        !           805: dnl  comments to the right of assembly instructions, where just dnl would
        !           806: dnl  remove the linefeed, and concatenate adjacent lines.
        !           807: dnl
        !           808: dnl  "C" and/or "dnl" are useful when an assembler doesn't support comments,
        !           809: dnl  or where different assemblers for a particular CPU have different
        !           810: dnl  comment styles.  The intermediate ".s" files will end up with no
        !           811: dnl  comments, just code.
        !           812: dnl
        !           813: dnl  Using "C" is not intended to cause offence to anyone who doesn't like
        !           814: dnl  FORTRAN; but if that happens it's an unexpected bonus.
        !           815:
        !           816: define(C, `
        !           817: dnl')
        !           818:
        !           819:
        !           820: dnl  Various possible defines passed from the Makefile that are to be tested
        !           821: dnl  with ifdef() rather than be expanded.
        !           822:
        !           823: m4_not_for_expansion(`PIC')
        !           824:
        !           825: dnl  aors_n
        !           826: m4_not_for_expansion(`OPERATION_add_n')
        !           827: m4_not_for_expansion(`OPERATION_sub_n')
        !           828:
        !           829: dnl  aorsmul_n
        !           830: m4_not_for_expansion(`OPERATION_addmul_1')
        !           831: m4_not_for_expansion(`OPERATION_submul_1')
        !           832:
        !           833: dnl  logops_n
        !           834: m4_not_for_expansion(`OPERATION_and_n')
        !           835: m4_not_for_expansion(`OPERATION_andn_n')
        !           836: m4_not_for_expansion(`OPERATION_nand_n')
        !           837: m4_not_for_expansion(`OPERATION_ior_n')
        !           838: m4_not_for_expansion(`OPERATION_iorn_n')
        !           839: m4_not_for_expansion(`OPERATION_nior_n')
        !           840: m4_not_for_expansion(`OPERATION_xor_n')
        !           841: m4_not_for_expansion(`OPERATION_xnor_n')
        !           842:
        !           843: dnl  popham
        !           844: m4_not_for_expansion(`OPERATION_popcount')
        !           845: m4_not_for_expansion(`OPERATION_hamdist')
        !           846:
        !           847:
        !           848: dnl  Usage: m4_config_gmp_mparam(`symbol')
        !           849: dnl
        !           850: dnl  Check that `symbol' is defined.  If it isn't, issue an error and
        !           851: dnl  terminate immediately.  The error message explains that the symbol
        !           852: dnl  should be in config.m4, copied from gmp-mparam.h.
        !           853: dnl
        !           854: dnl  Processing is terminated immediately since missing something like
        !           855: dnl  KARATSUBA_SQR_THRESHOLD can lead to infinite loops with endless error
        !           856: dnl  messages.
        !           857:
        !           858: define(m4_config_gmp_mparam,
        !           859: m4_assert_numargs(1)
        !           860: `ifdef(`$1',,
        !           861: `m4_error(`$1 is not defined.
        !           862:        "configure" should have extracted this from gmp-mparam.h and put it
        !           863:        in config.m4, but somehow this has failed.
        !           864: ')m4exit(1)')')
        !           865:
        !           866:
        !           867: dnl  Usage: defreg(name,reg)
        !           868: dnl
        !           869: dnl  Give a name to a $ style register.  For example,
        !           870: dnl
        !           871: dnl         defreg(foo,$12)
        !           872: dnl
        !           873: dnl  defreg() inserts an extra pair of quotes after the $ so that it's not
        !           874: dnl  interpreted as an m4 macro parameter, ie. foo is actually $`'12.  m4
        !           875: dnl  strips those quotes when foo is expanded.
        !           876: dnl
        !           877: dnl  deflit() is used to make the new definition, so it will expand
        !           878: dnl  literally even if followed by parentheses ie. foo(99) will become
        !           879: dnl  $12(99).  (But there's nowhere that would be used is there?)
        !           880: dnl
        !           881: dnl  When making further definitions from existing defreg() macros, remember
        !           882: dnl  to use defreg() again to protect the $ in the new definitions too.  For
        !           883: dnl  example,
        !           884: dnl
        !           885: dnl         defreg(a0,$4)
        !           886: dnl         defreg(a1,$5)
        !           887: dnl         ...
        !           888: dnl
        !           889: dnl         defreg(PARAM_DST,a0)
        !           890: dnl
        !           891: dnl  This is only because a0 is expanding at the time the PARAM_DST
        !           892: dnl  definition is made, leaving a literal $4 that must be re-quoted.  On
        !           893: dnl  the other hand in something like the following ra is only expanded when
        !           894: dnl  ret is used and its $`'31 protection will have its desired effect at
        !           895: dnl  that time.
        !           896: dnl
        !           897: dnl         defreg(ra,$31)
        !           898: dnl         ...
        !           899: dnl         define(ret,`j ra')
        !           900: dnl
        !           901: dnl  Note that only $n forms are meant to be used here, and something like
        !           902: dnl  128($30) doesn't get protected and will come out wrong.
        !           903:
        !           904: define(defreg,
        !           905: m4_assert_numargs(2)
        !           906: `deflit(`$1',
        !           907: substr(`$2',0,1)``''substr(`$2',1))')
        !           908:
        !           909:
        !           910: dnl  Usage: m4_instruction_wrapper(num)
        !           911: dnl
        !           912: dnl  Put this, unquoted, on a line on its own, at the start of a macro
        !           913: dnl  that's a wrapper around an assembler instruction.  It adds code to give
        !           914: dnl  a descriptive error message if the macro is invoked without arguments.
        !           915: dnl
        !           916: dnl  For example, suppose jmp needs to be wrapped,
        !           917: dnl
        !           918: dnl         define(jmp,
        !           919: dnl         m4_instruction_wrapper()
        !           920: dnl         m4_assert_numargs(1)
        !           921: dnl                 `.byte 0x42
        !           922: dnl                 .long  $1
        !           923: dnl                 nop')
        !           924: dnl
        !           925: dnl  The point of m4_instruction_wrapper is to get a better error message
        !           926: dnl  than m4_assert_numargs would give if jmp is accidentally used as plain
        !           927: dnl  "jmp foo" instead of the intended "jmp( foo)".  "jmp()" with no
        !           928: dnl  argument also provokes the error message.
        !           929: dnl
        !           930: dnl  m4_instruction_wrapper should only be used with wrapped instructions
        !           931: dnl  that take arguments, since obviously something meant to be used as
        !           932: dnl  plain "ret", say, doesn't want to give an error when used that way.
        !           933:
        !           934: define(m4_instruction_wrapper,
        !           935: m4_assert_numargs(0)
        !           936: ``m4_instruction_wrapper_internal'(m4_doublequote($`'0),dnl
        !           937: m4_doublequote(ifdef(`__file__',__file__,`the m4 sources')),dnl
        !           938: $`#',m4_doublequote($`'1))`dnl'')
        !           939:
        !           940: dnl  Called: m4_instruction_wrapper_internal($0,`filename',$#,$1)
        !           941: define(m4_instruction_wrapper_internal,
        !           942: `ifelse(eval($3<=1 && m4_length(`$4')==0),1,
        !           943: `m4_error(`$1 is a macro replacing that instruction and needs arguments, see $2 for details
        !           944: ')')')
        !           945:
        !           946:
        !           947: dnl  Usage: UNROLL_LOG2, UNROLL_MASK, UNROLL_BYTES
        !           948: dnl         CHUNK_LOG2, CHUNK_MASK, CHUNK_BYTES
        !           949: dnl
        !           950: dnl  When code supports a variable amount of loop unrolling, the convention
        !           951: dnl  is to define UNROLL_COUNT to the number of limbs processed per loop.
        !           952: dnl  When testing code this can be varied to see how much the loop overhead
        !           953: dnl  is costing.  For example,
        !           954: dnl
        !           955: dnl         deflit(UNROLL_COUNT, 32)
        !           956: dnl
        !           957: dnl  If the forloop() generating the unrolled loop has a pattern processing
        !           958: dnl  more than one limb, the convention is to express this with CHUNK_COUNT.
        !           959: dnl  For example,
        !           960: dnl
        !           961: dnl         deflit(CHUNK_COUNT, 2)
        !           962: dnl
        !           963: dnl  The LOG2, MASK and BYTES definitions below are derived from these COUNT
        !           964: dnl  definitions.  If COUNT is redefined, the LOG2, MASK and BYTES follow
        !           965: dnl  the new definition automatically.
        !           966: dnl
        !           967: dnl  LOG2 is the log base 2 of COUNT.  MASK is COUNT-1, which can be used as
        !           968: dnl  a bit mask.  BYTES is BYTES_PER_MP_LIMB*COUNT, the number of bytes
        !           969: dnl  processed in each unrolled loop.
        !           970: dnl
        !           971: dnl  BYTES_PER_MP_LIMB is defined in a CPU specific m4 include file.  It
        !           972: dnl  exists only so the BYTES definitions here can be common to all CPUs.
        !           973: dnl  In the actual code for a given CPU, an explicit 4 or 8 may as well be
        !           974: dnl  used because the code is only for a particular CPU, it doesn't need to
        !           975: dnl  be general.
        !           976: dnl
        !           977: dnl  Note that none of these macros do anything except give conventional
        !           978: dnl  names to commonly used things.  You still have to write your own
        !           979: dnl  expressions for a forloop() and the resulting address displacements.
        !           980: dnl  Something like the following would be typical for 4 bytes per limb.
        !           981: dnl
        !           982: dnl         forloop(`i',0,UNROLL_COUNT-1,`
        !           983: dnl                 deflit(`disp',eval(i*4))
        !           984: dnl                 ...
        !           985: dnl         ')
        !           986: dnl
        !           987: dnl  Or when using CHUNK_COUNT,
        !           988: dnl
        !           989: dnl         forloop(`i',0,UNROLL_COUNT/CHUNK_COUNT-1,`
        !           990: dnl                 deflit(`disp0',eval(i*CHUNK_COUNT*4))
        !           991: dnl                 deflit(`disp1',eval(disp0+4))
        !           992: dnl                 ...
        !           993: dnl         ')
        !           994: dnl
        !           995: dnl  Clearly `i' can be run starting from 1, or from high to low or whatever
        !           996: dnl  best suits.
        !           997:
        !           998: deflit(UNROLL_LOG2,
        !           999: m4_assert_defined(`UNROLL_COUNT')
        !          1000: `m4_log2(UNROLL_COUNT)')
        !          1001:
        !          1002: deflit(UNROLL_MASK,
        !          1003: m4_assert_defined(`UNROLL_COUNT')
        !          1004: `eval(UNROLL_COUNT-1)')
        !          1005:
        !          1006: deflit(UNROLL_BYTES,
        !          1007: m4_assert_defined(`UNROLL_COUNT')
        !          1008: m4_assert_defined(`BYTES_PER_MP_LIMB')
        !          1009: `eval(UNROLL_COUNT * BYTES_PER_MP_LIMB)')
        !          1010:
        !          1011: deflit(CHUNK_LOG2,
        !          1012: m4_assert_defined(`CHUNK_COUNT')
        !          1013: `m4_log2(CHUNK_COUNT)')
        !          1014:
        !          1015: deflit(CHUNK_MASK,
        !          1016: m4_assert_defined(`CHUNK_COUNT')
        !          1017: `eval(CHUNK_COUNT-1)')
        !          1018:
        !          1019: deflit(CHUNK_BYTES,
        !          1020: m4_assert_defined(`CHUNK_COUNT')
        !          1021: m4_assert_defined(`BYTES_PER_MP_LIMB')
        !          1022: `eval(CHUNK_COUNT * BYTES_PER_MP_LIMB)')
        !          1023:
        !          1024:
        !          1025: dnl  Usage: MPN(name)
        !          1026: dnl
        !          1027: dnl  Add MPN_PREFIX to a name.
        !          1028: dnl  MPN_PREFIX defaults to "__gmpn_" if not defined.
        !          1029:
        !          1030: ifdef(`MPN_PREFIX',,
        !          1031: `define(`MPN_PREFIX',`__gmpn_')')
        !          1032:
        !          1033: define(MPN,
        !          1034: m4_assert_numargs(1)
        !          1035: `MPN_PREFIX`'$1')
        !          1036:
        !          1037:
        !          1038: dnl  Usage: mpn_add_n, etc
        !          1039: dnl
        !          1040: dnl  Convenience definitions using MPN(), like the #defines in gmp.h.  Each
        !          1041: dnl  function that might be implemented in assembler is here.
        !          1042:
        !          1043: define(define_mpn,
        !          1044: m4_assert_numargs(1)
        !          1045: `define(`mpn_$1',`MPN(`$1')')')
        !          1046:
        !          1047: define_mpn(add)
        !          1048: define_mpn(add_1)
        !          1049: define_mpn(add_n)
        !          1050: define_mpn(add_nc)
        !          1051: define_mpn(addmul_1)
        !          1052: define_mpn(addmul_1c)
        !          1053: define_mpn(addsub_n)
        !          1054: define_mpn(addsub_nc)
        !          1055: define_mpn(and_n)
        !          1056: define_mpn(andn_n)
        !          1057: define_mpn(bdivmod)
        !          1058: define_mpn(cmp)
        !          1059: define_mpn(com_n)
        !          1060: define_mpn(copyd)
        !          1061: define_mpn(copyi)
        !          1062: define_mpn(divexact_by3c)
        !          1063: define_mpn(divrem)
        !          1064: define_mpn(divrem_1)
        !          1065: define_mpn(divrem_1c)
        !          1066: define_mpn(divrem_2)
        !          1067: define_mpn(divrem_classic)
        !          1068: define_mpn(divrem_newton)
        !          1069: define_mpn(dump)
        !          1070: define_mpn(gcd)
        !          1071: define_mpn(gcd_1)
        !          1072: define_mpn(gcdext)
        !          1073: define_mpn(get_str)
        !          1074: define_mpn(hamdist)
        !          1075: define_mpn(invert_limb)
        !          1076: define_mpn(ior_n)
        !          1077: define_mpn(iorn_n)
        !          1078: define_mpn(kara_mul_n)
        !          1079: define_mpn(kara_sqr_n)
        !          1080: define_mpn(lshift)
        !          1081: define_mpn(lshiftc)
        !          1082: define_mpn(mod_1)
        !          1083: define_mpn(mod_1c)
        !          1084: define_mpn(mul)
        !          1085: define_mpn(mul_1)
        !          1086: define_mpn(mul_1c)
        !          1087: define_mpn(mul_basecase)
        !          1088: define_mpn(mul_n)
        !          1089: define_mpn(perfect_square_p)
        !          1090: define_mpn(popcount)
        !          1091: define_mpn(preinv_mod_1)
        !          1092: define_mpn(nand_n)
        !          1093: define_mpn(nior_n)
        !          1094: define_mpn(random)
        !          1095: define_mpn(random2)
        !          1096: define_mpn(rshift)
        !          1097: define_mpn(rshiftc)
        !          1098: define_mpn(scan0)
        !          1099: define_mpn(scan1)
        !          1100: define_mpn(set_str)
        !          1101: define_mpn(sqr_basecase)
        !          1102: define_mpn(sub_n)
        !          1103: define_mpn(sqrtrem)
        !          1104: define_mpn(sub)
        !          1105: define_mpn(sub_1)
        !          1106: define_mpn(sub_n)
        !          1107: define_mpn(sub_nc)
        !          1108: define_mpn(submul_1)
        !          1109: define_mpn(submul_1c)
        !          1110: define_mpn(toom3_mul_n)
        !          1111: define_mpn(toom3_sqr_n)
        !          1112: define_mpn(umul_ppmm)
        !          1113: define_mpn(udiv_qrnnd)
        !          1114: define_mpn(xnor_n)
        !          1115: define_mpn(xor_n)
        !          1116:
        !          1117: define(`ASM_START',
        !          1118:        `')
        !          1119:
        !          1120: define(`PROLOGUE',
        !          1121:        `
        !          1122:        TEXT
        !          1123:        ALIGN(4)
        !          1124:        GLOBL   GSYM_PREFIX`$1'
        !          1125:        TYPE(GSYM_PREFIX`$1',`function')
        !          1126: GSYM_PREFIX`$1':')
        !          1127:
        !          1128: define(`EPILOGUE',
        !          1129:        `
        !          1130:        SIZE(GSYM_PREFIX`$1',.-GSYM_PREFIX`$1')')
        !          1131:
        !          1132: dnl  LSYM_PREFIX might be L$, so defn() must be used to quote it or the L
        !          1133: dnl  will expand as the L macro, an infinite recursion.
        !          1134: define(`L',`defn(`LSYM_PREFIX')$1')
        !          1135:
        !          1136: define(`INT32',
        !          1137:        `
        !          1138:        ALIGN(4)
        !          1139: $1:
        !          1140:        W32     $2
        !          1141:        ')
        !          1142:
        !          1143: define(`INT64',
        !          1144:        `
        !          1145:        ALIGN(8)
        !          1146: $1:
        !          1147:        W32     $2
        !          1148:        W32     $3
        !          1149:        ')
        !          1150:
        !          1151:
        !          1152: dnl  Usage: ALIGN(bytes)
        !          1153: dnl
        !          1154: dnl  Emit a ".align" directive.  The alignment is specified in bytes, and
        !          1155: dnl  will normally need to be a power of 2.  The actual ".align" generated
        !          1156: dnl  is either bytes or logarithmic according to what ./configure detects.
        !          1157: dnl
        !          1158: dnl  ALIGN_FILL_0x90, if defined and equal to "yes", means a ", 0x90" should
        !          1159: dnl  be appended (this is for x86).
        !          1160:
        !          1161: define(ALIGN,
        !          1162: m4_assert_numargs(1)
        !          1163: m4_assert_defined(`ALIGN_LOGARITHMIC')
        !          1164: `.align        ifelse(ALIGN_LOGARITHMIC,yes,`m4_log2($1)',`eval($1)')dnl
        !          1165: ifelse(ALIGN_FILL_0x90,yes,`, 0x90')')
        !          1166:
        !          1167:
        !          1168: dnl  Usage: MULFUNC_PROLOGUE(function function...)
        !          1169: dnl
        !          1170: dnl  A dummy macro which is grepped for by ./configure to know what
        !          1171: dnl  functions a multi-function file is providing.  Use this if there aren't
        !          1172: dnl  explicit PROLOGUE()s for each possible function.
        !          1173: dnl
        !          1174: dnl  Multiple MULFUNC_PROLOGUEs can be used, or just one with the function
        !          1175: dnl  names separated by spaces.
        !          1176:
        !          1177: define(`MULFUNC_PROLOGUE',
        !          1178: m4_assert_numargs(1)
        !          1179: `')
        !          1180:
        !          1181:
        !          1182: divert`'dnl

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>