register and the second is the stack slot. */
typedef void (*mips_save_restore_fn) (rtx, rtx);
-struct constant;
+struct mips16_constant;
struct mips_arg_info;
struct mips_address_info;
struct mips_integer_op;
static rtx mips16_gp_pseudo_reg (void);
static void mips16_fp_args (FILE *, int, int);
static void build_mips16_function_stub (FILE *);
-static rtx add_constant (struct constant **, rtx, enum machine_mode);
-static void dump_constants (struct constant *, rtx);
-static rtx mips_find_symbol (rtx);
+static rtx dump_constants_1 (enum machine_mode, rtx, rtx);
+static void dump_constants (struct mips16_constant *, rtx);
+static int mips16_insn_length (rtx);
+static int mips16_rewrite_pool_refs (rtx *, void *);
static void mips16_lay_out_constants (void);
static void mips_avoid_hazard (rtx, rtx, int *, rtx *, rtx);
static void mips_avoid_hazards (void);
/* Current frame information, calculated by compute_frame_size. */
struct mips_frame_info frame;
- /* Length of instructions in function; mips16 only. */
- long insns_len;
-
/* The register to use as the global pointer within this function. */
unsigned int global_pointer;
can support a given mode. */
char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
-/* The length of all strings seen when compiling for the mips16. This
- is used to tell how many strings are in the constant pool, so that
- we can see if we may have an overflow. This is reset each time the
- constant pool is output. */
-int mips_string_length;
-
-/* When generating mips16 code, a list of all strings that are to be
- output after the current function. */
-
-static GTY(()) rtx mips16_strings;
-
-/* In mips16 mode, we build a list of all the string constants we see
- in a particular function. */
-
-struct string_constant
-{
- struct string_constant *next;
- const char *label;
-};
-
-static struct string_constant *string_constants;
-
/* List of all MIPS punctuation characters used by print_operand. */
char mips_print_operand_punct[256];
mips_classify_symbol (rtx x)
{
if (GET_CODE (x) == LABEL_REF)
- return (TARGET_ABICALLS ? SYMBOL_GOT_LOCAL : SYMBOL_GENERAL);
+ {
+ if (TARGET_MIPS16)
+ return SYMBOL_CONSTANT_POOL;
+ if (TARGET_ABICALLS)
+ return SYMBOL_GOT_LOCAL;
+ return SYMBOL_GENERAL;
+ }
if (GET_CODE (x) != SYMBOL_REF)
abort ();
if (SYMBOL_REF_SMALL_P (x))
return SYMBOL_SMALL_DATA;
- /* When generating mips16 code, SYMBOL_REF_FLAG indicates a string
- in the current function's constant pool. */
- if (TARGET_MIPS16 && SYMBOL_REF_FLAG (x))
- return SYMBOL_CONSTANT_POOL;
-
if (TARGET_ABICALLS)
{
if (SYMBOL_REF_DECL (x) == 0)
/* In other cases the relocations can handle any offset. */
return true;
- case SYMBOL_SMALL_DATA:
case SYMBOL_CONSTANT_POOL:
+ /* Allow constant pool references to be converted to LABEL+CONSTANT.
+ In this case, we no longer have access to the underlying constant,
+ but the original symbol-based access was known to be valid. */
+ if (GET_CODE (x) == LABEL_REF)
+ return true;
+
+ /* Fall through. */
+
+ case SYMBOL_SMALL_DATA:
/* Make sure that the offset refers to something within the
underlying object. This should guarantee that the final
PC- or GP-relative offset is within the 16-bit limit. */
return true;
case SYMBOL_CONSTANT_POOL:
- /* PC-relative addressing is only available for lw, sw, ld and sd. */
+ /* PC-relative addressing is only available for lw and ld. */
return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
case SYMBOL_GOT_LOCAL:
{
return m16_check_op (op, (- 0x7f) << 3, 0x80 << 3, 7);
}
-
-/* References to the string table on the mips16 only use a small
- offset if the function is small. We can't check for LABEL_REF here,
- because the offset is always large if the label is before the
- referencing instruction. */
-
-int
-m16_usym8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == SYMBOL_REF
- && SYMBOL_REF_FLAG (op)
- && cfun->machine->insns_len > 0
- && (cfun->machine->insns_len + get_pool_size () + mips_string_length
- < 4 * 0x100))
- {
- struct string_constant *l;
-
- /* Make sure this symbol is on thelist of string constants to be
- output for this function. It is possible that it has already
- been output, in which case this requires a large offset. */
- for (l = string_constants; l != NULL; l = l->next)
- if (strcmp (l->label, XSTR (op, 0)) == 0)
- return 1;
- }
-
- return 0;
-}
-
-int
-m16_usym5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == SYMBOL_REF
- && SYMBOL_REF_FLAG (op)
- && cfun->machine->insns_len > 0
- && (cfun->machine->insns_len + get_pool_size () + mips_string_length
- < 4 * 0x20))
- {
- struct string_constant *l;
-
- /* Make sure this symbol is on thelist of string constants to be
- output for this function. It is possible that it has already
- been output, in which case this requires a large offset. */
- for (l = string_constants; l != NULL; l = l->next)
- if (strcmp (l->label, XSTR (op, 0)) == 0)
- return 1;
- }
-
- return 0;
-}
\f
static bool
mips_rtx_costs (rtx x, int code, int outer_code, int *total)
mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
- rtx string;
-
/* Reinstate the normal $gp. */
REGNO (pic_offset_table_rtx) = GLOBAL_POINTER_REGNUM;
mips_output_cplocal ();
assemble_name (file, fnname);
fputs ("\n", file);
}
-
- while (string_constants != NULL)
- {
- struct string_constant *next;
-
- next = string_constants->next;
- free (string_constants);
- string_constants = next;
- }
-
- /* If any following function uses the same strings as this one, force
- them to refer those strings indirectly. Nearby functions could
- refer them using pc-relative addressing, but it isn't safe in
- general. For instance, some functions may be placed in sections
- other than .text, and we don't know whether they be close enough
- to this one. In large files, even other .text functions can be
- too far away. */
- for (string = mips16_strings; string != 0; string = XEXP (string, 1))
- SYMBOL_REF_FLAG (XEXP (string, 0)) = 0;
- free_EXPR_LIST_list (&mips16_strings);
}
\f
/* Emit instructions to restore register REG from slot MEM. */
insn = get_insns ();
insn_locators_initialize ();
split_all_insns_noflow ();
+ if (TARGET_MIPS16)
+ mips16_lay_out_constants ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
mips_select_section (tree decl, int reloc,
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
- if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
- && TREE_CODE (decl) == STRING_CST)
+ if (TARGET_EMBEDDED_PIC && TREE_CODE (decl) == STRING_CST)
/* For embedded position independent code, put constant strings in the
- text section, because the data section is limited to 64K in size.
- For mips16 code, put strings in the text section so that a PC
- relative load instruction can be used to get their address. */
+ text section, because the data section is limited to 64K in size. */
text_section ();
else if (targetm.have_named_sections)
default_elf_select_section (decl, reloc, align);
/* When generating embedded PIC code, SYMBOL_REF_FLAG is set for
- symbols which are not in the .text section.
-
- When generating mips16 code, SYMBOL_REF_FLAG is set for string
- constants which are put in the .text section. We also record the
- total length of all such strings; this total is used to decide
- whether we need to split the constant table, and need not be
- precisely correct. */
+ symbols which are not in the .text section. */
static void
mips_encode_section_info (tree decl, rtx rtl, int first)
if (GET_CODE (symbol) != SYMBOL_REF)
return;
- if (TARGET_MIPS16)
- {
- if (first && TREE_CODE (decl) == STRING_CST
- /* If this string is from a function, and the function will
- go in a gnu linkonce section, then we can't directly
- access the string. This gets an assembler error
- "unsupported PC relative reference to different section".
- If we modify SELECT_SECTION to put it in function_section
- instead of text_section, it still fails because
- DECL_SECTION_NAME isn't set until assemble_start_function.
- If we fix that, it still fails because strings are shared
- among multiple functions, and we have cross section
- references again. We force it to work by putting string
- addresses in the constant pool and indirecting. */
- && (! current_function_decl
- || ! DECL_ONE_ONLY (current_function_decl)))
- {
- mips16_strings = alloc_EXPR_LIST (0, symbol, mips16_strings);
- SYMBOL_REF_FLAG (symbol) = 1;
- mips_string_length += TREE_STRING_LENGTH (decl);
- }
- }
-
if (TARGET_EMBEDDED_PIC)
{
if (TREE_CODE (decl) == VAR_DECL)
return 0;
}
-/* We keep a list of constants we which we have to add to internal
- constant tables in the middle of large functions. */
+/* An entry in the mips16 constant pool. VALUE is the pool constant,
+ MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
-struct constant
-{
- struct constant *next;
+struct mips16_constant {
+ struct mips16_constant *next;
rtx value;
rtx label;
enum machine_mode mode;
};
-/* Add a constant to the list in *PCONSTANTS. */
+/* Information about an incomplete mips16 constant pool. FIRST is the
+ first constant, HIGHEST_ADDRESS is the highest address that the first
+ byte of the pool can have, and INSN_ADDRESS is the current instruction
+ address. */
+
+struct mips16_constant_pool {
+ struct mips16_constant *first;
+ int highest_address;
+ int insn_address;
+};
+
+/* Add constant VALUE to POOL and return its label. MODE is the
+ value's mode (used for CONST_INTs, etc.). */
static rtx
-add_constant (struct constant **pconstants, rtx val, enum machine_mode mode)
+add_constant (struct mips16_constant_pool *pool,
+ rtx value, enum machine_mode mode)
{
- struct constant *c;
+ struct mips16_constant **p, *c;
+ bool first_of_size_p;
- for (c = *pconstants; c != NULL; c = c->next)
- if (mode == c->mode && rtx_equal_p (val, c->value))
- return c->label;
+ /* See whether the constant is already in the pool. If so, return the
+ existing label, otherwise leave P pointing to the place where the
+ constant should be added.
- c = (struct constant *) xmalloc (sizeof *c);
- c->value = val;
+ Keep the pool sorted in increasing order of mode size so that we can
+ reduce the number of alignments needed. */
+ first_of_size_p = true;
+ for (p = &pool->first; *p != 0; p = &(*p)->next)
+ {
+ if (mode == (*p)->mode && rtx_equal_p (value, (*p)->value))
+ return (*p)->label;
+ if (GET_MODE_SIZE (mode) < GET_MODE_SIZE ((*p)->mode))
+ break;
+ if (GET_MODE_SIZE (mode) == GET_MODE_SIZE ((*p)->mode))
+ first_of_size_p = false;
+ }
+
+ /* In the worst case, the constant needed by the earliest instruction
+ will end up at the end of the pool. The entire pool must then be
+ accessible from that instruction.
+
+ When adding the first constant, set the pool's highest address to
+ the address of the first out-of-range byte. Adjust this address
+ downwards each time a new constant is added. */
+ if (pool->first == 0)
+ /* For pc-relative lw, addiu and daddiu instructions, the base PC value
+ is the address of the instruction with the lowest two bits clear.
+ The base PC value for ld has the lowest three bits clear. Assume
+ the worst case here. */
+ pool->highest_address = pool->insn_address - (UNITS_PER_WORD - 2) + 0x8000;
+ pool->highest_address -= GET_MODE_SIZE (mode);
+ if (first_of_size_p)
+ /* Take into account the worst possible padding due to alignment. */
+ pool->highest_address -= GET_MODE_SIZE (mode) - 1;
+
+ /* Create a new entry. */
+ c = (struct mips16_constant *) xmalloc (sizeof *c);
+ c->value = value;
c->mode = mode;
c->label = gen_label_rtx ();
- c->next = *pconstants;
- *pconstants = c;
+ c->next = *p;
+ *p = c;
+
return c->label;
}
+/* Output constant VALUE after instruction INSN and return the last
+ instruction emitted. MODE is the mode of the constant. */
+
+static rtx
+dump_constants_1 (enum machine_mode mode, rtx value, rtx insn)
+{
+ switch (GET_MODE_CLASS (mode))
+ {
+ case MODE_INT:
+ {
+ rtx size = GEN_INT (GET_MODE_SIZE (mode));
+ return emit_insn_after (gen_consttable_int (value, size), insn);
+ }
+
+ case MODE_FLOAT:
+ return emit_insn_after (gen_consttable_float (value), insn);
+
+ case MODE_VECTOR_FLOAT:
+ case MODE_VECTOR_INT:
+ {
+ int i;
+ for (i = 0; i < CONST_VECTOR_NUNITS (value); i++)
+ insn = dump_constants_1 (GET_MODE_INNER (mode),
+ CONST_VECTOR_ELT (value, i), insn);
+ return insn;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+
/* Dump out the constants in CONSTANTS after INSN. */
static void
-dump_constants (struct constant *constants, rtx insn)
+dump_constants (struct mips16_constant *constants, rtx insn)
{
- struct constant *c;
+ struct mips16_constant *c, *next;
int align;
- c = constants;
align = 0;
- while (c != NULL)
+ for (c = constants; c != NULL; c = next)
{
- rtx r;
- struct constant *next;
-
- switch (GET_MODE_SIZE (c->mode))
+ /* If necessary, increase the alignment of PC. */
+ if (align < GET_MODE_SIZE (c->mode))
{
- case 1:
- align = 0;
- break;
- case 2:
- if (align < 1)
- insn = emit_insn_after (gen_align_2 (), insn);
- align = 1;
- break;
- case 4:
- if (align < 2)
- insn = emit_insn_after (gen_align_4 (), insn);
- align = 2;
- break;
- default:
- if (align < 3)
- insn = emit_insn_after (gen_align_8 (), insn);
- align = 3;
- break;
+ int align_log = floor_log2 (GET_MODE_SIZE (c->mode));
+ insn = emit_insn_after (gen_align (GEN_INT (align_log)), insn);
}
+ align = GET_MODE_SIZE (c->mode);
insn = emit_label_after (c->label, insn);
-
- switch (c->mode)
- {
- case QImode:
- r = gen_consttable_qi (c->value);
- break;
- case HImode:
- r = gen_consttable_hi (c->value);
- break;
- case SImode:
- r = gen_consttable_si (c->value);
- break;
- case SFmode:
- r = gen_consttable_sf (c->value);
- break;
- case DImode:
- r = gen_consttable_di (c->value);
- break;
- case DFmode:
- r = gen_consttable_df (c->value);
- break;
- default:
- abort ();
- }
-
- insn = emit_insn_after (r, insn);
+ insn = dump_constants_1 (c->mode, c->value, insn);
next = c->next;
free (c);
- c = next;
}
emit_barrier_after (insn);
}
-/* Find the symbol in an address expression. */
+/* Return the length of instruction INSN.
-static rtx
-mips_find_symbol (rtx addr)
+ ??? MIPS16 switch tables go in .text, but we don't define
+ JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
+ compute their lengths correctly. */
+
+static int
+mips16_insn_length (rtx insn)
{
- if (GET_CODE (addr) == MEM)
- addr = XEXP (addr, 0);
- while (GET_CODE (addr) == CONST)
- addr = XEXP (addr, 0);
- if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
- return addr;
- if (GET_CODE (addr) == PLUS)
+ if (GET_CODE (insn) == JUMP_INSN)
{
- rtx l1, l2;
-
- l1 = mips_find_symbol (XEXP (addr, 0));
- l2 = mips_find_symbol (XEXP (addr, 1));
- if (l1 != NULL_RTX && l2 == NULL_RTX)
- return l1;
- else if (l1 == NULL_RTX && l2 != NULL_RTX)
- return l2;
+ rtx body = PATTERN (insn);
+ if (GET_CODE (body) == ADDR_VEC)
+ return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 0);
+ if (GET_CODE (body) == ADDR_DIFF_VEC)
+ return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 1);
}
- return NULL_RTX;
+ return get_attr_length (insn);
}
-/* In mips16 mode, we need to look through the function to check for
- PC relative loads that are out of range. */
+/* Rewrite *X so that constant pool references refer to the constant's
+ label instead. DATA points to the constant pool structure. */
-static void
-mips16_lay_out_constants (void)
+static int
+mips16_rewrite_pool_refs (rtx *x, void *data)
{
- int insns_len, max_internal_pool_size, pool_size, addr, first_constant_ref;
- rtx first, insn;
- struct constant *constants;
+ struct mips16_constant_pool *pool = data;
+ if (GET_CODE (*x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (*x))
+ *x = gen_rtx_LABEL_REF (Pmode, add_constant (pool,
+ get_pool_constant (*x),
+ get_pool_mode (*x)));
+ return 0;
+}
- first = get_insns ();
+/* Build MIPS16 constant pools. */
- /* Scan the function looking for PC relative loads which may be out
- of range. All such loads will either be from the constant table,
- or be getting the address of a constant string. If the size of
- the function plus the size of the constant table is less than
- 0x8000, then all loads are in range. */
+static void
+mips16_lay_out_constants (void)
+{
+ struct mips16_constant_pool pool;
+ rtx insn, barrier;
- insns_len = 0;
- for (insn = first; insn; insn = NEXT_INSN (insn))
+ barrier = 0;
+ memset (&pool, 0, sizeof (pool));
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
- insns_len += get_attr_length (insn);
-
- /* ??? We put switch tables in .text, but we don't define
- JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
- compute their lengths correctly. */
- if (GET_CODE (insn) == JUMP_INSN)
- {
- rtx body;
-
- body = PATTERN (insn);
- if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
- insns_len += (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC)
- * GET_MODE_SIZE (GET_MODE (body)));
- insns_len += GET_MODE_SIZE (GET_MODE (body)) - 1;
- }
- }
-
- /* Store the original value of insns_len in cfun->machine, so
- that m16_usym8_4 and m16_usym5_4 can look at it. */
- cfun->machine->insns_len = insns_len;
+ /* Rewrite constant pool references in INSN. */
+ if (INSN_P (insn))
+ for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
- pool_size = get_pool_size ();
- if (insns_len + pool_size + mips_string_length < 0x8000)
- return;
+ pool.insn_address += mips16_insn_length (insn);
- /* Loop over the insns and figure out what the maximum internal pool
- size could be. */
- max_internal_pool_size = 0;
- for (insn = first; insn; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET)
+ if (pool.first != NULL)
{
- rtx src;
-
- src = mips_find_symbol (SET_SRC (PATTERN (insn)));
- if (src == NULL_RTX)
- continue;
- if (CONSTANT_POOL_ADDRESS_P (src))
- max_internal_pool_size += GET_MODE_SIZE (get_pool_mode (src));
- else if (SYMBOL_REF_FLAG (src))
- max_internal_pool_size += GET_MODE_SIZE (Pmode);
- }
- }
+ /* If there are no natural barriers between the first user of
+ the pool and the highest acceptable address, we'll need to
+ create a new instruction to jump around the constant pool.
+ In the worst case, this instruction will be 4 bytes long.
+
+ If it's too late to do this transformation after INSN,
+ do it immediately before INSN. */
+ if (barrier == 0 && pool.insn_address + 4 > pool.highest_address)
+ {
+ rtx label, jump;
- constants = NULL;
- addr = 0;
- first_constant_ref = -1;
+ label = gen_label_rtx ();
- for (insn = first; insn; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET)
- {
- rtx val, src;
- enum machine_mode mode = VOIDmode;
+ jump = emit_jump_insn_before (gen_jump (label), insn);
+ JUMP_LABEL (jump) = label;
+ LABEL_NUSES (label) = 1;
+ barrier = emit_barrier_after (jump);
- val = NULL_RTX;
- src = mips_find_symbol (SET_SRC (PATTERN (insn)));
- if (src != NULL_RTX && CONSTANT_POOL_ADDRESS_P (src))
- {
- /* ??? This is very conservative, which means that we
- will generate too many copies of the constant table.
- The only solution would seem to be some form of
- relaxing. */
- if (((insns_len - addr)
- + max_internal_pool_size
- + get_pool_offset (src))
- >= 0x8000)
- {
- val = get_pool_constant (src);
- mode = get_pool_mode (src);
- }
- max_internal_pool_size -= GET_MODE_SIZE (get_pool_mode (src));
- }
- else if (src != NULL_RTX && SYMBOL_REF_FLAG (src))
- {
- /* Including all of mips_string_length is conservative,
- and so is including all of max_internal_pool_size. */
- if (((insns_len - addr)
- + max_internal_pool_size
- + pool_size
- + mips_string_length)
- >= 0x8000)
- {
- val = src;
- mode = Pmode;
- }
- max_internal_pool_size -= Pmode;
+ emit_label_after (label, barrier);
+ pool.insn_address += 4;
}
- if (val != NULL_RTX)
+ /* See whether the constant pool is now out of range of the first
+ user. If so, output the constants after the previous barrier.
+ Note that any instructions between BARRIER and INSN (inclusive)
+ will use negative offsets to refer to the pool. */
+ if (pool.insn_address > pool.highest_address)
{
- rtx lab, newsrc;
-
- /* This PC relative load is out of range. ??? In the
- case of a string constant, we are only guessing that
- it is range, since we don't know the offset of a
- particular string constant. */
-
- lab = add_constant (&constants, val, mode);
- newsrc = gen_rtx_MEM (mode,
- gen_rtx_LABEL_REF (VOIDmode, lab));
- RTX_UNCHANGING_P (newsrc) = 1;
- PATTERN (insn) = gen_rtx_SET (VOIDmode,
- SET_DEST (PATTERN (insn)),
- newsrc);
- INSN_CODE (insn) = -1;
-
- if (first_constant_ref < 0)
- first_constant_ref = addr;
+ dump_constants (pool.first, barrier);
+ pool.first = NULL;
+ barrier = 0;
}
+ else if (BARRIER_P (insn))
+ barrier = insn;
}
-
- addr += get_attr_length (insn);
-
- /* ??? We put switch tables in .text, but we don't define
- JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
- compute their lengths correctly. */
- if (GET_CODE (insn) == JUMP_INSN)
- {
- rtx body;
-
- body = PATTERN (insn);
- if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
- addr += (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC)
- * GET_MODE_SIZE (GET_MODE (body)));
- addr += GET_MODE_SIZE (GET_MODE (body)) - 1;
- }
-
- if (GET_CODE (insn) == BARRIER)
- {
- /* Output any constants we have accumulated. Note that we
- don't need to change ADDR, since its only use is
- subtraction from INSNS_LEN, and both would be changed by
- the same amount.
- ??? If the instructions up to the next barrier reuse a
- constant, it would often be better to continue
- accumulating. */
- if (constants != NULL)
- dump_constants (constants, insn);
- constants = NULL;
- first_constant_ref = -1;
- }
-
- if (constants != NULL
- && (NEXT_INSN (insn) == NULL
- || (first_constant_ref >= 0
- && (((addr - first_constant_ref)
- + 2 /* for alignment */
- + 2 /* for a short jump insn */
- + pool_size)
- >= 0x8000))))
- {
- /* If we haven't had a barrier within 0x8000 bytes of a
- constant reference or we are at the end of the function,
- emit a barrier now. */
-
- rtx label, jump, barrier;
-
- label = gen_label_rtx ();
- jump = emit_jump_insn_after (gen_jump (label), insn);
- JUMP_LABEL (jump) = label;
- LABEL_NUSES (label) = 1;
- barrier = emit_barrier_after (jump);
- emit_label_after (label, barrier);
- first_constant_ref = -1;
- }
- }
-
- /* ??? If we output all references to a constant in internal
- constants table, we don't need to output the constant in the real
- constant table, but we have no way to prevent that. */
+ }
+ dump_constants (pool.first, get_last_insn ());
}