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