ada: Fix infinite loop with multiple limited with clauses
[official-gcc.git] / gcc / config / vax / builtins.md
blobfe58b364560db08b1932e5b05b2e2ae227ef28dc
1 ;; builtin definitions for DEC VAX.
2 ;; Copyright (C) 2007-2023 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
6 ;; GCC is free software; you can redistribute it and/or modify it under
7 ;; the terms of the GNU General Public License as published by the Free
8 ;; Software Foundation; either version 3, or (at your option) any later
9 ;; version.
11 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 ;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 ;; for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3.  If not see
18 ;; <http://www.gnu.org/licenses/>.
20 (define_constants
21   [
22     (VUNSPEC_LOCK 100)          ; sync lock operations
23   ]
26 (define_mode_attr width [(QI "8") (HI "16") (SI "32")])
27 (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")])
29 (define_int_iterator bit [0 1])
30 (define_int_attr ccss [(0 "cc") (1 "ss")])
32 (define_code_iterator any_extend [sign_extend zero_extend])
34 (define_expand "ffs<mode>2"
35   [(set (match_operand:SI 0 "nonimmediate_operand" "")
36         (ffs:SI (match_operand:VAXint 1 "general_operand" "")))]
37   ""
38   "
40   rtx label = gen_label_rtx ();
41   rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
42   rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx);
43   rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
45   emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1]));
46   emit_jump_insn (gen_rtx_SET (pc_rtx, target));
47   emit_insn (gen_neg<mode>2 (operands[0], const1_rtx));
48   emit_label (label);
49   emit_insn (gen_add<mode>3 (operands[0], operands[0], const1_rtx));
50   DONE;
51 }")
53 (define_insn_and_split "ctz<mode>2"
54   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
55         (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
56   ""
57   "#"
58   "reload_completed"
59   [(parallel
60      [(set (match_dup 0)
61            (ctz:SI (match_dup 1)))
62       (clobber (reg:CC VAX_PSL_REGNUM))])]
63   "")
65 (define_insn "*ctz<mode>2"
66   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
67         (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))
68    (clobber (reg:CC VAX_PSL_REGNUM))]
69   "reload_completed"
70   "ffs $0,$<width>,%1,%0")
72 (define_insn_and_split "ctz<mode>2_ccz"
73   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
74         (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
75   ""
76   "#"
77   "reload_completed"
78   [(parallel
79      [(set (reg:CCZ VAX_PSL_REGNUM)
80            (compare:CCZ (match_dup 1)
81                         (const_int 0)))
82       (set (match_dup 0)
83            (ctz:SI (match_dup 1)))])]
84   "")
86 (define_insn "*ctz<mode>2_ccz"
87   [(set (reg:CCZ VAX_PSL_REGNUM)
88         (compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT")
89                      (const_int 0)))
90    (set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
91         (ctz:SI (match_dup 1)))]
92   "reload_completed"
93   "ffs $0,$<width>,%1,%0")
95 ;; Our FFS hardware instruction supports any field width,
96 ;; so handle narrower inputs directly as well.
97 (define_peephole2
98   [(parallel
99      [(set (match_operand:SI 0 "register_operand")
100            (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
101       (clobber (reg:CC VAX_PSL_REGNUM))])
102    (parallel
103      [(set (match_operand:SI 2 "nonimmediate_operand")
104            (ctz:SI (match_dup 0)))
105       (clobber (reg:CC VAX_PSL_REGNUM))])]
106   "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])"
107   [(parallel
108      [(set (match_dup 2)
109            (ctz:SI (match_dup 1)))
110       (clobber (reg:CC VAX_PSL_REGNUM))])]
111   "")
113 ;; The FFS hardware instruction sets the Z condition code based on
114 ;; the input field rather than the output operand, so the compare
115 ;; elimination pass cannot handle it.  Try to get rid of the extra
116 ;; operation by hand.
118 ;; The "ctz<mode>2_ccz" patterns require their `operands[1]' not to
119 ;; have a mode dependent address, so all we need to verify is that
120 ;; the two operands are not the same, in which case it's the FFS
121 ;; output rather than input that condition codes are checked for.
122 (define_peephole2
123   [(parallel
124      [(set (match_operand:SI 0 "nonimmediate_operand")
125            (ctz:SI (match_operand:VAXint 1 "general_operand")))
126       (clobber (reg:CC VAX_PSL_REGNUM))])
127    (set (reg:CCZ VAX_PSL_REGNUM)
128         (compare:CCZ (match_dup 1)
129                      (const_int 0)))]
130   "!rtx_equal_p (operands[0], operands[1])"
131   [(parallel
132      [(set (reg:CCZ VAX_PSL_REGNUM)
133            (compare:CCZ (match_dup 1)
134                         (const_int 0)))
135       (set (match_dup 0)
136            (ctz:SI (match_dup 1)))])]
137   "")
139 ;; This effectively combines the two peepholes above,
140 ;; matching the sequence produced by `ffs<mode>2'.
141 (define_peephole2
142   [(parallel
143      [(set (match_operand:SI 0 "register_operand")
144            (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
145       (clobber (reg:CC VAX_PSL_REGNUM))])
146    (parallel
147      [(set (match_operand:SI 2 "nonimmediate_operand")
148            (ctz:SI (match_dup 0)))
149       (clobber (reg:CC VAX_PSL_REGNUM))])
150    (set (reg:CCZ VAX_PSL_REGNUM)
151         (compare:CCZ (match_dup 0)
152                      (const_int 0)))]
153   "!rtx_equal_p (operands[0], operands[2])
154    && peep2_reg_dead_p (3, operands[0])"
155   [(parallel
156      [(set (reg:CCZ VAX_PSL_REGNUM)
157            (compare:CCZ (match_dup 1)
158                         (const_int 0)))
159       (set (match_dup 2)
160            (ctz:SI (match_dup 1)))])]
161   "")
163 (define_expand "sync_lock_test_and_set<mode>"
164   [(match_operand:VAXint 0 "nonimmediate_operand" "=&g")
165    (match_operand:VAXint 1 "memory_operand" "+m")
166    (match_operand:VAXint 2 "const_int_operand" "n")]
167   ""
168   "
170   rtx label;
172   if (operands[2] != const1_rtx)
173     FAIL;
175   label = gen_label_rtx ();
176   emit_move_insn (operands[0], const1_rtx);
177   emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label));
178   emit_move_insn (operands[0], const0_rtx);
179   emit_label (label);
180   DONE;
183 (define_expand "sync_lock_release<mode>"
184   [(match_operand:VAXint 0 "memory_operand" "+m")
185    (match_operand:VAXint 1 "const_int_operand" "n")]
186   ""
187   "
189   rtx label;
191   if (operands[1] != const0_rtx)
192     FAIL;
194   label = gen_label_rtx ();
195   emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label));
196   emit_label (label);
197   DONE;
200 (define_insn "jbb<ccss>i<mode>"
201   [(unspec_volatile
202     [(set (pc)
203           (if_then_else
204             (eq (zero_extract:SI
205                   (match_operand:VAXint 0 "any_memory_operand" "+<bb_mem>")
206                   (const_int 1)
207                   (match_operand:SI 1 "general_operand" "nrmT"))
208                 (const_int bit))
209             (label_ref (match_operand 2 "" ""))
210             (pc)))
211      (set (zero_extract:SI (match_dup 0)
212                            (const_int 1)
213                            (match_dup 1))
214           (const_int bit))]
215     VUNSPEC_LOCK)]
216   ""
217   "jb<ccss>i %1,%0,%l2")