diff options
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/aix61.h | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 28 | ||||
-rw-r--r-- | gcc/config/rs6000/xcoff.h | 22 |
3 files changed, 50 insertions, 3 deletions
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h index d8387fa52a5..42f4ba54a70 100644 --- a/gcc/config/rs6000/aix61.h +++ b/gcc/config/rs6000/aix61.h @@ -163,7 +163,8 @@ do { \ %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ %{!maix64:\ %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" + %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}\ + %{shared:crtcxa_s%O%s;:crtcxa%O%s}" /* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a4af648a319..b3db6817647 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6326,6 +6326,34 @@ "mulhdu %0,%1,%2" [(set_attr "type" "lmul")]) +(define_expand "mulditi3" + [(set (match_operand:TI 0 "gpc_reg_operand") + (mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand")) + (sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] + "TARGET_POWERPC64" +{ + rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); + emit_insn (gen_muldi3 (l, operands[1], operands[2])); + emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2])); + emit_move_insn (gen_lowpart (DImode, operands[0]), l); + emit_move_insn (gen_highpart (DImode, operands[0]), h); + DONE; +}) + +(define_expand "umulditi3" + [(set (match_operand:TI 0 "gpc_reg_operand") + (mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand")) + (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] + "TARGET_POWERPC64" +{ + rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); + emit_insn (gen_muldi3 (l, operands[1], operands[2])); + emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2])); + emit_move_insn (gen_lowpart (DImode, operands[0]), l); + emit_move_insn (gen_highpart (DImode, operands[0]), h); + DONE; +}) + (define_insn "rotldi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index bde208f4c79..512bcb5472e 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -283,7 +283,7 @@ RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ if ((ALIGN) > 32) \ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \ - exact_log2 ((ALIGN) / BITS_PER_UNIT)); \ + floor_log2 ((ALIGN) / BITS_PER_UNIT)); \ else if ((SIZE) > 4) \ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",3\n", (SIZE)); \ else \ @@ -292,12 +292,30 @@ /* This says how to output an assembler line to define a local common symbol. - Alignment cannot be specified, but we can try to maintain + The assembler in AIX 6.1 and later supports an alignment argument. + For earlier releases of AIX, we try to maintain alignment after preceding TOC section if it was aligned for 64-bit mode. */ #define LOCAL_COMMON_ASM_OP "\t.lcomm " +#if TARGET_AIX_VERSION >= 61 +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ + do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \ + RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ + if ((ALIGN) > 32) \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s,%u\n", \ + (SIZE), xcoff_bss_section_name, \ + floor_log2 ((ALIGN) / BITS_PER_UNIT)); \ + else if ((SIZE) > 4) \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s,3\n", \ + (SIZE), xcoff_bss_section_name); \ + else \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \ + (SIZE), xcoff_bss_section_name); \ + } while (0) +#endif + #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \ RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ |