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