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
8 This file is part of GAS.
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)
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.
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. */
40 #endif /* NO_VARARGS */
41 #endif /* NO_STDARG */
43 #include "opcode/mips.h"
49 /* MIPS ISA (Instruction Set Architecture) level. */
50 static int mips_isa
= -1;
52 static int mips_warn_about_macros
;
53 static int mips_noreorder
;
54 static int mips_nomove
;
56 static int mips_nobopt
;
59 /* The size of the small data section. */
60 static int g_switch_value
= 8;
66 /* handle of the OPCODE hash table */
67 static struct hash_control
*op_hash
= NULL
;
69 /* This array holds the chars that always start a comment. If the
70 pre-processor is disabled, these aren't very useful */
71 const char comment_chars
[] = "#";
73 /* This array holds the chars that only start a comment at the beginning of
74 a line. If the line seems to have the form '# 123 filename'
75 .line and .file directives will appear in the pre-processed output */
76 /* Note that input_file.c hand checks for '#' at the beginning of the
77 first line of the input file. This is because the compiler outputs
78 #NO_APP at the beginning of its output. */
79 /* Also note that C style comments are always supported. */
80 const char line_comment_chars
[] = "#";
82 /* This array holds machine specific line separator characters. */
83 const char line_separator_chars
[] = "";
85 /* Chars that can be used to separate mant from exp in floating point nums */
86 const char EXP_CHARS
[] = "eE";
88 /* Chars that mean this number is a floating point constant */
91 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
93 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
94 changed in read.c . Ideally it shouldn't have to know about it at all,
95 but nothing is ideal around here.
98 static char *insn_error
;
100 static int byte_order
= BYTE_ORDER
;
102 static int auto_align
= 1;
104 /* Symbol labelling the current insn. */
105 static symbolS
*insn_label
;
107 /* To output NOP instructions correctly, we need to keep information
108 about the previous two instructions. */
110 /* Whether we are optimizing. The default value of 2 means to remove
111 unneeded NOPs and swap branch instructions when possible. A value
112 of 1 means to not swap branches. A value of 0 means to always
114 static int mips_optimize
= 2;
116 /* The previous instruction. */
117 static struct mips_cl_insn prev_insn
;
119 /* The instruction before prev_insn. */
120 static struct mips_cl_insn prev_prev_insn
;
122 /* If we don't want information for prev_insn or prev_prev_insn, we
123 point the insn_mo field at this dummy integer. */
124 static const struct mips_opcode dummy_opcode
= { 0 };
126 /* Non-zero if prev_insn is valid. */
127 static int prev_insn_valid
;
129 /* The frag for the previous instruction. */
130 static struct frag
*prev_insn_frag
;
132 /* The offset into prev_insn_frag for the previous instruction. */
133 static long prev_insn_where
;
135 /* The reloc for the previous instruction, if any. */
136 static fixS
*prev_insn_fixp
;
138 /* Non-zero if the previous instruction was in a delay slot. */
139 static int prev_insn_is_delay_slot
;
141 /* Non-zero if the previous instruction was in a .set noreorder. */
142 static int prev_insn_unreordered
;
144 /* Non-zero if the previous previous instruction was in a .set
146 static int prev_prev_insn_unreordered
;
148 /* Prototypes for static functions. */
151 #define internalError() \
152 as_fatal ("internal Error, line %d, %s", __LINE__, __FILE__)
154 #define internalError() as_fatal ("MIPS internal Error");
157 static int insn_uses_reg
PARAMS ((struct mips_cl_insn
*ip
,
159 static void append_insn
PARAMS ((struct mips_cl_insn
* ip
,
161 bfd_reloc_code_real_type r
));
162 static void mips_no_prev_insn
PARAMS ((void));
163 static void mips_emit_delays
PARAMS ((void));
164 static int gp_reference
PARAMS ((expressionS
* ep
));
165 static void macro_build
PARAMS ((int *counter
, expressionS
* ep
,
166 const char *name
, const char *fmt
,
168 static void macro_build_lui
PARAMS ((int *counter
, expressionS
* ep
,
170 static void set_at
PARAMS ((int *counter
, int reg
, int unsignedp
));
171 static void check_absolute_expr
PARAMS ((struct mips_cl_insn
* ip
,
173 static void load_register
PARAMS ((int *counter
,
174 int reg
, expressionS
* ep
));
175 static void macro
PARAMS ((struct mips_cl_insn
* ip
));
176 static void mips_ip
PARAMS ((char *str
, struct mips_cl_insn
* ip
));
177 static int my_getSmallExpression
PARAMS ((expressionS
* ep
, char *str
));
178 static void my_getExpression
PARAMS ((expressionS
* ep
, char *str
));
179 static symbolS
*get_symbol
PARAMS ((void));
180 static void mips_align
PARAMS ((int to
, int fill
));
181 static void s_align
PARAMS ((int));
182 static void s_stringer
PARAMS ((int));
183 static void s_change_sec
PARAMS ((int));
184 static void s_cons
PARAMS ((int));
185 static void s_err
PARAMS ((int));
186 static void s_extern
PARAMS ((int));
187 static void s_float_cons
PARAMS ((int));
188 static void s_option
PARAMS ((int));
189 static void s_mipsset
PARAMS ((int));
190 static void s_mips_space
PARAMS ((int));
192 static void md_obj_begin
PARAMS ((void));
193 static void md_obj_end
PARAMS ((void));
194 static long get_number
PARAMS ((void));
195 static void s_ent
PARAMS ((int));
196 static void s_mipsend
PARAMS ((int));
197 static void s_file
PARAMS ((int));
198 static void s_frame
PARAMS ((int));
199 static void s_loc
PARAMS ((int));
200 static void s_mask
PARAMS ((char));
205 The following pseudo-ops from the Kane and Heinrich MIPS book
206 should be defined here, but are currently unsupported: .alias,
207 .galive, .gjaldef, .gjrlive, .livereg, .noalias.
209 The following pseudo-ops from the Kane and Heinrich MIPS book are
210 specific to the type of debugging information being generated, and
211 should be defined by the object format: .aent, .begin, .bend,
212 .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
215 The following pseudo-ops from the Kane and Heinrich MIPS book are
216 not MIPS CPU specific, but are also not specific to the object file
217 format. This file is probably the best place to define them, but
218 they are not currently supported: .asm0, .endr, .lab, .repeat,
219 .struct, .weakext. */
221 const pseudo_typeS md_pseudo_table
[] =
223 /* MIPS specific pseudo-ops. */
224 {"option", s_option
, 0},
225 {"set", s_mipsset
, 0},
226 {"rdata", s_change_sec
, 'r',},
227 {"sdata", s_change_sec
, 's',},
229 /* Relatively generic pseudo-ops that happen to be used on MIPS
231 {"asciiz", s_stringer
, 1},
232 {"bss", s_change_sec
, 'b'},
236 /* These pseudo-ops are defined in read.c, but must be overridden
237 here for one reason or another. */
238 {"align", s_align
, 0},
239 {"ascii", s_stringer
, 0},
240 {"asciz", s_stringer
, 1},
242 {"data", s_change_sec
, 'd'},
243 {"double", s_float_cons
, 'd'},
244 {"extern", s_extern
, 0},
245 {"float", s_float_cons
, 'f'},
246 {"space", s_mips_space
, 0},
247 {"text", s_change_sec
, 't'},
251 /* These pseudo-ops should be defined by the object file format.
252 However, ECOFF is the only format which currently defines them,
253 so we have versions here for a.out. */
255 {"end", s_mipsend
, 0},
258 {"fmask", s_ignore
, 'F'},
259 {"frame", s_ignore
, 0},
260 {"loc", s_ignore
, 0},
261 {"mask", s_ignore
, 'R'},
262 {"verstamp", s_ignore
, 0},
269 const relax_typeS md_relax_table
[] =
275 static char *expr_end
;
277 static expressionS imm_expr
;
278 static expressionS offset_expr
;
279 static bfd_reloc_code_real_type imm_reloc
;
280 static bfd_reloc_code_real_type offset_reloc
;
283 * This function is called once, at assembler startup time. It should
284 * set up all the tables, etc. that the MD part of the assembler will need.
289 register char *retval
= NULL
;
290 register unsigned int i
= 0;
294 if (strcmp (TARGET_CPU
, "mips") == 0)
296 else if (strcmp (TARGET_CPU
, "r6000") == 0
297 || strcmp (TARGET_CPU
, "mips2") == 0)
299 else if (strcmp (TARGET_CPU
, "mips64") == 0
300 || strcmp (TARGET_CPU
, "r4000") == 0
301 || strcmp (TARGET_CPU
, "mips3") == 0)
307 if ((op_hash
= hash_new ()) == NULL
)
309 as_fatal ("Virtual memory exhausted");
311 for (i
= 0; i
< NUMOPCODES
;)
313 const char *name
= mips_opcodes
[i
].name
;
315 retval
= hash_insert (op_hash
, name
, &mips_opcodes
[i
]);
316 if (retval
!= NULL
&& *retval
!= '\0')
318 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
319 mips_opcodes
[i
].name
, retval
);
320 as_fatal ("Broken assembler. No assembly attempted.");
324 if (mips_opcodes
[i
].pinfo
!= INSN_MACRO
325 && ((mips_opcodes
[i
].match
& mips_opcodes
[i
].mask
)
326 != mips_opcodes
[i
].match
))
328 fprintf (stderr
, "internal error: bad opcode: `%s' \"%s\"\n",
329 mips_opcodes
[i
].name
, mips_opcodes
[i
].args
);
330 as_fatal ("Broken assembler. No assembly attempted.");
334 while ((i
< NUMOPCODES
) && !strcmp (mips_opcodes
[i
].name
, name
));
337 mips_no_prev_insn ();
339 /* set the default alignment for the text section (2**2) */
340 record_alignment (text_section
, 2);
343 bfd_set_gp_size (stdoutput
, g_switch_value
);
363 struct mips_cl_insn insn
;
365 imm_expr
.X_op
= O_absent
;
366 offset_expr
.X_op
= O_absent
;
368 mips_ip (str
, &insn
);
371 as_bad ("%s `%s'", insn_error
, str
);
374 if (insn
.insn_mo
->pinfo
== INSN_MACRO
)
380 if (imm_expr
.X_op
!= O_absent
)
381 append_insn (&insn
, &imm_expr
, imm_reloc
);
382 else if (offset_expr
.X_op
!= O_absent
)
383 append_insn (&insn
, &offset_expr
, offset_reloc
);
385 append_insn (&insn
, NULL
, BFD_RELOC_UNUSED
);
389 /* See whether instruction IP reads register REG. If FPR is non-zero,
390 REG is a floating point register. */
393 insn_uses_reg (ip
, reg
, fpr
)
394 struct mips_cl_insn
*ip
;
398 /* Don't report on general register 0, since it never changes. */
399 if (! fpr
&& reg
== 0)
404 /* If we are called with either $f0 or $f1, we must check $f0.
405 This is not optimal, because it will introduce an unnecessary
406 NOP between "lwc1 $f0" and "swc1 $f1". To fix this we would
407 need to distinguish reading both $f0 and $f1 or just one of
408 them. Note that we don't have to check the other way,
409 because there is no instruction that sets both $f0 and $f1
410 and requires a delay. */
411 if ((ip
->insn_mo
->pinfo
& INSN_READ_FPR_S
)
412 && ((ip
->insn_opcode
>> OP_SH_FS
) & OP_MASK_FS
) == (reg
&~ 1))
414 if ((ip
->insn_mo
->pinfo
& INSN_READ_FPR_T
)
415 && ((ip
->insn_opcode
>> OP_SH_FT
) & OP_MASK_FT
) == (reg
&~ 1))
420 if ((ip
->insn_mo
->pinfo
& INSN_READ_GPR_S
)
421 && ((ip
->insn_opcode
>> OP_SH_RS
) & OP_MASK_RS
) == reg
)
423 if ((ip
->insn_mo
->pinfo
& INSN_READ_GPR_T
)
424 && ((ip
->insn_opcode
>> OP_SH_RT
) & OP_MASK_RT
) == reg
)
431 #define ALIGN_ERR "Attempt to assemble instruction onto non word boundary."
432 #define ALIGN_ERR2 "GAS doesn't do implicit alignment; use .align directive."
436 * Output an instruction.
439 append_insn (ip
, address_expr
, reloc_type
)
440 struct mips_cl_insn
*ip
;
441 expressionS
*address_expr
;
442 bfd_reloc_code_real_type reloc_type
;
448 if (! mips_noreorder
)
450 /* If the previous insn required any delay slots, see if we need
451 to insert a NOP or two. There are eight kinds of possible
452 hazards, of which an instruction can have at most one type.
453 (1) a load from memory delay
454 (2) a load from a coprocessor delay
455 (3) an unconditional branch delay
456 (4) a conditional branch delay
457 (5) a move to coprocessor register delay
458 (6) a load coprocessor register from memory delay
459 (7) a coprocessor condition code delay
460 (8) a HI/LO special register delay
462 There are a lot of optimizations we could do that we don't.
463 In particular, we do not, in general, reorder instructions.
464 If you use gcc with optimization, it will reorder
465 instructions and generally do much more optimization then we
466 do here; repeating all that work in the assembler would only
467 benefit hand written assembly code, and does not seem worth
470 /* This is how a NOP is emitted. */
471 #define emit_nop() md_number_to_chars (frag_more (4), 0, 4)
473 /* The previous insn might require a delay slot, depending upon
474 the contents of the current insn. */
475 if ((prev_insn
.insn_mo
->pinfo
& INSN_LOAD_COPROC_DELAY
)
477 && (prev_insn
.insn_mo
->pinfo
& INSN_LOAD_MEMORY_DELAY
)))
479 /* A load from a coprocessor or from memory. All load
480 delays delay the use of general register rt for one
481 instruction on the r3000. The r6000 and r4000 use
483 know (prev_insn
.insn_mo
->pinfo
& INSN_WRITE_GPR_T
);
484 if (mips_optimize
== 0
485 || insn_uses_reg (ip
,
486 ((prev_insn
.insn_opcode
>> OP_SH_RT
)
491 else if ((prev_insn
.insn_mo
->pinfo
& INSN_COPROC_MOVE_DELAY
)
493 && (prev_insn
.insn_mo
->pinfo
& INSN_COPROC_MEMORY_DELAY
)))
495 /* A generic coprocessor delay. The previous instruction
496 modified a coprocessor general or control register. If
497 it modified a control register, we need to avoid any
498 coprocessor instruction (this is probably not always
499 required, but it sometimes is). If it modified a general
500 register, we avoid using that register.
502 On the r6000 and r4000 loading a coprocessor register
503 from memory is interlocked, and does not require a delay.
505 This case is not handled very well. There is no special
506 knowledge of CP0 handling, and the coprocessors other
507 than the floating point unit are not distinguished at
509 if (prev_insn
.insn_mo
->pinfo
& INSN_WRITE_FPR_T
)
511 if (mips_optimize
== 0
512 || insn_uses_reg (ip
,
513 ((prev_insn
.insn_opcode
>> OP_SH_FT
)
518 else if (prev_insn
.insn_mo
->pinfo
& INSN_WRITE_FPR_S
)
520 if (mips_optimize
== 0
521 || insn_uses_reg (ip
,
522 ((prev_insn
.insn_opcode
>> OP_SH_FS
)
529 /* We don't know exactly what the previous instruction
530 does. If the current instruction uses a coprocessor
531 register, we must insert a NOP. If previous
532 instruction may set the condition codes, and the
533 current instruction uses them, we must insert two
535 if (mips_optimize
== 0
536 || ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
537 && (ip
->insn_mo
->pinfo
& INSN_READ_COND_CODE
)))
539 else if (ip
->insn_mo
->pinfo
& INSN_COP
)
543 else if (prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
545 /* The previous instruction sets the coprocessor condition
546 codes, but does not require a general coprocessor delay
547 (this means it is a floating point comparison
548 instruction). If this instruction uses the condition
549 codes, we need to insert a single NOP. */
550 if (mips_optimize
== 0
551 || ip
->insn_mo
->pinfo
& INSN_READ_COND_CODE
)
554 else if (prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
)
556 /* The previous instruction reads the LO register; if the
557 current instruction writes to the LO register, we must
559 if (mips_optimize
== 0
560 || ip
->insn_mo
->pinfo
& INSN_WRITE_LO
)
563 else if (prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
565 /* The previous instruction reads the HI register; if the
566 current instruction writes to the HI register, we must
568 if (mips_optimize
== 0
569 || ip
->insn_mo
->pinfo
& INSN_WRITE_HI
)
573 /* There are two cases which require two intervening
574 instructions: 1) setting the condition codes using a move to
575 coprocessor instruction which requires a general coprocessor
576 delay and then reading the condition codes 2) reading the HI
577 or LO register and then writing to it. If we are not already
578 emitting a NOP instruction, we must check for these cases
579 compared to the instruction previous to the previous
582 && (((prev_prev_insn
.insn_mo
->pinfo
& INSN_COPROC_MOVE_DELAY
)
583 && (prev_prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
584 && (ip
->insn_mo
->pinfo
& INSN_READ_COND_CODE
))
585 || ((prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
)
586 && (ip
->insn_mo
->pinfo
& INSN_WRITE_LO
))
587 || ((prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
588 && (ip
->insn_mo
->pinfo
& INSN_WRITE_HI
))))
591 /* Now emit the right number of NOP instructions. */
597 if (insn_label
!= NULL
)
599 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
600 insn_label
->sy_frag
= frag_now
;
601 S_SET_VALUE (insn_label
, frag_now_fix ());
608 /* This is testing the address of the frag, not the alignment of
609 the instruction in the current section. */
617 if (address_expr
!= NULL
)
619 if (address_expr
->X_op
== O_constant
)
624 ip
->insn_opcode
|= address_expr
->X_add_number
;
628 ip
->insn_opcode
|= address_expr
->X_add_number
& 0xffff;
631 case BFD_RELOC_MIPS_JMP
:
632 case BFD_RELOC_16_PCREL_S2
:
641 assert (reloc_type
!= BFD_RELOC_UNUSED
);
643 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 4,
645 reloc_type
== BFD_RELOC_16_PCREL_S2
,
650 md_number_to_chars (f
, ip
->insn_opcode
, 4);
652 if (! mips_noreorder
)
654 /* Filling the branch delay slot is more complex. We try to
655 switch the branch with the previous instruction, which we can
656 do if the previous instruction does not set up a condition
657 that the branch tests and if the branch is not itself the
658 target of any branch. */
659 if ((ip
->insn_mo
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
660 || (ip
->insn_mo
->pinfo
& INSN_COND_BRANCH_DELAY
))
662 if (mips_optimize
< 2
663 /* If we have seen .set nobopt, don't optimize. */
665 /* If we have seen .set volatile or .set nomove, don't
668 /* If we had to emit any NOP instructions, then we
669 already know we can not swap. */
671 /* If we don't even know the previous insn, we can not
674 /* If the previous insn is already in a branch delay
675 slot, then we can not swap. */
676 || prev_insn_is_delay_slot
677 /* If the previous previous insn was in a .set
678 noreorder, we can't swap. Actually, the MIPS
679 assembler will swap in this situation. However, gcc
680 configured -with-gnu-as will generate code like
686 in which we can not swap the bne and INSN. If gcc is
687 not configured -with-gnu-as, it does not output the
688 .set pseudo-ops. We don't have to check
689 prev_insn_unreordered, because prev_insn_valid will
690 be 0 in that case. We don't want to use
691 prev_prev_insn_valid, because we do want to be able
692 to swap at the start of a function. */
693 || prev_prev_insn_unreordered
694 /* If the branch is itself the target of a branch, we
695 can not swap. We cheat on this; all we check for is
696 whether there is a label on this instruction. If
697 there are any branches to anything other than a
698 label, users must use .set noreorder. */
699 || insn_label
!= NULL
700 /* If the branch reads the condition codes, we don't
701 even try to swap, because in the sequence
706 we can not swap, and I don't feel like handling that
708 || (ip
->insn_mo
->pinfo
& INSN_READ_COND_CODE
)
709 /* We can not swap with an instruction that requires a
710 delay slot, becase the target of the branch might
711 interfere with that instruction. */
712 || (prev_insn
.insn_mo
->pinfo
713 & (INSN_LOAD_COPROC_DELAY
714 | INSN_COPROC_MOVE_DELAY
715 | INSN_WRITE_COND_CODE
719 && (prev_insn
.insn_mo
->pinfo
720 & (INSN_LOAD_MEMORY_DELAY
721 | INSN_COPROC_MEMORY_DELAY
)))
722 /* We can not swap with a branch instruction. */
723 || (prev_insn
.insn_mo
->pinfo
724 & (INSN_UNCOND_BRANCH_DELAY
725 | INSN_COND_BRANCH_DELAY
726 | INSN_COND_BRANCH_LIKELY
))
727 /* If the branch reads a register that the previous
728 instruction sets, we can not swap. */
729 || ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_GPR_T
)
730 && insn_uses_reg (ip
,
731 ((prev_insn
.insn_opcode
>> OP_SH_RT
)
734 || ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_GPR_D
)
735 && insn_uses_reg (ip
,
736 ((prev_insn
.insn_opcode
>> OP_SH_RD
)
739 /* If the branch writes a register that the previous
740 instruction sets, we can not swap (we know that
741 branches write only to RD or to $31). */
742 || ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_GPR_T
)
743 && (((ip
->insn_mo
->pinfo
& INSN_WRITE_GPR_D
)
744 && (((prev_insn
.insn_opcode
>> OP_SH_RT
) & OP_MASK_RT
)
745 == ((ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
)))
746 || ((ip
->insn_mo
->pinfo
& INSN_WRITE_GPR_31
)
747 && (((prev_insn
.insn_opcode
>> OP_SH_RT
)
750 || ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_GPR_D
)
751 && (((ip
->insn_mo
->pinfo
& INSN_WRITE_GPR_D
)
752 && (((prev_insn
.insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
)
753 == ((ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
)))
754 || ((ip
->insn_mo
->pinfo
& INSN_WRITE_GPR_31
)
755 && (((prev_insn
.insn_opcode
>> OP_SH_RD
)
758 /* If the branch writes a register that the previous
759 instruction reads, we can not swap (we know that
760 branches only write to RD or to $31). */
761 || ((ip
->insn_mo
->pinfo
& INSN_WRITE_GPR_D
)
762 && insn_uses_reg (&prev_insn
,
763 ((ip
->insn_opcode
>> OP_SH_RD
)
766 || ((ip
->insn_mo
->pinfo
& INSN_WRITE_GPR_31
)
767 && insn_uses_reg (&prev_insn
, 31, 0))
768 /* If the previous previous instruction has a load
769 delay, and sets a register that the branch reads, we
771 || (((prev_prev_insn
.insn_mo
->pinfo
& INSN_LOAD_COPROC_DELAY
)
773 && (prev_prev_insn
.insn_mo
->pinfo
774 & INSN_LOAD_MEMORY_DELAY
)))
775 && insn_uses_reg (ip
,
776 ((prev_prev_insn
.insn_opcode
>> OP_SH_RT
)
780 /* We could do even better for unconditional branches to
781 portions of this object file; we could pick up the
782 instruction at the destination, put it in the delay
783 slot, and bump the destination address. */
785 /* Update the previous insn information. */
786 prev_prev_insn
= *ip
;
787 prev_insn
.insn_mo
= &dummy_opcode
;
794 /* It looks like we can actually do the swap. */
795 prev_f
= prev_insn_frag
->fr_literal
+ prev_insn_where
;
796 memcpy (temp
, prev_f
, 4);
797 memcpy (prev_f
, f
, 4);
801 prev_insn_fixp
->fx_frag
= frag_now
;
802 prev_insn_fixp
->fx_where
= f
- frag_now
->fr_literal
;
806 fixp
->fx_frag
= prev_insn_frag
;
807 fixp
->fx_where
= prev_insn_where
;
809 /* Update the previous insn information; leave prev_insn
811 prev_prev_insn
= *ip
;
813 prev_insn_is_delay_slot
= 1;
815 /* If that was an unconditional branch, forget the previous
817 if (ip
->insn_mo
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
819 prev_prev_insn
.insn_mo
= &dummy_opcode
;
820 prev_insn
.insn_mo
= &dummy_opcode
;
823 else if (ip
->insn_mo
->pinfo
& INSN_COND_BRANCH_LIKELY
)
825 /* We don't yet optimize a branch likely. What we should do
826 is look at the target, copy the instruction found there
827 into the delay slot, and increment the branch to jump to
828 the next instruction. */
830 /* Update the previous insn information. */
831 prev_prev_insn
= *ip
;
832 prev_insn
.insn_mo
= &dummy_opcode
;
836 /* Update the previous insn information. */
838 prev_prev_insn
.insn_mo
= &dummy_opcode
;
840 prev_prev_insn
= prev_insn
;
843 /* Any time we see a branch, we always fill the delay slot
844 immediately; since this insn is not a branch, we know it
845 is not in a delay slot. */
846 prev_insn_is_delay_slot
= 0;
849 prev_prev_insn_unreordered
= prev_insn_unreordered
;
850 prev_insn_unreordered
= 0;
851 prev_insn_frag
= frag_now
;
852 prev_insn_where
= f
- frag_now
->fr_literal
;
853 prev_insn_fixp
= fixp
;
857 /* We just output an insn, so the next one doesn't have a label. */
861 /* This function forgets that there was any previous instruction or
867 prev_insn
.insn_mo
= &dummy_opcode
;
868 prev_prev_insn
.insn_mo
= &dummy_opcode
;
870 prev_insn_is_delay_slot
= 0;
871 prev_insn_unreordered
= 0;
872 prev_prev_insn_unreordered
= 0;
876 /* This function must be called whenever we turn on noreorder or emit
877 something other than instructions. It inserts any NOPS which might
878 be needed by the previous instruction, and clears the information
879 kept for the previous instructions. */
884 if (! mips_noreorder
)
889 if ((prev_insn
.insn_mo
->pinfo
890 & (INSN_LOAD_COPROC_DELAY
891 | INSN_COPROC_MOVE_DELAY
892 | INSN_WRITE_COND_CODE
896 && (prev_insn
.insn_mo
->pinfo
897 & (INSN_LOAD_MEMORY_DELAY
898 | INSN_COPROC_MEMORY_DELAY
))))
901 if ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
902 || (prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
903 || (prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
))
906 else if ((prev_prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
907 || (prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
908 || (prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
))
913 if (insn_label
!= NULL
)
915 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
916 insn_label
->sy_frag
= frag_now
;
917 S_SET_VALUE (insn_label
, frag_now_fix ());
920 mips_no_prev_insn ();
924 /* Return 1 if an expression can be accessed via the GP register. */
935 sym
= ep
->X_add_symbol
;
936 if (sym
== (symbolS
*) NULL
937 || ep
->X_op_symbol
!= (symbolS
*) NULL
)
940 /* Certain symbols can not be referenced off the GP, although it
941 appears as though they can. */
942 symname
= S_GET_NAME (sym
);
943 if (symname
!= (const char *) NULL
944 && (strcmp (symname
, "eprol") == 0
945 || strcmp (symname
, "etext") == 0
946 || strcmp (symname
, "_gp") == 0
947 || strcmp (symname
, "edata") == 0
948 || strcmp (symname
, "_fbss") == 0
949 || strcmp (symname
, "_fdata") == 0
950 || strcmp (symname
, "_ftext") == 0
951 || strcmp (symname
, "end") == 0))
953 if (! S_IS_DEFINED (sym
)
954 && S_GET_VALUE (sym
) != 0
955 && S_GET_VALUE (sym
) <= g_switch_value
)
957 segname
= segment_name (S_GET_SEGMENT (ep
->X_add_symbol
));
958 return (strcmp (segname
, ".sdata") == 0
959 || strcmp (segname
, ".sbss") == 0
960 || strcmp (segname
, ".lit8") == 0
961 || strcmp (segname
, ".lit4") == 0);
962 #else /* ! defined (OBJ_ECOFF) */
963 /* The GP register is only used for ECOFF. */
965 #endif /* ! defined (OBJ_ECOFF) */
968 /* Build an instruction created by a macro expansion. This is passed
969 a pointer to the count of instructions created so far, an
970 expression, the name of the instruction to build, an operand format
971 string, and corresponding arguments. */
975 macro_build (int *counter
,
980 #else /* ! defined (NO_STDARG) */
982 macro_build (counter
, ep
, name
, fmt
, va_alist
)
988 #endif /* ! defined (NO_STDARG) */
990 struct mips_cl_insn insn
;
991 bfd_reloc_code_real_type r
;
995 va_start (args
, fmt
);
1001 * If the macro is about to expand into a second instruction,
1002 * print a warning if needed. We need to pass ip as a parameter
1003 * to generate a better warning message here...
1005 if (mips_warn_about_macros
&& *counter
== 1)
1006 as_warn ("Macro instruction expanded into multiple instructions");
1008 *counter
+= 1; /* bump instruction counter */
1010 r
= BFD_RELOC_UNUSED
;
1011 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
1012 assert (insn
.insn_mo
);
1013 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1015 while (strcmp (fmt
, insn
.insn_mo
->args
) != 0)
1018 assert (insn
.insn_mo
->name
);
1019 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1021 assert (insn
.insn_mo
->pinfo
!= INSN_MACRO
);
1022 insn
.insn_opcode
= insn
.insn_mo
->match
;
1038 insn
.insn_opcode
|= va_arg (args
, int) << 16;
1044 insn
.insn_opcode
|= va_arg (args
, int) << 16;
1049 insn
.insn_opcode
|= va_arg (args
, int) << 11;
1054 insn
.insn_opcode
|= va_arg (args
, int) << 11;
1058 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1062 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1066 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1073 insn
.insn_opcode
|= va_arg (args
, int) << 21;
1083 assert (ep
!= NULL
&& ep
->X_op
== O_constant
);
1084 insn
.insn_opcode
|= (ep
->X_add_number
>> 16) & 0xffff;
1089 assert (ep
!= NULL
);
1091 * This allows macro() to pass an immediate expression for
1092 * creating short branches without creating a symbol.
1093 * Note that the expression still might come from the assembly
1094 * input, in which case the value is not checked for range nor
1095 * is a relocation entry generated (yuck).
1097 if (ep
->X_op
== O_constant
)
1099 insn
.insn_opcode
|= (ep
->X_add_number
>> 2) & 0xffff;
1103 r
= BFD_RELOC_16_PCREL_S2
;
1112 assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
1114 /* Use GP relative addressing if possible. */
1115 if (r
== BFD_RELOC_LO16
1116 && gp_reference (ep
))
1117 r
= BFD_RELOC_MIPS_GPREL
;
1119 append_insn (&insn
, ep
, r
);
1123 * Generate a "lui" instruction.
1126 macro_build_lui (counter
, ep
, regnum
)
1131 expressionS high_expr
;
1132 struct mips_cl_insn insn
;
1133 bfd_reloc_code_real_type r
;
1134 CONST
char *name
= "lui";
1135 CONST
char *fmt
= "t,u";
1139 if (high_expr
.X_op
== O_constant
)
1141 /* we can compute the instruction now without a relocation entry */
1142 if (high_expr
.X_add_number
& 0x8000)
1143 high_expr
.X_add_number
+= 0x10000;
1144 high_expr
.X_add_number
=
1145 ((unsigned long) high_expr
.X_add_number
>> 16) & 0xffff;
1146 r
= BFD_RELOC_UNUSED
;
1149 r
= BFD_RELOC_HI16_S
;
1152 * If the macro is about to expand into a second instruction,
1153 * print a warning if needed. We need to pass ip as a parameter
1154 * to generate a better warning message here...
1156 if (mips_warn_about_macros
&& *counter
== 1)
1157 as_warn ("Macro instruction expanded into multiple instructions");
1159 *counter
+= 1; /* bump instruction counter */
1161 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
1162 assert (insn
.insn_mo
);
1163 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1164 assert (strcmp (fmt
, insn
.insn_mo
->args
) == 0);
1166 insn
.insn_opcode
= insn
.insn_mo
->match
| (regnum
<< 16);
1167 if (r
== BFD_RELOC_UNUSED
)
1169 insn
.insn_opcode
|= high_expr
.X_add_number
;
1170 append_insn (&insn
, NULL
, r
);
1173 append_insn (&insn
, &high_expr
, r
);
1177 * Generates code to set the $at register to true (one)
1178 * if reg is less than the immediate expression.
1181 set_at (counter
, reg
, unsignedp
)
1186 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
1187 macro_build (counter
, &imm_expr
,
1188 unsignedp
? "sltiu" : "slti",
1192 load_register (counter
, AT
, &imm_expr
);
1193 macro_build (counter
, NULL
,
1194 unsignedp
? "sltu" : "slt",
1195 "d,v,t", AT
, reg
, AT
);
1199 /* Warn if an expression is not a constant. */
1202 check_absolute_expr (ip
, ex
)
1203 struct mips_cl_insn
*ip
;
1206 if (ex
->X_op
!= O_constant
)
1207 as_warn ("Instruction %s requires absolute expression", ip
->insn_mo
->name
);
1211 * This routine generates the least number of instructions neccessary to load
1212 * an absolute expression value into a register.
1215 load_register (counter
, reg
, ep
)
1220 assert (ep
->X_op
== O_constant
);
1221 if (ep
->X_add_number
>= -0x8000 && ep
->X_add_number
< 0x8000)
1222 macro_build (counter
, ep
,
1223 mips_isa
< 3 ? "addiu" : "daddiu",
1225 else if (ep
->X_add_number
>= 0 && ep
->X_add_number
< 0x10000)
1226 macro_build (counter
, ep
, "ori", "t,r,i", reg
, 0);
1227 else if ((ep
->X_add_number
&~ (offsetT
) 0x7fffffff) == 0
1228 || ((ep
->X_add_number
&~ (offsetT
) 0x7fffffff)
1229 == ~ (offsetT
) 0x7fffffff))
1231 macro_build (counter
, ep
, "lui", "t,u", reg
);
1232 if ((ep
->X_add_number
& 0xffff) != 0)
1233 macro_build (counter
, ep
, "ori", "t,r,i", reg
, reg
);
1235 else if (mips_isa
< 3)
1237 as_bad ("Number larger than 32 bits");
1238 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, 0);
1243 expressionS hi32
, lo32
;
1247 hi32
.X_add_number
>>= shift
;
1248 hi32
.X_add_number
&= 0xffffffff;
1249 if ((hi32
.X_add_number
& 0x80000000) != 0)
1250 hi32
.X_add_number
|= ~ (offsetT
) 0xffffffff;
1251 load_register (counter
, reg
, &hi32
);
1253 lo32
.X_add_number
&= 0xffffffff;
1254 if ((lo32
.X_add_number
& 0xffff0000) == 0)
1255 macro_build (counter
, NULL
, "dsll32", "d,w,<", reg
, reg
, 0);
1260 macro_build (counter
, NULL
, "dsll", "d,w,<", reg
, reg
, 16);
1262 mid16
.X_add_number
>>= 16;
1263 macro_build (counter
, &mid16
, "ori", "t,r,i", reg
, reg
);
1264 macro_build (counter
, NULL
, "dsll", "d,w,<", reg
, reg
, 16);
1266 if ((lo32
.X_add_number
& 0xffff) != 0)
1267 macro_build (counter
, &lo32
, "ori", "t,r,i", reg
, reg
);
1273 * This routine implements the seemingly endless macro or synthesized
1274 * instructions and addressing modes in the mips assembly language. Many
1275 * of these macros are simple and are similar to each other. These could
1276 * probably be handled by some kind of table or grammer aproach instead of
1277 * this verbose method. Others are not simple macros but are more like
1278 * optimizing code generation.
1279 * One interesting optimization is when several store macros appear
1280 * consecutivly that would load AT with the upper half of the same address.
1281 * The ensuing load upper instructions are ommited. This implies some kind
1282 * of global optimization. We currently only optimize within a single macro.
1283 * For many of the load and store macros if the address is specified as a
1284 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
1285 * first load register 'at' with zero and use it as the base register. The
1286 * mips assembler simply uses register $zero. Just one tiny optimization
1291 struct mips_cl_insn
*ip
;
1293 register int treg
, sreg
, dreg
, breg
;
1307 treg
= (ip
->insn_opcode
>> 16) & 0x1f;
1308 dreg
= (ip
->insn_opcode
>> 11) & 0x1f;
1309 sreg
= breg
= (ip
->insn_opcode
>> 21) & 0x1f;
1310 mask
= ip
->insn_mo
->mask
;
1312 expr1
.X_op
= O_constant
;
1313 expr1
.X_op_symbol
= NULL
;
1314 expr1
.X_add_symbol
= NULL
;
1315 expr1
.X_add_number
= 1;
1327 mips_emit_delays ();
1330 expr1
.X_add_number
= 8;
1331 macro_build (&icnt
, &expr1
, "bgez", "s,p", sreg
);
1333 macro_build (&icnt
, NULL
, "nop", "", 0);
1335 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
, 0);
1336 macro_build (&icnt
, NULL
,
1337 dbl
? "dsub" : "sub",
1338 "d,v,t", dreg
, 0, sreg
);
1361 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
1363 macro_build (&icnt
, &imm_expr
, s
, "t,r,j", treg
, sreg
);
1366 load_register (&icnt
, AT
, &imm_expr
);
1367 macro_build (&icnt
, NULL
, s2
, "d,v,t", treg
, sreg
, AT
);
1386 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
1388 if (mask
!= M_NOR_I
)
1389 macro_build (&icnt
, &imm_expr
, s
, "t,r,i", treg
, sreg
);
1392 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
);
1393 macro_build (&icnt
, &imm_expr
, "nor", "d,v,t", treg
, treg
, 0);
1398 load_register (&icnt
, AT
, &imm_expr
);
1399 macro_build (&icnt
, NULL
, s2
, "d,v,t", treg
, sreg
, AT
);
1416 if (imm_expr
.X_add_number
== 0)
1418 macro_build (&icnt
, &offset_expr
, s
, "s,t,p", sreg
, 0);
1421 load_register (&icnt
, AT
, &imm_expr
);
1422 macro_build (&icnt
, &offset_expr
, s
, "s,t,p", sreg
, AT
);
1430 macro_build (&icnt
, &offset_expr
,
1431 likely
? "bgezl" : "bgez",
1437 macro_build (&icnt
, &offset_expr
,
1438 likely
? "blezl" : "blez",
1442 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1443 macro_build (&icnt
, &offset_expr
,
1444 likely
? "beql" : "beq",
1451 /* check for > max integer */
1452 maxnum
= 0x7fffffff;
1460 if (imm_expr
.X_add_number
>= maxnum
)
1463 /* result is always false */
1466 as_warn ("Branch %s is always false (nop)", ip
->insn_mo
->name
);
1467 macro_build (&icnt
, NULL
, "nop", "", 0);
1471 as_warn ("Branch likely %s is always false", ip
->insn_mo
->name
);
1472 macro_build (&icnt
, &offset_expr
, "bnel", "s,t,p", 0, 0);
1476 imm_expr
.X_add_number
++;
1480 if (mask
== M_BGEL_I
)
1482 if (imm_expr
.X_add_number
== 0)
1484 macro_build (&icnt
, &offset_expr
,
1485 likely
? "bgezl" : "bgez",
1489 if (imm_expr
.X_add_number
== 1)
1491 macro_build (&icnt
, &offset_expr
,
1492 likely
? "bgtzl" : "bgtz",
1496 maxnum
= 0x7fffffff;
1504 maxnum
= - maxnum
- 1;
1505 if (imm_expr
.X_add_number
<= maxnum
)
1508 /* result is always true */
1509 as_warn ("Branch %s is always true", ip
->insn_mo
->name
);
1510 macro_build (&icnt
, &offset_expr
, "b", "p");
1513 set_at (&icnt
, sreg
, 0);
1514 macro_build (&icnt
, &offset_expr
,
1515 likely
? "beql" : "beq",
1526 macro_build (&icnt
, &offset_expr
,
1527 likely
? "beql" : "beq",
1531 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1532 macro_build (&icnt
, &offset_expr
,
1533 likely
? "beql" : "beq",
1540 if (sreg
== 0 || imm_expr
.X_add_number
== -1)
1542 imm_expr
.X_add_number
++;
1546 if (mask
== M_BGEUL_I
)
1548 if (imm_expr
.X_add_number
== 0)
1550 if (imm_expr
.X_add_number
== 1)
1552 macro_build (&icnt
, &offset_expr
,
1553 likely
? "bnel" : "bne",
1557 set_at (&icnt
, sreg
, 1);
1558 macro_build (&icnt
, &offset_expr
,
1559 likely
? "beql" : "beq",
1568 macro_build (&icnt
, &offset_expr
,
1569 likely
? "bgtzl" : "bgtz",
1575 macro_build (&icnt
, &offset_expr
,
1576 likely
? "bltzl" : "bltz",
1580 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1581 macro_build (&icnt
, &offset_expr
,
1582 likely
? "bnel" : "bne",
1591 macro_build (&icnt
, &offset_expr
,
1592 likely
? "bnel" : "bne",
1598 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1599 macro_build (&icnt
, &offset_expr
,
1600 likely
? "bnel" : "bne",
1609 macro_build (&icnt
, &offset_expr
,
1610 likely
? "blezl" : "blez",
1616 macro_build (&icnt
, &offset_expr
,
1617 likely
? "bgezl" : "bgez",
1621 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1622 macro_build (&icnt
, &offset_expr
,
1623 likely
? "beql" : "beq",
1630 maxnum
= 0x7fffffff;
1638 if (imm_expr
.X_add_number
>= maxnum
)
1640 imm_expr
.X_add_number
++;
1644 if (mask
== M_BLTL_I
)
1646 if (imm_expr
.X_add_number
== 0)
1648 macro_build (&icnt
, &offset_expr
,
1649 likely
? "bltzl" : "bltz",
1653 if (imm_expr
.X_add_number
== 1)
1655 macro_build (&icnt
, &offset_expr
,
1656 likely
? "blezl" : "blez",
1660 set_at (&icnt
, sreg
, 0);
1661 macro_build (&icnt
, &offset_expr
,
1662 likely
? "bnel" : "bne",
1671 macro_build (&icnt
, &offset_expr
,
1672 likely
? "beql" : "beq",
1678 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1679 macro_build (&icnt
, &offset_expr
,
1680 likely
? "beql" : "beq",
1687 if (sreg
== 0 || imm_expr
.X_add_number
== -1)
1689 imm_expr
.X_add_number
++;
1693 if (mask
== M_BLTUL_I
)
1695 if (imm_expr
.X_add_number
== 0)
1697 if (imm_expr
.X_add_number
== 1)
1699 macro_build (&icnt
, &offset_expr
,
1700 likely
? "beql" : "beq",
1704 set_at (&icnt
, sreg
, 1);
1705 macro_build (&icnt
, &offset_expr
,
1706 likely
? "bnel" : "bne",
1715 macro_build (&icnt
, &offset_expr
,
1716 likely
? "bltzl" : "bltz",
1722 macro_build (&icnt
, &offset_expr
,
1723 likely
? "bgtzl" : "bgtz",
1727 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1728 macro_build (&icnt
, &offset_expr
,
1729 likely
? "bnel" : "bne",
1740 macro_build (&icnt
, &offset_expr
,
1741 likely
? "bnel" : "bne",
1745 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1746 macro_build (&icnt
, &offset_expr
,
1747 likely
? "bnel" : "bne",
1763 as_warn ("Divide by zero.");
1764 macro_build (&icnt
, NULL
, "break", "c", 7);
1769 /* The MIPS assembler treats a destination of $0 as a
1770 request for just the machine instruction. */
1771 macro_build (&icnt
, NULL
,
1772 dbl
? "ddiv" : "div",
1777 mips_emit_delays ();
1779 macro_build (&icnt
, NULL
,
1780 dbl
? "ddiv" : "div",
1782 expr1
.X_add_number
= 8;
1783 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1784 macro_build (&icnt
, NULL
, "nop", "", 0);
1785 macro_build (&icnt
, NULL
, "break", "c", 7);
1786 expr1
.X_add_number
= -1;
1787 macro_build (&icnt
, &expr1
,
1788 dbl
? "daddiu" : "addiu",
1790 expr1
.X_add_number
= dbl
? 20 : 16;
1791 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, AT
);
1794 expr1
.X_add_number
= 1;
1795 macro_build (&icnt
, &expr1
, "daddiu", "t,r,j", AT
, 0);
1796 macro_build (&icnt
, NULL
, "dsll32", "d,w,<", AT
, AT
, 31);
1800 expr1
.X_add_number
= 0x80000000;
1801 macro_build (&icnt
, &expr1
, "lui", "t,u", AT
);
1803 expr1
.X_add_number
= 8;
1804 macro_build (&icnt
, &expr1
, "bne", "s,t,p", sreg
, AT
);
1805 macro_build (&icnt
, NULL
, "nop", "", 0);
1806 macro_build (&icnt
, NULL
, "break", "c", 6);
1808 macro_build (&icnt
, NULL
, s
, "d", dreg
);
1847 if (imm_expr
.X_add_number
== 0)
1849 as_warn ("Divide by zero.");
1850 macro_build (&icnt
, NULL
, "break", "c", 7);
1853 if (imm_expr
.X_add_number
== 1)
1855 if (strcmp (s2
, "mflo") == 0)
1856 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
);
1858 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1861 if (imm_expr
.X_add_number
== -1
1862 && s
[strlen (s
) - 1] != 'u')
1864 if (strcmp (s2
, "mflo") == 0)
1867 macro_build (&icnt
, NULL
, "dneg", "d,w", dreg
, sreg
);
1869 macro_build (&icnt
, NULL
, "neg", "d,w", dreg
, sreg
);
1872 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1876 load_register (&icnt
, AT
, &imm_expr
);
1877 macro_build (&icnt
, NULL
, s
, "s,t", sreg
, AT
);
1878 macro_build (&icnt
, NULL
, s2
, "d", dreg
);
1897 mips_emit_delays ();
1899 macro_build (&icnt
, NULL
, s
, "s,t", sreg
, treg
);
1900 expr1
.X_add_number
= 8;
1901 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1902 macro_build (&icnt
, NULL
, "nop", "", 0);
1903 macro_build (&icnt
, NULL
, "break", "c", 7);
1905 macro_build (&icnt
, NULL
, s2
, "d", dreg
);
1909 if (offset_expr
.X_op
== O_constant
)
1911 load_register (&icnt
, treg
, &offset_expr
);
1914 if (gp_reference (&offset_expr
))
1915 macro_build (&icnt
, &offset_expr
,
1916 mips_isa
< 3 ? "addiu" : "daddiu",
1920 /* FIXME: This won't work for a 64 bit address. */
1921 macro_build_lui (&icnt
, &offset_expr
, treg
);
1922 macro_build (&icnt
, &offset_expr
,
1923 mips_isa
< 3 ? "addiu" : "daddiu",
1924 "t,r,j", treg
, treg
);
1929 tempreg
= (breg
== treg
) ? AT
: treg
;
1930 if (offset_expr
.X_op
== O_constant
)
1931 load_register (&icnt
, tempreg
, &offset_expr
);
1932 else if (gp_reference (&offset_expr
))
1933 macro_build (&icnt
, &offset_expr
,
1934 mips_isa
< 3 ? "addiu" : "daddiu",
1935 "t,r,j", tempreg
, GP
);
1938 /* FIXME: This won't work for a 64 bit address. */
1939 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1940 macro_build (&icnt
, &offset_expr
,
1941 mips_isa
< 3 ? "addiu" : "daddiu",
1942 "t,r,j", tempreg
, tempreg
);
1945 macro_build (&icnt
, NULL
, "addu", "d,v,t", treg
, tempreg
, breg
);
2015 if (breg
== treg
|| coproc
)
2084 if (mask
== M_LWC1_AB
2085 || mask
== M_SWC1_AB
2087 || mask
== M_LDC1_AB
2088 || mask
== M_SDC1_AB
)
2094 if (gp_reference (&offset_expr
))
2098 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, GP
);
2101 macro_build (&icnt
, (expressionS
*) NULL
,
2102 mips_isa
< 3 ? "addu" : "daddu",
2103 "d,v,t", tempreg
, breg
, GP
);
2107 /* FIXME: This won't work for a 64 bit address. */
2108 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2110 macro_build (&icnt
, NULL
,
2111 mips_isa
< 3 ? "addu" : "daddu",
2112 "d,v,t", tempreg
, tempreg
, breg
);
2114 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, tempreg
);
2121 load_register (&icnt
, treg
, &imm_expr
);
2126 lw $v0,%lo(foo)($at)
2127 lw $v1,%lo(foo+4)($at)
2132 /* FIXME: This won't work for a 64 bit address. */
2133 macro_build_lui (&icnt
, &offset_expr
, AT
);
2135 macro_build (&icnt
, &offset_expr
, "ld", "t,o(b)", treg
, AT
);
2138 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
, AT
);
2139 offset_expr
.X_add_number
+= 4;
2140 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
+ 1, AT
);
2145 /* Load a floating point number from the .lit8 section. */
2148 macro_build (&icnt
, &offset_expr
, "ldc1", "T,o(b)", treg
, GP
);
2154 /* Even on a big endian machine $fn comes before $fn+1. We have
2155 to adjust when loading from memory. */
2156 assert (mips_isa
< 2);
2157 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2158 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2160 offset_expr
.X_add_number
+= 4;
2161 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2162 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2168 * The MIPS assembler seems to check for X_add_number not
2169 * being double aligned and generating:
2172 * addiu at,at,%lo(foo+1)
2175 * But, the resulting address is the same after relocation so why
2176 * generate the extra instruction?
2178 if (gp_reference (&offset_expr
))
2184 macro_build (&icnt
, &offset_expr
,
2185 mips_isa
< 3 ? "addu" : "daddu",
2186 "d,v,t", AT
, breg
, GP
);
2192 /* FIXME: This won't work for a 64 bit address. */
2193 macro_build_lui (&icnt
, &offset_expr
, AT
);
2195 macro_build (&icnt
, NULL
,
2196 mips_isa
< 3 ? "addu" : "daddu",
2197 "d,v,t", AT
, AT
, breg
);
2201 macro_build (&icnt
, &offset_expr
, "ldc1", "T,o(b)", treg
, tempreg
);
2204 /* Even on a big endian machine $fn comes before $fn+1. We
2205 have to adjust when loading from memory. */
2206 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2207 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2209 offset_expr
.X_add_number
+= 4;
2210 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2211 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2224 assert (mips_isa
< 3);
2225 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
2226 offset_expr
.X_add_number
+= 4;
2227 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, breg
);
2250 if (gp_reference (&offset_expr
))
2258 macro_build (&icnt
, (expressionS
*) NULL
,
2259 mips_isa
< 3 ? "addu" : "daddu",
2260 "d,v,t", tempreg
, breg
, GP
);
2264 /* FIXME: This won't work for a 64 bit address. */
2265 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2267 macro_build (&icnt
, NULL
,
2268 mips_isa
< 3 ? "addu" : "daddu",
2269 "d,v,t", tempreg
, tempreg
, breg
);
2272 macro_build (&icnt
, &offset_expr
, s2
, "t,o(b)", treg
, tempreg
);
2275 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, tempreg
);
2276 offset_expr
.X_add_number
+= 4;
2277 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, tempreg
);
2286 macro_build (&icnt
, NULL
,
2287 dbl
? "dmultu" : "multu",
2289 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2295 /* The MIPS assembler some times generates shifts and adds. I'm
2296 not trying to be that fancy. GCC should do this for us
2298 load_register (&icnt
, AT
, &imm_expr
);
2299 macro_build (&icnt
, NULL
,
2300 dbl
? "dmult" : "mult",
2302 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2308 mips_emit_delays ();
2310 macro_build (&icnt
, NULL
,
2311 dbl
? "dmult" : "mult",
2313 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2314 macro_build (&icnt
, NULL
,
2315 dbl
? "dsra32" : "sra",
2316 "d,w,<", dreg
, dreg
, 31);
2317 macro_build (&icnt
, NULL
, "mfhi", "d", AT
);
2318 expr1
.X_add_number
= 8;
2319 macro_build (&icnt
, &expr1
, "beq", "s,t,p", dreg
, AT
);
2320 macro_build (&icnt
, NULL
, "nop", "", 0);
2321 macro_build (&icnt
, NULL
, "break", "c", 6);
2323 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2329 mips_emit_delays ();
2331 macro_build (&icnt
, NULL
,
2332 dbl
? "dmultu" : "multu",
2334 macro_build (&icnt
, NULL
, "mfhi", "d", AT
);
2335 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2336 expr1
.X_add_number
= 8;
2337 macro_build (&icnt
, &expr1
, "beq", "s,t,p", AT
, 0);
2338 macro_build (&icnt
, NULL
, "nop", "", 0);
2339 macro_build (&icnt
, NULL
, "break", "c", 6);
2344 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
2345 macro_build (&icnt
, NULL
, "srlv", "d,t,s", AT
, sreg
, AT
);
2346 macro_build (&icnt
, NULL
, "sllv", "d,t,s", dreg
, sreg
, treg
);
2347 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2351 macro_build (&icnt
, NULL
, "sll", "d,w,<", AT
, sreg
,
2352 imm_expr
.X_add_number
& 0x1f);
2353 macro_build (&icnt
, NULL
, "srl", "d,w,<", dreg
, sreg
,
2354 (0 - imm_expr
.X_add_number
) & 0x1f);
2355 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2359 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
2360 macro_build (&icnt
, NULL
, "sllv", "d,t,s", AT
, sreg
, AT
);
2361 macro_build (&icnt
, NULL
, "srlv", "d,t,s", dreg
, sreg
, treg
);
2362 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2366 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, sreg
,
2367 imm_expr
.X_add_number
& 0x1f);
2368 macro_build (&icnt
, NULL
, "sll", "d,w,<", dreg
, sreg
,
2369 (0 - imm_expr
.X_add_number
) & 0x1f);
2370 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2374 assert (mips_isa
< 2);
2375 /* Even on a big endian machine $fn comes before $fn+1. We have
2376 to adjust when storing to memory. */
2377 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2378 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2380 offset_expr
.X_add_number
+= 4;
2381 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2382 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2387 if (gp_reference (&offset_expr
))
2393 macro_build (&icnt
, (expressionS
*) NULL
,
2394 mips_isa
< 3 ? "addu" : "daddu",
2395 "d,v,t", AT
, breg
, GP
);
2401 /* FIXME: This won't work for a 64 bit address. */
2402 macro_build_lui (&icnt
, &offset_expr
, AT
);
2404 macro_build (&icnt
, NULL
,
2405 mips_isa
< 3 ? "addu" : "daddu",
2406 "d,v,t", AT
, AT
, breg
);
2410 macro_build (&icnt
, &offset_expr
, "sdc1", "T,o(b)", treg
, tempreg
);
2413 /* Even on a big endian machine $fn comes before $fn+1. We
2414 have to adjust when storing to memory. */
2415 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2416 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2418 offset_expr
.X_add_number
+= 4;
2419 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2420 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2429 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, treg
);
2431 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
2434 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
2435 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
2440 if (imm_expr
.X_add_number
== 0)
2442 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
2447 as_warn ("Instruction %s: result is always false",
2449 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
2452 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
2454 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
2457 else if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
< 0)
2459 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2460 macro_build (&icnt
, &imm_expr
,
2461 mips_isa
< 3 ? "addiu" : "daddiu",
2462 "t,r,j", dreg
, sreg
);
2467 load_register (&icnt
, AT
, &imm_expr
);
2468 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
2471 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
2476 case M_SGE
: /* sreg >= treg <==> not (sreg < treg) */
2482 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, sreg
, treg
);
2483 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2486 case M_SGE_I
: /* sreg >= I <==> not (sreg < I) */
2488 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2490 macro_build (&icnt
, &expr1
,
2491 mask
== M_SGE_I
? "slti" : "sltiu",
2492 "t,r,j", dreg
, sreg
);
2497 load_register (&icnt
, AT
, &imm_expr
);
2498 macro_build (&icnt
, NULL
,
2499 mask
== M_SGE_I
? "slt" : "sltu",
2500 "d,v,t", dreg
, sreg
, AT
);
2503 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2508 case M_SGT
: /* sreg > treg <==> treg < sreg */
2514 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
2517 case M_SGT_I
: /* sreg > I <==> I < sreg */
2523 load_register (&icnt
, AT
, &imm_expr
);
2524 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
2527 case M_SLE
: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
2533 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
2534 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2537 case M_SLE_I
: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
2543 load_register (&icnt
, AT
, &imm_expr
);
2544 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
2545 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2549 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2551 macro_build (&icnt
, &imm_expr
, "slti", "t,r,j", dreg
, sreg
);
2554 load_register (&icnt
, AT
, &imm_expr
);
2555 macro_build (&icnt
, NULL
, "slt", "d,v,t", dreg
, sreg
, AT
);
2559 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2561 macro_build (&icnt
, &imm_expr
, "sltiu", "t,r,j", dreg
, sreg
);
2564 load_register (&icnt
, AT
, &imm_expr
);
2565 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, sreg
, AT
);
2570 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, treg
);
2572 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
2575 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
2576 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
2581 if (imm_expr
.X_add_number
== 0)
2583 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
2588 as_warn ("Instruction %s: result is always true",
2590 macro_build (&icnt
, &expr1
,
2591 mips_isa
< 3 ? "addiu" : "daddiu",
2595 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
2597 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
2600 else if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
< 0)
2602 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2603 macro_build (&icnt
, &imm_expr
,
2604 mips_isa
< 3 ? "addiu" : "daddiu",
2605 "t,r,j", dreg
, sreg
);
2610 load_register (&icnt
, AT
, &imm_expr
);
2611 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
2614 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
2622 if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
<= 0x8000)
2624 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2625 macro_build (&icnt
, &imm_expr
,
2626 dbl
? "daddi" : "addi",
2627 "t,r,j", dreg
, sreg
);
2630 load_register (&icnt
, AT
, &imm_expr
);
2631 macro_build (&icnt
, NULL
,
2632 dbl
? "dsub" : "sub",
2633 "d,v,t", dreg
, sreg
, AT
);
2639 if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
<= 0x8000)
2641 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2642 macro_build (&icnt
, &imm_expr
,
2643 dbl
? "daddiu" : "addiu",
2644 "t,r,j", dreg
, sreg
);
2647 load_register (&icnt
, AT
, &imm_expr
);
2648 macro_build (&icnt
, NULL
,
2649 dbl
? "dsubu" : "subu",
2650 "d,v,t", dreg
, sreg
, AT
);
2671 load_register (&icnt
, AT
, &imm_expr
);
2672 macro_build (&icnt
, NULL
, s
, "s,t", sreg
, AT
);
2677 assert (mips_isa
< 2);
2678 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* floating reg */
2679 dreg
= (ip
->insn_opcode
>> 06) & 0x1f; /* floating reg */
2682 * Is the double cfc1 instruction a bug in the mips assembler;
2683 * or is there a reason for it?
2685 mips_emit_delays ();
2687 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
2688 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
2689 macro_build (&icnt
, NULL
, "nop", "");
2690 expr1
.X_add_number
= 3;
2691 macro_build (&icnt
, &expr1
, "ori", "t,r,i", AT
, treg
);
2692 expr1
.X_add_number
= 2;
2693 macro_build (&icnt
, &expr1
, "xori", "t,r,i", AT
, AT
);
2694 macro_build (&icnt
, NULL
, "ctc1", "t,G", AT
, 31);
2695 macro_build (&icnt
, NULL
, "nop", "");
2696 macro_build (&icnt
, NULL
,
2697 mask
== M_TRUNCWD
? "cvt.w.d" : "cvt.w.s", "D,S", dreg
, sreg
);
2698 macro_build (&icnt
, NULL
, "ctc1", "t,G", treg
, 31);
2699 macro_build (&icnt
, NULL
, "nop", "");
2709 /* avoid load delay */
2710 offset_expr
.X_add_number
+= 1;
2711 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
2712 offset_expr
.X_add_number
-= 1;
2713 macro_build (&icnt
, &offset_expr
, "lbu", "t,o(b)", AT
, breg
);
2714 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2715 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2719 /* does this work on a big endian machine? */
2720 offset_expr
.X_add_number
+= 3;
2721 macro_build (&icnt
, &offset_expr
, "lwl", "t,o(b)", treg
, breg
);
2722 offset_expr
.X_add_number
-= 3;
2723 macro_build (&icnt
, &offset_expr
, "lwr", "t,o(b)", treg
, breg
);
2729 if (offset_expr
.X_op
== O_constant
)
2730 load_register (&icnt
, AT
, &offset_expr
);
2731 else if (gp_reference (&offset_expr
))
2732 macro_build (&icnt
, &offset_expr
,
2733 mips_isa
< 3 ? "addiu" : "daddiu",
2737 /* FIXME: This won't work for a 64 bit address. */
2738 macro_build_lui (&icnt
, &offset_expr
, AT
);
2739 macro_build (&icnt
, &offset_expr
,
2740 mips_isa
< 3 ? "addiu" : "daddiu",
2743 if (mask
== M_ULW_A
)
2745 expr1
.X_add_number
= 3;
2746 macro_build (&icnt
, &expr1
, "lwl", "t,o(b)", treg
, AT
);
2747 imm_expr
.X_add_number
= 0;
2748 macro_build (&icnt
, &expr1
, "lwr", "t,o(b)", treg
, AT
);
2752 macro_build (&icnt
, &expr1
,
2753 mask
== M_ULH_A
? "lb" : "lbu", "t,o(b)", treg
, AT
);
2754 imm_expr
.X_add_number
= 0;
2755 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
2756 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2757 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2762 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", treg
, breg
);
2763 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, treg
, 8);
2764 offset_expr
.X_add_number
+= 1;
2765 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", AT
, breg
);
2769 offset_expr
.X_add_number
+= 3;
2770 macro_build (&icnt
, &offset_expr
, "swl", "t,o(b)", treg
, breg
);
2771 offset_expr
.X_add_number
-= 3;
2772 macro_build (&icnt
, &offset_expr
, "swr", "t,o(b)", treg
, breg
);
2777 if (offset_expr
.X_op
== O_constant
)
2778 load_register (&icnt
, AT
, &offset_expr
);
2779 else if (gp_reference (&offset_expr
))
2780 macro_build (&icnt
, &offset_expr
,
2781 mips_isa
< 3 ? "addiu" : "daddiu",
2785 /* FIXME: This won't work for a 64 bit address. */
2786 macro_build_lui (&icnt
, &offset_expr
, AT
);
2787 macro_build (&icnt
, &offset_expr
,
2788 mips_isa
< 3 ? "addiu" : "daddiu",
2791 if (mask
== M_USW_A
)
2793 expr1
.X_add_number
= 3;
2794 macro_build (&icnt
, &expr1
, "swl", "t,o(b)", treg
, AT
);
2795 expr1
.X_add_number
= 0;
2796 macro_build (&icnt
, &expr1
, "swr", "t,o(b)", treg
, AT
);
2800 expr1
.X_add_number
= 0;
2801 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
2802 macro_build (&icnt
, NULL
, "srl", "d,w,<", treg
, treg
, 8);
2803 expr1
.X_add_number
= 1;
2804 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
2805 expr1
.X_add_number
= 0;
2806 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
2807 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2808 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2813 as_bad ("Macro %s not implemented yet", ip
->insn_mo
->name
);
2817 as_warn ("Macro used $at after \".set noat\"");
2822 This routine assembles an instruction into its binary format. As a side
2823 effect it sets one of the global variables imm_reloc or offset_reloc to the
2824 type of relocation to do if one of the operands is an address expression.
2829 struct mips_cl_insn
*ip
;
2834 struct mips_opcode
*insn
;
2837 unsigned int lastregno
= 0;
2842 for (s
= str
; islower (*s
) || (*s
>= '0' && *s
<= '3') || *s
== '.'; ++s
)
2854 as_warn ("Unknown opcode: `%s'", str
);
2857 if ((insn
= (struct mips_opcode
*) hash_find (op_hash
, str
)) == NULL
)
2859 as_warn ("`%s' not in hash table.", str
);
2860 insn_error
= "ERROR: Unrecognized opcode";
2868 assert (strcmp (insn
->name
, str
) == 0);
2870 if (insn
->pinfo
== INSN_MACRO
)
2871 insn_isa
= insn
->match
;
2872 else if (insn
->pinfo
& INSN_ISA2
)
2874 else if (insn
->pinfo
& INSN_ISA3
)
2879 if (insn_isa
> mips_isa
)
2881 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
]
2882 && strcmp (insn
->name
, insn
[1].name
) == 0)
2887 insn_error
= "ERROR: instruction not supported on this processor";
2892 ip
->insn_opcode
= insn
->match
;
2893 for (args
= insn
->args
;; ++args
)
2899 case '\0': /* end of args */
2912 ip
->insn_opcode
|= lastregno
<< 21;
2917 ip
->insn_opcode
|= lastregno
<< 16;
2921 ip
->insn_opcode
|= lastregno
<< 11;
2927 /* handle optional base register.
2928 Either the base register is omitted or
2929 we must have a left paren. */
2930 /* this is dependent on the next operand specifier
2931 is a 'b' for base register */
2932 assert (args
[1] == 'b');
2936 case ')': /* these must match exactly */
2941 case '<': /* must be at least one digit */
2943 * According to the manual, if the shift amount is greater
2944 * than 31 or less than 0 the the shift amount should be
2945 * mod 32. In reality the mips assembler issues an error.
2946 * We issue a warning and do the mod.
2948 my_getExpression (&imm_expr
, s
);
2949 check_absolute_expr (ip
, &imm_expr
);
2950 if ((unsigned long) imm_expr
.X_add_number
> 31)
2952 as_warn ("Improper shift amount (%d)",
2953 imm_expr
.X_add_number
);
2954 imm_expr
.X_add_number
= imm_expr
.X_add_number
% 32;
2956 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2957 imm_expr
.X_op
= O_absent
;
2961 case 'c': /* break code */
2962 my_getExpression (&imm_expr
, s
);
2963 check_absolute_expr (ip
, &imm_expr
);
2964 if ((unsigned) imm_expr
.X_add_number
> 1023)
2965 as_warn ("Illegal break code (%d)", imm_expr
.X_add_number
);
2966 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 16;
2967 imm_expr
.X_op
= O_absent
;
2971 case 'B': /* syscall code */
2972 my_getExpression (&imm_expr
, s
);
2973 check_absolute_expr (ip
, &imm_expr
);
2974 if ((unsigned) imm_expr
.X_add_number
> 0xfffff)
2975 as_warn ("Illegal syscall code (%d)", imm_expr
.X_add_number
);
2976 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2977 imm_expr
.X_op
= O_absent
;
2981 case 'C': /* Coprocessor code */
2982 my_getExpression (&imm_expr
, s
);
2983 check_absolute_expr (ip
, &imm_expr
);
2984 if ((unsigned long) imm_expr
.X_add_number
>= (1<<25))
2986 as_warn ("Coproccesor code > 25 bits (%d)",
2987 imm_expr
.X_add_number
);
2988 imm_expr
.X_add_number
&= ((1<<25) - 1);
2990 ip
->insn_opcode
|= imm_expr
.X_add_number
;
2991 imm_expr
.X_op
= O_absent
;
2995 case 'b': /* base register */
2996 case 'd': /* destination register */
2997 case 's': /* source register */
2998 case 't': /* target register */
2999 case 'r': /* both target and source */
3000 case 'v': /* both dest and source */
3001 case 'w': /* both dest and target */
3002 case 'E': /* coprocessor target register */
3003 case 'G': /* coprocessor destination register */
3004 case 'x': /* ignore register name */
3018 while (isdigit (*s
));
3020 as_bad ("Invalid register number (%d)", regno
);
3022 else if (*args
!= 'E' && *args
!= 'G')
3024 if (s
[1] == 'f' && s
[2] == 'p')
3029 else if (s
[1] == 's' && s
[2] == 'p')
3034 else if (s
[1] == 'g' && s
[2] == 'p')
3039 else if (s
[1] == 'a' && s
[2] == 't')
3046 if (regno
== AT
&& ! mips_noat
)
3047 as_warn ("Used $at without \".set noat\"");
3054 if (c
== 'r' || c
== 'v' || c
== 'w')
3067 ip
->insn_opcode
|= regno
<< 21;
3071 ip
->insn_opcode
|= regno
<< 11;
3076 ip
->insn_opcode
|= regno
<< 16;
3079 /* This case exists because on the r3000 trunc
3080 expands into a macro which requires a gp
3081 register. On the r6000 or r4000 it is
3082 assembled into a single instruction which
3083 ignores the register. Thus the insn version
3084 is MIPS_ISA2 and uses 'x', and the macro
3085 version is MIPS_ISA1 and uses 't'. */
3096 ip
->insn_opcode
|= lastregno
<< 21;
3099 ip
->insn_opcode
|= lastregno
<< 16;
3104 case 'D': /* floating point destination register */
3105 case 'S': /* floating point source register */
3106 case 'T': /* floating point target register */
3110 if (s
[0] == '$' && s
[1] == 'f' && isdigit (s
[2]))
3120 while (isdigit (*s
));
3123 as_bad ("Invalid float register number (%d)", regno
);
3126 !(strcmp (str
, "mtc1") == 0 ||
3127 strcmp (str
, "mfc1") == 0 ||
3128 strcmp (str
, "lwc1") == 0 ||
3129 strcmp (str
, "swc1") == 0))
3130 as_warn ("Float register should be even, was %d",
3138 if (c
== 'V' || c
== 'W')
3148 ip
->insn_opcode
|= regno
<< 6;
3152 ip
->insn_opcode
|= regno
<< 11;
3156 ip
->insn_opcode
|= regno
<< 16;
3164 ip
->insn_opcode
|= lastregno
<< 11;
3167 ip
->insn_opcode
|= lastregno
<< 16;
3173 my_getExpression (&imm_expr
, s
);
3174 check_absolute_expr (ip
, &imm_expr
);
3179 my_getExpression (&offset_expr
, s
);
3180 imm_reloc
= BFD_RELOC_32
;
3192 unsigned char temp
[8];
3198 /* These only appear as the last operand in an
3199 instruction, and every instruction that accepts
3200 them in any variant accepts them in all variants.
3201 This means we don't have to worry about backing out
3202 any changes if the instruction does not match.
3204 The difference between them is the size of the
3205 floating point constant and where it goes. For 'F'
3206 and 'L' the constant is 64 bits; for 'f' and 'l' it
3207 is 32 bits. Where the constant is placed is based
3208 on how the MIPS assembler does things:
3211 f -- immediate value
3215 f64
= *args
== 'F' || *args
== 'L';
3217 save_in
= input_line_pointer
;
3218 input_line_pointer
= s
;
3219 err
= md_atof (f64
? 'd' : 'f', (char *) temp
, &length
);
3220 s
= input_line_pointer
;
3221 input_line_pointer
= save_in
;
3222 if (err
!= NULL
&& *err
!= '\0')
3224 as_bad ("Bad floating point constant: %s", err
);
3225 memset (temp
, '\0', sizeof temp
);
3226 length
= f64
? 8 : 4;
3229 assert (length
== (f64
? 8 : 4));
3233 imm_expr
.X_op
= O_constant
;
3234 if (byte_order
== LITTLE_ENDIAN
)
3235 imm_expr
.X_add_number
=
3236 (((((((int) temp
[3] << 8)
3241 imm_expr
.X_add_number
=
3242 (((((((int) temp
[0] << 8)
3249 /* Switch to the right section. */
3251 subseg
= now_subseg
;
3255 subseg_new (".rdata", (subsegT
) 0);
3258 subseg_new (".lit8", (subsegT
) 0);
3261 subseg_new (".lit4", (subsegT
) 0);
3265 as_bad ("Can't use floating point insn in this section");
3267 /* Set the argument to the current address in the
3269 offset_expr
.X_op
= O_symbol
;
3270 offset_expr
.X_add_symbol
=
3271 symbol_new ("L0\001", now_seg
,
3272 (valueT
) frag_now_fix (), frag_now
);
3273 offset_expr
.X_add_number
= 0;
3275 /* Put the floating point number into the section. */
3276 p
= frag_more (length
);
3277 memcpy (p
, temp
, length
);
3279 /* Switch back to the original section. */
3280 subseg_set (seg
, subseg
);
3285 case 'i': /* 16 bit unsigned immediate */
3286 case 'j': /* 16 bit signed immediate */
3287 imm_reloc
= BFD_RELOC_LO16
;
3288 c
= my_getSmallExpression (&imm_expr
, s
);
3293 if (imm_expr
.X_op
== O_constant
)
3294 imm_expr
.X_add_number
=
3295 (imm_expr
.X_add_number
>> 16) & 0xffff;
3297 imm_reloc
= BFD_RELOC_HI16_S
;
3299 imm_reloc
= BFD_RELOC_HI16
;
3303 check_absolute_expr (ip
, &imm_expr
);
3306 if (imm_expr
.X_add_number
< 0
3307 || imm_expr
.X_add_number
>= 0x10000)
3309 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3310 !strcmp (insn
->name
, insn
[1].name
))
3312 as_bad ("16 bit expression not in range 0..65535");
3317 if (imm_expr
.X_add_number
< -0x8000 ||
3318 imm_expr
.X_add_number
>= 0x8000)
3320 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3321 !strcmp (insn
->name
, insn
[1].name
))
3323 as_bad ("16 bit expression not in range -32768..32767");
3329 case 'o': /* 16 bit offset */
3330 c
= my_getSmallExpression (&offset_expr
, s
);
3332 * If this value won't fit into a 16 bit offset, then
3333 * go find a macro that will generate the 32 bit offset
3336 if (offset_expr
.X_op
!= O_constant
3337 || offset_expr
.X_add_number
>= 0x8000
3338 || offset_expr
.X_add_number
< -0x8000)
3341 offset_reloc
= BFD_RELOC_LO16
;
3342 if (c
== 'h' || c
== 'H')
3344 assert (offset_expr
.X_op
== O_constant
);
3345 offset_expr
.X_add_number
=
3346 (offset_expr
.X_add_number
>> 16) & 0xffff;
3351 case 'p': /* pc relative offset */
3352 offset_reloc
= BFD_RELOC_16_PCREL_S2
;
3353 my_getExpression (&offset_expr
, s
);
3357 case 'u': /* upper 16 bits */
3358 c
= my_getSmallExpression (&imm_expr
, s
);
3359 if (imm_expr
.X_op
!= O_constant
3360 || imm_expr
.X_add_number
< 0
3361 || imm_expr
.X_add_number
>= 0x10000)
3362 as_bad ("lui expression not in range 0..65535");
3363 imm_reloc
= BFD_RELOC_LO16
;
3368 if (imm_expr
.X_op
== O_constant
)
3369 imm_expr
.X_add_number
=
3370 (imm_expr
.X_add_number
>> 16) & 0xffff;
3372 imm_reloc
= BFD_RELOC_HI16_S
;
3374 imm_reloc
= BFD_RELOC_HI16
;
3380 case 'a': /* 26 bit address */
3381 my_getExpression (&offset_expr
, s
);
3383 offset_reloc
= BFD_RELOC_MIPS_JMP
;
3387 fprintf (stderr
, "bad char = '%c'\n", *args
);
3392 /* Args don't match. */
3393 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3394 !strcmp (insn
->name
, insn
[1].name
))
3400 insn_error
= "ERROR: Illegal operands";
3409 my_getSmallExpression (ep
, str
)
3420 ((str
[1] == 'h' && str
[2] == 'i')
3421 || (str
[1] == 'H' && str
[2] == 'I')
3422 || (str
[1] == 'l' && str
[2] == 'o'))
3434 * A small expression may be followed by a base register.
3435 * Scan to the end of this operand, and then back over a possible
3436 * base register. Then scan the small expression up to that
3437 * point. (Based on code in sparc.c...)
3439 for (sp
= str
; *sp
&& *sp
!= ','; sp
++)
3441 if (sp
- 4 >= str
&& sp
[-1] == RP
)
3443 if (isdigit (sp
[-2]))
3445 for (sp
-= 3; sp
>= str
&& isdigit (*sp
); sp
--)
3447 if (*sp
== '$' && sp
> str
&& sp
[-1] == LP
)
3453 else if (sp
- 5 >= str
3456 && ((sp
[-3] == 'f' && sp
[-2] == 'p')
3457 || (sp
[-3] == 's' && sp
[-2] == 'p')
3458 || (sp
[-3] == 'g' && sp
[-2] == 'p')
3459 || (sp
[-3] == 'a' && sp
[-2] == 't')))
3465 /* no expression means zero offset */
3468 /* %xx(reg) is an error */
3469 ep
->X_op
= O_absent
;
3474 ep
->X_op
= O_absent
;
3477 ep
->X_add_symbol
= NULL
;
3478 ep
->X_op_symbol
= NULL
;
3479 ep
->X_add_number
= 0;
3484 my_getExpression (ep
, str
);
3491 my_getExpression (ep
, str
);
3492 return c
; /* => %hi or %lo encountered */
3496 my_getExpression (ep
, str
)
3502 save_in
= input_line_pointer
;
3503 input_line_pointer
= str
;
3505 expr_end
= input_line_pointer
;
3506 input_line_pointer
= save_in
;
3509 /* Turn a string in input_line_pointer into a floating point constant
3510 of type type, and store the appropriate bytes in *litP. The number
3511 of LITTLENUMS emitted is stored in *sizeP . An error message is
3512 returned, or NULL on OK. */
3515 md_atof (type
, litP
, sizeP
)
3521 LITTLENUM_TYPE words
[4];
3537 return "bad call to md_atof";
3540 t
= atof_ieee (input_line_pointer
, type
, words
);
3542 input_line_pointer
= t
;
3546 if (byte_order
== LITTLE_ENDIAN
)
3548 for (i
= prec
- 1; i
>= 0; i
--)
3550 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3556 for (i
= 0; i
< prec
; i
++)
3558 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3567 md_number_to_chars (buf
, val
, n
)
3615 md_number_to_chars (buf
, hi
, 4);
3640 md_parse_option (argP
, cntP
, vecP
)
3645 /* Accept -nocpp but ignore it. */
3646 if (strcmp (*argP
, "nocpp") == 0)
3652 if (strcmp (*argP
, "EL") == 0
3653 || strcmp (*argP
, "EB") == 0)
3655 /* FIXME: This breaks -L -EL. */
3663 if ((*argP
)[1] == '0')
3672 if ((*argP
)[1] == '\0' || (*argP
)[1] == '2')
3677 if (strncmp (*argP
, "mips", 4) == 0)
3679 mips_isa
= atol (*argP
+ 4);
3682 else if (mips_isa
< 1 || mips_isa
> 3)
3684 as_bad ("-mips%d not supported", mips_isa
);
3691 if (strncmp (*argP
, "mcpu=", 5) == 0)
3695 /* Identify the processor type */
3697 if (strcmp (p
, "default") == 0
3698 || strcmp (p
, "DEFAULT") == 0)
3702 if (*p
== 'r' || *p
== 'R')
3709 if (strcmp (p
, "2000") == 0
3710 || strcmp (p
, "2k") == 0
3711 || strcmp (p
, "2K") == 0)
3716 if (strcmp (p
, "3000") == 0
3717 || strcmp (p
, "3k") == 0
3718 || strcmp (p
, "3K") == 0)
3723 if (strcmp (p
, "4000") == 0
3724 || strcmp (p
, "4k") == 0
3725 || strcmp (p
, "4K") == 0)
3730 if (strcmp (p
, "6000") == 0
3731 || strcmp (p
, "6k") == 0
3732 || strcmp (p
, "6K") == 0)
3739 as_bad ("bad value (%s) for -mcpu= switch", *argP
+ 5);
3752 if ((*argP
)[1] != '\0')
3753 g_switch_value
= atoi (*argP
+ 1);
3756 **vecP
= (char *) NULL
;
3759 g_switch_value
= atoi (**vecP
);
3762 as_warn ("Number expected after -G");
3768 return 1; /* pretend you parsed the character */
3772 md_pcrel_from (fixP
)
3775 /* return the address of the delay slot */
3776 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
3780 md_apply_fix (fixP
, valueP
)
3787 assert (fixP
->fx_size
== 4);
3790 fixP
->fx_addnumber
= value
; /* Remember value for tc_gen_reloc */
3792 switch (fixP
->fx_r_type
)
3795 case BFD_RELOC_MIPS_JMP
:
3796 case BFD_RELOC_HI16
:
3797 case BFD_RELOC_HI16_S
:
3798 case BFD_RELOC_LO16
:
3799 case BFD_RELOC_MIPS_GPREL
:
3800 /* Nothing needed to do. The value comes from the reloc entry */
3803 case BFD_RELOC_16_PCREL_S2
:
3805 * We need to save the bits in the instruction since fixup_segment()
3806 * might be deleting the relocation entry (i.e., a branch within
3807 * the current segment).
3810 as_warn ("Branch to odd address (%x)", value
);
3812 if ((value
& ~0xFFFF) && (value
& ~0xFFFF) != (-1 & ~0xFFFF))
3813 as_bad ("Relocation overflow");
3815 /* update old instruction data */
3816 buf
= (unsigned char *) (fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
);
3820 insn
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
3824 insn
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | buf
[3];
3831 insn
|= value
& 0xFFFF;
3832 md_number_to_chars ((char *) buf
, insn
, 4);
3846 const struct mips_opcode
*p
;
3847 int treg
, sreg
, dreg
, shamt
;
3852 for (i
= 0; i
< NUMOPCODES
; ++i
)
3854 p
= &mips_opcodes
[i
];
3855 if (((oc
& p
->mask
) == p
->match
) && (p
->pinfo
!= INSN_MACRO
))
3857 printf ("%08lx %s\t", oc
, p
->name
);
3858 treg
= (oc
>> 16) & 0x1f;
3859 sreg
= (oc
>> 21) & 0x1f;
3860 dreg
= (oc
>> 11) & 0x1f;
3861 shamt
= (oc
>> 6) & 0x1f;
3863 for (args
= p
->args
;; ++args
)
3874 printf ("%c", *args
);
3878 assert (treg
== sreg
);
3879 printf ("$%d,$%d", treg
, sreg
);
3884 printf ("$%d", dreg
);
3889 printf ("$%d", treg
);
3894 printf ("$%d", sreg
);
3898 printf ("0x%08lx", oc
& 0x1ffffff);
3909 printf ("$%d", shamt
);
3920 printf ("%08lx UNDEFINED\n", oc
);
3931 name
= input_line_pointer
;
3932 c
= get_symbol_end ();
3933 p
= (symbolS
*) symbol_find_or_make (name
);
3934 *input_line_pointer
= c
;
3938 /* Align the current frag to a given power of two. The MIPS assembler
3939 also automatically adjusts any preceding label. */
3942 mips_align (to
, fill
)
3946 mips_emit_delays ();
3947 frag_align (to
, fill
);
3948 record_alignment (now_seg
, to
);
3949 if (insn_label
!= NULL
)
3951 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
3952 insn_label
->sy_frag
= frag_now
;
3953 S_SET_VALUE (insn_label
, frag_now_fix ());
3958 /* Align to a given power of two. .align 0 turns off the automatic
3959 alignment used by the data creating pseudo-ops. */
3966 register long temp_fill
;
3967 long max_alignment
= 15;
3971 o Note that the assembler pulls down any immediately preceeding label
3972 to the aligned address.
3973 o It's not documented but auto alignment is reinstated by
3974 a .align pseudo instruction.
3975 o Note also that after auto alignment is turned off the mips assembler
3976 issues an error on attempt to assemble an improperly aligned data item.
3981 temp
= get_absolute_expression ();
3982 if (temp
> max_alignment
)
3983 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
3986 as_warn ("Alignment negative: 0 assumed.");
3989 if (*input_line_pointer
== ',')
3991 input_line_pointer
++;
3992 temp_fill
= get_absolute_expression ();
3999 mips_align (temp
, (int) temp_fill
);
4006 demand_empty_rest_of_line ();
4009 /* Handle .ascii and .asciiz. This just calls stringer and forgets
4010 that there was a previous instruction. */
4013 s_stringer (append_zero
)
4016 mips_emit_delays ();
4018 stringer (append_zero
);
4027 mips_emit_delays ();
4036 subseg_new (".rdata", (subsegT
) get_absolute_expression ());
4037 demand_empty_rest_of_line ();
4046 #ifdef BFD_ASSEMBLER
4047 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
4049 subseg_new (bss_section
, (subsegT
) get_absolute_expression ());
4051 demand_empty_rest_of_line ();
4055 subseg_new (".sdata", (subsegT
) get_absolute_expression ());
4056 demand_empty_rest_of_line ();
4059 as_bad ("Global pointers not supported; recompile -G 0");
4060 demand_empty_rest_of_line ();
4071 mips_emit_delays ();
4072 if (log_size
> 0 && auto_align
)
4073 mips_align (log_size
, 0);
4075 cons (1 << log_size
);
4082 as_fatal ("Encountered `.err', aborting assembly");
4092 symbolP
= get_symbol ();
4093 if (*input_line_pointer
== ',')
4094 input_line_pointer
++;
4095 size
= get_absolute_expression ();
4096 S_SET_VALUE (symbolP
, size
);
4097 S_SET_EXTERNAL (symbolP
);
4100 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
4101 so we use an additional ECOFF specific field. */
4102 symbolP
->ecoff_undefined
= 1;
4110 mips_emit_delays ();
4127 if (strcmp (input_line_pointer
, "O1") != 0
4128 && strcmp (input_line_pointer
, "O2") != 0)
4129 as_warn ("Unrecognized option");
4130 demand_empty_rest_of_line ();
4137 char *name
= input_line_pointer
, ch
;
4139 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4140 input_line_pointer
++;
4141 ch
= *input_line_pointer
;
4142 *input_line_pointer
= '\0';
4144 if (strcmp (name
, "reorder") == 0)
4148 prev_insn_unreordered
= 1;
4149 prev_prev_insn_unreordered
= 1;
4153 else if (strcmp (name
, "noreorder") == 0)
4155 mips_emit_delays ();
4158 else if (strcmp (name
, "at") == 0)
4162 else if (strcmp (name
, "noat") == 0)
4166 else if (strcmp (name
, "macro") == 0)
4168 mips_warn_about_macros
= 0;
4170 else if (strcmp (name
, "nomacro") == 0)
4172 if (mips_noreorder
== 0)
4173 as_bad ("`noreorder' must be set before `nomacro'");
4174 mips_warn_about_macros
= 1;
4176 else if (strcmp (name
, "move") == 0 || strcmp (name
, "novolatile") == 0)
4180 else if (strcmp (name
, "nomove") == 0 || strcmp (name
, "volatile") == 0)
4184 else if (strcmp (name
, "bopt") == 0)
4188 else if (strcmp (name
, "nobopt") == 0)
4194 as_warn ("Tried to set unrecognized symbol: %s\n", name
);
4196 *input_line_pointer
= ch
;
4197 demand_empty_rest_of_line ();
4200 /* The same as the usual .space directive, except that we have to
4201 forget about any previous instruction. */
4204 s_mips_space (param
)
4207 mips_emit_delays ();
4218 if (*input_line_pointer
++ != '$')
4220 as_warn ("expected `$'");
4223 if (isdigit ((unsigned char) *input_line_pointer
))
4225 reg
= get_absolute_expression ();
4226 if (reg
< 0 || reg
>= 32)
4228 as_warn ("Bad register number");
4234 if (strncmp (input_line_pointer
, "fp", 2) == 0)
4236 else if (strncmp (input_line_pointer
, "sp", 2) == 0)
4238 else if (strncmp (input_line_pointer
, "gp", 2) == 0)
4240 else if (strncmp (input_line_pointer
, "at", 2) == 0)
4244 as_warn ("Unrecognized register name");
4247 input_line_pointer
+= 2;
4253 * Translate internal representation of relocation info to BFD target format.
4256 tc_gen_reloc (section
, fixp
)
4262 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
4263 assert (reloc
!= 0);
4265 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
4266 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4267 if (fixp
->fx_pcrel
== 0)
4268 reloc
->addend
= fixp
->fx_addnumber
;
4273 reloc
->addend
= -reloc
->address
;
4275 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4276 assert (reloc
->howto
!= 0);
4281 /* should never be called */
4283 md_section_align (seg
, addr
)
4287 int align
= bfd_get_section_alignment (stdoutput
, seg
);
4289 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
4293 md_estimate_size_before_relax (fragP
, segtype
)
4297 as_fatal ("md_estimate_size_before_relax");
4299 } /* md_estimate_size_before_relax() */
4301 /* This function is called whenever a label is defined. It is used
4302 when handling branch delays; if a branch has a label, we assume we
4306 mips_define_label (sym
)
4314 /* These functions should really be defined by the object file format,
4315 since they are related to debugging information. However, this
4316 code has to work for the a.out format, which does not define them,
4317 so we provide simple versions here. These don't actually generate
4318 any debugging information, but they do simple checking and someday
4319 somebody may make them useful. */
4323 struct loc
*loc_next
;
4324 unsigned long loc_fileno
;
4325 unsigned long loc_lineno
;
4326 unsigned long loc_offset
;
4327 unsigned short loc_delta
;
4328 unsigned short loc_count
;
4337 struct proc
*proc_next
;
4338 struct symbol
*proc_isym
;
4339 struct symbol
*proc_end
;
4340 unsigned long proc_reg_mask
;
4341 unsigned long proc_reg_offset
;
4342 unsigned long proc_fpreg_mask
;
4343 unsigned long proc_fpreg_offset
;
4344 unsigned long proc_frameoffset
;
4345 unsigned long proc_framereg
;
4346 unsigned long proc_pcreg
;
4348 struct file
*proc_file
;
4355 struct file
*file_next
;
4356 unsigned long file_fileno
;
4357 struct symbol
*file_symbol
;
4358 struct symbol
*file_end
;
4359 struct proc
*file_proc
;
4364 static struct obstack proc_frags
;
4365 static procS
*proc_lastP
;
4366 static procS
*proc_rootP
;
4367 static int numprocs
;
4372 obstack_begin (&proc_frags
, 0x2000);
4378 /* check for premature end, nesting errors, etc */
4379 if (proc_lastP
&& proc_lastP
->proc_end
== NULL
)
4380 as_warn ("missing `.end' at end of assembly");
4383 extern char hex_value
[];
4391 if (*input_line_pointer
== '-')
4393 ++input_line_pointer
;
4396 if (!isdigit (*input_line_pointer
))
4397 as_bad ("Expected simple number.");
4398 if (input_line_pointer
[0] == '0')
4400 if (input_line_pointer
[1] == 'x')
4402 input_line_pointer
+= 2;
4403 while (isxdigit (*input_line_pointer
))
4406 val
|= hex_value
[(int) *input_line_pointer
++];
4408 return negative
? -val
: val
;
4412 ++input_line_pointer
;
4413 while (isdigit (*input_line_pointer
))
4416 val
|= *input_line_pointer
++ - '0';
4418 return negative
? -val
: val
;
4421 if (!isdigit (*input_line_pointer
))
4423 printf (" *input_line_pointer == '%c' 0x%02x\n",
4424 *input_line_pointer
, *input_line_pointer
);
4425 as_warn ("Invalid number");
4428 while (isdigit (*input_line_pointer
))
4431 val
+= *input_line_pointer
++ - '0';
4433 return negative
? -val
: val
;
4436 /* The .file directive; just like the usual .file directive, but there
4437 is an initial number which is the ECOFF file index. */
4445 line
= get_number ();
4450 /* The .end directive. */
4458 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4461 demand_empty_rest_of_line ();
4465 if (now_seg
!= text_section
)
4466 as_warn (".end not in text section");
4469 as_warn (".end and no .ent seen yet.");
4475 assert (S_GET_NAME (p
));
4476 if (strcmp (S_GET_NAME (p
), S_GET_NAME (proc_lastP
->proc_isym
)))
4477 as_warn (".end symbol does not match .ent symbol.");
4480 proc_lastP
->proc_end
= (symbolS
*) 1;
4483 /* The .aent and .ent directives. */
4493 symbolP
= get_symbol ();
4494 if (*input_line_pointer
== ',')
4495 input_line_pointer
++;
4496 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4497 number
= get_number ();
4498 if (now_seg
!= text_section
)
4499 as_warn (".ent or .aent not in text section.");
4501 if (!aent
&& proc_lastP
&& proc_lastP
->proc_end
== NULL
)
4502 as_warn ("missing `.end'");
4506 procP
= (procS
*) obstack_alloc (&proc_frags
, sizeof (*procP
));
4507 procP
->proc_isym
= symbolP
;
4508 procP
->proc_reg_mask
= 0;
4509 procP
->proc_reg_offset
= 0;
4510 procP
->proc_fpreg_mask
= 0;
4511 procP
->proc_fpreg_offset
= 0;
4512 procP
->proc_frameoffset
= 0;
4513 procP
->proc_framereg
= 0;
4514 procP
->proc_pcreg
= 0;
4515 procP
->proc_end
= NULL
;
4516 procP
->proc_next
= NULL
;
4518 proc_lastP
->proc_next
= procP
;
4524 demand_empty_rest_of_line ();
4527 /* The .frame directive. */
4540 frame_reg
= tc_get_register ();
4541 if (*input_line_pointer
== ',')
4542 input_line_pointer
++;
4543 frame_off
= get_absolute_expression ();
4544 if (*input_line_pointer
== ',')
4545 input_line_pointer
++;
4546 pcreg
= tc_get_register ();
4549 assert (proc_rootP
);
4550 proc_rootP
->proc_framereg
= frame_reg
;
4551 proc_rootP
->proc_frameoffset
= frame_off
;
4552 proc_rootP
->proc_pcreg
= pcreg
;
4553 /* bob macho .frame */
4555 /* We don't have to write out a frame stab for unoptimized code. */
4556 if (!(frame_reg
== 30 && frame_off
== 0))
4559 as_warn ("No .ent for .frame to use.");
4560 (void) sprintf (str
, "R%d;%d", frame_reg
, frame_off
);
4561 symP
= symbol_new (str
, N_VFP
, 0, frag_now
);
4562 S_SET_TYPE (symP
, N_RMASK
);
4563 S_SET_OTHER (symP
, 0);
4564 S_SET_DESC (symP
, 0);
4565 symP
->sy_forward
= proc_lastP
->proc_isym
;
4566 /* bob perhaps I should have used pseudo set */
4568 demand_empty_rest_of_line ();
4572 /* The .fmask and .mask directives. */
4579 char str
[100], *strP
;
4585 mask
= get_number ();
4586 if (*input_line_pointer
== ',')
4587 input_line_pointer
++;
4588 off
= get_absolute_expression ();
4590 /* bob only for coff */
4591 assert (proc_rootP
);
4592 if (reg_type
== 'F')
4594 proc_rootP
->proc_fpreg_mask
= mask
;
4595 proc_rootP
->proc_fpreg_offset
= off
;
4599 proc_rootP
->proc_reg_mask
= mask
;
4600 proc_rootP
->proc_reg_offset
= off
;
4603 /* bob macho .mask + .fmask */
4605 /* We don't have to write out a mask stab if no saved regs. */
4609 as_warn ("No .ent for .mask to use.");
4611 for (i
= 0; i
< 32; i
++)
4615 sprintf (strP
, "%c%d,", reg_type
, i
);
4616 strP
+= strlen (strP
);
4620 sprintf (strP
, ";%d,", off
);
4621 symP
= symbol_new (str
, N_RMASK
, 0, frag_now
);
4622 S_SET_TYPE (symP
, N_RMASK
);
4623 S_SET_OTHER (symP
, 0);
4624 S_SET_DESC (symP
, 0);
4625 symP
->sy_forward
= proc_lastP
->proc_isym
;
4626 /* bob perhaps I should have used pseudo set */
4631 /* The .loc directive. */
4642 assert (now_seg
== text_section
);
4644 lineno
= get_number ();
4645 addroff
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
4647 symbolP
= symbol_new ("", N_SLINE
, addroff
, frag_now
);
4648 S_SET_TYPE (symbolP
, N_SLINE
);
4649 S_SET_OTHER (symbolP
, 0);
4650 S_SET_DESC (symbolP
, lineno
);
4651 symbolP
->sy_segment
= now_seg
;
4655 #endif /* ! defined (OBJ_ECOFF) */