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