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