MIPS/GCC: Mark text contents as code or data

gcc/
	* config/mips/mips-protos.h (mips_set_text_contents_type): New
	prototype.
	* config/mips/mips.h (ASM_OUTPUT_BEFORE_CASE_LABEL): New macro.
	(ASM_OUTPUT_CASE_END): Likewise.
	* config/mips/mips.c (mips_set_text_contents_type): New
	function.
	(mips16_emit_constants): Record the pool's initial label number
	with the `consttable' insn.  Emit a `consttable_end' insn at the
	end.
	(mips_final_prescan_insn): Call `mips_set_text_contents_type'
	for `consttable' insns.
	(mips_final_postscan_insn): Call `mips_set_text_contents_type'
	for `consttable_end' insns.
	* config/mips/mips.md (unspec): Add UNSPEC_CONSTTABLE_END enum
	value.
	(consttable): Add operand.
	(consttable_end): New insn.

	gcc/testsuite/
	* gcc.target/mips/data-sym-jump.c: New test case.
	* gcc.target/mips/data-sym-pool.c: New test case.
	* gcc.target/mips/insn-pseudo-4.c: Adjust for constant pool
	annotation.

From-SVN: r242502
This commit is contained in:
Maciej W. Rozycki 2016-11-16 17:12:08 +00:00 committed by Maciej W. Rozycki
parent 598eaaa2a2
commit 2fe2aba3cd
9 changed files with 209 additions and 6 deletions

View file

@ -1,3 +1,23 @@
2016-11-16 Maciej W. Rozycki <macro@imgtec.com>
* config/mips/mips-protos.h (mips_set_text_contents_type): New
prototype.
* config/mips/mips.h (ASM_OUTPUT_BEFORE_CASE_LABEL): New macro.
(ASM_OUTPUT_CASE_END): Likewise.
* config/mips/mips.c (mips_set_text_contents_type): New
function.
(mips16_emit_constants): Record the pool's initial label number
with the `consttable' insn. Emit a `consttable_end' insn at the
end.
(mips_final_prescan_insn): Call `mips_set_text_contents_type'
for `consttable' insns.
(mips_final_postscan_insn): Call `mips_set_text_contents_type'
for `consttable_end' insns.
* config/mips/mips.md (unspec): Add UNSPEC_CONSTTABLE_END enum
value.
(consttable): Add operand.
(consttable_end): New insn.
2016-11-16 Yuri Rumyantsev <ysrumyan@gmail.com>
* params.def (PARAM_VECT_EPILOGUES_NOMASK): New.

View file

@ -271,6 +271,8 @@ extern void mips_declare_object (FILE *, const char *, const char *,
const char *, ...) ATTRIBUTE_PRINTF_4;
extern void mips_declare_object_name (FILE *, const char *, tree);
extern void mips_finish_declare_object (FILE *, tree, int, int);
extern void mips_set_text_contents_type (FILE *, const char *,
unsigned long, bool);
extern bool mips_small_data_pattern_p (rtx);
extern rtx mips_rewrite_small_data (rtx);

View file

@ -9749,6 +9749,37 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
}
}
#endif
/* Mark text contents as code or data, mainly for the purpose of correct
disassembly. Emit a local symbol and set its type appropriately for
that purpose. Also emit `.insn' if marking contents as code so that
the ISA mode is recorded and any padding that follows is disassembled
as correct instructions. */
void
mips_set_text_contents_type (FILE *file ATTRIBUTE_UNUSED,
const char *prefix ATTRIBUTE_UNUSED,
unsigned long num ATTRIBUTE_UNUSED,
bool function_p ATTRIBUTE_UNUSED)
{
#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
char buf[(sizeof (num) * 10) / 4 + 2];
const char *fnname;
char *sname;
rtx symbol;
sprintf (buf, "%lu", num);
symbol = XEXP (DECL_RTL (current_function_decl), 0);
fnname = targetm.strip_name_encoding (XSTR (symbol, 0));
sname = ACONCAT ((prefix, fnname, "_", buf, NULL));
ASM_OUTPUT_TYPE_DIRECTIVE (file, sname, function_p ? "function" : "object");
assemble_name (file, sname);
fputs (":\n", file);
if (function_p)
fputs ("\t.insn\n", file);
#endif
}
/* Return the FOO in the name of the ".mdebug.FOO" section associated
with the current ABI. */
@ -17131,17 +17162,22 @@ mips16_emit_constants_1 (machine_mode mode, rtx value, rtx_insn *insn)
gcc_unreachable ();
}
/* Dump out the constants in CONSTANTS after INSN. */
/* Dump out the constants in CONSTANTS after INSN. Record the initial
label number in the `consttable' and `consttable_end' insns emitted
at the beginning and the end of the constant pool respectively, so
that individual pools can be uniquely marked as data for the purpose
of disassembly. */
static void
mips16_emit_constants (struct mips16_constant *constants, rtx_insn *insn)
{
int label_num = constants ? CODE_LABEL_NUMBER (constants->label) : 0;
struct mips16_constant *c, *next;
int align;
align = 0;
if (constants)
insn = emit_insn_after (gen_consttable (), insn);
insn = emit_insn_after (gen_consttable (GEN_INT (label_num)), insn);
for (c = constants; c != NULL; c = next)
{
/* If necessary, increase the alignment of PC. */
@ -17158,6 +17194,8 @@ mips16_emit_constants (struct mips16_constant *constants, rtx_insn *insn)
next = c->next;
free (c);
}
if (constants)
insn = emit_insn_after (gen_consttable_end (GEN_INT (label_num)), insn);
emit_barrier_after (insn);
}
@ -20268,16 +20306,32 @@ mips_need_noat_wrapper_p (rtx_insn *insn, rtx *opvec, int noperands)
return false;
}
/* Implement FINAL_PRESCAN_INSN. */
/* Implement FINAL_PRESCAN_INSN. Mark MIPS16 inline constant pools
as data for the purpose of disassembly. For simplicity embed the
pool's initial label number in the local symbol produced so that
multiple pools within a single function end up marked with unique
symbols. The label number is carried by the `consttable' insn
emitted at the beginning of each pool. */
void
mips_final_prescan_insn (rtx_insn *insn, rtx *opvec, int noperands)
{
if (INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
&& XINT (PATTERN (insn), 1) == UNSPEC_CONSTTABLE)
mips_set_text_contents_type (asm_out_file, "__pool_",
XINT (XVECEXP (PATTERN (insn), 0, 0), 0),
FALSE);
if (mips_need_noat_wrapper_p (insn, opvec, noperands))
mips_push_asm_switch (&mips_noat);
}
/* Implement TARGET_ASM_FINAL_POSTSCAN_INSN. */
/* Implement TARGET_ASM_FINAL_POSTSCAN_INSN. Reset text marking to
code after a MIPS16 inline constant pool. Like with the beginning
of a pool table use the pool's initial label number to keep symbols
unique. The label number is carried by the `consttable_end' insn
emitted at the end of each pool. */
static void
mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx_insn *insn,
@ -20285,6 +20339,13 @@ mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx_insn *insn,
{
if (mips_need_noat_wrapper_p (insn, opvec, noperands))
mips_pop_asm_switch (&mips_noat);
if (INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
&& XINT (PATTERN (insn), 1) == UNSPEC_CONSTTABLE_END)
mips_set_text_contents_type (asm_out_file, "__pend_",
XINT (XVECEXP (PATTERN (insn), 0, 0), 0),
TRUE);
}
/* Return the function that is used to expand the <u>mulsidi3 pattern.

View file

@ -2986,6 +2986,32 @@ do { \
LOCAL_LABEL_PREFIX, VALUE); \
} while (0)
/* Mark inline jump tables as data for the purpose of disassembly. For
simplicity embed the jump table's label number in the local symbol
produced so that multiple jump tables within a single function end
up marked with unique symbols. Retain the alignment setting from
`elfos.h' as we are replacing the definition from there. */
#undef ASM_OUTPUT_BEFORE_CASE_LABEL
#define ASM_OUTPUT_BEFORE_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
do \
{ \
ASM_OUTPUT_ALIGN ((STREAM), 2); \
if (JUMP_TABLES_IN_TEXT_SECTION) \
mips_set_text_contents_type (STREAM, "__jump_", NUM, FALSE); \
} \
while (0);
/* Reset text marking to code after an inline jump table. Like with
the beginning of a jump table use the label number to keep symbols
unique. */
#define ASM_OUTPUT_CASE_END(STREAM, NUM, TABLE) \
do \
if (JUMP_TABLES_IN_TEXT_SECTION) \
mips_set_text_contents_type (STREAM, "__jend_", NUM, TRUE); \
while (0);
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */

View file

@ -121,6 +121,7 @@
;; MIPS16 constant pools.
UNSPEC_ALIGN
UNSPEC_CONSTTABLE
UNSPEC_CONSTTABLE_END
UNSPEC_CONSTTABLE_INT
UNSPEC_CONSTTABLE_FLOAT
@ -7321,7 +7322,16 @@
;;
(define_insn "consttable"
[(unspec_volatile [(const_int 0)] UNSPEC_CONSTTABLE)]
[(unspec_volatile [(match_operand 0 "const_int_operand" "")]
UNSPEC_CONSTTABLE)]
""
""
[(set_attr "mode" "none")
(set_attr "insn_count" "0")])
(define_insn "consttable_end"
[(unspec_volatile [(match_operand 0 "const_int_operand" "")]
UNSPEC_CONSTTABLE_END)]
""
""
[(set_attr "mode" "none")

View file

@ -1,3 +1,10 @@
2016-11-16 Maciej W. Rozycki <macro@imgtec.com>
* gcc.target/mips/data-sym-jump.c: New test case.
* gcc.target/mips/data-sym-pool.c: New test case.
* gcc.target/mips/insn-pseudo-4.c: Adjust for constant pool
annotation.
2016-11-16 Yuri Rumyantsev <ysrumyan@gmail.com>
* lib/target-supports.exp (check_avx2_hw_available): New.

View file

@ -0,0 +1,50 @@
/* { dg-do compile } */
/* { dg-options "-mips16 -mcode-readable=yes" } */
/* { dg-skip-if "MIPS16 `casesi' loses at -Os" { *-*-* } { "-Os"} { "" } } */
int
frob (int i)
{
switch (i)
{
case -5:
return -2;
case -3:
return -1;
case 0:
return 0;
case 3:
return 1;
case 5:
break;
default:
__builtin_unreachable ();
}
return i;
}
/* Expect assembly like:
la $2, $L4
# Anything goes here.
.type __jump_frob_4, @object # Symbol # must match label.
__jump_frob_4: # The symbol must match.
$L4: # The label must match.
.half $L3-$L4 # Or `.word'. The subtrahend
.half $L2-$L4 # label must match thoughout
.half $L9-$L4 # (repeated 11 times).
.half $L2-$L4 # .
.half $L2-$L4 # .
.half $L8-$L4 # .
.half $L2-$L4 # .
.half $L2-$L4 # .
.half $L7-$L4 # .
.half $L2-$L4 # .
.half $L8-$L4 # .
.type __jend_frob_4, @function # Symbol # must match label.
__jend_frob_4: # The symbol must match.
.insn
that is `__jump_*'/`__jend_*' symbols inserted around a jump table. */
/* { dg-final { scan-assembler "\tla\t\\\$\[0-9\]+, (.L(\[0-9\]+))\n.*\t\\.type\t(__jump_frob_\\2), @object\n\\3:\n\\1:\n(?:\t\\.(?:half|word)\t.L\[0-9\]+-\\1\n)\{11\}\t\\.type\t(__jend_frob_\\2), @function\n\\4:\n\t\\.insn\n" } } */

View file

@ -0,0 +1,25 @@
/* { dg-do compile } */
/* { dg-options "-mips16 -mcode-readable=yes" } */
int
frob (void)
{
return 0x12345678;
}
/* Expect assembly like:
lw $2,$L3
# Anything goes here.
.type __pool_frob_3, @object # Symbol # must match label.
__pool_frob_3: # The symbol must match.
.align 2
$L3: # The label must match.
.word 305419896
.type __pend_frob_3, @function # Symbol # must match label.
__pend_frob_3: # The symbol must match.
.insn
that is `__pool_*'/`__pend_*' symbols inserted around a constant pool. */
/* { dg-final { scan-assembler "\tlw\t\\\$\[0-9\]+,(.L(\[0-9\]+))\n.*\t\\.type\t(__pool_frob_\\2), @object\n\\3:\n\t\\.align\t2\n\\1:\n\t\\.word\t305419896\n\t\\.type\t(__pend_frob_\\2), @function\n\\4:\n\t\\.insn\n" } } */

View file

@ -18,10 +18,12 @@ punt:
$L2: # The label must match.
.insn
$L3 = . # It's there, but we don't care.
.type __pool_unreachable_5, @object
__pool_unreachable_5:
.align 2
$L5: # The label must match.
.word 305419896
that is .insn to be inserted if a code label is at a constant pool. */
/* { dg-final { scan-assembler "\tlw\t(\\\$\[0-9\]+),(.L\[0-9\]+)\n.*\tbeqz\t\\1,(.L\[0-9\]+)\n.*\n\\3:\n\t\\.insn\n(?:.L\[0-9\]+ = \\.\n)?\t\\.align\t2\n\\2:\n\t\\.word\t305419896\n" } } */
/* { dg-final { scan-assembler "\tlw\t(\\\$\[0-9\]+),(.L\[0-9\]+)\n.*\tbeqz\t\\1,(.L\[0-9\]+)\n.*\n\\3:\n\t\\.insn\n(?:.L\[0-9\]+ = \\.\n)?\t\\.type\t__pool_unreachable_\[0-9\]+, @object\n__pool_unreachable_\[0-9\]+:\n\t\\.align\t2\n\\2:\n\t\\.word\t305419896\n" } } */