* [committed, 7/7] MIPS -mcode-readable support
@ 2007-08-08 15:59 Richard Sandiford
2007-08-20 18:12 ` David Daney
0 siblings, 1 reply; 3+ messages in thread
From: Richard Sandiford @ 2007-08-08 15:59 UTC (permalink / raw)
To: gcc-patches
This is the final patch in the -mcode-readable series.
After the rearrangements done by the previous patches, this one is
fairly straight-forward. The main complication is that MIPS16 has no
"lui" instruction, so we instead need to load the high part using "li"
and then shift it left. That is, we need a sequence like:
li $4,%hi(foo)
sll $4,16
Both of these instructions are extended ones, so (set ... (high ...))
takes the equivalent of 4 unextended instructions.
As usual, we want to split multi-instruction sequences so that they
can be individually scheduled, so we need a way of representing that
unshifted "%hi(foo)". The patch introduces a SYMBOL_32_HIGH type for
this purpose (to accompany the SYMBOL_64_* types that we already use for
static n64).
[ Note that as things stand, the sll will be further split into two
unextended slls. We can revisit them if they're too eager. ]
We also have to make various TARGET_MIPS16 conditions check what
type of code accesses are allowed. I've introduced some new
convenience macros for this. In particular, LABEL_REFs are used
for both in-function labels and jump tables, so we can only return
SYMBOL_PC_RELATIVE for labels if -mcode-readable=yes. This in turn
means that we need an unspec address wrapper around minipool accesses,
in order to force the minipool label to be SYMBOL_PC_RELATIVE for
-mcode-readable=pcrel.
Tested in the same way as the first patch and applied.
Richard
gcc/
2007-08-08 Richard Sandiford <richard@codesourcery.com>
Sandra Loosemore <sandra@codesourcery.com>
Chao-ying Fu <fu@mips.com>
Nigel Stephens <nigel@mips.com>
David Ung <davidu@mips.com>
* doc/invoke.texi (-mcode-readable): Document.
* config/mips/mips.opt (mcode-readable): New option.
* config/mips/mips-protos.h (SYMBOL_32_HIGH): New symbol type.
* config/mips/mips.h (mips_code_readable_setting): New enum.
(mips_code_readable): Declare.
(TARGET_MIPS16_TEXT_LOADS, TARGET_MIPS16_PCREL_LOADS): New macros.
(TARGET_MIPS16_SHORT_JUMP_TABLES): New macro.
(JUMP_TABLES_IN_TEXT_SECTION): Use it.
(CASE_VECTOR_MODE, CASE_VECTOR_PC_RELATIVE): Likewise. Remove
boiler-plate comments.
(ASM_OUTPUT_ADDR_DIFF_ELT): Use TARGET_MIPS16_SHORT_JUMP_TABLES.
* config/mips/mips.c (mips_code_readable): New variable.
(mips_classify_symbol): Only return SYMBOL_PC_RELATIVE for
MIPS16 labels if TARGET_MIPS16_SHORT_JUMP_TABLES. Use both the
context and -mcode-readable setting to restrict the use of
SYMBOL_PC_RELATIVE for MIPS16 constant pool references.
Only return TARGET_FORCE_TO_MEM if PC-relative loads are allowed.
(mips_symbolic_constant_p): Handle SYMBOL_32_HIGH.
(mips_blocks_for_constant_p): Only return false for
TARGET_MIPS16_PCREL_LOADS.
(mips_symbol_insns_1): Treat HIGHs as 2 extended instructions
for MIPS16. Handle SYMBOL_32_HIGH.
(mips_const_insns): Allow HIGHs for MIPS16 too.
(mips_unspec_address_offset): New function, split out from...
(mips_unspec_address): ...here.
(mips_output_move): Handle MIPS16 HIGH moves. Use "li" to load
16-bit symbolic constants. Assert approropiate conditions for
using the "la" and "dla" macros.
(mips_handle_option): Handle -mcode-readable=.
(override_options): Use %hi/%lo relocations for TARGET_MIPS16 too.
Set up mips_lo_relocs[SYMBOL_32_HIGH].
(mips_strip_unspec_address): New function, split out from...
(print_operand_reloc): ...here.
(print_operand): Pass constants through mips_strip_unspec_address.
(print_operand_address): Likewise.
(mips_output_mi_thunk): Remove guard of mips16_lay_out_constants.
(mips_select_rtx_section): Remove MIPS16 handling.
(mips16_gp_pseudo_reg): Check currently_expanding_to_rtl.
(mips16_rewrite_pool_refs): Wrap the labels in an address UNSPEC.
(mips16_lay_out_constants): Do nothing unless
TARGET_MIPS16_PCREL_LOADS.
(mips_avoid_hazards): Remove guard of mips16_lay_out_constants.
* config/mips/mips.md: Split HIGHs for MIPS16.
(tablejump): Use TARGET_MIPS16_SHORT_JUMP_TABLES.
gcc/testsuite/
* gcc.target/mips/code-readable-1.c: New test.
* gcc.target/mips/code-readable-2.c: Likewise.
* gcc.target/mips/code-readable-3.c: Likewise.
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi 2007-08-08 15:22:01.000000000 +0100
+++ gcc/doc/invoke.texi 2007-08-08 16:46:13.000000000 +0100
@@ -628,6 +628,7 @@ Objective-C and Objective-C++ Dialects}.
-mlong64 -mlong32 -msym32 -mno-sym32 @gol
-G@var{num} -membedded-data -mno-embedded-data @gol
-muninit-const-in-rodata -mno-uninit-const-in-rodata @gol
+-mcode-readable=@var{setting} @gol
-msplit-addresses -mno-split-addresses @gol
-mexplicit-relocs -mno-explicit-relocs @gol
-mcheck-zero-division -mno-check-zero-division @gol
@@ -11779,6 +11780,31 @@ when executing, and thus may be preferre
Put uninitialized @code{const} variables in the read-only data section.
This option is only meaningful in conjunction with @option{-membedded-data}.
+@item -mcode-readable=@var{setting}
+@opindex mcode-readable
+Specify whether GCC may generate code that reads from executable sections.
+There are three possible settings:
+
+@table @gcctabopt
+@item -mcode-readable=yes
+Instructions may freely access executable sections. This is the
+default setting.
+
+@item -mcode-readable=pcrel
+MIPS16 PC-relative load instructions can access executable sections,
+but other instructions must not do so. This option is useful on 4KSc
+and 4KSd processors when the code TLBs have the Read Inhibit bit set.
+It is also useful on processors that can be configured to have a dual
+instruction/data SRAM interface and that, like the M4K, automatically
+redirect PC-relative loads to the instruction RAM.
+
+@item -mcode-readable=no
+Instructions must not access executable sections. This option can be
+useful on targets that are configured to have a dual instruction/data
+SRAM interface but that (unlike the M4K) do not automatically redirect
+PC-relative loads to the instruction RAM.
+@end table
+
@item -msplit-addresses
@itemx -mno-split-addresses
@opindex msplit-addresses
Index: gcc/config/mips/mips.opt
===================================================================
--- gcc/config/mips/mips.opt 2007-08-08 15:22:01.000000000 +0100
+++ gcc/config/mips/mips.opt 2007-08-08 16:49:02.000000000 +0100
@@ -228,6 +228,10 @@ msym32
Target Report Var(TARGET_SYM32)
Assume all symbols have 32-bit values
+mcode-readable=
+Target RejectNegative Joined
+-mcode-readable=SETTING Specify when instructions are allowed to access code
+
mtune=
Target RejectNegative Joined Var(mips_tune_string)
-mtune=PROCESSOR Optimize the output for PROCESSOR
Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h 2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips-protos.h 2007-08-08 16:46:13.000000000 +0100
@@ -93,6 +93,9 @@ enum mips_symbol_context {
UNSPEC wrappers around SYMBOL_TLS, corresponding to the
thread-local storage relocation operators.
+ SYMBOL_32_HIGH
+ For a 32-bit symbolic address X, this is the value of %hi(X).
+
SYMBOL_64_HIGH
For a 64-bit symbolic address X, this is the value of
(%highest(X) << 16) + %higher(X).
@@ -125,6 +128,7 @@ enum mips_symbol_type {
SYMBOL_DTPREL,
SYMBOL_GOTTPREL,
SYMBOL_TPREL,
+ SYMBOL_32_HIGH,
SYMBOL_64_HIGH,
SYMBOL_64_MID,
SYMBOL_64_LOW,
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h 2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips.h 2007-08-08 16:46:13.000000000 +0100
@@ -114,6 +114,13 @@ struct mips_cpu_info {
int isa;
};
+/* Enumerates the setting of the -mcode-readable option. */
+enum mips_code_readable_setting {
+ CODE_READABLE_NO,
+ CODE_READABLE_PCREL,
+ CODE_READABLE_YES
+};
+
#ifndef USED_FOR_TARGET
extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
extern const char *current_function_file; /* filename current function is in */
@@ -138,6 +145,7 @@ extern GTY(()) rtx cmp_operands[2];
extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
extern const struct mips_rtx_cost_data *mips_cost;
+extern enum mips_code_readable_setting mips_code_readable;
#endif
/* Macros to silence warnings about numbers being signed in traditional
@@ -214,6 +222,16 @@ #define GENERATE_MIPS16E (TARGET_MIPS16
/* Generate mips16e register save/restore sequences. */
#define GENERATE_MIPS16E_SAVE_RESTORE (GENERATE_MIPS16E && mips_abi == ABI_32)
+/* True if we're generating a form of MIPS16 code in which general
+ text loads are allowed. */
+#define TARGET_MIPS16_TEXT_LOADS \
+ (TARGET_MIPS16 && mips_code_readable == CODE_READABLE_YES)
+
+/* True if we're generating a form of MIPS16 code in which PC-relative
+ loads are allowed. */
+#define TARGET_MIPS16_PCREL_LOADS \
+ (TARGET_MIPS16 && mips_code_readable >= CODE_READABLE_PCREL)
+
/* Generic ISA defines. */
#define ISA_MIPS1 (mips_isa == 1)
#define ISA_MIPS2 (mips_isa == 2)
@@ -2270,17 +2288,18 @@ #define SYMBOL_FLAG_LONG_CALL (SYMBOL_FL
#define SYMBOL_REF_LONG_CALL_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
-/* Specify the machine mode that this machine uses
- for the index in the tablejump instruction.
- ??? Using HImode in mips16 mode can cause overflow. */
-#define CASE_VECTOR_MODE \
- (TARGET_MIPS16 ? HImode : ptr_mode)
-
-/* Define as C expression which evaluates to nonzero if the tablejump
- instruction expects the table to contain offsets from the address of the
- table.
- Do not define this if the table should contain absolute addresses. */
-#define CASE_VECTOR_PC_RELATIVE (TARGET_MIPS16)
+/* True if we're generating a form of MIPS16 code in which jump tables
+ are stored in the text section and encoded as 16-bit PC-relative
+ offsets. This is only possible when general text loads are allowed,
+ since the table access itself will be an "lh" instruction. */
+/* ??? 16-bit offsets can overflow in large functions. */
+#define TARGET_MIPS16_SHORT_JUMP_TABLES TARGET_MIPS16_TEXT_LOADS
+
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_MIPS16_SHORT_JUMP_TABLES
+
+#define CASE_VECTOR_MODE (TARGET_MIPS16_SHORT_JUMP_TABLES ? HImode : ptr_mode)
+
+#define CASE_VECTOR_PC_RELATIVE TARGET_MIPS16_SHORT_JUMP_TABLES
/* Define this as 1 if `char' should by default be signed; else as 0. */
#ifndef DEFAULT_SIGNED_CHAR
@@ -2650,7 +2669,7 @@ #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
do { \
- if (TARGET_MIPS16) \
+ if (TARGET_MIPS16_SHORT_JUMP_TABLES) \
fprintf (STREAM, "\t.half\t%sL%d-%sL%d\n", \
LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL); \
else if (TARGET_GPWORD) \
@@ -2673,10 +2692,6 @@ #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,
LOCAL_LABEL_PREFIX, VALUE); \
} while (0)
-/* When generating MIPS16 code, we want the jump table to be in the text
- section so that we can load its address using a PC-relative addition. */
-#define JUMP_TABLES_IN_TEXT_SECTION TARGET_MIPS16
-
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c 2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips.c 2007-08-08 16:46:13.000000000 +0100
@@ -616,6 +616,9 @@ int mips_abi = MIPS_ABI_DEFAULT;
/* Cost information to use. */
const struct mips_rtx_cost_data *mips_cost;
+/* The -mtext-loads setting. */
+enum mips_code_readable_setting mips_code_readable = CODE_READABLE_YES;
+
/* Whether we are generating mips16 hard float code. In mips16 mode
we always set TARGET_SOFT_FLOAT; this variable is nonzero if
-msoft-float was not specified by the user, which means that we
@@ -1444,7 +1447,10 @@ mips_classify_symbol (rtx x, enum mips_s
if (GET_CODE (x) == LABEL_REF)
{
- if (TARGET_MIPS16)
+ /* LABEL_REFs are used for jump tables as well as text labels.
+ Only return SYMBOL_PC_RELATIVE if we know the label is in
+ the text section. */
+ if (TARGET_MIPS16_SHORT_JUMP_TABLES)
return SYMBOL_PC_RELATIVE;
if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
return SYMBOL_GOT_PAGE_OFST;
@@ -1458,7 +1464,10 @@ mips_classify_symbol (rtx x, enum mips_s
if (CONSTANT_POOL_ADDRESS_P (x))
{
- if (TARGET_MIPS16)
+ if (TARGET_MIPS16_TEXT_LOADS)
+ return SYMBOL_PC_RELATIVE;
+
+ if (TARGET_MIPS16_PCREL_LOADS && context == SYMBOL_CONTEXT_MEM)
return SYMBOL_PC_RELATIVE;
if (!TARGET_EMBEDDED_DATA
@@ -1502,7 +1511,7 @@ mips_classify_symbol (rtx x, enum mips_s
return SYMBOL_GOT_PAGE_OFST;
}
- if (TARGET_MIPS16 && context != SYMBOL_CONTEXT_CALL)
+ if (TARGET_MIPS16_PCREL_LOADS && context != SYMBOL_CONTEXT_CALL)
return SYMBOL_FORCE_TO_MEM;
return SYMBOL_ABSOLUTE;
}
@@ -1560,6 +1569,7 @@ mips_symbolic_constant_p (rtx x, enum mi
{
case SYMBOL_ABSOLUTE:
case SYMBOL_FORCE_TO_MEM:
+ case SYMBOL_32_HIGH:
case SYMBOL_64_HIGH:
case SYMBOL_64_MID:
case SYMBOL_64_LOW:
@@ -1774,14 +1784,14 @@ mips_cannot_force_const_mem (rtx x)
return false;
}
-/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. MIPS16 uses per-function
- constant pools, but normal-mode code doesn't need to. */
+/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. We can't use blocks for
+ constants when we're using a per-function constant pool. */
static bool
mips_use_blocks_for_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
rtx x ATTRIBUTE_UNUSED)
{
- return !TARGET_MIPS16;
+ return !TARGET_MIPS16_PCREL_LOADS;
}
\f
/* Like mips_symbol_insns, but treat extended MIPS16 instructions as a
@@ -1805,8 +1815,9 @@ mips_symbol_insns_1 (enum mips_symbol_ty
dsll $at,$at,16
The final address is then $at + %lo(symbol). With 32-bit
- symbols we just need a preparatory lui. */
- return ABI_HAS_64BIT_SYMBOLS ? 6 : 2;
+ symbols we just need a preparatory lui for normal mode and
+ a preparatory "li; sll" for MIPS16. */
+ return ABI_HAS_64BIT_SYMBOLS ? 6 : TARGET_MIPS16 ? 3 : 2;
case SYMBOL_GP_RELATIVE:
/* Treat GP-relative accesses as taking a single instruction on
@@ -1863,6 +1874,7 @@ mips_symbol_insns_1 (enum mips_symbol_ty
case SYMBOL_GOTOFF_DISP:
case SYMBOL_GOTOFF_CALL:
case SYMBOL_GOTOFF_LOADGP:
+ case SYMBOL_32_HIGH:
case SYMBOL_64_HIGH:
case SYMBOL_64_MID:
case SYMBOL_64_LOW:
@@ -1875,7 +1887,7 @@ mips_symbol_insns_1 (enum mips_symbol_ty
/* A 16-bit constant formed by a single relocation, or a 32-bit
constant formed from a high 16-bit relocation and a low 16-bit
relocation. Use mips_split_p to determine which. */
- return mips_split_p[type] ? 2 : 1;
+ return !mips_split_p[type] ? 1 : TARGET_MIPS16 ? 3 : 2;
case SYMBOL_TLS:
/* We don't treat a bare TLS symbol as a constant. */
@@ -1989,13 +2001,14 @@ mips_const_insns (rtx x)
switch (GET_CODE (x))
{
case HIGH:
- if (TARGET_MIPS16
- || !mips_symbolic_constant_p (XEXP (x, 0), SYMBOL_CONTEXT_LEA,
- &symbol_type)
+ if (!mips_symbolic_constant_p (XEXP (x, 0), SYMBOL_CONTEXT_LEA,
+ &symbol_type)
|| !mips_split_p[symbol_type])
return 0;
- return 1;
+ /* This is simply an lui for normal mode. It is an extended
+ "li" followed by an extended "sll" for MIPS16. */
+ return TARGET_MIPS16 ? 4 : 1;
case CONST_INT:
if (TARGET_MIPS16)
@@ -2173,6 +2186,20 @@ mips_split_symbol (rtx temp, rtx addr, e
}
+/* Wrap symbol or label BASE in an unspec address of type SYMBOL_TYPE
+ and add CONST_INT OFFSET to the result. */
+
+static rtx
+mips_unspec_address_offset (rtx base, rtx offset,
+ enum mips_symbol_type symbol_type)
+{
+ base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
+ UNSPEC_ADDRESS_FIRST + symbol_type);
+ if (offset != const0_rtx)
+ base = gen_rtx_PLUS (Pmode, base, offset);
+ return gen_rtx_CONST (Pmode, base);
+}
+
/* Return an UNSPEC address with underlying address ADDRESS and symbol
type SYMBOL_TYPE. */
@@ -2182,11 +2209,7 @@ mips_unspec_address (rtx address, enum m
rtx base, offset;
split_const (address, &base, &offset);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
- UNSPEC_ADDRESS_FIRST + symbol_type);
- if (offset != const0_rtx)
- base = gen_rtx_PLUS (Pmode, base, offset);
- return gen_rtx_CONST (Pmode, base);
+ return mips_unspec_address_offset (base, offset, symbol_type);
}
@@ -3130,6 +3153,7 @@ mips_split_64bit_move (rtx dest, rtx src
mips_output_move (rtx dest, rtx src)
{
enum rtx_code dest_code, src_code;
+ enum mips_symbol_type symbol_type;
bool dbl_p;
dest_code = GET_CODE (dest);
@@ -3217,13 +3241,27 @@ mips_output_move (rtx dest, rtx src)
}
if (src_code == HIGH)
- return "lui\t%0,%h1";
+ return TARGET_MIPS16 ? "#" : "lui\t%0,%h1";
if (CONST_GP_P (src))
return "move\t%0,%1";
+ if (mips_symbolic_constant_p (src, SYMBOL_CONTEXT_LEA, &symbol_type)
+ && mips_lo_relocs[symbol_type] != 0)
+ {
+ /* A signed 16-bit constant formed by applying a relocation
+ operator to a symbolic address. */
+ gcc_assert (!mips_split_p[symbol_type]);
+ return "li\t%0,%R1";
+ }
+
if (symbolic_operand (src, VOIDmode))
- return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
+ {
+ gcc_assert (TARGET_MIPS16
+ ? TARGET_MIPS16_TEXT_LOADS
+ : !TARGET_EXPLICIT_RELOCS);
+ return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
+ }
}
if (src_code == REG && FP_REG_P (REGNO (src)))
{
@@ -5007,6 +5045,17 @@ mips_handle_option (size_t code, const c
mips_cache_flush_func = NULL;
return true;
+ case OPT_mcode_readable_:
+ if (strcmp (arg, "yes") == 0)
+ mips_code_readable = CODE_READABLE_YES;
+ else if (strcmp (arg, "pcrel") == 0)
+ mips_code_readable = CODE_READABLE_PCREL;
+ else if (strcmp (arg, "no") == 0)
+ mips_code_readable = CODE_READABLE_NO;
+ else
+ return false;
+ return true;
+
default:
return true;
}
@@ -5456,11 +5505,13 @@ override_options (void)
}
else
{
- if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
+ if (TARGET_EXPLICIT_RELOCS || mips_split_addresses || TARGET_MIPS16)
{
mips_split_p[SYMBOL_ABSOLUTE] = true;
mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
+
+ mips_lo_relocs[SYMBOL_32_HIGH] = "%hi(";
}
}
@@ -5718,6 +5769,20 @@ mips_debugger_offset (rtx addr, HOST_WID
return offset;
}
\f
+/* If OP is an UNSPEC address, return the address to which it refers,
+ otherwise return OP itself. */
+
+static rtx
+mips_strip_unspec_address (rtx op)
+{
+ rtx base, offset;
+
+ split_const (op, &base, &offset);
+ if (UNSPEC_ADDRESS_P (base))
+ op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
+ return op;
+}
+
/* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are:
'X' OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
@@ -6055,7 +6120,7 @@ print_operand (FILE *file, rtx op, int l
fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
else
- output_addr_const (file, op);
+ output_addr_const (file, mips_strip_unspec_address (op));
}
@@ -6068,19 +6133,13 @@ print_operand_reloc (FILE *file, rtx op,
{
enum mips_symbol_type symbol_type;
const char *p;
- rtx base, offset;
if (!mips_symbolic_constant_p (op, context, &symbol_type)
|| relocs[symbol_type] == 0)
fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
- /* If OP uses an UNSPEC address, we want to print the inner symbol. */
- split_const (op, &base, &offset);
- if (UNSPEC_ADDRESS_P (base))
- op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
-
fputs (relocs[symbol_type], file);
- output_addr_const (file, op);
+ output_addr_const (file, mips_strip_unspec_address (op));
for (p = relocs[symbol_type]; *p != 0; p++)
if (*p == '(')
fputc (')', file);
@@ -6113,7 +6172,7 @@ print_operand_address (FILE *file, rtx x
return;
case ADDRESS_SYMBOLIC:
- output_addr_const (file, x);
+ output_addr_const (file, mips_strip_unspec_address (x));
return;
}
gcc_unreachable ();
@@ -8192,8 +8251,7 @@ mips_output_mi_thunk (FILE *file, tree t
insn = get_insns ();
insn_locators_alloc ();
split_all_insns_noflow ();
- if (TARGET_MIPS16)
- mips16_lay_out_constants ();
+ mips16_lay_out_constants ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1);
@@ -8232,14 +8290,7 @@ symbolic_expression_p (rtx x)
mips_select_rtx_section (enum machine_mode mode, rtx x,
unsigned HOST_WIDE_INT align)
{
- if (TARGET_MIPS16)
- {
- /* In mips16 mode, the constant table always goes in the same section
- as the function, so that constants can be loaded using PC relative
- addressing. */
- return function_section (current_function_decl);
- }
- else if (TARGET_EMBEDDED_DATA)
+ if (TARGET_EMBEDDED_DATA)
{
/* For embedded applications, always put constants in read-only data,
in order to reduce RAM usage. */
@@ -8827,7 +8878,7 @@ mips16_gp_pseudo_reg (void)
/* Don't initialize the pseudo register if we are being called from
the tree optimizers' cost-calculation routines. */
if (!cfun->machine->initialized_mips16_gp_pseudo_p
- && current_ir_type () != IR_GIMPLE)
+ && (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl))
{
rtx insn, scan;
@@ -9546,11 +9597,23 @@ mips16_insn_length (rtx insn)
mips16_rewrite_pool_refs (rtx *x, void *data)
{
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;
+ rtx base, offset, label;
+
+ if (MEM_P (*x))
+ x = &XEXP (*x, 0);
+ else if (!TARGET_MIPS16_TEXT_LOADS)
+ return 0;
+
+ split_const (*x, &base, &offset);
+ if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
+ {
+ label = add_constant (pool, get_pool_constant (base),
+ get_pool_mode (base));
+ base = gen_rtx_LABEL_REF (Pmode, label);
+ *x = mips_unspec_address_offset (base, offset, SYMBOL_PC_RELATIVE);
+ return -1;
+ }
+ return GET_CODE (*x) == CONST ? -1 : 0;
}
/* Build MIPS16 constant pools. */
@@ -9561,6 +9624,9 @@ mips16_lay_out_constants (void)
struct mips16_constant_pool pool;
rtx insn, barrier;
+ if (!TARGET_MIPS16_PCREL_LOADS)
+ return;
+
barrier = 0;
memset (&pool, 0, sizeof (pool));
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -10117,9 +10183,8 @@ mips_avoid_hazards (void)
static void
mips_reorg (void)
{
- if (TARGET_MIPS16)
- mips16_lay_out_constants ();
- else if (TARGET_EXPLICIT_RELOCS)
+ mips16_lay_out_constants ();
+ if (TARGET_EXPLICIT_RELOCS)
{
if (mips_flag_delayed_branch)
dbr_schedule (get_insns ());
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-08-08 16:46:04.000000000 +0100
+++ gcc/config/mips/mips.md 2007-08-08 16:46:13.000000000 +0100
@@ -3181,6 +3181,22 @@ (define_insn_and_split "*lea64"
}
[(set_attr "length" "24")])
+;; Split HIGHs into:
+;;
+;; li op0,%hi(sym)
+;; sll op0,16
+;;
+;; on MIPS16 targets.
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (high:SI (match_operand:SI 1 "absolute_symbolic_operand" "")))]
+ "TARGET_MIPS16 && reload_completed"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))]
+{
+ operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH);
+})
+
;; Insns to fetch a symbol from a big GOT.
(define_insn_and_split "*xgot_hi<mode>"
@@ -5050,7 +5066,7 @@ (define_expand "tablejump"
(use (label_ref (match_operand 1 "")))]
""
{
- if (TARGET_MIPS16)
+ if (TARGET_MIPS16_SHORT_JUMP_TABLES)
operands[0] = expand_binop (Pmode, add_optab,
convert_to_mode (Pmode, operands[0], false),
gen_rtx_LABEL_REF (Pmode, operands[1]),
Index: gcc/testsuite/gcc.target/mips/code-readable-1.c
===================================================================
--- /dev/null 2007-08-08 08:10:29.588099250 +0100
+++ gcc/testsuite/gcc.target/mips/code-readable-1.c 2007-08-08 16:46:13.000000000 +0100
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mips16 -mcode-readable=yes -mgp32" } */
+
+int
+foo (int i)
+{
+ switch (i)
+ {
+ case 1: return 40;
+ case 2: return 11;
+ case 3: return 29;
+ case 4: return 10;
+ case 5: return 12;
+ case 6: return 35;
+ case 7: return 23;
+ default: return 0;
+ }
+}
+
+extern int k[];
+
+int *
+bar (void)
+{
+ return k;
+}
+
+/* { dg-final { scan-assembler "\tla\t" } } */
+/* { dg-final { scan-assembler "\t\.half\t" } } */
+/* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\.word\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
Index: gcc/testsuite/gcc.target/mips/code-readable-2.c
===================================================================
--- /dev/null 2007-08-08 08:10:29.588099250 +0100
+++ gcc/testsuite/gcc.target/mips/code-readable-2.c 2007-08-08 16:46:13.000000000 +0100
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mips16 -mcode-readable=pcrel -mgp32" } */
+
+int
+foo (int i)
+{
+ switch (i)
+ {
+ case 1: return 40;
+ case 2: return 11;
+ case 3: return 29;
+ case 4: return 10;
+ case 5: return 12;
+ case 6: return 35;
+ case 7: return 23;
+ default: return 0;
+ }
+}
+
+extern int k[];
+
+int *
+bar (void)
+{
+ return k;
+}
+
+/* { dg-final { scan-assembler-not "\tla\t" } } */
+/* { dg-final { scan-assembler-not "\t\.half\t" } } */
+/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\.word\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
Index: gcc/testsuite/gcc.target/mips/code-readable-3.c
===================================================================
--- /dev/null 2007-08-08 08:10:29.588099250 +0100
+++ gcc/testsuite/gcc.target/mips/code-readable-3.c 2007-08-08 16:46:13.000000000 +0100
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mips16 -mcode-readable=no -mgp32" } */
+
+int
+foo (int i)
+{
+ switch (i)
+ {
+ case 1: return 40;
+ case 2: return 11;
+ case 3: return 29;
+ case 4: return 10;
+ case 5: return 12;
+ case 6: return 35;
+ case 7: return 23;
+ default: return 0;
+ }
+}
+
+extern int k[];
+
+int *
+bar (void)
+{
+ return k;
+}
+
+/* { dg-final { scan-assembler-not "\tla\t" } } */
+/* { dg-final { scan-assembler-not "\t\.half\t" } } */
+/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler-not "\t\.word\tk\n" } } */
+/* { dg-final { scan-assembler "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler "%lo\\(k\\)" } } */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [committed, 7/7] MIPS -mcode-readable support
2007-08-08 15:59 [committed, 7/7] MIPS -mcode-readable support Richard Sandiford
@ 2007-08-20 18:12 ` David Daney
2007-08-20 18:25 ` Richard Sandiford
0 siblings, 1 reply; 3+ messages in thread
From: David Daney @ 2007-08-20 18:12 UTC (permalink / raw)
To: gcc-patches, richard
[-- Attachment #1: Type: text/plain, Size: 397 bytes --]
Richard Sandiford wrote:
> gcc/testsuite/
> * gcc.target/mips/code-readable-1.c: New test.
> * gcc.target/mips/code-readable-2.c: Likewise.
> * gcc.target/mips/code-readable-3.c: Likewise.
See:
http://gcc.gnu.org/ml/gcc-testresults/2007-08/msg00661.html
Similar results I think on mips64-linux cross compiler.
It is probably not expected that I would get the attached errors.
David Daney
[-- Attachment #2: code-readable.errors --]
[-- Type: text/plain, Size: 5435 bytes --]
Executing on host: /home/build/gcc-build/gcc/xgcc -B/home/build/gcc-build/gcc/ /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c -mips16 -mcode-readable=yes -mgp32 -fno-show-column -S -o code-readable-1.s (timeout = 300)
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c: In function 'bar':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: error: insn does not satisfy its constraints:
(insn 21 2 5 /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:24 (set (reg:SI 2 $2)
(symbol_ref:SI ("k") [flags 0x40] <var_decl 0x2ae04380 k>)) 212 {*movsi_mips16} (nil))
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: internal compiler error: in extract_constrain_insn_cached, at recog.c:1907
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c: In function 'bar':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: error: insn does not satisfy its constraints:
(insn 21 2 5 /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:24 (set (reg:SI 2 $2)
(symbol_ref:SI ("k") [flags 0x40] <var_decl 0x2ae04380 k>)) 212 {*movsi_mips16} (nil))
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: internal compiler error: in extract_constrain_insn_cached, at recog.c:1907
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
FAIL: gcc.target/mips/code-readable-1.c (internal compiler error)
FAIL: gcc.target/mips/code-readable-1.c (test for excess errors)
Excess errors:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: error: insn does not satisfy its constraints:
(insn 21 2 5 /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:24 (set (reg:SI 2 $2)
(symbol_ref:SI ("k") [flags 0x40] <var_decl 0x2ae04380 k>)) 212 {*movsi_mips16} (nil))
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-1.c:25: internal compiler error: in extract_constrain_insn_cached, at recog.c:1907
ERROR: gcc.target/mips/code-readable-1.c: error executing dg-final: couldn't open "code-readable-1.s": no such file or directory
UNRESOLVED: gcc.target/mips/code-readable-1.c: error executing dg-final: couldn't open "code-readable-1.s": no such file or directory
Executing on host: /home/build/gcc-build/gcc/xgcc -B/home/build/gcc-build/gcc/ /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c -mips16 -mcode-readable=pcrel -mgp32 -fno-show-column -S -o code-readable-2.s (timeout = 300)
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
FAIL: gcc.target/mips/code-readable-2.c (internal compiler error)
FAIL: gcc.target/mips/code-readable-2.c (test for excess errors)
Excess errors:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-2.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
ERROR: gcc.target/mips/code-readable-2.c: error executing dg-final: couldn't open "code-readable-2.s": no such file or directory
UNRESOLVED: gcc.target/mips/code-readable-2.c: error executing dg-final: couldn't open "code-readable-2.s": no such file or directory
Executing on host: /home/build/gcc-build/gcc/xgcc -B/home/build/gcc-build/gcc/ /home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c -mips16 -mcode-readable=no -mgp32 -fno-show-column -S -o code-readable-3.s (timeout = 300)
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c: In function 'foo':
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
FAIL: gcc.target/mips/code-readable-3.c (internal compiler error)
FAIL: gcc.target/mips/code-readable-3.c (test for excess errors)
Excess errors:
/home/build/gcc/gcc/testsuite/gcc.target/mips/code-readable-3.c:17: internal compiler error: in mips_output_move, at config/mips/mips.c:3282
ERROR: gcc.target/mips/code-readable-3.c: error executing dg-final: couldn't open "code-readable-3.s": no such file or directory
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [committed, 7/7] MIPS -mcode-readable support
2007-08-20 18:12 ` David Daney
@ 2007-08-20 18:25 ` Richard Sandiford
0 siblings, 0 replies; 3+ messages in thread
From: Richard Sandiford @ 2007-08-20 18:25 UTC (permalink / raw)
To: David Daney; +Cc: gcc-patches
David Daney <ddaney@avtrex.com> writes:
> Richard Sandiford wrote:
>
>> gcc/testsuite/
>> * gcc.target/mips/code-readable-1.c: New test.
>> * gcc.target/mips/code-readable-2.c: Likewise.
>> * gcc.target/mips/code-readable-3.c: Likewise.
>
> See:
> http://gcc.gnu.org/ml/gcc-testresults/2007-08/msg00661.html
>
> Similar results I think on mips64-linux cross compiler.
>
> It is probably not expected that I would get the attached errors.
Actually, it is kind-of expected. This is just because we're trying to
use MIPS16 abicalls, which isn't a supported combination. I've never been
brave enough to make it a hard error, because -- as the gcc.target/mips
directory shows -- there are cases where a careful user could get by with
-mips16 -mabicalls, and I'd probably be accused of breaking something that
previously worked. These particular tests are not such cases.
For the time being, can you try adding -mno-abicalls to the
dg-mips-options for these tests?
Richard
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-08-20 18:12 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08 15:59 [committed, 7/7] MIPS -mcode-readable support Richard Sandiford
2007-08-20 18:12 ` David Daney
2007-08-20 18:25 ` Richard Sandiford
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).