static void sparc_trampoline_init (rtx, tree, rtx);
static enum machine_mode sparc_preferred_simd_mode (enum machine_mode);
static reg_class_t sparc_preferred_reload_class (rtx x, reg_class_t rclass);
+static bool sparc_print_operand_punct_valid_p (unsigned char);
+static void sparc_print_operand (FILE *, rtx, int);
+static void sparc_print_operand_address (FILE *, rtx);
\f
#ifdef SUBTARGET_ATTRIBUTE_TABLE
/* Table of valid machine attributes. */
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT sparc_trampoline_init
+#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
+#define TARGET_PRINT_OPERAND_PUNCT_VALID_P sparc_print_operand_punct_valid_p
+#undef TARGET_PRINT_OPERAND
+#define TARGET_PRINT_OPERAND sparc_print_operand
+#undef TARGET_PRINT_OPERAND_ADDRESS
+#define TARGET_PRINT_OPERAND_ADDRESS sparc_print_operand_address
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Validate and override various options, and do some machine dependent
return 1;
}
\f
-/* Print operand X (an rtx) in assembler syntax to file FILE.
+/* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
+
+static bool
+sparc_print_operand_punct_valid_p (unsigned char code)
+{
+ if (code == '#'
+ || code == '*'
+ || code == '('
+ || code == ')'
+ || code == '_'
+ || code == '&')
+ return true;
+
+ return false;
+}
+
+/* Implement TARGET_PRINT_OPERAND.
+ Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
For `%' followed by punctuation, CODE is the punctuation and X is null. */
-void
-print_operand (FILE *file, rtx x, int code)
+static void
+sparc_print_operand (FILE *file, rtx x, int code)
{
switch (code)
{
}
else if (GET_CODE (x) == LO_SUM)
{
- print_operand (file, XEXP (x, 0), 0);
+ sparc_print_operand (file, XEXP (x, 0), 0);
if (TARGET_CM_MEDMID)
fputs ("+%l44(", file);
else
output_operand_lossage ("floating point constant not a valid immediate operand");
else { output_addr_const (file, x); }
}
+
+/* Implement TARGET_PRINT_OPERAND_ADDRESS. */
+
+static void
+sparc_print_operand_address (FILE *file, rtx x)
+{
+ register rtx base, index = 0;
+ int offset = 0;
+ register rtx addr = x;
+
+ if (REG_P (addr))
+ fputs (reg_names[REGNO (addr)], file);
+ else if (GET_CODE (addr) == PLUS)
+ {
+ if (CONST_INT_P (XEXP (addr, 0)))
+ offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
+ else if (CONST_INT_P (XEXP (addr, 1)))
+ offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
+ else
+ base = XEXP (addr, 0), index = XEXP (addr, 1);
+ if (GET_CODE (base) == LO_SUM)
+ {
+ gcc_assert (USE_AS_OFFSETABLE_LO10
+ && TARGET_ARCH64
+ && ! TARGET_CM_MEDMID);
+ output_operand (XEXP (base, 0), 0);
+ fputs ("+%lo(", file);
+ output_address (XEXP (base, 1));
+ fprintf (file, ")+%d", offset);
+ }
+ else
+ {
+ fputs (reg_names[REGNO (base)], file);
+ if (index == 0)
+ fprintf (file, "%+d", offset);
+ else if (REG_P (index))
+ fprintf (file, "+%s", reg_names[REGNO (index)]);
+ else if (GET_CODE (index) == SYMBOL_REF
+ || GET_CODE (index) == LABEL_REF
+ || GET_CODE (index) == CONST)
+ fputc ('+', file), output_addr_const (file, index);
+ else gcc_unreachable ();
+ }
+ }
+ else if (GET_CODE (addr) == MINUS
+ && GET_CODE (XEXP (addr, 1)) == LABEL_REF)
+ {
+ output_addr_const (file, XEXP (addr, 0));
+ fputs ("-(", file);
+ output_addr_const (file, XEXP (addr, 1));
+ fputs ("-.)", file);
+ }
+ else if (GET_CODE (addr) == LO_SUM)
+ {
+ output_operand (XEXP (addr, 0), 0);
+ if (TARGET_CM_MEDMID)
+ fputs ("+%l44(", file);
+ else
+ fputs ("+%lo(", file);
+ output_address (XEXP (addr, 1));
+ fputc (')', file);
+ }
+ else if (flag_pic
+ && GET_CODE (addr) == CONST
+ && GET_CODE (XEXP (addr, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST
+ && GET_CODE (XEXP (XEXP (XEXP (addr, 0), 1), 0)) == MINUS
+ && XEXP (XEXP (XEXP (XEXP (addr, 0), 1), 0), 1) == pc_rtx)
+ {
+ addr = XEXP (addr, 0);
+ output_addr_const (file, XEXP (addr, 0));
+ /* Group the args of the second CONST in parenthesis. */
+ fputs ("-(", file);
+ /* Skip past the second CONST--it does nothing for us. */
+ output_addr_const (file, XEXP (XEXP (addr, 1), 0));
+ /* Close the parenthesis. */
+ fputc (')', file);
+ }
+ else
+ {
+ output_addr_const (file, addr);
+ }
+}
\f
/* Target hook for assembling integer objects. The sparc version has
special handling for aligned DI-mode objects. */
} \
} while (0)
-#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
- ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '(' \
- || (CHAR) == ')' || (CHAR) == '_' || (CHAR) == '&')
-
-/* Print operand X (an rtx) in assembler syntax to file FILE.
- CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
- For `%' followed by punctuation, CODE is the punctuation and X is null. */
-
-#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
-
-/* Print a memory address as an operand to reference that memory location. */
-
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-{ register rtx base, index = 0; \
- int offset = 0; \
- register rtx addr = ADDR; \
- if (GET_CODE (addr) == REG) \
- fputs (reg_names[REGNO (addr)], FILE); \
- else if (GET_CODE (addr) == PLUS) \
- { \
- if (GET_CODE (XEXP (addr, 0)) == CONST_INT) \
- offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);\
- else if (GET_CODE (XEXP (addr, 1)) == CONST_INT) \
- offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
- else \
- base = XEXP (addr, 0), index = XEXP (addr, 1); \
- if (GET_CODE (base) == LO_SUM) \
- { \
- gcc_assert (USE_AS_OFFSETABLE_LO10 \
- && TARGET_ARCH64 \
- && ! TARGET_CM_MEDMID); \
- output_operand (XEXP (base, 0), 0); \
- fputs ("+%lo(", FILE); \
- output_address (XEXP (base, 1)); \
- fprintf (FILE, ")+%d", offset); \
- } \
- else \
- { \
- fputs (reg_names[REGNO (base)], FILE); \
- if (index == 0) \
- fprintf (FILE, "%+d", offset); \
- else if (GET_CODE (index) == REG) \
- fprintf (FILE, "+%s", reg_names[REGNO (index)]); \
- else if (GET_CODE (index) == SYMBOL_REF \
- || GET_CODE (index) == LABEL_REF \
- || GET_CODE (index) == CONST) \
- fputc ('+', FILE), output_addr_const (FILE, index); \
- else gcc_unreachable (); \
- } \
- } \
- else if (GET_CODE (addr) == MINUS \
- && GET_CODE (XEXP (addr, 1)) == LABEL_REF) \
- { \
- output_addr_const (FILE, XEXP (addr, 0)); \
- fputs ("-(", FILE); \
- output_addr_const (FILE, XEXP (addr, 1)); \
- fputs ("-.)", FILE); \
- } \
- else if (GET_CODE (addr) == LO_SUM) \
- { \
- output_operand (XEXP (addr, 0), 0); \
- if (TARGET_CM_MEDMID) \
- fputs ("+%l44(", FILE); \
- else \
- fputs ("+%lo(", FILE); \
- output_address (XEXP (addr, 1)); \
- fputc (')', FILE); \
- } \
- else if (flag_pic && GET_CODE (addr) == CONST \
- && GET_CODE (XEXP (addr, 0)) == MINUS \
- && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST \
- && GET_CODE (XEXP (XEXP (XEXP (addr, 0), 1), 0)) == MINUS \
- && XEXP (XEXP (XEXP (XEXP (addr, 0), 1), 0), 1) == pc_rtx) \
- { \
- addr = XEXP (addr, 0); \
- output_addr_const (FILE, XEXP (addr, 0)); \
- /* Group the args of the second CONST in parenthesis. */ \
- fputs ("-(", FILE); \
- /* Skip past the second CONST--it does nothing for us. */\
- output_addr_const (FILE, XEXP (XEXP (addr, 1), 0)); \
- /* Close the parenthesis. */ \
- fputc (')', FILE); \
- } \
- else \
- { \
- output_addr_const (FILE, addr); \
- } \
-}
-
/* TLS support defaulting to original Sun flavor. GNU extensions
must be activated in separate configuration files. */
#ifdef HAVE_AS_TLS