* config/tc-mips.c (mips_ip): Don't warn on 'i' or 'j' mismatch if
[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 {
2248 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
2249 !strcmp (insn->name, insn[1].name))
2250 break;
2251 as_bad ("16 bit expression not in range 0..65535");
2252 }
2253 }
2254 else
2255 {
2256 if (imm_expr.X_add_number < -32768 ||
2257 imm_expr.X_add_number > 32767)
2258 {
2259 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
2260 !strcmp (insn->name, insn[1].name))
2261 break;
2262 as_bad ("16 bit expression not in range -32768..32767");
2263 }
2264 }
2265 s = expr_end;
2266 continue;
2267
2268 case 'o': /* 16 bit offset */
2269 c = my_getSmallExpression (&offset_expr, s);
2270 /*
2271 * If this value won't fit into a 16 bit offset, then
2272 * go find a macro that will generate the 32 bit offset
2273 * code pattern.
2274 */
2275 if ((offset_expr.X_add_symbol
2276 && offset_expr.X_seg != &bfd_abs_section)
2277 || offset_expr.X_subtract_symbol
2278 || offset_expr.X_add_number > 32767
2279 || offset_expr.X_add_number < -32768)
2280 break;
2281
2282 offset_reloc = BFD_RELOC_LO16;
2283 if (c == 'h' || c == 'H')
2284 offset_expr.X_add_number =
2285 (offset_expr.X_add_number >> 16) & 0xffff;
2286 s = expr_end;
2287 continue;
2288
2289 case 'p': /* pc relative offset */
2290 offset_reloc = BFD_RELOC_16_PCREL_S2;
2291 my_getExpression (&offset_expr, s);
2292 s = expr_end;
2293 continue;
2294
2295 case 'u': /* upper 16 bits */
2296 c = my_getSmallExpression (&imm_expr, s);
2297 if ((unsigned long) imm_expr.X_add_number > 65535)
2298 as_bad ("lui expression not in range 0..65535");
2299 imm_reloc = BFD_RELOC_LO16;
2300 if (c)
2301 {
2302 if (c != 'l')
2303 {
2304 if (imm_expr.X_seg == &bfd_abs_section)
2305 imm_expr.X_add_number =
2306 (imm_expr.X_add_number >> 16) & 0xffff;
2307 else if (c == 'h')
2308 imm_reloc = BFD_RELOC_HI16_S;
2309 else
2310 imm_reloc = BFD_RELOC_HI16;
2311 }
2312 }
2313 s = expr_end;
2314 continue;
2315
2316 case 'a': /* 26 bit address */
2317 my_getExpression (&offset_expr, s);
2318 s = expr_end;
2319 offset_reloc = BFD_RELOC_MIPS_JMP;
2320 continue;
2321
2322 default:
2323 fprintf (stderr, "bad char = '%c'\n", *args);
2324 internalError ();
2325 }
2326 break;
2327 }
2328 /* Args don't match. */
2329 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
2330 !strcmp (insn->name, insn[1].name))
2331 {
2332 ++insn;
2333 s = argsStart;
2334 continue;
2335 }
2336 insn_error = "ERROR: Illegal operands";
2337 return;
2338 }
2339 }
2340
2341 #define LP '('
2342 #define RP ')'
2343
2344 static int
2345 my_getSmallExpression (ep, str)
2346 expressionS *ep;
2347 char *str;
2348 {
2349 char *sp;
2350 int c = 0;
2351
2352 if (*str == ' ')
2353 str++;
2354 if (*str == LP
2355 || (*str == '%' &&
2356 ((str[1] == 'h' && str[2] == 'i')
2357 || (str[1] == 'H' && str[2] == 'I')
2358 || (str[1] == 'l' && str[2] == 'o'))
2359 && str[3] == LP))
2360 {
2361 if (*str == LP)
2362 c = 0;
2363 else
2364 {
2365 c = str[1];
2366 str += 3;
2367 }
2368
2369 /*
2370 * A small expression may be followed by a base register.
2371 * Scan to the end of this operand, and then back over a possible
2372 * base register. Then scan the small expression up to that
2373 * point. (Based on code in sparc.c...)
2374 */
2375 for (sp = str; *sp && *sp != ','; sp++)
2376 ;
2377 if (sp - 4 >= str && sp[-1] == RP)
2378 {
2379 if (isdigit (sp[-2]))
2380 {
2381 for (sp -= 3; sp >= str && isdigit (*sp); sp--)
2382 ;
2383 if (*sp == '$' && sp > str && sp[-1] == LP)
2384 {
2385 sp--;
2386 goto do_it;
2387 }
2388 }
2389 else if (sp - 5 >= str
2390 && sp[-5] == LP
2391 && sp[-4] == '$'
2392 && ((sp[-3] == 'f' && sp[-2] == 'p')
2393 || (sp[-3] == 's' && sp[-2] == 'p')
2394 || (sp[-3] == 'g' && sp[-2] == 'p')
2395 || (sp[-3] == 'a' && sp[-2] == 't')))
2396 {
2397 sp -= 5;
2398 do_it:
2399 if (sp == str)
2400 {
2401 /* no expression means zero offset */
2402 if (c)
2403 {
2404 /* %xx(reg) is an error */
2405 ep->X_seg = absent_section;
2406 expr_end = str - 3;
2407 }
2408 else
2409 {
2410 ep->X_seg = &bfd_abs_section;
2411 expr_end = sp;
2412 }
2413 ep->X_add_symbol = NULL;
2414 ep->X_subtract_symbol = NULL;
2415 ep->X_add_number = 0;
2416 }
2417 else
2418 {
2419 *sp = '\0';
2420 my_getExpression (ep, str);
2421 *sp = LP;
2422 }
2423 return c;
2424 }
2425 }
2426 }
2427 my_getExpression (ep, str);
2428 return c; /* => %hi or %lo encountered */
2429 }
2430
2431 static void
2432 my_getExpression (ep, str)
2433 expressionS *ep;
2434 char *str;
2435 {
2436 char *save_in;
2437 asection *seg;
2438
2439 save_in = input_line_pointer;
2440 input_line_pointer = str;
2441 seg = expression (ep);
2442 expr_end = input_line_pointer;
2443 input_line_pointer = save_in;
2444 }
2445
2446 char *
2447 md_atof (type, litP, sizeP)
2448 char type;
2449 char *litP;
2450 int *sizeP;
2451 {
2452 internalError ();
2453 return NULL;
2454 }
2455
2456 void
2457 md_number_to_chars (buf, val, n)
2458 char *buf;
2459 valueT val;
2460 int n;
2461 {
2462 switch (byte_order)
2463 {
2464 case LITTLE_ENDIAN:
2465 switch (n)
2466 {
2467 case 4:
2468 *buf++ = val;
2469 *buf++ = val >> 8;
2470 *buf++ = val >> 16;
2471 *buf = val >> 24;
2472 return;
2473
2474 case 2:
2475 *buf++ = val;
2476 *buf = val >> 8;
2477 return;
2478
2479 case 1:
2480 *buf = val;
2481 return;
2482
2483 default:
2484 internalError ();
2485 }
2486
2487 case BIG_ENDIAN:
2488 switch (n)
2489 {
2490 case 4:
2491 *buf++ = val >> 24;
2492 *buf++ = val >> 16;
2493 case 2:
2494 *buf++ = val >> 8;
2495 case 1:
2496 *buf = val;
2497 return;
2498
2499 default:
2500 internalError ();
2501 }
2502
2503 default:
2504 internalError ();
2505 }
2506 }
2507
2508 int
2509 md_parse_option (argP, cntP, vecP)
2510 char **argP;
2511 int *cntP;
2512 char ***vecP;
2513 {
2514 /* Accept -nocpp but ignore it. */
2515 if (!strcmp (*argP, "nocpp"))
2516 {
2517 *argP += 5;
2518 return 1;
2519 }
2520
2521 if (strcmp (*argP, "EL") == 0
2522 || strcmp (*argP, "EB") == 0)
2523 {
2524 /* FIXME: This breaks -L -EL. */
2525 flagseen['L'] = 0;
2526 *argP = "";
2527 return 1;
2528 }
2529
2530 #ifdef OBJ_ECOFF
2531 if (**argP == 'G')
2532 {
2533 if ((*argP)[1] != '\0')
2534 g_switch_value = atoi (*argP + 1);
2535 else if (*cntP)
2536 {
2537 **vecP = (char *) NULL;
2538 (*cntP)--;
2539 (*vecP)++;
2540 g_switch_value = atoi (**vecP);
2541 }
2542 else
2543 as_warn ("Number expected after -G");
2544 *argP = "";
2545 return 1;
2546 }
2547 #endif
2548 return 1; /* pretend you parsed the character */
2549 }
2550
2551 long
2552 md_pcrel_from (fixP)
2553 fixS *fixP;
2554 {
2555 /* return the address of the delay slot */
2556 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2557 }
2558
2559 int
2560 md_apply_fix (fixP, valueP)
2561 fixS *fixP;
2562 valueT *valueP;
2563 {
2564 unsigned char *buf;
2565 long insn, value;
2566
2567 assert (fixP->fx_size == 4);
2568
2569 value = *valueP;
2570 fixP->fx_addnumber = value; /* Remember value for tc_gen_reloc */
2571
2572 switch (fixP->fx_r_type)
2573 {
2574 case BFD_RELOC_32:
2575 case BFD_RELOC_MIPS_JMP:
2576 case BFD_RELOC_HI16:
2577 case BFD_RELOC_HI16_S:
2578 case BFD_RELOC_LO16:
2579 case BFD_RELOC_MIPS_GPREL:
2580 /* Nothing needed to do. The value comes from the reloc entry */
2581 return 1;
2582
2583 case BFD_RELOC_16_PCREL_S2:
2584 /*
2585 * We need to save the bits in the instruction since fixup_segment()
2586 * might be deleting the relocation entry (i.e., a branch within
2587 * the current segment).
2588 */
2589 if (value & 0x3)
2590 as_warn ("Branch to odd address (%x)", value);
2591 value >>= 2;
2592 if ((value & ~0xFFFF) && (value & ~0xFFFF) != (-1 & ~0xFFFF))
2593 as_bad ("Relocation overflow");
2594
2595 /* update old instruction data */
2596 buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
2597 switch (byte_order)
2598 {
2599 case LITTLE_ENDIAN:
2600 insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2601 break;
2602
2603 case BIG_ENDIAN:
2604 insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
2605 break;
2606
2607 default:
2608 internalError ();
2609 return 0;
2610 }
2611 insn |= value & 0xFFFF;
2612 md_number_to_chars ((char *) buf, insn, 4);
2613 break;
2614
2615 default:
2616 internalError ();
2617 }
2618 return 1;
2619 }
2620
2621 #if 0
2622 void
2623 printInsn (oc)
2624 unsigned long oc;
2625 {
2626 const struct mips_opcode *p;
2627 int treg, sreg, dreg, shamt;
2628 short imm;
2629 const char *args;
2630 int i;
2631
2632 for (i = 0; i < NUMOPCODES; ++i)
2633 {
2634 p = &mips_opcodes[i];
2635 if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))
2636 {
2637 printf ("%08lx %s\t", oc, p->name);
2638 treg = (oc >> 16) & 0x1f;
2639 sreg = (oc >> 21) & 0x1f;
2640 dreg = (oc >> 11) & 0x1f;
2641 shamt = (oc >> 6) & 0x1f;
2642 imm = oc;
2643 for (args = p->args;; ++args)
2644 {
2645 switch (*args)
2646 {
2647 case '\0':
2648 printf ("\n");
2649 break;
2650
2651 case ',':
2652 case '(':
2653 case ')':
2654 printf ("%c", *args);
2655 continue;
2656
2657 case 'r':
2658 assert (treg == sreg);
2659 printf ("$%d,$%d", treg, sreg);
2660 continue;
2661
2662 case 'd':
2663 case 'G':
2664 printf ("$%d", dreg);
2665 continue;
2666
2667 case 't':
2668 case 'E':
2669 printf ("$%d", treg);
2670 continue;
2671
2672 case 'b':
2673 case 's':
2674 printf ("$%d", sreg);
2675 continue;
2676
2677 case 'a':
2678 printf ("0x%08lx", oc & 0x1ffffff);
2679 continue;
2680
2681 case 'i':
2682 case 'j':
2683 case 'o':
2684 case 'u':
2685 printf ("%d", imm);
2686 continue;
2687
2688 case '<':
2689 printf ("$%d", shamt);
2690 continue;
2691
2692 default:
2693 internalError ();
2694 }
2695 break;
2696 }
2697 return;
2698 }
2699 }
2700 printf ("%08lx UNDEFINED\n", oc);
2701 }
2702 #endif
2703
2704 static symbolS *
2705 get_symbol ()
2706 {
2707 int c;
2708 char *name;
2709 symbolS *p;
2710
2711 name = input_line_pointer;
2712 c = get_symbol_end ();
2713 p = (symbolS *) symbol_find_or_make (name);
2714 *input_line_pointer = c;
2715 return p;
2716 }
2717
2718 static long
2719 get_optional_absolute_expression ()
2720 {
2721 expressionS exp;
2722 asection *s;
2723
2724 s = expression (&exp);
2725 if (!(s == &bfd_abs_section || s == big_section || s == absent_section))
2726 {
2727 as_bad ("Bad Absolute Expression.");
2728 }
2729 return exp.X_add_number;
2730 }
2731
2732 static void
2733 s_align (x)
2734 int x;
2735 {
2736 register int temp;
2737 register long temp_fill;
2738 long max_alignment = 15;
2739
2740 /*
2741
2742 o Note that the assembler pulls down any immediately preceeding label
2743 to the aligned address.
2744 o It's not documented but auto alignment is reinstated by
2745 a .align pseudo instruction.
2746 o Note also that after auto alignment is turned off the mips assembler
2747 issues an error on attempt to assemble an improperly aligned data item.
2748 We don't.
2749
2750 */
2751
2752 temp = get_absolute_expression ();
2753 if (temp > max_alignment)
2754 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
2755 else if (temp < 0)
2756 {
2757 as_warn ("Alignment negative: 0 assumed.");
2758 temp = 0;
2759 }
2760 if (*input_line_pointer == ',')
2761 {
2762 input_line_pointer++;
2763 temp_fill = get_absolute_expression ();
2764 }
2765 else
2766 temp_fill = 0;
2767 if (temp)
2768 {
2769 auto_align = 1;
2770 if (!need_pass_2)
2771 frag_align (temp, (int) temp_fill);
2772 }
2773 else
2774 {
2775 auto_align = 0;
2776 }
2777
2778 record_alignment (now_seg, temp);
2779
2780 demand_empty_rest_of_line ();
2781 }
2782
2783 static void
2784 s_change_sec (sec)
2785 int sec;
2786 {
2787 switch (sec)
2788 {
2789 case 't':
2790 s_text ();
2791 break;
2792 case 'r':
2793 #ifdef OBJ_ECOFF
2794 subseg_new (".rdata", (subsegT) get_absolute_expression ());
2795 break;
2796 #else
2797 /* Fall through. */
2798 #endif
2799 case 'd':
2800 s_data ();
2801 break;
2802 case 'b':
2803 #ifdef BFD_ASSEMBLER
2804 subseg_set (bss_section, (subsegT) get_absolute_expression ());
2805 #else
2806 subseg_new (bss_section, (subsegT) get_absolute_expression ());
2807 #endif
2808 demand_empty_rest_of_line ();
2809 break;
2810 case 's':
2811 #ifdef OBJ_ECOFF
2812 subseg_new (".sdata", (subsegT) get_absolute_expression ());
2813 break;
2814 #else
2815 as_bad ("Global pointers not supported; recompile -G 0");
2816 return;
2817 #endif
2818 }
2819 auto_align = 1;
2820 }
2821
2822 static void
2823 s_cons (log_size)
2824 int log_size;
2825 {
2826
2827 if (log_size > 0 && auto_align)
2828 frag_align (log_size, 0);
2829 cons (1 << log_size);
2830 }
2831
2832 static void
2833 s_err (x)
2834 int x;
2835 {
2836 as_fatal ("Encountered `.err', aborting assembly");
2837 }
2838
2839 static void
2840 s_extern (x)
2841 int x;
2842 {
2843 long size;
2844 symbolS *symbolP;
2845
2846 symbolP = get_symbol ();
2847 if (*input_line_pointer == ',')
2848 input_line_pointer++;
2849 size = get_optional_absolute_expression ();
2850 S_SET_VALUE (symbolP, size);
2851 S_SET_EXTERNAL (symbolP);
2852
2853 #ifdef OBJ_ECOFF
2854 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
2855 so we use an additional ECOFF specific field. */
2856 symbolP->ecoff_undefined = 1;
2857 #endif
2858 }
2859
2860 static void
2861 s_float_cons (is_double)
2862 int is_double;
2863 {
2864 char *f;
2865 short words[4];
2866 int error_code, repeat;
2867 extern FLONUM_TYPE generic_floating_point_number;
2868
2869 if (auto_align)
2870 if (is_double)
2871 frag_align (3, 0);
2872 else
2873 frag_align (2, 0);
2874
2875 SKIP_WHITESPACE ();
2876 if (!is_end_of_line[(unsigned char) *input_line_pointer])
2877 {
2878 do
2879 {
2880 error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
2881 &generic_floating_point_number);
2882 if (error_code)
2883 {
2884 if (error_code == ERROR_EXPONENT_OVERFLOW)
2885 as_warn ("Bad floating-point constant: exponent overflow");
2886 else
2887 as_warn ("Bad floating-point constant: unknown error code=%d.", error_code);
2888 }
2889
2890 if (is_double)
2891 {
2892 gen_to_words ((LITTLENUM_TYPE *) words,
2893 4 /* precision */ ,
2894 11 /* exponent_bits */ );
2895 }
2896 else
2897 {
2898 gen_to_words ((LITTLENUM_TYPE *) words,
2899 2 /* precision */ ,
2900 8 /* exponent_bits */ );
2901 }
2902 if (*input_line_pointer == ':')
2903 {
2904 input_line_pointer++;
2905 repeat = get_absolute_expression ();
2906 }
2907 else
2908 {
2909 repeat = 1;
2910 }
2911 if (is_double)
2912 {
2913 f = frag_more (repeat * 8);
2914 for (; repeat--; f += 8)
2915 {
2916 md_number_to_chars (f + 6, words[0], 2);
2917 md_number_to_chars (f + 4, words[1], 2);
2918 md_number_to_chars (f + 2, words[2], 2);
2919 md_number_to_chars (f, words[3], 2);
2920 }
2921 }
2922 else
2923 {
2924 f = frag_more (repeat * 4);
2925 for (; repeat--; f += 4)
2926 {
2927 md_number_to_chars (f + 2, words[0], 2);
2928 md_number_to_chars (f, words[1], 2);
2929 }
2930 }
2931 SKIP_WHITESPACE ();
2932 if (*input_line_pointer != ',')
2933 break;
2934 input_line_pointer++;
2935 SKIP_WHITESPACE ();
2936 }
2937 while (1);
2938 }
2939 demand_empty_rest_of_line ();
2940 }
2941
2942 static void
2943 s_option (x)
2944 int x;
2945 {
2946 if (strcmp (input_line_pointer, "O1") != 0
2947 && strcmp (input_line_pointer, "O2") != 0)
2948 as_warn ("Unrecognized option");
2949 demand_empty_rest_of_line ();
2950 }
2951
2952 static void
2953 s_mipsset (x)
2954 int x;
2955 {
2956 char *name = input_line_pointer, ch;
2957
2958 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2959 input_line_pointer++;
2960 ch = *input_line_pointer;
2961 *input_line_pointer = '\0';
2962
2963 if (strcmp (name, "reorder") == 0)
2964 {
2965 mips_noreorder = 0;
2966 }
2967 else if (strcmp (name, "noreorder") == 0)
2968 {
2969 mips_noreorder = 1;
2970 }
2971 else if (strcmp (name, "at") == 0)
2972 {
2973 mips_noat = 0;
2974 }
2975 else if (strcmp (name, "noat") == 0)
2976 {
2977 mips_noat = 1;
2978 }
2979 else if (strcmp (name, "macro") == 0)
2980 {
2981 mips_warn_about_macros = 0;
2982 }
2983 else if (strcmp (name, "nomacro") == 0)
2984 {
2985 if (mips_noreorder == 0)
2986 as_bad ("`noreorder' must be set before `nomacro'");
2987 mips_warn_about_macros = 1;
2988 }
2989 else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
2990 {
2991 mips_nomove = 0;
2992 }
2993 else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
2994 {
2995 mips_nomove = 1;
2996 }
2997 else if (strcmp (name, "bopt") == 0)
2998 {
2999 mips_nobopt = 0;
3000 }
3001 else if (strcmp (name, "nobopt") == 0)
3002 {
3003 mips_nobopt = 1;
3004 }
3005 else
3006 {
3007 as_warn ("Tried to set unrecognized symbol: %s\n", name);
3008 }
3009 *input_line_pointer = ch;
3010 demand_empty_rest_of_line ();
3011 }
3012
3013 int
3014 tc_get_register ()
3015 {
3016 int reg;
3017
3018 SKIP_WHITESPACE ();
3019 if (*input_line_pointer++ != '$')
3020 {
3021 as_warn ("expected `$'");
3022 return 0;
3023 }
3024 if (isdigit ((unsigned char) *input_line_pointer))
3025 {
3026 reg = get_absolute_expression ();
3027 if (reg < 0 || reg >= 32)
3028 {
3029 as_warn ("Bad register number");
3030 reg = 0;
3031 }
3032 }
3033 else
3034 {
3035 if (strncmp (input_line_pointer, "fp", 2) == 0)
3036 reg = 30;
3037 else if (strncmp (input_line_pointer, "sp", 2) == 0)
3038 reg = 29;
3039 else if (strncmp (input_line_pointer, "gp", 2) == 0)
3040 reg = 28;
3041 else if (strncmp (input_line_pointer, "at", 2) == 0)
3042 reg = 1;
3043 else
3044 {
3045 as_warn ("Unrecognized register name");
3046 return 0;
3047 }
3048 input_line_pointer += 2;
3049 }
3050 return reg;
3051 }
3052
3053 /*
3054 * Translate internal representation of relocation info to BFD target format.
3055 */
3056 arelent *
3057 tc_gen_reloc (section, fixp)
3058 asection *section;
3059 fixS *fixp;
3060 {
3061 arelent *reloc;
3062
3063 reloc = (arelent *) xmalloc (sizeof (arelent));
3064 assert (reloc != 0);
3065
3066 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
3067 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3068 if (fixp->fx_pcrel == 0)
3069 reloc->addend = fixp->fx_addnumber;
3070 else
3071 #ifdef OBJ_ELF
3072 reloc->addend = 0;
3073 #else
3074 reloc->addend = -reloc->address;
3075 #endif
3076 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3077 assert (reloc->howto != 0);
3078
3079 return reloc;
3080 }
3081
3082 /* should never be called */
3083 valueT
3084 md_section_align (seg, addr)
3085 asection *seg;
3086 valueT addr;
3087 {
3088 int align = bfd_get_section_alignment (stdoutput, seg);
3089
3090 return ((addr + (1 << align) - 1) & (-1 << align));
3091 }
3092
3093 int
3094 md_estimate_size_before_relax (fragP, segtype)
3095 fragS *fragP;
3096 asection *segtype;
3097 {
3098 as_fatal ("md_estimate_size_before_relax");
3099 return (1);
3100 } /* md_estimate_size_before_relax() */
3101 \f
3102 #ifndef OBJ_ECOFF
3103
3104 /* These functions should really be defined by the object file format,
3105 since they are related to debugging information. However, this
3106 code has to work for the a.out format, which does not define them,
3107 so we provide simple versions here. These don't actually generate
3108 any debugging information, but they do simple checking and someday
3109 somebody may make them useful. */
3110
3111 typedef struct loc
3112 {
3113 struct loc *loc_next;
3114 unsigned long loc_fileno;
3115 unsigned long loc_lineno;
3116 unsigned long loc_offset;
3117 unsigned short loc_delta;
3118 unsigned short loc_count;
3119 #if 0
3120 fragS *loc_frag;
3121 #endif
3122 }
3123 locS;
3124
3125 typedef struct proc
3126 {
3127 struct proc *proc_next;
3128 struct symbol *proc_isym;
3129 struct symbol *proc_end;
3130 unsigned long proc_reg_mask;
3131 unsigned long proc_reg_offset;
3132 unsigned long proc_fpreg_mask;
3133 unsigned long proc_fpreg_offset;
3134 unsigned long proc_frameoffset;
3135 unsigned long proc_framereg;
3136 unsigned long proc_pcreg;
3137 locS *proc_iline;
3138 struct file *proc_file;
3139 int proc_index;
3140 }
3141 procS;
3142
3143 typedef struct file
3144 {
3145 struct file *file_next;
3146 unsigned long file_fileno;
3147 struct symbol *file_symbol;
3148 struct symbol *file_end;
3149 struct proc *file_proc;
3150 int file_numprocs;
3151 }
3152 fileS;
3153
3154 static struct obstack proc_frags;
3155 static procS *proc_lastP;
3156 static procS *proc_rootP;
3157 static int numprocs;
3158
3159 static void
3160 md_obj_begin ()
3161 {
3162 obstack_begin (&proc_frags, 0x2000);
3163 }
3164
3165 static void
3166 md_obj_end ()
3167 {
3168 /* check for premature end, nesting errors, etc */
3169 if (proc_lastP && proc_lastP->proc_end == NULL)
3170 as_warn ("missing `.end' at end of assembly");
3171 }
3172
3173 extern char hex_value[];
3174
3175 static long
3176 get_number ()
3177 {
3178 int negative = 0;
3179 long val = 0;
3180
3181 if (*input_line_pointer == '-')
3182 {
3183 ++input_line_pointer;
3184 negative = 1;
3185 }
3186 if (!isdigit (*input_line_pointer))
3187 as_bad ("Expected simple number.");
3188 if (input_line_pointer[0] == '0')
3189 {
3190 if (input_line_pointer[1] == 'x')
3191 {
3192 input_line_pointer += 2;
3193 while (isxdigit (*input_line_pointer))
3194 {
3195 val <<= 4;
3196 val |= hex_value[(int) *input_line_pointer++];
3197 }
3198 return negative ? -val : val;
3199 }
3200 else
3201 {
3202 ++input_line_pointer;
3203 while (isdigit (*input_line_pointer))
3204 {
3205 val <<= 3;
3206 val |= *input_line_pointer++ - '0';
3207 }
3208 return negative ? -val : val;
3209 }
3210 }
3211 if (!isdigit (*input_line_pointer))
3212 {
3213 printf (" *input_line_pointer == '%c' 0x%02x\n",
3214 *input_line_pointer, *input_line_pointer);
3215 as_warn ("Invalid number");
3216 return -1;
3217 }
3218 while (isdigit (*input_line_pointer))
3219 {
3220 val *= 10;
3221 val += *input_line_pointer++ - '0';
3222 }
3223 return negative ? -val : val;
3224 }
3225
3226 /* The .file directive; just like the usual .file directive, but there
3227 is an initial number which is the ECOFF file index. */
3228
3229 static void
3230 s_file (x)
3231 int x;
3232 {
3233 int line;
3234
3235 line = get_number ();
3236 s_app_file (0);
3237 }
3238
3239
3240 /* The .end directive. */
3241
3242 static void
3243 s_mipsend (x)
3244 int x;
3245 {
3246 symbolS *p;
3247
3248 if (!is_end_of_line[(unsigned char) *input_line_pointer])
3249 {
3250 p = get_symbol ();
3251 demand_empty_rest_of_line ();
3252 }
3253 else
3254 p = NULL;
3255 if (now_seg != text_section)
3256 as_warn (".end not in text section");
3257 if (!proc_lastP)
3258 {
3259 as_warn (".end and no .ent seen yet.");
3260 return;
3261 }
3262
3263 if (p != NULL)
3264 {
3265 assert (S_GET_NAME (p));
3266 if (strcmp (S_GET_NAME (p), S_GET_NAME (proc_lastP->proc_isym)))
3267 as_warn (".end symbol does not match .ent symbol.");
3268 }
3269
3270 proc_lastP->proc_end = (symbolS *) 1;
3271 }
3272
3273 /* The .aent and .ent directives. */
3274
3275 static void
3276 s_ent (aent)
3277 int aent;
3278 {
3279 int number = 0;
3280 procS *procP;
3281 symbolS *symbolP;
3282
3283 symbolP = get_symbol ();
3284 if (*input_line_pointer == ',')
3285 input_line_pointer++;
3286 if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
3287 number = get_number ();
3288 if (now_seg != text_section)
3289 as_warn (".ent or .aent not in text section.");
3290
3291 if (!aent && proc_lastP && proc_lastP->proc_end == NULL)
3292 as_warn ("missing `.end'");
3293
3294 if (!aent)
3295 {
3296 procP = (procS *) obstack_alloc (&proc_frags, sizeof (*procP));
3297 procP->proc_isym = symbolP;
3298 procP->proc_reg_mask = 0;
3299 procP->proc_reg_offset = 0;
3300 procP->proc_fpreg_mask = 0;
3301 procP->proc_fpreg_offset = 0;
3302 procP->proc_frameoffset = 0;
3303 procP->proc_framereg = 0;
3304 procP->proc_pcreg = 0;
3305 procP->proc_end = NULL;
3306 procP->proc_next = NULL;
3307 if (proc_lastP)
3308 proc_lastP->proc_next = procP;
3309 else
3310 proc_rootP = procP;
3311 proc_lastP = procP;
3312 numprocs++;
3313 }
3314 demand_empty_rest_of_line ();
3315 }
3316
3317 /* The .frame directive. */
3318
3319 static void
3320 s_frame (x)
3321 int x;
3322 {
3323 #if 0
3324 char str[100];
3325 symbolS *symP;
3326 int frame_reg;
3327 int frame_off;
3328 int pcreg;
3329
3330 frame_reg = tc_get_register ();
3331 if (*input_line_pointer == ',')
3332 input_line_pointer++;
3333 frame_off = get_optional_absolute_expression ();
3334 if (*input_line_pointer == ',')
3335 input_line_pointer++;
3336 pcreg = tc_get_register ();
3337
3338 /* bob third eye */
3339 assert (proc_rootP);
3340 proc_rootP->proc_framereg = frame_reg;
3341 proc_rootP->proc_frameoffset = frame_off;
3342 proc_rootP->proc_pcreg = pcreg;
3343 /* bob macho .frame */
3344
3345 /* We don't have to write out a frame stab for unoptimized code. */
3346 if (!(frame_reg == 30 && frame_off == 0))
3347 {
3348 if (!proc_lastP)
3349 as_warn ("No .ent for .frame to use.");
3350 (void) sprintf (str, "R%d;%d", frame_reg, frame_off);
3351 symP = symbol_new (str, N_VFP, 0, frag_now);
3352 S_SET_TYPE (symP, N_RMASK);
3353 S_SET_OTHER (symP, 0);
3354 S_SET_DESC (symP, 0);
3355 symP->sy_forward = proc_lastP->proc_isym;
3356 /* bob perhaps I should have used pseudo set */
3357 }
3358 demand_empty_rest_of_line ();
3359 #endif
3360 }
3361
3362 /* The .fmask and .mask directives. */
3363
3364 static void
3365 s_mask (reg_type)
3366 char reg_type;
3367 {
3368 #if 0
3369 char str[100], *strP;
3370 symbolS *symP;
3371 int i;
3372 unsigned int mask;
3373 int off;
3374
3375 mask = get_number ();
3376 if (*input_line_pointer == ',')
3377 input_line_pointer++;
3378 off = get_absolute_expression ();
3379
3380 /* bob only for coff */
3381 assert (proc_rootP);
3382 if (reg_type == 'F')
3383 {
3384 proc_rootP->proc_fpreg_mask = mask;
3385 proc_rootP->proc_fpreg_offset = off;
3386 }
3387 else
3388 {
3389 proc_rootP->proc_reg_mask = mask;
3390 proc_rootP->proc_reg_offset = off;
3391 }
3392
3393 /* bob macho .mask + .fmask */
3394
3395 /* We don't have to write out a mask stab if no saved regs. */
3396 if (!(mask == 0))
3397 {
3398 if (!proc_lastP)
3399 as_warn ("No .ent for .mask to use.");
3400 strP = str;
3401 for (i = 0; i < 32; i++)
3402 {
3403 if (mask % 2)
3404 {
3405 sprintf (strP, "%c%d,", reg_type, i);
3406 strP += strlen (strP);
3407 }
3408 mask /= 2;
3409 }
3410 sprintf (strP, ";%d,", off);
3411 symP = symbol_new (str, N_RMASK, 0, frag_now);
3412 S_SET_TYPE (symP, N_RMASK);
3413 S_SET_OTHER (symP, 0);
3414 S_SET_DESC (symP, 0);
3415 symP->sy_forward = proc_lastP->proc_isym;
3416 /* bob perhaps I should have used pseudo set */
3417 }
3418 #endif
3419 }
3420
3421 /* The .loc directive. */
3422
3423 static void
3424 s_loc (x)
3425 int x;
3426 {
3427 #if 0
3428 symbolS *symbolP;
3429 int lineno;
3430 int addroff;
3431
3432 assert (now_seg == text_section);
3433
3434 lineno = get_number ();
3435 addroff = obstack_next_free (&frags) - frag_now->fr_literal;
3436
3437 symbolP = symbol_new ("", N_SLINE, addroff, frag_now);
3438 S_SET_TYPE (symbolP, N_SLINE);
3439 S_SET_OTHER (symbolP, 0);
3440 S_SET_DESC (symbolP, lineno);
3441 symbolP->sy_segment = now_seg;
3442 #endif
3443 }
3444
3445 #endif /* ! defined (OBJ_ECOFF) */