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