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}
asection *sec;
fragS *fragP;
{
- printf ("call to md_convert_frag \n");
abort ();
}
{
int bits = op->bits;
- /* printf("get_reloc: bits=%d address=%d\n",bits,op->flags & OPERAND_ADDR); */
if (bits <= 4)
return (0);
{
/* 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");
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++)
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;
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++)
{
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;
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)
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.");
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);
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,
/* 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];
|| (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 */
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 */
/* 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);
{
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 */
expressionS myops[6];
unsigned long insn;
- /* printf("do_assemble: str=%s\n",str); */
-
/* Drop leading whitespace */
while (*str == ' ')
str++;
input_line_pointer = save;
insn = build_insn ((*opcode), myops, 0);
- /* printf("sub-insn = %lx\n",insn); */
return (insn);
}
return NULL;
}
reloc->addend = fixp->fx_addnumber;
- /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
return reloc;
}
{
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;
}
}
}
- /* 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)
{
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;
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
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;