From fa1e3be84c08373b9d1d546da2466cd1aa00a53b Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Wed, 4 Dec 1996 23:47:30 +0000 Subject: [PATCH] Wed Dec 4 15:42:41 1996 Martin M. Hunt * tc-d10v.c (md_assemble, d10v_cleanup): Fix bug with multiple sections. --- gas/config/tc-d10v.c | 70 +++++++++++--------------------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c index a7e98b76897..1bd9debea21 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; -- 2.30.2