re PR target/4863 (arm/thumb: code for switch statements: branch out of range)

PR target/4863
* arm.md (tablejump): Make this a define_expand.  For PIC add the
offset to the base of the table.
(thumb_tablejump): Matcher for Thumb tablejump insn.
* config/arm/aout.h (ASM_OUTPUT_ADDR_DIFF_ELT): Output thumb entries
as the difference of two labels.
* config/arm/aof.h (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
* config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Only put ARM jump
tables in the code.
* config/arm/coff.h (JUMP_TABLES_IN_TEXT_SECTION): Likewise.
* arm.c (get_jump_table_size): If the table is not in the text
section, return zero.

From-SVN: r50968
This commit is contained in:
Richard Earnshaw 2002-03-18 13:45:33 +00:00 committed by Richard Earnshaw
parent a975f55099
commit 4a031dbfa3
7 changed files with 79 additions and 11 deletions

View File

@ -1,3 +1,18 @@
2002-03-18 Richard Earnshaw <rearnsha@arm.com>
PR target/4863
* arm.md (tablejump): Make this a define_expand. For PIC add the
offset to the base of the table.
(thumb_tablejump): Matcher for Thumb tablejump insn.
* config/arm/aout.h (ASM_OUTPUT_ADDR_DIFF_ELT): Output thumb entries
as the difference of two labels.
* config/arm/aof.h (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
* config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Only put ARM jump
tables in the code.
* config/arm/coff.h (JUMP_TABLES_IN_TEXT_SECTION): Likewise.
* arm.c (get_jump_table_size): If the table is not in the text
section, return zero.
2002-03-17 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (alpha_emit_set_const_1): Build add insns

View File

@ -120,6 +120,10 @@ do { \
(*ptr++) (); \
} while (0)
/* We really want to put Thumb tables in a read-only data section, but
switching to another section during function output is not
possible. We could however do what the SPARC does and defer the
whole table generation until the end of the function. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
#ifndef ARM_OS_NAME
@ -322,8 +326,13 @@ do { \
/* Output of Dispatch Tables */
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE))
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
do { \
if (TARGET_ARM) \
fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
else \
fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
} while (0)
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))

View File

@ -181,8 +181,16 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE)
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE)
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
do \
{ \
if (TARGET_ARM) \
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE); \
else \
asm_fprintf (STREAM, "\t.word\t%LL%d-%LL%d\n", VALUE, REL); \
} \
while (0)
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \

View File

@ -5329,14 +5329,29 @@ is_jump_table (insn)
return NULL_RTX;
}
#ifndef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION 0
#endif
static HOST_WIDE_INT
get_jump_table_size (insn)
rtx insn;
{
rtx body = PATTERN (insn);
int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
/* ADDR_VECs only take room if read-only data does into the text
section. */
if (JUMP_TABLES_IN_TEXT_SECTION
#if !defined(READONLY_DATA_SECTION)
|| 1
#endif
)
{
rtx body = PATTERN (insn);
int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
}
return 0;
}
/* Move a minipool fix MP from its current location to before MAX_MP.

View File

@ -9117,11 +9117,28 @@
;; Miscellaneous Thumb patterns
(define_insn "tablejump"
(define_expand "tablejump"
[(parallel [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
(use (label_ref (match_operand 1 "" "")))])]
"TARGET_THUMB"
"
if (flag_pic)
{
/* Hopefully, CSE will eliminate this copy. */
rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
rtx reg2 = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (reg2, operands[0], reg1));
operands[0] = reg2;
}
"
)
(define_insn "*thumb_tablejump"
[(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
(use (label_ref (match_operand 1 "" "")))]
"TARGET_THUMB"
"mov pc, %0"
"mov\\t%|pc, %0"
[(set_attr "length" "2")]
)

View File

@ -72,7 +72,9 @@ Boston, MA 02111-1307, USA. */
/* Define this macro if jump tables (for `tablejump' insns) should be
output in the text section, along with the assembler instructions.
Otherwise, the readonly data section is used. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
/* We put ARM jump tables in the text section, because it makes the code
more efficient, but for Thumb it's better to put them out of band. */
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION rdata_section

View File

@ -103,7 +103,9 @@ Boston, MA 02111-1307, USA. */
/* Define this macro if jump tables (for `tablejump' insns) should be
output in the text section, along with the assembler instructions.
Otherwise, the readonly data section is used. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
/* We put ARM jump tables in the text section, because it makes the code
more efficient, but for Thumb it's better to put them out of band. */
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
#ifndef LINK_SPEC
#define LINK_SPEC "%{mbig-endian:-EB} -X"