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