|
|
1.1 root 1: /* Subroutines used for code generation on IBM RS/6000.
2: Copyright (C) 1991 Free Software Foundation, Inc.
3: Contributed by Richard Kenner ([email protected])
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: #include <stdio.h>
22: #include "config.h"
23: #include "rtl.h"
24: #include "regs.h"
25: #include "hard-reg-set.h"
26: #include "real.h"
27: #include "insn-config.h"
28: #include "conditions.h"
29: #include "insn-flags.h"
30: #include "output.h"
31: #include "insn-attr.h"
32: #include "flags.h"
33: #include "recog.h"
34: #include "expr.h"
35: #include "obstack.h"
36:
37: #define min(A,B) ((A) < (B) ? (A) : (B))
38: #define max(A,B) ((A) > (B) ? (A) : (B))
39:
40: /* Names of bss and data sections. These should be unique names for each
41: compilation unit. */
42:
43: char *rs6000_bss_section_name;
44: char *rs6000_private_data_section_name;
45: char *rs6000_read_only_section_name;
46:
47: /* Set to non-zero by "fix" operation to indicate that itrunc and
48: uitrunc must be defined. */
49:
50: int rs6000_trunc_used;
51:
52: /* Set to non-zero once they have been defined. */
53:
54: static int trunc_defined;
55:
56: /* Save information from a "cmpxx" operation until the branch or scc is
57: emitted. */
58:
59: rtx rs6000_compare_op0, rs6000_compare_op1;
60: int rs6000_compare_fp_p;
61:
62: /* Return non-zero if this function is known to have a null epilogue. */
63:
64: int
65: direct_return ()
66: {
67: return (reload_completed
68: && first_reg_to_save () == 32
69: && first_fp_reg_to_save () == 64
70: && ! regs_ever_live[65]
71: && ! rs6000_pushes_stack ());
72: }
73:
74: /* Returns 1 always. */
75:
76: int
77: any_operand (op, mode)
78: register rtx op;
79: enum machine_mode mode;
80: {
81: return 1;
82: }
83:
84: /* Return 1 if OP is a constant that can fit in a D field. */
85:
86: int
87: short_cint_operand (op, mode)
88: register rtx op;
89: enum machine_mode mode;
90: {
91: return (GET_CODE (op) == CONST_INT
92: && (unsigned) (INTVAL (op) + 0x8000) < 0x10000);
93: }
94:
95: /* Similar for a unsigned D field. */
96:
97: int
98: u_short_cint_operand (op, mode)
99: register rtx op;
100: enum machine_mode mode;
101: {
102: return (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0);
103: }
104:
105: /* Returns 1 if OP is a register that is not special (i.e., not MQ,
106: ctr, or lr). */
107:
108: int
109: gen_reg_operand (op, mode)
110: register rtx op;
111: enum machine_mode mode;
112: {
113: return (register_operand (op, mode)
114: && (GET_CODE (op) != REG || REGNO (op) >= 67 || REGNO (op) < 64));
115: }
116:
117: /* Returns 1 if OP is either a pseudo-register or a register denoting a
118: CR field. */
119:
120: int
121: cc_reg_operand (op, mode)
122: register rtx op;
123: enum machine_mode mode;
124: {
125: return (register_operand (op, mode)
126: && (GET_CODE (op) != REG
127: || REGNO (op) >= FIRST_PSEUDO_REGISTER
128: || CR_REGNO_P (REGNO (op))));
129: }
130:
131: /* Returns 1 if OP is either a constant integer valid for a D-field or a
132: non-special register. If a register, it must be in the proper mode unless
133: MODE is VOIDmode. */
134:
135: int
136: reg_or_short_operand (op, mode)
137: register rtx op;
138: enum machine_mode mode;
139: {
140: if (GET_CODE (op) == CONST_INT)
141: return short_cint_operand (op, mode);
142:
143: return gen_reg_operand (op, mode);
144: }
145:
146: /* Similar, except check if the negation of the constant would be valid for
147: a D-field. */
148:
149: int
150: reg_or_neg_short_operand (op, mode)
151: register rtx op;
152: enum machine_mode mode;
153: {
154: if (GET_CODE (op) == CONST_INT)
155: return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
156:
157: return gen_reg_operand (op, mode);
158: }
159:
160: /* Return 1 if the operand is either a register or an integer whose high-order
161: 16 bits are zero. */
162:
163: int
164: reg_or_u_short_operand (op, mode)
165: register rtx op;
166: enum machine_mode mode;
167: {
168: if (GET_CODE (op) == CONST_INT
169: && (INTVAL (op) & 0xffff0000) == 0)
170: return 1;
171:
172: return gen_reg_operand (op, mode);
173: }
174:
175: /* Return 1 is the operand is either a non-special register or ANY
176: constant integer. */
177:
178: int
179: reg_or_cint_operand (op, mode)
180: register rtx op;
181: enum machine_mode mode;
182: {
183: return GET_CODE (op) == CONST_INT || gen_reg_operand (op, mode);
184: }
185:
186: /* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
187: register with one instruction per word. For SFmode, this means that
188: the low 16-bits are zero. For DFmode, it means the low 16-bits of
189: the first word are zero and the high 16 bits of the second word
190: are zero (usually all bits in the low-order word will be zero).
191:
192: We only do this if we can safely read CONST_DOUBLE_{LOW,HIGH}. */
193:
194: int
195: easy_fp_constant (op, mode)
196: register rtx op;
197: register enum machine_mode mode;
198: {
199: rtx low, high;
200:
201: if (GET_CODE (op) != CONST_DOUBLE
202: || GET_MODE (op) != mode
203: || GET_MODE_CLASS (mode) != MODE_FLOAT)
204: return 0;
205:
206: high = operand_subword (op, 0, 0, mode);
207: low = operand_subword (op, 1, 0, mode);
208:
209: if (high == 0 || GET_CODE (high) != CONST_INT || (INTVAL (high) & 0xffff))
210: return 0;
211:
212: return (mode == SFmode
213: || (low != 0 && GET_CODE (low) == CONST_INT
214: && (INTVAL (low) & 0xffff0000) == 0));
215: }
216:
217: /* Return 1 if the operand is either a floating-point register, a pseudo
218: register, or memory. */
219:
220: int
221: fp_reg_or_mem_operand (op, mode)
222: register rtx op;
223: enum machine_mode mode;
224: {
225: return (memory_operand (op, mode)
226: || (register_operand (op, mode)
227: && (GET_CODE (op) != REG
228: || REGNO (op) >= FIRST_PSEUDO_REGISTER
229: || FP_REGNO_P (REGNO (op)))));
230: }
231:
232: /* Return 1 if the operand is either an easy FP constant (see above) or
233: memory. */
234:
235: int
236: mem_or_easy_const_operand (op, mode)
237: register rtx op;
238: enum machine_mode mode;
239: {
240: return memory_operand (op, mode) || easy_fp_constant (op, mode);
241: }
242:
243: /* Return 1 if the operand is either a non-special register or an item
244: that can be used as the operand of an SI add insn. */
245:
246: int
247: add_operand (op, mode)
248: register rtx op;
249: enum machine_mode mode;
250: {
251: return (reg_or_short_operand (op, mode)
252: || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0));
253: }
254:
255: /* Return 1 if the operand is a non-special register or a constant that
256: can be used as the operand of an OR or XOR insn on the RS/6000. */
257:
258: int
259: logical_operand (op, mode)
260: register rtx op;
261: enum machine_mode mode;
262: {
263: return (gen_reg_operand (op, mode)
264: || (GET_CODE (op) == CONST_INT
265: && ((INTVAL (op) & 0xffff0000) == 0
266: || (INTVAL (op) & 0xffff) == 0)));
267: }
268:
269: /* Return 1 if C is a constant that can be encoded in a mask on the
270: RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
271: Reject all ones and all zeros, since these should have been optimized
272: away and confuse the making of MB and ME. */
273:
274: int
275: mask_constant (c)
276: register int c;
277: {
278: int i;
279: int last_bit_value;
280: int transitions = 0;
281:
282: if (c == 0 || c == ~0)
283: return 0;
284:
285: last_bit_value = c & 1;
286:
287: for (i = 1; i < 32; i++)
288: if (((c >>= 1) & 1) != last_bit_value)
289: last_bit_value ^= 1, transitions++;
290:
291: return transitions <= 2;
292: }
293:
294: /* Return 1 if the operand is a constant that is a mask on the RS/6000. */
295:
296: int
297: mask_operand (op, mode)
298: register rtx op;
299: enum machine_mode mode;
300: {
301: return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op));
302: }
303:
304: /* Return 1 if the operand is either a non-special register or a
305: constant that can be used as the operand of an RS/6000 logical AND insn. */
306:
307: int
308: and_operand (op, mode)
309: register rtx op;
310: enum machine_mode mode;
311: {
312: return (reg_or_short_operand (op, mode)
313: || logical_operand (op, mode)
314: || mask_operand (op, mode));
315: }
316:
317: /* Return 1 if the operand is a general register or memory operand. */
318:
319: int
320: reg_or_mem_operand (op, mode)
321: register rtx op;
322: register enum machine_mode mode;
323: {
324: return gen_reg_operand (op, mode) || memory_operand (op, mode);
325: }
326:
327: /* Return 1 if the operand, used inside a MEM, is a valid first argument
328: to CALL. This is a SYMBOL_REF or a pseudo-register, which will be
329: forced to lr. */
330:
331: int
332: call_operand (op, mode)
333: register rtx op;
334: enum machine_mode mode;
335: {
336: if (mode != VOIDmode && GET_MODE (op) != mode)
337: return 0;
338:
339: return (GET_CODE (op) == SYMBOL_REF
340: || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER));
341: }
342:
343: /* Return 1 if this operand is a valid input for a move insn. */
344:
345: int
346: input_operand (op, mode)
347: register rtx op;
348: enum machine_mode mode;
349: {
350: if (memory_operand (op, mode))
351: return 1;
352:
353: /* For floating-point or multi-word mode, only register or memory
354: is valid. */
355: if (GET_MODE_CLASS (mode) == MODE_FLOAT
356: || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
357: return gen_reg_operand (op, mode);
358:
359: /* For SImode, we can also load from a special register, so any register
360: is valid. */
361: if (mode == SImode && register_operand (op, mode))
362: return 1;
363:
364: /* For HImode and QImode, any constant is valid along with any
365: non-special register. */
366: if (mode == HImode || mode == QImode)
367: return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
368:
369: /* Otherwise, we will be doing this SET with an add, so anything valid
370: for an add will be valid. */
371: return add_operand (op, mode);
372: }
373:
374: /* Return 1 if OP is a load multiple operation. It is known to be a
375: PARALLEL and the first section will be tested. */
376:
377: int
378: load_multiple_operation (op, mode)
379: rtx op;
380: enum machine_mode mode;
381: {
382: int count = XVECLEN (op, 0);
383: int dest_regno;
384: rtx src_addr;
385: int i;
386:
387: /* Perform a quick check so we don't blow up below. */
388: if (count <= 1
389: || GET_CODE (XVECEXP (op, 0, 0)) != SET
390: || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
391: || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
392: return 0;
393:
394: dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
395: src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
396:
397: for (i = 1; i < count; i++)
398: {
399: rtx elt = XVECEXP (op, 0, i);
400:
401: if (GET_CODE (elt) != SET
402: || GET_CODE (SET_DEST (elt)) != REG
403: || GET_MODE (SET_DEST (elt)) != SImode
404: || REGNO (SET_DEST (elt)) != dest_regno + i
405: || GET_CODE (SET_SRC (elt)) != MEM
406: || GET_MODE (SET_SRC (elt)) != SImode
407: || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
408: || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
409: || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
410: || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
411: return 0;
412: }
413:
414: return 1;
415: }
416:
417: /* Similar, but tests for store multiple. Here, the second vector element
418: is a CLOBBER. It will be tested later. */
419:
420: int
421: store_multiple_operation (op, mode)
422: rtx op;
423: enum machine_mode mode;
424: {
425: int count = XVECLEN (op, 0) - 1;
426: int src_regno;
427: rtx dest_addr;
428: int i;
429:
430: /* Perform a quick check so we don't blow up below. */
431: if (count <= 1
432: || GET_CODE (XVECEXP (op, 0, 0)) != SET
433: || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
434: || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
435: return 0;
436:
437: src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
438: dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
439:
440: for (i = 1; i < count; i++)
441: {
442: rtx elt = XVECEXP (op, 0, i + 1);
443:
444: if (GET_CODE (elt) != SET
445: || GET_CODE (SET_SRC (elt)) != REG
446: || GET_MODE (SET_SRC (elt)) != SImode
447: || REGNO (SET_SRC (elt)) != src_regno + i
448: || GET_CODE (SET_DEST (elt)) != MEM
449: || GET_MODE (SET_DEST (elt)) != SImode
450: || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
451: || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
452: || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
453: || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
454: return 0;
455: }
456:
457: return 1;
458: }
459:
460: /* Return 1 if OP is a comparison operation that is valid for a branch insn.
461: We only check the opcode against the mode of the CC value here. */
462:
463: int
464: branch_comparison_operator (op, mode)
465: register rtx op;
466: enum machine_mode mode;
467: {
468: enum rtx_code code = GET_CODE (op);
469: enum machine_mode cc_mode;
470:
471: if (GET_RTX_CLASS (code) != '<')
472: return 0;
473:
474: cc_mode = GET_MODE (XEXP (op, 0));
475: if (GET_MODE_CLASS (cc_mode) != MODE_CC)
476: return 0;
477:
478: if ((code == GT || code == LT || code == GE || code == LE)
479: && cc_mode == CCUNSmode)
480: return 0;
481:
482: if ((code == GTU || code == LTU || code == GEU || code == LEU)
483: && (cc_mode != CCUNSmode))
484: return 0;
485:
486: return 1;
487: }
488:
489: /* Return 1 if OP is a comparison operation that is valid for an scc insn.
490: We check the opcode against the mode of the CC value and disallow EQ or
491: NE comparisons for integers. */
492:
493: int
494: scc_comparison_operator (op, mode)
495: register rtx op;
496: enum machine_mode mode;
497: {
498: enum rtx_code code = GET_CODE (op);
499: enum machine_mode cc_mode;
500:
501: if (GET_MODE (op) != mode && mode != VOIDmode)
502: return 0;
503:
504: if (GET_RTX_CLASS (code) != '<')
505: return 0;
506:
507: cc_mode = GET_MODE (XEXP (op, 0));
508: if (GET_MODE_CLASS (cc_mode) != MODE_CC)
509: return 0;
510:
511: if (code == NE && cc_mode != CCFPmode)
512: return 0;
513:
514: if ((code == GT || code == LT || code == GE || code == LE)
515: && cc_mode == CCUNSmode)
516: return 0;
517:
518: if ((code == GTU || code == LTU || code == GEU || code == LEU)
519: && (cc_mode != CCUNSmode))
520: return 0;
521:
522: return 1;
523: }
524:
525: /* Return 1 if ANDOP is a mask that has no bits on that are not in the
526: mask required to convert the result of a rotate insn into a shift
527: left insn of SHIFTOP bits. Both are known to be CONST_INT. */
528:
529: int
530: includes_lshift_p (shiftop, andop)
531: register rtx shiftop;
532: register rtx andop;
533: {
534: int shift_mask = (~0 << INTVAL (shiftop));
535:
536: return (INTVAL (andop) & ~shift_mask) == 0;
537: }
538:
539: /* Similar, but for right shift. */
540:
541: int
542: includes_rshift_p (shiftop, andop)
543: register rtx shiftop;
544: register rtx andop;
545: {
546: unsigned shift_mask = ~0;
547:
548: shift_mask >>= INTVAL (shiftop);
549:
550: return (INTVAL (andop) & ~ shift_mask) == 0;
551: }
552:
553: /* Return the register class of a scratch register needed to copy IN into
554: or out of a register in CLASS in MODE. If it can be done directly,
555: NO_REGS is returned. */
556:
557: enum reg_class
558: secondary_reload_class (class, mode, in)
559: enum reg_class class;
560: enum machine_mode mode;
561: rtx in;
562: {
563: int regno = true_regnum (in);
564:
565: if (regno >= FIRST_PSEUDO_REGISTER)
566: regno = -1;
567:
568: /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
569: into anything. */
570: if (class == GENERAL_REGS || class == BASE_REGS
571: || (regno >= 0 && INT_REGNO_P (regno)))
572: return NO_REGS;
573:
574: /* Constants, memory, and FP registers can go into FP registers. */
575: if ((regno == -1 || FP_REGNO_P (regno))
576: && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
577: return NO_REGS;
578:
579: /* We can copy among the CR registers. */
580: if ((class == CR_REGS || class == CR0_REGS)
581: && regno >= 0 && CR_REGNO_P (regno))
582: return NO_REGS;
583:
584: /* Otherwise, we need GENERAL_REGS. */
585: return GENERAL_REGS;
586: }
587:
588: /* Given a comparison operation, return the bit number in CCR to test. We
589: know this is a valid comparison.
590:
591: SCC_P is 1 if this is for an scc. That means that %D will have been
592: used instead of %C, so the bits will be in different places.
593:
594: Return -1 if OP isn't a valid compaison for some reason. */
595:
596: int
597: ccr_bit (op, scc_p)
598: register rtx op;
599: int scc_p;
600: {
601: enum rtx_code code = GET_CODE (op);
602: enum machine_mode cc_mode;
603: int cc_regnum;
604: int base_bit;
605:
606: if (GET_RTX_CLASS (code) != '<')
607: return -1;
608:
609: cc_mode = GET_MODE (XEXP (op, 0));
610: cc_regnum = REGNO (XEXP (op, 0));
611: base_bit = 4 * (cc_regnum - 68);
612:
613: switch (code)
614: {
615: case NE:
616: return scc_p ? base_bit + 3 : base_bit + 2;
617: case EQ:
618: return base_bit + 2;
619: case GT: case GTU:
620: return base_bit + 1;
621: case LT: case LTU:
622: return base_bit;
623:
624: case GE: case GEU:
625: /* If floating-point, we will have done a cror to put the bit in the
626: unordered position. So test that bit. For integer, this is ! LT
627: unless this is an scc insn. */
628: return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit;
629:
630: case LE: case LEU:
631: return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1;
632:
633: default:
634: abort ();
635: }
636: }
637:
638: /* Print an operand. Recognize special options, documented below. */
639:
640: void
641: print_operand (file, x, code)
642: FILE *file;
643: rtx x;
644: char code;
645: {
646: int i;
647: int val;
648:
649: /* These macros test for integers and extract the low-order bits. */
650: #define INT_P(X) \
651: ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
652: && GET_MODE (X) == VOIDmode)
653:
654: #define INT_LOWPART(X) \
655: (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
656:
657: switch (code)
658: {
659: case 'h':
660: /* If constant, output low-order six bits. Otherwise, write normally. */
661: if (INT_P (x))
662: fprintf (file, "%d", INT_LOWPART (x) & 31);
663: else
664: print_operand (file, x, 0);
665: return;
666:
667: case 'H':
668: /* X must be a constant. Output the low order 6 bits plus 24. */
669: if (! INT_P (x))
670: output_operand_lossage ("invalid %%H value");
671:
672: fprintf (file, "%d", (INT_LOWPART (x) + 24) & 31);
673: return;
674:
675: case 'b':
676: /* Low-order 16 bits of constant, unsigned. */
677: if (! INT_P (x))
678: output_operand_lossage ("invalid %%b value");
679:
680: fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
681: return;
682:
683: case 'w':
684: /* If constant, low-order 16 bits of constant, signed. Otherwise, write
685: normally. */
686: if (INT_P (x))
687: fprintf (file, "%d", (INT_LOWPART (x) << 16) >> 16);
688: else
689: print_operand (file, x, 0);
690: return;
691:
692: case 'W':
693: /* If constant, low-order 16 bits of constant, unsigned.
694: Otherwise, write normally. */
695: if (INT_P (x))
696: fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
697: else
698: print_operand (file, x, 0);
699: return;
700:
701: case 'u':
702: /* High-order 16 bits of constant. */
703: if (! INT_P (x))
704: output_operand_lossage ("invalid %%u value");
705:
706: fprintf (file, "%d", (INT_LOWPART (x) >> 16) & 0xffff);
707: return;
708:
709: case 's':
710: /* Low 5 bits of 32 - value */
711: if (! INT_P (x))
712: output_operand_lossage ("invalid %%s value");
713:
714: fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31);
715: return;
716:
717: case 'S':
718: /* Low 5 bits of 31 - value */
719: if (! INT_P (x))
720: output_operand_lossage ("invalid %%S value");
721:
722: fprintf (file, "%d", (31 - INT_LOWPART (x)) & 31);
723: return;
724:
725: case 'p':
726: /* X is a CONST_INT that is a power of two. Output the logarithm. */
727: if (! INT_P (x)
728: || (i = exact_log2 (INT_LOWPART (x))) < 0)
729: output_operand_lossage ("invalid %%p value");
730:
731: fprintf (file, "%d", i);
732: return;
733:
734: case 'm':
735: /* MB value for a mask operand. */
736: if (! mask_operand (x, VOIDmode))
737: output_operand_lossage ("invalid %%m value");
738:
739: val = INT_LOWPART (x);
740:
741: /* If the high bit is set and the low bit is not, the value is zero.
742: If the high bit is zero, the value is the first 1 bit we find from
743: the left. */
744: if (val < 0 && (val & 1) == 0)
745: {
746: fprintf (file, "0");
747: return;
748: }
749: else if (val >= 0)
750: {
751: for (i = 1; i < 32; i++)
752: if ((val <<= 1) < 0)
753: break;
754: fprintf (file, "%d", i);
755: return;
756: }
757:
758: /* Otherwise, look for the first 0 bit from the right. The result is its
759: number plus 1. We know the low-order bit is one. */
760: for (i = 0; i < 32; i++)
761: if (((val >>= 1) & 1) == 0)
762: break;
763:
764: /* If we ended in ...01, I would be 0. The correct value is 31, so
765: we want 31 - i. */
766: fprintf (file, "%d", 31 - i);
767: return;
768:
769: case 'M':
770: /* ME value for a mask operand. */
771: if (! mask_operand (x, VOIDmode))
772: output_operand_lossage ("invalid %%m value");
773:
774: val = INT_LOWPART (x);
775:
776: /* If the low bit is set and the high bit is not, the value is 31.
777: If the low bit is zero, the value is the first 1 bit we find from
778: the right. */
779: if ((val & 1) && val >= 0)
780: {
781: fprintf (file, "31");
782: return;
783: }
784: else if ((val & 1) == 0)
785: {
786: for (i = 0; i < 32; i++)
787: if ((val >>= 1) & 1)
788: break;
789:
790: /* If we had ....10, I would be 0. The result should be
791: 30, so we need 30 - i. */
792: fprintf (file, "%d", 30 - i);
793: return;
794: }
795:
796: /* Otherwise, look for the first 0 bit from the left. The result is its
797: number minus 1. We know the high-order bit is one. */
798: for (i = 0; i < 32; i++)
799: if ((val <<= 1) >= 0)
800: break;
801:
802: fprintf (file, "%d", i);
803: return;
804:
805: case 'f':
806: /* X is a CR register. Print the shift count needed to move it
807: to the high-order four bits. */
808: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
809: output_operand_lossage ("invalid %%f value");
810: else
811: fprintf (file, "%d", 4 * (REGNO (x) - 68));
812: return;
813:
814: case 'F':
815: /* Similar, but print the count for the rotate in the opposite
816: direction. */
817: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
818: output_operand_lossage ("invalid %%F value");
819: else
820: fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));
821: return;
822:
823: case 'R':
824: /* X is a CR register. Print the mask for `mtcrf'. */
825: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
826: output_operand_lossage ("invalid %%R value");
827: else
828: fprintf (file, "%d", 128 >> (REGNO (x) - 68));
829: return;
830:
831: case 'X':
832: if (GET_CODE (x) == MEM
833: && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
834: fprintf (file, "x");
835: return;
836:
837: case 'U':
838: /* Print `u' is this has an auto-increment or auto-decremement. */
839: if (GET_CODE (x) == MEM
840: && (GET_CODE (XEXP (x, 0)) == PRE_INC
841: || GET_CODE (XEXP (x, 0)) == PRE_DEC))
842: fprintf (file, "u");
843: return;
844:
845: case 'I':
846: /* Print `i' is this is a constant, else nothing. */
847: if (INT_P (x))
848: fprintf (file, "i");
849: return;
850:
851: case 'N':
852: /* Write the number of elements in the vector times 4. */
853: if (GET_CODE (x) != PARALLEL)
854: output_operand_lossage ("invalid %%N value");
855:
856: fprintf (file, "%d", XVECLEN (x, 0) * 4);
857: return;
858:
859: case 'O':
860: /* Similar, but subtract 1 first. */
861: if (GET_CODE (x) != PARALLEL)
862: output_operand_lossage ("invalid %%N value");
863:
864: fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
865: return;
866:
867: case 'P':
868: /* The operand must be an indirect memory reference. The result
869: is the register number. */
870: if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
871: || REGNO (XEXP (x, 0)) >= 32)
872: output_operand_lossage ("invalid %%P value");
873:
874: fprintf (file, "%d", REGNO (XEXP (x, 0)));
875: return;
876:
877: case 'L':
878: /* Write second word of DImode or DFmode reference. Works on register
879: or non-indexed memory only. */
880: if (GET_CODE (x) == REG)
881: fprintf (file, "%d", REGNO (x) + 1);
882: else if (GET_CODE (x) == MEM)
883: {
884: /* Handle possible auto-increment. Since it is pre-increment and
885: we have already done it, we can just use an offset of four. */
886: if (GET_CODE (XEXP (x, 0)) == PRE_INC
887: || GET_CODE (XEXP (x, 0)) == PRE_DEC)
888: output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
889: else
890: output_address (plus_constant (XEXP (x, 0), 4));
891: }
892: return;
893:
894: case 'Y':
895: /* Similar, for third word of TImode */
896: if (GET_CODE (x) == REG)
897: fprintf (file, "%d", REGNO (x) + 2);
898: else if (GET_CODE (x) == MEM)
899: {
900: if (GET_CODE (XEXP (x, 0)) == PRE_INC
901: || GET_CODE (XEXP (x, 0)) == PRE_DEC)
902: output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
903: else
904: output_address (plus_constant (XEXP (x, 0), 8));
905: }
906: return;
907:
908: case 'Z':
909: /* Similar, for last word of TImode. */
910: if (GET_CODE (x) == REG)
911: fprintf (file, "%d", REGNO (x) + 3);
912: else if (GET_CODE (x) == MEM)
913: {
914: if (GET_CODE (XEXP (x, 0)) == PRE_INC
915: || GET_CODE (XEXP (x, 0)) == PRE_DEC)
916: output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
917: else
918: output_address (plus_constant (XEXP (x, 0), 12));
919: }
920: return;
921:
922: case 't':
923: /* Write 12 if this jump operation will branch if true, 4 otherwise.
924: All floating-point operations except NE branch true and integer
925: EQ, LT, GT, LTU and GTU also branch true. */
926: if (GET_RTX_CLASS (GET_CODE (x)) != '<')
927: output_operand_lossage ("invalid %%t value");
928:
929: else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
930: && GET_CODE (x) != NE)
931: || GET_CODE (x) == EQ
932: || GET_CODE (x) == LT || GET_CODE (x) == GT
933: || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
934: fprintf (file, "12");
935: else
936: fprintf (file, "4");
937: return;
938:
939: case 'T':
940: /* Opposite of 't': write 4 if this jump operation will branch if true,
941: 12 otherwise. */
942: if (GET_RTX_CLASS (GET_CODE (x)) != '<')
943: output_operand_lossage ("invalid %%t value");
944:
945: else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
946: && GET_CODE (x) != NE)
947: || GET_CODE (x) == EQ
948: || GET_CODE (x) == LT || GET_CODE (x) == GT
949: || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
950: fprintf (file, "4");
951: else
952: fprintf (file, "12");
953: return;
954:
955: case 'j':
956: /* Write the bit number in CCR for jump. */
957: i = ccr_bit (x, 0);
958: if (i == -1)
959: output_operand_lossage ("invalid %%j code");
960: else
961: fprintf (file, "%d", i);
962: return;
963:
964: case 'J':
965: /* Similar, but add one for shift count in rlinm for scc and pass
966: scc flag to `ccr_bit'. */
967: i = ccr_bit (x, 1);
968: if (i == -1)
969: output_operand_lossage ("invalid %%J code");
970: else
971: fprintf (file, "%d", i + 1);
972: return;
973:
974: case 'C':
975: /* This is an optional cror needed for LE or GE floating-point
976: comparisons. Otherwise write nothing. */
977: if ((GET_CODE (x) == LE || GET_CODE (x) == GE)
978: && GET_MODE (XEXP (x, 0)) == CCFPmode)
979: {
980: int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
981:
982: fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
983: base_bit + 2, base_bit + (GET_CODE (x) == GE));
984: }
985: return;
986:
987: case 'D':
988: /* Similar, except that this is for an scc, so we must be able to
989: encode the test in a single bit that is one. We do the above
990: for any LE, GE, GEU, or LEU and invert the bit for NE. */
991: if (GET_CODE (x) == LE || GET_CODE (x) == GE
992: || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
993: {
994: int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
995:
996: fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
997: base_bit + 2,
998: base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
999: }
1000:
1001: else if (GET_CODE (x) == NE)
1002: {
1003: int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
1004:
1005: fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
1006: base_bit + 2, base_bit + 2);
1007: }
1008: return;
1009:
1010: case 'z':
1011: /* X is a SYMBOL_REF. Write out the name preceeded by a
1012: period and without any trailing data in backets. Used for function
1013: names. */
1014: if (GET_CODE (x) != SYMBOL_REF)
1015: abort ();
1016:
1017: fprintf (file, ".");
1018: RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
1019: return;
1020:
1021: case 0:
1022: if (GET_CODE (x) == REG)
1023: fprintf (file, "%s", reg_names[REGNO (x)]);
1024: else if (GET_CODE (x) == MEM)
1025: {
1026: /* We need to handle PRE_INC and PRE_DEC here, since we need to
1027: know the width from the mode. */
1028: if (GET_CODE (XEXP (x, 0)) == PRE_INC)
1029: fprintf (file, "%d(%d)", GET_MODE_SIZE (GET_MODE (x)),
1030: REGNO (XEXP (XEXP (x, 0), 0)));
1031: else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
1032: fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)),
1033: REGNO (XEXP (XEXP (x, 0), 0)));
1034: else
1035: output_address (XEXP (x, 0));
1036: }
1037: else
1038: output_addr_const (file, x);
1039: break;
1040:
1041: default:
1042: output_operand_lossage ("invalid %%xn code");
1043: }
1044: }
1045:
1046: /* Print the address of an operand. */
1047:
1048: void
1049: print_operand_address (file, x)
1050: FILE *file;
1051: register rtx x;
1052: {
1053: if (GET_CODE (x) == REG)
1054: fprintf (file, "0(%d)", REGNO (x));
1055: else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
1056: {
1057: output_addr_const (file, x);
1058: fprintf (file, "(2)");
1059: }
1060: else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
1061: {
1062: if (REGNO (XEXP (x, 0)) == 0)
1063: fprintf (file, "%d,%d", REGNO (XEXP (x, 1)), REGNO (XEXP (x, 0)));
1064: else
1065: fprintf (file, "%d,%d", REGNO (XEXP (x, 0)), REGNO (XEXP (x, 1)));
1066: }
1067: else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
1068: fprintf (file, "%d(%d)", INTVAL (XEXP (x, 1)), REGNO (XEXP (x, 0)));
1069: else
1070: abort ();
1071: }
1072:
1073: /* This page contains routines that are used to determine what the function
1074: prologue and epilogue code will do and write them out. */
1075:
1076: /* Return the first fixed-point register that is required to be saved. 32 if
1077: none. */
1078:
1079: int
1080: first_reg_to_save ()
1081: {
1082: int first_reg;
1083:
1084: /* Find lowest numbered live register. */
1085: for (first_reg = 13; first_reg <= 31; first_reg++)
1086: if (regs_ever_live[first_reg])
1087: break;
1088:
1089: return first_reg;
1090: }
1091:
1092: /* Similar, for FP regs. */
1093:
1094: int
1095: first_fp_reg_to_save ()
1096: {
1097: int first_reg;
1098:
1099: /* Find lowest numbered live register. */
1100: for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
1101: if (regs_ever_live[first_reg])
1102: break;
1103:
1104: return first_reg;
1105: }
1106:
1107: /* Return 1 if we need to save CR. */
1108:
1109: int
1110: must_save_cr ()
1111: {
1112: return regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72];
1113: }
1114:
1115: /* Compute the size of the save area in the stack, including the space for
1116: the fixed area. */
1117:
1118: int
1119: rs6000_sa_size ()
1120: {
1121: int size;
1122: int i;
1123:
1124: /* We have the six fixed words, plus the size of the register save
1125: areas, rounded to a double-word. */
1126: size = 6 + (32 - first_reg_to_save ()) + (64 - first_fp_reg_to_save ()) * 2;
1127: if (size & 1)
1128: size++;
1129:
1130: return size * 4;
1131: }
1132:
1133: /* Return non-zero if this function makes calls. */
1134:
1135: int
1136: rs6000_makes_calls ()
1137: {
1138: rtx insn;
1139:
1140: for (insn = get_insns (); insn; insn = next_insn (insn))
1141: if (GET_CODE (insn) == CALL_INSN)
1142: return 1;
1143:
1144: return 0;
1145: }
1146:
1147: /* Return non-zero if this function needs to push space on the stack. */
1148:
1149: int
1150: rs6000_pushes_stack ()
1151: {
1152: int total_size = (rs6000_sa_size () + get_frame_size ()
1153: + current_function_outgoing_args_size);
1154:
1155: /* We need to push the stack if a frame pointer is needed (because the
1156: stack might be dynamically adjusted), if we are debugging, if the
1157: total stack size is more than 220 bytes, or if we make calls. */
1158:
1159: return (frame_pointer_needed || write_symbols != NO_DEBUG
1160: || total_size > 220
1161: || rs6000_makes_calls ());
1162: }
1163:
1164: /* Write function prologue. */
1165:
1166: void
1167: output_prolog (file, size)
1168: FILE *file;
1169: int size;
1170: {
1171: int first_reg = first_reg_to_save ();
1172: int must_push = rs6000_pushes_stack ();
1173: int first_fp_reg = first_fp_reg_to_save ();
1174: int basic_size = rs6000_sa_size ();
1175: int total_size = (basic_size + size + current_function_outgoing_args_size);
1176:
1177: /* Round size to multiple of 8 bytes. */
1178: total_size = (total_size + 7) & ~7;
1179:
1180: /* Write .extern for any function we will call to save and restore fp
1181: values. */
1182: if (first_fp_reg < 62)
1183: fprintf (file, "\t.extern ._savef%d\n\t.extern ._restf%d\n",
1184: first_fp_reg - 32, first_fp_reg - 32);
1185:
1186: /* Write .extern for truncation routines, if needed. */
1187: if (rs6000_trunc_used && ! trunc_defined)
1188: {
1189: fprintf (file, "\t.extern .itrunc\n\t.extern .uitrunc\n");
1190: trunc_defined = 1;
1191: }
1192:
1193: /* If we have to call a function to save fpr's, we will be using LR. */
1194: if (first_fp_reg < 62)
1195: regs_ever_live[65] = 1;
1196:
1197: /* If we use the link register, get it into r0. */
1198: if (regs_ever_live[65])
1199: fprintf (file, "\tmflr 0\n");
1200:
1201: /* If we need to save CR, put it into r12. */
1202: if (must_save_cr ())
1203: fprintf (file, "\tmfcr 12\n");
1204:
1205: /* Do any required saving of fpr's. If only one or two to save, do it
1206: ourself. Otherwise, call function. */
1207: if (first_fp_reg == 62)
1208: fprintf (file, "\tstfd 30,-16(1)\n\tstfd 31,-8(1)\n");
1209: else if (first_fp_reg == 63)
1210: fprintf (file, "\tstfd 31,-8(1)\n");
1211: else if (first_fp_reg != 64)
1212: fprintf (file, "\tbl ._savef%d\n\tcror 15,15,15\n", first_fp_reg - 32);
1213:
1214: /* Now save gpr's. */
1215: if (first_reg == 31)
1216: fprintf (file, "\tst 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8);
1217: else if (first_reg != 32)
1218: fprintf (file, "\tstm %d,%d(1)\n", first_reg,
1219: - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8);
1220:
1221: /* Save lr if we used it. */
1222: if (regs_ever_live[65])
1223: fprintf (file, "\tst 0,8(1)\n");
1224:
1225: /* Save CR if we use any that must be preserved. */
1226: if (must_save_cr ())
1227: fprintf (file, "\tst 12,4(1)\n");
1228:
1229: /* Update stack and set back pointer. */
1230: if (must_push)
1231: {
1232: if (total_size < 32767)
1233: fprintf (file, "\tstu 1,%d(1)\n", - total_size);
1234: else
1235: {
1236: fprintf (file, "\tcau 0,0,%d\n\toril 0,0,%d\n",
1237: (total_size >> 16) & 0xffff, total_size & 0xffff);
1238: fprintf (file, "\tsf 12,0,1\n\tst 1,0(12)\n\toril 1,12,0\n");
1239: }
1240: }
1241:
1242: /* Set frame pointer, if needed. */
1243: if (frame_pointer_needed)
1244: fprintf (file, "\toril 31,1,0\n");
1245: }
1246:
1247: /* Write function epilogue. */
1248:
1249: void
1250: output_epilog (file, size)
1251: FILE *file;
1252: int size;
1253: {
1254: int first_reg = first_reg_to_save ();
1255: int must_push = rs6000_pushes_stack ();
1256: int first_fp_reg = first_fp_reg_to_save ();
1257: int basic_size = rs6000_sa_size ();
1258: int total_size = (basic_size + size + current_function_outgoing_args_size);
1259: rtx insn = get_last_insn ();
1260:
1261: /* Round size to multiple of 8 bytes. */
1262: total_size = (total_size + 7) & ~7;
1263:
1264: /* If the last insn was a BARRIER, we don't have to write anything except
1265: the trace table. */
1266: if (GET_CODE (insn) == NOTE)
1267: insn = prev_nonnote_insn (insn);
1268: if (insn == 0 || GET_CODE (insn) != BARRIER)
1269: {
1270: /* If we have a frame pointer, a call to alloca, or a large stack
1271: frame, restore the old stack pointer using the backchain. Otherwise,
1272: we know what size to update it with. */
1273: if (frame_pointer_needed || current_function_calls_alloca
1274: || total_size > 32767)
1275: fprintf (file, "\tl 1,0(1)\n");
1276: else if (must_push)
1277: fprintf (file, "\tai 1,1,%d\n", total_size);
1278:
1279: /* Get the old lr if we saved it. To speed things up, copy it into
1280: lr here if we don't have to save more than 2 fp regs. */
1281: if (regs_ever_live[65])
1282: {
1283: fprintf (file, "\tl 0,8(1)\n");
1284: if (first_fp_reg >= 62)
1285: fprintf (file, "\tmtlr 0\n");
1286: }
1287:
1288: /* Get the old cr if we saved it. */
1289: if (must_save_cr ())
1290: fprintf (file, "\tl 12,4(1)\n");
1291:
1292: /* Restore gpr's. */
1293: if (first_reg == 31)
1294: fprintf (file, "\tl 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8);
1295: else if (first_reg != 32)
1296: fprintf (file, "\tlm %d,%d(1)\n", first_reg,
1297: - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8);
1298:
1299: /* Restore fpr's. */
1300: if (first_fp_reg == 62)
1301: fprintf (file, "\tlfd 30,-16(1)\n\tlfd 31,-8(1)\n");
1302: else if (first_fp_reg == 63)
1303: fprintf (file, "\tlfd 31,-8(1)\n");
1304: else if (first_fp_reg != 64)
1305: fprintf (file, "\tbl ._restf%d\n\tcror 15,15,15\n", first_fp_reg - 32);
1306:
1307: /* If we used the link register, get it from r0 if we haven't
1308: already. */
1309: if (regs_ever_live[65] && first_fp_reg < 62)
1310: fprintf (file, "\tmtlr 0\n");
1311:
1312: /* If we saved cr, restore it here. Just set cr2, cr3, and cr4. */
1313: if (must_save_cr ())
1314: fprintf (file, "\tmtcrf 0x38,12\n");
1315:
1316: fprintf (file, "\tbr\n");
1317: }
1318: }
1319:
1320: /* Output a TOC entry. We derive the entry name from what is
1321: being written. */
1322:
1323: void
1324: output_toc (file, x, labelno)
1325: FILE *file;
1326: rtx x;
1327: int labelno;
1328: {
1329: char buf[256];
1330: char *name = buf;
1331: rtx base = x;
1332: int offset = 0;
1333:
1334: ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
1335:
1336: /* Handle FP constants specially. */
1337: if (GET_CODE (x) == CONST_DOUBLE
1338: && GET_MODE (x) == DFmode
1339: && TARGET_FLOAT_FORMAT == HOST_FLOAT_FORMAT
1340: && BITS_PER_WORD == HOST_BITS_PER_INT
1341: && TARGET_FP_IN_TOC)
1342: {
1343: fprintf (file, "\t.tc FD_%x_%x[TC],%d,%d\n",
1344: CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
1345: CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
1346: return;
1347: }
1348: else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode
1349: && TARGET_FP_IN_TOC)
1350: {
1351: rtx val = operand_subword (x, 0, 0, SFmode);
1352:
1353: if (val == 0 || GET_CODE (val) != CONST_INT)
1354: abort ();
1355:
1356: fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val));
1357: return;
1358: }
1359:
1360: if (GET_CODE (x) == CONST)
1361: {
1362: base = XEXP (XEXP (x, 0), 0);
1363: offset = INTVAL (XEXP (XEXP (x, 0), 1));
1364: }
1365:
1366: if (GET_CODE (base) == SYMBOL_REF)
1367: name = XSTR (base, 0);
1368: else if (GET_CODE (base) == LABEL_REF)
1369: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
1370: else if (GET_CODE (base) == CODE_LABEL)
1371: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
1372: else
1373: abort ();
1374:
1375: fprintf (file, "\t.tc ");
1376: RS6000_OUTPUT_BASENAME (file, name);
1377:
1378: if (offset < 0)
1379: fprintf (file, "P.N.%d", - offset);
1380: else if (offset)
1381: fprintf (file, ".P.%d", offset);
1382:
1383: fprintf (file, "[TC],");
1384: output_addr_const (file, x);
1385: fprintf (file, "\n");
1386: }
1387:
1388: /* Output an assembler pseudo-op to write an ASCII string of N characters
1389: starting at P to FILE.
1390:
1391: On the RS/6000, we have to do this using the .byte operation and
1392: write out special characters outside the quoted string.
1393: Also, the assembler is broken; very long strings are truncated,
1394: so we must artificially break them up early. */
1395:
1396: void
1397: output_ascii (file, p, n)
1398: FILE *file;
1399: char *p;
1400: int n;
1401: {
1402: char c;
1403: int i, count_string;
1404: char *for_string = "\t.byte \"";
1405: char *for_decimal = "\t.byte ";
1406: char *to_close = NULL;
1407:
1408: count_string = 0;
1409: for (i = 0; i < n; i++)
1410: {
1411: c = *p++;
1412: if (c >= ' ' && c < 0177)
1413: {
1414: if (for_string)
1415: fputs (for_string, file);
1416: putc (c, file);
1417:
1418: /* Write two quotes to get one. */
1419: if (c == '"')
1420: {
1421: putc (c, file);
1422: ++count_string;
1423: }
1424:
1425: for_string = NULL;
1426: for_decimal = "\"\n\t.byte ";
1427: to_close = "\"\n";
1428: ++count_string;
1429:
1430: if (count_string >= 512)
1431: {
1432: fputs (to_close, file);
1433:
1434: for_string = "\t.byte \"";
1435: for_decimal = "\t.byte ";
1436: to_close = NULL;
1437: count_string = 0;
1438: }
1439: }
1440: else
1441: {
1442: if (for_decimal)
1443: fputs (for_decimal, file);
1444: fprintf (file, "%d", c);
1445:
1446: for_string = "\n\t.byte \"";
1447: for_decimal = ", ";
1448: to_close = "\n";
1449: count_string = 0;
1450: }
1451: }
1452:
1453: /* Now close the string if we have written one. Then end the line. */
1454: if (to_close)
1455: fprintf (file, to_close);
1456: }
1457:
1458: /* Generate a unique section name for FILENAME for a section type
1459: represented by SECTION_DESC. Output goes into BUF.
1460:
1461: SECTION_DESC can be any string, as long as it is different for each
1462: possible section type.
1463:
1464: We name the section in the same manner as xlc. The name begins with an
1465: underscore followed by the filename (after stripping any leading directory
1466: names) with the period replaced by the string SECTION_DESC. If FILENAME
1467: does not contain a period, SECTION_DESC is appended at the end of the
1468: name. */
1469:
1470: void
1471: rs6000_gen_section_name (buf, filename, section_desc)
1472: char **buf;
1473: char *filename;
1474: char *section_desc;
1475: {
1476: char *q, *after_last_slash;
1477: char *p;
1478: int len;
1479: int used_desc = 0;
1480:
1481: after_last_slash = filename;
1482: for (q = filename; *q; q++)
1483: if (*q == '/')
1484: after_last_slash = q + 1;
1485:
1486: len = strlen (filename) + strlen (section_desc) + 2;
1487: *buf = (char *) permalloc (len);
1488:
1489: p = *buf;
1490: *p++ = '_';
1491:
1492: for (q = after_last_slash; *q; q++)
1493: {
1494: if (*q == '.')
1495: {
1496: strcpy (p, section_desc);
1497: p += strlen (section_desc);
1498: used_desc = 1;
1499: }
1500:
1501: else if (isalnum (*q))
1502: *p++ = *q;
1503: }
1504:
1505: if (! used_desc)
1506: strcpy (p, section_desc);
1507: else
1508: *p = '\0';
1509: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.