From e1f83b4dcdd1d12f29268a3052af19fd242345dc Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Mon, 15 Jan 1996 03:07:35 +0000 Subject: [PATCH] make exception table work with -mrelocable; fix long long ++/--; Make long longs passed correctly in V.4 From-SVN: r10978 --- gcc/config/rs6000/eabi-ci.asm | 5 ++++ gcc/config/rs6000/eabi-cn.asm | 5 ++++ gcc/config/rs6000/eabi.asm | 27 +++++++++++++++++++- gcc/config/rs6000/rs6000.c | 7 +++++- gcc/config/rs6000/rs6000.md | 47 ++++------------------------------- gcc/ginclude/va-ppc.h | 13 +++++++++- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/gcc/config/rs6000/eabi-ci.asm b/gcc/config/rs6000/eabi-ci.asm index 5d3d347a595..4c2872145c0 100644 --- a/gcc/config/rs6000/eabi-ci.asm +++ b/gcc/config/rs6000/eabi-ci.asm @@ -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__: diff --git a/gcc/config/rs6000/eabi-cn.asm b/gcc/config/rs6000/eabi-cn.asm index f3ed0e638f0..e9ea7f62ff4 100644 --- a/gcc/config/rs6000/eabi-cn.asm +++ b/gcc/config/rs6000/eabi-cn.asm @@ -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__: diff --git a/gcc/config/rs6000/eabi.asm b/gcc/config/rs6000/eabi.asm index e5483ed759a..c69dfefe424 100644 --- a/gcc/config/rs6000/eabi.asm +++ b/gcc/config/rs6000/eabi.asm @@ -90,6 +90,12 @@ .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). */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 7e630828133..ae045450b71 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 1be7f52e598..b2dec1a338e 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -3618,23 +3618,11 @@ ;; (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 @@ -3642,32 +3630,7 @@ {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")))] @@ -5660,7 +5623,7 @@ (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" @@ -5673,7 +5636,7 @@ (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 diff --git a/gcc/ginclude/va-ppc.h b/gcc/ginclude/va-ppc.h index 09f11e0d298..4e7d8266636 100644 --- a/gcc/ginclude/va-ppc.h +++ b/gcc/ginclude/va-ppc.h @@ -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); \ } \ -- 2.30.2