@@ -89,6 +89,7 @@ gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in gcc/config/c6x/genmult
gcc/config/m68k/m68k-tables.opt: gcc/config/m68k/m68k-devices.def gcc/config/m68k/m68k-isas.def gcc/config/m68k/m68k-microarchs.def gcc/config/m68k/genopt.sh
gcc/config/mips/mips-tables.opt: gcc/config/mips/mips-cpus.def gcc/config/mips/genopt.sh
gcc/config/rs6000/rs6000-tables.opt: gcc/config/rs6000/rs6000-cpus.def gcc/config/rs6000/genopt.sh
+gcc/config/rs6000/integer.md: gcc/config/rs6000/integer.mdm gcc/config/rs6000/mdm.pl
gcc/config/tilegx/mul-tables.c: gcc/config/tilepro/gen-mul-tables.cc
gcc/config/tilepro/mul-tables.c: gcc/config/tilepro/gen-mul-tables.cc
# And then, language-specific files
new file mode 100644
@@ -0,0 +1,145 @@
+; Generated by mdm.pl; do not edit (edit the .mdm instead).
+; vi:ro
+
+
+; Copyright (C) 1990-2013 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC 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 3, or (at your
+; option) any later version.
+;
+; GCC 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 GCC; see the file COPYING3. If not see
+; <http://www.gnu.org/licenses/>.
+
+
+; This file describes the integer (GPR-to-GPR) PowerPC instructions.
+; Most of these have record-form ("dot") variants, and are described
+; using define_dot_insn.
+
+
+; -- Rotate and shift instructions:
+; rlwinm[.], rlwnm[.], rldicl[.], rldicr[.], rldic[.], rldcl[.], rldcr[.]
+; rlwimi[.], rldimi[.]
+; slw[.], srw[.], srawi[.], sraw[.], sld[.], srd[.], sradi[.], srad[.]
+
+
+(define_insn "lshrdi3"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
+ "TARGET_POWERPC64"
+ "@
+ srd %0,%1,%2
+ srdi %0,%1,%H2"
+ [(set_attr "type" "var_shift_rotate,shift")])
+
+(define_insn "*lshrdi3_dot"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+ (compare:CC
+ (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+ (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=r,r,r,r"))]
+ "(TARGET_POWERPC64)
+ && (DImode == Pmode && rs6000_gen_cell_microcode)"
+ "@
+ srd. %0,%1,%2
+ srdi. %0,%1,%H2
+ #
+ #"
+ [(set_attr "length" "4,4,8,8")
+ (set_attr "dot" "yes,yes,no,no")
+ (set_attr "type" "var_shift_rotate,shift,var_shift_rotate,shift")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC
+ (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "reg_or_cint_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 ""))]
+ "((TARGET_POWERPC64)
+ && (DImode == Pmode && rs6000_gen_cell_microcode))
+ && (reload_completed)"
+ [(set (match_dup 0)
+ (lshiftrt:DI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
+
+(define_insn "*lshrdi3_dot2"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+ (compare:CC
+ (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+ (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
+ (lshiftrt:DI (match_dup 1)
+ (match_dup 2)))]
+ "(TARGET_POWERPC64)
+ && (DImode == Pmode && rs6000_gen_cell_microcode)"
+ "@
+ srd. %0,%1,%2
+ srdi. %0,%1,%H2
+ #
+ #"
+ [(set_attr "length" "4,4,8,8")
+ (set_attr "dot" "yes,yes,no,no")
+ (set_attr "type" "var_shift_rotate,shift,var_shift_rotate,shift")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC
+ (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "reg_or_cint_operand" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "")
+ (lshiftrt:DI (match_dup 1)
+ (match_dup 2)))]
+ "((TARGET_POWERPC64)
+ && (DImode == Pmode && rs6000_gen_cell_microcode))
+ && (reload_completed)"
+ [(set (match_dup 0)
+ (lshiftrt:DI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
+
+
+; -- Logical instructions:
+; andi., andis., ori, oris, xori, xoris
+; and[.], or[.], xor[.], nand[.], nor[.], eqv[.], andc[.], orc[.]
+; extsb[.], extsh[.], extsw[.], cntlzw[.], cntlzd[.]
+
+
+; -- Arithmetic instructions:
+; addi, addis, add[.], subf[.], neg[.]
+; addic[.], subfic, addc[.], subfc[.]
+; adde[.], subfe[.], addme[.], subfme[.], addze[.], subfze[.]
+; mulli, mullw[.], mulhw[.], mulhwu[.], mulld[.], mulhd[.], mulhdu[.]
+; divw[.], divwu[.], divd[.], divdu[.]
+
+
+; -- Compare instructions:
+; cmpwi, cmpdi, cmpw, cmpd, cmplwi, cmpldi, cmplw, cmpld
+
+
+; -- Trap instructions:
+; twi, tw, tdi, td
+
+
+; -- System register instructions:
+; mtcrf, mfcr, mtocrf, mfocrf
new file mode 100644
@@ -0,0 +1,66 @@
+; Copyright (C) 1990-2013 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC 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 3, or (at your
+; option) any later version.
+;
+; GCC 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 GCC; see the file COPYING3. If not see
+; <http://www.gnu.org/licenses/>.
+
+
+; This file describes the integer (GPR-to-GPR) PowerPC instructions.
+; Most of these have record-form ("dot") variants, and are described
+; using define_dot_insn.
+
+
+; -- Rotate and shift instructions:
+; rlwinm[.], rlwnm[.], rldicl[.], rldicr[.], rldic[.], rldcl[.], rldcr[.]
+; rlwimi[.], rldimi[.]
+; slw[.], srw[.], srawi[.], sraw[.], sld[.], srd[.], sradi[.], srad[.]
+
+
+(define_dot_insn "lshrdi3"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
+ "TARGET_POWERPC64"
+ "DImode == Pmode && rs6000_gen_cell_microcode"
+ "@
+ srd %0,%1,%2
+ srdi %0,%1,%H2"
+ [(set_attr "type" "var_shift_rotate,shift")])
+
+
+; -- Logical instructions:
+; andi., andis., ori, oris, xori, xoris
+; and[.], or[.], xor[.], nand[.], nor[.], eqv[.], andc[.], orc[.]
+; extsb[.], extsh[.], extsw[.], cntlzw[.], cntlzd[.]
+
+
+; -- Arithmetic instructions:
+; addi, addis, add[.], subf[.], neg[.]
+; addic[.], subfic, addc[.], subfc[.]
+; adde[.], subfe[.], addme[.], subfme[.], addze[.], subfze[.]
+; mulli, mullw[.], mulhw[.], mulhwu[.], mulld[.], mulhd[.], mulhdu[.]
+; divw[.], divwu[.], divd[.], divdu[.]
+
+
+; -- Compare instructions:
+; cmpwi, cmpdi, cmpw, cmpd, cmplwi, cmpldi, cmplw, cmpld
+
+
+; -- Trap instructions:
+; twi, tw, tdi, td
+
+
+; -- System register instructions:
+; mtcrf, mfcr, mtocrf, mfocrf
new file mode 100755
@@ -0,0 +1,470 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC 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 3, or (at your
+# option) any later version.
+#
+# GCC 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+
+# Pre-process a machine description file as text. Preserve whitespace and
+# comments as much as possible.
+#
+# Currently this just expands "define_dot_insn" constructs into three
+# "define_insn"s and two "define_split"s, which handle integer PowerPC
+# record form instructions.
+
+
+use v5.14; # Needed for /r; otherwise, v5.10 for (?-1).
+use strict;
+use warnings;
+use re "/s"; # Newlines are not usually significant in MD files.
+
+
+# Interpolate arrays into strings without spaces between the elements.
+$" = "";
+
+
+my $ws = qr/
+ (?>
+ \s # whitespace char
+ | ;.*?\n # lisp comment
+ | \/\*.*?\*\/ # C comment
+ )+
+ /x;
+
+my $string = qr/
+ (?>
+ "
+ (?: \\. | [^\"] )*
+ "
+ )
+ /x;
+
+my $block = qr/
+ ((?>
+ \{
+ (?: [^{}]++ | (?-1) )*+
+ \}
+ ))
+ /x;
+
+# An "atom" is any RTL construct, followed by optional whitespace.
+my $atom = qr/
+ ((?>
+ \( $ws?+ (?: (?-1) )++ \)
+ | \[ $ws?+ (?: (?-1) )++ \]
+ | [-:<>\w]++
+ | $string
+ | $block
+ )$ws?+)
+ /x;
+
+
+# Split an atom into something that matches $head, a list of atoms, and
+# finally something that matches $tail. No error checking is done or
+# needed, that's the callers' job.
+sub decompose {
+ my ($x, $head, $tail) = @_;
+ $x =~ /^(\Q$head\E$ws?+)/g;
+ $head = $1;
+
+ my @body;
+ my $last = pos $x;
+ while ($x =~ /\G($atom)/g) {
+ push @body, $1;
+ $last = pos $x;
+ }
+ pos $x = $last;
+
+ $x =~ /\G(\Q$tail\E$ws?+)/g;
+ $tail = $1;
+
+ return ($head, @body, $tail);
+}
+
+# Merge two conditions (double-quoted pieces of C code) into one.
+sub join_cond {
+ my ($c1, $c2) = @_;
+
+ return $c1 if $c2 =~ /^""/;
+ return $c2 if $c1 =~ /^""/;
+
+ $c1 =~ s/^"([^"]*).*/"\($1\)\n /;
+ $c2 =~ s/^"([^"]*)"/ && \($1\)"/;
+
+ return "$c1$c2";
+}
+
+# Double a constraint, e.g. "=r,i" becomes "=r,i,r,i".
+sub double_constraint {
+ my $x = shift;
+ return $x =~ s/(\w[^"]*)/$1,$1/r;
+}
+
+# Double all constraints in an atom.
+sub double_constraints {
+ my $pattern = shift;
+
+ if ($pattern =~ /^\(match_operand\b/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ $body[3] = double_constraint $body[3];
+ return "$head@body";
+ }
+
+ if ($pattern =~ /^\(match_scratch\b/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ $body[2] = double_constraint $body[2];
+ return "$head@body";
+ }
+
+ if ($pattern =~ /^[([]/) {
+ my $first = substr $pattern, 0, 1;
+ my $last = ($first eq "(") ? ")" : "]";
+ my ($head, @body) = decompose $pattern, $first, $last;
+ my $tail = pop @body;
+
+ @body = map { double_constraints($_) } @body;
+
+ return "$head@body$tail";
+ }
+
+ return $pattern;
+}
+
+# Remove a constraint, e.g. "=r,i" becomes "".
+sub remove_constraint {
+ my $x = shift;
+ return $x =~ s/"[^"]*/"/r;
+}
+
+# Remove all constraints in an atom.
+sub remove_constraints {
+ my $pattern = shift;
+
+ if ($pattern =~ /^\(match_operand\b/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ $body[3] = remove_constraint $body[3];
+ return "$head@body";
+ }
+
+ if ($pattern =~ /^\(match_scratch\b/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ $body[2] = remove_constraint $body[2];
+ return "$head@body";
+ }
+
+ if ($pattern =~ /^[([]/) {
+ my $first = substr $pattern, 0, 1;
+ my $last = ($first eq "(") ? ")" : "]";
+ my ($head, @body) = decompose $pattern, $first, $last;
+ my $tail = pop @body;
+
+ @body = map { remove_constraints($_) } @body;
+
+ return "$head@body$tail";
+ }
+
+ return $pattern;
+}
+
+# Change all "match_operand" and "match_scratch" to the equally numbered
+# "match_dup" construct.
+sub make_match_dups {
+ my $pattern = shift;
+
+ if ($pattern =~ /^\(match_(?:operand|scratch)\b/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ my $tail = pop @body;
+ $body[1] =~ /(\d+)/;
+ return "${head}match_dup $1$tail";
+ }
+
+ if ($pattern =~ /^[([]/) {
+ my $first = substr $pattern, 0, 1;
+ my $last = ($first eq "(") ? ")" : "]";
+ my ($head, @body) = decompose $pattern, $first, $last;
+ my $tail = pop @body;
+
+ @body = map { make_match_dups($_) } @body;
+
+ return "$head@body$tail";
+ }
+
+ return $pattern;
+}
+
+# Find out the highest operand number used in a "match_<anything>".
+sub max_op {
+ my $pattern = shift;
+
+ if ($pattern =~ /^\(match_/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ return $body[1];
+ }
+
+ if ($pattern =~ /^[([]/) {
+ my $first = substr $pattern, 0, 1;
+ my $last = ($first eq "(") ? ")" : "]";
+ my ($head, @body) = decompose $pattern, $first, $last;
+ pop @body;
+
+ my $max = -1;
+ for (@body) {
+ my $x = max_op($_);
+ $max = $x if $x > $max;
+ }
+ return $max;
+ }
+
+ return -1;
+}
+
+# Find out the number of alternatives in this insn pattern.
+sub num_alts {
+ my $pattern = shift;
+
+ if ($pattern =~ /^\(match_operand/) {
+ my ($head, @body) = decompose $pattern, "(", ")";
+ $body[3] =~ /"([^"]*)"/;
+ return 1 + $1 =~ tr/,//;
+ }
+
+ if ($pattern =~ /^[([]/) {
+ my $first = substr $pattern, 0, 1;
+ my $last = ($first eq "(") ? ")" : "]";
+ my ($head, @body) = decompose $pattern, $first, $last;
+ pop @body;
+
+ my $max = 1;
+ for (@body) {
+ my $x = num_alts($_);
+ $max = $x if $x > $max;
+ }
+ return $max;
+ }
+
+ return 1;
+}
+
+# Make the various new patterns used in the two "define_insn"s and the
+# two "define_split"s we manufacture: a "dot" pattern for the "compare
+# the result of the insn to zero, and clobber" version; a "dot2" pattern
+# for the "compare and set" version; and a "split" pattern for the result
+# of the splitters.
+#
+# If the original pattern is a parallel, the set of the GPR that the dot
+# compare uses has to be first.
+sub make_dotpatterns {
+ my ($pattern, $n_ops, $n_alts) = @_;
+
+ my ($head, @body) = decompose $pattern, "[", "]";
+ my $tail = pop @body;
+
+ my $first = shift @body;
+ my ($ihead, @ibody) = decompose $first, "(", ")";
+ my $itail = pop @ibody;
+ die "$ARGV: insn not a valid SET in define_dot_insn pattern: $pattern\n"
+ if $ibody[0] !~ /^set\b/ or scalar @ibody != 3;
+ my ($set, $dst, $src) = @ibody;
+
+ my $compare = "(compare:CC\n\t$src\n\t(const_int 0))";
+ $compare = double_constraints $compare;
+ my $constraint = (",x" x $n_alts) . (",?y" x $n_alts);
+ $constraint =~ s/^,/=/;
+
+ my $set_cc = "$set(match_operand:CC $n_ops " .
+ qq/"cc_reg_operand" "$constraint")\n /;
+
+ my @double_body = map { double_constraints $_ } @body;
+
+ my $dotset = "(clobber $dst" =~ s/\).*/))/r =~ s/operand/scratch/r;
+ $dotset =~ s/"[^"]*"$ws//;
+ $dotset = double_constraints $dotset;
+ my $dotpat = "$head$ihead$set_cc$compare)";
+ $dotpat .= "\n @double_body" if scalar @body;
+ $dotpat .= "\n $dotset$tail";
+
+ my $src_dup = make_match_dups $src;
+ my $dot2set = double_constraints "$ihead$set$dst$src_dup$itail";
+ my $dot2pat = "$head$ihead$set_cc$compare)\n $dot2set";
+ $dot2pat .= "@double_body" if scalar @body;
+ $dot2pat .= $tail;
+
+ my @dup_body = map { make_match_dups $_ } @body;
+
+ my $dup = make_match_dups $first;
+ my @dd = decompose $dup, "(", ")";
+ $dd[2] =~ s/\).*/)/;
+ my $comp = "(set (match_dup $n_ops)\n\t" .
+ "(compare:CC $dd[2]\n\t\t " .
+ "(const_int 0)))";
+ my $splitpat = "$dup";
+ $splitpat = "(parallel [\n $splitpat@dup_body])" if (scalar @body);
+ $splitpat = "$head$splitpat\n $comp$tail";
+
+ return ($dotpat, $dot2pat, $splitpat);
+}
+
+# Construct an output template suitable for the dot instructions: change
+# the mnemonics to include the ".", and add "#" alternatives for the split.
+sub make_dottemplate {
+ my ($template, $n_alts) = @_;
+
+ die "$ARGV: template not a string: $template\n" if $template !~ /^"/;
+
+ $template =~ s/^"(?:\s*@\s*)?//;
+ $template =~ s/(^\s*+\S++)/$1./mg;
+ my $hashes = "\n #" x $n_alts;
+ $template =~ s/"/$hashes"/;
+ return qq/"@\n $template/;
+}
+
+# Change a set_attr with multiple alternatives to have those alternatives
+# twice, that is, for the split versions as well.
+sub make_dotattr {
+ my $attr = shift;
+
+ die "$ARGV: syntax error in attr: $attr\n" if $attr !~ /^\(/;
+
+ my ($head, @body) = decompose $attr, "(", ")";
+
+ $body[2] =~ s/"([^"]*)"/"$1,$1"/
+ if $body[0] =~ /^set_attr\b/
+ and $body[2] =~ /,/;
+
+ return "$head@body";
+}
+
+# Make an attribute vector for a dot insn: double all existing attributes,
+# add a "length" attribute, add a "dot" attribute.
+#
+# This currently only supports single insns in the pattern.
+sub make_dotattrs {
+ my ($attrs, $n_alts) = @_;
+
+ $attrs ||= "[]";
+
+ my ($head, @body) = decompose $attrs, "[", "]";
+ my $tail = pop @body;
+
+ @body = map { make_dotattr($_) } @body;
+
+ my $length_attr = (",4" x $n_alts) . (",8" x $n_alts);
+ $length_attr =~ s/^,//;
+ $length_attr = qq/(set_attr "length" "$length_attr")\n /;
+
+ my $dot_attr = (",yes" x $n_alts) . (",no" x $n_alts);
+ $dot_attr =~ s/^,//;
+ $dot_attr = qq/(set_attr "dot" "$dot_attr")/;
+ $dot_attr .= "\n " unless $attrs eq "[]";
+
+ return "$head$length_attr$dot_attr@body$tail";
+}
+
+# Split a "define_dot_insn" into the appropriate three "define_insn"s and
+# two "define_split"s.
+sub handle_define_dot_insn {
+ my $x = shift;
+ my ($head, @body) = decompose $x, "(", ")";
+ my $tail = pop @body;
+
+ # TODO: check the atom types of @body here? This script might
+ # die a fiery death if the input file gets it wrong.
+
+ my $define_dot_insn = shift @body;
+ my $name = shift @body;
+ my $pattern = shift @body;
+ my $cond = shift @body;
+ my $dotcond = shift @body;
+ my $template = shift @body;
+ my $attrs = shift @body;
+
+ my $n_ops = 1 + max_op $pattern;
+ my $n_alts = num_alts $pattern;
+
+ my $define_insn = $define_dot_insn =~ s/dot_//r;
+ my $define_split = $name =~ s/^"[^"]*"/define_split/r;
+
+ my $name1 = $name =~ s/^"\*?([^"]*)/"*$1_dot/r;
+ my $name2 = $name =~ s/^"\*?([^"]*)/"*$1_dot2/r;
+
+ my ($dotpat, $dot2pat, $splittedpat) =
+ make_dotpatterns $pattern, $n_ops, $n_alts;
+
+ $dotcond = join_cond $cond, $dotcond;
+
+ my $dottemplate = make_dottemplate $template, $n_alts;
+
+ my $dotattrs = make_dotattrs $attrs, $n_alts;
+
+ my $splitpat = remove_constraints $dotpat;
+ my $split2pat = remove_constraints $dot2pat;
+ $splitpat =~ s/cc_reg/cc_reg_not_cr0/;
+ $split2pat =~ s/cc_reg/cc_reg_not_cr0/;
+
+ my $splitcond = join_cond $dotcond, qq/"reload_completed"\n /;
+
+ my $prep = qq/""/;
+
+ if (not defined $attrs) {
+ $attrs = "";
+ $dottemplate .= "\n ";
+ }
+
+ print $head;
+ print $define_insn, $name, $pattern, $cond, $template, $attrs;
+ print ")\n\n(";
+ print $define_insn, $name1, $dotpat, $dotcond, $dottemplate, $dotattrs;
+ print ")\n\n(";
+ print $define_split, $splitpat, $splitcond, $splittedpat, $prep;
+ print ")\n\n(";
+ print $define_insn, $name2, $dot2pat, $dotcond, $dottemplate, $dotattrs;
+ print ")\n\n(";
+ print $define_split, $split2pat, $splitcond, $splittedpat, $prep;
+ print $tail;
+}
+
+sub handle_other {
+ print @_;
+}
+
+
+# Slurp the whole input file.
+my $mdm;
+{
+ local $/;
+ $mdm = <>;
+}
+
+print "; Generated by mdm.pl; do not edit (edit the .mdm instead).\n";
+print "; vi:ro\n\n\n";
+
+# Handle leading whitespace.
+$mdm =~ /^($ws?+)/g;
+print $1;
+
+# Finally, handle the rest.
+while ($mdm =~ /\G($atom|(?>.))/g) {
+ my $x = $1;
+
+ $x =~ /^\((\w+)/ or die "$ARGV: bad toplevel construct:\n$x\n";
+
+ if ($1 eq "define_dot_insn") {
+ handle_define_dot_insn $x;
+ } else {
+ handle_other $x;
+ }
+}
@@ -149,6 +149,9 @@ (define_c_enum "unspecv"
(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto"
(const_string "integer"))
+;; Is this instruction a "dot" (record) instruction or not?
+(define_attr "dot" "no,yes" (const_string "no"))
+
;; Define floating point instruction sub-types for use with Xfpu.md
(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
@@ -361,6 +364,8 @@ (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
(DF "TARGET_DOUBLE_FLOAT")])
+(include "integer.md")
+
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
@@ -7671,83 +7676,6 @@ (define_split
(const_int 0)))]
"")
-(define_expand "lshrdi3"
- [(set (match_operand:DI 0 "gpc_reg_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "reg_or_cint_operand" "")))]
- "TARGET_POWERPC64"
- "")
-
-(define_insn "*lshrdi3_internal1"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
- (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
- (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
- "TARGET_POWERPC64"
- "@
- srd %0,%1,%2
- srdi %0,%1,%H2"
- [(set_attr "type" "var_shift_rotate,shift")])
-
-(define_insn "*lshrdi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
- (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
- (const_int 0)))
- (clobber (match_scratch:DI 3 "=r,r,r,r"))]
- "TARGET_64BIT "
- "@
- srd. %3,%1,%2
- srdi. %3,%1,%H2
- #
- #"
- [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
- (set_attr "length" "4,4,8,8")])
-
-(define_split
- [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
- (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "reg_or_cint_operand" ""))
- (const_int 0)))
- (clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
- [(set (match_dup 3)
- (lshiftrt:DI (match_dup 1) (match_dup 2)))
- (set (match_dup 0)
- (compare:CC (match_dup 3)
- (const_int 0)))]
- "")
-
-(define_insn "*lshrdi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
- (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
- (const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
- (lshiftrt:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT"
- "@
- srd. %0,%1,%2
- srdi. %0,%1,%H2
- #
- #"
- [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
- (set_attr "length" "4,4,8,8")])
-
-(define_split
- [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
- (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "reg_or_cint_operand" ""))
- (const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "")
- (lshiftrt:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
- [(set (match_dup 0)
- (lshiftrt:DI (match_dup 1) (match_dup 2)))
- (set (match_dup 3)
- (compare:CC (match_dup 0)
- (const_int 0)))]
- "")
-
(define_expand "ashrdi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -65,6 +65,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \
$(srcdir)/config/rs6000/a2.md \
$(srcdir)/config/rs6000/predicates.md \
$(srcdir)/config/rs6000/constraints.md \
+ $(srcdir)/config/rs6000/integer.md \
$(srcdir)/config/rs6000/darwin.md \
$(srcdir)/config/rs6000/sync.md \
$(srcdir)/config/rs6000/vector.md \
@@ -74,3 +75,8 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \
$(srcdir)/config/rs6000/spe.md \
$(srcdir)/config/rs6000/dfp.md \
$(srcdir)/config/rs6000/paired.md
+
+MDM := $(srcdir)/config/rs6000/mdm.pl
+
+$(srcdir)/config/rs6000/%.md: $(srcdir)/config/rs6000/%.mdm $(MDM)
+ $(MDM) $< > $@ || (rm $@ ; exit 1)