make exception table work with -mrelocable; fix long long ++/--; Make long longs...
authorMichael Meissner <meissner@gcc.gnu.org>
Mon, 15 Jan 1996 03:07:35 +0000 (03:07 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Mon, 15 Jan 1996 03:07:35 +0000 (03:07 +0000)
From-SVN: r10978

gcc/config/rs6000/eabi-ci.asm
gcc/config/rs6000/eabi-cn.asm
gcc/config/rs6000/eabi.asm
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/ginclude/va-ppc.h

index 5d3d347a59504a1dbb68255e048089e619cf0acd..4c2872145c0dd7d135e02ec0c1c778ef1ceabbbb 100644 (file)
@@ -97,3 +97,8 @@ _SDA2_BASE_ = .+32768
        .globl  __SBSS2_START__
        .type   __SBSS2_START__,@object
 __SBSS2_START__:
+
+       .section ".gcc_except_table","aw"
+       .globl  __EXCEPT_START__
+       .type   __EXCEPT_START__,@object
+__EXCEPT_START__:
index f3ed0e638f076bb45df7b5b73c697779c7370d1d..e9ea7f62ff4b94731837431d8abf716028c68b29 100644 (file)
@@ -95,3 +95,8 @@ __SDATA2_END__:
        .globl  __SBSS2_END__
        .type   __SBSS2_END__,@object
 __SBSS2_END__:
+
+       .section ".gcc_except_table","aw"
+       .globl  __EXCEPT_END__
+       .type   __EXCEPT_END__,@object
+__EXCEPT_END__:
index e5483ed759a7190149ee1bd6c34f5f0a15c79d4e..c69dfefe424b2fc11b6bcfa9971a5f75f0f64486 100644 (file)
 .Ldtore = .-.LCTOC1
        .long   __DTOR_END__                    /* end of .dtor section */
 
+.Lexcepts = .-.LCTOC1
+       .long   __EXCEPT_START__                /* start of .gcc_except_table section */
+
+.Lexcepte = .-.LCTOC1
+       .long   __EXCEPT_END__                  /* end of .gcc_except_table section */
+
 .Linit = .-.LCTOC1
        .long   .Linit_p                        /* address of variable to say we've been called */
 
@@ -182,7 +188,7 @@ FUNC_START(__eabi)
        lwz     4,.Ldtore(11)                   /* destructors pointers end */
 
        cmpw    1,3,4                           /* any pointers to adjust */
-       bc      12,6,.Lfix
+       bc      12,6,.Lexcept
 
 .Ldloop:
        lwz     5,0(3)                          /* next pointer */
@@ -192,6 +198,25 @@ FUNC_START(__eabi)
        cmpw    1,3,4                           /* more pointers to adjust? */
        bc      4,6,.Ldloop
 
+/* Fixup the .gcc_except_table section for G++ exceptions */
+
+.Lexcept:
+       lwz     3,.Lexcepts(11)                 /* exception table pointers start */
+       lwz     4,.Lexcepte(11)                 /* exception table pointers end */
+
+       cmpw    1,3,4                           /* any pointers to adjust */
+       bc      12,6,.Lfix
+
+.Leloop:
+       lwz     5,0(3)                          /* next pointer */
+       addi    3,3,4                           /* bump to next word */
+       cmpi    1,5,0
+       beq     1,.Leloop                       /* if NULL pointer, don't adjust */
+       add     5,5,12                          /* adjust */
+       stw     5,-4(3)
+       cmpw    1,3,4                           /* more pointers to adjust? */
+       bc      4,6,.Leloop
+
 /* Fixup any user initialized pointers now (the compiler drops pointers to */
 /* each of the relocs that it does in the .fixup section).  */
 
index 7e63082813367be89fb3736ec7ad287bbe6555f6..ae045450b71e142349adbd9e3431480cf94260bc 100644 (file)
@@ -900,13 +900,18 @@ init_cumulative_args (cum, fntype, libname, incoming)
    of an argument with the specified mode and type.  If it is not defined, 
    PARM_BOUNDARY is used for all arguments.
    
-   Windows NT wants anything >= 8 bytes to be double word aligned.  */
+   Windows NT wants anything >= 8 bytes to be double word aligned.
+
+   V.4 wants long longs to be double word aligned.  */
 
 int
 function_arg_boundary (mode, type)
      enum machine_mode mode;
      tree type;
 {
+  if (DEFAULT_ABI == ABI_V4 && mode == DImode)
+    return 64;
+
   if (DEFAULT_ABI != ABI_NT || TARGET_64BIT)
     return PARM_BOUNDARY;
 
index 1be7f52e598da7f776effc969e5565afedcb0e5c..b2dec1a338e72dfd3d3604988c80bbae780e521f 100644 (file)
 ;; (for example, having an input in 7,8 and an output in 6,7).  We
 ;; also allow for the the output being the same as one of the inputs.
 
-(define_expand "adddi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-       (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
-                (match_operand:DI 2 "reg_or_short_operand" "")))]
-  ""
-  "
-{
-  if (! TARGET_POWER && ! TARGET_POWERPC64
-      && short_cint_operand (operands[2], DImode))
-    FAIL;
-}")
-
-(define_insn ""
+(define_insn "adddi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
        (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
                 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
-  "TARGET_POWER && ! TARGET_POWERPC64"
+  "! TARGET_POWERPC64"
   "@
    {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
    {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1
    {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1"
   [(set_attr "length" "8")])
 
-(define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
-       (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,0")
-                (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
-  "! TARGET_POWER && ! TARGET_POWERPC64"
-  "*
-{
-  return (WORDS_BIG_ENDIAN)
-  ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
-  : \"addc %0,%1,%2\;adde %L0,%L1,%L2\";
-}"
-  [(set_attr "length" "8")])
-
-(define_expand "subdi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-       (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
-                 (match_operand:DI 2 "gpc_reg_operand" "")))]
-  ""
-  "
-{
-  if (! TARGET_POWER && ! TARGET_POWERPC64
-      && short_cint_operand (operands[1], DImode))
-    FAIL;
-}")
-
-(define_insn ""
+(define_insn "subddi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
        (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
                  (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
    (clobber (match_scratch:SI 5 "=&r"))
    (clobber (match_scratch:SI 6 "=l"))]
   "DEFAULT_ABI == ABI_NT"
-  "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0);\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
+  "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
   [(set_attr "length" "24")])
 
 (define_insn "call_value_indirect_nt"
    (clobber (match_scratch:SI 6 "=&r"))
    (clobber (match_scratch:SI 7 "=l"))]
   "DEFAULT_ABI == ABI_NT"
-  "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1);\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
+  "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
   [(set_attr "length" "24")])
 
 ;; A function pointer under System V is just a normal pointer
index 09f11e0d2981d9c3bfb02137e17c9d786a15f301..4e7d826663698c04a5edec6172fd9d082690f152 100644 (file)
@@ -91,6 +91,9 @@ __extension__ ({                                                      \
 #define __va_float_p(TYPE)     (__builtin_classify_type(*(TYPE *)0) == 8)
 #endif
 
+#define __va_longlong_p(TYPE) \
+  ((__builtin_classify_type(*(TYPE *)0) == 1) && (sizeof(TYPE) == 8))
+
 #define __va_aggregate_p(TYPE) (__builtin_classify_type(*(TYPE *)0) >= 12)
 #define __va_size(TYPE)                ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long))
 
@@ -111,8 +114,13 @@ __extension__ (*({                                                 \
     }                                                                  \
                                                                        \
   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)            \
-          && (AP)->gpr + __va_size(TYPE) <= 8)                         \
+          && (AP)->gpr + __va_size(TYPE) <= 8                          \
+          && (!__va_longlong_p(TYPE)                                   \
+              || (AP)->gpr + __va_size(TYPE) <= 7))                    \
     {                                                                  \
+      if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0)               \
+       (AP)->gpr++;                                                    \
+                                                                       \
       __ptr = __VA_GP_REGSAVE (AP, TYPE);                              \
       (AP)->gpr += __va_size (TYPE);                                   \
     }                                                                  \
@@ -132,6 +140,9 @@ __extension__ (*({                                                  \
     }                                                                  \
   else                                                                 \
     {                                                                  \
+      if (__va_longlong_p(TYPE) && ((long)(AP)->overflow_arg_area & 4) != 0) \
+       (AP)->overflow_arg_area += 4;                                   \
+                                                                       \
       __ptr = (TYPE *) (void *) ((AP)->overflow_arg_area);             \
       (AP)->overflow_arg_area += __va_size (TYPE) * sizeof (long);     \
     }                                                                  \