This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Midlevel RTL part 1
- From: Jan Hubicka <jh at suse dot cz>
- To: rth at cygnus dot com, patches at x86-64 dot org, gcc-patches at gcc dot gnu dot org, gcc-pdo at atrey dot karlin dot mff dot cuni dot cz
- Date: Mon, 21 Jan 2002 20:19:03 +0100
- Subject: Midlevel RTL part 1
Hi
I've bootstrapped and installed teh attached patch to cfg-branch.
* Makefile.in (md_file): Add dependancy on midrtl.md.
* emit-rtl.c (try_split): Avoid recursive splitting in
RTL lowering process; avoid abort on badly updated probability
notes for now.
* function.c (prepare_function_start): RTL form is initiallly
RTL_FORM_MID.
* function.h (struct function): Add rtl_form.
* genrecog.c (pred_table): Add generic operands.
* gensupport.c (init_md_reader): Implicitly inlucde midrtl.md
file.
* optabs.c (prepare_generic_operand): New function.
(expand_binop, expand_unop, emit_cmp_and_jump_insns):
Generate midlevel RTL.
* recog.c (generic_address, generic_src_operand, generic_dest_operand):
New functions.
* recog.h (generic_address, generic_src_operand, generic_dest_operand):
Declare.
* toplev.c (rest_of_compilation): Do RTL lowering.
* i386.c (ix86_expand_int_movcc): Do not crash on DImode comparisons.
* midrtl.md: New file.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.775.2.19
diff -c -3 -p -r1.775.2.19 Makefile.in
*** Makefile.in 2002/01/18 23:23:53 1.775.2.19
--- Makefile.in 2002/01/21 19:09:37
*************** xmake_file=@dep_host_xmake_file@
*** 252,258 ****
tmake_file=@dep_tmake_file@
out_file=$(srcdir)/config/@out_file@
out_object_file=@out_object_file@
! md_file=$(srcdir)/config/@md_file@
tm_p_file_list=@tm_p_file_list@
tm_p_file=@tm_p_file@
build_xm_file_list=@build_xm_file_list@
--- 252,258 ----
tmake_file=@dep_tmake_file@
out_file=$(srcdir)/config/@out_file@
out_object_file=@out_object_file@
! md_file=$(srcdir)/config/@md_file@ $(srcdir)/midrtl.md
tm_p_file_list=@tm_p_file_list@
tm_p_file=@tm_p_file@
build_xm_file_list=@build_xm_file_list@
Index: caller-save.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/caller-save.c,v
retrieving revision 1.47.2.2
diff -c -3 -p -r1.47.2.2 caller-save.c
*** caller-save.c 2002/01/07 14:50:18 1.47.2.2
--- caller-save.c 2002/01/21 19:09:37
*************** init_caller_save ()
*** 115,121 ****
--- 115,124 ----
rtx address;
int i, j;
enum machine_mode mode;
+ enum rtl_form old = cfun->rtl_form;
+ cfun->rtl_form = RTL_FORM_LOW;
+
/* First find all the registers that we need to deal with and all
the modes that they can have. If we can't find a mode to use,
we can't have the register live over calls. */
*************** init_caller_save ()
*** 234,239 ****
--- 237,243 ----
}
end_sequence ();
+ cfun->rtl_form = old;
}
/* Initialize save areas by showing that we haven't allocated any yet. */
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.223.2.8
diff -c -3 -p -r1.223.2.8 emit-rtl.c
*** emit-rtl.c 2002/01/17 14:34:00 1.223.2.8
--- emit-rtl.c 2002/01/21 19:09:38
*************** try_split (pat, trial, last)
*** 3003,3011 ****
/* We can preserve the REG_BR_PROB notes only if exactly
one jump is created, otherwise the machine description
is responsible for this step using
! split_branch_probability variable. */
if (njumps != 1)
abort ();
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB,
GEN_INT (probability),
--- 3003,3017 ----
/* We can preserve the REG_BR_PROB notes only if exactly
one jump is created, otherwise the machine description
is responsible for this step using
! split_branch_probability variable.
!
! MIDlevel RTL lowering process create this from time to time.
! Lets give up this condition for now.
! */
! #if 0
if (njumps != 1)
abort ();
+ #endif
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB,
GEN_INT (probability),
*************** try_split (pat, trial, last)
*** 3089,3106 ****
set LAST and continue from the insn after the one returned.
We can't use next_active_insn here since AFTER may be a note.
Ignore deleted insns, which can be occur if not optimizing. */
! for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
! if (! INSN_DELETED_P (tem) && INSN_P (tem))
! tem = try_split (PATTERN (tem), tem, 1);
}
/* Avoid infinite loop if the result matches the original pattern. */
else if (rtx_equal_p (seq, pat))
return trial;
! else
{
PATTERN (trial) = seq;
INSN_CODE (trial) = -1;
! try_split (seq, trial, last);
}
/* Return either the first or the last insn, depending on which was
--- 3095,3115 ----
set LAST and continue from the insn after the one returned.
We can't use next_active_insn here since AFTER may be a note.
Ignore deleted insns, which can be occur if not optimizing. */
! if (cfun->rtl_form != RTL_FORM_MIDLOW)
! for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
! if (! INSN_DELETED_P (tem) && INSN_P (tem))
! tem = try_split (PATTERN (tem), tem, 1);
}
/* Avoid infinite loop if the result matches the original pattern. */
else if (rtx_equal_p (seq, pat))
return trial;
! else
{
PATTERN (trial) = seq;
INSN_CODE (trial) = -1;
! /* Avoid recursive splitting during RTL lowering process. */
! if (cfun->rtl_form != RTL_FORM_MIDLOW)
! try_split (seq, trial, last);
}
/* Return either the first or the last insn, depending on which was
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.322.2.6
diff -c -3 -p -r1.322.2.6 function.c
*** function.c 2002/01/07 14:50:47 1.322.2.6
--- function.c 2002/01/21 19:09:40
*************** prepare_function_start ()
*** 6133,6138 ****
--- 6133,6140 ----
cfun->stack_alignment_needed = STACK_BOUNDARY;
cfun->preferred_stack_boundary = STACK_BOUNDARY;
+ cfun->rtl_form = RTL_FORM_MID;
+
/* Set if a call to setjmp is seen. */
current_function_calls_setjmp = 0;
Index: function.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.h,v
retrieving revision 1.71.2.4
diff -c -3 -p -r1.71.2.4 function.h
*** function.h 2002/01/07 14:50:47 1.71.2.4
--- function.h 2002/01/21 19:09:40
*************** struct function
*** 487,492 ****
--- 487,505 ----
FUNCTION_FREQUENCY_HOT,
FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
} function_frequency;
+
+ /* Record current form of RTL during at current compilation phase.
+ The order is reverse of how lowering happens, so comparisons works. */
+ enum rtl_form {
+ /* The lowlevel RTL form - each insn corresponds to pattern in machine
+ description. */
+ RTL_FORM_LOW,
+ /* Code lowering is in the progress - the generic patterns are being split
+ to lowlevel instructions. */
+ RTL_FORM_MIDLOW,
+ /* Majority of insns are well formed generic patterns. */
+ RTL_FORM_MID
+ } rtl_form;
};
/* The function currently being compiled. */
Index: genconstants.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genconstants.c,v
retrieving revision 1.2.8.1
diff -c -3 -p -r1.2.8.1 genconstants.c
*** genconstants.c 2001/12/14 23:08:15 1.2.8.1
--- genconstants.c 2002/01/21 19:09:42
*************** main (argc, argv)
*** 63,69 ****
if (argc <= 1)
fatal ("no input file name");
! if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
/* Scan and discard the entire file. This has the side effect
--- 63,69 ----
if (argc <= 1)
fatal ("no input file name");
! if (init_md_reader (argv[1], argv[2]) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
/* Scan and discard the entire file. This has the side effect
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genrecog.c,v
retrieving revision 1.111.2.4
diff -c -3 -p -r1.111.2.4 genrecog.c
*** genrecog.c 2002/01/07 14:50:51 1.111.2.4
--- genrecog.c 2002/01/21 19:09:43
*************** static const struct pred_table
*** 186,191 ****
--- 186,199 ----
const char *const name;
const RTX_CODE codes[NUM_RTX_CODE];
} preds[] = {
+ {"generic_src_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
+ VEC_CONST, LABEL_REF, SUBREG, REG, MEM}},
+ {"generic_dest_operand", {SUBREG, REG, MEM}},
+ {"generic_unary_operator", {NEG, NOT, ABS, SQRT, FFS}},
+ {"generic_binary_operator", {SS_PLUS, SS_MINUS, US_PLUS, US_MINUS,
+ PLUS, MINUS, DIV, MOD, UDIV, UMOD, ASHIFT,
+ ASHIFTRT, LSHIFTRT, MULT, AND, IOR, XOR,
+ SMIN, SMAX, UMIN, UMAX}},
{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG, MEM}},
#ifdef PREDICATE_CODES
*************** static const char *const special_mode_pr
*** 220,226 ****
#ifdef SPECIAL_MODE_PREDICATES
SPECIAL_MODE_PREDICATES
#endif
! "pmode_register_operand"
};
#define NUM_SPECIAL_MODE_PREDS ARRAY_SIZE (special_mode_pred_table)
--- 228,236 ----
#ifdef SPECIAL_MODE_PREDICATES
SPECIAL_MODE_PREDICATES
#endif
! "pmode_register_operand",
! "generic_src_operand",
! "generic_dest_operand"
};
#define NUM_SPECIAL_MODE_PREDS ARRAY_SIZE (special_mode_pred_table)
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gensupport.c,v
retrieving revision 1.23.2.2
diff -c -3 -p -r1.23.2.2 gensupport.c
*** gensupport.c 2001/12/14 23:08:18 1.23.2.2
--- gensupport.c 2002/01/21 19:09:43
*************** init_md_reader_args (argc, argv)
*** 958,973 ****
char **argv;
{
int i;
! const char *in_fname;
max_include_len = 0;
in_fname = NULL;
for (i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
{
if (in_fname == NULL)
in_fname = argv[i];
}
else
{
--- 958,976 ----
char **argv;
{
int i;
! const char *in_fname, *mid_fname;
max_include_len = 0;
in_fname = NULL;
+ mid_fname = NULL;
for (i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
{
if (in_fname == NULL)
in_fname = argv[i];
+ else if (mid_fname == NULL)
+ mid_fname = argv[i];
}
else
{
*************** init_md_reader_args (argc, argv)
*** 1002,1015 ****
}
}
}
! return init_md_reader (in_fname);
}
/* The entry point for initializing the reader. */
int
! init_md_reader (filename)
! const char *filename;
{
FILE *input_file;
int c;
--- 1005,1018 ----
}
}
}
! return init_md_reader (in_fname, mid_fname);
}
/* The entry point for initializing the reader. */
int
! init_md_reader (filename, midfilename)
! const char *filename, *midfilename;
{
FILE *input_file;
int c;
*************** init_md_reader (filename)
*** 1033,1038 ****
--- 1036,1045 ----
obstack_init (rtl_obstack);
errors = 0;
sequence_num = 0;
+
+ /* Read the midlevel RTL description first. */
+ if (init_include_reader (fopen (midfilename, "r")) == FATAL_EXIT_CODE)
+ errors = 1;
/* Read the entire file. */
while (1)
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gensupport.h,v
retrieving revision 1.3.8.1
diff -c -3 -p -r1.3.8.1 gensupport.h
*** gensupport.h 2001/11/22 16:04:38 1.3.8.1
--- gensupport.h 2002/01/21 19:09:43
*************** struct obstack;
*** 22,28 ****
extern struct obstack *rtl_obstack;
extern int init_md_reader_args PARAMS ((int, char **));
! extern int init_md_reader PARAMS ((const char *));
extern rtx read_md_rtx PARAMS ((int *, int *));
extern void message_with_line PARAMS ((int, const char *, ...))
--- 22,28 ----
extern struct obstack *rtl_obstack;
extern int init_md_reader_args PARAMS ((int, char **));
! extern int init_md_reader PARAMS ((const char *, const char *));
extern rtx read_md_rtx PARAMS ((int *, int *));
extern void message_with_line PARAMS ((int, const char *, ...))
Index: midrtl.md
===================================================================
RCS file: midrtl.md
diff -N midrtl.md
*** /dev/null Tue May 5 13:32:27 1998
--- midrtl.md Mon Jan 21 11:09:43 2002
***************
*** 0 ****
--- 1,114 ----
+ ;; GCC midlevel RTL description
+ ;; Copyright (C) 2002 Free Software Foundation, Inc.
+ ;; Contributed by Jan Hubicka
+ ;;
+ ;; This file is part of GNU CC.
+ ;;
+ ;; GNU CC is free software; you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation; either version 2, or (at your option)
+ ;; any later version.
+ ;;
+ ;; GNU CC is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ;; GNU General Public License for more details.
+ ;;
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU CC; see the file COPYING. If not, write to
+ ;; the Free Software Foundation, 59 Temple Place - Suite 330,
+ ;; Boston, MA 02111-1307, USA.
+
+ (define_insn_and_split "_generic_move"
+ [(set (match_operand 0 "generic_dest_operand" "")
+ (match_operand 1 "generic_src_operand" ""))]
+ "cfun->rtl_form >= RTL_FORM_MID"
+ "#"
+ "cfun->rtl_form == RTL_FORM_MIDLOW"
+ [(const_int 0)]
+ {
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+ })
+
+ (define_insn_and_split "generic_unary_operation"
+ [(set (match_operand 0 "generic_dest_operand" "")
+ (match_operator 2 "generic_unary_operator"
+ [(match_operand 1 "generic_src_operand" "")]))]
+ "cfun->rtl_form >= RTL_FORM_MID"
+ "#"
+ "cfun->rtl_form == RTL_FORM_MIDLOW"
+ [(const_int 0)]
+ {
+ rtx res;
+ res = expand_simple_unop (GET_MODE (operands[0]), GET_CODE (operands[2]),
+ operands[1], operands[0], 1);
+ if (!res)
+ abort ();
+ if (res != operands[0])
+ emit_move_insn (operands[0], res);
+ DONE;
+ })
+
+ (define_insn_and_split "_generic_binary_operation"
+ [(set (match_operand 0 "generic_dest_operand" "")
+ (match_operator 3 "generic_binary_operator"
+ [(match_operand 1 "generic_src_operand" "")
+ (match_operand 2 "generic_src_operand" "")]))]
+ "cfun->rtl_form >= RTL_FORM_MID"
+ "#"
+ "cfun->rtl_form == RTL_FORM_MIDLOW"
+ [(const_int 0)]
+ {
+ rtx res;
+
+ res = expand_generic_binop (GET_CODE (operands[3]), operands[1],
+ operands[2], operands[0]);
+ if (!res)
+ abort ();
+ if (res != operands[0])
+ emit_move_insn (operands[0], res);
+ DONE;
+ })
+
+ (define_insn_and_split "_generic_simplejump"
+ [(set (pc) (label_ref (match_operand 0 "" "")))]
+ "cfun->rtl_form >= RTL_FORM_MID"
+ "#"
+ "cfun->rtl_form == RTL_FORM_MIDLOW"
+ [(const_int 0)]
+ {
+ emit_insn (gen_jump (operands[0]));
+ DONE;
+ })
+
+ (define_insn_and_split "_generic_indirectjump"
+ [(set (pc) (match_operand 0 "generic_src_operand" ""))]
+ "cfun->rtl_form >= RTL_FORM_MID"
+ "#"
+ "cfun->rtl_form == RTL_FORM_MIDLOW"
+ [(const_int 0)]
+ {
+ emit_insn (gen_indirect_jump (operands[0]));
+ DONE;
+ })
+
+ (define_insn_and_split "_generic_condjump"
+ [(set (pc)
+ (if_then_else (match_operator 3 "comparison_operator"
+ [(match_operand 0 "generic_src_operand" "")
+ (match_operand 1 "generic_src_operand" "")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "cfun->rtl_form >= RTL_FORM_MID && GET_MODE (operands[0]) != VOIDmode"
+ "#"
+ "cfun->rtl_form == RTL_FORM_MIDLOW"
+ [(const_int 0)]
+ {
+ emit_cmp_and_jump_insns (operands[0], operands[1], GET_CODE (operands[3]),
+ NULL_RTX, GET_MODE (operands[0]),
+ unsigned_condition (GET_CODE (operands[3]))
+ == GET_CODE (operands[3]),
+ operands[2]);
+ DONE;
+ })
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/optabs.c,v
retrieving revision 1.116.2.5
diff -c -3 -p -r1.116.2.5 optabs.c
*** optabs.c 2002/01/14 21:18:01 1.116.2.5
--- optabs.c 2002/01/21 19:09:44
*************** static void emit_cmp_and_jump_insn_1 PAR
*** 118,123 ****
--- 118,124 ----
enum rtx_code, int, rtx));
static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
enum machine_mode *, int *));
+ static rtx prepare_generic_operand PARAMS ((rtx, enum machine_mode, int));
/* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
the result of operation CODE applied to OP0 (and OP1 if it is a binary
*************** expand_simple_binop (mode, code, op0, op
*** 621,626 ****
--- 622,665 ----
return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
}
+
+ rtx
+ expand_generic_binop (code, op0, op1, target)
+ enum rtx_code code;
+ rtx op0, op1;
+ rtx target;
+ {
+ enum machine_mode mode = GET_MODE (target);
+ switch (code)
+ {
+ case MULT:
+ return expand_mult (mode, op0, op1, target, 1);
+ break;
+ case DIV:
+ if (!INTEGRAL_MODE_P (mode))
+ return expand_simple_binop (mode, code, op0, op1, target,
+ 1, OPTAB_LIB_WIDEN);
+ else
+ return expand_divmod (0,
+ FLOAT_MODE_P (mode)
+ ? RDIV_EXPR : TRUNC_DIV_EXPR, mode,
+ op0, op1, target, 0);
+ break;
+ case MOD:
+ return expand_divmod (1, TRUNC_MOD_EXPR, mode, op0, op1, target, 0);
+ break;
+ case UDIV:
+ return expand_divmod (0, TRUNC_DIV_EXPR, mode, op0, op1, target, 1);
+ break;
+ case UMOD:
+ return expand_divmod (1, TRUNC_MOD_EXPR, mode, op0, op1, target, 1);
+ break;
+ default:
+ return expand_simple_binop (mode, code, op0, op1, target,
+ 1, OPTAB_LIB_WIDEN);
+ break;
+ }
+ }
/* Generate code to perform an operation specified by BINOPTAB
on operands OP0 and OP1, with result having machine-mode MODE.
*************** expand_binop (mode, binoptab, op0, op1,
*** 717,722 ****
--- 756,777 ----
}
}
+ if (cfun->rtl_form >= RTL_FORM_MID && binoptab->code != UNKNOWN
+ && !COMPLEX_MODE_P (GET_MODE_CLASS (mode))
+ && binoptab->code != ROTATE && binoptab->code != ROTATERT
+ && binoptab->code != SMIN && binoptab->code != SMAX
+ && binoptab->code != UMIN && binoptab->code != UMAX)
+ {
+ if (!target)
+ target = gen_reg_rtx (mode);
+ op0 = prepare_generic_operand (op0, mode, 1);
+ op1 = prepare_generic_operand (op1, shift_op ? QImode : mode, 1);
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_fmt_ee (binoptab->code, mode,
+ op0, op1)));
+ return target;
+ }
+
/* If we can do it with a three-operand insn, do so. */
if (methods != OPTAB_MUST_WIDEN
*************** expand_unop (mode, unoptab, op0, target,
*** 2090,2095 ****
--- 2145,2162 ----
if (target)
target = protect_from_queue (target, 1);
+ if (cfun->rtl_form >= RTL_FORM_MID && unoptab->code != UNKNOWN
+ && !COMPLEX_MODE_P (GET_MODE_CLASS (mode))
+ && unoptab->code != ABS)
+ {
+ if (!target)
+ target = gen_reg_rtx (mode);
+ op0 = prepare_generic_operand (op0, mode, 1);
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_fmt_e (unoptab->code, mode, op0)));
+ return target;
+ }
+
if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
int icode = (int) unoptab->handlers[(int) mode].insn_code;
*************** prepare_operand (icode, x, opnum, mode,
*** 3243,3248 ****
--- 3310,3330 ----
return x;
}
+ static rtx
+ prepare_generic_operand (x, mode, unsignedp)
+ rtx x;
+ enum machine_mode mode;
+ int unsignedp;
+ {
+ x = protect_from_queue (x, 0);
+ x = force_not_mem (x);
+
+ if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode)
+ x = convert_modes (mode, GET_MODE (x), x, unsignedp);
+
+ return x;
+ }
+
/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
we can do the comparison.
The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
*************** emit_cmp_and_jump_insns (x, y, compariso
*** 3365,3370 ****
--- 3447,3468 ----
emit_queue ();
if (unsignedp)
comparison = unsigned_condition (comparison);
+
+ if (cfun->rtl_form >= RTL_FORM_MID && mode != BLKmode && label
+ && !COMPLEX_MODE_P (GET_MODE_CLASS (mode)))
+ {
+ op0 = prepare_generic_operand (op0, mode, unsignedp);
+ op1 = prepare_generic_operand (op1, mode, unsignedp);
+ if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
+ op0 = force_reg (mode, op0);
+ emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode,
+ gen_rtx_fmt_ee (comparison, VOIDmode,
+ op0, op1),
+ gen_rtx_LABEL_REF (VOIDmode, label),
+ pc_rtx)));
+ return;
+ }
prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
ccp_jump);
Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.133.2.3
diff -c -3 -p -r1.133.2.3 recog.c
*** recog.c 2002/01/16 18:19:59 1.133.2.3
--- recog.c 2002/01/21 19:09:45
*************** peephole2_optimize (dump_file)
*** 3220,3222 ****
--- 3220,3431 ----
#endif
}
#endif /* HAVE_peephole2 */
+
+ int
+ generic_address (op)
+ rtx op;
+ {
+ #if 0
+ rtx offset = NULL, base = NULL, index = NULL, mult = NULL;
+
+ switch (GET_CODE (op))
+ {
+ case REG:
+ base = op;
+ break;
+ case PLUS:
+ if (CONSTANT_P (XEXP (op, 1)))
+ {
+ offset = XEXP (op, 1);
+ op = XEXP (op, 0);
+ if (GET_CODE (op) == MULT)
+ goto mult;
+ base = op;
+ }
+ else
+ {
+ base = XEXP (op, 1);
+ op = XEXP (op, 0);
+ if (REG_P (op))
+ index = op;
+ else if (GET_CODE (op) == MULT)
+ goto mult;
+ else
+ return 0;
+ }
+ break;
+ case MULT:
+ mult:
+ index = XEXP (mult, 0);
+ mult = XEXP (mult, 1);
+ break;
+ default:
+ offset = op;
+ }
+ if (offset)
+ switch (GET_CODE (offset))
+ {
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_INT:
+ case CONST_DOUBLE:
+ break;
+ default:
+ return 0;
+ }
+ if (base && (!REG_P (base) || GET_MODE (base) != Pmode))
+ return 0;
+ if (index && (!REG_P (index) || GET_MODE (index) != Pmode))
+ return 0;
+ if (mult && GET_CODE (mult) != CONST_INT)
+ return 0;
+ return 1;
+ #endif
+ return address_operand (op, VOIDmode);
+ }
+
+ int
+ generic_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+ {
+ enum machine_mode op_mode = GET_MODE (op);
+ enum rtx_code code = GET_CODE (op);
+
+ if (mode != VOIDmode && op_mode != VOIDmode && mode != op_mode)
+ return 0;
+ if (mode == VOIDmode && op_mode != VOIDmode)
+ switch (GET_MODE_CLASS (op_mode))
+ {
+ case MODE_INT:
+ case MODE_FLOAT:
+ /* Does not work yet due to partial lowering done by codegen. */
+ #if 0
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ #endif
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ break;
+ default:
+ return 0;
+ }
+ switch (code)
+ {
+ /* Accept constants. */
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST:
+ case CONSTANT_P_RTX:
+ case VEC_CONST:
+ /* Accept registers. */
+ case ADDRESSOF:
+ case REG:
+ return 1;
+ /* Accept memory. */
+ case MEM:
+ return generic_address (XEXP (op, 0));
+ /* Accept subreg of register. */
+ case SUBREG:
+ return (REG_P (SUBREG_REG (op)));
+ default:
+ return 0;
+ }
+ }
+ int
+ generic_dest_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+ {
+ enum machine_mode op_mode = GET_MODE (op);
+ enum rtx_code code = GET_CODE (op);
+
+ if (mode != VOIDmode && op_mode != VOIDmode && mode != op_mode)
+ return 0;
+ if (mode == VOIDmode && op_mode != VOIDmode)
+ switch (GET_MODE_CLASS (op_mode))
+ {
+ case MODE_INT:
+ case MODE_FLOAT:
+ /* Does not work yet due to partial lowering done by codegen. */
+ #if 0
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ #endif
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ break;
+ default:
+ return 0;
+ }
+ switch (code)
+ {
+ /* Accept registers. */
+ case REG:
+ return 1;
+ /* Accept memory. */
+ case MEM:
+ return generic_address (XEXP (op, 0));
+ /* Accept subreg of register. */
+ case SUBREG:
+ return (REG_P (SUBREG_REG (op)));
+ default:
+ return 0;
+ }
+ }
+
+ int
+ generic_unary_operator (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+ switch (GET_CODE (op))
+ {
+ case NEG:
+ case NOT:
+ case ABS:
+ case SQRT:
+ case FFS:
+ return 1;
+ default:
+ return 0;
+ }
+ return 0;
+ }
+
+ int
+ generic_binary_operator (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+ switch (GET_CODE (op))
+ {
+ case SS_PLUS:
+ case SS_MINUS:
+ case US_PLUS:
+ case US_MINUS:
+ case PLUS:
+ case MINUS:
+ case DIV:
+ case MOD:
+ case UDIV:
+ case UMOD:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case MULT:
+ case AND:
+ case IOR:
+ case XOR:
+ case SMIN:
+ case SMAX:
+ case UMIN:
+ case UMAX:
+ return 1;
+ default:
+ return 0;
+ }
+ }
Index: recog.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.h,v
retrieving revision 1.41
diff -c -3 -p -r1.41 recog.h
*** recog.h 2001/10/07 16:50:52 1.41
--- recog.h 2002/01/21 19:09:45
*************** extern int reg_fits_class_p PARAMS ((rt
*** 96,101 ****
--- 96,105 ----
enum machine_mode));
extern rtx *find_single_use PARAMS ((rtx, rtx, rtx *));
+ extern int generic_address PARAMS ((rtx));
+
+ extern int generic_src_operand PARAMS ((rtx, enum machine_mode));
+ extern int generic_dest_operand PARAMS ((rtx, enum machine_mode));
extern int general_operand PARAMS ((rtx, enum machine_mode));
extern int address_operand PARAMS ((rtx, enum machine_mode));
extern int register_operand PARAMS ((rtx, enum machine_mode));
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.537.2.35
diff -c -3 -p -r1.537.2.35 toplev.c
*** toplev.c 2002/01/19 20:53:44 1.537.2.35
--- toplev.c 2002/01/21 19:09:47
*************** rest_of_compilation (decl)
*** 3080,3085 ****
--- 3080,3101 ----
}
#endif
+ /* Lower into lowlevel RTL now. */
+ cfun->rtl_form = RTL_FORM_MIDLOW;
+ {
+ rtx insn;
+ int old_defer = flag_defer_pop;
+
+ flag_defer_pop = 0;
+ split_all_insns (0);
+ flag_defer_pop = old_defer;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ INSN_CODE (insn) = -1;
+ }
+ reg_scan (insns, max_reg_num (), 0);
+ cfun->rtl_form = RTL_FORM_LOW;
+
if (optimize > 0)
{
timevar_push (TV_CSE2);
*************** lang_independent_init ()
*** 5154,5159 ****
--- 5170,5176 ----
{
decl_printable_name = decl_name;
lang_expand_expr = (lang_expand_expr_t) do_abort;
+
/* Set the language-dependent identifier size. */
tree_code_length[(int) IDENTIFIER_NODE]
Index: unroll.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/unroll.c,v
retrieving revision 1.144.2.7
diff -c -3 -p -r1.144.2.7 unroll.c
*** unroll.c 2002/01/14 21:18:05 1.144.2.7
--- unroll.c 2002/01/21 19:09:49
*************** unroll_loop (loop, insn_count, strength_
*** 930,935 ****
--- 930,946 ----
start_sequence ();
+ /* Final value may have form of (PLUS val1 const1_rtx). We need
+ to convert it into general operand, so compute the real value. */
+
+ if (GET_CODE (final_value) == PLUS)
+ {
+ final_value = expand_simple_binop (mode, PLUS,
+ copy_rtx (XEXP (final_value, 0)),
+ copy_rtx (XEXP (final_value, 1)),
+ NULL_RTX, 0, OPTAB_LIB_WIDEN);
+ }
+
/* Calculate the difference between the final and initial values.
Final value may be a (plus (reg x) (const_int 1)) rtx.
Let the following cse pass simplify this if initial value is
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.353.2.2
diff -c -3 -p -r1.353.2.2 i386.c
*** i386.c 2002/01/14 21:18:22 1.353.2.2
--- i386.c 2002/01/21 19:09:54
*************** ix86_expand_int_movcc (operands)
*** 7871,7876 ****
--- 7871,7879 ----
ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
}
+ if (GET_MODE (ix86_compare_op0) == DImode && !TARGET_64BIT)
+ return 0;
+
start_sequence ();
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
compare_seq = gen_sequence ();
*************** ix86_expand_int_movcc (operands)
*** 8030,8035 ****
--- 8033,8040 ----
out = emit_store_flag (out, code, ix86_compare_op0,
ix86_compare_op1, VOIDmode, 0, 1);
+ if (!out)
+ return 0;
nops = 0;
/* On x86_64 the lea instruction operates on Pmode, so we need to get arithmetics
*************** ix86_expand_int_movcc (operands)
*** 8119,8124 ****
--- 8124,8131 ----
out = emit_store_flag (out, code, ix86_compare_op0,
ix86_compare_op1, VOIDmode, 0, 1);
+ if (!out)
+ return 0;
out = expand_simple_binop (mode, PLUS,
out, constm1_rtx,
*************** ix86_expand_fp_movcc (operands)
*** 8344,8349 ****
--- 8351,8360 ----
return 1;
}
+ /* We can't easilly compare DImode operands. */
+ if (GET_MODE (ix86_compare_op0) == DImode && !TARGET_64BIT)
+ return 0;
+
/* The floating point conditional move instructions don't directly
support conditions resulting from a signed integer comparison. */
*************** x86_initialize_trampoline (tramp, fnaddr
*** 10662,10670 ****
if (!TARGET_64BIT)
{
/* Compute offset from the end of the jmp to the target function. */
! rtx disp = expand_binop (SImode, sub_optab, fnaddr,
! plus_constant (tramp, 10),
NULL_RTX, 1, OPTAB_DIRECT);
emit_move_insn (gen_rtx_MEM (QImode, tramp),
GEN_INT (trunc_int_for_mode (0xb9, QImode)));
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);
--- 10673,10683 ----
if (!TARGET_64BIT)
{
/* Compute offset from the end of the jmp to the target function. */
! rtx disp = expand_binop (SImode, add_optab, tramp, GEN_INT (10),
NULL_RTX, 1, OPTAB_DIRECT);
+ disp = expand_binop (SImode, sub_optab, fnaddr,
+ disp,
+ NULL_RTX, 1, OPTAB_DIRECT);
emit_move_insn (gen_rtx_MEM (QImode, tramp),
GEN_INT (trunc_int_for_mode (0xb9, QImode)));
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);