+ if (*input_line_pointer != ':')
+ {
+ input_line_pointer = hold;
+ break;
+ }
+ if (exp.X_op == O_absent)
+ {
+ as_warn (_("using a bit field width of zero"));
+ exp.X_add_number = 0;
+ exp.X_op = O_constant;
+ }
+
+ if (exp.X_op != O_constant)
+ {
+ *input_line_pointer = '\0';
+ as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
+ *input_line_pointer = ':';
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if ((width = exp.X_add_number) >
+ (unsigned int)(BITS_PER_CHAR * nbytes))
+ {
+ as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"), width, nbytes, (BITS_PER_CHAR * nbytes));
+ width = BITS_PER_CHAR * nbytes;
+ } /* Too big. */
+
+
+ if (width > bits_available)
+ {
+ /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
+ input_line_pointer = hold;
+ exp.X_add_number = value;
+ break;
+ }
+
+ /* Skip ':'. */
+ hold = ++input_line_pointer;
+
+ expression (&exp);
+ if (exp.X_op != O_constant)
+ {
+ char cache = *input_line_pointer;
+
+ *input_line_pointer = '\0';
+ as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
+ *input_line_pointer = cache;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ value |= ((~(-1 << width) & exp.X_add_number)
+ << ((BITS_PER_CHAR * nbytes) - bits_available));
+
+ if ((bits_available -= width) == 0
+ || is_it_end_of_statement ()
+ || *input_line_pointer != ',')
+ break;
+
+ hold = ++input_line_pointer;
+ expression (&exp);
+ }
+
+ exp.X_add_number = value;
+ exp.X_op = O_constant;
+ exp.X_unsigned = 1;
+ }