mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-25 18:10:23 +08:00
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 <chang.seok.bae@intel.com>
This commit is contained in:
parent
ccd2d5c542
commit
a578634b61
@ -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;
|
||||
|
||||
/*
|
||||
|
21
asm/nasm.c
21
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 {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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? */
|
||||
|
Loading…
x
Reference in New Issue
Block a user