* config/tc-mips.c (S_EX_*): New enum for my_getSmallExpression()
return values. (mips_ip): Use the new return values instead of characters. Add support for %higher and %highest. (LP): Remove. (RP): Remove. (my_getSmallExpression): Make parsing case insensitive and more reliable. Add support for %higher and %highest. Further support to parse %gprel and %neg is implemented but currently deactivated.
This commit is contained in:
parent
fab80407fe
commit
fb1b323293
|
@ -1,3 +1,15 @@
|
||||||
|
2001-08-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||||
|
|
||||||
|
* config/tc-mips.c (S_EX_*): New enum for my_getSmallExpression()
|
||||||
|
return values.
|
||||||
|
(mips_ip): Use the new return values instead of characters. Add
|
||||||
|
support for %higher and %highest.
|
||||||
|
(LP): Remove.
|
||||||
|
(RP): Remove.
|
||||||
|
(my_getSmallExpression): Make parsing case insensitive and more
|
||||||
|
reliable. Add support for %higher and %highest. Further support to
|
||||||
|
parse %gprel and %neg is implemented but currently deactivated.
|
||||||
|
|
||||||
2001-08-17 Alan Modra <amodra@bigpond.net.au>
|
2001-08-17 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* ecoff.c (ecoff_frob_symbol): Remove casts from bfd_get_gp_size.
|
* ecoff.c (ecoff_frob_symbol): Remove casts from bfd_get_gp_size.
|
||||||
|
|
|
@ -728,6 +728,19 @@ static const char *mips_isa_to_str PARAMS ((int));
|
||||||
static const char *mips_cpu_to_str PARAMS ((int));
|
static const char *mips_cpu_to_str PARAMS ((int));
|
||||||
static int validate_mips_insn PARAMS ((const struct mips_opcode *));
|
static int validate_mips_insn PARAMS ((const struct mips_opcode *));
|
||||||
|
|
||||||
|
/* Return values of my_getSmallExpression() */
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
S_EX_NONE = 0,
|
||||||
|
S_EX_LO,
|
||||||
|
S_EX_HI,
|
||||||
|
S_EX_HIGHER,
|
||||||
|
S_EX_HIGHEST,
|
||||||
|
S_EX_GPREL,
|
||||||
|
S_EX_NEG
|
||||||
|
};
|
||||||
|
|
||||||
/* Table and functions used to map between CPU/ISA names, and
|
/* Table and functions used to map between CPU/ISA names, and
|
||||||
ISA levels, and CPU numbers. */
|
ISA levels, and CPU numbers. */
|
||||||
|
|
||||||
|
@ -7655,14 +7668,18 @@ mips_ip (str, ip)
|
||||||
case 'j': /* 16 bit signed immediate */
|
case 'j': /* 16 bit signed immediate */
|
||||||
imm_reloc = BFD_RELOC_LO16;
|
imm_reloc = BFD_RELOC_LO16;
|
||||||
c = my_getSmallExpression (&imm_expr, s);
|
c = my_getSmallExpression (&imm_expr, s);
|
||||||
if (c != '\0')
|
if (c != S_EX_NONE)
|
||||||
{
|
{
|
||||||
if (c != 'l')
|
if (c != S_EX_LO)
|
||||||
{
|
{
|
||||||
if (imm_expr.X_op == O_constant)
|
if (imm_expr.X_op == O_constant)
|
||||||
imm_expr.X_add_number =
|
imm_expr.X_add_number =
|
||||||
(imm_expr.X_add_number >> 16) & 0xffff;
|
(imm_expr.X_add_number >> 16) & 0xffff;
|
||||||
else if (c == 'h')
|
else if (c == S_EX_HIGHEST)
|
||||||
|
imm_reloc = BFD_RELOC_MIPS_HIGHEST;
|
||||||
|
else if (c == S_EX_HIGHER)
|
||||||
|
imm_reloc = BFD_RELOC_MIPS_HIGHER;
|
||||||
|
else if (c == S_EX_HI)
|
||||||
{
|
{
|
||||||
imm_reloc = BFD_RELOC_HI16_S;
|
imm_reloc = BFD_RELOC_HI16_S;
|
||||||
imm_unmatched_hi = true;
|
imm_unmatched_hi = true;
|
||||||
|
@ -7675,7 +7692,7 @@ mips_ip (str, ip)
|
||||||
}
|
}
|
||||||
if (*args == 'i')
|
if (*args == 'i')
|
||||||
{
|
{
|
||||||
if ((c == '\0' && imm_expr.X_op != O_constant)
|
if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
|
||||||
|| ((imm_expr.X_add_number < 0
|
|| ((imm_expr.X_add_number < 0
|
||||||
|| imm_expr.X_add_number >= 0x10000)
|
|| imm_expr.X_add_number >= 0x10000)
|
||||||
&& imm_expr.X_op == O_constant))
|
&& imm_expr.X_op == O_constant))
|
||||||
|
@ -7708,7 +7725,7 @@ mips_ip (str, ip)
|
||||||
max = 0x8000;
|
max = 0x8000;
|
||||||
else
|
else
|
||||||
max = 0x10000;
|
max = 0x10000;
|
||||||
if ((c == '\0' && imm_expr.X_op != O_constant)
|
if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
|
||||||
|| ((imm_expr.X_add_number < -0x8000
|
|| ((imm_expr.X_add_number < -0x8000
|
||||||
|| imm_expr.X_add_number >= max)
|
|| imm_expr.X_add_number >= max)
|
||||||
&& imm_expr.X_op == O_constant)
|
&& imm_expr.X_op == O_constant)
|
||||||
|
@ -7742,7 +7759,7 @@ mips_ip (str, ip)
|
||||||
fashion is that the macro function doesn't expect to
|
fashion is that the macro function doesn't expect to
|
||||||
see anything which can be handled in a single
|
see anything which can be handled in a single
|
||||||
constant instruction. */
|
constant instruction. */
|
||||||
if (c == 0
|
if (c == S_EX_NONE
|
||||||
&& (offset_expr.X_op != O_constant
|
&& (offset_expr.X_op != O_constant
|
||||||
|| offset_expr.X_add_number >= 0x8000
|
|| offset_expr.X_add_number >= 0x8000
|
||||||
|| offset_expr.X_add_number < -0x8000)
|
|| offset_expr.X_add_number < -0x8000)
|
||||||
|
@ -7752,7 +7769,7 @@ mips_ip (str, ip)
|
||||||
!= S_GET_SEGMENT (offset_expr.X_op_symbol))))
|
!= S_GET_SEGMENT (offset_expr.X_op_symbol))))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (c == 'h' || c == 'H')
|
if (c == S_EX_HI)
|
||||||
{
|
{
|
||||||
if (offset_expr.X_op != O_constant)
|
if (offset_expr.X_op != O_constant)
|
||||||
break;
|
break;
|
||||||
|
@ -7774,12 +7791,14 @@ mips_ip (str, ip)
|
||||||
imm_reloc = BFD_RELOC_LO16;
|
imm_reloc = BFD_RELOC_LO16;
|
||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
if (c != 'l')
|
if (c != S_EX_LO)
|
||||||
{
|
{
|
||||||
if (imm_expr.X_op == O_constant)
|
if (imm_expr.X_op == O_constant)
|
||||||
imm_expr.X_add_number =
|
imm_expr.X_add_number =
|
||||||
(imm_expr.X_add_number >> 16) & 0xffff;
|
(imm_expr.X_add_number >> 16) & 0xffff;
|
||||||
else if (c == 'h')
|
else if (c == S_EX_HIGHEST)
|
||||||
|
imm_reloc = BFD_RELOC_MIPS_HIGHEST;
|
||||||
|
else if (c == S_EX_HI)
|
||||||
{
|
{
|
||||||
imm_reloc = BFD_RELOC_HI16_S;
|
imm_reloc = BFD_RELOC_HI16_S;
|
||||||
imm_unmatched_hi = true;
|
imm_unmatched_hi = true;
|
||||||
|
@ -8581,8 +8600,6 @@ mips16_immed (file, line, type, val, warn, small, ext, insn, use_extend,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LP '('
|
|
||||||
#define RP ')'
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
my_getSmallExpression (ep, str)
|
my_getSmallExpression (ep, str)
|
||||||
|
@ -8590,85 +8607,144 @@ my_getSmallExpression (ep, str)
|
||||||
char *str;
|
char *str;
|
||||||
{
|
{
|
||||||
char *sp;
|
char *sp;
|
||||||
int c = 0;
|
char *oldstr = str;
|
||||||
|
int c = S_EX_NONE;
|
||||||
|
|
||||||
if (*str == ' ')
|
if (*str == ' ')
|
||||||
str++;
|
str++;
|
||||||
if (*str == LP
|
if (*str == '(')
|
||||||
|| (*str == '%' &&
|
c = S_EX_NONE;
|
||||||
((str[1] == 'h' && str[2] == 'i')
|
else if (str[0] == '%'
|
||||||
|| (str[1] == 'H' && str[2] == 'I')
|
&& tolower(str[1]) == 'l'
|
||||||
|| (str[1] == 'l' && str[2] == 'o'))
|
&& tolower(str[2]) == 'o'
|
||||||
&& str[3] == LP))
|
&& str[3] == '(')
|
||||||
{
|
{
|
||||||
if (*str == LP)
|
c = S_EX_LO;
|
||||||
c = 0;
|
str += sizeof ("%lo(") - 2;
|
||||||
else
|
}
|
||||||
{
|
else if (str[0] == '%'
|
||||||
c = str[1];
|
&& tolower(str[1]) == 'h'
|
||||||
str += 3;
|
&& tolower(str[2]) == 'i'
|
||||||
}
|
&& str[3] == '(')
|
||||||
|
{
|
||||||
|
c = S_EX_HI;
|
||||||
|
str += sizeof ("%hi(") - 2;
|
||||||
|
}
|
||||||
|
else if (str[0] == '%'
|
||||||
|
&& tolower(str[1]) == 'h'
|
||||||
|
&& tolower(str[2]) == 'i'
|
||||||
|
&& tolower(str[3]) == 'g'
|
||||||
|
&& tolower(str[4]) == 'h'
|
||||||
|
&& tolower(str[5]) == 'e'
|
||||||
|
&& tolower(str[6]) == 'r'
|
||||||
|
&& str[7] == '(')
|
||||||
|
{
|
||||||
|
c = S_EX_HIGHER;
|
||||||
|
str += sizeof ("%higher(") - 2;
|
||||||
|
}
|
||||||
|
else if (str[0] == '%'
|
||||||
|
&& tolower(str[1]) == 'h'
|
||||||
|
&& tolower(str[2]) == 'i'
|
||||||
|
&& tolower(str[3]) == 'g'
|
||||||
|
&& tolower(str[4]) == 'h'
|
||||||
|
&& tolower(str[5]) == 'e'
|
||||||
|
&& tolower(str[6]) == 's'
|
||||||
|
&& tolower(str[7]) == 't'
|
||||||
|
&& str[8] == '(')
|
||||||
|
{
|
||||||
|
c = S_EX_HIGHEST;
|
||||||
|
str += sizeof ("%highest(") - 2;
|
||||||
|
}
|
||||||
|
/* currently unsupported */
|
||||||
|
#if 0
|
||||||
|
else if (str[0] == '%'
|
||||||
|
&& tolower(str[1]) == 'g'
|
||||||
|
&& tolower(str[2]) == 'p'
|
||||||
|
&& tolower(str[3]) == 'r'
|
||||||
|
&& tolower(str[4]) == 'e'
|
||||||
|
&& tolower(str[5]) == 'l'
|
||||||
|
&& str[6] == '(')
|
||||||
|
{
|
||||||
|
c = S_EX_GPREL;
|
||||||
|
str += sizeof ("%gprel(") - 2;
|
||||||
|
}
|
||||||
|
else if (str[0] == '%'
|
||||||
|
&& tolower(str[1]) == 'n'
|
||||||
|
&& tolower(str[2]) == 'e'
|
||||||
|
&& tolower(str[3]) == 'g'
|
||||||
|
&& str[4] == '(')
|
||||||
|
{
|
||||||
|
c = S_EX_NEG;
|
||||||
|
str += sizeof ("%neg(") - 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_getExpression (ep, str);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A small expression may be followed by a base register.
|
* A small expression may be followed by a base register.
|
||||||
* Scan to the end of this operand, and then back over a possible
|
* Scan to the end of this operand, and then back over a possible
|
||||||
* base register. Then scan the small expression up to that
|
* base register. Then scan the small expression up to that
|
||||||
* point. (Based on code in sparc.c...)
|
* point. (Based on code in sparc.c...)
|
||||||
*/
|
*/
|
||||||
for (sp = str; *sp && *sp != ','; sp++)
|
for (sp = str; *sp && *sp != ','; sp++)
|
||||||
;
|
;
|
||||||
if (sp - 4 >= str && sp[-1] == RP)
|
if (sp - 4 >= str && sp[-1] == ')')
|
||||||
|
{
|
||||||
|
if (isdigit ((unsigned char) sp[-2]))
|
||||||
{
|
{
|
||||||
if (isdigit ((unsigned char) sp[-2]))
|
for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
|
||||||
|
;
|
||||||
|
if (*sp == '$' && sp > str && sp[-1] == '(')
|
||||||
{
|
{
|
||||||
for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
|
sp--;
|
||||||
;
|
goto do_it;
|
||||||
if (*sp == '$' && sp > str && sp[-1] == LP)
|
|
||||||
{
|
|
||||||
sp--;
|
|
||||||
goto do_it;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (sp - 5 >= str
|
}
|
||||||
&& sp[-5] == LP
|
else if (sp - 5 >= str
|
||||||
&& sp[-4] == '$'
|
&& sp[-5] == '('
|
||||||
&& ((sp[-3] == 'f' && sp[-2] == 'p')
|
&& sp[-4] == '$'
|
||||||
|| (sp[-3] == 's' && sp[-2] == 'p')
|
&& ((sp[-3] == 'f' && sp[-2] == 'p')
|
||||||
|| (sp[-3] == 'g' && sp[-2] == 'p')
|
|| (sp[-3] == 's' && sp[-2] == 'p')
|
||||||
|| (sp[-3] == 'a' && sp[-2] == 't')))
|
|| (sp[-3] == 'g' && sp[-2] == 'p')
|
||||||
|
|| (sp[-3] == 'a' && sp[-2] == 't')))
|
||||||
|
{
|
||||||
|
sp -= 5;
|
||||||
|
do_it:
|
||||||
|
if (sp == str)
|
||||||
{
|
{
|
||||||
sp -= 5;
|
/* no expression means zero offset */
|
||||||
do_it:
|
if (c != S_EX_NONE)
|
||||||
if (sp == str)
|
|
||||||
{
|
{
|
||||||
/* no expression means zero offset */
|
/* %xx(reg) is an error */
|
||||||
if (c)
|
ep->X_op = O_absent;
|
||||||
{
|
expr_end = oldstr;
|
||||||
/* %xx(reg) is an error */
|
|
||||||
ep->X_op = O_absent;
|
|
||||||
expr_end = str - 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ep->X_op = O_constant;
|
|
||||||
expr_end = sp;
|
|
||||||
}
|
|
||||||
ep->X_add_symbol = NULL;
|
|
||||||
ep->X_op_symbol = NULL;
|
|
||||||
ep->X_add_number = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*sp = '\0';
|
ep->X_op = O_constant;
|
||||||
my_getExpression (ep, str);
|
expr_end = sp;
|
||||||
*sp = LP;
|
|
||||||
}
|
}
|
||||||
return c;
|
ep->X_add_symbol = NULL;
|
||||||
|
ep->X_op_symbol = NULL;
|
||||||
|
ep->X_add_number = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*sp = '\0';
|
||||||
|
my_getExpression (ep, str);
|
||||||
|
*sp = '(';
|
||||||
|
}
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_getExpression (ep, str);
|
my_getExpression (ep, str);
|
||||||
return c; /* => %hi or %lo encountered */
|
|
||||||
|
/* => %highest, %higher, %hi, %lo, %gprel, %neg encountered */
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue