mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 02:50:08 +08:00
v9 stuff.
This commit is contained in:
@ -20,9 +20,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
/* $Id$
|
/* $Id$
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.3 1991/05/19 08:00:57 rich
|
Revision 1.4 1991/05/22 01:17:48 rich
|
||||||
Updated to relect a gdb change in sparc-opcode.h.
|
v9 stuff.
|
||||||
|
|
||||||
|
* Revision 1.3 1991/05/19 08:00:57 rich
|
||||||
|
* Updated to relect a gdb change in sparc-opcode.h.
|
||||||
|
*
|
||||||
* Revision 1.2 1991/04/18 21:14:21 steve
|
* Revision 1.2 1991/04/18 21:14:21 steve
|
||||||
* Send the right # of args to an fprintf
|
* Send the right # of args to an fprintf
|
||||||
*
|
*
|
||||||
@ -82,39 +85,58 @@ union sparc_insn
|
|||||||
unsigned long int code;
|
unsigned long int code;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned int OP:2;
|
unsigned int _OP:2;
|
||||||
#define op ldst.OP
|
#define op ldst._OP
|
||||||
unsigned int RD:5;
|
unsigned int _RD:5;
|
||||||
#define rd ldst.RD
|
#define rd ldst._RD
|
||||||
unsigned int op3:6;
|
unsigned int op3:6;
|
||||||
unsigned int RS1:5;
|
unsigned int _RS1:5;
|
||||||
#define rs1 ldst.RS1
|
#define rs1 ldst._RS1
|
||||||
unsigned int i:1;
|
unsigned int i:1;
|
||||||
unsigned int ASI:8;
|
unsigned int _ASI:8;
|
||||||
#define asi ldst.ASI
|
#define asi ldst._ASI
|
||||||
unsigned int RS2:5;
|
unsigned int _RS2:5;
|
||||||
#define rs2 ldst.RS2
|
#define rs2 ldst._RS2
|
||||||
#define shcnt rs2
|
#define shcnt rs2
|
||||||
} ldst;
|
} ldst;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned int OP:2, RD:5, op3:6, RS1:5, i:1;
|
unsigned int _OP:2, _RD:5, op3:6, _RS1:5, i:1;
|
||||||
unsigned int IMM13:13;
|
unsigned int IMM13:13;
|
||||||
#define imm13 IMM13.IMM13
|
#define imm13 IMM13.IMM13
|
||||||
} IMM13;
|
} IMM13;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned int OP:2;
|
unsigned int _OP:2;
|
||||||
unsigned int a:1;
|
unsigned int a:1;
|
||||||
unsigned int cond:4;
|
unsigned int cond:4;
|
||||||
unsigned int op2:3;
|
unsigned int op2:3;
|
||||||
unsigned int DISP22:22;
|
unsigned int DISP22:22;
|
||||||
#define disp22 branch.DISP22
|
#define disp22 branch.DISP22
|
||||||
} branch;
|
} branch;
|
||||||
|
#ifndef NO_V9
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int _OP:2, _RD:5, op3:6, _RS1:5;
|
||||||
|
unsigned int DISP14:14;
|
||||||
|
#define disp14 DISP14.DISP14
|
||||||
|
} DISP14;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int _OP:2;
|
||||||
|
unsigned int a:1;
|
||||||
|
unsigned int cond:4;
|
||||||
|
unsigned int op2:3;
|
||||||
|
unsigned int p:1;
|
||||||
|
unsigned int DISP21:21;
|
||||||
|
#define disp21 branch.DISP21
|
||||||
|
} branch2;
|
||||||
|
#endif /* NO_V9 */
|
||||||
|
|
||||||
#define imm22 disp22
|
#define imm22 disp22
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned int OP:2;
|
unsigned int _OP:2;
|
||||||
unsigned int DISP30:30;
|
unsigned int DISP30:30;
|
||||||
#define disp30 call.DISP30
|
#define disp30 call.DISP30
|
||||||
} call;
|
} call;
|
||||||
@ -198,19 +220,34 @@ memcpy(&insn,buffer, sizeof (insn));
|
|||||||
|
|
||||||
if (opcode->args[0] != ',')
|
if (opcode->args[0] != ',')
|
||||||
fputs (" ", stream);
|
fputs (" ", stream);
|
||||||
for (s = opcode->args; *s != '\0'; ++s)
|
for (s = opcode->args; *s != '\0'; ++s) {
|
||||||
{
|
while (*s == ',') {
|
||||||
if (*s == ',')
|
|
||||||
{
|
|
||||||
fputs (",", stream);
|
fputs (",", stream);
|
||||||
++s;
|
++s;
|
||||||
if (*s == 'a')
|
|
||||||
{
|
switch (*s) {
|
||||||
|
case 'a':
|
||||||
fputs ("a", stream);
|
fputs ("a", stream);
|
||||||
++s;
|
++s;
|
||||||
}
|
continue;
|
||||||
|
#ifndef NO_V9
|
||||||
|
case 'N':
|
||||||
|
fputs("pn", stream);
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
fputs("pt", stream);
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
#endif /* NO_V9 */
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} /* switch on arg */
|
||||||
|
} /* while there are comma started args */
|
||||||
|
|
||||||
fputs (" ", stream);
|
fputs (" ", stream);
|
||||||
}
|
|
||||||
|
|
||||||
switch (*s)
|
switch (*s)
|
||||||
{
|
{
|
||||||
@ -297,6 +334,35 @@ memcpy(&insn,buffer, sizeof (insn));
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef NO_V9
|
||||||
|
case 'k':
|
||||||
|
print_address ((bfd_vma)
|
||||||
|
(memaddr
|
||||||
|
+ (((int) insn.disp14 << 18) >> 18) * 4),
|
||||||
|
stream);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'K':
|
||||||
|
print_address ((bfd_vma)
|
||||||
|
(memaddr
|
||||||
|
+ (((int) insn.disp21 << 11) >> 11) * 4),
|
||||||
|
stream);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Y':
|
||||||
|
fputs ("%amr", stream);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif /* NO_V9 */
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
fprintf(stream, "%%asr%d", insn.rs1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
fprintf(stream, "%%asr%d", insn.rd);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
print_address ((bfd_vma) memaddr + insn.disp30 * 4,
|
print_address ((bfd_vma) memaddr + insn.disp30 * 4,
|
||||||
stream);
|
stream);
|
||||||
|
@ -40,6 +40,10 @@ void md_ri_to_chars();
|
|||||||
symbolS *md_undefined_symbol();
|
symbolS *md_undefined_symbol();
|
||||||
static void sparc_ip();
|
static void sparc_ip();
|
||||||
|
|
||||||
|
static enum sparc_architecture current_architecture = v6;
|
||||||
|
static int architecture_requested = 0;
|
||||||
|
static int warn_on_bump = 1;
|
||||||
|
|
||||||
const relax_typeS md_relax_table[] = {
|
const relax_typeS md_relax_table[] = {
|
||||||
0 };
|
0 };
|
||||||
|
|
||||||
@ -64,13 +68,13 @@ const pseudo_typeS md_pseudo_table[] = {
|
|||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
int md_short_jump_size = 4;
|
const int md_short_jump_size = 4;
|
||||||
int md_long_jump_size = 4;
|
const int md_long_jump_size = 4;
|
||||||
int md_reloc_size = 12; /* Size of relocation record */
|
const int md_reloc_size = 12; /* Size of relocation record */
|
||||||
|
|
||||||
/* This array holds the chars that always start a comment. If the
|
/* This array holds the chars that always start a comment. If the
|
||||||
pre-processor is disabled, these aren't very useful */
|
pre-processor is disabled, these aren't very useful */
|
||||||
char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
|
const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
|
||||||
|
|
||||||
/* This array holds the chars that only start a comment at the beginning of
|
/* This array holds the chars that only start a comment at the beginning of
|
||||||
a line. If the line seems to have the form '# 123 filename'
|
a line. If the line seems to have the form '# 123 filename'
|
||||||
@ -78,16 +82,17 @@ char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
|
|||||||
/* Note that input_file.c hand checks for '#' at the beginning of the
|
/* Note that input_file.c hand checks for '#' at the beginning of the
|
||||||
first line of the input file. This is because the compiler outputs
|
first line of the input file. This is because the compiler outputs
|
||||||
#NO_APP at the beginning of its output. */
|
#NO_APP at the beginning of its output. */
|
||||||
/* Also note that comments started like this one will always work */
|
/* Also note that comments started like this one will always
|
||||||
char line_comment_chars[] = "#";
|
work if '/' isn't otherwise defined. */
|
||||||
|
const char line_comment_chars[] = "#";
|
||||||
|
|
||||||
/* Chars that can be used to separate mant from exp in floating point nums */
|
/* Chars that can be used to separate mant from exp in floating point nums */
|
||||||
char EXP_CHARS[] = "eE";
|
const char EXP_CHARS[] = "eE";
|
||||||
|
|
||||||
/* Chars that mean this number is a floating point constant */
|
/* Chars that mean this number is a floating point constant */
|
||||||
/* As in 0f12.456 */
|
/* As in 0f12.456 */
|
||||||
/* or 0d1.2345e12 */
|
/* or 0d1.2345e12 */
|
||||||
char FLT_CHARS[] = "rRsSfFdDxXpP";
|
const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
||||||
|
|
||||||
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
|
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
|
||||||
changed in read.c . Ideally it shouldn't have to know about it at all,
|
changed in read.c . Ideally it shouldn't have to know about it at all,
|
||||||
@ -98,11 +103,6 @@ static unsigned char octal[256];
|
|||||||
#define isoctal(c) octal[c]
|
#define isoctal(c) octal[c]
|
||||||
static unsigned char toHex[256];
|
static unsigned char toHex[256];
|
||||||
|
|
||||||
/*
|
|
||||||
* anull bit - causes the branch delay slot instructions to not be executed
|
|
||||||
*/
|
|
||||||
#define ANNUL (1 << 29)
|
|
||||||
|
|
||||||
struct sparc_it {
|
struct sparc_it {
|
||||||
char *error;
|
char *error;
|
||||||
unsigned long opcode;
|
unsigned long opcode;
|
||||||
@ -421,6 +421,7 @@ char *str;
|
|||||||
static void sparc_ip(str)
|
static void sparc_ip(str)
|
||||||
char *str;
|
char *str;
|
||||||
{
|
{
|
||||||
|
char *error_message = "";
|
||||||
char *s;
|
char *s;
|
||||||
const char *args;
|
const char *args;
|
||||||
char c;
|
char c;
|
||||||
@ -471,6 +472,68 @@ char *str;
|
|||||||
for (args = insn->args; ; ++args) {
|
for (args = insn->args; ; ++args) {
|
||||||
switch (*args) {
|
switch (*args) {
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
if (strncmp(s, "%asr", 4) == 0) {
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
if (isdigit(*s)) {
|
||||||
|
long num = 0;
|
||||||
|
|
||||||
|
while (isdigit(*s)) {
|
||||||
|
num = num*10 + *s-'0';
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num < 16 || 31 < num) {
|
||||||
|
error_message = ": asr number must be between 15 and 31";
|
||||||
|
goto error;
|
||||||
|
} /* out of range */
|
||||||
|
|
||||||
|
opcode |= (*args == 'M' ? RS1(num) : RD(num));
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
error_message = ": expecting %asrN";
|
||||||
|
goto error;
|
||||||
|
} /* if %asr followed by a number. */
|
||||||
|
|
||||||
|
} /* if %asr */
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef NO_V9
|
||||||
|
case 'k':
|
||||||
|
the_insn.reloc = RELOC_WDISP14;
|
||||||
|
the_insn.pcrel = 1;
|
||||||
|
goto immediate;
|
||||||
|
|
||||||
|
case 'K':
|
||||||
|
the_insn.reloc = RELOC_WDISP21;
|
||||||
|
the_insn.pcrel = 1;
|
||||||
|
goto immediate;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
if (*s == 'p' && s[1] == 'n') {
|
||||||
|
s += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
if (*s == 'p' && s[1] == 't') {
|
||||||
|
s += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Y':
|
||||||
|
if (strncmp(s, "%amr", 4) == 0) {
|
||||||
|
s += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif /* NO_V9 */
|
||||||
|
|
||||||
case '\0': /* end of args */
|
case '\0': /* end of args */
|
||||||
if (*s == '\0') {
|
if (*s == '\0') {
|
||||||
match = 1;
|
match = 1;
|
||||||
@ -825,15 +888,35 @@ char *str;
|
|||||||
++insn;
|
++insn;
|
||||||
s = argsStart;
|
s = argsStart;
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else
|
as_bad("Illegal operands%s", error_message);
|
||||||
{
|
|
||||||
as_bad("Illegal operands");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
if (insn->architecture > current_architecture) {
|
||||||
|
if (current_architecture != cypress
|
||||||
|
&& (!architecture_requested || warn_on_bump)) {
|
||||||
|
|
||||||
|
if (warn_on_bump) {
|
||||||
|
as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
|
||||||
|
architecture_pname[current_architecture],
|
||||||
|
architecture_pname[insn->architecture],
|
||||||
|
str);
|
||||||
|
} /* if warning */
|
||||||
|
|
||||||
|
current_architecture = insn->architecture;
|
||||||
|
} else {
|
||||||
|
as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
|
||||||
|
str,
|
||||||
|
architecture_pname[insn->architecture],
|
||||||
|
architecture_pname[current_architecture]);
|
||||||
|
return;
|
||||||
|
} /* if bump ok else error */
|
||||||
|
} /* if architecture higher */
|
||||||
|
} /* if no match */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
} /* forever looking for a match */
|
||||||
|
|
||||||
the_insn.opcode = opcode;
|
the_insn.opcode = opcode;
|
||||||
return;
|
return;
|
||||||
@ -1007,6 +1090,21 @@ long val;
|
|||||||
buf[3] = val;
|
buf[3] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef NO_V9
|
||||||
|
case RELOC_WDISP14:
|
||||||
|
val = (val >>= 2) + 1;
|
||||||
|
buf[2] |= (val >> 8) & 0x3f ;
|
||||||
|
buf[3] = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RELOC_WDISP21:
|
||||||
|
val = (val >>= 2) + 1;
|
||||||
|
buf[1] |= (val >> 16) & 0x1f;
|
||||||
|
buf[2] = val >> 8;
|
||||||
|
buf[3] = val;
|
||||||
|
break;
|
||||||
|
#endif /* NO_V9 */
|
||||||
|
|
||||||
case RELOC_HI22:
|
case RELOC_HI22:
|
||||||
if(!fixP->fx_addsy) {
|
if(!fixP->fx_addsy) {
|
||||||
buf[1] |= (val >> 26) & 0x3f;
|
buf[1] |= (val >> 26) & 0x3f;
|
||||||
@ -1242,11 +1340,72 @@ relax_addressT segment_address_in_file;
|
|||||||
} /* emit_sparc_reloc() */
|
} /* emit_sparc_reloc() */
|
||||||
#endif /* aout or bout */
|
#endif /* aout or bout */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* md_parse_option
|
||||||
|
* Invocation line includes a switch not recognized by the base assembler.
|
||||||
|
* See if it's a processor-specific option. These are:
|
||||||
|
*
|
||||||
|
* -bump
|
||||||
|
* Warn on architecture bumps. See also -A.
|
||||||
|
*
|
||||||
|
* -Av6, -Av7, -Acypress, -Av8
|
||||||
|
* -Av9
|
||||||
|
* Select the architecture. Instructions or features not
|
||||||
|
* supported by the selected architecture cause fatal errors.
|
||||||
|
*
|
||||||
|
* The default is to start at v6, and bump the architecture up
|
||||||
|
* whenever an instruction is seen at a higher level.
|
||||||
|
*
|
||||||
|
* If -bump is specified, a warning is printing when bumping to
|
||||||
|
* higher levels.
|
||||||
|
*
|
||||||
|
* If an architecture is specified, all instructions must match
|
||||||
|
* that architecture. Any higher level instructions are flagged
|
||||||
|
* as errors.
|
||||||
|
*
|
||||||
|
* if both an architecture and -bump are specified, the
|
||||||
|
* architecture starts at the specified level, but bumps are
|
||||||
|
* warnings.
|
||||||
|
*
|
||||||
|
* Note that where cypress specific instructions conflict with
|
||||||
|
* other instructions, the other instruction is assumed. Nothing
|
||||||
|
* is upward compatible with cypress. Thus, to get the cypress
|
||||||
|
* instruction set you MUST -Acypress.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
int md_parse_option(argP, cntP, vecP)
|
int md_parse_option(argP, cntP, vecP)
|
||||||
char **argP;
|
char **argP;
|
||||||
int *cntP;
|
int *cntP;
|
||||||
char ***vecP;
|
char ***vecP;
|
||||||
{
|
{
|
||||||
|
char *p;
|
||||||
|
const char **arch;
|
||||||
|
|
||||||
|
if (!strcmp(*argP,"bump")){
|
||||||
|
warn_on_bump = 1;
|
||||||
|
|
||||||
|
} else if (**argP == 'A'){
|
||||||
|
p = (*argP) + 1;
|
||||||
|
|
||||||
|
for (arch = architecture_pname; *arch != NULL; ++arch){
|
||||||
|
if (strcmp(p, *arch) == 0){
|
||||||
|
break;
|
||||||
|
} /* found a match */
|
||||||
|
} /* walk the pname table */
|
||||||
|
|
||||||
|
if (*arch == NULL){
|
||||||
|
as_bad("unknown architecture: %s", p);
|
||||||
|
} else {
|
||||||
|
current_architecture = (enum sparc_architecture) (arch - architecture_pname);
|
||||||
|
architecture_requested = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Unknown option */
|
||||||
|
(*argP)++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
**argP = '\0'; /* Done parsing this switch */
|
||||||
return 1;
|
return 1;
|
||||||
} /* md_parse_option() */
|
} /* md_parse_option() */
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user