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:
parent
598eaaa2a2
commit
2fe2aba3cd
9 changed files with 209 additions and 6 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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.
|
||||
|
|
50
gcc/testsuite/gcc.target/mips/data-sym-jump.c
Normal file
50
gcc/testsuite/gcc.target/mips/data-sym-jump.c
Normal 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" } } */
|
25
gcc/testsuite/gcc.target/mips/data-sym-pool.c
Normal file
25
gcc/testsuite/gcc.target/mips/data-sym-pool.c
Normal 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" } } */
|
|
@ -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" } } */
|
||||
|
|
Loading…
Add table
Reference in a new issue