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