$NetBSD: patch-ax,v 1.3 2002/03/28 10:11:53 jmc Exp $ --- ../gcc-2.95.3/gcc/config/sparc/sparc.h.orig 2000/07/26 00:18:51 1.1.1.1 +++ ../gcc-2.95.3/gcc/config/sparc/sparc.h 2002/03/28 08:14:56 1.3 @@ -50,11 +50,11 @@ /* Code model selection. -mcmodel is used to select the v9 code model. - Different code models aren't supported for v8 code. + Different code models aren't supported for v7/8 code. TARGET_CM_32: 32 bit address space, top 32 bits = 0, pointers are 32 bits. Note that this isn't intended - to imply a v8 abi. + to imply a v7/8 abi. TARGET_CM_MEDLOW: 32 bit address space, top 32 bits = 0, avoid generating %uhi and %ulo terms, @@ -173,8 +173,8 @@ #endif #if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x -#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__ -D__sparc_v8__" -#define ASM_CPU32_DEFAULT_SPEC "-Av8" +#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__" +#define ASM_CPU32_DEFAULT_SPEC "-Asparclite" #endif #endif @@ -233,7 +233,7 @@ %{mcpu=v8:-D__sparc_v8__} \ %{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \ %{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \ -%{mcpu=sparclite86x:-D__sparclite86x__ -D__sparc_v8__} \ +%{mcpu=sparclite86x:-D__sparclite86x__} \ %{mcpu=v9:-D__sparc_v9__} \ %{mcpu=ultrasparc:-D__sparc_v9__} \ %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \ @@ -297,6 +297,7 @@ %{msparclite:-Asparclite} \ %{mf930:-Asparclite} %{mf934:-Asparclite} \ %{mcpu=sparclite:-Asparclite} \ +%{mcpu=sparclite86x:-Asparclite} \ %{mcpu=f930:-Asparclite} %{mcpu=f934:-Asparclite} \ %{mv8plus:-Av8plus} \ %{mcpu=v9:-Av9} \ @@ -542,9 +543,8 @@ #define TARGET_VIS (target_flags & MASK_VIS) /* Compile for Solaris V8+. 32 bit Solaris preserves the high bits of - the current out and global registers. Linux saves the high bits on - context switches but not signals. */ -#define MASK_V8PLUS 0x2000000 + the current out and global registers and Linux 2.2+ as well. */ +#define MASK_V8PLUS 0x2000000 #define TARGET_V8PLUS (target_flags & MASK_V8PLUS) /* TARGET_HARD_MUL: Use hardware multiply instructions but not %y. @@ -555,7 +555,7 @@ #define TARGET_HARD_MUL32 \ ((TARGET_V8 || TARGET_SPARCLITE \ || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS) \ - && ! TARGET_V8PLUS) + && ! TARGET_V8PLUS && TARGET_ARCH32) #define TARGET_HARD_MUL \ (TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET \ @@ -1822,6 +1822,31 @@ ASM_OUTPUT_LABEL (FILE, NAME); \ } while (0) +/* Output the special assembly code needed to tell the assembler some + register is used as global register variable. */ + +#ifdef HAVE_AS_REGISTER_PSEUDO_OP +#define ASM_DECLARE_REGISTER_GLOBAL(FILE, DECL, REGNO, NAME) \ +do { \ + if (TARGET_ARCH64) \ + { \ + int __end = HARD_REGNO_NREGS ((REGNO), DECL_MODE (decl)) + (REGNO); \ + int __reg; \ + extern char sparc_hard_reg_printed[8]; \ + for (__reg = (REGNO); __reg < 8 && __reg < __end; __reg++) \ + if ((__reg & ~1) == 2 || (__reg & ~1) == 6) \ + { \ + if (__reg == (REGNO)) \ + fprintf ((FILE), "\t.register\t%%g%d, %s\n", __reg, (NAME)); \ + else \ + fprintf ((FILE), "\t.register\t%%g%d, .gnu.part%d.%s\n", \ + __reg, __reg - (REGNO), (NAME)); \ + sparc_hard_reg_printed[__reg] = 1; \ + } \ + } \ +} while (0) +#endif + /* This macro generates the assembly code for function entry. FILE is a stdio stream to output the code to. SIZE is an int: how many units of temporary storage to allocate. @@ -2234,6 +2259,14 @@ : 0)) #endif +/* Should gcc use [%reg+%lo(xx)+offset] addresses? */ + +#ifdef HAVE_AS_OFFSETABLE_LO10 +#define USE_AS_OFFSETABLE_LO10 1 +#else +#define USE_AS_OFFSETABLE_LO10 0 +#endif + /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid memory address for an instruction. The MODE argument is the machine mode for the MEM expression @@ -2258,6 +2291,9 @@ #define RTX_OK_FOR_OFFSET_P(X) \ (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000) + +#define RTX_OK_FOR_OLO10_P(X) \ + (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8) #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { if (RTX_OK_FOR_BASE_P (X)) \ @@ -2309,6 +2345,30 @@ || RTX_OK_FOR_OFFSET_P (op0)) \ goto ADDR; \ } \ + else if (USE_AS_OFFSETABLE_LO10 \ + && GET_CODE (op0) == LO_SUM \ + && TARGET_ARCH64 \ + && ! TARGET_CM_MEDMID \ + && RTX_OK_FOR_OLO10_P (op1)) \ + { \ + register rtx op00 = XEXP (op0, 0); \ + register rtx op01 = XEXP (op0, 1); \ + if (RTX_OK_FOR_BASE_P (op00) \ + && CONSTANT_P (op01)) \ + goto ADDR; \ + } \ + else if (USE_AS_OFFSETABLE_LO10 \ + && GET_CODE (op1) == LO_SUM \ + && TARGET_ARCH64 \ + && ! TARGET_CM_MEDMID \ + && RTX_OK_FOR_OLO10_P (op0)) \ + { \ + register rtx op10 = XEXP (op1, 0); \ + register rtx op11 = XEXP (op1, 1); \ + if (RTX_OK_FOR_BASE_P (op10) \ + && CONSTANT_P (op11)) \ + goto ADDR; \ + } \ } \ else if (GET_CODE (X) == LO_SUM) \ { \ @@ -2565,26 +2625,25 @@ #define MULSI3_LIBCALL "*.umul" /* Define library calls for quad FP operations. These are all part of the - SPARC ABI. - ??? ARCH64 still does not work as the _Qp_* routines take pointers. */ -#define ADDTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_add" : "_Q_add") -#define SUBTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_sub" : "_Q_sub") -#define NEGTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_neg" : "_Q_neg") -#define MULTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_mul" : "_Q_mul") -#define DIVTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_div" : "_Q_div") -#define FLOATSITF2_LIBCALL (TARGET_ARCH64 ? "_Qp_itoq" : "_Q_itoq") -#define FIX_TRUNCTFSI2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtoi" : "_Q_qtoi") -#define FIXUNS_TRUNCTFSI2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtoui" : "_Q_qtou") -#define EXTENDSFTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_stoq" : "_Q_stoq") -#define TRUNCTFSF2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtos" : "_Q_qtos") -#define EXTENDDFTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_dtoq" : "_Q_dtoq") -#define TRUNCTFDF2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtod" : "_Q_qtod") -#define EQTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_feq" : "_Q_feq") -#define NETF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fne" : "_Q_fne") -#define GTTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fgt" : "_Q_fgt") -#define GETF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fge" : "_Q_fge") -#define LTTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_flt" : "_Q_flt") -#define LETF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fle" : "_Q_fle") + SPARC 32bit ABI. */ +#define ADDTF3_LIBCALL "_Q_add" +#define SUBTF3_LIBCALL "_Q_sub" +#define NEGTF2_LIBCALL "_Q_neg" +#define MULTF3_LIBCALL "_Q_mul" +#define DIVTF3_LIBCALL "_Q_div" +#define FLOATSITF2_LIBCALL "_Q_itoq" +#define FIX_TRUNCTFSI2_LIBCALL "_Q_qtoi" +#define FIXUNS_TRUNCTFSI2_LIBCALL "_Q_qtou" +#define EXTENDSFTF2_LIBCALL "_Q_stoq" +#define TRUNCTFSF2_LIBCALL "_Q_qtos" +#define EXTENDDFTF2_LIBCALL "_Q_dtoq" +#define TRUNCTFDF2_LIBCALL "_Q_qtod" +#define EQTF2_LIBCALL "_Q_feq" +#define NETF2_LIBCALL "_Q_fne" +#define GTTF2_LIBCALL "_Q_fgt" +#define GETF2_LIBCALL "_Q_fge" +#define LTTF2_LIBCALL "_Q_flt" +#define LETF2_LIBCALL "_Q_fle" /* We can define the TFmode sqrt optab only if TARGET_FPU. This is because with soft-float, the SFmode and DFmode sqrt instructions will be absent, @@ -2592,34 +2651,37 @@ for calls to the builtin function sqrt, but this fails. */ #define INIT_TARGET_OPTABS \ do { \ - add_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, ADDTF3_LIBCALL); \ - sub_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, SUBTF3_LIBCALL); \ - neg_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, NEGTF2_LIBCALL); \ - smul_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, MULTF3_LIBCALL); \ - flodiv_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, DIVTF3_LIBCALL); \ - eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EQTF2_LIBCALL); \ - netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, NETF2_LIBCALL); \ - gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, GTTF2_LIBCALL); \ - getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, GETF2_LIBCALL); \ - lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, LTTF2_LIBCALL); \ - letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, LETF2_LIBCALL); \ - trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, TRUNCTFSF2_LIBCALL); \ - trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, TRUNCTFDF2_LIBCALL); \ - extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EXTENDSFTF2_LIBCALL); \ - extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EXTENDDFTF2_LIBCALL); \ - floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, FLOATSITF2_LIBCALL); \ - fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, FIX_TRUNCTFSI2_LIBCALL); \ - fixunstfsi_libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, FIXUNS_TRUNCTFSI2_LIBCALL); \ - if (TARGET_FPU) \ - sqrt_optab->handlers[(int) TFmode].libfunc \ - = gen_rtx_SYMBOL_REF (Pmode, "_Q_sqrt"); \ - INIT_SUBTARGET_OPTABS; \ + if (TARGET_ARCH32) \ + { \ + add_optab->handlers[(int) TFmode].libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, ADDTF3_LIBCALL); \ + sub_optab->handlers[(int) TFmode].libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, SUBTF3_LIBCALL); \ + neg_optab->handlers[(int) TFmode].libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, NEGTF2_LIBCALL); \ + smul_optab->handlers[(int) TFmode].libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, MULTF3_LIBCALL); \ + flodiv_optab->handlers[(int) TFmode].libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, DIVTF3_LIBCALL); \ + eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EQTF2_LIBCALL); \ + netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, NETF2_LIBCALL); \ + gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, GTTF2_LIBCALL); \ + getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, GETF2_LIBCALL); \ + lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, LTTF2_LIBCALL); \ + letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, LETF2_LIBCALL); \ + trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, TRUNCTFSF2_LIBCALL); \ + trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, TRUNCTFDF2_LIBCALL); \ + extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EXTENDSFTF2_LIBCALL);\ + extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, EXTENDDFTF2_LIBCALL);\ + floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, FLOATSITF2_LIBCALL); \ + fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, FIX_TRUNCTFSI2_LIBCALL); \ + fixunstfsi_libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, FIXUNS_TRUNCTFSI2_LIBCALL); \ + if (TARGET_FPU) \ + sqrt_optab->handlers[(int) TFmode].libfunc \ + = gen_rtx_SYMBOL_REF (Pmode, "_Q_sqrt"); \ + } \ + INIT_SUBTARGET_OPTABS; \ } while (0) /* This is meant to be redefined in the host dependent files */ @@ -3109,15 +3171,29 @@ offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\ else \ base = XEXP (addr, 0), index = XEXP (addr, 1); \ - 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) == CONST) \ - fputc ('+', FILE), output_addr_const (FILE, index); \ - else abort (); \ + if (GET_CODE (base) == LO_SUM) \ + { \ + if (! USE_AS_OFFSETABLE_LO10 \ + || TARGET_ARCH32 \ + || TARGET_CM_MEDMID) \ + abort (); \ + 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) == CONST) \ + fputc ('+', FILE), output_addr_const (FILE, index); \ + else abort (); \ + } \ } \ else if (GET_CODE (addr) == MINUS \ && GET_CODE (XEXP (addr, 1)) == LABEL_REF) \