diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index 24bf0b20..b644e352 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -156,7 +156,10 @@ struct bytecode { } reserve; } data; - unsigned long len; /* total length of entire bytecode */ + expr *multiple; /* number of times bytecode is repeated */ + + unsigned long len; /* total length of entire bytecode (including + multiple copies) */ /* where it came from */ char *filename; @@ -385,11 +388,21 @@ SetOpcodeSel(jmprel_opcode_sel *old_sel, jmprel_opcode_sel new_sel) *old_sel = new_sel; } +void +SetBCMultiple(bytecode *bc, expr *e) +{ + if (bc->multiple) + bc->multiple = expr_new_tree(bc->multiple, EXPR_MUL, e); + else + bc->multiple = e; +} + static bytecode * bytecode_new_common(void) { bytecode *bc = xmalloc(sizeof(bytecode)); + bc->multiple = (expr *)NULL; bc->len = 0; bc->filename = xstrdup(in_filename); @@ -632,6 +645,12 @@ bytecode_print(bytecode *bc) default: printf("_Unknown_\n"); } + printf("Multiple="); + if (!bc->multiple) + printf("1"); + else + expr_print(bc->multiple); + printf("\n"); printf("Length=%lu\n", bc->len); printf("Filename=\"%s\" Line Number=%u\n", bc->filename ? bc->filename : "", bc->lineno); diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index be485e4f..4b49f2e2 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -81,6 +81,8 @@ void SetInsnShiftFlag(bytecode *bc); void SetOpcodeSel(jmprel_opcode_sel *old_sel, jmprel_opcode_sel new_sel); +void SetBCMultiple(bytecode *bc, expr *e); + /* IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling this * function (it doesn't make a copy). */ diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index 91192326..6d495b7f 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -117,7 +117,7 @@ static bytecode *nasm_parser_temp_bc; %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string +%type expr expr_no_string expr_no_fltstr %type explabel %type label_id %type target @@ -154,17 +154,19 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | label { $$ = (bytecode *)NULL; } - | label exp { $$ = $2; } - | label_id EQU expr { + | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | label { $$ = (bytecode *)NULL; } + | label exp { $$ = $2; } + | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; } ; exp: instr - | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } + | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } + | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -385,14 +387,17 @@ imm32: imm ; /* jump targets */ -target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } - | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } - | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } +target: expr_no_string { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } + | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } + | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } +expr_no_string: expr_no_fltstr | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } +; + +expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index 91192326..6d495b7f 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -117,7 +117,7 @@ static bytecode *nasm_parser_temp_bc; %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string +%type expr expr_no_string expr_no_fltstr %type explabel %type label_id %type target @@ -154,17 +154,19 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | label { $$ = (bytecode *)NULL; } - | label exp { $$ = $2; } - | label_id EQU expr { + | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | label { $$ = (bytecode *)NULL; } + | label exp { $$ = $2; } + | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; } ; exp: instr - | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } + | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } + | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -385,14 +387,17 @@ imm32: imm ; /* jump targets */ -target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } - | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } - | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } +target: expr_no_string { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } + | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } + | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } +expr_no_string: expr_no_fltstr | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } +; + +expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/src/bytecode.c b/src/bytecode.c index 24bf0b20..b644e352 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -156,7 +156,10 @@ struct bytecode { } reserve; } data; - unsigned long len; /* total length of entire bytecode */ + expr *multiple; /* number of times bytecode is repeated */ + + unsigned long len; /* total length of entire bytecode (including + multiple copies) */ /* where it came from */ char *filename; @@ -385,11 +388,21 @@ SetOpcodeSel(jmprel_opcode_sel *old_sel, jmprel_opcode_sel new_sel) *old_sel = new_sel; } +void +SetBCMultiple(bytecode *bc, expr *e) +{ + if (bc->multiple) + bc->multiple = expr_new_tree(bc->multiple, EXPR_MUL, e); + else + bc->multiple = e; +} + static bytecode * bytecode_new_common(void) { bytecode *bc = xmalloc(sizeof(bytecode)); + bc->multiple = (expr *)NULL; bc->len = 0; bc->filename = xstrdup(in_filename); @@ -632,6 +645,12 @@ bytecode_print(bytecode *bc) default: printf("_Unknown_\n"); } + printf("Multiple="); + if (!bc->multiple) + printf("1"); + else + expr_print(bc->multiple); + printf("\n"); printf("Length=%lu\n", bc->len); printf("Filename=\"%s\" Line Number=%u\n", bc->filename ? bc->filename : "", bc->lineno); diff --git a/src/bytecode.h b/src/bytecode.h index be485e4f..4b49f2e2 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -81,6 +81,8 @@ void SetInsnShiftFlag(bytecode *bc); void SetOpcodeSel(jmprel_opcode_sel *old_sel, jmprel_opcode_sel new_sel); +void SetBCMultiple(bytecode *bc, expr *e); + /* IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling this * function (it doesn't make a copy). */ diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index 91192326..6d495b7f 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -117,7 +117,7 @@ static bytecode *nasm_parser_temp_bc; %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string +%type expr expr_no_string expr_no_fltstr %type explabel %type label_id %type target @@ -154,17 +154,19 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | label { $$ = (bytecode *)NULL; } - | label exp { $$ = $2; } - | label_id EQU expr { + | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | label { $$ = (bytecode *)NULL; } + | label exp { $$ = $2; } + | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; } ; exp: instr - | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } + | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } + | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -385,14 +387,17 @@ imm32: imm ; /* jump targets */ -target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } - | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } - | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } +target: expr_no_string { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } + | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } + | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } +expr_no_string: expr_no_fltstr | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } +; + +expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index 91192326..6d495b7f 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -117,7 +117,7 @@ static bytecode *nasm_parser_temp_bc; %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string +%type expr expr_no_string expr_no_fltstr %type explabel %type label_id %type target @@ -154,17 +154,19 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | label { $$ = (bytecode *)NULL; } - | label exp { $$ = $2; } - | label_id EQU expr { + | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | label { $$ = (bytecode *)NULL; } + | label exp { $$ = $2; } + | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; } ; exp: instr - | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } + | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } + | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -385,14 +387,17 @@ imm32: imm ; /* jump targets */ -target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } - | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } - | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } +target: expr_no_string { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } + | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } + | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } +expr_no_string: expr_no_fltstr | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } +; + +expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }