* ldexp.c (fold_unary): New. Split out from exp_fold_tree.

(fold_binary): Correct abs - non-abs case.
	(fold_trinary): New.  Split out from exp_fold_tree.
This commit is contained in:
Alan Modra 2002-09-25 02:42:13 +00:00
parent 20c2fc380d
commit 0ae1cf52b2
2 changed files with 138 additions and 91 deletions

View File

@ -1,3 +1,9 @@
2002-09-25 Alan Modra <amodra@bigpond.net.au>
* ldexp.c (fold_unary): New. Split out from exp_fold_tree.
(fold_binary): Correct abs - non-abs case.
(fold_trinary): New. Split out from exp_fold_tree.
2002-09-24 Alan Modra <amodra@bigpond.net.au>
* emulparams/elf64ppc.sh (DATA_ADDR): Define.

View File

@ -50,11 +50,21 @@ static etree_value_type new_rel
PARAMS ((bfd_vma, char *, lang_output_section_statement_type *section));
static etree_value_type new_rel_from_section
PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
static etree_value_type fold_unary
PARAMS ((etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot, bfd_vma *dotp));
static etree_value_type fold_binary
PARAMS ((etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot, bfd_vma *dotp));
static etree_value_type fold_trinary
PARAMS ((etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot, bfd_vma *dotp));
static etree_value_type fold_name
PARAMS ((etree_type *tree,
lang_output_section_statement_type *current_section,
@ -246,6 +256,93 @@ new_rel_from_section (value, section)
return new;
}
static etree_value_type
fold_unary (tree, current_section, allocation_done, dot, dotp)
etree_type *tree;
lang_output_section_statement_type *current_section;
lang_phase_type allocation_done;
bfd_vma dot;
bfd_vma *dotp;
{
etree_value_type result;
result = exp_fold_tree (tree->unary.child,
current_section,
allocation_done, dot, dotp);
if (result.valid_p)
{
switch (tree->type.node_code)
{
case ALIGN_K:
if (allocation_done != lang_first_phase_enum)
result = new_rel_from_section (align_n (dot, result.value),
current_section);
else
result.valid_p = false;
break;
case ABSOLUTE:
if (allocation_done != lang_first_phase_enum)
{
result.value += result.section->bfd_section->vma;
result.section = abs_output_section;
}
else
result.valid_p = false;
break;
case '~':
make_abs (&result);
result.value = ~result.value;
break;
case '!':
make_abs (&result);
result.value = !result.value;
break;
case '-':
make_abs (&result);
result.value = -result.value;
break;
case NEXT:
/* Return next place aligned to value. */
if (allocation_done == lang_allocating_phase_enum)
{
make_abs (&result);
result.value = align_n (dot, result.value);
}
else
result.valid_p = false;
break;
case DATA_SEGMENT_END:
if (allocation_done != lang_first_phase_enum
&& current_section == abs_output_section
&& (exp_data_seg.phase == exp_dataseg_align_seen
|| exp_data_seg.phase == exp_dataseg_adjust
|| allocation_done != lang_allocating_phase_enum))
{
if (exp_data_seg.phase == exp_dataseg_align_seen)
{
exp_data_seg.phase = exp_dataseg_end_seen;
exp_data_seg.end = result.value;
}
}
else
result.valid_p = false;
break;
default:
FAIL ();
break;
}
}
return result;
}
static etree_value_type
fold_binary (tree, current_section, allocation_done, dot, dotp)
etree_type *tree;
@ -279,15 +376,14 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
&& (tree->type.node_code == '+'
|| tree->type.node_code == '-'))
{
etree_value_type hold;
/* If there is only one absolute term, make sure it is the
second one. */
if (other.section != abs_output_section)
{
hold = result;
result = other;
other = hold;
/* Keep the section of the other term. */
if (tree->type.node_code == '+')
other.value = result.value + other.value;
else
other.value = result.value - other.value;
return other;
}
}
else if (result.section != other.section
@ -382,6 +478,28 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
return result;
}
static etree_value_type
fold_trinary (tree, current_section, allocation_done, dot, dotp)
etree_type *tree;
lang_output_section_statement_type *current_section;
lang_phase_type allocation_done;
bfd_vma dot;
bfd_vma *dotp;
{
etree_value_type result;
result = exp_fold_tree (tree->trinary.cond, current_section,
allocation_done, dot, dotp);
if (result.valid_p)
result = exp_fold_tree ((result.value
? tree->trinary.lhs
: tree->trinary.rhs),
current_section,
allocation_done, dot, dotp);
return result;
}
etree_value_type
invalid ()
{
@ -584,90 +702,8 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
break;
case etree_unary:
result = exp_fold_tree (tree->unary.child,
current_section,
allocation_done, dot, dotp);
if (result.valid_p)
{
switch (tree->type.node_code)
{
case ALIGN_K:
if (allocation_done != lang_first_phase_enum)
result = new_rel_from_section (align_n (dot, result.value),
current_section);
else
result.valid_p = false;
break;
case ABSOLUTE:
if (allocation_done != lang_first_phase_enum)
{
result.value += result.section->bfd_section->vma;
result.section = abs_output_section;
}
else
result.valid_p = false;
break;
case '~':
make_abs (&result);
result.value = ~result.value;
break;
case '!':
make_abs (&result);
result.value = !result.value;
break;
case '-':
make_abs (&result);
result.value = -result.value;
break;
case NEXT:
/* Return next place aligned to value. */
if (allocation_done == lang_allocating_phase_enum)
{
make_abs (&result);
result.value = align_n (dot, result.value);
}
else
result.valid_p = false;
break;
case DATA_SEGMENT_END:
if (allocation_done != lang_first_phase_enum
&& current_section == abs_output_section
&& (exp_data_seg.phase == exp_dataseg_align_seen
|| exp_data_seg.phase == exp_dataseg_adjust
|| allocation_done != lang_allocating_phase_enum))
{
if (exp_data_seg.phase == exp_dataseg_align_seen)
{
exp_data_seg.phase = exp_dataseg_end_seen;
exp_data_seg.end = result.value;
}
}
else
result.valid_p = false;
break;
default:
FAIL ();
break;
}
}
break;
case etree_trinary:
result = exp_fold_tree (tree->trinary.cond, current_section,
allocation_done, dot, dotp);
if (result.valid_p)
result = exp_fold_tree ((result.value
? tree->trinary.lhs
: tree->trinary.rhs),
current_section,
allocation_done, dot, dotp);
result = fold_unary (tree, current_section, allocation_done,
dot, dotp);
break;
case etree_binary:
@ -675,6 +711,11 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
dot, dotp);
break;
case etree_trinary:
result = fold_trinary (tree, current_section, allocation_done,
dot, dotp);
break;
case etree_assign:
case etree_provide:
case etree_provided: