- secondary_out_class
- = find_secondary_reload (out, class, outmode, 0,
- &secondary_out_icode, &secondary_out_mode,
- &tertiary_out_class, &tertiary_out_icode,
- &tertiary_out_mode);
-#endif
-
- /* We can only record one secondary and one tertiary reload. If both
- IN and OUT need secondary reloads, we can only make an in-out
- reload if neither need an insn and if the classes are compatible.
- If they aren't, all we can do is abort since making two separate
- reloads is invalid. */
-
- if (secondary_class != NO_REGS && secondary_out_class != NO_REGS
- && reg_class_subset_p (secondary_out_class, secondary_class))
- secondary_class = secondary_out_class;
-
- if (secondary_class != NO_REGS && secondary_out_class != NO_REGS
- && (! reg_class_subset_p (secondary_class, secondary_out_class)
- || secondary_icode != CODE_FOR_nothing
- || secondary_out_icode != CODE_FOR_nothing))
- abort ();
-
- /* If we need a secondary reload for OUT but not IN, copy the
- information. */
- if (secondary_class == NO_REGS && secondary_out_class != NO_REGS)
- {
- secondary_class = secondary_out_class;
- secondary_icode = secondary_out_icode;
- tertiary_class = tertiary_out_class;
- tertiary_icode = tertiary_out_icode;
- tertiary_mode = tertiary_out_mode;
- }
-
- if (secondary_class != NO_REGS)
- {
- /* Secondary reloads don't conflict as badly as the primary object
- being reload. Specifically, we can always treat them as
- being for an input or output address and hence allowed to be
- reused in the same manner such address components could be
- reused. This is used as the reload_type for our secondary
- reloads. */
-
- enum reload_type secondary_type
- = (type == RELOAD_FOR_INPUT ? RELOAD_FOR_INPUT_ADDRESS
- : type == RELOAD_FOR_OUTPUT ? RELOAD_FOR_OUTPUT_ADDRESS
- : type);
-
- /* This case isn't valid, so fail. Reload is allowed to use the
- same register for RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT
- reloads, but in the case of a secondary register, we actually
- need two different registers for correct code. We fail here
- to prevent the possibility of silently generating incorrect code
- later.
-
- The convention is that secondary input reloads are valid only if
- the secondary_class is different from class. If you have such
- a case, you can not use secondary reloads, you must work around
- the problem some other way.
-
- Allow this when secondary_mode is not inmode and assume that
- the generated code handles this case (it does on the Alpha, which
- is the only place this currently happens). */
-
- if (type == RELOAD_FOR_INPUT && secondary_class == class
- && secondary_mode == inmode)
- abort ();
-
- /* If we need a tertiary reload, see if we have one we can reuse
- or else make one. */
-
- if (tertiary_class != NO_REGS)
- {
- for (tertiary_reload = 0; tertiary_reload < n_reloads;
- tertiary_reload++)
- if (reload_secondary_p[tertiary_reload]
- && (reg_class_subset_p (tertiary_class,
- reload_reg_class[tertiary_reload])
- || reg_class_subset_p (reload_reg_class[tertiary_reload],
- tertiary_class))
- && ((reload_inmode[tertiary_reload] == tertiary_mode)
- || reload_inmode[tertiary_reload] == VOIDmode)
- && ((reload_outmode[tertiary_reload] == tertiary_mode)
- || reload_outmode[tertiary_reload] == VOIDmode)
- && (reload_secondary_icode[tertiary_reload]
- == CODE_FOR_nothing)
- && (reg_class_size[(int) tertiary_class] == 1
-#ifdef SMALL_REGISTER_CLASSES
- || 1
-#endif
- )
- && MERGABLE_RELOADS (secondary_type,
- reload_when_needed[tertiary_reload],
- opnum, reload_opnum[tertiary_reload]))
- {
- if (tertiary_mode != VOIDmode)
- reload_inmode[tertiary_reload] = tertiary_mode;
- if (tertiary_out_mode != VOIDmode)
- reload_outmode[tertiary_reload] = tertiary_mode;
- if (reg_class_subset_p (tertiary_class,
- reload_reg_class[tertiary_reload]))
- reload_reg_class[tertiary_reload] = tertiary_class;
- if (MERGE_TO_OTHER (secondary_type,
- reload_when_needed[tertiary_reload],
- opnum,
- reload_opnum[tertiary_reload]))
- reload_when_needed[tertiary_reload] = RELOAD_OTHER;
- reload_opnum[tertiary_reload]
- = MIN (reload_opnum[tertiary_reload], opnum);
- reload_optional[tertiary_reload] &= optional;
- reload_secondary_p[tertiary_reload] = 1;
- }
-
- if (tertiary_reload == n_reloads)
- {
- /* We need to make a new tertiary reload for this register
- class. */
- reload_in[tertiary_reload] = reload_out[tertiary_reload] = 0;
- reload_reg_class[tertiary_reload] = tertiary_class;
- reload_inmode[tertiary_reload] = tertiary_mode;
- reload_outmode[tertiary_reload] = tertiary_mode;
- reload_reg_rtx[tertiary_reload] = 0;
- reload_optional[tertiary_reload] = optional;
- reload_inc[tertiary_reload] = 0;
- /* Maybe we could combine these, but it seems too tricky. */
- reload_nocombine[tertiary_reload] = 1;
- reload_in_reg[tertiary_reload] = 0;
- reload_opnum[tertiary_reload] = opnum;
- reload_when_needed[tertiary_reload] = secondary_type;
- reload_secondary_reload[tertiary_reload] = -1;
- reload_secondary_icode[tertiary_reload] = CODE_FOR_nothing;
- reload_secondary_p[tertiary_reload] = 1;
-
- n_reloads++;
- i = n_reloads;
- }
- }
-
- /* See if we can reuse an existing secondary reload. */
- for (secondary_reload = 0; secondary_reload < n_reloads;
- secondary_reload++)
- if (reload_secondary_p[secondary_reload]
- && (reg_class_subset_p (secondary_class,
- reload_reg_class[secondary_reload])
- || reg_class_subset_p (reload_reg_class[secondary_reload],
- secondary_class))
- && ((reload_inmode[secondary_reload] == secondary_mode)
- || reload_inmode[secondary_reload] == VOIDmode)
- && ((reload_outmode[secondary_reload] == secondary_out_mode)
- || reload_outmode[secondary_reload] == VOIDmode)
- && reload_secondary_reload[secondary_reload] == tertiary_reload
- && reload_secondary_icode[secondary_reload] == tertiary_icode
- && (reg_class_size[(int) secondary_class] == 1
-#ifdef SMALL_REGISTER_CLASSES
- || 1
-#endif
- )
- && MERGABLE_RELOADS (secondary_type,
- reload_when_needed[secondary_reload],
- opnum, reload_opnum[secondary_reload]))
- {
- if (secondary_mode != VOIDmode)
- reload_inmode[secondary_reload] = secondary_mode;
- if (secondary_out_mode != VOIDmode)
- reload_outmode[secondary_reload] = secondary_out_mode;
- if (reg_class_subset_p (secondary_class,
- reload_reg_class[secondary_reload]))
- reload_reg_class[secondary_reload] = secondary_class;
- if (MERGE_TO_OTHER (secondary_type,
- reload_when_needed[secondary_reload],
- opnum, reload_opnum[secondary_reload]))
- reload_when_needed[secondary_reload] = RELOAD_OTHER;
- reload_opnum[secondary_reload]
- = MIN (reload_opnum[secondary_reload], opnum);
- reload_optional[secondary_reload] &= optional;
- reload_secondary_p[secondary_reload] = 1;
- }
-
- if (secondary_reload == n_reloads)
- {
- /* We need to make a new secondary reload for this register
- class. */
- reload_in[secondary_reload] = reload_out[secondary_reload] = 0;
- reload_reg_class[secondary_reload] = secondary_class;
- reload_inmode[secondary_reload] = secondary_mode;
- reload_outmode[secondary_reload] = secondary_out_mode;
- reload_reg_rtx[secondary_reload] = 0;
- reload_optional[secondary_reload] = optional;
- reload_inc[secondary_reload] = 0;
- /* Maybe we could combine these, but it seems too tricky. */
- reload_nocombine[secondary_reload] = 1;
- reload_in_reg[secondary_reload] = 0;
- reload_opnum[secondary_reload] = opnum;
- reload_when_needed[secondary_reload] = secondary_type;
- reload_secondary_reload[secondary_reload] = tertiary_reload;
- reload_secondary_icode[secondary_reload] = tertiary_icode;
- reload_secondary_p[secondary_reload] = 1;
-
- n_reloads++;
- i = n_reloads;
-
-#ifdef SECONDARY_MEMORY_NEEDED
- /* If we need a memory location to copy between the two
- reload regs, set it up now. */
-
- if (in != 0 && secondary_icode == CODE_FOR_nothing
- && SECONDARY_MEMORY_NEEDED (secondary_class, class, inmode))
- get_secondary_mem (in, inmode, opnum, type);
-
- if (out != 0 && secondary_icode == CODE_FOR_nothing
- && SECONDARY_MEMORY_NEEDED (class, secondary_class, outmode))
- get_secondary_mem (out, outmode, opnum, type);
-#endif
- }
- }