Thread View: gnu.gcc.bug
1 messages
1 total messages
Started by LIOCHON
Thu, 01 Oct 1992 14:01
help for reloading
Author: LIOCHON
Date: Thu, 01 Oct 1992 14:01
Date: Thu, 01 Oct 1992 14:01
265 lines
8631 bytes
8631 bytes
I am trying to implement floats and doubles for the ST9
microcontroller, starting from the GCC version 1.39.90
modified by Pierre Willard (TCE LA) to be used on the ST9
8/16 bit microcontroller.
GCC9 (GCC for the ST9 microcontroller) can use 8 16-bit registers
(rr0, rr2, rr4, rr6, rr8, rr10, rr12, rr14).
rr12 is used to store the frame pointer.
A ST9 double is 64-bit long, therefore 4 registers are needed to
store a double.
I got problems in the reloading phase as there are some limitations
within GCC (see below some comments in reload1.c).
I send you a few modifications, which solve partly the problem
although I am not sure it can be of any use to you.
I think my problems come from the fact that machine modes that
require groups of more than 2 consecutive registers are not properly
handled by gcc-1.39.90.
Do you know if these limitations have been removed in more recent
versions of GCC ?
If not, can you suggest me some directions to modify the code : I am
new in the job as a user of GCC.
I can't send you easily the environment in which the bugs occurred :
GCC9 is much different from the standard GCC version and it is still
under development. I hope you can however answer my questions.
Thank you,
Robert Jamier
SGS-THOMSON
av. des Martyrs
BP 217
38019 Grenoble Cedex
FRANCE
Phone (033) 76 58 53 05
Fax (033) 76 58 56 68
extracted from reload1.c :
--------------------------
/* For each class, the machine mode which requires consecutive
groups of regs of that class.
If two different modes ever require groups of one class,
they must be the same size and equally restrictive for that class,
otherwise we can't handle the complexity. */
/* If a group of consecutive regs are needed,
record which machine mode needs them.
Crash if two dissimilar machine modes both need
groups of consecutive regs of the same class. */
/* If this reg will not be available for groups,
pick one that does not foreclose possible groups.
This is a kludge, and not very general,
but it should be sufficient to make the 386 work,
and the problem should not occur on machines with
more registers. */
within reload
_____________
I changed :
-----------
if (group_mode[(int) reload_reg_class[i]] != VOIDmode
&&
(! modes_equiv_for_class_p (group_mode[(int) reload_reg_class[i]], mode, reload_reg_class[i])
||
group_size[(int) reload_reg_class[i]] != size))
abort ();
/* Record size and mode of a group of this class. */
group_size[(int) reload_reg_class[i]] = size;
group_mode[(int) reload_reg_class[i]] = mode;
into :
------
/* Record size and mode of a group of this class. */
group_size[(int) reload_reg_class[i]] = max(group_size[(int) reload_reg_class[i]], size);
if (group_size[(int) reload_reg_class[i]] == size)
group_mode[(int) reload_reg_class[i]] = mode;
within possible_group_p
_______________________
I changed :
-----------
/* Nonzero if, after spilling reg REGNO for non-groups,
it will still be possible to find a group if we still need one. */
static int
possible_group_p (regno, max_groups)
int regno;
int *max_groups;
{
int i;
int group = 0;
for (i = 0; i < (int) N_REG_CLASSES; i++)
group |= max_groups[i];
if (group == 0)
return 1;
/* Consider each pair of consecutive registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER - 1; i++)
{
if (i == regno || i + 1 == regno)
continue;
/* A pair of consecutive regs we can still spill does the trick. */
if (spill_reg_order[i] < 0 && spill_reg_order[i + 1] < 0
&& !regs_explicitly_used[i] && !regs_explicitly_used[i + 1]
&& !fixed_regs[i] && i != FRAME_POINTER_REGNUM
&& !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM)
return 1;
/* A pair of one already spilled and one we can spill does it
provided the one already spilled is not otherwise reserved. */
if (spill_reg_order[i] < 0 && !regs_explicitly_used[i]
&& !fixed_regs[i] && i != FRAME_POINTER_REGNUM
&& spill_reg_order[i + 1] >= 0
&& !counted_for_groups[i + 1]
&& !counted_for_nongroups[i + 1])
return 1;
if (spill_reg_order[i + 1] < 0 && !regs_explicitly_used[i + 1]
&& !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM
&& spill_reg_order[i] >= 0
&& !counted_for_groups[i]
&& !counted_for_nongroups[i])
return 1;
}
return 0;
}
into :
------
static int
possible_group_p (regno, max_groups, group_size)
int regno;
int *max_groups, *group_size;
{
int i;
int group = 0;
int size = 0;
for (i = 0; i < (int) N_REG_CLASSES; i++)
{
group |= max_groups[i];
size = max(size, group_size[i]);
}
if (group == 0)
return 1;
if (size == 2)
/* Consider each pair of consecutive registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER - 1; i++)
{
if (i == regno || i + 1 == regno)
continue;
/* A pair of consecutive regs we can still spill does the trick. */
if (spill_reg_order[i] < 0 && spill_reg_order[i + 1] < 0
&& !regs_explicitly_used[i] && !regs_explicitly_used[i + 1]
&& !fixed_regs[i] && i != FRAME_POINTER_REGNUM
&& !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM)
return 1;
/* A pair of one already spilled and one we can spill does it
provided the one already spilled is not otherwise reserved. */
if (spill_reg_order[i] < 0 && !regs_explicitly_used[i]
&& !fixed_regs[i] && i != FRAME_POINTER_REGNUM
&& spill_reg_order[i + 1] >= 0
&& !counted_for_groups[i + 1]
&& !counted_for_nongroups[i + 1])
return 1;
if (spill_reg_order[i + 1] < 0 && !regs_explicitly_used[i + 1]
&& !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM
&& spill_reg_order[i] >= 0
&& !counted_for_groups[i]
&& !counted_for_nongroups[i])
return 1;
}
else
for (i = 0; i < FIRST_PSEUDO_REGISTER - 1; i++)
{
int j;
for (j = 0; j < size; j++)
if ((i+j) == regno)
break;
if ((i+j) == regno)
continue;
for (j = 0; j < size; j++)
if (!(spill_reg_order[i+j] < 0
&& !regs_explicitly_used[i+j]
&& !fixed_regs[i+j]
&& (i+j) != FRAME_POINTER_REGNUM))
break;
if (j == size)
return 1;
}
return 0;
}
within reload
_____________
/* If this reg will not be available for groups,
pick one that does not foreclose possible groups.
This is a kludge, and not very general,
but it should be sufficient to make the 386 work,
and the problem should not occur on machines with
more registers. */
I changed :
-----------
/* Now similarly satisfy all need for single registers. */
while (max_needs[class] > 0 || max_nongroups[class] > 0)
{
/* Consider the potential reload regs that aren't
yet in use as reload regs, in order of preference.
Find the most preferred one that's in this class. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (potential_reload_regs[i] >= 0
&& TEST_HARD_REG_BIT (reg_class_contents[class],
potential_reload_regs[i])
/* If this reg will not be available for groups,
pick one that does not foreclose possible groups.
This is a kludge, and not very general,
but it should be sufficient to make the 386 work,
and the problem should not occur on machines with
more registers. */
/* (RJ) for the ST9
&& (max_nongroups[class] == 0
|| possible_group_p (potential_reload_regs[i], max_groups, group_size))
*/
&& possible_group_p (potential_reload_regs[i], max_groups, group_size))
break;
/* I should be the index in potential_reload_regs
of the new reload reg we have found. */
something_changed
|= new_spill_reg (i, class, max_needs, max_nongroups,
global, dumpfile);
}
I then got a crash within new_spill_reg :
if (i >= FIRST_PSEUDO_REGISTER)
abort (); /* Caller failed to find any register. */
What should I do next ?
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads