* config/mips-opcode.h: Moved to opcode/mips.h.
[binutils-gdb.git] / gas / config / tc-mips.c
1 /* tc-mips.c -- assemble code for a MIPS chip.
2 Copyright (C) 1993 Free Software Foundation, Inc.
3 Contributed by the OSF and Ralph Campbell.
4 Written by Keith Knowles and Ralph Campbell, working independently.
5 Modified for ECOFF support by Ian Lance Taylor of Cygnus Support.
6
7 This file is part of GAS.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 #include "as.h"
24
25 #include <ctype.h>
26
27 #ifndef __STDC__
28 #ifndef NO_STDARG
29 #define NO_STDARG
30 #endif
31 #endif
32
33 #ifndef NO_STDARG
34 #include <stdarg.h>
35 #else
36 #ifndef NO_VARARGS
37 #include <varargs.h>
38 #endif /* NO_VARARGS */
39 #endif /* NO_STDARG */
40
41 #include "opcode/mips.h"
42
43 #define AT 1
44 #define GP 28
45 #define RA 31
46
47 static int mips_warn_about_macros;
48 static int mips_noreorder;
49 static int mips_nomove;
50 static int mips_noat;
51 static int mips_nobopt;
52
53 #ifdef OBJ_ECOFF
54 /* The size of the small data section. */
55 static int g_switch_value = 8;
56 #endif
57
58 #define N_RMASK 0xc4
59 #define N_VFP 0xd4
60
61 /* handle of the OPCODE hash table */
62 static struct hash_control *op_hash = NULL;
63
64 /* This array holds the chars that always start a comment. If the
65 pre-processor is disabled, these aren't very useful */
66 const char comment_chars[] = "#";
67
68 /* This array holds the chars that only start a comment at the beginning of
69 a line. If the line seems to have the form '# 123 filename'
70 .line and .file directives will appear in the pre-processed output */
71 /* Note that input_file.c hand checks for '#' at the beginning of the
72 first line of the input file. This is because the compiler outputs
73 #NO_APP at the beginning of its output. */
74 /* Also note that C style comments are always supported. */
75 const char line_comment_chars[] = "#";
76
77 /* This array holds machine specific line separator characters. */
78 const char line_separator_chars[] = "";
79
80 /* Chars that can be used to separate mant from exp in floating point nums */
81 const char EXP_CHARS[] = "eE";
82
83 /* Chars that mean this number is a floating point constant */
84 /* As in 0f12.456 */
85 /* or 0d1.2345e12 */
86 const char FLT_CHARS[] = "rRsSfFdDxXpP";
87
88 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
89 changed in read.c . Ideally it shouldn't have to know about it at all,
90 but nothing is ideal around here.
91 */
92
93 static char *insn_error;
94
95 static int byte_order = BYTE_ORDER;
96
97 static int auto_align = 1;
98 \f
99 /* Prototypes for static functions. */
100
101 #ifdef __STDC__
102 #define internalError() \
103 as_fatal ("internal Error, line %d, %s", __LINE__, __FILE__)
104 #else
105 #define internalError() as_fatal ("MIPS internal Error");
106 #endif
107
108 static void append_insn PARAMS ((struct mips_cl_insn * ip,
109 expressionS * p,
110 bfd_reloc_code_real_type r));
111 static int gp_reference PARAMS ((expressionS * ep));
112 static void macro_build PARAMS ((int *counter, expressionS * ep,
113 const char *name, const char *fmt,
114 ...));
115 static void macro_build_lui PARAMS ((int *counter, expressionS * ep,
116 int regnum));
117 static void set_at PARAMS ((int *counter, int reg));
118 static void set_at_unsigned PARAMS ((int *counter, int reg));
119 static void check_absolute_expr PARAMS ((struct mips_cl_insn * ip,
120 expressionS * expr));
121 static void load_register PARAMS ((int *counter,
122 struct mips_cl_insn * ip,
123 int reg, expressionS * ep));
124 static void macro PARAMS ((struct mips_cl_insn * ip));
125 static void mips_ip PARAMS ((char *str, struct mips_cl_insn * ip));
126 static int my_getSmallExpression PARAMS ((expressionS * ep, char *str));
127 static void my_getExpression PARAMS ((expressionS * ep, char *str));
128 static symbolS *get_symbol PARAMS ((void));
129 static long get_optional_absolute_expression PARAMS ((void));
130 static void s_align PARAMS ((int));
131 static void s_change_sec PARAMS ((int));
132 static void s_cons PARAMS ((int));
133 static void s_err PARAMS ((int));
134 static void s_extern PARAMS ((int));
135 static void s_float_cons PARAMS ((int));
136 static void s_option PARAMS ((int));
137 static void s_mipsset PARAMS ((int));
138 #ifndef OBJ_ECOFF
139 static void md_obj_begin PARAMS ((void));
140 static void md_obj_end PARAMS ((void));
141 static long get_number PARAMS ((void));
142 static void s_ent PARAMS ((int));
143 static void s_mipsend PARAMS ((int));
144 static void s_file PARAMS ((int));
145 static void s_frame PARAMS ((int));
146 static void s_loc PARAMS ((int));
147 static void s_mask PARAMS ((char));
148 #endif
149 \f
150 /* Pseudo-op table.
151
152 The following pseudo-ops from the Kane and Heinrich MIPS book
153 should be defined here, but are currently unsupported: .alias,
154 .galive, .gjaldef, .gjrlive, .livereg, .noalias.
155
156 The following pseudo-ops from the Kane and Heinrich MIPS book are
157 specific to the type of debugging information being generated, and
158 should be defined by the object format: .aent, .begin, .bend,
159 .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
160 .vreg.
161
162 The following pseudo-ops from the Kane and Heinrich MIPS book are
163 not MIPS CPU specific, but are also not specific to the object file
164 format. This file is probably the best place to define them, but
165 they are not currently supported: .asm0, .endr, .lab, .repeat,
166 .struct, .weakext. */
167
168 const pseudo_typeS md_pseudo_table[] =
169 {
170 /* MIPS specific pseudo-ops. */
171 {"option", s_option, 0},
172 {"set", s_mipsset, 0},
173 {"rdata", s_change_sec, 'r',},
174 {"sdata", s_change_sec, 's',},
175
176 /* Relatively generic pseudo-ops that happen to be used on MIPS
177 chips. */
178 {"asciiz", stringer, 1},
179 {"bss", s_change_sec, 'b'},
180 {"err", s_err, 0},
181 {"half", s_cons, 1},
182
183 /* These pseudo-ops are defined in read.c, but must be overridden
184 here for one reason or another. */
185 {"align", s_align, 0},
186 {"byte", s_cons, 0},
187 {"data", s_change_sec, 'd'},
188 {"double", s_float_cons, 1},
189 {"extern", s_extern, 0},
190 {"float", s_float_cons, 0},
191 {"text", s_change_sec, 't'},
192 {"word", s_cons, 2},
193
194 #ifndef OBJ_ECOFF
195 /* These pseudo-ops should be defined by the object file format.
196 However, ECOFF is the only format which currently defines them,
197 so we have versions here for a.out. */
198 {"aent", s_ent, 1},
199 {"end", s_mipsend, 0},
200 {"ent", s_ent, 0},
201 {"file", s_file, 0},
202 {"fmask", s_ignore, 'F'},
203 {"frame", s_ignore, 0},
204 {"loc", s_ignore, 0},
205 {"mask", s_ignore, 'R'},
206 {"verstamp", s_ignore, 0},
207 #endif
208
209 /* Sentinel. */
210 {NULL}
211 };
212 \f
213 const relax_typeS md_relax_table[] =
214 {
215 { 0 }
216 };
217
218
219 static char *expr_end;
220
221 static expressionS imm_expr;
222 static expressionS offset_expr;
223 static bfd_reloc_code_real_type imm_reloc;
224 static bfd_reloc_code_real_type offset_reloc;
225
226 /*
227 * This function is called once, at assembler startup time. It should
228 * set up all the tables, etc. that the MD part of the assembler will need.
229 */
230 void
231 md_begin ()
232 {
233 register char *retval = NULL;
234 register unsigned int i = 0;
235
236 if ((op_hash = hash_new ()) == NULL)
237 {
238 as_fatal ("Virtual memory exhausted");
239 }
240 for (i = 0; i < NUMOPCODES;)
241 {
242 const char *name = mips_opcodes[i].name;
243
244 retval = hash_insert (op_hash, name, &mips_opcodes[i]);
245 if (retval != NULL && *retval != '\0')
246 {
247 fprintf (stderr, "internal error: can't hash `%s': %s\n",
248 mips_opcodes[i].name, retval);
249 as_fatal ("Broken assembler. No assembly attempted.");
250 }
251 do
252 {
253 if ((mips_opcodes[i].match & mips_opcodes[i].mask) !=
254 mips_opcodes[i].match)
255 {
256 fprintf (stderr, "internal error: bad opcode: `%s' \"%s\"\n",
257 mips_opcodes[i].name, mips_opcodes[i].args);
258 as_fatal ("Broken assembler. No assembly attempted.");
259 }
260 ++i;
261 }
262 while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
263 }
264
265 #ifndef OBJ_ECOFF
266 md_obj_begin ();
267 #endif
268 }
269
270 void
271 md_end ()
272 {
273 #ifndef OBJ_ECOFF
274 md_obj_end ();
275 #endif
276 }
277
278 void
279 md_assemble (str)
280 char *str;
281 {
282 struct mips_cl_insn insn;
283 static int init;
284
285 if (!init)
286 {
287 /* set the default alignment for the text section (2**2) */
288 /* This should go in md_begin but text_section isn't initialized then */
289 record_alignment (text_section, 2);
290 #ifdef OBJ_ECOFF
291 bfd_set_gp_size (stdoutput, g_switch_value);
292 #endif
293 init = 1;
294 }
295
296 imm_expr.X_seg = absent_section;
297 offset_expr.X_seg = absent_section;
298
299 mips_ip (str, &insn);
300 if (insn_error)
301 {
302 as_bad ("%s `%s'", insn_error, str);
303 return;
304 }
305 if (insn.insn_mo->pinfo == INSN_MACRO)
306 {
307 macro (&insn);
308 }
309 else
310 {
311 if (imm_expr.X_seg != absent_section)
312 append_insn (&insn, &imm_expr, imm_reloc);
313 else if (offset_expr.X_seg != absent_section)
314 append_insn (&insn, &offset_expr, offset_reloc);
315 else
316 append_insn (&insn, NULL, BFD_RELOC_UNUSED);
317 }
318 }
319
320 #define ALIGN_ERR "Attempt to assemble instruction onto non word boundary."
321 #define ALIGN_ERR2 "GAS doesn't do implicit alignment; use .align directive."
322
323 /*
324 * append insn
325 * Output an instruction.
326 */
327 static void
328 append_insn (ip, address_expr, reloc_type)
329 struct mips_cl_insn *ip;
330 expressionS *address_expr;
331 bfd_reloc_code_real_type reloc_type;
332 {
333 char *f;
334
335 f = frag_more (4);
336 #if 0 /* This is testing the address of the frag, not the alignment of
337 the instruction in the current section. */
338 if ((int) f & 3)
339 {
340 as_bad (ALIGN_ERR);
341 as_bad (ALIGN_ERR2);
342 }
343 #endif
344 if (address_expr != NULL)
345 {
346 fixS *fixP;
347
348 if (address_expr->X_seg == &bfd_abs_section)
349 {
350 switch (reloc_type)
351 {
352 case BFD_RELOC_32:
353 ip->insn_opcode |= address_expr->X_add_number;
354 break;
355
356 case BFD_RELOC_LO16:
357 ip->insn_opcode |= address_expr->X_add_number & 0xffff;
358 break;
359
360 case BFD_RELOC_MIPS_JMP:
361 case BFD_RELOC_16_PCREL_S2:
362 goto need_reloc;
363
364 default:
365 internalError ();
366 }
367 }
368 else
369 {
370 assert (reloc_type != BFD_RELOC_UNUSED);
371 need_reloc:
372 fixP = fix_new (frag_now, f - frag_now->fr_literal, 4,
373 address_expr->X_add_symbol,
374 address_expr->X_subtract_symbol,
375 address_expr->X_add_number,
376 reloc_type == BFD_RELOC_16_PCREL_S2,
377 reloc_type);
378 }
379 }
380 md_number_to_chars (f, ip->insn_opcode, 4);
381
382 /*
383 * Fill all delay slots with nops.
384 */
385 if (!mips_noreorder)
386 {
387 if (ip->insn_mo->pinfo & ANY_DELAY)
388 {
389 f = frag_more (4);
390 md_number_to_chars (f, 0, 4);
391 };
392
393 /* One extra nop */
394 if (ip->insn_mo->pinfo & (INSN_READ_HI | INSN_READ_LO))
395 {
396 f = frag_more (4);
397 md_number_to_chars (f, 0, 4);
398 }
399 }
400 }
401
402 /* Return 1 if an expression can be accessed via the GP register. */
403
404 static int
405 gp_reference (ep)
406 expressionS *ep;
407 {
408 #ifdef OBJ_ECOFF
409 symbolS *sym;
410 const char *symname;
411 const char *segname;
412
413 sym = ep->X_add_symbol;
414 if (sym == (symbolS *) NULL
415 || ep->X_subtract_symbol != (symbolS *) NULL)
416 return 0;
417
418 /* Certain symbols can not be referenced off the GP, although it
419 appears as though they can. */
420 symname = S_GET_NAME (sym);
421 if (symname != (const char *) NULL
422 && (strcmp (symname, "eprol") == 0
423 || strcmp (symname, "etext") == 0
424 || strcmp (symname, "_gp") == 0
425 || strcmp (symname, "edata") == 0
426 || strcmp (symname, "_fbss") == 0
427 || strcmp (symname, "_fdata") == 0
428 || strcmp (symname, "_ftext") == 0
429 || strcmp (symname, "end") == 0))
430 return 0;
431 if (! S_IS_DEFINED (sym)
432 && S_GET_VALUE (sym) != 0
433 && S_GET_VALUE (sym) <= g_switch_value)
434 return 1;
435 segname = segment_name (S_GET_SEGMENT (ep->X_add_symbol));
436 return (strcmp (segname, ".sdata") == 0
437 || strcmp (segname, ".sbss") == 0);
438 #else /* ! defined (OBJ_ECOFF) */
439 /* The GP register is only used for ECOFF. */
440 return 0;
441 #endif /* ! defined (OBJ_ECOFF) */
442 }
443
444 /* Build an instruction created by a macro expansion. This is passed
445 a pointer to the count of instructions created so far, an
446 expression, the name of the instruction to build, an operand format
447 string, and corresponding arguments. */
448
449 #ifndef NO_STDARG
450 static void
451 macro_build (int *counter,
452 expressionS * ep,
453 const char *name,
454 const char *fmt,
455 ...)
456 #else /* ! defined (NO_STDARG) */
457 static void
458 macro_build (counter, ep, name, fmt, va_alist)
459 int *counter;
460 expressionS *ep;
461 const char *name;
462 const char *fmt;
463 va_dcl
464 #endif /* ! defined (NO_STDARG) */
465 {
466 struct mips_cl_insn insn;
467 bfd_reloc_code_real_type r;
468 va_list args;
469
470 #ifndef NO_STDARG
471 va_start (args, fmt);
472 #else
473 va_start (args);
474 #endif
475
476 /*
477 * If the macro is about to expand into a second instruction,
478 * print a warning if needed. We need to pass ip as a parameter
479 * to generate a better warning message here...
480 */
481 if (mips_warn_about_macros && *counter == 1)
482 as_warn ("Macro instruction expanded into multiple instructions");
483
484 *counter += 1; /* bump instruction counter */
485
486 r = BFD_RELOC_UNUSED;
487 insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
488 assert (insn.insn_mo);
489 assert (strcmp (name, insn.insn_mo->name) == 0);
490
491 while (strcmp (fmt, insn.insn_mo->args) != 0)
492 {
493 ++insn.insn_mo;
494 assert (insn.insn_mo->name);
495 assert (strcmp (name, insn.insn_mo->name) == 0);
496 }
497 assert (insn.insn_mo->pinfo != INSN_MACRO);
498 insn.insn_opcode = insn.insn_mo->match;
499 for (;;)
500 {
501 switch (*fmt++)
502 {
503 case '\0':
504 break;
505
506 case ',':
507 case '(':
508 case ')':
509 continue;
510
511 case 't':
512 case 'w':
513 case 'E':
514 insn.insn_opcode |= va_arg (args, int) << 16;
515 continue;
516
517 case 'c':
518 case 'T':
519 case 'W':
520 insn.insn_opcode |= va_arg (args, int) << 16;
521 continue;
522
523 case 'd':
524 case 'G':
525 insn.insn_opcode |= va_arg (args, int) << 11;
526 continue;
527
528 case 'V':
529 case 'S':
530 insn.insn_opcode |= va_arg (args, int) << 11;
531 continue;
532
533 case '<':
534 insn.insn_opcode |= va_arg (args, int) << 6;
535 continue;
536
537 case 'D':
538 insn.insn_opcode |= va_arg (args, int) << 6;
539 continue;
540
541 case 'B':
542 insn.insn_opcode |= va_arg (args, int) << 6;
543 continue;
544
545 case 'b':
546 case 's':
547 case 'r':
548 case 'v':
549 insn.insn_opcode |= va_arg (args, int) << 21;
550 continue;
551
552 case 'i':
553 case 'j':
554 case 'o':
555 r = BFD_RELOC_LO16;
556 continue;
557
558 case 'p':
559 assert (ep != NULL);
560 /*
561 * This allows macro() to pass an immediate expression for
562 * creating short branches without creating a symbol.
563 * Note that the expression still might come from the assembly
564 * input, in which case the value is not checked for range nor
565 * is a relocation entry generated (yuck).
566 */
567 if (ep->X_add_symbol == NULL && ep->X_seg == &bfd_abs_section)
568 {
569 insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff;
570 ep = NULL;
571 }
572 else
573 r = BFD_RELOC_16_PCREL_S2;
574 continue;
575
576 default:
577 internalError ();
578 }
579 break;
580 }
581 va_end (args);
582 assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
583
584 /* Use GP relative addressing if possible. */
585 if (r == BFD_RELOC_LO16
586 && gp_reference (ep))
587 r = BFD_RELOC_MIPS_GPREL;
588
589 append_insn (&insn, ep, r);
590 }
591
592 /*
593 * Generate a "lui" instruction.
594 */
595 static void
596 macro_build_lui (counter, ep, regnum)
597 int *counter;
598 expressionS *ep;
599 int regnum;
600 {
601 expressionS high_expr;
602 struct mips_cl_insn insn;
603 bfd_reloc_code_real_type r;
604 CONST char *name = "lui";
605 CONST char *fmt = "t,u";
606
607 high_expr = *ep;
608
609 if (high_expr.X_seg == &bfd_abs_section)
610 {
611 /* we can compute the instruction now without a relocation entry */
612 if (high_expr.X_add_number & 0x8000)
613 high_expr.X_add_number += 0x10000;
614 high_expr.X_add_number =
615 ((unsigned long) high_expr.X_add_number >> 16) & 0xffff;
616 r = BFD_RELOC_UNUSED;
617 }
618 else
619 r = BFD_RELOC_HI16_S;
620
621 /*
622 * If the macro is about to expand into a second instruction,
623 * print a warning if needed. We need to pass ip as a parameter
624 * to generate a better warning message here...
625 */
626 if (mips_warn_about_macros && *counter == 1)
627 as_warn ("Macro instruction expanded into multiple instructions");
628
629 *counter += 1; /* bump instruction counter */
630
631 insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
632 assert (insn.insn_mo);
633 assert (strcmp (name, insn.insn_mo->name) == 0);
634 assert (strcmp (fmt, insn.insn_mo->args) == 0);
635
636 insn.insn_opcode = insn.insn_mo->match | (regnum << 16);
637 if (r == BFD_RELOC_UNUSED)
638 {
639 insn.insn_opcode |= high_expr.X_add_number;
640 append_insn (&insn, NULL, r);
641 }
642 else
643 append_insn (&insn, &high_expr, r);
644 }
645
646 /* set_at()
647 * Generates code to set the $at register to true (one)
648 * if reg is less than the immediate expression.
649 */
650 static void
651 set_at (counter, reg)
652 int *counter;
653 int reg;
654 {
655
656 switch (imm_expr.X_add_number & 0xffff8000)
657 {
658 case 0:
659 case 0xffff8000:
660 macro_build (counter, &imm_expr, "slti", "t,r,j", AT, reg);
661 return;
662
663 case 0x8000:
664 macro_build (counter, &imm_expr, "ori", "t,r,i", AT, 0);
665 break;
666
667 default:
668 macro_build_lui (counter, &imm_expr, AT);
669 if (imm_expr.X_add_number & 0xffff)
670 macro_build (counter, &imm_expr, "addiu", "t,r,j", AT, AT);
671 }
672 macro_build (counter, NULL, "slt", "d,v,t", AT, reg, AT);
673 }
674
675 /* set_at_unsigned()
676 * Generates code to set the $at register to true (one)
677 * if reg is less than the immediate expression.
678 * Unsigned comparison is perfomed.
679 */
680 static void
681 set_at_unsigned (counter, reg)
682 int *counter;
683 int reg;
684 {
685
686 switch (imm_expr.X_add_number & 0xffff8000)
687 {
688 case 0:
689 case 0xffff8000:
690 macro_build (counter, &imm_expr, "sltiu", "t,r,j", AT, reg);
691 return;
692
693 case 0x8000:
694 macro_build (counter, &imm_expr, "ori", "t,r,i", AT, 0);
695 break;
696
697 default:
698 macro_build_lui (counter, &imm_expr, AT);
699 if (imm_expr.X_add_number & 0xffff)
700 macro_build (counter, &imm_expr, "addiu", "t,r,j", AT, AT);
701 }
702 macro_build (counter, NULL, "sltu", "d,v,t", AT, reg, AT);
703 }
704
705 static void
706 check_absolute_expr (ip, expr)
707 struct mips_cl_insn *ip;
708 expressionS *expr;
709 {
710
711 if (expr->X_seg != &bfd_abs_section)
712 as_warn ("Instruction %s requires absolute expression", ip->insn_mo->name);
713 }
714
715 /* load_register()
716 * This routine generates the least number of instructions neccessary to load
717 * an absolute expression value into a register.
718 */
719 static void
720 load_register (counter, ip, reg, ep)
721 int *counter;
722 struct mips_cl_insn *ip;
723 int reg;
724 expressionS *ep;
725 {
726 switch (ep->X_add_number & 0xffff8000)
727 {
728 case 0:
729 case 0xffff8000:
730 macro_build (counter, ep, "addiu", "t,r,j", reg, 0);
731 break;
732
733 case 0x8000:
734 macro_build (counter, ep, "ori", "t,r,i", reg, 0);
735 break;
736
737 default:
738 macro_build_lui (counter, ep, reg);
739 if (ep->X_add_number & 0xffff)
740 macro_build (counter, ep, "addiu", "t,r,j", reg, reg);
741 }
742 }
743
744
745 /*
746 * Build macros
747 * This routine implements the seemingly endless macro or synthesized
748 * instructions and addressing modes in the mips assembly language. Many
749 * of these macros are simple and are similar to each other. These could
750 * probably be handled by some kind of table or grammer aproach instead of
751 * this verbose method. Others are not simple macros but are more like
752 * optimizing code generation.
753 * One interesting optimization is when several store macros appear
754 * consecutivly that would load AT with the upper half of the same address.
755 * The ensuing load upper instructions are ommited. This implies some kind
756 * of global optimization. We currently only optimize within a single macro.
757 * For many of the load and store macros if the address is specified as a
758 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
759 * first load register 'at' with zero and use it as the base register. The
760 * mips assembler simply uses register $zero. Just one tiny optimization
761 * we're missing.
762 */
763 static void
764 macro (ip)
765 struct mips_cl_insn *ip;
766 {
767 register int treg, sreg, dreg, breg;
768 int tempreg;
769 int mask;
770 int icnt = 0;
771 int used_at;
772 int save_reorder_condition;
773 expressionS expr1;
774 const char *s;
775 const char *fmt;
776
777 treg = (ip->insn_opcode >> 16) & 0x1f;
778 dreg = (ip->insn_opcode >> 11) & 0x1f;
779 sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
780 mask = ip->insn_mo->mask;
781
782 expr1.X_seg = &bfd_abs_section;
783 expr1.X_subtract_symbol = NULL;
784 expr1.X_add_symbol = NULL;
785 expr1.X_add_number = 1;
786
787 switch (mask)
788 {
789 case M_ABS:
790 case M_ABSU:
791 /*
792 Note: mips algorithm requires the move in the delay slot.
793 <main>: bgez $a0,0x4001bc <main+12>
794 <main+4>: move v0,$a0
795 <main+8>: sub v0,$zero,$a0
796 <main+12>: nop
797 */
798
799 save_reorder_condition = mips_noreorder;
800 mips_noreorder = 1;
801
802 expr1.X_add_number = 8;
803 macro_build (&icnt, &expr1, "bgez", "s,p", sreg);
804 macro_build (&icnt, NULL, "move", "d,s", dreg, sreg, 0);
805 macro_build (&icnt, NULL, mask == M_ABS ? "sub" : "subu", "d,v,t",
806 dreg, 0, sreg);
807
808 mips_noreorder = save_reorder_condition;
809 return;
810
811 case M_ADD_I:
812 case M_ADDU_I:
813 switch (imm_expr.X_add_number & 0xffff8000)
814 {
815 case 0:
816 case 0xffff8000:
817 macro_build (&icnt, &imm_expr,
818 mask == M_ADD_I ? "addi" : "addiu", "t,r,j", treg, sreg);
819 return;
820
821 case 0x8000:
822 macro_build (&icnt, &imm_expr, "ori", "t,r,i", AT, 0);
823 break;
824
825 default:
826 macro_build_lui (&icnt, &imm_expr, AT);
827 if (imm_expr.X_add_number & 0xffff)
828 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", AT, AT);
829 break;
830 }
831 macro_build (&icnt, NULL,
832 mask == M_ADD_I ? "add" : "addu", "d,v,t", treg, sreg, AT);
833 break;
834
835 case M_AND_I:
836 case M_OR_I:
837 case M_NOR_I:
838 case M_XOR_I:
839 switch (imm_expr.X_add_number & 0xffff8000)
840 {
841 case 0:
842 case 0x8000:
843 switch (mask)
844 {
845 case M_AND_I:
846 macro_build (&icnt, &imm_expr, "andi", "t,r,i", treg, sreg);
847 return;
848 case M_OR_I:
849 macro_build (&icnt, &imm_expr, "ori", "t,r,i", treg, sreg);
850 return;
851 case M_NOR_I:
852 macro_build (&icnt, &imm_expr, "ori", "t,r,i", treg, sreg);
853 macro_build (&icnt, &imm_expr, "nor", "d,v,t", treg, treg, 0);
854 return;
855 case M_XOR_I:
856 macro_build (&icnt, &imm_expr, "xori", "t,r,i", treg, sreg);
857 return;
858 default:
859 internalError ();
860 }
861
862 case 0xffff8000:
863 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", AT, 0);
864 break;
865
866 default:
867 macro_build_lui (&icnt, &imm_expr, AT);
868 if (imm_expr.X_add_number & 0xffff)
869 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", AT, AT);
870 }
871 switch (mask)
872 {
873 case M_AND_I:
874 macro_build (&icnt, NULL, "and", "d,v,t", treg, sreg, AT);
875 break;
876 case M_OR_I:
877 macro_build (&icnt, NULL, "or", "d,v,t", treg, sreg, AT);
878 break;
879 case M_NOR_I:
880 macro_build (&icnt, NULL, "nor", "d,v,t", treg, sreg, AT);
881 break;
882 case M_XOR_I:
883 macro_build (&icnt, NULL, "xor", "d,v,t", treg, sreg, AT);
884 break;
885 default:
886 internalError ();
887 }
888 break;
889
890 case M_BEQ_I:
891 case M_BNE_I:
892 if (imm_expr.X_add_number == 0)
893 {
894 macro_build (&icnt, &offset_expr, mask == M_BEQ_I ? "beq" : "bne",
895 "s,t,p", sreg, 0);
896 return;
897 }
898 load_register (&icnt, ip, AT, &imm_expr);
899 macro_build (&icnt, &offset_expr, mask == M_BEQ_I ? "beq" : "bne",
900 "s,t,p", sreg, AT);
901 break;
902
903 case M_BGE:
904 if (treg == 0)
905 {
906 macro_build (&icnt, &offset_expr, "bgez", "s,p", sreg);
907 return;
908 }
909 if (sreg == 0)
910 {
911 macro_build (&icnt, &offset_expr, "blez", "s,p", treg);
912 return;
913 }
914 macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
915 macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
916 break;
917
918 case M_BGT_I:
919 /* check for > max integer */
920 if (imm_expr.X_add_number == 0x7fffffff)
921 {
922 do_false:
923 /* result is always false */
924 as_warn ("Branch %s is always false (nop)", ip->insn_mo->name);
925 macro_build (&icnt, NULL, "nop", "", 0);
926 return;
927 }
928 imm_expr.X_add_number++;
929 /* FALLTHROUGH */
930
931 case M_BGE_I:
932 if (imm_expr.X_add_number == 0)
933 {
934 macro_build (&icnt, &offset_expr, "bgez", "s,p", sreg);
935 return;
936 }
937 if (imm_expr.X_add_number == 1)
938 {
939 macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
940 return;
941 }
942 if (imm_expr.X_add_number == 0x80000000)
943 {
944 do_true:
945 /* result is always true */
946 as_warn ("Branch %s is always true", ip->insn_mo->name);
947 macro_build (&icnt, &offset_expr, "b", "p");
948 return;
949 }
950 set_at (&icnt, sreg);
951 macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
952 break;
953
954 case M_BGEU:
955 if (treg == 0)
956 goto do_true;
957 if (sreg == 0)
958 {
959 macro_build (&icnt, &offset_expr, "beq", "s,t,p", 0, treg);
960 return;
961 }
962 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
963 macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
964 break;
965
966 case M_BGTU_I:
967 if (sreg == 0 || imm_expr.X_add_number == 0xffffffff)
968 goto do_false;
969 imm_expr.X_add_number++;
970 /* FALLTHROUGH */
971
972 case M_BGEU_I:
973 if (imm_expr.X_add_number == 0)
974 goto do_true;
975 if (imm_expr.X_add_number == 1)
976 {
977 macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
978 return;
979 }
980 set_at_unsigned (&icnt, sreg);
981 macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
982 break;
983
984 case M_BGT:
985 if (treg == 0)
986 {
987 macro_build (&icnt, &offset_expr, "bgtz", "s,p", sreg);
988 return;
989 }
990 if (sreg == 0)
991 {
992 macro_build (&icnt, &offset_expr, "bltz", "s,p", treg);
993 return;
994 }
995 macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
996 macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
997 break;
998
999 case M_BGTU:
1000 if (treg == 0)
1001 {
1002 macro_build (&icnt, &offset_expr, "bne", "s,t,p", sreg, 0);
1003 return;
1004 }
1005 if (sreg == 0)
1006 goto do_false;
1007 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
1008 macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
1009 break;
1010
1011 case M_BLE:
1012 if (treg == 0)
1013 {
1014 macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
1015 return;
1016 }
1017 if (sreg == 0)
1018 {
1019 macro_build (&icnt, &offset_expr, "bgez", "s,p", treg);
1020 return;
1021 }
1022 macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
1023 macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
1024 break;
1025
1026 case M_BLE_I:
1027 if (imm_expr.X_add_number == 0x7fffffff)
1028 goto do_true;
1029 imm_expr.X_add_number++;
1030 /* FALLTHROUGH */
1031
1032 case M_BLT_I:
1033 if (imm_expr.X_add_number == 0)
1034 {
1035 macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
1036 return;
1037 }
1038 if (imm_expr.X_add_number == 1)
1039 {
1040 macro_build (&icnt, &offset_expr, "blez", "s,p", sreg);
1041 return;
1042 }
1043 set_at (&icnt, sreg);
1044 macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
1045 break;
1046
1047 case M_BLEU:
1048 if (treg == 0)
1049 {
1050 macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
1051 return;
1052 }
1053 if (sreg == 0)
1054 goto do_true;
1055 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
1056 macro_build (&icnt, &offset_expr, "beq", "s,t,p", AT, 0);
1057 break;
1058
1059 case M_BLEU_I:
1060 if (sreg == 0 || imm_expr.X_add_number == 0xffffffff)
1061 goto do_true;
1062 imm_expr.X_add_number++;
1063 /* FALLTHROUGH */
1064
1065 case M_BLTU_I:
1066 if (imm_expr.X_add_number == 0)
1067 goto do_false;
1068 if (imm_expr.X_add_number == 1)
1069 {
1070 macro_build (&icnt, &offset_expr, "beq", "s,t,p", sreg, 0);
1071 return;
1072 }
1073 set_at_unsigned (&icnt, sreg);
1074 macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
1075 break;
1076
1077 case M_BLT:
1078 if (treg == 0)
1079 {
1080 macro_build (&icnt, &offset_expr, "bltz", "s,p", sreg);
1081 return;
1082 }
1083 if (sreg == 0)
1084 {
1085 macro_build (&icnt, &offset_expr, "bgtz", "s,p", treg);
1086 return;
1087 }
1088 macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
1089 macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
1090 break;
1091
1092 case M_BLTU:
1093 if (treg == 0)
1094 goto do_false;
1095 if (sreg == 0)
1096 {
1097 macro_build (&icnt, &offset_expr, "bne", "s,t,p", 0, treg);
1098 return;
1099 }
1100 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
1101 macro_build (&icnt, &offset_expr, "bne", "s,t,p", AT, 0);
1102 break;
1103
1104 case M_DIV_3:
1105 case M_REM_3:
1106 if (treg == 0)
1107 {
1108 as_warn ("Divide by zero.");
1109 macro_build (&icnt, NULL, "break", "c", 7);
1110 return;
1111 }
1112
1113 save_reorder_condition = mips_noreorder;
1114 mips_noreorder = 1;
1115 macro_build (&icnt, NULL, "div", "s,t", sreg, treg);
1116 expr1.X_add_number = 8;
1117 macro_build (&icnt, &expr1, "bne", "s,t,p", treg, 0);
1118 macro_build (&icnt, NULL, "nop", "", 0);
1119 macro_build (&icnt, NULL, "break", "c", 7);
1120 expr1.X_add_number = -1;
1121 macro_build (&icnt, &expr1, "addiu", "t,r,j", AT, 0);
1122 expr1.X_add_number = 16;
1123 macro_build (&icnt, &expr1, "bne", "s,t,p", treg, AT);
1124 expr1.X_add_number = 0x80000000;
1125 macro_build_lui (&icnt, &expr1, AT);
1126 expr1.X_add_number = 8;
1127 macro_build (&icnt, &expr1, "bne", "s,t,p", sreg, AT);
1128 macro_build (&icnt, NULL, "nop", "", 0);
1129 macro_build (&icnt, NULL, "break", "c", 6);
1130 mips_noreorder = save_reorder_condition;
1131 macro_build (&icnt, NULL, mask == M_DIV_3 ? "mflo" : "mfhi", "d", dreg);
1132 /* with reorder on there will be two implicit nop instructions here. */
1133 break;
1134
1135 case M_DIV_3I:
1136 case M_DIVU_3I:
1137 case M_REM_3I:
1138 case M_REMU_3I:
1139 if (imm_expr.X_add_number == 0)
1140 {
1141 as_warn ("Divide by zero.");
1142 macro_build (&icnt, NULL, "break", "c", 7);
1143 return;
1144 }
1145 if (imm_expr.X_add_number == 1)
1146 {
1147 if (mask == (int) M_DIV_3I || mask == (int) M_DIVU_3I)
1148 macro_build (&icnt, NULL, "move", "d,s", dreg, sreg);
1149 else
1150 macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
1151 return;
1152 }
1153
1154 load_register (&icnt, ip, AT, &imm_expr);
1155 if (mask == (int) M_DIV_3I || mask == (int) M_REM_3I)
1156 macro_build (&icnt, NULL, "div", "s,t", sreg, AT);
1157 else
1158 macro_build (&icnt, NULL, "divu", "s,t", sreg, AT);
1159
1160 if (mask == (int) M_DIV_3I || mask == (int) M_DIVU_3I)
1161 macro_build (&icnt, NULL, "mflo", "d", dreg);
1162 else
1163 macro_build (&icnt, NULL, "mfhi", "d", dreg);
1164 /* two implicit nop's required for mflo or mfhi */
1165 break;
1166
1167 case M_DIVU_3:
1168 case M_REMU_3:
1169 save_reorder_condition = mips_noreorder;
1170 mips_noreorder = 1;
1171 macro_build (&icnt, NULL, "divu", "s,t", sreg, treg);
1172 expr1.X_add_number = 8;
1173 macro_build (&icnt, &expr1, "bne", "s,t,p", treg, 0);
1174 macro_build (&icnt, NULL, "nop", "", 0);
1175 macro_build (&icnt, NULL, "break", "c", 7);
1176 mips_noreorder = save_reorder_condition;
1177 macro_build (&icnt, NULL, mask == M_DIVU_3 ? "mflo" : "mfhi", "d", dreg);
1178 /* with reorder on there will be two implicit nop instructions here. */
1179 return;
1180
1181 case M_LA:
1182 if (offset_expr.X_seg == &bfd_abs_section)
1183 {
1184 load_register (&icnt, ip, treg, &offset_expr);
1185 return;
1186 }
1187 if (gp_reference (&offset_expr))
1188 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", treg, GP);
1189 else
1190 {
1191 macro_build_lui (&icnt, &offset_expr, treg);
1192 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", treg, treg);
1193 }
1194 return;
1195
1196 case M_LA_AB:
1197 tempreg = (breg == treg) ? AT : treg;
1198 if (offset_expr.X_seg == &bfd_abs_section)
1199 load_register (&icnt, ip, tempreg, &offset_expr);
1200 else if (gp_reference (&offset_expr))
1201 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", tempreg, GP);
1202 else
1203 {
1204 macro_build_lui (&icnt, &offset_expr, tempreg);
1205 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", tempreg, tempreg);
1206 }
1207 if (breg != 0)
1208 macro_build (&icnt, NULL, "addu", "d,v,t", treg, tempreg, breg);
1209 if (breg == treg)
1210 break;
1211 return;
1212
1213 case M_LB_AB:
1214 s = "lb";
1215 goto ld;
1216 case M_LBU_AB:
1217 s = "lbu";
1218 goto ld;
1219 case M_LH_AB:
1220 s = "lh";
1221 goto ld;
1222 case M_LHU_AB:
1223 s = "lhu";
1224 goto ld;
1225 case M_LW_AB:
1226 s = "lw";
1227 goto ld;
1228 case M_LWC0_AB:
1229 s = "lwc0";
1230 goto ld;
1231 case M_LWC1_AB:
1232 s = "lwc1";
1233 goto ld;
1234 case M_LWC2_AB:
1235 s = "lwc2";
1236 goto ld;
1237 case M_LWC3_AB:
1238 s = "lwc3";
1239 goto ld;
1240 case M_LWL_AB:
1241 s = "lwl";
1242 goto ld;
1243 case M_LWR_AB:
1244 s = "lwr";
1245 ld:
1246 if (breg == treg || mask == M_LWC1_AB)
1247 {
1248 tempreg = AT;
1249 used_at = 1;
1250 }
1251 else
1252 {
1253 tempreg = treg;
1254 used_at = 0;
1255 }
1256 goto ld_st;
1257 case M_SB_AB:
1258 s = "sb";
1259 goto st;
1260 case M_SH_AB:
1261 s = "sh";
1262 goto st;
1263 case M_SW_AB:
1264 s = "sw";
1265 goto st;
1266 case M_SWC0_AB:
1267 s = "swc0";
1268 goto st;
1269 case M_SWC1_AB:
1270 s = "swc1";
1271 goto st;
1272 case M_SWC2_AB:
1273 s = "swc2";
1274 goto st;
1275 case M_SWC3_AB:
1276 s = "swc3";
1277 goto st;
1278 case M_SWL_AB:
1279 s = "swl";
1280 goto st;
1281 case M_SWR_AB:
1282 s = "swr";
1283 st:
1284 tempreg = AT;
1285 used_at = 1;
1286 ld_st:
1287 if (mask == M_LWC1_AB || mask == M_SWC1_AB)
1288 fmt = "T,o(b)";
1289 else
1290 fmt = "t,o(b)";
1291 if (gp_reference (&offset_expr))
1292 {
1293 if (breg == 0)
1294 {
1295 macro_build (&icnt, &offset_expr, s, fmt, treg, GP);
1296 return;
1297 }
1298 macro_build (&icnt, (expressionS *) NULL, "addu", "d,v,t",
1299 tempreg, breg, GP);
1300 }
1301 else
1302 {
1303 macro_build_lui (&icnt, &offset_expr, tempreg);
1304 if (breg != 0)
1305 macro_build (&icnt, NULL, "addu", "d,v,t", tempreg, tempreg, breg);
1306 }
1307 macro_build (&icnt, &offset_expr, s, fmt, treg, tempreg);
1308 if (used_at)
1309 break;
1310 return;
1311
1312 case M_LI:
1313 load_register (&icnt, ip, treg, &imm_expr);
1314 return;
1315
1316 case M_LI_D:
1317 /*
1318 0x400370 <main>: lui $at,%hi(foo)
1319 0x400374 <main+4>: lw $v0,%lo(foo)($at)
1320 0x400378 <main+8>: lw $v1,%lo(foo+4)($at)
1321 .data
1322 <foo>:
1323 .float 3.133435
1324 */
1325 /* FIXME: I don't think this is used at present, because the 'F'
1326 format character is not supported. When this is supported,
1327 it should use the GP register. */
1328 macro_build_lui (&icnt, &offset_expr, AT);
1329 macro_build (&icnt, &offset_expr, "lw", "t,o(b)", treg, AT);
1330 offset_expr.X_add_number = 4;
1331 macro_build (&icnt, &offset_expr, "lw", "t,o(b)", treg + 1, AT);
1332 break;
1333
1334 case M_LI_DD:
1335 /*
1336 0x4003a0 <main>: lwc1 $f0,-32752($gp)
1337 0x4003a4 <main+4>: lwc1 $f1,-32748($gp)
1338 0x4003a8 <main+8>: nop
1339 */
1340 /* FIXME: This is nonsense. It isn't used anyhow. */
1341 sreg = (ip->insn_opcode >> 11) & 0x1f; /* Fs reg */
1342 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg, AT);
1343 offset_expr.X_add_number = 4;
1344 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg + 1, AT);
1345 break;
1346
1347 case M_L_DOB:
1348 /* Even on a big endian machine $fn comes before $fn+1. We have
1349 to adjust when loading from memory. */
1350 save_reorder_condition = mips_noreorder;
1351 mips_noreorder = 1;
1352 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
1353 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
1354 breg);
1355 /* unecessary implicit nop */
1356 mips_noreorder = save_reorder_condition;
1357 offset_expr.X_add_number += 4;
1358 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
1359 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
1360 breg);
1361 return;
1362
1363 case M_L_DAB:
1364 /*
1365 * The MIPS assembler seems to check for X_add_number not
1366 * being double aligned and generating:
1367 * lui at,%hi(foo+1)
1368 * addu at,at,v1
1369 * addiu at,at,%lo(foo+1)
1370 * lwc1 f2,0(at)
1371 * lwc1 f3,4(at)
1372 * But, the resulting address is the same after relocation so why
1373 * generate the extra instruction?
1374 */
1375 if (gp_reference (&offset_expr))
1376 {
1377 if (breg == 0)
1378 tempreg = GP;
1379 else
1380 {
1381 macro_build (&icnt, &offset_expr, "addu", "d,v,t", AT, breg, GP);
1382 tempreg = AT;
1383 }
1384 }
1385 else
1386 {
1387 macro_build_lui (&icnt, &offset_expr, AT);
1388 if (breg != 0)
1389 macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
1390 tempreg = AT;
1391 }
1392 /* Even on a big endian machine $fn comes before $fn+1. We have
1393 to adjust when loading from memory. */
1394 save_reorder_condition = mips_noreorder;
1395 mips_noreorder = 1;
1396 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
1397 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
1398 tempreg);
1399 /* unecessary implicit nop */
1400 mips_noreorder = save_reorder_condition;
1401 offset_expr.X_add_number += 4;
1402 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
1403 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
1404 tempreg);
1405 if (tempreg == AT)
1406 break;
1407 return;
1408
1409 case M_LD_OB:
1410 s = "lw";
1411 goto sd_ob;
1412 case M_SD_OB:
1413 s = "sw";
1414 sd_ob:
1415 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg, breg);
1416 offset_expr.X_add_number = 4;
1417 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg + 1, breg);
1418 return;
1419
1420 case M_LD_AB:
1421 s = "lw";
1422 if (breg == treg)
1423 {
1424 tempreg = AT;
1425 used_at = 1;
1426 }
1427 else
1428 {
1429 tempreg = treg;
1430 used_at = 0;
1431 }
1432 goto sd_ab;
1433 case M_SD_AB:
1434 s = "sw";
1435 tempreg = AT;
1436 used_at = 1;
1437 sd_ab:
1438 if (gp_reference (&offset_expr))
1439 {
1440 if (breg == 0)
1441 {
1442 tempreg = GP;
1443 used_at = 0;
1444 }
1445 else
1446 macro_build (&icnt, (expressionS *) NULL, "addu", "d,v,t",
1447 tempreg, breg, GP);
1448 }
1449 else
1450 {
1451 macro_build_lui (&icnt, &offset_expr, tempreg);
1452 if (breg != 0)
1453 macro_build (&icnt, NULL, "addu", "d,v,t", tempreg, tempreg, breg);
1454 }
1455 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg, tempreg);
1456 offset_expr.X_add_number += 4;
1457 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg + 1, tempreg);
1458 if (used_at)
1459 break;
1460 return;
1461
1462 case M_MUL:
1463 macro_build (&icnt, NULL, "multu", "s,t", sreg, treg);
1464 macro_build (&icnt, NULL, "mflo", "d", dreg);
1465 /* two implicit nop's required for mflo */
1466 return;
1467
1468 case M_MUL_I:
1469 /*
1470 * The mips assembler some times generates shifts and adds.
1471 * Im not trying to be that fancy. GCC should do this for us
1472 * anyway.
1473 */
1474 load_register (&icnt, ip, AT, &imm_expr);
1475 macro_build (&icnt, NULL, "mult", "s,t", sreg, AT);
1476 macro_build (&icnt, NULL, "mflo", "d", dreg);
1477 /* two implicit nop's required for mflo */
1478 break;
1479
1480 case M_ROL:
1481 macro_build (&icnt, NULL, "subu", "d,v,t", AT, 0, treg);
1482 macro_build (&icnt, NULL, "srlv", "d,t,s", AT, sreg, AT);
1483 macro_build (&icnt, NULL, "sllv", "d,t,s", dreg, sreg, treg);
1484 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
1485 break;
1486
1487 case M_ROL_I:
1488 macro_build (&icnt, NULL, "sll", "d,w,<", AT, sreg,
1489 imm_expr.X_add_number & 0x1f);
1490 macro_build (&icnt, NULL, "srl", "d,w,<", dreg, sreg,
1491 (0 - imm_expr.X_add_number) & 0x1f);
1492 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
1493 break;
1494
1495 case M_ROR:
1496 macro_build (&icnt, NULL, "subu", "d,v,t", AT, 0, treg);
1497 macro_build (&icnt, NULL, "sllv", "d,t,s", AT, sreg, AT);
1498 macro_build (&icnt, NULL, "srlv", "d,t,s", dreg, sreg, treg);
1499 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
1500 break;
1501
1502 case M_ROR_I:
1503 macro_build (&icnt, NULL, "srl", "d,w,<", AT, sreg,
1504 imm_expr.X_add_number & 0x1f);
1505 macro_build (&icnt, NULL, "sll", "d,w,<", dreg, sreg,
1506 (0 - imm_expr.X_add_number) & 0x1f);
1507 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
1508 break;
1509
1510 case M_S_DOB:
1511 /* Even on a big endian machine $fn comes before $fn+1. We have
1512 to adjust when storing to memory. */
1513 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
1514 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
1515 breg);
1516 offset_expr.X_add_number += 4;
1517 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
1518 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
1519 breg);
1520 return;
1521
1522 case M_S_DAB:
1523 if (gp_reference (&offset_expr))
1524 {
1525 if (breg == 0)
1526 tempreg = GP;
1527 else
1528 {
1529 macro_build (&icnt, (expressionS *) NULL, "addu", "d,v,t",
1530 AT, breg, GP);
1531 tempreg = AT;
1532 }
1533 }
1534 else
1535 {
1536 macro_build_lui (&icnt, &offset_expr, AT);
1537 if (breg != 0)
1538 macro_build (&icnt, NULL, "addu", "d,v,t", AT, AT, breg);
1539 tempreg = AT;
1540 }
1541 /* Even on a big endian machine $fn comes before $fn+1. We have
1542 to adjust when storing to memory. */
1543 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
1544 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
1545 tempreg);
1546 offset_expr.X_add_number += 4;
1547 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
1548 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
1549 tempreg);
1550 if (tempreg == AT)
1551 break;
1552 return;
1553
1554 case M_SEQ:
1555 if (sreg == 0)
1556 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, treg);
1557 else if (treg == 0)
1558 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, sreg);
1559 else
1560 {
1561 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, treg);
1562 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, dreg);
1563 }
1564 return;
1565
1566 case M_SEQ_I:
1567 if (imm_expr.X_add_number == 0)
1568 {
1569 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, sreg);
1570 return;
1571 }
1572 if (sreg == 0)
1573 {
1574 as_warn ("Instruction %s: result is always false",
1575 ip->insn_mo->name);
1576 macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
1577 return;
1578 }
1579 switch (imm_expr.X_add_number & 0xffff8000)
1580 {
1581 case 0:
1582 case 0x8000:
1583 macro_build (&icnt, &imm_expr, "xori", "t,r,i", dreg, sreg);
1584 used_at = 0;
1585 break;
1586
1587 case 0xffff8000:
1588 if (imm_expr.X_add_number != -32768)
1589 {
1590 imm_expr.X_add_number = -imm_expr.X_add_number;
1591 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", dreg, sreg);
1592 used_at = 0;
1593 break;
1594 }
1595 /* FALLTHROUGH */
1596
1597 default:
1598 macro_build_lui (&icnt, &imm_expr, AT);
1599 if (imm_expr.X_add_number & 0xffff)
1600 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", AT, AT);
1601 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, AT);
1602 used_at = 1;
1603 }
1604 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, dreg);
1605 if (used_at)
1606 break;
1607 return;
1608
1609 case M_SGE: /* sreg >= treg <==> not (sreg < treg) */
1610 s = "slt";
1611 goto sge;
1612 case M_SGEU:
1613 s = "sltu";
1614 sge:
1615 macro_build (&icnt, NULL, s, "d,v,t", dreg, sreg, treg);
1616 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
1617 return;
1618
1619 case M_SGE_I: /* sreg >= I <==> not (sreg < I) */
1620 case M_SGEU_I:
1621 if (imm_expr.X_add_number < 32768 && imm_expr.X_add_number > -32769)
1622 {
1623 macro_build (&icnt, &expr1,
1624 mask == M_SGE_I ? "slti" : "sltiu", "t,r,j", dreg, sreg);
1625 used_at = 0;
1626 }
1627 else
1628 {
1629 load_register (&icnt, ip, AT, &imm_expr);
1630 macro_build (&icnt, NULL,
1631 mask == M_SGE_I ? "slt" : "sltu", "d,v,t", dreg, sreg, AT);
1632 used_at = 1;
1633 }
1634 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
1635 if (used_at)
1636 break;
1637 return;
1638
1639 case M_SGT: /* sreg > treg <==> treg < sreg */
1640 s = "slt";
1641 goto sgt;
1642 case M_SGTU:
1643 s = "sltu";
1644 sgt:
1645 macro_build (&icnt, NULL, s, "d,v,t", dreg, treg, sreg);
1646 return;
1647
1648 case M_SGT_I: /* sreg > I <==> I < sreg */
1649 s = "slt";
1650 goto sgti;
1651 case M_SGTU_I:
1652 s = "sltu";
1653 sgti:
1654 load_register (&icnt, ip, AT, &imm_expr);
1655 macro_build (&icnt, NULL, s, "d,v,t", dreg, AT, sreg);
1656 break;
1657
1658 case M_SLE: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
1659 s = "slt";
1660 goto sle;
1661 case M_SLEU:
1662 s = "sltu";
1663 sle:
1664 macro_build (&icnt, NULL, s, "d,v,t", dreg, treg, sreg);
1665 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
1666 return;
1667
1668 case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
1669 s = "slt";
1670 goto slei;
1671 case M_SLEU_I:
1672 s = "sltu";
1673 slei:
1674 load_register (&icnt, ip, AT, &imm_expr);
1675 macro_build (&icnt, NULL, s, "d,v,t", dreg, AT, sreg);
1676 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
1677 break;
1678
1679 case M_SLT_I:
1680 if (imm_expr.X_add_number < 32768 && imm_expr.X_add_number > -32769)
1681 {
1682 macro_build (&icnt, &imm_expr, "slti", "t,r,j", dreg, sreg);
1683 return;
1684 }
1685 load_register (&icnt, ip, AT, &imm_expr);
1686 macro_build (&icnt, NULL, "slt", "d,v,t", dreg, sreg, AT);
1687 break;
1688
1689 case M_SLTU_I:
1690 if (imm_expr.X_add_number < 32768 && imm_expr.X_add_number > -32769)
1691 {
1692 macro_build (&icnt, &imm_expr, "sltiu", "t,r,j", dreg, sreg);
1693 return;
1694 }
1695 load_register (&icnt, ip, AT, &imm_expr);
1696 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, sreg, AT);
1697 break;
1698
1699 case M_SNE:
1700 if (sreg == 0)
1701 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, treg);
1702 else if (treg == 0)
1703 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, sreg);
1704 else
1705 {
1706 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, treg);
1707 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);
1708 }
1709 return;
1710
1711 case M_SNE_I:
1712 if (imm_expr.X_add_number == 0)
1713 {
1714 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, sreg);
1715 return;
1716 }
1717 if (sreg == 0)
1718 {
1719 as_warn ("Instruction %s: result is always true",
1720 ip->insn_mo->name);
1721 macro_build (&icnt, &expr1, "addiu", "t,r,j", dreg, 0);
1722 return;
1723 }
1724 switch (imm_expr.X_add_number & 0xffff8000)
1725 {
1726 case 0:
1727 case 0x8000:
1728 macro_build (&icnt, &imm_expr, "xori", "t,r,i", dreg, sreg);
1729 used_at = 0;
1730 break;
1731
1732 case 0xffff8000:
1733 if (imm_expr.X_add_number != -32768)
1734 {
1735 imm_expr.X_add_number = -imm_expr.X_add_number;
1736 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", dreg, sreg);
1737 used_at = 0;
1738 break;
1739 }
1740 /* FALLTHROUGH */
1741
1742 default:
1743 macro_build_lui (&icnt, &imm_expr, AT);
1744 if (imm_expr.X_add_number & 0xffff)
1745 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", AT, AT);
1746 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, AT);
1747 used_at = 1;
1748 }
1749 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);
1750 if (used_at)
1751 break;
1752 return;
1753
1754 case M_SUB_I:
1755 if (imm_expr.X_add_number < 32768 && imm_expr.X_add_number > -32768)
1756 {
1757 imm_expr.X_add_number = -imm_expr.X_add_number;
1758 macro_build (&icnt, &imm_expr, "addi", "t,r,j", dreg, sreg);
1759 return;
1760 }
1761 load_register (&icnt, ip, AT, &imm_expr);
1762 macro_build (&icnt, NULL, "sub", "d,v,t", dreg, sreg, AT);
1763 break;
1764
1765 case M_SUBU_I:
1766 if (imm_expr.X_add_number < 32768 && imm_expr.X_add_number > -32768)
1767 {
1768 imm_expr.X_add_number = -imm_expr.X_add_number;
1769 macro_build (&icnt, &imm_expr, "addiu", "t,r,j", dreg, sreg);
1770 return;
1771 }
1772 load_register (&icnt, ip, AT, &imm_expr);
1773 macro_build (&icnt, NULL, "subu", "d,v,t", dreg, sreg, AT);
1774 break;
1775
1776 case M_TRUNCWD:
1777 case M_TRUNCWS:
1778 sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
1779 dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
1780
1781 /*
1782 * Is the double cfc1 instruction a bug in the mips assembler;
1783 * or is there a reason for it?
1784 */
1785 save_reorder_condition = mips_noreorder;
1786 mips_noreorder = 1;
1787 macro_build (&icnt, NULL, "cfc1", "t,G", treg, 31);
1788 macro_build (&icnt, NULL, "cfc1", "t,G", treg, 31);
1789 macro_build (&icnt, NULL, "nop", "");
1790 expr1.X_add_number = 3;
1791 macro_build (&icnt, &expr1, "ori", "t,r,i", AT, treg);
1792 expr1.X_add_number = 2;
1793 macro_build (&icnt, &expr1, "xori", "t,r,i", AT, AT);
1794 macro_build (&icnt, NULL, "ctc1", "t,G", AT, 31);
1795 macro_build (&icnt, NULL, "nop", "");
1796 macro_build (&icnt, NULL,
1797 mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg);
1798 macro_build (&icnt, NULL, "ctc1", "t,G", treg, 31);
1799 macro_build (&icnt, NULL, "nop", "");
1800 mips_noreorder = save_reorder_condition;
1801 break;
1802
1803 case M_ULH:
1804 s = "lb";
1805 goto ulh;
1806 case M_ULHU:
1807 s = "lbu";
1808 ulh:
1809 /* avoid load delay */
1810 offset_expr.X_add_number += 1;
1811 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg, breg);
1812 offset_expr.X_add_number -= 1;
1813 macro_build (&icnt, &offset_expr, "lbu", "t,o(b)", AT, breg);
1814 macro_build (&icnt, NULL, "sll", "d,w,<", treg, treg, 8);
1815 macro_build (&icnt, NULL, "or", "d,v,t", treg, treg, AT);
1816 break;
1817
1818 case M_ULW:
1819 /* does this work on a big endian machine? */
1820 offset_expr.X_add_number += 3;
1821 macro_build (&icnt, &offset_expr, "lwl", "t,o(b)", treg, breg);
1822 offset_expr.X_add_number -= 3;
1823 macro_build (&icnt, &offset_expr, "lwr", "t,o(b)", treg, breg);
1824 return;
1825
1826 case M_ULH_A:
1827 case M_ULHU_A:
1828 case M_ULW_A:
1829 if (offset_expr.X_seg == &bfd_abs_section)
1830 load_register (&icnt, ip, AT, &offset_expr);
1831 else if (gp_reference (&offset_expr))
1832 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", AT, GP);
1833 else
1834 {
1835 macro_build_lui (&icnt, &offset_expr, AT);
1836 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", AT, AT);
1837 }
1838 if (mask == M_ULW_A)
1839 {
1840 expr1.X_add_number = 3;
1841 macro_build (&icnt, &expr1, "lwl", "t,o(b)", treg, AT);
1842 imm_expr.X_add_number = 0;
1843 macro_build (&icnt, &expr1, "lwr", "t,o(b)", treg, AT);
1844 }
1845 else
1846 {
1847 macro_build (&icnt, &expr1,
1848 mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg, AT);
1849 imm_expr.X_add_number = 0;
1850 macro_build (&icnt, &expr1, "lbu", "t,o(b)", AT, AT);
1851 macro_build (&icnt, NULL, "sll", "d,w,<", treg, treg, 8);
1852 macro_build (&icnt, NULL, "or", "d,v,t", treg, treg, AT);
1853 }
1854 break;
1855
1856 case M_USH:
1857 macro_build (&icnt, &offset_expr, "sb", "t,o(b)", treg, breg);
1858 macro_build (&icnt, NULL, "srl", "d,w,<", AT, treg, 8);
1859 offset_expr.X_add_number += 1;
1860 macro_build (&icnt, &offset_expr, "sb", "t,o(b)", AT, breg);
1861 break;
1862
1863 case M_USW:
1864 offset_expr.X_add_number += 3;
1865 macro_build (&icnt, &offset_expr, "swl", "t,o(b)", treg, breg);
1866 offset_expr.X_add_number -= 3;
1867 macro_build (&icnt, &offset_expr, "swr", "t,o(b)", treg, breg);
1868 return;
1869
1870 case M_USH_A:
1871 case M_USW_A:
1872 if (offset_expr.X_seg == &bfd_abs_section)
1873 load_register (&icnt, ip, AT, &offset_expr);
1874 else if (gp_reference (&offset_expr))
1875 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", AT, GP);
1876 else
1877 {
1878 macro_build_lui (&icnt, &offset_expr, AT);
1879 macro_build (&icnt, &offset_expr, "addiu", "t,r,j", AT, AT);
1880 }
1881 if (mask == M_USW_A)
1882 {
1883 expr1.X_add_number = 3;
1884 macro_build (&icnt, &expr1, "swl", "t,o(b)", treg, AT);
1885 expr1.X_add_number = 0;
1886 macro_build (&icnt, &expr1, "swr", "t,o(b)", treg, AT);
1887 }
1888 else
1889 {
1890 expr1.X_add_number = 0;
1891 macro_build (&icnt, &expr1, "sb", "t,o(b)", treg, AT);
1892 macro_build (&icnt, NULL, "srl", "d,w,<", treg, treg, 8);
1893 expr1.X_add_number = 1;
1894 macro_build (&icnt, &expr1, "sb", "t,o(b)", treg, AT);
1895 expr1.X_add_number = 0;
1896 macro_build (&icnt, &expr1, "lbu", "t,o(b)", AT, AT);
1897 macro_build (&icnt, NULL, "sll", "d,w,<", treg, treg, 8);
1898 macro_build (&icnt, NULL, "or", "d,v,t", treg, treg, AT);
1899 }
1900 break;
1901
1902 default:
1903 as_bad ("Macro %s not implemented yet", ip->insn_mo->name);
1904 }
1905 if (mips_noat)
1906 as_warn ("Macro used $at after \".set noat\"");
1907 }
1908
1909
1910 /*
1911 This routine assembles an instruction into its binary format. As a side
1912 effect it sets one of the global variables imm_reloc or offset_reloc to the
1913 type of relocation to do if one of the operands is an address expression.
1914 */
1915 static void
1916 mips_ip (str, ip)
1917 char *str;
1918 struct mips_cl_insn *ip;
1919 {
1920 char *s;
1921 const char *args;
1922 char c;
1923 struct mips_opcode *insn;
1924 char *argsStart;
1925 unsigned int regno;
1926 unsigned int lastregno = 0;
1927 char *s_reset;
1928
1929 insn_error = NULL;
1930
1931 for (s = str; islower (*s) || (*s >= '0' && *s <= '3') || *s == '.'; ++s)
1932 continue;
1933 switch (*s)
1934 {
1935 case '\0':
1936 break;
1937
1938 case ' ':
1939 *s++ = '\0';
1940 break;
1941
1942 default:
1943 as_warn ("Unknown opcode: `%s'", str);
1944 exit (1);
1945 }
1946 if ((insn = (struct mips_opcode *) hash_find (op_hash, str)) == NULL)
1947 {
1948 as_warn ("`%s' not in hash table.", str);
1949 insn_error = "ERROR: Unrecognized opcode";
1950 return;
1951 }
1952 argsStart = s;
1953 for (;;)
1954 {
1955 assert (strcmp (insn->name, str) == 0);
1956 ip->insn_mo = insn;
1957 ip->insn_opcode = insn->match;
1958 for (args = insn->args;; ++args)
1959 {
1960 if (*s == ' ')
1961 ++s;
1962 switch (*args)
1963 {
1964 case '\0': /* end of args */
1965 if (*s == '\0')
1966 return;
1967 break;
1968
1969 case ',':
1970 if (*s++ == *args)
1971 continue;
1972 s--;
1973 switch (*++args)
1974 {
1975 case 'r':
1976 case 'v':
1977 ip->insn_opcode |= lastregno << 21;
1978 continue;
1979
1980 case 'w':
1981 case 'W':
1982 ip->insn_opcode |= lastregno << 16;
1983 continue;
1984
1985 case 'V':
1986 ip->insn_opcode |= lastregno << 11;
1987 continue;
1988 }
1989 break;
1990
1991 case '(':
1992 /* handle optional base register.
1993 Either the base register is omitted or
1994 we must have a left paren. */
1995 /* this is dependent on the next operand specifier
1996 is a 'b' for base register */
1997 assert (args[1] == 'b');
1998 if (*s == '\0')
1999 return;
2000
2001 case ')': /* these must match exactly */
2002 if (*s++ == *args)
2003 continue;
2004 break;
2005
2006 case '<': /* must be at least one digit */
2007 /*
2008 * According to the manual, if the shift amount is greater
2009 * than 31 or less than 0 the the shift amount should be
2010 * mod 32. In reality the mips assembler issues an error.
2011 * We issue a warning and do the mod.
2012 */
2013 my_getExpression (&imm_expr, s);
2014 check_absolute_expr (ip, &imm_expr);
2015 if ((unsigned long) imm_expr.X_add_number > 31)
2016 {
2017 as_warn ("Improper shift amount (%d)",
2018 imm_expr.X_add_number);
2019 imm_expr.X_add_number = imm_expr.X_add_number % 32;
2020 }
2021 ip->insn_opcode |= imm_expr.X_add_number << 6;
2022 imm_expr.X_seg = absent_section;
2023 s = expr_end;
2024 continue;
2025
2026 case 'c': /* break code */
2027 my_getExpression (&imm_expr, s);
2028 check_absolute_expr (ip, &imm_expr);
2029 if ((unsigned) imm_expr.X_add_number > 1023)
2030 as_warn ("Illegal break code (%d)", imm_expr.X_add_number);
2031 ip->insn_opcode |= imm_expr.X_add_number << 16;
2032 imm_expr.X_seg = absent_section;
2033 s = expr_end;
2034 continue;
2035
2036 case 'B': /* syscall code */
2037 my_getExpression (&imm_expr, s);
2038 check_absolute_expr (ip, &imm_expr);
2039 if ((unsigned) imm_expr.X_add_number > 0xfffff)
2040 as_warn ("Illegal syscall code (%d)", imm_expr.X_add_number);
2041 ip->insn_opcode |= imm_expr.X_add_number << 6;
2042 imm_expr.X_seg = absent_section;
2043 s = expr_end;
2044 continue;
2045
2046 case 'b': /* base register */
2047 case 'd': /* destination register */
2048 case 's': /* source register */
2049 case 't': /* target register */
2050 case 'r': /* both target and source */
2051 case 'v': /* both dest and source */
2052 case 'w': /* both dest and target */
2053 case 'E': /* coprocessor target register */
2054 case 'G': /* coprocessor destination register */
2055 s_reset = s;
2056 if (s[0] == '$')
2057 {
2058 if (isdigit (s[1]))
2059 {
2060 ++s;
2061 regno = 0;
2062 do
2063 {
2064 regno *= 10;
2065 regno += *s - '0';
2066 ++s;
2067 }
2068 while (isdigit (*s));
2069 }
2070 else if (s[1] == 'f' && s[2] == 'p')
2071 {
2072 s += 3;
2073 regno = 30;
2074 }
2075 else if (s[1] == 's' && s[2] == 'p')
2076 {
2077 s += 3;
2078 regno = 29;
2079 }
2080 else if (s[1] == 'g' && s[2] == 'p')
2081 {
2082 s += 3;
2083 regno = 28;
2084 }
2085 else if (s[1] == 'a' && s[2] == 't')
2086 {
2087 s += 3;
2088 regno = 1;
2089 }
2090 else
2091 goto notreg;
2092 if (regno > 31)
2093 as_bad ("Invalid register number (%d)", regno);
2094 if (regno == AT && !mips_noat)
2095 as_warn ("Used $at without \".set noat\"");
2096 c = *args;
2097 if (*s == ' ')
2098 s++;
2099 if (args[1] != *s)
2100 {
2101 if (c == 'r' || c == 'v' || c == 'w')
2102 {
2103 regno = lastregno;
2104 s = s_reset;
2105 args++;
2106 }
2107 }
2108 switch (c)
2109 {
2110 case 'r':
2111 case 's':
2112 case 'v':
2113 case 'b':
2114 ip->insn_opcode |= regno << 21;
2115 break;
2116 case 'd':
2117 case 'G':
2118 ip->insn_opcode |= regno << 11;
2119 break;
2120 case 'w':
2121 case 't':
2122 case 'E':
2123 ip->insn_opcode |= regno << 16;
2124 }
2125 lastregno = regno;
2126 continue;
2127 }
2128 notreg:
2129 switch (*args++)
2130 {
2131 case 'r':
2132 case 'v':
2133 ip->insn_opcode |= lastregno << 21;
2134 continue;
2135 case 'w':
2136 ip->insn_opcode |= lastregno << 16;
2137 continue;
2138 }
2139 break;
2140
2141 case 'D': /* floating point destination register */
2142 case 'S': /* floating point source register */
2143 case 'T': /* floating point target register */
2144 case 'V':
2145 case 'W':
2146 s_reset = s;
2147 if (s[0] == '$' && s[1] == 'f' && isdigit (s[2]))
2148 {
2149 s += 2;
2150 regno = 0;
2151 do
2152 {
2153 regno *= 10;
2154 regno += *s - '0';
2155 ++s;
2156 }
2157 while (isdigit (*s));
2158
2159 if (regno > 31)
2160 as_bad ("Invalid float register number (%d)", regno);
2161
2162 if ((regno & 1) &&
2163 !(strcmp (str, "mtc1") == 0 ||
2164 strcmp (str, "mfc1") == 0 ||
2165 strcmp (str, "lwc1") == 0 ||
2166 strcmp (str, "swc1") == 0))
2167 as_warn ("Float register should be even, was %d",
2168 regno);
2169
2170 c = *args;
2171 if (*s == ' ')
2172 s++;
2173 if (args[1] != *s)
2174 {
2175 if (c == 'V' || c == 'W')
2176 {
2177 regno = lastregno;
2178 s = s_reset;
2179 args++;
2180 }
2181 }
2182 switch (c)
2183 {
2184 case 'D':
2185 ip->insn_opcode |= regno << 6;
2186 break;
2187 case 'V':
2188 case 'S':
2189 ip->insn_opcode |= regno << 11;
2190 break;
2191 case 'W':
2192 case 'T':
2193 ip->insn_opcode |= regno << 16;
2194 }
2195 lastregno = regno;
2196 continue;
2197 }
2198 switch (*args++)
2199 {
2200 case 'V':
2201 ip->insn_opcode |= lastregno << 11;
2202 continue;
2203 case 'W':
2204 ip->insn_opcode |= lastregno << 16;
2205 continue;
2206 }
2207 break;
2208
2209 case 'I':
2210 my_getExpression (&imm_expr, s);
2211 check_absolute_expr (ip, &imm_expr);
2212 s = expr_end;
2213 continue;
2214
2215 case 'A':
2216 my_getExpression (&offset_expr, s);
2217 imm_reloc = BFD_RELOC_32;
2218 s = expr_end;
2219 continue;
2220
2221 case 'F':
2222 as_bad ("Floating point constants only implemented for pseudo ops.");
2223 continue;
2224
2225 case 'i': /* 16 bit unsigned immediate */
2226 case 'j': /* 16 bit signed immediate */
2227 imm_reloc = BFD_RELOC_LO16;
2228 c = my_getSmallExpression (&imm_expr, s);
2229 if (c)
2230 {
2231 if (c != 'l')
2232 {
2233 if (imm_expr.X_seg == &bfd_abs_section)
2234 imm_expr.X_add_number =
2235 (imm_expr.X_add_number >> 16) & 0xffff;
2236 else if (c == 'h')
2237 imm_reloc = BFD_RELOC_HI16_S;
2238 else
2239 imm_reloc = BFD_RELOC_HI16;
2240 }
2241 }
2242 else
2243 check_absolute_expr (ip, &imm_expr);
2244 if (*args == 'i')
2245 {
2246 if ((unsigned long) imm_expr.X_add_number > 65535)
2247 as_bad ("16 bit expression not in range 0..65535");
2248 }
2249 else
2250 {
2251 if (imm_expr.X_add_number < -32768 ||
2252 imm_expr.X_add_number > 32767)
2253 as_bad ("16 bit expression not in range -32768..32767");
2254 }
2255 s = expr_end;
2256 continue;
2257
2258 case 'o': /* 16 bit offset */
2259 c = my_getSmallExpression (&offset_expr, s);
2260 /*
2261 * If this value won't fit into a 16 bit offset, then
2262 * go find a macro that will generate the 32 bit offset
2263 * code pattern.
2264 */
2265 if ((offset_expr.X_add_symbol
2266 && offset_expr.X_seg != &bfd_abs_section)
2267 || offset_expr.X_subtract_symbol
2268 || offset_expr.X_add_number > 32767
2269 || offset_expr.X_add_number < -32768)
2270 break;
2271
2272 offset_reloc = BFD_RELOC_LO16;
2273 if (c == 'h' || c == 'H')
2274 offset_expr.X_add_number =
2275 (offset_expr.X_add_number >> 16) & 0xffff;
2276 s = expr_end;
2277 continue;
2278
2279 case 'p': /* pc relative offset */
2280 offset_reloc = BFD_RELOC_16_PCREL_S2;
2281 my_getExpression (&offset_expr, s);
2282 s = expr_end;
2283 continue;
2284
2285 case 'u': /* upper 16 bits */
2286 c = my_getSmallExpression (&imm_expr, s);
2287 if ((unsigned long) imm_expr.X_add_number > 65535)
2288 as_bad ("lui expression not in range 0..65535");
2289 imm_reloc = BFD_RELOC_LO16;
2290 if (c)
2291 {
2292 if (c != 'l')
2293 {
2294 if (imm_expr.X_seg == &bfd_abs_section)
2295 imm_expr.X_add_number =
2296 (imm_expr.X_add_number >> 16) & 0xffff;
2297 else if (c == 'h')
2298 imm_reloc = BFD_RELOC_HI16_S;
2299 else
2300 imm_reloc = BFD_RELOC_HI16;
2301 }
2302 }
2303 s = expr_end;
2304 continue;
2305
2306 case 'a': /* 26 bit address */
2307 my_getExpression (&offset_expr, s);
2308 s = expr_end;
2309 offset_reloc = BFD_RELOC_MIPS_JMP;
2310 continue;
2311
2312 default:
2313 fprintf (stderr, "bad char = '%c'\n", *args);
2314 internalError ();
2315 }
2316 break;
2317 }
2318 /* Args don't match. */
2319 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
2320 !strcmp (insn->name, insn[1].name))
2321 {
2322 ++insn;
2323 s = argsStart;
2324 continue;
2325 }
2326 insn_error = "ERROR: Illegal operands";
2327 return;
2328 }
2329 }
2330
2331 #define LP '('
2332 #define RP ')'
2333
2334 static int
2335 my_getSmallExpression (ep, str)
2336 expressionS *ep;
2337 char *str;
2338 {
2339 char *sp;
2340 int c = 0;
2341
2342 if (*str == ' ')
2343 str++;
2344 if (*str == LP
2345 || (*str == '%' &&
2346 ((str[1] == 'h' && str[2] == 'i')
2347 || (str[1] == 'H' && str[2] == 'I')
2348 || (str[1] == 'l' && str[2] == 'o'))
2349 && str[3] == LP))
2350 {
2351 if (*str == LP)
2352 c = 0;
2353 else
2354 {
2355 c = str[1];
2356 str += 3;
2357 }
2358
2359 /*
2360 * A small expression may be followed by a base register.
2361 * Scan to the end of this operand, and then back over a possible
2362 * base register. Then scan the small expression up to that
2363 * point. (Based on code in sparc.c...)
2364 */
2365 for (sp = str; *sp && *sp != ','; sp++)
2366 ;
2367 if (sp - 4 >= str && sp[-1] == RP)
2368 {
2369 if (isdigit (sp[-2]))
2370 {
2371 for (sp -= 3; sp >= str && isdigit (*sp); sp--)
2372 ;
2373 if (*sp == '$' && sp > str && sp[-1] == LP)
2374 {
2375 sp--;
2376 goto do_it;
2377 }
2378 }
2379 else if (sp - 5 >= str
2380 && sp[-5] == LP
2381 && sp[-4] == '$'
2382 && ((sp[-3] == 'f' && sp[-2] == 'p')
2383 || (sp[-3] == 's' && sp[-2] == 'p')
2384 || (sp[-3] == 'g' && sp[-2] == 'p')
2385 || (sp[-3] == 'a' && sp[-2] == 't')))
2386 {
2387 sp -= 5;
2388 do_it:
2389 if (sp == str)
2390 {
2391 /* no expression means zero offset */
2392 if (c)
2393 {
2394 /* %xx(reg) is an error */
2395 ep->X_seg = absent_section;
2396 expr_end = str - 3;
2397 }
2398 else
2399 {
2400 ep->X_seg = &bfd_abs_section;
2401 expr_end = sp;
2402 }
2403 ep->X_add_symbol = NULL;
2404 ep->X_subtract_symbol = NULL;
2405 ep->X_add_number = 0;
2406 }
2407 else
2408 {
2409 *sp = '\0';
2410 my_getExpression (ep, str);
2411 *sp = LP;
2412 }
2413 return c;
2414 }
2415 }
2416 }
2417 my_getExpression (ep, str);
2418 return c; /* => %hi or %lo encountered */
2419 }
2420
2421 static void
2422 my_getExpression (ep, str)
2423 expressionS *ep;
2424 char *str;
2425 {
2426 char *save_in;
2427 asection *seg;
2428
2429 save_in = input_line_pointer;
2430 input_line_pointer = str;
2431 seg = expression (ep);
2432 expr_end = input_line_pointer;
2433 input_line_pointer = save_in;
2434 }
2435
2436 char *
2437 md_atof (type, litP, sizeP)
2438 char type;
2439 char *litP;
2440 int *sizeP;
2441 {
2442 internalError ();
2443 return NULL;
2444 }
2445
2446 void
2447 md_number_to_chars (buf, val, n)
2448 char *buf;
2449 valueT val;
2450 int n;
2451 {
2452 switch (byte_order)
2453 {
2454 case LITTLE_ENDIAN:
2455 switch (n)
2456 {
2457 case 4:
2458 *buf++ = val;
2459 *buf++ = val >> 8;
2460 *buf++ = val >> 16;
2461 *buf = val >> 24;
2462 return;
2463
2464 case 2:
2465 *buf++ = val;
2466 *buf = val >> 8;
2467 return;
2468
2469 case 1:
2470 *buf = val;
2471 return;
2472
2473 default:
2474 internalError ();
2475 }
2476
2477 case BIG_ENDIAN:
2478 switch (n)
2479 {
2480 case 4:
2481 *buf++ = val >> 24;
2482 *buf++ = val >> 16;
2483 case 2:
2484 *buf++ = val >> 8;
2485 case 1:
2486 *buf = val;
2487 return;
2488
2489 default:
2490 internalError ();
2491 }
2492
2493 default:
2494 internalError ();
2495 }
2496 }
2497
2498 int
2499 md_parse_option (argP, cntP, vecP)
2500 char **argP;
2501 int *cntP;
2502 char ***vecP;
2503 {
2504 /* Accept -nocpp but ignore it. */
2505 if (!strcmp (*argP, "nocpp"))
2506 {
2507 *argP += 5;
2508 return 1;
2509 }
2510
2511 if (strcmp (*argP, "EL") == 0
2512 || strcmp (*argP, "EB") == 0)
2513 {
2514 /* FIXME: This breaks -L -EL. */
2515 flagseen['L'] = 0;
2516 *argP = "";
2517 return 1;
2518 }
2519
2520 #ifdef OBJ_ECOFF
2521 if (**argP == 'G')
2522 {
2523 if ((*argP)[1] != '\0')
2524 g_switch_value = atoi (*argP + 1);
2525 else if (*cntP)
2526 {
2527 **vecP = (char *) NULL;
2528 (*cntP)--;
2529 (*vecP)++;
2530 g_switch_value = atoi (**vecP);
2531 }
2532 else
2533 as_warn ("Number expected after -G");
2534 *argP = "";
2535 return 1;
2536 }
2537 #endif
2538 return 1; /* pretend you parsed the character */
2539 }
2540
2541 long
2542 md_pcrel_from (fixP)
2543 fixS *fixP;
2544 {
2545 /* return the address of the delay slot */
2546 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2547 }
2548
2549 int
2550 md_apply_fix (fixP, valueP)
2551 fixS *fixP;
2552 valueT *valueP;
2553 {
2554 unsigned char *buf;
2555 long insn, value;
2556
2557 assert (fixP->fx_size == 4);
2558
2559 value = *valueP;
2560 fixP->fx_addnumber = value; /* Remember value for tc_gen_reloc */
2561
2562 switch (fixP->fx_r_type)
2563 {
2564 case BFD_RELOC_32:
2565 case BFD_RELOC_MIPS_JMP:
2566 case BFD_RELOC_HI16:
2567 case BFD_RELOC_HI16_S:
2568 case BFD_RELOC_LO16:
2569 case BFD_RELOC_MIPS_GPREL:
2570 /* Nothing needed to do. The value comes from the reloc entry */
2571 return 1;
2572
2573 case BFD_RELOC_16_PCREL_S2:
2574 /*
2575 * We need to save the bits in the instruction since fixup_segment()
2576 * might be deleting the relocation entry (i.e., a branch within
2577 * the current segment).
2578 */
2579 if (value & 0x3)
2580 as_warn ("Branch to odd address (%x)", value);
2581 value >>= 2;
2582 if ((value & ~0xFFFF) && (value & ~0xFFFF) != (-1 & ~0xFFFF))
2583 as_bad ("Relocation overflow");
2584
2585 /* update old instruction data */
2586 buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
2587 switch (byte_order)
2588 {
2589 case LITTLE_ENDIAN:
2590 insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2591 break;
2592
2593 case BIG_ENDIAN:
2594 insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
2595 break;
2596
2597 default:
2598 internalError ();
2599 return 0;
2600 }
2601 insn |= value & 0xFFFF;
2602 md_number_to_chars ((char *) buf, insn, 4);
2603 break;
2604
2605 default:
2606 internalError ();
2607 }
2608 return 1;
2609 }
2610
2611 #if 0
2612 void
2613 printInsn (oc)
2614 unsigned long oc;
2615 {
2616 const struct mips_opcode *p;
2617 int treg, sreg, dreg, shamt;
2618 short imm;
2619 const char *args;
2620 int i;
2621
2622 for (i = 0; i < NUMOPCODES; ++i)
2623 {
2624 p = &mips_opcodes[i];
2625 if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))
2626 {
2627 printf ("%08lx %s\t", oc, p->name);
2628 treg = (oc >> 16) & 0x1f;
2629 sreg = (oc >> 21) & 0x1f;
2630 dreg = (oc >> 11) & 0x1f;
2631 shamt = (oc >> 6) & 0x1f;
2632 imm = oc;
2633 for (args = p->args;; ++args)
2634 {
2635 switch (*args)
2636 {
2637 case '\0':
2638 printf ("\n");
2639 break;
2640
2641 case ',':
2642 case '(':
2643 case ')':
2644 printf ("%c", *args);
2645 continue;
2646
2647 case 'r':
2648 assert (treg == sreg);
2649 printf ("$%d,$%d", treg, sreg);
2650 continue;
2651
2652 case 'd':
2653 case 'G':
2654 printf ("$%d", dreg);
2655 continue;
2656
2657 case 't':
2658 case 'E':
2659 printf ("$%d", treg);
2660 continue;
2661
2662 case 'b':
2663 case 's':
2664 printf ("$%d", sreg);
2665 continue;
2666
2667 case 'a':
2668 printf ("0x%08lx", oc & 0x1ffffff);
2669 continue;
2670
2671 case 'i':
2672 case 'j':
2673 case 'o':
2674 case 'u':
2675 printf ("%d", imm);
2676 continue;
2677
2678 case '<':
2679 printf ("$%d", shamt);
2680 continue;
2681
2682 default:
2683 internalError ();
2684 }
2685 break;
2686 }
2687 return;
2688 }
2689 }
2690 printf ("%08lx UNDEFINED\n", oc);
2691 }
2692 #endif
2693
2694 static symbolS *
2695 get_symbol ()
2696 {
2697 int c;
2698 char *name;
2699 symbolS *p;
2700
2701 name = input_line_pointer;
2702 c = get_symbol_end ();
2703 p = (symbolS *) symbol_find_or_make (name);
2704 *input_line_pointer = c;
2705 return p;
2706 }
2707
2708 static long
2709 get_optional_absolute_expression ()
2710 {
2711 expressionS exp;
2712 asection *s;
2713
2714 s = expression (&exp);
2715 if (!(s == &bfd_abs_section || s == big_section || s == absent_section))
2716 {
2717 as_bad ("Bad Absolute Expression.");
2718 }
2719 return exp.X_add_number;
2720 }
2721
2722 static void
2723 s_align (x)
2724 int x;
2725 {
2726 register int temp;
2727 register long temp_fill;
2728 long max_alignment = 15;
2729
2730 /*
2731
2732 o Note that the assembler pulls down any immediately preceeding label
2733 to the aligned address.
2734 o It's not documented but auto alignment is reinstated by
2735 a .align pseudo instruction.
2736 o Note also that after auto alignment is turned off the mips assembler
2737 issues an error on attempt to assemble an improperly aligned data item.
2738 We don't.
2739
2740 */
2741
2742 temp = get_absolute_expression ();
2743 if (temp > max_alignment)
2744 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
2745 else if (temp < 0)
2746 {
2747 as_warn ("Alignment negative: 0 assumed.");
2748 temp = 0;
2749 }
2750 if (*input_line_pointer == ',')
2751 {
2752 input_line_pointer++;
2753 temp_fill = get_absolute_expression ();
2754 }
2755 else
2756 temp_fill = 0;
2757 if (temp)
2758 {
2759 auto_align = 1;
2760 if (!need_pass_2)
2761 frag_align (temp, (int) temp_fill);
2762 }
2763 else
2764 {
2765 auto_align = 0;
2766 }
2767
2768 record_alignment (now_seg, temp);
2769
2770 demand_empty_rest_of_line ();
2771 }
2772
2773 static void
2774 s_change_sec (sec)
2775 int sec;
2776 {
2777 switch (sec)
2778 {
2779 case 't':
2780 s_text ();
2781 break;
2782 case 'r':
2783 #ifdef OBJ_ECOFF
2784 subseg_new (".rdata", (subsegT) get_absolute_expression ());
2785 break;
2786 #else
2787 /* Fall through. */
2788 #endif
2789 case 'd':
2790 s_data ();
2791 break;
2792 case 'b':
2793 #ifdef BFD_ASSEMBLER
2794 subseg_set (bss_section, (subsegT) get_absolute_expression ());
2795 #else
2796 subseg_new (bss_section, (subsegT) get_absolute_expression ());
2797 #endif
2798 demand_empty_rest_of_line ();
2799 break;
2800 case 's':
2801 #ifdef OBJ_ECOFF
2802 subseg_new (".sdata", (subsegT) get_absolute_expression ());
2803 break;
2804 #else
2805 as_bad ("Global pointers not supported; recompile -G 0");
2806 return;
2807 #endif
2808 }
2809 auto_align = 1;
2810 }
2811
2812 static void
2813 s_cons (log_size)
2814 int log_size;
2815 {
2816
2817 if (log_size > 0 && auto_align)
2818 frag_align (log_size, 0);
2819 cons (1 << log_size);
2820 }
2821
2822 static void
2823 s_err (x)
2824 int x;
2825 {
2826 as_fatal ("Encountered `.err', aborting assembly");
2827 }
2828
2829 static void
2830 s_extern (x)
2831 int x;
2832 {
2833 long size;
2834 symbolS *symbolP;
2835
2836 symbolP = get_symbol ();
2837 if (*input_line_pointer == ',')
2838 input_line_pointer++;
2839 size = get_optional_absolute_expression ();
2840 S_SET_VALUE (symbolP, size);
2841 S_SET_EXTERNAL (symbolP);
2842
2843 #ifdef OBJ_ECOFF
2844 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
2845 so we use an additional ECOFF specific field. */
2846 symbolP->ecoff_undefined = 1;
2847 #endif
2848 }
2849
2850 static void
2851 s_float_cons (is_double)
2852 int is_double;
2853 {
2854 char *f;
2855 short words[4];
2856 int error_code, repeat;
2857 extern FLONUM_TYPE generic_floating_point_number;
2858
2859 if (auto_align)
2860 if (is_double)
2861 frag_align (3, 0);
2862 else
2863 frag_align (2, 0);
2864
2865 SKIP_WHITESPACE ();
2866 if (!is_end_of_line[(unsigned char) *input_line_pointer])
2867 {
2868 do
2869 {
2870 error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
2871 &generic_floating_point_number);
2872 if (error_code)
2873 {
2874 if (error_code == ERROR_EXPONENT_OVERFLOW)
2875 as_warn ("Bad floating-point constant: exponent overflow");
2876 else
2877 as_warn ("Bad floating-point constant: unknown error code=%d.", error_code);
2878 }
2879
2880 if (is_double)
2881 {
2882 gen_to_words ((LITTLENUM_TYPE *) words,
2883 4 /* precision */ ,
2884 11 /* exponent_bits */ );
2885 }
2886 else
2887 {
2888 gen_to_words ((LITTLENUM_TYPE *) words,
2889 2 /* precision */ ,
2890 8 /* exponent_bits */ );
2891 }
2892 if (*input_line_pointer == ':')
2893 {
2894 input_line_pointer++;
2895 repeat = get_absolute_expression ();
2896 }
2897 else
2898 {
2899 repeat = 1;
2900 }
2901 if (is_double)
2902 {
2903 f = frag_more (repeat * 8);
2904 for (; repeat--; f += 8)
2905 {
2906 md_number_to_chars (f + 6, words[0], 2);
2907 md_number_to_chars (f + 4, words[1], 2);
2908 md_number_to_chars (f + 2, words[2], 2);
2909 md_number_to_chars (f, words[3], 2);
2910 }
2911 }
2912 else
2913 {
2914 f = frag_more (repeat * 4);
2915 for (; repeat--; f += 4)
2916 {
2917 md_number_to_chars (f + 2, words[0], 2);
2918 md_number_to_chars (f, words[1], 2);
2919 }
2920 }
2921 SKIP_WHITESPACE ();
2922 if (*input_line_pointer != ',')
2923 break;
2924 input_line_pointer++;
2925 SKIP_WHITESPACE ();
2926 }
2927 while (1);
2928 }
2929 demand_empty_rest_of_line ();
2930 }
2931
2932 static void
2933 s_option (x)
2934 int x;
2935 {
2936 if (strcmp (input_line_pointer, "O1") != 0
2937 && strcmp (input_line_pointer, "O2") != 0)
2938 as_warn ("Unrecognized option");
2939 demand_empty_rest_of_line ();
2940 }
2941
2942 static void
2943 s_mipsset (x)
2944 int x;
2945 {
2946 char *name = input_line_pointer, ch;
2947
2948 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2949 input_line_pointer++;
2950 ch = *input_line_pointer;
2951 *input_line_pointer = '\0';
2952
2953 if (strcmp (name, "reorder") == 0)
2954 {
2955 mips_noreorder = 0;
2956 }
2957 else if (strcmp (name, "noreorder") == 0)
2958 {
2959 mips_noreorder = 1;
2960 }
2961 else if (strcmp (name, "at") == 0)
2962 {
2963 mips_noat = 0;
2964 }
2965 else if (strcmp (name, "noat") == 0)
2966 {
2967 mips_noat = 1;
2968 }
2969 else if (strcmp (name, "macro") == 0)
2970 {
2971 mips_warn_about_macros = 0;
2972 }
2973 else if (strcmp (name, "nomacro") == 0)
2974 {
2975 if (mips_noreorder == 0)
2976 as_bad ("`noreorder' must be set before `nomacro'");
2977 mips_warn_about_macros = 1;
2978 }
2979 else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
2980 {
2981 mips_nomove = 0;
2982 }
2983 else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
2984 {
2985 mips_nomove = 1;
2986 }
2987 else if (strcmp (name, "bopt") == 0)
2988 {
2989 mips_nobopt = 0;
2990 }
2991 else if (strcmp (name, "nobopt") == 0)
2992 {
2993 mips_nobopt = 1;
2994 }
2995 else
2996 {
2997 as_warn ("Tried to set unrecognized symbol: %s\n", name);
2998 }
2999 *input_line_pointer = ch;
3000 demand_empty_rest_of_line ();
3001 }
3002
3003 int
3004 tc_get_register ()
3005 {
3006 int reg;
3007
3008 SKIP_WHITESPACE ();
3009 if (*input_line_pointer++ != '$')
3010 {
3011 as_warn ("expected `$'");
3012 return 0;
3013 }
3014 if (isdigit ((unsigned char) *input_line_pointer))
3015 {
3016 reg = get_absolute_expression ();
3017 if (reg < 0 || reg >= 32)
3018 {
3019 as_warn ("Bad register number");
3020 reg = 0;
3021 }
3022 }
3023 else
3024 {
3025 if (strncmp (input_line_pointer, "fp", 2) == 0)
3026 reg = 30;
3027 else if (strncmp (input_line_pointer, "sp", 2) == 0)
3028 reg = 29;
3029 else if (strncmp (input_line_pointer, "gp", 2) == 0)
3030 reg = 28;
3031 else if (strncmp (input_line_pointer, "at", 2) == 0)
3032 reg = 1;
3033 else
3034 {
3035 as_warn ("Unrecognized register name");
3036 return 0;
3037 }
3038 input_line_pointer += 2;
3039 }
3040 return reg;
3041 }
3042
3043 /*
3044 * Translate internal representation of relocation info to BFD target format.
3045 */
3046 arelent *
3047 tc_gen_reloc (section, fixp)
3048 asection *section;
3049 fixS *fixp;
3050 {
3051 arelent *reloc;
3052
3053 reloc = (arelent *) xmalloc (sizeof (arelent));
3054 assert (reloc != 0);
3055
3056 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
3057 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3058 if (fixp->fx_pcrel == 0)
3059 reloc->addend = fixp->fx_addnumber;
3060 else
3061 #ifdef OBJ_ELF
3062 reloc->addend = 0;
3063 #else
3064 reloc->addend = -reloc->address;
3065 #endif
3066 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3067 assert (reloc->howto != 0);
3068
3069 return reloc;
3070 }
3071
3072 /* should never be called */
3073 valueT
3074 md_section_align (seg, addr)
3075 asection *seg;
3076 valueT addr;
3077 {
3078 int align = bfd_get_section_alignment (stdoutput, seg);
3079
3080 return ((addr + (1 << align) - 1) & (-1 << align));
3081 }
3082
3083 int
3084 md_estimate_size_before_relax (fragP, segtype)
3085 fragS *fragP;
3086 asection *segtype;
3087 {
3088 as_fatal ("md_estimate_size_before_relax");
3089 return (1);
3090 } /* md_estimate_size_before_relax() */
3091 \f
3092 #ifndef OBJ_ECOFF
3093
3094 /* These functions should really be defined by the object file format,
3095 since they are related to debugging information. However, this
3096 code has to work for the a.out format, which does not define them,
3097 so we provide simple versions here. These don't actually generate
3098 any debugging information, but they do simple checking and someday
3099 somebody may make them useful. */
3100
3101 typedef struct loc
3102 {
3103 struct loc *loc_next;
3104 unsigned long loc_fileno;
3105 unsigned long loc_lineno;
3106 unsigned long loc_offset;
3107 unsigned short loc_delta;
3108 unsigned short loc_count;
3109 #if 0
3110 fragS *loc_frag;
3111 #endif
3112 }
3113 locS;
3114
3115 typedef struct proc
3116 {
3117 struct proc *proc_next;
3118 struct symbol *proc_isym;
3119 struct symbol *proc_end;
3120 unsigned long proc_reg_mask;
3121 unsigned long proc_reg_offset;
3122 unsigned long proc_fpreg_mask;
3123 unsigned long proc_fpreg_offset;
3124 unsigned long proc_frameoffset;
3125 unsigned long proc_framereg;
3126 unsigned long proc_pcreg;
3127 locS *proc_iline;
3128 struct file *proc_file;
3129 int proc_index;
3130 }
3131 procS;
3132
3133 typedef struct file
3134 {
3135 struct file *file_next;
3136 unsigned long file_fileno;
3137 struct symbol *file_symbol;
3138 struct symbol *file_end;
3139 struct proc *file_proc;
3140 int file_numprocs;
3141 }
3142 fileS;
3143
3144 static struct obstack proc_frags;
3145 static procS *proc_lastP;
3146 static procS *proc_rootP;
3147 static int numprocs;
3148
3149 static void
3150 md_obj_begin ()
3151 {
3152 obstack_begin (&proc_frags, 0x2000);
3153 }
3154
3155 static void
3156 md_obj_end ()
3157 {
3158 /* check for premature end, nesting errors, etc */
3159 if (proc_lastP && proc_lastP->proc_end == NULL)
3160 as_warn ("missing `.end' at end of assembly");
3161 }
3162
3163 extern char hex_value[];
3164
3165 static long
3166 get_number ()
3167 {
3168 int negative = 0;
3169 long val = 0;
3170
3171 if (*input_line_pointer == '-')
3172 {
3173 ++input_line_pointer;
3174 negative = 1;
3175 }
3176 if (!isdigit (*input_line_pointer))
3177 as_bad ("Expected simple number.");
3178 if (input_line_pointer[0] == '0')
3179 {
3180 if (input_line_pointer[1] == 'x')
3181 {
3182 input_line_pointer += 2;
3183 while (isxdigit (*input_line_pointer))
3184 {
3185 val <<= 4;
3186 val |= hex_value[(int) *input_line_pointer++];
3187 }
3188 return negative ? -val : val;
3189 }
3190 else
3191 {
3192 ++input_line_pointer;
3193 while (isdigit (*input_line_pointer))
3194 {
3195 val <<= 3;
3196 val |= *input_line_pointer++ - '0';
3197 }
3198 return negative ? -val : val;
3199 }
3200 }
3201 if (!isdigit (*input_line_pointer))
3202 {
3203 printf (" *input_line_pointer == '%c' 0x%02x\n",
3204 *input_line_pointer, *input_line_pointer);
3205 as_warn ("Invalid number");
3206 return -1;
3207 }
3208 while (isdigit (*input_line_pointer))
3209 {
3210 val *= 10;
3211 val += *input_line_pointer++ - '0';
3212 }
3213 return negative ? -val : val;
3214 }
3215
3216 /* The .file directive; just like the usual .file directive, but there
3217 is an initial number which is the ECOFF file index. */
3218
3219 static void
3220 s_file (x)
3221 int x;
3222 {
3223 int line;
3224
3225 line = get_number ();
3226 s_app_file (0);
3227 }
3228
3229
3230 /* The .end directive. */
3231
3232 static void
3233 s_mipsend (x)
3234 int x;
3235 {
3236 symbolS *p;
3237
3238 if (!is_end_of_line[(unsigned char) *input_line_pointer])
3239 {
3240 p = get_symbol ();
3241 demand_empty_rest_of_line ();
3242 }
3243 else
3244 p = NULL;
3245 if (now_seg != text_section)
3246 as_warn (".end not in text section");
3247 if (!proc_lastP)
3248 {
3249 as_warn (".end and no .ent seen yet.");
3250 return;
3251 }
3252
3253 if (p != NULL)
3254 {
3255 assert (S_GET_NAME (p));
3256 if (strcmp (S_GET_NAME (p), S_GET_NAME (proc_lastP->proc_isym)))
3257 as_warn (".end symbol does not match .ent symbol.");
3258 }
3259
3260 proc_lastP->proc_end = (symbolS *) 1;
3261 }
3262
3263 /* The .aent and .ent directives. */
3264
3265 static void
3266 s_ent (aent)
3267 int aent;
3268 {
3269 int number = 0;
3270 procS *procP;
3271 symbolS *symbolP;
3272
3273 symbolP = get_symbol ();
3274 if (*input_line_pointer == ',')
3275 input_line_pointer++;
3276 if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
3277 number = get_number ();
3278 if (now_seg != text_section)
3279 as_warn (".ent or .aent not in text section.");
3280
3281 if (!aent && proc_lastP && proc_lastP->proc_end == NULL)
3282 as_warn ("missing `.end'");
3283
3284 if (!aent)
3285 {
3286 procP = (procS *) obstack_alloc (&proc_frags, sizeof (*procP));
3287 procP->proc_isym = symbolP;
3288 procP->proc_reg_mask = 0;
3289 procP->proc_reg_offset = 0;
3290 procP->proc_fpreg_mask = 0;
3291 procP->proc_fpreg_offset = 0;
3292 procP->proc_frameoffset = 0;
3293 procP->proc_framereg = 0;
3294 procP->proc_pcreg = 0;
3295 procP->proc_end = NULL;
3296 procP->proc_next = NULL;
3297 if (proc_lastP)
3298 proc_lastP->proc_next = procP;
3299 else
3300 proc_rootP = procP;
3301 proc_lastP = procP;
3302 numprocs++;
3303 }
3304 demand_empty_rest_of_line ();
3305 }
3306
3307 /* The .frame directive. */
3308
3309 static void
3310 s_frame (x)
3311 int x;
3312 {
3313 #if 0
3314 char str[100];
3315 symbolS *symP;
3316 int frame_reg;
3317 int frame_off;
3318 int pcreg;
3319
3320 frame_reg = tc_get_register ();
3321 if (*input_line_pointer == ',')
3322 input_line_pointer++;
3323 frame_off = get_optional_absolute_expression ();
3324 if (*input_line_pointer == ',')
3325 input_line_pointer++;
3326 pcreg = tc_get_register ();
3327
3328 /* bob third eye */
3329 assert (proc_rootP);
3330 proc_rootP->proc_framereg = frame_reg;
3331 proc_rootP->proc_frameoffset = frame_off;
3332 proc_rootP->proc_pcreg = pcreg;
3333 /* bob macho .frame */
3334
3335 /* We don't have to write out a frame stab for unoptimized code. */
3336 if (!(frame_reg == 30 && frame_off == 0))
3337 {
3338 if (!proc_lastP)
3339 as_warn ("No .ent for .frame to use.");
3340 (void) sprintf (str, "R%d;%d", frame_reg, frame_off);
3341 symP = symbol_new (str, N_VFP, 0, frag_now);
3342 S_SET_TYPE (symP, N_RMASK);
3343 S_SET_OTHER (symP, 0);
3344 S_SET_DESC (symP, 0);
3345 symP->sy_forward = proc_lastP->proc_isym;
3346 /* bob perhaps I should have used pseudo set */
3347 }
3348 demand_empty_rest_of_line ();
3349 #endif
3350 }
3351
3352 /* The .fmask and .mask directives. */
3353
3354 static void
3355 s_mask (reg_type)
3356 char reg_type;
3357 {
3358 #if 0
3359 char str[100], *strP;
3360 symbolS *symP;
3361 int i;
3362 unsigned int mask;
3363 int off;
3364
3365 mask = get_number ();
3366 if (*input_line_pointer == ',')
3367 input_line_pointer++;
3368 off = get_absolute_expression ();
3369
3370 /* bob only for coff */
3371 assert (proc_rootP);
3372 if (reg_type == 'F')
3373 {
3374 proc_rootP->proc_fpreg_mask = mask;
3375 proc_rootP->proc_fpreg_offset = off;
3376 }
3377 else
3378 {
3379 proc_rootP->proc_reg_mask = mask;
3380 proc_rootP->proc_reg_offset = off;
3381 }
3382
3383 /* bob macho .mask + .fmask */
3384
3385 /* We don't have to write out a mask stab if no saved regs. */
3386 if (!(mask == 0))
3387 {
3388 if (!proc_lastP)
3389 as_warn ("No .ent for .mask to use.");
3390 strP = str;
3391 for (i = 0; i < 32; i++)
3392 {
3393 if (mask % 2)
3394 {
3395 sprintf (strP, "%c%d,", reg_type, i);
3396 strP += strlen (strP);
3397 }
3398 mask /= 2;
3399 }
3400 sprintf (strP, ";%d,", off);
3401 symP = symbol_new (str, N_RMASK, 0, frag_now);
3402 S_SET_TYPE (symP, N_RMASK);
3403 S_SET_OTHER (symP, 0);
3404 S_SET_DESC (symP, 0);
3405 symP->sy_forward = proc_lastP->proc_isym;
3406 /* bob perhaps I should have used pseudo set */
3407 }
3408 #endif
3409 }
3410
3411 /* The .loc directive. */
3412
3413 static void
3414 s_loc (x)
3415 int x;
3416 {
3417 #if 0
3418 symbolS *symbolP;
3419 int lineno;
3420 int addroff;
3421
3422 assert (now_seg == text_section);
3423
3424 lineno = get_number ();
3425 addroff = obstack_next_free (&frags) - frag_now->fr_literal;
3426
3427 symbolP = symbol_new ("", N_SLINE, addroff, frag_now);
3428 S_SET_TYPE (symbolP, N_SLINE);
3429 S_SET_OTHER (symbolP, 0);
3430 S_SET_DESC (symbolP, lineno);
3431 symbolP->sy_segment = now_seg;
3432 #endif
3433 }
3434
3435 #endif /* ! defined (OBJ_ECOFF) */