diff options
author | Timothy Moore <moore@gnu.org> | 1992-10-14 14:50:17 +0000 |
---|---|---|
committer | Timothy Moore <moore@gnu.org> | 1992-10-14 14:50:17 +0000 |
commit | d2a94ec006a7ae0fb8afcc3d5f816bc88c8bd06d (patch) | |
tree | bdd6c0d148307229409a4445e234f40d777b4250 /gcc | |
parent | 12c83d0b3529153a3725d4f28db68b50ab967fdd (diff) | |
download | gcc-d2a94ec006a7ae0fb8afcc3d5f816bc88c8bd06d.zip gcc-d2a94ec006a7ae0fb8afcc3d5f816bc88c8bd06d.tar.gz gcc-d2a94ec006a7ae0fb8afcc3d5f816bc88c8bd06d.tar.bz2 |
*** empty log message ***
From-SVN: r2460
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/pa/pa-hpux.h | 8 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 187 | ||||
-rw-r--r-- | gcc/config/pa/pa.h | 62 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 329 | ||||
-rw-r--r-- | gcc/config/pa/xm-pa.h | 1 | ||||
-rw-r--r-- | gcc/ginclude/va-pa.h | 23 |
6 files changed, 450 insertions, 160 deletions
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h index d614cbc..52ab59b 100644 --- a/gcc/config/pa/pa-hpux.h +++ b/gcc/config/pa/pa-hpux.h @@ -25,3 +25,11 @@ #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE" + +/* Link against shared libraries */ +#ifdef hpux8 +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 8 +#undef LINK_SPEC +#define LINK_SPEC "-u main %{g*:-a archive} %{p:-a archive} %{pg:-a archive}" +#endif diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 7f34d80..ddc7f9e 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -33,6 +33,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "tree.h" #include "c-tree.h" #include "expr.h" +#include "obstack.h" /* Save the operands last given to a compare for use when we generate a scc or bcc insn. */ @@ -204,6 +205,22 @@ fp_reg_operand (op, mode) { return reg_renumber && FP_REG_P (op); } + +int +check_fp_mov (operands) + rtx *operands; +{ + enum machine_mode mode = GET_MODE (operands[0]); + + if (fp_reg_operand (operands[0], mode)) + return (register_operand (operands[1], mode) + || short_memory_operand (operands[1], mode)); + else if (fp_reg_operand (operands[1], mode)) + return (register_operand (operands[0], mode) + || short_memory_operand (operands[0], mode)); + else + return 1; +} extern int current_function_uses_pic_offset_table; extern rtx force_reg (), validize_mem (); @@ -481,63 +498,6 @@ initialize_pic () void finalize_pic () { - /* The table we use to reference PIC data. */ - rtx global_offset_table; - /* Labels to get the PC in the prologue of this function. */ - rtx l1, l2; - rtx seq; - int orig_flag_pic = flag_pic; - - if (current_function_uses_pic_offset_table == 0) - return; - - if (! flag_pic) - abort (); - - flag_pic = 0; - l1 = gen_label_rtx (); - l2 = gen_label_rtx (); - - start_sequence (); - - emit_label (l1); - /* Note that we pun calls and jumps here! */ - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)), - gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2))))); - emit_label (l2); - - /* Initialize every time through, since we can't easily - know this to be permanent. */ - global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "*__GLOBAL_OFFSET_TABLE_"); - pic_pc_rtx = gen_rtx (CONST, Pmode, - gen_rtx (MINUS, Pmode, - global_offset_table, - gen_rtx (CONST, Pmode, - gen_rtx (MINUS, Pmode, - gen_rtx (LABEL_REF, VOIDmode, l1), - pc_rtx)))); - - emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx, - gen_rtx (HIGH, Pmode, pic_pc_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, - pic_offset_table_rtx, - gen_rtx (LO_SUM, Pmode, - pic_offset_table_rtx, pic_pc_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, - pic_offset_table_rtx, - gen_rtx (PLUS, SImode, - pic_offset_table_rtx, gen_rtx (REG, SImode, 15)))); - /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */ - LABEL_PRESERVE_P (l1) = 1; - LABEL_PRESERVE_P (l2) = 1; - flag_pic = orig_flag_pic; - - seq = gen_sequence (); - end_sequence (); - emit_insn_after (seq, get_insns ()); - /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp can cause life info to screw up. */ emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); @@ -570,15 +530,36 @@ hppa_address_cost (X) normally. */ int -emit_move_sequence (operands, mode) +emit_move_sequence (operands, mode, scratch_reg) rtx *operands; enum machine_mode mode; + rtx scratch_reg; { register rtx operand0 = operands[0]; register rtx operand1 = operands[1]; - /* Handle most common case first: storing into a register. */ - if (register_operand (operand0, mode)) + if (fp_reg_operand (operand0, mode) + && GET_CODE (operand1) == MEM + && !short_memory_operand (operand1, mode) + && scratch_reg) + { + emit_move_insn (scratch_reg, XEXP (operand1 , 0)); + emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode, + scratch_reg))); + return 1; + } + else if (fp_reg_operand (operand1, mode) + && GET_CODE (operand0) == MEM + && !short_memory_operand (operand0, mode) + && scratch_reg) + { + emit_move_insn (scratch_reg, XEXP (operand0 , 0)); + emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode, scratch_reg), + operand1)); + return 1; + } + /* Handle most common case: storing into a register. */ + else if (register_operand (operand0, mode)) { if (register_operand (operand1, mode) || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1)) @@ -608,21 +589,6 @@ emit_move_sequence (operands, mode) } /* Simplify the source if we need to. */ -#if 0 - if (GET_CODE (operand1) == HIGH - && symbolic_operand (XEXP (operand1, 0), mode) - && !read_only_operand (XEXP (operand1, 0))) - { - rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (mode); - - emit_insn (gen_rtx (SET, VOIDmode, temp, operand1)); - emit_insn (gen_rtx (SET, VOIDmode, - operand0, - gen_rtx (PLUS, mode, - temp, gen_rtx (REG, mode, 27)))); - return 1; - } -#endif if (GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode)) { if (symbolic_operand (operand1, mode)) @@ -636,12 +602,28 @@ emit_move_sequence (operands, mode) /* use dp, register 27. */ else if (read_only_operand (operand1)) { - emit_insn (gen_rtx (SET, VOIDmode, + rtx set = gen_rtx (SET, VOIDmode, operand0, - gen_rtx (HIGH, mode, operand1))); + gen_rtx (LO_SUM, mode, operand0, operand1)); + emit_insn (gen_rtx (SET, VOIDmode, operand0, - gen_rtx (LO_SUM, mode, operand0, operand1))); + gen_rtx (HIGH, mode, operand1))); + if (TARGET_SHARED_LIBS + && function_label_operand (operand1, mode)) + { + rtx temp = reload_in_progress ? scratch_reg + : gen_reg_rtx (mode); + if (!temp) + abort (); + emit_insn (gen_rtx (PARALLEL, VOIDmode, + gen_rtvec (2, + set, + gen_rtx (CLOBBER, VOIDmode, + temp)))); + } + else + emit_insn (set); return 1; } else @@ -1223,7 +1205,7 @@ char * output_and (operands) rtx *operands; { - if (GET_CODE (operands[2]) == CONST_INT) + if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) { unsigned mask = INTVAL (operands[2]); int ls0, ls1, ms0, p, len; @@ -1494,6 +1476,7 @@ output_function_prologue (file, size, leaf_function) { extern char call_used_regs[]; extern int frame_pointer_needed; + extern int current_function_returns_struct; int i, offset; actual_fsize = compute_frame_size (size, leaf_function) + 32; @@ -1537,6 +1520,12 @@ output_function_prologue (file, size, leaf_function) fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),30\n", actual_fsize, actual_fsize); } + /* The hppa calling conventions say that that %r19, the pic offset + register, is saved at sp - 32 (in this function's frame) */ + if (flag_pic) + { + fprintf (file, "\tstw %%r19,-32(%%r30)\n"); + } /* Instead of taking one argument, the counter label, as most normal mcounts do, _mcount appears to behave differently on the HPPA. It takes the return address of the caller, the address of this @@ -1561,6 +1550,8 @@ output_function_prologue (file, size, leaf_function) : STACK_POINTER_REGNUM; offsetadj = frame_pointer_needed ? 0 : actual_fsize; + if (current_function_returns_struct) + print_stw (file, STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg); for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4) if (regs_ever_live[i]) { @@ -1578,6 +1569,8 @@ output_function_prologue (file, size, leaf_function) for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4) if (regs_ever_live[i]) print_ldw (file, i, arg_offset, basereg); + if (current_function_returns_struct) + print_ldw (file, STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg); } /* Normal register save. */ @@ -2385,7 +2378,13 @@ secondary_reload_class (class, mode, in) { int regno = true_regnum (in); - if (class == SHIFT_REGS && (regno <= 0 || regno >= 32)) + if ((TARGET_SHARED_LIBS && function_label_operand (in, mode)) + || ((regno >= FIRST_PSEUDO_REGISTER || regno == -1) + && ((mode == QImode || mode == HImode || mode == SImode + || mode == DImode) + && (class == FP_REGS || class == SNAKE_FP_REGS + || class == HI_SNAKE_FP_REGS))) + || (class == SHIFT_REGS && (regno <= 0 || regno >= 32))) return GENERAL_REGS; return NO_REGS; @@ -2448,3 +2447,31 @@ hppa_builtin_saveregs (arglist) current_function_internal_arg_pointer, offset, 0, 0, OPTAB_LIB_WIDEN)); } + +extern struct obstack *saveable_obstack; + +/* In HPUX 8.0's shared library scheme, special relocations are needed + for function labels if they might be passed to a function + in a shared library (because shared libraries don't live in code + space), and special magic is needed to construct their address. */ + +void +hppa_encode_label (sym) + rtx sym; +{ + char *str = XSTR (sym, 0); + int len = strlen (str); + char *newstr = obstack_alloc (saveable_obstack, len + 2) ; + + strcpy (newstr + 1, str); + newstr[0] = '@'; + XSTR (sym,0) = newstr; +} + +int +function_label_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + return GET_CODE (op) == SYMBOL_REF && (XSTR (op, 0))[0] == '@'; +} diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index bba8e6e..8ab5323 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -106,6 +106,11 @@ extern int target_flags; #define TARGET_KERNEL (target_flags & 4) +/* Generate code that will link against HPUX 8.0 shared libraries. + Older linkers and assemblers might not support this. */ + +#define TARGET_SHARED_LIBS (target_flags & 8) + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } @@ -119,6 +124,8 @@ extern int target_flags; {"pa-risc-1-1", 1}, \ {"no-bss", 2}, \ {"kernel", 4}, \ + {"shared-libs", 8}, \ + {"no-shared-libs", -8},\ { "", TARGET_DEFAULT}} #define TARGET_DEFAULT 0 @@ -233,7 +240,8 @@ extern int target_flags; Reg 3 = Unused Reg 4 = Frame Pointer (Gnu) Reg 5-18 = Preserved Registers - Reg 19-22 = Temporary Registers + Reg 19 = Linkage Table Register in HPUX 8.0 shared library scheme. + Reg 20-22 = Temporary Registers Reg 23-26 = Temporary/Parameter Registers Reg 27 = Global Data Pointer (hp) Reg 28 = Temporary/???/Return Value register @@ -376,12 +384,20 @@ extern int target_flags; /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. On the HP-PA, the cpu registers can hold any mode. We force this to be an even register is it cannot hold the full mode. */ +#if 0 #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode \ : (REGNO) < 32 ? ((GET_MODE_SIZE (MODE) <= 4) ? 1 : ((REGNO) & 1) == 0)\ : (REGNO) < 48 ? (GET_MODE_SIZE (MODE) >= 4) \ : (GET_MODE_SIZE (MODE) > 4 ? ((REGNO) & 1) == 0 \ : GET_MODE_SIZE (MODE) == 4)) +#endif +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode \ + : (REGNO) < 32 ? ((GET_MODE_SIZE (MODE) <= 4) ? 1 : ((REGNO) & 1) == 0)\ + : (REGNO) < 48 ? (GET_MODE_SIZE (MODE) >= 4) \ + : (GET_MODE_SIZE (MODE) > 4 ? ((REGNO) & 1) == 0 \ + : 1)) /* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. @@ -431,7 +447,7 @@ extern int leaf_function; /* Register which holds offset table for position-independent data references. */ -#define PIC_OFFSET_TABLE_REGNUM 18 +#define PIC_OFFSET_TABLE_REGNUM 19 #define INITIALIZE_PIC initialize_pic () #define FINALIZE_PIC finalize_pic () @@ -462,11 +478,14 @@ extern int leaf_function; /* The HP-PA has four kinds of registers: general regs, 1.0 fp regs, 1.1 fp regs, and the high 1.1 fp regs, to which the operands of - fmpyadd and fmpysub are restricted. */ + fmpyadd and fmpysub are restricted. + + FP_OR_SNAKE_FP_REGS is for reload_{in,out}di only and isn't used + anywhere else.*/ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS, HI_SNAKE_FP_REGS, SNAKE_FP_REGS, GENERAL_OR_SNAKE_FP_REGS, - SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES}; + FP_OR_SNAKE_FP_REGS, SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES}; #define N_REG_CLASSES (int) LIM_REG_CLASSES @@ -475,7 +494,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS, #define REG_CLASS_NAMES \ { "NO_REGS", "R1_REGS", "GENERAL_REGS", "FP_REGS", "GENERAL_OR_FP_REGS",\ "HI_SNAKE_FP_REGS", "SNAKE_FP_REGS", "GENERAL_OR_SNAKE_FP_REGS",\ - "SHIFT_REGS", "ALL_REGS"} + "FP_OR_SNAKE_FP_REGS","SHIFT_REGS", "ALL_REGS"} /* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET @@ -491,6 +510,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS, {0, 0, 0xffff0000, 0xffff}, /* HI_SNAKE_FP_REGS */ \ {0, 0xffff0000, ~0, 0xffff}, /* SNAKE_FP_REGS */ \ {-2, 0xffff0000, ~0, 0xffff}, /* GENERAL_OR_SNAKE_FP_REGS */\ + {0, ~0, ~0, 0xffff}, /* FP_OR_SNAKE_FP_REGS */\ {0, 0, 0, 0x10000}, /* SHIFT_REGS */ \ {-2, ~0, ~0, 0x1ffff}} /* ALL_REGS */ @@ -519,7 +539,8 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS, ((C) == 'x' ? (TARGET_SNAKE ? SNAKE_FP_REGS : NO_REGS) : \ ((C) == 'y' ? (TARGET_SNAKE ? HI_SNAKE_FP_REGS : NO_REGS) : \ ((C) == 'q' ? SHIFT_REGS : \ - ((C) == 'a' ? R1_REGS : NO_REGS))))) + ((C) == 'a' ? R1_REGS : \ + ((C) == 'z' ? FP_OR_SNAKE_FP_REGS : NO_REGS)))))) /* The letters I, J, K, L and M in a register constraint string can be used to stand for particular ranges of immediate operands. @@ -794,6 +815,13 @@ extern enum cmp_type hppa_branch_type; do { fprintf (FILE, ",ARGW%d=FU", (ARG0)); \ fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0) #endif + +#ifdef BUGGY_GAS +#define EXPORT_PARMS(FILE) fputs (",PRIV_LEV=3", FILE) +#else +#define EXPORT_PARMS(FILE) fputs (",ENTRY,PRIV_LEV=3", FILE) +#endif + #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ do { tree fntype = DECL_RESULT (DECL); \ tree tree_type = TREE_TYPE (DECL); \ @@ -802,7 +830,7 @@ extern enum cmp_type hppa_branch_type; if (TREE_PUBLIC (DECL)) \ { extern int current_function_varargs; \ fputs ("\t.EXPORT ", FILE); assemble_name (FILE, NAME); \ - fputs (",PRIV_LEV=3", FILE); \ + EXPORT_PARMS (FILE); \ for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \ parm = TREE_CHAIN (parm)) \ { \ @@ -984,8 +1012,8 @@ extern union tree_node *current_function_decl; #define REGNO_OK_FOR_BASE_P(REGNO) \ ((REGNO) && ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)) #define REGNO_OK_FOR_FP_P(REGNO) \ - (((REGNO) >= 32 || reg_renumber[REGNO] >= 32)\ - && ((REGNO) <= 111 || reg_renumber[REGNO] <= 111)) + (((REGNO) >= 32 && (REGNO) <= 111)\ + || (reg_renumber[REGNO] >= 32 && reg_renumber[REGNO] <= 111)) /* Now macros that check whether X is a register and also, strictly, whether it is in a specified class. @@ -1200,7 +1228,7 @@ extern union tree_node *current_function_decl; if (memory_address_p (MODE, X)) \ goto WIN; \ if (flag_pic) (X) = legitimize_pic_address (X, MODE, gen_reg_rtx (Pmode));\ - else if ((GET_CODE (X) == SYMBOL_REF && read_only_operand (X))\ + else if ((GET_CODE (X) == SYMBOL_REF & read_only_operand (X)) \ || GET_CODE (X) == LABEL_REF) \ (X) = gen_rtx (LO_SUM, Pmode, \ copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, X)), X); \ @@ -1246,7 +1274,10 @@ extern union tree_node *current_function_decl; do \ { \ if (TREE_CODE (DECL) == FUNCTION_DECL) \ - SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \ + { \ + hppa_encode_label (XEXP (DECL_RTL (DECL), 0)); \ + SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \ + } \ else \ { \ rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ @@ -1376,7 +1407,7 @@ while (0) case MOD: \ case UMOD: \ return COSTS_N_INSNS (60); \ - case PLUS: /* this includes shNadd insns */ \ + case PLUS: /* this includes shNadd insns */ \ return COSTS_N_INSNS (1) + 2; /* Conditional branches with empty delay slots have a length of two. */ @@ -1518,7 +1549,7 @@ bss_section () \ `assemble_name' uses this. */ #define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, "%s", NAME) + fprintf ((FILE), "%s", (NAME) + ((NAME)[0] == '@' ? 1 : 0)) /* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */ @@ -1578,6 +1609,7 @@ bss_section () \ #define ASM_OUTPUT_ASCII(FILE, P, SIZE) \ output_ascii ((FILE), (P), (SIZE)) +#if 0 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ fprintf (FILE, "\tstws,mb %s,4(0,30)\n", reg_names[REGNO]) @@ -1586,7 +1618,10 @@ bss_section () \ #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ fprintf (FILE, "\tldws,ma -4(0,30),%s\n", reg_names[REGNO]) +#endif +#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) +#define ASM_OUTPUT_REG_POP(FILE,REGNO) /* This is how to output an element of a case-vector that is absolute. Note that this method makes filling these branch delay slots virtually impossible. */ @@ -1732,3 +1767,4 @@ extern void output_global_address (); extern struct rtx_def *legitimize_pic_address (); extern struct rtx_def *gen_cmp_fp (); extern struct rtx_def *gen_scond_fp (); +extern void hppa_encode_label (); diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 1832f4c..7cdbcf1 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -209,7 +209,7 @@ (define_expand "seq" [(set (match_operand:SI 0 "register_operand" "") - (eq:CC (match_dup 1) + (eq:SI (match_dup 1) (match_dup 2)))] "" " @@ -228,7 +228,7 @@ (define_expand "sne" [(set (match_operand:SI 0 "register_operand" "") - (ne:CC (match_dup 1) + (ne:SI (match_dup 1) (match_dup 2)))] "" " @@ -245,7 +245,7 @@ (define_expand "slt" [(set (match_operand:SI 0 "register_operand" "") - (lt:CC (match_dup 1) + (lt:SI (match_dup 1) (match_dup 2)))] "" " @@ -262,7 +262,7 @@ (define_expand "sgt" [(set (match_operand:SI 0 "register_operand" "") - (gt:CC (match_dup 1) + (gt:SI (match_dup 1) (match_dup 2)))] "" " @@ -279,7 +279,7 @@ (define_expand "sle" [(set (match_operand:SI 0 "register_operand" "") - (le:CC (match_dup 1) + (le:SI (match_dup 1) (match_dup 2)))] "" " @@ -296,7 +296,7 @@ (define_expand "sge" [(set (match_operand:SI 0 "register_operand" "") - (ge:CC (match_dup 1) + (ge:SI (match_dup 1) (match_dup 2)))] "" " @@ -313,7 +313,7 @@ (define_expand "sltu" [(set (match_operand:SI 0 "register_operand" "") - (ltu:CC (match_dup 1) + (ltu:SI (match_dup 1) (match_dup 2)))] "" " @@ -326,7 +326,7 @@ (define_expand "sgtu" [(set (match_operand:SI 0 "register_operand" "") - (gtu:CC (match_dup 1) + (gtu:SI (match_dup 1) (match_dup 2)))] "" " @@ -339,7 +339,7 @@ (define_expand "sleu" [(set (match_operand:SI 0 "register_operand" "") - (leu:CC (match_dup 1) + (leu:SI (match_dup 1) (match_dup 2)))] "" " @@ -352,7 +352,7 @@ (define_expand "sgeu" [(set (match_operand:SI 0 "register_operand" "") - (geu:CC (match_dup 1) + (geu:SI (match_dup 1) (match_dup 2)))] "" " @@ -368,7 +368,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") - (match_operator:CC 3 "comparison_operator" + (match_operator:SI 3 "comparison_operator" [(match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "arith11_operand" "r,I")]))] "" @@ -660,10 +660,43 @@ "" " { - if (emit_move_sequence (operands, SImode)) + if (emit_move_sequence (operands, SImode, 0)) DONE; }") +;; Reloading an SImode or DImode value requires a scratch register if +;; going in to or out of float point registers. + +(define_expand "reload_insi" + [(set (match_operand:SI 0 "register_operand" "=z") + (match_operand:SI 1 "general_operand" "")) + (clobber (match_operand:SI 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, SImode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + +(define_expand "reload_outsi" + [(set (match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "register_operand""z")) + (clobber (match_operand:SI 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, SImode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + ;; Moves to and from the shift register. (define_insn "" @@ -680,10 +713,39 @@ "mfctl 11,%0" [(set_attr "type" "move")]) +;;; Experimental + +(define_insn "" + [(set (match_operand:SI 0 "fp_reg_operand" "=fx") + (match_operand:SI 1 "short_memory_operand" "T"))] + "" + "fldws%F1 %1,%0" + [(set_attr "type" "fpload") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:SI 0 "short_memory_operand" "=T") + (match_operand:SI 1 "fp_reg_operand" "fx"))] + "" + "fstws%F0 %1,%0" + [(set_attr "type" "fpstore") + (set_attr "length" "1")]) + +;;; pic symbol refrences + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "symbolic_operand" ""))))] + "flag_pic && operands[1] == pic_offset_table_rtx" + "ldw T'%2(%1),%0" + [(set_attr "type" "load") + (set_attr "length" "1")]) + (define_insn "" [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" - "=r,r,Q,!r,!*f*x,!*f*x") - (match_operand:SI 1 "move_operand" "rM,Q,rM,!*f*x*y,!r,!*f*x"))] + "=r,r,Q,!r,!fx,!fx") + (match_operand:SI 1 "move_operand" "rM,Q,rM,!fxy,!r,!fx"))] "" "@ copy %r1,%0 @@ -712,7 +774,7 @@ xoperands[2] = label_rtx; output_asm_insn (\"bl .+8,%0\;addil L'%1-%2,%0\", xoperands); ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label_rtx)); - output_asm_insn (\"ldo R'%1(1),%0\", xoperands); + output_asm_insn (\"ldo R'%1-%2(1),%0\", xoperands); return \"\"; } " @@ -781,6 +843,14 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") + (high:SI (match_operand:SI 1 "function_label_operand" "")))] + "TARGET_SHARED_LIBS" + "ldil LP'%G1,%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand 1 "" "")))] "check_pic (1)" "ldil L'%G1,%0" @@ -798,6 +868,16 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "function_label_operand" ""))) + (clobber (match_operand:SI 3 "register_operand" "=r"))] + "TARGET_SHARED_LIBS" + "ldo RP'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(%%r27),%3\;add %0,%3,%0" + [(set_attr "type" "multi") + (set_attr "length" "4")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "immediate_operand" "i")))] "" "ldo R'%G2(%1),%0" @@ -805,44 +885,29 @@ ;; is not an "arith_operand". [(set_attr "length" "1")]) -;;; Experimental - -(define_insn "" - [(set (match_operand:SI 0 "fp_reg_operand" "=*f*x") - (match_operand:SI 1 "short_memory_operand" "T"))] - "" - "fldws%F1 %1,%0" - [(set_attr "type" "fpload") - (set_attr "length" "1")]) - -(define_insn "" - [(set (match_operand:SI 0 "short_memory_operand" "=T") - (match_operand:SI 1 "fp_reg_operand" "*f*x"))] - "" - "fstws%F0 %1,%0" - [(set_attr "type" "fpstore") - (set_attr "length" "1")]) - (define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "") (match_operand:HI 1 "general_operand" ""))] "" " { - if (emit_move_sequence (operands, HImode)) + if (emit_move_sequence (operands, HImode, 0)) DONE; }") (define_insn "" - [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") - (match_operand:HI 1 "move_operand" "rM,Q,rM"))] + [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!r,!*fx,!*fx") + (match_operand:HI 1 "move_operand" "rM,Q,rM,*fx,r,!*fx"))] "" "@ copy %r1,%0 ldh%M1 %1,%0 - sth%M0 %r1,%0" - [(set_attr "type" "move,load,store") - (set_attr "length" "1,1,1")]) + sth%M0 %r1,%0 + fstws %1,-16(30)\;ldw -16(30),%0 + stw %1,-16(30)\;fldws -16(30),%0 + fcpy,sgl %1,%0" + [(set_attr "type" "move,load,store,move,move,fpalu") + (set_attr "length" "1,1,1,2,2,1")]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") @@ -887,20 +952,23 @@ "" " { - if (emit_move_sequence (operands, QImode)) + if (emit_move_sequence (operands, QImode, 0)) DONE; }") (define_insn "" - [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") - (match_operand:QI 1 "move_operand" "rM,Q,rM"))] + [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!r,!*fx,!*fx") + (match_operand:QI 1 "move_operand" "rM,Q,rM,*fx,r,*fx"))] "" "@ copy %r1,%0 ldb%M1 %1,%0 - stb%M0 %r1,%0" - [(set_attr "type" "move,load,store") - (set_attr "length" "1,1,1")]) + stb%M0 %r1,%0 + fstws %1,-16(30)\;ldw -16(30),%0 + stw %1,-16(30)\;fldws -16(30),%0 + fcpy,sgl %1,%0" + [(set_attr "type" "move,load,store,move,move,fpalu") + (set_attr "length" "1,1,1,2,2,1")]) (define_insn "" [(set (match_operand:QI 0 "register_operand" "=r") @@ -918,6 +986,83 @@ "ldo R'%G2(%1),%0" [(set_attr "length" "1")]) +;; Sneaky ways of using index modes + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") + (const_int 4)) + (match_operand:SI 2 "register_operand" "r"))))] + "" + "ldwx,s %1(0,%2),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (mem:SI (match_operand:SI 1 "register_operand" "+r"))) + (set (match_dup 1) + (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") + (const_int 4)) + (match_dup 1)))] + "" + "ldwx,sm %2(0,%1),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (mem:SI (match_operand:SI 1 "register_operand" "+r"))) + (set (match_dup 1) + (plus:SI (match_dup 1) + (match_operand:SI 2 "register_operand" "r")))] + "" + "ldwx,m %2(0,%1),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (mem:HI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") + (const_int 2)) + (match_operand:SI 1 "register_operand" "r"))))] + "" + "ldhx,s %2(0,%1),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (mem:HI (match_operand:SI 1 "register_operand" "+r"))) + (set (match_dup 1) + (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") + (const_int 2)) + (match_dup 1)))] + "" + "ldhx,sm %2(0,%1),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (mem:HI (match_operand:SI 1 "register_operand" "+r"))) + (set (match_dup 1) + (plus:SI (match_dup 1) + (match_operand:SI 2 "register_operand" "r")))] + "" + "ldhx,m %2(0,%1),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (mem:QI (match_operand:SI 1 "register_operand" "+r"))) + (set (match_dup 1) + (plus:SI (match_dup 1) + (match_operand:SI 2 "register_operand" "r")))] + "" + "ldbx,m %2(0,%1),%0") + ;; The definition of this insn does not really explain what it does, ;; but it should suffice ;; that anything generated as this insn will be recognized as one @@ -997,16 +1142,17 @@ "" " { - if (emit_move_sequence (operands, DFmode)) + if (emit_move_sequence (operands, DFmode, 0)) DONE; }") (define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" - "=fx,r,Q,Q,fx,&r,?fx,?r") + "=fx,*r,Q,?Q,fx,*&r,?fx,?r") (match_operand:DF 1 "reg_or_nonsymb_mem_operand" - "fx,r,fx,r,Q,Q,r,fx"))] - "" + "fx,*r,fx,*r,Q,Q,*r,fx"))] + "register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode)" "* { if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) @@ -1022,10 +1168,40 @@ "" " { - if (emit_move_sequence (operands, DImode)) + if (emit_move_sequence (operands, DImode, 0)) DONE; }") +(define_expand "reload_indi" + [(set (match_operand:DI 0 "register_operand" "=z") + (match_operand:DI 1 "general_operand" "")) + (clobber (match_operand:SI 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, DImode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + +(define_expand "reload_outdi" + [(set (match_operand:DI 0 "general_operand" "") + (match_operand:DI 1 "register_operand" "z")) + (clobber (match_operand:SI 2 "register_operand" "=&r"))] + "" + " +{ + if (emit_move_sequence (operands, DImode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + DONE; +}") + (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "" "")))] @@ -1064,11 +1240,29 @@ [(set_attr "type" "move") (set_attr "length" "2")]) +;;; Experimental + +(define_insn "" + [(set (match_operand:DI 0 "fp_reg_operand" "=fx") + (match_operand:DI 1 "short_memory_operand" "T"))] + "" + "fldds%F1 %1,%0" + [(set_attr "type" "fpload") + (set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:DI 0 "short_memory_operand" "=T") + (match_operand:DI 1 "fp_reg_operand" "fx"))] + "" + "fstds%F0 %1,%0" + [(set_attr "type" "fpstore") + (set_attr "length" "1")]) + (define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" - "=r,Q,&r,&r,*f*x,*f*x,*f*x,r,Q") + "=r,Q,&r,&r,fx,fx,r") (match_operand:DI 1 "general_operand" - "r,r,Q,i,r,*f*x,Q,*f*x,*f*x"))] + "r,r,Q,i,r,fx,fx"))] "" "* { @@ -1076,8 +1270,8 @@ return output_fp_move_double (operands); return output_move_double (operands); }" - [(set_attr "type" "move,store,load,misc,multi,fpalu,fpload,multi,fpstore") - (set_attr "length" "2,3,3,3,3,2,3,3,3")]) + [(set_attr "type" "move,store,load,misc,multi,fpalu,multi") + (set_attr "length" "2,3,3,3,3,2,3")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r,r") @@ -1104,7 +1298,7 @@ "" " { - if (emit_move_sequence (operands, SFmode)) + if (emit_move_sequence (operands, SFmode, 0)) DONE; }") @@ -1386,8 +1580,8 @@ ;; The mulsi3 insns set up registers for the millicode call. (define_expand "mulsi3" - [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" "")) - (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" "")) + [(set (reg:SI 26) (match_operand:SI 1 "register_operand" "")) + (set (reg:SI 25) (match_operand:SI 2 "arith32_operand" "")) (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) (clobber (match_scratch:SI 3 "")) (clobber (reg:SI 26)) @@ -1395,7 +1589,26 @@ (clobber (reg:SI 31))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] "" - "") + " +{ + if (TARGET_SNAKE && !(CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))) + { + rtx scratch = gen_reg_rtx (DImode); + emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2])); + emit_insn (gen_rtx (SET, VOIDmode, + operands[0], + gen_rtx (SUBREG, SImode, scratch, 1))); + DONE; + } +}") + +(define_insn "umulsidi3" + [(set (match_operand:DI 0 "register_operand" "=x") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "x")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "x"))))] + "TARGET_SNAKE" + "xmpyu %1,%2,%0" + [(set_attr "type" "fpmul")]) (define_insn "" [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) diff --git a/gcc/config/pa/xm-pa.h b/gcc/config/pa/xm-pa.h index 4f168a6..f6bdea8 100644 --- a/gcc/config/pa/xm-pa.h +++ b/gcc/config/pa/xm-pa.h @@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <magic.h> #if defined(SHL_MAGIC) #define hpux8 1 +#define HAVE_VPRINTF #endif #define USG diff --git a/gcc/ginclude/va-pa.h b/gcc/ginclude/va-pa.h index eb6c600..c01850a 100644 --- a/gcc/ginclude/va-pa.h +++ b/gcc/ginclude/va-pa.h @@ -1,4 +1,3 @@ -#if __GNUC__ > 1 /* Define __gnuc_va_list. */ @@ -11,12 +10,23 @@ typedef double *__gnuc_va_list; /* If this is for internal libc use, don't define anything but __gnuc_va_list. */ #if defined (_STDARG_H) || defined (_VARARGS_H) +#if __GNUC__ > 1 +#define __va_ellipsis ... +#define __gnuc_va_start(AP) ((AP) = (va_list)__builtin_saveregs()) +#else +#define va_alist __va_a__, __va_b__, __va_c__, __va_d__ +#define __va_ellipsis +#define __gnuc_va_start(AP)\ + (AP) = (double *) &__va_a__, &__va_b__, &__va_c__, &__va_d__, \ + (AP) = (double *)((char *)(AP) + 4) +#endif /* __GNUC__ > 1 */ + #ifdef _STDARG_H -#define va_start(AP,LASTARG) ((AP) = (va_list)__builtin_saveregs()) +#define va_start(AP,LASTARG) __gnuc_va_start (AP) #else /* The ... causes current_function_varargs to be set in cc1. */ -#define va_dcl long va_alist; ... -#define va_start(AP) ((AP) = (va_list)__builtin_saveregs()) +#define va_dcl long va_alist; __va_ellipsis +#define va_start(AP) __gnuc_va_start (AP) #endif #define va_arg(AP,TYPE) \ @@ -31,8 +41,3 @@ typedef double *__gnuc_va_list; #define va_end(AP) #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ - -#else /* not __GNUC__ > 1 */ -#include "/usr/local/lib/gcc-include/va-hp9k8.h" -#define _VA_LIST_ -#endif |