From 99114bbfa1de1c286fffef4b0dff20a360066e2a Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hongjiu.lu@intel.com>
Date: Thu, 18 Aug 2011 14:52:06 +0000
Subject: [PATCH] Allow HOST_WIDE_INT for option variable.

2011-08-18  H.J. Lu  <hongjiu.lu@intel.com>
	    Igor Zamyatin <igor.zamyatin@intel.com>

	* hwint.h (HOST_WIDE_INT_1): New.

	* opt-functions.awk (switch_bit_fields): Initialize the
	host_wide_int field.
	(host_wide_int_var_name): New.
	(var_type_struct): Check and return HOST_WIDE_INT.

	* opt-read.awk: Handle HOST_WIDE_INT for "Variable".

	* optc-save-gen.awk: Support HOST_WIDE_INT on var_target_other.

	* opth-gen.awk: Use HOST_WIDE_INT_1 on HOST_WIDE_INT.  Properly
	check masks for HOST_WIDE_INT.

	* opts-common.c (set_option): Support HOST_WIDE_INT flag_var.
	(option_enabled): Likewise.
	(get_option_state): Likewise.

	* opts.h (cl_option): Add cl_host_wide_int.  Change var_value
	to HOST_WIDE_INT.

Co-Authored-By: Igor Zamyatin <igor.zamyatin@intel.com>

From-SVN: r177864
---
 gcc/ChangeLog         | 24 ++++++++++++++++++++
 gcc/hwint.h           |  2 ++
 gcc/opt-functions.awk | 25 +++++++++++++++++++--
 gcc/opt-read.awk      |  3 +++
 gcc/optc-save-gen.awk | 10 +++++++--
 gcc/opth-gen.awk      | 12 ++++++++--
 gcc/opts-common.c     | 51 ++++++++++++++++++++++++++++++++++---------
 gcc/opts.h            |  4 +++-
 8 files changed, 114 insertions(+), 17 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f07787cf912..dabaf4eda27d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2011-08-18  H.J. Lu  <hongjiu.lu@intel.com>
+	    Igor Zamyatin <igor.zamyatin@intel.com>
+
+	* hwint.h (HOST_WIDE_INT_1): New.
+
+	* opt-functions.awk (switch_bit_fields): Initialize the
+	host_wide_int field.
+	(host_wide_int_var_name): New.
+	(var_type_struct): Check and return HOST_WIDE_INT.
+
+	* opt-read.awk: Handle HOST_WIDE_INT for "Variable".
+
+	* optc-save-gen.awk: Support HOST_WIDE_INT on var_target_other.
+
+	* opth-gen.awk: Use HOST_WIDE_INT_1 on HOST_WIDE_INT.  Properly
+	check masks for HOST_WIDE_INT.
+
+	* opts-common.c (set_option): Support HOST_WIDE_INT flag_var.
+	(option_enabled): Likewise.
+	(get_option_state): Likewise.
+
+	* opts.h (cl_option): Add cl_host_wide_int.  Change var_value
+	to HOST_WIDE_INT.
+
 2011-08-18  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 	    Marc Glisse  <marc.glisse@normalesup.org>
 
diff --git a/gcc/hwint.h b/gcc/hwint.h
index c8b3c31bfb75..2643aee3e016 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -79,6 +79,7 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
 # define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
 # define HOST_WIDE_INT_PRINT_C "L"
+# define HOST_WIDE_INT_1 1L
   /* 'long' might be 32 or 64 bits, and the number of leading zeroes
      must be tweaked accordingly.  */
 # if HOST_BITS_PER_WIDE_INT == 64
@@ -91,6 +92,7 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
 #else
 # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
 # define HOST_WIDE_INT_PRINT_C "LL"
+# define HOST_WIDE_INT_1 1LL
   /* We can assume that 'long long' is at least 64 bits.  */
 # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
     "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
index 945eeb15418c..1f582fb4a165 100644
--- a/gcc/opt-functions.awk
+++ b/gcc/opt-functions.awk
@@ -110,6 +110,11 @@ function switch_flags (flags)
 # Return bit-field initializers for option flags FLAGS.
 function switch_bit_fields (flags)
 {
+	vn = var_name(flags);
+	if (host_wide_int[vn] == "yes")
+		hwi = "Host_Wide_Int"
+	else
+		hwi = ""
 	result = ""
 	sep_args = opt_args("Args", flags)
 	if (sep_args == "")
@@ -126,6 +131,7 @@ function switch_bit_fields (flags)
 	  flag_init("RejectNegative", flags) \
 	  flag_init("JoinedOrMissing", flags) \
 	  flag_init("UInteger", flags) \
+	  flag_init("Host_Wide_Int", hwi) \
 	  flag_init("ToLower", flags) \
 	  flag_init("Report", flags)
 
@@ -140,6 +146,17 @@ function var_name(flags)
 	return nth_arg(0, opt_args("Var", flags))
 }
 
+# Return the name of the variable if FLAGS has a HOST_WIDE_INT variable. 
+# Return the empty string otherwise.
+function host_wide_int_var_name(flags)
+{
+	split (flags, array, "[ \t]+")
+	if (array[1] == "HOST_WIDE_INT")
+		return array[2]
+	else
+		return ""
+}
+
 # Return true if the option described by FLAGS has a globally-visible state.
 function global_state_p(flags)
 {
@@ -197,8 +214,12 @@ function var_type_struct(flags)
 		return enum_type[en] " "
 	}
 	else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) {
-		if (flag_set_p(".*Mask.*", flags))
-			return "int "
+		if (flag_set_p(".*Mask.*", flags)) {
+			if (host_wide_int[var_name(flags)] == "yes")
+				return "HOST_WIDE_INT "
+			else
+				return "int "
+		}
 		else
 			return "signed char "
 	}
diff --git a/gcc/opt-read.awk b/gcc/opt-read.awk
index c488ed5cde53..6a4d4de0eb42 100644
--- a/gcc/opt-read.awk
+++ b/gcc/opt-read.awk
@@ -51,6 +51,9 @@ BEGIN {
 		else if ($1 == "Variable") {
 			extra_vars[n_extra_vars] = $2
 			n_extra_vars++
+			name = host_wide_int_var_name($2)
+			if (name != "")
+				host_wide_int[name] = "yes"
 		}
 		else if ($1 == "TargetVariable") {
 			# Combination of TargetSave and Variable
diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk
index 4efc11598bfe..654d86926024 100644
--- a/gcc/optc-save-gen.awk
+++ b/gcc/optc-save-gen.awk
@@ -363,10 +363,16 @@ print "{";
 print "  fputs (\"\\n\", file);";
 for (i = 0; i < n_target_other; i++) {
 	print "  if (ptr->x_" var_target_other[i] ")";
-	print "    fprintf (file, \"%*s%s (%#lx)\\n\",";
+	if (host_wide_int[var_target_other[i]] == "yes")
+		print "    fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
+	else
+		print "    fprintf (file, \"%*s%s (%#x)\\n\",";
 	print "             indent, \"\",";
 	print "             \"" var_target_other[i] "\",";
-	print "             (unsigned long)ptr->x_" var_target_other[i] ");";
+	if (host_wide_int[var_target_other[i]] == "yes")
+		print "             ptr->x_" var_target_other[i] ");";
+	else
+		print "             (unsigned long)ptr->x_" var_target_other[i] ");";
 	print "";
 }
 
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index 876e0f6336e6..2bae69533993 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -300,18 +300,26 @@ for (i = 0; i < n_opts; i++) {
 	name = opt_args("Mask", flags[i])
 	vname = var_name(flags[i])
 	mask = "MASK_"
+	mask_1 = "1"
 	if (vname != "") {
 		mask = "OPTION_MASK_"
+		if (host_wide_int[vname] == "yes")
+			mask_1 = "HOST_WIDE_INT_1"
 	}
 	if (name != "" && !flag_set_p("MaskExists", flags[i]))
-		print "#define " mask name " (1 << " masknum[vname]++ ")"
+		print "#define " mask name " (" mask_1 " << " masknum[vname]++ ")"
 }
 for (i = 0; i < n_extra_masks; i++) {
 	print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")"
 }
 
 for (var in masknum) {
-	if (masknum[var] > 31) {
+	if (var != "" && host_wide_int[var] == "yes") {
+		print" #if defined(HOST_BITS_PER_WIDE_INT) && " masknum[var] " >= HOST_BITS_PER_WIDE_INT"
+		print "#error too many masks for " var
+		print "#endif"
+	}
+	else if (masknum[var] > 31) {
 		if (var == "")
 			print "#error too many target masks"
 		else
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 973dd7e97e7e..0b86764cd79d 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -1088,9 +1088,14 @@ set_option (struct gcc_options *opts, struct gcc_options *opts_set,
 	break;
 
     case CLVC_EQUAL:
-	*(int *) flag_var = (value
-			     ? option->var_value
-			     : !option->var_value);
+	if (option->cl_host_wide_int) 
+	  *(HOST_WIDE_INT *) flag_var = (value
+					 ? option->var_value
+					 : !option->var_value);
+	else
+	  *(int *) flag_var = (value
+			       ? option->var_value
+			       : !option->var_value);
 	if (set_flag_var)
 	  *(int *) set_flag_var = 1;
 	break;
@@ -1098,11 +1103,26 @@ set_option (struct gcc_options *opts, struct gcc_options *opts_set,
     case CLVC_BIT_CLEAR:
     case CLVC_BIT_SET:
 	if ((value != 0) == (option->var_type == CLVC_BIT_SET))
-	  *(int *) flag_var |= option->var_value;
+	  {
+	    if (option->cl_host_wide_int) 
+	      *(HOST_WIDE_INT *) flag_var |= option->var_value;
+	    else 
+	      *(int *) flag_var |= option->var_value;
+	  }
 	else
-	  *(int *) flag_var &= ~option->var_value;
+	  {
+	    if (option->cl_host_wide_int) 
+	      *(HOST_WIDE_INT *) flag_var &= ~option->var_value;
+	    else 
+	      *(int *) flag_var &= ~option->var_value;
+	  }
 	if (set_flag_var)
-	  *(int *) set_flag_var |= option->var_value;
+	  {
+	    if (option->cl_host_wide_int) 
+	      *(HOST_WIDE_INT *) set_flag_var |= option->var_value;
+	    else
+	      *(int *) set_flag_var |= option->var_value;
+	  }
 	break;
 
     case CLVC_STRING:
@@ -1173,13 +1193,22 @@ option_enabled (int opt_idx, void *opts)
 	return *(int *) flag_var != 0;
 
       case CLVC_EQUAL:
-	return *(int *) flag_var == option->var_value;
+	if (option->cl_host_wide_int) 
+	  return *(HOST_WIDE_INT *) flag_var == option->var_value;
+	else
+	  return *(int *) flag_var == option->var_value;
 
       case CLVC_BIT_CLEAR:
-	return (*(int *) flag_var & option->var_value) == 0;
+	if (option->cl_host_wide_int) 
+	  return (*(HOST_WIDE_INT *) flag_var & option->var_value) == 0;
+	else
+	  return (*(int *) flag_var & option->var_value) == 0;
 
       case CLVC_BIT_SET:
-	return (*(int *) flag_var & option->var_value) != 0;
+	if (option->cl_host_wide_int) 
+	  return (*(HOST_WIDE_INT *) flag_var & option->var_value) != 0;
+	else 
+	  return (*(int *) flag_var & option->var_value) != 0;
 
       case CLVC_STRING:
       case CLVC_ENUM:
@@ -1206,7 +1235,9 @@ get_option_state (struct gcc_options *opts, int option,
     case CLVC_BOOLEAN:
     case CLVC_EQUAL:
       state->data = flag_var;
-      state->size = sizeof (int);
+      state->size = (cl_options[option].cl_host_wide_int
+		     ? sizeof (HOST_WIDE_INT)
+		     : sizeof (int));
       break;
 
     case CLVC_BIT_CLEAR:
diff --git a/gcc/opts.h b/gcc/opts.h
index b070c8fd6ac6..3c0fe3f8cb7e 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -96,6 +96,8 @@ struct cl_option
   BOOL_BITFIELD cl_missing_ok : 1;
   /* Argument is an integer >=0.  */
   BOOL_BITFIELD cl_uinteger : 1;
+  /* Argument is a HOST_WIDE_INT.  */
+  BOOL_BITFIELD cl_host_wide_int : 1;
   /* Argument should be converted to lowercase.  */
   BOOL_BITFIELD cl_tolower : 1;
   /* Report argument with -fverbose-asm  */
@@ -109,7 +111,7 @@ struct cl_option
   /* How this option's value is determined and sets a field.  */
   enum cl_var_type var_type;
   /* Value or bit-mask with which to set a field.  */
-  int var_value;
+  HOST_WIDE_INT var_value;
 };
 
 /* Records that the state of an option consists of SIZE bytes starting
-- 
GitLab