diff options
author | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-25 00:57:16 +0000 |
---|---|---|
committer | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-25 00:57:16 +0000 |
commit | d80dc9207760d65b12ca3abe0a365722af2f5554 (patch) | |
tree | 655ced866b891c8b722de3e93c488c9a3492bc31 /gcc/config | |
parent | d04c855dc7694081dab7696d2531822dd948035c (diff) | |
download | gcc-d80dc9207760d65b12ca3abe0a365722af2f5554.tar.gz |
libgcc/
* config.host: Match little-endian powerpc-linux.
gcc/
* config.gcc: Support little-endian powerpc-linux targets.
* config/rs6000/linux.h (LINK_OS_LINUX_EMUL): Define.
(LINK_OS_LINUX_SPEC): Define.
* config/rs6000/linuxspe.h (TARGET_DEFAULT):
Preserve MASK_LITTLE_ENDIAN.
* config/rs6000/default64.h (TARGET_DEFAULT): Likewise.
* config/rs6000/linuxaltivec.h (TARGET_DEFAULT): Likewise.
* config/rs6000/linux64.h (OPTION_LITTLE_ENDIAN): Don't zero.
(LINK_OS_LINUX_EMUL32, LINK_OS_LINUX_EMUL64): Define.
(LINK_OS_LINUX_SPEC32, LINK_OS_LINUX_SPEC64): Use above.
* config/rs6000/rs6000.c (output_toc): Don't use .tc for TARGET_ELF.
Correct fp word order for little-endian. Don't shift toc entries
smaller than a word for little-endian.
* config/rs6000/rs6000.md (bswaphi2, bswapsi2 split): Comment.
(bswapdi2 splits): Correct low-part subreg for little-endian.
Remove wrong BYTES_BIG_ENDIAN tests, and rename vars to remove
low/high where such is correct only for be.
* config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Allow
little-endian for -mcall-aixdesc.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198273 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/default64.h | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/linux.h | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/linux64.h | 15 | ||||
-rw-r--r-- | gcc/config/rs6000/linuxaltivec.h | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/linuxspe.h | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 36 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 101 | ||||
-rw-r--r-- | gcc/config/rs6000/sysv4.h | 6 |
8 files changed, 101 insertions, 83 deletions
diff --git a/gcc/config/rs6000/default64.h b/gcc/config/rs6000/default64.h index 5a6192d186c..9ecd25c2723 100644 --- a/gcc/config/rs6000/default64.h +++ b/gcc/config/rs6000/default64.h @@ -18,5 +18,10 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN) +#else #undef TARGET_DEFAULT #define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT) +#endif diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h index 8ec3548c21a..5329f01874b 100644 --- a/gcc/config/rs6000/linux.h +++ b/gcc/config/rs6000/linux.h @@ -79,6 +79,17 @@ #undef LINK_OS_DEFAULT_SPEC #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#define LINK_OS_LINUX_EMUL "%{!mbig: %{!mbig-endian: -m elf32lppclinux}}%{mbig|mbig-endian: -m elf32ppclinux}" +#else +#define LINK_OS_LINUX_EMUL "%{!mlittle: %{!mlittle-endian: -m elf32ppclinux}}%{mlittle|mlittle-endian: -m elf32lppclinux}" +#endif + +#undef LINK_OS_LINUX_SPEC +#define LINK_OS_LINUX_SPEC LINK_OS_LINUX_EMUL " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" + #define LINK_GCC_C_SEQUENCE_SPEC \ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index dc6f67fcc11..15336dd7d23 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -212,10 +212,6 @@ extern int dot_symbols; #ifndef RS6000_BI_ARCH -/* 64-bit PowerPC Linux is always big-endian. */ -#undef OPTION_LITTLE_ENDIAN -#define OPTION_LITTLE_ENDIAN 0 - /* 64-bit PowerPC Linux always has a TOC. */ #undef TARGET_TOC #define TARGET_TOC 1 @@ -376,12 +372,19 @@ extern int dot_symbols; #define GNU_USER_DYNAMIC_LINKER64 \ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64) +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#define LINK_OS_LINUX_EMUL32 "%{!mbig: %{!mbig-endian: -m elf32lppclinux}}%{mbig|mbig-endian: -m elf32ppclinux}" +#define LINK_OS_LINUX_EMUL64 "%{!mbig: %{!mbig-endian: -m elf64lppc}}%{mbig|mbig-endian: -m elf64ppc}" +#else +#define LINK_OS_LINUX_EMUL32 "%{!mlittle: %{!mlittle-endian: -m elf32ppclinux}}%{mlittle|mlittle-endian: -m elf32lppclinux}" +#define LINK_OS_LINUX_EMUL64 "%{!mlittle: %{!mlittle-endian: -m elf64ppc}}%{mlittle|mlittle-endian: -m elf64lppc}" +#endif -#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " %{!shared: %{!static: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}}" -#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " %{!shared: %{!static: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}}" diff --git a/gcc/config/rs6000/linuxaltivec.h b/gcc/config/rs6000/linuxaltivec.h index 632f58d5baf..f778dd8f737 100644 --- a/gcc/config/rs6000/linuxaltivec.h +++ b/gcc/config/rs6000/linuxaltivec.h @@ -20,8 +20,13 @@ <http://www.gnu.org/licenses/>. */ /* Override rs6000.h and sysv4.h definition. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_ALTIVEC | MASK_LITTLE_ENDIAN) +#else #undef TARGET_DEFAULT #define TARGET_DEFAULT MASK_ALTIVEC +#endif #undef SUBSUBTARGET_OVERRIDE_OPTIONS #define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1 diff --git a/gcc/config/rs6000/linuxspe.h b/gcc/config/rs6000/linuxspe.h index 99b8c73716d..54b0d115950 100644 --- a/gcc/config/rs6000/linuxspe.h +++ b/gcc/config/rs6000/linuxspe.h @@ -20,8 +20,13 @@ <http://www.gnu.org/licenses/>. */ /* Override rs6000.h and sysv4.h definition. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_STRICT_ALIGN | MASK_LITTLE_ENDIAN) +#else #undef TARGET_DEFAULT #define TARGET_DEFAULT MASK_STRICT_ALIGN +#endif #undef ASM_DEFAULT_SPEC #define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6000bedff07..7c329754482 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -22408,20 +22408,22 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", k[0] & 0xffffffff, k[1] & 0xffffffff, k[2] & 0xffffffff, k[3] & 0xffffffff); fprintf (file, "0x%lx%08lx,0x%lx%08lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff, - k[2] & 0xffffffff, k[3] & 0xffffffff); + k[WORDS_BIG_ENDIAN ? 0 : 1] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 1 : 0] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 2 : 3] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 3 : 2] & 0xffffffff); return; } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", @@ -22448,18 +22450,19 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0] & 0xffffffff, k[1] & 0xffffffff); fprintf (file, "0x%lx%08lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff); + k[WORDS_BIG_ENDIAN ? 0 : 1] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 1 : 0] & 0xffffffff); return; } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc FD_%lx_%lx[TC],", @@ -22483,7 +22486,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); @@ -22492,7 +22495,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); @@ -22524,9 +22527,8 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) } #endif - /* TOC entries are always Pmode-sized, but since this - is a bigendian machine then if we're putting smaller - integer constants in the TOC we have to pad them. + /* TOC entries are always Pmode-sized, so when big-endian + smaller integer constants in the TOC need to be padded. (This is still a win over putting the constants in a separate constant pool, because then we'd have to have both a TOC entry _and_ the actual constant.) @@ -22537,7 +22539,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) /* It would be easy to make this work, but it doesn't now. */ gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode)); - if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) + if (WORDS_BIG_ENDIAN && POINTER_SIZE > GET_MODE_BITSIZE (mode)) { #if HOST_BITS_PER_WIDE_INT == 32 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), @@ -22552,7 +22554,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc ID_%lx_%lx[TC],", @@ -22565,7 +22567,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) { if (POINTER_SIZE < GET_MODE_BITSIZE (mode)) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc ID_%lx_%lx[TC],", @@ -22575,7 +22577,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff); @@ -22613,7 +22615,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) gcc_unreachable (); } - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file); else { diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 0a5d32728a1..14bd9bfb432 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -2090,6 +2090,8 @@ [(set_attr "length" "4,4,12") (set_attr "type" "load,store,*")]) +;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is +;; correct for -mlittle as well as -mbig. (define_split [(set (match_operand:HI 0 "gpc_reg_operand" "") (bswap:HI (match_operand:HI 1 "gpc_reg_operand" ""))) @@ -2143,6 +2145,8 @@ [(set_attr "length" "4,4,12") (set_attr "type" "load,store,*")]) +;; We are always BITS_BIG_ENDIAN, so the bit positions below in +;; zero_extract insns do not change for -mlittle. (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))] @@ -2225,8 +2229,10 @@ rtx op2 = operands[2]; rtx op3 = operands[3]; rtx op4 = operands[4]; - rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 4); - rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, 4); + rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); + rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); rtx addr1; rtx addr2; rtx word_high; @@ -2286,8 +2292,10 @@ rtx src = operands[1]; rtx op2 = operands[2]; rtx op3 = operands[3]; - rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4); - rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4); + rtx src_si = simplify_gen_subreg (SImode, src, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); + rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); rtx addr1; rtx addr2; rtx word_high; @@ -2347,10 +2355,11 @@ rtx src = operands[1]; rtx op2 = operands[2]; rtx op3 = operands[3]; - rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, 4); - rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4); - rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, 4); - rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4); + int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; + rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); + rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); + rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); + rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); emit_insn (gen_bswapsi2 (dest_si, src_si)); @@ -2375,15 +2384,15 @@ [(const_int 0)] " { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx dest_hi = simplify_gen_subreg (SImode, dest, DImode, 0); - rtx dest_lo = simplify_gen_subreg (SImode, dest, DImode, 4); + rtx dest = operands[0]; + rtx src = operands[1]; + rtx op2 = operands[2]; + rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); + rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); rtx addr1; rtx addr2; - rtx word_high; - rtx word_low; + rtx word1; + rtx word2; addr1 = XEXP (src, 0); if (GET_CODE (addr1) == PLUS) @@ -2408,19 +2417,11 @@ addr2 = gen_rtx_PLUS (SImode, op2, addr1); } - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (src, SImode, addr1); - word_low = change_address (src, SImode, addr2); - } - else - { - word_high = change_address (src, SImode, addr2); - word_low = change_address (src, SImode, addr1); - } + word1 = change_address (src, SImode, addr1); + word2 = change_address (src, SImode, addr2); - emit_insn (gen_bswapsi2 (dest_hi, word_low)); - emit_insn (gen_bswapsi2 (dest_lo, word_high)); + emit_insn (gen_bswapsi2 (dest2, word1)); + emit_insn (gen_bswapsi2 (dest1, word2)); }") (define_split @@ -2431,15 +2432,15 @@ [(const_int 0)] " { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0); - rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4); + rtx dest = operands[0]; + rtx src = operands[1]; + rtx op2 = operands[2]; + rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); + rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); rtx addr1; rtx addr2; - rtx word_high; - rtx word_low; + rtx word1; + rtx word2; addr1 = XEXP (dest, 0); if (GET_CODE (addr1) == PLUS) @@ -2464,19 +2465,11 @@ addr2 = gen_rtx_PLUS (SImode, op2, addr1); } - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (dest, SImode, addr1); - word_low = change_address (dest, SImode, addr2); - } - else - { - word_high = change_address (dest, SImode, addr2); - word_low = change_address (dest, SImode, addr1); - } + word1 = change_address (dest, SImode, addr1); + word2 = change_address (dest, SImode, addr2); - emit_insn (gen_bswapsi2 (word_high, src_low)); - emit_insn (gen_bswapsi2 (word_low, src_high)); + emit_insn (gen_bswapsi2 (word2, src1)); + emit_insn (gen_bswapsi2 (word1, src2)); }") (define_split @@ -2487,15 +2480,15 @@ [(const_int 0)] " { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0); - rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4); - rtx dest_high = simplify_gen_subreg (SImode, dest, DImode, 0); - rtx dest_low = simplify_gen_subreg (SImode, dest, DImode, 4); + rtx dest = operands[0]; + rtx src = operands[1]; + rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); + rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); + rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); + rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); - emit_insn (gen_bswapsi2 (dest_high, src_low)); - emit_insn (gen_bswapsi2 (dest_low, src_high)); + emit_insn (gen_bswapsi2 (dest1, src2)); + emit_insn (gen_bswapsi2 (dest2, src1)); }") (define_insn "mulsi3" diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index 54bdb210c27..e54c253a4c7 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -187,12 +187,6 @@ do { \ rs6000_abi_name); \ } \ \ - if (rs6000_current_abi == ABI_AIX && TARGET_LITTLE_ENDIAN) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_LITTLE_ENDIAN; \ - error ("-mcall-aixdesc must be big endian"); \ - } \ - \ if (TARGET_SECURE_PLT != secure_plt) \ { \ error ("-msecure-plt not supported by your assembler"); \ |