Line 255... |
Line 255... |
}
|
}
|
}
|
}
|
|
|
static int mask_or_shift = 0;
|
static int mask_or_shift = 0;
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/*!Parse an operand
|
|
|
|
We use some semantic information about the operand to determine its type.
|
|
|
|
@param[in] s Pointer to start of the operand string
|
|
@param[out] operandp The parsed operand expression
|
|
@param[in] opt Non-zero (TRUE) if this operand is optional, zero
|
|
(FALSE) otherwise.
|
|
@param[in] is_reg Non-zero (TRUE) if this operand is a register, zero
|
|
(FALSE) otherwise.
|
|
|
|
@return Pointer to the operand string immediately after the operand just
|
|
parsed. */
|
|
/*----------------------------------------------------------------------------*/
|
static char *
|
static char *
|
parse_operand (char *s, expressionS *operandp, int opt)
|
parse_operand (char *s,
|
|
expressionS *operandp,
|
|
int opt,
|
|
int is_reg)
|
{
|
{
|
char *save = input_line_pointer;
|
char *save = input_line_pointer;
|
char *new_pointer;
|
char *new_pointer;
|
|
|
#if DEBUG
|
#if DEBUG
|
printf (" PROCESS NEW OPERAND(%s) == %c (%d)\n", s, opt ? opt : '!', opt);
|
printf (" PROCESS NEW OPERAND(%s): %s, %s\n", s,
|
|
opt ? "optional" : "not optional",
|
|
is_reg ? "register", "not register");
|
#endif
|
#endif
|
|
|
input_line_pointer = s;
|
input_line_pointer = s;
|
|
|
if (strncasecmp (s, "HI(", 3) == 0)
|
if (strncasecmp (s, "HI(", 3) == 0)
|
Line 285... |
Line 305... |
mask_or_shift = 0;
|
mask_or_shift = 0;
|
|
|
if ((*s == '(') && (*(s+1) == 'r'))
|
if ((*s == '(') && (*(s+1) == 'r'))
|
s++;
|
s++;
|
|
|
|
/* JPB 18-Aug-10: The old assumption was that any symbol starting with 'r'
|
|
and followed by a digit was a register. That was fine when we prepended
|
|
underscores, but not when that was dropped. We need to makes sure that
|
|
this is a register operand. */
|
|
if (is_reg)
|
|
{
|
if ((*s == 'r') && ISDIGIT (*(s + 1)))
|
if ((*s == 'r') && ISDIGIT (*(s + 1)))
|
{
|
{
|
operandp->X_add_number = strtol (s + 1, NULL, 10);
|
operandp->X_add_number = strtol (s + 1, NULL, 10);
|
operandp->X_op = O_register;
|
operandp->X_op = O_register;
|
operandp->X_add_symbol = NULL;// Added to stop a know() in machine_ip()
|
operandp->X_add_symbol = NULL;// Added to stop know() in machine_ip()
|
operandp->X_op_symbol = NULL; // Added to stop a know() in machine_ip()
|
operandp->X_op_symbol = NULL; // Added to stop know() in machine_ip()
|
// erroring out - it appears this wasn't
|
// erroring out - it appears this
|
// getting cleared sometimes. - JB 100718
|
// wasn't getting cleared sometimes. -
|
|
// JB 100718
|
|
}
|
|
else
|
|
{
|
|
as_bad (_("register expected"));
|
|
}
|
|
|
|
/* Skip the argument */
|
for (; (*s != ',') && (*s != '\0');)
|
for (; (*s != ',') && (*s != '\0');)
|
s++;
|
s++;
|
input_line_pointer = save;
|
input_line_pointer = save;
|
return s;
|
return s;
|
}
|
}
|
Line 382... |
Line 416... |
if (insn->args[0] != '\0')
|
if (insn->args[0] != '\0')
|
/* Prime the pump. */
|
/* Prime the pump. */
|
s = parse_operand (s,
|
s = parse_operand (s,
|
&operand,
|
&operand,
|
(insn->args[0] == 'I') ||
|
(insn->args[0] == 'I') ||
|
(strcmp(insn->name, "l.nop") == 0) );
|
(strcmp(insn->name, "l.nop") == 0),
|
|
'r' == insn->args[0]);
|
|
|
for (args = insn->args;; ++args)
|
for (args = insn->args;; ++args)
|
{
|
{
|
#if DEBUG
|
#if DEBUG
|
printf (" args = %s\n", args);
|
printf (" args = %s\n", args);
|
Line 413... |
Line 448... |
if (*s++ == ',')
|
if (*s++ == ',')
|
{
|
{
|
reloc = BFD_RELOC_NONE;
|
reloc = BFD_RELOC_NONE;
|
|
|
/* Parse next operand. */
|
/* Parse next operand. */
|
s = parse_operand (s, &operand, args[1] == 'I');
|
s = parse_operand (s, &operand, args[1] == 'I', 'r' == args[1]);
|
#if DEBUG
|
#if DEBUG
|
printf (" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n",
|
printf (" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n",
|
(int) operand.X_add_number, args, s);
|
(int) operand.X_add_number, args, s);
|
#endif
|
#endif
|
continue;
|
continue;
|
}
|
}
|
break;
|
break;
|
|
|
case '(': /* Must match a (. */
|
case '(': /* Must match a (. */
|
s = parse_operand (s, &operand, args[1] == 'I');
|
s = parse_operand (s, &operand, args[1] == 'I', 'r' == args[1]);
|
continue;
|
continue;
|
|
|
case ')': /* Must match a ). */
|
case ')': /* Must match a ). */
|
continue;
|
continue;
|
|
|