]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/optabs.c
formatting tweaks
[thirdparty/gcc.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include "config.h"
23 #include "rtl.h"
24 #include "tree.h"
25 #include "flags.h"
26 #include "insn-flags.h"
27 #include "insn-codes.h"
28 #include "expr.h"
29 #include "insn-config.h"
30 #include "recog.h"
31 #include "reload.h"
32 #include <ctype.h>
33
34 /* Each optab contains info on how this target machine
35 can perform a particular operation
36 for all sizes and kinds of operands.
37
38 The operation to be performed is often specified
39 by passing one of these optabs as an argument.
40
41 See expr.h for documentation of these optabs. */
42
43 optab add_optab;
44 optab sub_optab;
45 optab smul_optab;
46 optab smul_highpart_optab;
47 optab umul_highpart_optab;
48 optab smul_widen_optab;
49 optab umul_widen_optab;
50 optab sdiv_optab;
51 optab sdivmod_optab;
52 optab udiv_optab;
53 optab udivmod_optab;
54 optab smod_optab;
55 optab umod_optab;
56 optab flodiv_optab;
57 optab ftrunc_optab;
58 optab and_optab;
59 optab ior_optab;
60 optab xor_optab;
61 optab ashl_optab;
62 optab lshr_optab;
63 optab ashr_optab;
64 optab rotl_optab;
65 optab rotr_optab;
66 optab smin_optab;
67 optab smax_optab;
68 optab umin_optab;
69 optab umax_optab;
70
71 optab mov_optab;
72 optab movstrict_optab;
73
74 optab neg_optab;
75 optab abs_optab;
76 optab one_cmpl_optab;
77 optab ffs_optab;
78 optab sqrt_optab;
79 optab sin_optab;
80 optab cos_optab;
81
82 optab cmp_optab;
83 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
84 optab tst_optab;
85
86 optab strlen_optab;
87
88 /* Tables of patterns for extending one integer mode to another. */
89 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
90
91 /* Tables of patterns for converting between fixed and floating point. */
92 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
94 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
95
96 /* Contains the optab used for each rtx code. */
97 optab code_to_optab[NUM_RTX_CODE + 1];
98
99 /* SYMBOL_REF rtx's for the library functions that are called
100 implicitly and not via optabs. */
101
102 rtx extendsfdf2_libfunc;
103 rtx extendsfxf2_libfunc;
104 rtx extendsftf2_libfunc;
105 rtx extenddfxf2_libfunc;
106 rtx extenddftf2_libfunc;
107
108 rtx truncdfsf2_libfunc;
109 rtx truncxfsf2_libfunc;
110 rtx trunctfsf2_libfunc;
111 rtx truncxfdf2_libfunc;
112 rtx trunctfdf2_libfunc;
113
114 rtx memcpy_libfunc;
115 rtx bcopy_libfunc;
116 rtx memcmp_libfunc;
117 rtx bcmp_libfunc;
118 rtx memset_libfunc;
119 rtx bzero_libfunc;
120
121 rtx eqhf2_libfunc;
122 rtx nehf2_libfunc;
123 rtx gthf2_libfunc;
124 rtx gehf2_libfunc;
125 rtx lthf2_libfunc;
126 rtx lehf2_libfunc;
127
128 rtx eqsf2_libfunc;
129 rtx nesf2_libfunc;
130 rtx gtsf2_libfunc;
131 rtx gesf2_libfunc;
132 rtx ltsf2_libfunc;
133 rtx lesf2_libfunc;
134
135 rtx eqdf2_libfunc;
136 rtx nedf2_libfunc;
137 rtx gtdf2_libfunc;
138 rtx gedf2_libfunc;
139 rtx ltdf2_libfunc;
140 rtx ledf2_libfunc;
141
142 rtx eqxf2_libfunc;
143 rtx nexf2_libfunc;
144 rtx gtxf2_libfunc;
145 rtx gexf2_libfunc;
146 rtx ltxf2_libfunc;
147 rtx lexf2_libfunc;
148
149 rtx eqtf2_libfunc;
150 rtx netf2_libfunc;
151 rtx gttf2_libfunc;
152 rtx getf2_libfunc;
153 rtx lttf2_libfunc;
154 rtx letf2_libfunc;
155
156 rtx floatsisf_libfunc;
157 rtx floatdisf_libfunc;
158 rtx floattisf_libfunc;
159
160 rtx floatsidf_libfunc;
161 rtx floatdidf_libfunc;
162 rtx floattidf_libfunc;
163
164 rtx floatsixf_libfunc;
165 rtx floatdixf_libfunc;
166 rtx floattixf_libfunc;
167
168 rtx floatsitf_libfunc;
169 rtx floatditf_libfunc;
170 rtx floattitf_libfunc;
171
172 rtx fixsfsi_libfunc;
173 rtx fixsfdi_libfunc;
174 rtx fixsfti_libfunc;
175
176 rtx fixdfsi_libfunc;
177 rtx fixdfdi_libfunc;
178 rtx fixdfti_libfunc;
179
180 rtx fixxfsi_libfunc;
181 rtx fixxfdi_libfunc;
182 rtx fixxfti_libfunc;
183
184 rtx fixtfsi_libfunc;
185 rtx fixtfdi_libfunc;
186 rtx fixtfti_libfunc;
187
188 rtx fixunssfsi_libfunc;
189 rtx fixunssfdi_libfunc;
190 rtx fixunssfti_libfunc;
191
192 rtx fixunsdfsi_libfunc;
193 rtx fixunsdfdi_libfunc;
194 rtx fixunsdfti_libfunc;
195
196 rtx fixunsxfsi_libfunc;
197 rtx fixunsxfdi_libfunc;
198 rtx fixunsxfti_libfunc;
199
200 rtx fixunstfsi_libfunc;
201 rtx fixunstfdi_libfunc;
202 rtx fixunstfti_libfunc;
203
204 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
205 gives the gen_function to make a branch to test that condition. */
206
207 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
208
209 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
210 gives the insn code to make a store-condition insn
211 to test that condition. */
212
213 enum insn_code setcc_gen_code[NUM_RTX_CODE];
214
215 #ifdef HAVE_conditional_move
216 /* Indexed by the machine mode, gives the insn code to make a conditional
217 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
218 setcc_gen_code to cut down on the number of named patterns. Consider a day
219 when a lot more rtx codes are conditional (eg: for the ARM). */
220
221 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
222 #endif
223
224 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
225 static rtx widen_operand PROTO((rtx, enum machine_mode,
226 enum machine_mode, int, int));
227 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
228 int, int *));
229 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
230 int));
231 static rtx ftruncify PROTO((rtx));
232 static optab init_optab PROTO((enum rtx_code));
233 static void init_libfuncs PROTO((optab, int, int, char *, int));
234 static void init_integral_libfuncs PROTO((optab, char *, int));
235 static void init_floating_libfuncs PROTO((optab, char *, int));
236 static void init_complex_libfuncs PROTO((optab, char *, int));
237 \f
238 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
239 the result of operation CODE applied to OP0 (and OP1 if it is a binary
240 operation).
241
242 If the last insn does not set TARGET, don't do anything, but return 1.
243
244 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
245 don't add the REG_EQUAL note but return 0. Our caller can then try
246 again, ensuring that TARGET is not one of the operands. */
247
248 static int
249 add_equal_note (seq, target, code, op0, op1)
250 rtx seq;
251 rtx target;
252 enum rtx_code code;
253 rtx op0, op1;
254 {
255 rtx set;
256 int i;
257 rtx note;
258
259 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
260 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
261 || GET_CODE (seq) != SEQUENCE
262 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
263 || GET_CODE (target) == ZERO_EXTRACT
264 || (! rtx_equal_p (SET_DEST (set), target)
265 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
266 SUBREG. */
267 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
268 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
269 target))))
270 return 1;
271
272 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
273 besides the last insn. */
274 if (reg_overlap_mentioned_p (target, op0)
275 || (op1 && reg_overlap_mentioned_p (target, op1)))
276 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
277 if (reg_set_p (target, XVECEXP (seq, 0, i)))
278 return 0;
279
280 if (GET_RTX_CLASS (code) == '1')
281 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
282 else
283 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
284
285 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
286 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
287 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
288
289 return 1;
290 }
291 \f
292 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
293 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
294 not actually do a sign-extend or zero-extend, but can leave the
295 higher-order bits of the result rtx undefined, for example, in the case
296 of logical operations, but not right shifts. */
297
298 static rtx
299 widen_operand (op, mode, oldmode, unsignedp, no_extend)
300 rtx op;
301 enum machine_mode mode, oldmode;
302 int unsignedp;
303 int no_extend;
304 {
305 rtx result;
306
307 /* If we must extend do so. If OP is either a constant or a SUBREG
308 for a promoted object, also extend since it will be more efficient to
309 do so. */
310 if (! no_extend
311 || GET_MODE (op) == VOIDmode
312 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
313 return convert_modes (mode, oldmode, op, unsignedp);
314
315 /* If MODE is no wider than a single word, we return a paradoxical
316 SUBREG. */
317 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
318 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
319
320 /* Otherwise, get an object of MODE, clobber it, and set the low-order
321 part to OP. */
322
323 result = gen_reg_rtx (mode);
324 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
325 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
326 return result;
327 }
328 \f
329 /* Generate code to perform an operation specified by BINOPTAB
330 on operands OP0 and OP1, with result having machine-mode MODE.
331
332 UNSIGNEDP is for the case where we have to widen the operands
333 to perform the operation. It says to use zero-extension.
334
335 If TARGET is nonzero, the value
336 is generated there, if it is convenient to do so.
337 In all cases an rtx is returned for the locus of the value;
338 this may or may not be TARGET. */
339
340 rtx
341 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
342 enum machine_mode mode;
343 optab binoptab;
344 rtx op0, op1;
345 rtx target;
346 int unsignedp;
347 enum optab_methods methods;
348 {
349 enum optab_methods next_methods
350 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
351 ? OPTAB_WIDEN : methods);
352 enum mode_class class;
353 enum machine_mode wider_mode;
354 register rtx temp;
355 int commutative_op = 0;
356 int shift_op = (binoptab->code == ASHIFT
357 || binoptab->code == ASHIFTRT
358 || binoptab->code == LSHIFTRT
359 || binoptab->code == ROTATE
360 || binoptab->code == ROTATERT);
361 rtx entry_last = get_last_insn ();
362 rtx last;
363
364 class = GET_MODE_CLASS (mode);
365
366 op0 = protect_from_queue (op0, 0);
367 op1 = protect_from_queue (op1, 0);
368 if (target)
369 target = protect_from_queue (target, 1);
370
371 if (flag_force_mem)
372 {
373 op0 = force_not_mem (op0);
374 op1 = force_not_mem (op1);
375 }
376
377 /* If subtracting an integer constant, convert this into an addition of
378 the negated constant. */
379
380 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
381 {
382 op1 = negate_rtx (mode, op1);
383 binoptab = add_optab;
384 }
385
386 /* If we are inside an appropriately-short loop and one operand is an
387 expensive constant, force it into a register. */
388 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
389 && rtx_cost (op0, binoptab->code) > 2)
390 op0 = force_reg (mode, op0);
391
392 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
393 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
394 op1 = force_reg (mode, op1);
395
396 /* Record where to delete back to if we backtrack. */
397 last = get_last_insn ();
398
399 /* If operation is commutative,
400 try to make the first operand a register.
401 Even better, try to make it the same as the target.
402 Also try to make the last operand a constant. */
403 if (GET_RTX_CLASS (binoptab->code) == 'c'
404 || binoptab == smul_widen_optab
405 || binoptab == umul_widen_optab
406 || binoptab == smul_highpart_optab
407 || binoptab == umul_highpart_optab)
408 {
409 commutative_op = 1;
410
411 if (((target == 0 || GET_CODE (target) == REG)
412 ? ((GET_CODE (op1) == REG
413 && GET_CODE (op0) != REG)
414 || target == op1)
415 : rtx_equal_p (op1, target))
416 || GET_CODE (op0) == CONST_INT)
417 {
418 temp = op1;
419 op1 = op0;
420 op0 = temp;
421 }
422 }
423
424 /* If we can do it with a three-operand insn, do so. */
425
426 if (methods != OPTAB_MUST_WIDEN
427 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
428 {
429 int icode = (int) binoptab->handlers[(int) mode].insn_code;
430 enum machine_mode mode0 = insn_operand_mode[icode][1];
431 enum machine_mode mode1 = insn_operand_mode[icode][2];
432 rtx pat;
433 rtx xop0 = op0, xop1 = op1;
434
435 if (target)
436 temp = target;
437 else
438 temp = gen_reg_rtx (mode);
439
440 /* If it is a commutative operator and the modes would match
441 if we would swap the operands, we can save the conversions. */
442 if (commutative_op)
443 {
444 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
445 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
446 {
447 register rtx tmp;
448
449 tmp = op0; op0 = op1; op1 = tmp;
450 tmp = xop0; xop0 = xop1; xop1 = tmp;
451 }
452 }
453
454 /* In case the insn wants input operands in modes different from
455 the result, convert the operands. */
456
457 if (GET_MODE (op0) != VOIDmode
458 && GET_MODE (op0) != mode0
459 && mode0 != VOIDmode)
460 xop0 = convert_to_mode (mode0, xop0, unsignedp);
461
462 if (GET_MODE (xop1) != VOIDmode
463 && GET_MODE (xop1) != mode1
464 && mode1 != VOIDmode)
465 xop1 = convert_to_mode (mode1, xop1, unsignedp);
466
467 /* Now, if insn's predicates don't allow our operands, put them into
468 pseudo regs. */
469
470 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
471 && mode0 != VOIDmode)
472 xop0 = copy_to_mode_reg (mode0, xop0);
473
474 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
475 && mode1 != VOIDmode)
476 xop1 = copy_to_mode_reg (mode1, xop1);
477
478 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
479 temp = gen_reg_rtx (mode);
480
481 pat = GEN_FCN (icode) (temp, xop0, xop1);
482 if (pat)
483 {
484 /* If PAT is a multi-insn sequence, try to add an appropriate
485 REG_EQUAL note to it. If we can't because TEMP conflicts with an
486 operand, call ourselves again, this time without a target. */
487 if (GET_CODE (pat) == SEQUENCE
488 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
489 {
490 delete_insns_since (last);
491 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
492 unsignedp, methods);
493 }
494
495 emit_insn (pat);
496 return temp;
497 }
498 else
499 delete_insns_since (last);
500 }
501
502 /* If this is a multiply, see if we can do a widening operation that
503 takes operands of this mode and makes a wider mode. */
504
505 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
506 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
507 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
508 != CODE_FOR_nothing))
509 {
510 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
511 unsignedp ? umul_widen_optab : smul_widen_optab,
512 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
513
514 if (temp != 0)
515 {
516 if (GET_MODE_CLASS (mode) == MODE_INT)
517 return gen_lowpart (mode, temp);
518 else
519 return convert_to_mode (mode, temp, unsignedp);
520 }
521 }
522
523 /* Look for a wider mode of the same class for which we think we
524 can open-code the operation. Check for a widening multiply at the
525 wider mode as well. */
526
527 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
528 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
529 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
530 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
531 {
532 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
533 || (binoptab == smul_optab
534 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
535 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
536 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
537 != CODE_FOR_nothing)))
538 {
539 rtx xop0 = op0, xop1 = op1;
540 int no_extend = 0;
541
542 /* For certain integer operations, we need not actually extend
543 the narrow operands, as long as we will truncate
544 the results to the same narrowness. */
545
546 if ((binoptab == ior_optab || binoptab == and_optab
547 || binoptab == xor_optab
548 || binoptab == add_optab || binoptab == sub_optab
549 || binoptab == smul_optab || binoptab == ashl_optab)
550 && class == MODE_INT)
551 no_extend = 1;
552
553 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
554
555 /* The second operand of a shift must always be extended. */
556 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
557 no_extend && binoptab != ashl_optab);
558
559 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
560 unsignedp, OPTAB_DIRECT);
561 if (temp)
562 {
563 if (class != MODE_INT)
564 {
565 if (target == 0)
566 target = gen_reg_rtx (mode);
567 convert_move (target, temp, 0);
568 return target;
569 }
570 else
571 return gen_lowpart (mode, temp);
572 }
573 else
574 delete_insns_since (last);
575 }
576 }
577
578 /* These can be done a word at a time. */
579 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
580 && class == MODE_INT
581 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
582 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
583 {
584 int i;
585 rtx insns;
586 rtx equiv_value;
587
588 /* If TARGET is the same as one of the operands, the REG_EQUAL note
589 won't be accurate, so use a new target. */
590 if (target == 0 || target == op0 || target == op1)
591 target = gen_reg_rtx (mode);
592
593 start_sequence ();
594
595 /* Do the actual arithmetic. */
596 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
597 {
598 rtx target_piece = operand_subword (target, i, 1, mode);
599 rtx x = expand_binop (word_mode, binoptab,
600 operand_subword_force (op0, i, mode),
601 operand_subword_force (op1, i, mode),
602 target_piece, unsignedp, next_methods);
603
604 if (x == 0)
605 break;
606
607 if (target_piece != x)
608 emit_move_insn (target_piece, x);
609 }
610
611 insns = get_insns ();
612 end_sequence ();
613
614 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
615 {
616 if (binoptab->code != UNKNOWN)
617 equiv_value
618 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
619 else
620 equiv_value = 0;
621
622 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
623 return target;
624 }
625 }
626
627 /* Synthesize double word shifts from single word shifts. */
628 if ((binoptab == lshr_optab || binoptab == ashl_optab
629 || binoptab == ashr_optab)
630 && class == MODE_INT
631 && GET_CODE (op1) == CONST_INT
632 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
633 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
634 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
635 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
636 {
637 rtx insns, inter, equiv_value;
638 rtx into_target, outof_target;
639 rtx into_input, outof_input;
640 int shift_count, left_shift, outof_word;
641
642 /* If TARGET is the same as one of the operands, the REG_EQUAL note
643 won't be accurate, so use a new target. */
644 if (target == 0 || target == op0 || target == op1)
645 target = gen_reg_rtx (mode);
646
647 start_sequence ();
648
649 shift_count = INTVAL (op1);
650
651 /* OUTOF_* is the word we are shifting bits away from, and
652 INTO_* is the word that we are shifting bits towards, thus
653 they differ depending on the direction of the shift and
654 WORDS_BIG_ENDIAN. */
655
656 left_shift = binoptab == ashl_optab;
657 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
658
659 outof_target = operand_subword (target, outof_word, 1, mode);
660 into_target = operand_subword (target, 1 - outof_word, 1, mode);
661
662 outof_input = operand_subword_force (op0, outof_word, mode);
663 into_input = operand_subword_force (op0, 1 - outof_word, mode);
664
665 if (shift_count >= BITS_PER_WORD)
666 {
667 inter = expand_binop (word_mode, binoptab,
668 outof_input,
669 GEN_INT (shift_count - BITS_PER_WORD),
670 into_target, unsignedp, next_methods);
671
672 if (inter != 0 && inter != into_target)
673 emit_move_insn (into_target, inter);
674
675 /* For a signed right shift, we must fill the word we are shifting
676 out of with copies of the sign bit. Otherwise it is zeroed. */
677 if (inter != 0 && binoptab != ashr_optab)
678 inter = CONST0_RTX (word_mode);
679 else if (inter != 0)
680 inter = expand_binop (word_mode, binoptab,
681 outof_input,
682 GEN_INT (BITS_PER_WORD - 1),
683 outof_target, unsignedp, next_methods);
684
685 if (inter != 0 && inter != outof_target)
686 emit_move_insn (outof_target, inter);
687 }
688 else
689 {
690 rtx carries;
691 optab reverse_unsigned_shift, unsigned_shift;
692
693 /* For a shift of less then BITS_PER_WORD, to compute the carry,
694 we must do a logical shift in the opposite direction of the
695 desired shift. */
696
697 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
698
699 /* For a shift of less than BITS_PER_WORD, to compute the word
700 shifted towards, we need to unsigned shift the orig value of
701 that word. */
702
703 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
704
705 carries = expand_binop (word_mode, reverse_unsigned_shift,
706 outof_input,
707 GEN_INT (BITS_PER_WORD - shift_count),
708 0, unsignedp, next_methods);
709
710 if (carries == 0)
711 inter = 0;
712 else
713 inter = expand_binop (word_mode, unsigned_shift, into_input,
714 op1, 0, unsignedp, next_methods);
715
716 if (inter != 0)
717 inter = expand_binop (word_mode, ior_optab, carries, inter,
718 into_target, unsignedp, next_methods);
719
720 if (inter != 0 && inter != into_target)
721 emit_move_insn (into_target, inter);
722
723 if (inter != 0)
724 inter = expand_binop (word_mode, binoptab, outof_input,
725 op1, outof_target, unsignedp, next_methods);
726
727 if (inter != 0 && inter != outof_target)
728 emit_move_insn (outof_target, inter);
729 }
730
731 insns = get_insns ();
732 end_sequence ();
733
734 if (inter != 0)
735 {
736 if (binoptab->code != UNKNOWN)
737 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
738 else
739 equiv_value = 0;
740
741 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
742 return target;
743 }
744 }
745
746 /* Synthesize double word rotates from single word shifts. */
747 if ((binoptab == rotl_optab || binoptab == rotr_optab)
748 && class == MODE_INT
749 && GET_CODE (op1) == CONST_INT
750 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
751 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
752 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
753 {
754 rtx insns, equiv_value;
755 rtx into_target, outof_target;
756 rtx into_input, outof_input;
757 rtx inter;
758 int shift_count, left_shift, outof_word;
759
760 /* If TARGET is the same as one of the operands, the REG_EQUAL note
761 won't be accurate, so use a new target. */
762 if (target == 0 || target == op0 || target == op1)
763 target = gen_reg_rtx (mode);
764
765 start_sequence ();
766
767 shift_count = INTVAL (op1);
768
769 /* OUTOF_* is the word we are shifting bits away from, and
770 INTO_* is the word that we are shifting bits towards, thus
771 they differ depending on the direction of the shift and
772 WORDS_BIG_ENDIAN. */
773
774 left_shift = (binoptab == rotl_optab);
775 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
776
777 outof_target = operand_subword (target, outof_word, 1, mode);
778 into_target = operand_subword (target, 1 - outof_word, 1, mode);
779
780 outof_input = operand_subword_force (op0, outof_word, mode);
781 into_input = operand_subword_force (op0, 1 - outof_word, mode);
782
783 if (shift_count == BITS_PER_WORD)
784 {
785 /* This is just a word swap. */
786 emit_move_insn (outof_target, into_input);
787 emit_move_insn (into_target, outof_input);
788 inter = const0_rtx;
789 }
790 else
791 {
792 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
793 rtx first_shift_count, second_shift_count;
794 optab reverse_unsigned_shift, unsigned_shift;
795
796 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
797 ? lshr_optab : ashl_optab);
798
799 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
800 ? ashl_optab : lshr_optab);
801
802 if (shift_count > BITS_PER_WORD)
803 {
804 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
805 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
806 }
807 else
808 {
809 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
810 second_shift_count = GEN_INT (shift_count);
811 }
812
813 into_temp1 = expand_binop (word_mode, unsigned_shift,
814 outof_input, first_shift_count,
815 NULL_RTX, unsignedp, next_methods);
816 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
817 into_input, second_shift_count,
818 into_target, unsignedp, next_methods);
819
820 if (into_temp1 != 0 && into_temp2 != 0)
821 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
822 into_target, unsignedp, next_methods);
823 else
824 inter = 0;
825
826 if (inter != 0 && inter != into_target)
827 emit_move_insn (into_target, inter);
828
829 outof_temp1 = expand_binop (word_mode, unsigned_shift,
830 into_input, first_shift_count,
831 NULL_RTX, unsignedp, next_methods);
832 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
833 outof_input, second_shift_count,
834 outof_target, unsignedp, next_methods);
835
836 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
837 inter = expand_binop (word_mode, ior_optab,
838 outof_temp1, outof_temp2,
839 outof_target, unsignedp, next_methods);
840
841 if (inter != 0 && inter != outof_target)
842 emit_move_insn (outof_target, inter);
843 }
844
845 insns = get_insns ();
846 end_sequence ();
847
848 if (inter != 0)
849 {
850 if (binoptab->code != UNKNOWN)
851 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
852 else
853 equiv_value = 0;
854
855 /* We can't make this a no conflict block if this is a word swap,
856 because the word swap case fails if the input and output values
857 are in the same register. */
858 if (shift_count != BITS_PER_WORD)
859 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
860 else
861 emit_insns (insns);
862
863
864 return target;
865 }
866 }
867
868 /* These can be done a word at a time by propagating carries. */
869 if ((binoptab == add_optab || binoptab == sub_optab)
870 && class == MODE_INT
871 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
872 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
873 {
874 int i;
875 rtx carry_tmp = gen_reg_rtx (word_mode);
876 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
877 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
878 rtx carry_in, carry_out;
879 rtx xop0, xop1;
880
881 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
882 value is one of those, use it. Otherwise, use 1 since it is the
883 one easiest to get. */
884 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
885 int normalizep = STORE_FLAG_VALUE;
886 #else
887 int normalizep = 1;
888 #endif
889
890 /* Prepare the operands. */
891 xop0 = force_reg (mode, op0);
892 xop1 = force_reg (mode, op1);
893
894 if (target == 0 || GET_CODE (target) != REG
895 || target == xop0 || target == xop1)
896 target = gen_reg_rtx (mode);
897
898 /* Indicate for flow that the entire target reg is being set. */
899 if (GET_CODE (target) == REG)
900 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
901
902 /* Do the actual arithmetic. */
903 for (i = 0; i < nwords; i++)
904 {
905 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
906 rtx target_piece = operand_subword (target, index, 1, mode);
907 rtx op0_piece = operand_subword_force (xop0, index, mode);
908 rtx op1_piece = operand_subword_force (xop1, index, mode);
909 rtx x;
910
911 /* Main add/subtract of the input operands. */
912 x = expand_binop (word_mode, binoptab,
913 op0_piece, op1_piece,
914 target_piece, unsignedp, next_methods);
915 if (x == 0)
916 break;
917
918 if (i + 1 < nwords)
919 {
920 /* Store carry from main add/subtract. */
921 carry_out = gen_reg_rtx (word_mode);
922 carry_out = emit_store_flag (carry_out,
923 binoptab == add_optab ? LTU : GTU,
924 x, op0_piece,
925 word_mode, 1, normalizep);
926 if (carry_out == 0)
927 break;
928 }
929
930 if (i > 0)
931 {
932 /* Add/subtract previous carry to main result. */
933 x = expand_binop (word_mode,
934 normalizep == 1 ? binoptab : otheroptab,
935 x, carry_in,
936 target_piece, 1, next_methods);
937 if (x == 0)
938 break;
939 else if (target_piece != x)
940 emit_move_insn (target_piece, x);
941
942 if (i + 1 < nwords)
943 {
944 /* THIS CODE HAS NOT BEEN TESTED. */
945 /* Get out carry from adding/subtracting carry in. */
946 carry_tmp = emit_store_flag (carry_tmp,
947 binoptab == add_optab
948 ? LTU : GTU,
949 x, carry_in,
950 word_mode, 1, normalizep);
951
952 /* Logical-ior the two poss. carry together. */
953 carry_out = expand_binop (word_mode, ior_optab,
954 carry_out, carry_tmp,
955 carry_out, 0, next_methods);
956 if (carry_out == 0)
957 break;
958 }
959 }
960
961 carry_in = carry_out;
962 }
963
964 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
965 {
966 rtx temp = emit_move_insn (target, target);
967
968 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
969 gen_rtx (binoptab->code, mode,
970 copy_rtx (xop0),
971 copy_rtx (xop1)),
972 REG_NOTES (temp));
973 return target;
974 }
975 else
976 delete_insns_since (last);
977 }
978
979 /* If we want to multiply two two-word values and have normal and widening
980 multiplies of single-word values, we can do this with three smaller
981 multiplications. Note that we do not make a REG_NO_CONFLICT block here
982 because we are not operating on one word at a time.
983
984 The multiplication proceeds as follows:
985 _______________________
986 [__op0_high_|__op0_low__]
987 _______________________
988 * [__op1_high_|__op1_low__]
989 _______________________________________________
990 _______________________
991 (1) [__op0_low__*__op1_low__]
992 _______________________
993 (2a) [__op0_low__*__op1_high_]
994 _______________________
995 (2b) [__op0_high_*__op1_low__]
996 _______________________
997 (3) [__op0_high_*__op1_high_]
998
999
1000 This gives a 4-word result. Since we are only interested in the
1001 lower 2 words, partial result (3) and the upper words of (2a) and
1002 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1003 calculated using non-widening multiplication.
1004
1005 (1), however, needs to be calculated with an unsigned widening
1006 multiplication. If this operation is not directly supported we
1007 try using a signed widening multiplication and adjust the result.
1008 This adjustment works as follows:
1009
1010 If both operands are positive then no adjustment is needed.
1011
1012 If the operands have different signs, for example op0_low < 0 and
1013 op1_low >= 0, the instruction treats the most significant bit of
1014 op0_low as a sign bit instead of a bit with significance
1015 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1016 with 2**BITS_PER_WORD - op0_low, and two's complements the
1017 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1018 the result.
1019
1020 Similarly, if both operands are negative, we need to add
1021 (op0_low + op1_low) * 2**BITS_PER_WORD.
1022
1023 We use a trick to adjust quickly. We logically shift op0_low right
1024 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1025 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1026 logical shift exists, we do an arithmetic right shift and subtract
1027 the 0 or -1. */
1028
1029 if (binoptab == smul_optab
1030 && class == MODE_INT
1031 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1032 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1033 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1034 && ((umul_widen_optab->handlers[(int) mode].insn_code
1035 != CODE_FOR_nothing)
1036 || (smul_widen_optab->handlers[(int) mode].insn_code
1037 != CODE_FOR_nothing)))
1038 {
1039 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1040 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1041 rtx op0_high = operand_subword_force (op0, high, mode);
1042 rtx op0_low = operand_subword_force (op0, low, mode);
1043 rtx op1_high = operand_subword_force (op1, high, mode);
1044 rtx op1_low = operand_subword_force (op1, low, mode);
1045 rtx product = 0;
1046 rtx op0_xhigh;
1047 rtx op1_xhigh;
1048
1049 /* If the target is the same as one of the inputs, don't use it. This
1050 prevents problems with the REG_EQUAL note. */
1051 if (target == op0 || target == op1
1052 || (target != 0 && GET_CODE (target) != REG))
1053 target = 0;
1054
1055 /* Multiply the two lower words to get a double-word product.
1056 If unsigned widening multiplication is available, use that;
1057 otherwise use the signed form and compensate. */
1058
1059 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1060 {
1061 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1062 target, 1, OPTAB_DIRECT);
1063
1064 /* If we didn't succeed, delete everything we did so far. */
1065 if (product == 0)
1066 delete_insns_since (last);
1067 else
1068 op0_xhigh = op0_high, op1_xhigh = op1_high;
1069 }
1070
1071 if (product == 0
1072 && smul_widen_optab->handlers[(int) mode].insn_code
1073 != CODE_FOR_nothing)
1074 {
1075 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1076 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1077 target, 1, OPTAB_DIRECT);
1078 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1079 NULL_RTX, 1, next_methods);
1080 if (op0_xhigh)
1081 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1082 op0_xhigh, op0_xhigh, 0, next_methods);
1083 else
1084 {
1085 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1086 NULL_RTX, 0, next_methods);
1087 if (op0_xhigh)
1088 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1089 op0_xhigh, op0_xhigh, 0,
1090 next_methods);
1091 }
1092
1093 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1094 NULL_RTX, 1, next_methods);
1095 if (op1_xhigh)
1096 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1097 op1_xhigh, op1_xhigh, 0, next_methods);
1098 else
1099 {
1100 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1101 NULL_RTX, 0, next_methods);
1102 if (op1_xhigh)
1103 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1104 op1_xhigh, op1_xhigh, 0,
1105 next_methods);
1106 }
1107 }
1108
1109 /* If we have been able to directly compute the product of the
1110 low-order words of the operands and perform any required adjustments
1111 of the operands, we proceed by trying two more multiplications
1112 and then computing the appropriate sum.
1113
1114 We have checked above that the required addition is provided.
1115 Full-word addition will normally always succeed, especially if
1116 it is provided at all, so we don't worry about its failure. The
1117 multiplication may well fail, however, so we do handle that. */
1118
1119 if (product && op0_xhigh && op1_xhigh)
1120 {
1121 rtx product_high = operand_subword (product, high, 1, mode);
1122 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1123 NULL_RTX, 0, OPTAB_DIRECT);
1124
1125 if (temp != 0)
1126 temp = expand_binop (word_mode, add_optab, temp, product_high,
1127 product_high, 0, next_methods);
1128
1129 if (temp != 0 && temp != product_high)
1130 emit_move_insn (product_high, temp);
1131
1132 if (temp != 0)
1133 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1134 NULL_RTX, 0, OPTAB_DIRECT);
1135
1136 if (temp != 0)
1137 temp = expand_binop (word_mode, add_optab, temp,
1138 product_high, product_high,
1139 0, next_methods);
1140
1141 if (temp != 0 && temp != product_high)
1142 emit_move_insn (product_high, temp);
1143
1144 if (temp != 0)
1145 {
1146 temp = emit_move_insn (product, product);
1147 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1148 gen_rtx (MULT, mode, copy_rtx (op0),
1149 copy_rtx (op1)),
1150 REG_NOTES (temp));
1151
1152 return product;
1153 }
1154 }
1155
1156 /* If we get here, we couldn't do it for some reason even though we
1157 originally thought we could. Delete anything we've emitted in
1158 trying to do it. */
1159
1160 delete_insns_since (last);
1161 }
1162
1163 /* We need to open-code the complex type operations: '+, -, * and /' */
1164
1165 /* At this point we allow operations between two similar complex
1166 numbers, and also if one of the operands is not a complex number
1167 but rather of MODE_FLOAT or MODE_INT. However, the caller
1168 must make sure that the MODE of the non-complex operand matches
1169 the SUBMODE of the complex operand. */
1170
1171 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1172 {
1173 rtx real0 = 0, imag0 = 0;
1174 rtx real1 = 0, imag1 = 0;
1175 rtx realr, imagr, res;
1176 rtx seq;
1177 rtx equiv_value;
1178 int ok = 0;
1179
1180 /* Find the correct mode for the real and imaginary parts */
1181 enum machine_mode submode
1182 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1183 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1184 0);
1185
1186 if (submode == BLKmode)
1187 abort ();
1188
1189 if (! target)
1190 target = gen_reg_rtx (mode);
1191
1192 start_sequence ();
1193
1194 realr = gen_realpart (submode, target);
1195 imagr = gen_imagpart (submode, target);
1196
1197 if (GET_MODE (op0) == mode)
1198 {
1199 real0 = gen_realpart (submode, op0);
1200 imag0 = gen_imagpart (submode, op0);
1201 }
1202 else
1203 real0 = op0;
1204
1205 if (GET_MODE (op1) == mode)
1206 {
1207 real1 = gen_realpart (submode, op1);
1208 imag1 = gen_imagpart (submode, op1);
1209 }
1210 else
1211 real1 = op1;
1212
1213 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1214 abort ();
1215
1216 switch (binoptab->code)
1217 {
1218 case PLUS:
1219 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1220 case MINUS:
1221 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1222 res = expand_binop (submode, binoptab, real0, real1,
1223 realr, unsignedp, methods);
1224
1225 if (res == 0)
1226 break;
1227 else if (res != realr)
1228 emit_move_insn (realr, res);
1229
1230 if (imag0 && imag1)
1231 res = expand_binop (submode, binoptab, imag0, imag1,
1232 imagr, unsignedp, methods);
1233 else if (imag0)
1234 res = imag0;
1235 else if (binoptab->code == MINUS)
1236 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1237 else
1238 res = imag1;
1239
1240 if (res == 0)
1241 break;
1242 else if (res != imagr)
1243 emit_move_insn (imagr, res);
1244
1245 ok = 1;
1246 break;
1247
1248 case MULT:
1249 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1250
1251 if (imag0 && imag1)
1252 {
1253 rtx temp1, temp2;
1254
1255 /* Don't fetch these from memory more than once. */
1256 real0 = force_reg (submode, real0);
1257 real1 = force_reg (submode, real1);
1258 imag0 = force_reg (submode, imag0);
1259 imag1 = force_reg (submode, imag1);
1260
1261 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1262 unsignedp, methods);
1263
1264 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1265 unsignedp, methods);
1266
1267 if (temp1 == 0 || temp2 == 0)
1268 break;
1269
1270 res = expand_binop (submode, sub_optab, temp1, temp2,
1271 realr, unsignedp, methods);
1272
1273 if (res == 0)
1274 break;
1275 else if (res != realr)
1276 emit_move_insn (realr, res);
1277
1278 temp1 = expand_binop (submode, binoptab, real0, imag1,
1279 NULL_RTX, unsignedp, methods);
1280
1281 temp2 = expand_binop (submode, binoptab, real1, imag0,
1282 NULL_RTX, unsignedp, methods);
1283
1284 if (temp1 == 0 || temp2 == 0)
1285 break;
1286
1287 res = expand_binop (submode, add_optab, temp1, temp2,
1288 imagr, unsignedp, methods);
1289
1290 if (res == 0)
1291 break;
1292 else if (res != imagr)
1293 emit_move_insn (imagr, res);
1294
1295 ok = 1;
1296 }
1297 else
1298 {
1299 /* Don't fetch these from memory more than once. */
1300 real0 = force_reg (submode, real0);
1301 real1 = force_reg (submode, real1);
1302
1303 res = expand_binop (submode, binoptab, real0, real1,
1304 realr, unsignedp, methods);
1305 if (res == 0)
1306 break;
1307 else if (res != realr)
1308 emit_move_insn (realr, res);
1309
1310 if (imag0 != 0)
1311 res = expand_binop (submode, binoptab,
1312 real1, imag0, imagr, unsignedp, methods);
1313 else
1314 res = expand_binop (submode, binoptab,
1315 real0, imag1, imagr, unsignedp, methods);
1316
1317 if (res == 0)
1318 break;
1319 else if (res != imagr)
1320 emit_move_insn (imagr, res);
1321
1322 ok = 1;
1323 }
1324 break;
1325
1326 case DIV:
1327 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1328
1329 if (imag1 == 0)
1330 {
1331 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1332
1333 /* Don't fetch these from memory more than once. */
1334 real1 = force_reg (submode, real1);
1335
1336 /* Simply divide the real and imaginary parts by `c' */
1337 if (class == MODE_COMPLEX_FLOAT)
1338 res = expand_binop (submode, binoptab, real0, real1,
1339 realr, unsignedp, methods);
1340 else
1341 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1342 real0, real1, realr, unsignedp);
1343
1344 if (res == 0)
1345 break;
1346 else if (res != realr)
1347 emit_move_insn (realr, res);
1348
1349 if (class == MODE_COMPLEX_FLOAT)
1350 res = expand_binop (submode, binoptab, imag0, real1,
1351 imagr, unsignedp, methods);
1352 else
1353 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1354 imag0, real1, imagr, unsignedp);
1355
1356 if (res == 0)
1357 break;
1358 else if (res != imagr)
1359 emit_move_insn (imagr, res);
1360
1361 ok = 1;
1362 }
1363 else
1364 {
1365 /* Divisor is of complex type:
1366 X/(a+ib) */
1367 rtx divisor;
1368 rtx real_t, imag_t;
1369 rtx lhs, rhs;
1370 rtx temp1, temp2;
1371
1372 /* Don't fetch these from memory more than once. */
1373 real0 = force_reg (submode, real0);
1374 real1 = force_reg (submode, real1);
1375
1376 if (imag0 != 0)
1377 imag0 = force_reg (submode, imag0);
1378
1379 imag1 = force_reg (submode, imag1);
1380
1381 /* Divisor: c*c + d*d */
1382 temp1 = expand_binop (submode, smul_optab, real1, real1,
1383 NULL_RTX, unsignedp, methods);
1384
1385 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1386 NULL_RTX, unsignedp, methods);
1387
1388 if (temp1 == 0 || temp2 == 0)
1389 break;
1390
1391 divisor = expand_binop (submode, add_optab, temp1, temp2,
1392 NULL_RTX, unsignedp, methods);
1393 if (divisor == 0)
1394 break;
1395
1396 if (imag0 == 0)
1397 {
1398 /* ((a)(c-id))/divisor */
1399 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1400
1401 /* Calculate the dividend */
1402 real_t = expand_binop (submode, smul_optab, real0, real1,
1403 NULL_RTX, unsignedp, methods);
1404
1405 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1406 NULL_RTX, unsignedp, methods);
1407
1408 if (real_t == 0 || imag_t == 0)
1409 break;
1410
1411 imag_t = expand_unop (submode, neg_optab, imag_t,
1412 NULL_RTX, unsignedp);
1413 }
1414 else
1415 {
1416 /* ((a+ib)(c-id))/divider */
1417 /* Calculate the dividend */
1418 temp1 = expand_binop (submode, smul_optab, real0, real1,
1419 NULL_RTX, unsignedp, methods);
1420
1421 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1422 NULL_RTX, unsignedp, methods);
1423
1424 if (temp1 == 0 || temp2 == 0)
1425 break;
1426
1427 real_t = expand_binop (submode, add_optab, temp1, temp2,
1428 NULL_RTX, unsignedp, methods);
1429
1430 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1431 NULL_RTX, unsignedp, methods);
1432
1433 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1434 NULL_RTX, unsignedp, methods);
1435
1436 if (temp1 == 0 || temp2 == 0)
1437 break;
1438
1439 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1440 NULL_RTX, unsignedp, methods);
1441
1442 if (real_t == 0 || imag_t == 0)
1443 break;
1444 }
1445
1446 if (class == MODE_COMPLEX_FLOAT)
1447 res = expand_binop (submode, binoptab, real_t, divisor,
1448 realr, unsignedp, methods);
1449 else
1450 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1451 real_t, divisor, realr, unsignedp);
1452
1453 if (res == 0)
1454 break;
1455 else if (res != realr)
1456 emit_move_insn (realr, res);
1457
1458 if (class == MODE_COMPLEX_FLOAT)
1459 res = expand_binop (submode, binoptab, imag_t, divisor,
1460 imagr, unsignedp, methods);
1461 else
1462 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1463 imag_t, divisor, imagr, unsignedp);
1464
1465 if (res == 0)
1466 break;
1467 else if (res != imagr)
1468 emit_move_insn (imagr, res);
1469
1470 ok = 1;
1471 }
1472 break;
1473
1474 default:
1475 abort ();
1476 }
1477
1478 seq = get_insns ();
1479 end_sequence ();
1480
1481 if (ok)
1482 {
1483 if (binoptab->code != UNKNOWN)
1484 equiv_value
1485 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1486 else
1487 equiv_value = 0;
1488
1489 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1490
1491 return target;
1492 }
1493 }
1494
1495 /* It can't be open-coded in this mode.
1496 Use a library call if one is available and caller says that's ok. */
1497
1498 if (binoptab->handlers[(int) mode].libfunc
1499 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1500 {
1501 rtx insns;
1502 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1503 rtx op1x = op1;
1504 enum machine_mode op1_mode = mode;
1505 rtx value;
1506
1507 start_sequence ();
1508
1509 if (shift_op)
1510 {
1511 op1_mode = word_mode;
1512 /* Specify unsigned here,
1513 since negative shift counts are meaningless. */
1514 op1x = convert_to_mode (word_mode, op1, 1);
1515 }
1516
1517 if (GET_MODE (op0) != VOIDmode
1518 && GET_MODE (op0) != mode)
1519 op0 = convert_to_mode (mode, op0, unsignedp);
1520
1521 /* Pass 1 for NO_QUEUE so we don't lose any increments
1522 if the libcall is cse'd or moved. */
1523 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1524 NULL_RTX, 1, mode, 2,
1525 op0, mode, op1x, op1_mode);
1526
1527 insns = get_insns ();
1528 end_sequence ();
1529
1530 target = gen_reg_rtx (mode);
1531 emit_libcall_block (insns, target, value,
1532 gen_rtx (binoptab->code, mode, op0, op1));
1533
1534 return target;
1535 }
1536
1537 delete_insns_since (last);
1538
1539 /* It can't be done in this mode. Can we do it in a wider mode? */
1540
1541 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1542 || methods == OPTAB_MUST_WIDEN))
1543 {
1544 /* Caller says, don't even try. */
1545 delete_insns_since (entry_last);
1546 return 0;
1547 }
1548
1549 /* Compute the value of METHODS to pass to recursive calls.
1550 Don't allow widening to be tried recursively. */
1551
1552 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1553
1554 /* Look for a wider mode of the same class for which it appears we can do
1555 the operation. */
1556
1557 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1558 {
1559 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1560 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1561 {
1562 if ((binoptab->handlers[(int) wider_mode].insn_code
1563 != CODE_FOR_nothing)
1564 || (methods == OPTAB_LIB
1565 && binoptab->handlers[(int) wider_mode].libfunc))
1566 {
1567 rtx xop0 = op0, xop1 = op1;
1568 int no_extend = 0;
1569
1570 /* For certain integer operations, we need not actually extend
1571 the narrow operands, as long as we will truncate
1572 the results to the same narrowness. */
1573
1574 if ((binoptab == ior_optab || binoptab == and_optab
1575 || binoptab == xor_optab
1576 || binoptab == add_optab || binoptab == sub_optab
1577 || binoptab == smul_optab || binoptab == ashl_optab)
1578 && class == MODE_INT)
1579 no_extend = 1;
1580
1581 xop0 = widen_operand (xop0, wider_mode, mode,
1582 unsignedp, no_extend);
1583
1584 /* The second operand of a shift must always be extended. */
1585 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1586 no_extend && binoptab != ashl_optab);
1587
1588 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1589 unsignedp, methods);
1590 if (temp)
1591 {
1592 if (class != MODE_INT)
1593 {
1594 if (target == 0)
1595 target = gen_reg_rtx (mode);
1596 convert_move (target, temp, 0);
1597 return target;
1598 }
1599 else
1600 return gen_lowpart (mode, temp);
1601 }
1602 else
1603 delete_insns_since (last);
1604 }
1605 }
1606 }
1607
1608 delete_insns_since (entry_last);
1609 return 0;
1610 }
1611 \f
1612 /* Expand a binary operator which has both signed and unsigned forms.
1613 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1614 signed operations.
1615
1616 If we widen unsigned operands, we may use a signed wider operation instead
1617 of an unsigned wider operation, since the result would be the same. */
1618
1619 rtx
1620 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1621 enum machine_mode mode;
1622 optab uoptab, soptab;
1623 rtx op0, op1, target;
1624 int unsignedp;
1625 enum optab_methods methods;
1626 {
1627 register rtx temp;
1628 optab direct_optab = unsignedp ? uoptab : soptab;
1629 struct optab wide_soptab;
1630
1631 /* Do it without widening, if possible. */
1632 temp = expand_binop (mode, direct_optab, op0, op1, target,
1633 unsignedp, OPTAB_DIRECT);
1634 if (temp || methods == OPTAB_DIRECT)
1635 return temp;
1636
1637 /* Try widening to a signed int. Make a fake signed optab that
1638 hides any signed insn for direct use. */
1639 wide_soptab = *soptab;
1640 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1641 wide_soptab.handlers[(int) mode].libfunc = 0;
1642
1643 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1644 unsignedp, OPTAB_WIDEN);
1645
1646 /* For unsigned operands, try widening to an unsigned int. */
1647 if (temp == 0 && unsignedp)
1648 temp = expand_binop (mode, uoptab, op0, op1, target,
1649 unsignedp, OPTAB_WIDEN);
1650 if (temp || methods == OPTAB_WIDEN)
1651 return temp;
1652
1653 /* Use the right width lib call if that exists. */
1654 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1655 if (temp || methods == OPTAB_LIB)
1656 return temp;
1657
1658 /* Must widen and use a lib call, use either signed or unsigned. */
1659 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1660 unsignedp, methods);
1661 if (temp != 0)
1662 return temp;
1663 if (unsignedp)
1664 return expand_binop (mode, uoptab, op0, op1, target,
1665 unsignedp, methods);
1666 return 0;
1667 }
1668 \f
1669 /* Generate code to perform an operation specified by BINOPTAB
1670 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1671 We assume that the order of the operands for the instruction
1672 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1673 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1674
1675 Either TARG0 or TARG1 may be zero, but what that means is that
1676 that result is not actually wanted. We will generate it into
1677 a dummy pseudo-reg and discard it. They may not both be zero.
1678
1679 Returns 1 if this operation can be performed; 0 if not. */
1680
1681 int
1682 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1683 optab binoptab;
1684 rtx op0, op1;
1685 rtx targ0, targ1;
1686 int unsignedp;
1687 {
1688 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1689 enum mode_class class;
1690 enum machine_mode wider_mode;
1691 rtx entry_last = get_last_insn ();
1692 rtx last;
1693
1694 class = GET_MODE_CLASS (mode);
1695
1696 op0 = protect_from_queue (op0, 0);
1697 op1 = protect_from_queue (op1, 0);
1698
1699 if (flag_force_mem)
1700 {
1701 op0 = force_not_mem (op0);
1702 op1 = force_not_mem (op1);
1703 }
1704
1705 /* If we are inside an appropriately-short loop and one operand is an
1706 expensive constant, force it into a register. */
1707 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1708 && rtx_cost (op0, binoptab->code) > 2)
1709 op0 = force_reg (mode, op0);
1710
1711 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1712 && rtx_cost (op1, binoptab->code) > 2)
1713 op1 = force_reg (mode, op1);
1714
1715 if (targ0)
1716 targ0 = protect_from_queue (targ0, 1);
1717 else
1718 targ0 = gen_reg_rtx (mode);
1719 if (targ1)
1720 targ1 = protect_from_queue (targ1, 1);
1721 else
1722 targ1 = gen_reg_rtx (mode);
1723
1724 /* Record where to go back to if we fail. */
1725 last = get_last_insn ();
1726
1727 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1728 {
1729 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1730 enum machine_mode mode0 = insn_operand_mode[icode][1];
1731 enum machine_mode mode1 = insn_operand_mode[icode][2];
1732 rtx pat;
1733 rtx xop0 = op0, xop1 = op1;
1734
1735 /* In case this insn wants input operands in modes different from the
1736 result, convert the operands. */
1737 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1738 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1739
1740 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1741 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1742
1743 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1744 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1745 xop0 = copy_to_mode_reg (mode0, xop0);
1746
1747 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1748 xop1 = copy_to_mode_reg (mode1, xop1);
1749
1750 /* We could handle this, but we should always be called with a pseudo
1751 for our targets and all insns should take them as outputs. */
1752 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1753 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1754 abort ();
1755
1756 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1757 if (pat)
1758 {
1759 emit_insn (pat);
1760 return 1;
1761 }
1762 else
1763 delete_insns_since (last);
1764 }
1765
1766 /* It can't be done in this mode. Can we do it in a wider mode? */
1767
1768 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1769 {
1770 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1771 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1772 {
1773 if (binoptab->handlers[(int) wider_mode].insn_code
1774 != CODE_FOR_nothing)
1775 {
1776 register rtx t0 = gen_reg_rtx (wider_mode);
1777 register rtx t1 = gen_reg_rtx (wider_mode);
1778
1779 if (expand_twoval_binop (binoptab,
1780 convert_modes (wider_mode, mode, op0,
1781 unsignedp),
1782 convert_modes (wider_mode, mode, op1,
1783 unsignedp),
1784 t0, t1, unsignedp))
1785 {
1786 convert_move (targ0, t0, unsignedp);
1787 convert_move (targ1, t1, unsignedp);
1788 return 1;
1789 }
1790 else
1791 delete_insns_since (last);
1792 }
1793 }
1794 }
1795
1796 delete_insns_since (entry_last);
1797 return 0;
1798 }
1799 \f
1800 /* Generate code to perform an operation specified by UNOPTAB
1801 on operand OP0, with result having machine-mode MODE.
1802
1803 UNSIGNEDP is for the case where we have to widen the operands
1804 to perform the operation. It says to use zero-extension.
1805
1806 If TARGET is nonzero, the value
1807 is generated there, if it is convenient to do so.
1808 In all cases an rtx is returned for the locus of the value;
1809 this may or may not be TARGET. */
1810
1811 rtx
1812 expand_unop (mode, unoptab, op0, target, unsignedp)
1813 enum machine_mode mode;
1814 optab unoptab;
1815 rtx op0;
1816 rtx target;
1817 int unsignedp;
1818 {
1819 enum mode_class class;
1820 enum machine_mode wider_mode;
1821 register rtx temp;
1822 rtx last = get_last_insn ();
1823 rtx pat;
1824
1825 class = GET_MODE_CLASS (mode);
1826
1827 op0 = protect_from_queue (op0, 0);
1828
1829 if (flag_force_mem)
1830 {
1831 op0 = force_not_mem (op0);
1832 }
1833
1834 if (target)
1835 target = protect_from_queue (target, 1);
1836
1837 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1838 {
1839 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1840 enum machine_mode mode0 = insn_operand_mode[icode][1];
1841 rtx xop0 = op0;
1842
1843 if (target)
1844 temp = target;
1845 else
1846 temp = gen_reg_rtx (mode);
1847
1848 if (GET_MODE (xop0) != VOIDmode
1849 && GET_MODE (xop0) != mode0)
1850 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1851
1852 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1853
1854 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1855 xop0 = copy_to_mode_reg (mode0, xop0);
1856
1857 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1858 temp = gen_reg_rtx (mode);
1859
1860 pat = GEN_FCN (icode) (temp, xop0);
1861 if (pat)
1862 {
1863 if (GET_CODE (pat) == SEQUENCE
1864 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1865 {
1866 delete_insns_since (last);
1867 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1868 }
1869
1870 emit_insn (pat);
1871
1872 return temp;
1873 }
1874 else
1875 delete_insns_since (last);
1876 }
1877
1878 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1879
1880 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1881 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1882 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1883 {
1884 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1885 {
1886 rtx xop0 = op0;
1887
1888 /* For certain operations, we need not actually extend
1889 the narrow operand, as long as we will truncate the
1890 results to the same narrowness. */
1891
1892 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1893 (unoptab == neg_optab
1894 || unoptab == one_cmpl_optab)
1895 && class == MODE_INT);
1896
1897 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1898 unsignedp);
1899
1900 if (temp)
1901 {
1902 if (class != MODE_INT)
1903 {
1904 if (target == 0)
1905 target = gen_reg_rtx (mode);
1906 convert_move (target, temp, 0);
1907 return target;
1908 }
1909 else
1910 return gen_lowpart (mode, temp);
1911 }
1912 else
1913 delete_insns_since (last);
1914 }
1915 }
1916
1917 /* These can be done a word at a time. */
1918 if (unoptab == one_cmpl_optab
1919 && class == MODE_INT
1920 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1921 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1922 {
1923 int i;
1924 rtx insns;
1925
1926 if (target == 0 || target == op0)
1927 target = gen_reg_rtx (mode);
1928
1929 start_sequence ();
1930
1931 /* Do the actual arithmetic. */
1932 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1933 {
1934 rtx target_piece = operand_subword (target, i, 1, mode);
1935 rtx x = expand_unop (word_mode, unoptab,
1936 operand_subword_force (op0, i, mode),
1937 target_piece, unsignedp);
1938 if (target_piece != x)
1939 emit_move_insn (target_piece, x);
1940 }
1941
1942 insns = get_insns ();
1943 end_sequence ();
1944
1945 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1946 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1947 return target;
1948 }
1949
1950 /* Open-code the complex negation operation. */
1951 else if (unoptab == neg_optab
1952 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1953 {
1954 rtx target_piece;
1955 rtx x;
1956 rtx seq;
1957
1958 /* Find the correct mode for the real and imaginary parts */
1959 enum machine_mode submode
1960 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1961 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1962 0);
1963
1964 if (submode == BLKmode)
1965 abort ();
1966
1967 if (target == 0)
1968 target = gen_reg_rtx (mode);
1969
1970 start_sequence ();
1971
1972 target_piece = gen_imagpart (submode, target);
1973 x = expand_unop (submode, unoptab,
1974 gen_imagpart (submode, op0),
1975 target_piece, unsignedp);
1976 if (target_piece != x)
1977 emit_move_insn (target_piece, x);
1978
1979 target_piece = gen_realpart (submode, target);
1980 x = expand_unop (submode, unoptab,
1981 gen_realpart (submode, op0),
1982 target_piece, unsignedp);
1983 if (target_piece != x)
1984 emit_move_insn (target_piece, x);
1985
1986 seq = get_insns ();
1987 end_sequence ();
1988
1989 emit_no_conflict_block (seq, target, op0, 0,
1990 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1991 return target;
1992 }
1993
1994 /* Now try a library call in this mode. */
1995 if (unoptab->handlers[(int) mode].libfunc)
1996 {
1997 rtx insns;
1998 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1999 rtx value;
2000
2001 start_sequence ();
2002
2003 /* Pass 1 for NO_QUEUE so we don't lose any increments
2004 if the libcall is cse'd or moved. */
2005 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2006 NULL_RTX, 1, mode, 1, op0, mode);
2007 insns = get_insns ();
2008 end_sequence ();
2009
2010 target = gen_reg_rtx (mode);
2011 emit_libcall_block (insns, target, value,
2012 gen_rtx (unoptab->code, mode, op0));
2013
2014 return target;
2015 }
2016
2017 /* It can't be done in this mode. Can we do it in a wider mode? */
2018
2019 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2020 {
2021 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2022 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2023 {
2024 if ((unoptab->handlers[(int) wider_mode].insn_code
2025 != CODE_FOR_nothing)
2026 || unoptab->handlers[(int) wider_mode].libfunc)
2027 {
2028 rtx xop0 = op0;
2029
2030 /* For certain operations, we need not actually extend
2031 the narrow operand, as long as we will truncate the
2032 results to the same narrowness. */
2033
2034 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2035 (unoptab == neg_optab
2036 || unoptab == one_cmpl_optab)
2037 && class == MODE_INT);
2038
2039 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2040 unsignedp);
2041
2042 if (temp)
2043 {
2044 if (class != MODE_INT)
2045 {
2046 if (target == 0)
2047 target = gen_reg_rtx (mode);
2048 convert_move (target, temp, 0);
2049 return target;
2050 }
2051 else
2052 return gen_lowpart (mode, temp);
2053 }
2054 else
2055 delete_insns_since (last);
2056 }
2057 }
2058 }
2059
2060 /* If there is no negate operation, try doing a subtract from zero.
2061 The US Software GOFAST library needs this. */
2062 if (unoptab == neg_optab)
2063 {
2064 rtx temp;
2065 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2066 target, unsignedp, OPTAB_LIB_WIDEN);
2067 if (temp)
2068 return temp;
2069 }
2070
2071 return 0;
2072 }
2073 \f
2074 /* Emit code to compute the absolute value of OP0, with result to
2075 TARGET if convenient. (TARGET may be 0.) The return value says
2076 where the result actually is to be found.
2077
2078 MODE is the mode of the operand; the mode of the result is
2079 different but can be deduced from MODE.
2080
2081 UNSIGNEDP is relevant if extension is needed. */
2082
2083 rtx
2084 expand_abs (mode, op0, target, unsignedp, safe)
2085 enum machine_mode mode;
2086 rtx op0;
2087 rtx target;
2088 int unsignedp;
2089 int safe;
2090 {
2091 rtx temp, op1;
2092
2093 /* First try to do it with a special abs instruction. */
2094 temp = expand_unop (mode, abs_optab, op0, target, 0);
2095 if (temp != 0)
2096 return temp;
2097
2098 /* If this machine has expensive jumps, we can do integer absolute
2099 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2100 where W is the width of MODE. */
2101
2102 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2103 {
2104 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2105 size_int (GET_MODE_BITSIZE (mode) - 1),
2106 NULL_RTX, 0);
2107
2108 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2109 OPTAB_LIB_WIDEN);
2110 if (temp != 0)
2111 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2112 OPTAB_LIB_WIDEN);
2113
2114 if (temp != 0)
2115 return temp;
2116 }
2117
2118 /* If that does not win, use conditional jump and negate. */
2119 op1 = gen_label_rtx ();
2120 if (target == 0 || ! safe
2121 || GET_MODE (target) != mode
2122 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2123 || (GET_CODE (target) == REG
2124 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2125 target = gen_reg_rtx (mode);
2126
2127 emit_move_insn (target, op0);
2128 NO_DEFER_POP;
2129
2130 /* If this mode is an integer too wide to compare properly,
2131 compare word by word. Rely on CSE to optimize constant cases. */
2132 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2133 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2134 NULL_RTX, op1);
2135 else
2136 {
2137 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2138 NULL_RTX, 0);
2139 if (temp == const1_rtx)
2140 return target;
2141 else if (temp != const0_rtx)
2142 {
2143 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2144 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2145 else
2146 abort ();
2147 }
2148 }
2149
2150 op0 = expand_unop (mode, neg_optab, target, target, 0);
2151 if (op0 != target)
2152 emit_move_insn (target, op0);
2153 emit_label (op1);
2154 OK_DEFER_POP;
2155 return target;
2156 }
2157 \f
2158 /* Emit code to compute the absolute value of OP0, with result to
2159 TARGET if convenient. (TARGET may be 0.) The return value says
2160 where the result actually is to be found.
2161
2162 MODE is the mode of the operand; the mode of the result is
2163 different but can be deduced from MODE.
2164
2165 UNSIGNEDP is relevant for complex integer modes. */
2166
2167 rtx
2168 expand_complex_abs (mode, op0, target, unsignedp)
2169 enum machine_mode mode;
2170 rtx op0;
2171 rtx target;
2172 int unsignedp;
2173 {
2174 enum mode_class class = GET_MODE_CLASS (mode);
2175 enum machine_mode wider_mode;
2176 register rtx temp;
2177 rtx entry_last = get_last_insn ();
2178 rtx last;
2179 rtx pat;
2180
2181 /* Find the correct mode for the real and imaginary parts. */
2182 enum machine_mode submode
2183 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2184 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2185 0);
2186
2187 if (submode == BLKmode)
2188 abort ();
2189
2190 op0 = protect_from_queue (op0, 0);
2191
2192 if (flag_force_mem)
2193 {
2194 op0 = force_not_mem (op0);
2195 }
2196
2197 last = get_last_insn ();
2198
2199 if (target)
2200 target = protect_from_queue (target, 1);
2201
2202 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2203 {
2204 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2205 enum machine_mode mode0 = insn_operand_mode[icode][1];
2206 rtx xop0 = op0;
2207
2208 if (target)
2209 temp = target;
2210 else
2211 temp = gen_reg_rtx (submode);
2212
2213 if (GET_MODE (xop0) != VOIDmode
2214 && GET_MODE (xop0) != mode0)
2215 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2216
2217 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2218
2219 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2220 xop0 = copy_to_mode_reg (mode0, xop0);
2221
2222 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2223 temp = gen_reg_rtx (submode);
2224
2225 pat = GEN_FCN (icode) (temp, xop0);
2226 if (pat)
2227 {
2228 if (GET_CODE (pat) == SEQUENCE
2229 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2230 {
2231 delete_insns_since (last);
2232 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2233 }
2234
2235 emit_insn (pat);
2236
2237 return temp;
2238 }
2239 else
2240 delete_insns_since (last);
2241 }
2242
2243 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2244
2245 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2246 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2247 {
2248 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2249 {
2250 rtx xop0 = op0;
2251
2252 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2253 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2254
2255 if (temp)
2256 {
2257 if (class != MODE_COMPLEX_INT)
2258 {
2259 if (target == 0)
2260 target = gen_reg_rtx (submode);
2261 convert_move (target, temp, 0);
2262 return target;
2263 }
2264 else
2265 return gen_lowpart (submode, temp);
2266 }
2267 else
2268 delete_insns_since (last);
2269 }
2270 }
2271
2272 /* Open-code the complex absolute-value operation
2273 if we can open-code sqrt. Otherwise it's not worth while. */
2274 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2275 {
2276 rtx real, imag, total;
2277
2278 real = gen_realpart (submode, op0);
2279 imag = gen_imagpart (submode, op0);
2280
2281 /* Square both parts. */
2282 real = expand_mult (submode, real, real, NULL_RTX, 0);
2283 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2284
2285 /* Sum the parts. */
2286 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2287 0, OPTAB_LIB_WIDEN);
2288
2289 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2290 target = expand_unop (submode, sqrt_optab, total, target, 0);
2291 if (target == 0)
2292 delete_insns_since (last);
2293 else
2294 return target;
2295 }
2296
2297 /* Now try a library call in this mode. */
2298 if (abs_optab->handlers[(int) mode].libfunc)
2299 {
2300 rtx insns;
2301 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2302 rtx value;
2303
2304 start_sequence ();
2305
2306 /* Pass 1 for NO_QUEUE so we don't lose any increments
2307 if the libcall is cse'd or moved. */
2308 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2309 NULL_RTX, 1, submode, 1, op0, mode);
2310 insns = get_insns ();
2311 end_sequence ();
2312
2313 target = gen_reg_rtx (submode);
2314 emit_libcall_block (insns, target, value,
2315 gen_rtx (abs_optab->code, mode, op0));
2316
2317 return target;
2318 }
2319
2320 /* It can't be done in this mode. Can we do it in a wider mode? */
2321
2322 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2323 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2324 {
2325 if ((abs_optab->handlers[(int) wider_mode].insn_code
2326 != CODE_FOR_nothing)
2327 || abs_optab->handlers[(int) wider_mode].libfunc)
2328 {
2329 rtx xop0 = op0;
2330
2331 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2332
2333 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2334
2335 if (temp)
2336 {
2337 if (class != MODE_COMPLEX_INT)
2338 {
2339 if (target == 0)
2340 target = gen_reg_rtx (submode);
2341 convert_move (target, temp, 0);
2342 return target;
2343 }
2344 else
2345 return gen_lowpart (submode, temp);
2346 }
2347 else
2348 delete_insns_since (last);
2349 }
2350 }
2351
2352 delete_insns_since (entry_last);
2353 return 0;
2354 }
2355 \f
2356 /* Generate an instruction whose insn-code is INSN_CODE,
2357 with two operands: an output TARGET and an input OP0.
2358 TARGET *must* be nonzero, and the output is always stored there.
2359 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2360 the value that is stored into TARGET. */
2361
2362 void
2363 emit_unop_insn (icode, target, op0, code)
2364 int icode;
2365 rtx target;
2366 rtx op0;
2367 enum rtx_code code;
2368 {
2369 register rtx temp;
2370 enum machine_mode mode0 = insn_operand_mode[icode][1];
2371 rtx pat;
2372
2373 temp = target = protect_from_queue (target, 1);
2374
2375 op0 = protect_from_queue (op0, 0);
2376
2377 /* Sign extension from memory is often done specially on RISC
2378 machines, so forcing into a register here can pessimize code. */
2379 if (flag_force_mem && code != SIGN_EXTEND)
2380 op0 = force_not_mem (op0);
2381
2382 /* Now, if insn does not accept our operands, put them into pseudos. */
2383
2384 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2385 op0 = copy_to_mode_reg (mode0, op0);
2386
2387 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2388 || (flag_force_mem && GET_CODE (temp) == MEM))
2389 temp = gen_reg_rtx (GET_MODE (temp));
2390
2391 pat = GEN_FCN (icode) (temp, op0);
2392
2393 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2394 add_equal_note (pat, temp, code, op0, NULL_RTX);
2395
2396 emit_insn (pat);
2397
2398 if (temp != target)
2399 emit_move_insn (target, temp);
2400 }
2401 \f
2402 /* Emit code to perform a series of operations on a multi-word quantity, one
2403 word at a time.
2404
2405 Such a block is preceded by a CLOBBER of the output, consists of multiple
2406 insns, each setting one word of the output, and followed by a SET copying
2407 the output to itself.
2408
2409 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2410 note indicating that it doesn't conflict with the (also multi-word)
2411 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2412 notes.
2413
2414 INSNS is a block of code generated to perform the operation, not including
2415 the CLOBBER and final copy. All insns that compute intermediate values
2416 are first emitted, followed by the block as described above.
2417
2418 TARGET, OP0, and OP1 are the output and inputs of the operations,
2419 respectively. OP1 may be zero for a unary operation.
2420
2421 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2422 on the last insn.
2423
2424 If TARGET is not a register, INSNS is simply emitted with no special
2425 processing. Likewise if anything in INSNS is not an INSN or if
2426 there is a libcall block inside INSNS.
2427
2428 The final insn emitted is returned. */
2429
2430 rtx
2431 emit_no_conflict_block (insns, target, op0, op1, equiv)
2432 rtx insns;
2433 rtx target;
2434 rtx op0, op1;
2435 rtx equiv;
2436 {
2437 rtx prev, next, first, last, insn;
2438
2439 if (GET_CODE (target) != REG || reload_in_progress)
2440 return emit_insns (insns);
2441 else
2442 for (insn = insns; insn; insn = NEXT_INSN (insn))
2443 if (GET_CODE (insn) != INSN
2444 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2445 return emit_insns (insns);
2446
2447 /* First emit all insns that do not store into words of the output and remove
2448 these from the list. */
2449 for (insn = insns; insn; insn = next)
2450 {
2451 rtx set = 0;
2452 int i;
2453
2454 next = NEXT_INSN (insn);
2455
2456 if (GET_CODE (PATTERN (insn)) == SET)
2457 set = PATTERN (insn);
2458 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2459 {
2460 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2461 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2462 {
2463 set = XVECEXP (PATTERN (insn), 0, i);
2464 break;
2465 }
2466 }
2467
2468 if (set == 0)
2469 abort ();
2470
2471 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2472 {
2473 if (PREV_INSN (insn))
2474 NEXT_INSN (PREV_INSN (insn)) = next;
2475 else
2476 insns = next;
2477
2478 if (next)
2479 PREV_INSN (next) = PREV_INSN (insn);
2480
2481 add_insn (insn);
2482 }
2483 }
2484
2485 prev = get_last_insn ();
2486
2487 /* Now write the CLOBBER of the output, followed by the setting of each
2488 of the words, followed by the final copy. */
2489 if (target != op0 && target != op1)
2490 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2491
2492 for (insn = insns; insn; insn = next)
2493 {
2494 next = NEXT_INSN (insn);
2495 add_insn (insn);
2496
2497 if (op1 && GET_CODE (op1) == REG)
2498 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2499 REG_NOTES (insn));
2500
2501 if (op0 && GET_CODE (op0) == REG)
2502 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2503 REG_NOTES (insn));
2504 }
2505
2506 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2507 != CODE_FOR_nothing)
2508 {
2509 last = emit_move_insn (target, target);
2510 if (equiv)
2511 REG_NOTES (last)
2512 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2513 }
2514 else
2515 last = get_last_insn ();
2516
2517 if (prev == 0)
2518 first = get_insns ();
2519 else
2520 first = NEXT_INSN (prev);
2521
2522 /* Encapsulate the block so it gets manipulated as a unit. */
2523 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2524 REG_NOTES (first));
2525 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2526
2527 return last;
2528 }
2529 \f
2530 /* Emit code to make a call to a constant function or a library call.
2531
2532 INSNS is a list containing all insns emitted in the call.
2533 These insns leave the result in RESULT. Our block is to copy RESULT
2534 to TARGET, which is logically equivalent to EQUIV.
2535
2536 We first emit any insns that set a pseudo on the assumption that these are
2537 loading constants into registers; doing so allows them to be safely cse'ed
2538 between blocks. Then we emit all the other insns in the block, followed by
2539 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2540 note with an operand of EQUIV.
2541
2542 Moving assignments to pseudos outside of the block is done to improve
2543 the generated code, but is not required to generate correct code,
2544 hence being unable to move an assignment is not grounds for not making
2545 a libcall block. There are two reasons why it is safe to leave these
2546 insns inside the block: First, we know that these pseudos cannot be
2547 used in generated RTL outside the block since they are created for
2548 temporary purposes within the block. Second, CSE will not record the
2549 values of anything set inside a libcall block, so we know they must
2550 be dead at the end of the block.
2551
2552 Except for the first group of insns (the ones setting pseudos), the
2553 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2554
2555 void
2556 emit_libcall_block (insns, target, result, equiv)
2557 rtx insns;
2558 rtx target;
2559 rtx result;
2560 rtx equiv;
2561 {
2562 rtx prev, next, first, last, insn;
2563
2564 /* First emit all insns that set pseudos. Remove them from the list as
2565 we go. Avoid insns that set pseudos which were referenced in previous
2566 insns. These can be generated by move_by_pieces, for example,
2567 to update an address. Similarly, avoid insns that reference things
2568 set in previous insns. */
2569
2570 for (insn = insns; insn; insn = next)
2571 {
2572 rtx set = single_set (insn);
2573
2574 next = NEXT_INSN (insn);
2575
2576 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2577 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2578 && (insn == insns
2579 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2580 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2581 && ! modified_in_p (SET_SRC (set), insns)
2582 && ! modified_between_p (SET_SRC (set), insns, insn))))
2583 {
2584 if (PREV_INSN (insn))
2585 NEXT_INSN (PREV_INSN (insn)) = next;
2586 else
2587 insns = next;
2588
2589 if (next)
2590 PREV_INSN (next) = PREV_INSN (insn);
2591
2592 add_insn (insn);
2593 }
2594 }
2595
2596 prev = get_last_insn ();
2597
2598 /* Write the remaining insns followed by the final copy. */
2599
2600 for (insn = insns; insn; insn = next)
2601 {
2602 next = NEXT_INSN (insn);
2603
2604 add_insn (insn);
2605 }
2606
2607 last = emit_move_insn (target, result);
2608 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2609 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2610
2611 if (prev == 0)
2612 first = get_insns ();
2613 else
2614 first = NEXT_INSN (prev);
2615
2616 /* Encapsulate the block so it gets manipulated as a unit. */
2617 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2618 REG_NOTES (first));
2619 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2620 }
2621 \f
2622 /* Generate code to store zero in X. */
2623
2624 void
2625 emit_clr_insn (x)
2626 rtx x;
2627 {
2628 emit_move_insn (x, const0_rtx);
2629 }
2630
2631 /* Generate code to store 1 in X
2632 assuming it contains zero beforehand. */
2633
2634 void
2635 emit_0_to_1_insn (x)
2636 rtx x;
2637 {
2638 emit_move_insn (x, const1_rtx);
2639 }
2640
2641 /* Generate code to compare X with Y
2642 so that the condition codes are set.
2643
2644 MODE is the mode of the inputs (in case they are const_int).
2645 UNSIGNEDP nonzero says that X and Y are unsigned;
2646 this matters if they need to be widened.
2647
2648 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2649 and ALIGN specifies the known shared alignment of X and Y.
2650
2651 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2652 It is ignored for fixed-point and block comparisons;
2653 it is used only for floating-point comparisons. */
2654
2655 void
2656 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2657 rtx x, y;
2658 enum rtx_code comparison;
2659 rtx size;
2660 enum machine_mode mode;
2661 int unsignedp;
2662 int align;
2663 {
2664 enum mode_class class;
2665 enum machine_mode wider_mode;
2666
2667 class = GET_MODE_CLASS (mode);
2668
2669 /* They could both be VOIDmode if both args are immediate constants,
2670 but we should fold that at an earlier stage.
2671 With no special code here, this will call abort,
2672 reminding the programmer to implement such folding. */
2673
2674 if (mode != BLKmode && flag_force_mem)
2675 {
2676 x = force_not_mem (x);
2677 y = force_not_mem (y);
2678 }
2679
2680 /* If we are inside an appropriately-short loop and one operand is an
2681 expensive constant, force it into a register. */
2682 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2683 x = force_reg (mode, x);
2684
2685 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2686 y = force_reg (mode, y);
2687
2688 /* Don't let both operands fail to indicate the mode. */
2689 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2690 x = force_reg (mode, x);
2691
2692 /* Handle all BLKmode compares. */
2693
2694 if (mode == BLKmode)
2695 {
2696 emit_queue ();
2697 x = protect_from_queue (x, 0);
2698 y = protect_from_queue (y, 0);
2699
2700 if (size == 0)
2701 abort ();
2702 #ifdef HAVE_cmpstrqi
2703 if (HAVE_cmpstrqi
2704 && GET_CODE (size) == CONST_INT
2705 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2706 {
2707 enum machine_mode result_mode
2708 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2709 rtx result = gen_reg_rtx (result_mode);
2710 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2711 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2712 result_mode, 0, 0);
2713 }
2714 else
2715 #endif
2716 #ifdef HAVE_cmpstrhi
2717 if (HAVE_cmpstrhi
2718 && GET_CODE (size) == CONST_INT
2719 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2720 {
2721 enum machine_mode result_mode
2722 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2723 rtx result = gen_reg_rtx (result_mode);
2724 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2725 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2726 result_mode, 0, 0);
2727 }
2728 else
2729 #endif
2730 #ifdef HAVE_cmpstrsi
2731 if (HAVE_cmpstrsi)
2732 {
2733 enum machine_mode result_mode
2734 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2735 rtx result = gen_reg_rtx (result_mode);
2736 size = protect_from_queue (size, 0);
2737 emit_insn (gen_cmpstrsi (result, x, y,
2738 convert_to_mode (SImode, size, 1),
2739 GEN_INT (align)));
2740 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2741 result_mode, 0, 0);
2742 }
2743 else
2744 #endif
2745 {
2746 rtx result;
2747
2748 #ifdef TARGET_MEM_FUNCTIONS
2749 emit_library_call (memcmp_libfunc, 0,
2750 TYPE_MODE (integer_type_node), 3,
2751 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2752 convert_to_mode (TYPE_MODE (sizetype), size,
2753 TREE_UNSIGNED (sizetype)),
2754 TYPE_MODE (sizetype));
2755 #else
2756 emit_library_call (bcmp_libfunc, 0,
2757 TYPE_MODE (integer_type_node), 3,
2758 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2759 convert_to_mode (TYPE_MODE (integer_type_node),
2760 size,
2761 TREE_UNSIGNED (integer_type_node)),
2762 TYPE_MODE (integer_type_node));
2763 #endif
2764
2765 /* Immediately move the result of the libcall into a pseudo
2766 register so reload doesn't clobber the value if it needs
2767 the return register for a spill reg. */
2768 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
2769 emit_move_insn (result,
2770 hard_libcall_value (TYPE_MODE (integer_type_node)));
2771 emit_cmp_insn (result,
2772 const0_rtx, comparison, NULL_RTX,
2773 TYPE_MODE (integer_type_node), 0, 0);
2774 }
2775 return;
2776 }
2777
2778 /* Handle some compares against zero. */
2779
2780 if (y == CONST0_RTX (mode)
2781 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2782 {
2783 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2784
2785 emit_queue ();
2786 x = protect_from_queue (x, 0);
2787 y = protect_from_queue (y, 0);
2788
2789 /* Now, if insn does accept these operands, put them into pseudos. */
2790 if (! (*insn_operand_predicate[icode][0])
2791 (x, insn_operand_mode[icode][0]))
2792 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2793
2794 emit_insn (GEN_FCN (icode) (x));
2795 return;
2796 }
2797
2798 /* Handle compares for which there is a directly suitable insn. */
2799
2800 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2801 {
2802 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2803
2804 emit_queue ();
2805 x = protect_from_queue (x, 0);
2806 y = protect_from_queue (y, 0);
2807
2808 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2809 if (! (*insn_operand_predicate[icode][0])
2810 (x, insn_operand_mode[icode][0]))
2811 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2812
2813 if (! (*insn_operand_predicate[icode][1])
2814 (y, insn_operand_mode[icode][1]))
2815 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2816
2817 emit_insn (GEN_FCN (icode) (x, y));
2818 return;
2819 }
2820
2821 /* Try widening if we can find a direct insn that way. */
2822
2823 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2824 {
2825 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2826 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2827 {
2828 if (cmp_optab->handlers[(int) wider_mode].insn_code
2829 != CODE_FOR_nothing)
2830 {
2831 x = protect_from_queue (x, 0);
2832 y = protect_from_queue (y, 0);
2833 x = convert_modes (wider_mode, mode, x, unsignedp);
2834 y = convert_modes (wider_mode, mode, y, unsignedp);
2835 emit_cmp_insn (x, y, comparison, NULL_RTX,
2836 wider_mode, unsignedp, align);
2837 return;
2838 }
2839 }
2840 }
2841
2842 /* Handle a lib call just for the mode we are using. */
2843
2844 if (cmp_optab->handlers[(int) mode].libfunc
2845 && class != MODE_FLOAT)
2846 {
2847 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2848 rtx result;
2849
2850 /* If we want unsigned, and this mode has a distinct unsigned
2851 comparison routine, use that. */
2852 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2853 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2854
2855 emit_library_call (libfunc, 1,
2856 word_mode, 2, x, mode, y, mode);
2857
2858 /* Immediately move the result of the libcall into a pseudo
2859 register so reload doesn't clobber the value if it needs
2860 the return register for a spill reg. */
2861 result = gen_reg_rtx (word_mode);
2862 emit_move_insn (result, hard_libcall_value (word_mode));
2863
2864 /* Integer comparison returns a result that must be compared against 1,
2865 so that even if we do an unsigned compare afterward,
2866 there is still a value that can represent the result "less than". */
2867 emit_cmp_insn (result, const1_rtx,
2868 comparison, NULL_RTX, word_mode, unsignedp, 0);
2869 return;
2870 }
2871
2872 if (class == MODE_FLOAT)
2873 emit_float_lib_cmp (x, y, comparison);
2874
2875 else
2876 abort ();
2877 }
2878
2879 /* Nonzero if a compare of mode MODE can be done straightforwardly
2880 (without splitting it into pieces). */
2881
2882 int
2883 can_compare_p (mode)
2884 enum machine_mode mode;
2885 {
2886 do
2887 {
2888 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2889 return 1;
2890 mode = GET_MODE_WIDER_MODE (mode);
2891 } while (mode != VOIDmode);
2892
2893 return 0;
2894 }
2895 \f
2896 /* Emit a library call comparison between floating point X and Y.
2897 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2898
2899 void
2900 emit_float_lib_cmp (x, y, comparison)
2901 rtx x, y;
2902 enum rtx_code comparison;
2903 {
2904 enum machine_mode mode = GET_MODE (x);
2905 rtx libfunc = 0;
2906 rtx result;
2907
2908 if (mode == HFmode)
2909 switch (comparison)
2910 {
2911 case EQ:
2912 libfunc = eqhf2_libfunc;
2913 break;
2914
2915 case NE:
2916 libfunc = nehf2_libfunc;
2917 break;
2918
2919 case GT:
2920 libfunc = gthf2_libfunc;
2921 break;
2922
2923 case GE:
2924 libfunc = gehf2_libfunc;
2925 break;
2926
2927 case LT:
2928 libfunc = lthf2_libfunc;
2929 break;
2930
2931 case LE:
2932 libfunc = lehf2_libfunc;
2933 break;
2934 }
2935 else if (mode == SFmode)
2936 switch (comparison)
2937 {
2938 case EQ:
2939 libfunc = eqsf2_libfunc;
2940 break;
2941
2942 case NE:
2943 libfunc = nesf2_libfunc;
2944 break;
2945
2946 case GT:
2947 libfunc = gtsf2_libfunc;
2948 break;
2949
2950 case GE:
2951 libfunc = gesf2_libfunc;
2952 break;
2953
2954 case LT:
2955 libfunc = ltsf2_libfunc;
2956 break;
2957
2958 case LE:
2959 libfunc = lesf2_libfunc;
2960 break;
2961 }
2962 else if (mode == DFmode)
2963 switch (comparison)
2964 {
2965 case EQ:
2966 libfunc = eqdf2_libfunc;
2967 break;
2968
2969 case NE:
2970 libfunc = nedf2_libfunc;
2971 break;
2972
2973 case GT:
2974 libfunc = gtdf2_libfunc;
2975 break;
2976
2977 case GE:
2978 libfunc = gedf2_libfunc;
2979 break;
2980
2981 case LT:
2982 libfunc = ltdf2_libfunc;
2983 break;
2984
2985 case LE:
2986 libfunc = ledf2_libfunc;
2987 break;
2988 }
2989 else if (mode == XFmode)
2990 switch (comparison)
2991 {
2992 case EQ:
2993 libfunc = eqxf2_libfunc;
2994 break;
2995
2996 case NE:
2997 libfunc = nexf2_libfunc;
2998 break;
2999
3000 case GT:
3001 libfunc = gtxf2_libfunc;
3002 break;
3003
3004 case GE:
3005 libfunc = gexf2_libfunc;
3006 break;
3007
3008 case LT:
3009 libfunc = ltxf2_libfunc;
3010 break;
3011
3012 case LE:
3013 libfunc = lexf2_libfunc;
3014 break;
3015 }
3016 else if (mode == TFmode)
3017 switch (comparison)
3018 {
3019 case EQ:
3020 libfunc = eqtf2_libfunc;
3021 break;
3022
3023 case NE:
3024 libfunc = netf2_libfunc;
3025 break;
3026
3027 case GT:
3028 libfunc = gttf2_libfunc;
3029 break;
3030
3031 case GE:
3032 libfunc = getf2_libfunc;
3033 break;
3034
3035 case LT:
3036 libfunc = lttf2_libfunc;
3037 break;
3038
3039 case LE:
3040 libfunc = letf2_libfunc;
3041 break;
3042 }
3043 else
3044 {
3045 enum machine_mode wider_mode;
3046
3047 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3048 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3049 {
3050 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3051 != CODE_FOR_nothing)
3052 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3053 {
3054 x = protect_from_queue (x, 0);
3055 y = protect_from_queue (y, 0);
3056 x = convert_to_mode (wider_mode, x, 0);
3057 y = convert_to_mode (wider_mode, y, 0);
3058 emit_float_lib_cmp (x, y, comparison);
3059 return;
3060 }
3061 }
3062 abort ();
3063 }
3064
3065 if (libfunc == 0)
3066 abort ();
3067
3068 emit_library_call (libfunc, 1,
3069 word_mode, 2, x, mode, y, mode);
3070
3071 /* Immediately move the result of the libcall into a pseudo
3072 register so reload doesn't clobber the value if it needs
3073 the return register for a spill reg. */
3074 result = gen_reg_rtx (word_mode);
3075 emit_move_insn (result, hard_libcall_value (word_mode));
3076
3077 emit_cmp_insn (result, const0_rtx, comparison,
3078 NULL_RTX, word_mode, 0, 0);
3079 }
3080 \f
3081 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3082
3083 void
3084 emit_indirect_jump (loc)
3085 rtx loc;
3086 {
3087 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3088 (loc, Pmode)))
3089 loc = copy_to_mode_reg (Pmode, loc);
3090
3091 emit_jump_insn (gen_indirect_jump (loc));
3092 emit_barrier ();
3093 }
3094 \f
3095 #ifdef HAVE_conditional_move
3096
3097 /* Emit a conditional move instruction if the machine supports one for that
3098 condition and machine mode.
3099
3100 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3101 the mode to use should they be constants. If it is VOIDmode, they cannot
3102 both be constants.
3103
3104 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3105 should be stored there. MODE is the mode to use should they be constants.
3106 If it is VOIDmode, they cannot both be constants.
3107
3108 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3109 is not supported. */
3110
3111 rtx
3112 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3113 unsignedp)
3114 rtx target;
3115 enum rtx_code code;
3116 rtx op0, op1;
3117 enum machine_mode cmode;
3118 rtx op2, op3;
3119 enum machine_mode mode;
3120 int unsignedp;
3121 {
3122 rtx tem, subtarget, comparison, insn;
3123 enum insn_code icode;
3124
3125 /* If one operand is constant, make it the second one. Only do this
3126 if the other operand is not constant as well. */
3127
3128 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3129 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3130 {
3131 tem = op0;
3132 op0 = op1;
3133 op1 = tem;
3134 code = swap_condition (code);
3135 }
3136
3137 if (cmode == VOIDmode)
3138 cmode = GET_MODE (op0);
3139
3140 if ((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3141 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3142 {
3143 tem = op2;
3144 op2 = op3;
3145 op3 = tem;
3146 /* ??? This may not be appropriate (consider IEEE). Perhaps we should
3147 call can_reverse_comparison_p here and bail out if necessary.
3148 It's not clear whether we need to do this canonicalization though. */
3149 code = reverse_condition (code);
3150 }
3151
3152 if (mode == VOIDmode)
3153 mode = GET_MODE (op2);
3154
3155 icode = movcc_gen_code[mode];
3156
3157 if (icode == CODE_FOR_nothing)
3158 return 0;
3159
3160 if (flag_force_mem)
3161 {
3162 op2 = force_not_mem (op2);
3163 op3 = force_not_mem (op3);
3164 }
3165
3166 if (target)
3167 target = protect_from_queue (target, 1);
3168 else
3169 target = gen_reg_rtx (mode);
3170
3171 subtarget = target;
3172
3173 emit_queue ();
3174
3175 op2 = protect_from_queue (op2, 0);
3176 op3 = protect_from_queue (op3, 0);
3177
3178 /* If the insn doesn't accept these operands, put them in pseudos. */
3179
3180 if (! (*insn_operand_predicate[icode][0])
3181 (subtarget, insn_operand_mode[icode][0]))
3182 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3183
3184 if (! (*insn_operand_predicate[icode][2])
3185 (op2, insn_operand_mode[icode][2]))
3186 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3187
3188 if (! (*insn_operand_predicate[icode][3])
3189 (op3, insn_operand_mode[icode][3]))
3190 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3191
3192 /* Everything should now be in the suitable form, so emit the compare insn
3193 and then the conditional move. */
3194
3195 comparison
3196 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3197
3198 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3199 if (GET_CODE (comparison) != code)
3200 /* This shouldn't happen. */
3201 abort ();
3202
3203 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3204
3205 /* If that failed, then give up. */
3206 if (insn == 0)
3207 return 0;
3208
3209 emit_insn (insn);
3210
3211 if (subtarget != target)
3212 convert_move (target, subtarget, 0);
3213
3214 return target;
3215 }
3216
3217 /* Return non-zero if a conditional move of mode MODE is supported.
3218
3219 This function is for combine so it can tell whether an insn that looks
3220 like a conditional move is actually supported by the hardware. If we
3221 guess wrong we lose a bit on optimization, but that's it. */
3222 /* ??? sparc64 supports conditionally moving integers values based on fp
3223 comparisons, and vice versa. How do we handle them? */
3224
3225 int
3226 can_conditionally_move_p (mode)
3227 enum machine_mode mode;
3228 {
3229 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3230 return 1;
3231
3232 return 0;
3233 }
3234
3235 #endif /* HAVE_conditional_move */
3236 \f
3237 /* These three functions generate an insn body and return it
3238 rather than emitting the insn.
3239
3240 They do not protect from queued increments,
3241 because they may be used 1) in protect_from_queue itself
3242 and 2) in other passes where there is no queue. */
3243
3244 /* Generate and return an insn body to add Y to X. */
3245
3246 rtx
3247 gen_add2_insn (x, y)
3248 rtx x, y;
3249 {
3250 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3251
3252 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3253 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3254 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3255 abort ();
3256
3257 return (GEN_FCN (icode) (x, x, y));
3258 }
3259
3260 int
3261 have_add2_insn (mode)
3262 enum machine_mode mode;
3263 {
3264 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3265 }
3266
3267 /* Generate and return an insn body to subtract Y from X. */
3268
3269 rtx
3270 gen_sub2_insn (x, y)
3271 rtx x, y;
3272 {
3273 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3274
3275 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3276 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3277 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3278 abort ();
3279
3280 return (GEN_FCN (icode) (x, x, y));
3281 }
3282
3283 int
3284 have_sub2_insn (mode)
3285 enum machine_mode mode;
3286 {
3287 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3288 }
3289
3290 /* Generate the body of an instruction to copy Y into X.
3291 It may be a SEQUENCE, if one insn isn't enough. */
3292
3293 rtx
3294 gen_move_insn (x, y)
3295 rtx x, y;
3296 {
3297 register enum machine_mode mode = GET_MODE (x);
3298 enum insn_code insn_code;
3299 rtx seq;
3300
3301 if (mode == VOIDmode)
3302 mode = GET_MODE (y);
3303
3304 insn_code = mov_optab->handlers[(int) mode].insn_code;
3305
3306 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3307 find a mode to do it in. If we have a movcc, use it. Otherwise,
3308 find the MODE_INT mode of the same width. */
3309
3310 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3311 {
3312 enum machine_mode tmode = VOIDmode;
3313 rtx x1 = x, y1 = y;
3314
3315 if (mode != CCmode
3316 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3317 tmode = CCmode;
3318 else
3319 for (tmode = QImode; tmode != VOIDmode;
3320 tmode = GET_MODE_WIDER_MODE (tmode))
3321 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3322 break;
3323
3324 if (tmode == VOIDmode)
3325 abort ();
3326
3327 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3328 may call change_address which is not appropriate if we were
3329 called when a reload was in progress. We don't have to worry
3330 about changing the address since the size in bytes is supposed to
3331 be the same. Copy the MEM to change the mode and move any
3332 substitutions from the old MEM to the new one. */
3333
3334 if (reload_in_progress)
3335 {
3336 x = gen_lowpart_common (tmode, x1);
3337 if (x == 0 && GET_CODE (x1) == MEM)
3338 {
3339 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3340 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3341 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3342 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3343 copy_replacements (x1, x);
3344 }
3345
3346 y = gen_lowpart_common (tmode, y1);
3347 if (y == 0 && GET_CODE (y1) == MEM)
3348 {
3349 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3350 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3351 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3352 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3353 copy_replacements (y1, y);
3354 }
3355 }
3356 else
3357 {
3358 x = gen_lowpart (tmode, x);
3359 y = gen_lowpart (tmode, y);
3360 }
3361
3362 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3363 return (GEN_FCN (insn_code) (x, y));
3364 }
3365
3366 start_sequence ();
3367 emit_move_insn_1 (x, y);
3368 seq = gen_sequence ();
3369 end_sequence ();
3370 return seq;
3371 }
3372 \f
3373 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3374 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3375 no such operation exists, CODE_FOR_nothing will be returned. */
3376
3377 enum insn_code
3378 can_extend_p (to_mode, from_mode, unsignedp)
3379 enum machine_mode to_mode, from_mode;
3380 int unsignedp;
3381 {
3382 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3383 }
3384
3385 /* Generate the body of an insn to extend Y (with mode MFROM)
3386 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3387
3388 rtx
3389 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3390 rtx x, y;
3391 enum machine_mode mto, mfrom;
3392 int unsignedp;
3393 {
3394 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3395 }
3396 \f
3397 /* can_fix_p and can_float_p say whether the target machine
3398 can directly convert a given fixed point type to
3399 a given floating point type, or vice versa.
3400 The returned value is the CODE_FOR_... value to use,
3401 or CODE_FOR_nothing if these modes cannot be directly converted.
3402
3403 *TRUNCP_PTR is set to 1 if it is necessary to output
3404 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3405
3406 static enum insn_code
3407 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3408 enum machine_mode fltmode, fixmode;
3409 int unsignedp;
3410 int *truncp_ptr;
3411 {
3412 *truncp_ptr = 0;
3413 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3414 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3415
3416 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3417 {
3418 *truncp_ptr = 1;
3419 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3420 }
3421 return CODE_FOR_nothing;
3422 }
3423
3424 static enum insn_code
3425 can_float_p (fltmode, fixmode, unsignedp)
3426 enum machine_mode fixmode, fltmode;
3427 int unsignedp;
3428 {
3429 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3430 }
3431 \f
3432 /* Generate code to convert FROM to floating point
3433 and store in TO. FROM must be fixed point and not VOIDmode.
3434 UNSIGNEDP nonzero means regard FROM as unsigned.
3435 Normally this is done by correcting the final value
3436 if it is negative. */
3437
3438 void
3439 expand_float (to, from, unsignedp)
3440 rtx to, from;
3441 int unsignedp;
3442 {
3443 enum insn_code icode;
3444 register rtx target = to;
3445 enum machine_mode fmode, imode;
3446
3447 /* Crash now, because we won't be able to decide which mode to use. */
3448 if (GET_MODE (from) == VOIDmode)
3449 abort ();
3450
3451 /* Look for an insn to do the conversion. Do it in the specified
3452 modes if possible; otherwise convert either input, output or both to
3453 wider mode. If the integer mode is wider than the mode of FROM,
3454 we can do the conversion signed even if the input is unsigned. */
3455
3456 for (imode = GET_MODE (from); imode != VOIDmode;
3457 imode = GET_MODE_WIDER_MODE (imode))
3458 for (fmode = GET_MODE (to); fmode != VOIDmode;
3459 fmode = GET_MODE_WIDER_MODE (fmode))
3460 {
3461 int doing_unsigned = unsignedp;
3462
3463 icode = can_float_p (fmode, imode, unsignedp);
3464 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3465 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3466
3467 if (icode != CODE_FOR_nothing)
3468 {
3469 to = protect_from_queue (to, 1);
3470 from = protect_from_queue (from, 0);
3471
3472 if (imode != GET_MODE (from))
3473 from = convert_to_mode (imode, from, unsignedp);
3474
3475 if (fmode != GET_MODE (to))
3476 target = gen_reg_rtx (fmode);
3477
3478 emit_unop_insn (icode, target, from,
3479 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3480
3481 if (target != to)
3482 convert_move (to, target, 0);
3483 return;
3484 }
3485 }
3486
3487 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3488
3489 /* Unsigned integer, and no way to convert directly.
3490 Convert as signed, then conditionally adjust the result. */
3491 if (unsignedp)
3492 {
3493 rtx label = gen_label_rtx ();
3494 rtx temp;
3495 REAL_VALUE_TYPE offset;
3496
3497 emit_queue ();
3498
3499 to = protect_from_queue (to, 1);
3500 from = protect_from_queue (from, 0);
3501
3502 if (flag_force_mem)
3503 from = force_not_mem (from);
3504
3505 /* Look for a usable floating mode FMODE wider than the source and at
3506 least as wide as the target. Using FMODE will avoid rounding woes
3507 with unsigned values greater than the signed maximum value. */
3508
3509 for (fmode = GET_MODE (to); fmode != VOIDmode;
3510 fmode = GET_MODE_WIDER_MODE (fmode))
3511 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3512 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3513 break;
3514
3515 if (fmode == VOIDmode)
3516 {
3517 /* There is no such mode. Pretend the target is wide enough. */
3518 fmode = GET_MODE (to);
3519
3520 /* Avoid double-rounding when TO is narrower than FROM. */
3521 if ((significand_size (fmode) + 1)
3522 < GET_MODE_BITSIZE (GET_MODE (from)))
3523 {
3524 rtx temp1;
3525 rtx neglabel = gen_label_rtx ();
3526
3527 /* Don't use TARGET if it isn't a register, is a hard register,
3528 or is the wrong mode. */
3529 if (GET_CODE (target) != REG
3530 || REGNO (target) < FIRST_PSEUDO_REGISTER
3531 || GET_MODE (target) != fmode)
3532 target = gen_reg_rtx (fmode);
3533
3534 imode = GET_MODE (from);
3535 do_pending_stack_adjust ();
3536
3537 /* Test whether the sign bit is set. */
3538 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3539 emit_jump_insn (gen_blt (neglabel));
3540
3541 /* The sign bit is not set. Convert as signed. */
3542 expand_float (target, from, 0);
3543 emit_jump_insn (gen_jump (label));
3544 emit_barrier ();
3545
3546 /* The sign bit is set.
3547 Convert to a usable (positive signed) value by shifting right
3548 one bit, while remembering if a nonzero bit was shifted
3549 out; i.e., compute (from & 1) | (from >> 1). */
3550
3551 emit_label (neglabel);
3552 temp = expand_binop (imode, and_optab, from, const1_rtx,
3553 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3554 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3555 NULL_RTX, 1);
3556 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3557 OPTAB_LIB_WIDEN);
3558 expand_float (target, temp, 0);
3559
3560 /* Multiply by 2 to undo the shift above. */
3561 temp = expand_binop (fmode, add_optab, target, target,
3562 target, 0, OPTAB_LIB_WIDEN);
3563 if (temp != target)
3564 emit_move_insn (target, temp);
3565
3566 do_pending_stack_adjust ();
3567 emit_label (label);
3568 goto done;
3569 }
3570 }
3571
3572 /* If we are about to do some arithmetic to correct for an
3573 unsigned operand, do it in a pseudo-register. */
3574
3575 if (GET_MODE (to) != fmode
3576 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3577 target = gen_reg_rtx (fmode);
3578
3579 /* Convert as signed integer to floating. */
3580 expand_float (target, from, 0);
3581
3582 /* If FROM is negative (and therefore TO is negative),
3583 correct its value by 2**bitwidth. */
3584
3585 do_pending_stack_adjust ();
3586 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3587 emit_jump_insn (gen_bge (label));
3588
3589 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3590 Rather than setting up a dconst_dot_5, let's hope SCO
3591 fixes the bug. */
3592 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3593 temp = expand_binop (fmode, add_optab, target,
3594 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3595 target, 0, OPTAB_LIB_WIDEN);
3596 if (temp != target)
3597 emit_move_insn (target, temp);
3598
3599 do_pending_stack_adjust ();
3600 emit_label (label);
3601 goto done;
3602 }
3603 #endif
3604
3605 /* No hardware instruction available; call a library routine to convert from
3606 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3607 {
3608 rtx libfcn;
3609 rtx insns;
3610 rtx value;
3611
3612 to = protect_from_queue (to, 1);
3613 from = protect_from_queue (from, 0);
3614
3615 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3616 from = convert_to_mode (SImode, from, unsignedp);
3617
3618 if (flag_force_mem)
3619 from = force_not_mem (from);
3620
3621 if (GET_MODE (to) == SFmode)
3622 {
3623 if (GET_MODE (from) == SImode)
3624 libfcn = floatsisf_libfunc;
3625 else if (GET_MODE (from) == DImode)
3626 libfcn = floatdisf_libfunc;
3627 else if (GET_MODE (from) == TImode)
3628 libfcn = floattisf_libfunc;
3629 else
3630 abort ();
3631 }
3632 else if (GET_MODE (to) == DFmode)
3633 {
3634 if (GET_MODE (from) == SImode)
3635 libfcn = floatsidf_libfunc;
3636 else if (GET_MODE (from) == DImode)
3637 libfcn = floatdidf_libfunc;
3638 else if (GET_MODE (from) == TImode)
3639 libfcn = floattidf_libfunc;
3640 else
3641 abort ();
3642 }
3643 else if (GET_MODE (to) == XFmode)
3644 {
3645 if (GET_MODE (from) == SImode)
3646 libfcn = floatsixf_libfunc;
3647 else if (GET_MODE (from) == DImode)
3648 libfcn = floatdixf_libfunc;
3649 else if (GET_MODE (from) == TImode)
3650 libfcn = floattixf_libfunc;
3651 else
3652 abort ();
3653 }
3654 else if (GET_MODE (to) == TFmode)
3655 {
3656 if (GET_MODE (from) == SImode)
3657 libfcn = floatsitf_libfunc;
3658 else if (GET_MODE (from) == DImode)
3659 libfcn = floatditf_libfunc;
3660 else if (GET_MODE (from) == TImode)
3661 libfcn = floattitf_libfunc;
3662 else
3663 abort ();
3664 }
3665 else
3666 abort ();
3667
3668 start_sequence ();
3669
3670 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3671 GET_MODE (to),
3672 1, from, GET_MODE (from));
3673 insns = get_insns ();
3674 end_sequence ();
3675
3676 emit_libcall_block (insns, target, value,
3677 gen_rtx (FLOAT, GET_MODE (to), from));
3678 }
3679
3680 done:
3681
3682 /* Copy result to requested destination
3683 if we have been computing in a temp location. */
3684
3685 if (target != to)
3686 {
3687 if (GET_MODE (target) == GET_MODE (to))
3688 emit_move_insn (to, target);
3689 else
3690 convert_move (to, target, 0);
3691 }
3692 }
3693 \f
3694 /* expand_fix: generate code to convert FROM to fixed point
3695 and store in TO. FROM must be floating point. */
3696
3697 static rtx
3698 ftruncify (x)
3699 rtx x;
3700 {
3701 rtx temp = gen_reg_rtx (GET_MODE (x));
3702 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3703 }
3704
3705 void
3706 expand_fix (to, from, unsignedp)
3707 register rtx to, from;
3708 int unsignedp;
3709 {
3710 enum insn_code icode;
3711 register rtx target = to;
3712 enum machine_mode fmode, imode;
3713 int must_trunc = 0;
3714 rtx libfcn = 0;
3715
3716 /* We first try to find a pair of modes, one real and one integer, at
3717 least as wide as FROM and TO, respectively, in which we can open-code
3718 this conversion. If the integer mode is wider than the mode of TO,
3719 we can do the conversion either signed or unsigned. */
3720
3721 for (imode = GET_MODE (to); imode != VOIDmode;
3722 imode = GET_MODE_WIDER_MODE (imode))
3723 for (fmode = GET_MODE (from); fmode != VOIDmode;
3724 fmode = GET_MODE_WIDER_MODE (fmode))
3725 {
3726 int doing_unsigned = unsignedp;
3727
3728 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3729 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3730 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3731
3732 if (icode != CODE_FOR_nothing)
3733 {
3734 to = protect_from_queue (to, 1);
3735 from = protect_from_queue (from, 0);
3736
3737 if (fmode != GET_MODE (from))
3738 from = convert_to_mode (fmode, from, 0);
3739
3740 if (must_trunc)
3741 from = ftruncify (from);
3742
3743 if (imode != GET_MODE (to))
3744 target = gen_reg_rtx (imode);
3745
3746 emit_unop_insn (icode, target, from,
3747 doing_unsigned ? UNSIGNED_FIX : FIX);
3748 if (target != to)
3749 convert_move (to, target, unsignedp);
3750 return;
3751 }
3752 }
3753
3754 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3755 /* For an unsigned conversion, there is one more way to do it.
3756 If we have a signed conversion, we generate code that compares
3757 the real value to the largest representable positive number. If if
3758 is smaller, the conversion is done normally. Otherwise, subtract
3759 one plus the highest signed number, convert, and add it back.
3760
3761 We only need to check all real modes, since we know we didn't find
3762 anything with a wider integer mode. */
3763
3764 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3765 for (fmode = GET_MODE (from); fmode != VOIDmode;
3766 fmode = GET_MODE_WIDER_MODE (fmode))
3767 /* Make sure we won't lose significant bits doing this. */
3768 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3769 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3770 &must_trunc))
3771 {
3772 int bitsize;
3773 REAL_VALUE_TYPE offset;
3774 rtx limit, lab1, lab2, insn;
3775
3776 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3777 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3778 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3779 lab1 = gen_label_rtx ();
3780 lab2 = gen_label_rtx ();
3781
3782 emit_queue ();
3783 to = protect_from_queue (to, 1);
3784 from = protect_from_queue (from, 0);
3785
3786 if (flag_force_mem)
3787 from = force_not_mem (from);
3788
3789 if (fmode != GET_MODE (from))
3790 from = convert_to_mode (fmode, from, 0);
3791
3792 /* See if we need to do the subtraction. */
3793 do_pending_stack_adjust ();
3794 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3795 emit_jump_insn (gen_bge (lab1));
3796
3797 /* If not, do the signed "fix" and branch around fixup code. */
3798 expand_fix (to, from, 0);
3799 emit_jump_insn (gen_jump (lab2));
3800 emit_barrier ();
3801
3802 /* Otherwise, subtract 2**(N-1), convert to signed number,
3803 then add 2**(N-1). Do the addition using XOR since this
3804 will often generate better code. */
3805 emit_label (lab1);
3806 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3807 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3808 expand_fix (to, target, 0);
3809 target = expand_binop (GET_MODE (to), xor_optab, to,
3810 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3811 to, 1, OPTAB_LIB_WIDEN);
3812
3813 if (target != to)
3814 emit_move_insn (to, target);
3815
3816 emit_label (lab2);
3817
3818 /* Make a place for a REG_NOTE and add it. */
3819 insn = emit_move_insn (to, to);
3820 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3821 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3822 copy_rtx (from)),
3823 REG_NOTES (insn));
3824
3825 return;
3826 }
3827 #endif
3828
3829 /* We can't do it with an insn, so use a library call. But first ensure
3830 that the mode of TO is at least as wide as SImode, since those are the
3831 only library calls we know about. */
3832
3833 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3834 {
3835 target = gen_reg_rtx (SImode);
3836
3837 expand_fix (target, from, unsignedp);
3838 }
3839 else if (GET_MODE (from) == SFmode)
3840 {
3841 if (GET_MODE (to) == SImode)
3842 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3843 else if (GET_MODE (to) == DImode)
3844 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3845 else if (GET_MODE (to) == TImode)
3846 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3847 else
3848 abort ();
3849 }
3850 else if (GET_MODE (from) == DFmode)
3851 {
3852 if (GET_MODE (to) == SImode)
3853 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3854 else if (GET_MODE (to) == DImode)
3855 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3856 else if (GET_MODE (to) == TImode)
3857 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3858 else
3859 abort ();
3860 }
3861 else if (GET_MODE (from) == XFmode)
3862 {
3863 if (GET_MODE (to) == SImode)
3864 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3865 else if (GET_MODE (to) == DImode)
3866 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3867 else if (GET_MODE (to) == TImode)
3868 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3869 else
3870 abort ();
3871 }
3872 else if (GET_MODE (from) == TFmode)
3873 {
3874 if (GET_MODE (to) == SImode)
3875 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3876 else if (GET_MODE (to) == DImode)
3877 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3878 else if (GET_MODE (to) == TImode)
3879 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3880 else
3881 abort ();
3882 }
3883 else
3884 abort ();
3885
3886 if (libfcn)
3887 {
3888 rtx insns;
3889 rtx value;
3890
3891 to = protect_from_queue (to, 1);
3892 from = protect_from_queue (from, 0);
3893
3894 if (flag_force_mem)
3895 from = force_not_mem (from);
3896
3897 start_sequence ();
3898
3899 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3900
3901 1, from, GET_MODE (from));
3902 insns = get_insns ();
3903 end_sequence ();
3904
3905 emit_libcall_block (insns, target, value,
3906 gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3907 GET_MODE (to), from));
3908 }
3909
3910 if (target != to)
3911 {
3912 if (GET_MODE (to) == GET_MODE (target))
3913 emit_move_insn (to, target);
3914 else
3915 convert_move (to, target, 0);
3916 }
3917 }
3918 \f
3919 static optab
3920 init_optab (code)
3921 enum rtx_code code;
3922 {
3923 int i;
3924 optab op = (optab) xmalloc (sizeof (struct optab));
3925 op->code = code;
3926 for (i = 0; i < NUM_MACHINE_MODES; i++)
3927 {
3928 op->handlers[i].insn_code = CODE_FOR_nothing;
3929 op->handlers[i].libfunc = 0;
3930 }
3931
3932 if (code != UNKNOWN)
3933 code_to_optab[(int) code] = op;
3934
3935 return op;
3936 }
3937
3938 /* Initialize the libfunc fields of an entire group of entries in some
3939 optab. Each entry is set equal to a string consisting of a leading
3940 pair of underscores followed by a generic operation name followed by
3941 a mode name (downshifted to lower case) followed by a single character
3942 representing the number of operands for the given operation (which is
3943 usually one of the characters '2', '3', or '4').
3944
3945 OPTABLE is the table in which libfunc fields are to be initialized.
3946 FIRST_MODE is the first machine mode index in the given optab to
3947 initialize.
3948 LAST_MODE is the last machine mode index in the given optab to
3949 initialize.
3950 OPNAME is the generic (string) name of the operation.
3951 SUFFIX is the character which specifies the number of operands for
3952 the given generic operation.
3953 */
3954
3955 static void
3956 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3957 register optab optable;
3958 register int first_mode;
3959 register int last_mode;
3960 register char *opname;
3961 register int suffix;
3962 {
3963 register int mode;
3964 register unsigned opname_len = strlen (opname);
3965
3966 for (mode = first_mode; (int) mode <= (int) last_mode;
3967 mode = (enum machine_mode) ((int) mode + 1))
3968 {
3969 register char *mname = mode_name[(int) mode];
3970 register unsigned mname_len = strlen (mname);
3971 register char *libfunc_name
3972 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3973 register char *p;
3974 register char *q;
3975
3976 p = libfunc_name;
3977 *p++ = '_';
3978 *p++ = '_';
3979 for (q = opname; *q; )
3980 *p++ = *q++;
3981 for (q = mname; *q; q++)
3982 *p++ = tolower (*q);
3983 *p++ = suffix;
3984 *p++ = '\0';
3985 optable->handlers[(int) mode].libfunc
3986 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3987 }
3988 }
3989
3990 /* Initialize the libfunc fields of an entire group of entries in some
3991 optab which correspond to all integer mode operations. The parameters
3992 have the same meaning as similarly named ones for the `init_libfuncs'
3993 routine. (See above). */
3994
3995 static void
3996 init_integral_libfuncs (optable, opname, suffix)
3997 register optab optable;
3998 register char *opname;
3999 register int suffix;
4000 {
4001 init_libfuncs (optable, SImode, TImode, opname, suffix);
4002 }
4003
4004 /* Initialize the libfunc fields of an entire group of entries in some
4005 optab which correspond to all real mode operations. The parameters
4006 have the same meaning as similarly named ones for the `init_libfuncs'
4007 routine. (See above). */
4008
4009 static void
4010 init_floating_libfuncs (optable, opname, suffix)
4011 register optab optable;
4012 register char *opname;
4013 register int suffix;
4014 {
4015 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4016 }
4017
4018 /* Initialize the libfunc fields of an entire group of entries in some
4019 optab which correspond to all complex floating modes. The parameters
4020 have the same meaning as similarly named ones for the `init_libfuncs'
4021 routine. (See above). */
4022
4023 static void
4024 init_complex_libfuncs (optable, opname, suffix)
4025 register optab optable;
4026 register char *opname;
4027 register int suffix;
4028 {
4029 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
4030 }
4031
4032 /* Call this once to initialize the contents of the optabs
4033 appropriately for the current target machine. */
4034
4035 void
4036 init_optabs ()
4037 {
4038 int i, j;
4039 enum insn_code *p;
4040
4041 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4042
4043 for (p = fixtab[0][0];
4044 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4045 p++)
4046 *p = CODE_FOR_nothing;
4047
4048 for (p = fixtrunctab[0][0];
4049 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4050 p++)
4051 *p = CODE_FOR_nothing;
4052
4053 for (p = floattab[0][0];
4054 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4055 p++)
4056 *p = CODE_FOR_nothing;
4057
4058 for (p = extendtab[0][0];
4059 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4060 p++)
4061 *p = CODE_FOR_nothing;
4062
4063 for (i = 0; i < NUM_RTX_CODE; i++)
4064 setcc_gen_code[i] = CODE_FOR_nothing;
4065
4066 #ifdef HAVE_conditional_move
4067 for (i = 0; i < NUM_MACHINE_MODES; i++)
4068 movcc_gen_code[i] = CODE_FOR_nothing;
4069 #endif
4070
4071 add_optab = init_optab (PLUS);
4072 sub_optab = init_optab (MINUS);
4073 smul_optab = init_optab (MULT);
4074 smul_highpart_optab = init_optab (UNKNOWN);
4075 umul_highpart_optab = init_optab (UNKNOWN);
4076 smul_widen_optab = init_optab (UNKNOWN);
4077 umul_widen_optab = init_optab (UNKNOWN);
4078 sdiv_optab = init_optab (DIV);
4079 sdivmod_optab = init_optab (UNKNOWN);
4080 udiv_optab = init_optab (UDIV);
4081 udivmod_optab = init_optab (UNKNOWN);
4082 smod_optab = init_optab (MOD);
4083 umod_optab = init_optab (UMOD);
4084 flodiv_optab = init_optab (DIV);
4085 ftrunc_optab = init_optab (UNKNOWN);
4086 and_optab = init_optab (AND);
4087 ior_optab = init_optab (IOR);
4088 xor_optab = init_optab (XOR);
4089 ashl_optab = init_optab (ASHIFT);
4090 ashr_optab = init_optab (ASHIFTRT);
4091 lshr_optab = init_optab (LSHIFTRT);
4092 rotl_optab = init_optab (ROTATE);
4093 rotr_optab = init_optab (ROTATERT);
4094 smin_optab = init_optab (SMIN);
4095 smax_optab = init_optab (SMAX);
4096 umin_optab = init_optab (UMIN);
4097 umax_optab = init_optab (UMAX);
4098 mov_optab = init_optab (UNKNOWN);
4099 movstrict_optab = init_optab (UNKNOWN);
4100 cmp_optab = init_optab (UNKNOWN);
4101 ucmp_optab = init_optab (UNKNOWN);
4102 tst_optab = init_optab (UNKNOWN);
4103 neg_optab = init_optab (NEG);
4104 abs_optab = init_optab (ABS);
4105 one_cmpl_optab = init_optab (NOT);
4106 ffs_optab = init_optab (FFS);
4107 sqrt_optab = init_optab (SQRT);
4108 sin_optab = init_optab (UNKNOWN);
4109 cos_optab = init_optab (UNKNOWN);
4110 strlen_optab = init_optab (UNKNOWN);
4111
4112 for (i = 0; i < NUM_MACHINE_MODES; i++)
4113 {
4114 movstr_optab[i] = CODE_FOR_nothing;
4115 clrstr_optab[i] = CODE_FOR_nothing;
4116
4117 #ifdef HAVE_SECONDARY_RELOADS
4118 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4119 #endif
4120 }
4121
4122 /* Fill in the optabs with the insns we support. */
4123 init_all_optabs ();
4124
4125 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4126 /* This flag says the same insns that convert to a signed fixnum
4127 also convert validly to an unsigned one. */
4128 for (i = 0; i < NUM_MACHINE_MODES; i++)
4129 for (j = 0; j < NUM_MACHINE_MODES; j++)
4130 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4131 #endif
4132
4133 #ifdef EXTRA_CC_MODES
4134 init_mov_optab ();
4135 #endif
4136
4137 /* Initialize the optabs with the names of the library functions. */
4138 init_integral_libfuncs (add_optab, "add", '3');
4139 init_floating_libfuncs (add_optab, "add", '3');
4140 init_integral_libfuncs (sub_optab, "sub", '3');
4141 init_floating_libfuncs (sub_optab, "sub", '3');
4142 init_integral_libfuncs (smul_optab, "mul", '3');
4143 init_floating_libfuncs (smul_optab, "mul", '3');
4144 init_integral_libfuncs (sdiv_optab, "div", '3');
4145 init_integral_libfuncs (udiv_optab, "udiv", '3');
4146 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4147 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4148 init_integral_libfuncs (smod_optab, "mod", '3');
4149 init_integral_libfuncs (umod_optab, "umod", '3');
4150 init_floating_libfuncs (flodiv_optab, "div", '3');
4151 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4152 init_integral_libfuncs (and_optab, "and", '3');
4153 init_integral_libfuncs (ior_optab, "ior", '3');
4154 init_integral_libfuncs (xor_optab, "xor", '3');
4155 init_integral_libfuncs (ashl_optab, "ashl", '3');
4156 init_integral_libfuncs (ashr_optab, "ashr", '3');
4157 init_integral_libfuncs (lshr_optab, "lshr", '3');
4158 init_integral_libfuncs (smin_optab, "min", '3');
4159 init_floating_libfuncs (smin_optab, "min", '3');
4160 init_integral_libfuncs (smax_optab, "max", '3');
4161 init_floating_libfuncs (smax_optab, "max", '3');
4162 init_integral_libfuncs (umin_optab, "umin", '3');
4163 init_integral_libfuncs (umax_optab, "umax", '3');
4164 init_integral_libfuncs (neg_optab, "neg", '2');
4165 init_floating_libfuncs (neg_optab, "neg", '2');
4166 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4167 init_integral_libfuncs (ffs_optab, "ffs", '2');
4168
4169 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4170 init_integral_libfuncs (cmp_optab, "cmp", '2');
4171 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4172 init_floating_libfuncs (cmp_optab, "cmp", '2');
4173
4174 #ifdef MULSI3_LIBCALL
4175 smul_optab->handlers[(int) SImode].libfunc
4176 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4177 #endif
4178 #ifdef MULDI3_LIBCALL
4179 smul_optab->handlers[(int) DImode].libfunc
4180 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4181 #endif
4182
4183 #ifdef DIVSI3_LIBCALL
4184 sdiv_optab->handlers[(int) SImode].libfunc
4185 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4186 #endif
4187 #ifdef DIVDI3_LIBCALL
4188 sdiv_optab->handlers[(int) DImode].libfunc
4189 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4190 #endif
4191
4192 #ifdef UDIVSI3_LIBCALL
4193 udiv_optab->handlers[(int) SImode].libfunc
4194 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4195 #endif
4196 #ifdef UDIVDI3_LIBCALL
4197 udiv_optab->handlers[(int) DImode].libfunc
4198 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4199 #endif
4200
4201 #ifdef MODSI3_LIBCALL
4202 smod_optab->handlers[(int) SImode].libfunc
4203 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4204 #endif
4205 #ifdef MODDI3_LIBCALL
4206 smod_optab->handlers[(int) DImode].libfunc
4207 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4208 #endif
4209
4210 #ifdef UMODSI3_LIBCALL
4211 umod_optab->handlers[(int) SImode].libfunc
4212 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4213 #endif
4214 #ifdef UMODDI3_LIBCALL
4215 umod_optab->handlers[(int) DImode].libfunc
4216 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4217 #endif
4218
4219 /* Use cabs for DC complex abs, since systems generally have cabs.
4220 Don't define any libcall for SCmode, so that cabs will be used. */
4221 abs_optab->handlers[(int) DCmode].libfunc
4222 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4223
4224 /* The ffs function operates on `int'. */
4225 #ifndef INT_TYPE_SIZE
4226 #define INT_TYPE_SIZE BITS_PER_WORD
4227 #endif
4228 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4229 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4230
4231 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4232 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4233 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4234 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4235 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4236
4237 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4238 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4239 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4240 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4241 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4242
4243 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4244 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4245 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4246 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4247 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4248 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4249
4250 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4251 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4252 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4253 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4254 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4255 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4256
4257 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4258 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4259 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4260 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4261 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4262 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4263
4264 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4265 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4266 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4267 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4268 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4269 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4270
4271 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4272 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4273 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4274 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4275 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4276 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4277
4278 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4279 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4280 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4281 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4282 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4283 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4284
4285 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4286 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4287 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4288
4289 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4290 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4291 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4292
4293 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4294 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4295 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4296
4297 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4298 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4299 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4300
4301 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4302 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4303 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4304
4305 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4306 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4307 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4308
4309 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4310 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4311 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4312
4313 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4314 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4315 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4316
4317 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4318 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4319 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4320
4321 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4322 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4323 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4324
4325 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4326 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4327 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4328
4329 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4330 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4331 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4332
4333 #ifdef INIT_TARGET_OPTABS
4334 /* Allow the target to add more libcalls or rename some, etc. */
4335 INIT_TARGET_OPTABS;
4336 #endif
4337 }
4338 \f
4339 #ifdef BROKEN_LDEXP
4340
4341 /* SCO 3.2 apparently has a broken ldexp. */
4342
4343 double
4344 ldexp(x,n)
4345 double x;
4346 int n;
4347 {
4348 if (n > 0)
4349 while (n--)
4350 x *= 2;
4351
4352 return x;
4353 }
4354 #endif /* BROKEN_LDEXP */