Add per-section and per-sub-section literal pools.

This commit is contained in:
Nick Clifton 2002-07-30 10:56:04 +00:00
parent 5ec4a8f313
commit 3d0c950043
3 changed files with 145 additions and 117 deletions

View File

@ -1,3 +1,17 @@
2002-07-30 Nick Clifton <nickc@redhat.com>
* config/tc-arm.c (struct literal_pool): Add fields to allow
multiple literal pools to be maintained.
(find_literal_pool): New function.
(find_or_make_literal_pool): New function.
(add_to_literal_pool): Use find_or_make_literal_pool.
(arm_s_text, arm_s_data, arm_s_section): Remove - no longer
needed.
(s_ltorg): Use find_literal_pool.
(arm_cleanup): Dump all literal pools.
* doc/c-arm.texi: Document new behaviour of only dumping literal
pools upon request.
2002-07-26 Alan Modra <amodra@bigpond.net.au>
* config/tc-ppc.c (ppc_set_cpu): Use PPC_OPCODE_64 as the default

View File

@ -2061,9 +2061,6 @@ static void s_code PARAMS ((int));
static void s_force_thumb PARAMS ((int));
static void s_thumb_func PARAMS ((int));
static void s_thumb_set PARAMS ((int));
static void arm_s_text PARAMS ((int));
static void arm_s_data PARAMS ((int));
static void arm_s_section PARAMS ((int));
#ifdef OBJ_ELF
static void s_arm_elf_cons PARAMS ((int));
#endif
@ -2085,17 +2082,10 @@ const pseudo_typeS md_pseudo_table[] =
{ "even", s_even, 0 },
{ "ltorg", s_ltorg, 0 },
{ "pool", s_ltorg, 0 },
/* Allow for the effect of section changes. */
{ "text", arm_s_text, 0 },
{ "data", arm_s_data, 0 },
{ "section", arm_s_section, 0 },
{ "section.s", arm_s_section, 0 },
{ "sect", arm_s_section, 0 },
{ "sect.s", arm_s_section, 0 },
#ifdef OBJ_ELF
{ "word", s_arm_elf_cons, 4 },
{ "long", s_arm_elf_cons, 4 },
{ "file", dwarf2_directive_file, 0 },
{ "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
#else
{ "word", cons, 4},
@ -2125,73 +2115,130 @@ static int arm_parse_fpu PARAMS ((char *));
symbolS * last_label_seen;
static int label_is_thumb_function_name = false;
/* Literal stuff. */
/* Literal Pool stuff. */
#define MAX_LITERAL_POOL_SIZE 1024
typedef struct literalS
/* Literal pool structure. Held on a per-section
and per-sub-section basis. */
typedef struct literal_pool
{
struct expressionS exp;
struct arm_it * inst;
} literalT;
expressionS literals [MAX_LITERAL_POOL_SIZE];
unsigned int next_free_entry;
unsigned int id;
symbolS * symbol;
segT section;
subsegT sub_section;
struct literal_pool * next;
} literal_pool;
literalT literals[MAX_LITERAL_POOL_SIZE];
/* Pointer to a linked list of literal pools. */
literal_pool * list_of_pools = NULL;
/* Next free entry in the pool. */
int next_literal_pool_place = 0;
static literal_pool * find_literal_pool PARAMS ((void));
static literal_pool * find_or_make_literal_pool PARAMS ((void));
/* Next literal pool number. */
int lit_pool_num = 1;
static literal_pool *
find_literal_pool ()
{
literal_pool * pool;
symbolS * current_poolP = NULL;
for (pool = list_of_pools; pool != NULL; pool = pool->next)
{
if (pool->section == now_seg
&& pool->sub_section == now_subseg)
break;
}
return pool;
}
static literal_pool *
find_or_make_literal_pool ()
{
/* Next literal pool ID number. */
static unsigned int latest_pool_num = 1;
literal_pool * pool;
pool = find_literal_pool ();
if (pool == NULL)
{
/* Create a new pool. */
pool = (literal_pool *) xmalloc (sizeof (* pool));
if (! pool)
return NULL;
pool->next_free_entry = 0;
pool->section = now_seg;
pool->sub_section = now_subseg;
pool->next = list_of_pools;
pool->symbol = NULL;
/* Add it to the list. */
list_of_pools = pool;
}
/* New pools, and emptied pools, will have a NULL symbol. */
if (pool->symbol == NULL)
{
pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
(valueT) 0, &zero_address_frag);
pool->id = latest_pool_num ++;
}
/* Done. */
return pool;
}
/* Add the literal in the global 'inst'
structure to the relevent literal pool. */
static int
add_to_lit_pool ()
{
int lit_count = 0;
literal_pool * pool;
unsigned int entry;
if (current_poolP == NULL)
current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
(valueT) 0, &zero_address_frag);
pool = find_or_make_literal_pool ();
/* Check if this literal value is already in the pool: */
while (lit_count < next_literal_pool_place)
/* Check if this literal value is already in the pool. */
for (entry = 0; entry < pool->next_free_entry; entry ++)
{
if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
&& inst.reloc.exp.X_op == O_constant
&& (literals[lit_count].exp.X_add_number
if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
&& (inst.reloc.exp.X_op == O_constant)
&& (pool->literals[entry].X_add_number
== inst.reloc.exp.X_add_number)
&& literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
&& (pool->literals[entry].X_unsigned
== inst.reloc.exp.X_unsigned))
break;
if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
&& inst.reloc.exp.X_op == O_symbol
&& (literals[lit_count].exp.X_add_number
if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
&& (inst.reloc.exp.X_op == O_symbol)
&& (pool->literals[entry].X_add_number
== inst.reloc.exp.X_add_number)
&& (literals[lit_count].exp.X_add_symbol
&& (pool->literals[entry].X_add_symbol
== inst.reloc.exp.X_add_symbol)
&& (literals[lit_count].exp.X_op_symbol
&& (pool->literals[entry].X_op_symbol
== inst.reloc.exp.X_op_symbol))
break;
lit_count++;
break;
}
if (lit_count == next_literal_pool_place) /* New entry. */
/* Do we need to create a new entry? */
if (entry == pool->next_free_entry)
{
if (next_literal_pool_place >= MAX_LITERAL_POOL_SIZE)
if (entry >= MAX_LITERAL_POOL_SIZE)
{
inst.error = _("literal pool overflow");
inst.error = _("Literal Pool Overflow");
return FAIL;
}
literals[next_literal_pool_place].exp = inst.reloc.exp;
lit_count = next_literal_pool_place++;
pool->literals[entry] = inst.reloc.exp;
pool->next_free_entry += 1;
}
inst.reloc.exp.X_op = O_symbol;
inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
inst.reloc.exp.X_add_symbol = current_poolP;
inst.reloc.exp.X_op = O_symbol;
inst.reloc.exp.X_add_number = (entry) * 4 - 8;
inst.reloc.exp.X_add_symbol = pool->symbol;
return SUCCESS;
}
@ -2353,10 +2400,14 @@ static void
s_ltorg (ignored)
int ignored ATTRIBUTE_UNUSED;
{
int lit_count = 0;
unsigned int entry;
literal_pool * pool;
char sym_name[20];
if (current_poolP == NULL)
pool = find_literal_pool ();
if (pool == NULL
|| pool->symbol == NULL
|| pool->next_free_entry == 0)
return;
/* Align pool as you have word accesses.
@ -2366,24 +2417,25 @@ s_ltorg (ignored)
record_alignment (now_seg, 2);
sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
sprintf (sym_name, "$$lit_\002%x", pool->id);
symbol_locate (current_poolP, sym_name, now_seg,
symbol_locate (pool->symbol, sym_name, now_seg,
(valueT) frag_now_fix (), frag_now);
symbol_table_insert (current_poolP);
symbol_table_insert (pool->symbol);
ARM_SET_THUMB (current_poolP, thumb_mode);
ARM_SET_THUMB (pool->symbol, thumb_mode);
#if defined OBJ_COFF || defined OBJ_ELF
ARM_SET_INTERWORK (current_poolP, support_interwork);
ARM_SET_INTERWORK (pool->symbol, support_interwork);
#endif
while (lit_count < next_literal_pool_place)
for (entry = 0; entry < pool->next_free_entry; entry ++)
/* First output the expression in the instruction to the pool. */
emit_expr (&(literals[lit_count++].exp), 4); /* .word */
emit_expr (&(pool->literals[entry]), 4); /* .word */
next_literal_pool_place = 0;
current_poolP = NULL;
/* Mark the pool as empty. */
pool->next_free_entry = 0;
pool->symbol = NULL;
}
/* Same as s_align_ptwo but align 0 => align 2. */
@ -2550,55 +2602,6 @@ s_thumb_set (equiv)
#endif
}
/* If we change section we must dump the literal pool first. */
static void
arm_s_text (ignore)
int ignore;
{
if (now_seg != text_section)
s_ltorg (0);
#ifdef OBJ_ELF
obj_elf_text (ignore);
#else
s_text (ignore);
#endif
}
static void
arm_s_data (ignore)
int ignore;
{
if (flag_readonly_data_in_text)
{
if (now_seg != text_section)
s_ltorg (0);
}
else if (now_seg != data_section)
s_ltorg (0);
#ifdef OBJ_ELF
obj_elf_data (ignore);
#else
s_data (ignore);
#endif
}
static void
arm_s_section (ignore)
int ignore;
{
s_ltorg (0);
#ifdef OBJ_ELF
obj_elf_section (ignore);
#endif
#ifdef OBJ_COFF
obj_coff_section (ignore);
#endif
}
static void
opcode_select (width)
int width;
@ -10254,10 +10257,10 @@ tc_gen_reloc (section, fixp)
case BFD_RELOC_ARM_LITERAL:
case BFD_RELOC_ARM_HWLITERAL:
/* If this is called then the a literal has been referenced across
a section boundary - possibly due to an implicit dump. */
/* If this is called then the a literal has
been referenced across a section boundary. */
as_bad_where (fixp->fx_file, fixp->fx_line,
_("literal referenced across section boundary (Implicit dump?)"));
_("Literal referenced across section boundary"));
return NULL;
#ifdef OBJ_ELF
@ -10504,8 +10507,9 @@ md_assemble (str)
-k Generate PIC code
-mthumb Start in Thumb mode
-mthumb-interwork Code supports ARM/Thumb interworking
-mimplicit-litpool-dump Dump literal pool on section change
For now we will also provide support for
For now we will also provide support for:
-mapcs-32 32-bit Program counter
-mapcs-26 26-bit Program counter
@ -11210,12 +11214,14 @@ cons_fix_new_arm (frag, where, size, exp)
void
arm_cleanup ()
{
if (current_poolP == NULL)
return;
literal_pool * pool;
/* Put it at the end of text section. */
subseg_set (text_section, 0);
s_ltorg (0);
for (pool = list_of_pools; pool; pool = pool->next)
{
/* Put it at the end of the relevent section. */
subseg_set (pool->section, pool->sub_section);
s_ltorg (0);
}
}
void

View File

@ -340,6 +340,14 @@ way that the @code{.thumb_func} directive does.
This directive causes the current contents of the literal pool to be
dumped into the current section (which is assumed to be the .text
section) at the current location (aligned to a word boundary).
@code{GAS} maintains a separate literal pool for each section and each
sub-section. The @code{.ltorg} directive will only affect the literal
pool of the current section and sub-section. At the end of assembly
all remaining, un-empty literal pools will automatically be dumped.
Note - older versions of @code{GAS} would dump the current literal
pool any time a section change occurred. This is no longer done, since
it prevents accurate control of the placement of literal pools.
@cindex @code{.pool} directive, ARM
@item .pool