summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Johnson <peter@tortall.net>2010-04-08 03:46:43 +0000
committerPeter Johnson <peter@tortall.net>2010-04-08 03:46:43 +0000
commitbc3a8286ea4033931940742a8dc0b944747e1ce5 (patch)
treea4acc1aa904067ee3d8a521413f707833374d420
parent2de9ac8edef56733c697653616bda00f46a73401 (diff)
downloadyasm-bc3a8286ea4033931940742a8dc0b944747e1ce5.tar.gz
NASM preproc: Add basic support for %{x:y} parameter list expansion.
Contributed by: Mathieu Monnier nasm64developer has a more advanced 3-parameter version that will take some time to integrate, so for now just provide the simpler version. svn path=/trunk/yasm/; revision=2312
-rw-r--r--modules/preprocs/nasm/nasm-pp.c207
1 files changed, 128 insertions, 79 deletions
diff --git a/modules/preprocs/nasm/nasm-pp.c b/modules/preprocs/nasm/nasm-pp.c
index 211eca2e..b892a64a 100644
--- a/modules/preprocs/nasm/nasm-pp.c
+++ b/modules/preprocs/nasm/nasm-pp.c
@@ -3858,105 +3858,51 @@ expand_mmac_params(Token * tline)
char *text = NULL;
int type = 0, cc; /* type = 0 to placate optimisers */
char tmpbuf[30];
+ char *second_text = NULL;
int n, i;
MMacro *mac;
t = tline;
tline = tline->next;
+ second_text = strchr(t->text, ':');
+
mac = istk->mstk;
while (mac && !mac->name) /* avoid mistaking %reps for macros */
mac = mac->next_active;
if (!mac)
error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
else
- switch (t->text[1])
+ {
+ if (second_text)
{
- /*
- * We have to make a substitution of one of the
- * forms %1, %-1, %+1, %%foo, %0.
- */
- case '0':
- type = TOK_NUMBER;
- sprintf(tmpbuf, "%ld", mac->nparam);
- text = nasm_strdup(tmpbuf);
- break;
- case '%':
- type = TOK_ID;
- sprintf(tmpbuf, "..@%lu.", mac->unique);
- text = nasm_strcat(tmpbuf, t->text + 2);
- break;
- case '-':
- n = atoi(t->text + 2) - 1;
- if (n >= mac->nparam)
+ int end = atoi(second_text+1)-1;
+ int is_fst = 1;
+ int k;
+ n = atoi(t->text + 1)-1;
+ if (end < 0)
+ end += mac->nparam;
+
+ for (k = n; k <= end; k++)
+ {
+ if (k >= mac->nparam)
tt = NULL;
else
{
if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
- }
- cc = find_cc(tt);
- if (cc == -1)
- {
- error(ERR_NONFATAL,
- "macro parameter %d is not a condition code",
- n + 1);
- text = NULL;
+ k = (k + mac->rotate) % mac->nparam;
+ tt = mac->params[k];
}
- else
+ if (tt)
{
- type = TOK_ID;
- if (inverse_ccs[cc] == -1)
+ if (!is_fst && mac->paramlen[k])
{
- error(ERR_NONFATAL,
- "condition code `%s' is not invertible",
- conditions[cc]);
- text = NULL;
+ *tail = new_Token(NULL, TOK_OTHER, ",", 0);
+ tail = &(*tail)->next;
}
- else
- text =
- nasm_strdup(conditions[inverse_ccs
- [cc]]);
- }
- break;
- case '+':
- n = atoi(t->text + 2) - 1;
- if (n >= mac->nparam)
- tt = NULL;
- else
- {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
- }
- cc = find_cc(tt);
- if (cc == -1)
- {
- error(ERR_NONFATAL,
- "macro parameter %d is not a condition code",
- n + 1);
- text = NULL;
- }
- else
- {
- type = TOK_ID;
- text = nasm_strdup(conditions[cc]);
- }
- break;
- default:
- n = atoi(t->text + 1) - 1;
- if (n >= mac->nparam)
- tt = NULL;
- else
- {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
- }
- if (tt)
- {
- for (i = 0; i < mac->paramlen[n]; i++)
+ if (mac->paramlen[k])
+ is_fst = 0;
+ for (i = 0; i < mac->paramlen[k]; i++)
{
*tail =
new_Token(NULL, tt->type, tt->text,
@@ -3966,8 +3912,111 @@ expand_mmac_params(Token * tline)
}
}
text = NULL; /* we've done it here */
- break;
+ }
+ }
+ else
+ {
+ switch (t->text[1])
+ {
+ /*
+ * We have to make a substitution of one of the
+ * forms %1, %-1, %+1, %%foo, %0.
+ */
+ case '0':
+ type = TOK_NUMBER;
+ sprintf(tmpbuf, "%ld", mac->nparam);
+ text = nasm_strdup(tmpbuf);
+ break;
+ case '%':
+ type = TOK_ID;
+ sprintf(tmpbuf, "..@%lu.", mac->unique);
+ text = nasm_strcat(tmpbuf, t->text + 2);
+ break;
+ case '-':
+ n = atoi(t->text + 2) - 1;
+ if (n >= mac->nparam)
+ tt = NULL;
+ else
+ {
+ if (mac->nparam > 1)
+ n = (n + mac->rotate) % mac->nparam;
+ tt = mac->params[n];
+ }
+ cc = find_cc(tt);
+ if (cc == -1)
+ {
+ error(ERR_NONFATAL,
+ "macro parameter %d is not a condition code",
+ n + 1);
+ text = NULL;
+ }
+ else
+ {
+ type = TOK_ID;
+ if (inverse_ccs[cc] == -1)
+ {
+ error(ERR_NONFATAL,
+ "condition code `%s' is not invertible",
+ conditions[cc]);
+ text = NULL;
+ }
+ else
+ text =
+ nasm_strdup(conditions[inverse_ccs
+ [cc]]);
+ }
+ break;
+ case '+':
+ n = atoi(t->text + 2) - 1;
+ if (n >= mac->nparam)
+ tt = NULL;
+ else
+ {
+ if (mac->nparam > 1)
+ n = (n + mac->rotate) % mac->nparam;
+ tt = mac->params[n];
+ }
+ cc = find_cc(tt);
+ if (cc == -1)
+ {
+ error(ERR_NONFATAL,
+ "macro parameter %d is not a condition code",
+ n + 1);
+ text = NULL;
+ }
+ else
+ {
+ type = TOK_ID;
+ text = nasm_strdup(conditions[cc]);
+ }
+ break;
+ default:
+ n = atoi(t->text + 1) - 1;
+ if (n >= mac->nparam)
+ tt = NULL;
+ else
+ {
+ if (mac->nparam > 1)
+ n = (n + mac->rotate) % mac->nparam;
+ tt = mac->params[n];
+ }
+ if (tt)
+ {
+ for (i = 0; i < mac->paramlen[n]; i++)
+ {
+ *tail =
+ new_Token(NULL, tt->type, tt->text,
+ 0);
+ tail = &(*tail)->next;
+ tt = tt->next;
+ }
+ }
+ text = NULL; /* we've done it here */
+ break;
+ }
}
+ }
+
if (!text)
{
delete_Token(t);