.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 */
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 */
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). */
;; (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
#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))
} \
\
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); \
} \
} \
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); \
} \