diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 25f0028f573..b69b58d0e11 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2001-08-21 Richard Henderson + + * final.c (LABEL_ALIGN_AFTER_BARRIER): Default to no alignment. + (final_scan_insn): Consider jump tables data even if we have no + independant text section if !JUMP_TABLES_IN_TEXT_SECTION. Use + ADDR_VEC_ALIGN. + * config/ia64/ia64.h (JUMP_TABLES_IN_TEXT_SECTION): Remove. + (ASM_OUTPUT_CASE_END): Remove. + (ASM_OUTPUT_ADDR_DIFF_ELT): Emit pc-relative references. + * config/ia64/ia64.md (tablejump): Decode pc-relative references. + * config/ia64/sysv4.h (ASM_OUTPUT_BEFORE_CASE_LABEL): Remove. + 2001-08-21 Richard Henderson * config/ia64/ia64.c (emit_all_insn_group_barriers): Flush state diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 40fbf941c75..ccd6df7fbaa 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1933,19 +1933,6 @@ do { \ #define BSS_SECTION_ASM_OP "\t.bss" -/* Define this macro if jump tables (for `tablejump' insns) should be output in - the text section, along with the assembler instructions. */ - -/* ??? It is probably better for the jump tables to be in the rodata section, - which is where they go by default. Unfortunately, that currently does not - work, because of some problem with pcrelative relocations not getting - resolved correctly. */ -/* ??? FIXME ??? rth says that we should use @gprel to solve this problem. */ -/* ??? If jump tables are in the text section, then we can use 4 byte - entries instead of 8 byte entries. */ - -#define JUMP_TABLES_IN_TEXT_SECTION 1 - /* Define this macro if references to a symbol must be treated differently depending on something about the variable or function named by the symbol (such as what section it is in). */ @@ -2437,19 +2424,13 @@ do { \ /* ??? Depends on the pointer size. */ #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ - fprintf (STREAM, "\tdata8 .L%d-.L%d\n", VALUE, REL) + fprintf (STREAM, "\tdata8 @pcrel(.L%d)\n", VALUE) /* This is how to output an element of a case-vector that is absolute. (Ia64 does not use such vectors, but we must define this macro anyway.) */ #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) abort () -/* Define this if something special must be output at the end of a jump-table. - We need to align back to a 16 byte boundary because offsets are smaller than - instructions. */ - -#define ASM_OUTPUT_CASE_END(STREAM, NUM, TABLE) ASM_OUTPUT_ALIGN (STREAM, 4) - /* Jump tables only need 8 byte alignment. */ #define ADDR_VEC_ALIGN(ADDR_VEC) 3 @@ -2488,21 +2469,16 @@ do { \ /* Assembler Commands for Alignment. */ -/* The alignment (log base 2) to put in front of LABEL, which follows - a BARRIER. */ - /* ??? Investigate. */ -/* ??? Emitting align directives increases the size of the line number debug - info, because each .align forces use of an extended opcode. Perhaps try - to fix this in the assembler? */ +/* The alignment (log base 2) to put in front of LABEL, which follows + a BARRIER. */ /* #define LABEL_ALIGN_AFTER_BARRIER(LABEL) */ /* The desired alignment for the location counter at the beginning of a loop. */ -/* ??? Investigate. */ /* #define LOOP_ALIGN(LABEL) */ /* Define this macro if `ASM_OUTPUT_SKIP' should not be used in the text diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 5c1b9302b50..5c8793f5bcf 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -4758,21 +4758,48 @@ [(set_attr "itanium_class" "br")]) (define_expand "tablejump" - [(match_operand:DI 0 "register_operand" "") - (match_operand 1 "" "")] + [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" "")) + (use (label_ref (match_operand 1 "" "")))])] "" - " { - rtx tmp1 = gen_reg_rtx (DImode); - rtx tmp2 = gen_reg_rtx (DImode); + rtx op0 = operands[0]; + rtx addr; - emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[1])); - emit_insn (gen_adddi3 (tmp2, operands[0], tmp1)); - emit_jump_insn (gen_tablejump_internal (tmp2, operands[1])); - DONE; -}") + /* ??? Bother -- do_tablejump is "helpful" and pulls the table + element into a register without bothering to see whether that + is necessary given the operand predicate. Check for MEM just + in case someone fixes this. */ + if (GET_CODE (op0) == MEM) + addr = XEXP (op0, 0); + else + { + /* Otherwise, cheat and guess that the previous insn in the + stream was the memory load. Grab the address from that. + Note we have to momentarily pop out of the sequence started + by the insn-emit wrapper in order to grab the last insn. */ + rtx last, set; -(define_insn "tablejump_internal" + end_sequence (); + last = get_last_insn (); + start_sequence (); + set = single_set (last); + + if (! rtx_equal_p (SET_DEST (set), op0) + || GET_CODE (SET_SRC (set)) != MEM) + abort (); + addr = XEXP (SET_SRC (set), 0); + if (rtx_equal_p (addr, op0)) + abort (); + } + + /* Jump table elements are stored pc-relative. That is, a displacement + from the entry to the label. Thus to convert to an absolute address + we add the address of the memory from which the value is loaded. */ + operands[0] = expand_simple_binop (DImode, PLUS, op0, addr, + NULL_RTX, 1, OPTAB_DIRECT); +}) + +(define_insn "*tablejump_internal" [(set (pc) (match_operand:DI 0 "register_operand" "b")) (use (label_ref (match_operand 1 "" "")))] "" diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h index da37502cf3a..0abb7e8cd7e 100644 --- a/gcc/config/ia64/sysv4.h +++ b/gcc/config/ia64/sysv4.h @@ -135,11 +135,6 @@ do { \ emit_safe_across_calls (STREAM); \ } while (0) -/* Case label alignment is handled by ADDR_VEC_ALIGN now. */ - -#undef ASM_OUTPUT_BEFORE_CASE_LABEL -#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) - /* We override svr4.h so that we can support the sdata section. */ #undef SELECT_SECTION diff --git a/gcc/final.c b/gcc/final.c index a07a568fc5e..ca38b96f639 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -785,7 +785,7 @@ get_attr_length (insn) #endif #ifndef LABEL_ALIGN_AFTER_BARRIER -#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 1 +#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0 #endif #ifndef LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP @@ -2338,12 +2338,16 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) #else if (! JUMP_TABLES_IN_TEXT_SECTION) { + int log_align; + readonly_data_section (); -#ifdef READONLY_DATA_SECTION - ASM_OUTPUT_ALIGN (file, - exact_log2 (BIGGEST_ALIGNMENT - / BITS_PER_UNIT)); -#endif /* READONLY_DATA_SECTION */ + +#ifdef ADDR_VEC_ALIGN + log_align = ADDR_VEC_ALIGN (nextbody); +#else + log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); +#endif + ASM_OUTPUT_ALIGN (file, log_align); } else function_section (current_function_decl);