Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/pdp11/pdp11.md @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | f6334be47118 |
rev | line source |
---|---|
0 | 1 ;;- Machine description for the pdp11 for GNU C compiler |
2 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005 | |
3 ;; 2007, 2008 Free Software Foundation, Inc. | |
4 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at). | |
5 | |
6 ;; This file is part of GCC. | |
7 | |
8 ;; GCC is free software; you can redistribute it and/or modify | |
9 ;; it under the terms of the GNU General Public License as published by | |
10 ;; the Free Software Foundation; either version 3, or (at your option) | |
11 ;; any later version. | |
12 | |
13 ;; GCC is distributed in the hope that it will be useful, | |
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 ;; GNU General Public License for more details. | |
17 | |
18 ;; You should have received a copy of the GNU General Public License | |
19 ;; along with GCC; see the file COPYING3. If not see | |
20 ;; <http://www.gnu.org/licenses/>. | |
21 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
22 ;; Match CONST_DOUBLE zero for tstd/tstf. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
23 (define_predicate "register_or_const0_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
24 (ior (match_operand 0 "register_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
25 (match_test "op == CONST0_RTX (GET_MODE (op))"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
26 |
0 | 27 |
28 ;; HI is 16 bit | |
29 ;; QI is 8 bit | |
30 | |
31 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
32 | |
33 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code | |
34 ;;- updates for most instructions. | |
35 | |
36 ;;- Operand classes for the register allocator: | |
37 | |
38 ;; Compare instructions. | |
39 | |
40 ;; currently we only support df floats, which saves us quite some | |
41 ;; hassle switching the FP mode! | |
42 ;; we assume that CPU is always in long float mode, and | |
43 ;; 16 bit integer mode - currently, the prologue for main does this, | |
44 ;; but maybe we should just set up a NEW crt0 properly, | |
45 ;; -- and what about signal handling code? | |
46 ;; (we don't even let sf floats in the register file, so | |
47 ;; we only should have to worry about truncating and widening | |
48 ;; when going to memory) | |
49 | |
50 ;; abort() call by g++ - must define libfunc for cmp_optab | |
51 ;; and ucmp_optab for mode SImode, because we don't have that!!! | |
52 ;; - yet since no libfunc is there, we abort () | |
53 | |
54 ;; The only thing that remains to be done then is output | |
55 ;; the floats in a way the assembler can handle it (and | |
56 ;; if you're really into it, use a PDP11 float emulation | |
57 ;; library to do floating point constant folding - but | |
58 ;; I guess you'll get reasonable results even when not | |
59 ;; doing this) | |
60 ;; the last thing to do is fix the UPDATE_CC macro to check | |
61 ;; for floating point condition codes, and set cc_status | |
62 ;; properly, also setting the CC_IN_FCCR flag. | |
63 | |
64 ;; define attributes | |
65 ;; currently type is only fpu or arith or unknown, maybe branch later ? | |
66 ;; default is arith | |
67 (define_attr "type" "unknown,arith,fp" (const_string "arith")) | |
68 | |
69 ;; length default is 1 word each | |
70 (define_attr "length" "" (const_int 1)) | |
71 | |
72 ;; a user's asm statement | |
73 (define_asm_attributes | |
74 [(set_attr "type" "unknown") | |
75 ; all bets are off how long it is - make it 256, forces long jumps | |
76 ; whenever jumping around it !!! | |
77 (set_attr "length" "256")]) | |
78 | |
79 ;; define function units | |
80 | |
81 ;; arithmetic - values here immediately when next insn issued | |
82 ;; or does it mean the number of cycles after this insn was issued? | |
83 ;; how do I say that fpu insns use cpu also? (pre-interaction phase) | |
84 | |
85 ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0) | |
86 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0) | |
87 | |
88 ;; compare | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
89 (define_insn "*cmpdf" |
0 | 90 [(set (cc0) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
91 (compare (match_operand:DF 0 "general_operand" "fR,fR,Q,Q,F") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 (match_operand:DF 1 "register_or_const0_operand" "G,a,G,a,a")))] |
0 | 93 "TARGET_FPU" |
94 "* | |
95 { | |
96 cc_status.flags = CC_IN_FPU; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
97 if (which_alternative == 0 || which_alternative == 2) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
98 return \"{tstd|tstf} %0, %1\;cfcc\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
99 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
100 return \"{cmpd|cmpf} %0, %1\;cfcc\"; |
0 | 101 }" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
102 [(set_attr "length" "2,2,3,3,6")]) |
0 | 103 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
104 (define_insn "*cmphi" |
0 | 105 [(set (cc0) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
106 (compare (match_operand:HI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
107 (match_operand:HI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))] |
0 | 108 "" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
109 "@ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 tst %0 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
111 cmp %0,%1 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
112 cmp %0,%1 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
113 tst %0 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
114 cmp %0,%1 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
115 cmp %0,%1" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
116 [(set_attr "length" "1,1,2,2,2,3")]) |
0 | 117 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
118 (define_insn "*cmpqi" |
0 | 119 [(set (cc0) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
120 (compare (match_operand:QI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
121 (match_operand:QI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))] |
0 | 122 "" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 "@ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 tstb %0 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
125 cmpb %0,%1 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
126 cmpb %0,%1 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
127 tstb %0 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
128 cmpb %0,%1 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
129 cmpb %0,%1" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
130 [(set_attr "length" "1,1,2,2,2,3")]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
131 |
0 | 132 |
133 ;; sob instruction - we need an assembler which can make this instruction | |
134 ;; valid under _all_ circumstances! | |
135 | |
136 (define_insn "" | |
137 [(set (pc) | |
138 (if_then_else | |
139 (ne (plus:HI (match_operand:HI 0 "register_operand" "+r") | |
140 (const_int -1)) | |
141 (const_int 0)) | |
142 (label_ref (match_operand 1 "" "")) | |
143 (pc))) | |
144 (set (match_dup 0) | |
145 (plus:HI (match_dup 0) | |
146 (const_int -1)))] | |
147 "TARGET_40_PLUS" | |
148 "* | |
149 { | |
150 static int labelcount = 0; | |
151 static char buf[1000]; | |
152 | |
153 if (get_attr_length (insn) == 1) | |
154 return \"sob %0, %l1\"; | |
155 | |
156 /* emulate sob */ | |
157 output_asm_insn (\"dec %0\", operands); | |
158 | |
159 sprintf (buf, \"bge LONG_SOB%d\", labelcount); | |
160 output_asm_insn (buf, NULL); | |
161 | |
162 output_asm_insn (\"jmp %l1\", operands); | |
163 | |
164 sprintf (buf, \"LONG_SOB%d:\", labelcount++); | |
165 output_asm_insn (buf, NULL); | |
166 | |
167 return \"\"; | |
168 }" | |
169 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
170 (pc)) | |
171 (const_int -256)) | |
172 (ge (minus (match_dup 0) | |
173 (pc)) | |
174 (const_int 0))) | |
175 (const_int 4) | |
176 (const_int 1)))]) | |
177 | |
178 ;; These control RTL generation for conditional jump insns | |
179 ;; and match them for register allocation. | |
180 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
181 (define_expand "cbranchdf4" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
182 [(set (cc0) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
183 (compare (match_operand:DF 1 "general_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
184 (match_operand:DF 2 "general_operand"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
185 (set (pc) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
186 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
187 [(cc0) (const_int 0)]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
188 (label_ref (match_operand 3 "" "")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
189 (pc)))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
190 "" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
191 "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
192 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
193 (define_expand "cbranchhi4" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
194 [(set (cc0) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
195 (compare (match_operand:HI 1 "general_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
196 (match_operand:HI 2 "general_operand"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
197 (set (pc) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
198 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
199 [(cc0) (const_int 0)]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
200 (label_ref (match_operand 3 "" "")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
201 (pc)))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
202 "" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
203 "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
204 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
205 (define_expand "cbranchqi4" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
206 [(set (cc0) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
207 (compare (match_operand:QI 1 "general_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
208 (match_operand:QI 2 "general_operand"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
209 (set (pc) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
210 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
211 [(cc0) (const_int 0)]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
212 (label_ref (match_operand 3 "" "")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
213 (pc)))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
214 "" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
215 "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
216 |
0 | 217 ;; problem with too short jump distance! we need an assembler which can |
218 ;; make this valid for all jump distances! | |
219 ;; e.g. gas! | |
220 | |
221 ;; these must be changed to check for CC_IN_FCCR if float is to be | |
222 ;; enabled | |
223 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
224 (define_insn "*branch" |
0 | 225 [(set (pc) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
226 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
227 [(cc0) (const_int 0)]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
228 (label_ref (match_operand 1 "" "")) |
0 | 229 (pc)))] |
230 "" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
231 "* return output_jump(GET_CODE (operands[0]), 0, get_attr_length(insn));" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1) |
0 | 233 (pc)) |
234 (const_int -128)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
235 (ge (minus (match_dup 1) |
0 | 236 (pc)) |
237 (const_int 128))) | |
238 (const_int 3) | |
239 (const_int 1)))]) | |
240 | |
241 | |
242 ;; These match inverted jump insns for register allocation. | |
243 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
244 (define_insn "*branch_inverted" |
0 | 245 [(set (pc) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
246 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
247 [(cc0) (const_int 0)]) |
0 | 248 (pc) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
249 (label_ref (match_operand 1 "" ""))))] |
0 | 250 "" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
251 "* return output_jump(GET_CODE (operands[0]), 1, get_attr_length(insn));" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
252 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1) |
0 | 253 (pc)) |
254 (const_int -128)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
255 (ge (minus (match_dup 1) |
0 | 256 (pc)) |
257 (const_int 128))) | |
258 (const_int 3) | |
259 (const_int 1)))]) | |
260 | |
261 ;; Move instructions | |
262 | |
263 (define_insn "movdi" | |
264 [(set (match_operand:DI 0 "general_operand" "=g,rm,o") | |
265 (match_operand:DI 1 "general_operand" "m,r,a"))] | |
266 "" | |
267 "* return output_move_quad (operands);" | |
268 ;; what's the mose expensive code - say twice movsi = 16 | |
269 [(set_attr "length" "16,16,16")]) | |
270 | |
271 (define_insn "movsi" | |
272 [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m") | |
273 (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))] | |
274 "" | |
275 "* return output_move_double (operands);" | |
276 ;; what's the most expensive code ? - I think 8! | |
277 ;; we could split it up and make several sub-cases... | |
278 [(set_attr "length" "2,3,4,8,8")]) | |
279 | |
280 (define_insn "movhi" | |
281 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
282 (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))] | |
283 "" | |
284 "* | |
285 { | |
286 if (operands[1] == const0_rtx) | |
287 return \"clr %0\"; | |
288 | |
289 return \"mov %1, %0\"; | |
290 }" | |
291 [(set_attr "length" "1,2,2,3")]) | |
292 | |
293 (define_insn "movqi" | |
294 [(set (match_operand:QI 0 "nonimmediate_operand" "=g") | |
295 (match_operand:QI 1 "general_operand" "g"))] | |
296 "" | |
297 "* | |
298 { | |
299 if (operands[1] == const0_rtx) | |
300 return \"clrb %0\"; | |
301 | |
302 return \"movb %1, %0\"; | |
303 }" | |
304 [(set_attr "length" "1")]) | |
305 | |
306 ;; do we have to supply all these moves? e.g. to | |
307 ;; NO_LOAD_FPU_REGs ? | |
308 (define_insn "movdf" | |
309 [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m") | |
310 (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))] | |
311 "" | |
312 "* if (which_alternative ==0) | |
313 return \"ldd %1, %0\"; | |
314 else if (which_alternative == 1) | |
315 return \"std %1, %0\"; | |
316 else | |
317 return output_move_quad (operands); " | |
318 ;; just a guess.. | |
319 [(set_attr "length" "1,1,5,5,16")]) | |
320 | |
321 (define_insn "movsf" | |
322 [(set (match_operand:SF 0 "general_operand" "=g,r,g") | |
323 (match_operand:SF 1 "general_operand" "r,rmF,g"))] | |
324 "TARGET_FPU" | |
325 "* return output_move_double (operands);" | |
326 [(set_attr "length" "8,8,8")]) | |
327 | |
328 ;; maybe fiddle a bit with move_ratio, then | |
329 ;; let constraints only accept a register ... | |
330 | |
331 (define_expand "movmemhi" | |
332 [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g") | |
333 (match_operand:BLK 1 "general_operand" "g,g")) | |
334 (use (match_operand:HI 2 "arith_operand" "n,&mr")) | |
335 (use (match_operand:HI 3 "immediate_operand" "i,i")) | |
336 (clobber (match_scratch:HI 4 "=&r,X")) | |
337 (clobber (match_dup 5)) | |
338 (clobber (match_dup 6)) | |
339 (clobber (match_dup 2))])] | |
340 "(TARGET_BCOPY_BUILTIN)" | |
341 " | |
342 { | |
343 operands[0] | |
344 = replace_equiv_address (operands[0], | |
345 copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); | |
346 operands[1] | |
347 = replace_equiv_address (operands[1], | |
348 copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); | |
349 | |
350 operands[5] = XEXP (operands[0], 0); | |
351 operands[6] = XEXP (operands[1], 0); | |
352 }") | |
353 | |
354 | |
355 (define_insn "" ; "movmemhi" | |
356 [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r")) | |
357 (mem:BLK (match_operand:HI 1 "general_operand" "r,r"))) | |
358 (use (match_operand:HI 2 "arith_operand" "n,&r")) | |
359 (use (match_operand:HI 3 "immediate_operand" "i,i")) | |
360 (clobber (match_scratch:HI 4 "=&r,X")) | |
361 (clobber (match_dup 0)) | |
362 (clobber (match_dup 1)) | |
363 (clobber (match_dup 2))] | |
364 "(TARGET_BCOPY_BUILTIN)" | |
365 "* return output_block_move (operands);" | |
366 ;;; just a guess | |
367 [(set_attr "length" "40")]) | |
368 | |
369 | |
370 | |
371 ;;- truncation instructions | |
372 | |
373 (define_insn "truncdfsf2" | |
374 [(set (match_operand:SF 0 "general_operand" "=r,R,Q") | |
375 (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))] | |
376 "TARGET_FPU" | |
377 "* if (which_alternative ==0) | |
378 { | |
379 output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands); | |
380 output_asm_insn(\"mov (sp)+, %0\", operands); | |
381 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1); | |
382 output_asm_insn(\"mov (sp)+, %0\", operands); | |
383 return \"\"; | |
384 } | |
385 else if (which_alternative == 1) | |
386 return \"{stcdf|movfo} %1, %0\"; | |
387 else | |
388 return \"{stcdf|movfo} %1, %0\"; | |
389 " | |
390 [(set_attr "length" "3,1,2")]) | |
391 | |
392 | |
393 (define_expand "truncsihi2" | |
394 [(set (match_operand:HI 0 "general_operand" "=g") | |
395 (subreg:HI | |
396 (match_operand:SI 1 "general_operand" "or") | |
397 0))] | |
398 "" | |
399 "") | |
400 | |
401 | |
402 ;;- zero extension instructions | |
403 | |
404 (define_insn "zero_extendqihi2" | |
405 [(set (match_operand:HI 0 "general_operand" "=r") | |
406 (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))] | |
407 "" | |
408 "bic $0177400, %0" | |
409 [(set_attr "length" "2")]) | |
410 | |
411 (define_expand "zero_extendhisi2" | |
412 [(set (subreg:HI | |
413 (match_dup 0) | |
414 2) | |
415 (match_operand:HI 1 "register_operand" "r")) | |
416 (set (subreg:HI | |
417 (match_operand:SI 0 "register_operand" "=r") | |
418 0) | |
419 (const_int 0))] | |
420 "" | |
421 "/* operands[1] = make_safe_from (operands[1], operands[0]); */") | |
422 | |
423 | |
424 ;;- sign extension instructions | |
425 | |
426 (define_insn "extendsfdf2" | |
427 [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
428 (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))] | |
429 "TARGET_FPU" | |
430 "@ | |
431 mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0 | |
432 {ldcfd|movof} %1, %0 | |
433 {ldcfd|movof} %1, %0" | |
434 [(set_attr "length" "2,1,2")]) | |
435 | |
436 ;; does movb sign extend in register-to-register move? | |
437 (define_insn "extendqihi2" | |
438 [(set (match_operand:HI 0 "register_operand" "=r,r") | |
439 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))] | |
440 "" | |
441 "movb %1, %0" | |
442 [(set_attr "length" "1,2")]) | |
443 | |
444 (define_insn "extendqisi2" | |
445 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
446 (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))] | |
447 "TARGET_40_PLUS" | |
448 "* | |
449 { | |
450 rtx latehalf[2]; | |
451 | |
452 /* make register pair available */ | |
453 latehalf[0] = operands[0]; | |
454 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1); | |
455 | |
456 output_asm_insn(\"movb %1, %0\", operands); | |
457 output_asm_insn(\"sxt %0\", latehalf); | |
458 | |
459 return \"\"; | |
460 }" | |
461 [(set_attr "length" "2,3")]) | |
462 | |
463 ;; maybe we have to use define_expand to say that we have the instruction, | |
464 ;; unconditionally, and then match dependent on CPU type: | |
465 | |
466 (define_expand "extendhisi2" | |
467 [(set (match_operand:SI 0 "general_operand" "=g") | |
468 (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] | |
469 "" | |
470 "") | |
471 | |
472 (define_insn "" ; "extendhisi2" | |
473 [(set (match_operand:SI 0 "general_operand" "=o,<,r") | |
474 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))] | |
475 "TARGET_40_PLUS" | |
476 "* | |
477 { | |
478 rtx latehalf[2]; | |
479 | |
480 /* we don't want to mess with auto increment */ | |
481 | |
482 switch (which_alternative) | |
483 { | |
484 case 0: | |
485 | |
486 latehalf[0] = operands[0]; | |
487 operands[0] = adjust_address(operands[0], HImode, 2); | |
488 | |
489 output_asm_insn(\"mov %1, %0\", operands); | |
490 output_asm_insn(\"sxt %0\", latehalf); | |
491 | |
492 return \"\"; | |
493 | |
494 case 1: | |
495 | |
496 /* - auto-decrement - right direction ;-) */ | |
497 output_asm_insn(\"mov %1, %0\", operands); | |
498 output_asm_insn(\"sxt %0\", operands); | |
499 | |
500 return \"\"; | |
501 | |
502 case 2: | |
503 | |
504 /* make register pair available */ | |
505 latehalf[0] = operands[0]; | |
506 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
507 | |
508 output_asm_insn(\"mov %1, %0\", operands); | |
509 output_asm_insn(\"sxt %0\", latehalf); | |
510 | |
511 return \"\"; | |
512 | |
513 default: | |
514 | |
515 gcc_unreachable (); | |
516 } | |
517 }" | |
518 [(set_attr "length" "5,3,3")]) | |
519 | |
520 | |
521 (define_insn "" | |
522 [(set (match_operand:SI 0 "register_operand" "=r") | |
523 (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))] | |
524 "(! TARGET_40_PLUS)" | |
525 "* | |
526 { | |
527 static int count = 0; | |
528 char buf[100]; | |
529 rtx lateoperands[2]; | |
530 | |
531 lateoperands[0] = operands[0]; | |
532 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
533 | |
534 output_asm_insn(\"tst %0\", operands); | |
535 sprintf(buf, \"bge extendhisi%d\", count); | |
536 output_asm_insn(buf, NULL); | |
537 output_asm_insn(\"mov -1, %0\", lateoperands); | |
538 sprintf(buf, \"bne extendhisi%d\", count+1); | |
539 output_asm_insn(buf, NULL); | |
540 sprintf(buf, \"\\nextendhisi%d:\", count); | |
541 output_asm_insn(buf, NULL); | |
542 output_asm_insn(\"clr %0\", lateoperands); | |
543 sprintf(buf, \"\\nextendhisi%d:\", count+1); | |
544 output_asm_insn(buf, NULL); | |
545 | |
546 count += 2; | |
547 | |
548 return \"\"; | |
549 }" | |
550 [(set_attr "length" "6")]) | |
551 | |
552 ;; make float to int and vice versa | |
553 ;; using the cc_status.flag field we could probably cut down | |
554 ;; on seti and setl | |
555 ;; assume that we are normally in double and integer mode - | |
556 ;; what do pdp library routines do to fpu mode ? | |
557 | |
558 (define_insn "floatsidf2" | |
559 [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
560 (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))] | |
561 "TARGET_FPU" | |
562 "* if (which_alternative ==0) | |
563 { | |
564 rtx latehalf[2]; | |
565 | |
566 latehalf[0] = NULL; | |
567 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); | |
568 output_asm_insn(\"mov %1, -(sp)\", latehalf); | |
569 output_asm_insn(\"mov %1, -(sp)\", operands); | |
570 | |
571 output_asm_insn(\"setl\", operands); | |
572 output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands); | |
573 output_asm_insn(\"seti\", operands); | |
574 return \"\"; | |
575 } | |
576 else if (which_alternative == 1) | |
577 return \"setl\;{ldcld|movif} %1, %0\;seti\"; | |
578 else | |
579 return \"setl\;{ldcld|movif} %1, %0\;seti\"; | |
580 " | |
581 [(set_attr "length" "5,3,4")]) | |
582 | |
583 (define_insn "floathidf2" | |
584 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
585 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))] | |
586 "TARGET_FPU" | |
587 "{ldcid|movif} %1, %0" | |
588 [(set_attr "length" "1,2")]) | |
589 | |
590 ;; cut float to int | |
591 (define_insn "fix_truncdfsi2" | |
592 [(set (match_operand:SI 0 "general_operand" "=r,R,Q") | |
593 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))] | |
594 "TARGET_FPU" | |
595 "* if (which_alternative ==0) | |
596 { | |
597 output_asm_insn(\"setl\", operands); | |
598 output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands); | |
599 output_asm_insn(\"seti\", operands); | |
600 output_asm_insn(\"mov (sp)+, %0\", operands); | |
601 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
602 output_asm_insn(\"mov (sp)+, %0\", operands); | |
603 return \"\"; | |
604 } | |
605 else if (which_alternative == 1) | |
606 return \"setl\;{stcdl|movfi} %1, %0\;seti\"; | |
607 else | |
608 return \"setl\;{stcdl|movfi} %1, %0\;seti\"; | |
609 " | |
610 [(set_attr "length" "5,3,4")]) | |
611 | |
612 (define_insn "fix_truncdfhi2" | |
613 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
614 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] | |
615 "TARGET_FPU" | |
616 "{stcdi|movfi} %1, %0" | |
617 [(set_attr "length" "1,2")]) | |
618 | |
619 | |
620 ;;- arithmetic instructions | |
621 ;;- add instructions | |
622 | |
623 (define_insn "adddf3" | |
624 [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
625 (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0") | |
626 (match_operand:DF 2 "general_operand" "fR,Q,F")))] | |
627 "TARGET_FPU" | |
628 "{addd|addf} %2, %0" | |
629 [(set_attr "length" "1,2,5")]) | |
630 | |
631 (define_insn "addsi3" | |
632 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") | |
633 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") | |
634 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] | |
635 "" | |
636 "* | |
637 { /* Here we trust that operands don't overlap | |
638 | |
639 or is lateoperands the low word?? - looks like it! */ | |
640 | |
641 rtx lateoperands[3]; | |
642 | |
643 lateoperands[0] = operands[0]; | |
644 | |
645 if (REG_P (operands[0])) | |
646 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
647 else | |
648 operands[0] = adjust_address (operands[0], HImode, 2); | |
649 | |
650 if (! CONSTANT_P(operands[2])) | |
651 { | |
652 lateoperands[2] = operands[2]; | |
653 | |
654 if (REG_P (operands[2])) | |
655 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
656 else | |
657 operands[2] = adjust_address (operands[2], HImode, 2); | |
658 | |
659 output_asm_insn (\"add %2, %0\", operands); | |
660 output_asm_insn (\"adc %0\", lateoperands); | |
661 output_asm_insn (\"add %2, %0\", lateoperands); | |
662 return \"\"; | |
663 } | |
664 | |
665 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff); | |
666 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); | |
667 | |
668 if (INTVAL(operands[2])) | |
669 { | |
670 output_asm_insn (\"add %2, %0\", operands); | |
671 output_asm_insn (\"adc %0\", lateoperands); | |
672 } | |
673 | |
674 if (INTVAL(lateoperands[2])) | |
675 output_asm_insn (\"add %2, %0\", lateoperands); | |
676 | |
677 return \"\"; | |
678 }" | |
679 [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")]) | |
680 | |
681 (define_insn "addhi3" | |
682 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
683 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") | |
684 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] | |
685 "" | |
686 "* | |
687 { | |
688 if (GET_CODE (operands[2]) == CONST_INT) | |
689 { | |
690 if (INTVAL(operands[2]) == 1) | |
691 return \"inc %0\"; | |
692 else if (INTVAL(operands[2]) == -1) | |
693 return \"dec %0\"; | |
694 } | |
695 | |
696 return \"add %2, %0\"; | |
697 }" | |
698 [(set_attr "length" "1,2,2,3")]) | |
699 | |
700 (define_insn "addqi3" | |
701 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
702 (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") | |
703 (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] | |
704 "" | |
705 "* | |
706 { | |
707 if (GET_CODE (operands[2]) == CONST_INT) | |
708 { | |
709 if (INTVAL(operands[2]) == 1) | |
710 return \"incb %0\"; | |
711 else if (INTVAL(operands[2]) == -1) | |
712 return \"decb %0\"; | |
713 } | |
714 | |
715 return \"add %2, %0\"; | |
716 }" | |
717 [(set_attr "length" "1,2,2,3")]) | |
718 | |
719 | |
720 ;;- subtract instructions | |
721 ;; we don't have to care for constant second | |
722 ;; args, since they are canonical plus:xx now! | |
723 ;; also for minus:DF ?? | |
724 | |
725 (define_insn "subdf3" | |
726 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
727 (minus:DF (match_operand:DF 1 "register_operand" "0,0") | |
728 (match_operand:DF 2 "general_operand" "fR,Q")))] | |
729 "TARGET_FPU" | |
730 "{subd|subf} %2, %0" | |
731 [(set_attr "length" "1,2")]) | |
732 | |
733 (define_insn "subsi3" | |
734 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o") | |
735 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") | |
736 (match_operand:SI 2 "general_operand" "r,o,r,o")))] | |
737 "" | |
738 "* | |
739 { /* Here we trust that operands don't overlap | |
740 | |
741 or is lateoperands the low word?? - looks like it! */ | |
742 | |
743 rtx lateoperands[3]; | |
744 | |
745 lateoperands[0] = operands[0]; | |
746 | |
747 if (REG_P (operands[0])) | |
748 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
749 else | |
750 operands[0] = adjust_address (operands[0], HImode, 2); | |
751 | |
752 lateoperands[2] = operands[2]; | |
753 | |
754 if (REG_P (operands[2])) | |
755 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
756 else | |
757 operands[2] = adjust_address (operands[2], HImode, 2); | |
758 | |
759 output_asm_insn (\"sub %2, %0\", operands); | |
760 output_asm_insn (\"sbc %0\", lateoperands); | |
761 output_asm_insn (\"sub %2, %0\", lateoperands); | |
762 return \"\"; | |
763 }" | |
764 ;; offsettable memory addresses always are expensive!!! | |
765 [(set_attr "length" "3,5,6,8")]) | |
766 | |
767 (define_insn "subhi3" | |
768 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
769 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") | |
770 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
771 "" | |
772 "* | |
773 { | |
774 gcc_assert (GET_CODE (operands[2]) != CONST_INT); | |
775 | |
776 return \"sub %2, %0\"; | |
777 }" | |
778 [(set_attr "length" "1,2,2,3")]) | |
779 | |
780 (define_insn "subqi3" | |
781 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
782 (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0") | |
783 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
784 "" | |
785 "* | |
786 { | |
787 gcc_assert (GET_CODE (operands[2]) != CONST_INT); | |
788 | |
789 return \"sub %2, %0\"; | |
790 }" | |
791 [(set_attr "length" "1,2,2,3")]) | |
792 | |
793 ;;;;- and instructions | |
794 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn. | |
795 | |
796 (define_insn "andsi3" | |
797 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") | |
798 (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") | |
799 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))] | |
800 "" | |
801 "* | |
802 { /* Here we trust that operands don't overlap | |
803 | |
804 or is lateoperands the low word?? - looks like it! */ | |
805 | |
806 rtx lateoperands[3]; | |
807 | |
808 lateoperands[0] = operands[0]; | |
809 | |
810 if (REG_P (operands[0])) | |
811 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
812 else | |
813 operands[0] = adjust_address (operands[0], HImode, 2); | |
814 | |
815 if (! CONSTANT_P(operands[2])) | |
816 { | |
817 lateoperands[2] = operands[2]; | |
818 | |
819 if (REG_P (operands[2])) | |
820 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
821 else | |
822 operands[2] = adjust_address (operands[2], HImode, 2); | |
823 | |
824 output_asm_insn (\"bic %2, %0\", operands); | |
825 output_asm_insn (\"bic %2, %0\", lateoperands); | |
826 return \"\"; | |
827 } | |
828 | |
829 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff); | |
830 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); | |
831 | |
832 /* these have different lengths, so we should have | |
833 different constraints! */ | |
834 if (INTVAL(operands[2])) | |
835 output_asm_insn (\"bic %2, %0\", operands); | |
836 | |
837 if (INTVAL(lateoperands[2])) | |
838 output_asm_insn (\"bic %2, %0\", lateoperands); | |
839 | |
840 return \"\"; | |
841 }" | |
842 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) | |
843 | |
844 (define_insn "andhi3" | |
845 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
846 (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0") | |
847 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))] | |
848 "" | |
849 "bic %2, %0" | |
850 [(set_attr "length" "1,2,2,3")]) | |
851 | |
852 (define_insn "andqi3" | |
853 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
854 (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0") | |
855 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))] | |
856 "" | |
857 "bicb %2, %0" | |
858 [(set_attr "length" "1,2,2,3")]) | |
859 | |
860 ;;- Bit set (inclusive or) instructions | |
861 (define_insn "iorsi3" | |
862 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") | |
863 (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") | |
864 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] | |
865 "" | |
866 "* | |
867 { /* Here we trust that operands don't overlap | |
868 | |
869 or is lateoperands the low word?? - looks like it! */ | |
870 | |
871 rtx lateoperands[3]; | |
872 | |
873 lateoperands[0] = operands[0]; | |
874 | |
875 if (REG_P (operands[0])) | |
876 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
877 else | |
878 operands[0] = adjust_address (operands[0], HImode, 2); | |
879 | |
880 if (! CONSTANT_P(operands[2])) | |
881 { | |
882 lateoperands[2] = operands[2]; | |
883 | |
884 if (REG_P (operands[2])) | |
885 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
886 else | |
887 operands[2] = adjust_address (operands[2], HImode, 2); | |
888 | |
889 output_asm_insn (\"bis %2, %0\", operands); | |
890 output_asm_insn (\"bis %2, %0\", lateoperands); | |
891 return \"\"; | |
892 } | |
893 | |
894 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff); | |
895 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); | |
896 | |
897 /* these have different lengths, so we should have | |
898 different constraints! */ | |
899 if (INTVAL(operands[2])) | |
900 output_asm_insn (\"bis %2, %0\", operands); | |
901 | |
902 if (INTVAL(lateoperands[2])) | |
903 output_asm_insn (\"bis %2, %0\", lateoperands); | |
904 | |
905 return \"\"; | |
906 }" | |
907 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) | |
908 | |
909 (define_insn "iorhi3" | |
910 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
911 (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") | |
912 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
913 "" | |
914 "bis %2, %0" | |
915 [(set_attr "length" "1,2,2,3")]) | |
916 | |
917 (define_insn "iorqi3" | |
918 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
919 (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") | |
920 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
921 "" | |
922 "bisb %2, %0") | |
923 | |
924 ;;- xor instructions | |
925 (define_insn "xorsi3" | |
926 [(set (match_operand:SI 0 "register_operand" "=r") | |
927 (xor:SI (match_operand:SI 1 "register_operand" "%0") | |
928 (match_operand:SI 2 "arith_operand" "r")))] | |
929 "TARGET_40_PLUS" | |
930 "* | |
931 { /* Here we trust that operands don't overlap */ | |
932 | |
933 rtx lateoperands[3]; | |
934 | |
935 lateoperands[0] = operands[0]; | |
936 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
937 | |
938 if (REG_P(operands[2])) | |
939 { | |
940 lateoperands[2] = operands[2]; | |
941 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
942 | |
943 output_asm_insn (\"xor %2, %0\", operands); | |
944 output_asm_insn (\"xor %2, %0\", lateoperands); | |
945 | |
946 return \"\"; | |
947 } | |
948 | |
949 }" | |
950 [(set_attr "length" "2")]) | |
951 | |
952 (define_insn "xorhi3" | |
953 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
954 (xor:HI (match_operand:HI 1 "general_operand" "%0,0") | |
955 (match_operand:HI 2 "register_operand" "r,r")))] | |
956 "TARGET_40_PLUS" | |
957 "xor %2, %0" | |
958 [(set_attr "length" "1,2")]) | |
959 | |
960 ;;- one complement instructions | |
961 | |
962 (define_insn "one_cmplhi2" | |
963 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
964 (not:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
965 "" | |
966 "com %0" | |
967 [(set_attr "length" "1,2")]) | |
968 | |
969 (define_insn "one_cmplqi2" | |
970 [(set (match_operand:QI 0 "general_operand" "=rR,rR") | |
971 (not:QI (match_operand:QI 1 "general_operand" "0,g")))] | |
972 "" | |
973 "@ | |
974 comb %0 | |
975 movb %1, %0\; comb %0" | |
976 [(set_attr "length" "1,2")]) | |
977 | |
978 ;;- arithmetic shift instructions | |
979 (define_insn "ashlsi3" | |
980 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
981 (ashift:SI (match_operand:SI 1 "register_operand" "0,0") | |
982 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
983 "TARGET_45" | |
984 "ashc %2,%0" | |
985 [(set_attr "length" "1,2")]) | |
986 | |
987 ;; Arithmetic right shift on the pdp works by negating the shift count. | |
988 (define_expand "ashrsi3" | |
989 [(set (match_operand:SI 0 "register_operand" "=r") | |
990 (ashift:SI (match_operand:SI 1 "register_operand" "0") | |
991 (match_operand:HI 2 "general_operand" "g")))] | |
992 "" | |
993 " | |
994 { | |
995 operands[2] = negate_rtx (HImode, operands[2]); | |
996 }") | |
997 | |
998 ;; define asl aslb asr asrb - ashc missing! | |
999 | |
1000 ;; asl | |
1001 (define_insn "" | |
1002 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1003 (ashift:HI (match_operand:HI 1 "general_operand" "0,0") | |
1004 (const_int 1)))] | |
1005 "" | |
1006 "asl %0" | |
1007 [(set_attr "length" "1,2")]) | |
1008 | |
1009 ;; and another possibility for asr is << -1 | |
1010 ;; might cause problems since -1 can also be encoded as 65535! | |
1011 ;; not in gcc2 ??? | |
1012 | |
1013 ;; asr | |
1014 (define_insn "" | |
1015 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1016 (ashift:HI (match_operand:HI 1 "general_operand" "0,0") | |
1017 (const_int -1)))] | |
1018 "" | |
1019 "asr %0" | |
1020 [(set_attr "length" "1,2")]) | |
1021 | |
1022 ;; lsr | |
1023 (define_insn "" | |
1024 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1025 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0") | |
1026 (const_int 1)))] | |
1027 "" | |
1028 "clc\;ror %0" | |
1029 [(set_attr "length" "1,2")]) | |
1030 | |
1031 (define_insn "lshrsi3" | |
1032 [(set (match_operand:SI 0 "register_operand" "=r") | |
1033 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") | |
1034 (const_int 1)))] | |
1035 "" | |
1036 { | |
1037 | |
1038 rtx lateoperands[2]; | |
1039 | |
1040 lateoperands[0] = operands[0]; | |
1041 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
1042 | |
1043 lateoperands[1] = operands[1]; | |
1044 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); | |
1045 | |
1046 output_asm_insn (\"clc\", operands); | |
1047 output_asm_insn (\"ror %0\", lateoperands); | |
1048 output_asm_insn (\"ror %0\", operands); | |
1049 | |
1050 return \"\"; | |
1051 } | |
1052 [(set_attr "length" "5")]) | |
1053 | |
1054 ;; shift is by arbitrary count is expensive, | |
1055 ;; shift by one cheap - so let's do that, if | |
1056 ;; space doesn't matter | |
1057 (define_insn "" | |
1058 [(set (match_operand:HI 0 "general_operand" "=r") | |
1059 (ashift:HI (match_operand:HI 1 "general_operand" "0") | |
1060 (match_operand:HI 2 "expand_shift_operand" "O")))] | |
1061 "! optimize_size" | |
1062 "* | |
1063 { | |
1064 register int i; | |
1065 | |
1066 for (i = 1; i <= abs(INTVAL(operands[2])); i++) | |
1067 if (INTVAL(operands[2]) < 0) | |
1068 output_asm_insn(\"asr %0\", operands); | |
1069 else | |
1070 output_asm_insn(\"asl %0\", operands); | |
1071 | |
1072 return \"\"; | |
1073 }" | |
1074 ;; longest is 4 | |
1075 [(set (attr "length") (const_int 4))]) | |
1076 | |
1077 ;; aslb | |
1078 (define_insn "" | |
1079 [(set (match_operand:QI 0 "general_operand" "=r,o") | |
1080 (ashift:QI (match_operand:QI 1 "general_operand" "0,0") | |
1081 (match_operand:HI 2 "const_immediate_operand" "n,n")))] | |
1082 "" | |
1083 "* | |
1084 { /* allowing predec or post_inc is possible, but hairy! */ | |
1085 int i, cnt; | |
1086 | |
1087 cnt = INTVAL(operands[2]) & 0x0007; | |
1088 | |
1089 for (i=0 ; i < cnt ; i++) | |
1090 output_asm_insn(\"aslb %0\", operands); | |
1091 | |
1092 return \"\"; | |
1093 }" | |
1094 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!! | |
1095 [(set_attr_alternative "length" | |
1096 [(const_int 7) | |
1097 (const_int 14)])]) | |
1098 | |
1099 ;;; asr | |
1100 ;(define_insn "" | |
1101 ; [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1102 ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0") | |
1103 ; (const_int 1)))] | |
1104 ; "" | |
1105 ; "asr %0" | |
1106 ; [(set_attr "length" "1,2")]) | |
1107 | |
1108 ;; asrb | |
1109 (define_insn "" | |
1110 [(set (match_operand:QI 0 "general_operand" "=r,o") | |
1111 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") | |
1112 (match_operand:HI 2 "const_immediate_operand" "n,n")))] | |
1113 "" | |
1114 "* | |
1115 { /* allowing predec or post_inc is possible, but hairy! */ | |
1116 int i, cnt; | |
1117 | |
1118 cnt = INTVAL(operands[2]) & 0x0007; | |
1119 | |
1120 for (i=0 ; i < cnt ; i++) | |
1121 output_asm_insn(\"asrb %0\", operands); | |
1122 | |
1123 return \"\"; | |
1124 }" | |
1125 [(set_attr_alternative "length" | |
1126 [(const_int 7) | |
1127 (const_int 14)])]) | |
1128 | |
1129 ;; the following is invalid - too complex!!! - just say 14 !!! | |
1130 ; [(set (attr "length") (plus (and (match_dup 2) | |
1131 ; (const_int 7)) | |
1132 ; (and (match_dup 2) | |
1133 ; (const_int 7))))]) | |
1134 | |
1135 | |
1136 | |
1137 ;; can we get +-1 in the next pattern? should | |
1138 ;; have been caught by previous patterns! | |
1139 | |
1140 (define_insn "ashlhi3" | |
1141 [(set (match_operand:HI 0 "register_operand" "=r,r") | |
1142 (ashift:HI (match_operand:HI 1 "register_operand" "0,0") | |
1143 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1144 "" | |
1145 "* | |
1146 { | |
1147 if (GET_CODE(operands[2]) == CONST_INT) | |
1148 { | |
1149 if (INTVAL(operands[2]) == 1) | |
1150 return \"asl %0\"; | |
1151 else if (INTVAL(operands[2]) == -1) | |
1152 return \"asr %0\"; | |
1153 } | |
1154 | |
1155 return \"ash %2,%0\"; | |
1156 }" | |
1157 [(set_attr "length" "1,2")]) | |
1158 | |
1159 ;; Arithmetic right shift on the pdp works by negating the shift count. | |
1160 (define_expand "ashrhi3" | |
1161 [(set (match_operand:HI 0 "register_operand" "=r") | |
1162 (ashift:HI (match_operand:HI 1 "register_operand" "0") | |
1163 (match_operand:HI 2 "general_operand" "g")))] | |
1164 "" | |
1165 " | |
1166 { | |
1167 operands[2] = negate_rtx (HImode, operands[2]); | |
1168 }") | |
1169 | |
1170 ;;;;- logical shift instructions | |
1171 ;;(define_insn "lshrsi3" | |
1172 ;; [(set (match_operand:HI 0 "register_operand" "=r") | |
1173 ;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") | |
1174 ;; (match_operand:HI 2 "arith_operand" "rI")))] | |
1175 ;; "" | |
1176 ;; "srl %0,%2") | |
1177 | |
1178 ;; absolute | |
1179 | |
1180 (define_insn "absdf2" | |
1181 [(set (match_operand:DF 0 "general_operand" "=fR,Q") | |
1182 (abs:DF (match_operand:DF 1 "general_operand" "0,0")))] | |
1183 "TARGET_FPU" | |
1184 "{absd|absf} %0" | |
1185 [(set_attr "length" "1,2")]) | |
1186 | |
1187 (define_insn "abshi2" | |
1188 [(set (match_operand:HI 0 "general_operand" "=r,o") | |
1189 (abs:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
1190 "TARGET_ABSHI_BUILTIN" | |
1191 "* | |
1192 { | |
1193 static int count = 0; | |
1194 char buf[200]; | |
1195 | |
1196 output_asm_insn(\"tst %0\", operands); | |
1197 sprintf(buf, \"bge abshi%d\", count); | |
1198 output_asm_insn(buf, NULL); | |
1199 output_asm_insn(\"neg %0\", operands); | |
1200 sprintf(buf, \"\\nabshi%d:\", count++); | |
1201 output_asm_insn(buf, NULL); | |
1202 | |
1203 return \"\"; | |
1204 }" | |
1205 [(set_attr "length" "3,5")]) | |
1206 | |
1207 | |
1208 ;; define expand abshi - is much better !!! - but | |
1209 ;; will it be optimized into an abshi2 ? | |
1210 ;; it will leave better code, because the tsthi might be | |
1211 ;; optimized away!! | |
1212 ; -- just a thought - don't have time to check | |
1213 ; | |
1214 ;(define_expand "abshi2" | |
1215 ; [(match_operand:HI 0 "general_operand" "") | |
1216 ; (match_operand:HI 1 "general_operand" "")] | |
1217 ; "" | |
1218 ; " | |
1219 ;{ | |
1220 ; rtx label = gen_label_rtx (); | |
1221 ; | |
1222 ; /* do I need this? */ | |
1223 ; do_pending_stack_adjust (); | |
1224 ; | |
1225 ; emit_move_insn (operands[0], operands[1]); | |
1226 ; | |
1227 ; emit_insn (gen_tsthi (operands[0])); | |
1228 ; emit_insn (gen_bge (label1)); | |
1229 ; | |
1230 ; emit_insn (gen_neghi(operands[0], operands[0]) | |
1231 ; | |
1232 ; emit_barrier (); | |
1233 ; | |
1234 ; emit_label (label); | |
1235 ; | |
1236 ; /* allow REG_NOTES to be set on last insn (labels don't have enough | |
1237 ; fields, and can't be used for REG_NOTES anyway). */ | |
1238 ; emit_use (stack_pointer_rtx); | |
1239 ; DONE; | |
1240 ;}") | |
1241 | |
1242 ;; negate insns | |
1243 | |
1244 (define_insn "negdf2" | |
1245 [(set (match_operand:DF 0 "general_operand" "=fR,Q") | |
1246 (neg:DF (match_operand:DF 1 "register_operand" "0,0")))] | |
1247 "TARGET_FPU" | |
1248 "{negd|negf} %0" | |
1249 [(set_attr "length" "1,2")]) | |
1250 | |
1251 (define_insn "negsi2" | |
1252 [(set (match_operand:SI 0 "register_operand" "=r") | |
1253 (neg:SI (match_operand:SI 1 "general_operand" "0")))] | |
1254 "" | |
1255 { | |
1256 | |
1257 rtx lateoperands[2]; | |
1258 | |
1259 lateoperands[0] = operands[0]; | |
1260 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
1261 | |
1262 lateoperands[1] = operands[1]; | |
1263 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); | |
1264 | |
1265 output_asm_insn (\"com %0\", operands); | |
1266 output_asm_insn (\"com %0\", lateoperands); | |
1267 output_asm_insn (\"inc %0\", operands); | |
1268 output_asm_insn (\"adc %0\", lateoperands); | |
1269 | |
1270 return \"\"; | |
1271 } | |
1272 [(set_attr "length" "5")]) | |
1273 | |
1274 (define_insn "neghi2" | |
1275 [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1276 (neg:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
1277 "" | |
1278 "neg %0" | |
1279 [(set_attr "length" "1,2")]) | |
1280 | |
1281 (define_insn "negqi2" | |
1282 [(set (match_operand:QI 0 "general_operand" "=rR,Q") | |
1283 (neg:QI (match_operand:QI 1 "general_operand" "0,0")))] | |
1284 "" | |
1285 "negb %0" | |
1286 [(set_attr "length" "1,2")]) | |
1287 | |
1288 | |
1289 ;; Unconditional and other jump instructions | |
1290 (define_insn "jump" | |
1291 [(set (pc) | |
1292 (label_ref (match_operand 0 "" "")))] | |
1293 "" | |
1294 "jmp %l0" | |
1295 [(set_attr "length" "2")]) | |
1296 | |
1297 (define_insn "" | |
1298 [(set (pc) | |
1299 (label_ref (match_operand 0 "" ""))) | |
1300 (clobber (const_int 1))] | |
1301 "" | |
1302 "jmp %l0" | |
1303 [(set_attr "length" "2")]) | |
1304 | |
1305 (define_insn "tablejump" | |
1306 [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q")) | |
1307 (use (label_ref (match_operand 1 "" "")))] | |
1308 "" | |
1309 "jmp %0" | |
1310 [(set_attr "length" "1,2")]) | |
1311 | |
1312 ;; indirect jump - let's be conservative! | |
1313 ;; allow only register_operand, even though we could also | |
1314 ;; allow labels etc. | |
1315 | |
1316 (define_insn "indirect_jump" | |
1317 [(set (pc) (match_operand:HI 0 "register_operand" "r"))] | |
1318 "" | |
1319 "jmp (%0)") | |
1320 | |
1321 ;;- jump to subroutine | |
1322 | |
1323 (define_insn "call" | |
1324 [(call (match_operand:HI 0 "general_operand" "rR,Q") | |
1325 (match_operand:HI 1 "general_operand" "g,g")) | |
1326 ;; (use (reg:HI 0)) what was that ??? | |
1327 ] | |
1328 ;;- Don't use operand 1 for most machines. | |
1329 "" | |
1330 "jsr pc, %0" | |
1331 [(set_attr "length" "1,2")]) | |
1332 | |
1333 ;;- jump to subroutine | |
1334 (define_insn "call_value" | |
1335 [(set (match_operand 0 "" "") | |
1336 (call (match_operand:HI 1 "general_operand" "rR,Q") | |
1337 (match_operand:HI 2 "general_operand" "g,g"))) | |
1338 ;; (use (reg:HI 0)) - what was that ???? | |
1339 ] | |
1340 ;;- Don't use operand 2 for most machines. | |
1341 "" | |
1342 "jsr pc, %1" | |
1343 [(set_attr "length" "1,2")]) | |
1344 | |
1345 ;;- nop instruction | |
1346 (define_insn "nop" | |
1347 [(const_int 0)] | |
1348 "" | |
1349 "nop") | |
1350 | |
1351 | |
1352 ;;- multiply | |
1353 | |
1354 (define_insn "muldf3" | |
1355 [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
1356 (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0") | |
1357 (match_operand:DF 2 "general_operand" "fR,Q,F")))] | |
1358 "TARGET_FPU" | |
1359 "{muld|mulf} %2, %0" | |
1360 [(set_attr "length" "1,2,5")]) | |
1361 | |
1362 ;; 16 bit result multiply: | |
1363 ;; currently we multiply only into odd registers, so we don't use two | |
1364 ;; registers - but this is a bit inefficient at times. If we define | |
1365 ;; a register class for each register, then we can specify properly | |
1366 ;; which register need which scratch register .... | |
1367 | |
1368 (define_insn "mulhi3" | |
1369 [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs | |
1370 (mult:HI (match_operand:HI 1 "register_operand" "%0,0") | |
1371 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1372 "TARGET_45" | |
1373 "mul %2, %0" | |
1374 [(set_attr "length" "1,2")]) | |
1375 | |
1376 ;; 32 bit result | |
1377 (define_expand "mulhisi3" | |
1378 [(set (match_dup 3) | |
1379 (match_operand:HI 1 "general_operand" "g,g")) | |
1380 (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! | |
1381 (mult:SI (truncate:HI | |
1382 (match_dup 0)) | |
1383 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1384 "TARGET_45" | |
1385 "operands[3] = gen_lowpart(HImode, operands[1]);") | |
1386 | |
1387 (define_insn "" | |
1388 [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! | |
1389 (mult:SI (truncate:HI | |
1390 (match_operand:SI 1 "register_operand" "%0,0")) | |
1391 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1392 "TARGET_45" | |
1393 "mul %2, %0" | |
1394 [(set_attr "length" "1,2")]) | |
1395 | |
1396 ;(define_insn "mulhisi3" | |
1397 ; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! | |
1398 ; (mult:SI (truncate:HI | |
1399 ; (match_operand:SI 1 "register_operand" "%0,0")) | |
1400 ; (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1401 ; "TARGET_45" | |
1402 ; "mul %2, %0" | |
1403 ; [(set_attr "length" "1,2")]) | |
1404 | |
1405 ;;- divide | |
1406 (define_insn "divdf3" | |
1407 [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
1408 (div:DF (match_operand:DF 1 "register_operand" "0,0,0") | |
1409 (match_operand:DF 2 "general_operand" "fR,Q,F")))] | |
1410 "TARGET_FPU" | |
1411 "{divd|divf} %2, %0" | |
1412 [(set_attr "length" "1,2,5")]) | |
1413 | |
1414 | |
1415 (define_expand "divhi3" | |
1416 [(set (subreg:HI (match_dup 1) 0) | |
1417 (div:HI (match_operand:SI 1 "general_operand" "0") | |
1418 (match_operand:HI 2 "general_operand" "g"))) | |
1419 (set (match_operand:HI 0 "general_operand" "=r") | |
1420 (subreg:HI (match_dup 1) 0))] | |
1421 "TARGET_45" | |
1422 "") | |
1423 | |
1424 (define_insn "" | |
1425 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) | |
1426 (div:HI (match_operand:SI 1 "general_operand" "0") | |
1427 (match_operand:HI 2 "general_operand" "g")))] | |
1428 "TARGET_45" | |
1429 "div %2,%0" | |
1430 [(set_attr "length" "2")]) | |
1431 | |
1432 (define_expand "modhi3" | |
1433 [(set (subreg:HI (match_dup 1) 2) | |
1434 (mod:HI (match_operand:SI 1 "general_operand" "0") | |
1435 (match_operand:HI 2 "general_operand" "g"))) | |
1436 (set (match_operand:HI 0 "general_operand" "=r") | |
1437 (subreg:HI (match_dup 1) 2))] | |
1438 "TARGET_45" | |
1439 "") | |
1440 | |
1441 (define_insn "" | |
1442 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2) | |
1443 (mod:HI (match_operand:SI 1 "general_operand" "0") | |
1444 (match_operand:HI 2 "general_operand" "g")))] | |
1445 "TARGET_45" | |
1446 "div %2,%0" | |
1447 [(set_attr "length" "2")]) | |
1448 | |
1449 ;(define_expand "divmodhi4" | |
1450 ; [(parallel [(set (subreg:HI (match_dup 1) 0) | |
1451 ; (div:HI (match_operand:SI 1 "general_operand" "0") | |
1452 ; (match_operand:HI 2 "general_operand" "g"))) | |
1453 ; (set (subreg:HI (match_dup 1) 2) | |
1454 ; (mod:HI (match_dup 1) | |
1455 ; (match_dup 2)))]) | |
1456 ; (set (match_operand:HI 3 "general_operand" "=r") | |
1457 ; (subreg:HI (match_dup 1) 2)) | |
1458 ; (set (match_operand:HI 0 "general_operand" "=r") | |
1459 ; (subreg:HI (match_dup 1) 0))] | |
1460 ; "TARGET_45" | |
1461 ; "") | |
1462 ; | |
1463 ;(define_insn "" | |
1464 ; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) | |
1465 ; (div:HI (match_operand:SI 1 "general_operand" "0") | |
1466 ; (match_operand:HI 2 "general_operand" "g"))) | |
1467 ; (set (subreg:HI (match_dup 0) 2) | |
1468 ; (mod:HI (match_dup 1) | |
1469 ; (match_dup 2)))] | |
1470 ; "TARGET_45" | |
1471 ; "div %2, %0") | |
1472 ; | |
1473 | |
1474 ;; is rotate doing the right thing to be included here ???? |