diff options
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/config/s390/s390-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 45 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 51 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 6 |
5 files changed, 80 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 12667fd..b70d6d2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2004-07-19 Andreas Krebbel <krebbel1@de.ibm.com> + + * config/s390/s390-protos.h (s390_return_address_offset): Prototype + added. + * config/s390/s390.c (regclass_map initializer): Register 35 added to + ADDR_REGS. + (load_multiple_operation, store_multiple_operation): Removed + pointless sanity check. + (s390_decompose_address): Added check for return_address_pointer_rtx. + (s390_return_addr_rtx): Use return_address_pointer_rtx for count == 0. + (s390_return_address_offset): New function. + * config/s390/s390.h (FIRST_PSEUDO_REGISTER): Increased to 36. + (FRAME_REGNO_P): Added check for register 35. + (FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS, + REG_ALLOC_ORDER): Appended entry for register 35. + (REG_CLASS_CONTENTS): Adjusted class masks for register 35. + (EH_RETURN_HANDLER_RTX): Use return_address_pointer_rtx. + (RETURN_ADDRESS_POINTER_REGNUM): New macro. + (ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET): Return address pointer + is eliminable using stack pointer or hard frame pointer. + (REGISTER_NAMES): Added name for register 35. + * config/s390/s390.md ("load_multiple", "store_multiple"): Removed + pointless sanity check. + 2004-07-19 Roger Sayle <roger@eyesopen.com> * fold-const.c (tree_expr_nonzero_p): Add function prototype. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 447edff..acb32b2 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -24,6 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA extern void optimization_options (int, int); extern void override_options (void); extern HOST_WIDE_INT s390_arg_frame_offset (void); +extern HOST_WIDE_INT s390_return_address_offset (void); extern void s390_emit_prologue (void); extern void s390_emit_epilogue (bool); extern void s390_function_profiler (FILE *, int); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 9de0350..4ebfbb3 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1038,7 +1038,7 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] = FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, - ADDR_REGS, NO_REGS, ADDR_REGS + ADDR_REGS, NO_REGS, ADDR_REGS, ADDR_REGS }; /* Return attribute type of insn. */ @@ -1613,9 +1613,6 @@ load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) else return 0; - if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx) - return 0; - for (i = 1; i < count; i++) { rtx elt = XVECEXP (op, 0, i); @@ -1676,9 +1673,6 @@ store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) else return 0; - if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx) - return 0; - for (i = 1; i < count; i++) { rtx elt = XVECEXP (op, 0, i); @@ -2258,15 +2252,19 @@ s390_decompose_address (register rtx addr, struct s390_address *out) /* Validate displacement. */ if (!disp) { - /* If the argument pointer is involved, the displacement will change - later anyway as the argument pointer gets eliminated. This could - make a valid displacement invalid, but it is more likely to make - an invalid displacement valid, because we sometimes access the - register save area via negative offsets to the arg pointer. + /* If the argument pointer or the return address pointer are involved, + the displacement will change later anyway as the virtual registers get + eliminated. This could make a valid displacement invalid, but it is + more likely to make an invalid displacement valid, because we sometimes + access the register save area via negative offsets to one of those + registers. Thus we don't check the displacement for validity here. If after elimination the displacement turns out to be invalid after all, this is fixed up by reload in any case. */ - if (base != arg_pointer_rtx && indx != arg_pointer_rtx) + if (base != arg_pointer_rtx + && indx != arg_pointer_rtx + && base != return_address_pointer_rtx + && indx != return_address_pointer_rtx) if (!DISP_IN_RANGE (offset)) return FALSE; } @@ -5499,7 +5497,7 @@ s390_reorg (void) frame pointer of that frame. */ rtx -s390_return_addr_rtx (int count, rtx frame) +s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED) { rtx addr; @@ -5512,10 +5510,10 @@ s390_return_addr_rtx (int count, rtx frame) value of RETURN_REGNUM is actually saved. */ if (count == 0) - cfun->machine->save_return_addr_p = true; - - /* To retrieve the return address we read the stack slot where the - corresponding RETURN_REGNUM value was saved. */ + { + cfun->machine->save_return_addr_p = true; + return gen_rtx_MEM (Pmode, return_address_pointer_rtx); + } addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD); addr = memory_address (Pmode, addr); @@ -5642,6 +5640,17 @@ s390_arg_frame_offset (void) return cfun->machine->frame_size + STACK_POINTER_OFFSET; } +/* Return offset between return address pointer (location of r14 + on the stack) and frame pointer initially after prologue. */ + +HOST_WIDE_INT +s390_return_address_offset (void) +{ + s390_frame_info (1, 1); + + return cfun->machine->frame_size + RETURN_REGNUM * UNITS_PER_WORD; +} + /* Emit insn to save fpr REGNUM at offset OFFSET relative to register BASE. Return generated insn. */ diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index f4d91fa..05b8ea9 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -284,14 +284,14 @@ if (INTEGRAL_MODE_P (MODE) && \ Reg 33: Condition code Reg 34: Frame pointer */ -#define FIRST_PSEUDO_REGISTER 35 +#define FIRST_PSEUDO_REGISTER 36 /* Standard register usage. */ #define GENERAL_REGNO_P(N) ((int)(N) >= 0 && (N) < 16) #define ADDR_REGNO_P(N) ((N) >= 1 && (N) < 16) #define FP_REGNO_P(N) ((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20)) #define CC_REGNO_P(N) ((N) == 33) -#define FRAME_REGNO_P(N) ((N) == 32 || (N) == 34) +#define FRAME_REGNO_P(N) ((N) == 32 || (N) == 34 || (N) == 35) #define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X))) #define ADDR_REG_P(X) (REG_P (X) && ADDR_REGNO_P (REGNO (X))) @@ -327,7 +327,7 @@ if (INTEGRAL_MODE_P (MODE) && \ 0, 0, 0, 0, \ 0, 0, 0, 0, \ 0, 0, 0, 0, \ - 1, 1, 1 } + 1, 1, 1, 1 } #define CALL_USED_REGISTERS \ { 1, 1, 1, 1, \ @@ -338,7 +338,7 @@ if (INTEGRAL_MODE_P (MODE) && \ 1, 1, 1, 1, \ 1, 1, 1, 1, \ 1, 1, 1, 1, \ - 1, 1, 1 } + 1, 1, 1, 1 } #define CALL_REALLY_USED_REGISTERS \ { 1, 1, 1, 1, \ @@ -349,7 +349,7 @@ if (INTEGRAL_MODE_P (MODE) && \ 1, 1, 1, 1, \ 1, 1, 1, 1, \ 1, 1, 1, 1, \ - 1, 1, 1 } + 1, 1, 1, 1 } #define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage () @@ -358,7 +358,7 @@ if (INTEGRAL_MODE_P (MODE) && \ { 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \ 16, 17, 18, 19, 20, 21, 22, 23, \ 24, 25, 26, 27, 28, 29, 30, 31, \ - 15, 32, 33, 34 } + 15, 32, 33, 34, 35 } /* Fitting values into registers. */ @@ -449,12 +449,12 @@ enum reg_class #define REG_CLASS_CONTENTS \ { \ { 0x00000000, 0x00000000 }, /* NO_REGS */ \ - { 0x0000fffe, 0x00000005 }, /* ADDR_REGS */ \ - { 0x0000ffff, 0x00000005 }, /* GENERAL_REGS */ \ + { 0x0000fffe, 0x0000000d }, /* ADDR_REGS */ \ + { 0x0000ffff, 0x0000000d }, /* GENERAL_REGS */ \ { 0xffff0000, 0x00000000 }, /* FP_REGS */ \ - { 0xfffffffe, 0x00000005 }, /* ADDR_FP_REGS */ \ - { 0xffffffff, 0x00000005 }, /* GENERAL_FP_REGS */ \ - { 0xffffffff, 0x00000007 }, /* ALL_REGS */ \ + { 0xfffffffe, 0x0000000d }, /* ADDR_FP_REGS */ \ + { 0xffffffff, 0x0000000d }, /* GENERAL_FP_REGS */ \ + { 0xffffffff, 0x0000000f }, /* ALL_REGS */ \ } /* Register -> class mapping. */ @@ -579,10 +579,8 @@ extern int current_function_outgoing_args_size; /* Describe how we implement __builtin_eh_return. */ #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM) -#define EH_RETURN_HANDLER_RTX \ - gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \ - -STACK_POINTER_OFFSET + UNITS_PER_WORD*RETURN_REGNUM)) - +#define EH_RETURN_HANDLER_RTX gen_rtx_MEM (Pmode, return_address_pointer_rtx) + /* Select a format to encode pointers in exception handling data. */ #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ (flag_pic \ @@ -596,6 +594,7 @@ extern int current_function_outgoing_args_size; #define FRAME_POINTER_REGNUM 34 #define HARD_FRAME_POINTER_REGNUM 11 #define ARG_POINTER_REGNUM 32 +#define RETURN_ADDRESS_POINTER_REGNUM 35 /* The static chain must be call-clobbered, but not used for function argument passing. As register 1 is clobbered by @@ -614,11 +613,13 @@ extern int current_function_outgoing_args_size; #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0 -#define ELIMINABLE_REGS \ -{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} +#define ELIMINABLE_REGS \ +{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ + { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ + { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} #define CAN_ELIMINATE(FROM, TO) (1) @@ -633,6 +634,10 @@ extern int current_function_outgoing_args_size; { (OFFSET) = s390_arg_frame_offset (); } \ else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ { (OFFSET) = s390_arg_frame_offset (); } \ + else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM \ + && ((TO) == STACK_POINTER_REGNUM \ + || (TO) == HARD_FRAME_POINTER_REGNUM)) \ + { (OFFSET) = s390_return_address_offset (); } \ else \ abort(); \ } @@ -914,10 +919,10 @@ extern int flag_pic; indexed by compiler's hard-register-number (see above). */ #define REGISTER_NAMES \ { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ - "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \ + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \ "%f0", "%f2", "%f4", "%f6", "%f1", "%f3", "%f5", "%f7", \ - "%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \ - "%ap", "%cc", "%fp" \ + "%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \ + "%ap", "%cc", "%fp", "%rp" \ } /* Emit a dtp-relative reference to a TLS variable. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 3f38542..d15e7c9 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1654,9 +1654,6 @@ } else FAIL; - - if (from == frame_pointer_rtx || from == arg_pointer_rtx) - FAIL; } else { @@ -1747,9 +1744,6 @@ } else FAIL; - - if (to == frame_pointer_rtx || to == arg_pointer_rtx) - FAIL; } else { |