xref: /openbsd/gnu/usr.bin/gcc/gcc/config/romp/romp.c (revision c87b03e5)
1 /* Subroutines used for code generation on ROMP.
2    Copyright (C) 1990, 1991, 1992, 1993, 1997, 1998, 1999, 2000, 2002
3    Free Software Foundation, Inc.
4    Contributed by Richard Kenner (kenner@nyu.edu)
5 
6 This file is part of GNU CC.
7 
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12 
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22 
23 
24 #include "config.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "real.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "obstack.h"
37 #include "tree.h"
38 #include "function.h"
39 #include "expr.h"
40 #include "ggc.h"
41 #include "toplev.h"
42 #include "tm_p.h"
43 #include "target.h"
44 #include "target-def.h"
45 
46 #define min(A,B)	((A) < (B) ? (A) : (B))
47 #define max(A,B)	((A) > (B) ? (A) : (B))
48 
49 static int unsigned_comparisons_p PARAMS ((rtx));
50 static void output_loadsave_fpregs PARAMS ((FILE *, enum rtx_code, rtx));
51 static void output_fpops PARAMS ((FILE *));
52 static void init_fpops PARAMS ((void));
53 static int memory_offset_in_range_p PARAMS ((rtx, enum machine_mode, int, int));
54 static unsigned int hash_rtx PARAMS ((rtx));
55 static void romp_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
56 static void romp_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
57 static void romp_select_rtx_section PARAMS ((enum machine_mode, rtx,
58 					     unsigned HOST_WIDE_INT));
59 static void romp_encode_section_info PARAMS ((tree, int));
60 
61 /* Initialize the GCC target structure.  */
62 #undef TARGET_ASM_FUNCTION_PROLOGUE
63 #define TARGET_ASM_FUNCTION_PROLOGUE romp_output_function_prologue
64 #undef TARGET_ASM_FUNCTION_EPILOGUE
65 #define TARGET_ASM_FUNCTION_EPILOGUE romp_output_function_epilogue
66 #undef TARGET_ASM_SELECT_RTX_SECTION
67 #define TARGET_ASM_SELECT_RTX_SECTION romp_select_rtx_section
68 #undef TARGET_ENCODE_SECTION_INFO
69 #define TARGET_ENCODE_SECTION_INFO romp_encode_section_info
70 
71 struct gcc_target targetm = TARGET_INITIALIZER;
72 
73 /* Return 1 if the insn using CC0 set by INSN does not contain
74    any unsigned tests applied to the condition codes.
75 
76    Based on `next_insn_tests_no_inequality' in recog.c.  */
77 
78 int
next_insn_tests_no_unsigned(insn)79 next_insn_tests_no_unsigned (insn)
80      rtx insn;
81 {
82   register rtx next = next_cc0_user (insn);
83 
84   if (next == 0)
85     {
86       if (find_reg_note (insn, REG_UNUSED, cc0_rtx))
87 	return 1;
88       else
89 	abort ();
90     }
91 
92   return ((GET_CODE (next) == JUMP_INSN
93 	   || GET_CODE (next) == INSN
94 	   || GET_CODE (next) == CALL_INSN)
95 	  && ! unsigned_comparisons_p (PATTERN (next)));
96 }
97 
98 static int
unsigned_comparisons_p(x)99 unsigned_comparisons_p (x)
100      rtx x;
101 {
102   register const char *fmt;
103   register int len, i;
104   register enum rtx_code code = GET_CODE (x);
105 
106   switch (code)
107     {
108     case REG:
109     case PC:
110     case CC0:
111     case CONST_INT:
112     case CONST_DOUBLE:
113     case CONST:
114     case LABEL_REF:
115     case SYMBOL_REF:
116       return 0;
117 
118     case LTU:
119     case GTU:
120     case LEU:
121     case GEU:
122       return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
123     default:
124       break;
125     }
126 
127   len = GET_RTX_LENGTH (code);
128   fmt = GET_RTX_FORMAT (code);
129 
130   for (i = 0; i < len; i++)
131     {
132       if (fmt[i] == 'e')
133 	{
134 	  if (unsigned_comparisons_p (XEXP (x, i)))
135 	    return 1;
136 	}
137       else if (fmt[i] == 'E')
138 	{
139 	  register int j;
140 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
141 	    if (unsigned_comparisons_p (XVECEXP (x, i, j)))
142 	      return 1;
143 	}
144     }
145 
146   return 0;
147 }
148 
149 /* Update the condition code from the insn.  Look mostly at the first
150    byte of the machine-specific insn description information.
151 
152    cc_state.value[12] refer to two possible values that might correspond
153    to the CC.  We only store register values.  */
154 
155 void
update_cc(body,insn)156 update_cc (body, insn)
157     rtx body ATTRIBUTE_UNUSED;
158     rtx insn;
159 {
160   switch (get_attr_cc (insn))
161     {
162     case CC_NONE:
163       /* Insn does not affect the CC at all.  */
164       break;
165 
166     case CC_CHANGE0:
167       /* Insn doesn't affect the CC but does modify operand[0], known to be
168 	 a register.  */
169       if (cc_status.value1 != 0
170 	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
171 	cc_status.value1 = 0;
172 
173       if (cc_status.value2 != 0
174 	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
175 	cc_status.value2 = 0;
176 
177       break;
178 
179     case CC_COPY1TO0:
180       /* Insn copies operand[1] to operand[0], both registers, but doesn't
181          affect the CC.  */
182       if (cc_status.value1 != 0
183 	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
184 	cc_status.value1 = 0;
185 
186       if (cc_status.value2 != 0
187 	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
188 	cc_status.value2 = 0;
189 
190       if (cc_status.value1 != 0
191 	  && rtx_equal_p (cc_status.value1, recog_data.operand[1]))
192 	cc_status.value2 = recog_data.operand[0];
193 
194       if (cc_status.value2 != 0
195 	  && rtx_equal_p (cc_status.value2, recog_data.operand[1]))
196 	cc_status.value1 = recog_data.operand[0];
197 
198       break;
199 
200     case CC_CLOBBER:
201       /* Insn clobbers CC.  */
202       CC_STATUS_INIT;
203       break;
204 
205     case CC_SETS:
206       /* Insn sets CC to recog_data.operand[0], but overflow is impossible.  */
207       CC_STATUS_INIT;
208       cc_status.flags |= CC_NO_OVERFLOW;
209       cc_status.value1 = recog_data.operand[0];
210       break;
211 
212    case CC_COMPARE:
213       /* Insn is a compare which sets the CC fully.  Update CC_STATUS for this
214 	 compare and mark whether the test will be signed or unsigned.  */
215       {
216 	register rtx p = PATTERN (insn);
217 
218 	CC_STATUS_INIT;
219 
220 	if (GET_CODE (p) == PARALLEL)
221 	  p = XVECEXP (p, 0, 0);
222 	cc_status.value1 = SET_SRC (p);
223 
224 	if (GET_CODE (SET_SRC (p)) == REG)
225 	  cc_status.flags |= CC_NO_OVERFLOW;
226 	if (! next_insn_tests_no_unsigned (insn))
227 	  cc_status.flags |= CC_UNSIGNED;
228       }
229       break;
230 
231     case CC_TBIT:
232       /* Insn sets T bit if result is nonzero.  Next insn must be branch.  */
233       CC_STATUS_INIT;
234       cc_status.flags = CC_IN_TB | CC_NOT_NEGATIVE;
235       break;
236 
237     default:
238       abort ();
239    }
240 }
241 
242 /* Return 1 if a previous compare needs to be re-issued.  This will happen
243    if two compares tested the same objects, but one was signed and the
244    other unsigned.  OP is the comparison operation being performed.  */
245 
246 int
restore_compare_p(op)247 restore_compare_p (op)
248      rtx op;
249 {
250   enum rtx_code code = GET_CODE (op);
251 
252   return (((code == GEU || code == LEU || code == GTU || code == LTU)
253 	   && ! (cc_status.flags & CC_UNSIGNED))
254 	  || ((code == GE || code == LE || code == GT || code == LT)
255 	      && (cc_status.flags & CC_UNSIGNED)));
256 }
257 
258 /*  Generate the (long) string corresponding to an inline multiply insn.
259     Note that `r10' does not refer to the register r10, but rather to the
260     SCR used as the MQ.  */
261 const char *
output_in_line_mul()262 output_in_line_mul ()
263 {
264   static char insns[200];
265   int i;
266 
267   strcpy (insns, "s %0,%0\n");
268   strcat (insns, "\tmts r10,%1\n");
269   for (i = 0; i < 16; i++)
270     strcat (insns, "\tm %0,%2\n");
271   strcat (insns, "\tmfs r10,%0");
272 
273   return insns;
274 }
275 
276 /* Returns 1 if OP is a memory reference with an offset from a register within
277    the range specified.  The offset must also be a multiple of the size of the
278    mode.  */
279 
280 static int
memory_offset_in_range_p(op,mode,low,high)281 memory_offset_in_range_p (op, mode, low, high)
282      register rtx op;
283      enum machine_mode mode;
284      int low, high;
285 {
286   int offset = 0;
287 
288   if (! memory_operand (op, mode))
289     return 0;
290 
291   while (GET_CODE (op) == SUBREG)
292     {
293       offset += SUBREG_BYTE (op);
294       op = SUBREG_REG (op);
295     }
296 
297   /* We must now have either (mem (reg (x)), (mem (plus (reg (x)) (c))),
298      or a constant pool address.  */
299   if (GET_CODE (op) != MEM)
300     abort ();
301 
302   /* Now use the actual mode and get the address.  */
303   mode = GET_MODE (op);
304   op = XEXP (op, 0);
305   if (GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
306     offset = get_pool_offset (op) + 12;
307   else if (GET_CODE (op) == PLUS)
308     {
309       if (GET_CODE (XEXP (op, 1)) != CONST_INT
310 	  || ! register_operand (XEXP (op, 0), Pmode))
311 	return 0;
312 
313       offset += INTVAL (XEXP (op, 1));
314     }
315 
316   else if (! register_operand (op, Pmode))
317     return 0;
318 
319   return (offset >= low && offset <= high
320 	  && (offset % GET_MODE_SIZE (mode) == 0));
321 }
322 
323 /* Return 1 if OP is a valid operand for a memory reference insn that can
324    only reference indirect through a register.   */
325 
326 int
zero_memory_operand(op,mode)327 zero_memory_operand (op, mode)
328      rtx op;
329      enum machine_mode mode;
330 {
331   return memory_offset_in_range_p (op, mode, 0, 0);
332 }
333 
334 /* Return 1 if OP is a valid operand for a `short' memory reference insn.  */
335 
336 int
short_memory_operand(op,mode)337 short_memory_operand (op, mode)
338      rtx op;
339      enum machine_mode mode;
340 {
341   if (mode == VOIDmode)
342     mode = GET_MODE (op);
343 
344   return memory_offset_in_range_p (op, mode, 0,
345 				   15 * min (UNITS_PER_WORD,
346 					     GET_MODE_SIZE (mode)));
347 }
348 
349 /* Returns 1 if OP is a memory reference involving a symbolic constant
350    that is not in the constant pool.  */
351 
352 int
symbolic_memory_operand(op,mode)353 symbolic_memory_operand (op, mode)
354      register rtx op;
355      enum machine_mode mode;
356 {
357   if (! memory_operand (op, mode))
358     return 0;
359 
360   while (GET_CODE (op) == SUBREG)
361     op = SUBREG_REG (op);
362 
363   if (GET_CODE (op) != MEM)
364     abort ();
365 
366   op = XEXP (op, 0);
367   if (constant_pool_address_operand (op, VOIDmode))
368     return 0;
369   else
370     return romp_symbolic_operand (op, Pmode)
371       || (GET_CODE (op) == PLUS && register_operand (XEXP (op, 0), Pmode)
372 	  && romp_symbolic_operand (XEXP (op, 1), Pmode));
373 }
374 
375 
376 /* Returns 1 if OP is a constant pool reference to the current function.  */
377 
378 int
current_function_operand(op,mode)379 current_function_operand (op, mode)
380      rtx op;
381      enum machine_mode mode ATTRIBUTE_UNUSED;
382 {
383   if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
384       ||  ! CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
385     return 0;
386 
387   op = get_pool_constant (XEXP (op, 0));
388   return (GET_CODE (op) == SYMBOL_REF
389 	  && ! strcmp (current_function_name, XSTR (op, 0)));
390 }
391 
392 /* Return nonzero if this function is known to have a null epilogue.  */
393 
394 int
null_epilogue()395 null_epilogue ()
396 {
397   return (reload_completed
398 	  && first_reg_to_save () == 16
399 	  && ! romp_pushes_stack ());
400 }
401 
402 /* Returns 1 if OP is the address of a location in the constant pool.  */
403 
404 int
constant_pool_address_operand(op,mode)405 constant_pool_address_operand (op, mode)
406      rtx op;
407      enum machine_mode mode ATTRIBUTE_UNUSED;
408 {
409   return ((GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
410 	  || (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS
411 	      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
412 	      && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
413 	      && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (op, 0), 0))));
414 }
415 
416 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
417    reference and a constant.  */
418 
419 int
romp_symbolic_operand(op,mode)420 romp_symbolic_operand (op, mode)
421      register rtx op;
422      enum machine_mode mode ATTRIBUTE_UNUSED;
423 {
424   switch (GET_CODE (op))
425     {
426     case SYMBOL_REF:
427     case LABEL_REF:
428       return ! op->integrated;
429 
430     case CONST:
431       op = XEXP (op, 0);
432       return (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
433 	      || GET_CODE (XEXP (op, 0)) == LABEL_REF)
434 	     && GET_CODE (XEXP (op, 1)) == CONST_INT;
435 
436     default:
437       return 0;
438     }
439 }
440 
441 /* Returns 1 if OP is a valid constant for the ROMP.  */
442 
443 int
constant_operand(op,mode)444 constant_operand (op, mode)
445     register rtx op;
446     enum machine_mode mode;
447 {
448   switch (GET_CODE (op))
449     {
450     case LABEL_REF:
451     case SYMBOL_REF:
452     case PLUS:
453     case CONST:
454       return romp_symbolic_operand (op,mode);
455 
456     case CONST_INT:
457       return (unsigned int) (INTVAL (op) + 0x8000) < 0x10000
458 	     || (INTVAL (op) & 0xffff) == 0 || (INTVAL (op) & 0xffff0000) == 0;
459 
460     default:
461       return 0;
462     }
463 }
464 
465 /* Returns 1 if OP is either a constant integer valid for the ROMP or a
466    register.  If a register, it must be in the proper mode unless MODE is
467    VOIDmode.  */
468 
469 int
reg_or_cint_operand(op,mode)470 reg_or_cint_operand (op, mode)
471       register rtx op;
472       enum machine_mode mode;
473 {
474   if (GET_CODE (op) == CONST_INT)
475     return constant_operand (op, mode);
476 
477   return register_operand (op, mode);
478 }
479 
480 /* Return 1 is the operand is either a register or ANY constant integer.  */
481 
482 int
reg_or_any_cint_operand(op,mode)483 reg_or_any_cint_operand (op, mode)
484     register rtx op;
485     enum machine_mode mode;
486 {
487      return GET_CODE (op) == CONST_INT || register_operand (op, mode);
488 }
489 
490 /* Return 1 if the operand is either a register or a valid D-type operand.  */
491 
492 int
reg_or_D_operand(op,mode)493 reg_or_D_operand (op, mode)
494     register rtx op;
495     enum machine_mode mode;
496 {
497   if (GET_CODE (op) == CONST_INT)
498     return (unsigned) (INTVAL (op) + 0x8000) < 0x10000;
499 
500   return register_operand (op, mode);
501 }
502 
503 /* Return 1 if the operand is either a register or an item that can be
504    used as the operand of an SI add insn.  */
505 
506 int
reg_or_add_operand(op,mode)507 reg_or_add_operand (op, mode)
508     register rtx op;
509     enum machine_mode mode;
510 {
511   return reg_or_D_operand (op, mode) || romp_symbolic_operand (op, mode)
512 	 || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0);
513 }
514 
515 /* Return 1 if the operand is either a register or an item that can be
516    used as the operand of a ROMP logical AND insn.  */
517 
518 int
reg_or_and_operand(op,mode)519 reg_or_and_operand (op, mode)
520     register rtx op;
521     enum machine_mode mode;
522 {
523   if (reg_or_cint_operand (op, mode))
524     return 1;
525 
526   if (GET_CODE (op) != CONST_INT)
527     return 0;
528 
529   return (INTVAL (op) & 0xffff) == 0xffff
530 	 || (INTVAL (op) & 0xffff0000) == 0xffff0000;
531 }
532 
533 /* Return 1 if the operand is a register or memory operand.  */
534 
535 int
reg_or_mem_operand(op,mode)536 reg_or_mem_operand (op, mode)
537      register rtx op;
538      register enum machine_mode mode;
539 {
540   return register_operand (op, mode) || memory_operand (op, mode);
541 }
542 
543 /* Return 1 if the operand is either a register or a memory operand that is
544    not symbolic.  */
545 
546 int
reg_or_nonsymb_mem_operand(op,mode)547 reg_or_nonsymb_mem_operand (op, mode)
548     register rtx op;
549     enum machine_mode mode;
550 {
551   if (register_operand (op, mode))
552     return 1;
553 
554   if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
555     return 1;
556 
557   return 0;
558 }
559 
560 /* Return 1 if this operand is valid for the ROMP.  This is any operand except
561    certain constant integers.  */
562 
563 int
romp_operand(op,mode)564 romp_operand (op, mode)
565     register rtx op;
566     enum machine_mode mode;
567 {
568   if (GET_CODE (op) == CONST_INT)
569     return constant_operand (op, mode);
570 
571   return general_operand (op, mode);
572 }
573 
574 /* Return 1 if the operand is (reg:mode 0).  */
575 
576 int
reg_0_operand(op,mode)577 reg_0_operand (op, mode)
578      rtx op;
579      enum machine_mode mode;
580 {
581   return ((mode == VOIDmode || mode == GET_MODE (op))
582 	  && GET_CODE (op) == REG && REGNO (op) == 0);
583 }
584 
585 /* Return 1 if the operand is (reg:mode 15).  */
586 
587 int
reg_15_operand(op,mode)588 reg_15_operand (op, mode)
589      rtx op;
590      enum machine_mode mode;
591 {
592   return ((mode == VOIDmode || mode == GET_MODE (op))
593 	  && GET_CODE (op) == REG && REGNO (op) == 15);
594 }
595 
596 /* Return 1 if this is a binary floating-point operation.  */
597 
598 int
float_binary(op,mode)599 float_binary (op, mode)
600     register rtx op;
601     enum machine_mode mode;
602 {
603   if (mode != VOIDmode && mode != GET_MODE (op))
604     return 0;
605 
606   if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
607     return 0;
608 
609   switch (GET_CODE (op))
610     {
611     case PLUS:
612     case MINUS:
613     case MULT:
614     case DIV:
615       return GET_MODE (XEXP (op, 0)) == GET_MODE (op)
616 	     && GET_MODE (XEXP (op, 1)) == GET_MODE (op);
617 
618     default:
619       return 0;
620     }
621 }
622 
623 /* Return 1 if this is a unary floating-point operation.  */
624 
625 int
float_unary(op,mode)626 float_unary (op, mode)
627     register rtx op;
628     enum machine_mode mode;
629 {
630   if (mode != VOIDmode && mode != GET_MODE (op))
631     return 0;
632 
633   if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
634     return 0;
635 
636   return (GET_CODE (op) == NEG || GET_CODE (op) == ABS)
637 	 && GET_MODE (XEXP (op, 0)) == GET_MODE (op);
638 }
639 
640 /* Return 1 if this is a valid floating-point conversion that can be done
641    as part of an operation by the RT floating-point routines.  */
642 
643 int
float_conversion(op,mode)644 float_conversion (op, mode)
645     register rtx op;
646     enum machine_mode mode;
647 {
648   if (mode != VOIDmode && mode != GET_MODE (op))
649     return 0;
650 
651   switch (GET_CODE (op))
652     {
653     case FLOAT_TRUNCATE:
654       return GET_MODE (op) == SFmode && GET_MODE (XEXP (op, 0)) == DFmode;
655 
656     case FLOAT_EXTEND:
657       return GET_MODE (op) == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
658 
659     case FLOAT:
660       return ((GET_MODE (XEXP (op, 0)) == SImode
661 	       || GET_CODE (XEXP (op, 0)) == CONST_INT)
662 	      && (GET_MODE (op) == SFmode || GET_MODE (op) == DFmode));
663 
664     case FIX:
665       return ((GET_MODE (op) == SImode
666 	       || GET_CODE (XEXP (op, 0)) == CONST_INT)
667 	      && (GET_MODE (XEXP (op, 0)) == SFmode
668 		  || GET_MODE (XEXP (op, 0)) == DFmode));
669 
670     default:
671       return 0;
672     }
673 }
674 
675 /* Print an operand.  Recognize special options, documented below.  */
676 
677 void
print_operand(file,x,code)678 print_operand (file, x, code)
679     FILE *file;
680     rtx x;
681     int code;
682 {
683   int i;
684 
685   switch (code)
686     {
687     case 'B':
688       /* Byte number (const/8) */
689       if (GET_CODE (x) != CONST_INT)
690 	output_operand_lossage ("invalid %%B value");
691 
692       fprintf (file, "%d", INTVAL (x) / 8);
693       break;
694 
695     case 'L':
696       /* Low order 16 bits of constant.  */
697       if (GET_CODE (x) != CONST_INT)
698 	output_operand_lossage ("invalid %%L value");
699 
700       fprintf (file, "%d", INTVAL (x) & 0xffff);
701       break;
702 
703     case 's':
704       /* Null or "16" depending on whether the constant is greater than 16.  */
705       if (GET_CODE (x) != CONST_INT)
706 	output_operand_lossage ("invalid %%s value");
707 
708       if (INTVAL (x) >= 16)
709 	fprintf (file, "16");
710 
711       break;
712 
713     case 'S':
714       /* For shifts: 's' will have given the half.  Just give the amount
715 	 within 16.  */
716       if (GET_CODE (x) != CONST_INT)
717 	output_operand_lossage ("invalid %%S value");
718 
719       fprintf (file, "%d", INTVAL (x) & 15);
720       break;
721 
722     case 'b':
723       /* The number of a single bit set or cleared, mod 16.  Note that the ROMP
724 	 numbers bits with the high-order bit 31.  */
725       if (GET_CODE (x) != CONST_INT)
726 	output_operand_lossage ("invalid %%b value");
727 
728       if ((i = exact_log2 (INTVAL (x))) >= 0)
729 	fprintf (file, "%d", (31 - i) % 16);
730       else if ((i = exact_log2 (~ INTVAL (x))) >= 0)
731 	fprintf (file, "%d", (31 - i) % 16);
732       else
733 	output_operand_lossage ("invalid %%b value");
734 
735       break;
736 
737     case 'h':
738       /* "l" or "u" depending on which half of the constant is zero.  */
739       if (GET_CODE (x) != CONST_INT)
740 	output_operand_lossage ("invalid %%h value");
741 
742       if ((INTVAL (x) & 0xffff0000) == 0)
743 	fprintf (file, "l");
744       else if ((INTVAL (x) & 0xffff) == 0)
745 	fprintf (file, "u");
746       else
747 	output_operand_lossage ("invalid %%h value");
748 
749       break;
750 
751     case 'H':
752       /* Upper or lower half, depending on which half is zero.  */
753       if (GET_CODE (x) != CONST_INT)
754 	output_operand_lossage ("invalid %%H value");
755 
756       if ((INTVAL (x) & 0xffff0000) == 0)
757 	fprintf (file, "%d", INTVAL (x) & 0xffff);
758       else if ((INTVAL (x) & 0xffff) == 0)
759 	fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
760       else
761 	output_operand_lossage ("invalid %%H value");
762 
763       break;
764 
765     case 'z':
766       /* Write two characters:
767 		'lo'	if the high order part is all ones
768 		'lz'	if the high order part is all zeros
769 		'uo'	if the low order part is all ones
770 		'uz'	if the low order part is all zeros
771        */
772       if (GET_CODE (x) != CONST_INT)
773 	output_operand_lossage ("invalid %%z value");
774 
775       if ((INTVAL (x) & 0xffff0000) == 0)
776 	fprintf (file, "lz");
777       else if ((INTVAL (x) & 0xffff0000) == 0xffff0000)
778 	fprintf (file, "lo");
779       else if ((INTVAL (x) & 0xffff) == 0)
780 	fprintf (file, "uz");
781       else if ((INTVAL (x) & 0xffff) == 0xffff)
782 	fprintf (file, "uo");
783       else
784 	output_operand_lossage ("invalid %%z value");
785 
786       break;
787 
788     case 'Z':
789       /* Upper or lower half, depending on which is nonzero or not
790 	 all ones.  Must be consistent with 'z' above.  */
791       if (GET_CODE (x) != CONST_INT)
792 	output_operand_lossage ("invalid %%Z value");
793 
794       if ((INTVAL (x) & 0xffff0000) == 0
795 	  || (INTVAL (x) & 0xffff0000) == 0xffff0000)
796 	fprintf (file, "%d", INTVAL (x) & 0xffff);
797       else if ((INTVAL (x) & 0xffff) == 0 || (INTVAL (x) & 0xffff) == 0xffff)
798 	fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
799       else
800 	output_operand_lossage ("invalid %%Z value");
801 
802       break;
803 
804     case 'k':
805       /* Same as 'z', except the trailing 'o' or 'z' is not written.  */
806       if (GET_CODE (x) != CONST_INT)
807 	output_operand_lossage ("invalid %%k value");
808 
809       if ((INTVAL (x) & 0xffff0000) == 0
810 	  || (INTVAL (x) & 0xffff0000) == 0xffff0000)
811 	fprintf (file, "l");
812       else if ((INTVAL (x) & 0xffff) == 0
813 	       || (INTVAL (x) & 0xffff) == 0xffff)
814 	fprintf (file, "u");
815       else
816 	output_operand_lossage ("invalid %%k value");
817 
818       break;
819 
820     case 't':
821       /* Similar to 's', except that we write 'h' or 'u'.  */
822       if (GET_CODE (x) != CONST_INT)
823 	output_operand_lossage ("invalid %%k value");
824 
825       if (INTVAL (x) < 16)
826 	fprintf (file, "u");
827       else
828 	fprintf (file, "l");
829       break;
830 
831     case 'M':
832       /* For memory operations, write 's' if the operand is a short
833 	 memory operand.  */
834       if (short_memory_operand (x, VOIDmode))
835 	fprintf (file, "s");
836       break;
837 
838     case 'N':
839       /* Like 'M', but check for zero memory offset.  */
840       if (zero_memory_operand (x, VOIDmode))
841 	fprintf (file, "s");
842       break;
843 
844     case 'O':
845       /* Write low-order part of DImode or DFmode.  Supported for MEM
846 	 and REG only.  */
847       if (GET_CODE (x) == REG)
848 	fprintf (file, "%s", reg_names[REGNO (x) + 1]);
849       else if (GET_CODE (x) == MEM)
850 	print_operand (file, gen_rtx_MEM (GET_MODE (x),
851 					  plus_constant (XEXP (x, 0), 4)), 0);
852       else
853 	abort ();
854       break;
855 
856     case 'C':
857       /* Offset in constant pool for constant pool address.  */
858       if (! constant_pool_address_operand (x, VOIDmode))
859 	abort ();
860       if (GET_CODE (x) == SYMBOL_REF)
861 	fprintf (file, "%d", get_pool_offset (x) + 12);
862       else
863 	/* Must be (const (plus (symbol_ref) (const_int))) */
864 	fprintf (file, "%d",
865 		 (get_pool_offset (XEXP (XEXP (x, 0), 0)) + 12
866 		  + INTVAL (XEXP (XEXP (x, 0), 1))));
867       break;
868 
869     case 'j':
870       /* Branch opcode.  Check for condition in test bit for eq/ne.  */
871       switch (GET_CODE (x))
872 	{
873 	case EQ:
874 	  if (cc_status.flags & CC_IN_TB)
875 	    fprintf (file, "ntb");
876 	  else
877 	    fprintf (file, "eq");
878 	  break;
879 
880 	case NE:
881 	  if (cc_status.flags & CC_IN_TB)
882 	    fprintf (file, "tb");
883 	  else
884 	    fprintf (file, "ne");
885 	  break;
886 
887 	case GT:
888 	case GTU:
889 	  fprintf (file, "h");
890 	  break;
891 
892 	case LT:
893 	case LTU:
894 	  fprintf (file, "l");
895 	  break;
896 
897 	case GE:
898 	case GEU:
899 	  fprintf (file, "he");
900 	  break;
901 
902 	case LE:
903 	case LEU:
904 	  fprintf (file, "le");
905 	  break;
906 
907 	default:
908 	  output_operand_lossage ("invalid %%j value");
909 	}
910       break;
911 
912     case 'J':
913       /* Reversed branch opcode.  */
914       switch (GET_CODE (x))
915 	{
916 	case EQ:
917 	  if (cc_status.flags & CC_IN_TB)
918 	    fprintf (file, "tb");
919 	  else
920 	    fprintf (file, "ne");
921 	  break;
922 
923 	case NE:
924 	  if (cc_status.flags & CC_IN_TB)
925 	    fprintf (file, "ntb");
926 	  else
927 	    fprintf (file, "eq");
928 	  break;
929 
930 	case GT:
931 	case GTU:
932 	  fprintf (file, "le");
933 	  break;
934 
935 	case LT:
936 	case LTU:
937 	  fprintf (file, "he");
938 	  break;
939 
940 	case GE:
941 	case GEU:
942 	  fprintf (file, "l");
943 	  break;
944 
945 	case LE:
946 	case LEU:
947 	  fprintf (file, "h");
948 	  break;
949 
950 	default:
951 	  output_operand_lossage ("invalid %%j value");
952 	}
953       break;
954 
955     case '.':
956       /* Output nothing.  Used as delimiter in, e.g., "mc%B1%.3 " */
957       break;
958 
959     case '#':
960       /* Output 'x' if this insn has a delay slot, else nothing.  */
961       if (dbr_sequence_length ())
962 	fprintf (file, "x");
963       break;
964 
965     case 0:
966       if (GET_CODE (x) == REG)
967 	fprintf (file, "%s", reg_names[REGNO (x)]);
968       else if (GET_CODE (x) == MEM)
969 	{
970 	  if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
971 	      && current_function_operand (x, Pmode))
972 	    fprintf (file, "r14");
973 	  else
974 	    output_address (XEXP (x, 0));
975 	}
976       else
977 	output_addr_const (file, x);
978       break;
979 
980     default:
981       output_operand_lossage ("invalid %%xn code");
982     }
983 }
984 
985 /* This page contains routines that are used to determine what the function
986    prologue and epilogue code will do and write them out.  */
987 
988 /*  Return the first register that is required to be saved. 16 if none.  */
989 
990 int
first_reg_to_save()991 first_reg_to_save()
992 {
993   int first_reg;
994 
995   /* Find lowest numbered live register.  */
996   for (first_reg = 6; first_reg <= 15; first_reg++)
997     if (regs_ever_live[first_reg])
998       break;
999 
1000   /* If we think that we do not have to save r14, see if it will be used
1001      to be sure.  */
1002   if (first_reg > 14 && romp_using_r14 ())
1003     first_reg = 14;
1004 
1005   return first_reg;
1006 }
1007 
1008 /* Compute the size of the save area in the stack, including the space for
1009    the first four incoming arguments.  */
1010 
1011 int
romp_sa_size()1012 romp_sa_size ()
1013 {
1014   int size;
1015   int i;
1016 
1017   /* We have the 4 words corresponding to the arguments passed in registers,
1018      4 reserved words, space for static chain, general register save area,
1019      and floating-point save area.  */
1020   size = 4 + 4 + 1 + (16 - first_reg_to_save ());
1021 
1022   /* The documentation says we have to leave 18 words in the save area if
1023      any floating-point registers at all are saved, not the three words
1024      per register you might otherwise expect.  */
1025   for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1026     if (regs_ever_live[i + 17])
1027       {
1028 	size += 18;
1029 	break;
1030       }
1031 
1032   return size * 4;
1033 }
1034 
1035 /* Return nonzero if this function makes calls or has fp operations
1036    (which are really calls).  */
1037 
1038 int
romp_makes_calls()1039 romp_makes_calls ()
1040 {
1041   rtx insn;
1042 
1043   for (insn = get_insns (); insn; insn = next_insn (insn))
1044     {
1045       if (GET_CODE (insn) == CALL_INSN)
1046 	return 1;
1047       else if (GET_CODE (insn) == INSN)
1048 	{
1049 	  rtx body = PATTERN (insn);
1050 
1051 	  if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER
1052 	      && GET_CODE (body) != ADDR_VEC
1053 	      && GET_CODE (body) != ADDR_DIFF_VEC
1054 	      && get_attr_type (insn) == TYPE_FP)
1055 	    return 1;
1056 	}
1057     }
1058 
1059   return 0;
1060 }
1061 
1062 /* Return nonzero if this function will use r14 as a pointer to its
1063    constant pool.  */
1064 
1065 int
romp_using_r14()1066 romp_using_r14 ()
1067 {
1068   /* If we are debugging, profiling, have a non-empty constant pool, or
1069      call a function, we need r14.  */
1070   return (write_symbols != NO_DEBUG || current_function_profile
1071 	  || get_pool_size () != 0 || romp_makes_calls ());
1072 }
1073 
1074 /* Return nonzero if this function needs to push space on the stack.  */
1075 
1076 int
romp_pushes_stack()1077 romp_pushes_stack ()
1078 {
1079   /* We need to push the stack if a frame pointer is needed (because the
1080      stack might be dynamically adjusted), if we are debugging, if the
1081      total required size is more than 100 bytes, or if we make calls.  */
1082 
1083   return (frame_pointer_needed || write_symbols != NO_DEBUG
1084 	  || (romp_sa_size () + get_frame_size ()) > 100
1085 	  || romp_makes_calls ());
1086 }
1087 
1088 /* Write function prologue.
1089 
1090    We compute the size of the fixed area required as follows:
1091 
1092    We always allocate 4 words for incoming arguments, 4 word reserved, 1
1093    word for static link, as many words as required for general register
1094    save area, plus 2 words for each FP reg 2-7 that must be saved.  */
1095 
1096 static void
romp_output_function_prologue(file,size)1097 romp_output_function_prologue (file, size)
1098      FILE *file;
1099      HOST_WIDE_INT size;
1100 {
1101   int first_reg;
1102   int reg_save_offset;
1103   HOST_WIDE_INT fp_save = size + current_function_outgoing_args_size;
1104 
1105   init_fpops ();
1106 
1107   /* Add in fixed size plus output argument area.  */
1108   size += romp_sa_size () + current_function_outgoing_args_size;
1109 
1110   /* Compute first register to save and perform the save operation if anything
1111      needs to be saved.  */
1112   first_reg = first_reg_to_save();
1113   reg_save_offset = - (4 + 4 + 1 + (16 - first_reg)) * 4;
1114   if (first_reg == 15)
1115     fprintf (file, "\tst r15,%d(r1)\n", reg_save_offset);
1116   else if (first_reg < 16)
1117     fprintf (file, "\tstm r%d,%d(r1)\n", first_reg, reg_save_offset);
1118 
1119   /* Set up pointer to data area if it is needed.  */
1120   if (romp_using_r14 ())
1121     fprintf (file, "\tcas r14,r0,r0\n");
1122 
1123   /* Set up frame pointer if needed.  */
1124   if (frame_pointer_needed)
1125     fprintf (file, "\tcal r13,-%d(r1)\n", romp_sa_size () + 64);
1126 
1127   /* Push stack if neeeded.  There are a couple of ways of doing this.  */
1128   if (romp_pushes_stack ())
1129     {
1130       if (size >= 32768)
1131 	{
1132 	  if (size >= 65536)
1133 	    {
1134 	      fprintf (file, "\tcau r0,%d(r0)\n", size >> 16);
1135 	      fprintf (file, "\toil r0,r0,%d\n", size & 0xffff);
1136 	    }
1137 	  else
1138 	    fprintf (file, "\tcal16 r0,%d(r0)\n", size);
1139 	  fprintf (file, "\ts r1,r0\n");
1140 	}
1141       else
1142 	fprintf (file, "\tcal r1,-%d(r1)\n", size);
1143     }
1144 
1145   /* Save floating-point registers.  */
1146   output_loadsave_fpregs (file, USE,
1147 			  plus_constant (stack_pointer_rtx, fp_save));
1148 }
1149 
1150 /* Output the offset information used by debuggers.
1151    This is the exactly the total_size value of output_function_epilogue()
1152    which is added to the frame pointer. However the value in the debug
1153    table is encoded in a space-saving way as follows:
1154 
1155    The first byte contains two fields: a 2-bit size field and the first
1156    6 bits of an offset value. The 2-bit size field is in the high-order
1157    position and specifies how many subsequent bytes follow after
1158    this one. An offset value is at most 4-bytes long.
1159 
1160    The last 6 bits of the first byte initialize the offset value. In many
1161    cases where procedures have small local storage, this is enough and, in
1162    this case, the high-order size field is zero so the byte can (almost) be
1163    used as is (see below). Thus, the byte value of 0x0d is encodes an offset
1164    size of 13 words, or 52 bytes.
1165 
1166    For procedures with a local space larger than 60 bytes, the 6 bits
1167    are the high-order 6 bits.  The remaining bytes follow as necessary,
1168    in Big Endian order.  Thus, the short value of 16907 (= 16384+523)
1169    encodes an offset of 2092 bytes (523 words).
1170 
1171    The total offset value is in words (not bytes), so the final value has to
1172    be multiplied by 4 before it can be used in address computations by a
1173    debugger.   */
1174 
1175 void
output_encoded_offset(file,reg_offset)1176 output_encoded_offset (file, reg_offset)
1177      FILE *file;
1178      unsigned reg_offset;
1179 {
1180   /* Convert the offset value to 4-byte words rather than bytes.  */
1181   reg_offset = (reg_offset + 3) / 4;
1182 
1183   /* Now output 1-4 bytes in encoded form.  */
1184   if (reg_offset < (1 << 6))
1185     /* Fits into one byte */
1186     fprintf (file, "\t.byte %d\n", reg_offset);
1187   else if (reg_offset < (1 << (6 + 8)))
1188     /* Fits into two bytes */
1189     fprintf (file, "\t.short %d\n", (1 << (6 + 8)) + reg_offset);
1190   else if (reg_offset < (1 << (6 + 8 + 8)))
1191     {
1192       /* Fits in three bytes */
1193       fprintf (file, "\t.byte %d\n", (2 << 6) + (reg_offset >> ( 6+ 8)));
1194       fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1195     }
1196   else
1197     {
1198       /* Use 4 bytes.  */
1199       fprintf (file, "\t.short %d", (3 << (6 + 8)) + (reg_offset >> (6 + 8)));
1200       fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1201     }
1202 }
1203 
1204 /* Write function epilogue.  */
1205 
1206 static void
romp_output_function_epilogue(file,size)1207 romp_output_function_epilogue (file, size)
1208      FILE *file;
1209      HOST_WIDE_INT size;
1210 {
1211   int first_reg = first_reg_to_save();
1212   int pushes_stack = romp_pushes_stack ();
1213   int reg_save_offset = - ((16 - first_reg) + 1 + 4 + 4) * 4;
1214   HOST_WIDE_INT total_size = (size + romp_sa_size ()
1215 			      + current_function_outgoing_args_size);
1216   HOST_WIDE_INT fp_save = size + current_function_outgoing_args_size;
1217   int long_frame = total_size >= 32768;
1218   rtx insn = get_last_insn ();
1219   int write_code = 1;
1220 
1221   int nargs = 0;		/* words of arguments */
1222   tree argptr;
1223 
1224   /* Compute the number of words of arguments.  Since this is just for
1225      the traceback table, we ignore arguments that don't have a size or
1226      don't have a fixed size.  */
1227 
1228   for (argptr = DECL_ARGUMENTS (current_function_decl);
1229        argptr; argptr = TREE_CHAIN (argptr))
1230     {
1231       int this_size = int_size_in_bytes (TREE_TYPE (argptr));
1232 
1233       if (this_size > 0)
1234 	nargs += (this_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1235     }
1236 
1237   /* If the last insn was a BARRIER, we don't have to write anything except
1238      the trace table.  */
1239   if (GET_CODE (insn) == NOTE)
1240     insn = prev_nonnote_insn (insn);
1241   if (insn && GET_CODE (insn) == BARRIER)
1242     write_code = 0;
1243 
1244   /* Restore floating-point registers.  */
1245   if (write_code)
1246     output_loadsave_fpregs (file, CLOBBER,
1247 			    plus_constant (gen_rtx_REG (Pmode, 1), fp_save));
1248 
1249   /* If we push the stack and do not have size > 32K, adjust the register
1250      save location to the current position of sp.  Otherwise, if long frame,
1251      restore sp from fp.  */
1252   if (pushes_stack && ! long_frame)
1253     reg_save_offset += total_size;
1254   else if (long_frame && write_code)
1255     fprintf (file, "\tcal r1,%d(r13)\n", romp_sa_size () + 64);
1256 
1257   /* Restore registers.  */
1258   if (first_reg == 15 && write_code)
1259     fprintf (file, "\tl r15,%d(r1)\n", reg_save_offset);
1260   else if (first_reg < 16 && write_code)
1261     fprintf (file, "\tlm r%d,%d(r1)\n", first_reg, reg_save_offset);
1262   if (first_reg == 16) first_reg = 0;
1263 
1264   /* Handle popping stack, if needed and write debug table entry.  */
1265   if (pushes_stack)
1266     {
1267       if (write_code)
1268 	{
1269 	  if (long_frame)
1270 	    fprintf (file, "\tbr r15\n");
1271 	  else
1272 	    fprintf (file, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size);
1273 	}
1274 
1275       /* Table header (0xdf), usual-type stack frame (0x07),
1276 	 table header (0xdf), and first register saved.
1277 
1278 	 The final 0x08 means that there is a byte following this one
1279 	 describing the number of parameter words and the register used as
1280 	 stack pointer.
1281 
1282 	 If GCC passed floating-point parameters in floating-point registers,
1283 	 it would be necessary to change the final byte from 0x08 to 0x0c.
1284 	 Also an additional entry byte would be need to be emitted to specify
1285 	 the first floating-point register.
1286 
1287 	 (See also Section 11 (Trace Tables) in ``IBM/4.3 Linkage Convention,''
1288 	 pages IBM/4.3-PSD:5-7 of Volume III of the IBM Academic Operating
1289 	 System Manual dated July 1987.)  */
1290 
1291       fprintf (file, "\t.long 0x%x\n", 0xdf07df08 + first_reg * 0x10);
1292 
1293       if (nargs > 15) nargs = 15;
1294 
1295       /* The number of parameter words and the register used as the stack
1296 	 pointer (encoded here as r1).
1297 
1298 	 Note: The MetWare Hich C Compiler R2.1y actually gets this wrong;
1299 	 it erroneously lists r13 but uses r1 as the stack too. But a bug in
1300 	 dbx 1.5 nullifies this mistake---most of the time.
1301          (Dbx retrieves the value of r13 saved on the stack which is often
1302 	 the value of r1 before the call.)  */
1303 
1304       fprintf (file, "\t.byte 0x%x1\n", nargs);
1305       output_encoded_offset (file, total_size);
1306     }
1307   else
1308     {
1309       if (write_code)
1310 	fprintf (file, "\tbr r15\n");
1311 
1312       /* Table header (0xdf), no stack frame (0x02),
1313 	 table header (0xdf) and no parameters saved (0x00).
1314 
1315 	 If GCC passed floating-point parameters in floating-point registers,
1316 	 it might be necessary to change the final byte from 0x00 to 0x04.
1317 	 Also a byte would be needed to specify the first floating-point
1318 	 register.  */
1319       fprintf (file, "\t.long 0xdf02df00\n");
1320     }
1321 
1322   /* Output any pending floating-point operations.  */
1323   output_fpops (file);
1324 }
1325 
1326 /* For the ROMP we need to make new SYMBOL_REFs for the actual name of a
1327    called routine.  To keep them unique we maintain a hash table of all
1328    that have been created so far.  */
1329 
1330 struct symref_hashent {
1331   rtx symref;			/* Created SYMBOL_REF rtx.  */
1332   struct symref_hashent *next;	/* Next with same hash code.  */
1333 };
1334 
1335 #define SYMHASHSIZE 151
1336 #define HASHBITS 65535
1337 
1338 /* Define the hash table itself.  */
1339 
1340 static struct symref_hashent *symref_hash_table[SYMHASHSIZE];
1341 
1342 /* Given a name (allocable in temporary storage), return a SYMBOL_REF
1343    for the name.  The rtx is allocated from the current rtl_obstack, while
1344    the name string is allocated from the permanent obstack.  */
1345 rtx
get_symref(name)1346 get_symref (name)
1347      register const char *name;
1348 {
1349   register const char *sp = name;
1350   unsigned int hash = 0;
1351   struct symref_hashent *p, **last_p;
1352 
1353   /* Compute the hash code for the string.  */
1354   while (*sp)
1355     hash = (hash << 4) + *sp++;
1356 
1357   /* Search for a matching entry in the hash table, keeping track of the
1358      insertion location as we do so.  */
1359   hash = (hash & HASHBITS) % SYMHASHSIZE;
1360   for (last_p = &symref_hash_table[hash], p = *last_p;
1361        p; last_p = &p->next, p = *last_p)
1362     if (strcmp (name, XSTR (p->symref, 0)) == 0)
1363       break;
1364 
1365   /* If couldn't find matching SYMBOL_REF, make a new one.  */
1366   if (p == 0)
1367     {
1368       /* Ensure SYMBOL_REF will stay around.  */
1369       p = *last_p = (struct symref_hashent *)
1370 			xmalloc (sizeof (struct symref_hashent));
1371       p->symref = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
1372       p->next = 0;
1373     }
1374 
1375   return p->symref;
1376 }
1377 
1378 /* Validate the precision of a floating-point operation.
1379 
1380    We merge conversions from integers and between floating-point modes into
1381    the insn.  However, this must not effect the desired precision of the
1382    insn.  The RT floating-point system uses the widest of the operand modes.
1383    If this should be a double-precision insn, ensure that one operand
1384    passed to the floating-point processor has double mode.
1385 
1386    Note that since we don't check anything if the mode is single precision,
1387    it, strictly speaking, isn't necessary to call this for those insns.
1388    However, we do so in case something else needs to be checked in the
1389    future.
1390 
1391    This routine returns 1 if the operation is OK.  */
1392 
1393 int
check_precision(opmode,op1,op2)1394 check_precision (opmode, op1, op2)
1395      enum machine_mode opmode;
1396      rtx op1, op2;
1397 {
1398   if (opmode == SFmode)
1399     return 1;
1400 
1401   /* If operand is not a conversion from an integer mode or an extension from
1402      single-precision, it must be a double-precision value.  */
1403   if (GET_CODE (op1) != FLOAT && GET_CODE (op1) != FLOAT_EXTEND)
1404     return 1;
1405 
1406   if (op2 && GET_CODE (op2) != FLOAT && GET_CODE (op2) != FLOAT_EXTEND)
1407     return 1;
1408 
1409   return 0;
1410 }
1411 
1412 /* Floating-point on the RT is done by creating an operation block in the data
1413    area that describes the operation.  If two floating-point operations are the
1414    same in a single function, they can use the same block.
1415 
1416    These routines are responsible for managing these blocks.  */
1417 
1418 /* Structure to describe a floating-point operation.  */
1419 
1420 struct fp_op {
1421   struct fp_op *next_same_hash;		/* Next op with same hash code.  */
1422   struct fp_op *next_in_mem;		/* Next op in memory.  */
1423   int mem_offset;			/* Offset from data area.  */
1424   short size;				/* Size of block in bytes.  */
1425   short noperands;			/* Number of operands in block.  */
1426   rtx ops[3];				/* RTL for operands.  */
1427   enum rtx_code opcode;			/* Operation being performed.  */
1428 };
1429 
1430 /* Size of hash table.  */
1431 #define FP_HASH_SIZE 101
1432 
1433 /* Hash table of floating-point operation blocks.  */
1434 static struct fp_op *fp_hash_table[FP_HASH_SIZE];
1435 
1436 /* First floating-point block in data area.  */
1437 static struct fp_op *first_fpop;
1438 
1439 /* Last block in data area so far.  */
1440 static struct fp_op *last_fpop_in_mem;
1441 
1442 /* Subroutine number in file, to get unique "LF" labels.  */
1443 static int subr_number = 0;
1444 
1445 /* Current word offset in data area (includes header and any constant pool).  */
1446 int data_offset;
1447 
1448 /* Compute hash code for an RTX used in floating-point.  */
1449 
1450 static unsigned int
hash_rtx(x)1451 hash_rtx (x)
1452      register rtx x;
1453 {
1454   register unsigned int hash = (((int) GET_CODE (x) << 10)
1455 				+ ((int) GET_MODE (x) << 20));
1456   register int i;
1457   register const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1458 
1459   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1460     if (fmt[i] == 'e')
1461       hash += hash_rtx (XEXP (x, i));
1462     else if (fmt[i] == 'u')
1463       hash += (unsigned HOST_WIDE_INT) XEXP (x, i);
1464     else if (fmt[i] == 'i')
1465       hash += XINT (x, i);
1466     else if (fmt[i] == 's')
1467       hash += (unsigned HOST_WIDE_INT) XSTR (x, i);
1468 
1469   return hash;
1470 }
1471 
1472 /* Given an operation code and up to three operands, return a character string
1473    corresponding to the code to emit to branch to a floating-point operation
1474    block.  INSN is provided to see if the delay slot has been filled or not.
1475 
1476    A new floating-point operation block is created if this operation has not
1477    been seen before.  */
1478 
1479 const char *
output_fpop(code,op0,op1,op2,insn)1480 output_fpop (code, op0, op1, op2, insn)
1481      enum rtx_code code;
1482      rtx op0, op1, op2;
1483      rtx insn ATTRIBUTE_UNUSED;
1484 {
1485   static char outbuf[40];
1486   unsigned int hash, hash0, hash1, hash2;
1487   int size, i;
1488   register struct fp_op *fpop, *last_fpop;
1489   int dyadic = (op2 != 0);
1490   enum machine_mode opmode;
1491   int noperands;
1492   rtx tem;
1493   unsigned int tem_hash;
1494   int fr0_avail = 0;
1495 
1496   /* Compute hash code for each operand.  If the operation is commutative,
1497      put the one with the smaller hash code first.  This will make us see
1498      more operations as identical.  */
1499   hash0 = op0 ? hash_rtx (op0) : 0;
1500   hash1 = op1 ? hash_rtx (op1) : 0;
1501   hash2 = op2 ? hash_rtx (op2) : 0;
1502 
1503   if (hash0 > hash1 && code == EQ)
1504     {
1505       tem = op0; op0 = op1; op1 = tem;
1506       tem_hash = hash0; hash0 = hash1; hash1 = tem_hash;
1507     }
1508   else if (hash1 > hash2 && (code == PLUS || code == MULT))
1509     {
1510       tem = op1; op1 = op2; op2 = tem;
1511       tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1512     }
1513 
1514   /* If operation is commutative and the first and third operands are equal,
1515      swap the second and third operands.  Note that we must consider two
1516      operands equal if they are the same register even if different modes.  */
1517   if (op2 && (code == PLUS || code == MULT)
1518       && (rtx_equal_p (op0, op2)
1519 	  || (GET_CODE (op0) == REG && GET_CODE (op2) == REG
1520 	      && REGNO (op0) == REGNO (op2))))
1521     {
1522       tem = op1; op1 = op2; op2 = tem;
1523       tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1524     }
1525 
1526   /* If the first and second operands are the same, merge them.  Don't do this
1527      for SFmode or SImode in general registers because this triggers a bug in
1528      the RT fp code.  */
1529   if (op1 && rtx_equal_p (op0, op1)
1530       && code != EQ && code != GE && code != SET
1531       && ((GET_MODE (op1) != SFmode && GET_MODE (op1) != SImode)
1532 	  || GET_CODE (op0) != REG || FP_REGNO_P (REGNO (op0))))
1533     {
1534       op1 = op2;
1535       op2 = 0;
1536     }
1537 
1538   noperands = 1 + (op1 != 0) + (op2 != 0);
1539 
1540   /* Compute hash code for entire expression and see if operation block
1541      already exists.  */
1542   hash = ((int) code << 13) + (hash0 << 2) + (hash1 << 1) + hash2;
1543 
1544   hash %= FP_HASH_SIZE;
1545   for (fpop = fp_hash_table[hash], last_fpop = 0;
1546        fpop;
1547        last_fpop = fpop, fpop = fpop->next_same_hash)
1548     if (fpop->opcode == code && noperands == fpop->noperands
1549 	&& (op0 == 0 || rtx_equal_p (op0, fpop->ops[0]))
1550 	&& (op1 == 0 || rtx_equal_p (op1, fpop->ops[1]))
1551 	&& (op2 == 0 || rtx_equal_p (op2, fpop->ops[2])))
1552       goto win;
1553 
1554   /* We have never seen this operation before.  */
1555   fpop = (struct fp_op *) xmalloc (sizeof (struct fp_op));
1556   fpop->mem_offset = data_offset;
1557   fpop->opcode = code;
1558   fpop->noperands = noperands;
1559   fpop->ops[0] = op0;
1560   fpop->ops[1] = op1;
1561   fpop->ops[2] = op2;
1562 
1563   /* Compute the size using the rules in Appendix A of the RT Linkage
1564      Convention (4.3/RT-PSD:5) manual.  These rules are a bit ambiguous,
1565      but if we guess wrong, it will effect only efficiency, not correctness.  */
1566 
1567   /* Size = 24 + 32 for each non-fp (or fr7) */
1568   size = 24;
1569   if (op0 && (GET_CODE (op0) != REG
1570 	      || ! FP_REGNO_P (REGNO (op0)) || REGNO (op0) == 23))
1571     size += 32;
1572 
1573   if (op1 && (GET_CODE (op1) != REG
1574 	      || ! FP_REGNO_P (REGNO (op1)) || REGNO (op1) == 23))
1575     size += 32;
1576 
1577   if (op2 && (GET_CODE (op2) != REG
1578 	      || ! FP_REGNO_P (REGNO (op2)) || REGNO (op2) == 23))
1579     size += 32;
1580 
1581   /* Size + 12 for each conversion.  First get operation mode.  */
1582   if ((op0 && GET_MODE (op0) == DFmode)
1583       || (op1 && GET_MODE (op1) == DFmode)
1584       || (op2 && GET_MODE (op2) == DFmode))
1585     opmode = DFmode;
1586   else
1587     opmode = SFmode;
1588 
1589   if (op0 && GET_MODE (op0) != opmode)
1590     size += 12;
1591   if (op1 && GET_MODE (op1) != opmode)
1592     size += 12;
1593   if (op2 && GET_MODE (op2) != opmode)
1594     size += 12;
1595 
1596   /* 12 more if first and third operand types not the same.  */
1597   if (op2 && GET_MODE (op0) != GET_MODE (op2))
1598     size += 12;
1599 
1600   /* CMP and CMPT need additional.  Also, compute size of save/restore here.  */
1601   if (code == EQ)
1602     size += 32;
1603   else if (code == GE)
1604     size += 64;
1605   else if (code == USE || code == CLOBBER)
1606     {
1607       /* 34 + 24 for each additional register plus 8 if fr7 saved.  (We
1608          call it 36 because we need to keep the block length a multiple
1609 	 of four.  */
1610       size = 36 - 24;
1611       for (i = 0; i <= 7; i++)
1612 	if (INTVAL (op0) & (1 << (7-i)))
1613 	  size += 24 + 8 * (i == 7);
1614     }
1615 
1616   /* We provide no general-purpose scratch registers.  */
1617   size +=16;
1618 
1619   /* No floating-point scratch registers are provided.  Compute extra
1620      length due to this.  This logic is that shown in the referenced
1621      appendix.  */
1622 
1623   i = 0;
1624   if (op0 && GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1625     i++;
1626   if (op1 && GET_CODE (op1) == REG && FP_REGNO_P (REGNO (op1)))
1627     i++;
1628   if (op2 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1629     i++;
1630 
1631   if ((op0 == 0 || GET_CODE (op0) != REG || REGNO(op0) != 17)
1632       && (op1 == 0 || GET_CODE (op1) != REG || REGNO(op1) != 17)
1633       && (op2 == 0 || GET_CODE (op2) != REG || REGNO(op2) != 17))
1634     fr0_avail = 1;
1635 
1636   if (dyadic)
1637     {
1638       if (i == 0)
1639 	size += fr0_avail ? 64 : 112;
1640       else if (fpop->noperands == 2 && i == 1)
1641 	size += fr0_avail ? 0 : 64;
1642       else if (fpop->noperands == 3)
1643 	{
1644 	  if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0))
1645 	      && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1646 	    {
1647 	      if (REGNO (op0) == REGNO (op2))
1648 #if 1
1649 		/* This triggers a bug on the RT.  */
1650 		abort ();
1651 #else
1652 		size += fr0_avail ? 0 : 64;
1653 #endif
1654 	    }
1655 	  else
1656 	    {
1657 	      i = 0;
1658 	      if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1659 		i++;
1660 	      if (GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1661 		i++;
1662 	      if (i == 0)
1663 		size += fr0_avail ? 64 : 112;
1664 	      else if (i == 1)
1665 		size += fr0_avail ? 0 : 64;
1666 	    }
1667 	}
1668     }
1669   else if (code != USE && code != CLOBBER
1670 	   && (GET_CODE (op0) != REG || ! FP_REGNO_P (REGNO (op0))))
1671     size += 64;
1672 
1673   if (! TARGET_FULL_FP_BLOCKS)
1674     {
1675       /* If we are not to pad the blocks, just compute its actual length.  */
1676       size = 12;	/* Header + opcode */
1677       if (code == USE || code == CLOBBER)
1678         size += 2;
1679       else
1680         {
1681 	  if (op0) size += 2;
1682 	  if (op1) size += 2;
1683 	  if (op2) size += 2;
1684 	}
1685 
1686       /* If in the middle of a word, round.  */
1687       if (size % UNITS_PER_WORD)
1688 	size += 2;
1689 
1690       /* Handle any immediates.  */
1691       if (code != USE && code != CLOBBER && op0 && GET_CODE (op0) != REG)
1692         size += 4;
1693       if (op1 && GET_CODE (op1) != REG)
1694         size += 4;
1695       if (op2 && GET_CODE (op2) != REG)
1696         size += 4;
1697 
1698       if (code != USE && code != CLOBBER &&
1699 	  op0 && GET_CODE (op0) == CONST_DOUBLE && GET_MODE (op0) == DFmode)
1700         size += 4;
1701       if (op1 && GET_CODE (op1) == CONST_DOUBLE && GET_MODE (op1) == DFmode)
1702         size += 4;
1703       if (op2 && GET_CODE (op2) == CONST_DOUBLE && GET_MODE (op2) == DFmode)
1704         size += 4;
1705     }
1706 
1707   /* Done with size computation!  Chain this in.  */
1708   fpop->size = size;
1709   data_offset += size / UNITS_PER_WORD;
1710   fpop->next_in_mem = 0;
1711   fpop->next_same_hash = 0;
1712 
1713   if (last_fpop_in_mem)
1714     last_fpop_in_mem->next_in_mem = fpop;
1715   else
1716     first_fpop = fpop;
1717   last_fpop_in_mem = fpop;
1718 
1719   if (last_fpop)
1720     last_fpop->next_same_hash = fpop;
1721   else
1722     fp_hash_table[hash] = fpop;
1723 
1724 win:
1725   /* FPOP describes the operation to be performed.  Return a string to branch
1726      to it.  */
1727   if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1728     sprintf (outbuf, "cal r15,%d(r14)\n\tbalr%s r15,r15",
1729 	     fpop->mem_offset * UNITS_PER_WORD,
1730 	     dbr_sequence_length () ? "x" : "");
1731   else
1732     sprintf (outbuf, "get r15,$L%dF%d\n\tbalr%s r15,r15",
1733 	     subr_number, fpop->mem_offset * UNITS_PER_WORD,
1734 	     dbr_sequence_length () ? "x" : "");
1735   return outbuf;
1736 }
1737 
1738 /* If necessary, output a floating-point operation to save or restore all
1739    floating-point registers.
1740 
1741    file is the file to write the operation to, CODE is USE for save, CLOBBER
1742    for restore, and ADDR is the address of the same area, as RTL.  */
1743 
1744 static void
output_loadsave_fpregs(file,code,addr)1745 output_loadsave_fpregs (file, code, addr)
1746      FILE *file;
1747      enum rtx_code code;
1748      rtx addr;
1749 {
1750   register int i;
1751   register int mask = 0;
1752 
1753   for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1754     if (regs_ever_live[i + 17])
1755       mask |= 1 << (7 - i);
1756 
1757   if (mask)
1758     fprintf (file, "\t%s\n",
1759 	     output_fpop (code, GEN_INT (mask), gen_rtx_MEM (Pmode, addr),
1760 				0, const0_rtx));
1761 
1762 }
1763 
1764 /* Output any floating-point operations at the end of the routine.  */
1765 
1766 static void
output_fpops(file)1767 output_fpops (file)
1768      FILE *file;
1769 {
1770   register struct fp_op *fpop;
1771   register int size_so_far;
1772   register int i;
1773   rtx immed[3];
1774 
1775   if (first_fpop == 0)
1776     return;
1777 
1778   data_section ();
1779 
1780   ASM_OUTPUT_ALIGN (file, 2);
1781 
1782   for (fpop = first_fpop; fpop; fpop = fpop->next_in_mem)
1783     {
1784       if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1785 	fprintf (file, "# data area offset = %d\n",
1786 		 fpop->mem_offset * UNITS_PER_WORD);
1787       else
1788 	fprintf (file, "L%dF%d:\n",
1789 		 subr_number, fpop->mem_offset * UNITS_PER_WORD);
1790 
1791       fprintf (file, "\tcas r0,r15,r0\n");
1792       fprintf (file, "\t.long FPGLUE\n");
1793       switch (fpop->opcode)
1794 	{
1795 	case USE:
1796 	  fprintf (file, "\t.byte 0x1d\t# STOREM\n");
1797 	  break;
1798 	case CLOBBER:
1799 	  fprintf (file, "\t.byte 0x0f\t# LOADM\n");
1800 	  break;
1801 	case ABS:
1802 	  fprintf (file, "\t.byte 0x00\t# ABS\n");
1803 	  break;
1804 	case PLUS:
1805 	  fprintf (file, "\t.byte 0x02\t# ADD\n");
1806 	  break;
1807 	case EQ:
1808 	  fprintf (file, "\t.byte 0x07\t# CMP\n");
1809 	  break;
1810 	case GE:
1811 	  fprintf (file, "\t.byte 0x08\t# CMPT\n");
1812 	  break;
1813 	case DIV:
1814 	  fprintf (file, "\t.byte 0x0c\t# DIV\n");
1815 	  break;
1816 	case SET:
1817 	  fprintf (file, "\t.byte 0x14\t# MOVE\n");
1818 	  break;
1819 	case MULT:
1820 	  fprintf (file, "\t.byte 0x15\t# MUL\n");
1821 	  break;
1822 	case NEG:
1823 	  fprintf (file, "\t.byte 0x16\t# NEG\n");
1824 	  break;
1825 	case SQRT:
1826 	  fprintf (file, "\t.byte 0x1c\t# SQRT\n");
1827 	  break;
1828 	case MINUS:
1829 	  fprintf (file, "\t.byte 0x1e\t# SUB\n");
1830 	  break;
1831 	default:
1832 	  abort ();
1833 	}
1834 
1835       fprintf (file, "\t.byte %d\n", fpop->noperands);
1836       fprintf (file, "\t.short 0x8001\n");
1837 
1838       if ((fpop->ops[0] == 0
1839 	   || GET_CODE (fpop->ops[0]) != REG || REGNO(fpop->ops[0]) != 17)
1840 	  && (fpop->ops[1] == 0 || GET_CODE (fpop->ops[1]) != REG
1841 	      || REGNO(fpop->ops[1]) != 17)
1842 	  && (fpop->ops[2] == 0 || GET_CODE (fpop->ops[2]) != REG
1843 	      || REGNO(fpop->ops[2]) != 17))
1844 	fprintf (file, "\t.byte %d, 0x80\n", fpop->size);
1845       else
1846 	fprintf (file, "\t.byte %d, 0\n", fpop->size);
1847       size_so_far = 12;
1848       for (i = 0; i < fpop->noperands; i++)
1849 	{
1850 	  register int type;
1851 	  register int opbyte;
1852 	  register const char *desc0;
1853 	  char desc1[50];
1854 
1855 	  immed[i] = 0;
1856 	  switch (GET_MODE (fpop->ops[i]))
1857 	    {
1858 	    case SImode:
1859 	    case VOIDmode:
1860 	      desc0 = "int";
1861 	      type = 0;
1862 	      break;
1863 	    case SFmode:
1864 	      desc0 = "float";
1865 	      type = 2;
1866 	      break;
1867 	    case DFmode:
1868 	      desc0 = "double";
1869 	      type = 3;
1870 	      break;
1871 	    default:
1872 	      abort ();
1873 	    }
1874 
1875 	  switch (GET_CODE (fpop->ops[i]))
1876 	    {
1877 	    case REG:
1878 	      strcpy(desc1, reg_names[REGNO (fpop->ops[i])]);
1879 	      if (FP_REGNO_P (REGNO (fpop->ops[i])))
1880 		{
1881 		  type += 0x10;
1882 		  opbyte = REGNO (fpop->ops[i]) - 17;
1883 		}
1884 	      else
1885 		{
1886 		  type += 0x00;
1887 		  opbyte = REGNO (fpop->ops[i]);
1888 		  if (type == 3)
1889 		    opbyte = (opbyte << 4) + opbyte + 1;
1890 		}
1891 	      break;
1892 
1893 	    case MEM:
1894 	      type += 0x30;
1895 	      if (GET_CODE (XEXP (fpop->ops[i], 0)) == PLUS)
1896 		{
1897 		  immed[i] = XEXP (XEXP (fpop->ops[i], 0), 1);
1898 		  opbyte = REGNO (XEXP (XEXP (fpop->ops[i], 0), 0));
1899 		  if (GET_CODE (immed[i]) == CONST_INT)
1900 		    sprintf (desc1, "%d(%s)", INTVAL (immed[i]),
1901 			     reg_names[opbyte]);
1902 		  else
1903 		    sprintf (desc1, "<memory> (%s)", reg_names[opbyte]);
1904 		}
1905 	      else if (GET_CODE (XEXP (fpop->ops[i], 0)) == REG)
1906 		{
1907 		  opbyte = REGNO (XEXP (fpop->ops[i], 0));
1908 		  immed[i] = const0_rtx;
1909  		  sprintf (desc1, "(%s)", reg_names[opbyte]);
1910 		}
1911 	      else
1912 		{
1913 		  immed[i] = XEXP (fpop->ops[i], 0);
1914 		  opbyte = 0;
1915 		  sprintf(desc1, "<memory>");
1916 		}
1917 	      break;
1918 
1919 	    case CONST_INT:
1920 	    case CONST_DOUBLE:
1921 	    case CONST:
1922 	    case SYMBOL_REF:
1923 	    case LABEL_REF:
1924 	      type += 0x20;
1925 	      opbyte = 0;
1926 	      immed[i] = fpop->ops[i];
1927 	      desc1[0] = '$';
1928 	      desc1[1] = '\0';
1929 	      break;
1930 
1931 	    default:
1932 	      abort ();
1933 	    }
1934 
1935 	  /* Save/restore is special.  */
1936 	  if (i == 0 && (fpop->opcode == USE || fpop->opcode == CLOBBER))
1937 	    type = 0xff, opbyte = INTVAL (fpop->ops[0]), immed[i] = 0;
1938 
1939 	  fprintf (file, "\t.byte 0x%x,0x%x # (%s) %s\n",
1940 		   type, opbyte, desc0, desc1);
1941 
1942 	  size_so_far += 2;
1943 	}
1944 
1945       /* If in the middle of a word, round.  */
1946       if (size_so_far % UNITS_PER_WORD)
1947 	{
1948 	  fprintf (file, "\t.space 2\n");
1949 	  size_so_far += 2;
1950 	}
1951 
1952       for (i = 0; i < fpop->noperands; i++)
1953 	if (immed[i])
1954 	  switch (GET_MODE (immed[i]))
1955 	    {
1956 	    case SImode:
1957 	    case VOIDmode:
1958 	      size_so_far += 4;
1959 	      fprintf (file, "\t.long ");
1960 	      output_addr_const (file, immed[i]);
1961 	      fprintf (file, "\n");
1962 	      break;
1963 
1964 	    case DFmode:
1965 	      size_so_far += 4;
1966 	    case SFmode:
1967 	      size_so_far += 4;
1968 	      if (GET_CODE (immed[i]) == CONST_DOUBLE)
1969 		{
1970 		  REAL_VALUE_TYPE r;
1971 		  REAL_VALUE_FROM_CONST_DOUBLE (r, immed[i]);
1972 		  assemble_real (r, GET_MODE (immed[i]),
1973 				 GET_MODE_ALIGNMENT (GET_MODE (immed[i])));
1974 		}
1975 	      else
1976 		abort ();
1977 	      break;
1978 
1979 	    default:
1980 	      abort ();
1981 	    }
1982 
1983       if (size_so_far != fpop->size)
1984         {
1985           if (TARGET_FULL_FP_BLOCKS)
1986 	    fprintf (file, "\t.space %d\n", fpop->size - size_so_far);
1987 	  else
1988 	    abort ();
1989 	}
1990     }
1991 
1992   /* Update for next subroutine.  */
1993   subr_number++;
1994   text_section ();
1995 }
1996 
1997  /* Initialize floating-point operation table.  */
1998 
1999 static void
init_fpops()2000 init_fpops()
2001 {
2002   register int i;
2003 
2004   first_fpop = last_fpop_in_mem = 0;
2005   for (i = 0; i < FP_HASH_SIZE; i++)
2006     fp_hash_table[i] = 0;
2007 }
2008 
2009 /* Return the offset value of an automatic variable (N_LSYM) having
2010    the given offset. Basically, we correct by going from a frame pointer to
2011    stack pointer value.
2012 */
2013 
2014 int
romp_debugger_auto_correction(offset)2015 romp_debugger_auto_correction(offset)
2016      int offset;
2017 {
2018   int fp_to_sp;
2019 
2020   /* We really want to go from STACK_POINTER_REGNUM to
2021      FRAME_POINTER_REGNUM, but this isn't defined. So go the other
2022      direction and negate.  */
2023   INITIAL_ELIMINATION_OFFSET (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM,
2024 			      fp_to_sp);
2025 
2026   /* The offset value points somewhere between the frame pointer and
2027      the stack pointer. What is up from the frame pointer is down from the
2028      stack pointer. Therefore the negation in the offset value too.  */
2029 
2030   return -(offset+fp_to_sp+4);
2031 }
2032 
2033 /* Return the offset value of an argument having
2034    the given offset. Basically, we correct by going from an arg pointer to
2035    stack pointer value.  */
2036 
2037 int
romp_debugger_arg_correction(offset)2038 romp_debugger_arg_correction (offset)
2039      int offset;
2040 {
2041   int fp_to_argp;
2042 
2043   INITIAL_ELIMINATION_OFFSET (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM,
2044 			      fp_to_argp);
2045 
2046   /* Actually, something different happens if offset is from a floating-point
2047      register argument, but we don't handle it here.  */
2048 
2049   return (offset - fp_to_argp);
2050 }
2051 
2052 void
romp_initialize_trampoline(tramp,fnaddr,cxt)2053 romp_initialize_trampoline (tramp, fnaddr, cxt)
2054      rtx tramp, fnaddr, cxt;
2055 {
2056   rtx addr, temp, val;
2057 
2058   temp = expand_simple_binop (SImode, PLUS, tramp, GEN_INT (4),
2059 			       0, 1, OPTAB_LIB_WIDEN);
2060   emit_move_insn (gen_rtx_MEM (SImode, memory_address (SImode, tramp)), temp);
2061 
2062   val = force_reg (SImode, cxt);
2063   addr = memory_address (HImode, plus_constant (tramp, 10));
2064   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, val));
2065   temp = expand_shift (RSHIFT_EXPR, SImode, val, build_int_2 (16, 0), 0, 1);
2066   addr = memory_address (HImode, plus_constant (tramp, 6));
2067   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, temp));
2068 
2069   val = force_reg (SImode, fnaddr);
2070   addr = memory_address (HImode, plus_constant (tramp, 24));
2071   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, val));
2072   temp = expand_shift (RSHIFT_EXPR, SImode, val, build_int_2 (16, 0), 0, 1);
2073   addr = memory_address (HImode, plus_constant (tramp, 20));
2074   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, temp));
2075 }
2076 
2077 /* On ROMP, all constants are in the data area.  */
2078 
2079 static void
romp_select_rtx_section(mode,x,align)2080 romp_select_rtx_section (mode, x, align)
2081      enum machine_mode mode ATTRIBUTE_UNUSED;
2082      rtx x ATTRIBUTE_UNUSED;
2083      unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
2084 {
2085   data section ();
2086 }
2087 
2088 /* For no good reason, we do the same as the other RT compilers and load
2089    the addresses of data areas for a function from our data area.  That means
2090    that we need to mark such SYMBOL_REFs.  We do so here.  */
2091 
2092 static void
romp_encode_section_info(decl,first)2093 romp_encode_section_info (decl, first)
2094      tree decl;
2095      int first ATTRIBUTE_UNUSED;
2096 {
2097   if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
2098     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
2099 }
2100