mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-04-12 18:40:23 +08:00
Various tab/space/comment cleanup
No change on binary level Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This commit is contained in:
parent
a353955a8d
commit
cfbcddf1a5
103
eval.c
103
eval.c
@ -1,5 +1,5 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
*
|
||||
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
@ -14,7 +14,7 @@
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
@ -77,8 +77,8 @@ static int *opflags;
|
||||
static struct eval_hints *hint;
|
||||
|
||||
extern int in_abs_seg; /* ABSOLUTE segment flag */
|
||||
extern int32_t abs_seg; /* ABSOLUTE segment */
|
||||
extern int32_t abs_offset; /* ABSOLUTE segment offset */
|
||||
extern int32_t abs_seg; /* ABSOLUTE segment */
|
||||
extern int32_t abs_offset; /* ABSOLUTE segment offset */
|
||||
|
||||
/*
|
||||
* Unimportant cleanup is done to avoid confusing people who are trying
|
||||
@ -635,18 +635,18 @@ static expr *expr5(int critical)
|
||||
|
||||
static expr *eval_floatize(enum floatize type)
|
||||
{
|
||||
uint8_t result[16], *p; /* Up to 128 bits */
|
||||
uint8_t result[16], *p; /* Up to 128 bits */
|
||||
static const struct {
|
||||
int bytes, start, len;
|
||||
int bytes, start, len;
|
||||
} formats[] = {
|
||||
{ 1, 0, 1 }, /* FLOAT_8 */
|
||||
{ 2, 0, 2 }, /* FLOAT_16 */
|
||||
{ 4, 0, 4 }, /* FLOAT_32 */
|
||||
{ 8, 0, 8 }, /* FLOAT_64 */
|
||||
{ 10, 0, 8 }, /* FLOAT_80M */
|
||||
{ 10, 8, 2 }, /* FLOAT_80E */
|
||||
{ 16, 0, 8 }, /* FLOAT_128L */
|
||||
{ 16, 8, 8 }, /* FLOAT_128H */
|
||||
{ 1, 0, 1 }, /* FLOAT_8 */
|
||||
{ 2, 0, 2 }, /* FLOAT_16 */
|
||||
{ 4, 0, 4 }, /* FLOAT_32 */
|
||||
{ 8, 0, 8 }, /* FLOAT_64 */
|
||||
{ 10, 0, 8 }, /* FLOAT_80M */
|
||||
{ 10, 8, 2 }, /* FLOAT_80E */
|
||||
{ 16, 0, 8 }, /* FLOAT_128L */
|
||||
{ 16, 8, 8 }, /* FLOAT_128H */
|
||||
};
|
||||
int sign = 1;
|
||||
int64_t val;
|
||||
@ -654,32 +654,32 @@ static expr *eval_floatize(enum floatize type)
|
||||
|
||||
i = scan(scpriv, tokval);
|
||||
if (i != '(') {
|
||||
error(ERR_NONFATAL, "expecting `('");
|
||||
return NULL;
|
||||
error(ERR_NONFATAL, "expecting `('");
|
||||
return NULL;
|
||||
}
|
||||
i = scan(scpriv, tokval);
|
||||
if (i == '-' || i == '+') {
|
||||
sign = (i == '-') ? -1 : 1;
|
||||
i = scan(scpriv, tokval);
|
||||
sign = (i == '-') ? -1 : 1;
|
||||
i = scan(scpriv, tokval);
|
||||
}
|
||||
if (i != TOKEN_FLOAT) {
|
||||
error(ERR_NONFATAL, "expecting floating-point number");
|
||||
return NULL;
|
||||
error(ERR_NONFATAL, "expecting floating-point number");
|
||||
return NULL;
|
||||
}
|
||||
if (!float_const(tokval->t_charptr, sign, result,
|
||||
formats[type].bytes, error))
|
||||
return NULL;
|
||||
formats[type].bytes, error))
|
||||
return NULL;
|
||||
i = scan(scpriv, tokval);
|
||||
if (i != ')') {
|
||||
error(ERR_NONFATAL, "expecting `)'");
|
||||
return NULL;
|
||||
error(ERR_NONFATAL, "expecting `)'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = result+formats[type].start+formats[type].len;
|
||||
val = 0;
|
||||
for (j = formats[type].len; j; j--) {
|
||||
p--;
|
||||
val = (val << 8) + *p;
|
||||
p--;
|
||||
val = (val << 8) + *p;
|
||||
}
|
||||
|
||||
begintemp();
|
||||
@ -699,31 +699,31 @@ static expr *eval_strfunc(enum strfunc type)
|
||||
parens = false;
|
||||
i = scan(scpriv, tokval);
|
||||
if (i == '(') {
|
||||
parens = true;
|
||||
i = scan(scpriv, tokval);
|
||||
parens = true;
|
||||
i = scan(scpriv, tokval);
|
||||
}
|
||||
if (i != TOKEN_STR) {
|
||||
error(ERR_NONFATAL, "expecting string");
|
||||
return NULL;
|
||||
error(ERR_NONFATAL, "expecting string");
|
||||
return NULL;
|
||||
}
|
||||
string_len = string_transform(tokval->t_charptr, tokval->t_inttwo,
|
||||
&string, type);
|
||||
&string, type);
|
||||
if (string_len == (size_t)-1) {
|
||||
error(ERR_NONFATAL, "invalid string for transform");
|
||||
return NULL;
|
||||
error(ERR_NONFATAL, "invalid string for transform");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
val = readstrnum(string, string_len, &rn_warn);
|
||||
if (parens) {
|
||||
i = scan(scpriv, tokval);
|
||||
if (i != ')') {
|
||||
error(ERR_NONFATAL, "expecting `)'");
|
||||
return NULL;
|
||||
}
|
||||
i = scan(scpriv, tokval);
|
||||
if (i != ')') {
|
||||
error(ERR_NONFATAL, "expecting `)'");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (rn_warn)
|
||||
error(ERR_WARNING|ERR_PASS1, "character constant too long");
|
||||
error(ERR_WARNING|ERR_PASS1, "character constant too long");
|
||||
|
||||
begintemp();
|
||||
addtotemp(EXPR_SIMPLE, val);
|
||||
@ -750,7 +750,6 @@ static expr *expr6(int critical)
|
||||
return NULL;
|
||||
return scalar_mult(e, -1L, false);
|
||||
|
||||
|
||||
case '+':
|
||||
i = scan(scpriv, tokval);
|
||||
return expr6(critical);
|
||||
@ -798,10 +797,10 @@ static expr *expr6(int critical)
|
||||
return e;
|
||||
|
||||
case TOKEN_FLOATIZE:
|
||||
return eval_floatize(tokval->t_integer);
|
||||
return eval_floatize(tokval->t_integer);
|
||||
|
||||
case TOKEN_STRFUNC:
|
||||
return eval_strfunc(tokval->t_integer);
|
||||
return eval_strfunc(tokval->t_integer);
|
||||
|
||||
case '(':
|
||||
i = scan(scpriv, tokval);
|
||||
@ -819,7 +818,7 @@ static expr *expr6(int critical)
|
||||
case TOKEN_STR:
|
||||
case TOKEN_REG:
|
||||
case TOKEN_ID:
|
||||
case TOKEN_INSN: /* Opcodes that occur here are really labels */
|
||||
case TOKEN_INSN: /* Opcodes that occur here are really labels */
|
||||
case TOKEN_HERE:
|
||||
case TOKEN_BASE:
|
||||
begintemp();
|
||||
@ -827,19 +826,19 @@ static expr *expr6(int critical)
|
||||
case TOKEN_NUM:
|
||||
addtotemp(EXPR_SIMPLE, tokval->t_integer);
|
||||
break;
|
||||
case TOKEN_STR:
|
||||
tmpval = readstrnum(tokval->t_charptr, tokval->t_inttwo, &rn_warn);
|
||||
if (rn_warn)
|
||||
error(ERR_WARNING|ERR_PASS1, "character constant too long");
|
||||
case TOKEN_STR:
|
||||
tmpval = readstrnum(tokval->t_charptr, tokval->t_inttwo, &rn_warn);
|
||||
if (rn_warn)
|
||||
error(ERR_WARNING|ERR_PASS1, "character constant too long");
|
||||
addtotemp(EXPR_SIMPLE, tmpval);
|
||||
break;
|
||||
break;
|
||||
case TOKEN_REG:
|
||||
addtotemp(tokval->t_integer, 1L);
|
||||
if (hint && hint->type == EAH_NOHINT)
|
||||
hint->base = tokval->t_integer, hint->type = EAH_MAKEBASE;
|
||||
break;
|
||||
case TOKEN_ID:
|
||||
case TOKEN_INSN:
|
||||
case TOKEN_INSN:
|
||||
case TOKEN_HERE:
|
||||
case TOKEN_BASE:
|
||||
/*
|
||||
@ -850,9 +849,9 @@ static expr *expr6(int critical)
|
||||
if (!location->known) {
|
||||
error(ERR_NONFATAL,
|
||||
"%s not supported in preprocess-only mode",
|
||||
(i == TOKEN_HERE ? "`$'" :
|
||||
i == TOKEN_BASE ? "`$$'" :
|
||||
"symbol references"));
|
||||
(i == TOKEN_HERE ? "`$'" :
|
||||
i == TOKEN_BASE ? "`$$'" :
|
||||
"symbol references"));
|
||||
addtotemp(EXPR_UNKNOWN, 1L);
|
||||
break;
|
||||
}
|
||||
|
422
parser.c
422
parser.c
@ -1,5 +1,5 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
*
|
||||
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
@ -14,7 +14,7 @@
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
@ -54,14 +54,14 @@
|
||||
#include "tables.h"
|
||||
|
||||
extern int in_abs_seg; /* ABSOLUTE segment flag */
|
||||
extern int32_t abs_seg; /* ABSOLUTE segment */
|
||||
extern int32_t abs_offset; /* ABSOLUTE segment offset */
|
||||
extern int32_t abs_seg; /* ABSOLUTE segment */
|
||||
extern int32_t abs_offset; /* ABSOLUTE segment offset */
|
||||
|
||||
static int is_comma_next(void);
|
||||
|
||||
static int i;
|
||||
static struct tokenval tokval;
|
||||
static struct location *location; /* Pointer to current line's segment,offset */
|
||||
static struct location *location; /* Pointer to current line's segment,offset */
|
||||
|
||||
void parser_global_info(struct location * locp)
|
||||
{
|
||||
@ -72,121 +72,121 @@ static int prefix_slot(enum prefixes prefix)
|
||||
{
|
||||
switch (prefix) {
|
||||
case P_WAIT:
|
||||
return PPS_WAIT;
|
||||
return PPS_WAIT;
|
||||
case R_CS:
|
||||
case R_DS:
|
||||
case R_SS:
|
||||
case R_ES:
|
||||
case R_FS:
|
||||
case R_GS:
|
||||
return PPS_SEG;
|
||||
return PPS_SEG;
|
||||
case P_LOCK:
|
||||
case P_REP:
|
||||
case P_REPE:
|
||||
case P_REPZ:
|
||||
case P_REPNE:
|
||||
case P_REPNZ:
|
||||
return PPS_LREP;
|
||||
return PPS_LREP;
|
||||
case P_O16:
|
||||
case P_O32:
|
||||
case P_O64:
|
||||
case P_OSP:
|
||||
return PPS_OSIZE;
|
||||
return PPS_OSIZE;
|
||||
case P_A16:
|
||||
case P_A32:
|
||||
case P_A64:
|
||||
case P_ASP:
|
||||
return PPS_ASIZE;
|
||||
return PPS_ASIZE;
|
||||
default:
|
||||
nasm_error(ERR_PANIC, "Invalid value %d passed to prefix_slot()", prefix);
|
||||
return -1;
|
||||
nasm_error(ERR_PANIC, "Invalid value %d passed to prefix_slot()", prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void process_size_override(insn * result, int operand)
|
||||
static void process_size_override(insn *result, int operand)
|
||||
{
|
||||
if (tasm_compatible_mode) {
|
||||
switch ((int)tokval.t_integer) {
|
||||
/* For TASM compatibility a size override inside the
|
||||
* brackets changes the size of the operand, not the
|
||||
* address type of the operand as it does in standard
|
||||
* NASM syntax. Hence:
|
||||
*
|
||||
* mov eax,[DWORD val]
|
||||
*
|
||||
* is valid syntax in TASM compatibility mode. Note that
|
||||
* you lose the ability to override the default address
|
||||
* type for the instruction, but we never use anything
|
||||
* but 32-bit flat model addressing in our code.
|
||||
*/
|
||||
case S_BYTE:
|
||||
result->oprs[operand].type |= BITS8;
|
||||
break;
|
||||
case S_WORD:
|
||||
result->oprs[operand].type |= BITS16;
|
||||
break;
|
||||
case S_DWORD:
|
||||
case S_LONG:
|
||||
result->oprs[operand].type |= BITS32;
|
||||
break;
|
||||
case S_QWORD:
|
||||
result->oprs[operand].type |= BITS64;
|
||||
break;
|
||||
case S_TWORD:
|
||||
result->oprs[operand].type |= BITS80;
|
||||
break;
|
||||
case S_OWORD:
|
||||
result->oprs[operand].type |= BITS128;
|
||||
break;
|
||||
default:
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"invalid operand size specification");
|
||||
break;
|
||||
}
|
||||
switch ((int)tokval.t_integer) {
|
||||
/* For TASM compatibility a size override inside the
|
||||
* brackets changes the size of the operand, not the
|
||||
* address type of the operand as it does in standard
|
||||
* NASM syntax. Hence:
|
||||
*
|
||||
* mov eax,[DWORD val]
|
||||
*
|
||||
* is valid syntax in TASM compatibility mode. Note that
|
||||
* you lose the ability to override the default address
|
||||
* type for the instruction, but we never use anything
|
||||
* but 32-bit flat model addressing in our code.
|
||||
*/
|
||||
case S_BYTE:
|
||||
result->oprs[operand].type |= BITS8;
|
||||
break;
|
||||
case S_WORD:
|
||||
result->oprs[operand].type |= BITS16;
|
||||
break;
|
||||
case S_DWORD:
|
||||
case S_LONG:
|
||||
result->oprs[operand].type |= BITS32;
|
||||
break;
|
||||
case S_QWORD:
|
||||
result->oprs[operand].type |= BITS64;
|
||||
break;
|
||||
case S_TWORD:
|
||||
result->oprs[operand].type |= BITS80;
|
||||
break;
|
||||
case S_OWORD:
|
||||
result->oprs[operand].type |= BITS128;
|
||||
break;
|
||||
default:
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"invalid operand size specification");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Standard NASM compatible syntax */
|
||||
switch ((int)tokval.t_integer) {
|
||||
case S_NOSPLIT:
|
||||
result->oprs[operand].eaflags |= EAF_TIMESTWO;
|
||||
break;
|
||||
case S_REL:
|
||||
result->oprs[operand].eaflags |= EAF_REL;
|
||||
break;
|
||||
case S_ABS:
|
||||
result->oprs[operand].eaflags |= EAF_ABS;
|
||||
break;
|
||||
case S_BYTE:
|
||||
result->oprs[operand].disp_size = 8;
|
||||
result->oprs[operand].eaflags |= EAF_BYTEOFFS;
|
||||
break;
|
||||
case P_A16:
|
||||
case P_A32:
|
||||
case P_A64:
|
||||
if (result->prefixes[PPS_ASIZE] &&
|
||||
result->prefixes[PPS_ASIZE] != tokval.t_integer)
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"conflicting address size specifications");
|
||||
else
|
||||
result->prefixes[PPS_ASIZE] = tokval.t_integer;
|
||||
break;
|
||||
case S_WORD:
|
||||
result->oprs[operand].disp_size = 16;
|
||||
result->oprs[operand].eaflags |= EAF_WORDOFFS;
|
||||
break;
|
||||
case S_DWORD:
|
||||
case S_LONG:
|
||||
result->oprs[operand].disp_size = 32;
|
||||
result->oprs[operand].eaflags |= EAF_WORDOFFS;
|
||||
break;
|
||||
case S_QWORD:
|
||||
result->oprs[operand].disp_size = 64;
|
||||
result->oprs[operand].eaflags |= EAF_WORDOFFS;
|
||||
break;
|
||||
default:
|
||||
nasm_error(ERR_NONFATAL, "invalid size specification in"
|
||||
" effective address");
|
||||
break;
|
||||
}
|
||||
/* Standard NASM compatible syntax */
|
||||
switch ((int)tokval.t_integer) {
|
||||
case S_NOSPLIT:
|
||||
result->oprs[operand].eaflags |= EAF_TIMESTWO;
|
||||
break;
|
||||
case S_REL:
|
||||
result->oprs[operand].eaflags |= EAF_REL;
|
||||
break;
|
||||
case S_ABS:
|
||||
result->oprs[operand].eaflags |= EAF_ABS;
|
||||
break;
|
||||
case S_BYTE:
|
||||
result->oprs[operand].disp_size = 8;
|
||||
result->oprs[operand].eaflags |= EAF_BYTEOFFS;
|
||||
break;
|
||||
case P_A16:
|
||||
case P_A32:
|
||||
case P_A64:
|
||||
if (result->prefixes[PPS_ASIZE] &&
|
||||
result->prefixes[PPS_ASIZE] != tokval.t_integer)
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"conflicting address size specifications");
|
||||
else
|
||||
result->prefixes[PPS_ASIZE] = tokval.t_integer;
|
||||
break;
|
||||
case S_WORD:
|
||||
result->oprs[operand].disp_size = 16;
|
||||
result->oprs[operand].eaflags |= EAF_WORDOFFS;
|
||||
break;
|
||||
case S_DWORD:
|
||||
case S_LONG:
|
||||
result->oprs[operand].disp_size = 32;
|
||||
result->oprs[operand].eaflags |= EAF_WORDOFFS;
|
||||
break;
|
||||
case S_QWORD:
|
||||
result->oprs[operand].disp_size = 64;
|
||||
result->oprs[operand].eaflags |= EAF_WORDOFFS;
|
||||
break;
|
||||
default:
|
||||
nasm_error(ERR_NONFATAL, "invalid size specification in"
|
||||
" effective address");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ restart_parse:
|
||||
|
||||
if (i == TOKEN_ID || (insn_is_label && i == TOKEN_INSN)) {
|
||||
/* there's a label here */
|
||||
first = false;
|
||||
first = false;
|
||||
result->label = tokval.t_charptr;
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i == ':') { /* skip over the optional colon */
|
||||
@ -254,13 +254,13 @@ restart_parse:
|
||||
}
|
||||
|
||||
for (j = 0; j < MAXPREFIX; j++)
|
||||
result->prefixes[j] = P_none;
|
||||
result->prefixes[j] = P_none;
|
||||
result->times = 1L;
|
||||
|
||||
while (i == TOKEN_PREFIX ||
|
||||
(i == TOKEN_REG && !(REG_SREG & ~nasm_reg_flags[tokval.t_integer])))
|
||||
{
|
||||
first = false;
|
||||
first = false;
|
||||
|
||||
/*
|
||||
* Handle special case: the TIMES prefix.
|
||||
@ -289,27 +289,27 @@ restart_parse:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int slot = prefix_slot(tokval.t_integer);
|
||||
if (result->prefixes[slot]) {
|
||||
int slot = prefix_slot(tokval.t_integer);
|
||||
if (result->prefixes[slot]) {
|
||||
if (result->prefixes[slot] == tokval.t_integer)
|
||||
nasm_error(ERR_WARNING,
|
||||
"instruction has redundant prefixes");
|
||||
nasm_error(ERR_WARNING,
|
||||
"instruction has redundant prefixes");
|
||||
else
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"instruction has conflicting prefixes");
|
||||
}
|
||||
result->prefixes[slot] = tokval.t_integer;
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"instruction has conflicting prefixes");
|
||||
}
|
||||
result->prefixes[slot] = tokval.t_integer;
|
||||
i = stdscan(NULL, &tokval);
|
||||
}
|
||||
}
|
||||
|
||||
if (i != TOKEN_INSN) {
|
||||
int j;
|
||||
enum prefixes pfx;
|
||||
int j;
|
||||
enum prefixes pfx;
|
||||
|
||||
for (j = 0; j < MAXPREFIX; j++)
|
||||
if ((pfx = result->prefixes[j]) != P_none)
|
||||
break;
|
||||
for (j = 0; j < MAXPREFIX; j++)
|
||||
if ((pfx = result->prefixes[j]) != P_none)
|
||||
break;
|
||||
|
||||
if (i == 0 && pfx != P_none) {
|
||||
/*
|
||||
@ -349,10 +349,10 @@ restart_parse:
|
||||
if (result->opcode == I_DB || result->opcode == I_DW ||
|
||||
result->opcode == I_DD || result->opcode == I_DQ ||
|
||||
result->opcode == I_DT || result->opcode == I_DO ||
|
||||
result->opcode == I_DY || result->opcode == I_INCBIN) {
|
||||
result->opcode == I_DY || result->opcode == I_INCBIN) {
|
||||
extop *eop, **tail = &result->eops, **fixptr;
|
||||
int oper_num = 0;
|
||||
int32_t sign;
|
||||
int32_t sign;
|
||||
|
||||
result->eops_float = false;
|
||||
|
||||
@ -363,75 +363,77 @@ restart_parse:
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i == 0)
|
||||
break;
|
||||
else if (first && i == ':') {
|
||||
insn_is_label = true;
|
||||
goto restart_parse;
|
||||
}
|
||||
first = false;
|
||||
else if (first && i == ':') {
|
||||
insn_is_label = true;
|
||||
goto restart_parse;
|
||||
}
|
||||
first = false;
|
||||
fixptr = tail;
|
||||
eop = *tail = nasm_malloc(sizeof(extop));
|
||||
tail = &eop->next;
|
||||
eop->next = NULL;
|
||||
eop->type = EOT_NOTHING;
|
||||
oper_num++;
|
||||
sign = +1;
|
||||
sign = +1;
|
||||
|
||||
/* is_comma_next() here is to distinguish this from
|
||||
a string used as part of an expression... */
|
||||
/*
|
||||
* is_comma_next() here is to distinguish this from
|
||||
* a string used as part of an expression...
|
||||
*/
|
||||
if (i == TOKEN_STR && is_comma_next()) {
|
||||
eop->type = EOT_DB_STRING;
|
||||
eop->stringval = tokval.t_charptr;
|
||||
eop->stringlen = tokval.t_inttwo;
|
||||
i = stdscan(NULL, &tokval); /* eat the comma */
|
||||
} else if (i == TOKEN_STRFUNC) {
|
||||
bool parens = false;
|
||||
const char *funcname = tokval.t_charptr;
|
||||
enum strfunc func = tokval.t_integer;
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i == '(') {
|
||||
parens = true;
|
||||
i = stdscan(NULL, &tokval);
|
||||
}
|
||||
if (i != TOKEN_STR) {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"%s must be followed by a string constant",
|
||||
funcname);
|
||||
eop->type = EOT_NOTHING;
|
||||
} else {
|
||||
eop->type = EOT_DB_STRING_FREE;
|
||||
eop->stringlen =
|
||||
string_transform(tokval.t_charptr, tokval.t_inttwo,
|
||||
&eop->stringval, func);
|
||||
if (eop->stringlen == (size_t)-1) {
|
||||
nasm_error(ERR_NONFATAL, "invalid string for transform");
|
||||
eop->type = EOT_NOTHING;
|
||||
}
|
||||
}
|
||||
if (parens && i && i != ')') {
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i != ')') {
|
||||
nasm_error(ERR_NONFATAL, "unterminated %s function",
|
||||
funcname);
|
||||
}
|
||||
}
|
||||
if (i && i != ',')
|
||||
i = stdscan(NULL, &tokval);
|
||||
} else if (i == '-' || i == '+') {
|
||||
char *save = stdscan_get();
|
||||
int token = i;
|
||||
sign = (i == '-') ? -1 : 1;
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i != TOKEN_FLOAT) {
|
||||
stdscan_set(save);
|
||||
i = tokval.t_type = token;
|
||||
goto is_expression;
|
||||
} else {
|
||||
goto is_float;
|
||||
}
|
||||
} else if (i == TOKEN_STRFUNC) {
|
||||
bool parens = false;
|
||||
const char *funcname = tokval.t_charptr;
|
||||
enum strfunc func = tokval.t_integer;
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i == '(') {
|
||||
parens = true;
|
||||
i = stdscan(NULL, &tokval);
|
||||
}
|
||||
if (i != TOKEN_STR) {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"%s must be followed by a string constant",
|
||||
funcname);
|
||||
eop->type = EOT_NOTHING;
|
||||
} else {
|
||||
eop->type = EOT_DB_STRING_FREE;
|
||||
eop->stringlen =
|
||||
string_transform(tokval.t_charptr, tokval.t_inttwo,
|
||||
&eop->stringval, func);
|
||||
if (eop->stringlen == (size_t)-1) {
|
||||
nasm_error(ERR_NONFATAL, "invalid string for transform");
|
||||
eop->type = EOT_NOTHING;
|
||||
}
|
||||
}
|
||||
if (parens && i && i != ')') {
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i != ')') {
|
||||
nasm_error(ERR_NONFATAL, "unterminated %s function",
|
||||
funcname);
|
||||
}
|
||||
}
|
||||
if (i && i != ',')
|
||||
i = stdscan(NULL, &tokval);
|
||||
} else if (i == '-' || i == '+') {
|
||||
char *save = stdscan_get();
|
||||
int token = i;
|
||||
sign = (i == '-') ? -1 : 1;
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i != TOKEN_FLOAT) {
|
||||
stdscan_set(save);
|
||||
i = tokval.t_type = token;
|
||||
goto is_expression;
|
||||
} else {
|
||||
goto is_float;
|
||||
}
|
||||
} else if (i == TOKEN_FLOAT) {
|
||||
is_float:
|
||||
eop->type = EOT_DB_STRING;
|
||||
result->eops_float = true;
|
||||
eop->type = EOT_DB_STRING;
|
||||
result->eops_float = true;
|
||||
|
||||
eop->stringlen = idata_bytes(result->opcode);
|
||||
if (eop->stringlen > 16) {
|
||||
@ -448,18 +450,18 @@ is_float:
|
||||
eop->stringlen = 0;
|
||||
}
|
||||
|
||||
eop = nasm_realloc(eop, sizeof(extop) + eop->stringlen);
|
||||
tail = &eop->next;
|
||||
*fixptr = eop;
|
||||
eop->stringval = (char *)eop + sizeof(extop);
|
||||
if (!eop->stringlen ||
|
||||
!float_const(tokval.t_charptr, sign,
|
||||
(uint8_t *)eop->stringval,
|
||||
eop->stringlen, nasm_error))
|
||||
eop->type = EOT_NOTHING;
|
||||
i = stdscan(NULL, &tokval); /* eat the comma */
|
||||
} else {
|
||||
/* anything else, assume it is an expression */
|
||||
eop = nasm_realloc(eop, sizeof(extop) + eop->stringlen);
|
||||
tail = &eop->next;
|
||||
*fixptr = eop;
|
||||
eop->stringval = (char *)eop + sizeof(extop);
|
||||
if (!eop->stringlen ||
|
||||
!float_const(tokval.t_charptr, sign,
|
||||
(uint8_t *)eop->stringval,
|
||||
eop->stringlen, nasm_error))
|
||||
eop->type = EOT_NOTHING;
|
||||
i = stdscan(NULL, &tokval); /* eat the comma */
|
||||
} else {
|
||||
/* anything else, assume it is an expression */
|
||||
expr *value;
|
||||
|
||||
is_expression:
|
||||
@ -543,7 +545,7 @@ is_expression:
|
||||
* of these, separated by commas, and terminated by a zero token. */
|
||||
|
||||
for (operand = 0; operand < MAX_OPERANDS; operand++) {
|
||||
expr *value; /* used most of the time */
|
||||
expr *value; /* used most of the time */
|
||||
int mref; /* is this going to be a memory ref? */
|
||||
int bracket; /* is it a [] mref, or a & mref? */
|
||||
int setsize = 0;
|
||||
@ -555,11 +557,11 @@ is_expression:
|
||||
i = stdscan(NULL, &tokval);
|
||||
if (i == 0)
|
||||
break; /* end of operands: get out of here */
|
||||
else if (first && i == ':') {
|
||||
insn_is_label = true;
|
||||
goto restart_parse;
|
||||
}
|
||||
first = false;
|
||||
else if (first && i == ':') {
|
||||
insn_is_label = true;
|
||||
goto restart_parse;
|
||||
}
|
||||
first = false;
|
||||
result->oprs[operand].type = 0; /* so far, no override */
|
||||
while (i == TOKEN_SPECIAL) { /* size specifiers */
|
||||
switch ((int)tokval.t_integer) {
|
||||
@ -625,7 +627,7 @@ is_expression:
|
||||
bracket = (i == '[');
|
||||
i = stdscan(NULL, &tokval); /* then skip the colon */
|
||||
while (i == TOKEN_SPECIAL || i == TOKEN_PREFIX) {
|
||||
process_size_override(result, operand);
|
||||
process_size_override(result, operand);
|
||||
i = stdscan(NULL, &tokval);
|
||||
}
|
||||
} else { /* immediate operand, or register */
|
||||
@ -660,14 +662,14 @@ is_expression:
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"instruction has conflicting segment overrides");
|
||||
else {
|
||||
result->prefixes[PPS_SEG] = value->type;
|
||||
if (!(REG_FSGS & ~nasm_reg_flags[value->type]))
|
||||
result->oprs[operand].eaflags |= EAF_FSGS;
|
||||
}
|
||||
result->prefixes[PPS_SEG] = value->type;
|
||||
if (!(REG_FSGS & ~nasm_reg_flags[value->type]))
|
||||
result->oprs[operand].eaflags |= EAF_FSGS;
|
||||
}
|
||||
|
||||
i = stdscan(NULL, &tokval); /* then skip the colon */
|
||||
while (i == TOKEN_SPECIAL || i == TOKEN_PREFIX) {
|
||||
process_size_override(result, operand);
|
||||
process_size_override(result, operand);
|
||||
i = stdscan(NULL, &tokval);
|
||||
}
|
||||
value = evaluate(stdscan, NULL, &tokval,
|
||||
@ -710,13 +712,15 @@ is_expression:
|
||||
} while (i != 0 && i != ',');
|
||||
}
|
||||
|
||||
/* now convert the exprs returned from evaluate() into operand
|
||||
* descriptions... */
|
||||
/*
|
||||
* now convert the exprs returned from evaluate()
|
||||
* into operand descriptions...
|
||||
*/
|
||||
|
||||
if (mref) { /* it's a memory reference */
|
||||
expr *e = value;
|
||||
int b, i, s; /* basereg, indexreg, scale */
|
||||
int64_t o; /* offset */
|
||||
int64_t o; /* offset */
|
||||
|
||||
b = i = -1, o = s = 0;
|
||||
result->oprs[operand].hintbase = hints.base;
|
||||
@ -812,18 +816,18 @@ is_expression:
|
||||
return result;
|
||||
}
|
||||
|
||||
/* It is memory, but it can match any r/m operand */
|
||||
/* It is memory, but it can match any r/m operand */
|
||||
result->oprs[operand].type |= MEMORY_ANY;
|
||||
|
||||
if (b == -1 && (i == -1 || s == 0)) {
|
||||
int is_rel = globalbits == 64 &&
|
||||
!(result->oprs[operand].eaflags & EAF_ABS) &&
|
||||
((globalrel &&
|
||||
!(result->oprs[operand].eaflags & EAF_FSGS)) ||
|
||||
(result->oprs[operand].eaflags & EAF_REL));
|
||||
if (b == -1 && (i == -1 || s == 0)) {
|
||||
int is_rel = globalbits == 64 &&
|
||||
!(result->oprs[operand].eaflags & EAF_ABS) &&
|
||||
((globalrel &&
|
||||
!(result->oprs[operand].eaflags & EAF_FSGS)) ||
|
||||
(result->oprs[operand].eaflags & EAF_REL));
|
||||
|
||||
result->oprs[operand].type |= is_rel ? IP_REL : MEM_OFFS;
|
||||
}
|
||||
result->oprs[operand].type |= is_rel ? IP_REL : MEM_OFFS;
|
||||
}
|
||||
result->oprs[operand].basereg = b;
|
||||
result->oprs[operand].indexreg = i;
|
||||
result->oprs[operand].scale = s;
|
||||
@ -850,9 +854,9 @@ is_expression:
|
||||
result->oprs[operand].type |= UNITY;
|
||||
if (optimizing >= 0 &&
|
||||
!(result->oprs[operand].type & STRICT)) {
|
||||
int64_t v64 = reloc_value(value);
|
||||
int32_t v32 = (int32_t)v64;
|
||||
int16_t v16 = (int16_t)v32;
|
||||
int64_t v64 = reloc_value(value);
|
||||
int32_t v32 = (int32_t)v64;
|
||||
int16_t v16 = (int16_t)v32;
|
||||
|
||||
if (v64 >= -128 && v64 <= 127)
|
||||
result->oprs[operand].type |= SBYTE64;
|
||||
@ -865,7 +869,7 @@ is_expression:
|
||||
}
|
||||
}
|
||||
} else { /* it's a register */
|
||||
unsigned int rs;
|
||||
unsigned int rs;
|
||||
|
||||
if (value->type >= EXPR_SIMPLE || value->value != 1) {
|
||||
nasm_error(ERR_NONFATAL, "invalid operand type");
|
||||
@ -940,7 +944,7 @@ is_expression:
|
||||
result->oprs[0].offset *= 32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -964,8 +968,8 @@ void cleanup_insn(insn * i)
|
||||
|
||||
while ((e = i->eops)) {
|
||||
i->eops = e->next;
|
||||
if (e->type == EOT_DB_STRING_FREE)
|
||||
nasm_free(e->stringval);
|
||||
if (e->type == EOT_DB_STRING_FREE)
|
||||
nasm_free(e->stringval);
|
||||
nasm_free(e);
|
||||
}
|
||||
}
|
||||
|
124
stdscan.c
124
stdscan.c
@ -57,12 +57,12 @@ static int stdscan_tempsize = 0, stdscan_templen = 0;
|
||||
|
||||
void stdscan_set(char *str)
|
||||
{
|
||||
stdscan_bufptr = str;
|
||||
stdscan_bufptr = str;
|
||||
}
|
||||
|
||||
char *stdscan_get(void)
|
||||
{
|
||||
return stdscan_bufptr;
|
||||
return stdscan_bufptr;
|
||||
}
|
||||
|
||||
static void stdscan_pop(void)
|
||||
@ -144,7 +144,7 @@ int stdscan(void *private_data, struct tokenval *tv)
|
||||
*r = '\0';
|
||||
/* right, so we have an identifier sitting in temp storage. now,
|
||||
* is it actually a register or instruction name, or what? */
|
||||
return nasm_token_hash(ourcopy, tv);
|
||||
return nasm_token_hash(ourcopy, tv);
|
||||
} else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {
|
||||
/*
|
||||
* It's a $ sign with no following hex number; this must
|
||||
@ -160,72 +160,74 @@ int stdscan(void *private_data, struct tokenval *tv)
|
||||
return tv->t_type = TOKEN_HERE;
|
||||
} else if (isnumstart(*stdscan_bufptr)) { /* now we've got a number */
|
||||
bool rn_error;
|
||||
bool is_hex = false;
|
||||
bool is_float = false;
|
||||
bool has_e = false;
|
||||
char c;
|
||||
bool is_hex = false;
|
||||
bool is_float = false;
|
||||
bool has_e = false;
|
||||
char c;
|
||||
|
||||
r = stdscan_bufptr;
|
||||
|
||||
if (*stdscan_bufptr == '$') {
|
||||
stdscan_bufptr++;
|
||||
is_hex = true;
|
||||
}
|
||||
if (*stdscan_bufptr == '$') {
|
||||
stdscan_bufptr++;
|
||||
is_hex = true;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
c = *stdscan_bufptr++;
|
||||
for (;;) {
|
||||
c = *stdscan_bufptr++;
|
||||
|
||||
if (!is_hex && (c == 'e' || c == 'E')) {
|
||||
has_e = true;
|
||||
if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-') {
|
||||
/* e can only be followed by +/- if it is either a
|
||||
prefixed hex number or a floating-point number */
|
||||
is_float = true;
|
||||
stdscan_bufptr++;
|
||||
}
|
||||
} else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') {
|
||||
is_hex = true;
|
||||
} else if (c == 'P' || c == 'p') {
|
||||
is_float = true;
|
||||
if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-')
|
||||
stdscan_bufptr++;
|
||||
} else if (isnumchar(c) || c == '_')
|
||||
; /* just advance */
|
||||
else if (c == '.')
|
||||
is_float = true;
|
||||
else
|
||||
break;
|
||||
}
|
||||
stdscan_bufptr--; /* Point to first character beyond number */
|
||||
if (!is_hex && (c == 'e' || c == 'E')) {
|
||||
has_e = true;
|
||||
if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-') {
|
||||
/*
|
||||
* e can only be followed by +/- if it is either a
|
||||
* prefixed hex number or a floating-point number
|
||||
*/
|
||||
is_float = true;
|
||||
stdscan_bufptr++;
|
||||
}
|
||||
} else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') {
|
||||
is_hex = true;
|
||||
} else if (c == 'P' || c == 'p') {
|
||||
is_float = true;
|
||||
if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-')
|
||||
stdscan_bufptr++;
|
||||
} else if (isnumchar(c) || c == '_')
|
||||
; /* just advance */
|
||||
else if (c == '.')
|
||||
is_float = true;
|
||||
else
|
||||
break;
|
||||
}
|
||||
stdscan_bufptr--; /* Point to first character beyond number */
|
||||
|
||||
if (has_e && !is_hex) {
|
||||
/* 1e13 is floating-point, but 1e13h is not */
|
||||
is_float = true;
|
||||
}
|
||||
if (has_e && !is_hex) {
|
||||
/* 1e13 is floating-point, but 1e13h is not */
|
||||
is_float = true;
|
||||
}
|
||||
|
||||
if (is_float) {
|
||||
tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);
|
||||
return tv->t_type = TOKEN_FLOAT;
|
||||
} else {
|
||||
r = stdscan_copy(r, stdscan_bufptr - r);
|
||||
tv->t_integer = readnum(r, &rn_error);
|
||||
stdscan_pop();
|
||||
if (rn_error) {
|
||||
/* some malformation occurred */
|
||||
return tv->t_type = TOKEN_ERRNUM;
|
||||
}
|
||||
tv->t_charptr = NULL;
|
||||
return tv->t_type = TOKEN_NUM;
|
||||
}
|
||||
if (is_float) {
|
||||
tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);
|
||||
return tv->t_type = TOKEN_FLOAT;
|
||||
} else {
|
||||
r = stdscan_copy(r, stdscan_bufptr - r);
|
||||
tv->t_integer = readnum(r, &rn_error);
|
||||
stdscan_pop();
|
||||
if (rn_error) {
|
||||
/* some malformation occurred */
|
||||
return tv->t_type = TOKEN_ERRNUM;
|
||||
}
|
||||
tv->t_charptr = NULL;
|
||||
return tv->t_type = TOKEN_NUM;
|
||||
}
|
||||
} else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"' ||
|
||||
*stdscan_bufptr == '`') {
|
||||
/* a quoted string */
|
||||
char start_quote = *stdscan_bufptr;
|
||||
tv->t_charptr = stdscan_bufptr;
|
||||
tv->t_inttwo = nasm_unquote(tv->t_charptr, &stdscan_bufptr);
|
||||
if (*stdscan_bufptr != start_quote)
|
||||
return tv->t_type = TOKEN_ERRSTR;
|
||||
stdscan_bufptr++; /* Skip final quote */
|
||||
*stdscan_bufptr == '`') {
|
||||
/* a quoted string */
|
||||
char start_quote = *stdscan_bufptr;
|
||||
tv->t_charptr = stdscan_bufptr;
|
||||
tv->t_inttwo = nasm_unquote(tv->t_charptr, &stdscan_bufptr);
|
||||
if (*stdscan_bufptr != start_quote)
|
||||
return tv->t_type = TOKEN_ERRSTR;
|
||||
stdscan_bufptr++; /* Skip final quote */
|
||||
return tv->t_type = TOKEN_STR;
|
||||
} else if (*stdscan_bufptr == ';') {
|
||||
/* a comment has happened - stay */
|
||||
|
Loading…
x
Reference in New Issue
Block a user