From: Michael Meissner Date: Thu, 25 Jan 1996 15:48:40 +0000 (+0000) Subject: more small data support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=88228c4b75737ccd236ef68919d5596ca14badb8;p=gcc.git more small data support From-SVN: r11101 --- diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 47e1f35af8f..24cbc8123c4 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 0ecc03c2b95..6a5264bbcea 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 8131d84c627..12d9a8518fb 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 183be95a485..36d61eb05b6 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 %*}}} \