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