From f2980bb4780a1bb599e9c9bd458c2b502c5185f4 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Mon, 27 Apr 1998 19:36:06 +0000 Subject: [PATCH] * cgen.c (cgen_asm_finish_insn): New arg relax_p. All callers updated. * config/tc-m32r.c (assemble_parallel_insn): No need to try non-relaxable variant any more. Simplify test for nop insn. (md_assemble): Only scan operands if m32rx. Set orig_insn in case scan of operands yields an insn different from original (e.g. a macro). Fix call to can_make_parallel. --- gas/ChangeLog | 11 +++ gas/config/tc-m32r.c | 168 +++++++++++++++++-------------------------- 2 files changed, 78 insertions(+), 101 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index b6d93f94d8c..90350ca66f7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +Mon Apr 27 12:07:33 1998 Doug Evans + + * cgen.c (cgen_asm_finish_insn): New arg relax_p. All callers updated. +start-sanitize-m32rx + * config/tc-m32r.c (assemble_parallel_insn): No need to try + non-relaxable variant any more. Simplify test for nop insn. + (md_assemble): Only scan operands if m32rx. Set orig_insn in case + scan of operands yields an insn different from original (e.g. a macro). + Fix call to can_make_parallel. +end-sanitize-m32rx + Mon Apr 27 15:16:12 1998 Ian Lance Taylor * ecoff.h: Change symbolS in function declaration to struct diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c index 9991b6b6d7d..aee758336d0 100644 --- a/gas/config/tc-m32r.c +++ b/gas/config/tc-m32r.c @@ -555,6 +555,7 @@ can_make_parallel (a, b) } #ifdef CGEN_INT_INSN + static void make_parallel (buffer) cgen_insn_t * buffer; @@ -576,7 +577,9 @@ make_parallel (buffer) bfd_putl16 (value, (char *) buffer); } } + #else + static void make_parallel (buffer) char * buffer; @@ -585,8 +588,8 @@ make_parallel (buffer) buffer [CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG ? 0 : 1] |= 0x80; } -#endif +#endif /* ! CGEN_INT_INSN */ static void assemble_parallel_insn (str, str2) @@ -612,61 +615,31 @@ assemble_parallel_insn (str, str2) as_bad (errmsg); return; } - - /* Check to see if this is an allowable parallel insn. */ - if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_PIPE) == PIPE_NONE) - { - as_bad (_("instruction '%s' cannot be executed in parallel."), str); - return; - } - + if (! enable_m32rx + /* FIXME: Need standard macro to perform this test. */ && CGEN_INSN_ATTR (first.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX)) { as_bad (_("instruction '%s' is for the M32RX only"), str); return; } - - /* Temporary Hack: - If the instruciton is relaxable, reparse it looking for a non-relaxable variant. - (We do not want to relax instructions inside a parallel construction, and if it - turns out that the branch is too far for the displacement field available to the - non-relaxed instruction, then this is the programmer's fault. - A better solution would be to pass attribute requirements to assemble_insn() so - that the relaxable variant would not be accepted as a valid parse of the instruction. */ - - if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_RELAXABLE) != 0) - { - char buf[128]; - char * p; - /* Oh dear - the insn is relaxable, so it might be replaced with a longer, - non-parallel version. Try appending ".s" to the instruction and reparsing it. */ - - p = strchr (str, ' '); - if (p == NULL) - abort(); - * p = 0; - sprintf (buf, "%s.s %s", str, p + 1); - * p = ' '; - /* Reset fixup list to empty. */ - cgen_save_fixups(); - - first.insn = CGEN_SYM (assemble_insn) (buf, & first.fields, first.buffer, & errmsg); - - if (first.insn == NULL) - abort(); + /* Check to see if this is an allowable parallel insn. */ + if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_PIPE) == PIPE_NONE) + { + as_bad (_("instruction '%s' cannot be executed in parallel."), str); + return; } *str2 = '|'; /* Restore the original assembly text, just in case it is needed. */ str3 = str; /* Save the original string pointer. */ str = str2 + 2; /* Advanced past the parsed string. */ str2 = str3; /* Remember the entire string in case it is needed for error messages. */ - + /* Preserve any fixups that have been generated and reset the list to empty. */ cgen_save_fixups(); - /* Get the indicies of the operands of the instruction. */ + /* Get the indices of the operands of the instruction. */ /* FIXME: CGEN_FIELDS is already recorded, but relying on that fact doesn't seem right. Perhaps allow passing fields like we do insn. */ /* FIXME: ALIAS insns do not have operands, so we use this function @@ -676,10 +649,12 @@ assemble_parallel_insn (str, str2) version (eg relaxability). When aliases behave differently this may have to change. */ first.orig_insn = first.insn; - first.insn = m32r_cgen_get_insn_operands (first.insn, bfd_getb16 ((char *) first.buffer), 16, - first.indices); + first.insn = m32r_cgen_lookup_get_insn_operands (NULL, + bfd_getb16 ((char *) first.buffer), + 16, + first.indices); if (first.insn == NULL) - as_fatal (_("internal error: m32r_cgen_get_insn_operands failed for first insn")); + as_fatal (_("internal error: m32r_cgen_lookup_get_insn_operands failed for first insn")); /* Parse the second instruction. */ if (! (second.insn = CGEN_SYM (assemble_insn) @@ -696,48 +671,32 @@ assemble_parallel_insn (str, str2) as_bad (_("instruction '%s' is for the M32RX only"), str); return; } + + /* Check to see if this is an allowable parallel insn. */ + if (CGEN_INSN_ATTR (second.insn, CGEN_INSN_PIPE) == PIPE_NONE) + { + as_bad (_("instruction '%s' cannot be executed in parallel."), str); + return; + } if (! enable_m32rx) { - if ( strcmp (first.insn->name, "nop") != 0 - && strcmp (second.insn->name, "nop") != 0) + if (CGEN_INSN_NUM (first.insn) != M32R_INSN_NOP + && CGEN_INSN_NUM (second.insn) != M32R_INSN_NOP) { as_bad (_("'%s': only the NOP instruction can be issued in parallel on the m32r"), str2); return; } } - /* See comment above. */ - if (CGEN_INSN_ATTR (second.insn, CGEN_INSN_RELAXABLE) != 0) - { - char buf[128]; - char * p; - /* Oh dear - the insn is relaxable, so it might be replaced with a longer, - non-parallel version. Try appending ".s" to the instruction and reparsing it. */ - - p = strchr (str, ' '); - if (p == NULL) - abort(); - * p = 0; - sprintf (buf, "%s.s %s", str, p + 1); - * p = ' '; - - /* Reset fixup list to empty, preserving saved fixups. */ - cgen_restore_fixups(); - cgen_save_fixups(); - - second.insn = CGEN_SYM (assemble_insn) (buf, & second.fields, second.buffer, & errmsg); - - if (second.insn == NULL) - abort(); - } - - /* Get the indicies of the operands of the instruction. */ + /* Get the indices of the operands of the instruction. */ second.orig_insn = second.insn; - second.insn = m32r_cgen_get_insn_operands (second.insn, bfd_getb16 ((char *) second.buffer), 16, - second.indices); + second.insn = m32r_cgen_lookup_get_insn_operands (NULL, + bfd_getb16 ((char *) second.buffer), + 16, + second.indices); if (second.insn == NULL) - as_fatal (_("internal error: m32r_cgen_get_insn_operands failed for second insn")); + as_fatal (_("internal error: m32r_cgen_lookup_get_insn_operands failed for second insn")); /* We assume that if the first instruction writes to a register that is read by the second instruction it is because the programmer intended @@ -763,7 +722,7 @@ assemble_parallel_insn (str, str2) /* Write it out. */ (void) cgen_asm_finish_insn (first.orig_insn, first.buffer, - CGEN_FIELDS_BITSIZE (& first.fields)); + CGEN_FIELDS_BITSIZE (& first.fields), 0); /* Force the top bit of the second insn to be set. */ make_parallel (second.buffer); @@ -773,14 +732,14 @@ assemble_parallel_insn (str, str2) /* Write it out. */ (void) cgen_asm_finish_insn (second.orig_insn, second.buffer, - CGEN_FIELDS_BITSIZE (& second.fields)); + CGEN_FIELDS_BITSIZE (& second.fields), 0); } /* Try swapping the instructions to see if they work that way. */ else if (can_make_parallel (& second, & first) == NULL) { /* Write out the second instruction first. */ (void) cgen_asm_finish_insn (second.orig_insn, second.buffer, - CGEN_FIELDS_BITSIZE (& second.fields)); + CGEN_FIELDS_BITSIZE (& second.fields), 0); /* Force the top bit of the first instruction to be set. */ make_parallel (first.buffer); @@ -790,7 +749,7 @@ assemble_parallel_insn (str, str2) /* Write out the first instruction. */ (void) cgen_asm_finish_insn (first.orig_insn, first.buffer, - CGEN_FIELDS_BITSIZE (& first.fields)); + CGEN_FIELDS_BITSIZE (& first.fields), 0); } else { @@ -801,8 +760,6 @@ assemble_parallel_insn (str, str2) /* Set these so m32r_fill_insn can use them. */ prev_seg = now_seg; prev_subseg = now_subseg; - - return; } /* end-sanitize-m32rx */ @@ -852,9 +809,10 @@ md_assemble (str) pig, can we call assemble_nop instead of !seen_relaxable_p? */ fill_insn (0); } - + + /* Doesn't really matter what we pass for RELAX_P here. */ (void) cgen_asm_finish_insn (insn.insn, insn.buffer, - CGEN_FIELDS_BITSIZE (& insn.fields)); + CGEN_FIELDS_BITSIZE (& insn.fields), 1); } else { @@ -863,17 +821,24 @@ md_assemble (str) int swap = false; /* end-sanitize-phase2-m32rx */ /* end-sanitize-m32rx */ - + if (CGEN_INSN_BITSIZE (insn.insn) != 16) abort(); - - /* Get the indices of the operands of the instruction. */ - insn.insn = m32r_cgen_get_insn_operands (insn.insn, - bfd_getb16 ((char *) insn.buffer), - 16, - insn.indices); - if (insn.insn == NULL) - as_fatal (_("internal error: m32r_cgen_get_insn_operands failed")); + + if (enable_m32rx) + { + /* Get the indices of the operands of the instruction. + FIXME: See assemble_parallel for notes on orig_insn. */ + insn.orig_insn = insn.insn; + insn.insn = m32r_cgen_lookup_get_insn_operands (NULL, + bfd_getb16 ((char *) insn.buffer), + 16, + insn.indices); + if (insn.insn == NULL) + as_fatal (_("internal error: m32r_cgen_get_insn_operands failed")); + } + else + insn.orig_insn = insn.insn; /* Keep track of whether we've seen a pair of 16 bit insns. prev_insn.insn is NULL when we're on a 32 bit boundary. */ @@ -891,21 +856,21 @@ md_assemble (str) input to the current instruction then it cannot be combined. Otherwise call can_make_parallel() with both orderings of the instructions to see if they can be combined. */ - if ( enable_m32rx - && optimize - && CGEN_INSN_ATTR (insn.insn, CGEN_INSN_RELAXABLE) == 0 + if ( enable_m32rx + && optimize + && CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_RELAXABLE) == 0 && ! writes_to_pc (& prev_insn) && ! first_writes_to_seconds_operands (& prev_insn, &insn, false) ) { if (can_make_parallel (& prev_insn, & insn) == NULL) make_parallel (insn.buffer); - else if (can_make_parallel (& insn, & prev_insn.insn) == NULL) + else if (can_make_parallel (& insn, & prev_insn) == NULL) swap = true; } /* end-sanitize-phase2-m32rx */ /* end-sanitize-m32rx */ - + prev_insn.insn = NULL; } else @@ -915,15 +880,16 @@ md_assemble (str) /* Record the frag that might be used by this insn. */ insn.frag = frag_now; - insn.addr = cgen_asm_finish_insn (insn.insn, insn.buffer, - CGEN_FIELDS_BITSIZE (& insn.fields)); + insn.addr = cgen_asm_finish_insn (insn.orig_insn, insn.buffer, + CGEN_FIELDS_BITSIZE (& insn.fields), + 1 /*relax_p*/); /* start-sanitize-m32rx */ /* start-sanitize-phase2-m32rx */ if (swap) { int tmp; - + #define SWAP_BYTES(a,b) tmp = a; a = b; b = tmp /* Swap the two insns */ @@ -948,13 +914,13 @@ md_assemble (str) /* If the insn needs the following one to be on a 32 bit boundary (e.g. subroutine calls), fill this insn's slot. */ if (prev_insn.insn != NULL - && CGEN_INSN_ATTR (insn.insn, CGEN_INSN_FILL_SLOT) != 0) + && CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_FILL_SLOT) != 0) fill_insn (0); /* If this is a relaxable insn (can be replaced with a larger version) mark the fact so that we can emit an alignment directive for a following 32 bit insn if we see one. */ - if (CGEN_INSN_ATTR (insn.insn, CGEN_INSN_RELAXABLE) != 0) + if (CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_RELAXABLE) != 0) seen_relaxable_p = 1; } -- 2.30.2