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>