summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-10-10 14:06:59 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-10-10 14:06:59 -0700
commitfd7dd1134501551409c4d7a07a15dddc32abbfef (patch)
tree573494cd4812989c7d5c81af6c21dc705580ed46
parentf57f55c9cb5e6f124b4eb7c7320b0d4bd28684b4 (diff)
downloadnasm-fd7dd1134501551409c4d7a07a15dddc32abbfef.tar.gz
Create option -Ox to tell NASM to do unlimited passes
Add option -Ox to tell NASM to do as many passes as it needs, instead of imposing a fixed number.
-rw-r--r--doc/nasmdoc.src3
-rw-r--r--nasm.c72
2 files changed, 46 insertions, 29 deletions
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index 73ccbf8f..f6616ebe 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -761,6 +761,9 @@ The syntax is:
The number specifies the maximum number of passes. The more
passes, the better the code, but the slower is the assembly.
+\b \c{-Ox} where \c{x} is the actual letter \c{x}, indicates to NASM
+ to do unlimited passes.
+
Note that this is a capital O, and is different from a small o, which
is used to specify the output format. See \k{opt-o}.
diff --git a/nasm.c b/nasm.c
index 12b51af2..86ac2d1d 100644
--- a/nasm.c
+++ b/nasm.c
@@ -14,6 +14,7 @@
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
+#include <limits.h>
#include "nasm.h"
#include "nasmlib.h"
@@ -405,35 +406,48 @@ static int process_arg(char *p, char *q)
ofmt->current_dfmt = ofmt->debug_formats[0];
} else if (p[1] == 'O') { /* Optimization level */
int opt;
- opt = -99;
- while (*param) {
- if (isdigit(*param)) {
- opt = atoi(param);
- while (isdigit(*++param)) ;
- if (opt <= 0)
- optimizing = -1; /* 0.98 behaviour */
- else if (opt == 1)
- optimizing = 0; /* Two passes, 0.98.09 behavior */
- else if (opt <= 5)
- /* The optimizer seems to have problems with
- < 5 passes? Hidden bug? */
- optimizing = 5; /* 5 passes */
- else
- optimizing = opt; /* More than 5 passes */
- } else {
- if (*param == 'v' || *param == '+') {
- ++param;
- opt_verbose_info = TRUE;
- opt = 0;
- } else { /* garbage */
- opt = -99;
- break;
- }
- }
- } /* while (*param) */
- if (opt == -99)
- report_error(ERR_FATAL,
- "command line optimization level must be 'v', 0..3 or <nn>");
+
+ if (!*param) {
+ /* Naked -O == -Ox */
+ optimizing = INT_MAX >> 1; /* Almost unlimited */
+ } else {
+ while (*param) {
+ switch (*param) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ opt = strtoul(param, &param, 10);
+
+ /* -O0 -> optimizing == -1, 0.98 behaviour */
+ /* -O1 -> optimizing == 0, 0.98.09 behaviour */
+ if (opt < 2)
+ optimizing = opt - 1;
+ else if (opt <= 5)
+ /* The optimizer seems to have problems with
+ < 5 passes? Hidden bug? */
+ optimizing = 5; /* 5 passes */
+ else
+ optimizing = opt; /* More than 5 passes */
+ break;
+
+ case 'v':
+ case '+':
+ param++;
+ opt_verbose_info = TRUE;
+ break;
+
+ case 'x':
+ param++;
+ optimizing = INT_MAX >> 1; /* Almost unlimited */
+ break;
+
+ default:
+ report_error(ERR_FATAL,
+ "unknown optimization option -O%c\n",
+ *param);
+ break;
+ }
+ }
+ }
} else if (p[1] == 'P' || p[1] == 'p') { /* pre-include */
pp_pre_include(param);
} else if (p[1] == 'D' || p[1] == 'd') { /* pre-define */