]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
-O now, additionally to taking a number, can work like -W and -f to take an actual...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 10:05:58 +0000 (11:05 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 10:05:58 +0000 (11:05 +0100)
gmqcc.h
main.c
opts.def

diff --git a/gmqcc.h b/gmqcc.h
index 44095a0958185e025853d70c425a795ddcfca61e..459c2ff0cf83ff37bff2d55e902bd1cf3a73da2e 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -877,6 +877,25 @@ static const opts_flag_def opts_warn_list[] = {
     { NULL, LONGBIT(0) }
 };
 
+enum {
+# define GMQCC_TYPE_OPTIMIZATIONS
+# define GMQCC_DEFINE_FLAG(NAME, MIN_O) OPTIM_##NAME,
+#  include "opts.def"
+    COUNT_OPTIMIZATIONS
+};
+static const opts_flag_def opts_opt_list[] = {
+# define GMQCC_TYPE_OPTIMIZATIONS
+# define GMQCC_DEFINE_FLAG(NAME, MIN_O) { #NAME, LONGBIT(OPTIM_##NAME) },
+#  include "opts.def"
+    { NULL, LONGBIT(0) }
+};
+static const unsigned int opts_opt_oflag[] = {
+# define GMQCC_TYPE_OPTIMIZATIONS
+# define GMQCC_DEFINE_FLAG(NAME, MIN_O) MIN_O,
+#  include "opts.def"
+    0
+};
+
 /* other options: */
 enum {
     COMPILER_QCC,     /* circa  QuakeC */
@@ -902,5 +921,7 @@ extern size_t      opts_max_array_size;
 extern uint32_t opts_flags[1 + (COUNT_FLAGS / 32)];
 #define OPTS_WARN(i) (!! (opts_warn[(i)/32] & (1<< ((i)%32))))
 extern uint32_t opts_warn[1 + (COUNT_WARNINGS / 32)];
+#define OPTS_OPTIMIZATION(i) (!! (opts_optimization[(i)/32] & (1<< ((i)%32))))
+extern uint32_t opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)];
 
 #endif
diff --git a/main.c b/main.c
index b33b9591674f855541f46b60c1483059e244844f..205cf0486fab79e744707321d6e68bb2e673f2fd 100644 (file)
--- a/main.c
+++ b/main.c
@@ -25,6 +25,7 @@
 #include "lexer.h"
 
 uint32_t    opts_flags[1 + (COUNT_FLAGS / 32)];
+uint32_t    opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)];
 
 uint32_t    opts_O        = 1;
 const char *opts_output   = "progs.dat";
@@ -111,6 +112,9 @@ static bool options_setflag(const char *name, bool on) {
 static bool options_setwarn(const char *name, bool on) {
     return options_setflag_all(name, on, opts_warn, opts_warn_list, COUNT_WARNINGS);
 }
+static bool options_setoptim(const char *name, bool on) {
+    return options_setflag_all(name, on, opts_optimization, opts_opt_list, COUNT_OPTIMIZATIONS);
+}
 
 static bool options_witharg(int *argc_, char ***argv_, char **out) {
     int  argc   = *argc_;
@@ -178,6 +182,13 @@ static void options_set(uint32_t *flags, size_t idx, bool on)
 #endif
 }
 
+static void set_optimizations(unsigned int level)
+{
+    size_t i;
+    for (i = 0; i < COUNT_OPTIMIZATIONS; ++i)
+        options_set(opts_optimization, i, level >= opts_opt_oflag[i]);
+}
+
 static bool options_parse(int argc, char **argv) {
     bool argend = false;
     size_t itr;
@@ -352,10 +363,37 @@ static bool options_parse(int argc, char **argv) {
 
                 case 'O':
                     if (!options_witharg(&argc, &argv, &argarg)) {
-                        con_out("option -O requires a numerical argument\n");
+                        con_out("option -O requires a numerical argument, or optimization name with an optional 'no-' prefix\n");
                         return false;
                     }
-                    opts_O = atoi(argarg);
+                    if (isdigit(argarg[0])) {
+                        opts_O = atoi(argarg);
+                        set_optimizations(opts_O);
+                    } else {
+                        util_strtocmd(argarg, argarg, strlen(argarg)+1);
+                        if (!strcmp(argarg, "HELP")) {
+                            con_out("Possible optimizations:\n");
+                            for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) {
+                                util_strtononcmd(opts_opt_list[itr].name, buffer, sizeof(buffer));
+                                con_out(" -O%s\n", buffer);
+                            }
+                            exit(0);
+                        }
+                        else if (!strcmp(argarg, "ALL"))
+                            set_optimizations(opts_O = 9999);
+                        else if (!strncmp(argarg, "NO_", 3)) {
+                            if (!options_setoptim(argarg+3, false)) {
+                                con_out("unknown optimization: %s\n", argarg+3);
+                                return false;
+                            }
+                        }
+                        else {
+                            if (!options_setoptim(argarg, true)) {
+                                con_out("unknown optimization: %s\n", argarg);
+                                return false;
+                            }
+                        }
+                    }
                     break;
 
                 case 'o':
index 9779889df06ddf556ad8f8372fd4b5a100f4856e..62da391c4b46bd1d1659e611e0ba39ea261c431e 100644 (file)
--- a/opts.def
+++ b/opts.def
     GMQCC_DEFINE_FLAG(MULTIBYTE_CHARACTER)
 #endif
 
+#ifdef GMQCC_TYPE_OPTIMIZATIONS
+    GMQCC_DEFINE_FLAG(MINOR, 1)
+    GMQCC_DEFINE_FLAG(TAIL_RECURSION, 1)
+    GMQCC_DEFINE_FLAG(TAIL_CALLS,     2)
+#endif
+
 /* some cleanup so we don't have to */
 #undef GMQCC_TYPE_FLAGS
 #undef GMQCC_TYPE_WARNS