mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 19:09:31 +08:00
* tc-txvu.c (*): Update to use handle new arguments for
parse/insert/extract/print handlers. ({encode,decode}_fixup_reloc_type): New function. (assemble_pke): Write out insn after parsing it.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
start-sanitize-sky
|
||||||
|
Tue Jan 27 14:13:37 1998 Doug Evans <devans@seba.cygnus.com>
|
||||||
|
|
||||||
|
* config/tc-txvu.c (*): Update to use handle new arguments for
|
||||||
|
parse/insert/extract/print handlers.
|
||||||
|
({encode,decode}_fixup_reloc_type): New function.
|
||||||
|
(assemble_pke): Write out insn after parsing it.
|
||||||
|
|
||||||
|
end-sanitize-sky
|
||||||
Tue Jan 27 13:32:01 1998 Robert Lipe <robertl@dgii.com>
|
Tue Jan 27 13:32:01 1998 Robert Lipe <robertl@dgii.com>
|
||||||
|
|
||||||
* configure.in (i386-*-sco3.2v5*): Defaults to ELF now.
|
* configure.in (i386-*-sco3.2v5*): Defaults to ELF now.
|
||||||
@ -48,7 +57,7 @@ Tue Jan 27 05:32:05 1998 Richard Henderson <rth@cygnus.com>
|
|||||||
start-sanitize-sky
|
start-sanitize-sky
|
||||||
Mon Jan 26 16:29:49 1998 Doug Evans <devans@seba.cygnus.com>
|
Mon Jan 26 16:29:49 1998 Doug Evans <devans@seba.cygnus.com>
|
||||||
|
|
||||||
* tc-txvu.c: First pass at dma/pke/gpuif support.
|
* config/tc-txvu.c: First pass at dma/pke/gpuif support.
|
||||||
(assemble_one_insn): Renamed from assemble_insn.
|
(assemble_one_insn): Renamed from assemble_insn.
|
||||||
Initialize errmsg = NULL before calling parse fn.
|
Initialize errmsg = NULL before calling parse fn.
|
||||||
Allow [] in suffix operand.
|
Allow [] in suffix operand.
|
||||||
|
@ -27,9 +27,11 @@
|
|||||||
#include "opcode/txvu.h"
|
#include "opcode/txvu.h"
|
||||||
#include "elf/txvu.h"
|
#include "elf/txvu.h"
|
||||||
|
|
||||||
|
enum cputype { CPU_VUUP, CPU_VULO, CPU_DMA, CPU_PKE, CPU_GPUIF };
|
||||||
|
|
||||||
static TXVU_INSN txvu_insert_operand
|
static TXVU_INSN txvu_insert_operand
|
||||||
PARAMS ((TXVU_INSN, const struct txvu_operand *, int, offsetT,
|
PARAMS ((TXVU_INSN, enum cputype, const txvu_operand *,
|
||||||
char *, unsigned int));
|
int, offsetT, char *, unsigned int));
|
||||||
|
|
||||||
const char comment_chars[] = ";";
|
const char comment_chars[] = ";";
|
||||||
const char line_comment_chars[] = "#";
|
const char line_comment_chars[] = "#";
|
||||||
@ -120,8 +122,6 @@ md_begin ()
|
|||||||
dma_pack_pke_p = 0;
|
dma_pack_pke_p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum cputype { CPU_VUUP, CPU_VULO, CPU_DMA, CPU_PKE, CPU_GPUIF };
|
|
||||||
|
|
||||||
/* We need to keep a list of fixups. We can't simply generate them as
|
/* We need to keep a list of fixups. We can't simply generate them as
|
||||||
we go, because that would require us to first create the frag, and
|
we go, because that would require us to first create the frag, and
|
||||||
that would screw up references to ``.''. */
|
that would screw up references to ``.''. */
|
||||||
@ -138,17 +138,24 @@ struct txvu_fixup
|
|||||||
static int fixup_count;
|
static int fixup_count;
|
||||||
static struct txvu_fixup fixups[MAX_FIXUPS];
|
static struct txvu_fixup fixups[MAX_FIXUPS];
|
||||||
|
|
||||||
|
/* Given a cpu type and operand number, return a temporary reloc type
|
||||||
|
for use in generating the fixup that encodes the cpu type and operand. */
|
||||||
|
static int encode_fixup_reloc_type PARAMS ((enum cputype, int));
|
||||||
|
/* Given an encoded fixup reloc type, decode it into cpu and operand. */
|
||||||
|
static void decode_fixup_reloc_type PARAMS ((int, enum cputype *,
|
||||||
|
const txvu_operand **));
|
||||||
|
|
||||||
static void assemble_dma PARAMS ((char *));
|
static void assemble_dma PARAMS ((char *));
|
||||||
static void assemble_gpuif PARAMS ((char *));
|
static void assemble_gpuif PARAMS ((char *));
|
||||||
static void assemble_pke PARAMS ((char *));
|
static void assemble_pke PARAMS ((char *));
|
||||||
static void assemble_vu PARAMS ((char *));
|
static void assemble_vu PARAMS ((char *));
|
||||||
static char * assemble_vu_insn PARAMS ((enum cputype,
|
static char * assemble_vu_insn PARAMS ((enum cputype,
|
||||||
const struct txvu_opcode *,
|
const txvu_opcode *,
|
||||||
const struct txvu_operand *,
|
const txvu_operand *,
|
||||||
char *, char *));
|
char *, char *));
|
||||||
static char * assemble_one_insn PARAMS ((enum cputype,
|
static char * assemble_one_insn PARAMS ((enum cputype,
|
||||||
const struct txvu_opcode *,
|
const txvu_opcode *,
|
||||||
const struct txvu_operand *,
|
const txvu_operand *,
|
||||||
char *, TXVU_INSN *));
|
char *, TXVU_INSN *));
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -178,11 +185,13 @@ static void
|
|||||||
assemble_dma (str)
|
assemble_dma (str)
|
||||||
char *str;
|
char *str;
|
||||||
{
|
{
|
||||||
TXVU_INSN buf[4];
|
TXVU_INSN insn_buf[4];
|
||||||
|
|
||||||
assemble_one_insn (CPU_DMA,
|
str = assemble_one_insn (CPU_DMA,
|
||||||
dma_opcode_lookup_asm (str), dma_operands,
|
dma_opcode_lookup_asm (str), dma_operands,
|
||||||
str, buf);
|
str, insn_buf);
|
||||||
|
if (str == NULL)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subroutine of md_assemble to assemble PKE instructions. */
|
/* Subroutine of md_assemble to assemble PKE instructions. */
|
||||||
@ -191,11 +200,69 @@ static void
|
|||||||
assemble_pke (str)
|
assemble_pke (str)
|
||||||
char *str;
|
char *str;
|
||||||
{
|
{
|
||||||
TXVU_INSN buf[4];
|
/* Space for the instruction.
|
||||||
|
The variable length insns can require much more space than this.
|
||||||
|
It is allocated later, when we know we have such an insn. */
|
||||||
|
TXVU_INSN insn_buf[5];
|
||||||
|
/* Insn's length, in 32 bit words. */
|
||||||
|
int len;
|
||||||
|
/* Non-zero if this is a variable length insn. */
|
||||||
|
int varlen_p;
|
||||||
|
/* Pointer to allocated frag. */
|
||||||
|
char *f;
|
||||||
|
int i;
|
||||||
|
|
||||||
assemble_one_insn (CPU_PKE,
|
str = assemble_one_insn (CPU_PKE,
|
||||||
pke_opcode_lookup_asm (str), pke_operands,
|
pke_opcode_lookup_asm (str), pke_operands,
|
||||||
str, buf);
|
str, insn_buf);
|
||||||
|
if (str == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Call back into the parser's state to get the insn's length.
|
||||||
|
This is just the length of the insn, not of any following data.
|
||||||
|
The result 0 if the length is unknown. */
|
||||||
|
varlen_p = pke_varlen_p ();
|
||||||
|
len = pke_len ();
|
||||||
|
|
||||||
|
if (varlen_p)
|
||||||
|
{
|
||||||
|
/* FIXME: not done yet */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f = frag_more (len * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write out the instruction.
|
||||||
|
Reminder: it is important to fetch enough space in one call to
|
||||||
|
`frag_more'. We use (f - frag_now->fr_literal) to compute where
|
||||||
|
we are and we don't want frag_now to change between calls. */
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
md_number_to_chars (f + i * 4, insn_buf[i], 4);
|
||||||
|
|
||||||
|
/* Create any fixups. */
|
||||||
|
/* FIXME: It might eventually be possible to combine all the various
|
||||||
|
copies of this bit of code. */
|
||||||
|
for (i = 0; i < fixup_count; ++i)
|
||||||
|
{
|
||||||
|
int op_type, reloc_type;
|
||||||
|
const txvu_operand *operand;
|
||||||
|
|
||||||
|
/* Create a fixup for this operand.
|
||||||
|
At this point we do not use a bfd_reloc_code_real_type for
|
||||||
|
operands residing in the insn, but instead just use the
|
||||||
|
operand index. This lets us easily handle fixups for any
|
||||||
|
operand type, although that is admittedly not a very exciting
|
||||||
|
feature. We pick a BFD reloc type in md_apply_fix. */
|
||||||
|
|
||||||
|
op_type = fixups[i].opindex;
|
||||||
|
reloc_type = encode_fixup_reloc_type (CPU_PKE, op_type);
|
||||||
|
operand = &pke_operands[op_type];
|
||||||
|
fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
|
||||||
|
&fixups[i].exp,
|
||||||
|
(operand->flags & TXVU_OPERAND_RELATIVE_BRANCH) != 0,
|
||||||
|
(bfd_reloc_code_real_type) reloc_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subroutine of md_assemble to assemble GPUIF instructions. */
|
/* Subroutine of md_assemble to assemble GPUIF instructions. */
|
||||||
@ -204,11 +271,13 @@ static void
|
|||||||
assemble_gpuif (str)
|
assemble_gpuif (str)
|
||||||
char *str;
|
char *str;
|
||||||
{
|
{
|
||||||
TXVU_INSN buf[4];
|
TXVU_INSN insn_buf[4];
|
||||||
|
|
||||||
assemble_one_insn (CPU_GPUIF,
|
str = assemble_one_insn (CPU_GPUIF,
|
||||||
gpuif_opcode_lookup_asm (str), gpuif_operands,
|
gpuif_opcode_lookup_asm (str), gpuif_operands,
|
||||||
str, buf);
|
str, insn_buf);
|
||||||
|
if (str == NULL)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subroutine of md_assemble to assemble VU instructions. */
|
/* Subroutine of md_assemble to assemble VU instructions. */
|
||||||
@ -254,8 +323,8 @@ assemble_vu (str)
|
|||||||
static char *
|
static char *
|
||||||
assemble_vu_insn (cpu, opcode, operand_table, str, buf)
|
assemble_vu_insn (cpu, opcode, operand_table, str, buf)
|
||||||
enum cputype cpu;
|
enum cputype cpu;
|
||||||
const struct txvu_opcode *opcode;
|
const txvu_opcode *opcode;
|
||||||
const struct txvu_operand *operand_table;
|
const txvu_operand *operand_table;
|
||||||
char *str;
|
char *str;
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
@ -276,7 +345,7 @@ assemble_vu_insn (cpu, opcode, operand_table, str, buf)
|
|||||||
for (i = 0; i < fixup_count; ++i)
|
for (i = 0; i < fixup_count; ++i)
|
||||||
{
|
{
|
||||||
int op_type, reloc_type;
|
int op_type, reloc_type;
|
||||||
const struct txvu_operand *operand;
|
const txvu_operand *operand;
|
||||||
|
|
||||||
/* Create a fixup for this operand.
|
/* Create a fixup for this operand.
|
||||||
At this point we do not use a bfd_reloc_code_real_type for
|
At this point we do not use a bfd_reloc_code_real_type for
|
||||||
@ -286,7 +355,7 @@ assemble_vu_insn (cpu, opcode, operand_table, str, buf)
|
|||||||
feature. We pick a BFD reloc type in md_apply_fix. */
|
feature. We pick a BFD reloc type in md_apply_fix. */
|
||||||
|
|
||||||
op_type = fixups[i].opindex;
|
op_type = fixups[i].opindex;
|
||||||
reloc_type = op_type + (int) BFD_RELOC_UNUSED;
|
reloc_type = encode_fixup_reloc_type (cpu, op_type);
|
||||||
operand = &txvu_operands[op_type];
|
operand = &txvu_operands[op_type];
|
||||||
fix_new_exp (frag_now, buf - frag_now->fr_literal, 4,
|
fix_new_exp (frag_now, buf - frag_now->fr_literal, 4,
|
||||||
&fixups[i].exp,
|
&fixups[i].exp,
|
||||||
@ -310,8 +379,8 @@ assemble_vu_insn (cpu, opcode, operand_table, str, buf)
|
|||||||
static char *
|
static char *
|
||||||
assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
||||||
enum cputype cpu;
|
enum cputype cpu;
|
||||||
const struct txvu_opcode *opcode;
|
const txvu_opcode *opcode;
|
||||||
const struct txvu_operand *operand_table;
|
const txvu_operand *operand_table;
|
||||||
char *str;
|
char *str;
|
||||||
TXVU_INSN *insn_buf;
|
TXVU_INSN *insn_buf;
|
||||||
{
|
{
|
||||||
@ -346,7 +415,7 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
|||||||
for (/*str = start, */ syn = opcode->syntax; *syn != '\0'; )
|
for (/*str = start, */ syn = opcode->syntax; *syn != '\0'; )
|
||||||
{
|
{
|
||||||
int mods,index;
|
int mods,index;
|
||||||
const struct txvu_operand *operand;
|
const txvu_operand *operand;
|
||||||
const char *errmsg;
|
const char *errmsg;
|
||||||
|
|
||||||
/* Non operand chars must match exactly.
|
/* Non operand chars must match exactly.
|
||||||
@ -382,7 +451,8 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
|||||||
if (operand->insert)
|
if (operand->insert)
|
||||||
{
|
{
|
||||||
errmsg = NULL;
|
errmsg = NULL;
|
||||||
(*operand->insert) (insn_buf, operand, mods, 0, &errmsg);
|
(*operand->insert) (opcode, operand, mods, insn_buf, 0,
|
||||||
|
&errmsg);
|
||||||
/* If we get an error, go on to try the next insn. */
|
/* If we get an error, go on to try the next insn. */
|
||||||
if (errmsg)
|
if (errmsg)
|
||||||
break;
|
break;
|
||||||
@ -421,7 +491,8 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
|||||||
c = *t;
|
c = *t;
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
errmsg = NULL;
|
errmsg = NULL;
|
||||||
suf_value = (*operand->parse) (&s, &errmsg);
|
suf_value = (*operand->parse) (opcode, operand, mods, &s,
|
||||||
|
&errmsg);
|
||||||
*t = c;
|
*t = c;
|
||||||
if (errmsg)
|
if (errmsg)
|
||||||
{
|
{
|
||||||
@ -433,8 +504,8 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
|||||||
}
|
}
|
||||||
/* Insert the suffix's value into the insn. */
|
/* Insert the suffix's value into the insn. */
|
||||||
if (operand->insert)
|
if (operand->insert)
|
||||||
(*operand->insert) (insn_buf, operand,
|
(*operand->insert) (opcode, operand, mods,
|
||||||
mods, suf_value, NULL);
|
insn_buf, suf_value, NULL);
|
||||||
else
|
else
|
||||||
*insn_buf |= suf_value << operand->shift;
|
*insn_buf |= suf_value << operand->shift;
|
||||||
|
|
||||||
@ -474,7 +545,8 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
|||||||
if (operand->parse)
|
if (operand->parse)
|
||||||
{
|
{
|
||||||
errmsg = NULL;
|
errmsg = NULL;
|
||||||
value = (*operand->parse) (&str, &errmsg);
|
value = (*operand->parse) (opcode, operand, mods,
|
||||||
|
&str, &errmsg);
|
||||||
if (errmsg)
|
if (errmsg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -509,8 +581,8 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
|
|||||||
if (operand->insert)
|
if (operand->insert)
|
||||||
{
|
{
|
||||||
const char *errmsg = NULL;
|
const char *errmsg = NULL;
|
||||||
(*operand->insert) (insn_buf, operand, mods,
|
(*operand->insert) (opcode, operand, mods,
|
||||||
value, &errmsg);
|
insn_buf, value, &errmsg);
|
||||||
if (errmsg != (const char *) NULL)
|
if (errmsg != (const char *) NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -579,6 +651,47 @@ md_undefined_symbol (name)
|
|||||||
|
|
||||||
/* Functions concerning relocs. */
|
/* Functions concerning relocs. */
|
||||||
|
|
||||||
|
/* Spacing between each cpu type's operand numbers.
|
||||||
|
Should be at least as bit as any operand table. */
|
||||||
|
#define RELOC_SPACING 256
|
||||||
|
|
||||||
|
/* Given a cpu type and operand number, return a temporary reloc type
|
||||||
|
for use in generating the fixup that encodes the cpu type and operand
|
||||||
|
number. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
encode_fixup_reloc_type (cpu, opnum)
|
||||||
|
enum cputype cpu;
|
||||||
|
int opnum;
|
||||||
|
{
|
||||||
|
return (int) BFD_RELOC_UNUSED + ((int) cpu * RELOC_SPACING) + opnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a fixup reloc type, decode it into cpu type and operand. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
decode_fixup_reloc_type (fixup_reloc, cpuP, operandP)
|
||||||
|
int fixup_reloc;
|
||||||
|
enum cputype *cpuP;
|
||||||
|
const txvu_operand **operandP;
|
||||||
|
{
|
||||||
|
enum cputype cpu = (fixup_reloc - (int) BFD_RELOC_UNUSED) / RELOC_SPACING;
|
||||||
|
int opnum = (fixup_reloc - (int) BFD_RELOC_UNUSED) % RELOC_SPACING;
|
||||||
|
|
||||||
|
*cpuP = cpu;
|
||||||
|
switch (cpu)
|
||||||
|
{
|
||||||
|
case CPU_VUUP : *operandP = &txvu_operands[opnum]; break;
|
||||||
|
case CPU_VULO : *operandP = &txvu_operands[opnum]; break;
|
||||||
|
case CPU_DMA : *operandP = &dma_operands[opnum]; break;
|
||||||
|
case CPU_PKE : *operandP = &pke_operands[opnum]; break;
|
||||||
|
case CPU_GPUIF : *operandP = &gpuif_operands[opnum]; break;
|
||||||
|
default : as_fatal ("bad fixup encoding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a fixup reloc type, return a pointer to the operand
|
||||||
|
|
||||||
/* The location from which a PC relative jump should be calculated,
|
/* The location from which a PC relative jump should be calculated,
|
||||||
given a PC relative reloc. */
|
given a PC relative reloc. */
|
||||||
|
|
||||||
@ -651,23 +764,22 @@ md_apply_fix3 (fixP, valueP, seg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for txvu_operand's. These are indicated with a reloc value
|
/* Check for dvp operand's. These are indicated with a reloc value
|
||||||
>= BFD_RELOC_UNUSED. */
|
>= BFD_RELOC_UNUSED. */
|
||||||
|
|
||||||
if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
|
if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
|
||||||
{
|
{
|
||||||
int opindex;
|
enum cputype cpu;
|
||||||
const struct txvu_operand *operand;
|
const txvu_operand *operand;
|
||||||
TXVU_INSN insn;
|
TXVU_INSN insn;
|
||||||
|
|
||||||
opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
|
decode_fixup_reloc_type ((int) fixP->fx_r_type,
|
||||||
|
& cpu, & operand);
|
||||||
operand = &txvu_operands[opindex];
|
|
||||||
|
|
||||||
/* Fetch the instruction, insert the fully resolved operand
|
/* Fetch the instruction, insert the fully resolved operand
|
||||||
value, and stuff the instruction back again. */
|
value, and stuff the instruction back again. */
|
||||||
insn = bfd_getl32 ((unsigned char *) where);
|
insn = bfd_getl32 ((unsigned char *) where);
|
||||||
insn = txvu_insert_operand (insn, operand, -1, (offsetT) value,
|
insn = txvu_insert_operand (insn, cpu, operand, -1, (offsetT) value,
|
||||||
fixP->fx_file, fixP->fx_line);
|
fixP->fx_file, fixP->fx_line);
|
||||||
bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
|
bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
|
||||||
|
|
||||||
@ -833,9 +945,10 @@ md_atof (type, litP, sizeP)
|
|||||||
/* Insert an operand value into an instruction. */
|
/* Insert an operand value into an instruction. */
|
||||||
|
|
||||||
static TXVU_INSN
|
static TXVU_INSN
|
||||||
txvu_insert_operand (insn, operand, mods, val, file, line)
|
txvu_insert_operand (insn, cpu, operand, mods, val, file, line)
|
||||||
TXVU_INSN insn;
|
TXVU_INSN insn;
|
||||||
const struct txvu_operand *operand;
|
enum cputype cpu;
|
||||||
|
const txvu_operand *operand;
|
||||||
int mods;
|
int mods;
|
||||||
offsetT val;
|
offsetT val;
|
||||||
char *file;
|
char *file;
|
||||||
@ -894,7 +1007,7 @@ txvu_insert_operand (insn, operand, mods, val, file, line)
|
|||||||
if (operand->insert)
|
if (operand->insert)
|
||||||
{
|
{
|
||||||
const char *errmsg = NULL;
|
const char *errmsg = NULL;
|
||||||
(*operand->insert) (&insn, operand, mods, (long) val, &errmsg);
|
(*operand->insert) (NULL, operand, mods, &insn, (long) val, &errmsg);
|
||||||
if (errmsg != (const char *) NULL)
|
if (errmsg != (const char *) NULL)
|
||||||
as_warn (errmsg);
|
as_warn (errmsg);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user