Home | History | Annotate | Line # | Download | only in arm
      1   1.1  mrg (* Auto-generate ARM ldm/stm patterns
      2  1.10  mrg    Copyright (C) 2010-2022 Free Software Foundation, Inc.
      3   1.1  mrg    Contributed by CodeSourcery.
      4   1.1  mrg 
      5   1.1  mrg    This file is part of GCC.
      6   1.1  mrg 
      7   1.1  mrg    GCC is free software; you can redistribute it and/or modify it under
      8   1.1  mrg    the terms of the GNU General Public License as published by the Free
      9   1.1  mrg    Software Foundation; either version 3, or (at your option) any later
     10   1.1  mrg    version.
     11   1.1  mrg 
     12   1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13   1.1  mrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14   1.1  mrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15   1.1  mrg    for more details.
     16   1.1  mrg 
     17   1.1  mrg    You should have received a copy of the GNU General Public License
     18   1.1  mrg    along with GCC; see the file COPYING3.  If not see
     19   1.1  mrg    <http://www.gnu.org/licenses/>.
     20   1.1  mrg 
     21   1.1  mrg    This is an O'Caml program.  The O'Caml compiler is available from:
     22   1.1  mrg 
     23   1.1  mrg      http://caml.inria.fr/
     24   1.1  mrg 
     25   1.1  mrg    Or from your favourite OS's friendly packaging system. Tested with version
     26   1.1  mrg    3.09.2, though other versions will probably work too.
     27   1.1  mrg 
     28   1.1  mrg    Run with:
     29   1.1  mrg      ocaml arm-ldmstm.ml >/path/to/gcc/config/arm/ldmstm.md
     30   1.1  mrg *)
     31   1.1  mrg 
     32   1.1  mrg type amode = IA | IB | DA | DB
     33   1.1  mrg 
     34   1.1  mrg type optype = IN | OUT | INOUT
     35   1.1  mrg 
     36   1.4  mrg let rec string_of_addrmode addrmode thumb update =
     37   1.4  mrg   if thumb || update
     38   1.4  mrg then
     39   1.1  mrg   match addrmode with
     40   1.4  mrg     IA -> "ia"
     41   1.4  mrg   | IB -> "ib"
     42   1.4  mrg   | DA -> "da"
     43   1.4  mrg   | DB -> "db"
     44   1.4  mrg else
     45   1.4  mrg   match addrmode with
     46   1.4  mrg     IA -> ""
     47   1.4  mrg   | IB -> "ib"
     48   1.4  mrg   | DA -> "da"
     49   1.4  mrg   | DB -> "db"
     50   1.1  mrg 
     51   1.1  mrg let rec initial_offset addrmode nregs =
     52   1.1  mrg   match addrmode with
     53   1.1  mrg     IA -> 0
     54   1.1  mrg   | IB -> 4
     55   1.1  mrg   | DA -> -4 * nregs + 4
     56   1.1  mrg   | DB -> -4 * nregs
     57   1.1  mrg 
     58   1.1  mrg let rec final_offset addrmode nregs =
     59   1.1  mrg   match addrmode with
     60   1.1  mrg     IA -> nregs * 4
     61   1.1  mrg   | IB -> nregs * 4
     62   1.1  mrg   | DA -> -4 * nregs
     63   1.1  mrg   | DB -> -4 * nregs
     64   1.1  mrg 
     65   1.1  mrg let constr thumb =
     66   1.1  mrg   if thumb then "l" else "rk"
     67   1.1  mrg 
     68   1.1  mrg let inout_constr op_type =
     69   1.1  mrg   match op_type with
     70   1.1  mrg   OUT -> "=&"
     71   1.1  mrg   | INOUT -> "+&"
     72   1.1  mrg   | IN -> ""
     73   1.1  mrg 
     74   1.1  mrg let destreg nregs first op_type thumb =
     75   1.1  mrg   if not first then
     76   1.1  mrg     Printf.sprintf "(match_dup %d)" (nregs + 1)
     77   1.1  mrg   else
     78   1.1  mrg     Printf.sprintf ("(match_operand:SI %d \"s_register_operand\" \"%s%s\")")
     79   1.1  mrg       (nregs + 1) (inout_constr op_type) (constr thumb)
     80   1.1  mrg 
     81   1.1  mrg let reg_predicate thumb =
     82   1.1  mrg   if thumb then "low_register_operand" else "arm_hard_general_register_operand"
     83   1.1  mrg 
     84   1.1  mrg let write_ldm_set thumb nregs offset opnr first =
     85   1.1  mrg   let indent = "     " in
     86   1.1  mrg   Printf.printf "%s" (if first then "    [" else indent);
     87   1.1  mrg   Printf.printf "(set (match_operand:SI %d \"%s\" \"\")\n" opnr (reg_predicate thumb);
     88   1.1  mrg   Printf.printf "%s     (mem:SI " indent;
     89   1.1  mrg   begin if offset != 0 then Printf.printf "(plus:SI " end;
     90   1.1  mrg   Printf.printf "%s" (destreg nregs first IN thumb);
     91   1.1  mrg   begin if offset != 0 then Printf.printf "\n%s             (const_int %d))" indent offset end;
     92   1.1  mrg   Printf.printf "))"
     93   1.1  mrg 
     94   1.1  mrg let write_stm_set thumb nregs offset opnr first =
     95   1.1  mrg   let indent = "     " in
     96   1.1  mrg   Printf.printf "%s" (if first then "    [" else indent);
     97   1.1  mrg   Printf.printf "(set (mem:SI ";
     98   1.1  mrg   begin if offset != 0 then Printf.printf "(plus:SI " end;
     99   1.1  mrg   Printf.printf "%s" (destreg nregs first IN thumb);
    100   1.1  mrg   begin if offset != 0 then Printf.printf " (const_int %d))" offset end;
    101   1.1  mrg   Printf.printf ")\n%s     (match_operand:SI %d \"%s\" \"\"))" indent opnr (reg_predicate thumb)
    102   1.1  mrg 
    103   1.1  mrg let write_ldm_peep_set extra_indent nregs opnr first =
    104   1.1  mrg   let indent = "   " ^ extra_indent in
    105   1.1  mrg   Printf.printf "%s" (if first then extra_indent ^ "  [" else indent);
    106   1.1  mrg   Printf.printf "(set (match_operand:SI %d \"s_register_operand\" \"\")\n" opnr;
    107   1.1  mrg   Printf.printf "%s     (match_operand:SI %d \"memory_operand\" \"\"))" indent (nregs + opnr)
    108   1.1  mrg 
    109   1.1  mrg let write_stm_peep_set extra_indent nregs opnr first =
    110   1.1  mrg   let indent = "   " ^ extra_indent in
    111   1.1  mrg   Printf.printf "%s" (if first then extra_indent ^ "  [" else indent);
    112   1.1  mrg   Printf.printf "(set (match_operand:SI %d \"memory_operand\" \"\")\n" (nregs + opnr);
    113   1.1  mrg   Printf.printf "%s     (match_operand:SI %d \"s_register_operand\" \"\"))" indent opnr
    114   1.1  mrg 
    115   1.1  mrg let write_any_load optype nregs opnr first =
    116   1.1  mrg   let indent = "   " in
    117   1.1  mrg   Printf.printf "%s" (if first then "  [" else indent);
    118   1.1  mrg   Printf.printf "(set (match_operand:SI %d \"s_register_operand\" \"\")\n" opnr;
    119   1.1  mrg   Printf.printf "%s     (match_operand:SI %d \"%s\" \"\"))" indent (nregs * 2 + opnr) optype
    120   1.1  mrg 
    121   1.1  mrg let write_const_store nregs opnr first =
    122   1.1  mrg   let indent = "   " in
    123   1.1  mrg   Printf.printf "%s(set (match_operand:SI %d \"memory_operand\" \"\")\n" indent (nregs + opnr);
    124   1.1  mrg   Printf.printf "%s     (match_dup %d))" indent opnr
    125   1.1  mrg 
    126   1.1  mrg let write_const_stm_peep_set nregs opnr first =
    127   1.1  mrg   write_any_load "const_int_operand" nregs opnr first;
    128   1.1  mrg   Printf.printf "\n";
    129   1.1  mrg   write_const_store nregs opnr false
    130   1.1  mrg 
    131   1.1  mrg   
    132   1.1  mrg let rec write_pat_sets func opnr offset first n_left =
    133   1.1  mrg   func offset opnr first;
    134   1.1  mrg   begin
    135   1.1  mrg     if n_left > 1 then begin
    136   1.1  mrg       Printf.printf "\n";
    137   1.1  mrg       write_pat_sets func (opnr + 1) (offset + 4) false (n_left - 1);
    138   1.1  mrg     end else
    139   1.1  mrg       Printf.printf "]"
    140   1.1  mrg   end
    141   1.1  mrg 
    142   1.1  mrg let rec write_peep_sets func opnr first n_left =
    143   1.1  mrg   func opnr first;
    144   1.1  mrg   begin
    145   1.1  mrg     if n_left > 1 then begin
    146   1.1  mrg       Printf.printf "\n";
    147   1.1  mrg       write_peep_sets func (opnr + 1) false (n_left - 1);
    148   1.1  mrg     end
    149   1.1  mrg   end
    150   1.1  mrg     
    151   1.1  mrg let can_thumb addrmode update is_store =
    152   1.1  mrg   match addrmode, update, is_store with
    153   1.1  mrg     (* Thumb1 mode only supports IA with update.  However, for LDMIA,
    154   1.1  mrg        if the address register also appears in the list of loaded
    155   1.1  mrg        registers, the loaded value is stored, hence the RTL pattern
    156   1.1  mrg        to describe such an insn does not have an update.  We check
    157   1.1  mrg        in the match_parallel predicate that the condition described
    158   1.1  mrg        above is met.  *)
    159   1.1  mrg     IA, _, false -> true
    160   1.1  mrg   | IA, true, true -> true
    161   1.1  mrg   | _ -> false
    162   1.1  mrg 
    163   1.3  mrg exception InvalidAddrMode of string;;
    164   1.3  mrg 
    165   1.1  mrg let target addrmode thumb =
    166   1.1  mrg   match addrmode, thumb with
    167   1.1  mrg     IA, true -> "TARGET_THUMB1"
    168   1.1  mrg   | IA, false -> "TARGET_32BIT"
    169   1.1  mrg   | DB, false -> "TARGET_32BIT"
    170   1.1  mrg   | _, false -> "TARGET_ARM"
    171   1.3  mrg   | _, _ -> raise (InvalidAddrMode "ERROR: Invalid Addressing mode for Thumb1.")
    172   1.1  mrg 
    173   1.1  mrg let write_pattern_1 name ls addrmode nregs write_set_fn update thumb =
    174   1.4  mrg   let astr = string_of_addrmode addrmode thumb update in
    175   1.1  mrg   Printf.printf "(define_insn \"*%s%s%d_%s%s\"\n"
    176   1.1  mrg     (if thumb then "thumb_" else "") name nregs astr
    177   1.1  mrg     (if update then "_update" else "");
    178   1.1  mrg   Printf.printf "  [(match_parallel 0 \"%s_multiple_operation\"\n" ls;
    179   1.1  mrg   begin
    180   1.1  mrg     if update then begin
    181   1.1  mrg       Printf.printf "    [(set %s\n          (plus:SI %s"
    182   1.1  mrg 	(destreg nregs true INOUT thumb) (destreg nregs false IN thumb);
    183   1.1  mrg       Printf.printf " (const_int %d)))\n"
    184   1.1  mrg 	(final_offset addrmode nregs)
    185   1.1  mrg     end
    186   1.1  mrg   end;
    187   1.1  mrg   write_pat_sets
    188   1.1  mrg     (write_set_fn thumb nregs) 1
    189   1.1  mrg     (initial_offset addrmode nregs)
    190   1.1  mrg     (not update) nregs;
    191   1.1  mrg   Printf.printf ")]\n  \"%s && XVECLEN (operands[0], 0) == %d\"\n"
    192   1.1  mrg     (target addrmode thumb)
    193   1.1  mrg     (if update then nregs + 1 else nregs);
    194   1.4  mrg   if thumb then
    195   1.4  mrg       Printf.printf "  \"%s%s\\t%%%d%s, {"   name astr (nregs + 1) (if update then "!" else "")
    196   1.4  mrg    else
    197   1.4  mrg       Printf.printf "  \"%s%s%%?\\t%%%d%s, {"  name astr (nregs + 1) (if update then "!" else "");
    198   1.1  mrg   for n = 1 to nregs; do
    199   1.1  mrg     Printf.printf "%%%d%s" n (if n < nregs then ", " else "")
    200   1.1  mrg   done;
    201   1.1  mrg   Printf.printf "}\"\n";
    202   1.1  mrg   Printf.printf "  [(set_attr \"type\" \"%s%d\")" ls nregs;
    203   1.3  mrg   if not thumb then begin
    204   1.1  mrg     Printf.printf "\n   (set_attr \"predicable\" \"yes\")";
    205   1.3  mrg     if addrmode == IA || addrmode == DB then
    206   1.3  mrg       Printf.printf "\n   (set_attr \"predicable_short_it\" \"no\")";
    207   1.1  mrg   end;
    208   1.1  mrg   Printf.printf "])\n\n"
    209   1.1  mrg 
    210   1.1  mrg let write_ldm_pattern addrmode nregs update =
    211   1.1  mrg   write_pattern_1 "ldm" "load" addrmode nregs write_ldm_set update false;
    212   1.1  mrg   begin if can_thumb addrmode update false then
    213   1.1  mrg     write_pattern_1 "ldm" "load" addrmode nregs write_ldm_set update true;
    214   1.1  mrg   end
    215   1.1  mrg 
    216   1.1  mrg let write_stm_pattern addrmode nregs update =
    217   1.1  mrg   write_pattern_1 "stm" "store" addrmode nregs write_stm_set update false;
    218   1.1  mrg   begin if can_thumb addrmode update true then
    219   1.1  mrg     write_pattern_1 "stm" "store" addrmode nregs write_stm_set update true;
    220   1.1  mrg   end
    221   1.1  mrg 
    222   1.1  mrg let write_ldm_commutative_peephole thumb =
    223   1.1  mrg   let nregs = 2 in
    224   1.1  mrg   Printf.printf "(define_peephole2\n";
    225   1.1  mrg   write_peep_sets (write_ldm_peep_set "" nregs) 0 true nregs;
    226   1.1  mrg   let indent = "   " in
    227   1.1  mrg   if thumb then begin
    228   1.1  mrg     Printf.printf "\n%s(set (match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2);
    229   1.1  mrg     Printf.printf "%s     (match_operator:SI %d \"commutative_binary_operator\"\n" indent (nregs * 2 + 1);
    230   1.1  mrg     Printf.printf "%s      [(match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2 + 2);
    231   1.1  mrg     Printf.printf "%s       (match_operand:SI %d \"s_register_operand\" \"\")]))]\n" indent (nregs * 2 + 3)
    232   1.1  mrg   end else begin
    233   1.1  mrg     Printf.printf "\n%s(parallel\n" indent;
    234   1.1  mrg     Printf.printf "%s  [(set (match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2);
    235   1.1  mrg     Printf.printf "%s        (match_operator:SI %d \"commutative_binary_operator\"\n" indent (nregs * 2 + 1);
    236   1.1  mrg     Printf.printf "%s         [(match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2 + 2);
    237   1.1  mrg     Printf.printf "%s          (match_operand:SI %d \"s_register_operand\" \"\")]))\n" indent (nregs * 2 + 3);
    238   1.1  mrg     Printf.printf "%s   (clobber (reg:CC CC_REGNUM))])]\n" indent
    239   1.1  mrg   end;
    240   1.1  mrg   Printf.printf "  \"((((REGNO (operands[%d]) == REGNO (operands[0]))\n" (nregs * 2 + 2);
    241   1.1  mrg   Printf.printf "         && (REGNO (operands[%d]) == REGNO (operands[1])))\n"  (nregs * 2 + 3);
    242   1.1  mrg   Printf.printf "      || ((REGNO (operands[%d]) == REGNO (operands[0]))\n" (nregs * 2 + 3);
    243   1.1  mrg   Printf.printf "         && (REGNO (operands[%d]) == REGNO (operands[1]))))\n" (nregs * 2 + 2);
    244   1.1  mrg   Printf.printf "    && (peep2_regno_dead_p (%d, REGNO (operands[0]))\n" (nregs + 1);
    245   1.1  mrg   Printf.printf "      || (REGNO (operands[0]) == REGNO (operands[%d])))\n"  (nregs * 2);
    246   1.1  mrg   Printf.printf "    && (peep2_regno_dead_p (%d, REGNO (operands[1]))\n" (nregs + 1);
    247   1.1  mrg   Printf.printf "      || (REGNO (operands[1]) == REGNO (operands[%d]))))\"\n" (nregs * 2);
    248   1.1  mrg   begin
    249   1.1  mrg     if thumb then
    250   1.1  mrg       Printf.printf "  [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))]\n"
    251   1.1  mrg 	(nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3)
    252   1.1  mrg     else begin
    253   1.1  mrg       Printf.printf "  [(parallel\n";
    254   1.1  mrg       Printf.printf "    [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))\n"
    255   1.1  mrg 	(nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3);
    256   1.1  mrg       Printf.printf "     (clobber (reg:CC CC_REGNUM))])]\n"
    257   1.1  mrg     end
    258   1.1  mrg   end;
    259   1.1  mrg   Printf.printf "{\n  if (!gen_ldm_seq (operands, %d, true))\n    FAIL;\n" nregs;
    260   1.1  mrg   Printf.printf "})\n\n"
    261   1.1  mrg 
    262   1.1  mrg let write_ldm_peephole nregs =
    263   1.1  mrg   Printf.printf "(define_peephole2\n";
    264   1.1  mrg   write_peep_sets (write_ldm_peep_set "" nregs) 0 true nregs;
    265   1.1  mrg   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
    266   1.1  mrg   Printf.printf "  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
    267   1.1  mrg 
    268   1.1  mrg let write_ldm_peephole_b nregs =
    269   1.1  mrg   if nregs > 2 then begin
    270   1.1  mrg     Printf.printf "(define_peephole2\n";
    271   1.1  mrg     write_ldm_peep_set "" nregs 0 true;
    272   1.1  mrg     Printf.printf "\n   (parallel\n";
    273   1.1  mrg     write_peep_sets (write_ldm_peep_set "  " nregs) 1 true (nregs - 1);
    274   1.1  mrg     Printf.printf "])]\n  \"\"\n  [(const_int 0)]\n{\n";
    275   1.1  mrg     Printf.printf "  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
    276   1.1  mrg   end
    277   1.1  mrg 
    278   1.1  mrg let write_stm_peephole nregs =
    279   1.1  mrg   Printf.printf "(define_peephole2\n";
    280   1.1  mrg   write_peep_sets (write_stm_peep_set "" nregs) 0 true nregs;
    281   1.1  mrg   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
    282   1.1  mrg   Printf.printf "  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
    283   1.1  mrg 
    284   1.1  mrg let write_stm_peephole_b nregs =
    285   1.1  mrg   if nregs > 2 then begin
    286   1.1  mrg     Printf.printf "(define_peephole2\n";
    287   1.1  mrg     write_stm_peep_set "" nregs 0 true;
    288   1.1  mrg     Printf.printf "\n   (parallel\n";
    289   1.1  mrg     write_peep_sets (write_stm_peep_set "" nregs) 1 true (nregs - 1);
    290   1.1  mrg     Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
    291   1.1  mrg     Printf.printf "  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
    292   1.1  mrg   end
    293   1.1  mrg 
    294   1.1  mrg let write_const_stm_peephole_a nregs =
    295   1.1  mrg   Printf.printf "(define_peephole2\n";
    296   1.1  mrg   write_peep_sets (write_const_stm_peep_set nregs) 0 true nregs;
    297   1.1  mrg   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
    298   1.1  mrg   Printf.printf "  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
    299   1.1  mrg 
    300   1.1  mrg let write_const_stm_peephole_b nregs =
    301   1.1  mrg   Printf.printf "(define_peephole2\n";
    302   1.1  mrg   write_peep_sets (write_any_load "const_int_operand" nregs) 0 true nregs;
    303   1.1  mrg   Printf.printf "\n";
    304   1.1  mrg   write_peep_sets (write_const_store nregs) 0 false nregs;
    305   1.1  mrg   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
    306   1.1  mrg   Printf.printf "  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
    307   1.1  mrg 
    308   1.1  mrg let patterns () =
    309   1.1  mrg   let addrmodes = [ IA; IB; DA; DB ]  in
    310   1.1  mrg   let sizes = [ 4; 3; 2] in
    311   1.1  mrg   List.iter
    312   1.1  mrg     (fun n ->
    313   1.1  mrg       List.iter
    314   1.1  mrg 	(fun addrmode ->
    315   1.1  mrg 	  write_ldm_pattern addrmode n false;
    316   1.1  mrg 	  write_ldm_pattern addrmode n true;
    317   1.1  mrg 	  write_stm_pattern addrmode n false;
    318   1.1  mrg 	  write_stm_pattern addrmode n true)
    319   1.1  mrg 	addrmodes;
    320   1.1  mrg       write_ldm_peephole n;
    321   1.1  mrg       write_ldm_peephole_b n;
    322   1.1  mrg       write_const_stm_peephole_a n;
    323   1.1  mrg       write_const_stm_peephole_b n;
    324   1.1  mrg       write_stm_peephole n;)
    325   1.1  mrg     sizes;
    326   1.1  mrg   write_ldm_commutative_peephole false;
    327   1.1  mrg   write_ldm_commutative_peephole true
    328   1.1  mrg 
    329   1.1  mrg let print_lines = List.iter (fun s -> Format.printf "%s@\n" s)
    330   1.1  mrg 
    331   1.1  mrg (* Do it.  *)
    332   1.1  mrg 
    333   1.1  mrg let _ = 
    334   1.1  mrg   print_lines [
    335   1.1  mrg "/* ARM ldm/stm instruction patterns.  This file was automatically generated";
    336   1.1  mrg "   using arm-ldmstm.ml.  Please do not edit manually.";
    337   1.1  mrg "";
    338  1.10  mrg "   Copyright (C) 2010-2022 Free Software Foundation, Inc.";
    339   1.1  mrg "   Contributed by CodeSourcery.";
    340   1.1  mrg "";
    341   1.1  mrg "   This file is part of GCC.";
    342   1.1  mrg "";
    343   1.1  mrg "   GCC is free software; you can redistribute it and/or modify it";
    344   1.1  mrg "   under the terms of the GNU General Public License as published";
    345   1.1  mrg "   by the Free Software Foundation; either version 3, or (at your";
    346   1.1  mrg "   option) any later version.";
    347   1.1  mrg "";
    348   1.1  mrg "   GCC is distributed in the hope that it will be useful, but WITHOUT";
    349   1.1  mrg "   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY";
    350   1.1  mrg "   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public";
    351   1.1  mrg "   License for more details.";
    352   1.1  mrg "";
    353   1.1  mrg "   You should have received a copy of the GNU General Public License and";
    354   1.1  mrg "   a copy of the GCC Runtime Library Exception along with this program;";
    355   1.1  mrg "   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see";
    356   1.1  mrg "   <http://www.gnu.org/licenses/>.  */";
    357   1.1  mrg ""];
    358   1.1  mrg   patterns ();
    359