mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-10-10 00:25:06 -04:00
preproc: add a %selbits() function
Although one can implement this "manually" in terms of %sel(), this function is *really* useful for making multi-mode tests and allows for better error checking. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
@@ -7738,9 +7738,9 @@ stdmac_tok(const SMacro *s, Token **params, int nparams)
|
|||||||
return reverse_tokens(tokenize(unquote_token_cstr(params[0])));
|
return reverse_tokens(tokenize(unquote_token_cstr(params[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* %cond() or %sel() */
|
/* %sel() */
|
||||||
static Token *
|
static Token *
|
||||||
stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
|
stdmac_sel(const SMacro *s, Token **params, int nparams)
|
||||||
{
|
{
|
||||||
int64_t which;
|
int64_t which;
|
||||||
|
|
||||||
@@ -7749,14 +7749,6 @@ stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
|
|||||||
*/
|
*/
|
||||||
which = get_tok_num(params[0], NULL);
|
which = get_tok_num(params[0], NULL);
|
||||||
|
|
||||||
if (s->expandpvt.u) {
|
|
||||||
/* Booleanize (for %cond): true -> 1, false -> 2 (else) */
|
|
||||||
which = which ? 1 : 2;
|
|
||||||
if (which >= nparams) {
|
|
||||||
/* false, and no else clause */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (unlikely(which < 1)) {
|
if (unlikely(which < 1)) {
|
||||||
nasm_warn(WARN_PP_SEL_RANGE,
|
nasm_warn(WARN_PP_SEL_RANGE,
|
||||||
"%s(%"PRId64") is not a valid selector", s->name, which);
|
"%s(%"PRId64") is not a valid selector", s->name, which);
|
||||||
@@ -7767,11 +7759,47 @@ stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
|
|||||||
s->name, which);
|
s->name, which);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new_Token(NULL, tok_smac_param(which), "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* %cond() */
|
||||||
|
static Token *
|
||||||
|
stdmac_cond(const SMacro *s, Token **params, int nparams)
|
||||||
|
{
|
||||||
|
int64_t which;
|
||||||
|
(void)s;
|
||||||
|
(void)params;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* params[0] will have been generated by make_tok_num.
|
||||||
|
*/
|
||||||
|
which = get_tok_num(params[0], NULL);
|
||||||
|
|
||||||
|
/* Booleanize: true -> 1, false -> 2 (else) */
|
||||||
|
which = which ? 1 : 2;
|
||||||
|
if (which >= nparams) {
|
||||||
|
/* false, and no else clause */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_Token(NULL, tok_smac_param(which), "", 0);
|
return new_Token(NULL, tok_smac_param(which), "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* %selbits() */
|
||||||
|
static Token *
|
||||||
|
stdmac_selbits(const SMacro *s, Token **params, int nparams)
|
||||||
|
{
|
||||||
|
int which = ilog2_32(globl.bits)-4;
|
||||||
|
(void)s;
|
||||||
|
(void)params;
|
||||||
|
|
||||||
|
if (nparams <= which)
|
||||||
|
which = nparams - 1;
|
||||||
|
|
||||||
|
return new_Token(NULL, tok_smac_param(which), "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* %count() function */
|
/* %count() function */
|
||||||
static Token *
|
static Token *
|
||||||
stdmac_count(const SMacro *s, Token **params, int nparams)
|
stdmac_count(const SMacro *s, Token **params, int nparams)
|
||||||
@@ -8173,6 +8201,7 @@ static void pp_add_magic_simple(void)
|
|||||||
{ "%null", false, 1, SPARM_GREEDY, stdmac_null },
|
{ "%null", false, 1, SPARM_GREEDY, stdmac_null },
|
||||||
{ "%pathsearch", false, 1, SPARM_PLAIN, stdmac_pathsearch },
|
{ "%pathsearch", false, 1, SPARM_PLAIN, stdmac_pathsearch },
|
||||||
{ "%realpath", false, 1, SPARM_PLAIN, stdmac_realpath },
|
{ "%realpath", false, 1, SPARM_PLAIN, stdmac_realpath },
|
||||||
|
{ "%selbits", false, 1, SPARM_PLAIN|SPARM_VARADIC, stdmac_selbits },
|
||||||
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
|
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
|
||||||
{ "%strcat", false, 1, SPARM_STR|SPARM_CONDQUOTE|SPARM_VARADIC, stdmac_strcat },
|
{ "%strcat", false, 1, SPARM_STR|SPARM_CONDQUOTE|SPARM_VARADIC, stdmac_strcat },
|
||||||
{ "%strlen", false, 1, SPARM_STR|SPARM_CONDQUOTE, stdmac_strlen },
|
{ "%strlen", false, 1, SPARM_STR|SPARM_CONDQUOTE, stdmac_strlen },
|
||||||
@@ -8268,15 +8297,16 @@ static void pp_add_magic_miscfunc(void)
|
|||||||
/* %sel() function */
|
/* %sel() function */
|
||||||
nasm_zero(tmpl);
|
nasm_zero(tmpl);
|
||||||
tmpl.nparam = 2;
|
tmpl.nparam = 2;
|
||||||
tmpl.expand = stdmac_cond_sel;
|
tmpl.expand = stdmac_sel;
|
||||||
nasm_newn(tmpl.params, tmpl.nparam);
|
nasm_newn(tmpl.params, tmpl.nparam);
|
||||||
tmpl.params[0].flags = SPARM_EVAL;
|
tmpl.params[0].flags = SPARM_EVAL;
|
||||||
tmpl.params[1].flags = SPARM_VARADIC;
|
tmpl.params[1].flags = SPARM_VARADIC;
|
||||||
define_magic("%sel", false, &tmpl);
|
define_magic("%sel", false, &tmpl);
|
||||||
|
|
||||||
/* %cond() function, a variation on %sel */
|
/* %cond() function */
|
||||||
|
nasm_zero(tmpl);
|
||||||
tmpl.nparam = 3;
|
tmpl.nparam = 3;
|
||||||
tmpl.expandpvt.u = 1; /* Booleanize */
|
tmpl.expand = stdmac_cond;
|
||||||
nasm_newn(tmpl.params, tmpl.nparam);
|
nasm_newn(tmpl.params, tmpl.nparam);
|
||||||
tmpl.params[0].flags = SPARM_EVAL;
|
tmpl.params[0].flags = SPARM_EVAL;
|
||||||
tmpl.params[1].flags = 0;
|
tmpl.params[1].flags = 0;
|
||||||
|
@@ -31,6 +31,8 @@ It is the production version of NASM since 2025.
|
|||||||
now be specified for the same group; the resulting group includes
|
now be specified for the same group; the resulting group includes
|
||||||
all sections specified in all \c{GROUP} directives for the group.
|
all sections specified in all \c{GROUP} directives for the group.
|
||||||
|
|
||||||
|
\b A new \c{%selbits()} preprocessor function. See \k{f_selbits}.
|
||||||
|
|
||||||
|
|
||||||
\S{cl-3.00} Version 3.00
|
\S{cl-3.00} Version 3.00
|
||||||
|
|
||||||
|
@@ -1011,6 +1011,24 @@ expands to nothing.
|
|||||||
The arguments not selected are never expanded.
|
The arguments not selected are never expanded.
|
||||||
|
|
||||||
|
|
||||||
|
\S{f_selbits} \i\c{%selbits()} Function
|
||||||
|
|
||||||
|
The \c{%selbits()} function returns its first, second, or third
|
||||||
|
argument depending on if the current mode is 16, 32 or 64 bits. If
|
||||||
|
less than three arguments are given, the last argument is considered
|
||||||
|
repeated. Like \c{%cond()}, this is a specialized version of the
|
||||||
|
\c{%sel()} function.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
\c BITS 64
|
||||||
|
\c
|
||||||
|
\c %define breg %selbits(bx,ebx,rbx)
|
||||||
|
\c %define vreg %selbits(ax,eax)
|
||||||
|
\c
|
||||||
|
\c mov vreg,[breg] ; mov eax,[rbx]
|
||||||
|
|
||||||
|
|
||||||
\S{f_str} \i\c\{%str()} Function
|
\S{f_str} \i\c\{%str()} Function
|
||||||
|
|
||||||
The \c{%str()} function converts its argument, including any commas,
|
The \c{%str()} function converts its argument, including any commas,
|
||||||
|
Reference in New Issue
Block a user