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