&& (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);
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;
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;
{
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;
{
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;
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:
{
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 ();
}
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 ();
}
|| (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 ();
'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
&& 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 \
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
}")
(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
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.
{ "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
#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; \
%{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) \
#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 %*}}} \