+Wed Jan 6 08:19:11 1993 Fred Fish (fnf@cygnus.com)
+
+ * defs.h (HOST_CHAR_BIT): New macro, defaults to either CHAR_BIT
+ from a configuration file (typically including <limits.h>), or to
+ TARGET_CHAR_BIT if CHAR_BIT is not defined.
+ * eval.c (evaluate_subexp): Use new BYTES_TO_EXP_ELEM macro.
+ * eval.c (evaluate_subexp): Add case for OP_BITSTRING.
+ * expprint.c (print_subexp): Use new BYTES_TO_EXP_ELEM macro.
+ * exppritn.c (print_subexp, dump_expression): Add case for
+ OP_BITSTRING.
+ * expression.h (OP_BITSTRING): New expression element type for
+ packed bitstrings.
+ * expression.h (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): New
+ macros to convert between number of expression elements and bytes
+ to store that many elements.
+ * i960-tdep.c (leafproc_return): Use new macros to access
+ minimal symbol name and address fields.
+ * m88k-pinsn.c (sprint_address): Use new macros to access
+ minimal symbol name and address fields.
+ * nindy-tdep.c (nindy_frame_chain_valid): Use new macro to access
+ minimal symbol address field.
+ * parse.c (write_exp_elt, write_exp_string, prefixify_expression,
+ parse_exp_1): Use new EXP_ELEM_TO_BYTES macro.
+ * parse.c (write_exp_string, length_of_subexp, prefixify_expression):
+ Use new BYTES_TO_EXP_ELEM macro.
+ * parse.c (write_exp_bitstring): New function to write packed
+ bitstrings into the expression element vector.
+ * parse.c (length_of_subexp, prefixify_subexp): Add case for
+ OP_BITSTRING.
+ * parser-defs.h (struct stoken): Document that it is used for
+ OP_BITSTRING as well as OP_STRING.
+ * parser-defs.h (write_exp_bitstring): Add prototype.
+ **** start-sanitize-chill ****
+ * ch-exp.y (BIT_STRING_LITERAL): Change token type to sval.
+ * ch-exp.y (NUM, PRED, SUCC, ABS, CARD, MAX, MIN, SIZE, UPPER,
+ LOWER, LENGTH): New tokens for keywords.
+ * ch-exp.y (chill_value_built_in_routine_call, mode_argument,
+ upper_lower_argument, length_argument, array_mode_name,
+ string_mode_name, variant_structure_mode_name): New non-terminals
+ and productions.
+ * ch-exp.y (literal): Useful production for BIT_STRING_LITERAL.
+ * ch-exp.y (match_bitstring_literal): New lexer support function
+ to recognize bitstring literals.
+ * ch-exp.y (tokentab6): New token table for 6 character keywords.
+ * ch-exp.y (tokentab5): Add LOWER, UPPER.
+ * ch-exp.y (tokentab4): Add PRED, SUCC, CARD, SIZE.
+ * ch-exp.y (tokentab3): Add NUM, ABS, MIN, MAX.
+ * ch-exp.y (yylex): Check tokentab6.
+ * ch-exp.y (yylex): Call match_bitstring_literal.
+ **** end-sanitize-chill ****
+
Mon Jan 4 16:54:18 1993 Fred Fish (fnf@cygnus.com)
* xcoffexec.c (vmap_symtab): Use new macros to access minimal
%token <voidval> SET_LITERAL
%token <voidval> EMPTINESS_LITERAL
%token <voidval> CHARACTER_STRING_LITERAL
-%token <voidval> BIT_STRING_LITERAL
+%token <sval> BIT_STRING_LITERAL
%token <voidval> STRING
%token <voidval> CONSTANT
%token <voidval> FI
%token <voidval> ELSIF
%token <voidval> ILLEGAL_TOKEN
+%token <voidval> NUM
+%token <voidval> PRED
+%token <voidval> SUCC
+%token <voidval> ABS
+%token <voidval> CARD
+%token <voidval> MAX
+%token <voidval> MIN
+%token <voidval> SIZE
+%token <voidval> UPPER
+%token <voidval> LOWER
+%token <voidval> LENGTH
/* Tokens which are not Chill tokens used in expressions, but rather GDB
specific things that we recognize in the same context as Chill tokens
%type <voidval> expression_conversion
%type <voidval> value_procedure_call
%type <voidval> value_built_in_routine_call
+%type <voidval> chill_value_built_in_routine_call
%type <voidval> start_expression
%type <voidval> zero_adic_operator
%type <voidval> parenthesised_expression
%type <voidval> first_element
%type <voidval> structure_primitive_value
%type <voidval> field_name
+%type <voidval> mode_argument
+%type <voidval> upper_lower_argument
+%type <voidval> length_argument
%type <voidval> mode_name
+%type <voidval> array_mode_name
+%type <voidval> string_mode_name
+%type <voidval> variant_structure_mode_name
%type <voidval> boolean_expression
%type <voidval> case_selector_list
%type <voidval> subexpression
}
| BIT_STRING_LITERAL
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (OP_BITSTRING);
+ write_exp_bitstring ($1);
+ write_exp_elt_opcode (OP_BITSTRING);
}
;
/* Z.200, 5.2.13 */
-value_built_in_routine_call: FIXME
+value_built_in_routine_call: chill_value_built_in_routine_call
{
$$ = 0; /* FIXME */
}
/* Z.200, 6.2 */
-single_assignment_action : location GDB_ASSIGNMENT value
+single_assignment_action :
+ location GDB_ASSIGNMENT value
{
write_exp_elt_opcode (BINOP_ASSIGN);
}
+ ;
+
+/* Z.200, 6.20.3 */
+
+chill_value_built_in_routine_call :
+ NUM '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | PRED '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | SUCC '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | ABS '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | CARD '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | MAX '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | MIN '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | SIZE '(' location ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | SIZE '(' mode_argument ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | UPPER '(' upper_lower_argument ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | LOWER '(' upper_lower_argument ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | LENGTH '(' length_argument ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ ;
+
+mode_argument : mode_name
+ {
+ $$ = 0; /* FIXME */
+ }
+ | array_mode_name '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | string_mode_name '(' expression ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ | variant_structure_mode_name '(' expression_list ')'
+ {
+ $$ = 0; /* FIXME */
+ }
+ ;
+
+upper_lower_argument : location
+ {
+ $$ = 0; /* FIXME */
+ }
+ | expression
+ {
+ $$ = 0; /* FIXME */
+ }
+ | mode_name
+ {
+ $$ = 0; /* FIXME */
+ }
+ ;
+
+length_argument : location
+ {
+ $$ = 0; /* FIXME */
+ }
+ | expression
+ {
+ $$ = 0; /* FIXME */
+ }
+ ;
/* Z.200, 12.4.3 */
/* FIXME: For now we just accept only a single integer literal. */
{
$$ = 0;
}
+ ;
/* Z.200, 12.4.3 */
{
$$ = 0;
}
+ ;
/* Things which still need productions... */
+array_mode_name : FIXME { $$ = 0; }
+string_mode_name : FIXME { $$ = 0; }
+variant_structure_mode_name: FIXME { $$ = 0; }
synonym_name : FIXME { $$ = 0; }
value_enumeration_name : FIXME { $$ = 0; }
value_do_with_name : FIXME { $$ = 0; }
}
}
+/* Recognize a bit-string literal, as specified in Z.200 sec 5.2.4.8
+ Note that according to 5.2.4.8, a single "_" is also a valid bit-string
+ literal, however GNU-chill requires there to be at least one "digit"
+ in any bit-string literal. */
+
+static int
+match_bitstring_literal ()
+{
+ char *tokptr = lexptr;
+ int mask;
+ int bitoffset = 0;
+ int bitcount = 0;
+ int base;
+ int digit;
+ static char *tempbuf;
+ static int tempbufsize;
+ static int tempbufindex;
+
+ /* Look for the required explicit base specifier. */
+
+ switch (*tokptr++)
+ {
+ case 'b':
+ case 'B':
+ base = 2;
+ break;
+ case 'o':
+ case 'O':
+ base = 8;
+ break;
+ case 'h':
+ case 'H':
+ base = 16;
+ break;
+ default:
+ return (0);
+ break;
+ }
+
+ /* Ensure that the character after the explicit base is a single quote. */
+
+ if (*tokptr++ != '\'')
+ {
+ return (0);
+ }
+
+ while (*tokptr != '\0' && *tokptr != '\'')
+ {
+ digit = tolower (*tokptr);
+ tokptr++;
+ switch (digit)
+ {
+ case '_':
+ continue;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ digit -= '0';
+ break;
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ digit -= 'a';
+ digit += 10;
+ break;
+ default:
+ return (0);
+ break;
+ }
+ if (digit >= base)
+ {
+ /* Found something not in domain for current base. */
+ return (0);
+ }
+ else
+ {
+ /* Extract bits from digit, starting with the msbit appropriate for
+ the current base, and packing them into the bitstring byte,
+ starting at the lsbit. */
+ for (mask = (base >> 1); mask > 0; mask >>= 1)
+ {
+ bitcount++;
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex >= tempbufsize)
+ {
+ tempbufsize += 64;
+ if (tempbuf == NULL)
+ {
+ tempbuf = (char *) malloc (tempbufsize);
+ }
+ else
+ {
+ tempbuf = (char *) realloc (tempbuf, tempbufsize);
+ }
+ }
+ if (digit & mask)
+ {
+ tempbuf[tempbufindex] |= (1 << bitoffset);
+ }
+ bitoffset++;
+ if (bitoffset == HOST_CHAR_BIT)
+ {
+ bitoffset = 0;
+ tempbufindex++;
+ }
+ }
+ }
+ }
+
+ /* Verify that we consumed everything up to the trailing single quote,
+ and that we found some bits (IE not just underbars). */
+
+ if (*tokptr++ != '\'')
+ {
+ return (0);
+ }
+ else
+ {
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = bitcount;
+ lexptr = tokptr;
+ return (BIT_STRING_LITERAL);
+ }
+}
+
/* Recognize tokens that start with '$'. These include:
$regname A native register name or a "standard
int token;
};
+static const struct token tokentab6[] =
+{
+ { "LENGTH", LENGTH }
+};
+
static const struct token tokentab5[] =
{
+ { "LOWER", LOWER },
+ { "UPPER", UPPER },
{ "ANDIF", ANDIF }
};
static const struct token tokentab4[] =
{
+ { "PRED", PRED },
+ { "SUCC", SUCC },
+ { "CARD", CARD },
+ { "SIZE", SIZE },
{ "ORIF", ORIF }
};
static const struct token tokentab3[] =
{
+ { "NUM", NUM },
+ { "ABS", ABS },
+ { "MAX", MAX },
+ { "MIN", MIN },
{ "MOD", MOD },
{ "REM", REM },
{ "NOT", NOT },
}
break;
}
+ /* See if it is a special token of length 6. */
+ for (i = 0; i < sizeof (tokentab6) / sizeof (tokentab6[0]); i++)
+ {
+ if (STREQN (lexptr, tokentab6[i].operator, 6))
+ {
+ lexptr += 6;
+ return (tokentab6[i].token);
+ }
+ }
/* See if it is a special token of length 5. */
for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++)
{
/* Look for a float literal before looking for an integer literal, so
we match as much of the input stream as possible. */
token = match_float_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+ token = match_bitstring_literal ();
if (token != 0)
{
return (token);
if ((msymbol = lookup_minimal_symbol_by_pc (ip)) != NULL)
{
- if ((p = index (msymbol -> name, '.')) && STREQ (p, ".lf"))
+ if ((p = index (SYMBOL_NAME (msymbol), '.')) && STREQ (p, ".lf"))
{
- if (next_insn (msymbol -> address, &insn1, &insn2)
+ if (next_insn (SYMBOL_VALUE_ADDRESS (msymbol), &insn1, &insn2)
&& (insn1 & 0xff87ffff) == 0x5c80161e /* mov g14, gx */
&& (dst = REG_SRCDST (insn1)) <= G0_REGNUM + 7)
{
the return address from g14; otherwise, read it
from the register into which g14 was moved. */
- return_addr = read_register ((ip == msymbol->address)
+ return_addr =
+ read_register ((ip == SYMBOL_VALUE_ADDRESS (msymbol))
? G14_REGNUM : dst);
/* We know we are in a leaf procedure, but we don't know
if (msymbol == NULL) return; /* If nothing comes through, don't
print anything symbolic */
- name = msymbol -> name;
- name_location = msymbol -> address;
+ name = SYMBOL_NAME (msymbol);
+ name_location = SYMBOL_VALUE_ADDRESS (msymbol);
} else {
name = fs->name;
name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (fs));
msymbol = lookup_minimal_symbol (sf, (struct objfile *) NULL);
if (msymbol == NULL)
return 0;
- a = msymbol -> address;
+ a = SYMBOL_VALUE_ADDRESS (msymbol);
}
return ( chain != read_memory_integer(a,4) );
if (expout_ptr >= expout_size)
{
expout_size *= 2;
- expout = (struct expression *) xrealloc ((char *) expout,
- sizeof (struct expression)
- + expout_size * sizeof (union exp_element));
+ expout = (struct expression *)
+ xrealloc ((char *) expout, sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size));
}
expout->elts[expout_ptr++] = expelt;
}
at each end to record the actual string length (not including the
null byte terminator). */
- lenelt = 2 + (len + sizeof (union exp_element)) / sizeof (union exp_element);
+ lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);
/* Ensure that we have enough available expression elements to store
everything. */
expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
expout = (struct expression *)
xrealloc ((char *) expout, (sizeof (struct expression)
- + (expout_size * sizeof (union exp_element))));
+ + EXP_ELEM_TO_BYTES (expout_size)));
}
/* Write the leading length expression element (which advances the current
expout_ptr += lenelt - 2;
write_exp_elt_longcst ((LONGEST) len);
}
+
+/* Add a bitstring constant to the end of the expression.
+
+ Bitstring constants are stored by first writing an expression element
+ that contains the length of the bitstring (in bits), then stuffing the
+ bitstring constant itself into however many expression elements are
+ needed to hold it, and then writing another expression element that
+ contains the length of the bitstring. I.E. an expression element at
+ each end of the bitstring records the bitstring length, so you can skip
+ over the expression elements containing the actual bitstring bytes from
+ either end of the bitstring. */
+
+void
+write_exp_bitstring (str)
+ struct stoken str;
+{
+ register int bits = str.length; /* length in bits */
+ register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ register int lenelt;
+ register char *strdata;
+
+ /* Compute the number of expression elements required to hold the bitstring,
+ along with one expression element at each end to record the actual
+ bitstring length in bits. */
+
+ lenelt = 2 + BYTES_TO_EXP_ELEM (len);
+
+ /* Ensure that we have enough available expression elements to store
+ everything. */
+
+ if ((expout_ptr + lenelt) >= expout_size)
+ {
+ expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
+ expout = (struct expression *)
+ xrealloc ((char *) expout, (sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size)));
+ }
+
+ /* Write the leading length expression element (which advances the current
+ expression element index), then write the bitstring constant, and then
+ write the trailing length expression element. */
+
+ write_exp_elt_longcst ((LONGEST) bits);
+ strdata = (char *) &expout->elts[expout_ptr];
+ memcpy (strdata, str.ptr, len);
+ expout_ptr += lenelt - 2;
+ write_exp_elt_longcst ((LONGEST) bits);
+}
\f
/* Return a null-terminated temporary copy of the name
of a string token. */
prefixify_expression (expr)
register struct expression *expr;
{
- register int len = sizeof (struct expression) +
- expr->nelts * sizeof (union exp_element);
+ register int len =
+ sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
register struct expression *temp;
register int inpos = expr->nelts, outpos = 0;
{
/* C++ */
case OP_SCOPE:
- oplen = 5 + ((longest_to_int (expr->elts[endpos - 2].longconst)
- + sizeof (union exp_element))
- / sizeof (union exp_element));
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
break;
case OP_LONG:
/* fall through */
case OP_M2_STRING:
case OP_STRING:
- oplen = 4 + ((longest_to_int (expr->elts[endpos - 2].longconst)
- + sizeof (union exp_element))
- / sizeof (union exp_element));
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+ break;
+
+ case OP_BITSTRING:
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
break;
case TERNOP_COND:
{
/* C++ */
case OP_SCOPE:
- oplen = 5 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
- + sizeof (union exp_element))
- / sizeof (union exp_element));
+ oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+ oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
break;
case OP_LONG:
/* fall through */
case OP_M2_STRING:
case OP_STRING:
- oplen = 4 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
- + sizeof (union exp_element))
- / sizeof (union exp_element));
+ oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+ break;
+
+ case OP_BITSTRING:
+ oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+ oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
break;
case TERNOP_COND:
to the beginning of the output. */
inend -= oplen;
memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend],
- oplen * sizeof (union exp_element));
+ EXP_ELEM_TO_BYTES (oplen));
outbeg += oplen;
/* Find the lengths of the arg subexpressions. */
expout_size = 10;
expout_ptr = 0;
expout = (struct expression *)
- xmalloc (sizeof (struct expression)
- + expout_size * sizeof (union exp_element));
+ xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
expout->language_defn = current_language;
make_cleanup (free_current_contents, &expout);
expout->nelts = expout_ptr;
expout = (struct expression *)
xrealloc ((char *) expout,
- sizeof (struct expression)
- + expout_ptr * sizeof (union exp_element));
+ sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr));;
/* Convert expression from postfix form as generated by yacc
parser, to a prefix form. */
struct funcall *funcall_chain;
-/* This kind of datum is used to represent the name
- of a symbol token. */
+/* A string token, either a char-string or bit-string. Char-strings are
+ used, for example, for the names of symbols. */
struct stoken
{
+ /* Pointer to first byte of char-string or first bit of bit-string */
char *ptr;
+ /* Length of string in bytes for char-string or bits for bit-string */
int length;
};
extern void
write_exp_string PARAMS ((struct stoken));
+extern void
+write_exp_bitstring PARAMS ((struct stoken));
+
extern void
start_arglist PARAMS ((void));