summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/aix61.h3
-rw-r--r--gcc/config/rs6000/rs6000.md28
-rw-r--r--gcc/config/rs6000/xcoff.h22
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)); \