|
|
1.1 root 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:
31: /* Each optab contains info on how this target machine
32: can perform a particular operation
33: for all sizes and kinds of operands.
34:
35: The operation to be performed is often specified
36: by passing one of these optabs as an argument.
37:
38: See expr.h for documentation of these optabs. */
39:
40: optab add_optab;
41: optab sub_optab;
42: optab smul_optab;
43: optab smul_widen_optab;
44: optab umul_widen_optab;
45: optab sdiv_optab;
46: optab sdivmod_optab;
47: optab udiv_optab;
48: optab udivmod_optab;
49: optab smod_optab;
50: optab umod_optab;
51: optab flodiv_optab;
52: optab ftrunc_optab;
53: optab and_optab;
54: optab ior_optab;
55: optab xor_optab;
56: optab ashl_optab;
57: optab lshr_optab;
58: optab lshl_optab;
59: optab ashr_optab;
60: optab rotl_optab;
61: optab rotr_optab;
62: optab smin_optab;
63: optab smax_optab;
64: optab umin_optab;
65: optab umax_optab;
66:
67: optab mov_optab;
68: optab movstrict_optab;
69:
70: optab neg_optab;
71: optab abs_optab;
72: optab one_cmpl_optab;
73: optab ffs_optab;
74:
75: optab cmp_optab;
76: optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
77: optab tst_optab;
78:
79: /* SYMBOL_REF rtx's for the library functions that are called
80: implicitly and not via optabs. */
81:
82: rtx extendsfdf2_libfunc;
83: rtx truncdfsf2_libfunc;
84: rtx memcpy_libfunc;
85: rtx bcopy_libfunc;
86: rtx memcmp_libfunc;
87: rtx bcmp_libfunc;
88: rtx memset_libfunc;
89: rtx bzero_libfunc;
90: rtx eqsf2_libfunc;
91: rtx nesf2_libfunc;
92: rtx gtsf2_libfunc;
93: rtx gesf2_libfunc;
94: rtx ltsf2_libfunc;
95: rtx lesf2_libfunc;
96: rtx eqdf2_libfunc;
97: rtx nedf2_libfunc;
98: rtx gtdf2_libfunc;
99: rtx gedf2_libfunc;
100: rtx ltdf2_libfunc;
101: rtx ledf2_libfunc;
102: rtx floatdisf_libfunc;
103: rtx floatsisf_libfunc;
104: rtx floatdidf_libfunc;
105: rtx floatsidf_libfunc;
106: rtx fixsfsi_libfunc;
107: rtx fixsfdi_libfunc;
108: rtx fixdfsi_libfunc;
109: rtx fixdfdi_libfunc;
110: rtx fixunssfsi_libfunc;
111: rtx fixunssfdi_libfunc;
112: rtx fixunsdfsi_libfunc;
113: rtx fixunsdfdi_libfunc;
114:
115: /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
116: gives the gen_function to make a branch to test that condition. */
117:
118: rtxfun bcc_gen_fctn[NUM_RTX_CODE];
119:
120: /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
121: gives the insn code to make a store-condition insn
122: to test that condition. */
123:
124: enum insn_code setcc_gen_code[NUM_RTX_CODE];
125:
126: static void emit_float_lib_cmp ();
127:
128: /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
129: the result of operation CODE applied to OP0 (and OP1 if it is a binary
130: operation).
131:
132: If the last insn does not set TARGET, don't do anything, but return 1.
133:
134: If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
135: don't add the REG_EQUAL note but return 0. Our caller can then try
136: again, ensuring that TARGET is not one of the operands. */
137:
138: static int
139: add_equal_note (seq, target, code, op0, op1)
140: rtx seq;
141: rtx target;
142: enum rtx_code code;
143: rtx op0, op1;
144: {
145: rtx set;
146: int i;
147: rtx note;
148:
149: if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
150: && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
151: || GET_CODE (seq) != SEQUENCE
152: || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
153: || GET_CODE (target) == ZERO_EXTRACT
154: || (! rtx_equal_p (SET_DEST (set), target)
155: /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
156: SUBREG. */
157: && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
158: || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
159: target))))
160: return 1;
161:
162: /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
163: besides the last insn. */
164: if (reg_overlap_mentioned_p (target, op0)
165: || (op1 && reg_overlap_mentioned_p (target, op1)))
166: for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
167: if (reg_set_p (target, XVECEXP (seq, 0, i)))
168: return 0;
169:
170: if (GET_RTX_CLASS (code) == '1')
171: note = gen_rtx (code, GET_MODE (target), op0);
172: else
173: note = gen_rtx (code, GET_MODE (target), op0, op1);
174:
175: REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
176: = gen_rtx (EXPR_LIST, REG_EQUAL, note,
177: REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
178:
179: return 1;
180: }
181:
182: /* Generate code to perform an operation specified by BINOPTAB
183: on operands OP0 and OP1, with result having machine-mode MODE.
184:
185: UNSIGNEDP is for the case where we have to widen the operands
186: to perform the operation. It says to use zero-extension.
187:
188: If TARGET is nonzero, the value
189: is generated there, if it is convenient to do so.
190: In all cases an rtx is returned for the locus of the value;
191: this may or may not be TARGET. */
192:
193: rtx
194: expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
195: enum machine_mode mode;
196: optab binoptab;
197: rtx op0, op1;
198: rtx target;
199: int unsignedp;
200: enum optab_methods methods;
201: {
202: enum mode_class class;
203: enum machine_mode wider_mode;
204: register rtx temp;
205: int commutative_op = 0;
206: int shift_op = (binoptab->code == ASHIFT
207: || binoptab->code == ASHIFTRT
208: || binoptab->code == LSHIFT
209: || binoptab->code == LSHIFTRT
210: || binoptab->code == ROTATE
211: || binoptab->code == ROTATERT);
212: rtx last;
213:
214: class = GET_MODE_CLASS (mode);
215:
216: op0 = protect_from_queue (op0, 0);
217: op1 = protect_from_queue (op1, 0);
218: if (target)
219: target = protect_from_queue (target, 1);
220:
221: if (flag_force_mem)
222: {
223: op0 = force_not_mem (op0);
224: op1 = force_not_mem (op1);
225: }
226:
227: /* If we are inside an appropriately-short loop and one operand is an
228: expensive constant, force it into a register. */
229: if (CONSTANT_P (op0) && preserve_subexpressions_p () && rtx_cost (op0) > 2)
230: op0 = force_reg (mode, op0);
231:
232: if (CONSTANT_P (op1) && preserve_subexpressions_p () && rtx_cost (op1) > 2)
233: op1 = force_reg (shift_op ? word_mode : mode, op1);
234:
235: #if 0 /* Turned off because it seems to be a kludgy method. */
236: /* If subtracting integer from pointer, and the pointer has a special mode,
237: then change it to an add. We use the add insn of Pmode for combining
238: integers with pointers, and the sub insn to subtract two pointers. */
239:
240: if (binoptab == sub_optab
241: && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
242: {
243: op1 = negate_rtx (GET_MODE(op1), op1);
244: binoptab = add_optab;
245: }
246: #endif /* 0 */
247:
248: /* Record where to delete back to if we backtrack. */
249: last = get_last_insn ();
250:
251: /* If operation is commutative,
252: try to make the first operand a register.
253: Even better, try to make it the same as the target.
254: Also try to make the last operand a constant. */
255: if (GET_RTX_CLASS (binoptab->code) == 'c'
256: || binoptab == smul_widen_optab
257: || binoptab == umul_widen_optab)
258: {
259: commutative_op = 1;
260:
261: if (((target == 0 || GET_CODE (target) == REG)
262: ? ((GET_CODE (op1) == REG
263: && GET_CODE (op0) != REG)
264: || target == op1)
265: : rtx_equal_p (op1, target))
266: || GET_CODE (op0) == CONST_INT)
267: {
268: temp = op1;
269: op1 = op0;
270: op0 = temp;
271: }
272: }
273:
274: /* If we can do it with a three-operand insn, do so. */
275:
276: if (methods != OPTAB_MUST_WIDEN
277: && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
278: {
279: int icode = (int) binoptab->handlers[(int) mode].insn_code;
280: enum machine_mode mode0 = insn_operand_mode[icode][1];
281: enum machine_mode mode1 = insn_operand_mode[icode][2];
282: rtx pat;
283: rtx xop0 = op0, xop1 = op1;
284:
285: if (target)
286: temp = target;
287: else
288: temp = gen_reg_rtx (mode);
289:
290: /* If it is a commutative operator and the modes would match
291: if we would swap the operands, we can save the conversions. */
292: if (commutative_op)
293: {
294: if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
295: && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
296: {
297: register rtx tmp;
298:
299: tmp = op0; op0 = op1; op1 = tmp;
300: tmp = xop0; xop0 = xop1; xop1 = tmp;
301: }
302: }
303:
304: /* In case the insn wants input operands in modes different from
305: the result, convert the operands. */
306:
307: if (GET_MODE (op0) != VOIDmode
308: && GET_MODE (op0) != mode0)
309: xop0 = convert_to_mode (mode0, xop0, unsignedp);
310:
311: if (GET_MODE (xop1) != VOIDmode
312: && GET_MODE (xop1) != mode1)
313: xop1 = convert_to_mode (mode1, xop1, unsignedp);
314:
315: /* Now, if insn's predicates don't allow our operands, put them into
316: pseudo regs. */
317:
318: if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
319: xop0 = copy_to_mode_reg (mode0, xop0);
320:
321: if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
322: xop1 = copy_to_mode_reg (mode1, xop1);
323:
324: if (! (*insn_operand_predicate[icode][0]) (temp, mode))
325: temp = gen_reg_rtx (mode);
326:
327: pat = GEN_FCN (icode) (temp, xop0, xop1);
328: if (pat)
329: {
330: /* If PAT is a multi-insn sequence, try to add an appropriate
331: REG_EQUAL note to it. If we can't because TEMP conflicts with an
332: operand, call ourselves again, this time without a target. */
333: if (GET_CODE (pat) == SEQUENCE
334: && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
335: {
336: delete_insns_since (last);
337: return expand_binop (mode, binoptab, op0, op1, 0, unsignedp,
338: methods);
339: }
340:
341: emit_insn (pat);
342: return temp;
343: }
344: else
345: delete_insns_since (last);
346: }
347:
348: /* These can be done a word at a time. */
349: if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
350: && class == MODE_INT
351: && GET_MODE_SIZE (mode) > UNITS_PER_WORD
352: && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
353: {
354: int i;
355: rtx insns;
356: rtx equiv_value;
357:
358: /* If TARGET is the same as one of the operands, the REG_EQUAL note
359: won't be accurate, so use a new target. */
360: if (target == 0 || target == op0 || target == op1)
361: target = gen_reg_rtx (mode);
362:
363: start_sequence ();
364:
365: /* Do the actual arithmetic. */
366: for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
367: {
368: rtx target_piece = operand_subword (target, i, 1, mode);
369: rtx x = expand_binop (word_mode, binoptab,
370: operand_subword_force (op0, i, mode),
371: operand_subword_force (op1, i, mode),
372: target_piece, unsignedp, methods);
373: if (target_piece != x)
374: emit_move_insn (target_piece, x);
375: }
376:
377: insns = get_insns ();
378: end_sequence ();
379:
380: if (binoptab->code != UNKNOWN)
381: equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
382: else
383: equiv_value = 0;
384:
385: emit_no_conflict_block (insns, target, op0, op1, equiv_value);
386: return target;
387: }
388:
389: /* These can be done a word at a time by propagating carries. */
390: if ((binoptab == add_optab || binoptab == sub_optab)
391: && class == MODE_INT
392: && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
393: && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
394: {
395: int i;
396: rtx carry_tmp = gen_reg_rtx (word_mode);
397: optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
398: int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
399: rtx carry_in, carry_out;
400:
401: /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
402: value is one of those, use it. Otherwise, use 1 since it is the
403: one easiest to get. */
404: #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
405: int normalizep = STORE_FLAG_VALUE;
406: #else
407: int normalizep = 1;
408: #endif
409:
410: /* Prepare the operands. */
411: op0 = force_reg (mode, op0);
412: op1 = force_reg (mode, op1);
413:
414: if (target == 0 || GET_CODE (target) != REG
415: || target == op0 || target == op1)
416: target = gen_reg_rtx (mode);
417:
418: /* Do the actual arithmetic. */
419: for (i = 0; i < nwords; i++)
420: {
421: int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
422: rtx target_piece = operand_subword (target, index, 1, mode);
423: rtx op0_piece = operand_subword_force (op0, index, mode);
424: rtx op1_piece = operand_subword_force (op1, index, mode);
425: rtx x;
426:
427: /* Main add/subtract of the input operands. */
428: x = expand_binop (word_mode, binoptab,
429: op0_piece, op1_piece,
430: target_piece, unsignedp, methods);
431: if (x == 0)
432: break;
433:
434: if (i + 1 < nwords)
435: {
436: /* Store carry from main add/subtract. */
437: carry_out = gen_reg_rtx (word_mode);
438: carry_out = emit_store_flag (carry_out,
439: binoptab == add_optab ? LTU : GTU,
440: x, op0_piece,
441: word_mode, 1, normalizep);
442: if (!carry_out)
443: break;
444: }
445:
446: if (i > 0)
447: {
448: /* Add/subtract previous carry to main result. */
449: x = expand_binop (word_mode,
450: normalizep == 1 ? binoptab : otheroptab,
451: x, carry_in,
452: target_piece, 1, methods);
453: if (target_piece != x)
454: emit_move_insn (target_piece, x);
455:
456: if (i + 1 < nwords)
457: {
458: /* THIS CODE HAS NOT BEEN TESTED. */
459: /* Get out carry from adding/subtracting carry in. */
460: carry_tmp = emit_store_flag (carry_tmp,
461: binoptab == add_optab
462: ? LTU : GTU,
463: x, carry_in,
464: word_mode, 1, normalizep);
465: /* Logical-ior the two poss. carry together. */
466: carry_out = expand_binop (word_mode, ior_optab,
467: carry_out, carry_tmp,
468: carry_out, 0, methods);
469: if (!carry_out)
470: break;
471: }
472: }
473:
474: carry_in = carry_out;
475: }
476:
477: if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
478: {
479: rtx temp;
480:
481: temp = emit_move_insn (target, target);
482: REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
483: gen_rtx (binoptab->code, mode, op0, op1),
484: REG_NOTES (temp));
485: return target;
486: }
487: else
488: delete_insns_since (last);
489: }
490:
491: /* If we want to multiply two two-word values and have normal and widening
492: multiplies of single-word values, we can do this with three smaller
493: multiplications. Note that we do not make a REG_NO_CONFLICT block here
494: because we are not operating on one word at a time.
495:
496: The multiplication proceeds as follows:
497: _______________________
498: [__op0_high_|__op0_low__]
499: _______________________
500: * [__op1_high_|__op1_low__]
501: _______________________________________________
502: _______________________
503: (1) [__op0_low__*__op1_low__]
504: _______________________
505: (2a) [__op0_low__*__op1_high_]
506: _______________________
507: (2b) [__op0_high_*__op1_low__]
508: _______________________
509: (3) [__op0_high_*__op1_high_]
510:
511:
512: This gives a 4-word result. Since we are only interested in the
513: lower 2 words, partial result (3) and the upper words of (2a) and
514: (2b) don't need to be calculated. Hence (2a) and (2b) can be
515: calculated using non-widening multiplication.
516:
517: (1), however, needs to be calculated with an unsigned widening
518: multiplication. If this operation is not directly supported we
519: try using a signed widening multiplication and adjust the result.
520: This adjustment works as follows:
521:
522: If both operands are positive then no adjustment is needed.
523:
524: If the operands have different signs, for example op0_low < 0 and
525: op1_low >= 0, the instruction treats the most significant bit of
526: op0_low as a sign bit instead of a bit with significance
527: 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
528: with 2**BITS_PER_WORD - op0_low, and two's complements the
529: result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
530: the result.
531:
532: Similarly, if both operands are negative, we need to add
533: (op0_low + op1_low) * 2**BITS_PER_WORD.
534:
535: We use a trick to adjust quickly. We logically shift op0_low right
536: (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
537: op0_high (op1_high) before it is used to calculate 2b (2a). If no
538: logical shift exists, we do an arithmetic right shift and subtract
539: the 0 or -1. */
540:
541: if (binoptab == smul_optab
542: && class == MODE_INT
543: && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
544: && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
545: && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
546: && ((umul_widen_optab->handlers[(int) mode].insn_code
547: != CODE_FOR_nothing)
548: || (smul_widen_optab->handlers[(int) mode].insn_code
549: != CODE_FOR_nothing)))
550: {
551: int low = (WORDS_BIG_ENDIAN ? 1 : 0);
552: int high = (WORDS_BIG_ENDIAN ? 0 : 1);
553: rtx op0_high = operand_subword_force (op0, high, mode);
554: rtx op0_low = operand_subword_force (op0, low, mode);
555: rtx op1_high = operand_subword_force (op1, high, mode);
556: rtx op1_low = operand_subword_force (op1, low, mode);
557: rtx product = 0;
558: rtx op0_xhigh;
559: rtx op1_xhigh;
560:
561: /* If the target is the same as one of the inputs, don't use it. This
562: prevents problems with the REG_EQUAL note. */
563: if (target == op0 || target == op1)
564: target = 0;
565:
566: /* Multiply the two lower words to get a double-word product.
567: If unsigned widening multiplication is available, use that;
568: otherwise use the signed form and compensate. */
569:
570: if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
571: {
572: product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
573: target, 1, OPTAB_DIRECT);
574:
575: /* If we didn't succeed, delete everything we did so far. */
576: if (product == 0)
577: delete_insns_since (last);
578: else
579: op0_xhigh = op0_high, op1_xhigh = op1_high;
580: }
581:
582: if (product == 0
583: && smul_widen_optab->handlers[(int) mode].insn_code
584: != CODE_FOR_nothing)
585: {
586: rtx wordm1 = gen_rtx (CONST_INT, VOIDmode, BITS_PER_WORD - 1);
587: product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
588: target, 1, OPTAB_DIRECT);
589: op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
590: 0, 1, OPTAB_DIRECT);
591: if (op0_xhigh)
592: op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
593: op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
594: else
595: {
596: op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
597: 0, 0, OPTAB_DIRECT);
598: if (op0_xhigh)
599: op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
600: op0_xhigh, op0_xhigh, 0,
601: OPTAB_DIRECT);
602: }
603:
604: op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
605: 0, 1, OPTAB_DIRECT);
606: if (op1_xhigh)
607: op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
608: op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
609: else
610: {
611: op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
612: 0, 0, OPTAB_DIRECT);
613: if (op1_xhigh)
614: op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
615: op1_xhigh, op1_xhigh, 0,
616: OPTAB_DIRECT);
617: }
618: }
619:
620: /* If we have been able to directly compute the product of the
621: low-order words of the operands and perform any required adjustments
622: of the operands, we proceed by trying two more multiplications
623: and then computing the appropriate sum.
624:
625: We have checked above that the required addition is provided.
626: Full-word addition will normally always succeed, especially if
627: it is provided at all, so we don't worry about its failure. The
628: multiplication may well fail, however, so we do handle that. */
629:
630: if (product && op0_xhigh && op1_xhigh)
631: {
632: rtx product_piece;
633: rtx product_high = operand_subword (product, high, 1, mode);
634: rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh, 0,
635: 0, OPTAB_DIRECT);
636:
637: if (temp)
638: {
639: product_piece = expand_binop (word_mode, add_optab, temp,
640: product_high, product_high,
641: 0, OPTAB_LIB_WIDEN);
642: if (product_piece != product_high)
643: emit_move_insn (product_high, product_piece);
644:
645: temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 0,
646: 0, OPTAB_DIRECT);
647:
648: product_piece = expand_binop (word_mode, add_optab, temp,
649: product_high, product_high,
650: 0, OPTAB_LIB_WIDEN);
651: if (product_piece != product_high)
652: emit_move_insn (product_high, product_piece);
653:
654: temp = emit_move_insn (product, product);
655: REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
656: gen_rtx (MULT, mode, op0, op1),
657: REG_NOTES (temp));
658:
659: return product;
660: }
661: }
662:
663: /* If we get here, we couldn't do it for some reason even though we
664: originally thought we could. Delete anything we've emitted in
665: trying to do it. */
666:
667: delete_insns_since (last);
668: }
669:
670: /* It can't be open-coded in this mode.
671: Use a library call if one is available and caller says that's ok. */
672:
673: if (binoptab->handlers[(int) mode].libfunc
674: && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
675: {
676: rtx insns;
677: rtx funexp = binoptab->handlers[(int) mode].libfunc;
678:
679: start_sequence ();
680:
681: /* Pass 1 for NO_QUEUE so we don't lose any increments
682: if the libcall is cse'd or moved. */
683: emit_library_call (binoptab->handlers[(int) mode].libfunc,
684: 1, mode, 2, op0, mode, op1,
685: (shift_op ? word_mode : mode));
686:
687: insns = get_insns ();
688: end_sequence ();
689:
690: target = gen_reg_rtx (mode);
691: emit_libcall_block (insns, target, hard_libcall_value (mode),
692: gen_rtx (binoptab->code, mode, op0, op1));
693:
694: return target;
695: }
696:
697: delete_insns_since (last);
698:
699: /* It can't be done in this mode. Can we do it in a wider mode? */
700:
701: if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
702: || methods == OPTAB_MUST_WIDEN))
703: return 0; /* Caller says, don't even try. */
704:
705: /* Compute the value of METHODS to pass to recursive calls.
706: Don't allow widening to be tried recursively. */
707:
708: methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
709:
710: /* Look for a wider mode of the same class for which it appears we can do
711: the operation. */
712:
713: if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
714: {
715: for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
716: wider_mode = GET_MODE_WIDER_MODE (wider_mode))
717: {
718: if ((binoptab->handlers[(int) wider_mode].insn_code
719: != CODE_FOR_nothing)
720: || (methods == OPTAB_LIB
721: && binoptab->handlers[(int) wider_mode].libfunc))
722: {
723: rtx xop0 = op0, xop1 = op1;
724: int no_extend = 0;
725:
726: /* For certain integer operations, we need not actually extend
727: the narrow operands, as long as we will truncate
728: the results to the same narrowness. */
729:
730: if ((binoptab == ior_optab || binoptab == and_optab
731: || binoptab == xor_optab
732: || binoptab == add_optab || binoptab == sub_optab
733: || binoptab == smul_optab
734: || binoptab == ashl_optab || binoptab == lshl_optab)
735: && class == MODE_INT)
736: no_extend = 1;
737:
738: /* If an operand is a constant integer, we might as well
739: convert it since that is more efficient than using a SUBREG,
740: unlike the case for other operands. */
741:
742: if (no_extend && GET_MODE (xop0) != VOIDmode)
743: xop0 = gen_rtx (SUBREG, wider_mode,
744: force_reg (GET_MODE (xop0), xop0), 0);
745: else
746: xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
747:
748: if (no_extend && GET_MODE (xop1) != VOIDmode)
749: xop1 = gen_rtx (SUBREG, wider_mode,
750: force_reg (GET_MODE (xop1), xop1), 0);
751: else
752: xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
753:
754: temp = expand_binop (wider_mode, binoptab, xop0, xop1, 0,
755: unsignedp, methods);
756: if (temp)
757: {
758: if (class != MODE_INT)
759: {
760: if (target == 0)
761: target = gen_reg_rtx (mode);
762: convert_move (target, temp, 0);
763: return target;
764: }
765: else
766: return gen_lowpart (mode, temp);
767: }
768: else
769: delete_insns_since (last);
770: }
771: }
772: }
773:
774: return 0;
775: }
776:
777: /* Expand a binary operator which has both signed and unsigned forms.
778: UOPTAB is the optab for unsigned operations, and SOPTAB is for
779: signed operations.
780:
781: If we widen unsigned operands, we may use a signed wider operation instead
782: of an unsigned wider operation, since the result would be the same. */
783:
784: rtx
785: sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
786: enum machine_mode mode;
787: optab uoptab, soptab;
788: rtx op0, op1, target;
789: int unsignedp;
790: enum optab_methods methods;
791: {
792: register rtx temp;
793: optab direct_optab = unsignedp ? uoptab : soptab;
794: struct optab wide_soptab;
795:
796: /* Do it without widening, if possible. */
797: temp = expand_binop (mode, direct_optab, op0, op1, target,
798: unsignedp, OPTAB_DIRECT);
799: if (temp || methods == OPTAB_DIRECT)
800: return temp;
801:
802: /* Try widening to a signed int. Make a fake signed optab that
803: hides any signed insn for direct use. */
804: wide_soptab = *soptab;
805: wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
806: wide_soptab.handlers[(int) mode].libfunc = 0;
807:
808: temp = expand_binop (mode, &wide_soptab, op0, op1, target,
809: unsignedp, OPTAB_WIDEN);
810:
811: /* For unsigned operands, try widening to an unsigned int. */
812: if (temp == 0 && unsignedp)
813: temp = expand_binop (mode, uoptab, op0, op1, target,
814: unsignedp, OPTAB_WIDEN);
815: if (temp || methods == OPTAB_WIDEN)
816: return temp;
817:
818: /* Use the right width lib call if that exists. */
819: temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
820: if (temp || methods == OPTAB_LIB)
821: return temp;
822:
823: /* Must widen and use a lib call, use either signed or unsigned. */
824: temp = expand_binop (mode, &wide_soptab, op0, op1, target,
825: unsignedp, methods);
826: if (temp != 0)
827: return temp;
828: if (unsignedp)
829: return expand_binop (mode, uoptab, op0, op1, target,
830: unsignedp, methods);
831: return 0;
832: }
833:
834: /* Generate code to perform an operation specified by BINOPTAB
835: on operands OP0 and OP1, with two results to TARG1 and TARG2.
836: We assume that the order of the operands for the instruction
837: is TARG0, OP0, OP1, TARG1, which would fit a pattern like
838: [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
839:
840: Either TARG0 or TARG1 may be zero, but what that means is that
841: that result is not actually wanted. We will generate it into
842: a dummy pseudo-reg and discard it. They may not both be zero.
843:
844: Returns 1 if this operation can be performed; 0 if not. */
845:
846: int
847: expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
848: optab binoptab;
849: rtx op0, op1;
850: rtx targ0, targ1;
851: int unsignedp;
852: {
853: enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
854: enum mode_class class;
855: enum machine_mode wider_mode;
856: rtx last;
857:
858: class = GET_MODE_CLASS (mode);
859:
860: op0 = protect_from_queue (op0, 0);
861: op1 = protect_from_queue (op1, 0);
862:
863: if (flag_force_mem)
864: {
865: op0 = force_not_mem (op0);
866: op1 = force_not_mem (op1);
867: }
868:
869: /* If we are inside an appropriately-short loop and one operand is an
870: expensive constant, force it into a register. */
871: if (CONSTANT_P (op0) && preserve_subexpressions_p () && rtx_cost (op0) > 2)
872: op0 = force_reg (mode, op0);
873:
874: if (CONSTANT_P (op1) && preserve_subexpressions_p () && rtx_cost (op1) > 2)
875: op1 = force_reg (mode, op1);
876:
877: if (targ0)
878: targ0 = protect_from_queue (targ0, 1);
879: else
880: targ0 = gen_reg_rtx (mode);
881: if (targ1)
882: targ1 = protect_from_queue (targ1, 1);
883: else
884: targ1 = gen_reg_rtx (mode);
885:
886: /* Record where to go back to if we fail. */
887: last = get_last_insn ();
888:
889: if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
890: {
891: int icode = (int) binoptab->handlers[(int) mode].insn_code;
892: enum machine_mode mode0 = insn_operand_mode[icode][1];
893: enum machine_mode mode1 = insn_operand_mode[icode][2];
894: rtx pat;
895: rtx xop0 = op0, xop1 = op1;
896:
897: /* In case this insn wants input operands in modes different from the
898: result, convert the operands. */
899: if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
900: xop0 = convert_to_mode (mode0, xop0, unsignedp);
901:
902: if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
903: xop1 = convert_to_mode (mode1, xop1, unsignedp);
904:
905: /* Now, if insn doesn't accept these operands, put them into pseudos. */
906: if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
907: xop0 = copy_to_mode_reg (mode0, xop0);
908:
909: if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
910: xop1 = copy_to_mode_reg (mode1, xop1);
911:
912: /* We could handle this, but we should always be called with a pseudo
913: for our targets and all insns should take them as outputs. */
914: if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
915: || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
916: abort ();
917:
918: pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
919: if (pat)
920: {
921: emit_insn (pat);
922: return 1;
923: }
924: else
925: delete_insns_since (last);
926: }
927:
928: /* It can't be done in this mode. Can we do it in a wider mode? */
929:
930: if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
931: {
932: for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
933: wider_mode = GET_MODE_WIDER_MODE (wider_mode))
934: {
935: if (binoptab->handlers[(int) wider_mode].insn_code
936: != CODE_FOR_nothing)
937: {
938: register rtx t0 = gen_reg_rtx (wider_mode);
939: register rtx t1 = gen_reg_rtx (wider_mode);
940:
941: if (expand_twoval_binop (binoptab,
942: convert_to_mode (wider_mode, op0,
943: unsignedp),
944: convert_to_mode (wider_mode, op1,
945: unsignedp),
946: t0, t1, unsignedp))
947: {
948: convert_move (targ0, t0, unsignedp);
949: convert_move (targ1, t1, unsignedp);
950: return 1;
951: }
952: else
953: delete_insns_since (last);
954: }
955: }
956: }
957:
958: return 0;
959: }
960:
961: /* Generate code to perform an operation specified by UNOPTAB
962: on operand OP0, with result having machine-mode MODE.
963:
964: UNSIGNEDP is for the case where we have to widen the operands
965: to perform the operation. It says to use zero-extension.
966:
967: If TARGET is nonzero, the value
968: is generated there, if it is convenient to do so.
969: In all cases an rtx is returned for the locus of the value;
970: this may or may not be TARGET. */
971:
972: rtx
973: expand_unop (mode, unoptab, op0, target, unsignedp)
974: enum machine_mode mode;
975: optab unoptab;
976: rtx op0;
977: rtx target;
978: int unsignedp;
979: {
980: enum mode_class class;
981: enum machine_mode wider_mode;
982: register rtx temp;
983: rtx last = get_last_insn ();
984: rtx pat;
985:
986: class = GET_MODE_CLASS (mode);
987:
988: op0 = protect_from_queue (op0, 0);
989:
990: if (flag_force_mem)
991: {
992: op0 = force_not_mem (op0);
993: }
994:
995: if (target)
996: target = protect_from_queue (target, 1);
997:
998: if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
999: {
1000: int icode = (int) unoptab->handlers[(int) mode].insn_code;
1001: enum machine_mode mode0 = insn_operand_mode[icode][1];
1002: rtx xop0 = op0;
1003:
1004: if (target)
1005: temp = target;
1006: else
1007: temp = gen_reg_rtx (mode);
1008:
1009: if (GET_MODE (xop0) != VOIDmode
1010: && GET_MODE (xop0) != mode0)
1011: xop0 = convert_to_mode (mode0, xop0, unsignedp);
1012:
1013: /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1014:
1015: if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1016: xop0 = copy_to_mode_reg (mode0, xop0);
1017:
1018: if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1019: temp = gen_reg_rtx (mode);
1020:
1021: pat = GEN_FCN (icode) (temp, xop0);
1022: if (pat)
1023: {
1024: if (GET_CODE (pat) == SEQUENCE
1025: && ! add_equal_note (pat, temp, unoptab->code, xop0, 0))
1026: {
1027: delete_insns_since (last);
1028: return expand_unop (mode, unoptab, op0, 0, unsignedp);
1029: }
1030:
1031: emit_insn (pat);
1032:
1033: return temp;
1034: }
1035: else
1036: delete_insns_since (last);
1037: }
1038:
1039: /* These can be done a word at a time. */
1040: if (unoptab == one_cmpl_optab
1041: && class == MODE_INT
1042: && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1043: && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1044: {
1045: int i;
1046: rtx insns;
1047:
1048: if (target == 0 || target == op0)
1049: target = gen_reg_rtx (mode);
1050:
1051: start_sequence ();
1052:
1053: /* Do the actual arithmetic. */
1054: for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1055: {
1056: rtx target_piece = operand_subword (target, i, 1, mode);
1057: rtx x = expand_unop (word_mode, unoptab,
1058: operand_subword_force (op0, i, mode),
1059: target_piece, unsignedp);
1060: if (target_piece != x)
1061: emit_move_insn (target_piece, x);
1062: }
1063:
1064: insns = get_insns ();
1065: end_sequence ();
1066:
1067: emit_no_conflict_block (insns, target, op0, 0,
1068: gen_rtx (unoptab->code, mode, op0));
1069: return target;
1070: }
1071:
1072: if (unoptab->handlers[(int) mode].libfunc)
1073: {
1074: rtx insns;
1075: rtx funexp = unoptab->handlers[(int) mode].libfunc;
1076:
1077: start_sequence ();
1078:
1079: /* Pass 1 for NO_QUEUE so we don't lose any increments
1080: if the libcall is cse'd or moved. */
1081: emit_library_call (unoptab->handlers[(int) mode].libfunc,
1082: 1, mode, 1, op0, mode);
1083: insns = get_insns ();
1084: end_sequence ();
1085:
1086: target = gen_reg_rtx (mode);
1087: emit_libcall_block (insns, target, hard_libcall_value (mode),
1088: gen_rtx (unoptab->code, mode, op0));
1089:
1090: return target;
1091: }
1092:
1093: /* It can't be done in this mode. Can we do it in a wider mode? */
1094:
1095: if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1096: {
1097: for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1098: wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1099: {
1100: if ((unoptab->handlers[(int) wider_mode].insn_code
1101: != CODE_FOR_nothing)
1102: || unoptab->handlers[(int) wider_mode].libfunc)
1103: {
1104: rtx xop0 = op0;
1105:
1106: /* For certain operations, we need not actually extend
1107: the narrow operand, as long as we will truncate the
1108: results to the same narrowness. */
1109:
1110: if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1111: && class == MODE_INT)
1112: xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1113: else
1114: xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1115:
1116: temp = expand_unop (wider_mode, unoptab, xop0, 0, unsignedp);
1117:
1118: if (temp)
1119: {
1120: if (class != MODE_INT)
1121: {
1122: if (target == 0)
1123: target = gen_reg_rtx (mode);
1124: convert_move (target, temp, 0);
1125: return target;
1126: }
1127: else
1128: return gen_lowpart (mode, temp);
1129: }
1130: else
1131: delete_insns_since (last);
1132: }
1133: }
1134: }
1135:
1136: return 0;
1137: }
1138:
1139: /* Generate an instruction whose insn-code is INSN_CODE,
1140: with two operands: an output TARGET and an input OP0.
1141: TARGET *must* be nonzero, and the output is always stored there.
1142: CODE is an rtx code such that (CODE OP0) is an rtx that describes
1143: the value that is stored into TARGET. */
1144:
1145: void
1146: emit_unop_insn (icode, target, op0, code)
1147: int icode;
1148: rtx target;
1149: rtx op0;
1150: enum rtx_code code;
1151: {
1152: register rtx temp;
1153: enum machine_mode mode0 = insn_operand_mode[icode][1];
1154: rtx pat;
1155:
1156: temp = target = protect_from_queue (target, 1);
1157:
1158: op0 = protect_from_queue (op0, 0);
1159:
1160: if (flag_force_mem)
1161: op0 = force_not_mem (op0);
1162:
1163: /* Now, if insn does not accept our operands, put them into pseudos. */
1164:
1165: if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1166: op0 = copy_to_mode_reg (mode0, op0);
1167:
1168: if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1169: || (flag_force_mem && GET_CODE (temp) == MEM))
1170: temp = gen_reg_rtx (GET_MODE (temp));
1171:
1172: pat = GEN_FCN (icode) (temp, op0);
1173:
1174: if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1175: add_equal_note (pat, temp, code, op0, 0);
1176:
1177: emit_insn (pat);
1178:
1179: if (temp != target)
1180: emit_move_insn (target, temp);
1181: }
1182:
1183: /* Emit code to perform a series of operations on a multi-word quantity, one
1184: word at a time.
1185:
1186: Such a block is preceeded by a CLOBBER of the output, consists of multiple
1187: insns, each setting one word of the output, and followed by a SET copying
1188: the output to itself.
1189:
1190: Each of the insns setting words of the output receives a REG_NO_CONFLICT
1191: note indicating that it doesn't conflict with the (also multi-word)
1192: inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1193: notes.
1194:
1195: INSNS is a block of code generated to perform the operation, not including
1196: the CLOBBER and final copy. All insns that compute intermediate values
1197: are first emitted, followed by the block as described above. Only
1198: INSNs are allowed in the block; no library calls or jumps may be
1199: present.
1200:
1201: TARGET, OP0, and OP1 are the output and inputs of the operations,
1202: respectively. OP1 may be zero for a unary operation.
1203:
1204: EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1205: on the last insn.
1206:
1207: If TARGET is not a register, INSNS is simply emitted with no special
1208: processing.
1209:
1210: The final insn emitted is returned. */
1211:
1212: rtx
1213: emit_no_conflict_block (insns, target, op0, op1, equiv)
1214: rtx insns;
1215: rtx target;
1216: rtx op0, op1;
1217: rtx equiv;
1218: {
1219: rtx prev, next, first, last, insn;
1220:
1221: if (GET_CODE (target) != REG || reload_in_progress)
1222: return emit_insns (insns);
1223:
1224: /* First emit all insns that do not store into words of the output and remove
1225: these from the list. */
1226: for (insn = insns; insn; insn = next)
1227: {
1228: rtx set = 0;
1229: int i;
1230:
1231: next = NEXT_INSN (insn);
1232:
1233: if (GET_CODE (insn) != INSN)
1234: abort ();
1235:
1236: if (GET_CODE (PATTERN (insn)) == SET)
1237: set = PATTERN (insn);
1238: else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1239: {
1240: for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1241: if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1242: {
1243: set = XVECEXP (PATTERN (insn), 0, i);
1244: break;
1245: }
1246: }
1247:
1248: if (set == 0)
1249: abort ();
1250:
1251: if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1252: {
1253: if (PREV_INSN (insn))
1254: NEXT_INSN (PREV_INSN (insn)) = next;
1255: else
1256: insns = next;
1257:
1258: if (next)
1259: PREV_INSN (next) = PREV_INSN (insn);
1260:
1261: add_insn (insn);
1262: }
1263: }
1264:
1265: prev = get_last_insn ();
1266:
1267: /* Now write the CLOBBER of the output, followed by the setting of each
1268: of the words, followed by the final copy. */
1269: if (target != op0 && target != op1)
1270: emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1271:
1272: for (insn = insns; insn; insn = next)
1273: {
1274: next = NEXT_INSN (insn);
1275: add_insn (insn);
1276:
1277: if (op1 && GET_CODE (op1) == REG)
1278: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1279: REG_NOTES (insn));
1280:
1281: if (op0 && GET_CODE (op0) == REG)
1282: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1283: REG_NOTES (insn));
1284: }
1285:
1286: last = emit_move_insn (target, target);
1287: if (equiv)
1288: REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1289:
1290: if (prev == 0)
1291: first = get_insns ();
1292: else
1293: first = NEXT_INSN (prev);
1294:
1295: /* Encapsulate the block so it gets manipulated as a unit. */
1296: REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1297: REG_NOTES (first));
1298: REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1299:
1300: return last;
1301: }
1302:
1303: /* Emit code to make a call to a constant function or a library call.
1304:
1305: INSNS is a list containing all insns emitted in the call.
1306: These insns leave the result in RESULT. Our block is to copy RESULT
1307: to TARGET, which is logically equivalent to EQUIV.
1308:
1309: We first emit any insns that set a pseudo on the assumption that these are
1310: loading constants into registers; doing so allows them to be safely cse'ed
1311: between blocks. Then we emit all the other insns in the block, followed by
1312: an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1313: note with an operand of EQUIV.
1314:
1315: Except for the first group of insns (the ones setting pseudos), the
1316: block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1317:
1318: void
1319: emit_libcall_block (insns, target, result, equiv)
1320: rtx insns;
1321: rtx target;
1322: rtx result;
1323: rtx equiv;
1324: {
1325: rtx prev, next, first, last, insn;
1326:
1327: /* First emit all insns that set pseudos. Remove them from the list as
1328: we go. */
1329:
1330: for (insn = insns; insn; insn = next)
1331: {
1332: rtx set = single_set (insn);
1333:
1334: next = NEXT_INSN (insn);
1335:
1336: if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1337: && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
1338: {
1339: if (PREV_INSN (insn))
1340: NEXT_INSN (PREV_INSN (insn)) = next;
1341: else
1342: insns = next;
1343:
1344: if (next)
1345: PREV_INSN (next) = PREV_INSN (insn);
1346:
1347: add_insn (insn);
1348: }
1349: }
1350:
1351: prev = get_last_insn ();
1352:
1353: /* Write the remaining insns followed by the final copy. */
1354:
1355: for (insn = insns; insn; insn = next)
1356: {
1357: next = NEXT_INSN (insn);
1358:
1359: add_insn (insn);
1360: }
1361:
1362: last = emit_move_insn (target, result);
1363: REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1364:
1365: if (prev == 0)
1366: first = get_insns ();
1367: else
1368: first = NEXT_INSN (prev);
1369:
1370: /* Encapsulate the block so it gets manipulated as a unit. */
1371: REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1372: REG_NOTES (first));
1373: REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1374: }
1375:
1376: /* Generate code to store zero in X. */
1377:
1378: void
1379: emit_clr_insn (x)
1380: rtx x;
1381: {
1382: emit_move_insn (x, const0_rtx);
1383: }
1384:
1385: /* Generate code to store 1 in X
1386: assuming it contains zero beforehand. */
1387:
1388: void
1389: emit_0_to_1_insn (x)
1390: rtx x;
1391: {
1392: emit_move_insn (x, const1_rtx);
1393: }
1394:
1395: /* Generate code to compare X with Y
1396: so that the condition codes are set.
1397:
1398: MODE is the mode of the inputs (in case they are const_int).
1399: UNSIGNEDP nonzero says that X and Y are unsigned;
1400: this matters if they need to be widened.
1401:
1402: If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1403: and ALIGN specifies the known shared alignment of X and Y.
1404:
1405: COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1406: It is ignored for fixed-point and block comparisons;
1407: it is used only for floating-point comparisons. */
1408:
1409: void
1410: emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1411: rtx x, y;
1412: enum rtx_code comparison;
1413: rtx size;
1414: int unsignedp;
1415: int align;
1416: {
1417: enum mode_class class;
1418: enum machine_mode wider_mode;
1419:
1420: class = GET_MODE_CLASS (mode);
1421:
1422: /* They could both be VOIDmode if both args are immediate constants,
1423: but we should fold that at an earlier stage.
1424: With no special code here, this will call abort,
1425: reminding the programmer to implement such folding. */
1426:
1427: if (mode != BLKmode && flag_force_mem)
1428: {
1429: x = force_not_mem (x);
1430: y = force_not_mem (y);
1431: }
1432:
1433: /* If we are inside an appropriately-short loop and one operand is an
1434: expensive constant, force it into a register. */
1435: if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x) > 2)
1436: x = force_reg (mode, x);
1437:
1438: if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y) > 2)
1439: y = force_reg (mode, y);
1440:
1441: /* Don't let both operands fail to indicate the mode. */
1442: if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1443: x = force_reg (mode, x);
1444:
1445: /* Handle all BLKmode compares. */
1446:
1447: if (mode == BLKmode)
1448: {
1449: emit_queue ();
1450: x = protect_from_queue (x, 0);
1451: y = protect_from_queue (y, 0);
1452:
1453: if (size == 0)
1454: abort ();
1455: #ifdef HAVE_cmpstrqi
1456: if (HAVE_cmpstrqi
1457: && GET_CODE (size) == CONST_INT
1458: && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1459: {
1460: enum machine_mode result_mode
1461: = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1462: rtx result = gen_reg_rtx (result_mode);
1463: emit_insn (gen_cmpstrqi (result, x, y, size,
1464: gen_rtx (CONST_INT, VOIDmode, align)));
1465: emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1466: }
1467: else
1468: #endif
1469: #ifdef HAVE_cmpstrhi
1470: if (HAVE_cmpstrhi
1471: && GET_CODE (size) == CONST_INT
1472: && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1473: {
1474: enum machine_mode result_mode
1475: = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1476: rtx result = gen_reg_rtx (result_mode);
1477: emit_insn (gen_cmpstrhi (result, x, y, size,
1478: gen_rtx (CONST_INT, VOIDmode, align)));
1479: emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1480: }
1481: else
1482: #endif
1483: #ifdef HAVE_cmpstrsi
1484: if (HAVE_cmpstrsi)
1485: {
1486: enum machine_mode result_mode
1487: = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1488: rtx result = gen_reg_rtx (result_mode);
1489: emit_insn (gen_cmpstrsi (result, x, y,
1490: convert_to_mode (SImode, size, 1),
1491: gen_rtx (CONST_INT, VOIDmode, align)));
1492: emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1493: }
1494: else
1495: #endif
1496: {
1497: #ifdef TARGET_MEM_FUNCTIONS
1498: emit_library_call (memcmp_libfunc, 0,
1499: TYPE_MODE (integer_type_node), 3,
1500: XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1501: size, Pmode);
1502: #else
1503: emit_library_call (bcmp_libfunc, 0,
1504: TYPE_MODE (integer_type_node), 3,
1505: XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1506: size, Pmode);
1507: #endif
1508: emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1509: const0_rtx, comparison, 0,
1510: TYPE_MODE (integer_type_node), 0, 0);
1511: }
1512: return;
1513: }
1514:
1515: /* Handle some compares against zero. */
1516:
1517: if (y == CONST0_RTX (mode)
1518: && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1519: {
1520: int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1521:
1522: emit_queue ();
1523: x = protect_from_queue (x, 0);
1524: y = protect_from_queue (y, 0);
1525:
1526: /* Now, if insn does accept these operands, put them into pseudos. */
1527: if (! (*insn_operand_predicate[icode][0])
1528: (x, insn_operand_mode[icode][0]))
1529: x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1530:
1531: emit_insn (GEN_FCN (icode) (x));
1532: return;
1533: }
1534:
1535: /* Handle compares for which there is a directly suitable insn. */
1536:
1537: if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1538: {
1539: int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1540:
1541: emit_queue ();
1542: x = protect_from_queue (x, 0);
1543: y = protect_from_queue (y, 0);
1544:
1545: /* Now, if insn doesn't accept these operands, put them into pseudos. */
1546: if (! (*insn_operand_predicate[icode][0])
1547: (x, insn_operand_mode[icode][0]))
1548: x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1549:
1550: if (! (*insn_operand_predicate[icode][1])
1551: (y, insn_operand_mode[icode][1]))
1552: y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1553:
1554: emit_insn (GEN_FCN (icode) (x, y));
1555: return;
1556: }
1557:
1558: /* Try widening if we can find a direct insn that way. */
1559:
1560: if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1561: {
1562: for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1563: wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1564: {
1565: if (cmp_optab->handlers[(int) wider_mode].insn_code
1566: != CODE_FOR_nothing)
1567: {
1568: x = convert_to_mode (wider_mode, x, unsignedp);
1569: y = convert_to_mode (wider_mode, y, unsignedp);
1570: emit_cmp_insn (x, y, comparison, 0,
1571: wider_mode, unsignedp, align);
1572: return;
1573: }
1574: }
1575: }
1576:
1577: /* Handle a lib call just for the mode we are using. */
1578:
1579: if (cmp_optab->handlers[(int) mode].libfunc
1580: && class != MODE_FLOAT)
1581: {
1582: rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1583: /* If we want unsigned, and this mode has a distinct unsigned
1584: comparison routine, use that. */
1585: if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1586: libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1587:
1588: emit_library_call (libfunc, 0,
1589: SImode, 2, x, mode, y, mode);
1590:
1591: /* Integer comparison returns a result that must be compared against 1,
1592: so that even if we do an unsigned compare afterward,
1593: there is still a value that can represent the result "less than". */
1594:
1595: emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1596: comparison, 0, SImode, unsignedp, 0);
1597: return;
1598: }
1599:
1600: if (class == MODE_FLOAT)
1601: emit_float_lib_cmp (x, y, comparison);
1602:
1603: else
1604: abort ();
1605: }
1606:
1607: /* Nonzero if a compare of mode MODE can be done straightforwardly
1608: (without splitting it into pieces). */
1609:
1610: int
1611: can_compare_p (mode)
1612: enum machine_mode mode;
1613: {
1614: do
1615: {
1616: if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1617: return 1;
1618: mode = GET_MODE_WIDER_MODE (mode);
1619: } while (mode != VOIDmode);
1620:
1621: return 0;
1622: }
1623:
1624: /* Emit a library call comparison between floating point X and Y.
1625: COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1626:
1627: static void
1628: emit_float_lib_cmp (x, y, comparison)
1629: rtx x, y;
1630: enum rtx_code comparison;
1631: {
1632: enum machine_mode mode = GET_MODE (x);
1633: rtx libfunc;
1634:
1635: if (mode == SFmode)
1636: switch (comparison)
1637: {
1638: case EQ:
1639: libfunc = eqsf2_libfunc;
1640: break;
1641:
1642: case NE:
1643: libfunc = nesf2_libfunc;
1644: break;
1645:
1646: case GT:
1647: libfunc = gtsf2_libfunc;
1648: break;
1649:
1650: case GE:
1651: libfunc = gesf2_libfunc;
1652: break;
1653:
1654: case LT:
1655: libfunc = ltsf2_libfunc;
1656: break;
1657:
1658: case LE:
1659: libfunc = lesf2_libfunc;
1660: break;
1661: }
1662: else if (mode == DFmode)
1663: switch (comparison)
1664: {
1665: case EQ:
1666: libfunc = eqdf2_libfunc;
1667: break;
1668:
1669: case NE:
1670: libfunc = nedf2_libfunc;
1671: break;
1672:
1673: case GT:
1674: libfunc = gtdf2_libfunc;
1675: break;
1676:
1677: case GE:
1678: libfunc = gedf2_libfunc;
1679: break;
1680:
1681: case LT:
1682: libfunc = ltdf2_libfunc;
1683: break;
1684:
1685: case LE:
1686: libfunc = ledf2_libfunc;
1687: break;
1688: }
1689: else
1690: {
1691: enum machine_mode wider_mode;
1692:
1693: for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1694: wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1695: {
1696: if ((cmp_optab->handlers[(int) wider_mode].insn_code
1697: != CODE_FOR_nothing)
1698: || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1699: {
1700: x = convert_to_mode (wider_mode, x, 0);
1701: y = convert_to_mode (wider_mode, y, 0);
1702: emit_float_lib_cmp (x, y, comparison);
1703: return;
1704: }
1705: }
1706: abort ();
1707: }
1708:
1709: emit_library_call (libfunc, 0,
1710: SImode, 2, x, mode, y, mode);
1711:
1712: emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1713: 0, SImode, 0, 0);
1714: }
1715:
1716: /* Generate code to indirectly jump to a location given in the rtx LOC. */
1717:
1718: void
1719: emit_indirect_jump (loc)
1720: rtx loc;
1721: {
1722: if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1723: (loc, VOIDmode)))
1724: loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1725: loc);
1726:
1727: emit_jump_insn (gen_indirect_jump (loc));
1728: }
1729:
1730: /* These three functions generate an insn body and return it
1731: rather than emitting the insn.
1732:
1733: They do not protect from queued increments,
1734: because they may be used 1) in protect_from_queue itself
1735: and 2) in other passes where there is no queue. */
1736:
1737: /* Generate and return an insn body to add Y to X. */
1738:
1739: rtx
1740: gen_add2_insn (x, y)
1741: rtx x, y;
1742: {
1743: int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1744:
1745: if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1746: || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1747: || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1748: abort ();
1749:
1750: return (GEN_FCN (icode) (x, x, y));
1751: }
1752:
1753: int
1754: have_add2_insn (mode)
1755: enum machine_mode mode;
1756: {
1757: return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1758: }
1759:
1760: /* Generate and return an insn body to subtract Y from X. */
1761:
1762: rtx
1763: gen_sub2_insn (x, y)
1764: rtx x, y;
1765: {
1766: int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
1767:
1768: if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1769: || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1770: || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1771: abort ();
1772:
1773: return (GEN_FCN (icode) (x, x, y));
1774: }
1775:
1776: int
1777: have_sub2_insn (mode)
1778: enum machine_mode mode;
1779: {
1780: return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1781: }
1782:
1783: /* Generate the body of an instruction to copy Y into X. */
1784:
1785: rtx
1786: gen_move_insn (x, y)
1787: rtx x, y;
1788: {
1789: register enum machine_mode mode = GET_MODE (x);
1790: enum insn_code insn_code;
1791:
1792: if (mode == VOIDmode)
1793: mode = GET_MODE (y);
1794:
1795: insn_code = mov_optab->handlers[(int) mode].insn_code;
1796:
1797: /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
1798: find a mode to do it in. If we have a movcc, use it. Otherwise,
1799: find the MODE_INT mode of the same width. */
1800:
1801: if (insn_code == CODE_FOR_nothing)
1802: {
1803: enum machine_mode tmode = VOIDmode;
1804: rtx x1 = x, y1 = y;
1805:
1806: if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
1807: && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
1808: tmode = CCmode;
1809: else if (GET_MODE_CLASS (mode) == MODE_CC)
1810: for (tmode = QImode; tmode != VOIDmode;
1811: tmode = GET_MODE_WIDER_MODE (tmode))
1812: if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
1813: break;
1814:
1815: if (tmode == VOIDmode)
1816: abort ();
1817:
1818: /* Get X and Y in TMODE. We can't use gen_lowpart here because it
1819: may call change_address which is not appropriate if we were
1820: called when a reload was in progress. We don't have to worry
1821: about changing the address since the size in bytes is supposed to
1822: be the same. Copy the MEM to change the mode and move any
1823: substitutions from the old MEM to the new one. */
1824:
1825: if (reload_in_progress)
1826: {
1827: x = gen_lowpart_common (tmode, x1);
1828: if (x == 0 && GET_CODE (x1) == MEM)
1829: {
1830: x = gen_rtx (MEM, tmode, XEXP (x1, 0));
1831: RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
1832: MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
1833: MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
1834: copy_replacements (x1, x);
1835: }
1836:
1837: y = gen_lowpart_common (tmode, y1);
1838: if (y == 0 && GET_CODE (y1) == MEM)
1839: {
1840: y = gen_rtx (MEM, tmode, XEXP (y1, 0));
1841: RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
1842: MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
1843: MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
1844: copy_replacements (y1, y);
1845: }
1846: }
1847: else
1848: {
1849: x = gen_lowpart (tmode, x);
1850: y = gen_lowpart (tmode, y);
1851: }
1852:
1853: insn_code = mov_optab->handlers[(int) tmode].insn_code;
1854: }
1855:
1856: return (GEN_FCN (insn_code) (x, y));
1857: }
1858:
1859: /* Tables of patterns for extending one integer mode to another. */
1860: static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
1861:
1862: /* Return the insn code used to extend FROM_MODE to TO_MODE.
1863: UNSIGNEDP specifies zero-extension instead of sign-extension. If
1864: no such operation exists, CODE_FOR_nothing will be returned. */
1865:
1866: enum insn_code
1867: can_extend_p (to_mode, from_mode, unsignedp)
1868: enum machine_mode to_mode, from_mode;
1869: int unsignedp;
1870: {
1871: return extendtab[(int) to_mode][(int) from_mode][unsignedp];
1872: }
1873:
1874: /* Generate the body of an insn to extend Y (with mode MFROM)
1875: into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
1876:
1877: rtx
1878: gen_extend_insn (x, y, mto, mfrom, unsignedp)
1879: rtx x, y;
1880: enum machine_mode mto, mfrom;
1881: int unsignedp;
1882: {
1883: return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
1884: }
1885:
1886: static void
1887: init_extends ()
1888: {
1889: enum insn_code *p;
1890:
1891: for (p = extendtab[0][0];
1892: p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
1893: p++)
1894: *p = CODE_FOR_nothing;
1895:
1896: #ifdef HAVE_extendditi2
1897: if (HAVE_extendditi2)
1898: extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
1899: #endif
1900: #ifdef HAVE_extendsiti2
1901: if (HAVE_extendsiti2)
1902: extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
1903: #endif
1904: #ifdef HAVE_extendhiti2
1905: if (HAVE_extendhiti2)
1906: extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
1907: #endif
1908: #ifdef HAVE_extendqiti2
1909: if (HAVE_extendqiti2)
1910: extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
1911: #endif
1912: #ifdef HAVE_extendsidi2
1913: if (HAVE_extendsidi2)
1914: extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
1915: #endif
1916: #ifdef HAVE_extendhidi2
1917: if (HAVE_extendhidi2)
1918: extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
1919: #endif
1920: #ifdef HAVE_extendqidi2
1921: if (HAVE_extendqidi2)
1922: extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
1923: #endif
1924: #ifdef HAVE_extendhisi2
1925: if (HAVE_extendhisi2)
1926: extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
1927: #endif
1928: #ifdef HAVE_extendqisi2
1929: if (HAVE_extendqisi2)
1930: extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
1931: #endif
1932: #ifdef HAVE_extendqihi2
1933: if (HAVE_extendqihi2)
1934: extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
1935: #endif
1936:
1937: #ifdef HAVE_zero_extendditi2
1938: if (HAVE_zero_extendsiti2)
1939: extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
1940: #endif
1941: #ifdef HAVE_zero_extendsiti2
1942: if (HAVE_zero_extendsiti2)
1943: extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
1944: #endif
1945: #ifdef HAVE_zero_extendhiti2
1946: if (HAVE_zero_extendhiti2)
1947: extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
1948: #endif
1949: #ifdef HAVE_zero_extendqiti2
1950: if (HAVE_zero_extendqiti2)
1951: extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
1952: #endif
1953: #ifdef HAVE_zero_extendsidi2
1954: if (HAVE_zero_extendsidi2)
1955: extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
1956: #endif
1957: #ifdef HAVE_zero_extendhidi2
1958: if (HAVE_zero_extendhidi2)
1959: extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
1960: #endif
1961: #ifdef HAVE_zero_extendqidi2
1962: if (HAVE_zero_extendqidi2)
1963: extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
1964: #endif
1965: #ifdef HAVE_zero_extendhisi2
1966: if (HAVE_zero_extendhisi2)
1967: extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
1968: #endif
1969: #ifdef HAVE_zero_extendqisi2
1970: if (HAVE_zero_extendqisi2)
1971: extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
1972: #endif
1973: #ifdef HAVE_zero_extendqihi2
1974: if (HAVE_zero_extendqihi2)
1975: extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
1976: #endif
1977: }
1978:
1979: /* can_fix_p and can_float_p say whether the target machine
1980: can directly convert a given fixed point type to
1981: a given floating point type, or vice versa.
1982: The returned value is the CODE_FOR_... value to use,
1983: or CODE_FOR_nothing if these modes cannot be directly converted. */
1984:
1985: static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1986: static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1987: static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1988:
1989: /* *TRUNCP_PTR is set to 1 if it is necessary to output
1990: an explicit FTRUNC insn before the fix insn; otherwise 0. */
1991:
1992: static enum insn_code
1993: can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
1994: enum machine_mode fltmode, fixmode;
1995: int unsignedp;
1996: int *truncp_ptr;
1997: {
1998: *truncp_ptr = 0;
1999: if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2000: return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2001:
2002: if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2003: {
2004: *truncp_ptr = 1;
2005: return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2006: }
2007: return CODE_FOR_nothing;
2008: }
2009:
2010: static enum insn_code
2011: can_float_p (fltmode, fixmode, unsignedp)
2012: enum machine_mode fixmode, fltmode;
2013: int unsignedp;
2014: {
2015: return floattab[(int) fltmode][(int) fixmode][unsignedp];
2016: }
2017:
2018: void
2019: init_fixtab ()
2020: {
2021: enum insn_code *p;
2022: for (p = fixtab[0][0];
2023: p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2024: p++)
2025: *p = CODE_FOR_nothing;
2026: for (p = fixtrunctab[0][0];
2027: p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2028: p++)
2029: *p = CODE_FOR_nothing;
2030:
2031: #ifdef HAVE_fixsfqi2
2032: if (HAVE_fixsfqi2)
2033: fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2034: #endif
2035: #ifdef HAVE_fixsfhi2
2036: if (HAVE_fixsfhi2)
2037: fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2038: #endif
2039: #ifdef HAVE_fixsfsi2
2040: if (HAVE_fixsfsi2)
2041: fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2042: #endif
2043: #ifdef HAVE_fixsfdi2
2044: if (HAVE_fixsfdi2)
2045: fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2046: #endif
2047:
2048: #ifdef HAVE_fixdfqi2
2049: if (HAVE_fixdfqi2)
2050: fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2051: #endif
2052: #ifdef HAVE_fixdfhi2
2053: if (HAVE_fixdfhi2)
2054: fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2055: #endif
2056: #ifdef HAVE_fixdfsi2
2057: if (HAVE_fixdfsi2)
2058: fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2059: #endif
2060: #ifdef HAVE_fixdfdi2
2061: if (HAVE_fixdfdi2)
2062: fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2063: #endif
2064: #ifdef HAVE_fixdfti2
2065: if (HAVE_fixdfti2)
2066: fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2067: #endif
2068:
2069: #ifdef HAVE_fixtfqi2
2070: if (HAVE_fixtfqi2)
2071: fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2072: #endif
2073: #ifdef HAVE_fixtfhi2
2074: if (HAVE_fixtfhi2)
2075: fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2076: #endif
2077: #ifdef HAVE_fixtfsi2
2078: if (HAVE_fixtfsi2)
2079: fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2080: #endif
2081: #ifdef HAVE_fixtfdi2
2082: if (HAVE_fixtfdi2)
2083: fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2084: #endif
2085: #ifdef HAVE_fixtfti2
2086: if (HAVE_fixtfti2)
2087: fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2088: #endif
2089:
2090: #ifdef HAVE_fixunssfqi2
2091: if (HAVE_fixunssfqi2)
2092: fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2093: #endif
2094: #ifdef HAVE_fixunssfhi2
2095: if (HAVE_fixunssfhi2)
2096: fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2097: #endif
2098: #ifdef HAVE_fixunssfsi2
2099: if (HAVE_fixunssfsi2)
2100: fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2101: #endif
2102: #ifdef HAVE_fixunssfdi2
2103: if (HAVE_fixunssfdi2)
2104: fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2105: #endif
2106:
2107: #ifdef HAVE_fixunsdfqi2
2108: if (HAVE_fixunsdfqi2)
2109: fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2110: #endif
2111: #ifdef HAVE_fixunsdfhi2
2112: if (HAVE_fixunsdfhi2)
2113: fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2114: #endif
2115: #ifdef HAVE_fixunsdfsi2
2116: if (HAVE_fixunsdfsi2)
2117: fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2118: #endif
2119: #ifdef HAVE_fixunsdfdi2
2120: if (HAVE_fixunsdfdi2)
2121: fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2122: #endif
2123: #ifdef HAVE_fixunsdfti2
2124: if (HAVE_fixunsdfti2)
2125: fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2126: #endif
2127:
2128: #ifdef HAVE_fixunstfqi2
2129: if (HAVE_fixunstfqi2)
2130: fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2131: #endif
2132: #ifdef HAVE_fixunstfhi2
2133: if (HAVE_fixunstfhi2)
2134: fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2135: #endif
2136: #ifdef HAVE_fixunstfsi2
2137: if (HAVE_fixunstfsi2)
2138: fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2139: #endif
2140: #ifdef HAVE_fixunstfdi2
2141: if (HAVE_fixunstfdi2)
2142: fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2143: #endif
2144: #ifdef HAVE_fixunstfti2
2145: if (HAVE_fixunstfti2)
2146: fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2147: #endif
2148:
2149: #ifdef HAVE_fix_truncsfqi2
2150: if (HAVE_fix_truncsfqi2)
2151: fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2152: #endif
2153: #ifdef HAVE_fix_truncsfhi2
2154: if (HAVE_fix_truncsfhi2)
2155: fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2156: #endif
2157: #ifdef HAVE_fix_truncsfsi2
2158: if (HAVE_fix_truncsfsi2)
2159: fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2160: #endif
2161: #ifdef HAVE_fix_truncsfdi2
2162: if (HAVE_fix_truncsfdi2)
2163: fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2164: #endif
2165:
2166: #ifdef HAVE_fix_truncdfqi2
2167: if (HAVE_fix_truncdfsi2)
2168: fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2169: #endif
2170: #ifdef HAVE_fix_truncdfhi2
2171: if (HAVE_fix_truncdfhi2)
2172: fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2173: #endif
2174: #ifdef HAVE_fix_truncdfsi2
2175: if (HAVE_fix_truncdfsi2)
2176: fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2177: #endif
2178: #ifdef HAVE_fix_truncdfdi2
2179: if (HAVE_fix_truncdfdi2)
2180: fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2181: #endif
2182: #ifdef HAVE_fix_truncdfti2
2183: if (HAVE_fix_truncdfti2)
2184: fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2185: #endif
2186:
2187: #ifdef HAVE_fix_trunctfqi2
2188: if (HAVE_fix_trunctfqi2)
2189: fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2190: #endif
2191: #ifdef HAVE_fix_trunctfhi2
2192: if (HAVE_fix_trunctfhi2)
2193: fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2194: #endif
2195: #ifdef HAVE_fix_trunctfsi2
2196: if (HAVE_fix_trunctfsi2)
2197: fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2198: #endif
2199: #ifdef HAVE_fix_trunctfdi2
2200: if (HAVE_fix_trunctfdi2)
2201: fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2202: #endif
2203: #ifdef HAVE_fix_trunctfti2
2204: if (HAVE_fix_trunctfti2)
2205: fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2206: #endif
2207:
2208: #ifdef HAVE_fixuns_truncsfqi2
2209: if (HAVE_fixuns_truncsfqi2)
2210: fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2211: #endif
2212: #ifdef HAVE_fixuns_truncsfhi2
2213: if (HAVE_fixuns_truncsfhi2)
2214: fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2215: #endif
2216: #ifdef HAVE_fixuns_truncsfsi2
2217: if (HAVE_fixuns_truncsfsi2)
2218: fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2219: #endif
2220: #ifdef HAVE_fixuns_truncsfdi2
2221: if (HAVE_fixuns_truncsfdi2)
2222: fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2223: #endif
2224:
2225: #ifdef HAVE_fixuns_truncdfqi2
2226: if (HAVE_fixuns_truncdfqi2)
2227: fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2228: #endif
2229: #ifdef HAVE_fixuns_truncdfhi2
2230: if (HAVE_fixuns_truncdfhi2)
2231: fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2232: #endif
2233: #ifdef HAVE_fixuns_truncdfsi2
2234: if (HAVE_fixuns_truncdfsi2)
2235: fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2236: #endif
2237: #ifdef HAVE_fixuns_truncdfdi2
2238: if (HAVE_fixuns_truncdfdi2)
2239: fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2240: #endif
2241: #ifdef HAVE_fixuns_truncdfti2
2242: if (HAVE_fixuns_truncdfti2)
2243: fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2244: #endif
2245:
2246: #ifdef HAVE_fixuns_trunctfqi2
2247: if (HAVE_fixuns_trunctfqi2)
2248: fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2249: #endif
2250: #ifdef HAVE_fixuns_trunctfhi2
2251: if (HAVE_fixuns_trunctfhi2)
2252: fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2253: #endif
2254: #ifdef HAVE_fixuns_trunctfsi2
2255: if (HAVE_fixuns_trunctfsi2)
2256: fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2257: #endif
2258: #ifdef HAVE_fixuns_trunctfdi2
2259: if (HAVE_fixuns_trunctfdi2)
2260: fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2261: #endif
2262: #ifdef HAVE_fixuns_trunctfti2
2263: if (HAVE_fixuns_trunctfti2)
2264: fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2265: #endif
2266:
2267: #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2268: /* This flag says the same insns that convert to a signed fixnum
2269: also convert validly to an unsigned one. */
2270: {
2271: int i;
2272: int j;
2273: for (i = 0; i < NUM_MACHINE_MODES; i++)
2274: for (j = 0; j < NUM_MACHINE_MODES; j++)
2275: fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2276: }
2277: #endif
2278: }
2279:
2280: void
2281: init_floattab ()
2282: {
2283: enum insn_code *p;
2284: for (p = floattab[0][0];
2285: p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2286: p++)
2287: *p = CODE_FOR_nothing;
2288:
2289: #ifdef HAVE_floatqisf2
2290: if (HAVE_floatqisf2)
2291: floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2292: #endif
2293: #ifdef HAVE_floathisf2
2294: if (HAVE_floathisf2)
2295: floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2296: #endif
2297: #ifdef HAVE_floatsisf2
2298: if (HAVE_floatsisf2)
2299: floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2300: #endif
2301: #ifdef HAVE_floatdisf2
2302: if (HAVE_floatdisf2)
2303: floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2304: #endif
2305: #ifdef HAVE_floattisf2
2306: if (HAVE_floattisf2)
2307: floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2308: #endif
2309:
2310: #ifdef HAVE_floatqidf2
2311: if (HAVE_floatqidf2)
2312: floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2313: #endif
2314: #ifdef HAVE_floathidf2
2315: if (HAVE_floathidf2)
2316: floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2317: #endif
2318: #ifdef HAVE_floatsidf2
2319: if (HAVE_floatsidf2)
2320: floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2321: #endif
2322: #ifdef HAVE_floatdidf2
2323: if (HAVE_floatdidf2)
2324: floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2325: #endif
2326: #ifdef HAVE_floattidf2
2327: if (HAVE_floattidf2)
2328: floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2329: #endif
2330:
2331: #ifdef HAVE_floatqitf2
2332: if (HAVE_floatqitf2)
2333: floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2334: #endif
2335: #ifdef HAVE_floathitf2
2336: if (HAVE_floathitf2)
2337: floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2338: #endif
2339: #ifdef HAVE_floatsitf2
2340: if (HAVE_floatsitf2)
2341: floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2342: #endif
2343: #ifdef HAVE_floatditf2
2344: if (HAVE_floatditf2)
2345: floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2346: #endif
2347: #ifdef HAVE_floattitf2
2348: if (HAVE_floattitf2)
2349: floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2350: #endif
2351:
2352: #ifdef HAVE_floatunsqisf2
2353: if (HAVE_floatunsqisf2)
2354: floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2355: #endif
2356: #ifdef HAVE_floatunshisf2
2357: if (HAVE_floatunshisf2)
2358: floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2359: #endif
2360: #ifdef HAVE_floatunssisf2
2361: if (HAVE_floatunssisf2)
2362: floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2363: #endif
2364: #ifdef HAVE_floatunsdisf2
2365: if (HAVE_floatunsdisf2)
2366: floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2367: #endif
2368: #ifdef HAVE_floatunstisf2
2369: if (HAVE_floatunstisf2)
2370: floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2371: #endif
2372:
2373: #ifdef HAVE_floatunsqidf2
2374: if (HAVE_floatunsqidf2)
2375: floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2376: #endif
2377: #ifdef HAVE_floatunshidf2
2378: if (HAVE_floatunshidf2)
2379: floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2380: #endif
2381: #ifdef HAVE_floatunssidf2
2382: if (HAVE_floatunssidf2)
2383: floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2384: #endif
2385: #ifdef HAVE_floatunsdidf2
2386: if (HAVE_floatunsdidf2)
2387: floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2388: #endif
2389: #ifdef HAVE_floatunstidf2
2390: if (HAVE_floatunstidf2)
2391: floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2392: #endif
2393:
2394: #ifdef HAVE_floatunsqitf2
2395: if (HAVE_floatunsqitf2)
2396: floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2397: #endif
2398: #ifdef HAVE_floatunshitf2
2399: if (HAVE_floatunshitf2)
2400: floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2401: #endif
2402: #ifdef HAVE_floatunssitf2
2403: if (HAVE_floatunssitf2)
2404: floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2405: #endif
2406: #ifdef HAVE_floatunsditf2
2407: if (HAVE_floatunsditf2)
2408: floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2409: #endif
2410: #ifdef HAVE_floatunstitf2
2411: if (HAVE_floatunstitf2)
2412: floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2413: #endif
2414: }
2415:
2416: /* Generate code to convert FROM to floating point
2417: and store in TO. FROM must be fixed point and not VOIDmode.
2418: UNSIGNEDP nonzero means regard FROM as unsigned.
2419: Normally this is done by correcting the final value
2420: if it is negative. */
2421:
2422: void
2423: expand_float (to, from, unsignedp)
2424: rtx to, from;
2425: int unsignedp;
2426: {
2427: enum insn_code icode;
2428: register rtx target = to;
2429: enum machine_mode fmode, imode;
2430:
2431: /* Crash now, because we won't be able to decide which mode to use. */
2432: if (GET_MODE (from) == VOIDmode)
2433: abort ();
2434:
2435: /* Look for an insn to do the conversion. Do it in the specified
2436: modes if possible; otherwise convert either input, output or both to
2437: wider mode. If the integer mode is wider than the mode of FROM,
2438: we can do the conversion signed even if the input is unsigned. */
2439:
2440: for (imode = GET_MODE (from); imode != VOIDmode;
2441: imode = GET_MODE_WIDER_MODE (imode))
2442: for (fmode = GET_MODE (to); fmode != VOIDmode;
2443: fmode = GET_MODE_WIDER_MODE (fmode))
2444: {
2445: int doing_unsigned = unsignedp;
2446:
2447: icode = can_float_p (fmode, imode, unsignedp);
2448: if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2449: icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2450:
2451: if (icode != CODE_FOR_nothing)
2452: {
2453: to = protect_from_queue (to, 1);
2454:
2455: if (imode != GET_MODE (from))
2456: from = convert_to_mode (imode, from, unsignedp);
2457: else
2458: from = protect_from_queue (from, 0);
2459:
2460: if (fmode != GET_MODE (to))
2461: target = gen_reg_rtx (fmode);
2462:
2463: emit_unop_insn (icode, target, from,
2464: doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2465:
2466: if (target != to)
2467: convert_move (to, target, 0);
2468: return;
2469: }
2470: }
2471:
2472: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2473:
2474: /* Unsigned integer, and no way to convert directly.
2475: Convert as signed, then conditionally adjust the result. */
2476: if (unsignedp)
2477: {
2478: rtx label = gen_label_rtx ();
2479: rtx temp;
2480: REAL_VALUE_TYPE offset;
2481:
2482: emit_queue ();
2483:
2484: to = protect_from_queue (to, 1);
2485: from = protect_from_queue (from, 0);
2486:
2487: if (flag_force_mem)
2488: from = force_not_mem (from);
2489:
2490: /* If we are about to do some arithmetic to correct for an
2491: unsigned operand, do it in a pseudo-register. */
2492:
2493: if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2494: target = gen_reg_rtx (GET_MODE (to));
2495:
2496: /* Convert as signed integer to floating. */
2497: expand_float (target, from, 0);
2498:
2499: /* If FROM is negative (and therefore TO is negative),
2500: correct its value by 2**bitwidth. */
2501:
2502: do_pending_stack_adjust ();
2503: emit_cmp_insn (from, const0_rtx, GE, 0, GET_MODE (from), 0, 0);
2504: emit_jump_insn (gen_bge (label));
2505: /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2506: Rather than setting up a dconst_dot_5, let's hope SCO
2507: fixes the bug. */
2508: offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2509: temp = expand_binop (GET_MODE (to), add_optab, target,
2510: immed_real_const_1 (offset, GET_MODE (to)),
2511: target, 0, OPTAB_LIB_WIDEN);
2512: if (temp != target)
2513: emit_move_insn (target, temp);
2514: do_pending_stack_adjust ();
2515: emit_label (label);
2516: }
2517: else
2518: #endif
2519:
2520: /* No hardware instruction available; call a library
2521: to convert from SImode or DImode into SFmode or DFmode. */
2522: {
2523: rtx libfcn;
2524: rtx insns;
2525:
2526: to = protect_from_queue (to, 1);
2527:
2528: if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2529: from = convert_to_mode (SImode, from, unsignedp);
2530: else
2531: from = protect_from_queue (from, 0);
2532:
2533: if (flag_force_mem)
2534: from = force_not_mem (from);
2535:
2536: if (GET_MODE (to) == SFmode)
2537: {
2538: if (GET_MODE (from) == SImode)
2539: libfcn = floatsisf_libfunc;
2540: else if (GET_MODE (from) == DImode)
2541: libfcn = floatdisf_libfunc;
2542: else
2543: abort ();
2544: }
2545: else if (GET_MODE (to) == DFmode)
2546: {
2547: if (GET_MODE (from) == SImode)
2548: libfcn = floatsidf_libfunc;
2549: else if (GET_MODE (from) == DImode)
2550: libfcn = floatdidf_libfunc;
2551: else
2552: abort ();
2553: }
2554: else
2555: abort ();
2556:
2557: start_sequence ();
2558:
2559: emit_library_call (libfcn, 0, GET_MODE (to), 1, from, GET_MODE (from));
2560: insns = get_insns ();
2561: end_sequence ();
2562:
2563: emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2564: gen_rtx (FLOAT, GET_MODE (to), from));
2565: }
2566:
2567: /* Copy result to requested destination
2568: if we have been computing in a temp location. */
2569:
2570: if (target != to)
2571: {
2572: if (GET_MODE (target) == GET_MODE (to))
2573: emit_move_insn (to, target);
2574: else
2575: convert_move (to, target, 0);
2576: }
2577: }
2578:
2579: /* expand_fix: generate code to convert FROM to fixed point
2580: and store in TO. FROM must be floating point. */
2581:
2582: static rtx
2583: ftruncify (x)
2584: rtx x;
2585: {
2586: rtx temp = gen_reg_rtx (GET_MODE (x));
2587: return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2588: }
2589:
2590: void
2591: expand_fix (to, from, unsignedp)
2592: register rtx to, from;
2593: int unsignedp;
2594: {
2595: enum insn_code icode;
2596: register rtx target = to;
2597: enum machine_mode fmode, imode;
2598: int must_trunc = 0;
2599: rtx libfcn = 0;
2600:
2601: /* We first try to find a pair of modes, one real and one integer, at
2602: least as wide as FROM and TO, respectively, in which we can open-code
2603: this conversion. If the integer mode is wider than the mode of TO,
2604: we can do the conversion either signed or unsigned. */
2605:
2606: for (imode = GET_MODE (to); imode != VOIDmode;
2607: imode = GET_MODE_WIDER_MODE (imode))
2608: for (fmode = GET_MODE (from); fmode != VOIDmode;
2609: fmode = GET_MODE_WIDER_MODE (fmode))
2610: {
2611: int doing_unsigned = unsignedp;
2612:
2613: icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2614: if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2615: icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2616:
2617: if (icode != CODE_FOR_nothing)
2618: {
2619: to = protect_from_queue (to, 1);
2620:
2621: if (fmode != GET_MODE (from))
2622: from = convert_to_mode (fmode, from, 0);
2623: else
2624: from = protect_from_queue (from, 0);
2625:
2626: if (must_trunc)
2627: from = ftruncify (from);
2628:
2629: if (imode != GET_MODE (to))
2630: target = gen_reg_rtx (imode);
2631:
2632: emit_unop_insn (icode, target, from,
2633: doing_unsigned ? UNSIGNED_FIX : FIX);
2634: if (target != to)
2635: convert_move (to, target, unsignedp);
2636: return;
2637: }
2638: }
2639:
2640: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2641: /* For an unsigned conversion, there is one more way to do it.
2642: If we have a signed conversion, we generate code that compares
2643: the real value to the largest representable positive number. If if
2644: is smaller, the conversion is done normally. Otherwise, subtract
2645: one plus the highest signed number, convert, and add it back.
2646:
2647: We only need to check all real modes, since we know we didn't find
2648: anything with a wider inetger mode. */
2649:
2650: if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
2651: for (fmode = GET_MODE (from); fmode != VOIDmode;
2652: fmode = GET_MODE_WIDER_MODE (fmode))
2653: /* Make sure we won't lose significant bits doing this. */
2654: if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
2655: && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
2656: &must_trunc))
2657: {
2658: int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
2659: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
2660: rtx limit = immed_real_const_1 (offset, fmode);
2661: rtx lab1 = gen_label_rtx ();
2662: rtx lab2 = gen_label_rtx ();
2663: rtx insn;
2664:
2665: emit_queue ();
2666: to = protect_from_queue (to, 1);
2667: from = protect_from_queue (from, 0);
2668:
2669: if (flag_force_mem)
2670: from = force_not_mem (from);
2671:
2672: if (fmode != GET_MODE (from))
2673: from = convert_to_mode (fmode, from, 0);
2674:
2675: /* See if we need to do the subtraction. */
2676: do_pending_stack_adjust ();
2677: emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
2678: emit_jump_insn (gen_bge (lab1));
2679:
2680: /* If not, do the signed "fix" and branch around fixup code. */
2681: expand_fix (to, from, 0);
2682: emit_jump_insn (gen_jump (lab2));
2683: emit_barrier ();
2684:
2685: /* Otherwise, subtract 2**(N-1), convert to signed number,
2686: then add 2**(N-1). Do the addition using XOR since this
2687: will often generate better code. */
2688: emit_label (lab1);
2689: target = expand_binop (GET_MODE (from), sub_optab, from, limit,
2690: 0, 0, OPTAB_LIB_WIDEN);
2691: expand_fix (to, target, 0);
2692: target = expand_binop (GET_MODE (to), xor_optab, to,
2693: gen_rtx (CONST_INT, VOIDmode,
2694: 1 << (bitsize - 1)),
2695: to, 1, OPTAB_LIB_WIDEN);
2696:
2697: if (target != to)
2698: emit_move_insn (to, target);
2699:
2700: emit_label (lab2);
2701:
2702: /* Make a place for a REG_NOTE and add it. */
2703: insn = emit_move_insn (to, to);
2704: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
2705: gen_rtx (UNSIGNED_FIX, GET_MODE (to),
2706: from), REG_NOTES (insn));
2707:
2708: return;
2709: }
2710: #endif
2711:
2712: /* We can't do it with an insn, so use a library call. But first ensure
2713: that the mode of TO is at least as wide as SImode, since those are the
2714: only library calls we know about. */
2715:
2716: if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
2717: {
2718: target = gen_reg_rtx (SImode);
2719:
2720: expand_fix (target, from, unsignedp);
2721: }
2722: else if (GET_MODE (from) == SFmode)
2723: {
2724: if (GET_MODE (to) == SImode)
2725: libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
2726: else if (GET_MODE (to) == DImode)
2727: libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
2728: else
2729: abort ();
2730: }
2731: else if (GET_MODE (from) == DFmode)
2732: {
2733: if (GET_MODE (to) == SImode)
2734: libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
2735: else if (GET_MODE (to) == DImode)
2736: libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
2737: else
2738: abort ();
2739: }
2740: else
2741: abort ();
2742:
2743: if (libfcn)
2744: {
2745: rtx insns;
2746:
2747: to = protect_from_queue (to, 1);
2748: from = protect_from_queue (from, 0);
2749:
2750: if (flag_force_mem)
2751: from = force_not_mem (from);
2752:
2753: start_sequence ();
2754:
2755: emit_library_call (libfcn, 0, GET_MODE (to), 1, from, GET_MODE (from));
2756: insns = get_insns ();
2757: end_sequence ();
2758:
2759: emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2760: gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
2761: GET_MODE (to), from));
2762: }
2763:
2764: if (GET_MODE (to) == GET_MODE (target))
2765: emit_move_insn (to, target);
2766: else
2767: convert_move (to, target, 0);
2768: }
2769:
2770: static optab
2771: init_optab (code)
2772: enum rtx_code code;
2773: {
2774: int i;
2775: optab op = (optab) xmalloc (sizeof (struct optab));
2776: op->code = code;
2777: for (i = 0; i < NUM_MACHINE_MODES; i++)
2778: {
2779: op->handlers[i].insn_code = CODE_FOR_nothing;
2780: op->handlers[i].libfunc = 0;
2781: }
2782: return op;
2783: }
2784:
2785: /* Call this once to initialize the contents of the optabs
2786: appropriately for the current target machine. */
2787:
2788: void
2789: init_optabs ()
2790: {
2791: int i;
2792:
2793: init_fixtab ();
2794: init_floattab ();
2795: init_extends ();
2796:
2797: add_optab = init_optab (PLUS);
2798: sub_optab = init_optab (MINUS);
2799: smul_optab = init_optab (MULT);
2800: smul_widen_optab = init_optab (UNKNOWN);
2801: umul_widen_optab = init_optab (UNKNOWN);
2802: sdiv_optab = init_optab (DIV);
2803: sdivmod_optab = init_optab (UNKNOWN);
2804: udiv_optab = init_optab (UDIV);
2805: udivmod_optab = init_optab (UNKNOWN);
2806: smod_optab = init_optab (MOD);
2807: umod_optab = init_optab (UMOD);
2808: flodiv_optab = init_optab (DIV);
2809: ftrunc_optab = init_optab (UNKNOWN);
2810: and_optab = init_optab (AND);
2811: ior_optab = init_optab (IOR);
2812: xor_optab = init_optab (XOR);
2813: ashl_optab = init_optab (ASHIFT);
2814: ashr_optab = init_optab (ASHIFTRT);
2815: lshl_optab = init_optab (LSHIFT);
2816: lshr_optab = init_optab (LSHIFTRT);
2817: rotl_optab = init_optab (ROTATE);
2818: rotr_optab = init_optab (ROTATERT);
2819: smin_optab = init_optab (SMIN);
2820: smax_optab = init_optab (SMAX);
2821: umin_optab = init_optab (UMIN);
2822: umax_optab = init_optab (UMAX);
2823: mov_optab = init_optab (UNKNOWN);
2824: movstrict_optab = init_optab (UNKNOWN);
2825: cmp_optab = init_optab (UNKNOWN);
2826: ucmp_optab = init_optab (UNKNOWN);
2827: tst_optab = init_optab (UNKNOWN);
2828: neg_optab = init_optab (NEG);
2829: abs_optab = init_optab (ABS);
2830: one_cmpl_optab = init_optab (NOT);
2831: ffs_optab = init_optab (FFS);
2832:
2833: #ifdef HAVE_addqi3
2834: if (HAVE_addqi3)
2835: add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
2836: #endif
2837: #ifdef HAVE_addhi3
2838: if (HAVE_addhi3)
2839: add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
2840: #endif
2841: #ifdef HAVE_addpsi3
2842: if (HAVE_addpsi3)
2843: add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
2844: #endif
2845: #ifdef HAVE_addsi3
2846: if (HAVE_addsi3)
2847: add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
2848: #endif
2849: #ifdef HAVE_adddi3
2850: if (HAVE_adddi3)
2851: add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
2852: #endif
2853: #ifdef HAVE_addti3
2854: if (HAVE_addti3)
2855: add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
2856: #endif
2857: #ifdef HAVE_addsf3
2858: if (HAVE_addsf3)
2859: add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
2860: #endif
2861: #ifdef HAVE_adddf3
2862: if (HAVE_adddf3)
2863: add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
2864: #endif
2865: #ifdef HAVE_addtf3
2866: if (HAVE_addtf3)
2867: add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
2868: #endif
2869: add_optab->handlers[(int) SFmode].libfunc
2870: = gen_rtx (SYMBOL_REF, Pmode, "__addsf3");
2871: add_optab->handlers[(int) DFmode].libfunc
2872: = gen_rtx (SYMBOL_REF, Pmode, "__adddf3");
2873:
2874: #ifdef HAVE_subqi3
2875: if (HAVE_subqi3)
2876: sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
2877: #endif
2878: #ifdef HAVE_subhi3
2879: if (HAVE_subhi3)
2880: sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
2881: #endif
2882: #ifdef HAVE_subpsi3
2883: if (HAVE_subpsi3)
2884: sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
2885: #endif
2886: #ifdef HAVE_subsi3
2887: if (HAVE_subsi3)
2888: sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
2889: #endif
2890: #ifdef HAVE_subdi3
2891: if (HAVE_subdi3)
2892: sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
2893: #endif
2894: #ifdef HAVE_subti3
2895: if (HAVE_subti3)
2896: sub_optab->handlers[(int) Imode].insn_code = CODE_FOR_subti3;
2897: #endif
2898: #ifdef HAVE_subsf3
2899: if (HAVE_subsf3)
2900: sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
2901: #endif
2902: #ifdef HAVE_subdf3
2903: if (HAVE_subdf3)
2904: sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
2905: #endif
2906: #ifdef HAVE_subtf3
2907: if (HAVE_subtf3)
2908: sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
2909: #endif
2910: sub_optab->handlers[(int) SFmode].libfunc
2911: = gen_rtx (SYMBOL_REF, Pmode, "__subsf3");
2912: sub_optab->handlers[(int) DFmode].libfunc
2913: = gen_rtx (SYMBOL_REF, Pmode, "__subdf3");
2914:
2915: #ifdef HAVE_mulqi3
2916: if (HAVE_mulqi3)
2917: smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
2918: #endif
2919: #ifdef HAVE_mulhi3
2920: if (HAVE_mulhi3)
2921: smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
2922: #endif
2923: #ifdef HAVE_mulpsi3
2924: if (HAVE_mulpsi3)
2925: smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
2926: #endif
2927: #ifdef HAVE_mulsi3
2928: if (HAVE_mulsi3)
2929: smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
2930: #endif
2931: #ifdef HAVE_muldi3
2932: if (HAVE_muldi3)
2933: smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
2934: #endif
2935: #ifdef HAVE_multi3
2936: if (HAVE_multi3)
2937: smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
2938: #endif
2939: #ifdef HAVE_mulsf3
2940: if (HAVE_mulsf3)
2941: smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
2942: #endif
2943: #ifdef HAVE_muldf3
2944: if (HAVE_muldf3)
2945: smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
2946: #endif
2947: #ifdef HAVE_multf3
2948: if (HAVE_multf3)
2949: smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
2950: #endif
2951:
2952: #ifdef MULSI3_LIBCALL
2953: smul_optab->handlers[(int) SImode].libfunc
2954: = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
2955: #else
2956: smul_optab->handlers[(int) SImode].libfunc
2957: = gen_rtx (SYMBOL_REF, Pmode, "__mulsi3");
2958: #endif
2959: #ifdef MULDI3_LIBCALL
2960: smul_optab->handlers[(int) DImode].libfunc
2961: = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
2962: #else
2963: smul_optab->handlers[(int) DImode].libfunc
2964: = gen_rtx (SYMBOL_REF, Pmode, "__muldi3");
2965: #endif
2966: smul_optab->handlers[(int) SFmode].libfunc
2967: = gen_rtx (SYMBOL_REF, Pmode, "__mulsf3");
2968: smul_optab->handlers[(int) DFmode].libfunc
2969: = gen_rtx (SYMBOL_REF, Pmode, "__muldf3");
2970:
2971: #ifdef HAVE_mulqihi3
2972: if (HAVE_mulqihi3)
2973: smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
2974: #endif
2975: #ifdef HAVE_mulhisi3
2976: if (HAVE_mulhisi3)
2977: smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
2978: #endif
2979: #ifdef HAVE_mulsidi3
2980: if (HAVE_mulsidi3)
2981: smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
2982: #endif
2983: #ifdef HAVE_mulditi3
2984: if (HAVE_mulditi3)
2985: smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
2986: #endif
2987:
2988: #ifdef HAVE_umulqihi3
2989: if (HAVE_umulqihi3)
2990: umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
2991: #endif
2992: #ifdef HAVE_umulhisi3
2993: if (HAVE_umulhisi3)
2994: umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
2995: #endif
2996: #ifdef HAVE_umulsidi3
2997: if (HAVE_umulsidi3)
2998: umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
2999: #endif
3000: #ifdef HAVE_umulditi3
3001: if (HAVE_umulditi3)
3002: umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3003: #endif
3004:
3005: #ifdef HAVE_divqi3
3006: if (HAVE_divqi3)
3007: sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3008: #endif
3009: #ifdef HAVE_divhi3
3010: if (HAVE_divhi3)
3011: sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3012: #endif
3013: #ifdef HAVE_divpsi3
3014: if (HAVE_divpsi3)
3015: sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3016: #endif
3017: #ifdef HAVE_divsi3
3018: if (HAVE_divsi3)
3019: sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3020: #endif
3021: #ifdef HAVE_divdi3
3022: if (HAVE_divdi3)
3023: sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3024: #endif
3025: #ifdef HAVE_divti3
3026: if (HAVE_divti3)
3027: sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3028: #endif
3029:
3030: #ifdef DIVSI3_LIBCALL
3031: sdiv_optab->handlers[(int) SImode].libfunc
3032: = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3033: #else
3034: sdiv_optab->handlers[(int) SImode].libfunc
3035: = gen_rtx (SYMBOL_REF, Pmode, "__divsi3");
3036: #endif
3037: #ifdef DIVDI3_LIBCALL
3038: sdiv_optab->handlers[(int) DImode].libfunc
3039: = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3040: #else
3041: sdiv_optab->handlers[(int) DImode].libfunc
3042: = gen_rtx (SYMBOL_REF, Pmode, "__divdi3");
3043: #endif
3044:
3045: #ifdef HAVE_udivqi3
3046: if (HAVE_udivqi3)
3047: udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3048: #endif
3049: #ifdef HAVE_udivhi3
3050: if (HAVE_udivhi3)
3051: udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3052: #endif
3053: #ifdef HAVE_udivpsi3
3054: if (HAVE_udivpsi3)
3055: udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3056: #endif
3057: #ifdef HAVE_udivsi3
3058: if (HAVE_udivsi3)
3059: udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3060: #endif
3061: #ifdef HAVE_udivdi3
3062: if (HAVE_udivdi3)
3063: udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3064: #endif
3065: #ifdef HAVE_udivti3
3066: if (HAVE_udivti3)
3067: udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3068: #endif
3069:
3070: #ifdef UDIVSI3_LIBCALL
3071: udiv_optab->handlers[(int) SImode].libfunc
3072: = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3073: #else
3074: udiv_optab->handlers[(int) SImode].libfunc
3075: = gen_rtx (SYMBOL_REF, Pmode, "__udivsi3");
3076: #endif
3077: #ifdef UDIVDI3_LIBCALL
3078: udiv_optab->handlers[(int) DImode].libfunc
3079: = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3080: #else
3081: udiv_optab->handlers[(int) DImode].libfunc
3082: = gen_rtx (SYMBOL_REF, Pmode, "__udivdi3");
3083: #endif
3084:
3085: #ifdef HAVE_divmodqi4
3086: if (HAVE_divmodqi4)
3087: sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3088: #endif
3089: #ifdef HAVE_divmodhi4
3090: if (HAVE_divmodhi4)
3091: sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3092: #endif
3093: #ifdef HAVE_divmodsi4
3094: if (HAVE_divmodsi4)
3095: sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3096: #endif
3097: #ifdef HAVE_divmoddi4
3098: if (HAVE_divmoddi4)
3099: sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3100: #endif
3101: #ifdef HAVE_divmodti4
3102: if (HAVE_divmodti4)
3103: sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3104: #endif
3105:
3106: #ifdef HAVE_udivmodqi4
3107: if (HAVE_udivmodqi4)
3108: udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3109: #endif
3110: #ifdef HAVE_udivmodhi4
3111: if (HAVE_udivmodhi4)
3112: udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3113: #endif
3114: #ifdef HAVE_udivmodsi4
3115: if (HAVE_udivmodsi4)
3116: udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3117: #endif
3118: #ifdef HAVE_udivmoddi4
3119: if (HAVE_udivmoddi4)
3120: udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3121: #endif
3122: #ifdef HAVE_udivmodti4
3123: if (HAVE_udivmodti4)
3124: udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3125: #endif
3126:
3127: #ifdef HAVE_modqi3
3128: if (HAVE_modqi3)
3129: smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3130: #endif
3131: #ifdef HAVE_modhi3
3132: if (HAVE_modhi3)
3133: smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3134: #endif
3135: #ifdef HAVE_modpsi3
3136: if (HAVE_modpsi3)
3137: smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3138: #endif
3139: #ifdef HAVE_modsi3
3140: if (HAVE_modsi3)
3141: smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3142: #endif
3143: #ifdef HAVE_moddi3
3144: if (HAVE_moddi3)
3145: smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3146: #endif
3147: #ifdef HAVE_modti3
3148: if (HAVE_modti3)
3149: smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3150: #endif
3151:
3152: #ifdef MODSI3_LIBCALL
3153: smod_optab->handlers[(int) SImode].libfunc
3154: = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3155: #else
3156: smod_optab->handlers[(int) SImode].libfunc
3157: = gen_rtx (SYMBOL_REF, Pmode, "__modsi3");
3158: #endif
3159: #ifdef MODDI3_LIBCALL
3160: smod_optab->handlers[(int) DImode].libfunc
3161: = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3162: #else
3163: smod_optab->handlers[(int) DImode].libfunc
3164: = gen_rtx (SYMBOL_REF, Pmode, "__moddi3");
3165: #endif
3166:
3167: #ifdef HAVE_umodqi3
3168: if (HAVE_umodqi3)
3169: umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3170: #endif
3171: #ifdef HAVE_umodhi3
3172: if (HAVE_umodhi3)
3173: umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3174: #endif
3175: #ifdef HAVE_umodpsi3
3176: if (HAVE_umodpsi3)
3177: umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3178: #endif
3179: #ifdef HAVE_umodsi3
3180: if (HAVE_umodsi3)
3181: umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3182: #endif
3183: #ifdef HAVE_umoddi3
3184: if (HAVE_umoddi3)
3185: umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3186: #endif
3187: #ifdef HAVE_umodti3
3188: if (HAVE_umodti3)
3189: umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3190: #endif
3191:
3192: #ifdef UMODSI3_LIBCALL
3193: umod_optab->handlers[(int) SImode].libfunc
3194: = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3195: #else
3196: umod_optab->handlers[(int) SImode].libfunc
3197: = gen_rtx (SYMBOL_REF, Pmode, "__umodsi3");
3198: #endif
3199: #ifdef UMODDI3_LIBCALL
3200: umod_optab->handlers[(int) DImode].libfunc
3201: = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3202: #else
3203: umod_optab->handlers[(int) DImode].libfunc
3204: = gen_rtx (SYMBOL_REF, Pmode, "__umoddi3");
3205: #endif
3206:
3207: #ifdef HAVE_divsf3
3208: if (HAVE_divsf3)
3209: flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3210: #endif
3211: #ifdef HAVE_divdf3
3212: if (HAVE_divdf3)
3213: flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3214: #endif
3215: #ifdef HAVE_divtf3
3216: if (HAVE_divtf3)
3217: flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3218: #endif
3219: flodiv_optab->handlers[(int) SFmode].libfunc
3220: = gen_rtx (SYMBOL_REF, Pmode, "__divsf3");
3221: flodiv_optab->handlers[(int) DFmode].libfunc
3222: = gen_rtx (SYMBOL_REF, Pmode, "__divdf3");
3223:
3224: #ifdef HAVE_ftruncsf2
3225: if (HAVE_ftruncsf2)
3226: ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3227: #endif
3228: #ifdef HAVE_ftruncdf2
3229: if (HAVE_ftruncdf2)
3230: ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3231: #endif
3232: #ifdef HAVE_ftrunctf2
3233: if (HAVE_ftrunctf2)
3234: ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3235: #endif
3236:
3237: #ifdef HAVE_andqi3
3238: if (HAVE_andqi3)
3239: and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3240: #endif
3241: #ifdef HAVE_andhi3
3242: if (HAVE_andhi3)
3243: and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3244: #endif
3245: #ifdef HAVE_andpsi3
3246: if (HAVE_andpsi3)
3247: and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3248: #endif
3249: #ifdef HAVE_andsi3
3250: if (HAVE_andsi3)
3251: and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3252: #endif
3253: #ifdef HAVE_anddi3
3254: if (HAVE_anddi3)
3255: and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3256: #endif
3257: #ifdef HAVE_andti3
3258: if (HAVE_andti3)
3259: and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3260: #endif
3261:
3262: #ifdef HAVE_iorqi3
3263: if (HAVE_iorqi3)
3264: ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3265: #endif
3266: #ifdef HAVE_iorhi3
3267: if (HAVE_iorhi3)
3268: ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3269: #endif
3270: #ifdef HAVE_iorpsi3
3271: if (HAVE_iorpsi3)
3272: ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3273: #endif
3274: #ifdef HAVE_iorsi3
3275: if (HAVE_iorsi3)
3276: ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3277: #endif
3278: #ifdef HAVE_iordi3
3279: if (HAVE_iordi3)
3280: ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3281: #endif
3282: #ifdef HAVE_iorti3
3283: if (HAVE_iorti3)
3284: ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3285: #endif
3286:
3287: #ifdef HAVE_xorqi3
3288: if (HAVE_xorqi3)
3289: xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3290: #endif
3291: #ifdef HAVE_xorhi3
3292: if (HAVE_xorhi3)
3293: xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3294: #endif
3295: #ifdef HAVE_xorpsi3
3296: if (HAVE_xorpsi3)
3297: xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3298: #endif
3299: #ifdef HAVE_xorsi3
3300: if (HAVE_xorsi3)
3301: xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3302: #endif
3303: #ifdef HAVE_xordi3
3304: if (HAVE_xordi3)
3305: xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3306: #endif
3307: #ifdef HAVE_xorti3
3308: if (HAVE_xorti3)
3309: xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3310: #endif
3311:
3312: #ifdef HAVE_ashlqi3
3313: if (HAVE_ashlqi3)
3314: ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3315: #endif
3316: #ifdef HAVE_ashlhi3
3317: if (HAVE_ashlhi3)
3318: ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3319: #endif
3320: #ifdef HAVE_ashlpsi3
3321: if (HAVE_ashlpsi3)
3322: ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3323: #endif
3324: #ifdef HAVE_ashlsi3
3325: if (HAVE_ashlsi3)
3326: ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3327: #endif
3328: #ifdef HAVE_ashldi3
3329: if (HAVE_ashldi3)
3330: ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3331: #endif
3332: #ifdef HAVE_ashlti3
3333: if (HAVE_ashlti3)
3334: ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3335: #endif
3336: ashl_optab->handlers[(int) SImode].libfunc
3337: = gen_rtx (SYMBOL_REF, Pmode, "__ashlsi3");
3338: ashl_optab->handlers[(int) DImode].libfunc
3339: = gen_rtx (SYMBOL_REF, Pmode, "__ashldi3");
3340:
3341: #ifdef HAVE_ashrqi3
3342: if (HAVE_ashrqi3)
3343: ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3344: #endif
3345: #ifdef HAVE_ashrhi3
3346: if (HAVE_ashrhi3)
3347: ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3348: #endif
3349: #ifdef HAVE_ashrpsi3
3350: if (HAVE_ashrpsi3)
3351: ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3352: #endif
3353: #ifdef HAVE_ashrsi3
3354: if (HAVE_ashrsi3)
3355: ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3356: #endif
3357: #ifdef HAVE_ashrdi3
3358: if (HAVE_ashrdi3)
3359: ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3360: #endif
3361: #ifdef HAVE_ashrti3
3362: if (HAVE_ashrti3)
3363: ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3364: #endif
3365: ashr_optab->handlers[(int) SImode].libfunc
3366: = gen_rtx (SYMBOL_REF, Pmode, "__ashrsi3");
3367: ashr_optab->handlers[(int) DImode].libfunc
3368: = gen_rtx (SYMBOL_REF, Pmode, "__ashrdi3");
3369:
3370: #ifdef HAVE_lshlqi3
3371: if (HAVE_lshlqi3)
3372: lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3373: #endif
3374: #ifdef HAVE_lshlhi3
3375: if (HAVE_lshlhi3)
3376: lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3377: #endif
3378: #ifdef HAVE_lshlpsi3
3379: if (HAVE_lshlpsi3)
3380: lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3381: #endif
3382: #ifdef HAVE_lshlsi3
3383: if (HAVE_lshlsi3)
3384: lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3385: #endif
3386: #ifdef HAVE_lshldi3
3387: if (HAVE_lshldi3)
3388: lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3389: #endif
3390: #ifdef HAVE_lshlti3
3391: if (HAVE_lshlti3)
3392: lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3393: #endif
3394: lshl_optab->handlers[(int) SImode].libfunc
3395: = gen_rtx (SYMBOL_REF, Pmode, "__lshlsi3");
3396: lshl_optab->handlers[(int) DImode].libfunc
3397: = gen_rtx (SYMBOL_REF, Pmode, "__lshldi3");
3398:
3399: #ifdef HAVE_lshrqi3
3400: if (HAVE_lshrqi3)
3401: lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3402: #endif
3403: #ifdef HAVE_lshrhi3
3404: if (HAVE_lshrhi3)
3405: lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3406: #endif
3407: #ifdef HAVE_lshrpsi3
3408: if (HAVE_lshrpsi3)
3409: lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3410: #endif
3411: #ifdef HAVE_lshrsi3
3412: if (HAVE_lshrsi3)
3413: lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3414: #endif
3415: #ifdef HAVE_lshrdi3
3416: if (HAVE_lshrdi3)
3417: lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3418: #endif
3419: #ifdef HAVE_lshrti3
3420: if (HAVE_lshrti3)
3421: lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3422: #endif
3423: lshr_optab->handlers[(int) SImode].libfunc
3424: = gen_rtx (SYMBOL_REF, Pmode, "__lshrsi3");
3425: lshr_optab->handlers[(int) DImode].libfunc
3426: = gen_rtx (SYMBOL_REF, Pmode, "__lshrdi3");
3427:
3428: #ifdef HAVE_rotlqi3
3429: if (HAVE_rotlqi3)
3430: rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3431: #endif
3432: #ifdef HAVE_rotlhi3
3433: if (HAVE_rotlhi3)
3434: rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3435: #endif
3436: #ifdef HAVE_rotlpsi3
3437: if (HAVE_rotlpsi3)
3438: rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3439: #endif
3440: #ifdef HAVE_rotlsi3
3441: if (HAVE_rotlsi3)
3442: rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3443: #endif
3444: #ifdef HAVE_rotldi3
3445: if (HAVE_rotldi3)
3446: rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3447: #endif
3448: #ifdef HAVE_rotlti3
3449: if (HAVE_rotlti3)
3450: rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3451: #endif
3452: rotl_optab->handlers[(int) SImode].libfunc
3453: = gen_rtx (SYMBOL_REF, Pmode, "__rotlsi3");
3454: rotl_optab->handlers[(int) DImode].libfunc
3455: = gen_rtx (SYMBOL_REF, Pmode, "__rotldi3");
3456:
3457: #ifdef HAVE_rotrqi3
3458: if (HAVE_rotrqi3)
3459: rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3460: #endif
3461: #ifdef HAVE_rotrhi3
3462: if (HAVE_rotrhi3)
3463: rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3464: #endif
3465: #ifdef HAVE_rotrpsi3
3466: if (HAVE_rotrpsi3)
3467: rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3468: #endif
3469: #ifdef HAVE_rotrsi3
3470: if (HAVE_rotrsi3)
3471: rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3472: #endif
3473: #ifdef HAVE_rotrdi3
3474: if (HAVE_rotrdi3)
3475: rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3476: #endif
3477: #ifdef HAVE_rotrti3
3478: if (HAVE_rotrti3)
3479: rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3480: #endif
3481: rotr_optab->handlers[(int) SImode].libfunc
3482: = gen_rtx (SYMBOL_REF, Pmode, "__rotrsi3");
3483: rotr_optab->handlers[(int) DImode].libfunc
3484: = gen_rtx (SYMBOL_REF, Pmode, "__rotrdi3");
3485:
3486: #ifdef HAVE_sminqi3
3487: if (HAVE_sminqi3)
3488: smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3489: #endif
3490: #ifdef HAVE_sminhi3
3491: if (HAVE_sminhi3)
3492: smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3493: #endif
3494: #ifdef HAVE_sminsi3
3495: if (HAVE_sminsi3)
3496: smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3497: #endif
3498: #ifdef HAVE_smindi3
3499: if (HAVE_smindi3)
3500: smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3501: #endif
3502: #ifdef HAVE_sminti3
3503: if (HAVE_sminti3)
3504: smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
3505: #endif
3506: #ifdef HAVE_sminsf3
3507: if (HAVE_sminsf3)
3508: smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sminsf3;
3509: #endif
3510: #ifdef HAVE_smindf3
3511: if (HAVE_smindf3)
3512: smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smindf3;
3513: #endif
3514: #ifdef HAVE_smintf3
3515: if (HAVE_smintf3)
3516: smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smintf3;
3517: #endif
3518:
3519: #ifdef HAVE_smaxqi3
3520: if (HAVE_smaxqi3)
3521: smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
3522: #endif
3523: #ifdef HAVE_smaxhi3
3524: if (HAVE_smaxhi3)
3525: smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
3526: #endif
3527: #ifdef HAVE_smaxsi3
3528: if (HAVE_smaxsi3)
3529: smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
3530: #endif
3531: #ifdef HAVE_smaxdi3
3532: if (HAVE_smaxdi3)
3533: smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
3534: #endif
3535: #ifdef HAVE_smaxti3
3536: if (HAVE_smaxti3)
3537: smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
3538: #endif
3539: #ifdef HAVE_smaxsf3
3540: if (HAVE_smaxsf3)
3541: smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_smaxsf3;
3542: #endif
3543: #ifdef HAVE_smaxdf3
3544: if (HAVE_smaxdf3)
3545: smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smaxdf3;
3546: #endif
3547: #ifdef HAVE_smaxtf3
3548: if (HAVE_smaxtf3)
3549: smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smaxtf3;
3550: #endif
3551:
3552: #ifdef HAVE_uminqi3
3553: if (HAVE_uminqi3)
3554: umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
3555: #endif
3556: #ifdef HAVE_uminhi3
3557: if (HAVE_uminhi3)
3558: umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
3559: #endif
3560: #ifdef HAVE_uminsi3
3561: if (HAVE_uminsi3)
3562: umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
3563: #endif
3564: #ifdef HAVE_umindi3
3565: if (HAVE_umindi3)
3566: umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
3567: #endif
3568: #ifdef HAVE_uminti3
3569: if (HAVE_uminti3)
3570: umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
3571: #endif
3572:
3573: #ifdef HAVE_umaxqi3
3574: if (HAVE_umaxqi3)
3575: umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
3576: #endif
3577: #ifdef HAVE_umaxhi3
3578: if (HAVE_umaxhi3)
3579: umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
3580: #endif
3581: #ifdef HAVE_umaxsi3
3582: if (HAVE_umaxsi3)
3583: umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
3584: #endif
3585: #ifdef HAVE_umaxdi3
3586: if (HAVE_umaxdi3)
3587: umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
3588: #endif
3589: #ifdef HAVE_umaxti3
3590: if (HAVE_umaxti3)
3591: umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
3592: #endif
3593:
3594: #ifdef HAVE_negqi2
3595: if (HAVE_negqi2)
3596: neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
3597: #endif
3598: #ifdef HAVE_neghi2
3599: if (HAVE_neghi2)
3600: neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
3601: #endif
3602: #ifdef HAVE_negpsi2
3603: if (HAVE_negpsi2)
3604: neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
3605: #endif
3606: #ifdef HAVE_negsi2
3607: if (HAVE_negsi2)
3608: neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
3609: #endif
3610: #ifdef HAVE_negdi2
3611: if (HAVE_negdi2)
3612: neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
3613: #endif
3614: #ifdef HAVE_negti2
3615: if (HAVE_negti2)
3616: neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
3617: #endif
3618: #ifdef HAVE_negsf2
3619: if (HAVE_negsf2)
3620: neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
3621: #endif
3622: #ifdef HAVE_negdf2
3623: if (HAVE_negdf2)
3624: neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
3625: #endif
3626: #ifdef HAVE_negtf2
3627: if (HAVE_negtf2)
3628: neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
3629: #endif
3630: neg_optab->handlers[(int) SImode].libfunc
3631: = gen_rtx (SYMBOL_REF, Pmode, "__negsi2");
3632: neg_optab->handlers[(int) DImode].libfunc
3633: = gen_rtx (SYMBOL_REF, Pmode, "__negdi2");
3634: neg_optab->handlers[(int) SFmode].libfunc
3635: = gen_rtx (SYMBOL_REF, Pmode, "__negsf2");
3636: neg_optab->handlers[(int) DFmode].libfunc
3637: = gen_rtx (SYMBOL_REF, Pmode, "__negdf2");
3638:
3639: #ifdef HAVE_absqi2
3640: if (HAVE_absqi2)
3641: abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
3642: #endif
3643: #ifdef HAVE_abshi2
3644: if (HAVE_abshi2)
3645: abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
3646: #endif
3647: #ifdef HAVE_abspsi2
3648: if (HAVE_abspsi2)
3649: abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
3650: #endif
3651: #ifdef HAVE_abssi2
3652: if (HAVE_abssi2)
3653: abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
3654: #endif
3655: #ifdef HAVE_absdi2
3656: if (HAVE_absdi2)
3657: abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
3658: #endif
3659: #ifdef HAVE_absti2
3660: if (HAVE_absti2)
3661: abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
3662: #endif
3663: #ifdef HAVE_abssf2
3664: if (HAVE_abssf2)
3665: abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
3666: #endif
3667: #ifdef HAVE_absdf2
3668: if (HAVE_absdf2)
3669: abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
3670: #endif
3671: #ifdef HAVE_abstf2
3672: if (HAVE_abstf2)
3673: abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
3674: #endif
3675: /* No library calls here! If there is no abs instruction,
3676: expand_expr will generate a conditional negation. */
3677:
3678: #ifdef HAVE_one_cmplqi2
3679: if (HAVE_one_cmplqi2)
3680: one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
3681: #endif
3682: #ifdef HAVE_one_cmplhi2
3683: if (HAVE_one_cmplhi2)
3684: one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
3685: #endif
3686: #ifdef HAVE_one_cmplpsi2
3687: if (HAVE_one_cmplpsi2)
3688: one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
3689: #endif
3690: #ifdef HAVE_one_cmplsi2
3691: if (HAVE_one_cmplsi2)
3692: one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
3693: #endif
3694: #ifdef HAVE_one_cmpldi2
3695: if (HAVE_one_cmpldi2)
3696: one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
3697: #endif
3698: #ifdef HAVE_one_cmplti2
3699: if (HAVE_one_cmplti2)
3700: one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
3701: #endif
3702: one_cmpl_optab->handlers[(int) SImode].libfunc
3703: = gen_rtx (SYMBOL_REF, Pmode, "__one_cmplsi2");
3704:
3705: #ifdef HAVE_ffsqi2
3706: if (HAVE_ffsqi2)
3707: ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
3708: #endif
3709: #ifdef HAVE_ffshi2
3710: if (HAVE_ffshi2)
3711: ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
3712: #endif
3713: #ifdef HAVE_ffspsi2
3714: if (HAVE_ffspsi2)
3715: ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
3716: #endif
3717: #ifdef HAVE_ffssi2
3718: if (HAVE_ffssi2)
3719: ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
3720: #endif
3721: #ifdef HAVE_ffsdi2
3722: if (HAVE_ffsdi2)
3723: ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
3724: #endif
3725: #ifdef HAVE_ffsti2
3726: if (HAVE_ffsti2)
3727: ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
3728: #endif
3729: ffs_optab->handlers[(int) SImode].libfunc
3730: = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3731:
3732: #ifdef HAVE_movqi
3733: if (HAVE_movqi)
3734: mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
3735: #endif
3736: #ifdef HAVE_movhi
3737: if (HAVE_movhi)
3738: mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
3739: #endif
3740: #ifdef HAVE_movpsi
3741: if (HAVE_movpsi)
3742: mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
3743: #endif
3744: #ifdef HAVE_movsi
3745: if (HAVE_movsi)
3746: mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
3747: #endif
3748: #ifdef HAVE_movdi
3749: if (HAVE_movdi)
3750: mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
3751: #endif
3752: #ifdef HAVE_movti
3753: if (HAVE_movti)
3754: mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
3755: #endif
3756: #ifdef HAVE_movsf
3757: if (HAVE_movsf)
3758: mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
3759: #endif
3760: #ifdef HAVE_movdf
3761: if (HAVE_movdf)
3762: mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
3763: #endif
3764: #ifdef HAVE_movtf
3765: if (HAVE_movtf)
3766: mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
3767: #endif
3768: #ifdef HAVE_movcc
3769: if (HAVE_movcc)
3770: mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
3771: #endif
3772:
3773: #ifdef EXTRA_CC_MODES
3774: init_mov_optab ();
3775: #endif
3776:
3777: #ifdef HAVE_movstrictqi
3778: if (HAVE_movstrictqi)
3779: movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
3780: #endif
3781: #ifdef HAVE_movstricthi
3782: if (HAVE_movstricthi)
3783: movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
3784: #endif
3785: #ifdef HAVE_movstrictpsi
3786: if (HAVE_movstrictpsi)
3787: movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
3788: #endif
3789: #ifdef HAVE_movstrictsi
3790: if (HAVE_movstrictsi)
3791: movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
3792: #endif
3793: #ifdef HAVE_movstrictdi
3794: if (HAVE_movstrictdi)
3795: movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
3796: #endif
3797: #ifdef HAVE_movstrictti
3798: if (HAVE_movstrictti)
3799: movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
3800: #endif
3801:
3802: #ifdef HAVE_cmpqi
3803: if (HAVE_cmpqi)
3804: cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
3805: #endif
3806: #ifdef HAVE_cmphi
3807: if (HAVE_cmphi)
3808: cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
3809: #endif
3810: #ifdef HAVE_cmppsi
3811: if (HAVE_cmppsi)
3812: cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
3813: #endif
3814: #ifdef HAVE_cmpsi
3815: if (HAVE_cmpsi)
3816: cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
3817: #endif
3818: #ifdef HAVE_cmpdi
3819: if (HAVE_cmpdi)
3820: cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
3821: #endif
3822: #ifdef HAVE_cmpti
3823: if (HAVE_cmpti)
3824: cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
3825: #endif
3826: #ifdef HAVE_cmpsf
3827: if (HAVE_cmpsf)
3828: cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
3829: #endif
3830: #ifdef HAVE_cmpdf
3831: if (HAVE_cmpdf)
3832: cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
3833: #endif
3834: #ifdef HAVE_cmptf
3835: if (HAVE_cmptf)
3836: cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
3837: #endif
3838: #ifdef HAVE_tstqi
3839: if (HAVE_tstqi)
3840: tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
3841: #endif
3842: #ifdef HAVE_tsthi
3843: if (HAVE_tsthi)
3844: tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
3845: #endif
3846: #ifdef HAVE_tstpsi
3847: if (HAVE_tstpsi)
3848: tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
3849: #endif
3850: #ifdef HAVE_tstsi
3851: if (HAVE_tstsi)
3852: tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
3853: #endif
3854: #ifdef HAVE_tstdi
3855: if (HAVE_tstdi)
3856: tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
3857: #endif
3858: #ifdef HAVE_tstti
3859: if (HAVE_tstti)
3860: tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
3861: #endif
3862: #ifdef HAVE_tstsf
3863: if (HAVE_tstsf)
3864: tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
3865: #endif
3866: #ifdef HAVE_tstdf
3867: if (HAVE_tstdf)
3868: tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
3869: #endif
3870: #ifdef HAVE_tsttf
3871: if (HAVE_tsttf)
3872: tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
3873: #endif
3874: /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3875: cmp_optab->handlers[(int) DImode].libfunc
3876: = gen_rtx (SYMBOL_REF, Pmode, "__cmpdi2");
3877: ucmp_optab->handlers[(int) DImode].libfunc
3878: = gen_rtx (SYMBOL_REF, Pmode, "__ucmpdi2");
3879:
3880: #ifdef HAVE_beq
3881: if (HAVE_beq)
3882: bcc_gen_fctn[(int) EQ] = gen_beq;
3883: #endif
3884: #ifdef HAVE_bne
3885: if (HAVE_bne)
3886: bcc_gen_fctn[(int) NE] = gen_bne;
3887: #endif
3888: #ifdef HAVE_bgt
3889: if (HAVE_bgt)
3890: bcc_gen_fctn[(int) GT] = gen_bgt;
3891: #endif
3892: #ifdef HAVE_bge
3893: if (HAVE_bge)
3894: bcc_gen_fctn[(int) GE] = gen_bge;
3895: #endif
3896: #ifdef HAVE_bgtu
3897: if (HAVE_bgtu)
3898: bcc_gen_fctn[(int) GTU] = gen_bgtu;
3899: #endif
3900: #ifdef HAVE_bgeu
3901: if (HAVE_bgeu)
3902: bcc_gen_fctn[(int) GEU] = gen_bgeu;
3903: #endif
3904: #ifdef HAVE_blt
3905: if (HAVE_blt)
3906: bcc_gen_fctn[(int) LT] = gen_blt;
3907: #endif
3908: #ifdef HAVE_ble
3909: if (HAVE_ble)
3910: bcc_gen_fctn[(int) LE] = gen_ble;
3911: #endif
3912: #ifdef HAVE_bltu
3913: if (HAVE_bltu)
3914: bcc_gen_fctn[(int) LTU] = gen_bltu;
3915: #endif
3916: #ifdef HAVE_bleu
3917: if (HAVE_bleu)
3918: bcc_gen_fctn[(int) LEU] = gen_bleu;
3919: #endif
3920:
3921: for (i = 0; i < NUM_RTX_CODE; i++)
3922: setcc_gen_code[i] = CODE_FOR_nothing;
3923:
3924: #ifdef HAVE_seq
3925: if (HAVE_seq)
3926: setcc_gen_code[(int) EQ] = CODE_FOR_seq;
3927: #endif
3928: #ifdef HAVE_sne
3929: if (HAVE_sne)
3930: setcc_gen_code[(int) NE] = CODE_FOR_sne;
3931: #endif
3932: #ifdef HAVE_sgt
3933: if (HAVE_sgt)
3934: setcc_gen_code[(int) GT] = CODE_FOR_sgt;
3935: #endif
3936: #ifdef HAVE_sge
3937: if (HAVE_sge)
3938: setcc_gen_code[(int) GE] = CODE_FOR_sge;
3939: #endif
3940: #ifdef HAVE_sgtu
3941: if (HAVE_sgtu)
3942: setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
3943: #endif
3944: #ifdef HAVE_sgeu
3945: if (HAVE_sgeu)
3946: setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
3947: #endif
3948: #ifdef HAVE_slt
3949: if (HAVE_slt)
3950: setcc_gen_code[(int) LT] = CODE_FOR_slt;
3951: #endif
3952: #ifdef HAVE_sle
3953: if (HAVE_sle)
3954: setcc_gen_code[(int) LE] = CODE_FOR_sle;
3955: #endif
3956: #ifdef HAVE_sltu
3957: if (HAVE_sltu)
3958: setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
3959: #endif
3960: #ifdef HAVE_sleu
3961: if (HAVE_sleu)
3962: setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
3963: #endif
3964:
3965: extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3966: truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3967: memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3968: bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3969: memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3970: bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
3971: memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3972: bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3973: eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3974: nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3975: gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3976: gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3977: ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3978: lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3979: eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3980: nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3981: gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3982: gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3983: ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3984: ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
3985: floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
3986: floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
3987: floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
3988: floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
3989: fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
3990: fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
3991: fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
3992: fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
3993: fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
3994: fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
3995: fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
3996: fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
3997: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.