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