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