Hi, I wanted to use 32 bit jump tables for VMS on ia64 (just to reduce executable size), as we know 64 offsets aren't necessary.
I override CASE_VECTOR_MODE in vms.h, I had to adjust ASM_OUTPUT_ADDR_DIFF_ELT. I also adjust ADDR_VEC_ALIGN to reduce the alignment in the SImode case. But this resulted in broken binaries because expand_simple_binop in 'tablejump' description was zero-extended its operand. But table jump vectors aren't unsigned (there could be backward branches). I also removed the :DI mode in the template although this is for documentation only, because this pattern is emitted directly via gen_tablejump in expr.c Tested by running a canadian gcc on ia64-hp-openvms. Ok for trunk ? Tristan. 2012-03-16 Tristan Gingold <ging...@adacore.com> * config/ia64/vms.h (CASE_VECTOR_MODE): Define. * config/ia64/ia64.md: Remove mode in template. Sign extend operand in expand_simple_binop. * config/ia64/ia64.h (ASM_OUTPUT_ADDR_DIFF_ELT): Use CASE_VECTOR_MODE instead of TARGET_ILP32. (ADDR_VEC_ALIGN): Make it depends on CASE_VECTOR_MODE. diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index a3ccd6f..7794573 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1480,19 +1480,17 @@ do { \ /* This macro should be provided on machines where the addresses in a dispatch table are relative to the table's own address. */ -/* ??? Depends on the pointer size. */ - #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ do { \ - if (TARGET_ILP32) \ + if (CASE_VECTOR_MODE == SImode) \ fprintf (STREAM, "\tdata4 @pcrel(.L%d)\n", VALUE); \ else \ fprintf (STREAM, "\tdata8 @pcrel(.L%d)\n", VALUE); \ } while (0) -/* Jump tables only need 8 byte alignment. */ +/* Jump tables only need 4 or 8 byte alignment. */ -#define ADDR_VEC_ALIGN(ADDR_VEC) 3 +#define ADDR_VEC_ALIGN(ADDR_VEC) (CASE_VECTOR_MODE == SImode ? 2 : 3) /* Assembler Commands for Exception Regions. */ diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 129cec8..349da7b 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -4578,7 +4578,7 @@ [(set_attr "itanium_class" "br")]) (define_expand "tablejump" - [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" "")) + [(parallel [(set (pc) (match_operand 0 "memory_operand" "")) (use (label_ref (match_operand 1 "" "")))])] "" { @@ -4614,7 +4614,7 @@ 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); + NULL_RTX, 0, OPTAB_DIRECT); }) (define_insn "*tablejump_internal" diff --git a/gcc/config/ia64/vms.h b/gcc/config/ia64/vms.h index 0c02f8a..d4cc03b 100644 --- a/gcc/config/ia64/vms.h +++ b/gcc/config/ia64/vms.h @@ -154,6 +154,10 @@ STATIC func_ptr __CTOR_LIST__[1] \ #undef TARGET_PROMOTE_FUNCTION_MODE #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote +/* Code is always in P0 (lower 31 bit addresses) on VMS. */ +#undef CASE_VECTOR_MODE +#define CASE_VECTOR_MODE SImode + /* IA64 VMS doesn't fully support COMDAT sections. */ #define SUPPORTS_ONE_ONLY 0