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