aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>1996-01-25 15:48:40 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1996-01-25 15:48:40 +0000
commit88228c4b75737ccd236ef68919d5596ca14badb8 (patch)
tree47f101117eaaa02f3151a29315a72fb84f2ae387
parent6f64bf5f42f0bc3c27a16e47898416d8eccd5c91 (diff)
downloadgcc-88228c4b75737ccd236ef68919d5596ca14badb8.zip
gcc-88228c4b75737ccd236ef68919d5596ca14badb8.tar.gz
gcc-88228c4b75737ccd236ef68919d5596ca14badb8.tar.bz2
more small data support
From-SVN: r11101
-rw-r--r--gcc/config/rs6000/rs6000.c49
-rw-r--r--gcc/config/rs6000/rs6000.h8
-rw-r--r--gcc/config/rs6000/rs6000.md19
-rw-r--r--gcc/config/rs6000/sysv4.h32
4 files changed, 81 insertions, 27 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 47e1f35..24cbc81 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -836,6 +836,13 @@ input_operand (op, mode)
&& (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF))
return 1;
+ /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
+ to be valid. */
+ if (DEFAULT_ABI == ABI_V4
+ && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
+ && small_data_operand (op, Pmode))
+ return 1;
+
/* Otherwise, we will be doing this SET with an add, so anything valid
for an add will be valid. */
return add_operand (op, mode);
@@ -853,11 +860,19 @@ small_data_operand (op, mode)
if (DEFAULT_ABI != ABI_V4)
return 0;
- if (GET_CODE (op) != SYMBOL_REF && GET_CODE (op) != CONST)
+ if (GET_CODE (op) == SYMBOL_REF)
+ sym_ref = op;
+
+ else if (GET_CODE (op) != CONST
+ || GET_CODE (XEXP (op, 0)) != PLUS
+ || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
+ || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
return 0;
- sym_ref = eliminate_constant_term (op, &const_part);
- if (!sym_ref || GET_CODE (sym_ref) != SYMBOL_REF || *XSTR (sym_ref, 0) != '@')
+ else
+ sym_ref = XEXP (XEXP (op, 0), 0);
+
+ if (*XSTR (sym_ref, 0) != '@')
return 0;
return 1;
@@ -2071,9 +2086,9 @@ print_operand (file, x, code)
we have already done it, we can just use an offset of four. */
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
- output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
+ print_operand_address (file, plus_constant (XEXP (XEXP (x, 0), 0), 4));
else
- output_address (plus_constant (XEXP (x, 0), 4));
+ print_operand_address (file, plus_constant (XEXP (x, 0), 4));
}
return;
@@ -2281,9 +2296,9 @@ print_operand (file, x, code)
{
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
- output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
+ print_operand_address (file, plus_constant (XEXP (XEXP (x, 0), 0), 8));
else
- output_address (plus_constant (XEXP (x, 0), 8));
+ print_operand_address (file, plus_constant (XEXP (x, 0), 8));
}
return;
@@ -2327,9 +2342,9 @@ print_operand (file, x, code)
{
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
- output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
+ print_operand_address (file, plus_constant (XEXP (XEXP (x, 0), 0), 12));
else
- output_address (plus_constant (XEXP (x, 0), 12));
+ print_operand_address (file, plus_constant (XEXP (x, 0), 12));
}
return;
@@ -2347,10 +2362,10 @@ print_operand (file, x, code)
fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)),
REGNO (XEXP (XEXP (x, 0), 0)));
else
- output_address (XEXP (x, 0));
+ print_operand_address (file, XEXP (x, 0));
}
else
- output_addr_const (file, x);
+ print_operand_address (file, x);
return;
default:
@@ -4152,8 +4167,6 @@ rs6000_select_rtx_section (mode, x)
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x))
toc_section ();
- else if (TARGET_SDATA && GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) <= 8)
- sdata2_section ();
else
const_section ();
}
@@ -4172,12 +4185,8 @@ rs6000_select_section (decl, reloc)
if (TREE_CODE (decl) == STRING_CST)
{
- if ((! flag_writable_strings) && TARGET_SDATA && (size <= 8))
- sdata2_section ();
- else if (! flag_writable_strings)
+ if (! flag_writable_strings)
const_section ();
- else if (TARGET_SDATA && (size <= 8))
- sdata_section ();
else
data_section ();
}
@@ -4190,14 +4199,14 @@ rs6000_select_section (decl, reloc)
|| (DECL_INITIAL (decl) != error_mark_node
&& !TREE_CONSTANT (DECL_INITIAL (decl))))
{
- if (TARGET_SDATA && (size <= 8) && (size > 0))
+ if (TARGET_SDATA && (size > 0) && (size <= g_switch_value))
sdata_section ();
else
data_section ();
}
else
{
- if (TARGET_SDATA && (size <= 8) && (size > 0))
+ if (TARGET_SDATA && (size > 0) && (size <= g_switch_value))
sdata2_section ();
else
const_section ();
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 0ecc03c..6a5264b 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1005,13 +1005,15 @@ enum reg_class
'Q' means that is a memory operand that is just an offset from a reg.
'R' is for AIX TOC entries.
'S' is for Windows NT SYMBOL_REFs
- 'T' is for Windows NT LABEL_REFs. */
+ 'T' is for Windows NT LABEL_REFs.
+ 'U' is for V.4 small data references. */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
: (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \
: (C) == 'S' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == SYMBOL_REF)\
: (C) == 'T' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == LABEL_REF) \
+ : (C) == 'U' ? (DEFAULT_ABI == ABI_V4 && small_data_operand (OP, GET_MODE (OP))) \
: 0)
/* Given an rtx X being reloaded into a reg required to be
@@ -1687,7 +1689,9 @@ typedef struct rs6000_args
&& LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0))))
#define LEGITIMATE_SMALL_DATA_P(MODE, X) \
- (DEFAULT_ABI == ABI_V4 && small_data_operand (X, MODE))
+ (DEFAULT_ABI == ABI_V4 \
+ && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \
+ && small_data_operand (X, MODE))
#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET) \
(GET_CODE (X) == CONST_INT \
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8131d84..12d9a851 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4731,6 +4731,16 @@
if (GET_CODE (operands[1]) == CONST_DOUBLE)
operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ /* Use default pattern for address of ELF small data */
+ if (TARGET_ELF
+ && TARGET_SDATA
+ && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
+ && !small_data_operand (operands[1], SImode))
+ {
+ emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
+ DONE;
+ }
+
if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
@@ -4826,14 +4836,15 @@
}")
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
- (match_operand:SI 1 "input_operand" "r,S,T,m,r,I,J,n,R,*h,r,r,0"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
+ (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
"gpc_reg_operand (operands[0], SImode)
|| gpc_reg_operand (operands[1], SImode)"
"@
mr %0,%1
{l|lwz} %0,[toc]%1(2)
{l|lwz} %0,[toc]%l1(2)
+ {cal|la} %0,%1
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1
@@ -4844,8 +4855,8 @@
mt%0 %1
mt%0 %1
cror 0,0,0"
- [(set_attr "type" "*,load,load,load,*,*,*,*,*,*,*,mtjmpr,*")
- (set_attr "length" "4,4,4,4,4,4,4,8,4,4,4,4,4")])
+ [(set_attr "type" "*,load,load,*,load,*,*,*,*,*,*,*,mtjmpr,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 183be95..36d61eb 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -99,6 +99,15 @@ Boston, MA 02111-1307, USA. */
{ "mvme", 0 }, \
{ "emb", 0 }, \
+/* Max # of bytes for variables to automatically be put into the .sdata
+ or .sdata2 sections. */
+extern int g_switch_value; /* value of the -G xx switch */
+extern int g_switch_set; /* whether -G xx was passed. */
+
+#ifndef SDATA_DEFAULT_SIZE
+#define SDATA_DEFAULT_SIZE 8
+#endif
+
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
`OVERRIDE_OPTIONS' to take account of this. This macro, if
@@ -110,11 +119,19 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
+ if (!g_switch_set) \
+ g_switch_value = SDATA_DEFAULT_SIZE; \
+ \
rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX : \
(TARGET_NT_CALLS) ? ABI_NT : \
(TARGET_AIX_CALLS) ? ABI_AIX_NODESC : \
ABI_V4); \
\
+ /* CYGNUS LOCAL -fcombine-statics vs. -msdata */ \
+ if (TARGET_SDATA) \
+ flag_combine_statics = 0; \
+ /* END CYGNUS LOCAL -fcombine-statics vs. -msdata */ \
+ \
if (TARGET_RELOCATABLE && TARGET_SDATA) \
{ \
target_flags &= ~MASK_SDATA; \
@@ -499,6 +516,19 @@ extern int rs6000_pic_labelno;
%{mrelocatable} %{mrelocatable-lib} %{memb} %{msdata: -memb} \
%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+#undef CC1_SPEC
+/* Pass -G xxx to the compiler */
+#define CC1_SPEC "%{G*}"
+
+/* Switch Recognition by gcc.c. Add -G xx support */
+
+#undef SWITCH_TAKES_ARG
+#define SWITCH_TAKES_ARG(CHAR) \
+ ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
+ || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
+ || (CHAR) == 'I' || (CHAR) == 'm' \
+ || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'G')
+
/* Output .file and comments listing what options there are */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
@@ -664,7 +694,7 @@ do { \
#undef LINK_SPEC
#define LINK_SPEC "\
-%{h*} %{V} %{v:%{!V:-V}} \
+%{h*} %{V} %{v:%{!V:-V}} %{G*} \
%{b} %{Wl,*:%*} \
%{static:-dn -Bstatic} \
%{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \