1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3 Contributed by Steve Chamberlain (sac@cygnus.com),
4 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
32 #include "insn-attr.h"
38 /* Forward declarations. */
39 void print_operand_address ();
42 /* CPU_TYPE, says what cpu we're compiling for. */
45 /* True if a #pragma interrupt has been seen for the current function. */
48 /* True if a #pragma saveall has been seen for the current function. */
51 static char *names_big
[] =
52 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
54 static char *names_extended
[] =
55 {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
57 static char *names_upper_extended
[] =
58 {"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
60 /* Points to one of the above. */
61 /* ??? The above could be put in an array indexed by CPU_TYPE. */
64 /* Various operations needed by the following, indexed by CPU_TYPE. */
65 /* ??? The h8/300 assembler doesn't understand pop.w (yet). */
67 static char *h8_push_ops
[2] =
69 static char *h8_pop_ops
[2] =
71 static char *h8_mov_ops
[2] =
74 char *h8_push_op
, *h8_pop_op
, *h8_mov_op
;
76 /* Initialize various cpu specific globals at start up. */
83 cpu_type
= (int) CPU_H8300
;
84 h8_reg_names
= names_big
;
88 cpu_type
= (int) CPU_H8300H
;
89 h8_reg_names
= names_extended
;
91 h8_push_op
= h8_push_ops
[cpu_type
];
92 h8_pop_op
= h8_pop_ops
[cpu_type
];
93 h8_mov_op
= h8_mov_ops
[cpu_type
];
101 static char *names_small
[] =
102 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
103 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7lBAD", "r7hBAD"};
105 return names_small
[REGNO (x
) * 2 + b
];
108 /* REGNO must be saved/restored across calls if this macro is true. */
110 #define WORD_REG_USED(regno) \
114 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
115 || (regs_ever_live[regno] & !call_used_regs[regno])))
117 /* Output assembly language to FILE for the operation OP with operand size
118 SIZE to adjust the stack pointer. */
119 /* ??? FPED is currently unused. */
122 dosize (file
, op
, size
, fped
)
131 /* ??? TARGET_H8300H can do this in one insn. */
133 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 2);
135 /* Fall through... */
138 fprintf (file
, "\t%ss\t#%d,sp\n", op
, size
);
145 fprintf (file
, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size
, op
);
147 fprintf (file
, "\t%s\t#%d,sp\n", op
, size
);
153 /* Output assembly language code for the function prologue. */
154 static int push_order
[FIRST_PSEUDO_REGISTER
] =
155 {6, 5, 4, 3, 2, 1, 0, -1, -1};
156 static int pop_order
[FIRST_PSEUDO_REGISTER
] =
157 {0, 1, 2, 3, 4, 5, 6, -1, -1};
159 /* This is what the stack looks like after the prolog of
160 a function with a frame has been set up:
166 <saved registers> <- sp
168 This is what the stack looks like after the prolog of
169 a function which doesn't have a frame:
174 <saved registers> <- sp
177 int current_function_anonymous_args
;
179 /* Extra arguments to pop, in words (IE: 2 bytes for 300, 4 for 300h */
180 static int extra_pop
;
183 function_prologue (file
, size
)
187 register int mask
= 0;
188 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
192 if (current_function_anonymous_args
&& TARGET_QUICKCALL
)
194 /* Push regs as if done by caller, and move around return address. */
196 switch (current_function_args_info
.nbytes
/ UNITS_PER_WORD
)
200 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[3]);
201 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[2]);
202 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[1]);
203 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[0]);
205 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[3]);
210 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[3]);
211 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[2]);
212 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[1]);
214 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[3]);
219 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[3]);
220 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[2]);
222 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[3]);
226 fprintf (file
, "; varargs\n");
231 if (frame_pointer_needed
)
234 fprintf (file
, "\t%s\t%s\n", h8_push_op
,
235 h8_reg_names
[FRAME_POINTER_REGNUM
]);
236 fprintf (file
, "\t%s\t%s,%s\n", h8_mov_op
,
237 h8_reg_names
[STACK_POINTER_REGNUM
],
238 h8_reg_names
[FRAME_POINTER_REGNUM
]);
240 /* leave room for locals */
241 dosize (file
, "sub", fsize
, 1);
243 /* Push the rest of the registers */
244 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
246 int regno
= push_order
[idx
];
248 if (regno
>= 0 && WORD_REG_USED (regno
) && regno
!= FRAME_POINTER_REGNUM
)
249 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[regno
]);
254 dosize (file
, "sub", fsize
, 0);
255 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
257 int regno
= push_order
[idx
];
259 if (regno
>= 0 && WORD_REG_USED (regno
))
260 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[regno
]);
265 /* Output assembly language code for the function epilogue. */
268 function_epilogue (file
, size
)
273 register int mask
= 0;
274 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
278 rtx insn
= get_last_insn ();
280 /* If the last insn was a BARRIER, we don't have to write any code. */
281 if (GET_CODE (insn
) == NOTE
)
282 insn
= prev_nonnote_insn (insn
);
283 if (insn
&& GET_CODE (insn
) == BARRIER
)
288 if (frame_pointer_needed
)
290 /* Pop saved registers */
291 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
293 regno
= pop_order
[idx
];
294 if (regno
>= 0 && regno
!= FRAME_POINTER_REGNUM
&& WORD_REG_USED (regno
))
295 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[regno
]);
297 /* deallocate locals */
298 dosize (file
, "add", fsize
, 1);
299 /* pop frame pointer */
300 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[FRAME_POINTER_REGNUM
]);
304 /* pop saved registers */
305 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
307 regno
= pop_order
[idx
];
308 if (regno
>= 0 && WORD_REG_USED (regno
))
309 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[regno
]);
311 /* deallocate locals */
312 dosize (file
, "add", fsize
, 0);
317 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[3]);
320 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[2]);
323 fprintf (file
, "\tjmp @%s\n", h8_reg_names
[3]);
327 if (pragma_interrupt
)
328 fprintf (file
, "\trte\n");
330 fprintf (file
, "\trts\n");
333 pragma_interrupt
= 0;
336 current_function_anonymous_args
= 0;
339 /* Output assembly code for the start of the file. */
341 asm_file_start (file
)
344 fprintf (file
, ";\tGCC For the Hitachi H8/300\n");
345 fprintf (file
, ";\tBy Hitachi America Ltd and Cygnus Support\n");
346 fprintf (file
, ";\trelease F-1\n");
348 fprintf (file
, "; -O%d\n", optimize
);
350 fprintf (file
, "\n\t.h8300h\n");
352 fprintf (file
, "\n\n");
353 output_file_directive (file
, main_input_filename
);
356 /* Output assembly language code for the end of file. */
362 fprintf (file
, "\t.end\n");
365 /* Return true if VALUE is a valid constant for constraint 'P'.
366 IE: VALUE is a power of two <= 2**15. */
369 small_power_of_two (value
)
395 /* Return true if VALUE is a valid constant for constraint 'O', which
396 means that the constant would be ok to use as a bit for a bclr
403 return small_power_of_two ((~value
) & 0xff);
406 /* Return true is OP is a valid source operand for an integer move
410 general_operand_src (op
, mode
)
412 enum machine_mode mode
;
414 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == POST_INC
)
416 return general_operand (op
, mode
);
419 /* Return true if OP is a valid destination operand for an integer move
423 general_operand_dst (op
, mode
)
425 enum machine_mode mode
;
427 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == PRE_DEC
)
429 return general_operand (op
, mode
);
432 /* Return true if OP is a const valid for a bit clear instruction. */
435 o_operand (operand
, mode
)
437 enum machine_mode mode
;
439 return (GET_CODE (operand
) == CONST_INT
440 && CONST_OK_FOR_O (INTVAL (operand
)));
443 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
446 p_operand (operand
, mode
)
448 enum machine_mode mode
;
450 return (GET_CODE (operand
) == CONST_INT
451 && CONST_OK_FOR_P (INTVAL (operand
)));
454 /* Return true if OP is a valid call operand. */
457 call_insn_operand (op
, mode
)
459 enum machine_mode mode
;
461 if (GET_CODE (op
) == MEM
)
463 rtx inside
= XEXP (op
, 0);
464 if (register_operand (inside
, Pmode
))
466 if (CONSTANT_ADDRESS_P (inside
))
472 /* Return true if OP is a valid jump operand. */
475 jump_address_operand (op
, mode
)
477 enum machine_mode mode
;
479 if (GET_CODE (op
) == REG
)
480 return mode
== Pmode
;
482 if (GET_CODE (op
) == MEM
)
484 rtx inside
= XEXP (op
, 0);
485 if (register_operand (inside
, Pmode
))
487 if (CONSTANT_ADDRESS_P (inside
))
493 /* Recognize valid operands for bitfield instructions. */
495 extern int rtx_equal_function_value_matters
;
498 bit_operand (op
, mode
)
500 enum machine_mode mode
;
502 /* We can except any general operand, expept that MEM operands must
503 be limited to those that use addresses valid for the 'U' constraint. */
504 if (!general_operand (op
, mode
))
507 /* Accept any mem during RTL generation. Otherwise, the code that does
508 insv and extzv will think that we can not handle memory. However,
509 to avoid reload problems, we only accept 'U' MEM operands after RTL
510 generation. This means that any named pattern which uses this predicate
511 must force its operands to match 'U' before emitting RTL. */
513 if (GET_CODE (op
) == REG
)
515 if (GET_CODE (op
) == SUBREG
)
517 if (!rtx_equal_function_value_matters
)
519 /* We're building rtl */
520 return GET_CODE (op
) == MEM
;
524 return (GET_CODE (op
) == MEM
525 && EXTRA_CONSTRAINT (op
, 'U'));
529 /* Recognize valid operators for bit test. */
532 eq_operator (x
, mode
)
534 enum machine_mode mode
;
536 return (GET_CODE (x
) == EQ
|| GET_CODE (x
) == NE
);
539 /* Handle machine specific pragmas for compatibility with existing
540 compilers for the H8/300.
542 pragma saveall generates prolog/epilog code which saves and
543 restores all the registers on function entry.
545 pragma interrupt saves and restores all registers, and exits with
546 an rte instruction rather than an rts. A pointer to a function
547 with this attribute may be safely used in an interrupt vector. */
558 while (c
== ' ' || c
== '\t')
561 if (c
== '\n' || c
== EOF
)
564 /* The only pragmas we understand are interrupt and saveall. */
565 while (psize
< sizeof (pbuf
) - 1
573 if (strcmp (pbuf
, "interrupt") == 0)
574 pragma_interrupt
= 1;
576 if (strcmp (pbuf
, "saveall") == 0)
579 /* ??? This is deprecated. Use section attributes. */
580 if (strcmp (pbuf
, "section") == 0)
582 while (c
&& !isalpha (c
))
585 while (psize
< sizeof (pbuf
) - 1
586 && isalpha (c
) || isdigit (c
) || c
== '_')
592 named_section (pbuf
);
598 /* If the next arg with MODE and TYPE is to be passed in a register, return
599 the rtx to represent where it is passed. CUM represents the state after
600 the last argument. NAMED is not used. */
602 static char *hand_list
[] =
622 /* Return an RTX to represent where a value with mode MODE will be returned
623 from a function. If the result is 0, the argument is pushed. */
626 function_arg (cum
, mode
, type
, named
)
627 CUMULATIVE_ARGS
*cum
;
628 enum machine_mode mode
;
636 /* Pass 3 regs worth of data in regs when user asked on the command line. */
637 if (TARGET_QUICKCALL
)
640 /* If calling hand written assembler, use 4 regs of args. */
646 fname
= XSTR (cum
->libcall
, 0);
648 /* See if this libcall is one of the hand coded ones. */
650 for (p
= hand_list
; *p
&& strcmp (*p
, fname
) != 0; p
++)
662 size
= int_size_in_bytes (type
);
664 size
= GET_MODE_SIZE (mode
);
666 if (size
+ cum
->nbytes
> regpass
* UNITS_PER_WORD
)
672 switch (cum
->nbytes
/ UNITS_PER_WORD
)
675 result
= gen_rtx (REG
, mode
, 0);
678 result
= gen_rtx (REG
, mode
, 1);
681 result
= gen_rtx (REG
, mode
, 2);
684 result
= gen_rtx (REG
, mode
, 3);
695 /* Return the cost of the rtx R with code CODE. */
730 /* Documentation for the machine specific operand escapes:
732 'A' print rn in h8/300 mode, erN in H8/300H mode
733 'C' print (operand - 2).
734 'E' like s but negative.
735 'F' like t but negative.
736 'G' constant just the negative
737 'L' fake label, changed after used twice.
738 'M' turn a 'M' constant into its negative mod 2.
739 'P' if operand is incing/decing sp, print .w, otherwise .b.
740 'S' print operand as a long word
741 'T' print operand as a word
742 'U' if operand is incing/decing sp, print l, otherwise nothing.
743 'V' find the set bit, and print its number.
744 'W' find the clear bit, and print its number.
745 'X' print operand as a byte
746 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
748 'b' print the bit opcode
749 'c' print the ibit opcode
750 'd' bcc if EQ, bcs if NE
751 'e' first word of 32 bit value - if reg, then least reg. if mem
752 then least. if const then most sig word
753 'f' second word of 32 bit value - if reg, then biggest reg. if mem
754 then +2. if const then least sig word
755 'g' bcs if EQ, bcc if NE
756 'j' print operand as condition code.
757 'k' print operand as reverse condition code.
758 's' print as low byte of 16 bit value
759 't' print as high byte of 16 bit value
760 'w' print as low byte of 32 bit value
761 'x' print as 2nd byte of 32 bit value
762 'y' print as 3rd byte of 32 bit value
763 'z' print as msb of 32 bit value
766 /* Return assembly language string which identifies a comparison type. */
775 if (cc_prev_status
.flags
& CC_DONE_CBIT
)
779 if (cc_prev_status
.flags
& CC_DONE_CBIT
)
803 /* Print operand X using operand code CODE to assembly language output file
807 print_operand (file
, x
, code
)
812 /* This is used to general unique labels for the 'L' code. */
813 static int lab
= 1000;
815 /* This is used for communication between the 'P' and 'U' codes. */
818 /* This is used for communication between the 'Z' and 'Y' codes. */
819 /* ??? 'V' and 'W' use it too. */
825 if (GET_CODE (x
) == REG
)
826 fprintf (file
, "%s", h8_reg_names
[REGNO (x
)]);
831 fprintf (file
, "#%d", INTVAL (x
) - 2);
834 switch (GET_CODE (x
))
837 fprintf (file
, "%sl", names_big
[REGNO (x
)]);
840 fprintf (file
, "#%d", (-INTVAL (x
)) & 0xff);
847 switch (GET_CODE (x
))
850 fprintf (file
, "%sh", names_big
[REGNO (x
)]);
853 fprintf (file
, "#%d", ((-INTVAL (x
)) & 0xff00) >> 8);
860 if (GET_CODE (x
) != CONST_INT
)
862 fprintf (file
, "#%d", 0xff & (-INTVAL (x
)));
865 /* 'L' must always be used twice in a single pattern. It generates
866 the same lable twice, and then will generate a unique label the
867 next time it is used. */
868 asm_fprintf (file
, "tl%d", (lab
++) / 2);
871 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
878 fprintf (file
, "#2");
884 fprintf (file
, "#1");
891 if (REGNO (XEXP (XEXP (x
, 0), 0)) == STACK_POINTER_REGNUM
)
894 fprintf (file
, ".w");
899 fprintf (file
, ".b");
903 if (GET_CODE (x
) == REG
)
904 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
909 if (GET_CODE (x
) == REG
)
910 fprintf (file
, "%s", names_big
[REGNO (x
)]);
915 fprintf (file
, "%s%s", names_big
[REGNO (x
)], last_p
);
918 bitint
= exact_log2 (INTVAL (x
));
921 fprintf (file
, "#%d", bitint
& 7);
924 bitint
= exact_log2 ((~INTVAL (x
)) & 0xff);
927 fprintf (file
, "#%d", bitint
& 7);
930 if (GET_CODE (x
) == REG
)
931 fprintf (file
, "%s", byte_reg (x
, 0));
938 if (GET_CODE (x
) == REG
)
939 fprintf (file
, "%s%c", names_big
[REGNO (x
)], bitint
> 7 ? 'h' : 'l');
941 print_operand (file
, x
, 0);
946 fprintf (file
, "#%d", bitint
& 7);
949 switch (GET_CODE (x
))
952 fprintf (file
, "bor");
955 fprintf (file
, "bxor");
958 fprintf (file
, "band");
963 switch (GET_CODE (x
))
966 fprintf (file
, "bior");
969 fprintf (file
, "bixor");
972 fprintf (file
, "biand");
977 switch (GET_CODE (x
))
980 fprintf (file
, "bcc");
983 fprintf (file
, "bcs");
990 switch (GET_CODE (x
))
994 fprintf (file
, "%s", names_big
[REGNO (x
)]);
996 fprintf (file
, "%s", names_upper_extended
[REGNO (x
)]);
999 x
= adj_offsettable_operand (x
, 0);
1000 print_operand (file
, x
, 0);
1003 fprintf (file
, "#%d", ((INTVAL (x
) >> 16) & 0xffff));
1011 switch (GET_CODE (x
))
1015 fprintf (file
, "%s", names_big
[REGNO (x
) + 1]);
1017 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1020 x
= adj_offsettable_operand (x
, 2);
1021 print_operand (file
, x
, 0);
1024 fprintf (file
, "#%d", INTVAL (x
) & 0xffff);
1031 switch (GET_CODE (x
))
1034 fprintf (file
, "bcc");
1037 fprintf (file
, "bcs");
1044 asm_fprintf (file
, cond_string (GET_CODE (x
)));
1047 asm_fprintf (file
, cond_string (reverse_condition (GET_CODE (x
))));
1050 if (GET_CODE (x
) == CONST_INT
)
1051 fprintf (file
, "#%d", (INTVAL (x
)) & 0xff);
1053 fprintf (file
, "%s", byte_reg (x
, 0));
1056 if (GET_CODE (x
) == CONST_INT
)
1057 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1059 fprintf (file
, "%s", byte_reg (x
, 1));
1062 if (GET_CODE (x
) != CONST_INT
)
1064 fprintf (file
, "%d", INTVAL (x
));
1067 if (GET_CODE (x
) == CONST_INT
)
1068 fprintf (file
, "#%d", INTVAL (x
) & 0xff);
1070 fprintf (file
, "%s", byte_reg (x
, TARGET_H8300
? 2 : 0));
1073 if (GET_CODE (x
) == CONST_INT
)
1074 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1076 fprintf (file
, "%s", byte_reg (x
, TARGET_H8300
? 3 : 1));
1079 if (GET_CODE (x
) == CONST_INT
)
1080 fprintf (file
, "#%d", (INTVAL (x
) >> 16) & 0xff);
1082 fprintf (file
, "%s", byte_reg (x
, 0));
1085 if (GET_CODE (x
) == CONST_INT
)
1086 fprintf (file
, "#%d", (INTVAL (x
) >> 24) & 0xff);
1088 fprintf (file
, "%s", byte_reg (x
, 1));
1093 switch (GET_CODE (x
))
1096 switch (GET_MODE (x
))
1099 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1100 fprintf (file
, "%s", byte_reg (x
, 0));
1101 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1102 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1106 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1109 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1117 fprintf (file
, "@");
1118 output_address (XEXP (x
, 0));
1125 fprintf (file
, "#");
1126 print_operand_address (file
, x
);
1132 /* Output assembly language output for the address ADDR to FILE. */
1135 print_operand_address (file
, addr
)
1139 switch (GET_CODE (addr
))
1142 fprintf (file
, "%s", h8_reg_names
[REGNO (addr
)]);
1146 fprintf (file
, "-%s", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1150 fprintf (file
, "%s+", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1154 fprintf (file
, "(");
1155 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1158 print_operand_address (file
, XEXP (addr
, 1));
1159 fprintf (file
, ",");
1160 print_operand_address (file
, XEXP (addr
, 0));
1165 print_operand_address (file
, XEXP (addr
, 0));
1166 fprintf (file
, "+");
1167 print_operand_address (file
, XEXP (addr
, 1));
1169 fprintf (file
, ")");
1174 /* Since the h8/300 only has 16 bit pointers, negative values are also
1175 those >= 32768. This happens for example with pointer minus a
1176 constant. We don't want to turn (char *p - 2) into
1177 (char *p + 65534) because loop unrolling can build upon this
1178 (IE: char *p + 131068). */
1179 int n
= INTVAL (addr
);
1181 n
= (int) (short) n
;
1183 /* ??? Why the special case for -ve values? */
1184 fprintf (file
, "-%d", -n
);
1186 fprintf (file
, "%d", n
);
1191 output_addr_const (file
, addr
);
1196 /* Output all insn addresses and their sizes into the assembly language
1197 output file. This is helpful for debugging whether the length attributes
1198 in the md file are correct. This is not meant to be a user selectable
1202 final_prescan_insn (insn
, operand
, num_operands
)
1206 /* This holds the last insn address. */
1207 static int last_insn_address
= 0;
1209 int uid
= INSN_UID (insn
);
1211 if (TARGET_RTL_DUMP
)
1213 fprintf (asm_out_file
, "\n****************");
1214 print_rtl (asm_out_file
, PATTERN (insn
));
1215 fprintf (asm_out_file
, "\n");
1218 if (TARGET_ADDRESSES
)
1220 fprintf (asm_out_file
, "; 0x%x %d\n", insn_addresses
[uid
],
1221 insn_addresses
[uid
] - last_insn_address
);
1222 last_insn_address
= insn_addresses
[uid
];
1226 /* Prepare for an SI sized move. */
1232 rtx src
= operands
[1];
1233 rtx dst
= operands
[0];
1234 if (!reload_in_progress
&& !reload_completed
)
1236 if (!register_operand (dst
, GET_MODE (dst
)))
1238 rtx tmp
= gen_reg_rtx (GET_MODE (dst
));
1239 emit_move_insn (tmp
, src
);
1246 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1247 Define the offset between two registers, one to be eliminated, and the other
1248 its replacement, at the start of a routine. */
1251 initial_offset (from
, to
)
1255 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1256 offset
= UNITS_PER_WORD
+ frame_pointer_needed
* UNITS_PER_WORD
;
1261 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1262 if ((regs_ever_live
[regno
]
1263 && (!call_used_regs
[regno
] || regno
== FRAME_POINTER_REGNUM
)))
1264 offset
+= UNITS_PER_WORD
;
1266 /* See the comments for get_frame_size. We need to round it up to
1269 offset
+= ((get_frame_size () + STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
1270 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
1272 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
1273 offset
+= UNITS_PER_WORD
; /* Skip saved PC */
1278 /* Update the condition code from the insn. */
1281 notice_update_cc (body
, insn
)
1285 switch (get_attr_cc (insn
))
1288 /* Insn does not affect the CC at all */
1292 /* Insn does not change the CC, but the 0't operand has been changed. */
1294 if (cc_status
.value1
!= 0
1295 && reg_overlap_mentioned_p (recog_operand
[0], cc_status
.value1
))
1296 cc_status
.value1
= 0;
1298 if (cc_status
.value2
!= 0
1299 && reg_overlap_mentioned_p (recog_operand
[0], cc_status
.value2
))
1300 cc_status
.value2
= 0;
1305 /* Insn sets CC to recog_operand[0], but overflow is impossible. */
1307 cc_status
.flags
|= CC_NO_OVERFLOW
;
1308 cc_status
.value1
= recog_operand
[0];
1312 /* The insn is a compare instruction */
1314 cc_status
.value1
= SET_SRC (body
);
1319 cc_status
.flags
|= CC_DONE_CBIT
;
1320 cc_status
.value1
= 0;
1325 /* Insn clobbers CC. */
1331 /* Recognize valid operators for bit instructions */
1334 bit_operator (x
, mode
)
1336 enum machine_mode mode
;
1338 enum rtx_code code
= GET_CODE (x
);
1347 We devote a fair bit of code to getting efficient shifts since we can only
1348 shift one bit at a time. See the .md file for more comments.
1350 Here are some thoughts on what the absolutely positively best code is.
1351 "Best" here means some rational trade-off between code size and speed,
1352 where speed is more preferred but not at the expense of generating 20 insns.
1354 H8/300 QImode shifts
1355 1-4 - do them inline
1356 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1358 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1359 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1361 H8/300 HImode shifts
1362 1-4 - do them inline
1364 7 - shift other way once, move byte into place, move carry bit into place
1365 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1366 9 - inline shift 1-4, move byte, set other byte
1367 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1369 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1370 - ASHIFTRT: shll, subx, set other byte
1372 H8/300 SImode shifts
1373 1-2 - do them inline
1375 7 - shift other way once, move bytes into place,
1376 move carry into place (possibly with sign extension)
1377 8 - move bytes into place, zero or sign extend other
1379 15 - shift other way once, move word into place, move carry into place
1380 16 - move word, zero or sign extend other
1382 24 - move bytes into place, zero or sign extend other
1384 28-30 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1387 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, byte byte into place,
1389 ASHIFTRT: shll top byte, subx, copy to other bytes
1391 H8/300H QImode shifts
1394 H8/300H HImode shifts
1397 H8/300H SImode shifts
1398 (These are complicated by the fact that we don't have byte level access to
1400 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1401 1-4 - do them inline
1403 15 - shift other way once, move word into place, move carry into place
1404 (with sign extension for ASHIFTRT)
1405 16 - move word into place, zero or sign extend other
1407 24 - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1408 move word 0 to word 1, zero word 0
1409 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1410 zero word 1, zero byte 1
1411 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1412 sign extend byte 0, sign extend word 0
1413 25-27 - either loop, or
1414 do 24 bit shift, inline rest
1415 28-30 - ASHIFT: rotate 4/3/2, mask
1416 LSHIFTRT: rotate 4/3/2, mask
1418 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1422 All of these haven't been implemented. I've just documented them and
1423 provided hooks so they can be.
1427 nshift_operator (x
, mode
)
1429 enum machine_mode mode
;
1431 switch (GET_CODE (x
))
1443 /* Called from the .md file to emit code to do shifts.
1444 Returns a boolean indicating success
1445 (currently this is always TRUE). */
1448 expand_a_shift (mode
, code
, operands
)
1449 enum machine_mode mode
;
1453 extern int rtx_equal_function_value_matters
;
1455 emit_move_insn (operands
[0], operands
[1]);
1457 /* need a loop to get all the bits we want - we generate the
1458 code at emit time, but need to allocate a scratch reg now */
1461 (PARALLEL
, VOIDmode
,
1463 gen_rtx (SET
, VOIDmode
, operands
[0],
1464 gen_rtx (code
, mode
, operands
[0], operands
[2])),
1465 gen_rtx (CLOBBER
, VOIDmode
, gen_rtx (SCRATCH
, QImode
, 0)))));
1470 /* Shift algorithm determination.
1472 There are various ways of doing a shift:
1473 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1475 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1476 necessary bits into position and then set the rest to zero.
1477 SHIFT_SPECIAL: Hand crafted assembler.
1478 SHIFT_LOOP: If the above methods fail, just loop. */
1489 /* Symbols of the various shifts which can be used as indices. */
1493 SHIFT_ASHIFT
, SHIFT_LSHIFTRT
, SHIFT_ASHIFTRT
1496 /* Symbols of the various modes which can be used as indices. */
1500 QIshift
, HIshift
, SIshift
1503 /* For single bit shift insns, record assembler and whether the condition code
1504 is valid afterwards. */
1512 /* Assembler instruction shift table.
1514 These tables are used to look up the basic shifts.
1515 They are indexed by cpu, shift_type, and mode.
1518 static const struct shift_insn shift_one
[2][3][3] =
1525 { "add.w %T0,%T0\t; shal.w", 1 },
1526 { "add.w %f0,%f0\t; shal.l\n\taddx %y0,%y0\n\taddx %z0,%z0\t; end shal.l", 0 }
1528 /* SHIFT_LSHIFTRT */
1531 { "shlr %t0\t; shlr.w\n\trotxr %s0\t; end shlr.w", 0 },
1532 { "shlr %z0\t; shlr.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shlr.l", 0 }
1534 /* SHIFT_ASHIFTRT */
1537 { "shar %t0\t; shar.w\n\trotxr %s0\t; end shar.w", 0 },
1538 { "shar %z0\t; shar.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shar.l", 0 }
1545 { "shal.b %X0", 1 },
1546 { "shal.w %T0", 1 },
1549 /* SHIFT_LSHIFTRT */
1551 { "shlr.b %X0", 1 },
1552 { "shlr.w %T0", 1 },
1555 /* SHIFT_ASHIFTRT */
1557 { "shar.b %X0", 1 },
1558 { "shar.w %T0", 1 },
1564 /* Rotates are organized by which shift they'll be used in implementing.
1565 There's no need to record whether the cc is valid afterwards because
1566 it is the AND insn that will decide this. */
1568 static const char *const rotate_one
[2][3][3] =
1575 "shlr %t0\t; rotr.w\n\trotxr %s0\n\tbst #7,%t0\t; end rotr.w",
1578 /* SHIFT_LSHIFTRT */
1581 "shll %s0\t; rotl.w\n\trotxl %t0\n\tbst #0,%s0\t; end rotl.w",
1584 /* SHIFT_ASHIFTRT */
1587 "shll %s0\t; rotl.w\n\trotxl %t0\n\tbst #0,%s0\t; end rotl.w",
1599 /* SHIFT_LSHIFTRT */
1605 /* SHIFT_ASHIFTRT */
1614 /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
1615 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
1616 We don't achieve maximum efficiency in all cases, but the hooks are here
1619 For now we just use lots of switch statements. Since we don't even come
1620 close to supporting all the cases, this is simplest. If this function ever
1621 gets too big, perhaps resort to a more table based lookup. Of course,
1622 at this point you may just wish to do it all in rtl.
1624 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
1625 1,2,3,4 will be inlined (1,2 for SI). */
1627 static enum shift_alg
1628 get_shift_alg (cpu
, shift_type
, mode
, count
, assembler_p
, cc_valid_p
)
1630 enum shift_type shift_type
;
1631 enum machine_mode mode
;
1633 const char **assembler_p
;
1636 /* The default is to loop. */
1637 enum shift_alg alg
= SHIFT_LOOP
;
1638 enum shift_mode shift_mode
;
1640 /* We don't handle negative shifts or shifts greater than the word size,
1641 they should have been handled already. */
1643 if (count
< 0 || count
> GET_MODE_BITSIZE (mode
))
1649 shift_mode
= QIshift
;
1652 shift_mode
= HIshift
;
1655 shift_mode
= SIshift
;
1661 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
1662 It is up to the caller to know that looping clobbers cc. */
1663 *assembler_p
= shift_one
[cpu
][shift_type
][shift_mode
].assembler
;
1664 *cc_valid_p
= shift_one
[cpu
][shift_type
][shift_mode
].cc_valid
;
1666 /* Now look for cases we want to optimize. */
1672 return SHIFT_INLINE
;
1673 else if (count
<= 6)
1675 if (shift_type
== SHIFT_ASHIFTRT
)
1681 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
1683 return SHIFT_ROT_AND
;
1686 else if (count
== 7)
1688 if (shift_type
== SHIFT_ASHIFTRT
)
1690 *assembler_p
= "shll %X0\t; shar.b(7)\n\tsubx %X0,%X0\t; end shar.b(7)";
1692 return SHIFT_SPECIAL
;
1696 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
1698 return SHIFT_ROT_AND
;
1704 return SHIFT_INLINE
;
1705 else if (count
== 8)
1710 *assembler_p
= "mov.b %s0,%t0\t; shal.w(8)\n\tsub.b %s0,%s0\t; end shal.w(8)";
1712 return SHIFT_SPECIAL
;
1713 case SHIFT_LSHIFTRT
:
1714 *assembler_p
= "mov.b %t0,%s0\t; shlr.w(8)\n\tsub.b %t0,%t0\t; end shlr.w(8)";
1716 return SHIFT_SPECIAL
;
1717 case SHIFT_ASHIFTRT
:
1718 if (cpu
== CPU_H8300
)
1719 *assembler_p
= "mov.b %t0,%s0\t; shar.w(8)\n\tshll %t0\n\tsubx %t0,%t0\t; end shar.w(8)";
1721 *assembler_p
= "mov.b %t0,%s0\t; shar.w(8)\n\texts.w %T0\t; end shar.w(8)";
1723 return SHIFT_SPECIAL
;
1727 else if (count
== 15)
1729 if (shift_type
== SHIFT_ASHIFTRT
)
1731 *assembler_p
= "shll %t0,%t0\t; shar.w(15)\n\tsubx %t0,%t0\n\tmov.b %t0,%s0\t; end shar.w(15)";
1733 return SHIFT_SPECIAL
;
1737 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
1739 return SHIFT_ROT_AND
;
1744 if (count
<= (cpu
== CPU_H8300
? 2 : 4))
1745 return SHIFT_INLINE
;
1746 else if (count
== 8)
1748 if (cpu
== CPU_H8300
)
1753 *assembler_p
= "mov.b %y0,%z0\t; shal.l(8)\n\tmov.b %x0,%y0\n\tmov.b %w0,%x0\n\tsub.b %w0,%w0\t; end shal.l(8)";
1755 return SHIFT_SPECIAL
;
1756 case SHIFT_LSHIFTRT
:
1757 *assembler_p
= "mov.b %x0,%w0\t; shlr.l(8)\n\tmov.b %y0,%x0\n\tmov.b %z0,%y0\n\tsub.b %z0,%z0\t; end shlr.l(8)";
1759 return SHIFT_SPECIAL
;
1760 case SHIFT_ASHIFTRT
:
1761 *assembler_p
= "mov.b %x0,%w0\t; shar.l(8)\n\tmov.b %y0,%x0\n\tmov.b %z0,%y0\n\tshll %z0\n\tsubx %z0,%z0; end shar.l(8)";
1763 return SHIFT_SPECIAL
;
1766 else /* CPU_H8300H */
1767 /* We don't have byte level access to the high word so this isn't
1768 easy to do. For now, just loop. */
1771 else if (count
== 16)
1776 *assembler_p
= "mov.w %f0,%e0\t; shal.l(16)\n\tsub.w %f0,%f0\t; end shal.l(16)";
1778 return SHIFT_SPECIAL
;
1779 case SHIFT_LSHIFTRT
:
1780 *assembler_p
= "mov.w %e0,%f0\t; shlr.l(16)\n\tsub.w %e0,%e0\t; end shlr.l(16)";
1782 return SHIFT_SPECIAL
;
1783 case SHIFT_ASHIFTRT
:
1784 if (cpu
== CPU_H8300
)
1785 *assembler_p
= "mov.w %e0,%f0\t; shar.l(16)\n\tshll %z0\n\tsubx %z0,%z0\n\tmov.b %z0,%y0\t; end shar.l(16)";
1787 *assembler_p
= "mov.w %e0,%f0\t; shar.l(16)\n\texts.l %S0\t; end shar.l(16)";
1789 return SHIFT_SPECIAL
;
1792 else if (count
>= 28 && count
<= 30)
1794 if (shift_type
== SHIFT_ASHIFTRT
)
1800 if (cpu
== CPU_H8300
)
1804 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
1806 return SHIFT_ROT_AND
;
1810 else if (count
== 31)
1812 if (shift_type
== SHIFT_ASHIFTRT
)
1814 if (cpu
== CPU_H8300
)
1815 *assembler_p
= "shll %z0\t; shar.l(31)\n\tsubx %w0,%w0\n\tmov.b %w0,%x0\n\tmov.w %f0,%e0\t; end shar.l(31)";
1817 *assembler_p
= "shll %e0\t; shar.l(31)\n\tsubx %w0,%w0\n\tmov.b %w0,%x0\n\tmov.w %f0,%e0\t; end shar.l(31)";
1819 return SHIFT_SPECIAL
;
1823 if (cpu
== CPU_H8300
)
1825 if (shift_type
== SHIFT_ASHIFT
)
1826 *assembler_p
= "sub.w %e0,%e0\t; shal.l(31)\n\tshlr %w0\n\tmov.w %e0,%f0\n\trotxr %z0\t; end shal.l(31)";
1828 *assembler_p
= "sub.w %f0,%f0\t; shlr.l(31)\n\tshll %z0\n\tmov.w %f0,%e0\n\trotxl %w0\t; end shlr.l(31)";
1830 return SHIFT_SPECIAL
;
1834 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
1836 return SHIFT_ROT_AND
;
1848 /* Emit the assembler code for doing shifts. */
1851 emit_a_shift (insn
, operands
)
1855 static int loopend_lab
;
1858 rtx inside
= PATTERN (insn
);
1859 rtx shift
= operands
[3];
1860 enum machine_mode mode
= GET_MODE (shift
);
1861 enum rtx_code code
= GET_CODE (shift
);
1862 enum shift_type shift_type
;
1863 enum shift_mode shift_mode
;
1870 shift_mode
= QIshift
;
1873 shift_mode
= HIshift
;
1876 shift_mode
= SIshift
;
1885 shift_type
= SHIFT_ASHIFTRT
;
1888 shift_type
= SHIFT_LSHIFTRT
;
1891 shift_type
= SHIFT_ASHIFT
;
1897 if (GET_CODE (operands
[2]) != CONST_INT
)
1899 /* Indexing by reg, so have to loop and test at top */
1900 output_asm_insn ("mov.b %X2,%X4", operands
);
1901 fprintf (asm_out_file
, "\tble .Lle%d\n", loopend_lab
);
1903 /* Get the assembler code to do one shift. */
1904 get_shift_alg (cpu_type
, shift_type
, mode
, 1, &assembler
, &cc_valid
);
1908 int n
= INTVAL (operands
[2]);
1911 /* If the count is negative, make it 0. */
1914 /* If the count is too big, truncate it.
1915 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
1916 do the intuitive thing. */
1917 else if (n
> GET_MODE_BITSIZE (mode
))
1918 n
= GET_MODE_BITSIZE (mode
);
1920 alg
= get_shift_alg (cpu_type
, shift_type
, mode
, n
, &assembler
, &cc_valid
);
1926 output_asm_insn (assembler
, operands
);
1928 cc_status
.value1
= operands
[0];
1932 int m
= GET_MODE_BITSIZE (mode
) - n
;
1933 int mask
= (shift_type
== SHIFT_ASHIFT
1934 ? ((1 << GET_MODE_BITSIZE (mode
) - n
) - 1) << n
1935 : (1 << GET_MODE_BITSIZE (mode
) - n
) - 1);
1937 /* Not all possibilities of rotate are supported. They shouldn't
1938 be generated, but let's watch for 'em. */
1942 output_asm_insn (assembler
, operands
);
1948 sprintf (insn_buf
, "and #%d,%%X0\t; end shift %d via rotate+and",
1950 cc_status
.value1
= operands
[0];
1953 sprintf (insn_buf
, "and #%d,%%s0\n\tand #%d,%%t0\t; end shift %d via rotate+and",
1954 mask
& 255, mask
>> 8, n
);
1962 sprintf (insn_buf
, "and.%c #%d,%%%c0",
1963 "bwl"[shift_mode
], mask
,
1964 mode
== QImode
? 'X' : mode
== HImode
? 'T' : 'S');
1965 cc_status
.value1
= operands
[0];
1967 output_asm_insn (insn_buf
, operands
);
1971 output_asm_insn (assembler
, operands
);
1975 /* Need a loop, move limit to tmp reg */
1976 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
, names_big
[REGNO (operands
[4])]);
1979 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
1980 output_asm_insn (assembler
, operands
);
1981 output_asm_insn ("add #0xff,%X4", operands
);
1982 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
1983 fprintf (asm_out_file
, ".Lle%d:\n", loopend_lab
);
1988 /* Fix the operands of a gen_xxx so that it could become a bit
1992 fix_bit_operand (operands
, what
, type
)
1997 /* The bit_operand predicate accepts any memory durint RTL generation, but
1998 only 'U' memory afterwards, so if this is a MEM operand, we must force
1999 it to be valid for 'U' by reloading the address. */
2001 if (GET_CODE (operands
[2]) == CONST_INT
)
2003 if (CONST_OK_FOR_LETTER_P (INTVAL (operands
[2]), what
))
2005 /* Ok to have a memory dest. */
2006 if (GET_CODE (operands
[0]) == MEM
&& !EXTRA_CONSTRAINT (operands
[0], 'U'))
2009 mem
= gen_rtx (MEM
, GET_MODE (operands
[0]),
2010 copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0)));
2011 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[0]);
2012 MEM_IN_STRUCT_P (mem
) = MEM_IN_STRUCT_P (operands
[0]);
2013 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (operands
[0]);
2017 if (GET_CODE (operands
[1]) == MEM
&& !EXTRA_CONSTRAINT (operands
[1], 'U'))
2020 mem
= gen_rtx (MEM
, GET_MODE (operands
[1]),
2021 copy_to_mode_reg (Pmode
, XEXP (operands
[1], 0)));
2022 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[1]);
2023 MEM_IN_STRUCT_P (mem
) = MEM_IN_STRUCT_P (operands
[1]);
2024 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (operands
[1]);
2031 /* Dest and src op must be register. */
2033 operands
[1] = force_reg (QImode
, operands
[1]);
2035 rtx res
= gen_reg_rtx (QImode
);
2036 emit_insn (gen_rtx (SET
, VOIDmode
, res
, gen_rtx (type
, QImode
, operands
[1], operands
[2])));
2037 emit_insn (gen_rtx (SET
, VOIDmode
, operands
[0], res
));