diff options
author | Peter Johnson <peter@tortall.net> | 2010-01-19 07:03:15 +0000 |
---|---|---|
committer | Peter Johnson <peter@tortall.net> | 2010-01-19 07:03:15 +0000 |
commit | 7d6b1a0ae4eafe0bd4b2197f74062934b7263cd6 (patch) | |
tree | 711d6abaddc9d2c3d4b543d97f0569064c924d34 | |
parent | d965ef7d7a7df127821ae2a49e0a2a710db32a54 (diff) | |
download | yasm-7d6b1a0ae4eafe0bd4b2197f74062934b7263cd6.tar.gz |
Nasm parser: Add some very basic MASM-ish syntax handling, along the lines
of the TASM "mode".
These code paths aren't used yet; they will be used for GAS .intel_syntax
handling.
Contributed by: Alexei Svitkine
svn path=/trunk/yasm/; revision=2277
-rw-r--r-- | modules/parsers/nasm/nasm-parse.c | 64 | ||||
-rw-r--r-- | modules/parsers/nasm/nasm-parser-struct.h | 1 | ||||
-rw-r--r-- | modules/parsers/nasm/nasm-parser.c | 1 | ||||
-rw-r--r-- | modules/parsers/nasm/nasm-parser.h | 2 | ||||
-rw-r--r-- | modules/parsers/nasm/nasm-token.re | 16 |
5 files changed, 80 insertions, 4 deletions
diff --git a/modules/parsers/nasm/nasm-parse.c b/modules/parsers/nasm/nasm-parse.c index 242d3f0b..72db7775 100644 --- a/modules/parsers/nasm/nasm-parse.c +++ b/modules/parsers/nasm/nasm-parse.c @@ -178,6 +178,7 @@ describe_token(int token) case INSN: str = "instruction"; break; case PREFIX: str = "instruction prefix"; break; case REG: str = "register"; break; + case REGGROUP: str = "register group"; break; case SEGREG: str = "segment register"; break; case TARGETMOD: str = "target modifier"; break; case LEFT_OP: str = "<<"; break; @@ -843,6 +844,12 @@ parse_operand(yasm_parser_nasm *parser_nasm) { yasm_insn_operand *op2; get_next_token(); + if (parser_nasm->masm && curtok == ID && !yasm__strcasecmp(ID_val, "flat")) { + get_next_token(); + if (curtok == ':') { + get_next_token(); + } + } op = parse_operand(parser_nasm); if (!op) { yasm_error_set(YASM_ERROR_SYNTAX, @@ -904,6 +911,35 @@ parse_operand(yasm_parser_nasm *parser_nasm) op = yasm_operand_create_reg(REG_val); get_next_token(); return op; + case REGGROUP: + { + unsigned long regindex; + uintptr_t reg = REGGROUP_val; + get_next_token(); /* REGGROUP */ + if (curtok != '(') + return yasm_operand_create_reg(reg); + get_next_token(); /* '(' */ + if (!expect(INTNUM)) { + yasm_error_set(YASM_ERROR_SYNTAX, + N_("integer register index expected")); + return NULL; + } + regindex = yasm_intnum_get_uint(INTNUM_val); + get_next_token(); /* INTNUM */ + if (!expect(')')) { + yasm_error_set(YASM_ERROR_SYNTAX, + N_("missing closing parenthesis for register index")); + return NULL; + } + get_next_token(); /* ')' */ + reg = yasm_arch_reggroup_get_reg(p_object->arch, reg, regindex); + if (reg == 0) { + yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"), + regindex); + return NULL; + } + return yasm_operand_create_reg(reg); + } case STRICT: get_next_token(); op = parse_operand(parser_nasm); @@ -914,6 +950,9 @@ parse_operand(yasm_parser_nasm *parser_nasm) { unsigned int size = SIZE_OVERRIDE_val; get_next_token(); + if (parser_nasm->masm && curtok == ID && !yasm__strcasecmp(ID_val, "ptr")) { + get_next_token(); + } op = parse_operand(parser_nasm); if (!op) return NULL; @@ -988,15 +1027,34 @@ parse_operand(yasm_parser_nasm *parser_nasm) yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR); if (!e) return NULL; - if (curtok != ':') + if (curtok != ':') { if (parser_nasm->tasm && yasm_expr_size(e)) { yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e); yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); op = yasm_operand_create_mem(ea); return op; - } else + } else if (curtok == '[') { + yasm_expr *f; + yasm_effaddr *ea; + yasm_insn_operand *op2; + + op = parse_operand(parser_nasm); + if (!op) + return NULL; + + f = op->data.ea->disp.abs; + e = p_expr_new_tree(e, YASM_EXPR_ADD, f); + ea = yasm_arch_ea_create(p_object->arch, e); + yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); + op2 = yasm_operand_create_mem(ea); + + yasm_xfree(op); + + return op2; + } else { return yasm_operand_create_imm(e); - else { + } + } else { yasm_expr *off; get_next_token(); off = parse_bexpr(parser_nasm, NORM_EXPR); diff --git a/modules/parsers/nasm/nasm-parser-struct.h b/modules/parsers/nasm/nasm-parser-struct.h index 506f02cc..60b098a5 100644 --- a/modules/parsers/nasm/nasm-parser-struct.h +++ b/modules/parsers/nasm/nasm-parser-struct.h @@ -42,6 +42,7 @@ typedef union { typedef struct yasm_parser_nasm { int tasm; + int masm; /*@only@*/ yasm_object *object; diff --git a/modules/parsers/nasm/nasm-parser.c b/modules/parsers/nasm/nasm-parser.c index b0ad4b51..11be0b6e 100644 --- a/modules/parsers/nasm/nasm-parser.c +++ b/modules/parsers/nasm/nasm-parser.c @@ -39,6 +39,7 @@ nasm_do_parse(yasm_object *object, yasm_preproc *pp, int save_input, yasm_parser_nasm parser_nasm; parser_nasm.tasm = tasm; + parser_nasm.masm = 0; parser_nasm.object = object; parser_nasm.linemap = linemap; diff --git a/modules/parsers/nasm/nasm-parser.h b/modules/parsers/nasm/nasm-parser.h index b213edcc..257429b8 100644 --- a/modules/parsers/nasm/nasm-parser.h +++ b/modules/parsers/nasm/nasm-parser.h @@ -57,6 +57,7 @@ enum tokentype { INSN, PREFIX, REG, + REGGROUP, SEGREG, TARGETMOD, LEFT_OP, @@ -104,6 +105,7 @@ enum nasm_parser_state { #define INSN_val (curval.bc) #define PREFIX_val (curval.arch_data) #define REG_val (curval.arch_data) +#define REGGROUP_val (curval.arch_data) #define SEGREG_val (curval.arch_data) #define TARGETMOD_val (curval.arch_data) #define ID_val (curval.str_val) diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re index 6e9b3ca4..f057bb17 100644 --- a/modules/parsers/nasm/nasm-token.re +++ b/modules/parsers/nasm/nasm-token.re @@ -84,6 +84,10 @@ handle_dot_label(YYSTYPE *lvalp, char *tok, size_t toklen, size_t zeropos, return NONLOCAL_ID; return SPECIAL_ID; } + if (parser_nasm->masm && tok[zeropos] == '.') { + lvalp->str_val = yasm__xstrndup(tok + zeropos, toklen - zeropos); + return SPECIAL_ID; + } if (parser_nasm->tasm && (!tasm_locals || (tok[zeropos] == '.' && tok[zeropos+1] != '@' && tok[zeropos+2] != '@'))) { @@ -416,10 +420,20 @@ scan: case YASM_ARCH_TARGETMOD: s->tok[TOKLEN] = savech; RETURN(TARGETMOD); + case YASM_ARCH_REGGROUP: + if (parser_nasm->masm) { + s->tok[TOKLEN] = savech; + RETURN(REGGROUP); + } default: break; } - if (parser_nasm->tasm) { + if (parser_nasm->masm) { + if (!yasm__strcasecmp(TOK, "offset")) { + s->tok[TOKLEN] = savech; + RETURN(OFFSET); + } + } else if (parser_nasm->tasm) { if (!yasm__strcasecmp(TOK, "shl")) { s->tok[TOKLEN] = savech; RETURN(LEFT_OP); |