+2013-01-15 Joseph Myers <joseph@codesourcery.com>
+ Mikael Pettersson <mikpe@it.uu.se>
+
+ PR target/43961
+ * config/arm/arm.h (ADDR_VEC_ALIGN): Align SImode jump tables for
+ Thumb.
+ (ASM_OUTPUT_CASE_LABEL): Remove.
+ (ASM_OUTPUT_BEFORE_CASE_LABEL): Define to empty.
+ * final.c (shorten_branches): Update alignment of labels before
+ jump tables if CASE_VECTOR_SHORTEN_MODE.
+
2013-01-15 Richard Biener <rguenther@suse.de>
PR bootstrap/55961
asm_fprintf (STREAM, "\tpop {%r}\n", REGNO); \
} while (0)
-/* Jump table alignment is explicit in ASM_OUTPUT_CASE_LABEL. */
-#define ADDR_VEC_ALIGN(JUMPTABLE) 0
-
-/* This is how to output a label which precedes a jumptable. Since
- Thumb instructions are 2 bytes, we may need explicit alignment here. */
-#undef ASM_OUTPUT_CASE_LABEL
-#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
- do \
- { \
- if (TARGET_THUMB && GET_MODE (PATTERN (JUMPTABLE)) == SImode) \
- ASM_OUTPUT_ALIGN (FILE, 2); \
- (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
- } \
- while (0)
+#define ADDR_VEC_ALIGN(JUMPTABLE) \
+ ((TARGET_THUMB && GET_MODE (PATTERN (JUMPTABLE)) == SImode) ? 2 : 0)
+
+/* Alignment for case labels comes from ADDR_VEC_ALIGN; avoid the
+ default alignment from elfos.h. */
+#undef ASM_OUTPUT_BEFORE_CASE_LABEL
+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) /* Empty. */
/* Make sure subsequent insns are aligned after a TBB. */
#define ASM_OUTPUT_CASE_END(FILE, NUM, JUMPTABLE) \
if (LABEL_P (insn))
{
int log = LABEL_TO_ALIGNMENT (insn);
+
+#ifdef CASE_VECTOR_SHORTEN_MODE
+ /* If the mode of a following jump table was changed, we
+ may need to update the alignment of this label. */
+ rtx next;
+ bool next_is_jumptable;
+
+ next = next_nonnote_insn (insn);
+ next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
+ if ((JUMP_TABLES_IN_TEXT_SECTION
+ || readonly_data_section == text_section)
+ && next_is_jumptable)
+ {
+ int newlog = ADDR_VEC_ALIGN (next);
+ if (newlog != log)
+ {
+ log = newlog;
+ LABEL_TO_ALIGNMENT (insn) = log;
+ something_changed = 1;
+ }
+ }
+#endif
+
if (log > insn_current_align)
{
int align = 1 << log;