diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d0176663e3c402ca0dfd98fdcdc855b5f62cebc4..2c449aaf7dc60e6956d06b2dc2fb077136853af7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-03-19 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR target/43399 + * config/arm/arm.c (emit_multi_reg_push): Update comments. + Use PRE_MODIFY instead of PRE_DEC. + (emit_sfm): Use PRE_MODIFY instead of PRE_DEC. + (vfp_emit_fstmd): Likewise. + 2010-03-19 Michael Matz <matz@suse.de> PR target/43305 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 466981a7e7b4da42ce4af5277c34136ddc766b57..864d3aff56b5a60fbc5cdc27f195e18c77e0ec2c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -11655,9 +11655,14 @@ vfp_emit_fstmd (int base_reg, int count) XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, - gen_frame_mem (BLKmode, - gen_rtx_PRE_DEC (BLKmode, - stack_pointer_rtx)), + gen_frame_mem + (BLKmode, + gen_rtx_PRE_MODIFY (Pmode, + stack_pointer_rtx, + plus_constant + (stack_pointer_rtx, + - (count * 8))) + ), gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, reg), UNSPEC_PUSH_MULT)); @@ -13910,16 +13915,17 @@ emit_multi_reg_push (unsigned long mask) /* For the body of the insn we are going to generate an UNSPEC in parallel with several USEs. This allows the insn to be recognized - by the push_multi pattern in the arm.md file. The insn looks - something like this: + by the push_multi pattern in the arm.md file. + + The body of the insn looks something like this: (parallel [ - (set (mem:BLK (pre_dec:BLK (reg:SI sp))) + (set (mem:BLK (pre_modify:SI (reg:SI sp) + (const_int:SI <num>))) (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT)) - (use (reg:SI 11 fp)) - (use (reg:SI 12 ip)) - (use (reg:SI 14 lr)) - (use (reg:SI 15 pc)) + (use (reg:SI XX)) + (use (reg:SI YY)) + ... ]) For the frame note however, we try to be more explicit and actually @@ -13932,13 +13938,20 @@ emit_multi_reg_push (unsigned long mask) (sequence [ (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20))) (set (mem:SI (reg:SI sp)) (reg:SI r4)) - (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI fp)) - (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI ip)) - (set (mem:SI (plus:SI (reg:SI sp) (const_int 12))) (reg:SI lr)) + (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI XX)) + (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI YY)) + ... ]) - This sequence is used both by the code to support stack unwinding for - exceptions handlers and the code to generate dwarf2 frame debugging. */ + FIXME:: In an ideal world the PRE_MODIFY would not exist and + instead we'd have a parallel expression detailing all + the stores to the various memory addresses so that debug + information is more up-to-date. Remember however while writing + this to take care of the constraints with the push instruction. + + Note also that this has to be taken care of for the VFP registers. + + For more see PR43399. */ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs)); dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_dwarf_regs + 1)); @@ -13952,9 +13965,14 @@ emit_multi_reg_push (unsigned long mask) XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, - gen_frame_mem (BLKmode, - gen_rtx_PRE_DEC (BLKmode, - stack_pointer_rtx)), + gen_frame_mem + (BLKmode, + gen_rtx_PRE_MODIFY (Pmode, + stack_pointer_rtx, + plus_constant + (stack_pointer_rtx, + -4 * num_regs)) + ), gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, reg), UNSPEC_PUSH_MULT)); @@ -13985,9 +14003,10 @@ emit_multi_reg_push (unsigned long mask) { tmp = gen_rtx_SET (VOIDmode, - gen_frame_mem (SImode, - plus_constant (stack_pointer_rtx, - 4 * j)), + gen_frame_mem + (SImode, + plus_constant (stack_pointer_rtx, + 4 * j)), reg); RTX_FRAME_RELATED_P (tmp) = 1; XVECEXP (dwarf, 0, dwarf_par_index++) = tmp; @@ -14039,9 +14058,14 @@ emit_sfm (int base_reg, int count) XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, - gen_frame_mem (BLKmode, - gen_rtx_PRE_DEC (BLKmode, - stack_pointer_rtx)), + gen_frame_mem + (BLKmode, + gen_rtx_PRE_MODIFY (Pmode, + stack_pointer_rtx, + plus_constant + (stack_pointer_rtx, + -12 * count)) + ), gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, reg), UNSPEC_PUSH_MULT));