Reverted previous change, and added this one instead:
[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 'z':
1058 continue;
1059
1060 case '<':
1061 insn.insn_opcode |= va_arg (args, int) << 6;
1062 continue;
1063
1064 case 'D':
1065 insn.insn_opcode |= va_arg (args, int) << 6;
1066 continue;
1067
1068 case 'B':
1069 insn.insn_opcode |= va_arg (args, int) << 6;
1070 continue;
1071
1072 case 'b':
1073 case 's':
1074 case 'r':
1075 case 'v':
1076 insn.insn_opcode |= va_arg (args, int) << 21;
1077 continue;
1078
1079 case 'i':
1080 case 'j':
1081 case 'o':
1082 r = BFD_RELOC_LO16;
1083 continue;
1084
1085 case 'u':
1086 assert (ep != NULL && ep->X_op == O_constant);
1087 insn.insn_opcode |= (ep->X_add_number >> 16) & 0xffff;
1088 ep = NULL;
1089 continue;
1090
1091 case 'p':
1092 assert (ep != NULL);
1093 /*
1094 * This allows macro() to pass an immediate expression for
1095 * creating short branches without creating a symbol.
1096 * Note that the expression still might come from the assembly
1097 * input, in which case the value is not checked for range nor
1098 * is a relocation entry generated (yuck).
1099 */
1100 if (ep->X_op == O_constant)
1101 {
1102 insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff;
1103 ep = NULL;
1104 }
1105 else
1106 r = BFD_RELOC_16_PCREL_S2;
1107 continue;
1108
1109 default:
1110 internalError ();
1111 }
1112 break;
1113 }
1114 va_end (args);
1115 assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
1116
1117 /* Use GP relative addressing if possible. */
1118 if (r == BFD_RELOC_LO16
1119 && gp_reference (ep))
1120 r = BFD_RELOC_MIPS_GPREL;
1121
1122 append_insn (&insn, ep, r);
1123 }
1124
1125 /*
1126 * Generate a "lui" instruction.
1127 */
1128 static void
1129 macro_build_lui (counter, ep, regnum)
1130 int *counter;
1131 expressionS *ep;
1132 int regnum;
1133 {
1134 expressionS high_expr;
1135 struct mips_cl_insn insn;
1136 bfd_reloc_code_real_type r;
1137 CONST char *name = "lui";
1138 CONST char *fmt = "t,u";
1139
1140 high_expr = *ep;
1141
1142 if (high_expr.X_op == O_constant)
1143 {
1144 /* we can compute the instruction now without a relocation entry */
1145 if (high_expr.X_add_number & 0x8000)
1146 high_expr.X_add_number += 0x10000;
1147 high_expr.X_add_number =
1148 ((unsigned long) high_expr.X_add_number >> 16) & 0xffff;
1149 r = BFD_RELOC_UNUSED;
1150 }
1151 else
1152 r = BFD_RELOC_HI16_S;
1153
1154 /*
1155 * If the macro is about to expand into a second instruction,
1156 * print a warning if needed. We need to pass ip as a parameter
1157 * to generate a better warning message here...
1158 */
1159 if (mips_warn_about_macros && *counter == 1)
1160 as_warn ("Macro instruction expanded into multiple instructions");
1161
1162 *counter += 1; /* bump instruction counter */
1163
1164 insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
1165 assert (insn.insn_mo);
1166 assert (strcmp (name, insn.insn_mo->name) == 0);
1167 assert (strcmp (fmt, insn.insn_mo->args) == 0);
1168
1169 insn.insn_opcode = insn.insn_mo->match | (regnum << 16);
1170 if (r == BFD_RELOC_UNUSED)
1171 {
1172 insn.insn_opcode |= high_expr.X_add_number;
1173 append_insn (&insn, NULL, r);
1174 }
1175 else
1176 append_insn (&insn, &high_expr, r);
1177 }
1178
1179 /* set_at()
1180 * Generates code to set the $at register to true (one)
1181 * if reg is less than the immediate expression.
1182 */
1183 static void
1184 set_at (counter, reg, unsignedp)
1185 int *counter;
1186 int reg;
1187 int unsignedp;
1188 {
1189 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
1190 macro_build (counter, &imm_expr,
1191 unsignedp ? "sltiu" : "slti",
1192 "t,r,j", AT, reg);
1193 else
1194 {
1195 load_register (counter, AT, &imm_expr);
1196 macro_build (counter, NULL,
1197 unsignedp ? "sltu" : "slt",
1198 "d,v,t", AT, reg, AT);
1199 }
1200 }
1201
1202 /* Warn if an expression is not a constant. */
1203
1204 static void
1205 check_absolute_expr (ip, ex)
1206 struct mips_cl_insn *ip;
1207 expressionS *ex;
1208 {
1209 if (ex->X_op != O_constant)
1210 as_warn ("Instruction %s requires absolute expression", ip->insn_mo->name);
1211 }
1212
1213 /* load_register()
1214 * This routine generates the least number of instructions neccessary to load
1215 * an absolute expression value into a register.
1216 */
1217 static void
1218 load_register (counter, reg, ep)
1219 int *counter;
1220 int reg;
1221 expressionS *ep;
1222 {
1223 assert (ep->X_op == O_constant);
1224 if (ep->X_add_number >= -0x8000 && ep->X_add_number < 0x8000)
1225 macro_build (counter, ep,
1226 mips_isa < 3 ? "addiu" : "daddiu",
1227 "t,r,j", reg, 0);
1228 else if (ep->X_add_number >= 0 && ep->X_add_number < 0x10000)
1229 macro_build (counter, ep, "ori", "t,r,i", reg, 0);
1230 else if ((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0
1231 || ((ep->X_add_number &~ (offsetT) 0x7fffffff)
1232 == ~ (offsetT) 0x7fffffff))
1233 {
1234 macro_build (counter, ep, "lui", "t,u", reg);
1235 if ((ep->X_add_number & 0xffff) != 0)
1236 macro_build (counter, ep, "ori", "t,r,i", reg, reg);
1237 }
1238 else if (mips_isa < 3)
1239 {
1240 as_bad ("Number larger than 32 bits");
1241 macro_build (counter, ep, "addiu", "t,r,j", reg, 0);
1242 }
1243 else
1244 {
1245 int shift;
1246 expressionS hi32, lo32;
1247
1248 hi32 = *ep;
1249 shift = 32;
1250 hi32.X_add_number >>= shift;
1251 hi32.X_add_number &= 0xffffffff;
1252 if ((hi32.X_add_number & 0x80000000) != 0)
1253 hi32.X_add_number |= ~ (offsetT) 0xffffffff;
1254 load_register (counter, reg, &hi32);
1255 lo32 = *ep;
1256 lo32.X_add_number &= 0xffffffff;
1257 if ((lo32.X_add_number & 0xffff0000) == 0)
1258 macro_build (counter, NULL, "dsll32", "d,w,<", reg, reg, 0);
1259 else
1260 {
1261 expressionS mid16;
1262
1263 macro_build (counter, NULL, "dsll", "d,w,<", reg, reg, 16);
1264 mid16 = lo32;
1265 mid16.X_add_number >>= 16;
1266 macro_build (counter, &mid16, "ori", "t,r,i", reg, reg);
1267 macro_build (counter, NULL, "dsll", "d,w,<", reg, reg, 16);
1268 }
1269 if ((lo32.X_add_number & 0xffff) != 0)
1270 macro_build (counter, &lo32, "ori", "t,r,i", reg, reg);
1271 }
1272 }
1273
1274 /*
1275 * Build macros
1276 * This routine implements the seemingly endless macro or synthesized
1277 * instructions and addressing modes in the mips assembly language. Many
1278 * of these macros are simple and are similar to each other. These could
1279 * probably be handled by some kind of table or grammer aproach instead of
1280 * this verbose method. Others are not simple macros but are more like
1281 * optimizing code generation.
1282 * One interesting optimization is when several store macros appear
1283 * consecutivly that would load AT with the upper half of the same address.
1284 * The ensuing load upper instructions are ommited. This implies some kind
1285 * of global optimization. We currently only optimize within a single macro.
1286 * For many of the load and store macros if the address is specified as a
1287 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
1288 * first load register 'at' with zero and use it as the base register. The
1289 * mips assembler simply uses register $zero. Just one tiny optimization
1290 * we're missing.
1291 */
1292 static void
1293 macro (ip)
1294 struct mips_cl_insn *ip;
1295 {
1296 register int treg, sreg, dreg, breg;
1297 int tempreg;
1298 int mask;
1299 int icnt = 0;
1300 int used_at;
1301 expressionS expr1;
1302 const char *s;
1303 const char *s2;
1304 const char *fmt;
1305 int likely = 0;
1306 int dbl = 0;
1307 int coproc = 0;
1308 offsetT maxnum;
1309
1310 treg = (ip->insn_opcode >> 16) & 0x1f;
1311 dreg = (ip->insn_opcode >> 11) & 0x1f;
1312 sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
1313 mask = ip->insn_mo->mask;
1314
1315 expr1.X_op = O_constant;
1316 expr1.X_op_symbol = NULL;
1317 expr1.X_add_symbol = NULL;
1318 expr1.X_add_number = 1;
1319
1320 switch (mask)
1321 {
1322 case M_DABS:
1323 dbl = 1;
1324 case M_ABS:
1325 /* bgez $a0,.+12
1326 move v0,$a0
1327 sub v0,$zero,$a0
1328 */
1329
1330 mips_emit_delays ();
1331 ++mips_noreorder;
1332
1333 expr1.X_add_number = 8;
1334 macro_build (&icnt, &expr1, "bgez", "s,p", sreg);
1335 if (dreg == sreg)
1336 macro_build (&icnt, NULL, "nop", "", 0);
1337 else
1338 macro_build (&icnt, NULL, "move", "d,s", dreg, sreg, 0);
1339 macro_build (&icnt, NULL,
1340 dbl ? "dsub" : "sub",
1341 "d,v,t", dreg, 0, sreg);
1342
1343 --mips_noreorder;
1344 return;
1345
1346 case M_ADD_I:
1347 s = "addi";
1348 s2 = "add";
1349 goto do_addi;
1350 case M_ADDU_I:
1351 s = "addiu";
1352 s2 = "addu";
1353 goto do_addi;
1354 case M_DADD_I:
1355 dbl = 1;
1356 s = "daddi";
1357 s2 = "dadd";
1358 goto do_addi;
1359 case M_DADDU_I:
1360 dbl = 1;
1361 s = "daddiu";
1362 s2 = "daddu";
1363 do_addi:
1364 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
1365 {
1366 macro_build (&icnt, &imm_expr, s, "t,r,j", treg, sreg);
1367 return;
1368 }
1369 load_register (&icnt, AT, &imm_expr);
1370 macro_build (&icnt, NULL, s2, "d,v,t", treg, sreg, AT);
1371 break;
1372
1373 case M_AND_I:
1374 s = "andi";
1375 s2 = "and";
1376 goto do_bit;
1377 case M_OR_I:
1378 s = "ori";
1379 s2 = "or";
1380 goto do_bit;
1381 case M_NOR_I:
1382 s = "";
1383 s2 = "nor";
1384 goto do_bit;
1385 case M_XOR_I:
1386 s = "xori";
1387 s2 = "xor";
1388 do_bit:
1389 if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
1390 {
1391 if (mask != M_NOR_I)
1392 macro_build (&icnt, &imm_expr, s, "t,r,i", treg, sreg);
1393 else
1394 {
1395 macro_build (&icnt, &imm_expr, "ori", "t,r,i", treg, sreg);
1396 macro_build (&icnt, &imm_expr, "nor", "d,v,t", treg, treg, 0);
1397 }
1398 return;
1399 }
1400
1401 load_register (&icnt, AT, &imm_expr);
1402 macro_build (&icnt, NULL, s2, "d,v,t", treg, sreg, AT);
1403 break;
1404
1405 case M_BEQ_I:
1406 s = "beq";
1407 goto beq_i;
1408 case M_BEQL_I:
1409 s = "beql";
1410 likely = 1;
1411 goto beq_i;
1412 case M_BNE_I:
1413 s = "bne";
1414 goto beq_i;
1415 case M_BNEL_I:
1416 s = "bnel";
1417 likely = 1;
1418 beq_i:
1419 if (imm_expr.X_add_number == 0)
1420 {
1421 macro_build (&icnt, &offset_expr, s, "s,t,p", sreg, 0);
1422 return;
1423 }
1424 load_register (&icnt, AT, &imm_expr);
1425 macro_build (&icnt, &offset_expr, s, "s,t,p", sreg, AT);
1426 break;
1427
1428 case M_BGEL:
1429 likely = 1;
1430 case M_BGE:
1431 if (treg == 0)
1432 {
1433 macro_build (&icnt, &offset_expr,
1434 likely ? "bgezl" : "bgez",
1435 "s,p", sreg);
1436 return;
1437 }
1438 if (sreg == 0)
1439 {
1440 macro_build (&icnt, &offset_expr,
1441 likely ? "blezl" : "blez",
1442 "s,p", treg);
1443 return;
1444 }
1445 macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
1446 macro_build (&icnt, &offset_expr,
1447 likely ? "beql" : "beq",
1448 "s,t,p", AT, 0);
1449 break;
1450
1451 case M_BGTL_I:
1452 likely = 1;
1453 case M_BGT_I:
1454 /* check for > max integer */
1455 maxnum = 0x7fffffff;
1456 if (mips_isa >= 3)
1457 {
1458 maxnum <<= 16;
1459 maxnum |= 0xffff;
1460 maxnum <<= 16;
1461 maxnum |= 0xffff;
1462 }
1463 if (imm_expr.X_add_number >= maxnum)
1464 {
1465 do_false:
1466 /* result is always false */
1467 if (! likely)
1468 {
1469 as_warn ("Branch %s is always false (nop)", ip->insn_mo->name);
1470 macro_build (&icnt, NULL, "nop", "", 0);
1471 }
1472 else
1473 {
1474 as_warn ("Branch likely %s is always false", ip->insn_mo->name);
1475 macro_build (&icnt, &offset_expr, "bnel", "s,t,p", 0, 0);
1476 }
1477 return;
1478 }
1479 imm_expr.X_add_number++;
1480 /* FALLTHROUGH */
1481 case M_BGE_I:
1482 case M_BGEL_I:
1483 if (mask == M_BGEL_I)
1484 likely = 1;
1485 if (imm_expr.X_add_number == 0)
1486 {
1487 macro_build (&icnt, &offset_expr,
1488 likely ? "bgezl" : "bgez",
1489 "s,p", sreg);
1490 return;
1491 }
1492 if (imm_expr.X_add_number == 1)
1493 {
1494 macro_build (&icnt, &offset_expr,
1495 likely ? "bgtzl" : "bgtz",
1496 "s,p", sreg);
1497 return;
1498 }
1499 maxnum = 0x7fffffff;
1500 if (mips_isa >= 3)
1501 {
1502 maxnum <<= 16;
1503 maxnum |= 0xffff;
1504 maxnum <<= 16;
1505 maxnum |= 0xffff;
1506 }
1507 maxnum = - maxnum - 1;
1508 if (imm_expr.X_add_number <= maxnum)
1509 {
1510 do_true:
1511 /* result is always true */
1512 as_warn ("Branch %s is always true", ip->insn_mo->name);
1513 macro_build (&icnt, &offset_expr, "b", "p");
1514 return;
1515 }
1516 set_at (&icnt, sreg, 0);
1517 macro_build (&icnt, &offset_expr,
1518 likely ? "beql" : "beq",
1519 "s,t,p", AT, 0);
1520 break;
1521
1522 case M_BGEUL:
1523 likely = 1;
1524 case M_BGEU:
1525 if (treg == 0)
1526 goto do_true;
1527 if (sreg == 0)
1528 {
1529 macro_build (&icnt, &offset_expr,
1530 likely ? "beql" : "beq",
1531 "s,t,p", 0, treg);
1532 return;
1533 }
1534 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
1535 macro_build (&icnt, &offset_expr,
1536 likely ? "beql" : "beq",
1537 "s,t,p", AT, 0);
1538 break;
1539
1540 case M_BGTUL_I:
1541 likely = 1;
1542 case M_BGTU_I:
1543 if (sreg == 0 || imm_expr.X_add_number == -1)
1544 goto do_false;
1545 imm_expr.X_add_number++;
1546 /* FALLTHROUGH */
1547 case M_BGEU_I:
1548 case M_BGEUL_I:
1549 if (mask == M_BGEUL_I)
1550 likely = 1;
1551 if (imm_expr.X_add_number == 0)
1552 goto do_true;
1553 if (imm_expr.X_add_number == 1)
1554 {
1555 macro_build (&icnt, &offset_expr,
1556 likely ? "bnel" : "bne",
1557 "s,t,p", sreg, 0);
1558 return;
1559 }
1560 set_at (&icnt, sreg, 1);
1561 macro_build (&icnt, &offset_expr,
1562 likely ? "beql" : "beq",
1563 "s,t,p", AT, 0);
1564 break;
1565
1566 case M_BGTL:
1567 likely = 1;
1568 case M_BGT:
1569 if (treg == 0)
1570 {
1571 macro_build (&icnt, &offset_expr,
1572 likely ? "bgtzl" : "bgtz",
1573 "s,p", sreg);
1574 return;
1575 }
1576 if (sreg == 0)
1577 {
1578 macro_build (&icnt, &offset_expr,
1579 likely ? "bltzl" : "bltz",
1580 "s,p", treg);
1581 return;
1582 }
1583 macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
1584 macro_build (&icnt, &offset_expr,
1585 likely ? "bnel" : "bne",
1586 "s,t,p", AT, 0);
1587 break;
1588
1589 case M_BGTUL:
1590 likely = 1;
1591 case M_BGTU:
1592 if (treg == 0)
1593 {
1594 macro_build (&icnt, &offset_expr,
1595 likely ? "bnel" : "bne",
1596 "s,t,p", sreg, 0);
1597 return;
1598 }
1599 if (sreg == 0)
1600 goto do_false;
1601 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
1602 macro_build (&icnt, &offset_expr,
1603 likely ? "bnel" : "bne",
1604 "s,t,p", AT, 0);
1605 break;
1606
1607 case M_BLEL:
1608 likely = 1;
1609 case M_BLE:
1610 if (treg == 0)
1611 {
1612 macro_build (&icnt, &offset_expr,
1613 likely ? "blezl" : "blez",
1614 "s,p", sreg);
1615 return;
1616 }
1617 if (sreg == 0)
1618 {
1619 macro_build (&icnt, &offset_expr,
1620 likely ? "bgezl" : "bgez",
1621 "s,p", treg);
1622 return;
1623 }
1624 macro_build (&icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
1625 macro_build (&icnt, &offset_expr,
1626 likely ? "beql" : "beq",
1627 "s,t,p", AT, 0);
1628 break;
1629
1630 case M_BLEL_I:
1631 likely = 1;
1632 case M_BLE_I:
1633 maxnum = 0x7fffffff;
1634 if (mips_isa >= 3)
1635 {
1636 maxnum <<= 16;
1637 maxnum |= 0xffff;
1638 maxnum <<= 16;
1639 maxnum |= 0xffff;
1640 }
1641 if (imm_expr.X_add_number >= maxnum)
1642 goto do_true;
1643 imm_expr.X_add_number++;
1644 /* FALLTHROUGH */
1645 case M_BLT_I:
1646 case M_BLTL_I:
1647 if (mask == M_BLTL_I)
1648 likely = 1;
1649 if (imm_expr.X_add_number == 0)
1650 {
1651 macro_build (&icnt, &offset_expr,
1652 likely ? "bltzl" : "bltz",
1653 "s,p", sreg);
1654 return;
1655 }
1656 if (imm_expr.X_add_number == 1)
1657 {
1658 macro_build (&icnt, &offset_expr,
1659 likely ? "blezl" : "blez",
1660 "s,p", sreg);
1661 return;
1662 }
1663 set_at (&icnt, sreg, 0);
1664 macro_build (&icnt, &offset_expr,
1665 likely ? "bnel" : "bne",
1666 "s,t,p", AT, 0);
1667 break;
1668
1669 case M_BLEUL:
1670 likely = 1;
1671 case M_BLEU:
1672 if (treg == 0)
1673 {
1674 macro_build (&icnt, &offset_expr,
1675 likely ? "beql" : "beq",
1676 "s,t,p", sreg, 0);
1677 return;
1678 }
1679 if (sreg == 0)
1680 goto do_true;
1681 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, treg, sreg);
1682 macro_build (&icnt, &offset_expr,
1683 likely ? "beql" : "beq",
1684 "s,t,p", AT, 0);
1685 break;
1686
1687 case M_BLEUL_I:
1688 likely = 1;
1689 case M_BLEU_I:
1690 if (sreg == 0 || imm_expr.X_add_number == -1)
1691 goto do_true;
1692 imm_expr.X_add_number++;
1693 /* FALLTHROUGH */
1694 case M_BLTU_I:
1695 case M_BLTUL_I:
1696 if (mask == M_BLTUL_I)
1697 likely = 1;
1698 if (imm_expr.X_add_number == 0)
1699 goto do_false;
1700 if (imm_expr.X_add_number == 1)
1701 {
1702 macro_build (&icnt, &offset_expr,
1703 likely ? "beql" : "beq",
1704 "s,t,p", sreg, 0);
1705 return;
1706 }
1707 set_at (&icnt, sreg, 1);
1708 macro_build (&icnt, &offset_expr,
1709 likely ? "bnel" : "bne",
1710 "s,t,p", AT, 0);
1711 break;
1712
1713 case M_BLTL:
1714 likely = 1;
1715 case M_BLT:
1716 if (treg == 0)
1717 {
1718 macro_build (&icnt, &offset_expr,
1719 likely ? "bltzl" : "bltz",
1720 "s,p", sreg);
1721 return;
1722 }
1723 if (sreg == 0)
1724 {
1725 macro_build (&icnt, &offset_expr,
1726 likely ? "bgtzl" : "bgtz",
1727 "s,p", treg);
1728 return;
1729 }
1730 macro_build (&icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
1731 macro_build (&icnt, &offset_expr,
1732 likely ? "bnel" : "bne",
1733 "s,t,p", AT, 0);
1734 break;
1735
1736 case M_BLTUL:
1737 likely = 1;
1738 case M_BLTU:
1739 if (treg == 0)
1740 goto do_false;
1741 if (sreg == 0)
1742 {
1743 macro_build (&icnt, &offset_expr,
1744 likely ? "bnel" : "bne",
1745 "s,t,p", 0, treg);
1746 return;
1747 }
1748 macro_build (&icnt, NULL, "sltu", "d,v,t", AT, sreg, treg);
1749 macro_build (&icnt, &offset_expr,
1750 likely ? "bnel" : "bne",
1751 "s,t,p", AT, 0);
1752 break;
1753
1754 case M_DDIV_3:
1755 dbl = 1;
1756 case M_DIV_3:
1757 s = "mflo";
1758 goto do_div3;
1759 case M_DREM_3:
1760 dbl = 1;
1761 case M_REM_3:
1762 s = "mfhi";
1763 do_div3:
1764 if (treg == 0)
1765 {
1766 as_warn ("Divide by zero.");
1767 macro_build (&icnt, NULL, "break", "c", 7);
1768 return;
1769 }
1770
1771 mips_emit_delays ();
1772 ++mips_noreorder;
1773 macro_build (&icnt, NULL,
1774 dbl ? "ddiv" : "div",
1775 "z,s,t", sreg, treg);
1776 expr1.X_add_number = 8;
1777 macro_build (&icnt, &expr1, "bne", "s,t,p", treg, 0);
1778 macro_build (&icnt, NULL, "nop", "", 0);
1779 macro_build (&icnt, NULL, "break", "c", 7);
1780 expr1.X_add_number = -1;
1781 macro_build (&icnt, &expr1,
1782 dbl ? "daddiu" : "addiu",
1783 "t,r,j", AT, 0);
1784 expr1.X_add_number = dbl ? 20 : 16;
1785 macro_build (&icnt, &expr1, "bne", "s,t,p", treg, AT);
1786 if (dbl)
1787 {
1788 expr1.X_add_number = 1;
1789 macro_build (&icnt, &expr1, "daddiu", "t,r,j", AT, 0);
1790 macro_build (&icnt, NULL, "dsll32", "d,w,<", AT, AT, 31);
1791 }
1792 else
1793 {
1794 expr1.X_add_number = 0x80000000;
1795 macro_build (&icnt, &expr1, "lui", "t,u", AT);
1796 }
1797 expr1.X_add_number = 8;
1798 macro_build (&icnt, &expr1, "bne", "s,t,p", sreg, AT);
1799 macro_build (&icnt, NULL, "nop", "", 0);
1800 macro_build (&icnt, NULL, "break", "c", 6);
1801 --mips_noreorder;
1802 macro_build (&icnt, NULL, s, "d", dreg);
1803 break;
1804
1805 case M_DIV_3I:
1806 s = "div";
1807 s2 = "mflo";
1808 goto do_divi;
1809 case M_DIVU_3I:
1810 s = "divu";
1811 s2 = "mflo";
1812 goto do_divi;
1813 case M_REM_3I:
1814 s = "div";
1815 s2 = "mfhi";
1816 goto do_divi;
1817 case M_REMU_3I:
1818 s = "divu";
1819 s2 = "mfhi";
1820 goto do_divi;
1821 case M_DDIV_3I:
1822 dbl = 1;
1823 s = "ddiv";
1824 s2 = "mflo";
1825 goto do_divi;
1826 case M_DDIVU_3I:
1827 dbl = 1;
1828 s = "ddivu";
1829 s2 = "mflo";
1830 goto do_divi;
1831 case M_DREM_3I:
1832 dbl = 1;
1833 s = "ddiv";
1834 s2 = "mfhi";
1835 goto do_divi;
1836 case M_DREMU_3I:
1837 dbl = 1;
1838 s = "ddivu";
1839 s2 = "mfhi";
1840 do_divi:
1841 if (imm_expr.X_add_number == 0)
1842 {
1843 as_warn ("Divide by zero.");
1844 macro_build (&icnt, NULL, "break", "c", 7);
1845 return;
1846 }
1847 if (imm_expr.X_add_number == 1)
1848 {
1849 if (strcmp (s2, "mflo") == 0)
1850 macro_build (&icnt, NULL, "move", "d,s", dreg, sreg);
1851 else
1852 macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
1853 return;
1854 }
1855 if (imm_expr.X_add_number == -1
1856 && s[strlen (s) - 1] != 'u')
1857 {
1858 if (strcmp (s2, "mflo") == 0)
1859 {
1860 if (dbl)
1861 macro_build (&icnt, NULL, "dneg", "d,w", dreg, sreg);
1862 else
1863 macro_build (&icnt, NULL, "neg", "d,w", dreg, sreg);
1864 }
1865 else
1866 macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
1867 return;
1868 }
1869
1870 load_register (&icnt, AT, &imm_expr);
1871 macro_build (&icnt, NULL, s, "z,s,t", sreg, AT);
1872 macro_build (&icnt, NULL, s2, "d", dreg);
1873 break;
1874
1875 case M_DIVU_3:
1876 s = "divu";
1877 s2 = "mflo";
1878 goto do_divu3;
1879 case M_REMU_3:
1880 s = "divu";
1881 s2 = "mfhi";
1882 goto do_divu3;
1883 case M_DDIVU_3:
1884 s = "ddivu";
1885 s2 = "mflo";
1886 goto do_divu3;
1887 case M_DREMU_3:
1888 s = "ddivu";
1889 s2 = "mfhi";
1890 do_divu3:
1891 mips_emit_delays ();
1892 ++mips_noreorder;
1893 macro_build (&icnt, NULL, s, "z,s,t", sreg, treg);
1894 expr1.X_add_number = 8;
1895 macro_build (&icnt, &expr1, "bne", "s,t,p", treg, 0);
1896 macro_build (&icnt, NULL, "nop", "", 0);
1897 macro_build (&icnt, NULL, "break", "c", 7);
1898 --mips_noreorder;
1899 macro_build (&icnt, NULL, s2, "d", dreg);
1900 return;
1901
1902 case M_LA:
1903 if (offset_expr.X_op == O_constant)
1904 {
1905 load_register (&icnt, treg, &offset_expr);
1906 return;
1907 }
1908 if (gp_reference (&offset_expr))
1909 macro_build (&icnt, &offset_expr,
1910 mips_isa < 3 ? "addiu" : "daddiu",
1911 "t,r,j", treg, GP);
1912 else
1913 {
1914 /* FIXME: This won't work for a 64 bit address. */
1915 macro_build_lui (&icnt, &offset_expr, treg);
1916 macro_build (&icnt, &offset_expr,
1917 mips_isa < 3 ? "addiu" : "daddiu",
1918 "t,r,j", treg, treg);
1919 }
1920 return;
1921
1922 case M_LA_AB:
1923 tempreg = (breg == treg) ? AT : treg;
1924 if (offset_expr.X_op == O_constant)
1925 load_register (&icnt, tempreg, &offset_expr);
1926 else if (gp_reference (&offset_expr))
1927 macro_build (&icnt, &offset_expr,
1928 mips_isa < 3 ? "addiu" : "daddiu",
1929 "t,r,j", tempreg, GP);
1930 else
1931 {
1932 /* FIXME: This won't work for a 64 bit address. */
1933 macro_build_lui (&icnt, &offset_expr, tempreg);
1934 macro_build (&icnt, &offset_expr,
1935 mips_isa < 3 ? "addiu" : "daddiu",
1936 "t,r,j", tempreg, tempreg);
1937 }
1938 if (breg != 0)
1939 macro_build (&icnt, NULL, "addu", "d,v,t", treg, tempreg, breg);
1940 if (breg == treg)
1941 break;
1942 return;
1943
1944 case M_LB_AB:
1945 s = "lb";
1946 goto ld;
1947 case M_LBU_AB:
1948 s = "lbu";
1949 goto ld;
1950 case M_LH_AB:
1951 s = "lh";
1952 goto ld;
1953 case M_LHU_AB:
1954 s = "lhu";
1955 goto ld;
1956 case M_LW_AB:
1957 s = "lw";
1958 goto ld;
1959 case M_LWC0_AB:
1960 s = "lwc0";
1961 coproc = 1;
1962 goto ld;
1963 case M_LWC1_AB:
1964 case M_LI_SS:
1965 s = "lwc1";
1966 coproc = 1;
1967 goto ld;
1968 case M_LWC2_AB:
1969 s = "lwc2";
1970 coproc = 1;
1971 goto ld;
1972 case M_LWC3_AB:
1973 s = "lwc3";
1974 coproc = 1;
1975 goto ld;
1976 case M_LWL_AB:
1977 s = "lwl";
1978 goto ld;
1979 case M_LWR_AB:
1980 s = "lwr";
1981 goto ld;
1982 case M_LDC1_AB:
1983 s = "ldc1";
1984 coproc = 1;
1985 goto ld;
1986 case M_LDC2_AB:
1987 s = "ldc2";
1988 coproc = 1;
1989 goto ld;
1990 case M_LDC3_AB:
1991 s = "ldc3";
1992 coproc = 1;
1993 goto ld;
1994 case M_LDL_AB:
1995 s = "ldl";
1996 goto ld;
1997 case M_LDR_AB:
1998 s = "ldr";
1999 goto ld;
2000 case M_LL_AB:
2001 s = "ll";
2002 goto ld;
2003 case M_LLD_AB:
2004 s = "lld";
2005 goto ld;
2006 case M_LWU_AB:
2007 s = "lwu";
2008 ld:
2009 if (breg == treg || coproc)
2010 {
2011 tempreg = AT;
2012 used_at = 1;
2013 }
2014 else
2015 {
2016 tempreg = treg;
2017 used_at = 0;
2018 }
2019 goto ld_st;
2020 case M_SB_AB:
2021 s = "sb";
2022 goto st;
2023 case M_SH_AB:
2024 s = "sh";
2025 goto st;
2026 case M_SW_AB:
2027 s = "sw";
2028 goto st;
2029 case M_SWC0_AB:
2030 s = "swc0";
2031 coproc = 1;
2032 goto st;
2033 case M_SWC1_AB:
2034 s = "swc1";
2035 coproc = 1;
2036 goto st;
2037 case M_SWC2_AB:
2038 s = "swc2";
2039 coproc = 1;
2040 goto st;
2041 case M_SWC3_AB:
2042 s = "swc3";
2043 coproc = 1;
2044 goto st;
2045 case M_SWL_AB:
2046 s = "swl";
2047 goto st;
2048 case M_SWR_AB:
2049 s = "swr";
2050 goto st;
2051 case M_SC_AB:
2052 s = "sc";
2053 goto st;
2054 case M_SCD_AB:
2055 s = "scd";
2056 goto st;
2057 case M_SDC1_AB:
2058 s = "sdc1";
2059 coproc = 1;
2060 goto st;
2061 case M_SDC2_AB:
2062 s = "sdc2";
2063 coproc = 1;
2064 goto st;
2065 case M_SDC3_AB:
2066 s = "sdc3";
2067 coproc = 1;
2068 goto st;
2069 case M_SDL_AB:
2070 s = "sdl";
2071 goto st;
2072 case M_SDR_AB:
2073 s = "sdr";
2074 st:
2075 tempreg = AT;
2076 used_at = 1;
2077 ld_st:
2078 if (mask == M_LWC1_AB
2079 || mask == M_SWC1_AB
2080 || mask == M_LI_SS
2081 || mask == M_LDC1_AB
2082 || mask == M_SDC1_AB)
2083 fmt = "T,o(b)";
2084 else if (coproc)
2085 fmt = "E,o(b)";
2086 else
2087 fmt = "t,o(b)";
2088 if (gp_reference (&offset_expr))
2089 {
2090 if (breg == 0)
2091 {
2092 macro_build (&icnt, &offset_expr, s, fmt, treg, GP);
2093 return;
2094 }
2095 macro_build (&icnt, (expressionS *) NULL,
2096 mips_isa < 3 ? "addu" : "daddu",
2097 "d,v,t", tempreg, breg, GP);
2098 }
2099 else
2100 {
2101 /* FIXME: This won't work for a 64 bit address. */
2102 macro_build_lui (&icnt, &offset_expr, tempreg);
2103 if (breg != 0)
2104 macro_build (&icnt, NULL,
2105 mips_isa < 3 ? "addu" : "daddu",
2106 "d,v,t", tempreg, tempreg, breg);
2107 }
2108 macro_build (&icnt, &offset_expr, s, fmt, treg, tempreg);
2109 if (used_at)
2110 break;
2111 return;
2112
2113 case M_LI:
2114 case M_LI_S:
2115 load_register (&icnt, treg, &imm_expr);
2116 return;
2117
2118 case M_LI_D:
2119 /* lui $at,%hi(foo)
2120 lw $v0,%lo(foo)($at)
2121 lw $v1,%lo(foo+4)($at)
2122 .rdata
2123 foo:
2124 .double 3.133435
2125 */
2126 /* FIXME: This won't work for a 64 bit address. */
2127 macro_build_lui (&icnt, &offset_expr, AT);
2128 if (mips_isa >= 3)
2129 macro_build (&icnt, &offset_expr, "ld", "t,o(b)", treg, AT);
2130 else
2131 {
2132 macro_build (&icnt, &offset_expr, "lw", "t,o(b)", treg, AT);
2133 offset_expr.X_add_number += 4;
2134 macro_build (&icnt, &offset_expr, "lw", "t,o(b)", treg + 1, AT);
2135 }
2136 break;
2137
2138 case M_LI_DD:
2139 /* Load a floating point number from the .lit8 section. */
2140 if (mips_isa >= 2)
2141 {
2142 macro_build (&icnt, &offset_expr, "ldc1", "T,o(b)", treg, GP);
2143 return;
2144 }
2145 breg = GP;
2146 /* Fall through. */
2147 case M_L_DOB:
2148 /* Even on a big endian machine $fn comes before $fn+1. We have
2149 to adjust when loading from memory. */
2150 assert (mips_isa < 2);
2151 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
2152 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
2153 breg);
2154 offset_expr.X_add_number += 4;
2155 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
2156 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
2157 breg);
2158 return;
2159
2160 case M_L_DAB:
2161 /*
2162 * The MIPS assembler seems to check for X_add_number not
2163 * being double aligned and generating:
2164 * lui at,%hi(foo+1)
2165 * addu at,at,v1
2166 * addiu at,at,%lo(foo+1)
2167 * lwc1 f2,0(at)
2168 * lwc1 f3,4(at)
2169 * But, the resulting address is the same after relocation so why
2170 * generate the extra instruction?
2171 */
2172 if (gp_reference (&offset_expr))
2173 {
2174 if (breg == 0)
2175 tempreg = GP;
2176 else
2177 {
2178 macro_build (&icnt, &offset_expr,
2179 mips_isa < 3 ? "addu" : "daddu",
2180 "d,v,t", AT, breg, GP);
2181 tempreg = AT;
2182 }
2183 }
2184 else
2185 {
2186 /* FIXME: This won't work for a 64 bit address. */
2187 macro_build_lui (&icnt, &offset_expr, AT);
2188 if (breg != 0)
2189 macro_build (&icnt, NULL,
2190 mips_isa < 3 ? "addu" : "daddu",
2191 "d,v,t", AT, AT, breg);
2192 tempreg = AT;
2193 }
2194 if (mips_isa >= 2)
2195 macro_build (&icnt, &offset_expr, "ldc1", "T,o(b)", treg, tempreg);
2196 else
2197 {
2198 /* Even on a big endian machine $fn comes before $fn+1. We
2199 have to adjust when loading from memory. */
2200 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
2201 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
2202 tempreg);
2203 offset_expr.X_add_number += 4;
2204 macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)",
2205 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
2206 tempreg);
2207 }
2208 if (tempreg == AT)
2209 break;
2210 return;
2211
2212 case M_LD_OB:
2213 s = "lw";
2214 goto sd_ob;
2215 case M_SD_OB:
2216 s = "sw";
2217 sd_ob:
2218 assert (mips_isa < 3);
2219 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg, breg);
2220 offset_expr.X_add_number += 4;
2221 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg + 1, breg);
2222 return;
2223
2224 case M_LD_AB:
2225 s = "lw";
2226 s2 = "ld";
2227 if (breg == treg)
2228 {
2229 tempreg = AT;
2230 used_at = 1;
2231 }
2232 else
2233 {
2234 tempreg = treg;
2235 used_at = 0;
2236 }
2237 goto sd_ab;
2238 case M_SD_AB:
2239 s = "sw";
2240 s2 = "sd";
2241 tempreg = AT;
2242 used_at = 1;
2243 sd_ab:
2244 if (gp_reference (&offset_expr))
2245 {
2246 if (breg == 0)
2247 {
2248 tempreg = GP;
2249 used_at = 0;
2250 }
2251 else
2252 macro_build (&icnt, (expressionS *) NULL,
2253 mips_isa < 3 ? "addu" : "daddu",
2254 "d,v,t", tempreg, breg, GP);
2255 }
2256 else
2257 {
2258 /* FIXME: This won't work for a 64 bit address. */
2259 macro_build_lui (&icnt, &offset_expr, tempreg);
2260 if (breg != 0)
2261 macro_build (&icnt, NULL,
2262 mips_isa < 3 ? "addu" : "daddu",
2263 "d,v,t", tempreg, tempreg, breg);
2264 }
2265 if (mips_isa >= 3)
2266 macro_build (&icnt, &offset_expr, s2, "t,o(b)", treg, tempreg);
2267 else
2268 {
2269 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg, tempreg);
2270 offset_expr.X_add_number += 4;
2271 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg + 1, tempreg);
2272 }
2273 if (used_at)
2274 break;
2275 return;
2276
2277 case M_DMUL:
2278 dbl = 1;
2279 case M_MUL:
2280 macro_build (&icnt, NULL,
2281 dbl ? "dmultu" : "multu",
2282 "s,t", sreg, treg);
2283 macro_build (&icnt, NULL, "mflo", "d", dreg);
2284 return;
2285
2286 case M_DMUL_I:
2287 dbl = 1;
2288 case M_MUL_I:
2289 /* The MIPS assembler some times generates shifts and adds. I'm
2290 not trying to be that fancy. GCC should do this for us
2291 anyway. */
2292 load_register (&icnt, AT, &imm_expr);
2293 macro_build (&icnt, NULL,
2294 dbl ? "dmult" : "mult",
2295 "s,t", sreg, AT);
2296 macro_build (&icnt, NULL, "mflo", "d", dreg);
2297 break;
2298
2299 case M_DMULO:
2300 dbl = 1;
2301 case M_MULO:
2302 mips_emit_delays ();
2303 ++mips_noreorder;
2304 macro_build (&icnt, NULL,
2305 dbl ? "dmult" : "mult",
2306 "s,t", sreg, treg);
2307 macro_build (&icnt, NULL, "mflo", "d", dreg);
2308 macro_build (&icnt, NULL,
2309 dbl ? "dsra32" : "sra",
2310 "d,w,<", dreg, dreg, 31);
2311 macro_build (&icnt, NULL, "mfhi", "d", AT);
2312 expr1.X_add_number = 8;
2313 macro_build (&icnt, &expr1, "beq", "s,t,p", dreg, AT);
2314 macro_build (&icnt, NULL, "nop", "", 0);
2315 macro_build (&icnt, NULL, "break", "c", 6);
2316 --mips_noreorder;
2317 macro_build (&icnt, NULL, "mflo", "d", dreg);
2318 break;
2319
2320 case M_DMULOU:
2321 dbl = 1;
2322 case M_MULOU:
2323 mips_emit_delays ();
2324 ++mips_noreorder;
2325 macro_build (&icnt, NULL,
2326 dbl ? "dmultu" : "multu",
2327 "s,t", sreg, treg);
2328 macro_build (&icnt, NULL, "mfhi", "d", AT);
2329 macro_build (&icnt, NULL, "mflo", "d", dreg);
2330 expr1.X_add_number = 8;
2331 macro_build (&icnt, &expr1, "beq", "s,t,p", AT, 0);
2332 macro_build (&icnt, NULL, "nop", "", 0);
2333 macro_build (&icnt, NULL, "break", "c", 6);
2334 --mips_noreorder;
2335 break;
2336
2337 case M_ROL:
2338 macro_build (&icnt, NULL, "subu", "d,v,t", AT, 0, treg);
2339 macro_build (&icnt, NULL, "srlv", "d,t,s", AT, sreg, AT);
2340 macro_build (&icnt, NULL, "sllv", "d,t,s", dreg, sreg, treg);
2341 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
2342 break;
2343
2344 case M_ROL_I:
2345 macro_build (&icnt, NULL, "sll", "d,w,<", AT, sreg,
2346 imm_expr.X_add_number & 0x1f);
2347 macro_build (&icnt, NULL, "srl", "d,w,<", dreg, sreg,
2348 (0 - imm_expr.X_add_number) & 0x1f);
2349 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
2350 break;
2351
2352 case M_ROR:
2353 macro_build (&icnt, NULL, "subu", "d,v,t", AT, 0, treg);
2354 macro_build (&icnt, NULL, "sllv", "d,t,s", AT, sreg, AT);
2355 macro_build (&icnt, NULL, "srlv", "d,t,s", dreg, sreg, treg);
2356 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
2357 break;
2358
2359 case M_ROR_I:
2360 macro_build (&icnt, NULL, "srl", "d,w,<", AT, sreg,
2361 imm_expr.X_add_number & 0x1f);
2362 macro_build (&icnt, NULL, "sll", "d,w,<", dreg, sreg,
2363 (0 - imm_expr.X_add_number) & 0x1f);
2364 macro_build (&icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
2365 break;
2366
2367 case M_S_DOB:
2368 assert (mips_isa < 2);
2369 /* Even on a big endian machine $fn comes before $fn+1. We have
2370 to adjust when storing to memory. */
2371 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
2372 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
2373 breg);
2374 offset_expr.X_add_number += 4;
2375 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
2376 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
2377 breg);
2378 return;
2379
2380 case M_S_DAB:
2381 if (gp_reference (&offset_expr))
2382 {
2383 if (breg == 0)
2384 tempreg = GP;
2385 else
2386 {
2387 macro_build (&icnt, (expressionS *) NULL,
2388 mips_isa < 3 ? "addu" : "daddu",
2389 "d,v,t", AT, breg, GP);
2390 tempreg = AT;
2391 }
2392 }
2393 else
2394 {
2395 /* FIXME: This won't work for a 64 bit address. */
2396 macro_build_lui (&icnt, &offset_expr, AT);
2397 if (breg != 0)
2398 macro_build (&icnt, NULL,
2399 mips_isa < 3 ? "addu" : "daddu",
2400 "d,v,t", AT, AT, breg);
2401 tempreg = AT;
2402 }
2403 if (mips_isa >= 2)
2404 macro_build (&icnt, &offset_expr, "sdc1", "T,o(b)", treg, tempreg);
2405 else
2406 {
2407 /* Even on a big endian machine $fn comes before $fn+1. We
2408 have to adjust when storing to memory. */
2409 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
2410 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
2411 tempreg);
2412 offset_expr.X_add_number += 4;
2413 macro_build (&icnt, &offset_expr, "swc1", "T,o(b)",
2414 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
2415 tempreg);
2416 }
2417 if (tempreg == AT)
2418 break;
2419 return;
2420
2421 case M_SEQ:
2422 if (sreg == 0)
2423 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, treg);
2424 else if (treg == 0)
2425 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, sreg);
2426 else
2427 {
2428 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, treg);
2429 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, dreg);
2430 }
2431 return;
2432
2433 case M_SEQ_I:
2434 if (imm_expr.X_add_number == 0)
2435 {
2436 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, sreg);
2437 return;
2438 }
2439 if (sreg == 0)
2440 {
2441 as_warn ("Instruction %s: result is always false",
2442 ip->insn_mo->name);
2443 macro_build (&icnt, NULL, "move", "d,s", dreg, 0);
2444 return;
2445 }
2446 if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
2447 {
2448 macro_build (&icnt, &imm_expr, "xori", "t,r,i", dreg, sreg);
2449 used_at = 0;
2450 }
2451 else if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number < 0)
2452 {
2453 imm_expr.X_add_number = -imm_expr.X_add_number;
2454 macro_build (&icnt, &imm_expr,
2455 mips_isa < 3 ? "addiu" : "daddiu",
2456 "t,r,j", dreg, sreg);
2457 used_at = 0;
2458 }
2459 else
2460 {
2461 load_register (&icnt, AT, &imm_expr);
2462 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, AT);
2463 used_at = 1;
2464 }
2465 macro_build (&icnt, &expr1, "sltiu", "t,r,j", dreg, dreg);
2466 if (used_at)
2467 break;
2468 return;
2469
2470 case M_SGE: /* sreg >= treg <==> not (sreg < treg) */
2471 s = "slt";
2472 goto sge;
2473 case M_SGEU:
2474 s = "sltu";
2475 sge:
2476 macro_build (&icnt, NULL, s, "d,v,t", dreg, sreg, treg);
2477 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
2478 return;
2479
2480 case M_SGE_I: /* sreg >= I <==> not (sreg < I) */
2481 case M_SGEU_I:
2482 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
2483 {
2484 macro_build (&icnt, &expr1,
2485 mask == M_SGE_I ? "slti" : "sltiu",
2486 "t,r,j", dreg, sreg);
2487 used_at = 0;
2488 }
2489 else
2490 {
2491 load_register (&icnt, AT, &imm_expr);
2492 macro_build (&icnt, NULL,
2493 mask == M_SGE_I ? "slt" : "sltu",
2494 "d,v,t", dreg, sreg, AT);
2495 used_at = 1;
2496 }
2497 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
2498 if (used_at)
2499 break;
2500 return;
2501
2502 case M_SGT: /* sreg > treg <==> treg < sreg */
2503 s = "slt";
2504 goto sgt;
2505 case M_SGTU:
2506 s = "sltu";
2507 sgt:
2508 macro_build (&icnt, NULL, s, "d,v,t", dreg, treg, sreg);
2509 return;
2510
2511 case M_SGT_I: /* sreg > I <==> I < sreg */
2512 s = "slt";
2513 goto sgti;
2514 case M_SGTU_I:
2515 s = "sltu";
2516 sgti:
2517 load_register (&icnt, AT, &imm_expr);
2518 macro_build (&icnt, NULL, s, "d,v,t", dreg, AT, sreg);
2519 break;
2520
2521 case M_SLE: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
2522 s = "slt";
2523 goto sle;
2524 case M_SLEU:
2525 s = "sltu";
2526 sle:
2527 macro_build (&icnt, NULL, s, "d,v,t", dreg, treg, sreg);
2528 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
2529 return;
2530
2531 case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
2532 s = "slt";
2533 goto slei;
2534 case M_SLEU_I:
2535 s = "sltu";
2536 slei:
2537 load_register (&icnt, AT, &imm_expr);
2538 macro_build (&icnt, NULL, s, "d,v,t", dreg, AT, sreg);
2539 macro_build (&icnt, &expr1, "xori", "t,r,i", dreg, dreg);
2540 break;
2541
2542 case M_SLT_I:
2543 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
2544 {
2545 macro_build (&icnt, &imm_expr, "slti", "t,r,j", dreg, sreg);
2546 return;
2547 }
2548 load_register (&icnt, AT, &imm_expr);
2549 macro_build (&icnt, NULL, "slt", "d,v,t", dreg, sreg, AT);
2550 break;
2551
2552 case M_SLTU_I:
2553 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
2554 {
2555 macro_build (&icnt, &imm_expr, "sltiu", "t,r,j", dreg, sreg);
2556 return;
2557 }
2558 load_register (&icnt, AT, &imm_expr);
2559 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, sreg, AT);
2560 break;
2561
2562 case M_SNE:
2563 if (sreg == 0)
2564 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, treg);
2565 else if (treg == 0)
2566 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, sreg);
2567 else
2568 {
2569 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, treg);
2570 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);
2571 }
2572 return;
2573
2574 case M_SNE_I:
2575 if (imm_expr.X_add_number == 0)
2576 {
2577 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, sreg);
2578 return;
2579 }
2580 if (sreg == 0)
2581 {
2582 as_warn ("Instruction %s: result is always true",
2583 ip->insn_mo->name);
2584 macro_build (&icnt, &expr1,
2585 mips_isa < 3 ? "addiu" : "daddiu",
2586 "t,r,j", dreg, 0);
2587 return;
2588 }
2589 if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
2590 {
2591 macro_build (&icnt, &imm_expr, "xori", "t,r,i", dreg, sreg);
2592 used_at = 0;
2593 }
2594 else if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number < 0)
2595 {
2596 imm_expr.X_add_number = -imm_expr.X_add_number;
2597 macro_build (&icnt, &imm_expr,
2598 mips_isa < 3 ? "addiu" : "daddiu",
2599 "t,r,j", dreg, sreg);
2600 used_at = 0;
2601 }
2602 else
2603 {
2604 load_register (&icnt, AT, &imm_expr);
2605 macro_build (&icnt, NULL, "xor", "d,v,t", dreg, sreg, AT);
2606 used_at = 1;
2607 }
2608 macro_build (&icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);
2609 if (used_at)
2610 break;
2611 return;
2612
2613 case M_DSUB_I:
2614 dbl = 1;
2615 case M_SUB_I:
2616 if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number <= 0x8000)
2617 {
2618 imm_expr.X_add_number = -imm_expr.X_add_number;
2619 macro_build (&icnt, &imm_expr,
2620 dbl ? "daddi" : "addi",
2621 "t,r,j", dreg, sreg);
2622 return;
2623 }
2624 load_register (&icnt, AT, &imm_expr);
2625 macro_build (&icnt, NULL,
2626 dbl ? "dsub" : "sub",
2627 "d,v,t", dreg, sreg, AT);
2628 break;
2629
2630 case M_DSUBU_I:
2631 dbl = 1;
2632 case M_SUBU_I:
2633 if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number <= 0x8000)
2634 {
2635 imm_expr.X_add_number = -imm_expr.X_add_number;
2636 macro_build (&icnt, &imm_expr,
2637 dbl ? "daddiu" : "addiu",
2638 "t,r,j", dreg, sreg);
2639 return;
2640 }
2641 load_register (&icnt, AT, &imm_expr);
2642 macro_build (&icnt, NULL,
2643 dbl ? "dsubu" : "subu",
2644 "d,v,t", dreg, sreg, AT);
2645 break;
2646
2647 case M_TEQ_I:
2648 s = "teq";
2649 goto trap;
2650 case M_TGE_I:
2651 s = "tge";
2652 goto trap;
2653 case M_TGEU_I:
2654 s = "tgeu";
2655 goto trap;
2656 case M_TLT_I:
2657 s = "tlt";
2658 goto trap;
2659 case M_TLTU_I:
2660 s = "tltu";
2661 goto trap;
2662 case M_TNE_I:
2663 s = "tne";
2664 trap:
2665 load_register (&icnt, AT, &imm_expr);
2666 macro_build (&icnt, NULL, s, "s,t", sreg, AT);
2667 break;
2668
2669 case M_TRUNCWD:
2670 case M_TRUNCWS:
2671 assert (mips_isa < 2);
2672 sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
2673 dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
2674
2675 /*
2676 * Is the double cfc1 instruction a bug in the mips assembler;
2677 * or is there a reason for it?
2678 */
2679 mips_emit_delays ();
2680 ++mips_noreorder;
2681 macro_build (&icnt, NULL, "cfc1", "t,G", treg, 31);
2682 macro_build (&icnt, NULL, "cfc1", "t,G", treg, 31);
2683 macro_build (&icnt, NULL, "nop", "");
2684 expr1.X_add_number = 3;
2685 macro_build (&icnt, &expr1, "ori", "t,r,i", AT, treg);
2686 expr1.X_add_number = 2;
2687 macro_build (&icnt, &expr1, "xori", "t,r,i", AT, AT);
2688 macro_build (&icnt, NULL, "ctc1", "t,G", AT, 31);
2689 macro_build (&icnt, NULL, "nop", "");
2690 macro_build (&icnt, NULL,
2691 mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg);
2692 macro_build (&icnt, NULL, "ctc1", "t,G", treg, 31);
2693 macro_build (&icnt, NULL, "nop", "");
2694 --mips_noreorder;
2695 break;
2696
2697 case M_ULH:
2698 s = "lb";
2699 goto ulh;
2700 case M_ULHU:
2701 s = "lbu";
2702 ulh:
2703 /* avoid load delay */
2704 offset_expr.X_add_number += 1;
2705 macro_build (&icnt, &offset_expr, s, "t,o(b)", treg, breg);
2706 offset_expr.X_add_number -= 1;
2707 macro_build (&icnt, &offset_expr, "lbu", "t,o(b)", AT, breg);
2708 macro_build (&icnt, NULL, "sll", "d,w,<", treg, treg, 8);
2709 macro_build (&icnt, NULL, "or", "d,v,t", treg, treg, AT);
2710 break;
2711
2712 case M_ULW:
2713 /* does this work on a big endian machine? */
2714 offset_expr.X_add_number += 3;
2715 macro_build (&icnt, &offset_expr, "lwl", "t,o(b)", treg, breg);
2716 offset_expr.X_add_number -= 3;
2717 macro_build (&icnt, &offset_expr, "lwr", "t,o(b)", treg, breg);
2718 return;
2719
2720 case M_ULH_A:
2721 case M_ULHU_A:
2722 case M_ULW_A:
2723 if (offset_expr.X_op == O_constant)
2724 load_register (&icnt, AT, &offset_expr);
2725 else if (gp_reference (&offset_expr))
2726 macro_build (&icnt, &offset_expr,
2727 mips_isa < 3 ? "addiu" : "daddiu",
2728 "t,r,j", AT, GP);
2729 else
2730 {
2731 /* FIXME: This won't work for a 64 bit address. */
2732 macro_build_lui (&icnt, &offset_expr, AT);
2733 macro_build (&icnt, &offset_expr,
2734 mips_isa < 3 ? "addiu" : "daddiu",
2735 "t,r,j", AT, AT);
2736 }
2737 if (mask == M_ULW_A)
2738 {
2739 expr1.X_add_number = 3;
2740 macro_build (&icnt, &expr1, "lwl", "t,o(b)", treg, AT);
2741 imm_expr.X_add_number = 0;
2742 macro_build (&icnt, &expr1, "lwr", "t,o(b)", treg, AT);
2743 }
2744 else
2745 {
2746 macro_build (&icnt, &expr1,
2747 mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg, AT);
2748 imm_expr.X_add_number = 0;
2749 macro_build (&icnt, &expr1, "lbu", "t,o(b)", AT, AT);
2750 macro_build (&icnt, NULL, "sll", "d,w,<", treg, treg, 8);
2751 macro_build (&icnt, NULL, "or", "d,v,t", treg, treg, AT);
2752 }
2753 break;
2754
2755 case M_USH:
2756 macro_build (&icnt, &offset_expr, "sb", "t,o(b)", treg, breg);
2757 macro_build (&icnt, NULL, "srl", "d,w,<", AT, treg, 8);
2758 offset_expr.X_add_number += 1;
2759 macro_build (&icnt, &offset_expr, "sb", "t,o(b)", AT, breg);
2760 break;
2761
2762 case M_USW:
2763 offset_expr.X_add_number += 3;
2764 macro_build (&icnt, &offset_expr, "swl", "t,o(b)", treg, breg);
2765 offset_expr.X_add_number -= 3;
2766 macro_build (&icnt, &offset_expr, "swr", "t,o(b)", treg, breg);
2767 return;
2768
2769 case M_USH_A:
2770 case M_USW_A:
2771 if (offset_expr.X_op == O_constant)
2772 load_register (&icnt, AT, &offset_expr);
2773 else if (gp_reference (&offset_expr))
2774 macro_build (&icnt, &offset_expr,
2775 mips_isa < 3 ? "addiu" : "daddiu",
2776 "t,r,j", AT, GP);
2777 else
2778 {
2779 /* FIXME: This won't work for a 64 bit address. */
2780 macro_build_lui (&icnt, &offset_expr, AT);
2781 macro_build (&icnt, &offset_expr,
2782 mips_isa < 3 ? "addiu" : "daddiu",
2783 "t,r,j", AT, AT);
2784 }
2785 if (mask == M_USW_A)
2786 {
2787 expr1.X_add_number = 3;
2788 macro_build (&icnt, &expr1, "swl", "t,o(b)", treg, AT);
2789 expr1.X_add_number = 0;
2790 macro_build (&icnt, &expr1, "swr", "t,o(b)", treg, AT);
2791 }
2792 else
2793 {
2794 expr1.X_add_number = 0;
2795 macro_build (&icnt, &expr1, "sb", "t,o(b)", treg, AT);
2796 macro_build (&icnt, NULL, "srl", "d,w,<", treg, treg, 8);
2797 expr1.X_add_number = 1;
2798 macro_build (&icnt, &expr1, "sb", "t,o(b)", treg, AT);
2799 expr1.X_add_number = 0;
2800 macro_build (&icnt, &expr1, "lbu", "t,o(b)", AT, AT);
2801 macro_build (&icnt, NULL, "sll", "d,w,<", treg, treg, 8);
2802 macro_build (&icnt, NULL, "or", "d,v,t", treg, treg, AT);
2803 }
2804 break;
2805
2806 default:
2807 as_bad ("Macro %s not implemented yet", ip->insn_mo->name);
2808 break;
2809 }
2810 if (mips_noat)
2811 as_warn ("Macro used $at after \".set noat\"");
2812 }
2813
2814
2815 /*
2816 This routine assembles an instruction into its binary format. As a side
2817 effect it sets one of the global variables imm_reloc or offset_reloc to the
2818 type of relocation to do if one of the operands is an address expression.
2819 */
2820 static void
2821 mips_ip (str, ip)
2822 char *str;
2823 struct mips_cl_insn *ip;
2824 {
2825 char *s;
2826 const char *args;
2827 char c;
2828 struct mips_opcode *insn;
2829 char *argsStart;
2830 unsigned int regno;
2831 unsigned int lastregno = 0;
2832 char *s_reset;
2833
2834 insn_error = NULL;
2835
2836 for (s = str; islower (*s) || (*s >= '0' && *s <= '3') || *s == '.'; ++s)
2837 continue;
2838 switch (*s)
2839 {
2840 case '\0':
2841 break;
2842
2843 case ' ':
2844 *s++ = '\0';
2845 break;
2846
2847 default:
2848 as_warn ("Unknown opcode: `%s'", str);
2849 exit (1);
2850 }
2851 if ((insn = (struct mips_opcode *) hash_find (op_hash, str)) == NULL)
2852 {
2853 as_warn ("`%s' not in hash table.", str);
2854 insn_error = "ERROR: Unrecognized opcode";
2855 return;
2856 }
2857 argsStart = s;
2858 for (;;)
2859 {
2860 int insn_isa;
2861
2862 assert (strcmp (insn->name, str) == 0);
2863
2864 if (insn->pinfo == INSN_MACRO)
2865 insn_isa = insn->match;
2866 else if (insn->pinfo & INSN_ISA2)
2867 insn_isa = 2;
2868 else if (insn->pinfo & INSN_ISA3)
2869 insn_isa = 3;
2870 else
2871 insn_isa = 1;
2872
2873 if (insn_isa > mips_isa)
2874 {
2875 if (insn + 1 < &mips_opcodes[NUMOPCODES]
2876 && strcmp (insn->name, insn[1].name) == 0)
2877 {
2878 ++insn;
2879 continue;
2880 }
2881 insn_error = "ERROR: instruction not supported on this processor";
2882 return;
2883 }
2884
2885 ip->insn_mo = insn;
2886 ip->insn_opcode = insn->match;
2887 for (args = insn->args;; ++args)
2888 {
2889 if (*s == ' ')
2890 ++s;
2891 switch (*args)
2892 {
2893 case '\0': /* end of args */
2894 if (*s == '\0')
2895 return;
2896 break;
2897
2898 case ',':
2899 if (*s++ == *args)
2900 continue;
2901 s--;
2902 switch (*++args)
2903 {
2904 case 'r':
2905 case 'v':
2906 ip->insn_opcode |= lastregno << 21;
2907 continue;
2908
2909 case 'w':
2910 case 'W':
2911 ip->insn_opcode |= lastregno << 16;
2912 continue;
2913
2914 case 'V':
2915 ip->insn_opcode |= lastregno << 11;
2916 continue;
2917 }
2918 break;
2919
2920 case '(':
2921 /* handle optional base register.
2922 Either the base register is omitted or
2923 we must have a left paren. */
2924 /* this is dependent on the next operand specifier
2925 is a 'b' for base register */
2926 assert (args[1] == 'b');
2927 if (*s == '\0')
2928 return;
2929
2930 case ')': /* these must match exactly */
2931 if (*s++ == *args)
2932 continue;
2933 break;
2934
2935 case '<': /* must be at least one digit */
2936 /*
2937 * According to the manual, if the shift amount is greater
2938 * than 31 or less than 0 the the shift amount should be
2939 * mod 32. In reality the mips assembler issues an error.
2940 * We issue a warning and do the mod.
2941 */
2942 my_getExpression (&imm_expr, s);
2943 check_absolute_expr (ip, &imm_expr);
2944 if ((unsigned long) imm_expr.X_add_number > 31)
2945 {
2946 as_warn ("Improper shift amount (%d)",
2947 imm_expr.X_add_number);
2948 imm_expr.X_add_number = imm_expr.X_add_number % 32;
2949 }
2950 ip->insn_opcode |= imm_expr.X_add_number << 6;
2951 imm_expr.X_op = O_absent;
2952 s = expr_end;
2953 continue;
2954
2955 case 'c': /* break code */
2956 my_getExpression (&imm_expr, s);
2957 check_absolute_expr (ip, &imm_expr);
2958 if ((unsigned) imm_expr.X_add_number > 1023)
2959 as_warn ("Illegal break code (%d)", imm_expr.X_add_number);
2960 ip->insn_opcode |= imm_expr.X_add_number << 16;
2961 imm_expr.X_op = O_absent;
2962 s = expr_end;
2963 continue;
2964
2965 case 'B': /* syscall code */
2966 my_getExpression (&imm_expr, s);
2967 check_absolute_expr (ip, &imm_expr);
2968 if ((unsigned) imm_expr.X_add_number > 0xfffff)
2969 as_warn ("Illegal syscall code (%d)", imm_expr.X_add_number);
2970 ip->insn_opcode |= imm_expr.X_add_number << 6;
2971 imm_expr.X_op = O_absent;
2972 s = expr_end;
2973 continue;
2974
2975 case 'C': /* Coprocessor code */
2976 my_getExpression (&imm_expr, s);
2977 check_absolute_expr (ip, &imm_expr);
2978 if ((unsigned long) imm_expr.X_add_number >= (1<<25))
2979 {
2980 as_warn ("Coproccesor code > 25 bits (%d)",
2981 imm_expr.X_add_number);
2982 imm_expr.X_add_number &= ((1<<25) - 1);
2983 }
2984 ip->insn_opcode |= imm_expr.X_add_number;
2985 imm_expr.X_op = O_absent;
2986 s = expr_end;
2987 continue;
2988
2989 case 'b': /* base register */
2990 case 'd': /* destination register */
2991 case 's': /* source register */
2992 case 't': /* target register */
2993 case 'r': /* both target and source */
2994 case 'v': /* both dest and source */
2995 case 'w': /* both dest and target */
2996 case 'E': /* coprocessor target register */
2997 case 'G': /* coprocessor destination register */
2998 case 'x': /* ignore register name */
2999 case 'z': /* must be zero register */
3000 s_reset = s;
3001 if (s[0] == '$')
3002 {
3003 if (isdigit (s[1]))
3004 {
3005 ++s;
3006 regno = 0;
3007 do
3008 {
3009 regno *= 10;
3010 regno += *s - '0';
3011 ++s;
3012 }
3013 while (isdigit (*s));
3014 if (regno > 31)
3015 as_bad ("Invalid register number (%d)", regno);
3016 }
3017 else if (*args != 'E' && *args != 'G')
3018 {
3019 if (s[1] == 'f' && s[2] == 'p')
3020 {
3021 s += 3;
3022 regno = 30;
3023 }
3024 else if (s[1] == 's' && s[2] == 'p')
3025 {
3026 s += 3;
3027 regno = 29;
3028 }
3029 else if (s[1] == 'g' && s[2] == 'p')
3030 {
3031 s += 3;
3032 regno = 28;
3033 }
3034 else if (s[1] == 'a' && s[2] == 't')
3035 {
3036 s += 3;
3037 regno = 1;
3038 }
3039 else
3040 goto notreg;
3041 if (regno == AT && ! mips_noat)
3042 as_warn ("Used $at without \".set noat\"");
3043 }
3044 c = *args;
3045 if (*s == ' ')
3046 s++;
3047 if (args[1] != *s)
3048 {
3049 if (c == 'r' || c == 'v' || c == 'w')
3050 {
3051 regno = lastregno;
3052 s = s_reset;
3053 args++;
3054 }
3055 }
3056 /* 'z' only matches $0. */
3057 if (c == 'z' && regno != 0)
3058 break;
3059 switch (c)
3060 {
3061 case 'r':
3062 case 's':
3063 case 'v':
3064 case 'b':
3065 ip->insn_opcode |= regno << 21;
3066 break;
3067 case 'd':
3068 case 'G':
3069 ip->insn_opcode |= regno << 11;
3070 break;
3071 case 'w':
3072 case 't':
3073 case 'E':
3074 ip->insn_opcode |= regno << 16;
3075 break;
3076 case 'x':
3077 /* This case exists because on the r3000 trunc
3078 expands into a macro which requires a gp
3079 register. On the r6000 or r4000 it is
3080 assembled into a single instruction which
3081 ignores the register. Thus the insn version
3082 is MIPS_ISA2 and uses 'x', and the macro
3083 version is MIPS_ISA1 and uses 't'. */
3084 break;
3085 case 'z':
3086 /* This case is for the div instruction, which
3087 acts differently if the destination argument
3088 is $0. This only matches $0, and is checked
3089 outside the switch. */
3090 break;
3091 }
3092 lastregno = regno;
3093 continue;
3094 }
3095 notreg:
3096 switch (*args++)
3097 {
3098 case 'r':
3099 case 'v':
3100 ip->insn_opcode |= lastregno << 21;
3101 continue;
3102 case 'w':
3103 ip->insn_opcode |= lastregno << 16;
3104 continue;
3105 }
3106 break;
3107
3108 case 'D': /* floating point destination register */
3109 case 'S': /* floating point source register */
3110 case 'T': /* floating point target register */
3111 case 'V':
3112 case 'W':
3113 s_reset = s;
3114 if (s[0] == '$' && s[1] == 'f' && isdigit (s[2]))
3115 {
3116 s += 2;
3117 regno = 0;
3118 do
3119 {
3120 regno *= 10;
3121 regno += *s - '0';
3122 ++s;
3123 }
3124 while (isdigit (*s));
3125
3126 if (regno > 31)
3127 as_bad ("Invalid float register number (%d)", regno);
3128
3129 if ((regno & 1) &&
3130 !(strcmp (str, "mtc1") == 0 ||
3131 strcmp (str, "mfc1") == 0 ||
3132 strcmp (str, "lwc1") == 0 ||
3133 strcmp (str, "swc1") == 0))
3134 as_warn ("Float register should be even, was %d",
3135 regno);
3136
3137 c = *args;
3138 if (*s == ' ')
3139 s++;
3140 if (args[1] != *s)
3141 {
3142 if (c == 'V' || c == 'W')
3143 {
3144 regno = lastregno;
3145 s = s_reset;
3146 args++;
3147 }
3148 }
3149 switch (c)
3150 {
3151 case 'D':
3152 ip->insn_opcode |= regno << 6;
3153 break;
3154 case 'V':
3155 case 'S':
3156 ip->insn_opcode |= regno << 11;
3157 break;
3158 case 'W':
3159 case 'T':
3160 ip->insn_opcode |= regno << 16;
3161 }
3162 lastregno = regno;
3163 continue;
3164 }
3165 switch (*args++)
3166 {
3167 case 'V':
3168 ip->insn_opcode |= lastregno << 11;
3169 continue;
3170 case 'W':
3171 ip->insn_opcode |= lastregno << 16;
3172 continue;
3173 }
3174 break;
3175
3176 case 'I':
3177 my_getExpression (&imm_expr, s);
3178 check_absolute_expr (ip, &imm_expr);
3179 s = expr_end;
3180 continue;
3181
3182 case 'A':
3183 my_getExpression (&offset_expr, s);
3184 imm_reloc = BFD_RELOC_32;
3185 s = expr_end;
3186 continue;
3187
3188 case 'F':
3189 case 'L':
3190 case 'f':
3191 case 'l':
3192 {
3193 int f64;
3194 char *save_in;
3195 char *err;
3196 unsigned char temp[8];
3197 int length;
3198 segT seg;
3199 subsegT subseg;
3200 char *p;
3201
3202 /* These only appear as the last operand in an
3203 instruction, and every instruction that accepts
3204 them in any variant accepts them in all variants.
3205 This means we don't have to worry about backing out
3206 any changes if the instruction does not match.
3207
3208 The difference between them is the size of the
3209 floating point constant and where it goes. For 'F'
3210 and 'L' the constant is 64 bits; for 'f' and 'l' it
3211 is 32 bits. Where the constant is placed is based
3212 on how the MIPS assembler does things:
3213 F -- .rdata
3214 L -- .lit8
3215 f -- immediate value
3216 l -- .lit4
3217 */
3218
3219 f64 = *args == 'F' || *args == 'L';
3220
3221 save_in = input_line_pointer;
3222 input_line_pointer = s;
3223 err = md_atof (f64 ? 'd' : 'f', (char *) temp, &length);
3224 s = input_line_pointer;
3225 input_line_pointer = save_in;
3226 if (err != NULL && *err != '\0')
3227 {
3228 as_bad ("Bad floating point constant: %s", err);
3229 memset (temp, '\0', sizeof temp);
3230 length = f64 ? 8 : 4;
3231 }
3232
3233 assert (length == (f64 ? 8 : 4));
3234
3235 if (*args == 'f')
3236 {
3237 imm_expr.X_op = O_constant;
3238 if (byte_order == LITTLE_ENDIAN)
3239 imm_expr.X_add_number =
3240 (((((((int) temp[3] << 8)
3241 | temp[2]) << 8)
3242 | temp[1]) << 8)
3243 | temp[0]);
3244 else
3245 imm_expr.X_add_number =
3246 (((((((int) temp[0] << 8)
3247 | temp[1]) << 8)
3248 | temp[2]) << 8)
3249 | temp[3]);
3250 }
3251 else
3252 {
3253 /* Switch to the right section. */
3254 seg = now_seg;
3255 subseg = now_subseg;
3256 switch (*args)
3257 {
3258 case 'F':
3259 subseg_new (".rdata", (subsegT) 0);
3260 break;
3261 case 'L':
3262 subseg_new (".lit8", (subsegT) 0);
3263 break;
3264 case 'l':
3265 subseg_new (".lit4", (subsegT) 0);
3266 break;
3267 }
3268 if (seg == now_seg)
3269 as_bad ("Can't use floating point insn in this section");
3270
3271 /* Set the argument to the current address in the
3272 section. */
3273 offset_expr.X_op = O_symbol;
3274 offset_expr.X_add_symbol =
3275 symbol_new ("L0\001", now_seg,
3276 (valueT) frag_now_fix (), frag_now);
3277 offset_expr.X_add_number = 0;
3278
3279 /* Put the floating point number into the section. */
3280 p = frag_more (length);
3281 memcpy (p, temp, length);
3282
3283 /* Switch back to the original section. */
3284 subseg_set (seg, subseg);
3285 }
3286 }
3287 continue;
3288
3289 case 'i': /* 16 bit unsigned immediate */
3290 case 'j': /* 16 bit signed immediate */
3291 imm_reloc = BFD_RELOC_LO16;
3292 c = my_getSmallExpression (&imm_expr, s);
3293 if (c)
3294 {
3295 if (c != 'l')
3296 {
3297 if (imm_expr.X_op == O_constant)
3298 imm_expr.X_add_number =
3299 (imm_expr.X_add_number >> 16) & 0xffff;
3300 else if (c == 'h')
3301 imm_reloc = BFD_RELOC_HI16_S;
3302 else
3303 imm_reloc = BFD_RELOC_HI16;
3304 }
3305 }
3306 else
3307 check_absolute_expr (ip, &imm_expr);
3308 if (*args == 'i')
3309 {
3310 if (imm_expr.X_add_number < 0
3311 || imm_expr.X_add_number >= 0x10000)
3312 {
3313 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
3314 !strcmp (insn->name, insn[1].name))
3315 break;
3316 as_bad ("16 bit expression not in range 0..65535");
3317 }
3318 }
3319 else
3320 {
3321 if (imm_expr.X_add_number < -0x8000 ||
3322 imm_expr.X_add_number >= 0x8000)
3323 {
3324 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
3325 !strcmp (insn->name, insn[1].name))
3326 break;
3327 as_bad ("16 bit expression not in range -32768..32767");
3328 }
3329 }
3330 s = expr_end;
3331 continue;
3332
3333 case 'o': /* 16 bit offset */
3334 c = my_getSmallExpression (&offset_expr, s);
3335 /*
3336 * If this value won't fit into a 16 bit offset, then
3337 * go find a macro that will generate the 32 bit offset
3338 * code pattern.
3339 */
3340 if (offset_expr.X_op != O_constant
3341 || offset_expr.X_add_number >= 0x8000
3342 || offset_expr.X_add_number < -0x8000)
3343 break;
3344
3345 offset_reloc = BFD_RELOC_LO16;
3346 if (c == 'h' || c == 'H')
3347 {
3348 assert (offset_expr.X_op == O_constant);
3349 offset_expr.X_add_number =
3350 (offset_expr.X_add_number >> 16) & 0xffff;
3351 }
3352 s = expr_end;
3353 continue;
3354
3355 case 'p': /* pc relative offset */
3356 offset_reloc = BFD_RELOC_16_PCREL_S2;
3357 my_getExpression (&offset_expr, s);
3358 s = expr_end;
3359 continue;
3360
3361 case 'u': /* upper 16 bits */
3362 c = my_getSmallExpression (&imm_expr, s);
3363 if (imm_expr.X_op != O_constant
3364 || imm_expr.X_add_number < 0
3365 || imm_expr.X_add_number >= 0x10000)
3366 as_bad ("lui expression not in range 0..65535");
3367 imm_reloc = BFD_RELOC_LO16;
3368 if (c)
3369 {
3370 if (c != 'l')
3371 {
3372 if (imm_expr.X_op == O_constant)
3373 imm_expr.X_add_number =
3374 (imm_expr.X_add_number >> 16) & 0xffff;
3375 else if (c == 'h')
3376 imm_reloc = BFD_RELOC_HI16_S;
3377 else
3378 imm_reloc = BFD_RELOC_HI16;
3379 }
3380 }
3381 s = expr_end;
3382 continue;
3383
3384 case 'a': /* 26 bit address */
3385 my_getExpression (&offset_expr, s);
3386 s = expr_end;
3387 offset_reloc = BFD_RELOC_MIPS_JMP;
3388 continue;
3389
3390 default:
3391 fprintf (stderr, "bad char = '%c'\n", *args);
3392 internalError ();
3393 }
3394 break;
3395 }
3396 /* Args don't match. */
3397 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
3398 !strcmp (insn->name, insn[1].name))
3399 {
3400 ++insn;
3401 s = argsStart;
3402 continue;
3403 }
3404 insn_error = "ERROR: Illegal operands";
3405 return;
3406 }
3407 }
3408
3409 #define LP '('
3410 #define RP ')'
3411
3412 static int
3413 my_getSmallExpression (ep, str)
3414 expressionS *ep;
3415 char *str;
3416 {
3417 char *sp;
3418 int c = 0;
3419
3420 if (*str == ' ')
3421 str++;
3422 if (*str == LP
3423 || (*str == '%' &&
3424 ((str[1] == 'h' && str[2] == 'i')
3425 || (str[1] == 'H' && str[2] == 'I')
3426 || (str[1] == 'l' && str[2] == 'o'))
3427 && str[3] == LP))
3428 {
3429 if (*str == LP)
3430 c = 0;
3431 else
3432 {
3433 c = str[1];
3434 str += 3;
3435 }
3436
3437 /*
3438 * A small expression may be followed by a base register.
3439 * Scan to the end of this operand, and then back over a possible
3440 * base register. Then scan the small expression up to that
3441 * point. (Based on code in sparc.c...)
3442 */
3443 for (sp = str; *sp && *sp != ','; sp++)
3444 ;
3445 if (sp - 4 >= str && sp[-1] == RP)
3446 {
3447 if (isdigit (sp[-2]))
3448 {
3449 for (sp -= 3; sp >= str && isdigit (*sp); sp--)
3450 ;
3451 if (*sp == '$' && sp > str && sp[-1] == LP)
3452 {
3453 sp--;
3454 goto do_it;
3455 }
3456 }
3457 else if (sp - 5 >= str
3458 && sp[-5] == LP
3459 && sp[-4] == '$'
3460 && ((sp[-3] == 'f' && sp[-2] == 'p')
3461 || (sp[-3] == 's' && sp[-2] == 'p')
3462 || (sp[-3] == 'g' && sp[-2] == 'p')
3463 || (sp[-3] == 'a' && sp[-2] == 't')))
3464 {
3465 sp -= 5;
3466 do_it:
3467 if (sp == str)
3468 {
3469 /* no expression means zero offset */
3470 if (c)
3471 {
3472 /* %xx(reg) is an error */
3473 ep->X_op = O_absent;
3474 expr_end = str - 3;
3475 }
3476 else
3477 {
3478 ep->X_op = O_absent;
3479 expr_end = sp;
3480 }
3481 ep->X_add_symbol = NULL;
3482 ep->X_op_symbol = NULL;
3483 ep->X_add_number = 0;
3484 }
3485 else
3486 {
3487 *sp = '\0';
3488 my_getExpression (ep, str);
3489 *sp = LP;
3490 }
3491 return c;
3492 }
3493 }
3494 }
3495 my_getExpression (ep, str);
3496 return c; /* => %hi or %lo encountered */
3497 }
3498
3499 static void
3500 my_getExpression (ep, str)
3501 expressionS *ep;
3502 char *str;
3503 {
3504 char *save_in;
3505
3506 save_in = input_line_pointer;
3507 input_line_pointer = str;
3508 expression (ep);
3509 expr_end = input_line_pointer;
3510 input_line_pointer = save_in;
3511 }
3512
3513 /* Turn a string in input_line_pointer into a floating point constant
3514 of type type, and store the appropriate bytes in *litP. The number
3515 of LITTLENUMS emitted is stored in *sizeP . An error message is
3516 returned, or NULL on OK. */
3517
3518 char *
3519 md_atof (type, litP, sizeP)
3520 int type;
3521 char *litP;
3522 int *sizeP;
3523 {
3524 int prec;
3525 LITTLENUM_TYPE words[4];
3526 char *t;
3527 int i;
3528
3529 switch (type)
3530 {
3531 case 'f':
3532 prec = 2;
3533 break;
3534
3535 case 'd':
3536 prec = 4;
3537 break;
3538
3539 default:
3540 *sizeP = 0;
3541 return "bad call to md_atof";
3542 }
3543
3544 t = atof_ieee (input_line_pointer, type, words);
3545 if (t)
3546 input_line_pointer = t;
3547
3548 *sizeP = prec * 2;
3549
3550 if (byte_order == LITTLE_ENDIAN)
3551 {
3552 for (i = prec - 1; i >= 0; i--)
3553 {
3554 md_number_to_chars (litP, (valueT) words[i], 2);
3555 litP += 2;
3556 }
3557 }
3558 else
3559 {
3560 for (i = 0; i < prec; i++)
3561 {
3562 md_number_to_chars (litP, (valueT) words[i], 2);
3563 litP += 2;
3564 }
3565 }
3566
3567 return NULL;
3568 }
3569
3570 void
3571 md_number_to_chars (buf, val, n)
3572 char *buf;
3573 valueT val;
3574 int n;
3575 {
3576 switch (byte_order)
3577 {
3578 case LITTLE_ENDIAN:
3579 switch (n)
3580 {
3581 case 8:
3582 *buf++ = val;
3583 val >>= 8;
3584 *buf++ = val;
3585 val >>= 8;
3586 *buf++ = val;
3587 val >>= 8;
3588 *buf++ = val;
3589 val >>= 8;
3590 /* FALLTHROUGH */
3591 case 4:
3592 *buf++ = val;
3593 val >>= 8;
3594 *buf++ = val;
3595 val >>= 8;
3596 /* FALLTHROUGH */
3597 case 2:
3598 *buf++ = val;
3599 val >>= 8;
3600 /* FALLTHROUGH */
3601 case 1:
3602 *buf = val;
3603 return;
3604
3605 default:
3606 internalError ();
3607 }
3608
3609 case BIG_ENDIAN:
3610 switch (n)
3611 {
3612 case 8:
3613 {
3614 valueT hi;
3615
3616 hi = val;
3617 hi >>= 16;
3618 hi >>= 16;
3619 md_number_to_chars (buf, hi, 4);
3620 buf += 4;
3621 }
3622 /* FALLTHROUGH */
3623 case 4:
3624 *buf++ = val >> 24;
3625 *buf++ = val >> 16;
3626 /* FALLTHROUGH */
3627 case 2:
3628 *buf++ = val >> 8;
3629 /* FALLTHROUGH */
3630 case 1:
3631 *buf = val;
3632 return;
3633
3634 default:
3635 internalError ();
3636 }
3637
3638 default:
3639 internalError ();
3640 }
3641 }
3642
3643 int
3644 md_parse_option (argP, cntP, vecP)
3645 char **argP;
3646 int *cntP;
3647 char ***vecP;
3648 {
3649 /* Accept -nocpp but ignore it. */
3650 if (strcmp (*argP, "nocpp") == 0)
3651 {
3652 *argP += 5;
3653 return 1;
3654 }
3655
3656 if (strcmp (*argP, "EL") == 0
3657 || strcmp (*argP, "EB") == 0)
3658 {
3659 /* FIXME: This breaks -L -EL. */
3660 flagseen['L'] = 0;
3661 *argP = "";
3662 return 1;
3663 }
3664
3665 if (**argP == 'O')
3666 {
3667 if ((*argP)[1] == '0')
3668 mips_optimize = 1;
3669 else
3670 mips_optimize = 2;
3671 return 1;
3672 }
3673
3674 if (**argP == 'g')
3675 {
3676 if ((*argP)[1] == '\0' || (*argP)[1] == '2')
3677 mips_optimize = 0;
3678 return 1;
3679 }
3680
3681 if (strncmp (*argP, "mips", 4) == 0)
3682 {
3683 mips_isa = atol (*argP + 4);
3684 if (mips_isa == 0)
3685 mips_isa = 1;
3686 else if (mips_isa < 1 || mips_isa > 3)
3687 {
3688 as_bad ("-mips%d not supported", mips_isa);
3689 mips_isa = 1;
3690 }
3691 *argP = "";
3692 return 1;
3693 }
3694
3695 if (strncmp (*argP, "mcpu=", 5) == 0)
3696 {
3697 char *p;
3698
3699 /* Identify the processor type */
3700 p = *argP + 5;
3701 if (strcmp (p, "default") == 0
3702 || strcmp (p, "DEFAULT") == 0)
3703 mips_isa = -1;
3704 else
3705 {
3706 if (*p == 'r' || *p == 'R')
3707 p++;
3708
3709 mips_isa = -1;
3710 switch (*p)
3711 {
3712 case '2':
3713 if (strcmp (p, "2000") == 0
3714 || strcmp (p, "2k") == 0
3715 || strcmp (p, "2K") == 0)
3716 mips_isa = 1;
3717 break;
3718
3719 case '3':
3720 if (strcmp (p, "3000") == 0
3721 || strcmp (p, "3k") == 0
3722 || strcmp (p, "3K") == 0)
3723 mips_isa = 1;
3724 break;
3725
3726 case '4':
3727 if (strcmp (p, "4000") == 0
3728 || strcmp (p, "4k") == 0
3729 || strcmp (p, "4K") == 0)
3730 mips_isa = 3;
3731 break;
3732
3733 case '6':
3734 if (strcmp (p, "6000") == 0
3735 || strcmp (p, "6k") == 0
3736 || strcmp (p, "6K") == 0)
3737 mips_isa = 2;
3738 break;
3739 }
3740
3741 if (mips_isa == -1)
3742 {
3743 as_bad ("bad value (%s) for -mcpu= switch", *argP + 5);
3744 mips_isa = 1;
3745 }
3746 }
3747
3748 *argP = "";
3749 return 1;
3750 }
3751
3752
3753 #ifdef OBJ_ECOFF
3754 if (**argP == 'G')
3755 {
3756 if ((*argP)[1] != '\0')
3757 g_switch_value = atoi (*argP + 1);
3758 else if (*cntP)
3759 {
3760 **vecP = (char *) NULL;
3761 (*cntP)--;
3762 (*vecP)++;
3763 g_switch_value = atoi (**vecP);
3764 }
3765 else
3766 as_warn ("Number expected after -G");
3767 *argP = "";
3768 return 1;
3769 }
3770 #endif
3771
3772 return 1; /* pretend you parsed the character */
3773 }
3774
3775 long
3776 md_pcrel_from (fixP)
3777 fixS *fixP;
3778 {
3779 /* return the address of the delay slot */
3780 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
3781 }
3782
3783 int
3784 md_apply_fix (fixP, valueP)
3785 fixS *fixP;
3786 valueT *valueP;
3787 {
3788 unsigned char *buf;
3789 long insn, value;
3790
3791 assert (fixP->fx_size == 4);
3792
3793 value = *valueP;
3794 fixP->fx_addnumber = value; /* Remember value for tc_gen_reloc */
3795
3796 switch (fixP->fx_r_type)
3797 {
3798 case BFD_RELOC_32:
3799 case BFD_RELOC_MIPS_JMP:
3800 case BFD_RELOC_HI16:
3801 case BFD_RELOC_HI16_S:
3802 case BFD_RELOC_LO16:
3803 case BFD_RELOC_MIPS_GPREL:
3804 /* Nothing needed to do. The value comes from the reloc entry */
3805 return 1;
3806
3807 case BFD_RELOC_16_PCREL_S2:
3808 /*
3809 * We need to save the bits in the instruction since fixup_segment()
3810 * might be deleting the relocation entry (i.e., a branch within
3811 * the current segment).
3812 */
3813 if (value & 0x3)
3814 as_warn ("Branch to odd address (%x)", value);
3815 value >>= 2;
3816 if ((value & ~0xFFFF) && (value & ~0xFFFF) != (-1 & ~0xFFFF))
3817 as_bad ("Relocation overflow");
3818
3819 /* update old instruction data */
3820 buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
3821 switch (byte_order)
3822 {
3823 case LITTLE_ENDIAN:
3824 insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
3825 break;
3826
3827 case BIG_ENDIAN:
3828 insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
3829 break;
3830
3831 default:
3832 internalError ();
3833 return 0;
3834 }
3835 insn |= value & 0xFFFF;
3836 md_number_to_chars ((char *) buf, insn, 4);
3837 break;
3838
3839 default:
3840 internalError ();
3841 }
3842 return 1;
3843 }
3844
3845 #if 0
3846 void
3847 printInsn (oc)
3848 unsigned long oc;
3849 {
3850 const struct mips_opcode *p;
3851 int treg, sreg, dreg, shamt;
3852 short imm;
3853 const char *args;
3854 int i;
3855
3856 for (i = 0; i < NUMOPCODES; ++i)
3857 {
3858 p = &mips_opcodes[i];
3859 if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))
3860 {
3861 printf ("%08lx %s\t", oc, p->name);
3862 treg = (oc >> 16) & 0x1f;
3863 sreg = (oc >> 21) & 0x1f;
3864 dreg = (oc >> 11) & 0x1f;
3865 shamt = (oc >> 6) & 0x1f;
3866 imm = oc;
3867 for (args = p->args;; ++args)
3868 {
3869 switch (*args)
3870 {
3871 case '\0':
3872 printf ("\n");
3873 break;
3874
3875 case ',':
3876 case '(':
3877 case ')':
3878 printf ("%c", *args);
3879 continue;
3880
3881 case 'r':
3882 assert (treg == sreg);
3883 printf ("$%d,$%d", treg, sreg);
3884 continue;
3885
3886 case 'd':
3887 case 'G':
3888 printf ("$%d", dreg);
3889 continue;
3890
3891 case 't':
3892 case 'E':
3893 printf ("$%d", treg);
3894 continue;
3895
3896 case 'b':
3897 case 's':
3898 printf ("$%d", sreg);
3899 continue;
3900
3901 case 'a':
3902 printf ("0x%08lx", oc & 0x1ffffff);
3903 continue;
3904
3905 case 'i':
3906 case 'j':
3907 case 'o':
3908 case 'u':
3909 printf ("%d", imm);
3910 continue;
3911
3912 case '<':
3913 printf ("$%d", shamt);
3914 continue;
3915
3916 default:
3917 internalError ();
3918 }
3919 break;
3920 }
3921 return;
3922 }
3923 }
3924 printf ("%08lx UNDEFINED\n", oc);
3925 }
3926 #endif
3927
3928 static symbolS *
3929 get_symbol ()
3930 {
3931 int c;
3932 char *name;
3933 symbolS *p;
3934
3935 name = input_line_pointer;
3936 c = get_symbol_end ();
3937 p = (symbolS *) symbol_find_or_make (name);
3938 *input_line_pointer = c;
3939 return p;
3940 }
3941
3942 /* Align the current frag to a given power of two. The MIPS assembler
3943 also automatically adjusts any preceding label. */
3944
3945 static void
3946 mips_align (to, fill)
3947 int to;
3948 int fill;
3949 {
3950 mips_emit_delays ();
3951 frag_align (to, fill);
3952 record_alignment (now_seg, to);
3953 if (insn_label != NULL)
3954 {
3955 assert (S_GET_SEGMENT (insn_label) == now_seg);
3956 insn_label->sy_frag = frag_now;
3957 S_SET_VALUE (insn_label, frag_now_fix ());
3958 insn_label = NULL;
3959 }
3960 }
3961
3962 /* Align to a given power of two. .align 0 turns off the automatic
3963 alignment used by the data creating pseudo-ops. */
3964
3965 static void
3966 s_align (x)
3967 int x;
3968 {
3969 register int temp;
3970 register long temp_fill;
3971 long max_alignment = 15;
3972
3973 /*
3974
3975 o Note that the assembler pulls down any immediately preceeding label
3976 to the aligned address.
3977 o It's not documented but auto alignment is reinstated by
3978 a .align pseudo instruction.
3979 o Note also that after auto alignment is turned off the mips assembler
3980 issues an error on attempt to assemble an improperly aligned data item.
3981 We don't.
3982
3983 */
3984
3985 temp = get_absolute_expression ();
3986 if (temp > max_alignment)
3987 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
3988 else if (temp < 0)
3989 {
3990 as_warn ("Alignment negative: 0 assumed.");
3991 temp = 0;
3992 }
3993 if (*input_line_pointer == ',')
3994 {
3995 input_line_pointer++;
3996 temp_fill = get_absolute_expression ();
3997 }
3998 else
3999 temp_fill = 0;
4000 if (temp)
4001 {
4002 auto_align = 1;
4003 mips_align (temp, (int) temp_fill);
4004 }
4005 else
4006 {
4007 auto_align = 0;
4008 }
4009
4010 demand_empty_rest_of_line ();
4011 }
4012
4013 /* Handle .ascii and .asciiz. This just calls stringer and forgets
4014 that there was a previous instruction. */
4015
4016 static void
4017 s_stringer (append_zero)
4018 int append_zero;
4019 {
4020 mips_emit_delays ();
4021 insn_label = NULL;
4022 stringer (append_zero);
4023 }
4024
4025 static void
4026 s_change_sec (sec)
4027 int sec;
4028 {
4029 segT segment;
4030
4031 mips_emit_delays ();
4032 segment = now_seg;
4033 switch (sec)
4034 {
4035 case 't':
4036 s_text ();
4037 break;
4038 case 'r':
4039 #ifdef OBJ_ECOFF
4040 subseg_new (".rdata", (subsegT) get_absolute_expression ());
4041 demand_empty_rest_of_line ();
4042 break;
4043 #else
4044 /* Fall through. */
4045 #endif
4046 case 'd':
4047 s_data ();
4048 break;
4049 case 'b':
4050 #ifdef BFD_ASSEMBLER
4051 subseg_set (bss_section, (subsegT) get_absolute_expression ());
4052 #else
4053 subseg_new (bss_section, (subsegT) get_absolute_expression ());
4054 #endif
4055 demand_empty_rest_of_line ();
4056 break;
4057 case 's':
4058 #ifdef OBJ_ECOFF
4059 subseg_new (".sdata", (subsegT) get_absolute_expression ());
4060 demand_empty_rest_of_line ();
4061 break;
4062 #else
4063 as_bad ("Global pointers not supported; recompile -G 0");
4064 demand_empty_rest_of_line ();
4065 return;
4066 #endif
4067 }
4068 auto_align = 1;
4069 }
4070
4071 static void
4072 s_cons (log_size)
4073 int log_size;
4074 {
4075 mips_emit_delays ();
4076 if (log_size > 0 && auto_align)
4077 mips_align (log_size, 0);
4078 insn_label = NULL;
4079 cons (1 << log_size);
4080 }
4081
4082 static void
4083 s_err (x)
4084 int x;
4085 {
4086 as_fatal ("Encountered `.err', aborting assembly");
4087 }
4088
4089 static void
4090 s_extern (x)
4091 int x;
4092 {
4093 long size;
4094 symbolS *symbolP;
4095
4096 symbolP = get_symbol ();
4097 if (*input_line_pointer == ',')
4098 input_line_pointer++;
4099 size = get_absolute_expression ();
4100 S_SET_VALUE (symbolP, size);
4101 S_SET_EXTERNAL (symbolP);
4102
4103 #ifdef OBJ_ECOFF
4104 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
4105 so we use an additional ECOFF specific field. */
4106 symbolP->ecoff_undefined = 1;
4107 #endif
4108 }
4109
4110 static void
4111 s_float_cons (type)
4112 int type;
4113 {
4114 mips_emit_delays ();
4115
4116 if (auto_align)
4117 if (type == 'd')
4118 mips_align (3, 0);
4119 else
4120 mips_align (2, 0);
4121
4122 insn_label = NULL;
4123
4124 float_cons (type);
4125 }
4126
4127 static void
4128 s_option (x)
4129 int x;
4130 {
4131 if (strcmp (input_line_pointer, "O1") != 0
4132 && strcmp (input_line_pointer, "O2") != 0)
4133 as_warn ("Unrecognized option");
4134 demand_empty_rest_of_line ();
4135 }
4136
4137 static void
4138 s_mipsset (x)
4139 int x;
4140 {
4141 char *name = input_line_pointer, ch;
4142
4143 while (!is_end_of_line[(unsigned char) *input_line_pointer])
4144 input_line_pointer++;
4145 ch = *input_line_pointer;
4146 *input_line_pointer = '\0';
4147
4148 if (strcmp (name, "reorder") == 0)
4149 {
4150 if (mips_noreorder)
4151 {
4152 prev_insn_unreordered = 1;
4153 prev_prev_insn_unreordered = 1;
4154 }
4155 mips_noreorder = 0;
4156 }
4157 else if (strcmp (name, "noreorder") == 0)
4158 {
4159 mips_emit_delays ();
4160 mips_noreorder = 1;
4161 }
4162 else if (strcmp (name, "at") == 0)
4163 {
4164 mips_noat = 0;
4165 }
4166 else if (strcmp (name, "noat") == 0)
4167 {
4168 mips_noat = 1;
4169 }
4170 else if (strcmp (name, "macro") == 0)
4171 {
4172 mips_warn_about_macros = 0;
4173 }
4174 else if (strcmp (name, "nomacro") == 0)
4175 {
4176 if (mips_noreorder == 0)
4177 as_bad ("`noreorder' must be set before `nomacro'");
4178 mips_warn_about_macros = 1;
4179 }
4180 else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
4181 {
4182 mips_nomove = 0;
4183 }
4184 else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
4185 {
4186 mips_nomove = 1;
4187 }
4188 else if (strcmp (name, "bopt") == 0)
4189 {
4190 mips_nobopt = 0;
4191 }
4192 else if (strcmp (name, "nobopt") == 0)
4193 {
4194 mips_nobopt = 1;
4195 }
4196 else
4197 {
4198 as_warn ("Tried to set unrecognized symbol: %s\n", name);
4199 }
4200 *input_line_pointer = ch;
4201 demand_empty_rest_of_line ();
4202 }
4203
4204 /* The same as the usual .space directive, except that we have to
4205 forget about any previous instruction. */
4206
4207 static void
4208 s_mips_space (param)
4209 int param;
4210 {
4211 mips_emit_delays ();
4212 insn_label = NULL;
4213 s_space (param);
4214 }
4215
4216 int
4217 tc_get_register ()
4218 {
4219 int reg;
4220
4221 SKIP_WHITESPACE ();
4222 if (*input_line_pointer++ != '$')
4223 {
4224 as_warn ("expected `$'");
4225 return 0;
4226 }
4227 if (isdigit ((unsigned char) *input_line_pointer))
4228 {
4229 reg = get_absolute_expression ();
4230 if (reg < 0 || reg >= 32)
4231 {
4232 as_warn ("Bad register number");
4233 reg = 0;
4234 }
4235 }
4236 else
4237 {
4238 if (strncmp (input_line_pointer, "fp", 2) == 0)
4239 reg = 30;
4240 else if (strncmp (input_line_pointer, "sp", 2) == 0)
4241 reg = 29;
4242 else if (strncmp (input_line_pointer, "gp", 2) == 0)
4243 reg = 28;
4244 else if (strncmp (input_line_pointer, "at", 2) == 0)
4245 reg = 1;
4246 else
4247 {
4248 as_warn ("Unrecognized register name");
4249 return 0;
4250 }
4251 input_line_pointer += 2;
4252 }
4253 return reg;
4254 }
4255
4256 /*
4257 * Translate internal representation of relocation info to BFD target format.
4258 */
4259 arelent *
4260 tc_gen_reloc (section, fixp)
4261 asection *section;
4262 fixS *fixp;
4263 {
4264 arelent *reloc;
4265
4266 reloc = (arelent *) xmalloc (sizeof (arelent));
4267 assert (reloc != 0);
4268
4269 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
4270 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4271 if (fixp->fx_pcrel == 0)
4272 reloc->addend = fixp->fx_addnumber;
4273 else
4274 #ifdef OBJ_ELF
4275 reloc->addend = 0;
4276 #else
4277 reloc->addend = -reloc->address;
4278 #endif
4279 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
4280 assert (reloc->howto != 0);
4281
4282 return reloc;
4283 }
4284
4285 /* should never be called */
4286 valueT
4287 md_section_align (seg, addr)
4288 asection *seg;
4289 valueT addr;
4290 {
4291 int align = bfd_get_section_alignment (stdoutput, seg);
4292
4293 return ((addr + (1 << align) - 1) & (-1 << align));
4294 }
4295
4296 int
4297 md_estimate_size_before_relax (fragP, segtype)
4298 fragS *fragP;
4299 asection *segtype;
4300 {
4301 as_fatal ("md_estimate_size_before_relax");
4302 return (1);
4303 } /* md_estimate_size_before_relax() */
4304
4305 /* This function is called whenever a label is defined. It is used
4306 when handling branch delays; if a branch has a label, we assume we
4307 can not move it. */
4308
4309 void
4310 mips_define_label (sym)
4311 symbolS *sym;
4312 {
4313 insn_label = sym;
4314 }
4315 \f
4316 #ifndef OBJ_ECOFF
4317
4318 /* These functions should really be defined by the object file format,
4319 since they are related to debugging information. However, this
4320 code has to work for the a.out format, which does not define them,
4321 so we provide simple versions here. These don't actually generate
4322 any debugging information, but they do simple checking and someday
4323 somebody may make them useful. */
4324
4325 typedef struct loc
4326 {
4327 struct loc *loc_next;
4328 unsigned long loc_fileno;
4329 unsigned long loc_lineno;
4330 unsigned long loc_offset;
4331 unsigned short loc_delta;
4332 unsigned short loc_count;
4333 #if 0
4334 fragS *loc_frag;
4335 #endif
4336 }
4337 locS;
4338
4339 typedef struct proc
4340 {
4341 struct proc *proc_next;
4342 struct symbol *proc_isym;
4343 struct symbol *proc_end;
4344 unsigned long proc_reg_mask;
4345 unsigned long proc_reg_offset;
4346 unsigned long proc_fpreg_mask;
4347 unsigned long proc_fpreg_offset;
4348 unsigned long proc_frameoffset;
4349 unsigned long proc_framereg;
4350 unsigned long proc_pcreg;
4351 locS *proc_iline;
4352 struct file *proc_file;
4353 int proc_index;
4354 }
4355 procS;
4356
4357 typedef struct file
4358 {
4359 struct file *file_next;
4360 unsigned long file_fileno;
4361 struct symbol *file_symbol;
4362 struct symbol *file_end;
4363 struct proc *file_proc;
4364 int file_numprocs;
4365 }
4366 fileS;
4367
4368 static struct obstack proc_frags;
4369 static procS *proc_lastP;
4370 static procS *proc_rootP;
4371 static int numprocs;
4372
4373 static void
4374 md_obj_begin ()
4375 {
4376 obstack_begin (&proc_frags, 0x2000);
4377 }
4378
4379 static void
4380 md_obj_end ()
4381 {
4382 /* check for premature end, nesting errors, etc */
4383 if (proc_lastP && proc_lastP->proc_end == NULL)
4384 as_warn ("missing `.end' at end of assembly");
4385 }
4386
4387 extern char hex_value[];
4388
4389 static long
4390 get_number ()
4391 {
4392 int negative = 0;
4393 long val = 0;
4394
4395 if (*input_line_pointer == '-')
4396 {
4397 ++input_line_pointer;
4398 negative = 1;
4399 }
4400 if (!isdigit (*input_line_pointer))
4401 as_bad ("Expected simple number.");
4402 if (input_line_pointer[0] == '0')
4403 {
4404 if (input_line_pointer[1] == 'x')
4405 {
4406 input_line_pointer += 2;
4407 while (isxdigit (*input_line_pointer))
4408 {
4409 val <<= 4;
4410 val |= hex_value[(int) *input_line_pointer++];
4411 }
4412 return negative ? -val : val;
4413 }
4414 else
4415 {
4416 ++input_line_pointer;
4417 while (isdigit (*input_line_pointer))
4418 {
4419 val <<= 3;
4420 val |= *input_line_pointer++ - '0';
4421 }
4422 return negative ? -val : val;
4423 }
4424 }
4425 if (!isdigit (*input_line_pointer))
4426 {
4427 printf (" *input_line_pointer == '%c' 0x%02x\n",
4428 *input_line_pointer, *input_line_pointer);
4429 as_warn ("Invalid number");
4430 return -1;
4431 }
4432 while (isdigit (*input_line_pointer))
4433 {
4434 val *= 10;
4435 val += *input_line_pointer++ - '0';
4436 }
4437 return negative ? -val : val;
4438 }
4439
4440 /* The .file directive; just like the usual .file directive, but there
4441 is an initial number which is the ECOFF file index. */
4442
4443 static void
4444 s_file (x)
4445 int x;
4446 {
4447 int line;
4448
4449 line = get_number ();
4450 s_app_file (0);
4451 }
4452
4453
4454 /* The .end directive. */
4455
4456 static void
4457 s_mipsend (x)
4458 int x;
4459 {
4460 symbolS *p;
4461
4462 if (!is_end_of_line[(unsigned char) *input_line_pointer])
4463 {
4464 p = get_symbol ();
4465 demand_empty_rest_of_line ();
4466 }
4467 else
4468 p = NULL;
4469 if (now_seg != text_section)
4470 as_warn (".end not in text section");
4471 if (!proc_lastP)
4472 {
4473 as_warn (".end and no .ent seen yet.");
4474 return;
4475 }
4476
4477 if (p != NULL)
4478 {
4479 assert (S_GET_NAME (p));
4480 if (strcmp (S_GET_NAME (p), S_GET_NAME (proc_lastP->proc_isym)))
4481 as_warn (".end symbol does not match .ent symbol.");
4482 }
4483
4484 proc_lastP->proc_end = (symbolS *) 1;
4485 }
4486
4487 /* The .aent and .ent directives. */
4488
4489 static void
4490 s_ent (aent)
4491 int aent;
4492 {
4493 int number = 0;
4494 procS *procP;
4495 symbolS *symbolP;
4496
4497 symbolP = get_symbol ();
4498 if (*input_line_pointer == ',')
4499 input_line_pointer++;
4500 if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
4501 number = get_number ();
4502 if (now_seg != text_section)
4503 as_warn (".ent or .aent not in text section.");
4504
4505 if (!aent && proc_lastP && proc_lastP->proc_end == NULL)
4506 as_warn ("missing `.end'");
4507
4508 if (!aent)
4509 {
4510 procP = (procS *) obstack_alloc (&proc_frags, sizeof (*procP));
4511 procP->proc_isym = symbolP;
4512 procP->proc_reg_mask = 0;
4513 procP->proc_reg_offset = 0;
4514 procP->proc_fpreg_mask = 0;
4515 procP->proc_fpreg_offset = 0;
4516 procP->proc_frameoffset = 0;
4517 procP->proc_framereg = 0;
4518 procP->proc_pcreg = 0;
4519 procP->proc_end = NULL;
4520 procP->proc_next = NULL;
4521 if (proc_lastP)
4522 proc_lastP->proc_next = procP;
4523 else
4524 proc_rootP = procP;
4525 proc_lastP = procP;
4526 numprocs++;
4527 }
4528 demand_empty_rest_of_line ();
4529 }
4530
4531 /* The .frame directive. */
4532
4533 static void
4534 s_frame (x)
4535 int x;
4536 {
4537 #if 0
4538 char str[100];
4539 symbolS *symP;
4540 int frame_reg;
4541 int frame_off;
4542 int pcreg;
4543
4544 frame_reg = tc_get_register ();
4545 if (*input_line_pointer == ',')
4546 input_line_pointer++;
4547 frame_off = get_absolute_expression ();
4548 if (*input_line_pointer == ',')
4549 input_line_pointer++;
4550 pcreg = tc_get_register ();
4551
4552 /* bob third eye */
4553 assert (proc_rootP);
4554 proc_rootP->proc_framereg = frame_reg;
4555 proc_rootP->proc_frameoffset = frame_off;
4556 proc_rootP->proc_pcreg = pcreg;
4557 /* bob macho .frame */
4558
4559 /* We don't have to write out a frame stab for unoptimized code. */
4560 if (!(frame_reg == 30 && frame_off == 0))
4561 {
4562 if (!proc_lastP)
4563 as_warn ("No .ent for .frame to use.");
4564 (void) sprintf (str, "R%d;%d", frame_reg, frame_off);
4565 symP = symbol_new (str, N_VFP, 0, frag_now);
4566 S_SET_TYPE (symP, N_RMASK);
4567 S_SET_OTHER (symP, 0);
4568 S_SET_DESC (symP, 0);
4569 symP->sy_forward = proc_lastP->proc_isym;
4570 /* bob perhaps I should have used pseudo set */
4571 }
4572 demand_empty_rest_of_line ();
4573 #endif
4574 }
4575
4576 /* The .fmask and .mask directives. */
4577
4578 static void
4579 s_mask (reg_type)
4580 char reg_type;
4581 {
4582 #if 0
4583 char str[100], *strP;
4584 symbolS *symP;
4585 int i;
4586 unsigned int mask;
4587 int off;
4588
4589 mask = get_number ();
4590 if (*input_line_pointer == ',')
4591 input_line_pointer++;
4592 off = get_absolute_expression ();
4593
4594 /* bob only for coff */
4595 assert (proc_rootP);
4596 if (reg_type == 'F')
4597 {
4598 proc_rootP->proc_fpreg_mask = mask;
4599 proc_rootP->proc_fpreg_offset = off;
4600 }
4601 else
4602 {
4603 proc_rootP->proc_reg_mask = mask;
4604 proc_rootP->proc_reg_offset = off;
4605 }
4606
4607 /* bob macho .mask + .fmask */
4608
4609 /* We don't have to write out a mask stab if no saved regs. */
4610 if (!(mask == 0))
4611 {
4612 if (!proc_lastP)
4613 as_warn ("No .ent for .mask to use.");
4614 strP = str;
4615 for (i = 0; i < 32; i++)
4616 {
4617 if (mask % 2)
4618 {
4619 sprintf (strP, "%c%d,", reg_type, i);
4620 strP += strlen (strP);
4621 }
4622 mask /= 2;
4623 }
4624 sprintf (strP, ";%d,", off);
4625 symP = symbol_new (str, N_RMASK, 0, frag_now);
4626 S_SET_TYPE (symP, N_RMASK);
4627 S_SET_OTHER (symP, 0);
4628 S_SET_DESC (symP, 0);
4629 symP->sy_forward = proc_lastP->proc_isym;
4630 /* bob perhaps I should have used pseudo set */
4631 }
4632 #endif
4633 }
4634
4635 /* The .loc directive. */
4636
4637 static void
4638 s_loc (x)
4639 int x;
4640 {
4641 #if 0
4642 symbolS *symbolP;
4643 int lineno;
4644 int addroff;
4645
4646 assert (now_seg == text_section);
4647
4648 lineno = get_number ();
4649 addroff = obstack_next_free (&frags) - frag_now->fr_literal;
4650
4651 symbolP = symbol_new ("", N_SLINE, addroff, frag_now);
4652 S_SET_TYPE (symbolP, N_SLINE);
4653 S_SET_OTHER (symbolP, 0);
4654 S_SET_DESC (symbolP, lineno);
4655 symbolP->sy_segment = now_seg;
4656 #endif
4657 }
4658
4659 #endif /* ! defined (OBJ_ECOFF) */