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