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;
1061 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1065 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1069 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1076 insn
.insn_opcode
|= va_arg (args
, int) << 21;
1086 assert (ep
!= NULL
&& ep
->X_op
== O_constant
);
1087 insn
.insn_opcode
|= (ep
->X_add_number
>> 16) & 0xffff;
1092 assert (ep
!= NULL
);
1094 * This allows macro() to pass an immediate expression for
1095 * creating short branches without creating a symbol.
1096 * Note that the expression still might come from the assembly
1097 * input, in which case the value is not checked for range nor
1098 * is a relocation entry generated (yuck).
1100 if (ep
->X_op
== O_constant
)
1102 insn
.insn_opcode
|= (ep
->X_add_number
>> 2) & 0xffff;
1106 r
= BFD_RELOC_16_PCREL_S2
;
1115 assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
1117 /* Use GP relative addressing if possible. */
1118 if (r
== BFD_RELOC_LO16
1119 && gp_reference (ep
))
1120 r
= BFD_RELOC_MIPS_GPREL
;
1122 append_insn (&insn
, ep
, r
);
1126 * Generate a "lui" instruction.
1129 macro_build_lui (counter
, ep
, regnum
)
1134 expressionS high_expr
;
1135 struct mips_cl_insn insn
;
1136 bfd_reloc_code_real_type r
;
1137 CONST
char *name
= "lui";
1138 CONST
char *fmt
= "t,u";
1142 if (high_expr
.X_op
== O_constant
)
1144 /* we can compute the instruction now without a relocation entry */
1145 if (high_expr
.X_add_number
& 0x8000)
1146 high_expr
.X_add_number
+= 0x10000;
1147 high_expr
.X_add_number
=
1148 ((unsigned long) high_expr
.X_add_number
>> 16) & 0xffff;
1149 r
= BFD_RELOC_UNUSED
;
1152 r
= BFD_RELOC_HI16_S
;
1155 * If the macro is about to expand into a second instruction,
1156 * print a warning if needed. We need to pass ip as a parameter
1157 * to generate a better warning message here...
1159 if (mips_warn_about_macros
&& *counter
== 1)
1160 as_warn ("Macro instruction expanded into multiple instructions");
1162 *counter
+= 1; /* bump instruction counter */
1164 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
1165 assert (insn
.insn_mo
);
1166 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1167 assert (strcmp (fmt
, insn
.insn_mo
->args
) == 0);
1169 insn
.insn_opcode
= insn
.insn_mo
->match
| (regnum
<< 16);
1170 if (r
== BFD_RELOC_UNUSED
)
1172 insn
.insn_opcode
|= high_expr
.X_add_number
;
1173 append_insn (&insn
, NULL
, r
);
1176 append_insn (&insn
, &high_expr
, r
);
1180 * Generates code to set the $at register to true (one)
1181 * if reg is less than the immediate expression.
1184 set_at (counter
, reg
, unsignedp
)
1189 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
1190 macro_build (counter
, &imm_expr
,
1191 unsignedp
? "sltiu" : "slti",
1195 load_register (counter
, AT
, &imm_expr
);
1196 macro_build (counter
, NULL
,
1197 unsignedp
? "sltu" : "slt",
1198 "d,v,t", AT
, reg
, AT
);
1202 /* Warn if an expression is not a constant. */
1205 check_absolute_expr (ip
, ex
)
1206 struct mips_cl_insn
*ip
;
1209 if (ex
->X_op
!= O_constant
)
1210 as_warn ("Instruction %s requires absolute expression", ip
->insn_mo
->name
);
1214 * This routine generates the least number of instructions neccessary to load
1215 * an absolute expression value into a register.
1218 load_register (counter
, reg
, ep
)
1223 assert (ep
->X_op
== O_constant
);
1224 if (ep
->X_add_number
>= -0x8000 && ep
->X_add_number
< 0x8000)
1225 macro_build (counter
, ep
,
1226 mips_isa
< 3 ? "addiu" : "daddiu",
1228 else if (ep
->X_add_number
>= 0 && ep
->X_add_number
< 0x10000)
1229 macro_build (counter
, ep
, "ori", "t,r,i", reg
, 0);
1230 else if ((ep
->X_add_number
&~ (offsetT
) 0x7fffffff) == 0
1231 || ((ep
->X_add_number
&~ (offsetT
) 0x7fffffff)
1232 == ~ (offsetT
) 0x7fffffff))
1234 macro_build (counter
, ep
, "lui", "t,u", reg
);
1235 if ((ep
->X_add_number
& 0xffff) != 0)
1236 macro_build (counter
, ep
, "ori", "t,r,i", reg
, reg
);
1238 else if (mips_isa
< 3)
1240 as_bad ("Number larger than 32 bits");
1241 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, 0);
1246 expressionS hi32
, lo32
;
1250 hi32
.X_add_number
>>= shift
;
1251 hi32
.X_add_number
&= 0xffffffff;
1252 if ((hi32
.X_add_number
& 0x80000000) != 0)
1253 hi32
.X_add_number
|= ~ (offsetT
) 0xffffffff;
1254 load_register (counter
, reg
, &hi32
);
1256 lo32
.X_add_number
&= 0xffffffff;
1257 if ((lo32
.X_add_number
& 0xffff0000) == 0)
1258 macro_build (counter
, NULL
, "dsll32", "d,w,<", reg
, reg
, 0);
1263 macro_build (counter
, NULL
, "dsll", "d,w,<", reg
, reg
, 16);
1265 mid16
.X_add_number
>>= 16;
1266 macro_build (counter
, &mid16
, "ori", "t,r,i", reg
, reg
);
1267 macro_build (counter
, NULL
, "dsll", "d,w,<", reg
, reg
, 16);
1269 if ((lo32
.X_add_number
& 0xffff) != 0)
1270 macro_build (counter
, &lo32
, "ori", "t,r,i", reg
, reg
);
1276 * This routine implements the seemingly endless macro or synthesized
1277 * instructions and addressing modes in the mips assembly language. Many
1278 * of these macros are simple and are similar to each other. These could
1279 * probably be handled by some kind of table or grammer aproach instead of
1280 * this verbose method. Others are not simple macros but are more like
1281 * optimizing code generation.
1282 * One interesting optimization is when several store macros appear
1283 * consecutivly that would load AT with the upper half of the same address.
1284 * The ensuing load upper instructions are ommited. This implies some kind
1285 * of global optimization. We currently only optimize within a single macro.
1286 * For many of the load and store macros if the address is specified as a
1287 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
1288 * first load register 'at' with zero and use it as the base register. The
1289 * mips assembler simply uses register $zero. Just one tiny optimization
1294 struct mips_cl_insn
*ip
;
1296 register int treg
, sreg
, dreg
, breg
;
1310 treg
= (ip
->insn_opcode
>> 16) & 0x1f;
1311 dreg
= (ip
->insn_opcode
>> 11) & 0x1f;
1312 sreg
= breg
= (ip
->insn_opcode
>> 21) & 0x1f;
1313 mask
= ip
->insn_mo
->mask
;
1315 expr1
.X_op
= O_constant
;
1316 expr1
.X_op_symbol
= NULL
;
1317 expr1
.X_add_symbol
= NULL
;
1318 expr1
.X_add_number
= 1;
1330 mips_emit_delays ();
1333 expr1
.X_add_number
= 8;
1334 macro_build (&icnt
, &expr1
, "bgez", "s,p", sreg
);
1336 macro_build (&icnt
, NULL
, "nop", "", 0);
1338 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
, 0);
1339 macro_build (&icnt
, NULL
,
1340 dbl
? "dsub" : "sub",
1341 "d,v,t", dreg
, 0, sreg
);
1364 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
1366 macro_build (&icnt
, &imm_expr
, s
, "t,r,j", treg
, sreg
);
1369 load_register (&icnt
, AT
, &imm_expr
);
1370 macro_build (&icnt
, NULL
, s2
, "d,v,t", treg
, sreg
, AT
);
1389 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
1391 if (mask
!= M_NOR_I
)
1392 macro_build (&icnt
, &imm_expr
, s
, "t,r,i", treg
, sreg
);
1395 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
);
1396 macro_build (&icnt
, &imm_expr
, "nor", "d,v,t", treg
, treg
, 0);
1401 load_register (&icnt
, AT
, &imm_expr
);
1402 macro_build (&icnt
, NULL
, s2
, "d,v,t", treg
, sreg
, AT
);
1419 if (imm_expr
.X_add_number
== 0)
1421 macro_build (&icnt
, &offset_expr
, s
, "s,t,p", sreg
, 0);
1424 load_register (&icnt
, AT
, &imm_expr
);
1425 macro_build (&icnt
, &offset_expr
, s
, "s,t,p", sreg
, AT
);
1433 macro_build (&icnt
, &offset_expr
,
1434 likely
? "bgezl" : "bgez",
1440 macro_build (&icnt
, &offset_expr
,
1441 likely
? "blezl" : "blez",
1445 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1446 macro_build (&icnt
, &offset_expr
,
1447 likely
? "beql" : "beq",
1454 /* check for > max integer */
1455 maxnum
= 0x7fffffff;
1463 if (imm_expr
.X_add_number
>= maxnum
)
1466 /* result is always false */
1469 as_warn ("Branch %s is always false (nop)", ip
->insn_mo
->name
);
1470 macro_build (&icnt
, NULL
, "nop", "", 0);
1474 as_warn ("Branch likely %s is always false", ip
->insn_mo
->name
);
1475 macro_build (&icnt
, &offset_expr
, "bnel", "s,t,p", 0, 0);
1479 imm_expr
.X_add_number
++;
1483 if (mask
== M_BGEL_I
)
1485 if (imm_expr
.X_add_number
== 0)
1487 macro_build (&icnt
, &offset_expr
,
1488 likely
? "bgezl" : "bgez",
1492 if (imm_expr
.X_add_number
== 1)
1494 macro_build (&icnt
, &offset_expr
,
1495 likely
? "bgtzl" : "bgtz",
1499 maxnum
= 0x7fffffff;
1507 maxnum
= - maxnum
- 1;
1508 if (imm_expr
.X_add_number
<= maxnum
)
1511 /* result is always true */
1512 as_warn ("Branch %s is always true", ip
->insn_mo
->name
);
1513 macro_build (&icnt
, &offset_expr
, "b", "p");
1516 set_at (&icnt
, sreg
, 0);
1517 macro_build (&icnt
, &offset_expr
,
1518 likely
? "beql" : "beq",
1529 macro_build (&icnt
, &offset_expr
,
1530 likely
? "beql" : "beq",
1534 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1535 macro_build (&icnt
, &offset_expr
,
1536 likely
? "beql" : "beq",
1543 if (sreg
== 0 || imm_expr
.X_add_number
== -1)
1545 imm_expr
.X_add_number
++;
1549 if (mask
== M_BGEUL_I
)
1551 if (imm_expr
.X_add_number
== 0)
1553 if (imm_expr
.X_add_number
== 1)
1555 macro_build (&icnt
, &offset_expr
,
1556 likely
? "bnel" : "bne",
1560 set_at (&icnt
, sreg
, 1);
1561 macro_build (&icnt
, &offset_expr
,
1562 likely
? "beql" : "beq",
1571 macro_build (&icnt
, &offset_expr
,
1572 likely
? "bgtzl" : "bgtz",
1578 macro_build (&icnt
, &offset_expr
,
1579 likely
? "bltzl" : "bltz",
1583 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1584 macro_build (&icnt
, &offset_expr
,
1585 likely
? "bnel" : "bne",
1594 macro_build (&icnt
, &offset_expr
,
1595 likely
? "bnel" : "bne",
1601 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1602 macro_build (&icnt
, &offset_expr
,
1603 likely
? "bnel" : "bne",
1612 macro_build (&icnt
, &offset_expr
,
1613 likely
? "blezl" : "blez",
1619 macro_build (&icnt
, &offset_expr
,
1620 likely
? "bgezl" : "bgez",
1624 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1625 macro_build (&icnt
, &offset_expr
,
1626 likely
? "beql" : "beq",
1633 maxnum
= 0x7fffffff;
1641 if (imm_expr
.X_add_number
>= maxnum
)
1643 imm_expr
.X_add_number
++;
1647 if (mask
== M_BLTL_I
)
1649 if (imm_expr
.X_add_number
== 0)
1651 macro_build (&icnt
, &offset_expr
,
1652 likely
? "bltzl" : "bltz",
1656 if (imm_expr
.X_add_number
== 1)
1658 macro_build (&icnt
, &offset_expr
,
1659 likely
? "blezl" : "blez",
1663 set_at (&icnt
, sreg
, 0);
1664 macro_build (&icnt
, &offset_expr
,
1665 likely
? "bnel" : "bne",
1674 macro_build (&icnt
, &offset_expr
,
1675 likely
? "beql" : "beq",
1681 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1682 macro_build (&icnt
, &offset_expr
,
1683 likely
? "beql" : "beq",
1690 if (sreg
== 0 || imm_expr
.X_add_number
== -1)
1692 imm_expr
.X_add_number
++;
1696 if (mask
== M_BLTUL_I
)
1698 if (imm_expr
.X_add_number
== 0)
1700 if (imm_expr
.X_add_number
== 1)
1702 macro_build (&icnt
, &offset_expr
,
1703 likely
? "beql" : "beq",
1707 set_at (&icnt
, sreg
, 1);
1708 macro_build (&icnt
, &offset_expr
,
1709 likely
? "bnel" : "bne",
1718 macro_build (&icnt
, &offset_expr
,
1719 likely
? "bltzl" : "bltz",
1725 macro_build (&icnt
, &offset_expr
,
1726 likely
? "bgtzl" : "bgtz",
1730 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1731 macro_build (&icnt
, &offset_expr
,
1732 likely
? "bnel" : "bne",
1743 macro_build (&icnt
, &offset_expr
,
1744 likely
? "bnel" : "bne",
1748 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1749 macro_build (&icnt
, &offset_expr
,
1750 likely
? "bnel" : "bne",
1766 as_warn ("Divide by zero.");
1767 macro_build (&icnt
, NULL
, "break", "c", 7);
1771 mips_emit_delays ();
1773 macro_build (&icnt
, NULL
,
1774 dbl
? "ddiv" : "div",
1775 "z,s,t", sreg
, treg
);
1776 expr1
.X_add_number
= 8;
1777 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1778 macro_build (&icnt
, NULL
, "nop", "", 0);
1779 macro_build (&icnt
, NULL
, "break", "c", 7);
1780 expr1
.X_add_number
= -1;
1781 macro_build (&icnt
, &expr1
,
1782 dbl
? "daddiu" : "addiu",
1784 expr1
.X_add_number
= dbl
? 20 : 16;
1785 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, AT
);
1788 expr1
.X_add_number
= 1;
1789 macro_build (&icnt
, &expr1
, "daddiu", "t,r,j", AT
, 0);
1790 macro_build (&icnt
, NULL
, "dsll32", "d,w,<", AT
, AT
, 31);
1794 expr1
.X_add_number
= 0x80000000;
1795 macro_build (&icnt
, &expr1
, "lui", "t,u", AT
);
1797 expr1
.X_add_number
= 8;
1798 macro_build (&icnt
, &expr1
, "bne", "s,t,p", sreg
, AT
);
1799 macro_build (&icnt
, NULL
, "nop", "", 0);
1800 macro_build (&icnt
, NULL
, "break", "c", 6);
1802 macro_build (&icnt
, NULL
, s
, "d", dreg
);
1841 if (imm_expr
.X_add_number
== 0)
1843 as_warn ("Divide by zero.");
1844 macro_build (&icnt
, NULL
, "break", "c", 7);
1847 if (imm_expr
.X_add_number
== 1)
1849 if (strcmp (s2
, "mflo") == 0)
1850 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
);
1852 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1855 if (imm_expr
.X_add_number
== -1
1856 && s
[strlen (s
) - 1] != 'u')
1858 if (strcmp (s2
, "mflo") == 0)
1861 macro_build (&icnt
, NULL
, "dneg", "d,w", dreg
, sreg
);
1863 macro_build (&icnt
, NULL
, "neg", "d,w", dreg
, sreg
);
1866 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1870 load_register (&icnt
, AT
, &imm_expr
);
1871 macro_build (&icnt
, NULL
, s
, "z,s,t", sreg
, AT
);
1872 macro_build (&icnt
, NULL
, s2
, "d", dreg
);
1891 mips_emit_delays ();
1893 macro_build (&icnt
, NULL
, s
, "z,s,t", sreg
, treg
);
1894 expr1
.X_add_number
= 8;
1895 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1896 macro_build (&icnt
, NULL
, "nop", "", 0);
1897 macro_build (&icnt
, NULL
, "break", "c", 7);
1899 macro_build (&icnt
, NULL
, s2
, "d", dreg
);
1903 if (offset_expr
.X_op
== O_constant
)
1905 load_register (&icnt
, treg
, &offset_expr
);
1908 if (gp_reference (&offset_expr
))
1909 macro_build (&icnt
, &offset_expr
,
1910 mips_isa
< 3 ? "addiu" : "daddiu",
1914 /* FIXME: This won't work for a 64 bit address. */
1915 macro_build_lui (&icnt
, &offset_expr
, treg
);
1916 macro_build (&icnt
, &offset_expr
,
1917 mips_isa
< 3 ? "addiu" : "daddiu",
1918 "t,r,j", treg
, treg
);
1923 tempreg
= (breg
== treg
) ? AT
: treg
;
1924 if (offset_expr
.X_op
== O_constant
)
1925 load_register (&icnt
, tempreg
, &offset_expr
);
1926 else if (gp_reference (&offset_expr
))
1927 macro_build (&icnt
, &offset_expr
,
1928 mips_isa
< 3 ? "addiu" : "daddiu",
1929 "t,r,j", tempreg
, GP
);
1932 /* FIXME: This won't work for a 64 bit address. */
1933 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1934 macro_build (&icnt
, &offset_expr
,
1935 mips_isa
< 3 ? "addiu" : "daddiu",
1936 "t,r,j", tempreg
, tempreg
);
1939 macro_build (&icnt
, NULL
, "addu", "d,v,t", treg
, tempreg
, breg
);
2009 if (breg
== treg
|| coproc
)
2078 if (mask
== M_LWC1_AB
2079 || mask
== M_SWC1_AB
2081 || mask
== M_LDC1_AB
2082 || mask
== M_SDC1_AB
)
2088 if (gp_reference (&offset_expr
))
2092 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, GP
);
2095 macro_build (&icnt
, (expressionS
*) NULL
,
2096 mips_isa
< 3 ? "addu" : "daddu",
2097 "d,v,t", tempreg
, breg
, GP
);
2101 /* FIXME: This won't work for a 64 bit address. */
2102 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2104 macro_build (&icnt
, NULL
,
2105 mips_isa
< 3 ? "addu" : "daddu",
2106 "d,v,t", tempreg
, tempreg
, breg
);
2108 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, tempreg
);
2115 load_register (&icnt
, treg
, &imm_expr
);
2120 lw $v0,%lo(foo)($at)
2121 lw $v1,%lo(foo+4)($at)
2126 /* FIXME: This won't work for a 64 bit address. */
2127 macro_build_lui (&icnt
, &offset_expr
, AT
);
2129 macro_build (&icnt
, &offset_expr
, "ld", "t,o(b)", treg
, AT
);
2132 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
, AT
);
2133 offset_expr
.X_add_number
+= 4;
2134 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
+ 1, AT
);
2139 /* Load a floating point number from the .lit8 section. */
2142 macro_build (&icnt
, &offset_expr
, "ldc1", "T,o(b)", treg
, GP
);
2148 /* Even on a big endian machine $fn comes before $fn+1. We have
2149 to adjust when loading from memory. */
2150 assert (mips_isa
< 2);
2151 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2152 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2154 offset_expr
.X_add_number
+= 4;
2155 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2156 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2162 * The MIPS assembler seems to check for X_add_number not
2163 * being double aligned and generating:
2166 * addiu at,at,%lo(foo+1)
2169 * But, the resulting address is the same after relocation so why
2170 * generate the extra instruction?
2172 if (gp_reference (&offset_expr
))
2178 macro_build (&icnt
, &offset_expr
,
2179 mips_isa
< 3 ? "addu" : "daddu",
2180 "d,v,t", AT
, breg
, GP
);
2186 /* FIXME: This won't work for a 64 bit address. */
2187 macro_build_lui (&icnt
, &offset_expr
, AT
);
2189 macro_build (&icnt
, NULL
,
2190 mips_isa
< 3 ? "addu" : "daddu",
2191 "d,v,t", AT
, AT
, breg
);
2195 macro_build (&icnt
, &offset_expr
, "ldc1", "T,o(b)", treg
, tempreg
);
2198 /* Even on a big endian machine $fn comes before $fn+1. We
2199 have to adjust when loading from memory. */
2200 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2201 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2203 offset_expr
.X_add_number
+= 4;
2204 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2205 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2218 assert (mips_isa
< 3);
2219 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
2220 offset_expr
.X_add_number
+= 4;
2221 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, breg
);
2244 if (gp_reference (&offset_expr
))
2252 macro_build (&icnt
, (expressionS
*) NULL
,
2253 mips_isa
< 3 ? "addu" : "daddu",
2254 "d,v,t", tempreg
, breg
, GP
);
2258 /* FIXME: This won't work for a 64 bit address. */
2259 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2261 macro_build (&icnt
, NULL
,
2262 mips_isa
< 3 ? "addu" : "daddu",
2263 "d,v,t", tempreg
, tempreg
, breg
);
2266 macro_build (&icnt
, &offset_expr
, s2
, "t,o(b)", treg
, tempreg
);
2269 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, tempreg
);
2270 offset_expr
.X_add_number
+= 4;
2271 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, tempreg
);
2280 macro_build (&icnt
, NULL
,
2281 dbl
? "dmultu" : "multu",
2283 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2289 /* The MIPS assembler some times generates shifts and adds. I'm
2290 not trying to be that fancy. GCC should do this for us
2292 load_register (&icnt
, AT
, &imm_expr
);
2293 macro_build (&icnt
, NULL
,
2294 dbl
? "dmult" : "mult",
2296 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2302 mips_emit_delays ();
2304 macro_build (&icnt
, NULL
,
2305 dbl
? "dmult" : "mult",
2307 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2308 macro_build (&icnt
, NULL
,
2309 dbl
? "dsra32" : "sra",
2310 "d,w,<", dreg
, dreg
, 31);
2311 macro_build (&icnt
, NULL
, "mfhi", "d", AT
);
2312 expr1
.X_add_number
= 8;
2313 macro_build (&icnt
, &expr1
, "beq", "s,t,p", dreg
, AT
);
2314 macro_build (&icnt
, NULL
, "nop", "", 0);
2315 macro_build (&icnt
, NULL
, "break", "c", 6);
2317 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2323 mips_emit_delays ();
2325 macro_build (&icnt
, NULL
,
2326 dbl
? "dmultu" : "multu",
2328 macro_build (&icnt
, NULL
, "mfhi", "d", AT
);
2329 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2330 expr1
.X_add_number
= 8;
2331 macro_build (&icnt
, &expr1
, "beq", "s,t,p", AT
, 0);
2332 macro_build (&icnt
, NULL
, "nop", "", 0);
2333 macro_build (&icnt
, NULL
, "break", "c", 6);
2338 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
2339 macro_build (&icnt
, NULL
, "srlv", "d,t,s", AT
, sreg
, AT
);
2340 macro_build (&icnt
, NULL
, "sllv", "d,t,s", dreg
, sreg
, treg
);
2341 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2345 macro_build (&icnt
, NULL
, "sll", "d,w,<", AT
, sreg
,
2346 imm_expr
.X_add_number
& 0x1f);
2347 macro_build (&icnt
, NULL
, "srl", "d,w,<", dreg
, sreg
,
2348 (0 - imm_expr
.X_add_number
) & 0x1f);
2349 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2353 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
2354 macro_build (&icnt
, NULL
, "sllv", "d,t,s", AT
, sreg
, AT
);
2355 macro_build (&icnt
, NULL
, "srlv", "d,t,s", dreg
, sreg
, treg
);
2356 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2360 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, sreg
,
2361 imm_expr
.X_add_number
& 0x1f);
2362 macro_build (&icnt
, NULL
, "sll", "d,w,<", dreg
, sreg
,
2363 (0 - imm_expr
.X_add_number
) & 0x1f);
2364 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2368 assert (mips_isa
< 2);
2369 /* Even on a big endian machine $fn comes before $fn+1. We have
2370 to adjust when storing to memory. */
2371 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2372 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2374 offset_expr
.X_add_number
+= 4;
2375 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2376 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2381 if (gp_reference (&offset_expr
))
2387 macro_build (&icnt
, (expressionS
*) NULL
,
2388 mips_isa
< 3 ? "addu" : "daddu",
2389 "d,v,t", AT
, breg
, GP
);
2395 /* FIXME: This won't work for a 64 bit address. */
2396 macro_build_lui (&icnt
, &offset_expr
, AT
);
2398 macro_build (&icnt
, NULL
,
2399 mips_isa
< 3 ? "addu" : "daddu",
2400 "d,v,t", AT
, AT
, breg
);
2404 macro_build (&icnt
, &offset_expr
, "sdc1", "T,o(b)", treg
, tempreg
);
2407 /* Even on a big endian machine $fn comes before $fn+1. We
2408 have to adjust when storing to memory. */
2409 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2410 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2412 offset_expr
.X_add_number
+= 4;
2413 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2414 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2423 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, treg
);
2425 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
2428 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
2429 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
2434 if (imm_expr
.X_add_number
== 0)
2436 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
2441 as_warn ("Instruction %s: result is always false",
2443 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
2446 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
2448 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
2451 else if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
< 0)
2453 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2454 macro_build (&icnt
, &imm_expr
,
2455 mips_isa
< 3 ? "addiu" : "daddiu",
2456 "t,r,j", dreg
, sreg
);
2461 load_register (&icnt
, AT
, &imm_expr
);
2462 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
2465 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
2470 case M_SGE
: /* sreg >= treg <==> not (sreg < treg) */
2476 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, sreg
, treg
);
2477 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2480 case M_SGE_I
: /* sreg >= I <==> not (sreg < I) */
2482 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2484 macro_build (&icnt
, &expr1
,
2485 mask
== M_SGE_I
? "slti" : "sltiu",
2486 "t,r,j", dreg
, sreg
);
2491 load_register (&icnt
, AT
, &imm_expr
);
2492 macro_build (&icnt
, NULL
,
2493 mask
== M_SGE_I
? "slt" : "sltu",
2494 "d,v,t", dreg
, sreg
, AT
);
2497 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2502 case M_SGT
: /* sreg > treg <==> treg < sreg */
2508 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
2511 case M_SGT_I
: /* sreg > I <==> I < sreg */
2517 load_register (&icnt
, AT
, &imm_expr
);
2518 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
2521 case M_SLE
: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
2527 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
2528 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2531 case M_SLE_I
: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
2537 load_register (&icnt
, AT
, &imm_expr
);
2538 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
2539 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
2543 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2545 macro_build (&icnt
, &imm_expr
, "slti", "t,r,j", dreg
, sreg
);
2548 load_register (&icnt
, AT
, &imm_expr
);
2549 macro_build (&icnt
, NULL
, "slt", "d,v,t", dreg
, sreg
, AT
);
2553 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2555 macro_build (&icnt
, &imm_expr
, "sltiu", "t,r,j", dreg
, sreg
);
2558 load_register (&icnt
, AT
, &imm_expr
);
2559 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, sreg
, AT
);
2564 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, treg
);
2566 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
2569 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
2570 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
2575 if (imm_expr
.X_add_number
== 0)
2577 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
2582 as_warn ("Instruction %s: result is always true",
2584 macro_build (&icnt
, &expr1
,
2585 mips_isa
< 3 ? "addiu" : "daddiu",
2589 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
2591 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
2594 else if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
< 0)
2596 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2597 macro_build (&icnt
, &imm_expr
,
2598 mips_isa
< 3 ? "addiu" : "daddiu",
2599 "t,r,j", dreg
, sreg
);
2604 load_register (&icnt
, AT
, &imm_expr
);
2605 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
2608 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
2616 if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
<= 0x8000)
2618 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2619 macro_build (&icnt
, &imm_expr
,
2620 dbl
? "daddi" : "addi",
2621 "t,r,j", dreg
, sreg
);
2624 load_register (&icnt
, AT
, &imm_expr
);
2625 macro_build (&icnt
, NULL
,
2626 dbl
? "dsub" : "sub",
2627 "d,v,t", dreg
, sreg
, AT
);
2633 if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
<= 0x8000)
2635 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2636 macro_build (&icnt
, &imm_expr
,
2637 dbl
? "daddiu" : "addiu",
2638 "t,r,j", dreg
, sreg
);
2641 load_register (&icnt
, AT
, &imm_expr
);
2642 macro_build (&icnt
, NULL
,
2643 dbl
? "dsubu" : "subu",
2644 "d,v,t", dreg
, sreg
, AT
);
2665 load_register (&icnt
, AT
, &imm_expr
);
2666 macro_build (&icnt
, NULL
, s
, "s,t", sreg
, AT
);
2671 assert (mips_isa
< 2);
2672 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* floating reg */
2673 dreg
= (ip
->insn_opcode
>> 06) & 0x1f; /* floating reg */
2676 * Is the double cfc1 instruction a bug in the mips assembler;
2677 * or is there a reason for it?
2679 mips_emit_delays ();
2681 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
2682 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
2683 macro_build (&icnt
, NULL
, "nop", "");
2684 expr1
.X_add_number
= 3;
2685 macro_build (&icnt
, &expr1
, "ori", "t,r,i", AT
, treg
);
2686 expr1
.X_add_number
= 2;
2687 macro_build (&icnt
, &expr1
, "xori", "t,r,i", AT
, AT
);
2688 macro_build (&icnt
, NULL
, "ctc1", "t,G", AT
, 31);
2689 macro_build (&icnt
, NULL
, "nop", "");
2690 macro_build (&icnt
, NULL
,
2691 mask
== M_TRUNCWD
? "cvt.w.d" : "cvt.w.s", "D,S", dreg
, sreg
);
2692 macro_build (&icnt
, NULL
, "ctc1", "t,G", treg
, 31);
2693 macro_build (&icnt
, NULL
, "nop", "");
2703 /* avoid load delay */
2704 offset_expr
.X_add_number
+= 1;
2705 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
2706 offset_expr
.X_add_number
-= 1;
2707 macro_build (&icnt
, &offset_expr
, "lbu", "t,o(b)", AT
, breg
);
2708 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2709 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2713 /* does this work on a big endian machine? */
2714 offset_expr
.X_add_number
+= 3;
2715 macro_build (&icnt
, &offset_expr
, "lwl", "t,o(b)", treg
, breg
);
2716 offset_expr
.X_add_number
-= 3;
2717 macro_build (&icnt
, &offset_expr
, "lwr", "t,o(b)", treg
, breg
);
2723 if (offset_expr
.X_op
== O_constant
)
2724 load_register (&icnt
, AT
, &offset_expr
);
2725 else if (gp_reference (&offset_expr
))
2726 macro_build (&icnt
, &offset_expr
,
2727 mips_isa
< 3 ? "addiu" : "daddiu",
2731 /* FIXME: This won't work for a 64 bit address. */
2732 macro_build_lui (&icnt
, &offset_expr
, AT
);
2733 macro_build (&icnt
, &offset_expr
,
2734 mips_isa
< 3 ? "addiu" : "daddiu",
2737 if (mask
== M_ULW_A
)
2739 expr1
.X_add_number
= 3;
2740 macro_build (&icnt
, &expr1
, "lwl", "t,o(b)", treg
, AT
);
2741 imm_expr
.X_add_number
= 0;
2742 macro_build (&icnt
, &expr1
, "lwr", "t,o(b)", treg
, AT
);
2746 macro_build (&icnt
, &expr1
,
2747 mask
== M_ULH_A
? "lb" : "lbu", "t,o(b)", treg
, AT
);
2748 imm_expr
.X_add_number
= 0;
2749 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
2750 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2751 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2756 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", treg
, breg
);
2757 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, treg
, 8);
2758 offset_expr
.X_add_number
+= 1;
2759 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", AT
, breg
);
2763 offset_expr
.X_add_number
+= 3;
2764 macro_build (&icnt
, &offset_expr
, "swl", "t,o(b)", treg
, breg
);
2765 offset_expr
.X_add_number
-= 3;
2766 macro_build (&icnt
, &offset_expr
, "swr", "t,o(b)", treg
, breg
);
2771 if (offset_expr
.X_op
== O_constant
)
2772 load_register (&icnt
, AT
, &offset_expr
);
2773 else if (gp_reference (&offset_expr
))
2774 macro_build (&icnt
, &offset_expr
,
2775 mips_isa
< 3 ? "addiu" : "daddiu",
2779 /* FIXME: This won't work for a 64 bit address. */
2780 macro_build_lui (&icnt
, &offset_expr
, AT
);
2781 macro_build (&icnt
, &offset_expr
,
2782 mips_isa
< 3 ? "addiu" : "daddiu",
2785 if (mask
== M_USW_A
)
2787 expr1
.X_add_number
= 3;
2788 macro_build (&icnt
, &expr1
, "swl", "t,o(b)", treg
, AT
);
2789 expr1
.X_add_number
= 0;
2790 macro_build (&icnt
, &expr1
, "swr", "t,o(b)", treg
, AT
);
2794 expr1
.X_add_number
= 0;
2795 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
2796 macro_build (&icnt
, NULL
, "srl", "d,w,<", treg
, treg
, 8);
2797 expr1
.X_add_number
= 1;
2798 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
2799 expr1
.X_add_number
= 0;
2800 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
2801 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2802 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2807 as_bad ("Macro %s not implemented yet", ip
->insn_mo
->name
);
2811 as_warn ("Macro used $at after \".set noat\"");
2816 This routine assembles an instruction into its binary format. As a side
2817 effect it sets one of the global variables imm_reloc or offset_reloc to the
2818 type of relocation to do if one of the operands is an address expression.
2823 struct mips_cl_insn
*ip
;
2828 struct mips_opcode
*insn
;
2831 unsigned int lastregno
= 0;
2836 for (s
= str
; islower (*s
) || (*s
>= '0' && *s
<= '3') || *s
== '.'; ++s
)
2848 as_warn ("Unknown opcode: `%s'", str
);
2851 if ((insn
= (struct mips_opcode
*) hash_find (op_hash
, str
)) == NULL
)
2853 as_warn ("`%s' not in hash table.", str
);
2854 insn_error
= "ERROR: Unrecognized opcode";
2862 assert (strcmp (insn
->name
, str
) == 0);
2864 if (insn
->pinfo
== INSN_MACRO
)
2865 insn_isa
= insn
->match
;
2866 else if (insn
->pinfo
& INSN_ISA2
)
2868 else if (insn
->pinfo
& INSN_ISA3
)
2873 if (insn_isa
> mips_isa
)
2875 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
]
2876 && strcmp (insn
->name
, insn
[1].name
) == 0)
2881 insn_error
= "ERROR: instruction not supported on this processor";
2886 ip
->insn_opcode
= insn
->match
;
2887 for (args
= insn
->args
;; ++args
)
2893 case '\0': /* end of args */
2906 ip
->insn_opcode
|= lastregno
<< 21;
2911 ip
->insn_opcode
|= lastregno
<< 16;
2915 ip
->insn_opcode
|= lastregno
<< 11;
2921 /* handle optional base register.
2922 Either the base register is omitted or
2923 we must have a left paren. */
2924 /* this is dependent on the next operand specifier
2925 is a 'b' for base register */
2926 assert (args
[1] == 'b');
2930 case ')': /* these must match exactly */
2935 case '<': /* must be at least one digit */
2937 * According to the manual, if the shift amount is greater
2938 * than 31 or less than 0 the the shift amount should be
2939 * mod 32. In reality the mips assembler issues an error.
2940 * We issue a warning and do the mod.
2942 my_getExpression (&imm_expr
, s
);
2943 check_absolute_expr (ip
, &imm_expr
);
2944 if ((unsigned long) imm_expr
.X_add_number
> 31)
2946 as_warn ("Improper shift amount (%ld)",
2947 (long) imm_expr
.X_add_number
);
2948 imm_expr
.X_add_number
= imm_expr
.X_add_number
% 32;
2950 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2951 imm_expr
.X_op
= O_absent
;
2955 case 'c': /* break code */
2956 my_getExpression (&imm_expr
, s
);
2957 check_absolute_expr (ip
, &imm_expr
);
2958 if ((unsigned) imm_expr
.X_add_number
> 1023)
2959 as_warn ("Illegal break code (%ld)",
2960 (long) imm_expr
.X_add_number
);
2961 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 16;
2962 imm_expr
.X_op
= O_absent
;
2966 case 'B': /* syscall code */
2967 my_getExpression (&imm_expr
, s
);
2968 check_absolute_expr (ip
, &imm_expr
);
2969 if ((unsigned) imm_expr
.X_add_number
> 0xfffff)
2970 as_warn ("Illegal syscall code (%ld)",
2971 (long) imm_expr
.X_add_number
);
2972 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2973 imm_expr
.X_op
= O_absent
;
2977 case 'C': /* Coprocessor code */
2978 my_getExpression (&imm_expr
, s
);
2979 check_absolute_expr (ip
, &imm_expr
);
2980 if ((unsigned long) imm_expr
.X_add_number
>= (1<<25))
2982 as_warn ("Coproccesor code > 25 bits (%ld)",
2983 (long) imm_expr
.X_add_number
);
2984 imm_expr
.X_add_number
&= ((1<<25) - 1);
2986 ip
->insn_opcode
|= imm_expr
.X_add_number
;
2987 imm_expr
.X_op
= O_absent
;
2991 case 'b': /* base register */
2992 case 'd': /* destination register */
2993 case 's': /* source register */
2994 case 't': /* target register */
2995 case 'r': /* both target and source */
2996 case 'v': /* both dest and source */
2997 case 'w': /* both dest and target */
2998 case 'E': /* coprocessor target register */
2999 case 'G': /* coprocessor destination register */
3000 case 'x': /* ignore register name */
3001 case 'z': /* must be zero register */
3015 while (isdigit (*s
));
3017 as_bad ("Invalid register number (%d)", regno
);
3019 else if (*args
!= 'E' && *args
!= 'G')
3021 if (s
[1] == 'f' && s
[2] == 'p')
3026 else if (s
[1] == 's' && s
[2] == 'p')
3031 else if (s
[1] == 'g' && s
[2] == 'p')
3036 else if (s
[1] == 'a' && s
[2] == 't')
3043 if (regno
== AT
&& ! mips_noat
)
3044 as_warn ("Used $at without \".set noat\"");
3051 if (c
== 'r' || c
== 'v' || c
== 'w')
3058 /* 'z' only matches $0. */
3059 if (c
== 'z' && regno
!= 0)
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'. */
3088 /* This case is for the div instruction, which
3089 acts differently if the destination argument
3090 is $0. This only matches $0, and is checked
3091 outside the switch. */
3102 ip
->insn_opcode
|= lastregno
<< 21;
3105 ip
->insn_opcode
|= lastregno
<< 16;
3110 case 'D': /* floating point destination register */
3111 case 'S': /* floating point source register */
3112 case 'T': /* floating point target register */
3116 if (s
[0] == '$' && s
[1] == 'f' && isdigit (s
[2]))
3126 while (isdigit (*s
));
3129 as_bad ("Invalid float register number (%d)", regno
);
3132 !(strcmp (str
, "mtc1") == 0 ||
3133 strcmp (str
, "mfc1") == 0 ||
3134 strcmp (str
, "lwc1") == 0 ||
3135 strcmp (str
, "swc1") == 0))
3136 as_warn ("Float register should be even, was %d",
3144 if (c
== 'V' || c
== 'W')
3154 ip
->insn_opcode
|= regno
<< 6;
3158 ip
->insn_opcode
|= regno
<< 11;
3162 ip
->insn_opcode
|= regno
<< 16;
3170 ip
->insn_opcode
|= lastregno
<< 11;
3173 ip
->insn_opcode
|= lastregno
<< 16;
3179 my_getExpression (&imm_expr
, s
);
3180 check_absolute_expr (ip
, &imm_expr
);
3185 my_getExpression (&offset_expr
, s
);
3186 imm_reloc
= BFD_RELOC_32
;
3198 unsigned char temp
[8];
3204 /* These only appear as the last operand in an
3205 instruction, and every instruction that accepts
3206 them in any variant accepts them in all variants.
3207 This means we don't have to worry about backing out
3208 any changes if the instruction does not match.
3210 The difference between them is the size of the
3211 floating point constant and where it goes. For 'F'
3212 and 'L' the constant is 64 bits; for 'f' and 'l' it
3213 is 32 bits. Where the constant is placed is based
3214 on how the MIPS assembler does things:
3217 f -- immediate value
3221 f64
= *args
== 'F' || *args
== 'L';
3223 save_in
= input_line_pointer
;
3224 input_line_pointer
= s
;
3225 err
= md_atof (f64
? 'd' : 'f', (char *) temp
, &length
);
3226 s
= input_line_pointer
;
3227 input_line_pointer
= save_in
;
3228 if (err
!= NULL
&& *err
!= '\0')
3230 as_bad ("Bad floating point constant: %s", err
);
3231 memset (temp
, '\0', sizeof temp
);
3232 length
= f64
? 8 : 4;
3235 assert (length
== (f64
? 8 : 4));
3239 imm_expr
.X_op
= O_constant
;
3240 if (byte_order
== LITTLE_ENDIAN
)
3241 imm_expr
.X_add_number
=
3242 (((((((int) temp
[3] << 8)
3247 imm_expr
.X_add_number
=
3248 (((((((int) temp
[0] << 8)
3255 /* Switch to the right section. */
3257 subseg
= now_subseg
;
3261 subseg_new (".rdata", (subsegT
) 0);
3264 subseg_new (".lit8", (subsegT
) 0);
3267 subseg_new (".lit4", (subsegT
) 0);
3271 as_bad ("Can't use floating point insn in this section");
3273 /* Set the argument to the current address in the
3275 offset_expr
.X_op
= O_symbol
;
3276 offset_expr
.X_add_symbol
=
3277 symbol_new ("L0\001", now_seg
,
3278 (valueT
) frag_now_fix (), frag_now
);
3279 offset_expr
.X_add_number
= 0;
3281 /* Put the floating point number into the section. */
3282 p
= frag_more (length
);
3283 memcpy (p
, temp
, length
);
3285 /* Switch back to the original section. */
3286 subseg_set (seg
, subseg
);
3291 case 'i': /* 16 bit unsigned immediate */
3292 case 'j': /* 16 bit signed immediate */
3293 imm_reloc
= BFD_RELOC_LO16
;
3294 c
= my_getSmallExpression (&imm_expr
, s
);
3299 if (imm_expr
.X_op
== O_constant
)
3300 imm_expr
.X_add_number
=
3301 (imm_expr
.X_add_number
>> 16) & 0xffff;
3303 imm_reloc
= BFD_RELOC_HI16_S
;
3305 imm_reloc
= BFD_RELOC_HI16
;
3309 check_absolute_expr (ip
, &imm_expr
);
3312 if (imm_expr
.X_add_number
< 0
3313 || imm_expr
.X_add_number
>= 0x10000)
3315 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3316 !strcmp (insn
->name
, insn
[1].name
))
3318 as_bad ("16 bit expression not in range 0..65535");
3323 if (imm_expr
.X_add_number
< -0x8000 ||
3324 imm_expr
.X_add_number
>= 0x8000)
3326 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3327 !strcmp (insn
->name
, insn
[1].name
))
3329 as_bad ("16 bit expression not in range -32768..32767");
3335 case 'o': /* 16 bit offset */
3336 c
= my_getSmallExpression (&offset_expr
, s
);
3338 * If this value won't fit into a 16 bit offset, then
3339 * go find a macro that will generate the 32 bit offset
3342 if (offset_expr
.X_op
!= O_constant
3343 || offset_expr
.X_add_number
>= 0x8000
3344 || offset_expr
.X_add_number
< -0x8000)
3347 offset_reloc
= BFD_RELOC_LO16
;
3348 if (c
== 'h' || c
== 'H')
3350 assert (offset_expr
.X_op
== O_constant
);
3351 offset_expr
.X_add_number
=
3352 (offset_expr
.X_add_number
>> 16) & 0xffff;
3357 case 'p': /* pc relative offset */
3358 offset_reloc
= BFD_RELOC_16_PCREL_S2
;
3359 my_getExpression (&offset_expr
, s
);
3363 case 'u': /* upper 16 bits */
3364 c
= my_getSmallExpression (&imm_expr
, s
);
3365 if (imm_expr
.X_op
!= O_constant
3366 || imm_expr
.X_add_number
< 0
3367 || imm_expr
.X_add_number
>= 0x10000)
3368 as_bad ("lui expression not in range 0..65535");
3369 imm_reloc
= BFD_RELOC_LO16
;
3374 if (imm_expr
.X_op
== O_constant
)
3375 imm_expr
.X_add_number
=
3376 (imm_expr
.X_add_number
>> 16) & 0xffff;
3378 imm_reloc
= BFD_RELOC_HI16_S
;
3380 imm_reloc
= BFD_RELOC_HI16
;
3386 case 'a': /* 26 bit address */
3387 my_getExpression (&offset_expr
, s
);
3389 offset_reloc
= BFD_RELOC_MIPS_JMP
;
3393 fprintf (stderr
, "bad char = '%c'\n", *args
);
3398 /* Args don't match. */
3399 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3400 !strcmp (insn
->name
, insn
[1].name
))
3406 insn_error
= "ERROR: Illegal operands";
3415 my_getSmallExpression (ep
, str
)
3426 ((str
[1] == 'h' && str
[2] == 'i')
3427 || (str
[1] == 'H' && str
[2] == 'I')
3428 || (str
[1] == 'l' && str
[2] == 'o'))
3440 * A small expression may be followed by a base register.
3441 * Scan to the end of this operand, and then back over a possible
3442 * base register. Then scan the small expression up to that
3443 * point. (Based on code in sparc.c...)
3445 for (sp
= str
; *sp
&& *sp
!= ','; sp
++)
3447 if (sp
- 4 >= str
&& sp
[-1] == RP
)
3449 if (isdigit (sp
[-2]))
3451 for (sp
-= 3; sp
>= str
&& isdigit (*sp
); sp
--)
3453 if (*sp
== '$' && sp
> str
&& sp
[-1] == LP
)
3459 else if (sp
- 5 >= str
3462 && ((sp
[-3] == 'f' && sp
[-2] == 'p')
3463 || (sp
[-3] == 's' && sp
[-2] == 'p')
3464 || (sp
[-3] == 'g' && sp
[-2] == 'p')
3465 || (sp
[-3] == 'a' && sp
[-2] == 't')))
3471 /* no expression means zero offset */
3474 /* %xx(reg) is an error */
3475 ep
->X_op
= O_absent
;
3480 ep
->X_op
= O_absent
;
3483 ep
->X_add_symbol
= NULL
;
3484 ep
->X_op_symbol
= NULL
;
3485 ep
->X_add_number
= 0;
3490 my_getExpression (ep
, str
);
3497 my_getExpression (ep
, str
);
3498 return c
; /* => %hi or %lo encountered */
3502 my_getExpression (ep
, str
)
3508 save_in
= input_line_pointer
;
3509 input_line_pointer
= str
;
3511 expr_end
= input_line_pointer
;
3512 input_line_pointer
= save_in
;
3515 /* Turn a string in input_line_pointer into a floating point constant
3516 of type type, and store the appropriate bytes in *litP. The number
3517 of LITTLENUMS emitted is stored in *sizeP . An error message is
3518 returned, or NULL on OK. */
3521 md_atof (type
, litP
, sizeP
)
3527 LITTLENUM_TYPE words
[4];
3543 return "bad call to md_atof";
3546 t
= atof_ieee (input_line_pointer
, type
, words
);
3548 input_line_pointer
= t
;
3552 if (byte_order
== LITTLE_ENDIAN
)
3554 for (i
= prec
- 1; i
>= 0; i
--)
3556 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3562 for (i
= 0; i
< prec
; i
++)
3564 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3573 md_number_to_chars (buf
, val
, n
)
3621 md_number_to_chars (buf
, hi
, 4);
3646 md_parse_option (argP
, cntP
, vecP
)
3651 /* Accept -nocpp but ignore it. */
3652 if (strcmp (*argP
, "nocpp") == 0)
3658 if (strcmp (*argP
, "EL") == 0
3659 || strcmp (*argP
, "EB") == 0)
3661 /* FIXME: This breaks -L -EL. */
3669 if ((*argP
)[1] == '0')
3678 if ((*argP
)[1] == '\0' || (*argP
)[1] == '2')
3683 if (strncmp (*argP
, "mips", 4) == 0)
3685 mips_isa
= atol (*argP
+ 4);
3688 else if (mips_isa
< 1 || mips_isa
> 3)
3690 as_bad ("-mips%d not supported", mips_isa
);
3697 if (strncmp (*argP
, "mcpu=", 5) == 0)
3701 /* Identify the processor type */
3703 if (strcmp (p
, "default") == 0
3704 || strcmp (p
, "DEFAULT") == 0)
3708 if (*p
== 'r' || *p
== 'R')
3715 if (strcmp (p
, "2000") == 0
3716 || strcmp (p
, "2k") == 0
3717 || strcmp (p
, "2K") == 0)
3722 if (strcmp (p
, "3000") == 0
3723 || strcmp (p
, "3k") == 0
3724 || strcmp (p
, "3K") == 0)
3729 if (strcmp (p
, "4000") == 0
3730 || strcmp (p
, "4k") == 0
3731 || strcmp (p
, "4K") == 0)
3736 if (strcmp (p
, "6000") == 0
3737 || strcmp (p
, "6k") == 0
3738 || strcmp (p
, "6K") == 0)
3745 as_bad ("bad value (%s) for -mcpu= switch", *argP
+ 5);
3758 if ((*argP
)[1] != '\0')
3759 g_switch_value
= atoi (*argP
+ 1);
3762 **vecP
= (char *) NULL
;
3765 g_switch_value
= atoi (**vecP
);
3768 as_warn ("Number expected after -G");
3774 return 1; /* pretend you parsed the character */
3778 md_pcrel_from (fixP
)
3781 /* return the address of the delay slot */
3782 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
3786 md_apply_fix (fixP
, valueP
)
3793 assert (fixP
->fx_size
== 4);
3796 fixP
->fx_addnumber
= value
; /* Remember value for tc_gen_reloc */
3798 switch (fixP
->fx_r_type
)
3801 case BFD_RELOC_MIPS_JMP
:
3802 case BFD_RELOC_HI16
:
3803 case BFD_RELOC_HI16_S
:
3804 case BFD_RELOC_LO16
:
3805 case BFD_RELOC_MIPS_GPREL
:
3806 /* Nothing needed to do. The value comes from the reloc entry */
3809 case BFD_RELOC_16_PCREL_S2
:
3811 * We need to save the bits in the instruction since fixup_segment()
3812 * might be deleting the relocation entry (i.e., a branch within
3813 * the current segment).
3816 as_warn ("Branch to odd address (%lx)", value
);
3818 if ((value
& ~0xFFFF) && (value
& ~0xFFFF) != (-1 & ~0xFFFF))
3819 as_bad ("Relocation overflow");
3821 /* update old instruction data */
3822 buf
= (unsigned char *) (fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
);
3826 insn
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
3830 insn
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | buf
[3];
3837 insn
|= value
& 0xFFFF;
3838 md_number_to_chars ((char *) buf
, insn
, 4);
3852 const struct mips_opcode
*p
;
3853 int treg
, sreg
, dreg
, shamt
;
3858 for (i
= 0; i
< NUMOPCODES
; ++i
)
3860 p
= &mips_opcodes
[i
];
3861 if (((oc
& p
->mask
) == p
->match
) && (p
->pinfo
!= INSN_MACRO
))
3863 printf ("%08lx %s\t", oc
, p
->name
);
3864 treg
= (oc
>> 16) & 0x1f;
3865 sreg
= (oc
>> 21) & 0x1f;
3866 dreg
= (oc
>> 11) & 0x1f;
3867 shamt
= (oc
>> 6) & 0x1f;
3869 for (args
= p
->args
;; ++args
)
3880 printf ("%c", *args
);
3884 assert (treg
== sreg
);
3885 printf ("$%d,$%d", treg
, sreg
);
3890 printf ("$%d", dreg
);
3895 printf ("$%d", treg
);
3900 printf ("$%d", sreg
);
3904 printf ("0x%08lx", oc
& 0x1ffffff);
3915 printf ("$%d", shamt
);
3926 printf ("%08lx UNDEFINED\n", oc
);
3937 name
= input_line_pointer
;
3938 c
= get_symbol_end ();
3939 p
= (symbolS
*) symbol_find_or_make (name
);
3940 *input_line_pointer
= c
;
3944 /* Align the current frag to a given power of two. The MIPS assembler
3945 also automatically adjusts any preceding label. */
3948 mips_align (to
, fill
)
3952 mips_emit_delays ();
3953 frag_align (to
, fill
);
3954 record_alignment (now_seg
, to
);
3955 if (insn_label
!= NULL
)
3957 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
3958 insn_label
->sy_frag
= frag_now
;
3959 S_SET_VALUE (insn_label
, frag_now_fix ());
3964 /* Align to a given power of two. .align 0 turns off the automatic
3965 alignment used by the data creating pseudo-ops. */
3972 register long temp_fill
;
3973 long max_alignment
= 15;
3977 o Note that the assembler pulls down any immediately preceeding label
3978 to the aligned address.
3979 o It's not documented but auto alignment is reinstated by
3980 a .align pseudo instruction.
3981 o Note also that after auto alignment is turned off the mips assembler
3982 issues an error on attempt to assemble an improperly aligned data item.
3987 temp
= get_absolute_expression ();
3988 if (temp
> max_alignment
)
3989 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
3992 as_warn ("Alignment negative: 0 assumed.");
3995 if (*input_line_pointer
== ',')
3997 input_line_pointer
++;
3998 temp_fill
= get_absolute_expression ();
4005 mips_align (temp
, (int) temp_fill
);
4012 demand_empty_rest_of_line ();
4015 /* Handle .ascii and .asciiz. This just calls stringer and forgets
4016 that there was a previous instruction. */
4019 s_stringer (append_zero
)
4022 mips_emit_delays ();
4024 stringer (append_zero
);
4033 mips_emit_delays ();
4042 subseg_new (".rdata", (subsegT
) get_absolute_expression ());
4043 demand_empty_rest_of_line ();
4052 #ifdef BFD_ASSEMBLER
4053 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
4055 subseg_new (bss_section
, (subsegT
) get_absolute_expression ());
4057 demand_empty_rest_of_line ();
4061 subseg_new (".sdata", (subsegT
) get_absolute_expression ());
4062 demand_empty_rest_of_line ();
4065 as_bad ("Global pointers not supported; recompile -G 0");
4066 demand_empty_rest_of_line ();
4077 mips_emit_delays ();
4078 if (log_size
> 0 && auto_align
)
4079 mips_align (log_size
, 0);
4081 cons (1 << log_size
);
4088 as_fatal ("Encountered `.err', aborting assembly");
4098 symbolP
= get_symbol ();
4099 if (*input_line_pointer
== ',')
4100 input_line_pointer
++;
4101 size
= get_absolute_expression ();
4102 S_SET_VALUE (symbolP
, size
);
4103 S_SET_EXTERNAL (symbolP
);
4106 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
4107 so we use an additional ECOFF specific field. */
4108 symbolP
->ecoff_undefined
= 1;
4116 mips_emit_delays ();
4133 if (strcmp (input_line_pointer
, "O1") != 0
4134 && strcmp (input_line_pointer
, "O2") != 0)
4135 as_warn ("Unrecognized option");
4136 demand_empty_rest_of_line ();
4143 char *name
= input_line_pointer
, ch
;
4145 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4146 input_line_pointer
++;
4147 ch
= *input_line_pointer
;
4148 *input_line_pointer
= '\0';
4150 if (strcmp (name
, "reorder") == 0)
4154 prev_insn_unreordered
= 1;
4155 prev_prev_insn_unreordered
= 1;
4159 else if (strcmp (name
, "noreorder") == 0)
4161 mips_emit_delays ();
4164 else if (strcmp (name
, "at") == 0)
4168 else if (strcmp (name
, "noat") == 0)
4172 else if (strcmp (name
, "macro") == 0)
4174 mips_warn_about_macros
= 0;
4176 else if (strcmp (name
, "nomacro") == 0)
4178 if (mips_noreorder
== 0)
4179 as_bad ("`noreorder' must be set before `nomacro'");
4180 mips_warn_about_macros
= 1;
4182 else if (strcmp (name
, "move") == 0 || strcmp (name
, "novolatile") == 0)
4186 else if (strcmp (name
, "nomove") == 0 || strcmp (name
, "volatile") == 0)
4190 else if (strcmp (name
, "bopt") == 0)
4194 else if (strcmp (name
, "nobopt") == 0)
4200 as_warn ("Tried to set unrecognized symbol: %s\n", name
);
4202 *input_line_pointer
= ch
;
4203 demand_empty_rest_of_line ();
4206 /* The same as the usual .space directive, except that we have to
4207 forget about any previous instruction. */
4210 s_mips_space (param
)
4213 mips_emit_delays ();
4224 if (*input_line_pointer
++ != '$')
4226 as_warn ("expected `$'");
4229 if (isdigit ((unsigned char) *input_line_pointer
))
4231 reg
= get_absolute_expression ();
4232 if (reg
< 0 || reg
>= 32)
4234 as_warn ("Bad register number");
4240 if (strncmp (input_line_pointer
, "fp", 2) == 0)
4242 else if (strncmp (input_line_pointer
, "sp", 2) == 0)
4244 else if (strncmp (input_line_pointer
, "gp", 2) == 0)
4246 else if (strncmp (input_line_pointer
, "at", 2) == 0)
4250 as_warn ("Unrecognized register name");
4253 input_line_pointer
+= 2;
4259 * Translate internal representation of relocation info to BFD target format.
4262 tc_gen_reloc (section
, fixp
)
4268 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
4269 assert (reloc
!= 0);
4271 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
4272 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4273 if (fixp
->fx_pcrel
== 0)
4274 reloc
->addend
= fixp
->fx_addnumber
;
4279 reloc
->addend
= -reloc
->address
;
4281 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4282 assert (reloc
->howto
!= 0);
4287 /* should never be called */
4289 md_section_align (seg
, addr
)
4293 int align
= bfd_get_section_alignment (stdoutput
, seg
);
4295 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
4299 md_estimate_size_before_relax (fragP
, segtype
)
4303 as_fatal ("md_estimate_size_before_relax");
4305 } /* md_estimate_size_before_relax() */
4307 /* This function is called whenever a label is defined. It is used
4308 when handling branch delays; if a branch has a label, we assume we
4312 mips_define_label (sym
)
4320 /* These functions should really be defined by the object file format,
4321 since they are related to debugging information. However, this
4322 code has to work for the a.out format, which does not define them,
4323 so we provide simple versions here. These don't actually generate
4324 any debugging information, but they do simple checking and someday
4325 somebody may make them useful. */
4329 struct loc
*loc_next
;
4330 unsigned long loc_fileno
;
4331 unsigned long loc_lineno
;
4332 unsigned long loc_offset
;
4333 unsigned short loc_delta
;
4334 unsigned short loc_count
;
4343 struct proc
*proc_next
;
4344 struct symbol
*proc_isym
;
4345 struct symbol
*proc_end
;
4346 unsigned long proc_reg_mask
;
4347 unsigned long proc_reg_offset
;
4348 unsigned long proc_fpreg_mask
;
4349 unsigned long proc_fpreg_offset
;
4350 unsigned long proc_frameoffset
;
4351 unsigned long proc_framereg
;
4352 unsigned long proc_pcreg
;
4354 struct file
*proc_file
;
4361 struct file
*file_next
;
4362 unsigned long file_fileno
;
4363 struct symbol
*file_symbol
;
4364 struct symbol
*file_end
;
4365 struct proc
*file_proc
;
4370 static struct obstack proc_frags
;
4371 static procS
*proc_lastP
;
4372 static procS
*proc_rootP
;
4373 static int numprocs
;
4378 obstack_begin (&proc_frags
, 0x2000);
4384 /* check for premature end, nesting errors, etc */
4385 if (proc_lastP
&& proc_lastP
->proc_end
== NULL
)
4386 as_warn ("missing `.end' at end of assembly");
4389 extern char hex_value
[];
4397 if (*input_line_pointer
== '-')
4399 ++input_line_pointer
;
4402 if (!isdigit (*input_line_pointer
))
4403 as_bad ("Expected simple number.");
4404 if (input_line_pointer
[0] == '0')
4406 if (input_line_pointer
[1] == 'x')
4408 input_line_pointer
+= 2;
4409 while (isxdigit (*input_line_pointer
))
4412 val
|= hex_value
[(int) *input_line_pointer
++];
4414 return negative
? -val
: val
;
4418 ++input_line_pointer
;
4419 while (isdigit (*input_line_pointer
))
4422 val
|= *input_line_pointer
++ - '0';
4424 return negative
? -val
: val
;
4427 if (!isdigit (*input_line_pointer
))
4429 printf (" *input_line_pointer == '%c' 0x%02x\n",
4430 *input_line_pointer
, *input_line_pointer
);
4431 as_warn ("Invalid number");
4434 while (isdigit (*input_line_pointer
))
4437 val
+= *input_line_pointer
++ - '0';
4439 return negative
? -val
: val
;
4442 /* The .file directive; just like the usual .file directive, but there
4443 is an initial number which is the ECOFF file index. */
4451 line
= get_number ();
4456 /* The .end directive. */
4464 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4467 demand_empty_rest_of_line ();
4471 if (now_seg
!= text_section
)
4472 as_warn (".end not in text section");
4475 as_warn (".end and no .ent seen yet.");
4481 assert (S_GET_NAME (p
));
4482 if (strcmp (S_GET_NAME (p
), S_GET_NAME (proc_lastP
->proc_isym
)))
4483 as_warn (".end symbol does not match .ent symbol.");
4486 proc_lastP
->proc_end
= (symbolS
*) 1;
4489 /* The .aent and .ent directives. */
4499 symbolP
= get_symbol ();
4500 if (*input_line_pointer
== ',')
4501 input_line_pointer
++;
4502 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4503 number
= get_number ();
4504 if (now_seg
!= text_section
)
4505 as_warn (".ent or .aent not in text section.");
4507 if (!aent
&& proc_lastP
&& proc_lastP
->proc_end
== NULL
)
4508 as_warn ("missing `.end'");
4512 procP
= (procS
*) obstack_alloc (&proc_frags
, sizeof (*procP
));
4513 procP
->proc_isym
= symbolP
;
4514 procP
->proc_reg_mask
= 0;
4515 procP
->proc_reg_offset
= 0;
4516 procP
->proc_fpreg_mask
= 0;
4517 procP
->proc_fpreg_offset
= 0;
4518 procP
->proc_frameoffset
= 0;
4519 procP
->proc_framereg
= 0;
4520 procP
->proc_pcreg
= 0;
4521 procP
->proc_end
= NULL
;
4522 procP
->proc_next
= NULL
;
4524 proc_lastP
->proc_next
= procP
;
4530 demand_empty_rest_of_line ();
4533 /* The .frame directive. */
4546 frame_reg
= tc_get_register ();
4547 if (*input_line_pointer
== ',')
4548 input_line_pointer
++;
4549 frame_off
= get_absolute_expression ();
4550 if (*input_line_pointer
== ',')
4551 input_line_pointer
++;
4552 pcreg
= tc_get_register ();
4555 assert (proc_rootP
);
4556 proc_rootP
->proc_framereg
= frame_reg
;
4557 proc_rootP
->proc_frameoffset
= frame_off
;
4558 proc_rootP
->proc_pcreg
= pcreg
;
4559 /* bob macho .frame */
4561 /* We don't have to write out a frame stab for unoptimized code. */
4562 if (!(frame_reg
== 30 && frame_off
== 0))
4565 as_warn ("No .ent for .frame to use.");
4566 (void) sprintf (str
, "R%d;%d", frame_reg
, frame_off
);
4567 symP
= symbol_new (str
, N_VFP
, 0, frag_now
);
4568 S_SET_TYPE (symP
, N_RMASK
);
4569 S_SET_OTHER (symP
, 0);
4570 S_SET_DESC (symP
, 0);
4571 symP
->sy_forward
= proc_lastP
->proc_isym
;
4572 /* bob perhaps I should have used pseudo set */
4574 demand_empty_rest_of_line ();
4578 /* The .fmask and .mask directives. */
4585 char str
[100], *strP
;
4591 mask
= get_number ();
4592 if (*input_line_pointer
== ',')
4593 input_line_pointer
++;
4594 off
= get_absolute_expression ();
4596 /* bob only for coff */
4597 assert (proc_rootP
);
4598 if (reg_type
== 'F')
4600 proc_rootP
->proc_fpreg_mask
= mask
;
4601 proc_rootP
->proc_fpreg_offset
= off
;
4605 proc_rootP
->proc_reg_mask
= mask
;
4606 proc_rootP
->proc_reg_offset
= off
;
4609 /* bob macho .mask + .fmask */
4611 /* We don't have to write out a mask stab if no saved regs. */
4615 as_warn ("No .ent for .mask to use.");
4617 for (i
= 0; i
< 32; i
++)
4621 sprintf (strP
, "%c%d,", reg_type
, i
);
4622 strP
+= strlen (strP
);
4626 sprintf (strP
, ";%d,", off
);
4627 symP
= symbol_new (str
, N_RMASK
, 0, frag_now
);
4628 S_SET_TYPE (symP
, N_RMASK
);
4629 S_SET_OTHER (symP
, 0);
4630 S_SET_DESC (symP
, 0);
4631 symP
->sy_forward
= proc_lastP
->proc_isym
;
4632 /* bob perhaps I should have used pseudo set */
4637 /* The .loc directive. */
4648 assert (now_seg
== text_section
);
4650 lineno
= get_number ();
4651 addroff
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
4653 symbolP
= symbol_new ("", N_SLINE
, addroff
, frag_now
);
4654 S_SET_TYPE (symbolP
, N_SLINE
);
4655 S_SET_OTHER (symbolP
, 0);
4656 S_SET_DESC (symbolP
, lineno
);
4657 symbolP
->sy_segment
= now_seg
;
4661 #endif /* ! defined (OBJ_ECOFF) */