aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>1998-02-24 20:40:41 +0000
committerDoug Evans <dje@google.com>1998-02-24 20:40:41 +0000
commitb6d331b9cd6965f15762c17f2ee2b4596fe88772 (patch)
tree7976e8deb35e334e8fa3a9829978818da5442021
parent9a760d248f9f9df53b74ef91d2e935596719c50b (diff)
downloadgdb-b6d331b9cd6965f15762c17f2ee2b4596fe88772.zip
gdb-b6d331b9cd6965f15762c17f2ee2b4596fe88772.tar.gz
gdb-b6d331b9cd6965f15762c17f2ee2b4596fe88772.tar.bz2
(create_colon_label): New argument `sto'. All callers updated.
(record_mach): New argument `force_next_p'. All callers updated. (cpu_sto): New function.
-rw-r--r--gas/ChangeLog3
-rw-r--r--gas/config/tc-dvp.c101
2 files changed, 72 insertions, 32 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7b7a4de..208a282 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -3,6 +3,9 @@ Tue Feb 24 11:01:25 1998 Doug Evans <devans@canuck.cygnus.com>
* config/tc-dvp.h (tc_frob_label): Define.
* config/tc-dvp.c (dvp_frob_label): New function.
+ (create_colon_label): New argument `sto'. All callers updated.
+ (record_mach): New argument `force_next_p'. All callers updated.
+ (cpu_sto): New function.
Mon Feb 23 15:55:12 1998 Doug Evans <devans@canuck.cygnus.com>
diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c
index bc33aaf..d03c6c5 100644
--- a/gas/config/tc-dvp.c
+++ b/gas/config/tc-dvp.c
@@ -45,7 +45,7 @@
static long parse_float PARAMS ((char **, const char **));
static symbolS * create_label PARAMS ((const char *, const char *));
-static symbolS * create_colon_label PARAMS ((const char *, const char *));
+static symbolS * create_colon_label PARAMS ((int, const char *, const char *));
static char * unique_name PARAMS ((const char *));
static long eval_expr PARAMS ((int, int, const char *, ...));
static long parse_dma_addr_autocount ();
@@ -101,13 +101,15 @@ static void push_asm_state PARAMS ((asm_state));
static void pop_asm_state PARAMS ((int));
static void set_asm_state PARAMS ((asm_state));
-/* Current mach (machine variant) type state.
+/* Current cpu (machine variant) type state.
We copy the mips16 way of recording what the current machine type is in
the code. A label is created whenever necessary and has an "other" value
the denotes the machine type. */
-static dvp_cpu cur_mach;
+static dvp_cpu cur_cpu;
/* Record the current mach type. */
-static void record_mach PARAMS ((dvp_cpu));
+static void record_mach PARAMS ((dvp_cpu, int));
+/* Given a dvp_cpu value, return the STO_DVP value to use. */
+static int cpu_sto PARAMS ((dvp_cpu, const char **));
/* Nonzero if inside .DmaData. */
static int dma_data_state = 0;
@@ -224,7 +226,7 @@ md_begin ()
/* Set the current mach to an illegal value to force a label for the
first insn. */
- cur_mach = -1;
+ cur_cpu = DVP_UNKNOWN;
/* Initialize the parsing state. */
cur_state_index = 0;
@@ -362,7 +364,7 @@ assemble_dma (str)
if (!output_dma)
return;
- record_mach (DVP_DMA);
+ record_mach (DVP_DMA, 0);
len = 4;
f = frag_more (len * 4);
@@ -434,9 +436,15 @@ assemble_vif (str)
if (output_vif)
{
/* Record the mach before doing the alignment so that we properly
- disassemble any inserted vifnop's. */
+ disassemble any inserted vifnop's. For variable length insns
+ force the recording of the mach type for the next insn. A label may
+ be embedded in it to compute the length and this will cause the
+ disassembler to wrongly disassemble the next insn. */
- record_mach (DVP_VIF);
+ if (opcode->flags & VIF_OPCODE_LENVAR)
+ record_mach (DVP_VIF, 1);
+ else
+ record_mach (DVP_VIF, 0);
if (opcode->flags & VIF_OPCODE_MPG)
{
@@ -558,7 +566,7 @@ assemble_gif (str)
frag_align (4, 0, 0);
record_alignment (now_seg, 4);
- record_mach (DVP_GIF);
+ record_mach (DVP_GIF, 1);
gif_insn_frag = f = frag_more (16);
for (i = 0; i < 4; ++i)
@@ -566,7 +574,7 @@ assemble_gif (str)
/* Insert a label so we can compute the number of quadwords when the
.endgif is seen. */
- gif_data_name = S_GET_NAME (create_colon_label ("", unique_name (NULL)));
+ gif_data_name = S_GET_NAME (create_colon_label (0, "", unique_name (NULL)));
/* Record the type of the gif tag so we know how to compute nloop
in s_endgif. */
@@ -602,7 +610,7 @@ assemble_vu (str)
frag_align (3, 0, 0);
record_alignment (now_seg, 3);
- record_mach (DVP_VUUP);
+ record_mach (DVP_VUUP, 0);
/* The lower instruction has the lower address.
Handle this by grabbing 8 bytes now, and then filling each word
@@ -968,31 +976,49 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
return 0;
}
-/* Record the current mach type in the object file. */
+/* Given a dvp cpu type, return it's STO_DVP value.
+ The section name prefix to use is stored in *PNAME. */
+
+static int
+cpu_sto (cpu, pname)
+ dvp_cpu cpu;
+ const char **pname;
+{
+ switch (cpu)
+ {
+ case DVP_DMA : *pname = ".dma."; return STO_DVP_DMA;
+ case DVP_VIF : *pname = ".vif."; return STO_DVP_VIF;
+ case DVP_GIF : *pname = ".gif."; return STO_DVP_GIF;
+ case DVP_VUUP : *pname = ".vu."; return STO_DVP_VU;
+ }
+ abort ();
+}
+
+/* Record the current mach type in the object file.
+ If FORCE_NEXT_P is non-zero, force a label to be emitted the next time
+ we're called. This is useful for variable length instructions that can
+ have labels embedded within them. */
static void
-record_mach (mach)
- dvp_cpu mach;
+record_mach (cpu, force_next_p)
+ dvp_cpu cpu;
+ int force_next_p;
{
symbolS *label;
- char *name;
- int other;
+ const char *name;
+ int sto;
- if (mach == cur_mach)
+ if (cpu == cur_cpu)
return;
- switch (mach)
- {
- case DVP_DMA : name = ".dma."; other = STO_DVP_DMA; break;
- case DVP_VIF : name = ".vif."; other = STO_DVP_VIF; break;
- case DVP_GIF : name = ".gif."; other = STO_DVP_GIF; break;
- case DVP_VUUP : name = ".vu."; other = STO_DVP_VU; break;
- default : abort ();
- }
+ sto = cpu_sto (cpu, &name);
+
+ label = create_colon_label (sto, "", unique_name (name));
- label = create_colon_label ("", unique_name (name));
- S_SET_OTHER (label, other);
- cur_mach = mach;
+ if (force_next_p)
+ cur_cpu = DVP_UNKNOWN;
+ else
+ cur_cpu = cpu;
}
/* Push/pop the current parsing state. */
@@ -1078,6 +1104,9 @@ void
dvp_frob_label (sym)
symbolS *sym;
{
+ /* All labels in vu code must be specially marked for the disassembler.
+ The disassembler ignores all previous information at each new label
+ (that has a higher address than the last one). */
if (CUR_ASM_STATE == ASM_MPG
|| CUR_ASM_STATE == ASM_VU)
S_SET_OTHER (sym, STO_DVP_VU);
@@ -1487,10 +1516,14 @@ create_label (prefix, name)
}
/* Create a label named by concatenating PREFIX to NAME,
- and define it as `.'. */
+ and define it as `.'.
+ STO, if non-zero, is the st_other value to assign to this label.
+ If STO is zero `cur_cpu' is set to DVP_UNKNOWN to force record_mach to
+ emit a cpu label. Otherwise the disassembler gets confused. */
static symbolS *
-create_colon_label (prefix, name)
+create_colon_label (sto, prefix, name)
+ int sto;
const char *prefix, *name;
{
int namelen = strlen (name);
@@ -1502,6 +1535,10 @@ create_colon_label (prefix, name)
strcpy (fullname, prefix);
strcat (fullname, name);
result = colon (fullname);
+ if (sto)
+ S_SET_OTHER (result, sto);
+ else
+ cur_cpu = DVP_UNKNOWN;
free (fullname);
return result;
}
@@ -1573,7 +1610,7 @@ inline_dma_data (autocount_p, insn_buf)
if (autocount_p)
{
- dma_data_name = S_GET_NAME (create_colon_label ("", unique_name (NULL)));
+ dma_data_name = S_GET_NAME (create_colon_label (0, "", unique_name (NULL)));
setup_dma_autocount (dma_data_name, insn_buf, 1);
}
else
@@ -1920,7 +1957,7 @@ s_enddmadata (ignore)
/* Fill the data out to a multiple of 16 bytes. */
/* FIXME: Are the fill contents right? */
frag_align (4, 0, 0);
- create_colon_label (END_LABEL_PREFIX, dma_data_name);
+ create_colon_label (0, END_LABEL_PREFIX, dma_data_name);
}
}