This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
"register struct" patch
- To: gcc at gcc dot gnu dot org
- Subject: "register struct" patch
- From: Benedetto Proietti <benedetto73 at iol dot it>
- Date: Tue, 26 Jun 2001 15:09:58 +0200
This is the patch introduced in the message
http://gcc.gnu.org/ml/gcc/2001-05/msg01321.html
Put the 2 attachments in a directory togheter with GCC 2.95.2
(gcc-2.95.2.tar.gz)
"cd" there, then launch "./doit".
It will configure and make extended "cpp" & "cc1" for "a29k" target.
"register struct" and "register arrays" are available, and generate
pseudo assembly.
This is something more than prototype, I haven't got much time to test
it.
Hope could help.
Feedback is *very* appreciated.
benedetto
Only in gcc-2.95.2-a29k/gcc: CVS
Only in gcc-2.95.2/gcc: ChangeLog
Only in gcc-2.95.2/gcc: ChangeLog.0
Only in gcc-2.95.2/gcc: ChangeLog.lib
Only in gcc-2.95.2/gcc: FSFChangeLog
Only in gcc-2.95.2/gcc: FSFChangeLog.10
Only in gcc-2.95.2/gcc: FSFChangeLog.11
Only in gcc-2.95.2-a29k/gcc: Make-hooks
Only in gcc-2.95.2-a29k/gcc: Make-host
Only in gcc-2.95.2-a29k/gcc: Make-lang
Only in gcc-2.95.2-a29k/gcc: Make-target
Only in gcc-2.95.2-a29k/gcc: Makefile
Only in gcc-2.95.2-a29k/gcc: Makefile.flc
diff -C 2 gcc-2.95.2/gcc/Makefile.in gcc-2.95.2-a29k/gcc/Makefile.in
*** gcc-2.95.2/gcc/Makefile.in Fri Aug 13 09:46:55 1999
--- gcc-2.95.2-a29k/gcc/Makefile.in Sat Mar 17 09:01:29 2001
***************
*** 1334,1338 ****
$(srcdir)/c-gperf.h: c-parse.gperf
! gperf -L C -F ', 0, 0' -p -j1 -i 1 -g -o -t -G -N is_reserved_word \
-k1,3,$$ $(srcdir)/c-parse.gperf >tmp-gperf.h
$(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h
--- 1334,1338 ----
$(srcdir)/c-gperf.h: c-parse.gperf
! gperf -L C -F ', 0, 0' -p -j1 -i 1 -o -t -G -N is_reserved_word \
-k1,3,$$ $(srcdir)/c-parse.gperf >tmp-gperf.h
$(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h
Only in gcc-2.95.2-a29k/gcc: README.#for
Only in gcc-2.95.2-a29k/gcc: TAGS
Only in gcc-2.95.2-a29k/gcc: a29k-cc1.tgz
Only in gcc-2.95.2-a29k/gcc: a29k.o
Only in gcc-2.95.2-a29k/gcc: alias.o
Only in gcc-2.95.2-a29k/gcc: auto-host.h
Only in gcc-2.95.2-a29k/gcc: bitmap.o
Only in gcc-2.95.2-a29k/gcc: c-aux-info.o
Only in gcc-2.95.2-a29k/gcc: c-common.o
Only in gcc-2.95.2-a29k/gcc: c-convert.o
Only in gcc-2.95.2-a29k/gcc: c-decl.o
Only in gcc-2.95.2-a29k/gcc: c-iterate.o
Only in gcc-2.95.2-a29k/gcc: c-lang.o
Only in gcc-2.95.2-a29k/gcc: c-lex.o
Only in gcc-2.95.2-a29k/gcc: c-parse.o
Only in gcc-2.95.2-a29k/gcc: c-pragma.o
diff -C 2 gcc-2.95.2/gcc/c-typeck.c gcc-2.95.2-a29k/gcc/c-typeck.c
*** gcc-2.95.2/gcc/c-typeck.c Thu Sep 16 06:17:51 1999
--- gcc-2.95.2-a29k/gcc/c-typeck.c Sun Mar 18 15:58:21 2001
***************
*** 1079,1082 ****
--- 1079,1089 ----
int volatilep = 0;
+ #if defined(__USE_REGARRAY__)
+ if (__USE_REGARRAY__)
+ {
+ if (GET_CODE(DECL_RTL(exp)) == REGSET)
+ return exp;
+ }
+ #endif
if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'
|| TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
***************
*** 3379,3382 ****
--- 3386,3393 ----
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
{
+ #if defined (__USE_REGARRAY__)
+ if (__USE_REGARRAY__ && DECL_RTL(x) && GET_CODE(DECL_RTL(x))==REGSET)
+ return 1;
+ #endif
if (TREE_PUBLIC (x))
{
***************
*** 4262,4266 ****
return convert (type, rhs);
}
!
if (!errtype)
{
--- 4273,4288 ----
return convert (type, rhs);
}
! #ifdef __USE_REGARRAY__
! if (__USE_REGARRAY__)
! {
! if (codel == ARRAY_TYPE && coder == POINTER_TYPE )
! // && DECL_RTL(rhs) && GET_CODE(DECL_RTL(rhs)) == REGSET)
! {
! if (pedantic)
! pedwarn ("ANSI C does not allow copying arrays");
! return rhs;
! }
! }
! #endif
if (!errtype)
{
Only in gcc-2.95.2-a29k/gcc: c-typeck.o
Only in gcc-2.95.2-a29k/gcc: caller-save.o
Only in gcc-2.95.2-a29k/gcc: calls.o
Only in gcc-2.95.2-a29k/gcc: cc1
Only in gcc-2.95.2-a29k/gcc: cccp
Only in gcc-2.95.2/gcc: cccp.1
diff -C 2 gcc-2.95.2/gcc/cccp.c gcc-2.95.2-a29k/gcc/cccp.c
*** gcc-2.95.2/gcc/cccp.c Tue Jun 1 19:10:01 1999
--- gcc-2.95.2-a29k/gcc/cccp.c Fri May 4 14:59:33 2001
***************
*** 278,281 ****
--- 278,289 ----
static int no_record_file;
+ #ifdef __USE_REGARRAY__
+ /*
+ Nonzero means that #for are recognized and preprocessed according to current
+ implementation. Zero means that #for are NOT recognized and errors are generated.
+ */
+ static int preprocess_fast_regs = 0;
+ #endif
+
/* Nonzero means that we have finished processing the command line options.
This flag is used to decide whether or not to issue certain errors
***************
*** 635,638 ****
--- 643,649 ----
T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
+ #ifdef __USE_REGARRAY__
+ T_FOR, /* */
+ #endif
T_UNUSED /* Used for something not defined. */
};
***************
*** 786,789 ****
--- 797,803 ----
static int do_warning DO_PROTO;
static int do_xifdef DO_PROTO;
+ #ifdef __USE_REGARRAY__
+ static int do_for DO_PROTO;
+ #endif
/* Here is the actual list of #-directives, most-often-used first. */
***************
*** 811,814 ****
--- 825,831 ----
{ 6, do_assert, "assert", T_ASSERT},
{ 8, do_unassert, "unassert", T_UNASSERT},
+ #ifdef __USE_REGARRAY__
+ { 3, do_for, "for", T_FOR},
+ #endif
{ -1, 0, "", T_UNUSED},
};
***************
*** 1319,1323 ****
} else {
switch (argv[i][1]) {
!
case 'i':
if (!strcmp (argv[i], "-include")) {
--- 1336,1346 ----
} else {
switch (argv[i][1]) {
! #ifdef __USE_REGARRAY__
! case 'm':
! if (!strcmp (argv[i], "-mfast-regs")) {
! preprocess_fast_regs = 1;
! }
! break;
! #endif
case 'i':
if (!strcmp (argv[i], "-include")) {
***************
*** 2561,2564 ****
--- 2584,2589 ----
RECACHE;
+ //fprintf (stderr, "betto: &rescan::ip= %#x\n", &ip);
+
beg_of_line = ibp;
***************
*** 6554,6557 ****
--- 6579,6746 ----
}
+
+ #ifdef __USE_REGARRAY__
+ static U_CHAR* parse_pound_for (U_CHAR*buf, U_CHAR** iv, int *n, int** index_list)
+ {
+ U_CHAR *ptr, *index_variable;
+ int iv_sizex;
+ int first_index, last_index, step;
+ int i, real_index, n_index;
+
+ buf = strchr(buf, '(');
+ buf++;
+ SKIP_WHITE_SPACE(buf);
+ ptr = strchr (buf, ',');
+ iv_sizex = ptr-buf;
+ index_variable = malloc(iv_sizex+1);
+ strncpy (index_variable, buf, iv_sizex/sizeof(U_CHAR));
+ index_variable[iv_sizex] = 0;
+ *iv = index_variable;
+ buf = ptr+1;
+
+ SKIP_WHITE_SPACE(buf);
+ ptr = strchr (buf, ',');
+ first_index = atoi(buf);
+ buf = ptr+1;
+
+ SKIP_WHITE_SPACE(buf);
+ ptr = strchr (buf, ',');
+ last_index = atoi(buf);
+ buf = ptr+1;
+
+ SKIP_WHITE_SPACE(buf);
+ step = atoi(buf);
+
+ /* fprintf (stderr, "index variable \'%s\', first index %d, last %d, step %d\n",
+ *iv, first_index, last_index, step); */
+
+ n_index = (last_index-first_index)/step+1;
+ *index_list = malloc (n_index * sizeof(int));
+
+ for (i=0, real_index=first_index; real_index<=last_index; i++, real_index+=step)
+ (*index_list)[i] = real_index;
+ *n = i;
+
+ return strchr(buf, '\n');
+ }
+ static void dump_pound_for_block (U_CHAR *start, U_CHAR*end, FILE_BUF *op)
+ {
+ FILE_BUF *fp; /* For input stack frame */
+ int last_no_line_directives, missing_newline = 0;
+ int bsize = (end-start)/sizeof(typeof(*end));
+
+ CHECK_DEPTH (return;);
+
+ fp = &instack[indepth + 1];
+ bzero ((char *) fp, sizeof (FILE_BUF));
+ fp->nominal_fname = fp->fname = instack[indepth].fname;
+ fp->nominal_fname_len = strlen (instack[indepth].fname);
+ fp->inc = instack[indepth].inc;
+ fp->length = 0;
+ fp->lineno = 1;
+ fp->if_stack = instack[indepth].if_stack;
+ fp->system_header_p = instack[indepth].system_header_p;
+ fp->dir = instack[indepth].dir;
+ fp->buf = (U_CHAR *) xmalloc (bsize+1);
+ memcpy (fp->buf, start, bsize);
+ fp->buf[bsize] = '\n';
+ fp->bufp = fp->buf;
+ fp->length = bsize+1;
+
+ if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
+ /* Backslash-newline at end is not good enough. */
+ || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
+ fp->buf[fp->length++] = '\n';
+ missing_newline = 1;
+ }
+ fp->buf[fp->length] = '\0';
+
+
+ /* Must do this before calling trigraph_pcp, so that the correct file name
+ will be printed in warning messages. */
+
+ indepth++;
+ input_file_stack_tick++;
+
+ if (!no_trigraphs)
+ trigraph_pcp (fp);
+
+ last_no_line_directives = no_line_directives;
+ //output_line_directive (&instack[indepth], op, 0, leave_file);
+ no_line_directives = 1;
+ rescan (op, 0);
+
+ no_line_directives = last_no_line_directives;
+ if (missing_newline)
+ fp->lineno--;
+
+ if (pedantic && missing_newline)
+ pedwarn ("file does not end in newline");
+
+ indepth--;
+ input_file_stack_tick++;
+ //output_line_directive (&instack[indepth], op, 0, leave_file);
+ free (fp->buf);
+ return;
+ }
+ static int do_for (U_CHAR *buf, U_CHAR *limit,
+ FILE_BUF *op,
+ struct directive *keyword ATTRIBUTE_UNUSED)
+ {
+ U_CHAR * index_variable, *end_for;
+ char pound_for_directive[1000], **value_list;
+ int loop_iterations, *index_list, i, hashcode, len;
+ char value[100];
+ MACRODEF mdef;
+ HASHNODE *hp;
+ static DEFINITION defn = { -1, 1, 0, 0, 0, 0, 0, 0, 0 };
+ U_CHAR ** fa0 = __builtin_frame_address(0);
+ U_CHAR ** fa1 = __builtin_frame_address(1);
+ U_CHAR ** fa2 = __builtin_frame_address(2);
+ volatile U_CHAR ** rescan_frame_address = __builtin_frame_address(2);
+ //fprintf (stderr, "betto: rescan_frame_address= %#x\n", rescan_frame_address);
+
+ if (!preprocess_fast_regs)
+ {
+ error ("use -mfast-regs to implement #for");
+ return 0;
+ }
+ if (pedantic)
+ pedwarn ("ANSI C does not allow `#for'");
+
+ buf = strchr(parse_pound_for (buf, &index_variable, &loop_iterations,&index_list),'{');
+ end_for = strchr (buf, '}');
+
+ mdef.defn = &defn;
+ mdef.symnam = index_variable;
+ mdef.symlen = strlen(index_variable);
+ hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
+ hp = install (mdef.symnam, mdef.symlen, T_MACRO, (char*) mdef.defn, hashcode);
+
+ check_expand (op, 1);
+ *op->bufp++ = '\n';
+ for (i=0; i<loop_iterations; i++)
+ {
+ // something like do_define with "index_variable" = index_list[i]
+ sprintf (value, "%d", index_list[i]);
+ hp->value.defn->expansion = value;
+
+ // dump text like do_include
+ /*
+ sprintf (pound_for_directive, "#for iteration %d (%s=%d)", i+1, index_variable,
+ index_list[i]);
+ len = strlen(pound_for_directive);
+ check_expand (op, len + 1);
+ bcopy ((char *) pound_for_directive, (char *) op->bufp, len);
+ op->bufp += len; */
+ dump_pound_for_block (buf+1, end_for-1, op);
+ }
+ buf = end_for+1;
+ rescan_frame_address -= 1;
+ ((FILE_BUF*)*rescan_frame_address)->bufp = buf;
+ return 21556;
+ }
+ #endif
+
/* Test whether there is an assertion named NAME
and optionally whether it has an asserted token list TOKENS.
Only in gcc-2.95.2-a29k/gcc: cccp.c.flc
Only in gcc-2.95.2-a29k/gcc: cccp.o
Only in gcc-2.95.2-a29k/gcc: cccp.s.NO
Only in gcc-2.95.2-a29k/gcc: cccp.s.O2
Only in gcc-2.95.2-a29k/gcc: cexp.o
Only in gcc-2.95.2/gcc: ch
diff -C 2 gcc-2.95.2/gcc/combine.c gcc-2.95.2-a29k/gcc/combine.c
*** gcc-2.95.2/gcc/combine.c Mon Oct 18 09:52:32 1999
--- gcc-2.95.2-a29k/gcc/combine.c Sun Mar 18 10:18:00 2001
***************
*** 937,940 ****
--- 937,951 ----
src = SET_SRC (set), dest = SET_DEST (set);
+ //Betto: register struct
+ #ifdef __USE_REGISTER_STRUCT__
+ if (__USE_REGISTER_STRUCT__)
+ {
+ if (GET_CODE(PATTERN(i3)) == PARALLEL && GET_CODE(XVECEXP(PATTERN (i3),0,0))==SET &&
+ (GET_CODE(SET_SRC(XVECEXP(PATTERN(i3),0,0))) == REGSET ||
+ GET_CODE(SET_DEST(XVECEXP(PATTERN(i3),0,0))) == REGSET))
+ return 0;
+ }
+ #endif
+
/* Don't eliminate a store in the stack pointer. */
if (dest == stack_pointer_rtx
Only in gcc-2.95.2-a29k/gcc: combine.o
Common subdirectories: gcc-2.95.2/gcc/config and gcc-2.95.2-a29k/gcc/config
Only in gcc-2.95.2-a29k/gcc: config.bak
Only in gcc-2.95.2-a29k/gcc: config.h
Only in gcc-2.95.2-a29k/gcc: config.run
Only in gcc-2.95.2-a29k/gcc: config.status
Only in gcc-2.95.2-a29k/gcc: convert.o
Common subdirectories: gcc-2.95.2/gcc/cp and gcc-2.95.2-a29k/gcc/cp
Only in gcc-2.95.2-a29k/gcc: cpp
Only in gcc-2.95.2/gcc: cpp.1
Only in gcc-2.95.2/gcc: cpp.texi
Only in gcc-2.95.2-a29k/gcc: cse.o
Only in gcc-2.95.2-a29k/gcc: cstamp-h
Only in gcc-2.95.2-a29k/gcc: dbxout.o
Only in gcc-2.95.2-a29k/gcc: dwarf2out.o
Only in gcc-2.95.2-a29k/gcc: dwarfout.o
Only in gcc-2.95.2-a29k/gcc: dyn-string.o
diff -C 2 gcc-2.95.2/gcc/emit-rtl.c gcc-2.95.2-a29k/gcc/emit-rtl.c
*** gcc-2.95.2/gcc/emit-rtl.c Wed Aug 11 09:28:52 1999
--- gcc-2.95.2-a29k/gcc/emit-rtl.c Sun Mar 18 10:18:27 2001
***************
*** 619,623 ****
else if (GET_CODE (reg) == REG)
REG_USERVAR_P (reg) = 1;
! else
abort ();
}
--- 619,634 ----
else if (GET_CODE (reg) == REG)
REG_USERVAR_P (reg) = 1;
! else
! #ifdef __USE_REGISTER_STRUCT__
! if (__USE_REGISTER_STRUCT__)
! {
! if (GET_CODE (reg) == REGSET)
! {
! int i;
! for (i=0; i<XVECLEN(reg, 0); i++)
! REG_USERVAR_P (XEXP (XVECEXP(reg, 0, i), 0)) = 1;
! }
! } else
! #endif
abort ();
}
Only in gcc-2.95.2-a29k/gcc: emit-rtl.c.flc
Only in gcc-2.95.2-a29k/gcc: emit-rtl.o
Only in gcc-2.95.2-a29k/gcc: except.o
Only in gcc-2.95.2-a29k/gcc: explow.o
Only in gcc-2.95.2-a29k/gcc: expmed.o
diff -C 2 gcc-2.95.2/gcc/expr.c gcc-2.95.2-a29k/gcc/expr.c
*** gcc-2.95.2/gcc/expr.c Thu Jul 1 00:59:55 1999
--- gcc-2.95.2-a29k/gcc/expr.c Sat Mar 24 10:24:52 2001
***************
*** 1397,1400 ****
--- 1397,1410 ----
}
+ #ifdef __USE_REGARRAY__
+ if (__USE_REGARRAY__)
+ {
+ if (mode == BLKmode && oldmode != BLKmode)
+ {
+ temp = gen_rtx_MEM (BLKmode, x);
+ return temp;
+ }
+ }
+ #endif
temp = gen_reg_rtx (mode);
convert_move (temp, x, unsignedp);
***************
*** 1649,1656 ****
x = protect_from_queue (x, 1);
y = protect_from_queue (y, 0);
- size = protect_from_queue (size, 0);
if (GET_CODE (x) != MEM)
abort ();
if (GET_CODE (y) != MEM)
abort ();
--- 1659,1680 ----
x = protect_from_queue (x, 1);
y = protect_from_queue (y, 0);
+ //Betto: hyper ... allowing hyper rtx
+ #ifdef __USE_REGISTER_STRUCT__
+ if (__USE_REGISTER_STRUCT__)
+ {
+ //Betto: register struct
+ if (GET_CODE (x) == REGSET || GET_CODE (y) == REGSET)
+ {
+ //emit_insn (gen_movstrsi(x,y,size,GEN_INT(align)));
+ emit_insn (gen_movblk(x,y));
+ return retval;
+ }
+ }
+ #endif
+ size = protect_from_queue (size, 0);
if (GET_CODE (x) != MEM)
abort ();
+
if (GET_CODE (y) != MEM)
abort ();
***************
*** 1946,1952 ****
int start, i;
! if (GET_CODE (dst) != PARALLEL)
abort ();
/* Check for a NULL entry, used to indicate that the parameter goes
both on the stack and in registers. */
--- 1970,1993 ----
int start, i;
! if (GET_CODE (dst) != PARALLEL
! #ifdef __USE_REGISTER_STRUCT__
! && GET_CODE(dst) != REGSET
! #endif
! )
abort ();
+ #ifdef __USE_REGISTER_STRUCT__
+ if (__USE_REGISTER_STRUCT__)
+ {
+ //Betto: register struct
+ if (GET_CODE (orig_src) == REGSET || GET_CODE (dst) == REGSET)
+ {
+ //emit_insn (gen_movstrsi(dst,orig_src,GEN_INT(ssize),GEN_INT(align)));
+ emit_insn (gen_movblk(dst,orig_src));
+ return;
+ }
+ }
+ #endif
+
/* Check for a NULL entry, used to indicate that the parameter goes
both on the stack and in registers. */
***************
*** 2590,2596 ****
y = protect_from_queue (y, 0);
if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
abort ();
!
/* Never force constant_p_rtx to memory. */
if (GET_CODE (y) == CONSTANT_P_RTX)
--- 2631,2646 ----
y = protect_from_queue (y, 0);
+ #ifdef __USE_REGARRAY__
+ if (__USE_REGARRAY__)
+ {
+ if (mode==BLKmode && (GET_CODE(x) == REGSET || GET_CODE(y) == REGSET))
+ ;
+ else
+ #endif
if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
abort ();
! #ifdef __USE_REGARRAY__
! }
! #endif
/* Never force constant_p_rtx to memory. */
if (GET_CODE (y) == CONSTANT_P_RTX)
***************
*** 2614,2617 ****
--- 2664,2672 ----
y = change_address (y, VOIDmode, XEXP (y, 0));
+ #if defined(__USE_REGARRAY__) || defined(__USE_REGISTER_STRUCT__)
+ if (__USE_REGARRAY__ || __USE_REGISTER_STRUCT__)
+ ;
+ else
+ #endif
if (mode == BLKmode)
abort ();
***************
*** 3883,3887 ****
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
! else if (GET_CODE (target) == PARALLEL)
emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)),
TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
--- 3938,3946 ----
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
! else if (GET_CODE (target) == PARALLEL
! #ifdef __USE_REGISTER_STRUCT__
! || GET_CODE(target) == REGSET
! #endif
! )
emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)),
TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
***************
*** 4745,4748 ****
--- 4804,4817 ----
return const0_rtx;
}
+ //Betto: register struct
+ #ifdef __USE_REGISTER_STRUCT__
+ if (GET_MODE(target)==BLKmode && GET_CODE(target)==REGSET)
+ {
+ /* qui si ritorna il registro vero, percio' si deve fare il conto con bitpos,
+ bitsize etc.. */
+ rtx to_rtx = RS_inside_register_struct(target, bitpos, bitsize);
+ return store_expr (exp, to_rtx, value_mode != VOIDmode);
+ }
+ #endif
else
{
***************
*** 6483,6486 ****
--- 6552,6564 ----
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
+ #if defined(__USE_REGARRAY__)
+ if (__USE_REGARRAY__ && GET_CODE(op0)==REGSET)
+ {
+ if (!CONSTANT_P (offset_rtx))
+ fatal (FASTREGS_SHORT ": cannot use indirection on register arrays"
+ " and register structs.");
+ }
+ else
+ #endif
if (GET_CODE (op0) != MEM)
abort ();
***************
*** 6651,6654 ****
--- 6729,6741 ----
(bitpos / BITS_PER_UNIT)));
else
+ //Betto: register struct
+ #ifdef __USE_REGISTER_STRUCT__
+ if (GET_CODE(op0) == REGSET)
+ {
+ op0 = RS_inside_register_struct (op0, bitpos, bitsize);
+ return op0;
+ }
+ else
+ #endif
op0 = change_address (op0, mode1,
plus_constant (XEXP (op0, 0),
***************
*** 8035,8038 ****
--- 8122,8130 ----
}
+ #if defined(__USE_REGARRAY__)
+ if (__USE_REGARRAY__ && GET_CODE(op0)==REGSET)
+ ;
+ else
+ #endif
if (GET_CODE (op0) != MEM)
abort ();
***************
*** 8048,8052 ****
return temp;
}
!
op0 = force_operand (XEXP (op0, 0), target);
}
--- 8140,8147 ----
return temp;
}
! #ifdef __USE_REGARRAY__
! if (__USE_REGARRAY__ && GET_CODE(op0) == REGSET) ;
! else
! #endif
op0 = force_operand (XEXP (op0, 0), target);
}
Only in gcc-2.95.2-a29k/gcc: expr.c.flc
diff -C 2 gcc-2.95.2/gcc/expr.h gcc-2.95.2-a29k/gcc/expr.h
*** gcc-2.95.2/gcc/expr.h Sat May 22 03:25:48 1999
--- gcc-2.95.2-a29k/gcc/expr.h Sat Mar 17 09:01:29 2001
***************
*** 396,399 ****
--- 396,418 ----
extern optab ior_optab; /* Logical or */
extern optab xor_optab; /* Logical xor */
+ //Betto: Jane CC
+ extern optab Jand_optab; /* Logical and */
+ extern optab Jior_optab; /* Logical or */
+ extern optab Jxor_optab; /* Logical xor */
+ extern optab Jnot_optab; /* Logical not */
+ extern optab jgt_optab;
+ extern optab jge_optab;
+ extern optab jlt_optab;
+ extern optab jle_optab;
+ extern optab jeq_optab;
+ extern optab jne_optab;
+ extern optab jlutinv_optab;
+ extern optab jlutinvsqrt_optab;
+ extern optab jlutinvloge_optab;
+ extern optab jlutinvlogm_optab;
+ extern optab jlutinvexp_optab;
+ extern optab localoffset_optab;
+ extern optab conj_optab;
+
extern optab ashl_optab; /* Arithmetic shift left */
extern optab ashr_optab; /* Arithmetic shift right */
Only in gcc-2.95.2-a29k/gcc: expr.o
Only in gcc-2.95.2/gcc: extend.texi
Only in gcc-2.95.2/gcc: f
Only in gcc-2.95.2-a29k/gcc: final.o
Common subdirectories: gcc-2.95.2/gcc/fixinc and gcc-2.95.2-a29k/gcc/fixinc
Only in gcc-2.95.2-a29k/gcc: fixinc.sh
Only in gcc-2.95.2-a29k/gcc: fixincl
Only in gcc-2.95.2-a29k/gcc: flow.o
Only in gcc-2.95.2-a29k/gcc: fold-const.o
Only in gcc-2.95.2-a29k/gcc: function.o
Only in gcc-2.95.2/gcc: gcc.1
Only in gcc-2.95.2/gcc: gcc.texi
Only in gcc-2.95.2/gcc: gcov.texi
Only in gcc-2.95.2-a29k/gcc: gcse.o
Only in gcc-2.95.2-a29k/gcc: genattr
Only in gcc-2.95.2-a29k/gcc: genattr.o
Only in gcc-2.95.2-a29k/gcc: genattrtab
Only in gcc-2.95.2-a29k/gcc: genattrtab.o
Only in gcc-2.95.2-a29k/gcc: gencheck
Only in gcc-2.95.2-a29k/gcc: gencheck.h
Only in gcc-2.95.2-a29k/gcc: gencheck.o
Only in gcc-2.95.2-a29k/gcc: gencodes
Only in gcc-2.95.2-a29k/gcc: gencodes.o
Only in gcc-2.95.2-a29k/gcc: genconfig
Only in gcc-2.95.2-a29k/gcc: genconfig.o
Only in gcc-2.95.2-a29k/gcc: genemit
Only in gcc-2.95.2-a29k/gcc: genemit.o
Only in gcc-2.95.2-a29k/gcc: genextract
Only in gcc-2.95.2-a29k/gcc: genextract.o
Only in gcc-2.95.2-a29k/gcc: genflags
Only in gcc-2.95.2-a29k/gcc: genflags.o
Only in gcc-2.95.2-a29k/gcc: gengenrtl
Only in gcc-2.95.2-a29k/gcc: gengenrtl.o
Only in gcc-2.95.2-a29k/gcc: genopinit
Only in gcc-2.95.2-a29k/gcc: genopinit.o
Only in gcc-2.95.2-a29k/gcc: genoutput
Only in gcc-2.95.2-a29k/gcc: genoutput.o
Only in gcc-2.95.2-a29k/gcc: genpeep
Only in gcc-2.95.2-a29k/gcc: genpeep.o
Only in gcc-2.95.2-a29k/gcc: genrecog
Only in gcc-2.95.2-a29k/gcc: genrecog.o
Only in gcc-2.95.2-a29k/gcc: genrtl.c
Only in gcc-2.95.2-a29k/gcc: genrtl.h
Only in gcc-2.95.2-a29k/gcc: genrtl.o
Only in gcc-2.95.2-a29k/gcc: getpwd.o
Common subdirectories: gcc-2.95.2/gcc/ginclude and gcc-2.95.2-a29k/gcc/ginclude
Only in gcc-2.95.2-a29k/gcc: global.o
Only in gcc-2.95.2-a29k/gcc: graph.o
diff -C 2 gcc-2.95.2/gcc/haifa-sched.c gcc-2.95.2-a29k/gcc/haifa-sched.c
*** gcc-2.95.2/gcc/haifa-sched.c Tue Oct 12 07:38:53 1999
--- gcc-2.95.2-a29k/gcc/haifa-sched.c Mon Mar 26 22:41:04 2001
***************
*** 3318,3324 ****
if (dest == 0)
return;
!
! if (GET_CODE (dest) == PARALLEL
! && GET_MODE (dest) == BLKmode)
{
register int i;
--- 3318,3322 ----
if (dest == 0)
return;
! if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
{
register int i;
***************
*** 3728,3731 ****
--- 3726,3760 ----
int maxreg = max_reg_num ();
int i;
+
+ #if defined(__USE_REGISTER_STRUCT__)
+ if (__USE_REGISTER_STRUCT__)
+ {
+ if (code == SET && GET_CODE(SET_DEST(x)) == REGSET)
+ {
+ rtx linearized = RS_linearize_regset (SET_DEST(x));
+ rtx magic = gen_rtx_SET (GET_MODE(x), 0, SET_SRC(x));
+ int i;
+ for (i=0; i<XVECLEN(linearized,0); i++)
+ {
+ if (GET_CODE(SET_SRC(x)) == REGSET)
+ {
+ int j;
+ rtx linearized2 = RS_linearize_regset (SET_SRC(x));
+ for (j=0; j<XVECLEN (linearized2, 0); j++)
+ {
+ SET_SRC(magic) = XVECEXP (linearized2, 0, j);
+ sched_analyze_insn (magic, insn, loop_notes);
+ }
+ }
+ else
+ {
+ SET_DEST (magic) = XVECEXP(linearized, 0, i);
+ //sched_analyze_1 (magic, insn);
+ sched_analyze_insn (magic, insn, loop_notes);
+ }
+ }
+ }
+ }
+ #endif
if (code == SET || code == CLOBBER)
Only in gcc-2.95.2-a29k/gcc: hash.o
Only in gcc-2.95.2-a29k/gcc: hconfig.h
Only in gcc-2.95.2-a29k/gcc: insn-attr.h
Only in gcc-2.95.2-a29k/gcc: insn-attrtab.c
Only in gcc-2.95.2-a29k/gcc: insn-attrtab.o
Only in gcc-2.95.2-a29k/gcc: insn-codes.h
Only in gcc-2.95.2-a29k/gcc: insn-config.h
Only in gcc-2.95.2-a29k/gcc: insn-emit.c
Only in gcc-2.95.2-a29k/gcc: insn-emit.o
Only in gcc-2.95.2-a29k/gcc: insn-extract.c
Only in gcc-2.95.2-a29k/gcc: insn-extract.o
Only in gcc-2.95.2-a29k/gcc: insn-flags.h
Only in gcc-2.95.2-a29k/gcc: insn-opinit.c
Only in gcc-2.95.2-a29k/gcc: insn-opinit.o
Only in gcc-2.95.2-a29k/gcc: insn-output.c
Only in gcc-2.95.2-a29k/gcc: insn-output.o
Only in gcc-2.95.2-a29k/gcc: insn-peep.c
Only in gcc-2.95.2-a29k/gcc: insn-peep.o
Only in gcc-2.95.2-a29k/gcc: insn-recog.c
Only in gcc-2.95.2-a29k/gcc: insn-recog.o
Only in gcc-2.95.2/gcc: install.texi
Only in gcc-2.95.2/gcc: install1.texi
Only in gcc-2.95.2-a29k/gcc: integrate.o
Common subdirectories: gcc-2.95.2/gcc/intl and gcc-2.95.2-a29k/gcc/intl
Only in gcc-2.95.2-a29k/gcc: intl.o
Only in gcc-2.95.2/gcc: invoke.texi
Only in gcc-2.95.2/gcc: java
Only in gcc-2.95.2-a29k/gcc: jump.o
diff -C 2 gcc-2.95.2/gcc/just-fixinc gcc-2.95.2-a29k/gcc/just-fixinc
*** gcc-2.95.2/gcc/just-fixinc Wed Dec 16 21:57:01 1998
--- gcc-2.95.2-a29k/gcc/just-fixinc Sat Mar 17 09:01:29 2001
***************
*** 1,4 ****
#!/bin/sh
! # $Id: just-fixinc,v 1.2 1998/04/03 16:35:58 law Exp $
# This script exists for use after installing
# the GCC binaries from a distribution tape/CD-ROM.
--- 1,4 ----
#!/bin/sh
! # $Id: just-fixinc,v 1.1.1.1 2000/12/18 14:47:22 betto Exp $
# This script exists for use after installing
# the GCC binaries from a distribution tape/CD-ROM.
Only in gcc-2.95.2-a29k/gcc: lcm.o
Only in gcc-2.95.2-a29k/gcc: libintl.h
Only in gcc-2.95.2-a29k/gcc: local-alloc.o
diff -C 2 gcc-2.95.2/gcc/loop.c gcc-2.95.2-a29k/gcc/loop.c
*** gcc-2.95.2/gcc/loop.c Mon Oct 25 08:44:53 1999
--- gcc-2.95.2-a29k/gcc/loop.c Sat Mar 17 09:01:29 2001
***************
*** 813,817 ****
--- 813,821 ----
if (GET_CODE (p) == INSN
&& (set = single_set (p))
+ #if 0 && defined(__USE_REGISTER_STRUCT__)
+ && (GET_CODE (SET_DEST (set)) == REGSET || GET_CODE (SET_DEST (set)) == REG)
+ #else
&& GET_CODE (SET_DEST (set)) == REG
+ #endif
&& ! VARRAY_CHAR (may_not_optimize, REGNO (SET_DEST (set))))
{
***************
*** 3507,3510 ****
--- 3511,3527 ----
last_set[regno] = insn;
}
+ #ifdef __USE_REGISTER_STRUCT__
+ if (GET_CODE (dest) == REGSET)
+ {
+ int i;
+ rtx linearized = RS_linearize_regset (dest);
+
+ for (i=0; i<XVECLEN(dest,0); i++)
+ {
+ rtx other = gen_rtx_SET (GET_MODE(dest), XVECEXP(dest,0,i), SET_SRC(x));
+ count_one_set (insn, other, may_not_move, last_set);
+ }
+ }
+ #endif
}
}
Only in gcc-2.95.2-a29k/gcc: loop.o
Only in gcc-2.95.2-a29k/gcc: mbchar.o
Only in gcc-2.95.2/gcc: md.texi
diff -C 2 gcc-2.95.2/gcc/mkinstalldirs gcc-2.95.2-a29k/gcc/mkinstalldirs
*** gcc-2.95.2/gcc/mkinstalldirs Thu Dec 17 07:43:04 1998
--- gcc-2.95.2-a29k/gcc/mkinstalldirs Sat Mar 17 09:01:29 2001
***************
*** 5,9 ****
# Public domain
! # $Id: mkinstalldirs,v 1.1 1998/05/19 07:09:56 drepper Exp $
errstatus=0
--- 5,9 ----
# Public domain
! # $Id: mkinstalldirs,v 1.1.1.1 2000/12/18 14:47:23 betto Exp $
errstatus=0
Only in gcc-2.95.2/gcc: objc
Only in gcc-2.95.2-a29k/gcc: obstack.c
Only in gcc-2.95.2-a29k/gcc: obstack.o
Only in gcc-2.95.2-a29k/gcc: optabs.c.flc
Only in gcc-2.95.2-a29k/gcc: optabs.o
Only in gcc-2.95.2-a29k/gcc: options.h
Common subdirectories: gcc-2.95.2/gcc/po and gcc-2.95.2-a29k/gcc/po
Only in gcc-2.95.2-a29k/gcc: prefix.o
Only in gcc-2.95.2-a29k/gcc: print-rtl.o
Only in gcc-2.95.2-a29k/gcc: print-tree.o
Only in gcc-2.95.2-a29k/gcc: profile.o
Only in gcc-2.95.2-a29k/gcc: real.o
Only in gcc-2.95.2-a29k/gcc: recog.o
Only in gcc-2.95.2-a29k/gcc: reg-stack.o
diff -C 2 gcc-2.95.2/gcc/regclass.c gcc-2.95.2-a29k/gcc/regclass.c
*** gcc-2.95.2/gcc/regclass.c Wed Jul 14 02:59:20 1999
--- gcc-2.95.2-a29k/gcc/regclass.c Fri Mar 23 14:53:51 2001
***************
*** 2058,2061 ****
--- 2058,2070 ----
switch (code)
{
+ #ifdef __USE_REGISTER_STRUCT__
+ case REGSET:
+ {
+ register int i;
+ for (i=0; i<XVECLEN(x, 0); i++)
+ reg_scan_mark_refs (XVECEXP (x, 0, i), insn, note_flag, min_regno);
+ break;
+ }
+ #endif
case CONST:
case CONST_INT:
***************
*** 2097,2110 ****
case SET:
! /* Count a set of the destination if it is a register. */
! for (dest = SET_DEST (x);
! GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
! || GET_CODE (dest) == ZERO_EXTEND;
! dest = XEXP (dest, 0))
! ;
!
! if (GET_CODE (dest) == REG
! && REGNO (dest) >= min_regno)
! REG_N_SETS (REGNO (dest))++;
/* If this is setting a pseudo from another pseudo or the sum of a
--- 2106,2163 ----
case SET:
! //Betto
! #ifdef __USE_REGISTER_STRUCT__
! if (__USE_REGISTER_STRUCT__)
! {
! if (GET_CODE(SET_DEST(x)) == REGSET)
! reg_scan_mark_refs (SET_DEST(x), insn, note_flag, min_regno);
! if (GET_CODE(SET_SRC(x)) == REGSET)
! reg_scan_mark_refs (SET_SRC(x), insn, note_flag, min_regno);
! }
! #endif
! /* l'algoritmo che segue deve essere sostanzialmente e formalmente identico sia
! per ogni elemento del regset (SE è un regset) sia per altri operatori RTL §*/
! #ifdef __USE_FASTREGS_MULTI_X__
! {
! int i,j;
! rtx orig = x;
! rtx linearized_dest = GET_CODE(SET_DEST(orig))==REGSET
! ? RS_linearize_regset (SET_DEST(orig)) : (rtx)0;
! rtx linearized_src = GET_CODE(SET_SRC(orig))==REGSET
! ? RS_linearize_regset (SET_SRC(orig)) : (rtx)0;
! x = gen_rtx_SET (GET_MODE(orig), 0, 0);
!
! if (GET_CODE(SET_DEST(orig))==REGSET)
! ;
! else
! SET_DEST(x) = SET_DEST(orig);
!
! if (GET_CODE(SET_SRC(orig))==REGSET)
! ;
! else
! SET_SRC(x) = SET_SRC(orig);
!
! for (i=0;
! i < (linearized_dest==0 ? 1 : XVECLEN(linearized_dest,0));
! i++)
! {
! SET_DEST(x) = linearized_dest ? XVECEXP(linearized_dest, 0, i) : SET_DEST(x);
! for (j=0;
! j < (linearized_src==0 ? 1 : XVECLEN(linearized_src,0));
! j++)
! {
! SET_SRC(x) = linearized_src
! ? XVECEXP(linearized_src, 0, i) : SET_SRC(x);
! #endif
! /* Count a set of the destination if it is a register. */
! for (dest = SET_DEST (x);
! GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
! || GET_CODE (dest) == ZERO_EXTEND;
! dest = XEXP (dest, 0))
! ;
!
! if (GET_CODE (dest) == REG
! && REGNO (dest) >= min_regno)
! REG_N_SETS (REGNO (dest))++;
/* If this is setting a pseudo from another pseudo or the sum of a
***************
*** 2120,2159 ****
on the type. */
! if (GET_CODE (SET_DEST (x)) == REG
! && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
! && REGNO (SET_DEST (x)) >= min_regno
! /* If the destination pseudo is set more than once, then other
! sets might not be to a pointer value (consider access to a
! union in two threads of control in the presense of global
! optimizations). So only set REGNO_POINTER_FLAG on the destination
! pseudo if this is the only set of that pseudo. */
! && REG_N_SETS (REGNO (SET_DEST (x))) == 1
! && ! REG_USERVAR_P (SET_DEST (x))
! && ! REGNO_POINTER_FLAG (REGNO (SET_DEST (x)))
! && ((GET_CODE (SET_SRC (x)) == REG
! && REGNO_POINTER_FLAG (REGNO (SET_SRC (x))))
! || ((GET_CODE (SET_SRC (x)) == PLUS
! || GET_CODE (SET_SRC (x)) == LO_SUM)
! && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
! && GET_CODE (XEXP (SET_SRC (x), 0)) == REG
! && REGNO_POINTER_FLAG (REGNO (XEXP (SET_SRC (x), 0))))
! || GET_CODE (SET_SRC (x)) == CONST
! || GET_CODE (SET_SRC (x)) == SYMBOL_REF
! || GET_CODE (SET_SRC (x)) == LABEL_REF
! || (GET_CODE (SET_SRC (x)) == HIGH
! && (GET_CODE (XEXP (SET_SRC (x), 0)) == CONST
! || GET_CODE (XEXP (SET_SRC (x), 0)) == SYMBOL_REF
! || GET_CODE (XEXP (SET_SRC (x), 0)) == LABEL_REF))
! || ((GET_CODE (SET_SRC (x)) == PLUS
! || GET_CODE (SET_SRC (x)) == LO_SUM)
! && (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST
! || GET_CODE (XEXP (SET_SRC (x), 1)) == SYMBOL_REF
! || GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF))
! || ((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
! && (GET_CODE (XEXP (note, 0)) == CONST
! || GET_CODE (XEXP (note, 0)) == SYMBOL_REF
! || GET_CODE (XEXP (note, 0)) == LABEL_REF))))
! REGNO_POINTER_FLAG (REGNO (SET_DEST (x))) = 1;
/* ... fall through ... */
--- 2173,2218 ----
on the type. */
! if (GET_CODE (SET_DEST (x)) == REG
! && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
! && REGNO (SET_DEST (x)) >= min_regno
! /* If the destination pseudo is set more than once, then other
! sets might not be to a pointer value (consider access to a
! union in two threads of control in the presense of global
! optimizations). So only set REGNO_POINTER_FLAG on the destination
! pseudo if this is the only set of that pseudo. */
! && REG_N_SETS (REGNO (SET_DEST (x))) == 1
! && ! REG_USERVAR_P (SET_DEST (x))
! && ! REGNO_POINTER_FLAG (REGNO (SET_DEST (x)))
! && ((GET_CODE (SET_SRC (x)) == REG
! && REGNO_POINTER_FLAG (REGNO (SET_SRC (x))))
! || ((GET_CODE (SET_SRC (x)) == PLUS
! || GET_CODE (SET_SRC (x)) == LO_SUM)
! && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
! && GET_CODE (XEXP (SET_SRC (x), 0)) == REG
! && REGNO_POINTER_FLAG (REGNO (XEXP (SET_SRC (x), 0))))
! || GET_CODE (SET_SRC (x)) == CONST
! || GET_CODE (SET_SRC (x)) == SYMBOL_REF
! || GET_CODE (SET_SRC (x)) == LABEL_REF
! || (GET_CODE (SET_SRC (x)) == HIGH
! && (GET_CODE (XEXP (SET_SRC (x), 0)) == CONST
! || GET_CODE (XEXP (SET_SRC (x), 0)) == SYMBOL_REF
! || GET_CODE (XEXP (SET_SRC (x), 0)) == LABEL_REF))
! || ((GET_CODE (SET_SRC (x)) == PLUS
! || GET_CODE (SET_SRC (x)) == LO_SUM)
! && (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST
! || GET_CODE (XEXP (SET_SRC (x), 1)) == SYMBOL_REF
! || GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF))
! || ((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
! && (GET_CODE (XEXP (note, 0)) == CONST
! || GET_CODE (XEXP (note, 0)) == SYMBOL_REF
! || GET_CODE (XEXP (note, 0)) == LABEL_REF))))
! REGNO_POINTER_FLAG (REGNO (SET_DEST (x))) = 1;
+ #ifdef __USE_FASTREGS_MULTI_X__
+ }
+ }
+ x = orig;
+ }
+ #endif
/* ... fall through ... */
Only in gcc-2.95.2-a29k/gcc: regclass.c.flc
Only in gcc-2.95.2-a29k/gcc: regclass.o
Only in gcc-2.95.2-a29k/gcc: regmove.o
Only in gcc-2.95.2-a29k/gcc: regset.c
Only in gcc-2.95.2-a29k/gcc: regset.h
Only in gcc-2.95.2-a29k/gcc: regset.h~
Only in gcc-2.95.2-a29k/gcc: reload.o
Only in gcc-2.95.2-a29k/gcc: reload1.o
Only in gcc-2.95.2-a29k/gcc: reorg.o
Only in gcc-2.95.2-a29k/gcc: resource.o
diff -C 2 gcc-2.95.2/gcc/rtl.def gcc-2.95.2-a29k/gcc/rtl.def
*** gcc-2.95.2/gcc/rtl.def Sun Jan 24 08:13:55 1999
--- gcc-2.95.2-a29k/gcc/rtl.def Sat Mar 17 09:01:29 2001
***************
*** 584,587 ****
--- 584,591 ----
in DECL_RTLs and during RTL generation, but not in the insn chain. */
DEF_RTL_EXPR(CONCAT, "concat", "ee", 'o')
+
+ /* Betto: (REGSET a b c ...) represents a virtual concatenation on many registers.
+ This is used for "register struct". */
+ DEF_RTL_EXPR(REGSET, "regset", "E", 'x')
/* A memory location; operand is the address. Can be nested inside a
Only in gcc-2.95.2-a29k/gcc: rtl.o
Only in gcc-2.95.2/gcc: rtl.texi
diff -C 2 gcc-2.95.2/gcc/rtlanal.c gcc-2.95.2-a29k/gcc/rtlanal.c
*** gcc-2.95.2/gcc/rtlanal.c Mon Apr 12 04:18:55 1999
--- gcc-2.95.2-a29k/gcc/rtlanal.c Sat Mar 17 09:01:29 2001
***************
*** 959,962 ****
--- 959,975 ----
}
else
+ //Betto: register struct
+ #ifdef __USE_REGISTER_STRUCT__
+ if (GET_CODE (x) == REGSET && GET_MODE (x) == BLKmode)
+ {
+ register int i;
+
+ /* If any register in here refers to it we return true. */
+ for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+ if (reg_overlap_mentioned_p (XVECEXP (x, 0, i), in))
+ return 1;
+ return 0;
+ } else
+ #endif
abort ();
***************
*** 1228,1231 ****
--- 1241,1254 ----
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), y);
}
+ //Betto: register struct
+ #ifdef __USE_REGISTER_STRUCT__
+ else if (GET_CODE (dest) == REGSET
+ && GET_MODE (dest) == BLKmode)
+ {
+ register int i;
+ for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+ (*fun) (XVECEXP (dest, 0, i), y);
+ }
+ #endif
else
(*fun) (dest, y);
Only in gcc-2.95.2-a29k/gcc: rtlanal.o
Only in gcc-2.95.2-a29k/gcc: s-attr
Only in gcc-2.95.2-a29k/gcc: s-attrtab
Only in gcc-2.95.2-a29k/gcc: s-check
Only in gcc-2.95.2-a29k/gcc: s-codes
Only in gcc-2.95.2-a29k/gcc: s-config
Only in gcc-2.95.2-a29k/gcc: s-emit
Only in gcc-2.95.2-a29k/gcc: s-extract
Only in gcc-2.95.2-a29k/gcc: s-flags
Only in gcc-2.95.2-a29k/gcc: s-genrtl
Only in gcc-2.95.2-a29k/gcc: s-opinit
Only in gcc-2.95.2-a29k/gcc: s-output
Only in gcc-2.95.2-a29k/gcc: s-peep
Only in gcc-2.95.2-a29k/gcc: s-recog
Only in gcc-2.95.2-a29k/gcc: sbitmap.o
Only in gcc-2.95.2-a29k/gcc: sched.o
Only in gcc-2.95.2-a29k/gcc: sdbout.o
Only in gcc-2.95.2-a29k/gcc: specs.h
Only in gcc-2.95.2-a29k/gcc: splay-tree.c
Only in gcc-2.95.2-a29k/gcc: splay-tree.o
diff -C 2 gcc-2.95.2/gcc/stmt.c gcc-2.95.2-a29k/gcc/stmt.c
*** gcc-2.95.2/gcc/stmt.c Sun May 30 15:19:44 1999
--- gcc-2.95.2-a29k/gcc/stmt.c Mon May 21 10:59:51 2001
***************
*** 3515,3518 ****
--- 3515,3562 ----
MEM_SET_IN_STRUCT_P (DECL_RTL (decl), AGGREGATE_TYPE_P (type));
}
+ //Betto: register structs
+ #ifdef __USE_REGISTER_STRUCT__
+ else if (DECL_MODE (decl) == BLKmode
+ && ! TREE_THIS_VOLATILE (decl)
+ && DECL_REGISTER (decl)
+ && TREE_CODE(TREE_TYPE(decl))==RECORD_TYPE
+ && TYPE_OK_FOR_REGSET(TREE_TYPE(decl)))
+ {
+ if (!TARGET_FAST_REGS)
+ {
+ error ("Use \"-mfast-regs\" to use \"register\" keyword with structs.");
+ }
+ else {
+ /* Automatic structs that go in registers. */
+ int unsignedp = TREE_UNSIGNED (type);
+ enum machine_mode reg_mode
+ = promote_mode (type, DECL_MODE (decl), &unsignedp, 0);
+
+ DECL_RTL (decl) = RS_rtl_of_register_struct(TREE_TYPE(decl));
+ }
+ }
+ #endif
+ //Betto: register arrays
+ #ifdef __USE_REGARRAY__
+ else if (DECL_MODE (decl) == BLKmode
+ && ! TREE_THIS_VOLATILE (decl) // could be removed
+ && DECL_REGISTER (decl)
+ && TREE_CODE(TREE_TYPE(decl))==ARRAY_TYPE
+ && TYPE_OK_FOR_REGARRAY(TREE_TYPE(decl)))
+ {
+ if (!TARGET_FAST_REGS)
+ {
+ error ("Use \"-mfast-regs\" to use \"register\" keyword with arrays.");
+ }
+ else {
+ /* Automatic structs that go in registers. */
+ int unsignedp = TREE_UNSIGNED (type);
+ enum machine_mode reg_mode
+ = promote_mode (type, DECL_MODE (decl), &unsignedp, 0);
+
+ DECL_RTL (decl) = RS_rtl_of_register_array(TREE_TYPE(decl));
+ }
+ }
+ #endif
else if (DECL_MODE (decl) != BLKmode
/* If -ffloat-store, don't put explicit float vars
Only in gcc-2.95.2-a29k/gcc: stmt.c.flc
Only in gcc-2.95.2-a29k/gcc: stmt.c~
Only in gcc-2.95.2-a29k/gcc: stmt.o
Only in gcc-2.95.2-a29k/gcc: stor-layout.o
diff -C 2 gcc-2.95.2/gcc/stupid.c gcc-2.95.2-a29k/gcc/stupid.c
*** gcc-2.95.2/gcc/stupid.c Sun Apr 25 13:43:45 1999
--- gcc-2.95.2-a29k/gcc/stupid.c Sat Mar 17 09:01:29 2001
***************
*** 609,704 ****
code = GET_CODE (x);
if (code == SET || code == CLOBBER)
{
! if (SET_DEST (x) != 0
! && (GET_CODE (SET_DEST (x)) == REG
! || (GET_CODE (SET_DEST (x)) == SUBREG
! && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
! && (REGNO (SUBREG_REG (SET_DEST (x)))
! >= FIRST_PSEUDO_REGISTER))))
{
! /* Register is being assigned. */
! /* If setting a SUBREG, we treat the entire reg as being set. */
! if (GET_CODE (SET_DEST (x)) == SUBREG)
! regno = REGNO (SUBREG_REG (SET_DEST (x)));
! else
! regno = REGNO (SET_DEST (x));
!
! /* For hard regs, update the where-live info. */
! if (regno < FIRST_PSEUDO_REGISTER)
! {
! register int j
! = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x)));
!
! while (--j >= 0)
! {
! regs_ever_live[regno+j] = 1;
! regs_live[regno+j] = 0;
!
! /* The following line is for unused outputs;
! they do get stored even though never used again. */
! MARK_LIVE_AFTER (insn, regno+j);
!
! /* When a hard reg is clobbered, mark it in use
! just before this insn, so it is live all through. */
! if (code == CLOBBER && INSN_SUID (insn) > 0)
! SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (insn) - 1],
! regno+j);
! }
! }
! /* For pseudo regs, record where born, where dead, number of
! times used, and whether live across a call. */
! else
{
! /* Update the life-interval bounds of this pseudo reg. */
!
! /* When a pseudo-reg is CLOBBERed, it is born just before
! the clobbering insn. When setting, just after. */
! int where_born = INSN_SUID (insn) - (code == CLOBBER);
!
! reg_where_born_exact[regno] = INSN_SUID (insn);
! reg_where_born_clobber[regno] = (code == CLOBBER);
!
! if (reg_where_dead_chain[regno] == 0)
! reg_where_dead_chain[regno] = chain;
!
! /* The reg must live at least one insn even
! in it is never again used--because it has to go
! in SOME hard reg. Mark it as dying after the current
! insn so that it will conflict with any other outputs of
! this insn. */
! if (reg_where_dead[regno] < where_born + 2)
! {
! reg_where_dead[regno] = where_born + 2;
! regs_live[regno] = 1;
! }
!
! /* Count the refs of this reg. */
! REG_N_REFS (regno)++;
!
! if (last_call_suid < reg_where_dead[regno])
! REG_N_CALLS_CROSSED (regno) += 1;
!
! if (last_setjmp_suid < reg_where_dead[regno])
! regs_crosses_setjmp[regno] = 1;
!
! /* If this register is clobbered or it is only used in
! this insn and is only set, mark it unused. We have
! to do this even when not optimizing so that MD patterns
! which count on this behavior (e.g., it not causing an
! output reload on an insn setting CC) will operate
! correctly. */
! if (GET_CODE (SET_DEST (x)) == REG
! && (code == CLOBBER
! || (REGNO_FIRST_UID (regno) == INSN_UID (insn)
! && REGNO_LAST_UID (regno) == INSN_UID (insn)
! && ! reg_mentioned_p (SET_DEST (x),
! SET_SRC (x)))))
! REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_UNUSED,
! SET_DEST (x),
! REG_NOTES (insn));
! }
}
!
/* Record references from the value being set,
or from addresses in the place being set if that's not a reg.
--- 609,742 ----
code = GET_CODE (x);
+ #ifdef __USE_REGISTER_STRUCT__
+ if (code == REGSET)
+ {
+ register int i;
+ for (i=0; i<XVECLEN(x, 0); i++)
+ stupid_mark_refs (XVECEXP (x, 0, i), chain);
+ return;
+ }
+ #endif
if (code == SET || code == CLOBBER)
{
! #ifdef __USE_REGISTER_STRUCT__
! if (code == SET)
{
! if (GET_CODE(SET_SRC(x)) == REGSET)
{
! stupid_mark_refs (SET_SRC(x), chain);
! }
}
! #endif
! //betto: going to loop on regstruct
! {
! int cond = (GET_CODE(SET_DEST(x)) != REGSET);
! int j = 0;
! rtx base = x;
! rtx new_rtx = cond ? 0 : gen_rtx_SET (GET_MODE(XVECEXP(SET_DEST(x) ,0,0)),
! XVECEXP(SET_DEST(x), 0, 0), SET_SRC(x));
! rtx linearized = cond ? 0 : RS_linearize_regset (SET_DEST(x));
! int lenn = cond ? 1 : XVECLEN(linearized,0);
! //base contains initial rtx
! //linearized contains linearized regset
! //new_rtx will contains the pseudo set.
! for (((x == cond) ? x : 0); (j<lenn); j++)
! {
! if (!cond)
! {
! x = gen_rtx_SET (GET_MODE(XVECEXP(linearized ,0, j)),
! XVECEXP(linearized, 0, j), SET_SRC(base));
! }
! if (SET_DEST (x) != 0
! && (GET_CODE (SET_DEST (x)) == REG
! || (GET_CODE (SET_DEST (x)) == SUBREG
! && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
! && (REGNO (SUBREG_REG (SET_DEST (x)))
! >= FIRST_PSEUDO_REGISTER))))
! {
! /* Register is being assigned. */
! /* If setting a SUBREG, we treat the entire reg as being set. */
! if (GET_CODE (SET_DEST (x)) == SUBREG)
! regno = REGNO (SUBREG_REG (SET_DEST (x)));
! else
! regno = REGNO (SET_DEST (x));
!
! /* For hard regs, update the where-live info. */
! if (regno < FIRST_PSEUDO_REGISTER)
! {
! register int j
! = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x)));
!
! while (--j >= 0)
! {
! regs_ever_live[regno+j] = 1;
! regs_live[regno+j] = 0;
!
! /* The following line is for unused outputs;
! they do get stored even though never used again. */
! MARK_LIVE_AFTER (insn, regno+j);
!
! /* When a hard reg is clobbered, mark it in use
! just before this insn, so it is live all through. */
! if (code == CLOBBER && INSN_SUID (insn) > 0)
! SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (insn) - 1],
! regno+j);
! }
! }
! /* For pseudo regs, record where born, where dead, number of
! times used, and whether live across a call. */
! else
! {
! /* Update the life-interval bounds of this pseudo reg. */
!
! /* When a pseudo-reg is CLOBBERed, it is born just before
! the clobbering insn. When setting, just after. */
! int where_born = INSN_SUID (insn) - (code == CLOBBER);
!
! reg_where_born_exact[regno] = INSN_SUID (insn);
! reg_where_born_clobber[regno] = (code == CLOBBER);
!
! if (reg_where_dead_chain[regno] == 0)
! reg_where_dead_chain[regno] = chain;
!
! /* The reg must live at least one insn even
! in it is never again used--because it has to go
! in SOME hard reg. Mark it as dying after the current
! insn so that it will conflict with any other outputs of
! this insn. */
! if (reg_where_dead[regno] < where_born + 2)
! {
! reg_where_dead[regno] = where_born + 2;
! regs_live[regno] = 1;
! }
!
! /* Count the refs of this reg. */
! REG_N_REFS (regno)++;
!
! if (last_call_suid < reg_where_dead[regno])
! REG_N_CALLS_CROSSED (regno) += 1;
!
! if (last_setjmp_suid < reg_where_dead[regno])
! regs_crosses_setjmp[regno] = 1;
!
! /* If this register is clobbered or it is only used in
! this insn and is only set, mark it unused. We have
! to do this even when not optimizing so that MD patterns
! which count on this behavior (e.g., it not causing an
! output reload on an insn setting CC) will operate
! correctly. */
! if (GET_CODE (SET_DEST (x)) == REG
! && (code == CLOBBER
! || (REGNO_FIRST_UID (regno) == INSN_UID (insn)
! && REGNO_LAST_UID (regno) == INSN_UID (insn)
! && ! reg_mentioned_p (SET_DEST (x),
! SET_SRC (x)))))
! REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_UNUSED,
! SET_DEST (x),
! REG_NOTES (insn));
! }
! }
! } // end for regstruct
! }
/* Record references from the value being set,
or from addresses in the place being set if that's not a reg.
Only in gcc-2.95.2-a29k/gcc: stupid.o
Only in gcc-2.95.2-a29k/gcc: tconfig.h
Common subdirectories: gcc-2.95.2/gcc/testsuite and gcc-2.95.2-a29k/gcc/testsuite
Only in gcc-2.95.2/gcc: texinfo.tex
Only in gcc-2.95.2-a29k/gcc: tm.h
Only in gcc-2.95.2/gcc: tm.texi
diff -C 2 gcc-2.95.2/gcc/toplev.c gcc-2.95.2-a29k/gcc/toplev.c
*** gcc-2.95.2/gcc/toplev.c Thu Oct 21 09:01:37 1999
--- gcc-2.95.2-a29k/gcc/toplev.c Sat Mar 17 09:01:29 2001
***************
*** 559,562 ****
--- 559,563 ----
faster code for sqrt to be generated. */
+ #warning "prova a mettere 1"
int flag_fast_math = 0;
Only in gcc-2.95.2-a29k/gcc: toplev.o
Only in gcc-2.95.2-a29k/gcc: tree-check.h
Only in gcc-2.95.2-a29k/gcc: tree.o
Only in gcc-2.95.2-a29k/gcc: unroll.o
Only in gcc-2.95.2-a29k/gcc: varasm.o
Only in gcc-2.95.2-a29k/gcc: varray.o
diff -C 2 gcc-2.95.2/gcc/version.c gcc-2.95.2-a29k/gcc/version.c
*** gcc-2.95.2/gcc/version.c Mon Oct 25 08:49:39 1999
--- gcc-2.95.2-a29k/gcc/version.c Sat Mar 17 09:01:29 2001
***************
*** 1 ****
! char *version_string = "2.95.2 19991024 (release)";
--- 1 ----
! char *version_string = "2.95.2 19991024 (release) with register structs";
Only in gcc-2.95.2-a29k/gcc: version.o
Only in gcc-2.95.2-a29k/gcc: xcoffout.o
Only in gcc-2.95.2-a29k/gcc/config/a29k: CVS
diff -C 2 gcc-2.95.2/gcc/config/a29k/a29k.c gcc-2.95.2-a29k/gcc/config/a29k/a29k.c
*** gcc-2.95.2/gcc/config/a29k/a29k.c Thu Jan 21 03:21:11 1999
--- gcc-2.95.2-a29k/gcc/config/a29k/a29k.c Tue Mar 27 18:09:27 2001
***************
*** 1190,1196 ****
GET_MODE (x) == SFmode ? "float" : "double0", u.d);
}
-
else
! output_addr_const (file, x);
}
--- 1190,1216 ----
GET_MODE (x) == SFmode ? "float" : "double0", u.d);
}
else
! #if defined(__USE_REGISTER_STRUCT__) || defined(__USE_REGARRAY__)
! //Betto: REGSET, register_struct,...
! if (GET_CODE (x) == REGSET)
! {
! int i;
! for (i=0; i< XVECLEN(x, 0); i++)
! {
! print_operand (file, XVECEXP(x,0,i), 0);
! if (i==XVECLEN(x,0)-1)
! break;
! fputc (' ', file);
! }
! }
! #endif
! else if (GET_CODE(x) == CONCAT)
! {
! print_operand (file, XEXP(x,0), 0);
! fputc (' ', file);
! print_operand (file, XEXP(x,1), 0);
! fputc (' ', file);
! } else
! output_addr_const (file, x);
}
***************
*** 1538,1539 ****
--- 1558,1562 ----
fprintf (file, "\tnop\n");
}
+
+ //Betto: REGSET
+ #include "regset.c"
Only in gcc-2.95.2-a29k/gcc/config/a29k: a29k.c.flc
Only in gcc-2.95.2-a29k/gcc/config/a29k: a29k.c~
diff -C 2 gcc-2.95.2/gcc/config/a29k/a29k.h gcc-2.95.2-a29k/gcc/config/a29k/a29k.h
*** gcc-2.95.2/gcc/config/a29k/a29k.h Thu Mar 25 13:54:05 1999
--- gcc-2.95.2-a29k/gcc/config/a29k/a29k.h Mon Jun 25 01:33:37 2001
***************
*** 21,24 ****
--- 21,28 ----
+ // REGSET REGARRAY register_struct Betto
+ #define MAX_REGISTERS_IN_REGSET 100
+ #include "regset.h"
+
/* Names to predefine in the preprocessor for this target machine. */
***************
*** 97,100 ****
--- 101,112 ----
#define TARGET_MULTM ((target_flags & 1024) == 0)
+ /* This means that we should use REGISTER STRUCT extensions ...
+ ... */
+
+ #define TARGET_FAST_REGS (target_flags & 2048)
+
+ #define DEBUG_FAST_REGS (target_flags & 4096)
+
+
#define TARGET_SWITCHES \
{ {"dw", 1, "Generate code assuming DW bit is set"}, \
***************
*** 117,120 ****
--- 129,134 ----
{"soft-float", 512, "Use software floating point"}, \
{"no-multm", 1024, "Do not generate multm instructions"}, \
+ {"fast-regs", 2048, "Use fast-regs extensions"}, \
+ {"debug-fast-regs", 2048, "Debug fast-regs extensions"}, \
{"", TARGET_DEFAULT, NULL}}
***************
*** 1670,1672 ****
{"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \
! {"epilogue_operand", {CODE_LABEL}},
--- 1684,1690 ----
{"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \
! {"epilogue_operand", {CODE_LABEL}}, \
! {"regset_operand", {REGSET}},
!
! // REGSET REGARRAY register_struct Betto
!
Only in gcc-2.95.2-a29k/gcc/config/a29k: a29k.h.flc
Only in gcc-2.95.2-a29k/gcc/config/a29k: a29k.h~
diff -C 2 gcc-2.95.2/gcc/config/a29k/a29k.md gcc-2.95.2-a29k/gcc/config/a29k/a29k.md
*** gcc-2.95.2/gcc/config/a29k/a29k.md Wed Dec 16 22:00:37 1998
--- gcc-2.95.2-a29k/gcc/config/a29k/a29k.md Tue Mar 27 18:09:06 2001
***************
*** 2873,2874 ****
--- 2873,2908 ----
"jmpfdec %0,%l1%#"
[(set_attr "type" "branch")])
+
+ (define_expand "movblk"
+ [(set (match_operand:BLK 0 "general_operand" "")
+ (match_operand:BLK 1 "general_operand" ""))]
+ ""
+ "{
+ if (GET_CODE(operands[0])==REGSET)
+ operands[0] = RS_linearize_regset (operands[0]);
+ if (GET_CODE(operands[1])==REGSET)
+ operands[1] = RS_linearize_regset (operands[1]);
+ }")
+
+ (define_insn "hard_movblk_to_regset"
+ [(set (match_operand:BLK 0 "regset_operand" "")
+ (match_operand:BLK 1 "memory_operand" "m"))]
+ ""
+ "burst load [%0] <-- %1")
+
+ (define_insn "hard_movblk_from_regset"
+ [(set (match_operand:BLK 0 "memory_operand" "m")
+ (match_operand:BLK 1 "regset_operand" ""))]
+ ""
+ "burst store %0 <-- [%1]")
+
+
+ ;;- Local variables:
+ ;;- mode:emacs-lisp
+ ;;- comment-start: ";;- "
+ ;;- eval: ( set-syntax-table ( copy-sequence ( syntax-table ) ) )
+ ;;- eval: ( modify-syntax-entry ?[ "(]" )
+ ;;- eval: ( modify-syntax-entry ?] ")[" )
+ ;;- eval: ( modify-syntax-entry ?{ "(}" )
+ ;;- eval: ( modify-syntax-entry ?} "){" )
+ ;;- End:
diff -C 2 -N gcc-2.95.2/gcc/regset.h gcc-2.95.2-a29k/gcc/regset.h
*** gcc-2.95.2/gcc/regset.h Thu Jan 1 01:00:00 1970
--- gcc-2.95.2-a29k/gcc/regset.h Mon Jun 25 01:42:46 2001
***************
*** 0 ****
--- 1,23 ----
+ /* Benedetto Proietti
+ Dynamic One s.a.s. di Bussotti Luciana & C.
+ 2000-2001
+
+ Register Struct
+ */
+
+ #ifndef __FAST_REGISTER_H__
+ #define __FAST_REGISTER_H__
+
+ #ifndef MAX_REGISTERS_IN_REGSET
+ #define MAX_REGISTERS_IN_REGSET (FIRST_PSEUDO_REGISTER/4)
+ #endif
+
+ #define FASTREGS_SHORT "FAST-REGS"
+
+ #define TYPE_OK_FOR_REGSET(TYPE) \
+ type_ok_for_regset(TYPE)
+
+ #define TYPE_OK_FOR_REGARRAY(TYPE) \
+ type_ok_for_regarray(TYPE)
+
+ #endif
diff -C 2 -N gcc-2.95.2/gcc/regset.c gcc-2.95.2-a29k/gcc/regset.c
*** gcc-2.95.2/gcc/regset.c Thu Jan 1 01:00:00 1970
--- gcc-2.95.2-a29k/gcc/regset.c Mon Jun 25 01:41:09 2001
***************
*** 0 ****
--- 1,276 ----
+ /* REGISTER STRUCTs
+
+ */
+
+ int type_ok_for_regset (tree type_of_rs)
+ {
+ return 1; // for now...
+ }
+
+ int type_ok_for_regarray (tree type_of_rs)
+ {
+ if (AGGREGATE_TYPE_P(TREE_TYPE(type_of_rs)))
+ return 0; // for now...
+ return 1;
+ }
+
+ rtx RS_rtl_of_register_array(tree rec)
+ {
+ int i;
+ enum machine_mode element_mode = TYPE_MODE(TREE_TYPE(rec));
+ tree temp = TYPE_DOMAIN(rec);
+ tree size = size_binop(MINUS_EXPR,
+ TYPE_MAX_VALUE(temp),
+ TYPE_MIN_VALUE(temp));
+
+ int int_size = TREE_INT_CST_LOW(size)+1;
+
+ rtx regarray = gen_rtx (REGSET, BLKmode, rtvec_alloc (int_size));
+ for (i=0; i<XVECLEN(regarray, 0); i++)
+ XVECEXP (regarray, 0, i) = gen_reg_rtx (element_mode);
+
+ return regarray;
+ }
+
+ /* Function: RS_rtl_of_register struct (tree)
+ Called by: expand_decl in stmt.c:3530
+
+ This function creates a REGSET consisting of a 'set' of REG rtl.
+ Each REG is a pseudo register. Future implementations probably will cover
+ explicit registers indications by the programmer as for standard register variables.
+
+ Note that this function is called for _each_ struct variable declared as register.
+ Infact, we _cannot_ create a REGSET just once for every structure: how could we
+ fill it with pseudo-registers?
+ */
+
+ rtx RS_rtl_of_register_struct(tree rec)
+ {
+ register tree field;
+ int nfields; //Betto: added to count fields ...
+ int curfield; //Betto: used for register struct
+ rtx regdecl_rtx; //Betto: to hold the REGSET
+
+ //Loop to count fields
+ //ehm... don't know any other simpler way of doing this, let me know if there is.
+ nfields = 0;
+ for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
+ nfields++;
+
+ //Allocate an empty vector... of rtx
+ regdecl_rtx = gen_rtx (REGSET, BLKmode, rtvec_alloc (nfields));
+ curfield = 0;
+
+ for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
+ {
+ /* For each field is created a REG (same machine mode of the field) or another
+ regset in case of nested structs. */
+ if (TYPE_MODE(TREE_TYPE(field))==BLKmode)
+ XVECEXP (regdecl_rtx, 0, curfield) = RS_rtl_of_register_struct(TREE_TYPE(field));
+ else
+ XVECEXP(regdecl_rtx, 0, curfield) = gen_reg_rtx (TYPE_MODE(TREE_TYPE(field)));
+ curfield++;
+ }
+
+ return regdecl_rtx;
+ }
+
+ #define BITSIZE_OF(X) (GET_MODE_SIZE (GET_MODE (X))*BITS_PER_UNIT)
+
+
+ static int calculate_aligned_size_of(rtx field)
+ {
+ int i, aligned_size, size;
+ if (GET_CODE(field) == REG)
+ {
+ size = BITSIZE_OF(field);
+ aligned_size = size; // ???? how to do ???
+ return aligned_size;
+ }
+ if (GET_CODE(field) == REGSET)
+ {
+ for (i=0; i<XVECLEN(field, 0); i++)
+ {
+ size += calculate_aligned_size_of(XVECEXP(field, 0, i));
+ }
+ return size;
+ }
+ fatal ("RS internal error: expected REG or REGSET in calculate_aligned_size_of().");
+ }
+
+ static rtx deep_visit_(rtx field, int *pbitpos, int bitsize)
+ {
+ rtx reg, last_reg; int i;
+
+ if (GET_CODE(field) == REG)
+ {
+ int size = BITSIZE_OF(field);
+ int aligned_size = size; // ??? how to do ???
+ if (*pbitpos == 0)
+ { // found!!
+ return field;
+ }
+ *pbitpos -= aligned_size;
+ return 0;
+ }
+ if (GET_CODE(field) == REGSET)
+ {
+ for (i=0; i<XVECLEN(field, 0); i++)
+ {
+ reg = deep_visit_(XVECEXP(field, 0 , i), pbitpos, bitsize);
+ if (*pbitpos <= 0)
+ {
+ if (reg == 0) //prossima foglia e' giusta.
+ continue;
+ if (*pbitpos<0)
+ error("RS: possible bug in inside_register_struct (bitpos<0).");
+ else // *pbitpos == 0
+ {
+ int cursize = calculate_aligned_size_of(reg);
+ if (cursize > bitsize)
+ {
+ if (GET_MODE(reg) != SCmode | bitsize!=BITS_PER_WORD)
+ fatal ("RS: register struct error.");
+ return gen_rtx_SUBREG(SFmode, reg, 0);
+ }
+ if (cursize == bitsize) // finally found
+ return reg;
+
+ //cursize < bitsize
+ if (i != 0) // non prima foglia
+ {
+ error ("RS: different sizes in inside_register_struct (2).");
+ return (rtx)-1;
+ }
+ //prima foglia, ritorniamo il padre
+ return field;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ /* Function RS_inside_register_struct
+
+ */
+
+ rtx RS_inside_register_struct(rtx target, int bitpos, int bitsize)
+ {
+ int _bitpos = bitpos;
+ rtx reg;
+
+ //fprintf (stderr, "inside register struct\n");
+ //print_rtl (stderr, target);
+ //fprintf (stderr, "\nlooking for object at bipos = %d\n", bitpos);
+
+ reg = deep_visit_(target, &_bitpos, bitsize);
+
+ if (_bitpos != 0)
+ warning ("RS: deep_visit_ did not work properly.");
+
+ #ifdef DEBUG_REGISTER_STRUCT
+ if (DEBUG_REGISTER_STRUCT)
+ {
+ if (_bitpos!=0 || (GET_CODE(reg) != REG && GET_CODE(reg)!=REGSET
+ && GET_CODE(reg) != SUBREG))
+ {
+ print_rtl(stderr, reg);
+ fprintf(stderr, "\n%d\n", _bitpos);
+ }
+ }
+ #endif
+ return reg;
+ }
+
+ static rtx _regstruct_linearized_;
+ static int _next_free_;
+
+ #define ADD_REGISTER(rs,r,j) XVECEXP (r, 0, j) = r;
+
+ static void RS_linearize_regset_internal (rtx elem)
+ {
+ int i;
+
+ if (GET_CODE(elem) == REG)
+ {
+ //ADD_REGISTER(_regstruct_linearized, elem, _next_free_++);
+ XVECEXP (_regstruct_linearized_, 0, _next_free_++) = elem;
+ if (_next_free_ > MAX_REGISTERS_IN_REGSET)
+ error ("RS: max register number (%d) exceeded in RS_linearize_regset",
+ MAX_REGISTERS_IN_REGSET);
+ return;
+ }
+ if (GET_CODE(elem) == REGSET)
+ {
+ for (i=0; i < XVECLEN(elem, 0); i++)
+ RS_linearize_regset_internal (XVECEXP(elem, 0, i));
+ }
+ }
+
+ rtx RS_linearize_regset (rtx elem)
+ {
+ _regstruct_linearized_ = gen_rtx (REGSET, BLKmode, rtvec_alloc (MAX_REGISTERS_IN_REGSET));
+ _next_free_ = 0;
+ RS_linearize_regset_internal (elem);
+ XVECLEN(_regstruct_linearized_,0) = _next_free_;
+ return (_regstruct_linearized_);
+ }
+
+ #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
+
+ int RS_sizeof_regset (rtx op)
+ {
+ rtx temp; int i, size=0;
+ if (GET_CODE(op) != REGSET)
+ abort();
+ temp = RS_linearize_regset(op);
+ for (i=0; i<XVECLEN(temp, 0); i++)
+ size += SIZE_FOR_MODE(XVECEXP(temp, 0, i));
+ return size;
+ }
+
+ int regset_operand (register rtx op, enum machine_mode mode)
+ {
+ register int i;
+ if (GET_CODE(op)!=REGSET)
+ return 0;
+
+ for (i=0; i<XVECLEN (op, 0); i++)
+ if (GET_CODE( XVECEXP (op, 0, i)) != REG)
+ return 0;
+ return 1;
+ }
+
+ void RS_normalize_regset (register rtx op)
+ {
+ int i;
+ op = RS_linearize_regset (op);
+ for (i=0; i<XVECLEN (op, 0); i++)
+ {
+ /* if (GET_CODE (XVECEXP (op, 0, i)) == REGSET)
+ RS_normalize_regset_operand (op);
+ else */
+ if (GET_CODE (XVECEXP (op, 0, i)) == SUBREG)
+ fprintf (stderr, "RS: SUBREG in regset.\n"); // SUBREG ok for now...
+ else if (GET_CODE (XVECEXP (op, 0, i)) != REG)
+ XVECEXP (op, 0, i) = force_reg (GET_MODE(XVECEXP (op, 0, i)), XVECEXP(op, 0, i));
+ }
+ }
+
+ #define HANDLE_PRAGMA(GETC,UNGETC,NAME) \
+ handle_pragma(GETC,UNGETC,NAME)
+
+
+ int handle_pragma(int (*__getc)(), int (*__ungetc)(), char * name)
+ {
+ fprintf (stderr, "%s\n");
+ if (strcmp(name, "for") == 0)
+ {
+ while ((*__getc)() != '\n') ;
+ return 1;
+ }
+ return 0;
+ }
+
+ #define HANDLE_GENERIC_PRAGMAS
tar xvfz gcc-2.95.2.tar.gz
cd gcc-2.95.2
patch -p1 < ../regset.1.patch
./configure --target=a29k
make -C libiberty CFLAGS="-O2" libiberty.a
cd gcc
make cc1 CFLAGS="-O2 -D__USE_FASTREGS_MULTI_X__=1 -D__USE_REGISTER_STRUCT__=1 -D__USE_REGARRAY__=1 "
make cpp CFLAGS="-D__USE_FASTREGS_MULTI_X__=1 -D__USE_REGISTER_STRUCT__=1 -D__USE_REGARRAY__=1 "
#do not compile cpp with -O2!!! (there's a bug...)