+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.
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);
}
}
#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
+}
\f
/* Return the FOO in the name of the ".mdebug.FOO" section associated
with the current ABI. */
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. */
next = c->next;
free (c);
}
+ if (constants)
+ insn = emit_insn_after (gen_consttable_end (GEN_INT (label_num)), insn);
emit_barrier_after (insn);
}
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,
{
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.
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. */
;; MIPS16 constant pools.
UNSPEC_ALIGN
UNSPEC_CONSTTABLE
+ UNSPEC_CONSTTABLE_END
UNSPEC_CONSTTABLE_INT
UNSPEC_CONSTTABLE_FLOAT
;;
(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")
+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.
--- /dev/null
+/* { 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" } } */
--- /dev/null
+/* { 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" } } */
$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" } } */