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"
48 static char *mips_regmask_frag
;
52 #define PIC_CALL_REG 25
58 /* Decide whether to do GP reference optimizations based on the object
68 /* These variables are filled in with the masks of registers used.
69 The object format code reads them and puts them in the appropriate
71 unsigned long mips_gprmask
;
72 unsigned long mips_cprmask
[4];
74 /* MIPS ISA (Instruction Set Architecture) level. */
75 static int mips_isa
= -1;
77 /* MIPS PIC level. 0 is normal, non-PIC code. 2 means to generate
78 SVR4 ABI PIC calls. FIXME: What does 1 mean? I'm using 2 because
79 Irix 5 cc outputs .option pic2. */
82 static int mips_warn_about_macros
;
83 static int mips_noreorder
;
84 static int mips_nomove
;
86 static int mips_nobopt
;
89 /* The size of the small data section. */
90 static int g_switch_value
= 8;
96 /* handle of the OPCODE hash table */
97 static struct hash_control
*op_hash
= NULL
;
99 /* This array holds the chars that always start a comment. If the
100 pre-processor is disabled, these aren't very useful */
101 const char comment_chars
[] = "#";
103 /* This array holds the chars that only start a comment at the beginning of
104 a line. If the line seems to have the form '# 123 filename'
105 .line and .file directives will appear in the pre-processed output */
106 /* Note that input_file.c hand checks for '#' at the beginning of the
107 first line of the input file. This is because the compiler outputs
108 #NO_APP at the beginning of its output. */
109 /* Also note that C style comments are always supported. */
110 const char line_comment_chars
[] = "#";
112 /* This array holds machine specific line separator characters. */
113 const char line_separator_chars
[] = "";
115 /* Chars that can be used to separate mant from exp in floating point nums */
116 const char EXP_CHARS
[] = "eE";
118 /* Chars that mean this number is a floating point constant */
121 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
123 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
124 changed in read.c . Ideally it shouldn't have to know about it at all,
125 but nothing is ideal around here.
128 static char *insn_error
;
130 static int byte_order
= BYTE_ORDER
;
132 static int auto_align
= 1;
134 /* Symbol labelling the current insn. */
135 static symbolS
*insn_label
;
137 /* When outputting SVR4 PIC code, the assembler needs to know the
138 offset in the stack frame from which to restore the $gp register.
139 This is set by the .cprestore pseudo-op, and saved in this
141 static offsetT mips_cprestore_offset
;
143 /* To output NOP instructions correctly, we need to keep information
144 about the previous two instructions. */
146 /* Whether we are optimizing. The default value of 2 means to remove
147 unneeded NOPs and swap branch instructions when possible. A value
148 of 1 means to not swap branches. A value of 0 means to always
150 static int mips_optimize
= 2;
152 /* The previous instruction. */
153 static struct mips_cl_insn prev_insn
;
155 /* The instruction before prev_insn. */
156 static struct mips_cl_insn prev_prev_insn
;
158 /* If we don't want information for prev_insn or prev_prev_insn, we
159 point the insn_mo field at this dummy integer. */
160 static const struct mips_opcode dummy_opcode
= { 0 };
162 /* Non-zero if prev_insn is valid. */
163 static int prev_insn_valid
;
165 /* The frag for the previous instruction. */
166 static struct frag
*prev_insn_frag
;
168 /* The offset into prev_insn_frag for the previous instruction. */
169 static long prev_insn_where
;
171 /* The reloc for the previous instruction, if any. */
172 static fixS
*prev_insn_fixp
;
174 /* Non-zero if the previous instruction was in a delay slot. */
175 static int prev_insn_is_delay_slot
;
177 /* Non-zero if the previous instruction was in a .set noreorder. */
178 static int prev_insn_unreordered
;
180 /* Non-zero if the previous previous instruction was in a .set
182 static int prev_prev_insn_unreordered
;
184 /* Prototypes for static functions. */
187 #define internalError() \
188 as_fatal ("internal Error, line %d, %s", __LINE__, __FILE__)
190 #define internalError() as_fatal ("MIPS internal Error");
193 static int insn_uses_reg
PARAMS ((struct mips_cl_insn
*ip
,
194 unsigned int reg
, int fpr
));
195 static void append_insn
PARAMS ((struct mips_cl_insn
* ip
,
197 bfd_reloc_code_real_type r
));
198 static void mips_no_prev_insn
PARAMS ((void));
199 static void mips_emit_delays
PARAMS ((void));
200 static int gp_reference
PARAMS ((expressionS
* ep
));
201 static void macro_build
PARAMS ((int *counter
, expressionS
* ep
,
202 const char *name
, const char *fmt
,
204 static void macro_build_lui
PARAMS ((int *counter
, expressionS
* ep
,
206 static void set_at
PARAMS ((int *counter
, int reg
, int unsignedp
));
207 static void check_absolute_expr
PARAMS ((struct mips_cl_insn
* ip
,
209 static void load_register
PARAMS ((int *counter
,
210 int reg
, expressionS
* ep
));
211 static void macro
PARAMS ((struct mips_cl_insn
* ip
));
212 static void mips_ip
PARAMS ((char *str
, struct mips_cl_insn
* ip
));
213 static int my_getSmallExpression
PARAMS ((expressionS
* ep
, char *str
));
214 static void my_getExpression
PARAMS ((expressionS
* ep
, char *str
));
215 static symbolS
*get_symbol
PARAMS ((void));
216 static void mips_align
PARAMS ((int to
, int fill
));
217 static void s_align
PARAMS ((int));
218 static void s_stringer
PARAMS ((int));
219 static void s_change_sec
PARAMS ((int));
220 static void s_cons
PARAMS ((int));
221 static void s_err
PARAMS ((int));
222 static void s_extern
PARAMS ((int));
223 static void s_float_cons
PARAMS ((int));
224 static void s_option
PARAMS ((int));
225 static void s_mipsset
PARAMS ((int));
226 static void s_mips_space
PARAMS ((int));
227 static void s_abicalls
PARAMS ((int));
228 static void s_cpload
PARAMS ((int));
229 static void s_cprestore
PARAMS ((int));
231 static void md_obj_begin
PARAMS ((void));
232 static void md_obj_end
PARAMS ((void));
233 static long get_number
PARAMS ((void));
234 static void s_ent
PARAMS ((int));
235 static void s_mipsend
PARAMS ((int));
236 static void s_file
PARAMS ((int));
238 static void s_frame
PARAMS ((int));
239 static void s_loc
PARAMS ((int));
240 static void s_mask
PARAMS ((char));
246 The following pseudo-ops from the Kane and Heinrich MIPS book
247 should be defined here, but are currently unsupported: .alias,
248 .galive, .gjaldef, .gjrlive, .livereg, .noalias.
250 The following pseudo-ops from the Kane and Heinrich MIPS book are
251 specific to the type of debugging information being generated, and
252 should be defined by the object format: .aent, .begin, .bend,
253 .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
256 The following pseudo-ops from the Kane and Heinrich MIPS book are
257 not MIPS CPU specific, but are also not specific to the object file
258 format. This file is probably the best place to define them, but
259 they are not currently supported: .asm0, .endr, .lab, .repeat,
260 .struct, .weakext. */
262 const pseudo_typeS md_pseudo_table
[] =
264 /* MIPS specific pseudo-ops. */
265 {"option", s_option
, 0},
266 {"set", s_mipsset
, 0},
267 {"rdata", s_change_sec
, 'r'},
268 {"sdata", s_change_sec
, 's'},
269 {"livereg", s_ignore
, 0},
270 { "abicalls", s_abicalls
, 0},
271 { "cpload", s_cpload
, 0},
272 { "cprestore", s_cprestore
, 0},
274 /* Relatively generic pseudo-ops that happen to be used on MIPS
276 {"asciiz", s_stringer
, 1},
277 {"bss", s_change_sec
, 'b'},
280 {"dword", s_cons
, 3},
282 /* These pseudo-ops are defined in read.c, but must be overridden
283 here for one reason or another. */
284 {"align", s_align
, 0},
285 {"ascii", s_stringer
, 0},
286 {"asciz", s_stringer
, 1},
288 {"data", s_change_sec
, 'd'},
289 {"double", s_float_cons
, 'd'},
290 {"extern", s_extern
, 0},
291 {"float", s_float_cons
, 'f'},
292 {"space", s_mips_space
, 0},
293 {"text", s_change_sec
, 't'},
297 /* These pseudo-ops should be defined by the object file format.
298 However, ECOFF is the only format which currently defines them,
299 so we have versions here for a.out. */
301 {"bgnb", s_ignore
, 0},
302 {"end", s_mipsend
, 0},
303 {"endb", s_ignore
, 0},
306 {"fmask", s_ignore
, 'F'},
307 {"frame", s_ignore
, 0},
308 {"loc", s_ignore
, 0},
309 {"mask", s_ignore
, 'R'},
310 {"verstamp", s_ignore
, 0},
317 const relax_typeS md_relax_table
[] =
323 static char *expr_end
;
325 static expressionS imm_expr
;
326 static expressionS offset_expr
;
327 static bfd_reloc_code_real_type imm_reloc
;
328 static bfd_reloc_code_real_type offset_reloc
;
330 /* FIXME: This should be handled in a different way. */
331 extern int target_big_endian
;
334 * This function is called once, at assembler startup time. It should
335 * set up all the tables, etc. that the MD part of the assembler will need.
341 register const char *retval
= NULL
;
342 register unsigned int i
= 0;
346 if (strcmp (TARGET_CPU
, "mips") == 0)
348 else if (strcmp (TARGET_CPU
, "r6000") == 0
349 || strcmp (TARGET_CPU
, "mips2") == 0)
351 else if (strcmp (TARGET_CPU
, "mips64") == 0
352 || strcmp (TARGET_CPU
, "r4000") == 0
353 || strcmp (TARGET_CPU
, "mips3") == 0)
362 ok
= bfd_set_arch_mach (stdoutput
, bfd_arch_mips
, 3000);
365 ok
= bfd_set_arch_mach (stdoutput
, bfd_arch_mips
, 6000);
368 ok
= bfd_set_arch_mach (stdoutput
, bfd_arch_mips
, 4000);
372 as_warn ("Could not set architecture and machine");
374 if ((op_hash
= hash_new ()) == NULL
)
376 as_fatal ("Virtual memory exhausted");
378 for (i
= 0; i
< NUMOPCODES
;)
380 const char *name
= mips_opcodes
[i
].name
;
382 retval
= hash_insert (op_hash
, name
, (PTR
) &mips_opcodes
[i
]);
385 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
386 mips_opcodes
[i
].name
, retval
);
387 as_fatal ("Broken assembler. No assembly attempted.");
391 if (mips_opcodes
[i
].pinfo
!= INSN_MACRO
392 && ((mips_opcodes
[i
].match
& mips_opcodes
[i
].mask
)
393 != mips_opcodes
[i
].match
))
395 fprintf (stderr
, "internal error: bad opcode: `%s' \"%s\"\n",
396 mips_opcodes
[i
].name
, mips_opcodes
[i
].args
);
397 as_fatal ("Broken assembler. No assembly attempted.");
401 while ((i
< NUMOPCODES
) && !strcmp (mips_opcodes
[i
].name
, name
));
404 mips_no_prev_insn ();
412 /* set the default alignment for the text section (2**2) */
413 record_alignment (text_section
, 2);
415 /* FIXME: This should be handled in a different way. */
416 target_big_endian
= byte_order
== BIG_ENDIAN
;
419 bfd_set_gp_size (stdoutput
, g_switch_value
);
423 /* Create a .reginfo section for register masks. */
431 regsec
= subseg_new (".reginfo", (subsegT
) 0);
433 /* I don't know why this section should be loaded, but the ABI
434 says that SHF_ALLOC should be set. */
435 bfd_set_section_flags (stdoutput
, regsec
,
436 SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_DATA
);
438 mips_regmask_frag
= frag_more (sizeof (Elf32_External_RegInfo
));
440 subseg_set (seg
, subseg
);
461 struct mips_cl_insn insn
;
463 imm_expr
.X_op
= O_absent
;
464 offset_expr
.X_op
= O_absent
;
466 mips_ip (str
, &insn
);
469 as_bad ("%s `%s'", insn_error
, str
);
472 if (insn
.insn_mo
->pinfo
== INSN_MACRO
)
478 if (imm_expr
.X_op
!= O_absent
)
479 append_insn (&insn
, &imm_expr
, imm_reloc
);
480 else if (offset_expr
.X_op
!= O_absent
)
481 append_insn (&insn
, &offset_expr
, offset_reloc
);
483 append_insn (&insn
, NULL
, BFD_RELOC_UNUSED
);
487 /* See whether instruction IP reads register REG. If FPR is non-zero,
488 REG is a floating point register. */
491 insn_uses_reg (ip
, reg
, fpr
)
492 struct mips_cl_insn
*ip
;
496 /* Don't report on general register 0, since it never changes. */
497 if (! fpr
&& reg
== 0)
502 /* If we are called with either $f0 or $f1, we must check $f0.
503 This is not optimal, because it will introduce an unnecessary
504 NOP between "lwc1 $f0" and "swc1 $f1". To fix this we would
505 need to distinguish reading both $f0 and $f1 or just one of
506 them. Note that we don't have to check the other way,
507 because there is no instruction that sets both $f0 and $f1
508 and requires a delay. */
509 if ((ip
->insn_mo
->pinfo
& INSN_READ_FPR_S
)
510 && (((ip
->insn_opcode
>> OP_SH_FS
) & OP_MASK_FS
)
511 == (reg
&~ (unsigned) 1)))
513 if ((ip
->insn_mo
->pinfo
& INSN_READ_FPR_T
)
514 && (((ip
->insn_opcode
>> OP_SH_FT
) & OP_MASK_FT
)
515 == (reg
&~ (unsigned) 1)))
520 if ((ip
->insn_mo
->pinfo
& INSN_READ_GPR_S
)
521 && ((ip
->insn_opcode
>> OP_SH_RS
) & OP_MASK_RS
) == reg
)
523 if ((ip
->insn_mo
->pinfo
& INSN_READ_GPR_T
)
524 && ((ip
->insn_opcode
>> OP_SH_RT
) & OP_MASK_RT
) == reg
)
531 #define ALIGN_ERR "Attempt to assemble instruction onto non word boundary."
532 #define ALIGN_ERR2 "GAS doesn't do implicit alignment; use .align directive."
536 * Output an instruction.
539 append_insn (ip
, address_expr
, reloc_type
)
540 struct mips_cl_insn
*ip
;
541 expressionS
*address_expr
;
542 bfd_reloc_code_real_type reloc_type
;
544 register unsigned long prev_pinfo
, pinfo
;
549 prev_pinfo
= prev_insn
.insn_mo
->pinfo
;
550 pinfo
= ip
->insn_mo
->pinfo
;
552 if (! mips_noreorder
)
554 /* If the previous insn required any delay slots, see if we need
555 to insert a NOP or two. There are eight kinds of possible
556 hazards, of which an instruction can have at most one type.
557 (1) a load from memory delay
558 (2) a load from a coprocessor delay
559 (3) an unconditional branch delay
560 (4) a conditional branch delay
561 (5) a move to coprocessor register delay
562 (6) a load coprocessor register from memory delay
563 (7) a coprocessor condition code delay
564 (8) a HI/LO special register delay
566 There are a lot of optimizations we could do that we don't.
567 In particular, we do not, in general, reorder instructions.
568 If you use gcc with optimization, it will reorder
569 instructions and generally do much more optimization then we
570 do here; repeating all that work in the assembler would only
571 benefit hand written assembly code, and does not seem worth
574 /* This is how a NOP is emitted. */
575 #define emit_nop() md_number_to_chars (frag_more (4), 0, 4)
577 /* The previous insn might require a delay slot, depending upon
578 the contents of the current insn. */
579 if ((prev_pinfo
& INSN_LOAD_COPROC_DELAY
)
581 && (prev_pinfo
& INSN_LOAD_MEMORY_DELAY
)))
583 /* A load from a coprocessor or from memory. All load
584 delays delay the use of general register rt for one
585 instruction on the r3000. The r6000 and r4000 use
587 know (prev_pinfo
& INSN_WRITE_GPR_T
);
588 if (mips_optimize
== 0
589 || insn_uses_reg (ip
,
590 ((prev_insn
.insn_opcode
>> OP_SH_RT
)
595 else if ((prev_pinfo
& INSN_COPROC_MOVE_DELAY
)
597 && (prev_pinfo
& INSN_COPROC_MEMORY_DELAY
)))
599 /* A generic coprocessor delay. The previous instruction
600 modified a coprocessor general or control register. If
601 it modified a control register, we need to avoid any
602 coprocessor instruction (this is probably not always
603 required, but it sometimes is). If it modified a general
604 register, we avoid using that register.
606 On the r6000 and r4000 loading a coprocessor register
607 from memory is interlocked, and does not require a delay.
609 This case is not handled very well. There is no special
610 knowledge of CP0 handling, and the coprocessors other
611 than the floating point unit are not distinguished at
613 if (prev_pinfo
& INSN_WRITE_FPR_T
)
615 if (mips_optimize
== 0
616 || insn_uses_reg (ip
,
617 ((prev_insn
.insn_opcode
>> OP_SH_FT
)
622 else if (prev_pinfo
& INSN_WRITE_FPR_S
)
624 if (mips_optimize
== 0
625 || insn_uses_reg (ip
,
626 ((prev_insn
.insn_opcode
>> OP_SH_FS
)
633 /* We don't know exactly what the previous instruction
634 does. If the current instruction uses a coprocessor
635 register, we must insert a NOP. If previous
636 instruction may set the condition codes, and the
637 current instruction uses them, we must insert two
639 if (mips_optimize
== 0
640 || ((prev_pinfo
& INSN_WRITE_COND_CODE
)
641 && (pinfo
& INSN_READ_COND_CODE
)))
643 else if (pinfo
& INSN_COP
)
647 else if (prev_pinfo
& INSN_WRITE_COND_CODE
)
649 /* The previous instruction sets the coprocessor condition
650 codes, but does not require a general coprocessor delay
651 (this means it is a floating point comparison
652 instruction). If this instruction uses the condition
653 codes, we need to insert a single NOP. */
654 if (mips_optimize
== 0
655 || (pinfo
& INSN_READ_COND_CODE
))
658 else if (prev_pinfo
& INSN_READ_LO
)
660 /* The previous instruction reads the LO register; if the
661 current instruction writes to the LO register, we must
663 if (mips_optimize
== 0
664 || (pinfo
& INSN_WRITE_LO
))
667 else if (prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
669 /* The previous instruction reads the HI register; if the
670 current instruction writes to the HI register, we must
672 if (mips_optimize
== 0
673 || (pinfo
& INSN_WRITE_HI
))
677 /* There are two cases which require two intervening
678 instructions: 1) setting the condition codes using a move to
679 coprocessor instruction which requires a general coprocessor
680 delay and then reading the condition codes 2) reading the HI
681 or LO register and then writing to it. If we are not already
682 emitting a NOP instruction, we must check for these cases
683 compared to the instruction previous to the previous
686 && (((prev_prev_insn
.insn_mo
->pinfo
& INSN_COPROC_MOVE_DELAY
)
687 && (prev_prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
688 && (pinfo
& INSN_READ_COND_CODE
))
689 || ((prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
)
690 && (pinfo
& INSN_WRITE_LO
))
691 || ((prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
692 && (pinfo
& INSN_WRITE_HI
))))
695 /* Now emit the right number of NOP instructions. */
701 if (insn_label
!= NULL
)
703 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
704 insn_label
->sy_frag
= frag_now
;
705 S_SET_VALUE (insn_label
, (valueT
) frag_now_fix ());
712 /* This is testing the address of the frag, not the alignment of
713 the instruction in the current section. */
721 if (address_expr
!= NULL
)
723 if (address_expr
->X_op
== O_constant
)
728 ip
->insn_opcode
|= address_expr
->X_add_number
;
732 ip
->insn_opcode
|= address_expr
->X_add_number
& 0xffff;
735 case BFD_RELOC_MIPS_JMP
:
736 case BFD_RELOC_16_PCREL_S2
:
745 assert (reloc_type
!= BFD_RELOC_UNUSED
);
747 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 4,
749 reloc_type
== BFD_RELOC_16_PCREL_S2
,
754 md_number_to_chars (f
, ip
->insn_opcode
, 4);
756 /* Update the register mask information. */
757 if (pinfo
& INSN_WRITE_GPR_D
)
758 mips_gprmask
|= 1 << ((ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
);
759 if ((pinfo
& (INSN_WRITE_GPR_T
| INSN_READ_GPR_T
)) != 0)
760 mips_gprmask
|= 1 << ((ip
->insn_opcode
>> OP_SH_RT
) & OP_MASK_RT
);
761 if (pinfo
& INSN_READ_GPR_S
)
762 mips_gprmask
|= 1 << ((ip
->insn_opcode
>> OP_SH_RS
) & OP_MASK_RS
);
763 if (pinfo
& INSN_WRITE_GPR_31
)
764 mips_gprmask
|= 1 << 31;
765 if (pinfo
& INSN_WRITE_FPR_D
)
766 mips_cprmask
[1] |= 1 << ((ip
->insn_opcode
>> OP_SH_FD
) & OP_MASK_FD
);
767 if ((pinfo
& (INSN_WRITE_FPR_S
| INSN_READ_FPR_S
)) != 0)
768 mips_cprmask
[1] |= 1 << ((ip
->insn_opcode
>> OP_SH_FS
) & OP_MASK_FS
);
769 if ((pinfo
& (INSN_WRITE_FPR_T
| INSN_READ_FPR_T
)) != 0)
770 mips_cprmask
[1] |= 1 << ((ip
->insn_opcode
>> OP_SH_FT
) & OP_MASK_FT
);
771 if (pinfo
& INSN_COP
)
773 /* We don't keep enough information to sort these cases out. */
775 /* Never set the bit for $0, which is always zero. */
776 mips_gprmask
&=~ 1 << 0;
778 if (! mips_noreorder
)
780 /* Filling the branch delay slot is more complex. We try to
781 switch the branch with the previous instruction, which we can
782 do if the previous instruction does not set up a condition
783 that the branch tests and if the branch is not itself the
784 target of any branch. */
785 if ((pinfo
& INSN_UNCOND_BRANCH_DELAY
)
786 || (pinfo
& INSN_COND_BRANCH_DELAY
))
788 if (mips_optimize
< 2
789 /* If we have seen .set nobopt, don't optimize. */
791 /* If we have seen .set volatile or .set nomove, don't
794 /* If we had to emit any NOP instructions, then we
795 already know we can not swap. */
797 /* If we don't even know the previous insn, we can not
800 /* If the previous insn is already in a branch delay
801 slot, then we can not swap. */
802 || prev_insn_is_delay_slot
803 /* If the previous previous insn was in a .set
804 noreorder, we can't swap. Actually, the MIPS
805 assembler will swap in this situation. However, gcc
806 configured -with-gnu-as will generate code like
812 in which we can not swap the bne and INSN. If gcc is
813 not configured -with-gnu-as, it does not output the
814 .set pseudo-ops. We don't have to check
815 prev_insn_unreordered, because prev_insn_valid will
816 be 0 in that case. We don't want to use
817 prev_prev_insn_valid, because we do want to be able
818 to swap at the start of a function. */
819 || prev_prev_insn_unreordered
820 /* If the branch is itself the target of a branch, we
821 can not swap. We cheat on this; all we check for is
822 whether there is a label on this instruction. If
823 there are any branches to anything other than a
824 label, users must use .set noreorder. */
825 || insn_label
!= NULL
826 /* If the branch reads the condition codes, we don't
827 even try to swap, because in the sequence
832 we can not swap, and I don't feel like handling that
834 || (pinfo
& INSN_READ_COND_CODE
)
835 /* We can not swap with an instruction that requires a
836 delay slot, becase the target of the branch might
837 interfere with that instruction. */
839 & (INSN_LOAD_COPROC_DELAY
840 | INSN_COPROC_MOVE_DELAY
841 | INSN_WRITE_COND_CODE
846 & (INSN_LOAD_MEMORY_DELAY
847 | INSN_COPROC_MEMORY_DELAY
)))
848 /* We can not swap with a branch instruction. */
850 & (INSN_UNCOND_BRANCH_DELAY
851 | INSN_COND_BRANCH_DELAY
852 | INSN_COND_BRANCH_LIKELY
))
853 /* We do not swap with a trap instruction, since it
854 complicates trap handlers to have the trap
855 instruction be in a delay slot. */
856 || (prev_pinfo
& INSN_TRAP
)
857 /* If the branch reads a register that the previous
858 instruction sets, we can not swap. */
859 || ((prev_pinfo
& INSN_WRITE_GPR_T
)
860 && insn_uses_reg (ip
,
861 ((prev_insn
.insn_opcode
>> OP_SH_RT
)
864 || ((prev_pinfo
& INSN_WRITE_GPR_D
)
865 && insn_uses_reg (ip
,
866 ((prev_insn
.insn_opcode
>> OP_SH_RD
)
869 /* If the branch writes a register that the previous
870 instruction sets, we can not swap (we know that
871 branches write only to RD or to $31). */
872 || ((prev_pinfo
& INSN_WRITE_GPR_T
)
873 && (((pinfo
& INSN_WRITE_GPR_D
)
874 && (((prev_insn
.insn_opcode
>> OP_SH_RT
) & OP_MASK_RT
)
875 == ((ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
)))
876 || ((pinfo
& INSN_WRITE_GPR_31
)
877 && (((prev_insn
.insn_opcode
>> OP_SH_RT
)
880 || ((prev_pinfo
& INSN_WRITE_GPR_D
)
881 && (((pinfo
& INSN_WRITE_GPR_D
)
882 && (((prev_insn
.insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
)
883 == ((ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
)))
884 || ((pinfo
& INSN_WRITE_GPR_31
)
885 && (((prev_insn
.insn_opcode
>> OP_SH_RD
)
888 /* If the branch writes a register that the previous
889 instruction reads, we can not swap (we know that
890 branches only write to RD or to $31). */
891 || ((pinfo
& INSN_WRITE_GPR_D
)
892 && insn_uses_reg (&prev_insn
,
893 ((ip
->insn_opcode
>> OP_SH_RD
)
896 || ((pinfo
& INSN_WRITE_GPR_31
)
897 && insn_uses_reg (&prev_insn
, 31, 0))
898 /* If the previous previous instruction has a load
899 delay, and sets a register that the branch reads, we
901 || (((prev_prev_insn
.insn_mo
->pinfo
& INSN_LOAD_COPROC_DELAY
)
903 && (prev_prev_insn
.insn_mo
->pinfo
904 & INSN_LOAD_MEMORY_DELAY
)))
905 && insn_uses_reg (ip
,
906 ((prev_prev_insn
.insn_opcode
>> OP_SH_RT
)
910 /* We could do even better for unconditional branches to
911 portions of this object file; we could pick up the
912 instruction at the destination, put it in the delay
913 slot, and bump the destination address. */
915 /* Update the previous insn information. */
916 prev_prev_insn
= *ip
;
917 prev_insn
.insn_mo
= &dummy_opcode
;
924 /* It looks like we can actually do the swap. */
925 prev_f
= prev_insn_frag
->fr_literal
+ prev_insn_where
;
926 memcpy (temp
, prev_f
, 4);
927 memcpy (prev_f
, f
, 4);
931 prev_insn_fixp
->fx_frag
= frag_now
;
932 prev_insn_fixp
->fx_where
= f
- frag_now
->fr_literal
;
936 fixp
->fx_frag
= prev_insn_frag
;
937 fixp
->fx_where
= prev_insn_where
;
939 /* Update the previous insn information; leave prev_insn
941 prev_prev_insn
= *ip
;
943 prev_insn_is_delay_slot
= 1;
945 /* If that was an unconditional branch, forget the previous
947 if (pinfo
& INSN_UNCOND_BRANCH_DELAY
)
949 prev_prev_insn
.insn_mo
= &dummy_opcode
;
950 prev_insn
.insn_mo
= &dummy_opcode
;
953 else if (pinfo
& INSN_COND_BRANCH_LIKELY
)
955 /* We don't yet optimize a branch likely. What we should do
956 is look at the target, copy the instruction found there
957 into the delay slot, and increment the branch to jump to
958 the next instruction. */
960 /* Update the previous insn information. */
961 prev_prev_insn
= *ip
;
962 prev_insn
.insn_mo
= &dummy_opcode
;
966 /* Update the previous insn information. */
968 prev_prev_insn
.insn_mo
= &dummy_opcode
;
970 prev_prev_insn
= prev_insn
;
973 /* Any time we see a branch, we always fill the delay slot
974 immediately; since this insn is not a branch, we know it
975 is not in a delay slot. */
976 prev_insn_is_delay_slot
= 0;
979 prev_prev_insn_unreordered
= prev_insn_unreordered
;
980 prev_insn_unreordered
= 0;
981 prev_insn_frag
= frag_now
;
982 prev_insn_where
= f
- frag_now
->fr_literal
;
983 prev_insn_fixp
= fixp
;
987 /* We just output an insn, so the next one doesn't have a label. */
991 /* This function forgets that there was any previous instruction or
997 prev_insn
.insn_mo
= &dummy_opcode
;
998 prev_prev_insn
.insn_mo
= &dummy_opcode
;
1000 prev_insn_is_delay_slot
= 0;
1001 prev_insn_unreordered
= 0;
1002 prev_prev_insn_unreordered
= 0;
1006 /* This function must be called whenever we turn on noreorder or emit
1007 something other than instructions. It inserts any NOPS which might
1008 be needed by the previous instruction, and clears the information
1009 kept for the previous instructions. */
1014 if (! mips_noreorder
)
1019 if ((prev_insn
.insn_mo
->pinfo
1020 & (INSN_LOAD_COPROC_DELAY
1021 | INSN_COPROC_MOVE_DELAY
1022 | INSN_WRITE_COND_CODE
1026 && (prev_insn
.insn_mo
->pinfo
1027 & (INSN_LOAD_MEMORY_DELAY
1028 | INSN_COPROC_MEMORY_DELAY
))))
1031 if ((prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
1032 || (prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
1033 || (prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
))
1036 else if ((prev_prev_insn
.insn_mo
->pinfo
& INSN_WRITE_COND_CODE
)
1037 || (prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_HI
)
1038 || (prev_prev_insn
.insn_mo
->pinfo
& INSN_READ_LO
))
1043 if (insn_label
!= NULL
)
1045 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
1046 insn_label
->sy_frag
= frag_now
;
1047 S_SET_VALUE (insn_label
, (valueT
) frag_now_fix ());
1050 mips_no_prev_insn ();
1054 /* Return 1 if an expression can be accessed via the GP register. */
1062 const char *symname
;
1063 const char *segname
;
1065 sym
= ep
->X_add_symbol
;
1066 if (sym
== (symbolS
*) NULL
1067 || ep
->X_op_symbol
!= (symbolS
*) NULL
)
1070 /* Certain symbols can not be referenced off the GP, although it
1071 appears as though they can. */
1072 symname
= S_GET_NAME (sym
);
1073 if (symname
!= (const char *) NULL
1074 && (strcmp (symname
, "eprol") == 0
1075 || strcmp (symname
, "etext") == 0
1076 || strcmp (symname
, "_gp") == 0
1077 || strcmp (symname
, "edata") == 0
1078 || strcmp (symname
, "_fbss") == 0
1079 || strcmp (symname
, "_fdata") == 0
1080 || strcmp (symname
, "_ftext") == 0
1081 || strcmp (symname
, "end") == 0
1082 || strcmp (symname
, "_gp_disp") == 0))
1084 if (! S_IS_DEFINED (sym
)
1085 && S_GET_VALUE (sym
) != 0
1086 && S_GET_VALUE (sym
) <= g_switch_value
)
1088 segname
= segment_name (S_GET_SEGMENT (ep
->X_add_symbol
));
1089 return (strcmp (segname
, ".sdata") == 0
1090 || strcmp (segname
, ".sbss") == 0
1091 || strcmp (segname
, ".lit8") == 0
1092 || strcmp (segname
, ".lit4") == 0);
1093 #else /* ! defined (GPOPT) */
1094 /* We are not optimizing for the GP register. */
1096 #endif /* ! defined (GPOPT) */
1099 /* Build an instruction created by a macro expansion. This is passed
1100 a pointer to the count of instructions created so far, an
1101 expression, the name of the instruction to build, an operand format
1102 string, and corresponding arguments. */
1106 macro_build (int *counter
,
1111 #else /* ! defined (NO_STDARG) */
1113 macro_build (counter
, ep
, name
, fmt
, va_alist
)
1119 #endif /* ! defined (NO_STDARG) */
1121 struct mips_cl_insn insn
;
1122 bfd_reloc_code_real_type r
;
1126 va_start (args
, fmt
);
1132 * If the macro is about to expand into a second instruction,
1133 * print a warning if needed. We need to pass ip as a parameter
1134 * to generate a better warning message here...
1136 if (mips_warn_about_macros
&& *counter
== 1)
1137 as_warn ("Macro instruction expanded into multiple instructions");
1139 *counter
+= 1; /* bump instruction counter */
1141 r
= BFD_RELOC_UNUSED
;
1142 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
1143 assert (insn
.insn_mo
);
1144 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1146 while (strcmp (fmt
, insn
.insn_mo
->args
) != 0
1147 || insn
.insn_mo
->pinfo
== INSN_MACRO
)
1150 assert (insn
.insn_mo
->name
);
1151 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1153 insn
.insn_opcode
= insn
.insn_mo
->match
;
1169 insn
.insn_opcode
|= va_arg (args
, int) << 16;
1175 insn
.insn_opcode
|= va_arg (args
, int) << 16;
1180 insn
.insn_opcode
|= va_arg (args
, int) << 11;
1185 insn
.insn_opcode
|= va_arg (args
, int) << 11;
1192 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1196 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1200 insn
.insn_opcode
|= va_arg (args
, int) << 6;
1207 insn
.insn_opcode
|= va_arg (args
, int) << 21;
1213 assert (ep
!= NULL
);
1214 r
= (bfd_reloc_code_real_type
) va_arg (args
, int);
1215 assert (ep
->X_op
== O_constant
|| ! gp_reference (ep
)
1216 ? r
== BFD_RELOC_LO16
|| r
== BFD_RELOC_MIPS_CALL16
1217 : r
== BFD_RELOC_MIPS_GPREL
|| r
== BFD_RELOC_MIPS_LITERAL
);
1221 assert (ep
!= NULL
&& ep
->X_op
== O_constant
);
1222 insn
.insn_opcode
|= (ep
->X_add_number
>> 16) & 0xffff;
1227 assert (ep
!= NULL
);
1229 * This allows macro() to pass an immediate expression for
1230 * creating short branches without creating a symbol.
1231 * Note that the expression still might come from the assembly
1232 * input, in which case the value is not checked for range nor
1233 * is a relocation entry generated (yuck).
1235 if (ep
->X_op
== O_constant
)
1237 insn
.insn_opcode
|= (ep
->X_add_number
>> 2) & 0xffff;
1241 r
= BFD_RELOC_16_PCREL_S2
;
1245 assert (ep
!= NULL
);
1246 r
= BFD_RELOC_MIPS_JMP
;
1255 assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
1257 append_insn (&insn
, ep
, r
);
1261 * Generate a "lui" instruction.
1264 macro_build_lui (counter
, ep
, regnum
)
1269 expressionS high_expr
;
1270 struct mips_cl_insn insn
;
1271 bfd_reloc_code_real_type r
;
1272 CONST
char *name
= "lui";
1273 CONST
char *fmt
= "t,u";
1277 if (high_expr
.X_op
== O_constant
)
1279 /* we can compute the instruction now without a relocation entry */
1280 if (high_expr
.X_add_number
& 0x8000)
1281 high_expr
.X_add_number
+= 0x10000;
1282 high_expr
.X_add_number
=
1283 ((unsigned long) high_expr
.X_add_number
>> 16) & 0xffff;
1284 r
= BFD_RELOC_UNUSED
;
1287 r
= BFD_RELOC_HI16_S
;
1290 * If the macro is about to expand into a second instruction,
1291 * print a warning if needed. We need to pass ip as a parameter
1292 * to generate a better warning message here...
1294 if (mips_warn_about_macros
&& *counter
== 1)
1295 as_warn ("Macro instruction expanded into multiple instructions");
1297 *counter
+= 1; /* bump instruction counter */
1299 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
1300 assert (insn
.insn_mo
);
1301 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
1302 assert (strcmp (fmt
, insn
.insn_mo
->args
) == 0);
1304 insn
.insn_opcode
= insn
.insn_mo
->match
| (regnum
<< 16);
1305 if (r
== BFD_RELOC_UNUSED
)
1307 insn
.insn_opcode
|= high_expr
.X_add_number
;
1308 append_insn (&insn
, NULL
, r
);
1311 append_insn (&insn
, &high_expr
, r
);
1315 * Generates code to set the $at register to true (one)
1316 * if reg is less than the immediate expression.
1319 set_at (counter
, reg
, unsignedp
)
1324 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
1325 macro_build (counter
, &imm_expr
,
1326 unsignedp
? "sltiu" : "slti",
1327 "t,r,j", AT
, reg
, (int) BFD_RELOC_LO16
);
1330 load_register (counter
, AT
, &imm_expr
);
1331 macro_build (counter
, NULL
,
1332 unsignedp
? "sltu" : "slt",
1333 "d,v,t", AT
, reg
, AT
);
1337 /* Warn if an expression is not a constant. */
1340 check_absolute_expr (ip
, ex
)
1341 struct mips_cl_insn
*ip
;
1344 if (ex
->X_op
!= O_constant
)
1345 as_warn ("Instruction %s requires absolute expression", ip
->insn_mo
->name
);
1349 * This routine generates the least number of instructions neccessary to load
1350 * an absolute expression value into a register.
1353 load_register (counter
, reg
, ep
)
1358 assert (ep
->X_op
== O_constant
);
1359 if (ep
->X_add_number
>= -0x8000 && ep
->X_add_number
< 0x8000)
1360 macro_build (counter
, ep
,
1361 mips_isa
< 3 ? "addiu" : "daddiu",
1362 "t,r,j", reg
, 0, (int) BFD_RELOC_LO16
);
1363 else if (ep
->X_add_number
>= 0 && ep
->X_add_number
< 0x10000)
1364 macro_build (counter
, ep
, "ori", "t,r,i", reg
, 0, (int) BFD_RELOC_LO16
);
1365 else if ((ep
->X_add_number
&~ (offsetT
) 0x7fffffff) == 0
1366 || ((ep
->X_add_number
&~ (offsetT
) 0x7fffffff)
1367 == ~ (offsetT
) 0x7fffffff))
1369 macro_build (counter
, ep
, "lui", "t,u", reg
);
1370 if ((ep
->X_add_number
& 0xffff) != 0)
1371 macro_build (counter
, ep
, "ori", "t,r,i", reg
, reg
,
1372 (int) BFD_RELOC_LO16
);
1374 else if (mips_isa
< 3)
1376 as_bad ("Number larger than 32 bits");
1377 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, 0,
1378 (int) BFD_RELOC_LO16
);
1383 expressionS hi32
, lo32
;
1387 hi32
.X_add_number
>>= shift
;
1388 hi32
.X_add_number
&= 0xffffffff;
1389 if ((hi32
.X_add_number
& 0x80000000) != 0)
1390 hi32
.X_add_number
|= ~ (offsetT
) 0xffffffff;
1391 load_register (counter
, reg
, &hi32
);
1393 lo32
.X_add_number
&= 0xffffffff;
1394 if ((lo32
.X_add_number
& 0xffff0000) == 0)
1395 macro_build (counter
, NULL
, "dsll32", "d,w,<", reg
, reg
, 0);
1400 macro_build (counter
, NULL
, "dsll", "d,w,<", reg
, reg
, 16);
1402 mid16
.X_add_number
>>= 16;
1403 macro_build (counter
, &mid16
, "ori", "t,r,i", reg
, reg
,
1404 (int) BFD_RELOC_LO16
);
1405 macro_build (counter
, NULL
, "dsll", "d,w,<", reg
, reg
, 16);
1407 if ((lo32
.X_add_number
& 0xffff) != 0)
1408 macro_build (counter
, &lo32
, "ori", "t,r,i", reg
, reg
,
1409 (int) BFD_RELOC_LO16
);
1415 * This routine implements the seemingly endless macro or synthesized
1416 * instructions and addressing modes in the mips assembly language. Many
1417 * of these macros are simple and are similar to each other. These could
1418 * probably be handled by some kind of table or grammer aproach instead of
1419 * this verbose method. Others are not simple macros but are more like
1420 * optimizing code generation.
1421 * One interesting optimization is when several store macros appear
1422 * consecutivly that would load AT with the upper half of the same address.
1423 * The ensuing load upper instructions are ommited. This implies some kind
1424 * of global optimization. We currently only optimize within a single macro.
1425 * For many of the load and store macros if the address is specified as a
1426 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
1427 * first load register 'at' with zero and use it as the base register. The
1428 * mips assembler simply uses register $zero. Just one tiny optimization
1433 struct mips_cl_insn
*ip
;
1435 register int treg
, sreg
, dreg
, breg
;
1448 bfd_reloc_code_real_type r
;
1450 treg
= (ip
->insn_opcode
>> 16) & 0x1f;
1451 dreg
= (ip
->insn_opcode
>> 11) & 0x1f;
1452 sreg
= breg
= (ip
->insn_opcode
>> 21) & 0x1f;
1453 mask
= ip
->insn_mo
->mask
;
1455 expr1
.X_op
= O_constant
;
1456 expr1
.X_op_symbol
= NULL
;
1457 expr1
.X_add_symbol
= NULL
;
1458 expr1
.X_add_number
= 1;
1470 mips_emit_delays ();
1473 expr1
.X_add_number
= 8;
1474 macro_build (&icnt
, &expr1
, "bgez", "s,p", sreg
);
1476 macro_build (&icnt
, NULL
, "nop", "", 0);
1478 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
, 0);
1479 macro_build (&icnt
, NULL
,
1480 dbl
? "dsub" : "sub",
1481 "d,v,t", dreg
, 0, sreg
);
1504 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
1506 macro_build (&icnt
, &imm_expr
, s
, "t,r,j", treg
, sreg
,
1507 (int) BFD_RELOC_LO16
);
1510 load_register (&icnt
, AT
, &imm_expr
);
1511 macro_build (&icnt
, NULL
, s2
, "d,v,t", treg
, sreg
, AT
);
1530 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
1532 if (mask
!= M_NOR_I
)
1533 macro_build (&icnt
, &imm_expr
, s
, "t,r,i", treg
, sreg
,
1534 (int) BFD_RELOC_LO16
);
1537 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
,
1538 (int) BFD_RELOC_LO16
);
1539 macro_build (&icnt
, &imm_expr
, "nor", "d,v,t", treg
, treg
, 0);
1544 load_register (&icnt
, AT
, &imm_expr
);
1545 macro_build (&icnt
, NULL
, s2
, "d,v,t", treg
, sreg
, AT
);
1562 if (imm_expr
.X_add_number
== 0)
1564 macro_build (&icnt
, &offset_expr
, s
, "s,t,p", sreg
, 0);
1567 load_register (&icnt
, AT
, &imm_expr
);
1568 macro_build (&icnt
, &offset_expr
, s
, "s,t,p", sreg
, AT
);
1576 macro_build (&icnt
, &offset_expr
,
1577 likely
? "bgezl" : "bgez",
1583 macro_build (&icnt
, &offset_expr
,
1584 likely
? "blezl" : "blez",
1588 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1589 macro_build (&icnt
, &offset_expr
,
1590 likely
? "beql" : "beq",
1597 /* check for > max integer */
1598 maxnum
= 0x7fffffff;
1606 if (imm_expr
.X_add_number
>= maxnum
)
1609 /* result is always false */
1612 as_warn ("Branch %s is always false (nop)", ip
->insn_mo
->name
);
1613 macro_build (&icnt
, NULL
, "nop", "", 0);
1617 as_warn ("Branch likely %s is always false", ip
->insn_mo
->name
);
1618 macro_build (&icnt
, &offset_expr
, "bnel", "s,t,p", 0, 0);
1622 imm_expr
.X_add_number
++;
1626 if (mask
== M_BGEL_I
)
1628 if (imm_expr
.X_add_number
== 0)
1630 macro_build (&icnt
, &offset_expr
,
1631 likely
? "bgezl" : "bgez",
1635 if (imm_expr
.X_add_number
== 1)
1637 macro_build (&icnt
, &offset_expr
,
1638 likely
? "bgtzl" : "bgtz",
1642 maxnum
= 0x7fffffff;
1650 maxnum
= - maxnum
- 1;
1651 if (imm_expr
.X_add_number
<= maxnum
)
1654 /* result is always true */
1655 as_warn ("Branch %s is always true", ip
->insn_mo
->name
);
1656 macro_build (&icnt
, &offset_expr
, "b", "p");
1659 set_at (&icnt
, sreg
, 0);
1660 macro_build (&icnt
, &offset_expr
,
1661 likely
? "beql" : "beq",
1672 macro_build (&icnt
, &offset_expr
,
1673 likely
? "beql" : "beq",
1677 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1678 macro_build (&icnt
, &offset_expr
,
1679 likely
? "beql" : "beq",
1686 if (sreg
== 0 || imm_expr
.X_add_number
== -1)
1688 imm_expr
.X_add_number
++;
1692 if (mask
== M_BGEUL_I
)
1694 if (imm_expr
.X_add_number
== 0)
1696 if (imm_expr
.X_add_number
== 1)
1698 macro_build (&icnt
, &offset_expr
,
1699 likely
? "bnel" : "bne",
1703 set_at (&icnt
, sreg
, 1);
1704 macro_build (&icnt
, &offset_expr
,
1705 likely
? "beql" : "beq",
1714 macro_build (&icnt
, &offset_expr
,
1715 likely
? "bgtzl" : "bgtz",
1721 macro_build (&icnt
, &offset_expr
,
1722 likely
? "bltzl" : "bltz",
1726 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1727 macro_build (&icnt
, &offset_expr
,
1728 likely
? "bnel" : "bne",
1737 macro_build (&icnt
, &offset_expr
,
1738 likely
? "bnel" : "bne",
1744 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1745 macro_build (&icnt
, &offset_expr
,
1746 likely
? "bnel" : "bne",
1755 macro_build (&icnt
, &offset_expr
,
1756 likely
? "blezl" : "blez",
1762 macro_build (&icnt
, &offset_expr
,
1763 likely
? "bgezl" : "bgez",
1767 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1768 macro_build (&icnt
, &offset_expr
,
1769 likely
? "beql" : "beq",
1776 maxnum
= 0x7fffffff;
1784 if (imm_expr
.X_add_number
>= maxnum
)
1786 imm_expr
.X_add_number
++;
1790 if (mask
== M_BLTL_I
)
1792 if (imm_expr
.X_add_number
== 0)
1794 macro_build (&icnt
, &offset_expr
,
1795 likely
? "bltzl" : "bltz",
1799 if (imm_expr
.X_add_number
== 1)
1801 macro_build (&icnt
, &offset_expr
,
1802 likely
? "blezl" : "blez",
1806 set_at (&icnt
, sreg
, 0);
1807 macro_build (&icnt
, &offset_expr
,
1808 likely
? "bnel" : "bne",
1817 macro_build (&icnt
, &offset_expr
,
1818 likely
? "beql" : "beq",
1824 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1825 macro_build (&icnt
, &offset_expr
,
1826 likely
? "beql" : "beq",
1833 if (sreg
== 0 || imm_expr
.X_add_number
== -1)
1835 imm_expr
.X_add_number
++;
1839 if (mask
== M_BLTUL_I
)
1841 if (imm_expr
.X_add_number
== 0)
1843 if (imm_expr
.X_add_number
== 1)
1845 macro_build (&icnt
, &offset_expr
,
1846 likely
? "beql" : "beq",
1850 set_at (&icnt
, sreg
, 1);
1851 macro_build (&icnt
, &offset_expr
,
1852 likely
? "bnel" : "bne",
1861 macro_build (&icnt
, &offset_expr
,
1862 likely
? "bltzl" : "bltz",
1868 macro_build (&icnt
, &offset_expr
,
1869 likely
? "bgtzl" : "bgtz",
1873 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1874 macro_build (&icnt
, &offset_expr
,
1875 likely
? "bnel" : "bne",
1886 macro_build (&icnt
, &offset_expr
,
1887 likely
? "bnel" : "bne",
1891 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1892 macro_build (&icnt
, &offset_expr
,
1893 likely
? "bnel" : "bne",
1909 as_warn ("Divide by zero.");
1910 macro_build (&icnt
, NULL
, "break", "c", 7);
1914 mips_emit_delays ();
1916 macro_build (&icnt
, NULL
,
1917 dbl
? "ddiv" : "div",
1918 "z,s,t", sreg
, treg
);
1919 expr1
.X_add_number
= 8;
1920 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1921 macro_build (&icnt
, NULL
, "nop", "", 0);
1922 macro_build (&icnt
, NULL
, "break", "c", 7);
1923 expr1
.X_add_number
= -1;
1924 macro_build (&icnt
, &expr1
,
1925 dbl
? "daddiu" : "addiu",
1926 "t,r,j", AT
, 0, (int) BFD_RELOC_LO16
);
1927 expr1
.X_add_number
= dbl
? 20 : 16;
1928 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, AT
);
1931 expr1
.X_add_number
= 1;
1932 macro_build (&icnt
, &expr1
, "daddiu", "t,r,j", AT
, 0,
1933 (int) BFD_RELOC_LO16
);
1934 macro_build (&icnt
, NULL
, "dsll32", "d,w,<", AT
, AT
, 31);
1938 expr1
.X_add_number
= 0x80000000;
1939 macro_build (&icnt
, &expr1
, "lui", "t,u", AT
);
1941 expr1
.X_add_number
= 8;
1942 macro_build (&icnt
, &expr1
, "bne", "s,t,p", sreg
, AT
);
1943 macro_build (&icnt
, NULL
, "nop", "", 0);
1944 macro_build (&icnt
, NULL
, "break", "c", 6);
1946 macro_build (&icnt
, NULL
, s
, "d", dreg
);
1985 if (imm_expr
.X_add_number
== 0)
1987 as_warn ("Divide by zero.");
1988 macro_build (&icnt
, NULL
, "break", "c", 7);
1991 if (imm_expr
.X_add_number
== 1)
1993 if (strcmp (s2
, "mflo") == 0)
1994 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
);
1996 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1999 if (imm_expr
.X_add_number
== -1
2000 && s
[strlen (s
) - 1] != 'u')
2002 if (strcmp (s2
, "mflo") == 0)
2005 macro_build (&icnt
, NULL
, "dneg", "d,w", dreg
, sreg
);
2007 macro_build (&icnt
, NULL
, "neg", "d,w", dreg
, sreg
);
2010 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
2014 load_register (&icnt
, AT
, &imm_expr
);
2015 macro_build (&icnt
, NULL
, s
, "z,s,t", sreg
, AT
);
2016 macro_build (&icnt
, NULL
, s2
, "d", dreg
);
2035 mips_emit_delays ();
2037 macro_build (&icnt
, NULL
, s
, "z,s,t", sreg
, treg
);
2038 expr1
.X_add_number
= 8;
2039 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
2040 macro_build (&icnt
, NULL
, "nop", "", 0);
2041 macro_build (&icnt
, NULL
, "break", "c", 7);
2043 macro_build (&icnt
, NULL
, s2
, "d", dreg
);
2047 if (offset_expr
.X_op
== O_constant
)
2049 load_register (&icnt
, treg
, &offset_expr
);
2052 if (gp_reference (&offset_expr
))
2053 macro_build (&icnt
, &offset_expr
,
2054 mips_isa
< 3 ? "addiu" : "daddiu",
2055 "t,r,j", treg
, GP
, (int) BFD_RELOC_MIPS_GPREL
);
2058 /* FIXME: This won't work for a 64 bit address. */
2059 macro_build_lui (&icnt
, &offset_expr
, treg
);
2060 macro_build (&icnt
, &offset_expr
,
2061 mips_isa
< 3 ? "addiu" : "daddiu",
2062 "t,r,j", treg
, treg
, (int) BFD_RELOC_LO16
);
2067 tempreg
= (breg
== treg
) ? AT
: treg
;
2068 if (offset_expr
.X_op
== O_constant
)
2069 load_register (&icnt
, tempreg
, &offset_expr
);
2070 else if (gp_reference (&offset_expr
))
2071 macro_build (&icnt
, &offset_expr
,
2072 mips_isa
< 3 ? "addiu" : "daddiu",
2073 "t,r,j", tempreg
, GP
, (int) BFD_RELOC_MIPS_GPREL
);
2076 /* FIXME: This won't work for a 64 bit address. */
2077 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2078 macro_build (&icnt
, &offset_expr
,
2079 mips_isa
< 3 ? "addiu" : "daddiu",
2080 "t,r,j", tempreg
, tempreg
,
2081 (int) BFD_RELOC_LO16
);
2084 macro_build (&icnt
, NULL
, "addu", "d,v,t", treg
, tempreg
, breg
);
2089 /* The jal instructions must be handled as macros because when
2090 generating PIC code they expand to multi-instruction
2091 sequences. Normally they are simple instructions. */
2098 macro_build (&icnt
, (expressionS
*) NULL
, "jalr", "d,s",
2103 /* I only know how to handle pic2. */
2104 assert (mips_pic
== 2);
2106 if (dreg
!= PIC_CALL_REG
)
2107 as_warn ("MIPS PIC call to register other than $25");
2109 macro_build (&icnt
, (expressionS
*) NULL
, "jalr", "d,s",
2111 expr1
.X_add_number
= mips_cprestore_offset
;
2112 macro_build (&icnt
, &expr1
,
2113 mips_isa
< 3 ? "lw" : "ld",
2114 "t,o(b)", GP
, (int) BFD_RELOC_LO16
, SP
);
2120 macro_build (&icnt
, &offset_expr
, "jal", "a");
2124 /* I only know how to handle pic2. */
2125 assert (mips_pic
== 2);
2127 /* We turn this into
2130 lw $gp,cprestore($sp)
2131 The %call16 generates the R_MIPS_CALL16 reloc. See the MIPS
2132 ABI. The cprestore value is set using the .cprestore
2134 macro_build (&icnt
, &offset_expr
,
2135 mips_isa
< 3 ? "lw" : "ld",
2136 "t,o(b)", PIC_CALL_REG
, (int) BFD_RELOC_MIPS_CALL16
, GP
);
2137 macro_build (&icnt
, (expressionS
*) NULL
, "jalr", "s", PIC_CALL_REG
);
2138 expr1
.X_add_number
= mips_cprestore_offset
;
2139 macro_build (&icnt
, &expr1
,
2140 mips_isa
< 3 ? "lw" : "ld",
2141 "t,o(b)", GP
, (int) BFD_RELOC_LO16
, SP
);
2209 if (breg
== treg
|| coproc
)
2278 if (mask
== M_LWC1_AB
2279 || mask
== M_SWC1_AB
2281 || mask
== M_LDC1_AB
2282 || mask
== M_SDC1_AB
)
2288 if (gp_reference (&offset_expr
))
2292 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
,
2293 (int) BFD_RELOC_MIPS_GPREL
, GP
);
2296 macro_build (&icnt
, (expressionS
*) NULL
,
2297 mips_isa
< 3 ? "addu" : "daddu",
2298 "d,v,t", tempreg
, breg
, GP
);
2299 r
= BFD_RELOC_MIPS_GPREL
;
2303 /* FIXME: This won't work for a 64 bit address. */
2304 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2306 macro_build (&icnt
, NULL
,
2307 mips_isa
< 3 ? "addu" : "daddu",
2308 "d,v,t", tempreg
, tempreg
, breg
);
2311 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, (int) r
, tempreg
);
2318 load_register (&icnt
, treg
, &imm_expr
);
2323 lw $v0,%lo(foo)($at)
2324 lw $v1,%lo(foo+4)($at)
2329 /* FIXME: This won't work for a 64 bit address. */
2330 macro_build_lui (&icnt
, &offset_expr
, AT
);
2332 macro_build (&icnt
, &offset_expr
, "ld", "t,o(b)", treg
,
2333 (int) BFD_RELOC_LO16
, AT
);
2336 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
,
2337 (int) BFD_RELOC_LO16
, AT
);
2338 offset_expr
.X_add_number
+= 4;
2339 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
+ 1,
2340 (int) BFD_RELOC_LO16
, AT
);
2345 /* Load a floating point number from the .lit8 section. */
2348 macro_build (&icnt
, &offset_expr
, "ldc1", "T,o(b)", treg
,
2349 (int) BFD_RELOC_MIPS_LITERAL
, GP
);
2353 r
= BFD_RELOC_MIPS_LITERAL
;
2357 /* Even on a big endian machine $fn comes before $fn+1. We have
2358 to adjust when loading from memory. */
2361 assert (mips_isa
< 2);
2362 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2363 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2365 offset_expr
.X_add_number
+= 4;
2366 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2367 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2373 * The MIPS assembler seems to check for X_add_number not
2374 * being double aligned and generating:
2377 * addiu at,at,%lo(foo+1)
2380 * But, the resulting address is the same after relocation so why
2381 * generate the extra instruction?
2383 if (gp_reference (&offset_expr
))
2389 macro_build (&icnt
, &offset_expr
,
2390 mips_isa
< 3 ? "addu" : "daddu",
2391 "d,v,t", AT
, breg
, GP
);
2394 r
= BFD_RELOC_MIPS_GPREL
;
2398 /* FIXME: This won't work for a 64 bit address. */
2399 macro_build_lui (&icnt
, &offset_expr
, AT
);
2401 macro_build (&icnt
, NULL
,
2402 mips_isa
< 3 ? "addu" : "daddu",
2403 "d,v,t", AT
, AT
, breg
);
2408 macro_build (&icnt
, &offset_expr
, "ldc1", "T,o(b)", treg
,
2412 /* Even on a big endian machine $fn comes before $fn+1. We
2413 have to adjust when loading from memory. */
2414 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2415 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2417 offset_expr
.X_add_number
+= 4;
2418 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
2419 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2432 assert (mips_isa
< 3);
2433 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
,
2434 (int) BFD_RELOC_LO16
, breg
);
2435 offset_expr
.X_add_number
+= 4;
2436 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1,
2437 (int) BFD_RELOC_LO16
, breg
);
2460 if (gp_reference (&offset_expr
))
2468 macro_build (&icnt
, (expressionS
*) NULL
,
2469 mips_isa
< 3 ? "addu" : "daddu",
2470 "d,v,t", tempreg
, breg
, GP
);
2471 r
= BFD_RELOC_MIPS_GPREL
;
2475 /* FIXME: This won't work for a 64 bit address. */
2476 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
2478 macro_build (&icnt
, NULL
,
2479 mips_isa
< 3 ? "addu" : "daddu",
2480 "d,v,t", tempreg
, tempreg
, breg
);
2484 macro_build (&icnt
, &offset_expr
, s2
, "t,o(b)", treg
,
2488 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
,
2490 offset_expr
.X_add_number
+= 4;
2491 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1,
2501 macro_build (&icnt
, NULL
,
2502 dbl
? "dmultu" : "multu",
2504 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2510 /* The MIPS assembler some times generates shifts and adds. I'm
2511 not trying to be that fancy. GCC should do this for us
2513 load_register (&icnt
, AT
, &imm_expr
);
2514 macro_build (&icnt
, NULL
,
2515 dbl
? "dmult" : "mult",
2517 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2523 mips_emit_delays ();
2525 macro_build (&icnt
, NULL
,
2526 dbl
? "dmult" : "mult",
2528 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2529 macro_build (&icnt
, NULL
,
2530 dbl
? "dsra32" : "sra",
2531 "d,w,<", dreg
, dreg
, 31);
2532 macro_build (&icnt
, NULL
, "mfhi", "d", AT
);
2533 expr1
.X_add_number
= 8;
2534 macro_build (&icnt
, &expr1
, "beq", "s,t,p", dreg
, AT
);
2535 macro_build (&icnt
, NULL
, "nop", "", 0);
2536 macro_build (&icnt
, NULL
, "break", "c", 6);
2538 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2544 mips_emit_delays ();
2546 macro_build (&icnt
, NULL
,
2547 dbl
? "dmultu" : "multu",
2549 macro_build (&icnt
, NULL
, "mfhi", "d", AT
);
2550 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
2551 expr1
.X_add_number
= 8;
2552 macro_build (&icnt
, &expr1
, "beq", "s,t,p", AT
, 0);
2553 macro_build (&icnt
, NULL
, "nop", "", 0);
2554 macro_build (&icnt
, NULL
, "break", "c", 6);
2559 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
2560 macro_build (&icnt
, NULL
, "srlv", "d,t,s", AT
, sreg
, AT
);
2561 macro_build (&icnt
, NULL
, "sllv", "d,t,s", dreg
, sreg
, treg
);
2562 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2566 macro_build (&icnt
, NULL
, "sll", "d,w,<", AT
, sreg
,
2567 imm_expr
.X_add_number
& 0x1f);
2568 macro_build (&icnt
, NULL
, "srl", "d,w,<", dreg
, sreg
,
2569 (0 - imm_expr
.X_add_number
) & 0x1f);
2570 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2574 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
2575 macro_build (&icnt
, NULL
, "sllv", "d,t,s", AT
, sreg
, AT
);
2576 macro_build (&icnt
, NULL
, "srlv", "d,t,s", dreg
, sreg
, treg
);
2577 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2581 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, sreg
,
2582 imm_expr
.X_add_number
& 0x1f);
2583 macro_build (&icnt
, NULL
, "sll", "d,w,<", dreg
, sreg
,
2584 (0 - imm_expr
.X_add_number
) & 0x1f);
2585 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
2589 assert (mips_isa
< 2);
2590 /* Even on a big endian machine $fn comes before $fn+1. We have
2591 to adjust when storing to memory. */
2592 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2593 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2594 (int) BFD_RELOC_LO16
, breg
);
2595 offset_expr
.X_add_number
+= 4;
2596 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2597 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2598 (int) BFD_RELOC_LO16
, breg
);
2602 if (gp_reference (&offset_expr
))
2608 macro_build (&icnt
, (expressionS
*) NULL
,
2609 mips_isa
< 3 ? "addu" : "daddu",
2610 "d,v,t", AT
, breg
, GP
);
2613 r
= BFD_RELOC_MIPS_GPREL
;
2617 /* FIXME: This won't work for a 64 bit address. */
2618 macro_build_lui (&icnt
, &offset_expr
, AT
);
2620 macro_build (&icnt
, NULL
,
2621 mips_isa
< 3 ? "addu" : "daddu",
2622 "d,v,t", AT
, AT
, breg
);
2627 macro_build (&icnt
, &offset_expr
, "sdc1", "T,o(b)", treg
,
2631 /* Even on a big endian machine $fn comes before $fn+1. We
2632 have to adjust when storing to memory. */
2633 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2634 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
2636 offset_expr
.X_add_number
+= 4;
2637 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
2638 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
2647 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, treg
,
2648 (int) BFD_RELOC_LO16
);
2650 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
,
2651 (int) BFD_RELOC_LO16
);
2654 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
2655 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
,
2656 (int) BFD_RELOC_LO16
);
2661 if (imm_expr
.X_add_number
== 0)
2663 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
,
2664 (int) BFD_RELOC_LO16
);
2669 as_warn ("Instruction %s: result is always false",
2671 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
2674 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
2676 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
,
2677 (int) BFD_RELOC_LO16
);
2680 else if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
< 0)
2682 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2683 macro_build (&icnt
, &imm_expr
,
2684 mips_isa
< 3 ? "addiu" : "daddiu",
2685 "t,r,j", dreg
, sreg
,
2686 (int) BFD_RELOC_LO16
);
2691 load_register (&icnt
, AT
, &imm_expr
);
2692 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
2695 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
,
2696 (int) BFD_RELOC_LO16
);
2701 case M_SGE
: /* sreg >= treg <==> not (sreg < treg) */
2707 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, sreg
, treg
);
2708 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
,
2709 (int) BFD_RELOC_LO16
);
2712 case M_SGE_I
: /* sreg >= I <==> not (sreg < I) */
2714 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2716 macro_build (&icnt
, &expr1
,
2717 mask
== M_SGE_I
? "slti" : "sltiu",
2718 "t,r,j", dreg
, sreg
, (int) BFD_RELOC_LO16
);
2723 load_register (&icnt
, AT
, &imm_expr
);
2724 macro_build (&icnt
, NULL
,
2725 mask
== M_SGE_I
? "slt" : "sltu",
2726 "d,v,t", dreg
, sreg
, AT
);
2729 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
,
2730 (int) BFD_RELOC_LO16
);
2735 case M_SGT
: /* sreg > treg <==> treg < sreg */
2741 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
2744 case M_SGT_I
: /* sreg > I <==> I < sreg */
2750 load_register (&icnt
, AT
, &imm_expr
);
2751 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
2754 case M_SLE
: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
2760 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
2761 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
,
2762 (int) BFD_RELOC_LO16
);
2765 case M_SLE_I
: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
2771 load_register (&icnt
, AT
, &imm_expr
);
2772 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
2773 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
,
2774 (int) BFD_RELOC_LO16
);
2778 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2780 macro_build (&icnt
, &imm_expr
, "slti", "t,r,j", dreg
, sreg
,
2781 (int) BFD_RELOC_LO16
);
2784 load_register (&icnt
, AT
, &imm_expr
);
2785 macro_build (&icnt
, NULL
, "slt", "d,v,t", dreg
, sreg
, AT
);
2789 if (imm_expr
.X_add_number
>= -0x8000 && imm_expr
.X_add_number
< 0x8000)
2791 macro_build (&icnt
, &imm_expr
, "sltiu", "t,r,j", dreg
, sreg
,
2792 (int) BFD_RELOC_LO16
);
2795 load_register (&icnt
, AT
, &imm_expr
);
2796 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, sreg
, AT
);
2801 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, treg
);
2803 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
2806 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
2807 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
2812 if (imm_expr
.X_add_number
== 0)
2814 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
2819 as_warn ("Instruction %s: result is always true",
2821 macro_build (&icnt
, &expr1
,
2822 mips_isa
< 3 ? "addiu" : "daddiu",
2823 "t,r,j", dreg
, 0, (int) BFD_RELOC_LO16
);
2826 if (imm_expr
.X_add_number
>= 0 && imm_expr
.X_add_number
< 0x10000)
2828 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
,
2829 (int) BFD_RELOC_LO16
);
2832 else if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
< 0)
2834 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2835 macro_build (&icnt
, &imm_expr
,
2836 mips_isa
< 3 ? "addiu" : "daddiu",
2837 "t,r,j", dreg
, sreg
, (int) BFD_RELOC_LO16
);
2842 load_register (&icnt
, AT
, &imm_expr
);
2843 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
2846 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
2854 if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
<= 0x8000)
2856 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2857 macro_build (&icnt
, &imm_expr
,
2858 dbl
? "daddi" : "addi",
2859 "t,r,j", dreg
, sreg
, (int) BFD_RELOC_LO16
);
2862 load_register (&icnt
, AT
, &imm_expr
);
2863 macro_build (&icnt
, NULL
,
2864 dbl
? "dsub" : "sub",
2865 "d,v,t", dreg
, sreg
, AT
);
2871 if (imm_expr
.X_add_number
> -0x8000 && imm_expr
.X_add_number
<= 0x8000)
2873 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
2874 macro_build (&icnt
, &imm_expr
,
2875 dbl
? "daddiu" : "addiu",
2876 "t,r,j", dreg
, sreg
, (int) BFD_RELOC_LO16
);
2879 load_register (&icnt
, AT
, &imm_expr
);
2880 macro_build (&icnt
, NULL
,
2881 dbl
? "dsubu" : "subu",
2882 "d,v,t", dreg
, sreg
, AT
);
2903 load_register (&icnt
, AT
, &imm_expr
);
2904 macro_build (&icnt
, NULL
, s
, "s,t", sreg
, AT
);
2909 assert (mips_isa
< 2);
2910 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* floating reg */
2911 dreg
= (ip
->insn_opcode
>> 06) & 0x1f; /* floating reg */
2914 * Is the double cfc1 instruction a bug in the mips assembler;
2915 * or is there a reason for it?
2917 mips_emit_delays ();
2919 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
2920 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
2921 macro_build (&icnt
, NULL
, "nop", "");
2922 expr1
.X_add_number
= 3;
2923 macro_build (&icnt
, &expr1
, "ori", "t,r,i", AT
, treg
,
2924 (int) BFD_RELOC_LO16
);
2925 expr1
.X_add_number
= 2;
2926 macro_build (&icnt
, &expr1
, "xori", "t,r,i", AT
, AT
,
2927 (int) BFD_RELOC_LO16
);
2928 macro_build (&icnt
, NULL
, "ctc1", "t,G", AT
, 31);
2929 macro_build (&icnt
, NULL
, "nop", "");
2930 macro_build (&icnt
, NULL
,
2931 mask
== M_TRUNCWD
? "cvt.w.d" : "cvt.w.s", "D,S", dreg
, sreg
);
2932 macro_build (&icnt
, NULL
, "ctc1", "t,G", treg
, 31);
2933 macro_build (&icnt
, NULL
, "nop", "");
2943 /* avoid load delay */
2944 offset_expr
.X_add_number
+= 1;
2945 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
,
2946 (int) BFD_RELOC_LO16
, breg
);
2947 offset_expr
.X_add_number
-= 1;
2948 macro_build (&icnt
, &offset_expr
, "lbu", "t,o(b)", AT
,
2949 (int) BFD_RELOC_LO16
, breg
);
2950 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2951 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
2955 /* does this work on a big endian machine? */
2956 offset_expr
.X_add_number
+= 3;
2957 macro_build (&icnt
, &offset_expr
, "lwl", "t,o(b)", treg
,
2958 (int) BFD_RELOC_LO16
, breg
);
2959 offset_expr
.X_add_number
-= 3;
2960 macro_build (&icnt
, &offset_expr
, "lwr", "t,o(b)", treg
,
2961 (int) BFD_RELOC_LO16
, breg
);
2967 if (offset_expr
.X_op
== O_constant
)
2968 load_register (&icnt
, AT
, &offset_expr
);
2969 else if (gp_reference (&offset_expr
))
2970 macro_build (&icnt
, &offset_expr
,
2971 mips_isa
< 3 ? "addiu" : "daddiu",
2972 "t,r,j", AT
, GP
, (int) BFD_RELOC_MIPS_GPREL
);
2975 /* FIXME: This won't work for a 64 bit address. */
2976 macro_build_lui (&icnt
, &offset_expr
, AT
);
2977 macro_build (&icnt
, &offset_expr
,
2978 mips_isa
< 3 ? "addiu" : "daddiu",
2979 "t,r,j", AT
, AT
, (int) BFD_RELOC_LO16
);
2981 if (mask
== M_ULW_A
)
2983 expr1
.X_add_number
= 3;
2984 macro_build (&icnt
, &expr1
, "lwl", "t,o(b)", treg
,
2985 (int) BFD_RELOC_LO16
, AT
);
2986 imm_expr
.X_add_number
= 0;
2987 macro_build (&icnt
, &expr1
, "lwr", "t,o(b)", treg
,
2988 (int) BFD_RELOC_LO16
, AT
);
2992 macro_build (&icnt
, &expr1
,
2993 mask
== M_ULH_A
? "lb" : "lbu", "t,o(b)", treg
,
2994 (int) BFD_RELOC_LO16
, AT
);
2995 imm_expr
.X_add_number
= 0;
2996 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
,
2997 (int) BFD_RELOC_LO16
, AT
);
2998 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
2999 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
3004 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", treg
,
3005 (int) BFD_RELOC_LO16
, breg
);
3006 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, treg
, 8);
3007 offset_expr
.X_add_number
+= 1;
3008 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", AT
,
3009 (int) BFD_RELOC_LO16
, breg
);
3013 offset_expr
.X_add_number
+= 3;
3014 macro_build (&icnt
, &offset_expr
, "swl", "t,o(b)", treg
,
3015 (int) BFD_RELOC_LO16
, breg
);
3016 offset_expr
.X_add_number
-= 3;
3017 macro_build (&icnt
, &offset_expr
, "swr", "t,o(b)", treg
,
3018 (int) BFD_RELOC_LO16
, breg
);
3023 if (offset_expr
.X_op
== O_constant
)
3024 load_register (&icnt
, AT
, &offset_expr
);
3025 else if (gp_reference (&offset_expr
))
3026 macro_build (&icnt
, &offset_expr
,
3027 mips_isa
< 3 ? "addiu" : "daddiu",
3028 "t,r,j", AT
, GP
, (int) BFD_RELOC_MIPS_GPREL
);
3031 /* FIXME: This won't work for a 64 bit address. */
3032 macro_build_lui (&icnt
, &offset_expr
, AT
);
3033 macro_build (&icnt
, &offset_expr
,
3034 mips_isa
< 3 ? "addiu" : "daddiu",
3035 "t,r,j", AT
, AT
, (int) BFD_RELOC_LO16
);
3037 if (mask
== M_USW_A
)
3039 expr1
.X_add_number
= 3;
3040 macro_build (&icnt
, &expr1
, "swl", "t,o(b)", treg
,
3041 (int) BFD_RELOC_LO16
, AT
);
3042 expr1
.X_add_number
= 0;
3043 macro_build (&icnt
, &expr1
, "swr", "t,o(b)", treg
,
3044 (int) BFD_RELOC_LO16
, AT
);
3048 expr1
.X_add_number
= 0;
3049 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
,
3050 (int) BFD_RELOC_LO16
, AT
);
3051 macro_build (&icnt
, NULL
, "srl", "d,w,<", treg
, treg
, 8);
3052 expr1
.X_add_number
= 1;
3053 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
,
3054 (int) BFD_RELOC_LO16
, AT
);
3055 expr1
.X_add_number
= 0;
3056 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
,
3057 (int) BFD_RELOC_LO16
, AT
);
3058 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
3059 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
3064 as_bad ("Macro %s not implemented yet", ip
->insn_mo
->name
);
3068 as_warn ("Macro used $at after \".set noat\"");
3073 This routine assembles an instruction into its binary format. As a side
3074 effect it sets one of the global variables imm_reloc or offset_reloc to the
3075 type of relocation to do if one of the operands is an address expression.
3080 struct mips_cl_insn
*ip
;
3085 struct mips_opcode
*insn
;
3088 unsigned int lastregno
= 0;
3093 for (s
= str
; islower (*s
) || (*s
>= '0' && *s
<= '3') || *s
== '.'; ++s
)
3105 as_warn ("Unknown opcode: `%s'", str
);
3108 if ((insn
= (struct mips_opcode
*) hash_find (op_hash
, str
)) == NULL
)
3110 as_warn ("`%s' not in hash table.", str
);
3111 insn_error
= "ERROR: Unrecognized opcode";
3119 assert (strcmp (insn
->name
, str
) == 0);
3121 if (insn
->pinfo
== INSN_MACRO
)
3122 insn_isa
= insn
->match
;
3123 else if (insn
->pinfo
& INSN_ISA2
)
3125 else if (insn
->pinfo
& INSN_ISA3
)
3130 if (insn_isa
> mips_isa
)
3132 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
]
3133 && strcmp (insn
->name
, insn
[1].name
) == 0)
3138 insn_error
= "ERROR: instruction not supported on this processor";
3143 ip
->insn_opcode
= insn
->match
;
3144 for (args
= insn
->args
;; ++args
)
3150 case '\0': /* end of args */
3163 ip
->insn_opcode
|= lastregno
<< 21;
3168 ip
->insn_opcode
|= lastregno
<< 16;
3172 ip
->insn_opcode
|= lastregno
<< 11;
3178 /* handle optional base register.
3179 Either the base register is omitted or
3180 we must have a left paren. */
3181 /* this is dependent on the next operand specifier
3182 is a 'b' for base register */
3183 assert (args
[1] == 'b');
3187 case ')': /* these must match exactly */
3192 case '<': /* must be at least one digit */
3194 * According to the manual, if the shift amount is greater
3195 * than 31 or less than 0 the the shift amount should be
3196 * mod 32. In reality the mips assembler issues an error.
3197 * We issue a warning and mask out all but the low 5 bits.
3199 my_getExpression (&imm_expr
, s
);
3200 check_absolute_expr (ip
, &imm_expr
);
3201 if ((unsigned long) imm_expr
.X_add_number
> 31)
3203 as_warn ("Improper shift amount (%ld)",
3204 (long) imm_expr
.X_add_number
);
3205 imm_expr
.X_add_number
= imm_expr
.X_add_number
& 0x1f;
3207 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
3208 imm_expr
.X_op
= O_absent
;
3212 case '>': /* shift amount minus 32 */
3213 my_getExpression (&imm_expr
, s
);
3214 check_absolute_expr (ip
, &imm_expr
);
3215 if ((unsigned long) imm_expr
.X_add_number
< 32
3216 || (unsigned long) imm_expr
.X_add_number
> 63)
3218 ip
->insn_opcode
|= (imm_expr
.X_add_number
- 32) << 6;
3219 imm_expr
.X_op
= O_absent
;
3223 case 'k': /* cache code */
3224 my_getExpression (&imm_expr
, s
);
3225 check_absolute_expr (ip
, &imm_expr
);
3226 if ((unsigned long) imm_expr
.X_add_number
> 31)
3228 as_warn ("Invalid cahce opcode (%lu)",
3229 (unsigned long) imm_expr
.X_add_number
);
3230 imm_expr
.X_add_number
&= 0x1f;
3232 ip
->insn_opcode
|= imm_expr
.X_add_number
<< OP_SH_CACHE
;
3233 imm_expr
.X_op
= O_absent
;
3237 case 'c': /* break code */
3238 my_getExpression (&imm_expr
, s
);
3239 check_absolute_expr (ip
, &imm_expr
);
3240 if ((unsigned) imm_expr
.X_add_number
> 1023)
3241 as_warn ("Illegal break code (%ld)",
3242 (long) imm_expr
.X_add_number
);
3243 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 16;
3244 imm_expr
.X_op
= O_absent
;
3248 case 'B': /* syscall code */
3249 my_getExpression (&imm_expr
, s
);
3250 check_absolute_expr (ip
, &imm_expr
);
3251 if ((unsigned) imm_expr
.X_add_number
> 0xfffff)
3252 as_warn ("Illegal syscall code (%ld)",
3253 (long) imm_expr
.X_add_number
);
3254 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
3255 imm_expr
.X_op
= O_absent
;
3259 case 'C': /* Coprocessor code */
3260 my_getExpression (&imm_expr
, s
);
3261 check_absolute_expr (ip
, &imm_expr
);
3262 if ((unsigned long) imm_expr
.X_add_number
>= (1<<25))
3264 as_warn ("Coproccesor code > 25 bits (%ld)",
3265 (long) imm_expr
.X_add_number
);
3266 imm_expr
.X_add_number
&= ((1<<25) - 1);
3268 ip
->insn_opcode
|= imm_expr
.X_add_number
;
3269 imm_expr
.X_op
= O_absent
;
3273 case 'b': /* base register */
3274 case 'd': /* destination register */
3275 case 's': /* source register */
3276 case 't': /* target register */
3277 case 'r': /* both target and source */
3278 case 'v': /* both dest and source */
3279 case 'w': /* both dest and target */
3280 case 'E': /* coprocessor target register */
3281 case 'G': /* coprocessor destination register */
3282 case 'x': /* ignore register name */
3283 case 'z': /* must be zero register */
3297 while (isdigit (*s
));
3299 as_bad ("Invalid register number (%d)", regno
);
3301 else if (*args
!= 'E' && *args
!= 'G')
3303 if (s
[1] == 'f' && s
[2] == 'p')
3308 else if (s
[1] == 's' && s
[2] == 'p')
3313 else if (s
[1] == 'g' && s
[2] == 'p')
3318 else if (s
[1] == 'a' && s
[2] == 't')
3325 if (regno
== AT
&& ! mips_noat
)
3326 as_warn ("Used $at without \".set noat\"");
3333 if (c
== 'r' || c
== 'v' || c
== 'w')
3340 /* 'z' only matches $0. */
3341 if (c
== 'z' && regno
!= 0)
3349 ip
->insn_opcode
|= regno
<< 21;
3353 ip
->insn_opcode
|= regno
<< 11;
3358 ip
->insn_opcode
|= regno
<< 16;
3361 /* This case exists because on the r3000 trunc
3362 expands into a macro which requires a gp
3363 register. On the r6000 or r4000 it is
3364 assembled into a single instruction which
3365 ignores the register. Thus the insn version
3366 is MIPS_ISA2 and uses 'x', and the macro
3367 version is MIPS_ISA1 and uses 't'. */
3370 /* This case is for the div instruction, which
3371 acts differently if the destination argument
3372 is $0. This only matches $0, and is checked
3373 outside the switch. */
3384 ip
->insn_opcode
|= lastregno
<< 21;
3387 ip
->insn_opcode
|= lastregno
<< 16;
3392 case 'D': /* floating point destination register */
3393 case 'S': /* floating point source register */
3394 case 'T': /* floating point target register */
3398 if (s
[0] == '$' && s
[1] == 'f' && isdigit (s
[2]))
3408 while (isdigit (*s
));
3411 as_bad ("Invalid float register number (%d)", regno
);
3413 if ((regno
& 1) != 0
3415 && ! (strcmp (str
, "mtc1") == 0 ||
3416 strcmp (str
, "mfc1") == 0 ||
3417 strcmp (str
, "lwc1") == 0 ||
3418 strcmp (str
, "swc1") == 0))
3419 as_warn ("Float register should be even, was %d",
3427 if (c
== 'V' || c
== 'W')
3437 ip
->insn_opcode
|= regno
<< 6;
3441 ip
->insn_opcode
|= regno
<< 11;
3445 ip
->insn_opcode
|= regno
<< 16;
3453 ip
->insn_opcode
|= lastregno
<< 11;
3456 ip
->insn_opcode
|= lastregno
<< 16;
3462 my_getExpression (&imm_expr
, s
);
3463 check_absolute_expr (ip
, &imm_expr
);
3468 my_getExpression (&offset_expr
, s
);
3469 imm_reloc
= BFD_RELOC_32
;
3481 unsigned char temp
[8];
3483 unsigned int length
;
3488 /* These only appear as the last operand in an
3489 instruction, and every instruction that accepts
3490 them in any variant accepts them in all variants.
3491 This means we don't have to worry about backing out
3492 any changes if the instruction does not match.
3494 The difference between them is the size of the
3495 floating point constant and where it goes. For 'F'
3496 and 'L' the constant is 64 bits; for 'f' and 'l' it
3497 is 32 bits. Where the constant is placed is based
3498 on how the MIPS assembler does things:
3501 f -- immediate value
3505 f64
= *args
== 'F' || *args
== 'L';
3507 save_in
= input_line_pointer
;
3508 input_line_pointer
= s
;
3509 err
= md_atof (f64
? 'd' : 'f', (char *) temp
, &len
);
3511 s
= input_line_pointer
;
3512 input_line_pointer
= save_in
;
3513 if (err
!= NULL
&& *err
!= '\0')
3515 as_bad ("Bad floating point constant: %s", err
);
3516 memset (temp
, '\0', sizeof temp
);
3517 length
= f64
? 8 : 4;
3520 assert (length
== (f64
? 8 : 4));
3524 imm_expr
.X_op
= O_constant
;
3525 if (byte_order
== LITTLE_ENDIAN
)
3526 imm_expr
.X_add_number
=
3527 (((((((int) temp
[3] << 8)
3532 imm_expr
.X_add_number
=
3533 (((((((int) temp
[0] << 8)
3540 /* Switch to the right section. */
3542 subseg
= now_subseg
;
3546 subseg_new (".rdata", (subsegT
) 0);
3549 subseg_new (".lit8", (subsegT
) 0);
3552 subseg_new (".lit4", (subsegT
) 0);
3556 as_bad ("Can't use floating point insn in this section");
3558 /* Set the argument to the current address in the
3560 offset_expr
.X_op
= O_symbol
;
3561 offset_expr
.X_add_symbol
=
3562 symbol_new ("L0\001", now_seg
,
3563 (valueT
) frag_now_fix (), frag_now
);
3564 offset_expr
.X_add_number
= 0;
3566 /* Put the floating point number into the section. */
3567 p
= frag_more ((int) length
);
3568 memcpy (p
, temp
, length
);
3570 /* Switch back to the original section. */
3571 subseg_set (seg
, subseg
);
3576 case 'i': /* 16 bit unsigned immediate */
3577 case 'j': /* 16 bit signed immediate */
3578 imm_reloc
= BFD_RELOC_LO16
;
3579 c
= my_getSmallExpression (&imm_expr
, s
);
3584 if (imm_expr
.X_op
== O_constant
)
3585 imm_expr
.X_add_number
=
3586 (imm_expr
.X_add_number
>> 16) & 0xffff;
3588 imm_reloc
= BFD_RELOC_HI16_S
;
3590 imm_reloc
= BFD_RELOC_HI16
;
3594 check_absolute_expr (ip
, &imm_expr
);
3597 if (imm_expr
.X_add_number
< 0
3598 || imm_expr
.X_add_number
>= 0x10000)
3600 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3601 !strcmp (insn
->name
, insn
[1].name
))
3603 as_bad ("16 bit expression not in range 0..65535");
3608 if (imm_expr
.X_add_number
< -0x8000 ||
3609 imm_expr
.X_add_number
>= 0x8000)
3611 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3612 !strcmp (insn
->name
, insn
[1].name
))
3614 as_bad ("16 bit expression not in range -32768..32767");
3620 case 'o': /* 16 bit offset */
3621 c
= my_getSmallExpression (&offset_expr
, s
);
3623 * If this value won't fit into a 16 bit offset, then
3624 * go find a macro that will generate the 32 bit offset
3627 if (offset_expr
.X_op
!= O_constant
3628 || offset_expr
.X_add_number
>= 0x8000
3629 || offset_expr
.X_add_number
< -0x8000)
3632 offset_reloc
= BFD_RELOC_LO16
;
3633 if (c
== 'h' || c
== 'H')
3635 assert (offset_expr
.X_op
== O_constant
);
3636 offset_expr
.X_add_number
=
3637 (offset_expr
.X_add_number
>> 16) & 0xffff;
3642 case 'p': /* pc relative offset */
3643 offset_reloc
= BFD_RELOC_16_PCREL_S2
;
3644 my_getExpression (&offset_expr
, s
);
3648 case 'u': /* upper 16 bits */
3649 c
= my_getSmallExpression (&imm_expr
, s
);
3650 if (imm_expr
.X_op
!= O_constant
3651 || imm_expr
.X_add_number
< 0
3652 || imm_expr
.X_add_number
>= 0x10000)
3653 as_bad ("lui expression not in range 0..65535");
3654 imm_reloc
= BFD_RELOC_LO16
;
3659 if (imm_expr
.X_op
== O_constant
)
3660 imm_expr
.X_add_number
=
3661 (imm_expr
.X_add_number
>> 16) & 0xffff;
3663 imm_reloc
= BFD_RELOC_HI16_S
;
3665 imm_reloc
= BFD_RELOC_HI16
;
3671 case 'a': /* 26 bit address */
3672 my_getExpression (&offset_expr
, s
);
3674 offset_reloc
= BFD_RELOC_MIPS_JMP
;
3678 fprintf (stderr
, "bad char = '%c'\n", *args
);
3683 /* Args don't match. */
3684 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
3685 !strcmp (insn
->name
, insn
[1].name
))
3691 insn_error
= "ERROR: Illegal operands";
3700 my_getSmallExpression (ep
, str
)
3711 ((str
[1] == 'h' && str
[2] == 'i')
3712 || (str
[1] == 'H' && str
[2] == 'I')
3713 || (str
[1] == 'l' && str
[2] == 'o'))
3725 * A small expression may be followed by a base register.
3726 * Scan to the end of this operand, and then back over a possible
3727 * base register. Then scan the small expression up to that
3728 * point. (Based on code in sparc.c...)
3730 for (sp
= str
; *sp
&& *sp
!= ','; sp
++)
3732 if (sp
- 4 >= str
&& sp
[-1] == RP
)
3734 if (isdigit (sp
[-2]))
3736 for (sp
-= 3; sp
>= str
&& isdigit (*sp
); sp
--)
3738 if (*sp
== '$' && sp
> str
&& sp
[-1] == LP
)
3744 else if (sp
- 5 >= str
3747 && ((sp
[-3] == 'f' && sp
[-2] == 'p')
3748 || (sp
[-3] == 's' && sp
[-2] == 'p')
3749 || (sp
[-3] == 'g' && sp
[-2] == 'p')
3750 || (sp
[-3] == 'a' && sp
[-2] == 't')))
3756 /* no expression means zero offset */
3759 /* %xx(reg) is an error */
3760 ep
->X_op
= O_absent
;
3765 ep
->X_op
= O_constant
;
3768 ep
->X_add_symbol
= NULL
;
3769 ep
->X_op_symbol
= NULL
;
3770 ep
->X_add_number
= 0;
3775 my_getExpression (ep
, str
);
3782 my_getExpression (ep
, str
);
3783 return c
; /* => %hi or %lo encountered */
3787 my_getExpression (ep
, str
)
3793 save_in
= input_line_pointer
;
3794 input_line_pointer
= str
;
3796 expr_end
= input_line_pointer
;
3797 input_line_pointer
= save_in
;
3800 /* Turn a string in input_line_pointer into a floating point constant
3801 of type type, and store the appropriate bytes in *litP. The number
3802 of LITTLENUMS emitted is stored in *sizeP . An error message is
3803 returned, or NULL on OK. */
3806 md_atof (type
, litP
, sizeP
)
3812 LITTLENUM_TYPE words
[4];
3828 return "bad call to md_atof";
3831 t
= atof_ieee (input_line_pointer
, type
, words
);
3833 input_line_pointer
= t
;
3837 if (byte_order
== LITTLE_ENDIAN
)
3839 for (i
= prec
- 1; i
>= 0; i
--)
3841 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3847 for (i
= 0; i
< prec
; i
++)
3849 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
3858 md_number_to_chars (buf
, val
, n
)
3906 md_number_to_chars (buf
, hi
, 4);
3931 md_parse_option (argP
, cntP
, vecP
)
3936 /* Accept -nocpp but ignore it. */
3937 if (strcmp (*argP
, "nocpp") == 0)
3943 if (strcmp (*argP
, "EL") == 0
3944 || strcmp (*argP
, "EB") == 0)
3946 /* FIXME: This breaks -L -EL. */
3954 if ((*argP
)[1] == '0')
3963 if ((*argP
)[1] == '\0' || (*argP
)[1] == '2')
3968 if (strncmp (*argP
, "mips", 4) == 0)
3970 mips_isa
= atol (*argP
+ 4);
3973 else if (mips_isa
< 1 || mips_isa
> 3)
3975 as_bad ("-mips%d not supported", mips_isa
);
3982 if (strncmp (*argP
, "mcpu=", 5) == 0)
3986 /* Identify the processor type */
3988 if (strcmp (p
, "default") == 0
3989 || strcmp (p
, "DEFAULT") == 0)
3993 if (*p
== 'r' || *p
== 'R')
4000 if (strcmp (p
, "2000") == 0
4001 || strcmp (p
, "2k") == 0
4002 || strcmp (p
, "2K") == 0)
4007 if (strcmp (p
, "3000") == 0
4008 || strcmp (p
, "3k") == 0
4009 || strcmp (p
, "3K") == 0)
4014 if (strcmp (p
, "4000") == 0
4015 || strcmp (p
, "4k") == 0
4016 || strcmp (p
, "4K") == 0)
4021 if (strcmp (p
, "6000") == 0
4022 || strcmp (p
, "6k") == 0
4023 || strcmp (p
, "6K") == 0)
4030 as_bad ("bad value (%s) for -mcpu= switch", *argP
+ 5);
4043 if ((*argP
)[1] != '\0')
4044 g_switch_value
= atoi (*argP
+ 1);
4047 **vecP
= (char *) NULL
;
4050 g_switch_value
= atoi (**vecP
);
4053 as_warn ("Number expected after -G");
4059 return 1; /* pretend you parsed the character */
4063 md_pcrel_from (fixP
)
4066 /* return the address of the delay slot */
4067 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4070 /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
4071 reloc for a cons. We could use the definition there, except that
4072 we want to handle 64 bit relocs specially. */
4075 cons_fix_new_mips (frag
, where
, nbytes
, exp
)
4078 unsigned int nbytes
;
4081 /* If we are assembling in 32 bit mode, turn an 8 byte reloc into a
4083 FIXME: There is no way to select anything but 32 bit mode right
4087 if (byte_order
== BIG_ENDIAN
)
4092 if (nbytes
!= 2 && nbytes
!= 4)
4093 as_bad ("Unsupported reloc size %d", nbytes
);
4095 fix_new_exp (frag_now
, where
, (int) nbytes
, exp
, 0,
4096 nbytes
== 2 ? BFD_RELOC_16
: BFD_RELOC_32
);
4100 md_apply_fix (fixP
, valueP
)
4107 assert (fixP
->fx_size
== 4);
4110 fixP
->fx_addnumber
= value
; /* Remember value for tc_gen_reloc */
4112 switch (fixP
->fx_r_type
)
4115 case BFD_RELOC_MIPS_JMP
:
4116 case BFD_RELOC_HI16
:
4117 case BFD_RELOC_HI16_S
:
4118 case BFD_RELOC_LO16
:
4119 case BFD_RELOC_MIPS_GPREL
:
4120 case BFD_RELOC_MIPS_LITERAL
:
4121 case BFD_RELOC_MIPS_CALL16
:
4122 /* Nothing needed to do. The value comes from the reloc entry */
4125 case BFD_RELOC_16_PCREL_S2
:
4127 * We need to save the bits in the instruction since fixup_segment()
4128 * might be deleting the relocation entry (i.e., a branch within
4129 * the current segment).
4132 as_warn ("Branch to odd address (%lx)", value
);
4134 if ((value
& ~0xFFFF) && (value
& ~0xFFFF) != (-1 & ~0xFFFF))
4135 as_bad ("Relocation overflow");
4137 /* update old instruction data */
4138 buf
= (unsigned char *) (fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
);
4142 insn
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
4146 insn
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | buf
[3];
4153 insn
|= value
& 0xFFFF;
4154 md_number_to_chars ((char *) buf
, (valueT
) insn
, 4);
4168 const struct mips_opcode
*p
;
4169 int treg
, sreg
, dreg
, shamt
;
4174 for (i
= 0; i
< NUMOPCODES
; ++i
)
4176 p
= &mips_opcodes
[i
];
4177 if (((oc
& p
->mask
) == p
->match
) && (p
->pinfo
!= INSN_MACRO
))
4179 printf ("%08lx %s\t", oc
, p
->name
);
4180 treg
= (oc
>> 16) & 0x1f;
4181 sreg
= (oc
>> 21) & 0x1f;
4182 dreg
= (oc
>> 11) & 0x1f;
4183 shamt
= (oc
>> 6) & 0x1f;
4185 for (args
= p
->args
;; ++args
)
4196 printf ("%c", *args
);
4200 assert (treg
== sreg
);
4201 printf ("$%d,$%d", treg
, sreg
);
4206 printf ("$%d", dreg
);
4211 printf ("$%d", treg
);
4215 printf ("0x%x", treg
);
4220 printf ("$%d", sreg
);
4224 printf ("0x%08lx", oc
& 0x1ffffff);
4236 printf ("$%d", shamt
);
4247 printf ("%08lx UNDEFINED\n", oc
);
4258 name
= input_line_pointer
;
4259 c
= get_symbol_end ();
4260 p
= (symbolS
*) symbol_find_or_make (name
);
4261 *input_line_pointer
= c
;
4265 /* Align the current frag to a given power of two. The MIPS assembler
4266 also automatically adjusts any preceding label. */
4269 mips_align (to
, fill
)
4273 mips_emit_delays ();
4274 frag_align (to
, fill
);
4275 record_alignment (now_seg
, to
);
4276 if (insn_label
!= NULL
)
4278 assert (S_GET_SEGMENT (insn_label
) == now_seg
);
4279 insn_label
->sy_frag
= frag_now
;
4280 S_SET_VALUE (insn_label
, (valueT
) frag_now_fix ());
4285 /* Align to a given power of two. .align 0 turns off the automatic
4286 alignment used by the data creating pseudo-ops. */
4293 register long temp_fill
;
4294 long max_alignment
= 15;
4298 o Note that the assembler pulls down any immediately preceeding label
4299 to the aligned address.
4300 o It's not documented but auto alignment is reinstated by
4301 a .align pseudo instruction.
4302 o Note also that after auto alignment is turned off the mips assembler
4303 issues an error on attempt to assemble an improperly aligned data item.
4308 temp
= get_absolute_expression ();
4309 if (temp
> max_alignment
)
4310 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
4313 as_warn ("Alignment negative: 0 assumed.");
4316 if (*input_line_pointer
== ',')
4318 input_line_pointer
++;
4319 temp_fill
= get_absolute_expression ();
4326 mips_align (temp
, (int) temp_fill
);
4333 demand_empty_rest_of_line ();
4336 /* Handle .ascii and .asciiz. This just calls stringer and forgets
4337 that there was a previous instruction. */
4340 s_stringer (append_zero
)
4343 mips_emit_delays ();
4345 stringer (append_zero
);
4356 mips_emit_delays ();
4366 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
4367 demand_empty_rest_of_line ();
4372 subseg_new (".rdata", (subsegT
) get_absolute_expression ());
4373 demand_empty_rest_of_line ();
4375 #else /* ! defined (OBJ_ECOFF) */
4377 seg
= subseg_new (".rodata", (subsegT
) get_absolute_expression ());
4378 bfd_set_section_flags (stdoutput
, seg
,
4384 demand_empty_rest_of_line ();
4386 #else /* ! defined (OBJ_ELF) */
4389 #endif /* ! defined (OBJ_ELF) */
4390 #endif /* ! defined (OBJ_ECOFF) */
4394 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
4396 bfd_set_section_flags (stdoutput
, seg
,
4397 SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
4399 demand_empty_rest_of_line ();
4401 #else /* ! defined (GPOPT) */
4402 as_bad ("Global pointers not supported; recompile -G 0");
4403 demand_empty_rest_of_line ();
4405 #endif /* ! defined (GPOPT) */
4415 mips_emit_delays ();
4416 if (log_size
> 0 && auto_align
)
4417 mips_align (log_size
, 0);
4419 cons (1 << log_size
);
4426 as_fatal ("Encountered `.err', aborting assembly");
4436 symbolP
= get_symbol ();
4437 if (*input_line_pointer
== ',')
4438 input_line_pointer
++;
4439 size
= get_absolute_expression ();
4440 S_SET_VALUE (symbolP
, size
);
4441 S_SET_EXTERNAL (symbolP
);
4444 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
4445 so we use an additional ECOFF specific field. */
4446 symbolP
->ecoff_undefined
= 1;
4454 mips_emit_delays ();
4474 opt
= input_line_pointer
;
4475 c
= get_symbol_end ();
4477 /* FIXME: What do these options mean? */
4480 /* FIXME: What does this mean? */
4482 else if (strncmp (opt
, "pic", 3) == 0)
4484 mips_pic
= atoi (opt
+ 3);
4485 /* FIXME: I don't know what other values mean. */
4486 assert (mips_pic
== 0 || mips_pic
== 2);
4489 as_warn ("Unrecognized option \"%s\"", opt
);
4491 *input_line_pointer
= c
;
4492 demand_empty_rest_of_line ();
4499 char *name
= input_line_pointer
, ch
;
4501 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4502 input_line_pointer
++;
4503 ch
= *input_line_pointer
;
4504 *input_line_pointer
= '\0';
4506 if (strcmp (name
, "reorder") == 0)
4510 prev_insn_unreordered
= 1;
4511 prev_prev_insn_unreordered
= 1;
4515 else if (strcmp (name
, "noreorder") == 0)
4517 mips_emit_delays ();
4520 else if (strcmp (name
, "at") == 0)
4524 else if (strcmp (name
, "noat") == 0)
4528 else if (strcmp (name
, "macro") == 0)
4530 mips_warn_about_macros
= 0;
4532 else if (strcmp (name
, "nomacro") == 0)
4534 if (mips_noreorder
== 0)
4535 as_bad ("`noreorder' must be set before `nomacro'");
4536 mips_warn_about_macros
= 1;
4538 else if (strcmp (name
, "move") == 0 || strcmp (name
, "novolatile") == 0)
4542 else if (strcmp (name
, "nomove") == 0 || strcmp (name
, "volatile") == 0)
4546 else if (strcmp (name
, "bopt") == 0)
4550 else if (strcmp (name
, "nobopt") == 0)
4556 as_warn ("Tried to set unrecognized symbol: %s\n", name
);
4558 *input_line_pointer
= ch
;
4559 demand_empty_rest_of_line ();
4562 /* The same as the usual .space directive, except that we have to
4563 forget about any previous instruction. */
4566 s_mips_space (param
)
4569 mips_emit_delays ();
4574 /* Handle the .abicalls pseudo-op. I believe this is equivalent to
4575 .option pic2. It means to generate SVR4 PIC calls. */
4582 demand_empty_rest_of_line ();
4585 /* Handle the .cpload pseudo-op. This is used when generating SVR4
4586 PIC code. It sets the $gp register for the function based on the
4587 function address, which is in the register named in the argument.
4588 This uses a relocation against _gp_disp, which is handled specially
4589 by the linker. The result is:
4590 lui $gp,%hi(_gp_disp)
4591 addiu $gp,$gp,%lo(_gp_disp)
4592 addu $gp,$gp,.cpload argument
4593 The .cpload argument is normally $25 or $t9. */
4603 ex
.X_add_symbol
= symbol_find_or_make ("_gp_disp");
4604 ex
.X_op_symbol
= NULL
;
4605 ex
.X_add_number
= 0;
4607 macro_build_lui (&icnt
, &ex
, GP
);
4608 macro_build (&icnt
, &ex
, "addiu", "t,r,j", GP
, GP
,
4609 (int) BFD_RELOC_LO16
);
4611 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t", GP
, GP
,
4612 tc_get_register ());
4614 demand_empty_rest_of_line ();
4617 /* Handle the .cprestore pseudo-op. This stores $gp into a given
4618 offset from $sp. The offset is remembered, and after making a PIC
4619 call $gp is restored from that location. */
4622 s_cprestore (ignore
)
4628 mips_cprestore_offset
= get_absolute_expression ();
4630 ex
.X_op
= O_constant
;
4631 ex
.X_add_symbol
= NULL
;
4632 ex
.X_op_symbol
= NULL
;
4633 ex
.X_add_number
= mips_cprestore_offset
;
4635 macro_build (&icnt
, &ex
,
4636 mips_isa
< 3 ? "sw" : "sd",
4637 "t,o(b)", GP
, (int) BFD_RELOC_LO16
, SP
);
4639 demand_empty_rest_of_line ();
4642 /* Parse a register string into a number. Called from the ECOFF code
4651 if (*input_line_pointer
++ != '$')
4653 as_warn ("expected `$'");
4656 if (isdigit ((unsigned char) *input_line_pointer
))
4658 reg
= get_absolute_expression ();
4659 if (reg
< 0 || reg
>= 32)
4661 as_warn ("Bad register number");
4667 if (strncmp (input_line_pointer
, "fp", 2) == 0)
4669 else if (strncmp (input_line_pointer
, "sp", 2) == 0)
4671 else if (strncmp (input_line_pointer
, "gp", 2) == 0)
4673 else if (strncmp (input_line_pointer
, "at", 2) == 0)
4677 as_warn ("Unrecognized register name");
4680 input_line_pointer
+= 2;
4686 * Translate internal representation of relocation info to BFD target format.
4689 tc_gen_reloc (section
, fixp
)
4695 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
4696 assert (reloc
!= 0);
4698 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
4699 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4700 if (fixp
->fx_pcrel
== 0)
4701 reloc
->addend
= fixp
->fx_addnumber
;
4706 reloc
->addend
= -reloc
->address
;
4708 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4709 if (reloc
->howto
== NULL
)
4711 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4712 "Can not represent relocation in this object file format");
4719 /* should never be called */
4721 md_section_align (seg
, addr
)
4725 int align
= bfd_get_section_alignment (stdoutput
, seg
);
4727 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
4731 md_estimate_size_before_relax (fragP
, segtype
)
4735 as_fatal ("md_estimate_size_before_relax");
4737 } /* md_estimate_size_before_relax() */
4739 /* This function is called whenever a label is defined. It is used
4740 when handling branch delays; if a branch has a label, we assume we
4744 mips_define_label (sym
)
4752 /* Write out the .reginfo section for a MIPS ELF file. */
4755 mips_elf_final_processing ()
4759 s
.ri_gprmask
= mips_gprmask
;
4760 s
.ri_cprmask
[0] = mips_cprmask
[0];
4761 s
.ri_cprmask
[1] = mips_cprmask
[1];
4762 s
.ri_cprmask
[2] = mips_cprmask
[2];
4763 s
.ri_cprmask
[3] = mips_cprmask
[3];
4764 /* The gp_value field is set by the MIPS ELF backend. */
4766 bfd_mips_elf32_swap_reginfo_out (stdoutput
, &s
,
4767 ((Elf32_External_RegInfo
*)
4768 mips_regmask_frag
));
4771 #endif /* OBJ_ELF */
4775 /* These functions should really be defined by the object file format,
4776 since they are related to debugging information. However, this
4777 code has to work for the a.out format, which does not define them,
4778 so we provide simple versions here. These don't actually generate
4779 any debugging information, but they do simple checking and someday
4780 somebody may make them useful. */
4784 struct loc
*loc_next
;
4785 unsigned long loc_fileno
;
4786 unsigned long loc_lineno
;
4787 unsigned long loc_offset
;
4788 unsigned short loc_delta
;
4789 unsigned short loc_count
;
4798 struct proc
*proc_next
;
4799 struct symbol
*proc_isym
;
4800 struct symbol
*proc_end
;
4801 unsigned long proc_reg_mask
;
4802 unsigned long proc_reg_offset
;
4803 unsigned long proc_fpreg_mask
;
4804 unsigned long proc_fpreg_offset
;
4805 unsigned long proc_frameoffset
;
4806 unsigned long proc_framereg
;
4807 unsigned long proc_pcreg
;
4809 struct file
*proc_file
;
4816 struct file
*file_next
;
4817 unsigned long file_fileno
;
4818 struct symbol
*file_symbol
;
4819 struct symbol
*file_end
;
4820 struct proc
*file_proc
;
4825 static struct obstack proc_frags
;
4826 static procS
*proc_lastP
;
4827 static procS
*proc_rootP
;
4828 static int numprocs
;
4833 obstack_begin (&proc_frags
, 0x2000);
4839 /* check for premature end, nesting errors, etc */
4840 if (proc_lastP
&& proc_lastP
->proc_end
== NULL
)
4841 as_warn ("missing `.end' at end of assembly");
4844 extern char hex_value
[];
4852 if (*input_line_pointer
== '-')
4854 ++input_line_pointer
;
4857 if (!isdigit (*input_line_pointer
))
4858 as_bad ("Expected simple number.");
4859 if (input_line_pointer
[0] == '0')
4861 if (input_line_pointer
[1] == 'x')
4863 input_line_pointer
+= 2;
4864 while (isxdigit (*input_line_pointer
))
4867 val
|= hex_value
[(int) *input_line_pointer
++];
4869 return negative
? -val
: val
;
4873 ++input_line_pointer
;
4874 while (isdigit (*input_line_pointer
))
4877 val
|= *input_line_pointer
++ - '0';
4879 return negative
? -val
: val
;
4882 if (!isdigit (*input_line_pointer
))
4884 printf (" *input_line_pointer == '%c' 0x%02x\n",
4885 *input_line_pointer
, *input_line_pointer
);
4886 as_warn ("Invalid number");
4889 while (isdigit (*input_line_pointer
))
4892 val
+= *input_line_pointer
++ - '0';
4894 return negative
? -val
: val
;
4897 /* The .file directive; just like the usual .file directive, but there
4898 is an initial number which is the ECOFF file index. */
4906 line
= get_number ();
4911 /* The .end directive. */
4919 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4922 demand_empty_rest_of_line ();
4926 if (now_seg
!= text_section
)
4927 as_warn (".end not in text section");
4930 as_warn (".end and no .ent seen yet.");
4936 assert (S_GET_NAME (p
));
4937 if (strcmp (S_GET_NAME (p
), S_GET_NAME (proc_lastP
->proc_isym
)))
4938 as_warn (".end symbol does not match .ent symbol.");
4941 proc_lastP
->proc_end
= (symbolS
*) 1;
4944 /* The .aent and .ent directives. */
4954 symbolP
= get_symbol ();
4955 if (*input_line_pointer
== ',')
4956 input_line_pointer
++;
4958 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4959 number
= get_number ();
4960 if (now_seg
!= text_section
)
4961 as_warn (".ent or .aent not in text section.");
4963 if (!aent
&& proc_lastP
&& proc_lastP
->proc_end
== NULL
)
4964 as_warn ("missing `.end'");
4968 procP
= (procS
*) obstack_alloc (&proc_frags
, sizeof (*procP
));
4969 procP
->proc_isym
= symbolP
;
4970 procP
->proc_reg_mask
= 0;
4971 procP
->proc_reg_offset
= 0;
4972 procP
->proc_fpreg_mask
= 0;
4973 procP
->proc_fpreg_offset
= 0;
4974 procP
->proc_frameoffset
= 0;
4975 procP
->proc_framereg
= 0;
4976 procP
->proc_pcreg
= 0;
4977 procP
->proc_end
= NULL
;
4978 procP
->proc_next
= NULL
;
4980 proc_lastP
->proc_next
= procP
;
4986 demand_empty_rest_of_line ();
4989 /* The .frame directive. */
5002 frame_reg
= tc_get_register ();
5003 if (*input_line_pointer
== ',')
5004 input_line_pointer
++;
5005 frame_off
= get_absolute_expression ();
5006 if (*input_line_pointer
== ',')
5007 input_line_pointer
++;
5008 pcreg
= tc_get_register ();
5011 assert (proc_rootP
);
5012 proc_rootP
->proc_framereg
= frame_reg
;
5013 proc_rootP
->proc_frameoffset
= frame_off
;
5014 proc_rootP
->proc_pcreg
= pcreg
;
5015 /* bob macho .frame */
5017 /* We don't have to write out a frame stab for unoptimized code. */
5018 if (!(frame_reg
== FP
&& frame_off
== 0))
5021 as_warn ("No .ent for .frame to use.");
5022 (void) sprintf (str
, "R%d;%d", frame_reg
, frame_off
);
5023 symP
= symbol_new (str
, N_VFP
, 0, frag_now
);
5024 S_SET_TYPE (symP
, N_RMASK
);
5025 S_SET_OTHER (symP
, 0);
5026 S_SET_DESC (symP
, 0);
5027 symP
->sy_forward
= proc_lastP
->proc_isym
;
5028 /* bob perhaps I should have used pseudo set */
5030 demand_empty_rest_of_line ();
5034 /* The .fmask and .mask directives. */
5041 char str
[100], *strP
;
5047 mask
= get_number ();
5048 if (*input_line_pointer
== ',')
5049 input_line_pointer
++;
5050 off
= get_absolute_expression ();
5052 /* bob only for coff */
5053 assert (proc_rootP
);
5054 if (reg_type
== 'F')
5056 proc_rootP
->proc_fpreg_mask
= mask
;
5057 proc_rootP
->proc_fpreg_offset
= off
;
5061 proc_rootP
->proc_reg_mask
= mask
;
5062 proc_rootP
->proc_reg_offset
= off
;
5065 /* bob macho .mask + .fmask */
5067 /* We don't have to write out a mask stab if no saved regs. */
5071 as_warn ("No .ent for .mask to use.");
5073 for (i
= 0; i
< 32; i
++)
5077 sprintf (strP
, "%c%d,", reg_type
, i
);
5078 strP
+= strlen (strP
);
5082 sprintf (strP
, ";%d,", off
);
5083 symP
= symbol_new (str
, N_RMASK
, 0, frag_now
);
5084 S_SET_TYPE (symP
, N_RMASK
);
5085 S_SET_OTHER (symP
, 0);
5086 S_SET_DESC (symP
, 0);
5087 symP
->sy_forward
= proc_lastP
->proc_isym
;
5088 /* bob perhaps I should have used pseudo set */
5093 /* The .loc directive. */
5104 assert (now_seg
== text_section
);
5106 lineno
= get_number ();
5107 addroff
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
5109 symbolP
= symbol_new ("", N_SLINE
, addroff
, frag_now
);
5110 S_SET_TYPE (symbolP
, N_SLINE
);
5111 S_SET_OTHER (symbolP
, 0);
5112 S_SET_DESC (symbolP
, lineno
);
5113 symbolP
->sy_segment
= now_seg
;
5117 #endif /* ! defined (OBJ_ECOFF) */