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