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