Commit 6541fe75 by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/25023 (ICE in def_cfa_1, at dwarf2out.c:792)

	PR debug/25023
	PR target/25293
	* expr.c (emit_move_resolve_push): Handle PRE_MODIFY
	and POST_MODIFY with CONST_INT adjustment equal to PUSH_ROUNDING.
	Fix POST_INC/POST_DEC handling if PUSH_ROUNDING is not identity.
	* config/i386/i386.md (pushhi2, pushqi2): Use pushl instead of pushw.
	Set mode to SI, adjust constraints.
	(pushhi2_rex64, pushqi2_rex64): Set mode to DI.
	* config/i386/i386.h (PUSH_ROUNDING): Round up to 4 instead of 2 for
	32-bit code.

	* gcc.target/i386/pr25293.c: New test.

From-SVN: r108463
parent 6d328225
2005-12-13 Jakub Jelinek <jakub@redhat.com>
PR debug/25023
PR target/25293
* expr.c (emit_move_resolve_push): Handle PRE_MODIFY
and POST_MODIFY with CONST_INT adjustment equal to PUSH_ROUNDING.
Fix POST_INC/POST_DEC handling if PUSH_ROUNDING is not identity.
* config/i386/i386.md (pushhi2, pushqi2): Use pushl instead of pushw.
Set mode to SI, adjust constraints.
(pushhi2_rex64, pushqi2_rex64): Set mode to DI.
* config/i386/i386.h (PUSH_ROUNDING): Round up to 4 instead of 2 for
32-bit code.
2005-12-13 Carlos O'Donell <carlos@codesourcery.com> 2005-12-13 Carlos O'Donell <carlos@codesourcery.com>
* c-cppbuiltin.c (builtin_define_float_constants): Add * c-cppbuiltin.c (builtin_define_float_constants): Add
......
...@@ -1374,9 +1374,10 @@ enum reg_class ...@@ -1374,9 +1374,10 @@ enum reg_class
/* If we generate an insn to push BYTES bytes, /* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by. this says how many the stack pointer really advances by.
On 386 pushw decrements by exactly 2 no matter what the position was. On 386, we have pushw instruction that decrements by exactly 2 no
On the 386 there is no pushb; we use pushw instead, and this matter what the position was, there is no pushb.
has the effect of rounding up to 2. But as CIE data alignment factor on this arch is -4, we need to make
sure all stack pointer adjustments are in multiple of 4.
For 64bit ABI we round up to 8 bytes. For 64bit ABI we round up to 8 bytes.
*/ */
...@@ -1384,7 +1385,7 @@ enum reg_class ...@@ -1384,7 +1385,7 @@ enum reg_class
#define PUSH_ROUNDING(BYTES) \ #define PUSH_ROUNDING(BYTES) \
(TARGET_64BIT \ (TARGET_64BIT \
? (((BYTES) + 7) & (-8)) \ ? (((BYTES) + 7) & (-8)) \
: (((BYTES) + 1) & (-2))) : (((BYTES) + 3) & (-4)))
/* If defined, the maximum amount of space required for outgoing arguments will /* If defined, the maximum amount of space required for outgoing arguments will
be computed and placed into the variable be computed and placed into the variable
......
...@@ -1274,14 +1274,12 @@ ...@@ -1274,14 +1274,12 @@
"ix86_expand_move (HImode, operands); DONE;") "ix86_expand_move (HImode, operands); DONE;")
(define_insn "*pushhi2" (define_insn "*pushhi2"
[(set (match_operand:HI 0 "push_operand" "=<,<") [(set (match_operand:HI 0 "push_operand" "=X")
(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))] (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
"!TARGET_64BIT" "!TARGET_64BIT"
"@ "push{l}\t%k1"
push{w}\t{|WORD PTR }%1
push{w}\t%1"
[(set_attr "type" "push") [(set_attr "type" "push")
(set_attr "mode" "HI")]) (set_attr "mode" "SI")])
;; For 64BIT abi we always round up to 8 bytes. ;; For 64BIT abi we always round up to 8 bytes.
(define_insn "*pushhi2_rex64" (define_insn "*pushhi2_rex64"
...@@ -1290,7 +1288,7 @@ ...@@ -1290,7 +1288,7 @@
"TARGET_64BIT" "TARGET_64BIT"
"push{q}\t%q1" "push{q}\t%q1"
[(set_attr "type" "push") [(set_attr "type" "push")
(set_attr "mode" "QI")]) (set_attr "mode" "DI")])
(define_insn "*movhi_1" (define_insn "*movhi_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
...@@ -1435,18 +1433,16 @@ ...@@ -1435,18 +1433,16 @@
"ix86_expand_move (QImode, operands); DONE;") "ix86_expand_move (QImode, operands); DONE;")
;; emit_push_insn when it calls move_by_pieces requires an insn to ;; emit_push_insn when it calls move_by_pieces requires an insn to
;; "push a byte". But actually we use pushw, which has the effect ;; "push a byte". But actually we use pushl, which has the effect
;; of rounding the amount pushed up to a halfword. ;; of rounding the amount pushed up to a word.
(define_insn "*pushqi2" (define_insn "*pushqi2"
[(set (match_operand:QI 0 "push_operand" "=X,X") [(set (match_operand:QI 0 "push_operand" "=X")
(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))] (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
"!TARGET_64BIT" "!TARGET_64BIT"
"@ "push{l}\t%k1"
push{w}\t{|word ptr }%1
push{w}\t%w1"
[(set_attr "type" "push") [(set_attr "type" "push")
(set_attr "mode" "HI")]) (set_attr "mode" "SI")])
;; For 64BIT abi we always round up to 8 bytes. ;; For 64BIT abi we always round up to 8 bytes.
(define_insn "*pushqi2_rex64" (define_insn "*pushqi2_rex64"
...@@ -1455,7 +1451,7 @@ ...@@ -1455,7 +1451,7 @@
"TARGET_64BIT" "TARGET_64BIT"
"push{q}\t%q1" "push{q}\t%q1"
[(set_attr "type" "push") [(set_attr "type" "push")
(set_attr "mode" "QI")]) (set_attr "mode" "DI")])
;; Situation is quite tricky about when to choose full sized (SImode) move ;; Situation is quite tricky about when to choose full sized (SImode) move
;; over QImode moves. For Q_REG -> Q_REG move we use full size only for ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
......
...@@ -2852,6 +2852,19 @@ emit_move_resolve_push (enum machine_mode mode, rtx x) ...@@ -2852,6 +2852,19 @@ emit_move_resolve_push (enum machine_mode mode, rtx x)
#endif #endif
if (code == PRE_DEC || code == POST_DEC) if (code == PRE_DEC || code == POST_DEC)
adjust = -adjust; adjust = -adjust;
else if (code == PRE_MODIFY || code == POST_MODIFY)
{
rtx expr = XEXP (XEXP (x, 0), 1);
HOST_WIDE_INT val;
gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
gcc_assert (GET_CODE (XEXP (expr, 1)) == CONST_INT);
val = INTVAL (XEXP (expr, 1));
if (GET_CODE (expr) == MINUS)
val = -val;
gcc_assert (adjust == val || adjust == -val);
adjust = val;
}
/* Do not use anti_adjust_stack, since we don't want to update /* Do not use anti_adjust_stack, since we don't want to update
stack_pointer_delta. */ stack_pointer_delta. */
...@@ -2865,13 +2878,13 @@ emit_move_resolve_push (enum machine_mode mode, rtx x) ...@@ -2865,13 +2878,13 @@ emit_move_resolve_push (enum machine_mode mode, rtx x)
{ {
case PRE_INC: case PRE_INC:
case PRE_DEC: case PRE_DEC:
case PRE_MODIFY:
temp = stack_pointer_rtx; temp = stack_pointer_rtx;
break; break;
case POST_INC: case POST_INC:
temp = plus_constant (stack_pointer_rtx, -GET_MODE_SIZE (mode));
break;
case POST_DEC: case POST_DEC:
temp = plus_constant (stack_pointer_rtx, GET_MODE_SIZE (mode)); case POST_MODIFY:
temp = plus_constant (stack_pointer_rtx, -adjust);
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
......
2005-12-13 Jakub Jelinek <jakub@redhat.com>
PR debug/25023
PR target/25293
* gcc.target/i386/pr25293.c: New test.
2005-12-13 Petr Machata <machata@post.cz> 2005-12-13 Petr Machata <machata@post.cz>
PR c++/24907 PR c++/24907
/* PR target/25293 */
/* { dg-do compile } */
/* { dg-options "-mpreferred-stack-boundary=2 -mtune=i586 -O2 -fomit-frame-pointer -g" } */
/* { dg-require-effective-target ilp32 } */
struct T { unsigned short t1, t2, t3, t4, t5, t6, t7; };
struct S { struct T s1; unsigned short s2, s3; };
unsigned short v1;
int f1 (void);
int f2 (struct T);
int f3 (const char *);
int
foo (struct S *x, struct T y)
{
unsigned short a, b, c;
unsigned long d, e;
int f = 0;
y.t6 = 6;
a = y.t7;
b = y.t6;
c = y.t7;
switch (a)
{
case 8:
case 7:
c = 9;
break;
case 1:
case 6:
case 3:
b = 16;
c = 9;
break;
}
if ((f = f1 ()))
goto error;
if ((f = f2 (y)))
goto error;
d = (long) &y;
e = (long) &x->s1;
__asm __volatile ("" : "+D" (e), "+S" (d) :: "memory");
x->s2 = b;
x->s3 = c;
f3 ("foo");
return 0;
error:
if (v1 >= 1)
f3 ("bar");
return f;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment