From: nasm-bot f. C. S. B. <cha...@in...> - 2018-08-15 21:46:38
|
Commit-ID: a578634b61615a4a0d5e51b1d1b046efdbd9867d Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=a578634b61615a4a0d5e51b1d1b046efdbd9867d Author: Chang S. Bae <cha...@in...> AuthorDate: Wed, 15 Aug 2018 23:22:21 +0300 Committer: Cyrill Gorcunov <gor...@gm...> CommitDate: Thu, 16 Aug 2018 00:01:31 +0300 optimization: Introduce new flag to turn-off selectively While configuring optimization in a level is conventional, a certain optimization tends to conflict with some pragma. For example, jump match conflicts with Mach-O's "subsections-via-symbols" macro. This configurability will workaround such conflicts. Signed-off-by: Chang S. Bae <cha...@in...> --- asm/assemble.c | 6 +++--- asm/nasm.c | 21 +++++++++++---------- asm/parser.c | 4 ++-- doc/opt_var.txt | 6 ++++-- include/nasm.h | 16 +++++++++++++++- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/asm/assemble.c b/asm/assemble.c index 5dd0d47..30dc047 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -528,9 +528,9 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits, if (((c & ~1) != 0370) || (ins->oprs[0].type & STRICT)) return false; - if (!optimizing) + if (!optimizing.level || (optimizing.flag & OPTIM_DISABLE_JMP_MATCH)) return false; - if (optimizing < 0 && c == 0371) + if (optimizing.level < 0 && c == 0371) return false; isize = calcsize(segment, offset, bits, ins, temp); @@ -2188,7 +2188,7 @@ static enum match_result matches(const struct itemplate *itemp, /* * Is it legal? */ - if (!(optimizing > 0) && itemp_has(itemp, IF_OPT)) + if (!(optimizing.level > 0) && itemp_has(itemp, IF_OPT)) return MERR_INVALOP; /* diff --git a/asm/nasm.c b/asm/nasm.c index 55e4a8c..0c1df9f 100644 --- a/asm/nasm.c +++ b/asm/nasm.c @@ -117,7 +117,8 @@ const struct dfmt *dfmt; static FILE *error_file; /* Where to write error messages */ FILE *ofile = NULL; -int optimizing = MAX_OPTIMIZE; /* number of optimization passes to take */ +struct optimization optimizing = + { MAX_OPTIMIZE, OPTIM_ALL_ENABLED }; /* number of optimization passes to take */ static int cmd_sb = 16; /* by default */ iflag_t cpu; @@ -867,7 +868,7 @@ static bool process_arg(char *p, char *q, int pass) if (!*param) { /* Naked -O == -Ox */ - optimizing = MAX_OPTIMIZE; + optimizing.level = MAX_OPTIMIZE; } else { while (*param) { switch (*param) { @@ -875,12 +876,12 @@ static bool process_arg(char *p, char *q, int pass) case '5': case '6': case '7': case '8': case '9': opt = strtoul(param, ¶m, 10); - /* -O0 -> optimizing == -1, 0.98 behaviour */ - /* -O1 -> optimizing == 0, 0.98.09 behaviour */ + /* -O0 -> optimizing.level == -1, 0.98 behaviour */ + /* -O1 -> optimizing.level == 0, 0.98.09 behaviour */ if (opt < 2) - optimizing = opt - 1; + optimizing.level = opt - 1; else - optimizing = opt; + optimizing.level = opt; break; case 'v': @@ -891,7 +892,7 @@ static bool process_arg(char *p, char *q, int pass) case 'x': param++; - optimizing = MAX_OPTIMIZE; + optimizing.level = MAX_OPTIMIZE; break; default: @@ -901,8 +902,8 @@ static bool process_arg(char *p, char *q, int pass) break; } } - if (optimizing > MAX_OPTIMIZE) - optimizing = MAX_OPTIMIZE; + if (optimizing.level > MAX_OPTIMIZE) + optimizing.level = MAX_OPTIMIZE; } } break; @@ -1448,7 +1449,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr) /* Not a directive, or even something that starts with [ */ parse_line(pass1, line, &output_ins); - if (optimizing > 0) { + if (optimizing.level > 0) { if (forwref != NULL && globallineno == forwref->lineno) { output_ins.forw_ref = true; do { diff --git a/asm/parser.c b/asm/parser.c index 2643099..90e4337 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -1028,7 +1028,7 @@ is_expression: op->segment = NO_SEG; /* don't care again */ op->wrt = NO_SEG; /* still don't care */ - if(optimizing >= 0 && !(op->type & STRICT)) { + if(optimizing.level >= 0 && !(op->type & STRICT)) { /* Be optimistic */ op->type |= UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD; @@ -1045,7 +1045,7 @@ is_expression: if (is_simple(value)) { if (n == 1) op->type |= UNITY; - if (optimizing >= 0 && !(op->type & STRICT)) { + if (optimizing.level >= 0 && !(op->type & STRICT)) { if ((uint32_t) (n + 128) <= 255) op->type |= SBYTEDWORD; if ((uint16_t) (n + 128) <= 255) diff --git a/doc/opt_var.txt b/doc/opt_var.txt index 4482e5d..af15c03 100644 --- a/doc/opt_var.txt +++ b/doc/opt_var.txt @@ -6,7 +6,8 @@ GLOBAL variables: - optimizing -1 flags nasm 0.98 compatible operation; + optimizing optimization meta data (with level and flag info) + .level -1 flags nasm 0.98 compatible operation; offsets usually are explicit (short/near) no optimization passes 0 flags non-optimized assembly; forward @@ -17,7 +18,8 @@ GLOBAL variables: the actual recommended minimum setting optimization passes (2 or more, plus passes 1 and 2 will be required) - + .flag 0 allow all optimizations + 1 disallow jump match optimization pass0 0 flags an optimizer pass (multiple passes) 1 flags pass1 (define labels) diff --git a/include/nasm.h b/include/nasm.h index b9f730c..020e363 100644 --- a/include/nasm.h +++ b/include/nasm.h @@ -1248,11 +1248,25 @@ enum decorator_tokens { * 2 = pass 2 */ +/* + * flag to disable optimizations selectively + * this is useful to turn-off certain optimizations + */ +enum optimization_disable_flag { + OPTIM_ALL_ENABLED = 0, + OPTIM_DISABLE_JMP_MATCH = 1 +}; + +struct optimization { + int level; + int flag; +}; + extern int pass0; extern int64_t passn; /* Actual pass number */ extern bool tasm_compatible_mode; -extern int optimizing; +extern struct optimization optimizing; extern int globalbits; /* 16, 32 or 64-bit mode */ extern int globalrel; /* default to relative addressing? */ extern int globalbnd; /* default to using bnd prefix? */ |