Annotation of OpenXM_contrib/gmp/mpn/asm-defs.m4, Revision 1.1.1.2
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:
1.1.1.2 ! ohara 12: dnl Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
! 13: dnl
1.1 maekawa 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
1.1.1.2 ! ohara 115: dnl m4wrap() sequence - in BSD m4, m4wrap() replaces any previous m4wrap()
! 116: dnl string, in SysV m4 it appends to it, and in GNU m4 it prepends.
! 117: dnl See m4wrap_prepend() below which brings uniformity to this.
! 118: dnl
! 119: dnl m4wrap() 0xFF - old versions of BSD m4 store EOF in a C "char" under an
! 120: dnl m4wrap() and on systems where char is unsigned by default a
! 121: dnl spurious 0xFF is output. This has been observed on recent Unicos
! 122: dnl Alpha and MacOS X systems. An autoconf test is used to check for
! 123: dnl this, see the m4wrap handling below. It might work to end the
! 124: dnl m4wrap string with a dnl to consume the 0xFF, but that probably
! 125: dnl induces the offending m4's to read from an already closed "FILE
! 126: dnl *", which could be bad on a glibc style stdio.
1.1 maekawa 127: dnl
128: dnl __file__,__line__ - GNU m4 and OpenBSD 2.7 m4 provide these, and
129: dnl they're used here to make error messages more informative. GNU m4
130: dnl gives an unhelpful "NONE 0" in an m4wrap(), but that's worked
131: dnl around.
132: dnl
133: dnl __file__ quoting - OpenBSD m4, unlike GNU m4, doesn't quote the
134: dnl filename in __file__, so care should be taken that no macro has
135: dnl the same name as a file, or an unwanted expansion will occur when
136: dnl printing an error or warning.
137: dnl
1.1.1.2 ! ohara 138: dnl changecom() - BSD m4 changecom doesn't quite work like the man page
! 139: dnl suggests, in particular "changecom" or "changecom()" doesn't
! 140: dnl disable the comment feature, and multi-character comment sequences
! 141: dnl don't seem to work. If the default `#' and newline aren't
! 142: dnl suitable it's necessary to change it to something else,
! 143: dnl eg. changecom(;).
! 144: dnl
! 145: dnl OpenBSD 2.6 m4 - in this m4, eval() rejects decimal constants containing
! 146: dnl an 8 or 9, making it pretty much unusable. The bug is confined to
! 147: dnl version 2.6 (it's not in 2.5, and has been fixed in 2.7).
1.1 maekawa 148: dnl
149: dnl SunOS /usr/bin/m4 - this m4 lacks a number of desired features,
150: dnl including $# and $@, defn(), m4exit(), m4wrap(), pushdef(),
151: dnl popdef(). /usr/5bin/m4 is a SysV style m4 which should always be
152: dnl available, and "configure" will reject /usr/bin/m4 in favour of
153: dnl /usr/5bin/m4 (if necessary).
154: dnl
155: dnl The sparc code actually has modest m4 requirements currently and
156: dnl could manage with /usr/bin/m4, but there's no reason to put our
157: dnl macros through contortions when /usr/5bin/m4 is available or GNU
158: dnl m4 can be installed.
159:
160:
161: ifdef(`__ASM_DEFS_M4_INCLUDED__',
162: `m4_error(`asm-defs.m4 already included, dont include it twice
163: ')m4exit(1)')
164: define(`__ASM_DEFS_M4_INCLUDED__')
165:
166:
167: dnl Detect and give a message about the unsuitable OpenBSD 2.6 m4.
168:
169: ifelse(eval(89),89,,
170: `errprint(
171: `This m4 doesnt accept 8 and/or 9 in constants in eval(), making it unusable.
172: This is probably OpenBSD 2.6 m4 (September 1999). Upgrade to OpenBSD 2.7,
173: or get a bug fix from the CVS (expr.c rev 1.9), or get GNU m4. Dont forget
174: to configure with M4=/wherever/m4 if you install one of these in a directory
175: not in $PATH.
176: ')m4exit(1)')
177:
178:
179: dnl Detect and give a message about the unsuitable SunOS /usr/bin/m4.
180: dnl
181: dnl Unfortunately this test doesn't work when m4 is run in the normal way
182: dnl from mpn/Makefile with "m4 -DOPERATION_foo foo.asm", since the bad m4
183: dnl takes "-" in "-D..." to mean read stdin, so it will look like it just
184: dnl hangs. But running "m4 asm-defs.m4" to try it out will work.
185: dnl
186: dnl We'd like to abort immediately on finding a problem, but unfortunately
187: dnl the bad m4 doesn't have an m4exit(), nor does an invalid eval() kill
188: dnl it. Unexpanded $#'s in some m4_assert_numargs() later on will comment
189: dnl out some closing parentheses and kill it with "m4: arg stack overflow".
190:
191: define(m4_dollarhash_works_test,``$#'')
192: ifelse(m4_dollarhash_works_test(x),1,,
193: `errprint(
194: `This m4 doesnt support $# and cant be used for GMP asm processing.
195: If this is on SunOS, ./configure should choose /usr/5bin/m4 if you have that
196: or can get it, otherwise install GNU m4. Dont forget to configure with
197: M4=/wherever/m4 if you install in a directory not in $PATH.
198: ')')
199: undefine(`m4_dollarhash_works_test')
200:
201:
202: dnl --------------------------------------------------------------------------
203: dnl Basic error handling things.
204:
205:
206: dnl Usage: m4_dollarhash_1_if_noparen_p
207: dnl
208: dnl Expand to 1 if a call "foo" gives $# set to 1 (as opposed to 0 like GNU
209: dnl and SysV m4 give).
210:
211: define(m4_dollarhash_1_if_noparen_test,`$#')
212: define(m4_dollarhash_1_if_noparen_p,
213: eval(m4_dollarhash_1_if_noparen_test==1))
214: undefine(`m4_dollarhash_1_if_noparen_test')
215:
216:
217: dnl Usage: m4wrap_prepend(string)
218: dnl
219: dnl Prepend the given string to what will be exapanded under m4wrap at the
220: dnl end of input.
221: dnl
222: dnl This macro exists to work around variations in m4wrap() behaviour in
223: dnl the various m4s (notes at the start of this file). Don't use m4wrap()
224: dnl directly since it will interfere with this scheme.
225:
226: define(m4wrap_prepend,
227: m4_assert_numargs(1)
228: `define(`m4wrap_string',`$1'defn(`m4wrap_string'))')
229:
230: define(m4wrap_string,`')
231:
1.1.1.2 ! ohara 232: define(m4wrap_works_p,
! 233: `ifelse(M4WRAP_SPURIOUS,yes,0,1)')
! 234:
! 235: ifelse(m4wrap_works_p,1,
! 236: `m4wrap(`m4wrap_string')')
! 237:
1.1 maekawa 238:
239: dnl Usage: m4_file_and_line
240: dnl
241: dnl Expand to the current file and line number, if the GNU m4 extensions
242: dnl __file__ and __line__ are available.
243: dnl
244: dnl In GNU m4 1.4 at the end of input when m4wrap text is expanded,
245: dnl __file__ is NONE and __line__ is 0, which is not a helpful thing to
246: dnl print. If m4_file_seen() has been called to note the last file seen,
247: dnl then that file at a big line number is used, otherwise "end of input"
248: dnl is used (although "end of input" won't parse as an error message).
249:
250: define(m4_file_and_line,
251: `ifdef(`__file__',
252: `ifelse(__file__`'__line__,`NONE0',
253: `ifdef(`m4_file_seen_last',`m4_file_seen_last: 999999: ',`end of input: ')',
254: `__file__: __line__: ')')')
255:
256:
257: dnl Usage: m4_errprint_commas(arg,...)
258: dnl
259: dnl The same as errprint(), but commas are printed between arguments
260: dnl instead of spaces.
261:
262: define(m4_errprint_commas,
263: `errprint(`$1')dnl
264: ifelse(eval($#>1),1,`errprint(`,')m4_errprint_commas(shift($@))')')
265:
266:
267: dnl Usage: m4_error(args...)
268: dnl m4_warning(args...)
269: dnl
270: dnl Print an error message, using m4_errprint_commas, prefixed with the
271: dnl current filename and line number (if available). m4_error sets up to
272: dnl give an error exit at the end of processing, m4_warning just prints.
273: dnl These macros are the recommended way to print errors.
274: dnl
275: dnl The arguments here should be quoted in the usual way to prevent them
276: dnl being expanded when the macro call is read. (m4_error takes care not
277: dnl to do any further expansion.)
278: dnl
279: dnl For example,
280: dnl
281: dnl m4_error(`some error message
282: dnl ')
283: dnl
284: dnl which prints
285: dnl
286: dnl foo.asm:123: some error message
287: dnl
288: dnl or if __file__ and __line__ aren't available
289: dnl
290: dnl some error message
291: dnl
292: dnl The "file:line:" format is a basic style, used by gcc and GNU m4, so
293: dnl emacs and other editors will recognise it in their normal error message
294: dnl parsing.
295:
296: define(m4_warning,
297: `m4_errprint_commas(m4_file_and_line`'$@)')
298:
299: define(m4_error,
1.1.1.2 ! ohara 300: `define(`m4_error_occurred',1)m4_warning($@)dnl
! 301: ifelse(m4wrap_works_p,0,`m4exit(1)')')
1.1 maekawa 302:
303: define(`m4_error_occurred',0)
304:
305: dnl This m4wrap_prepend() is first, so it'll be executed last.
306: m4wrap_prepend(
307: `ifelse(m4_error_occurred,1,
308: `m4_error(`Errors occurred during m4 processing
309: ')m4exit(1)')')
310:
311:
312: dnl Usage: m4_assert_numargs(num)
313: dnl
314: dnl Put this unquoted on a line on its own at the start of a macro
315: dnl definition to add some code to check that num many arguments get passed
316: dnl to the macro. For example,
317: dnl
318: dnl define(foo,
319: dnl m4_assert_numargs(2)
320: dnl `something `$1' and `$2' blah blah')
321: dnl
322: dnl Then a call like foo(one,two,three) will provoke an error like
323: dnl
324: dnl file:10: foo expected 2 arguments, got 3 arguments
325: dnl
326: dnl Here are some calls and how many arguments they're interpreted as passing.
327: dnl
328: dnl foo(abc,def) 2
329: dnl foo(xyz) 1
330: dnl foo() 0
331: dnl foo -1
332: dnl
333: dnl The -1 for no parentheses at all means a macro that's meant to be used
334: dnl that way can be checked with m4_assert_numargs(-1). For example,
335: dnl
336: dnl define(SPECIAL_SUFFIX,
337: dnl m4_assert_numargs(-1)
338: dnl `ifdef(`FOO',`_foo',`_bar')')
339: dnl
340: dnl But as an alternative see also deflit() below where parenthesized
341: dnl expressions following a macro are passed through to the output.
342: dnl
343: dnl Note that in BSD m4 there's no way to differentiate calls "foo" and
344: dnl "foo()", so in BSD m4 the distinction between the two isn't enforced.
345: dnl (In GNU and SysV m4 it can be checked, and is.)
346:
347:
348: dnl m4_assert_numargs is able to check its own arguments by calling
349: dnl assert_numargs_internal directly.
350: dnl
351: dnl m4_doublequote($`'0) expands to ``$0'', whereas ``$`'0'' would expand
352: dnl to `$`'0' and do the wrong thing, and likewise for $1. The same is
353: dnl done in other assert macros.
354: dnl
355: dnl $`#' leaves $# in the new macro being defined, and stops # being
356: dnl interpreted as a comment character.
357: dnl
358: dnl `dnl ' means an explicit dnl isn't necessary when m4_assert_numargs is
359: dnl used. The space means that if there is a dnl it'll still work.
360:
361: dnl Usage: m4_doublequote(x) expands to ``x''
362: define(m4_doublequote,
363: `m4_assert_numargs_internal(`$0',1,$#,len(`$1'))``$1''')
364:
365: define(m4_assert_numargs,
366: `m4_assert_numargs_internal(`$0',1,$#,len(`$1'))dnl
367: `m4_assert_numargs_internal'(m4_doublequote($`'0),$1,$`#',`len'(m4_doublequote($`'1)))`dnl '')
368:
369: dnl Called: m4_assert_numargs_internal(`macroname',wantargs,$#,len(`$1'))
370: define(m4_assert_numargs_internal,
371: `m4_assert_numargs_internal_check(`$1',`$2',m4_numargs_count(`$3',`$4'))')
372:
373: dnl Called: m4_assert_numargs_internal_check(`macroname',wantargs,gotargs)
374: dnl
375: dnl If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
376: dnl should be -1. If wantargs is -1 but gotargs is 0 and the two can't be
377: dnl distinguished then it's allowed to pass.
378: dnl
379: define(m4_assert_numargs_internal_check,
380: `ifelse(eval($2 == $3
381: || ($2==-1 && $3==0 && m4_dollarhash_1_if_noparen_p)),0,
382: `m4_error(`$1 expected 'm4_Narguments(`$2')`, got 'm4_Narguments(`$3')
383: )')')
384:
385: dnl Called: m4_numargs_count($#,len(`$1'))
386: dnl If $#==0 then -1 args, if $#==1 but len(`$1')==0 then 0 args, otherwise
387: dnl $# args.
388: define(m4_numargs_count,
389: `ifelse($1,0, -1,
390: `ifelse(eval($1==1 && $2-0==0),1, 0, $1)')')
391:
392: dnl Usage: m4_Narguments(N)
393: dnl "$1 argument" or "$1 arguments" with the plural according to $1.
394: define(m4_Narguments,
395: `$1 argument`'ifelse(`$1',1,,s)')
396:
397:
398: dnl --------------------------------------------------------------------------
399: dnl Additional error checking things.
400:
401:
402: dnl Usage: m4_file_seen()
403: dnl
404: dnl Record __file__ for the benefit of m4_file_and_line in m4wrap text.
405: dnl The basic __file__ macro comes out quoted, like `foo.asm', and
406: dnl m4_file_seen_last is defined like that too.
407: dnl
408: dnl This only needs to be used with something that could generate an error
409: dnl message in m4wrap text. The x86 PROLOGUE is the only such at the
410: dnl moment (at end of input its m4wrap checks for missing EPILOGUE). A few
411: dnl include()s can easily trick this scheme, but you'd expect an EPILOGUE
412: dnl in the same file as the PROLOGUE.
413:
414: define(m4_file_seen,
415: m4_assert_numargs(0)
416: `ifelse(__file__,`NONE',,
417: `define(`m4_file_seen_last',m4_doublequote(__file__))')')
418:
419:
420: dnl Usage: m4_assert_onearg()
421: dnl
422: dnl Put this, unquoted, at the start of a macro definition to add some code
423: dnl to check that one argument is passed to the macro, but with that
424: dnl argument allowed to be empty. For example,
425: dnl
426: dnl define(foo,
427: dnl m4_assert_onearg()
428: dnl `blah blah $1 blah blah')
429: dnl
430: dnl Calls "foo(xyz)" or "foo()" are accepted. A call "foo(xyz,abc)" fails.
431: dnl A call "foo" fails too, but BSD m4 can't detect this case (GNU and SysV
432: dnl m4 can).
433:
434: define(m4_assert_onearg,
435: m4_assert_numargs(0)
436: `m4_assert_onearg_internal'(m4_doublequote($`'0),$`#')`dnl ')
437:
438: dnl Called: m4_assert_onearg(`macroname',$#)
439: define(m4_assert_onearg_internal,
440: `ifelse($2,1,,
441: `m4_error(`$1 expected 1 argument, got 'm4_Narguments(`$2')
442: )')')
443:
444:
445: dnl Usage: m4_assert_numargs_range(low,high)
446: dnl
447: dnl Put this, unquoted, at the start of a macro definition to add some code
448: dnl to check that between low and high many arguments get passed to the
449: dnl macro. For example,
450: dnl
451: dnl define(foo,
452: dnl m4_assert_numargs_range(3,5)
453: dnl `mandatory $1 $2 $3 optional $4 $5 end')
454: dnl
455: dnl See m4_assert_numargs() for more info.
456:
457: define(m4_assert_numargs_range,
458: m4_assert_numargs(2)
459: ``m4_assert_numargs_range_internal'(m4_doublequote($`'0),$1,$2,$`#',`len'(m4_doublequote($`'1)))`dnl '')
460:
461: dnl Called: m4_assert_numargs_range_internal(`name',low,high,$#,len(`$1'))
462: define(m4_assert_numargs_range_internal,
463: m4_assert_numargs(5)
464: `m4_assert_numargs_range_check(`$1',`$2',`$3',m4_numargs_count(`$4',`$5'))')
465:
466: dnl Called: m4_assert_numargs_range_check(`name',low,high,gotargs)
467: dnl
468: dnl If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
469: dnl should be -1. To ensure a `high' of -1 works, a fudge is applied to
470: dnl gotargs if it's 0 and the 0 and -1 cases can't be distinguished.
471: dnl
472: define(m4_assert_numargs_range_check,
473: m4_assert_numargs(4)
474: `ifelse(eval($2 <= $4 &&
475: ($4 - ($4==0 && m4_dollarhash_1_if_noparen_p) <= $3)),0,
476: `m4_error(`$1 expected $2 to $3 arguments, got 'm4_Narguments(`$4')
477: )')')
478:
479:
480: dnl Usage: m4_assert_defined(symbol)
481: dnl
482: dnl Put this unquoted on a line of its own at the start of a macro
483: dnl definition to add some code to check that the given symbol is defined
484: dnl when the macro is used. For example,
485: dnl
486: dnl define(foo,
487: dnl m4_assert_defined(`FOO_PREFIX')
488: dnl `FOO_PREFIX whatever')
489: dnl
490: dnl This is a convenient way to check that the user or ./configure or
491: dnl whatever has defined the things needed by a macro, as opposed to
492: dnl silently generating garbage.
493:
494: define(m4_assert_defined,
495: m4_assert_numargs(1)
496: ``m4_assert_defined_internal'(m4_doublequote($`'0),``$1'')`dnl '')
497:
498: dnl Called: m4_assert_defined_internal(`macroname',`define_required')
499: define(m4_assert_defined_internal,
500: m4_assert_numargs(2)
501: `ifdef(`$2',,
502: `m4_error(`$1 needs $2 defined
503: ')')')
504:
505:
506: dnl Usage: m4_not_for_expansion(`SYMBOL')
507: dnl define_not_for_expansion(`SYMBOL')
508: dnl
509: dnl m4_not_for_expansion turns SYMBOL, if defined, into something which
510: dnl will give an error if expanded. For example,
511: dnl
512: dnl m4_not_for_expansion(`PIC')
513: dnl
514: dnl define_not_for_expansion is the same, but always makes a definition.
515: dnl
516: dnl These are for symbols that should be tested with ifdef(`FOO',...)
517: dnl rather than be expanded as such. They guard against accidentally
518: dnl omitting the quotes, as in ifdef(FOO,...). Note though that they only
519: dnl catches this when FOO is defined, so be sure to test code both with and
520: dnl without each definition.
521:
522: define(m4_not_for_expansion,
523: m4_assert_numargs(1)
524: `ifdef(`$1',`define_not_for_expansion(`$1')')')
525:
526: define(define_not_for_expansion,
527: m4_assert_numargs(1)
528: `ifelse(defn(`$1'),,,
529: `m4_error(``$1' has a non-empty value, maybe it shouldnt be munged with m4_not_for_expansion()
530: ')')dnl
531: define(`$1',`m4_not_for_expansion_internal(`$1')')')
532:
533: define(m4_not_for_expansion_internal,
534: `m4_error(``$1' is not meant to be expanded, perhaps you mean `ifdef(`$1',...)'
535: ')')
536:
537:
538: dnl --------------------------------------------------------------------------
539: dnl Various generic m4 things.
540:
541:
542: dnl Usage: m4_ifdef_anyof_p(`symbol',...)
543: dnl
544: dnl Expand to 1 if any of the symbols in the argument list are defined, or
545: dnl to 0 if not.
546:
547: define(m4_ifdef_anyof_p,
548: `ifelse(eval($#<=1 && m4_length(`$1')==0),1, 0,
549: `ifdef(`$1', 1,
550: `m4_ifdef_anyof_p(shift($@))')')')
551:
552:
553: dnl Usage: m4_length(string)
554: dnl
555: dnl Determine the length of a string. This is the same as len(), but
556: dnl always expands to a number, working around the BSD len() which
557: dnl evaluates to nothing given an empty argument.
558:
559: define(m4_length,
560: m4_assert_onearg()
561: `eval(len(`$1')-0)')
562:
563:
564: dnl Usage: m4_stringequal_p(x,y)
565: dnl
566: dnl Expand to 1 or 0 according as strings x and y are equal or not.
567:
568: define(m4_stringequal_p,
569: `ifelse(`$1',`$2',1,0)')
570:
571:
572: dnl Usage: m4_incr_or_decr(n,last)
573: dnl
574: dnl Do an incr(n) or decr(n), whichever is in the direction of "last".
575: dnl Both n and last must be numbers of course.
576:
577: define(m4_incr_or_decr,
578: m4_assert_numargs(2)
579: `ifelse(eval($1<$2),1,incr($1),decr($1))')
580:
581:
582: dnl Usage: forloop(i, first, last, statement)
583: dnl
584: dnl Based on GNU m4 examples/forloop.m4, but extended.
585: dnl
586: dnl statement is expanded repeatedly, with i successively defined as
587: dnl
588: dnl first, first+1, ..., last-1, last
589: dnl
590: dnl Or if first > last, then it's
591: dnl
592: dnl first, first-1, ..., last+1, last
593: dnl
594: dnl If first == last, then one expansion is done.
595: dnl
596: dnl A pushdef/popdef of i is done to preserve any previous definition (or
597: dnl lack of definition). first and last are eval()ed and so can be
598: dnl expressions.
599: dnl
600: dnl forloop_first is defined to 1 on the first iteration, 0 on the rest.
601: dnl forloop_last is defined to 1 on the last iteration, 0 on the others.
602: dnl Nested forloops are allowed, in which case forloop_first and
603: dnl forloop_last apply to the innermost loop that's open.
604: dnl
605: dnl A simple example,
606: dnl
607: dnl forloop(i, 1, 2*2+1, `dnl
608: dnl iteration number i ... ifelse(forloop_first,1,FIRST)
609: dnl ')
610:
611:
612: dnl "i" and "statement" are carefully quoted, but "first" and "last" are
613: dnl just plain numbers once eval()ed.
614:
615: define(`forloop',
616: m4_assert_numargs(4)
617: `pushdef(`$1',eval(`$2'))dnl
618: pushdef(`forloop_first',1)dnl
619: pushdef(`forloop_last',0)dnl
620: forloop_internal(`$1',eval(`$3'),`$4')`'dnl
621: popdef(`forloop_first')dnl
622: popdef(`forloop_last')dnl
623: popdef(`$1')')
624:
625: dnl Called: forloop_internal(`var',last,statement)
626: define(`forloop_internal',
627: m4_assert_numargs(3)
628: `ifelse($1,$2,
629: `define(`forloop_last',1)$3',
630: `$3`'dnl
631: define(`forloop_first',0)dnl
632: define(`$1',m4_incr_or_decr($1,$2))dnl
633: forloop_internal(`$1',$2,`$3')')')
634:
635:
636: dnl Usage: m4_toupper(x)
637: dnl m4_tolower(x)
638: dnl
639: dnl Convert the argument string to upper or lower case, respectively.
640: dnl Only one argument accepted.
641: dnl
642: dnl BSD m4 doesn't take ranges like a-z in translit(), so the full alphabet
643: dnl is written out.
644:
645: define(m4_alphabet_lower, `abcdefghijklmnopqrstuvwxyz')
646: define(m4_alphabet_upper, `ABCDEFGHIJKLMNOPQRSTUVWXYZ')
647:
648: define(m4_toupper,
649: m4_assert_onearg()
650: `translit(`$1', m4_alphabet_lower, m4_alphabet_upper)')
651:
652: define(m4_tolower,
653: m4_assert_onearg()
654: `translit(`$1', m4_alphabet_upper, m4_alphabet_lower)')
655:
656:
657: dnl Usage: m4_empty_if_zero(x)
658: dnl
659: dnl Evaluate to x, or to nothing if x is 0. x is eval()ed and so can be an
660: dnl expression.
661: dnl
662: dnl This is useful for x86 addressing mode displacements since forms like
663: dnl (%ebx) are one byte shorter than 0(%ebx). A macro `foo' for use as
664: dnl foo(%ebx) could be defined with the following so it'll be empty if the
665: dnl expression comes out zero.
666: dnl
667: dnl deflit(`foo', `m4_empty_if_zero(a+b*4-c)')
668: dnl
669: dnl Naturally this shouldn't be done if, say, a computed jump depends on
670: dnl the code being a particular size.
671:
672: define(m4_empty_if_zero,
673: m4_assert_onearg()
674: `ifelse(eval($1),0,,eval($1))')
675:
676:
677: dnl Usage: m4_log2(x)
678: dnl
679: dnl Calculate a logarithm to base 2.
680: dnl x must be an integral power of 2, between 2**0 and 2**30.
681: dnl x is eval()ed, so it can be an expression.
682: dnl An error results if x is invalid.
683: dnl
684: dnl 2**31 isn't supported, because an unsigned 2147483648 is out of range
685: dnl of a 32-bit signed int. Also, the bug in BSD m4 where an eval()
686: dnl resulting in 2147483648 (or -2147483648 as the case may be) gives `-('
687: dnl means tests like eval(1<<31==(x)) would be necessary, but that then
688: dnl gives an unattractive explosion of eval() error messages if x isn't
689: dnl numeric.
690:
691: define(m4_log2,
692: m4_assert_numargs(1)
693: `m4_log2_internal(0,1,eval(`$1'))')
694:
695: dnl Called: m4_log2_internal(n,2**n,target)
696: define(m4_log2_internal,
697: m4_assert_numargs(3)
698: `ifelse($2,$3,$1,
699: `ifelse($1,30,
700: `m4_error(`m4_log2() argument too big or not a power of two: $3
701: ')',
702: `m4_log2_internal(incr($1),eval(2*$2),$3)')')')
703:
704:
705: dnl Usage: m4_div2_towards_zero
706: dnl
707: dnl m4 division is probably whatever a C signed division is, and C doesn't
708: dnl specify what rounding gets used on negatives, so this expression forces
709: dnl a rounding towards zero.
710:
711: define(m4_div2_towards_zero,
712: m4_assert_numargs(1)
713: `eval((($1) + ((($1)<0) & ($1))) / 2)')
714:
715:
716: dnl Usage: m4_lshift(n,count)
717: dnl m4_rshift(n,count)
718: dnl
719: dnl Calculate n shifted left or right by count many bits. Both n and count
720: dnl are eval()ed and so can be expressions.
721: dnl
722: dnl Negative counts are allowed and mean a shift in the opposite direction.
723: dnl Negative n is allowed and right shifts will be arithmetic (meaning
724: dnl divide by 2**count, rounding towards zero, also meaning the sign bit is
725: dnl duplicated).
726: dnl
727: dnl Use these macros instead of << and >> in eval() since the basic ccs
728: dnl SysV m4 doesn't have those operators.
729:
730: define(m4_rshift,
731: m4_assert_numargs(2)
732: `m4_lshift(`$1',-(`$2'))')
733:
734: define(m4_lshift,
735: m4_assert_numargs(2)
736: `m4_lshift_internal(eval(`$1'),eval(`$2'))')
737:
738: define(m4_lshift_internal,
739: m4_assert_numargs(2)
740: `ifelse(eval($2-0==0),1,$1,
741: `ifelse(eval($2>0),1,
742: `m4_lshift_internal(eval($1*2),decr($2))',
743: `m4_lshift_internal(m4_div2_towards_zero($1),incr($2))')')')
744:
745:
1.1.1.2 ! ohara 746: dnl Usage: m4_popcount(n)
! 747: dnl
! 748: dnl Expand to the number 1 bits in n.
! 749:
! 750: define(m4_popcount,
! 751: m4_assert_numargs(1)
! 752: `m4_popcount_internal(0,eval(`$1'))')
! 753:
! 754: dnl Called: m4_popcount_internal(count,rem)
! 755: define(m4_popcount_internal,
! 756: m4_assert_numargs(2)
! 757: `ifelse($2,0,$1,
! 758: `m4_popcount_internal(eval($1+($2%2)),eval($2/2))')')
! 759:
! 760:
! 761: dnl Usage: m4_count_trailing_zeros(N)
! 762: dnl
! 763: dnl Determine the number of trailing zero bits on N. N is eval()ed and so
! 764: dnl can be an expression. If N is zero an error is generated.
! 765:
! 766: define(m4_count_trailing_zeros,
! 767: m4_assert_numargs(1)
! 768: `m4_count_trailing_zeros_internal(eval(`$1'),0)')
! 769:
! 770: dnl Called: m4_count_trailing_zeros_internal(val,count)
! 771: define(m4_count_trailing_zeros_internal,
! 772: m4_assert_numargs(2)
! 773: `ifelse($1,0,
! 774: `m4_error(`m4_count_trailing_zeros() given a zero value')',
! 775: `ifelse(eval(($1)%2),1,`$2',
! 776: `m4_count_trailing_zeros_internal(eval($1/2),incr($2))')')')
! 777:
! 778:
1.1 maekawa 779: dnl Usage: deflit(name,value)
780: dnl
781: dnl Like define(), but "name" expands like a literal, rather than taking
782: dnl arguments. For example "name(%eax)" expands to "value(%eax)".
783: dnl
784: dnl Limitations:
785: dnl
786: dnl $ characters in the value part must have quotes to stop them looking
787: dnl like macro parameters. For example, deflit(reg,`123+$`'4+567'). See
788: dnl defreg() below for handling simple register definitions like $7 etc.
789: dnl
790: dnl "name()" is turned into "name", unfortunately. In GNU and SysV m4 an
791: dnl error is generated when this happens, but in BSD m4 it will happen
792: dnl silently. The problem is that in BSD m4 $# is 1 in both "name" or
793: dnl "name()", so there's no way to differentiate them. Because we want
794: dnl plain "name" to turn into plain "value", we end up with "name()"
795: dnl turning into plain "value" too.
796: dnl
797: dnl "name(foo)" will lose any whitespace after commas in "foo", for example
798: dnl "disp(%eax, %ecx)" would become "128(%eax,%ecx)".
799: dnl
800: dnl These parentheses oddities shouldn't matter in assembler text, but if
801: dnl they do the suggested workaround is to write "name ()" or "name (foo)"
802: dnl to stop the parentheses looking like a macro argument list. If a space
803: dnl isn't acceptable in the output, then write "name`'()" or "name`'(foo)".
804: dnl The `' is stripped when read, but again stops the parentheses looking
805: dnl like parameters.
806:
807: dnl Quoting for deflit_emptyargcheck is similar to m4_assert_numargs. The
808: dnl stuff in the ifelse gives a $#, $1 and $@ evaluated in the new macro
809: dnl created, not in deflit.
810: define(deflit,
811: m4_assert_numargs(2)
812: `define(`$1',
813: `deflit_emptyargcheck'(``$1'',$`#',m4_doublequote($`'1))`dnl
814: $2`'dnl
815: ifelse(eval($'`#>1 || m4_length('m4_doublequote($`'1)`)!=0),1,($'`@))')')
816:
817: dnl Called: deflit_emptyargcheck(macroname,$#,`$1')
818: define(deflit_emptyargcheck,
819: `ifelse(eval($2==1 && !m4_dollarhash_1_if_noparen_p && m4_length(`$3')==0),1,
820: `m4_error(`dont use a deflit as $1() because it loses the brackets (see deflit in asm-incl.m4 for more information)
821: ')')')
822:
823:
824: dnl Usage: m4_assert(`expr')
825: dnl
826: dnl Test a compile-time requirement with an m4 expression. The expression
827: dnl should be quoted, and will be eval()ed and expected to be non-zero.
828: dnl For example,
829: dnl
830: dnl m4_assert(`FOO*2+6 < 14')
831:
832: define(m4_assert,
833: m4_assert_numargs(1)
834: `ifelse(eval($1),1,,
835: `m4_error(`assertion failed: $1
836: ')')')
837:
838:
1.1.1.2 ! ohara 839: dnl Usage: m4_repeat(count,text)
! 840: dnl
! 841: dnl Expand to the given repetitions of the given text. A zero count is
! 842: dnl allowed, and expands to nothing.
! 843:
! 844: define(m4_repeat,
! 845: m4_assert_numargs(2)
! 846: `m4_repeat_internal(eval($1),`$2')')
! 847:
! 848: define(m4_repeat_internal,
! 849: m4_assert_numargs(2)
! 850: `ifelse(`$1',0,,
! 851: `forloop(m4_repeat_internal_counter,1,$1,``$2'')')')
! 852:
! 853:
! 854: dnl Usage: m4_hex_lowmask(bits)
! 855: dnl
! 856: dnl Generate a hex constant which is a low mask of the given number of
! 857: dnl bits. For example m4_hex_lowmask(10) would give 0x3ff.
! 858:
! 859: define(m4_hex_lowmask,
! 860: m4_assert_numargs(1)
! 861: `m4_cpu_hex_constant(m4_hex_lowmask_internal1(eval(`$1')))')
! 862:
! 863: dnl Called: m4_hex_lowmask_internal1(bits)
! 864: define(m4_hex_lowmask_internal1,
! 865: m4_assert_numargs(1)
! 866: `ifelse($1,0,`0',
! 867: `m4_hex_lowmask_internal2(eval(($1)%4),eval(($1)/4))')')
! 868:
! 869: dnl Called: m4_hex_lowmask_internal(remainder,digits)
! 870: define(m4_hex_lowmask_internal2,
! 871: m4_assert_numargs(2)
! 872: `ifelse($1,1,`1',
! 873: `ifelse($1,2,`3',
! 874: `ifelse($1,3,`7')')')dnl
! 875: m4_repeat($2,`f')')
! 876:
! 877:
! 878: dnl --------------------------------------------------------------------------
! 879: dnl The following m4_list functions take a list as multiple arguments.
! 880: dnl Arguments are evaluated multiple times, there's no attempt at strict
! 881: dnl quoting. Empty list elements are not allowed, since an empty final
! 882: dnl argument is ignored. These restrictions don't affect the current uses,
! 883: dnl and make the implementation easier.
! 884:
! 885:
! 886: dnl Usage: m4_list_quote(list,...)
! 887: dnl
! 888: dnl Produce a list with quoted commas, so it can be a single argument
! 889: dnl string. For instance m4_list_quote(a,b,c) gives
! 890: dnl
! 891: dnl a`,'b`,'c`,'
! 892: dnl
! 893: dnl This can be used to put a list in a define,
! 894: dnl
! 895: dnl define(foolist, m4_list_quote(a,b,c))
! 896: dnl
! 897: dnl Which can then be used for instance as
! 898: dnl
! 899: dnl m4_list_find(target, foolist)
! 900:
! 901: define(m4_list_quote,
! 902: `ifelse(`$1',,,
! 903: `$1`,'m4_list_quote(shift($@))')')
! 904:
! 905:
! 906: dnl Usage: m4_list_find(key,list,...)
! 907: dnl
! 908: dnl Evaluate to 1 or 0 according to whether key is in the list elements.
! 909:
! 910: define(m4_list_find,
! 911: m4_assert_numargs_range(1,1000)
! 912: `ifelse(`$2',,0,
! 913: `ifelse(`$1',`$2',1,
! 914: `m4_list_find(`$1',shift(shift($@)))')')')
! 915:
! 916:
! 917: dnl Usage: m4_list_remove(key,list,...)
! 918: dnl
! 919: dnl Evaluate to the given list with `key' removed (if present).
! 920:
! 921: define(m4_list_remove,
! 922: m4_assert_numargs_range(1,1000)
! 923: `ifelse(`$2',,,
! 924: `ifelse(`$1',`$2',,`$2,')dnl
! 925: m4_list_remove(`$1',shift(shift($@)))')')
! 926:
! 927:
! 928: dnl Usage: m4_list_first(list,...)
! 929: dnl
! 930: dnl Evaluate to the first element of the list (if any).
! 931:
! 932: define(m4_list_first,`$1')
! 933:
! 934:
! 935: dnl Usage: m4_list_count(list,...)
! 936: dnl
! 937: dnl Evaluate to the number of elements in the list. This can't just use $#
! 938: dnl because the last element might be empty.
! 939:
! 940: define(m4_list_count,
! 941: `m4_list_count_internal(0,$@)')
! 942:
! 943: dnl Called: m4_list_internal(count,list,...)
! 944: define(m4_list_count_internal,
! 945: m4_assert_numargs_range(1,1000)
! 946: `ifelse(`$2',,$1,
! 947: `m4_list_count_internal(eval($1+1),shift(shift($@)))')')
! 948:
! 949:
1.1 maekawa 950: dnl --------------------------------------------------------------------------
951: dnl Various assembler things, not specific to any particular CPU.
952: dnl
953:
954:
955: dnl Usage: include_mpn(`filename')
956: dnl
957: dnl Like include(), but adds a path to the mpn source directory. For
958: dnl example,
959: dnl
960: dnl include_mpn(`sparc64/addmul_1h.asm')
961:
962: define(include_mpn,
963: m4_assert_numargs(1)
964: m4_assert_defined(`CONFIG_TOP_SRCDIR')
965: `include(CONFIG_TOP_SRCDIR`/mpn/$1')')
966:
967:
968: dnl Usage: C comment ...
969: dnl
1.1.1.2 ! ohara 970: dnl This works like a FORTRAN-style comment character. It can be used for
1.1 maekawa 971: dnl comments to the right of assembly instructions, where just dnl would
1.1.1.2 ! ohara 972: dnl remove the newline and concatenate adjacent lines.
1.1 maekawa 973: dnl
1.1.1.2 ! ohara 974: dnl C and/or dnl are useful when an assembler doesn't support comments, or
! 975: dnl where different assemblers for a particular CPU need different styles.
! 976: dnl The intermediate ".s" files will end up with no comments, just code.
1.1 maekawa 977: dnl
1.1.1.2 ! ohara 978: dnl Using C is not intended to cause offence to anyone who doesn't like
1.1 maekawa 979: dnl FORTRAN; but if that happens it's an unexpected bonus.
1.1.1.2 ! ohara 980: dnl
! 981: dnl During development, if comments are wanted in the .s files to help see
! 982: dnl what's expanding where, C can be redefined with something like
! 983: dnl
! 984: dnl define(`C',`#')
1.1 maekawa 985:
986: define(C, `
987: dnl')
988:
989:
990: dnl Various possible defines passed from the Makefile that are to be tested
991: dnl with ifdef() rather than be expanded.
992:
993: m4_not_for_expansion(`PIC')
1.1.1.2 ! ohara 994: m4_not_for_expansion(`DLL_EXPORT')
1.1 maekawa 995:
996: dnl aors_n
997: m4_not_for_expansion(`OPERATION_add_n')
998: m4_not_for_expansion(`OPERATION_sub_n')
999:
1.1.1.2 ! ohara 1000: dnl aorsmul_1
1.1 maekawa 1001: m4_not_for_expansion(`OPERATION_addmul_1')
1002: m4_not_for_expansion(`OPERATION_submul_1')
1003:
1004: dnl logops_n
1005: m4_not_for_expansion(`OPERATION_and_n')
1006: m4_not_for_expansion(`OPERATION_andn_n')
1007: m4_not_for_expansion(`OPERATION_nand_n')
1008: m4_not_for_expansion(`OPERATION_ior_n')
1009: m4_not_for_expansion(`OPERATION_iorn_n')
1010: m4_not_for_expansion(`OPERATION_nior_n')
1011: m4_not_for_expansion(`OPERATION_xor_n')
1012: m4_not_for_expansion(`OPERATION_xnor_n')
1013:
1014: dnl popham
1015: m4_not_for_expansion(`OPERATION_popcount')
1016: m4_not_for_expansion(`OPERATION_hamdist')
1017:
1.1.1.2 ! ohara 1018: dnl lorrshift
! 1019: m4_not_for_expansion(`OPERATION_lshift')
! 1020: m4_not_for_expansion(`OPERATION_rshift')
! 1021:
1.1 maekawa 1022:
1023: dnl Usage: m4_config_gmp_mparam(`symbol')
1024: dnl
1025: dnl Check that `symbol' is defined. If it isn't, issue an error and
1026: dnl terminate immediately. The error message explains that the symbol
1027: dnl should be in config.m4, copied from gmp-mparam.h.
1028: dnl
1.1.1.2 ! ohara 1029: dnl Termination is immediate since missing say SQR_KARATSUBA_THRESHOLD can
! 1030: dnl lead to infinite loops and endless error messages.
1.1 maekawa 1031:
1032: define(m4_config_gmp_mparam,
1033: m4_assert_numargs(1)
1034: `ifdef(`$1',,
1035: `m4_error(`$1 is not defined.
1036: "configure" should have extracted this from gmp-mparam.h and put it
1037: in config.m4, but somehow this has failed.
1038: ')m4exit(1)')')
1039:
1040:
1041: dnl Usage: defreg(name,reg)
1042: dnl
1043: dnl Give a name to a $ style register. For example,
1044: dnl
1045: dnl defreg(foo,$12)
1046: dnl
1047: dnl defreg() inserts an extra pair of quotes after the $ so that it's not
1048: dnl interpreted as an m4 macro parameter, ie. foo is actually $`'12. m4
1049: dnl strips those quotes when foo is expanded.
1050: dnl
1051: dnl deflit() is used to make the new definition, so it will expand
1052: dnl literally even if followed by parentheses ie. foo(99) will become
1053: dnl $12(99). (But there's nowhere that would be used is there?)
1054: dnl
1055: dnl When making further definitions from existing defreg() macros, remember
1056: dnl to use defreg() again to protect the $ in the new definitions too. For
1057: dnl example,
1058: dnl
1059: dnl defreg(a0,$4)
1060: dnl defreg(a1,$5)
1061: dnl ...
1062: dnl
1063: dnl defreg(PARAM_DST,a0)
1064: dnl
1065: dnl This is only because a0 is expanding at the time the PARAM_DST
1066: dnl definition is made, leaving a literal $4 that must be re-quoted. On
1067: dnl the other hand in something like the following ra is only expanded when
1068: dnl ret is used and its $`'31 protection will have its desired effect at
1069: dnl that time.
1070: dnl
1071: dnl defreg(ra,$31)
1072: dnl ...
1073: dnl define(ret,`j ra')
1074: dnl
1075: dnl Note that only $n forms are meant to be used here, and something like
1076: dnl 128($30) doesn't get protected and will come out wrong.
1077:
1078: define(defreg,
1079: m4_assert_numargs(2)
1080: `deflit(`$1',
1081: substr(`$2',0,1)``''substr(`$2',1))')
1082:
1083:
1.1.1.2 ! ohara 1084: dnl Usage: m4_instruction_wrapper()
1.1 maekawa 1085: dnl
1086: dnl Put this, unquoted, on a line on its own, at the start of a macro
1087: dnl that's a wrapper around an assembler instruction. It adds code to give
1088: dnl a descriptive error message if the macro is invoked without arguments.
1089: dnl
1090: dnl For example, suppose jmp needs to be wrapped,
1091: dnl
1092: dnl define(jmp,
1093: dnl m4_instruction_wrapper()
1094: dnl m4_assert_numargs(1)
1095: dnl `.byte 0x42
1096: dnl .long $1
1097: dnl nop')
1098: dnl
1099: dnl The point of m4_instruction_wrapper is to get a better error message
1100: dnl than m4_assert_numargs would give if jmp is accidentally used as plain
1101: dnl "jmp foo" instead of the intended "jmp( foo)". "jmp()" with no
1102: dnl argument also provokes the error message.
1103: dnl
1104: dnl m4_instruction_wrapper should only be used with wrapped instructions
1.1.1.2 ! ohara 1105: dnl that take arguments, since obviously something meant to be used as say
! 1106: dnl plain "ret" doesn't want to give an error when used that way.
1.1 maekawa 1107:
1108: define(m4_instruction_wrapper,
1109: m4_assert_numargs(0)
1110: ``m4_instruction_wrapper_internal'(m4_doublequote($`'0),dnl
1.1.1.2 ! ohara 1111: ifdef(`__file__',`m4_doublequote(__file__)',``the m4 sources''),dnl
1.1 maekawa 1112: $`#',m4_doublequote($`'1))`dnl'')
1113:
1114: dnl Called: m4_instruction_wrapper_internal($0,`filename',$#,$1)
1115: define(m4_instruction_wrapper_internal,
1116: `ifelse(eval($3<=1 && m4_length(`$4')==0),1,
1117: `m4_error(`$1 is a macro replacing that instruction and needs arguments, see $2 for details
1118: ')')')
1119:
1120:
1.1.1.2 ! ohara 1121: dnl Usage: m4_cpu_hex_constant(string)
! 1122: dnl
! 1123: dnl Expand to the string prefixed by a suitable `0x' hex marker. This
! 1124: dnl should be redefined as necessary for CPUs with different conventions.
! 1125:
! 1126: define(m4_cpu_hex_constant,
! 1127: m4_assert_numargs(1)
! 1128: `0x`$1'')
! 1129:
! 1130:
1.1 maekawa 1131: dnl Usage: UNROLL_LOG2, UNROLL_MASK, UNROLL_BYTES
1132: dnl CHUNK_LOG2, CHUNK_MASK, CHUNK_BYTES
1133: dnl
1134: dnl When code supports a variable amount of loop unrolling, the convention
1135: dnl is to define UNROLL_COUNT to the number of limbs processed per loop.
1136: dnl When testing code this can be varied to see how much the loop overhead
1137: dnl is costing. For example,
1138: dnl
1139: dnl deflit(UNROLL_COUNT, 32)
1140: dnl
1141: dnl If the forloop() generating the unrolled loop has a pattern processing
1142: dnl more than one limb, the convention is to express this with CHUNK_COUNT.
1143: dnl For example,
1144: dnl
1145: dnl deflit(CHUNK_COUNT, 2)
1146: dnl
1147: dnl The LOG2, MASK and BYTES definitions below are derived from these COUNT
1148: dnl definitions. If COUNT is redefined, the LOG2, MASK and BYTES follow
1149: dnl the new definition automatically.
1150: dnl
1151: dnl LOG2 is the log base 2 of COUNT. MASK is COUNT-1, which can be used as
1152: dnl a bit mask. BYTES is BYTES_PER_MP_LIMB*COUNT, the number of bytes
1153: dnl processed in each unrolled loop.
1154: dnl
1155: dnl BYTES_PER_MP_LIMB is defined in a CPU specific m4 include file. It
1156: dnl exists only so the BYTES definitions here can be common to all CPUs.
1157: dnl In the actual code for a given CPU, an explicit 4 or 8 may as well be
1158: dnl used because the code is only for a particular CPU, it doesn't need to
1159: dnl be general.
1160: dnl
1161: dnl Note that none of these macros do anything except give conventional
1162: dnl names to commonly used things. You still have to write your own
1163: dnl expressions for a forloop() and the resulting address displacements.
1164: dnl Something like the following would be typical for 4 bytes per limb.
1165: dnl
1166: dnl forloop(`i',0,UNROLL_COUNT-1,`
1167: dnl deflit(`disp',eval(i*4))
1168: dnl ...
1169: dnl ')
1170: dnl
1171: dnl Or when using CHUNK_COUNT,
1172: dnl
1173: dnl forloop(`i',0,UNROLL_COUNT/CHUNK_COUNT-1,`
1174: dnl deflit(`disp0',eval(i*CHUNK_COUNT*4))
1175: dnl deflit(`disp1',eval(disp0+4))
1176: dnl ...
1177: dnl ')
1178: dnl
1179: dnl Clearly `i' can be run starting from 1, or from high to low or whatever
1180: dnl best suits.
1181:
1182: deflit(UNROLL_LOG2,
1183: m4_assert_defined(`UNROLL_COUNT')
1184: `m4_log2(UNROLL_COUNT)')
1185:
1186: deflit(UNROLL_MASK,
1187: m4_assert_defined(`UNROLL_COUNT')
1188: `eval(UNROLL_COUNT-1)')
1189:
1190: deflit(UNROLL_BYTES,
1191: m4_assert_defined(`UNROLL_COUNT')
1192: m4_assert_defined(`BYTES_PER_MP_LIMB')
1193: `eval(UNROLL_COUNT * BYTES_PER_MP_LIMB)')
1.1.1.2 ! ohara 1194:
1.1 maekawa 1195: deflit(CHUNK_LOG2,
1196: m4_assert_defined(`CHUNK_COUNT')
1197: `m4_log2(CHUNK_COUNT)')
1198:
1199: deflit(CHUNK_MASK,
1200: m4_assert_defined(`CHUNK_COUNT')
1201: `eval(CHUNK_COUNT-1)')
1202:
1203: deflit(CHUNK_BYTES,
1204: m4_assert_defined(`CHUNK_COUNT')
1205: m4_assert_defined(`BYTES_PER_MP_LIMB')
1206: `eval(CHUNK_COUNT * BYTES_PER_MP_LIMB)')
1207:
1208:
1209: dnl Usage: MPN(name)
1210: dnl
1211: dnl Add MPN_PREFIX to a name.
1212: dnl MPN_PREFIX defaults to "__gmpn_" if not defined.
1213:
1214: ifdef(`MPN_PREFIX',,
1215: `define(`MPN_PREFIX',`__gmpn_')')
1216:
1217: define(MPN,
1218: m4_assert_numargs(1)
1219: `MPN_PREFIX`'$1')
1220:
1221:
1222: dnl Usage: mpn_add_n, etc
1223: dnl
1224: dnl Convenience definitions using MPN(), like the #defines in gmp.h. Each
1225: dnl function that might be implemented in assembler is here.
1226:
1227: define(define_mpn,
1228: m4_assert_numargs(1)
1229: `define(`mpn_$1',`MPN(`$1')')')
1230:
1231: define_mpn(add)
1232: define_mpn(add_1)
1233: define_mpn(add_n)
1234: define_mpn(add_nc)
1235: define_mpn(addmul_1)
1236: define_mpn(addmul_1c)
1237: define_mpn(addsub_n)
1238: define_mpn(addsub_nc)
1239: define_mpn(and_n)
1240: define_mpn(andn_n)
1241: define_mpn(bdivmod)
1242: define_mpn(cmp)
1243: define_mpn(com_n)
1244: define_mpn(copyd)
1245: define_mpn(copyi)
1.1.1.2 ! ohara 1246: define_mpn(count_leading_zeros)
! 1247: define_mpn(count_trailing_zeros)
! 1248: define_mpn(divexact_1)
1.1 maekawa 1249: define_mpn(divexact_by3c)
1250: define_mpn(divrem)
1251: define_mpn(divrem_1)
1252: define_mpn(divrem_1c)
1253: define_mpn(divrem_2)
1254: define_mpn(divrem_classic)
1255: define_mpn(divrem_newton)
1256: define_mpn(dump)
1257: define_mpn(gcd)
1258: define_mpn(gcd_1)
1.1.1.2 ! ohara 1259: define_mpn(gcd_finda)
1.1 maekawa 1260: define_mpn(gcdext)
1261: define_mpn(get_str)
1262: define_mpn(hamdist)
1263: define_mpn(invert_limb)
1264: define_mpn(ior_n)
1265: define_mpn(iorn_n)
1266: define_mpn(kara_mul_n)
1267: define_mpn(kara_sqr_n)
1268: define_mpn(lshift)
1269: define_mpn(lshiftc)
1270: define_mpn(mod_1)
1271: define_mpn(mod_1c)
1.1.1.2 ! ohara 1272: define_mpn(mod_34lsub1)
! 1273: define_mpn(modexact_1_odd)
! 1274: define_mpn(modexact_1c_odd)
1.1 maekawa 1275: define_mpn(mul)
1276: define_mpn(mul_1)
1277: define_mpn(mul_1c)
1.1.1.2 ! ohara 1278: define_mpn(mul_2)
1.1 maekawa 1279: define_mpn(mul_basecase)
1280: define_mpn(mul_n)
1281: define_mpn(perfect_square_p)
1282: define_mpn(popcount)
1.1.1.2 ! ohara 1283: define_mpn(preinv_divrem_1)
1.1 maekawa 1284: define_mpn(preinv_mod_1)
1285: define_mpn(nand_n)
1286: define_mpn(nior_n)
1287: define_mpn(random)
1288: define_mpn(random2)
1289: define_mpn(rshift)
1290: define_mpn(rshiftc)
1291: define_mpn(scan0)
1292: define_mpn(scan1)
1293: define_mpn(set_str)
1294: define_mpn(sqr_basecase)
1.1.1.2 ! ohara 1295: define_mpn(sqr_diagonal)
1.1 maekawa 1296: define_mpn(sub_n)
1297: define_mpn(sqrtrem)
1298: define_mpn(sub)
1299: define_mpn(sub_1)
1300: define_mpn(sub_n)
1301: define_mpn(sub_nc)
1302: define_mpn(submul_1)
1303: define_mpn(submul_1c)
1304: define_mpn(toom3_mul_n)
1305: define_mpn(toom3_sqr_n)
1306: define_mpn(umul_ppmm)
1307: define_mpn(udiv_qrnnd)
1308: define_mpn(xnor_n)
1309: define_mpn(xor_n)
1310:
1311:
1.1.1.2 ! ohara 1312: dnl Defines for C global arrays and variables, with names matching what's
! 1313: dnl used in the C code.
! 1314: dnl
! 1315: dnl Notice that GSYM_PREFIX is included, unlike with the function defines
! 1316: dnl above. Also, "deflit" is used so that something like __clz_tab(%ebx)
! 1317: dnl comes out as __gmpn_clz_tab(%ebx), for the benefit of CPUs with that
! 1318: dnl style assembler syntax.
! 1319:
! 1320: deflit(__clz_tab,
! 1321: m4_assert_defined(`GSYM_PREFIX')
! 1322: `GSYM_PREFIX`'MPN(`clz_tab')')
! 1323:
! 1324: deflit(modlimb_invert_table,
! 1325: m4_assert_defined(`GSYM_PREFIX')
! 1326: `GSYM_PREFIX`'__gmp_modlimb_invert_table')
! 1327:
! 1328:
! 1329: dnl Usage: ASM_START()
! 1330: dnl
! 1331: dnl Emit any directives needed once at the start of an assembler file, like
! 1332: dnl ".set noreorder" or whatever. The default for this is nothing, but
! 1333: dnl it's redefined by CPU specific m4 files.
! 1334:
! 1335: define(ASM_START)
! 1336:
! 1337:
! 1338: dnl Usage: PROLOGUE(foo[,param])
! 1339: dnl EPILOGUE(foo)
! 1340: dnl
! 1341: dnl Emit directives to start or end a function. GSYM_PREFIX is added by
! 1342: dnl these macros if necessary, so the given "foo" is what the function will
! 1343: dnl be called in C.
! 1344: dnl
! 1345: dnl The second parameter to PROLOGUE is used only for some CPUs and should
! 1346: dnl be omitted if not required.
! 1347: dnl
! 1348: dnl Nested or overlapping PROLOGUE/EPILOGUE pairs are allowed, if that
! 1349: dnl makes sense for the system. The name given to EPILOGUE must be a
! 1350: dnl currently open PROLOGUE.
! 1351: dnl
! 1352: dnl If only one PROLOGUE is open then the name can be omitted from
! 1353: dnl EPILOGUE. This is encouraged, since it means the name only has to
! 1354: dnl appear in one place, not two.
! 1355: dnl
! 1356: dnl The given name "foo" is not fully quoted here, it will be macro
! 1357: dnl expanded more than once. This is the way the m4_list macros work, and
! 1358: dnl it also helps the tune/many.pl program do a renaming like
! 1359: dnl -D__gmpn_add_n=mpn_add_n_foo when GSYM_PREFIX is not empty.
! 1360:
! 1361: define(PROLOGUE,
! 1362: m4_assert_numargs_range(1,2)
! 1363: `define(`PROLOGUE_list',m4_list_quote($1,PROLOGUE_list))dnl
! 1364: ifelse(`$2',,
! 1365: `PROLOGUE_cpu(GSYM_PREFIX`'$1)',
! 1366: `PROLOGUE_cpu(GSYM_PREFIX`'$1,`$2')')')
! 1367:
! 1368: define(EPILOGUE,
! 1369: m4_assert_numargs_range(0,1)
! 1370: `ifelse(`$1',,
! 1371: `ifelse(m4_list_count(PROLOGUE_list),0,
! 1372: `m4_error(`no open functions for EPILOGUE
! 1373: ')',
! 1374: `ifelse(m4_list_count(PROLOGUE_list),1,
! 1375: `EPILOGUE_internal(PROLOGUE_current_function)',
! 1376: `m4_error(`more than one open function for EPILOGUE
! 1377: ')')')',
! 1378: `EPILOGUE_internal(`$1')')')
! 1379:
! 1380: define(EPILOGUE_internal,
! 1381: m4_assert_numargs(1)
! 1382: m4_assert_defined(`EPILOGUE_cpu')
! 1383: `ifelse(m4_list_find($1,PROLOGUE_list),0,
! 1384: `m4_error(`EPILOGUE without PROLOGUE: $1
! 1385: ')')dnl
! 1386: define(`PROLOGUE_list',m4_list_quote(m4_list_remove($1,PROLOGUE_list)))dnl
! 1387: EPILOGUE_cpu(GSYM_PREFIX`$1')')
! 1388:
! 1389: dnl Currently open PROLOGUEs, as a comma-separated list.
! 1390: define(PROLOGUE_list)
! 1391:
! 1392:
! 1393: dnl Called: PROLOGUE_check(list,...)
! 1394: dnl Check there's no remaining open PROLOGUEs at the end of input.
! 1395: define(PROLOGUE_check,
! 1396: `ifelse($1,,,
! 1397: `m4_error(`no EPILOGUE for: $1
! 1398: ')dnl
! 1399: PROLOGUE_check(shift($@))')')
! 1400:
! 1401: m4wrap_prepend(`PROLOGUE_check(PROLOGUE_list)')
! 1402:
1.1 maekawa 1403:
1.1.1.2 ! ohara 1404: dnl Usage: PROLOGUE_current_function
! 1405: dnl
! 1406: dnl This macro expands to the current PROLOGUE/EPILOGUE function, or the
! 1407: dnl most recent PROLOGUE if such pairs are nested or overlapped.
! 1408:
! 1409: define(PROLOGUE_current_function,
! 1410: m4_assert_numargs(-1)
! 1411: `m4_list_first(PROLOGUE_list)')
! 1412:
! 1413:
! 1414: dnl Usage: PROLOGUE_cpu(GSYM_PREFIX`'foo[,param])
! 1415: dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
! 1416: dnl
! 1417: dnl These macros hold the CPU-specific parts of PROLOGUE and EPILOGUE.
! 1418: dnl Both are called with the function name, with GSYM_PREFIX already
! 1419: dnl prepended.
! 1420: dnl
! 1421: dnl The definitions here are something typical and sensible, but CPU or
! 1422: dnl system specific m4 files should redefine them as necessary. The
! 1423: dnl optional extra parameter to PROLOGUE_cpu is not expected and not
! 1424: dnl accepted here.
! 1425:
! 1426: define(PROLOGUE_cpu,
! 1427: m4_assert_numargs(1)
! 1428: ` TEXT
! 1429: ALIGN(8)
! 1430: GLOBL `$1' GLOBL_ATTR
! 1431: TYPE(`$1',`function')
! 1432: `$1'LABEL_SUFFIX')
! 1433:
! 1434: define(EPILOGUE_cpu,
! 1435: ` SIZE(`$1',.-`$1')')
! 1436:
! 1437:
! 1438: dnl Usage: L(name)
! 1439: dnl
! 1440: dnl Generate a local label with the given name. This is simply a
! 1441: dnl convenient way to add LSYM_PREFIX.
! 1442: dnl
1.1 maekawa 1443: dnl LSYM_PREFIX might be L$, so defn() must be used to quote it or the L
1.1.1.2 ! ohara 1444: dnl will expand again as the L macro, making an infinite recursion.
! 1445:
! 1446: define(`L',
! 1447: m4_assert_numargs(1)
! 1448: `defn(`LSYM_PREFIX')$1')
! 1449:
! 1450:
! 1451: dnl Usage: INT32(label,value)
! 1452: dnl INT64(label,first,second)
1.1 maekawa 1453:
1454: define(`INT32',
1.1.1.2 ! ohara 1455: m4_assert_defined(`W32')
! 1456: ` ALIGN(4)
! 1457: `$1'`'LABEL_SUFFIX
! 1458: W32 $2')
1.1 maekawa 1459:
1460: define(`INT64',
1.1.1.2 ! ohara 1461: m4_assert_defined(`W32')
! 1462: ` ALIGN(8)
! 1463: `$1'`'LABEL_SUFFIX
1.1 maekawa 1464: W32 $2
1.1.1.2 ! ohara 1465: W32 $3')
1.1 maekawa 1466:
1467:
1468: dnl Usage: ALIGN(bytes)
1469: dnl
1470: dnl Emit a ".align" directive. The alignment is specified in bytes, and
1471: dnl will normally need to be a power of 2. The actual ".align" generated
1.1.1.2 ! ohara 1472: dnl is either bytes or logarithmic according to what ./configure finds the
! 1473: dnl assembler needs.
1.1 maekawa 1474: dnl
1.1.1.2 ! ohara 1475: dnl If ALIGN_FILL_0x90 is defined and equal to "yes", then ", 0x90" is
! 1476: dnl appended. This is for x86, see mpn/x86/README.
1.1 maekawa 1477:
1478: define(ALIGN,
1479: m4_assert_numargs(1)
1480: m4_assert_defined(`ALIGN_LOGARITHMIC')
1481: `.align ifelse(ALIGN_LOGARITHMIC,yes,`m4_log2($1)',`eval($1)')dnl
1482: ifelse(ALIGN_FILL_0x90,yes,`, 0x90')')
1483:
1484:
1485: dnl Usage: MULFUNC_PROLOGUE(function function...)
1486: dnl
1487: dnl A dummy macro which is grepped for by ./configure to know what
1488: dnl functions a multi-function file is providing. Use this if there aren't
1489: dnl explicit PROLOGUE()s for each possible function.
1490: dnl
1491: dnl Multiple MULFUNC_PROLOGUEs can be used, or just one with the function
1492: dnl names separated by spaces.
1493:
1494: define(`MULFUNC_PROLOGUE',
1495: m4_assert_numargs(1)
1.1.1.2 ! ohara 1496: )
! 1497:
! 1498:
! 1499: dnl Usage: NAILS_SUPPORT(spec spec ...)
! 1500: dnl
! 1501: dnl A dummy macro which is grepped for by ./configure to know what nails
! 1502: dnl are supported in an asm file.
! 1503: dnl
! 1504: dnl Ranges can be given, or just individual values. Multiple values or
! 1505: dnl ranges can be given, separated by spaces. Multiple NAILS_SUPPORT
! 1506: dnl declarations work too. Some examples,
! 1507: dnl
! 1508: dnl NAILS_SUPPORT(1-20)
! 1509: dnl NAILS_SUPPORT(1 6 9-12)
! 1510: dnl NAILS_SUPPORT(1-10 16-20)
! 1511:
! 1512: define(NAILS_SUPPORT,
! 1513: m4_assert_numargs(1)
! 1514: )
! 1515:
! 1516:
! 1517: dnl Usage: GMP_NUMB_MASK
! 1518: dnl
! 1519: dnl A bit masks for the number part of a limb. Eg. with 6 bit nails in a
! 1520: dnl 32 bit limb, GMP_NUMB_MASK would be 0x3ffffff.
! 1521:
! 1522: define(GMP_NUMB_MASK,
! 1523: m4_assert_numargs(-1)
! 1524: m4_assert_defined(`GMP_NUMB_BITS')
! 1525: `m4_hex_lowmask(GMP_NUMB_BITS)')
1.1 maekawa 1526:
1527:
1528: divert`'dnl
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>