]> granicus.if.org Git - yasm/commitdiff
Nasm parser: Add some very basic MASM-ish syntax handling, along the lines
authorPeter Johnson <peter@tortall.net>
Tue, 19 Jan 2010 07:03:15 +0000 (07:03 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 19 Jan 2010 07:03:15 +0000 (07:03 -0000)
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

modules/parsers/nasm/nasm-parse.c
modules/parsers/nasm/nasm-parser-struct.h
modules/parsers/nasm/nasm-parser.c
modules/parsers/nasm/nasm-parser.h
modules/parsers/nasm/nasm-token.re

index 242d3f0b821f816cd2315e6a8bf60734420da229..72db77755a8a239716fe66d5d6a5e50f5ba0a886 100644 (file)
@@ -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);
index 506f02cc2ce80d3998299cba957202b8a665c6d8..60b098a5ec5d3586e59aa4829fc15b11c536523f 100644 (file)
@@ -42,6 +42,7 @@ typedef union {
 
 typedef struct yasm_parser_nasm {
     int tasm;
+    int masm;
 
     /*@only@*/ yasm_object *object;
 
index b0ad4b51df4f386c079fc642411c2dda3a7fbd57..11be0b6eea382e03255f28a409b88e400237ea3d 100644 (file)
@@ -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;
index b213edcc976c8bac990cced833a80da65007c0c5..257429b8a01ff3e68f6bc0e8e723212c0affe48c 100644 (file)
@@ -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)
index 6e9b3ca43a656e8bf41fbae86fdeb402702a5572..f057bb1767d6866df5e020f3b844b805acf549e7 100644 (file)
@@ -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);