+ else if (token == T_COUNT8)
+ {
+ buffer_put_uninit (output, 1);
+
+ get_token ();
+ if (token != T_LPAREN)
+ fatal ("`(' expected after COUNT8");
+ get_token ();
+
+ while (token != T_RPAREN)
+ parse_data_item (output);
+ get_token ();
+
+ integer_put (output->size - old_size - 1, integer_format,
+ output->data + old_size, 1);
+ }
+ else if (token == T_HEX)
+ {
+ const char *p;
+
+ get_token ();
+
+ if (token != T_STRING)
+ fatal ("string expected");
+
+ for (p = tok_string; *p; p++)
+ {
+ if (isspace ((unsigned char) *p))
+ continue;
+ else if (isxdigit ((unsigned char) p[0])
+ && isxdigit ((unsigned char) p[1]))
+ {
+ int high = hexit_value (p[0]);
+ int low = hexit_value (p[1]);
+ uint8_t byte = high * 16 + low;
+ buffer_put (output, &byte, 1);
+ p++;
+ }
+ else
+ fatal ("invalid format in hex string");
+ }
+ get_token ();
+ }
+ else if (token == T_LABEL)
+ {
+ struct symbol *sym = symbol_find (tok_string);
+ if (sym->offset == UINT_MAX)
+ sym->offset = output->size;
+ else if (sym->offset != output->size)
+ fatal ("%s: can't redefine label for offset %u with offset %u",
+ tok_string, sym->offset, output->size);
+ get_token ();
+ return;
+ }
+ else if (token == T_AT)
+ {
+ unsigned int value = symbol_find (tok_string)->offset;
+ get_token ();
+
+ while (token == T_MINUS || token == T_PLUS)
+ {
+ enum token_type op = token;
+ unsigned int operand;
+ get_token ();
+ if (token == T_AT)
+ operand = symbol_find (tok_string)->offset;
+ else if (token == T_INTEGER)
+ operand = tok_integer;
+ else
+ fatal ("expecting @label");
+ get_token ();
+
+ if (op == T_PLUS)
+ value += operand;
+ else
+ value -= operand;
+ }
+ integer_put (value, integer_format, buffer_put_uninit (output, 4), 4);
+ }