1 /* Subroutines for gcc2 for pdp11.
2 Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
6 This file is part of GCC.
8 GCC 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 3, or (at your option)
13 GCC 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.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
33 #include "insn-attr.h"
38 #include "diagnostic-core.h"
42 #include "target-def.h"
46 #define FPU_REG_P(X) ((X)>=8 && (X)<14)
47 #define CPU_REG_P(X) ((X)>=0 && (X)<8)
50 /* this is the current value returned by the macro FIRST_PARM_OFFSET
52 int current_first_parm_offset;
54 /* Routines to encode/decode pdp11 floats */
55 static void encode_pdp11_f (const struct real_format *fmt,
56 long *, const REAL_VALUE_TYPE *);
57 static void decode_pdp11_f (const struct real_format *,
58 REAL_VALUE_TYPE *, const long *);
59 static void encode_pdp11_d (const struct real_format *fmt,
60 long *, const REAL_VALUE_TYPE *);
61 static void decode_pdp11_d (const struct real_format *,
62 REAL_VALUE_TYPE *, const long *);
64 /* These two are taken from the corresponding vax descriptors
65 in real.c, changing only the encode/decode routine pointers. */
66 const struct real_format pdp11_f_format =
87 const struct real_format pdp11_d_format =
109 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
110 const REAL_VALUE_TYPE *r)
112 (*vax_f_format.encode) (fmt, buf, r);
113 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
117 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
118 REAL_VALUE_TYPE *r, const long *buf)
121 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
122 (*vax_f_format.decode) (fmt, r, &tbuf);
126 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
127 const REAL_VALUE_TYPE *r)
129 (*vax_d_format.encode) (fmt, buf, r);
130 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
131 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
135 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
136 REAL_VALUE_TYPE *r, const long *buf)
139 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
140 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
141 (*vax_d_format.decode) (fmt, r, tbuf);
144 /* This is where the condition code register lives. */
145 /* rtx cc0_reg_rtx; - no longer needed? */
147 static bool pdp11_handle_option (size_t, const char *, int);
148 static rtx find_addr_reg (rtx);
149 static const char *singlemove_string (rtx *);
150 static bool pdp11_assemble_integer (rtx, unsigned int, int);
151 static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT);
152 static void pdp11_output_function_epilogue (FILE *, HOST_WIDE_INT);
153 static bool pdp11_rtx_costs (rtx, int, int, int *, bool);
154 static bool pdp11_return_in_memory (const_tree, const_tree);
155 static rtx pdp11_function_value (const_tree, const_tree, bool);
156 static rtx pdp11_libcall_value (enum machine_mode, const_rtx);
157 static bool pdp11_function_value_regno_p (const unsigned int);
158 static void pdp11_trampoline_init (rtx, tree, rtx);
160 /* Initialize the GCC target structure. */
161 #undef TARGET_ASM_BYTE_OP
162 #define TARGET_ASM_BYTE_OP NULL
163 #undef TARGET_ASM_ALIGNED_HI_OP
164 #define TARGET_ASM_ALIGNED_HI_OP NULL
165 #undef TARGET_ASM_ALIGNED_SI_OP
166 #define TARGET_ASM_ALIGNED_SI_OP NULL
167 #undef TARGET_ASM_INTEGER
168 #define TARGET_ASM_INTEGER pdp11_assemble_integer
170 #undef TARGET_ASM_FUNCTION_PROLOGUE
171 #define TARGET_ASM_FUNCTION_PROLOGUE pdp11_output_function_prologue
172 #undef TARGET_ASM_FUNCTION_EPILOGUE
173 #define TARGET_ASM_FUNCTION_EPILOGUE pdp11_output_function_epilogue
175 #undef TARGET_ASM_OPEN_PAREN
176 #define TARGET_ASM_OPEN_PAREN "["
177 #undef TARGET_ASM_CLOSE_PAREN
178 #define TARGET_ASM_CLOSE_PAREN "]"
180 #undef TARGET_DEFAULT_TARGET_FLAGS
181 #define TARGET_DEFAULT_TARGET_FLAGS \
182 (MASK_FPU | MASK_45 | MASK_ABSHI_BUILTIN | TARGET_UNIX_ASM_DEFAULT)
183 #undef TARGET_HANDLE_OPTION
184 #define TARGET_HANDLE_OPTION pdp11_handle_option
186 #undef TARGET_RTX_COSTS
187 #define TARGET_RTX_COSTS pdp11_rtx_costs
189 #undef TARGET_RETURN_IN_MEMORY
190 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
192 #undef TARGET_FUNCTION_VALUE
193 #define TARGET_FUNCTION_VALUE pdp11_function_value
194 #undef TARGET_LIBCALL_VALUE
195 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
196 #undef TARGET_FUNCTION_VALUE_REGNO_P
197 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
199 #undef TARGET_TRAMPOLINE_INIT
200 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
202 struct gcc_target targetm = TARGET_INITIALIZER;
204 /* Implement TARGET_HANDLE_OPTION. */
207 pdp11_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED,
208 int value ATTRIBUTE_UNUSED)
213 target_flags &= ~(MASK_40 | MASK_45);
221 /* Nonzero if OP is a valid second operand for an arithmetic insn. */
224 arith_operand (rtx op, enum machine_mode mode)
226 return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
230 const_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
232 return (GET_CODE (op) == CONST_INT);
236 immediate15_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
238 return (GET_CODE (op) == CONST_INT && ((INTVAL (op) & 0x8000) == 0x0000));
242 expand_shift_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
244 return (GET_CODE (op) == CONST_INT
245 && abs (INTVAL(op)) > 1
246 && abs (INTVAL(op)) <= 4);
250 stream is a stdio stream to output the code to.
251 size is an int: how many units of temporary storage to allocate.
252 Refer to the array `regs_ever_live' to determine which registers
253 to save; `regs_ever_live[I]' is nonzero if register number I
254 is ever used in the function. This macro is responsible for
255 knowing which registers should not be saved even if used.
259 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
261 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
266 "\n\t; /* function prologue %s*/\n",
267 current_function_name ());
269 /* if we are outputting code for main,
270 the switch FPU to right mode if TARGET_FPU */
271 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
274 "\t;/* switch cpu to double float, single integer */\n");
275 fprintf(stream, "\tsetd\n");
276 fprintf(stream, "\tseti\n\n");
279 if (frame_pointer_needed)
281 fprintf(stream, "\tmov r5, -(sp)\n");
282 fprintf(stream, "\tmov sp, r5\n");
291 asm_fprintf (stream, "\tsub $%#wo, sp\n", fsize);
293 /* save CPU registers */
294 for (regno = 0; regno < 8; regno++)
295 if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
296 if (! ((regno == FRAME_POINTER_REGNUM)
297 && frame_pointer_needed))
298 fprintf (stream, "\tmov %s, -(sp)\n", reg_names[regno]);
299 /* fpu regs saving */
301 /* via_ac specifies the ac to use for saving ac4, ac5 */
304 for (regno = 8; regno < FIRST_PSEUDO_REGISTER ; regno++)
307 if (LOAD_FPU_REG_P(regno)
308 && df_regs_ever_live_p (regno)
309 && ! call_used_regs[regno])
311 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[regno]);
315 /* maybe make ac4, ac5 call used regs?? */
317 if (NO_LOAD_FPU_REG_P(regno)
318 && df_regs_ever_live_p (regno)
319 && ! call_used_regs[regno])
321 gcc_assert (via_ac != -1);
322 fprintf (stream, "\tldd %s, %s\n",
323 reg_names[regno], reg_names[via_ac]);
324 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[via_ac]);
328 fprintf (stream, "\t;/* end of prologue */\n\n");
332 The function epilogue should not depend on the current stack pointer!
333 It should use the frame pointer only. This is mandatory because
334 of alloca; we also take advantage of it to omit stack adjustments
337 /* maybe we can make leaf functions faster by switching to the
338 second register file - this way we don't have to save regs!
339 leaf functions are ~ 50% of all functions (dynamically!)
341 set/clear bit 11 (dec. 2048) of status word for switching register files -
342 but how can we do this? the pdp11/45 manual says bit may only
343 be set (p.24), but not cleared!
345 switching to kernel is probably more expensive, so we'll leave it
346 like this and not use the second set of registers...
348 maybe as option if you want to generate code for kernel mode? */
351 pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
353 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
358 fprintf (stream, "\n\t; /*function epilogue */\n");
360 if (frame_pointer_needed)
362 /* hope this is safe - m68k does it also .... */
363 df_set_regs_ever_live (FRAME_POINTER_REGNUM, false);
365 for (i =7, j = 0 ; i >= 0 ; i--)
366 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
369 /* remember # of pushed bytes for CPU regs */
372 /* change fp -> r5 due to the compile error on libgcc2.c */
373 for (i =7 ; i >= 0 ; i--)
374 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
375 fprintf(stream, "\tmov %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
376 (-fsize-2*j--)&0xffff, reg_names[i]);
379 via_ac = FIRST_PSEUDO_REGISTER -1;
381 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
382 if (df_regs_ever_live_p (i) && ! call_used_regs[i])
388 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
390 if (LOAD_FPU_REG_P(i)
391 && df_regs_ever_live_p (i)
392 && ! call_used_regs[i])
394 fprintf(stream, "\tldd %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
395 (-fsize-k)&0xffff, reg_names[i]);
399 if (NO_LOAD_FPU_REG_P(i)
400 && df_regs_ever_live_p (i)
401 && ! call_used_regs[i])
403 gcc_assert (LOAD_FPU_REG_P(via_ac));
405 fprintf(stream, "\tldd %#" HOST_WIDE_INT_PRINT "o(r5), %s\n",
406 (-fsize-k)&0xffff, reg_names[via_ac]);
407 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
412 fprintf(stream, "\tmov r5, sp\n");
413 fprintf (stream, "\tmov (sp)+, r5\n");
417 via_ac = FIRST_PSEUDO_REGISTER -1;
420 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
421 if (df_regs_ever_live_p (i) && call_used_regs[i])
424 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
426 if (LOAD_FPU_REG_P(i)
427 && df_regs_ever_live_p (i)
428 && ! call_used_regs[i])
429 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[i]);
431 if (NO_LOAD_FPU_REG_P(i)
432 && df_regs_ever_live_p (i)
433 && ! call_used_regs[i])
435 gcc_assert (LOAD_FPU_REG_P(via_ac));
437 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[via_ac]);
438 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
442 for (i=7; i >= 0; i--)
443 if (df_regs_ever_live_p (i) && !call_used_regs[i])
444 fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]);
447 fprintf((stream), "\tadd $%#" HOST_WIDE_INT_PRINT "o, sp\n",
451 fprintf (stream, "\trts pc\n");
452 fprintf (stream, "\t;/* end of epilogue*/\n\n\n");
455 /* Return the best assembler insn template
456 for moving operands[1] into operands[0] as a fullword. */
458 singlemove_string (rtx *operands)
460 if (operands[1] != const0_rtx)
467 /* Output assembler code to perform a doubleword move insn
468 with operands OPERANDS. */
471 output_move_double (rtx *operands)
473 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
475 rtx addreg0 = 0, addreg1 = 0;
477 /* First classify both operands. */
479 if (REG_P (operands[0]))
481 else if (offsettable_memref_p (operands[0]))
483 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
485 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
487 else if (GET_CODE (operands[0]) == MEM)
492 if (REG_P (operands[1]))
494 else if (CONSTANT_P (operands[1])
496 || GET_CODE (operands[1]) == CONST_DOUBLE
500 else if (offsettable_memref_p (operands[1]))
502 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
504 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
506 else if (GET_CODE (operands[1]) == MEM)
511 /* Check for the cases that the operand constraints are not
512 supposed to allow to happen. Abort if we get one,
513 because generating code for these cases is painful. */
515 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
517 /* If one operand is decrementing and one is incrementing
518 decrement the former register explicitly
519 and change that operand into ordinary indexing. */
521 if (optype0 == PUSHOP && optype1 == POPOP)
523 operands[0] = XEXP (XEXP (operands[0], 0), 0);
524 output_asm_insn ("sub $4,%0", operands);
525 operands[0] = gen_rtx_MEM (SImode, operands[0]);
528 if (optype0 == POPOP && optype1 == PUSHOP)
530 operands[1] = XEXP (XEXP (operands[1], 0), 0);
531 output_asm_insn ("sub $4,%1", operands);
532 operands[1] = gen_rtx_MEM (SImode, operands[1]);
536 /* If an operand is an unoffsettable memory ref, find a register
537 we can increment temporarily to make it refer to the second word. */
539 if (optype0 == MEMOP)
540 addreg0 = find_addr_reg (XEXP (operands[0], 0));
542 if (optype1 == MEMOP)
543 addreg1 = find_addr_reg (XEXP (operands[1], 0));
545 /* Ok, we can do one word at a time.
546 Normally we do the low-numbered word first,
547 but if either operand is autodecrementing then we
548 do the high-numbered word first.
550 In either case, set up in LATEHALF the operands to use
551 for the high-numbered word and in some cases alter the
552 operands in OPERANDS to be suitable for the low-numbered word. */
554 if (optype0 == REGOP)
555 latehalf[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
556 else if (optype0 == OFFSOP)
557 latehalf[0] = adjust_address (operands[0], HImode, 2);
559 latehalf[0] = operands[0];
561 if (optype1 == REGOP)
562 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
563 else if (optype1 == OFFSOP)
564 latehalf[1] = adjust_address (operands[1], HImode, 2);
565 else if (optype1 == CNSTOP)
567 if (CONSTANT_P (operands[1]))
569 /* now the mess begins, high word is in lower word???
571 that's what ashc makes me think, but I don't remember :-( */
572 latehalf[1] = GEN_INT (INTVAL(operands[1]) >> 16);
573 operands[1] = GEN_INT (INTVAL(operands[1]) & 0xff);
576 /* immediate 32-bit values not allowed */
577 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE);
580 latehalf[1] = operands[1];
582 /* If insn is effectively movd N(sp),-(sp) then we will do the
583 high word first. We should use the adjusted operand 1 (which is N+4(sp))
584 for the low word as well, to compensate for the first decrement of sp. */
585 if (optype0 == PUSHOP
586 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
587 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
588 operands[1] = latehalf[1];
590 /* If one or both operands autodecrementing,
591 do the two words, high-numbered first. */
593 /* Likewise, the first move would clobber the source of the second one,
594 do them in the other order. This happens only for registers;
595 such overlap can't happen in memory unless the user explicitly
596 sets it up, and that is an undefined circumstance. */
598 if (optype0 == PUSHOP || optype1 == PUSHOP
599 || (optype0 == REGOP && optype1 == REGOP
600 && REGNO (operands[0]) == REGNO (latehalf[1])))
602 /* Make any unoffsettable addresses point at high-numbered word. */
604 output_asm_insn ("add $2,%0", &addreg0);
606 output_asm_insn ("add $2,%0", &addreg1);
609 output_asm_insn (singlemove_string (latehalf), latehalf);
611 /* Undo the adds we just did. */
613 output_asm_insn ("sub $2,%0", &addreg0);
615 output_asm_insn ("sub $2,%0", &addreg1);
617 /* Do low-numbered word. */
618 return singlemove_string (operands);
621 /* Normal case: do the two words, low-numbered first. */
623 output_asm_insn (singlemove_string (operands), operands);
625 /* Make any unoffsettable addresses point at high-numbered word. */
627 output_asm_insn ("add $2,%0", &addreg0);
629 output_asm_insn ("add $2,%0", &addreg1);
632 output_asm_insn (singlemove_string (latehalf), latehalf);
634 /* Undo the adds we just did. */
636 output_asm_insn ("sub $2,%0", &addreg0);
638 output_asm_insn ("sub $2,%0", &addreg1);
642 /* Output assembler code to perform a quadword move insn
643 with operands OPERANDS. */
646 output_move_quad (rtx *operands)
648 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
650 rtx addreg0 = 0, addreg1 = 0;
652 output_asm_insn(";/* movdi/df: %1 -> %0 */", operands);
654 if (REG_P (operands[0]))
656 else if (offsettable_memref_p (operands[0]))
658 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
660 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
662 else if (GET_CODE (operands[0]) == MEM)
667 if (REG_P (operands[1]))
669 else if (CONSTANT_P (operands[1])
670 || GET_CODE (operands[1]) == CONST_DOUBLE)
672 else if (offsettable_memref_p (operands[1]))
674 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
676 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
678 else if (GET_CODE (operands[1]) == MEM)
683 /* Check for the cases that the operand constraints are not
684 supposed to allow to happen. Abort if we get one,
685 because generating code for these cases is painful. */
687 gcc_assert (optype0 != RNDOP && optype1 != RNDOP);
689 /* check if we move a CPU reg to an FPU reg, or vice versa! */
690 if (optype0 == REGOP && optype1 == REGOP)
691 /* bogus - 64 bit cannot reside in CPU! */
692 gcc_assert (!CPU_REG_P(REGNO(operands[0]))
693 && !CPU_REG_P (REGNO(operands[1])));
695 if (optype0 == REGOP || optype1 == REGOP)
697 /* check for use of clrd????
698 if you ever allow ac4 and ac5 (now we require secondary load)
699 you must check whether
700 you want to load into them or store from them -
701 then dump ac0 into $help$ movce ac4/5 to ac0, do the
702 store from ac0, and restore ac0 - if you can find
703 an unused ac[0-3], use that and you save a store and a load!*/
705 if (FPU_REG_P(REGNO(operands[0])))
707 if (GET_CODE(operands[1]) == CONST_DOUBLE)
710 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
712 if (REAL_VALUES_EQUAL (r, dconst0))
713 return "{clrd|clrf} %0";
716 return "{ldd|movf} %1, %0";
719 if (FPU_REG_P(REGNO(operands[1])))
720 return "{std|movf} %1, %0";
723 /* If one operand is decrementing and one is incrementing
724 decrement the former register explicitly
725 and change that operand into ordinary indexing. */
727 if (optype0 == PUSHOP && optype1 == POPOP)
729 operands[0] = XEXP (XEXP (operands[0], 0), 0);
730 output_asm_insn ("sub $8,%0", operands);
731 operands[0] = gen_rtx_MEM (DImode, operands[0]);
734 if (optype0 == POPOP && optype1 == PUSHOP)
736 operands[1] = XEXP (XEXP (operands[1], 0), 0);
737 output_asm_insn ("sub $8,%1", operands);
738 operands[1] = gen_rtx_MEM (SImode, operands[1]);
742 /* If an operand is an unoffsettable memory ref, find a register
743 we can increment temporarily to make it refer to the second word. */
745 if (optype0 == MEMOP)
746 addreg0 = find_addr_reg (XEXP (operands[0], 0));
748 if (optype1 == MEMOP)
749 addreg1 = find_addr_reg (XEXP (operands[1], 0));
751 /* Ok, we can do one word at a time.
752 Normally we do the low-numbered word first,
753 but if either operand is autodecrementing then we
754 do the high-numbered word first.
756 In either case, set up in LATEHALF the operands to use
757 for the high-numbered word and in some cases alter the
758 operands in OPERANDS to be suitable for the low-numbered word. */
760 if (optype0 == REGOP)
761 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
762 else if (optype0 == OFFSOP)
763 latehalf[0] = adjust_address (operands[0], SImode, 4);
765 latehalf[0] = operands[0];
767 if (optype1 == REGOP)
768 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
769 else if (optype1 == OFFSOP)
770 latehalf[1] = adjust_address (operands[1], SImode, 4);
771 else if (optype1 == CNSTOP)
773 if (GET_CODE (operands[1]) == CONST_DOUBLE)
777 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
778 REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
779 latehalf[1] = GEN_INT (dval[1]);
780 operands[1] = GEN_INT (dval[0]);
782 else if (GET_CODE(operands[1]) == CONST_INT)
784 latehalf[1] = const0_rtx;
790 latehalf[1] = operands[1];
792 /* If insn is effectively movd N(sp),-(sp) then we will do the
793 high word first. We should use the adjusted operand 1 (which is N+4(sp))
794 for the low word as well, to compensate for the first decrement of sp. */
795 if (optype0 == PUSHOP
796 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
797 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
798 operands[1] = latehalf[1];
800 /* If one or both operands autodecrementing,
801 do the two words, high-numbered first. */
803 /* Likewise, the first move would clobber the source of the second one,
804 do them in the other order. This happens only for registers;
805 such overlap can't happen in memory unless the user explicitly
806 sets it up, and that is an undefined circumstance. */
808 if (optype0 == PUSHOP || optype1 == PUSHOP
809 || (optype0 == REGOP && optype1 == REGOP
810 && REGNO (operands[0]) == REGNO (latehalf[1])))
812 /* Make any unoffsettable addresses point at high-numbered word. */
814 output_asm_insn ("add $4,%0", &addreg0);
816 output_asm_insn ("add $4,%0", &addreg1);
819 output_asm_insn(output_move_double(latehalf), latehalf);
821 /* Undo the adds we just did. */
823 output_asm_insn ("sub $4,%0", &addreg0);
825 output_asm_insn ("sub $4,%0", &addreg1);
827 /* Do low-numbered word. */
828 return output_move_double (operands);
831 /* Normal case: do the two words, low-numbered first. */
833 output_asm_insn (output_move_double (operands), operands);
835 /* Make any unoffsettable addresses point at high-numbered word. */
837 output_asm_insn ("add $4,%0", &addreg0);
839 output_asm_insn ("add $4,%0", &addreg1);
842 output_asm_insn (output_move_double (latehalf), latehalf);
844 /* Undo the adds we just did. */
846 output_asm_insn ("sub $4,%0", &addreg0);
848 output_asm_insn ("sub $4,%0", &addreg1);
854 /* Return a REG that occurs in ADDR with coefficient 1.
855 ADDR can be effectively incremented by incrementing REG. */
858 find_addr_reg (rtx addr)
860 while (GET_CODE (addr) == PLUS)
862 if (GET_CODE (XEXP (addr, 0)) == REG)
863 addr = XEXP (addr, 0);
864 if (GET_CODE (XEXP (addr, 1)) == REG)
865 addr = XEXP (addr, 1);
866 if (CONSTANT_P (XEXP (addr, 0)))
867 addr = XEXP (addr, 1);
868 if (CONSTANT_P (XEXP (addr, 1)))
869 addr = XEXP (addr, 0);
871 if (GET_CODE (addr) == REG)
876 /* Output an ascii string. */
878 output_ascii (FILE *file, const char *p, int size)
882 /* This used to output .byte "string", which doesn't work with the UNIX
883 assembler and I think not with DEC ones either. */
884 fprintf (file, "\t.byte ");
886 for (i = 0; i < size; i++)
888 register int c = p[i];
891 fprintf (file, "%#o", c);
899 /* --- stole from out-vax, needs changes */
902 print_operand_address (FILE *file, register rtx addr)
904 register rtx reg1, reg2, breg, ireg;
909 switch (GET_CODE (addr))
916 addr = XEXP (addr, 0);
920 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
925 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
930 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
937 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
938 || GET_CODE (XEXP (addr, 0)) == MEM)
940 offset = XEXP (addr, 0);
941 addr = XEXP (addr, 1);
943 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
944 || GET_CODE (XEXP (addr, 1)) == MEM)
946 offset = XEXP (addr, 1);
947 addr = XEXP (addr, 0);
949 if (GET_CODE (addr) != PLUS)
951 else if (GET_CODE (XEXP (addr, 0)) == MULT)
953 reg1 = XEXP (addr, 0);
954 addr = XEXP (addr, 1);
956 else if (GET_CODE (XEXP (addr, 1)) == MULT)
958 reg1 = XEXP (addr, 1);
959 addr = XEXP (addr, 0);
961 else if (GET_CODE (XEXP (addr, 0)) == REG)
963 reg1 = XEXP (addr, 0);
964 addr = XEXP (addr, 1);
966 else if (GET_CODE (XEXP (addr, 1)) == REG)
968 reg1 = XEXP (addr, 1);
969 addr = XEXP (addr, 0);
971 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
981 gcc_assert (addr == 0);
984 if (reg1 != 0 && GET_CODE (reg1) == MULT)
989 else if (reg2 != 0 && GET_CODE (reg2) == MULT)
994 else if (reg2 != 0 || GET_CODE (addr) == MEM)
1005 output_address (addr);
1008 gcc_assert (GET_CODE (breg) == REG);
1009 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
1013 if (GET_CODE (ireg) == MULT)
1014 ireg = XEXP (ireg, 0);
1015 gcc_assert (GET_CODE (ireg) == REG);
1016 gcc_unreachable(); /* ??? */
1017 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
1022 output_addr_const_pdp11 (file, addr);
1026 /* Target hook to assemble integer objects. We need to use the
1027 pdp-specific version of output_addr_const. */
1030 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
1036 fprintf (asm_out_file, "\t.byte\t");
1037 output_addr_const_pdp11 (asm_out_file, x);
1038 fprintf (asm_out_file, " /* char */\n");
1042 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
1043 output_addr_const_pdp11 (asm_out_file, x);
1044 fprintf (asm_out_file, " /* short */\n");
1047 return default_assemble_integer (x, size, aligned_p);
1051 /* register move costs, indexed by regs */
1053 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
1055 /* NO MUL GEN LFPU NLFPU FPU ALL */
1057 /* NO */ { 0, 0, 0, 0, 0, 0, 0},
1058 /* MUL */ { 0, 2, 2, 10, 22, 22, 22},
1059 /* GEN */ { 0, 2, 2, 10, 22, 22, 22},
1060 /* LFPU */ { 0, 10, 10, 2, 2, 2, 10},
1061 /* NLFPU */ { 0, 22, 22, 2, 2, 2, 22},
1062 /* FPU */ { 0, 22, 22, 2, 2, 2, 22},
1063 /* ALL */ { 0, 22, 22, 10, 22, 22, 22}
1067 /* -- note that some moves are tremendously expensive,
1068 because they require lots of tricks! do we have to
1069 charge the costs incurred by secondary reload class
1070 -- as we do here with 22 -- or not ? */
1073 register_move_cost(enum reg_class c1, enum reg_class c2)
1075 return move_costs[(int)c1][(int)c2];
1079 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
1080 bool speed ATTRIBUTE_UNUSED)
1085 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
1095 /* Twice as expensive as REG. */
1100 /* Twice (or 4 times) as expensive as 16 bit. */
1105 /* ??? There is something wrong in MULT because MULT is not
1106 as cheap as total = 2 even if we can shift! */
1107 /* If optimizing for size make mult etc cheap, but not 1, so when
1108 in doubt the faster insn is chosen. */
1110 *total = COSTS_N_INSNS (2);
1112 *total = COSTS_N_INSNS (11);
1117 *total = COSTS_N_INSNS (2);
1119 *total = COSTS_N_INSNS (25);
1124 *total = COSTS_N_INSNS (2);
1126 *total = COSTS_N_INSNS (26);
1130 /* Equivalent to length, so same for optimize_size. */
1131 *total = COSTS_N_INSNS (3);
1135 /* Only used for qi->hi. */
1136 *total = COSTS_N_INSNS (1);
1140 if (GET_MODE (x) == HImode)
1141 *total = COSTS_N_INSNS (1);
1142 else if (GET_MODE (x) == SImode)
1143 *total = COSTS_N_INSNS (6);
1145 *total = COSTS_N_INSNS (2);
1152 *total = COSTS_N_INSNS (1);
1153 else if (GET_MODE (x) == QImode)
1155 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
1156 *total = COSTS_N_INSNS (8); /* worst case */
1158 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
1160 else if (GET_MODE (x) == HImode)
1162 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1164 if (abs (INTVAL (XEXP (x, 1))) == 1)
1165 *total = COSTS_N_INSNS (1);
1167 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1170 *total = COSTS_N_INSNS (10); /* worst case */
1172 else if (GET_MODE (x) == SImode)
1174 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1175 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
1176 else /* worst case */
1177 *total = COSTS_N_INSNS (18);
1187 output_jump (enum rtx_code code, int inv, int length)
1191 static char buf[1000];
1192 const char *pos, *neg;
1196 case EQ: pos = "beq", neg = "bne"; break;
1197 case NE: pos = "bne", neg = "beq"; break;
1198 case GT: pos = "bgt", neg = "ble"; break;
1199 case GTU: pos = "bhi", neg = "blos"; break;
1200 case LT: pos = "blt", neg = "bge"; break;
1201 case LTU: pos = "blo", neg = "bhis"; break;
1202 case GE: pos = "bge", neg = "blt"; break;
1203 case GEU: pos = "bhis", neg = "blo"; break;
1204 case LE: pos = "ble", neg = "bgt"; break;
1205 case LEU: pos = "blos", neg = "bhi"; break;
1206 default: gcc_unreachable ();
1210 /* currently we don't need this, because the tstdf and cmpdf
1211 copy the condition code immediately, and other float operations are not
1212 yet recognized as changing the FCC - if so, then the length-cost of all
1213 jump insns increases by one, because we have to potentially copy the
1215 if (cc_status.flags & CC_IN_FPU)
1216 output_asm_insn("cfcc", NULL);
1223 sprintf(buf, "%s %%l1", inv ? neg : pos);
1229 sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
1243 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
1245 if (GET_CODE (SET_DEST (exp)) == CC0)
1247 cc_status.flags = 0;
1248 cc_status.value1 = SET_DEST (exp);
1249 cc_status.value2 = SET_SRC (exp);
1252 if (GET_MODE(SET_SRC(exp)) == DFmode)
1253 cc_status.flags |= CC_IN_FPU;
1256 else if ((GET_CODE (SET_DEST (exp)) == REG
1257 || GET_CODE (SET_DEST (exp)) == MEM)
1258 && GET_CODE (SET_SRC (exp)) != PC
1259 && (GET_MODE (SET_DEST(exp)) == HImode
1260 || GET_MODE (SET_DEST(exp)) == QImode)
1261 && (GET_CODE (SET_SRC(exp)) == PLUS
1262 || GET_CODE (SET_SRC(exp)) == MINUS
1263 || GET_CODE (SET_SRC(exp)) == AND
1264 || GET_CODE (SET_SRC(exp)) == IOR
1265 || GET_CODE (SET_SRC(exp)) == XOR
1266 || GET_CODE (SET_SRC(exp)) == NOT
1267 || GET_CODE (SET_SRC(exp)) == NEG
1268 || GET_CODE (SET_SRC(exp)) == REG
1269 || GET_CODE (SET_SRC(exp)) == MEM))
1271 cc_status.flags = 0;
1272 cc_status.value1 = SET_SRC (exp);
1273 cc_status.value2 = SET_DEST (exp);
1275 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1277 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1278 cc_status.value2 = 0;
1279 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
1281 && GET_CODE (cc_status.value2) == MEM)
1282 cc_status.value2 = 0;
1284 else if (GET_CODE (SET_SRC (exp)) == CALL)
1288 else if (GET_CODE (SET_DEST (exp)) == REG)
1291 if ((cc_status.value1
1292 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)))
1293 cc_status.value1 = 0;
1294 if ((cc_status.value2
1295 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)))
1296 cc_status.value2 = 0;
1298 else if (SET_DEST(exp) == pc_rtx)
1302 else /* if (GET_CODE (SET_DEST (exp)) == MEM) */
1304 /* the last else is a bit paranoiac, but since nearly all instructions
1305 play with condition codes, it's reasonable! */
1307 CC_STATUS_INIT; /* paranoia*/
1313 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1317 /* Eliminate non-memory operations */
1318 if (GET_CODE (op) != MEM)
1322 /* dword operations really put out 2 instructions, so eliminate them. */
1323 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1327 /* Decode the address now. */
1331 addr = XEXP (op, 0);
1333 switch (GET_CODE (addr))
1336 /* (R0) - no extra cost */
1341 /* -(R0), (R0)+ - cheap! */
1345 /* cheap - is encoded in addressing mode info!
1347 -- except for @(R0), which has to be @0(R0) !!! */
1349 if (GET_CODE (XEXP (addr, 0)) == REG)
1359 /* @#address - extra cost */
1363 /* X(R0) - extra cost */
1375 * output a block move:
1377 * operands[0] ... to
1378 * operands[1] ... from
1379 * operands[2] ... length
1380 * operands[3] ... alignment
1381 * operands[4] ... scratch register
1386 output_block_move(rtx *operands)
1388 static int count = 0;
1391 if (GET_CODE(operands[2]) == CONST_INT
1394 if (INTVAL(operands[2]) < 16
1395 && INTVAL(operands[3]) == 1)
1399 for (i = 1; i <= INTVAL(operands[2]); i++)
1400 output_asm_insn("movb (%1)+, (%0)+", operands);
1404 else if (INTVAL(operands[2]) < 32)
1408 for (i = 1; i <= INTVAL(operands[2])/2; i++)
1409 output_asm_insn("mov (%1)+, (%0)+", operands);
1411 /* may I assume that moved quantity is
1412 multiple of alignment ???
1421 /* can do other clever things, maybe... */
1424 if (CONSTANT_P(operands[2]) )
1426 /* just move count to scratch */
1427 output_asm_insn("mov %2, %4", operands);
1431 /* just clobber the register */
1432 operands[4] = operands[2];
1436 /* switch over alignment */
1437 switch (INTVAL(operands[3]))
1453 sprintf(buf, "\nmovestrhi%d:", count);
1454 output_asm_insn(buf, NULL);
1456 output_asm_insn("movb (%1)+, (%0)+", operands);
1460 sprintf(buf, "sob %%4, movestrhi%d", count);
1461 output_asm_insn(buf, operands);
1465 output_asm_insn("dec %4", operands);
1467 sprintf(buf, "bgt movestrhi%d", count);
1468 output_asm_insn(buf, NULL);
1490 generate_compact_code:
1492 output_asm_insn("asr %4", operands);
1494 sprintf(buf, "\nmovestrhi%d:", count);
1495 output_asm_insn(buf, NULL);
1497 output_asm_insn("mov (%1)+, (%0)+", operands);
1501 sprintf(buf, "sob %%4, movestrhi%d", count);
1502 output_asm_insn(buf, operands);
1506 output_asm_insn("dec %4", operands);
1508 sprintf(buf, "bgt movestrhi%d", count);
1509 output_asm_insn(buf, NULL);
1535 goto generate_compact_code;
1537 output_asm_insn("asr %4", operands);
1538 output_asm_insn("asr %4", operands);
1540 sprintf(buf, "\nmovestrhi%d:", count);
1541 output_asm_insn(buf, NULL);
1543 output_asm_insn("mov (%1)+, (%0)+", operands);
1544 output_asm_insn("mov (%1)+, (%0)+", operands);
1548 sprintf(buf, "sob %%4, movestrhi%d", count);
1549 output_asm_insn(buf, operands);
1553 output_asm_insn("dec %4", operands);
1555 sprintf(buf, "bgt movestrhi%d", count);
1556 output_asm_insn(buf, NULL);
1586 goto generate_compact_code;
1588 output_asm_insn("asr %4", operands);
1589 output_asm_insn("asr %4", operands);
1590 output_asm_insn("asr %4", operands);
1592 sprintf(buf, "\nmovestrhi%d:", count);
1593 output_asm_insn(buf, NULL);
1595 output_asm_insn("mov (%1)+, (%0)+", operands);
1596 output_asm_insn("mov (%1)+, (%0)+", operands);
1597 output_asm_insn("mov (%1)+, (%0)+", operands);
1598 output_asm_insn("mov (%1)+, (%0)+", operands);
1602 sprintf(buf, "sob %%4, movestrhi%d", count);
1603 output_asm_insn(buf, operands);
1607 output_asm_insn("dec %4", operands);
1609 sprintf(buf, "bgt movestrhi%d", count);
1610 output_asm_insn(buf, NULL);
1623 /* This function checks whether a real value can be encoded as
1624 a literal, i.e., addressing mode 27. In that mode, real values
1625 are one word values, so the remaining 48 bits have to be zero. */
1627 legitimate_const_double_p (rtx address)
1631 REAL_VALUE_FROM_CONST_DOUBLE (r, address);
1632 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
1633 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1638 /* A copy of output_addr_const modified for pdp11 expression syntax.
1639 output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1640 use, and for debugging output, which we don't support with this port either.
1641 So this copy should get called whenever needed.
1644 output_addr_const_pdp11 (FILE *file, rtx x)
1649 switch (GET_CODE (x))
1652 gcc_assert (flag_pic);
1657 assemble_name (file, XSTR (x, 0));
1661 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1662 assemble_name (file, buf);
1666 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1667 assemble_name (file, buf);
1671 /* Should we check for constants which are too big? Maybe cutting
1672 them off to 16 bits is OK? */
1673 fprintf (file, "%#ho", (unsigned short) INTVAL (x));
1677 /* This used to output parentheses around the expression,
1678 but that does not work on the 386 (either ATT or BSD assembler). */
1679 output_addr_const_pdp11 (file, XEXP (x, 0));
1683 if (GET_MODE (x) == VOIDmode)
1685 /* We can use %o if the number is one word and positive. */
1686 gcc_assert (!CONST_DOUBLE_HIGH (x));
1687 fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
1690 /* We can't handle floating point constants;
1691 PRINT_OPERAND must handle them. */
1692 output_operand_lossage ("floating constant misused");
1696 /* Some assemblers need integer constants to appear last (e.g. masm). */
1697 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1699 output_addr_const_pdp11 (file, XEXP (x, 1));
1700 if (INTVAL (XEXP (x, 0)) >= 0)
1701 fprintf (file, "+");
1702 output_addr_const_pdp11 (file, XEXP (x, 0));
1706 output_addr_const_pdp11 (file, XEXP (x, 0));
1707 if (INTVAL (XEXP (x, 1)) >= 0)
1708 fprintf (file, "+");
1709 output_addr_const_pdp11 (file, XEXP (x, 1));
1714 /* Avoid outputting things like x-x or x+5-x,
1715 since some assemblers can't handle that. */
1716 x = simplify_subtraction (x);
1717 if (GET_CODE (x) != MINUS)
1720 output_addr_const_pdp11 (file, XEXP (x, 0));
1721 fprintf (file, "-");
1722 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1723 && INTVAL (XEXP (x, 1)) < 0)
1725 fprintf (file, targetm.asm_out.open_paren);
1726 output_addr_const_pdp11 (file, XEXP (x, 1));
1727 fprintf (file, targetm.asm_out.close_paren);
1730 output_addr_const_pdp11 (file, XEXP (x, 1));
1735 output_addr_const_pdp11 (file, XEXP (x, 0));
1739 output_operand_lossage ("invalid expression as operand");
1743 /* Worker function for TARGET_RETURN_IN_MEMORY. */
1746 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1748 /* Should probably return DImode and DFmode in memory, lest
1749 we fill up all regs!
1751 have to, else we crash - exception: maybe return result in
1752 ac0 if DFmode and FPU present - compatibility problem with
1753 libraries for non-floating point.... */
1754 return (TYPE_MODE (type) == DImode
1755 || (TYPE_MODE (type) == DFmode && ! TARGET_AC0));
1758 /* Worker function for TARGET_FUNCTION_VALUE.
1760 On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! ) */
1763 pdp11_function_value (const_tree valtype,
1764 const_tree fntype_or_decl ATTRIBUTE_UNUSED,
1765 bool outgoing ATTRIBUTE_UNUSED)
1767 return gen_rtx_REG (TYPE_MODE (valtype),
1768 BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
1771 /* Worker function for TARGET_LIBCALL_VALUE. */
1774 pdp11_libcall_value (enum machine_mode mode,
1775 const_rtx fun ATTRIBUTE_UNUSED)
1777 return gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
1780 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1782 On the pdp, the first "output" reg is the only register thus used.
1784 maybe ac0 ? - as option someday! */
1787 pdp11_function_value_regno_p (const unsigned int regno)
1789 return (regno == 0) || (TARGET_AC0 && (regno == 8));
1792 /* Worker function for TARGET_TRAMPOLINE_INIT.
1794 trampoline - how should i do it in separate i+d ?
1795 have some allocate_trampoline magic???
1797 the following should work for shared I/D:
1799 MV #STATIC, $4 0x940Y 0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1800 JMP FUNCTION 0x0058 0x0000 <- FUNCTION
1804 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1806 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
1809 gcc_assert (!TARGET_SPLIT);
1811 mem = adjust_address (m_tramp, HImode, 0);
1812 emit_move_insn (mem, GEN_INT (0x9400+STATIC_CHAIN_REGNUM));
1813 mem = adjust_address (m_tramp, HImode, 2);
1814 emit_move_insn (mem, chain_value);
1815 mem = adjust_address (m_tramp, HImode, 4);
1816 emit_move_insn (mem, GEN_INT (0x0058));
1817 emit_move_insn (mem, fnaddr);