summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Johnson <peter@tortall.net>2010-01-19 07:03:15 +0000
committerPeter Johnson <peter@tortall.net>2010-01-19 07:03:15 +0000
commit7d6b1a0ae4eafe0bd4b2197f74062934b7263cd6 (patch)
tree711d6abaddc9d2c3d4b543d97f0569064c924d34
parentd965ef7d7a7df127821ae2a49e0a2a710db32a54 (diff)
downloadyasm-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.c64
-rw-r--r--modules/parsers/nasm/nasm-parser-struct.h1
-rw-r--r--modules/parsers/nasm/nasm-parser.c1
-rw-r--r--modules/parsers/nasm/nasm-parser.h2
-rw-r--r--modules/parsers/nasm/nasm-token.re16
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);