diff options
author | Jeff Law <law@redhat.com> | 1997-10-07 19:48:22 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1997-10-07 19:48:22 +0000 |
commit | db0af6f77141e89cca79cdeb4c6350693e4bfc24 (patch) | |
tree | b2e0da7bc34d379f17022dced68eca5dd3f227a8 /gdb/doc/LRS | |
parent | 758b6765b8732ade7c6ac4379f3810a5293ece30 (diff) | |
download | gdb-db0af6f77141e89cca79cdeb4c6350693e4bfc24.zip gdb-db0af6f77141e89cca79cdeb4c6350693e4bfc24.tar.gz gdb-db0af6f77141e89cca79cdeb4c6350693e4bfc24.tar.bz2 |
New file describing how stabs for live range splitting work. Should be
folded into the main stabs documentation.
Diffstat (limited to 'gdb/doc/LRS')
-rw-r--r-- | gdb/doc/LRS | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/gdb/doc/LRS b/gdb/doc/LRS new file mode 100644 index 0000000..5cd719e --- /dev/null +++ b/gdb/doc/LRS @@ -0,0 +1,531 @@ +Return-Path: owner-egcs@cygnus.com Sun +Received: from cygnus.com (runyon.cygnus.com [205.180.230.5]) by hurl.cygnus.com with ESMTP (8.7.1/8.7.1) id RAA11988 for <law@hurl.cygnus.com>; Sun, 5 Oct 1997 17:27:27 -0600 (MDT) +Received: (from majordom@localhost) + by runyon.cygnus.com (8.8.7-cygnus/8.8.7) id QAA27817; + Sun, 5 Oct 1997 16:16:45 -0700 (PDT) +Received: from YALPH1.physics.yale.edu (hepvms1.physics.yale.edu [198.125.138.1]) + by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id QAA27802; + Sun, 5 Oct 1997 16:16:38 -0700 (PDT) +Received: from hepunix2.physics.yale.edu by hepmail.physics.yale.edu + (PMDF V5.1-8 #17719) + with ESMTP id <01IOGJ0WO510CFQE02@hepmail.physics.yale.edu>; Sun, + 5 Oct 1997 19:20:08 EDT +Received: from hepunix1.physics.yale.edu by hepunix.physics.yale.edu + (PMDF V5.1-5 #17721) with SMTP id <0EHLPVM0N00788@hepunix.physics.yale.edu>; + Sun, 05 Oct 1997 19:14:13 -0400 (EDT) +Date: Sun, 05 Oct 1997 19:14:09 -0400 (EDT) +From: Weiwen Liu <liu@hepvms.physics.yale.edu> +Subject: Re: complex support on alpha +In-reply-to: <199710020532.WAA16123@dot.cygnus.com> +X-Sender: liu@hepunix1.physics.yale.edu +To: rth@cygnus.com +Cc: egcs@cygnus.com +Message-id: <Pine.OSF.3.96.971005190110.31383A-100000@hepunix1.physics.yale.edu> +MIME-version: 1.0 +Content-type: TEXT/PLAIN; charset=US-ASCII +Sender: owner-egcs@cygnus.com +Precedence: bulk + +On Wed, 1 Oct 1997, Richard Henderson wrote: + +> Well, it is enough to compile those examples properly, but it is +> not completely correct. The problem is that complex numbers should +> be treated as two distinct arguments on Alpha, which affects padding +> of the arguments passed on the stack. +> + +Here is a patch for it. It should be applied against egcs-970929. +Beside fixing complex-5.c in the testsuite, egcs with this patch generates +the same result from 'make check-gcc' as without it. + +On an alpha-dec-osf4.0, this patch correctly compiles the following test +program with F=char, short, int, long, float, double: +#ifndef F +#define F float +#endif + +typedef __complex__ F FC; + +FC f1(int odd, FC a, FC b, FC c) +{ + return a + b + c; +} + +FC f2a(F a, F b, F c, F d, F e, F f, F g, F h) +{ + return (a + c + e + g) + 1i * (b + d + f + h); +} + +FC f2b(FC a, FC b, FC c, FC d) +{ + return a + b + c + d; +} + +int main() +{ + FC a, b, c, d, e; + a = 1 + 2i; + b = 3+4i; + c = 5+6i; + d = 7+8i; + + e = f1(1,a,b,c); + if (e != 9+12i) + abort (); + e=f2b(a,b,c,d); + if (e != 16+20i) + abort (); + e=f2a(1,2,3,4,5,6,7,8); + if (e != 16+20i) + abort (); + return 0; +} + +This patch has only been tested on alpha-dec-osf4.0, because I have no +access to other machines. To support compless on other machines, the +machine-dependent tm.h has to be modified similarly to what is done for +alpha.h here. + +Weiwen + +Sun Oct 5 19:00:00 Weiwen Liu <liu@hepunix.phycis.yale.edu> + + * c-tree.h: Define complex_long_integer_type_node + to support __complex__ long. + * c-decl.c (init_decl_processing): Initialize + complex_long_integer_type_node. + * c-lex.c (yylex): Enable __complex__ long. + + * expr.h: Define COMPLEX_WORD_MODE and GET_COMPLEX_MODE_SIZE. + * emit-rtl.c (gen_lowpart_common, gen_highpart, + operand_subword): Use them. + * expr.c (move_block_to_reg, emit_push_insn): Use them. + + * emit-rtl.c (operand_subword): Deal with a complex mode. + + * regs.h: Correctly calculate REG_SIZE for a complex mode. + + * config/alpha/alpha.h: Correctly deal with a complex mode in + HARD_REGNO_NREGS, FUNCTION_VALUE, ALPHA_ARG_SIZE. + +*** gcc/c-decl.c.orig Sat Sep 27 14:16:06 1997 +--- gcc/c-decl.c Wed Oct 1 16:19:39 1997 +*************** tree double_type_node; +*** 135,140 **** +--- 135,141 ---- + tree long_double_type_node; + + tree complex_integer_type_node; ++ tree complex_long_integer_type_node; + tree complex_float_type_node; + tree complex_double_type_node; + tree complex_long_double_type_node; +*************** init_decl_processing () +*** 2989,2994 **** +--- 2990,3001 ---- + complex_integer_type_node)); + TREE_TYPE (complex_integer_type_node) = integer_type_node; + layout_type (complex_integer_type_node); ++ ++ complex_long_integer_type_node = make_node (COMPLEX_TYPE); ++ pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long int"), ++ complex_long_integer_type_node)); ++ TREE_TYPE (complex_long_integer_type_node) = long_integer_type_node; ++ layout_type (complex_long_integer_type_node); + + complex_float_type_node = make_node (COMPLEX_TYPE); + pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), +*** gcc/c-lex.c.orig Fri Aug 15 01:32:53 1997 +--- gcc/c-lex.c Wed Oct 1 16:19:39 1997 +*************** yylex () +*** 1769,1774 **** +--- 1769,1780 ---- + = build_complex (NULL_TREE, integer_zero_node, + convert (integer_type_node, + yylval.ttype)); ++ else if (TYPE_PRECISION (type) ++ <= TYPE_PRECISION (long_integer_type_node)) ++ yylval.ttype ++ = build_complex (NULL_TREE, integer_zero_node, ++ convert (long_integer_type_node, ++ yylval.ttype)); + else + error ("complex integer constant is too wide for `complex int'"); + } +*** gcc/c-tree.h.orig Mon Aug 11 11:57:03 1997 +--- gcc/c-tree.h Wed Oct 1 16:19:40 1997 +*************** extern tree long_long_integer_type_node; +*** 219,224 **** +--- 219,225 ---- + extern tree long_long_unsigned_type_node; + extern tree long_unsigned_type_node; + extern tree complex_integer_type_node; ++ extern tree complex_long_integer_type_node; + extern tree complex_float_type_node; + extern tree complex_double_type_node; + extern tree complex_long_double_type_node; +*** gcc/emit-rtl.c.orig Mon Sep 22 13:41:24 1997 +--- gcc/emit-rtl.c Sun Oct 5 17:48:05 1997 +*************** gen_lowpart_common (mode, x) +*** 635,644 **** + / UNITS_PER_WORD))) + return 0; + +! if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) +! word = ((GET_MODE_SIZE (GET_MODE (x)) +! - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) +! / UNITS_PER_WORD); + + if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND) + && (GET_MODE_CLASS (mode) == MODE_INT +--- 635,644 ---- + / UNITS_PER_WORD))) + return 0; + +! if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) >0) +! word = GET_COMPLEX_MODE_SIZE (GET_MODE (x)) +! - ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) +! / UNITS_PER_WORD); + + if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND) + && (GET_MODE_CLASS (mode) == MODE_INT +*************** gen_highpart (mode, x) +*** 1013,1022 **** + int word = 0; + + if (! WORDS_BIG_ENDIAN +! && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) +! word = ((GET_MODE_SIZE (GET_MODE (x)) +! - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) +! / UNITS_PER_WORD); + + /* + * ??? This fails miserably for complex values being passed in registers +--- 1013,1022 ---- + int word = 0; + + if (! WORDS_BIG_ENDIAN +! && GET_MODE_SIZE (GET_MODE (x)) > 0) +! word = GET_COMPLEX_MODE_SIZE (GET_MODE (x)) +! - ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) +! / UNITS_PER_WORD); + + /* + * ??? This fails miserably for complex values being passed in registers +*************** operand_subword (op, i, validate_address +*** 1100,1105 **** +--- 1100,1107 ---- + + /* If OP is narrower than a word or if we want a word outside OP, fail. */ + if (mode != BLKmode ++ && (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT ++ && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT) + && (GET_MODE_SIZE (mode) < UNITS_PER_WORD + || (i + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))) + return 0; +*************** operand_subword (op, i, validate_address +*** 1127,1133 **** + || op == arg_pointer_rtx + #endif + || op == stack_pointer_rtx) +! return gen_rtx (SUBREG, word_mode, op, i); + else + return gen_rtx (REG, word_mode, REGNO (op) + i); + } +--- 1129,1135 ---- + || op == arg_pointer_rtx + #endif + || op == stack_pointer_rtx) +! return gen_rtx (SUBREG, COMPLEX_WORD_MODE (mode), op, i); + else + return gen_rtx (REG, word_mode, REGNO (op) + i); + } +*************** operand_subword (op, i, validate_address +*** 1135,1141 **** + return gen_rtx (SUBREG, word_mode, SUBREG_REG (op), i + SUBREG_WORD (op)); + else if (GET_CODE (op) == CONCAT) + { +! int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD; + if (i < partwords) + return operand_subword (XEXP (op, 0), i, validate_address, mode); + return operand_subword (XEXP (op, 1), i - partwords, +--- 1137,1144 ---- + return gen_rtx (SUBREG, word_mode, SUBREG_REG (op), i + SUBREG_WORD (op)); + else if (GET_CODE (op) == CONCAT) + { +! int partwords = (GET_MODE_UNIT_SIZE (GET_MODE (op)) +! + (UNITS_PER_WORD - 1))/ UNITS_PER_WORD; + if (i < partwords) + return operand_subword (XEXP (op, 0), i, validate_address, mode); + return operand_subword (XEXP (op, 1), i - partwords, +*************** operand_subword (op, i, validate_address +*** 1145,1151 **** + /* Form a new MEM at the requested address. */ + if (GET_CODE (op) == MEM) + { +! rtx addr = plus_constant (XEXP (op, 0), i * UNITS_PER_WORD); + rtx new; + + if (validate_address) +--- 1148,1158 ---- + /* Form a new MEM at the requested address. */ + if (GET_CODE (op) == MEM) + { +! rtx addr = plus_constant ( +! XEXP (op, 0), +! (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT +! || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)? +! i*GET_MODE_UNIT_SIZE (mode): i * UNITS_PER_WORD); + rtx new; + + if (validate_address) +*************** operand_subword (op, i, validate_address +*** 1159,1165 **** + addr = memory_address (word_mode, addr); + } + +! new = gen_rtx (MEM, word_mode, addr); + + MEM_VOLATILE_P (new) = MEM_VOLATILE_P (op); + MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (op); +--- 1166,1172 ---- + addr = memory_address (word_mode, addr); + } + +! new = gen_rtx (MEM, COMPLEX_WORD_MODE (mode), addr); + + MEM_VOLATILE_P (new) = MEM_VOLATILE_P (op); + MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (op); +*** gcc/expr.c.orig Sat Oct 4 03:12:35 1997 +--- gcc/expr.c Sun Oct 5 18:21:18 1997 +*************** move_block_to_reg (regno, x, nregs, mode +*** 1701,1707 **** + #endif + + for (i = 0; i < nregs; i++) +! emit_move_insn (gen_rtx (REG, word_mode, regno + i), + operand_subword_force (x, i, mode)); + } + +--- 1701,1707 ---- + #endif + + for (i = 0; i < nregs; i++) +! emit_move_insn (gen_rtx (REG, COMPLEX_WORD_MODE (mode), regno + i), + operand_subword_force (x, i, mode)); + } + +*************** move_block_from_reg (regno, x, nregs, si +*** 1724,1729 **** +--- 1724,1731 ---- + /* If SIZE is that of a mode no bigger than a word, just use that + mode's store operation. */ + if (size <= UNITS_PER_WORD ++ && GET_MODE_CLASS (GET_MODE (x)) != MODE_COMPLEX_INT ++ && GET_MODE_CLASS (GET_MODE (x)) != MODE_COMPLEX_FLOAT + && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode) + { + emit_move_insn (change_address (x, mode, NULL), +*************** move_block_from_reg (regno, x, nregs, si +*** 1769,1780 **** + + for (i = 0; i < nregs; i++) + { +! rtx tem = operand_subword (x, i, 1, BLKmode); + + if (tem == 0) + abort (); + +! emit_move_insn (tem, gen_rtx (REG, word_mode, regno + i)); + } + } + +--- 1771,1786 ---- + + for (i = 0; i < nregs; i++) + { +! rtx tem = operand_subword +! (x, i, 1, (GET_MODE_CLASS(GET_MODE (x)) == MODE_COMPLEX_INT +! || GET_MODE_CLASS(GET_MODE (x)) == MODE_COMPLEX_FLOAT)? +! GET_MODE(x):BLKmode); + + if (tem == 0) + abort (); + +! emit_move_insn (tem, gen_rtx (REG, COMPLEX_WORD_MODE (GET_MODE (x)), +! regno + i)); + } + } + +*************** emit_push_insn (x, mode, type, size, ali +*** 2687,2693 **** + { + /* Scalar partly in registers. */ + +! int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD; + int i; + int not_stack; + /* # words of start of argument +--- 2693,2699 ---- + { + /* Scalar partly in registers. */ + +! int size = GET_COMPLEX_MODE_SIZE (mode); + int i; + int not_stack; + /* # words of start of argument +*************** emit_push_insn (x, mode, type, size, ali +*** 2696,2701 **** +--- 2702,2716 ---- + int args_offset = INTVAL (args_so_far); + int skip; + ++ /* For a complex argument passing partially in a register, ++ save the image part in stack immedially following the space ++ used for save the part passig in register (see function ++ assign_parms in function.c). */ ++ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT ++ || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) ++ if (GET_MODE_UNIT_SIZE (mode) < UNITS_PER_WORD) ++ args_offset += GET_MODE_UNIT_SIZE (mode) - UNITS_PER_WORD; ++ + /* Push padding now if padding above and stack grows down, + or if padding below and stack grows up. + But if space already allocated, this has already been done. */ +*************** emit_push_insn (x, mode, type, size, ali +*** 2742,2748 **** + #endif + if (i >= not_stack + offset) + emit_push_insn (operand_subword_force (x, i, mode), +! word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX, + 0, args_addr, + GEN_INT (args_offset + ((i - not_stack + skip) + * UNITS_PER_WORD))); +--- 2757,2764 ---- + #endif + if (i >= not_stack + offset) + emit_push_insn (operand_subword_force (x, i, mode), +! COMPLEX_WORD_MODE (mode), +! NULL_TREE, NULL_RTX, align, 0, NULL_RTX, + 0, args_addr, + GEN_INT (args_offset + ((i - not_stack + skip) + * UNITS_PER_WORD))); +*** gcc/expr.h.orig Sat Oct 4 23:46:34 1997 +--- gcc/expr.h Sun Oct 5 18:21:14 1997 +*************** extern void bc_adjust_stack PROTO ((in +*** 952,954 **** +--- 952,970 ---- + extern void bc_load_localaddr PROTO ((rtx)); + extern void do_jump_by_parts_greater_rtx PROTO ((enum machine_mode, int, + rtx, rtx, rtx, rtx)); ++ ++ /* Determine the mode for the imagine and real part of a complex MODE. ++ For a non-complex MODE, use WORD_MODE.*/ ++ #define COMPLEX_WORD_MODE(MODE) \ ++ (((GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \ ++ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \ ++ && GET_MODE_UNIT_SIZE (MODE) < UNITS_PER_WORD)? \ ++ mode_for_size (GET_MODE_UNIT_SIZE(MODE)*BITS_PER_UNIT, \ ++ (GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT)? \ ++ MODE_INT:MODE_FLOAT, \ ++ 0):word_mode) ++ ++ /* Calculate number of bytes needed for a complex MODE */ ++ #define GET_COMPLEX_MODE_SIZE(MODE) \ ++ (((GET_MODE_UNIT_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) \ ++ * (GET_MODE_SIZE (MODE)) / GET_MODE_UNIT_SIZE (MODE)) +*** gcc/regs.h.orig Mon Aug 11 11:57:12 1997 +--- gcc/regs.h Wed Oct 1 16:19:31 1997 +*************** Boston, MA 02111-1307, USA. */ +*** 27,33 **** + valid way to get this value. You cannot get it from the regno. */ + + #define REG_SIZE(R) \ +! ((mode_size[(int) GET_MODE (R)] + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + + /* Maximum register number used in this function, plus one. */ + +--- 27,36 ---- + valid way to get this value. You cannot get it from the regno. */ + + #define REG_SIZE(R) \ +! (GET_MODE_SIZE (GET_MODE (R)) == 0? \ +! 0:(((GET_MODE_UNIT_SIZE (GET_MODE (R)) + (UNITS_PER_WORD - 1)) \ +! / UNITS_PER_WORD) * (GET_MODE_SIZE (GET_MODE (R)) \ +! / GET_MODE_UNIT_SIZE (GET_MODE (R))))) + + /* Maximum register number used in this function, plus one. */ + +*** gcc/config/alpha/alpha.h.orig Wed Oct 1 16:16:31 1997 +--- gcc/config/alpha/alpha.h Fri Oct 3 11:41:58 1997 +*************** extern void override_options (); +*** 515,521 **** + but can be less for certain modes in special long registers. */ + + #define HARD_REGNO_NREGS(REGNO, MODE) \ +! ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + + /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. + On Alpha, the integer registers can hold any mode. The floating-point +--- 515,524 ---- + but can be less for certain modes in special long registers. */ + + #define HARD_REGNO_NREGS(REGNO, MODE) \ +! (GET_MODE_SIZE (MODE) == 0? \ +! 0:(((GET_MODE_UNIT_SIZE (MODE) + (UNITS_PER_WORD - 1)) \ +! / UNITS_PER_WORD) * (GET_MODE_SIZE (MODE) \ +! / GET_MODE_UNIT_SIZE (MODE)))) + + /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. + On Alpha, the integer registers can hold any mode. The floating-point +*************** enum reg_class { NO_REGS, GENERAL_REGS, +*** 891,901 **** + #define FUNCTION_VALUE(VALTYPE, FUNC) \ + gen_rtx (REG, \ + (INTEGRAL_MODE_P (TYPE_MODE (VALTYPE)) \ + && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ + ? word_mode : TYPE_MODE (VALTYPE), \ + ((TARGET_FPREGS \ + && (TREE_CODE (VALTYPE) == REAL_TYPE \ +! || TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \ + ? 32 : 0)) + + /* Define how to find the value returned by a library function +--- 894,908 ---- + #define FUNCTION_VALUE(VALTYPE, FUNC) \ + gen_rtx (REG, \ + (INTEGRAL_MODE_P (TYPE_MODE (VALTYPE)) \ ++ && (GET_MODE_CLASS(TYPE_MODE (VALTYPE)) \ ++ != MODE_COMPLEX_INT) \ + && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ + ? word_mode : TYPE_MODE (VALTYPE), \ + ((TARGET_FPREGS \ + && (TREE_CODE (VALTYPE) == REAL_TYPE \ +! || TREE_CODE (VALTYPE) == COMPLEX_TYPE) \ +! && (GET_MODE_CLASS(TYPE_MODE (VALTYPE)) \ +! != MODE_COMPLEX_INT)) \ + ? 32 : 0)) + + /* Define how to find the value returned by a library function +*************** enum reg_class { NO_REGS, GENERAL_REGS, +*** 953,959 **** + + #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \ + ((MODE) != BLKmode \ +! ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ + : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) + + /* Update the data in CUM to advance over an argument +--- 960,969 ---- + + #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED) \ + ((MODE) != BLKmode \ +! ? (GET_MODE_SIZE (MODE) > 0? \ +! (GET_MODE_UNIT_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ +! * GET_MODE_SIZE (MODE) / GET_MODE_UNIT_SIZE (MODE) \ +! : 0) \ + : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) + + /* Update the data in CUM to advance over an argument + + |