This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Changes To Fixup Saving, Restoring and Swapping
- To: cgen at sources dot redhat dot com, binutils at sources dot redhat dot com
- Subject: Re: Changes To Fixup Saving, Restoring and Swapping
- From: John Healy <jhealy at redhat dot com>
- Date: Fri, 06 Jul 2001 15:11:42 -0400
- References: <3B449A0D.33C3DCCA@redhat.com> <3B44A559.2E890F58.cygnus.local.cgen@redhat.com>
Committed.
John
>
>
> ------------------------------------------------------------------------
> [gas]
>
> 2001-07-05 John Healy <jhealy@redhat.com>
>
> * cgen.c (gas_cgen_save_fixups): Modified to allow more than one
> set of fixups to be stored.
> (gas_cgen_restore_fixups): Modified to allow the fixup chain to be
> restored to be chosen from any that are saved.
> (gas_cgen_swap_fixups): Modified to allow the current set of
> fixups to be swapped with any other set that has been saved.
> (gas_cgen_initialize_saved_fixups_array): New routine.
> * cgen.h: Modifed prototypes for gas_cgen_save_fixups,
> gas_cgen_restore_fixups, and gas_cgen_swap_fixups. Added definitions
> for MAX_SAVED_FIXUP_CHAINS.
> * config/tc-m32r.c (assemble_two_insns): Changed calls to fixup
> store, swap and restore fuctions to reflect the new interface.
>
> ------------------------------------------------------------------------
> Index: gas/cgen.c
> ===================================================================
> RCS file: /cvs/src/src/gas/cgen.c,v
> retrieving revision 1.12
> diff -c -3 -p -r1.12 cgen.c
> *** cgen.c 2001/05/16 23:06:02 1.12
> --- cgen.c 2001/07/05 17:24:01
> *************** queue_fixup (opindex, opinfo, expP)
> *** 94,155 ****
> ++ num_fixups;
> }
>
> ! /* The following three functions allow a backup of the fixup chain to be made,
> ! and to have this backup be swapped with the current chain. This allows
> ! certain ports, eg the m32r, to swap two instructions and swap their fixups
> ! at the same time. */
> ! /* ??? I think with cgen_asm_finish_insn (or something else) there is no
> ! more need for this. */
>
> ! static struct fixup saved_fixups[GAS_CGEN_MAX_FIXUPS];
> ! static int saved_num_fixups;
>
> ! void
> ! gas_cgen_save_fixups ()
> {
> ! saved_num_fixups = num_fixups;
> !
> ! memcpy (saved_fixups, fixups, sizeof (fixups[0]) * num_fixups);
> !
> ! num_fixups = 0;
> }
>
> ! void
> ! gas_cgen_restore_fixups ()
> {
> ! num_fixups = saved_num_fixups;
> !
> ! memcpy (fixups, saved_fixups, sizeof (fixups[0]) * num_fixups);
>
> ! saved_num_fixups = 0;
> }
>
> ! void
> ! gas_cgen_swap_fixups ()
> {
> ! int tmp;
> ! struct fixup tmp_fixup;
>
> ! if (num_fixups == 0)
> ! {
> ! gas_cgen_restore_fixups ();
> ! }
> ! else if (saved_num_fixups == 0)
> ! {
> ! gas_cgen_save_fixups ();
> ! }
> ! else
> ! {
> ! tmp = saved_num_fixups;
> ! saved_num_fixups = num_fixups;
> ! num_fixups = tmp;
> !
> ! for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
> ! {
> ! tmp_fixup = saved_fixups [tmp];
> ! saved_fixups [tmp] = fixups [tmp];
> ! fixups [tmp] = tmp_fixup;
> ! }
> }
> }
>
> --- 94,208 ----
> ++ num_fixups;
> }
>
> ! /* The following functions allow fixup chains to be stored, retrieved,
> ! and swapped. They are a generalization of a pre-existing scheme
> ! for storing, restoring and swapping fixup chains that was used by
> ! the m32r port. The functionality is essentially the same, only
> ! instead of only being able to store a single fixup chain, an entire
> ! array of fixup chains can be stored. It is the user's responsibility
> ! to keep track of how many fixup chains have been stored and which
> ! elements of the array they are in.
> !
> ! The algorithms used are the same as in the old scheme. Other than the
> ! "array-ness" of the whole thing, the functionality is identical to the
> ! old scheme.
> !
> ! gas_cgen_initialize_saved_fixups_array():
> ! Sets num_fixups_in_chain to 0 for each element. Call this from
> ! md_begin() if you plan to use these functions and you want the
> ! fixup count in each element to be set to 0 intially. This is
> ! not necessary, but it's included just in case. It performs
> ! the same function for each element in the array of fixup chains
> ! that gas_init_parse() performs for the current fixups.
> !
> ! gas_cgen_save_fixups (element):
> ! element - element number of the array you wish to store the fixups
> ! to. No mechanism is built in for tracking what element
> ! was last stored to.
> !
> ! gas_cgen_restore_fixups (element):
> ! element - element number of the array you wish to restore the fixups
> ! from.
> !
> ! gas_cgen_swap_fixups(int element):
> ! element - swap the current fixups with those in this element number.
> ! */
> !
> ! struct saved_fixups {
> ! struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
> ! int num_fixups_in_chain;
> ! };
>
> ! static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
>
> ! void
> ! gas_cgen_initialize_saved_fixups_array()
> {
> ! int i = 0;
> ! while (i < MAX_SAVED_FIXUP_CHAINS)
> ! stored_fixups[i++].num_fixups_in_chain = 0;
> }
>
> ! void
> ! gas_cgen_save_fixups (int i)
> {
> ! if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
> ! {
> ! as_fatal("Index into stored_fixups[] out of bounds.");
> ! return;
> ! }
> ! stored_fixups[i].num_fixups_in_chain = num_fixups;
> ! memcpy(stored_fixups[i].fixup_chain, fixups,
> ! sizeof (fixups[0])*num_fixups);
> ! num_fixups = 0;
> ! }
>
> ! void
> ! gas_cgen_restore_fixups(int i)
> ! {
> ! if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
> ! {
> ! as_fatal("Index into stored_fixups[] out of bounds.");
> ! return;
> ! }
> ! num_fixups = stored_fixups[i].num_fixups_in_chain;
> ! memcpy(fixups,stored_fixups[i].fixup_chain,
> ! (sizeof (stored_fixups[i].fixup_chain[0]))*num_fixups);
> ! stored_fixups[i].num_fixups_in_chain = 0;
> }
>
> ! void
> ! gas_cgen_swap_fixups(int i)
> {
> ! int tmp;
> ! struct fixup tmp_fixup;
>
> ! if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
> ! {
> ! as_fatal("Index into stored_fixups[] out of bounds.");
> ! return;
> ! }
> !
> ! if (num_fixups == 0)
> ! {
> ! gas_cgen_restore_fixups (i);
> ! }
> ! else if (stored_fixups[i].num_fixups_in_chain == 0)
> ! {
> ! gas_cgen_save_fixups (i);
> ! }
> ! else
> ! {
> ! tmp = stored_fixups[i].num_fixups_in_chain;
> ! stored_fixups[i].num_fixups_in_chain = num_fixups;
> ! num_fixups = tmp;
> !
> ! for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
> ! {
> ! tmp_fixup = stored_fixups[i].fixup_chain [tmp];
> ! stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
> ! fixups [tmp] = tmp_fixup;
> ! }
> }
> }
>
> Index: gas/cgen.h
> ===================================================================
> RCS file: /cvs/src/src/gas/cgen.h,v
> retrieving revision 1.7
> diff -c -3 -p -r1.7 cgen.h
> *** cgen.h 2001/03/08 23:24:22 1.7
> --- cgen.h 2001/07/05 17:24:01
> *************** extern const char * gas_cgen_parse_opera
> *** 53,61 ****
> /* Call this from md_assemble to initialize the assembler callback. */
> extern void gas_cgen_init_parse PARAMS ((void));
>
> ! extern void gas_cgen_save_fixups PARAMS ((void));
> ! extern void gas_cgen_restore_fixups PARAMS ((void));
> ! extern void gas_cgen_swap_fixups PARAMS ((void));
>
> /* Add a register to the assembler's hash table.
> This makes lets GAS parse registers for us.
> --- 53,64 ----
> /* Call this from md_assemble to initialize the assembler callback. */
> extern void gas_cgen_init_parse PARAMS ((void));
>
> ! /* Routines and macros for saving fixup chains. */
> ! extern void gas_cgen_save_fixups PARAMS ((int));
> ! extern void gas_cgen_restore_fixups PARAMS ((int));
> ! extern void gas_cgen_swap_fixups PARAMS ((int));
> ! extern void gas_cgen_initialize_saved_fixups_array PARAMS ((void));
> ! #define MAX_SAVED_FIXUP_CHAINS 50
>
> /* Add a register to the assembler's hash table.
> This makes lets GAS parse registers for us.
> Index: gas/config/tc-m32r.c
> ===================================================================
> RCS file: /cvs/src/src/gas/config/tc-m32r.c,v
> retrieving revision 1.19
> diff -c -3 -p -r1.19 tc-m32r.c
> *** tc-m32r.c 2001/05/10 11:32:51 1.19
> --- tc-m32r.c 2001/07/05 17:24:02
> *************** md_begin ()
> *** 554,559 ****
> --- 554,561 ----
> scom_symbol.section = &scom_section;
>
> allow_m32rx (enable_m32rx);
> +
> + gas_cgen_initialize_saved_fixups_array();
> }
>
> #define OPERAND_IS_COND_BIT(operand, indices, index) \
> *************** assemble_two_insns (str, str2, parallel_
> *** 832,838 ****
>
> /* Preserve any fixups that have been generated and reset the list
> to empty. */
> ! gas_cgen_save_fixups ();
>
> /* Get the indices of the operands of the instruction. */
> /* FIXME: CGEN_FIELDS is already recorded, but relying on that fact
> --- 834,840 ----
>
> /* Preserve any fixups that have been generated and reset the list
> to empty. */
> ! gas_cgen_save_fixups (0);
>
> /* Get the indices of the operands of the instruction. */
> /* FIXME: CGEN_FIELDS is already recorded, but relying on that fact
> *************** assemble_two_insns (str, str2, parallel_
> *** 941,947 ****
> || (errmsg = (char *) can_make_parallel (&first, &second)) == NULL)
> {
> /* Get the fixups for the first instruction. */
> ! gas_cgen_swap_fixups ();
>
> /* Write it out. */
> expand_debug_syms (first.debug_sym_link, 1);
> --- 943,949 ----
> || (errmsg = (char *) can_make_parallel (&first, &second)) == NULL)
> {
> /* Get the fixups for the first instruction. */
> ! gas_cgen_swap_fixups (0);
>
> /* Write it out. */
> expand_debug_syms (first.debug_sym_link, 1);
> *************** assemble_two_insns (str, str2, parallel_
> *** 953,959 ****
> make_parallel (second.buffer);
>
> /* Get its fixups. */
> ! gas_cgen_restore_fixups ();
>
> /* Write it out. */
> expand_debug_syms (second.debug_sym_link, 1);
> --- 955,961 ----
> make_parallel (second.buffer);
>
> /* Get its fixups. */
> ! gas_cgen_restore_fixups (0);
>
> /* Write it out. */
> expand_debug_syms (second.debug_sym_link, 1);
> *************** assemble_two_insns (str, str2, parallel_
> *** 972,978 ****
> make_parallel (first.buffer);
>
> /* Get the fixups for the first instruction. */
> ! gas_cgen_restore_fixups ();
>
> /* Write out the first instruction. */
> expand_debug_syms (first.debug_sym_link, 1);
> --- 974,980 ----
> make_parallel (first.buffer);
>
> /* Get the fixups for the first instruction. */
> ! gas_cgen_restore_fixups (0);
>
> /* Write out the first instruction. */
> expand_debug_syms (first.debug_sym_link, 1);