aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-d10v.c
diff options
context:
space:
mode:
authorMartin Hunt <hunt@redhat.com>1996-12-04 23:47:30 +0000
committerMartin Hunt <hunt@redhat.com>1996-12-04 23:47:30 +0000
commitfa1e3be84c08373b9d1d546da2466cd1aa00a53b (patch)
tree71b11d6af7cd114bc1b8588358e57fa1689e1e07 /gas/config/tc-d10v.c
parent996bee906f8cac2c8ecb14dbe4b434e6dc46881a (diff)
downloadgdb-fa1e3be84c08373b9d1d546da2466cd1aa00a53b.zip
gdb-fa1e3be84c08373b9d1d546da2466cd1aa00a53b.tar.gz
gdb-fa1e3be84c08373b9d1d546da2466cd1aa00a53b.tar.bz2
Wed Dec 4 15:42:41 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* tc-d10v.c (md_assemble, d10v_cleanup): Fix bug with multiple sections.
Diffstat (limited to 'gas/config/tc-d10v.c')
-rw-r--r--gas/config/tc-d10v.c70
1 files changed, 17 insertions, 53 deletions
diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c
index a7e98b7..1bd9deb 100644
--- a/gas/config/tc-d10v.c
+++ b/gas/config/tc-d10v.c
@@ -75,8 +75,8 @@ static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode
static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
offsetT value, int left, fixS *fix));
static int parallel_ok PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
- struct d10v_opcode *opcode2, unsigned long insn2));
-
+ struct d10v_opcode *opcode2, unsigned long insn2,
+ int exec_type));
struct option md_longopts[] = {
{NULL, no_argument, NULL, 0}
@@ -279,7 +279,6 @@ md_convert_frag (abfd, sec, fragP)
asection *sec;
fragS *fragP;
{
- printf ("call to md_convert_frag \n");
abort ();
}
@@ -354,7 +353,6 @@ get_reloc (op)
{
int bits = op->bits;
- /* printf("get_reloc: bits=%d address=%d\n",bits,op->flags & OPERAND_ADDR); */
if (bits <= 4)
return (0);
@@ -532,12 +530,6 @@ build_insn (opcode, opers, insn)
{
/* now create a fixup */
- /*
- printf("need a fixup: ");
- print_expr_1(stdout,&opers[i]);
- printf("\n");
- */
-
if (fixups->fc >= MAX_INSN_FIXUPS)
as_fatal ("too many fixups");
@@ -588,7 +580,6 @@ write_long (opcode, insn, fx)
char *f = frag_more(4);
insn |= FM11;
- /* printf("INSN: %08x\n",insn); */
number_to_chars_bigendian (f, insn, 4);
for (i=0; i < fx->fc; i++)
@@ -598,11 +589,6 @@ write_long (opcode, insn, fx)
where = f - frag_now->fr_literal;
if (fx->fix[i].size == 2)
where += 2;
- /*
- printf("fix_new_exp: where:%x size:%d\n ",where,fx->fix[i].size);
- print_expr_1(stdout,&(fx->fix[i].exp));
- printf("\n");
- */
if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
fx->fix[i].operand |= 4096;
@@ -640,7 +626,6 @@ write_1_short (opcode, insn, fx)
else
insn = FM00 | (insn << 15) | NOP; /* left container */
- /* printf("INSN: %08x\n",insn); */
number_to_chars_bigendian (f, insn, 4);
for (i=0; i < fx->fc; i++)
{
@@ -650,12 +635,6 @@ write_1_short (opcode, insn, fx)
if (fx->fix[i].size == 2)
where += 2;
- /*
- printf("fix_new_exp: where:%x size:%d\n ",where, fx->fix[i].size);
- print_expr_1(stdout,&(fx->fix[i].exp));
- printf("\n");
- */
-
if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
fx->fix[i].operand |= 4096;
@@ -705,7 +684,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
switch (exec_type)
{
case 0: /* order not specified */
- if ( Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2))
+ if ( Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
{
/* parallel */
if (opcode1->unit == IU)
@@ -734,7 +713,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
as_fatal ("One of these instructions may not be executed in parallel.");
- if ( !parallel_ok (opcode1, insn1, opcode2, insn2)
+ if ( !parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)
&& (opcode1->exec_type & PARONLY) == 0
&& (opcode2->exec_type & PARONLY) == 0)
as_fatal ("Two instructions may not be executed in parallel with each other.");
@@ -775,7 +754,6 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
as_fatal("unknown execution type passed to write_2_short()");
}
- /* printf("INSN: %08x\n",insn); */
f = frag_more(4);
number_to_chars_bigendian (f, insn, 4);
@@ -795,12 +773,6 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
fx->fix[i].operand |= 4096;
- /*
- printf("fix_new_exp: where:%x reloc:%d\n ",where,fx->fix[i].operand);
- print_expr_1(stdout,&(fx->fix[i].exp));
- printf("\n");
- */
-
fix_new_exp (frag_now,
where,
fx->fix[i].size,
@@ -819,9 +791,10 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
/* Check 2 instructions and determine if they can be safely */
/* executed in parallel. Returns 1 if they can be. */
static int
-parallel_ok (op1, insn1, op2, insn2)
+parallel_ok (op1, insn1, op2, insn2, exec_type)
struct d10v_opcode *op1, *op2;
unsigned long insn1, insn2;
+ int exec_type;
{
int i, j, flags, mask, shift, regno;
unsigned long ins, mod[2], used[2];
@@ -834,6 +807,11 @@ parallel_ok (op1, insn1, op2, insn2)
|| (op1->unit == MU && op2->unit == MU))
return 0;
+ /* If the first instruction is a branch and this is auto parallazation,
+ don't combine with any second instruction. */
+ if (exec_type == 0 && (op1->exec_type & BRANCH) != 0)
+ return 0;
+
/* The idea here is to create two sets of bitmasks (mod and used) */
/* which indicate which registers are modified or used by each instruction. */
/* The operation can only be done in parallel if instruction 1 and instruction 2 */
@@ -939,8 +917,6 @@ md_assemble (str)
static int etype=0; /* saved extype. used for multiline instructions */
char *str2;
- /* printf("md_assemble: str=%s\n",str); */
-
if (etype == 0)
{
/* look for the special multiple instruction separators */
@@ -966,8 +942,7 @@ md_assemble (str)
/* if two instructions are present and we already have one saved
then first write it out */
- if (prev_opcode)
- write_1_short (prev_opcode, prev_insn, fixups->next);
+ d10v_cleanup(0);
/* assemble first instruction and save it */
prev_insn = do_assemble (str, &prev_opcode);
@@ -1000,16 +975,15 @@ md_assemble (str)
{
if (extype)
as_fatal("Unable to mix instructions as specified");
- if (prev_opcode)
- {
- write_1_short (prev_opcode, prev_insn, fixups->next);
- prev_opcode = NULL;
- }
+ d10v_cleanup(0);
write_long (opcode, insn, fixups);
prev_opcode = NULL;
return;
}
+ if (prev_opcode && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
+ d10v_cleanup(0);
+
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
{
/* no instructions saved */
@@ -1044,8 +1018,6 @@ do_assemble (str, opcode)
expressionS myops[6];
unsigned long insn;
- /* printf("do_assemble: str=%s\n",str); */
-
/* Drop leading whitespace */
while (*str == ' ')
str++;
@@ -1078,7 +1050,6 @@ do_assemble (str, opcode)
input_line_pointer = save;
insn = build_insn ((*opcode), myops, 0);
- /* printf("sub-insn = %lx\n",insn); */
return (insn);
}
@@ -1270,7 +1241,6 @@ tc_gen_reloc (seg, fixp)
return NULL;
}
reloc->addend = fixp->fx_addnumber;
- /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
return reloc;
}
@@ -1290,7 +1260,6 @@ md_pcrel_from_section (fixp, sec)
{
if (fixp->fx_addsy != (symbolS *)NULL && !S_IS_DEFINED (fixp->fx_addsy))
return 0;
- /* printf("pcrel_from_section: %x\n", fixp->fx_frag->fr_address + fixp->fx_where); */
return fixp->fx_frag->fr_address + fixp->fx_where;
}
@@ -1329,8 +1298,6 @@ md_apply_fix3 (fixp, valuep, seg)
}
}
- /* printf("md_apply_fix: value=0x%x type=0x%x where=0x%x size=%d line=%d\n", value, fixp->fx_r_type,fixp->fx_where,fixp->fx_size, fixp->fx_line); */
-
op_type = fixp->fx_r_type;
if (op_type & 2048)
{
@@ -1367,9 +1334,7 @@ md_apply_fix3 (fixp, valuep, seg)
bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
else
{
- /* printf(" insn=%x value=%x where=%x pcrel=%x\n",insn,value,fixp->fx_where,fixp->fx_pcrel); */
insn = d10v_insert_operand (insn, op_type, (offsetT)value, left, fixp);
- /* printf(" new insn=%x\n",insn); */
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
}
break;
@@ -1385,7 +1350,6 @@ md_apply_fix3 (fixp, valuep, seg)
return 0;
}
-
/* d10v_cleanup() is called after the assembler has finished parsing the input
file or after a label is defined. Because the D10V assembler sometimes saves short
instructions to see if it can package them with the next instruction, there may
@@ -1397,7 +1361,7 @@ d10v_cleanup (done)
segT seg;
subsegT subseg;
- if ( prev_opcode && (done || (now_seg == prev_seg) && (now_subseg == prev_subseg)))
+ if (prev_opcode)
{
seg = now_seg;
subseg = now_subseg;