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