diff options
-rw-r--r-- | eval.c | 103 | ||||
-rw-r--r-- | parser.c | 422 | ||||
-rw-r--r-- | stdscan.c | 124 |
3 files changed, 327 insertions, 322 deletions
@@ -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; } @@ -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); } } @@ -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 */ |