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 support by Ian Lance Taylor of Cygnus Support.
7 This file is part of GAS.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
38 #endif /* NO_VARARGS */
39 #endif /* NO_STDARG */
41 #include "opcode/mips.h"
47 static int mips_warn_about_macros
;
48 static int mips_noreorder
;
49 static int mips_nomove
;
51 static int mips_nobopt
;
54 /* The size of the small data section. */
55 static int g_switch_value
= 8;
61 /* handle of the OPCODE hash table */
62 static struct hash_control
*op_hash
= NULL
;
64 /* This array holds the chars that always start a comment. If the
65 pre-processor is disabled, these aren't very useful */
66 const char comment_chars
[] = "#";
68 /* This array holds the chars that only start a comment at the beginning of
69 a line. If the line seems to have the form '# 123 filename'
70 .line and .file directives will appear in the pre-processed output */
71 /* Note that input_file.c hand checks for '#' at the beginning of the
72 first line of the input file. This is because the compiler outputs
73 #NO_APP at the beginning of its output. */
74 /* Also note that C style comments are always supported. */
75 const char line_comment_chars
[] = "#";
77 /* This array holds machine specific line separator characters. */
78 const char line_separator_chars
[] = "";
80 /* Chars that can be used to separate mant from exp in floating point nums */
81 const char EXP_CHARS
[] = "eE";
83 /* Chars that mean this number is a floating point constant */
86 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
88 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
89 changed in read.c . Ideally it shouldn't have to know about it at all,
90 but nothing is ideal around here.
93 static char *insn_error
;
95 static int byte_order
= BYTE_ORDER
;
97 static int auto_align
= 1;
99 /* Prototypes for static functions. */
102 #define internalError() \
103 as_fatal ("internal Error, line %d, %s", __LINE__, __FILE__)
105 #define internalError() as_fatal ("MIPS internal Error");
108 static void append_insn
PARAMS ((struct mips_cl_insn
* ip
,
110 bfd_reloc_code_real_type r
));
111 static int gp_reference
PARAMS ((expressionS
* ep
));
112 static void macro_build
PARAMS ((int *counter
, expressionS
* ep
,
113 const char *name
, const char *fmt
,
115 static void macro_build_lui
PARAMS ((int *counter
, expressionS
* ep
,
117 static void set_at
PARAMS ((int *counter
, int reg
));
118 static void set_at_unsigned
PARAMS ((int *counter
, int reg
));
119 static void check_absolute_expr
PARAMS ((struct mips_cl_insn
* ip
,
120 expressionS
* expr
));
121 static void load_register
PARAMS ((int *counter
,
122 struct mips_cl_insn
* ip
,
123 int reg
, expressionS
* ep
));
124 static void macro
PARAMS ((struct mips_cl_insn
* ip
));
125 static void mips_ip
PARAMS ((char *str
, struct mips_cl_insn
* ip
));
126 static int my_getSmallExpression
PARAMS ((expressionS
* ep
, char *str
));
127 static void my_getExpression
PARAMS ((expressionS
* ep
, char *str
));
128 static symbolS
*get_symbol
PARAMS ((void));
129 static long get_optional_absolute_expression
PARAMS ((void));
130 static void s_align
PARAMS ((int));
131 static void s_change_sec
PARAMS ((int));
132 static void s_cons
PARAMS ((int));
133 static void s_err
PARAMS ((int));
134 static void s_extern
PARAMS ((int));
135 static void s_float_cons
PARAMS ((int));
136 static void s_option
PARAMS ((int));
137 static void s_mipsset
PARAMS ((int));
139 static void md_obj_begin
PARAMS ((void));
140 static void md_obj_end
PARAMS ((void));
141 static long get_number
PARAMS ((void));
142 static void s_ent
PARAMS ((int));
143 static void s_mipsend
PARAMS ((int));
144 static void s_file
PARAMS ((int));
145 static void s_frame
PARAMS ((int));
146 static void s_loc
PARAMS ((int));
147 static void s_mask
PARAMS ((char));
152 The following pseudo-ops from the Kane and Heinrich MIPS book
153 should be defined here, but are currently unsupported: .alias,
154 .galive, .gjaldef, .gjrlive, .livereg, .noalias.
156 The following pseudo-ops from the Kane and Heinrich MIPS book are
157 specific to the type of debugging information being generated, and
158 should be defined by the object format: .aent, .begin, .bend,
159 .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
162 The following pseudo-ops from the Kane and Heinrich MIPS book are
163 not MIPS CPU specific, but are also not specific to the object file
164 format. This file is probably the best place to define them, but
165 they are not currently supported: .asm0, .endr, .lab, .repeat,
166 .struct, .weakext. */
168 const pseudo_typeS md_pseudo_table
[] =
170 /* MIPS specific pseudo-ops. */
171 {"option", s_option
, 0},
172 {"set", s_mipsset
, 0},
173 {"rdata", s_change_sec
, 'r',},
174 {"sdata", s_change_sec
, 's',},
176 /* Relatively generic pseudo-ops that happen to be used on MIPS
178 {"asciiz", stringer
, 1},
179 {"bss", s_change_sec
, 'b'},
183 /* These pseudo-ops are defined in read.c, but must be overridden
184 here for one reason or another. */
185 {"align", s_align
, 0},
187 {"data", s_change_sec
, 'd'},
188 {"double", s_float_cons
, 1},
189 {"extern", s_extern
, 0},
190 {"float", s_float_cons
, 0},
191 {"text", s_change_sec
, 't'},
195 /* These pseudo-ops should be defined by the object file format.
196 However, ECOFF is the only format which currently defines them,
197 so we have versions here for a.out. */
199 {"end", s_mipsend
, 0},
202 {"fmask", s_ignore
, 'F'},
203 {"frame", s_ignore
, 0},
204 {"loc", s_ignore
, 0},
205 {"mask", s_ignore
, 'R'},
206 {"verstamp", s_ignore
, 0},
213 const relax_typeS md_relax_table
[] =
219 static char *expr_end
;
221 static expressionS imm_expr
;
222 static expressionS offset_expr
;
223 static bfd_reloc_code_real_type imm_reloc
;
224 static bfd_reloc_code_real_type offset_reloc
;
227 * This function is called once, at assembler startup time. It should
228 * set up all the tables, etc. that the MD part of the assembler will need.
233 register char *retval
= NULL
;
234 register unsigned int i
= 0;
236 if ((op_hash
= hash_new ()) == NULL
)
238 as_fatal ("Virtual memory exhausted");
240 for (i
= 0; i
< NUMOPCODES
;)
242 const char *name
= mips_opcodes
[i
].name
;
244 retval
= hash_insert (op_hash
, name
, &mips_opcodes
[i
]);
245 if (retval
!= NULL
&& *retval
!= '\0')
247 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
248 mips_opcodes
[i
].name
, retval
);
249 as_fatal ("Broken assembler. No assembly attempted.");
253 if ((mips_opcodes
[i
].match
& mips_opcodes
[i
].mask
) !=
254 mips_opcodes
[i
].match
)
256 fprintf (stderr
, "internal error: bad opcode: `%s' \"%s\"\n",
257 mips_opcodes
[i
].name
, mips_opcodes
[i
].args
);
258 as_fatal ("Broken assembler. No assembly attempted.");
262 while ((i
< NUMOPCODES
) && !strcmp (mips_opcodes
[i
].name
, name
));
282 struct mips_cl_insn insn
;
287 /* set the default alignment for the text section (2**2) */
288 /* This should go in md_begin but text_section isn't initialized then */
289 record_alignment (text_section
, 2);
291 bfd_set_gp_size (stdoutput
, g_switch_value
);
296 imm_expr
.X_seg
= absent_section
;
297 offset_expr
.X_seg
= absent_section
;
299 mips_ip (str
, &insn
);
302 as_bad ("%s `%s'", insn_error
, str
);
305 if (insn
.insn_mo
->pinfo
== INSN_MACRO
)
311 if (imm_expr
.X_seg
!= absent_section
)
312 append_insn (&insn
, &imm_expr
, imm_reloc
);
313 else if (offset_expr
.X_seg
!= absent_section
)
314 append_insn (&insn
, &offset_expr
, offset_reloc
);
316 append_insn (&insn
, NULL
, BFD_RELOC_UNUSED
);
320 #define ALIGN_ERR "Attempt to assemble instruction onto non word boundary."
321 #define ALIGN_ERR2 "GAS doesn't do implicit alignment; use .align directive."
325 * Output an instruction.
328 append_insn (ip
, address_expr
, reloc_type
)
329 struct mips_cl_insn
*ip
;
330 expressionS
*address_expr
;
331 bfd_reloc_code_real_type reloc_type
;
336 #if 0 /* This is testing the address of the frag, not the alignment of
337 the instruction in the current section. */
344 if (address_expr
!= NULL
)
348 if (address_expr
->X_seg
== &bfd_abs_section
)
353 ip
->insn_opcode
|= address_expr
->X_add_number
;
357 ip
->insn_opcode
|= address_expr
->X_add_number
& 0xffff;
360 case BFD_RELOC_MIPS_JMP
:
361 case BFD_RELOC_16_PCREL_S2
:
370 assert (reloc_type
!= BFD_RELOC_UNUSED
);
372 fixP
= fix_new (frag_now
, f
- frag_now
->fr_literal
, 4,
373 address_expr
->X_add_symbol
,
374 address_expr
->X_subtract_symbol
,
375 address_expr
->X_add_number
,
376 reloc_type
== BFD_RELOC_16_PCREL_S2
,
380 md_number_to_chars (f
, ip
->insn_opcode
, 4);
383 * Fill all delay slots with nops.
387 if (ip
->insn_mo
->pinfo
& ANY_DELAY
)
390 md_number_to_chars (f
, 0, 4);
394 if (ip
->insn_mo
->pinfo
& (INSN_READ_HI
| INSN_READ_LO
))
397 md_number_to_chars (f
, 0, 4);
402 /* Return 1 if an expression can be accessed via the GP register. */
413 sym
= ep
->X_add_symbol
;
414 if (sym
== (symbolS
*) NULL
415 || ep
->X_subtract_symbol
!= (symbolS
*) NULL
)
418 /* Certain symbols can not be referenced off the GP, although it
419 appears as though they can. */
420 symname
= S_GET_NAME (sym
);
421 if (symname
!= (const char *) NULL
422 && (strcmp (symname
, "eprol") == 0
423 || strcmp (symname
, "etext") == 0
424 || strcmp (symname
, "_gp") == 0
425 || strcmp (symname
, "edata") == 0
426 || strcmp (symname
, "_fbss") == 0
427 || strcmp (symname
, "_fdata") == 0
428 || strcmp (symname
, "_ftext") == 0
429 || strcmp (symname
, "end") == 0))
431 if (! S_IS_DEFINED (sym
)
432 && S_GET_VALUE (sym
) != 0
433 && S_GET_VALUE (sym
) <= g_switch_value
)
435 segname
= segment_name (S_GET_SEGMENT (ep
->X_add_symbol
));
436 return (strcmp (segname
, ".sdata") == 0
437 || strcmp (segname
, ".sbss") == 0);
438 #else /* ! defined (OBJ_ECOFF) */
439 /* The GP register is only used for ECOFF. */
441 #endif /* ! defined (OBJ_ECOFF) */
444 /* Build an instruction created by a macro expansion. This is passed
445 a pointer to the count of instructions created so far, an
446 expression, the name of the instruction to build, an operand format
447 string, and corresponding arguments. */
451 macro_build (int *counter
,
456 #else /* ! defined (NO_STDARG) */
458 macro_build (counter
, ep
, name
, fmt
, va_alist
)
464 #endif /* ! defined (NO_STDARG) */
466 struct mips_cl_insn insn
;
467 bfd_reloc_code_real_type r
;
471 va_start (args
, fmt
);
477 * If the macro is about to expand into a second instruction,
478 * print a warning if needed. We need to pass ip as a parameter
479 * to generate a better warning message here...
481 if (mips_warn_about_macros
&& *counter
== 1)
482 as_warn ("Macro instruction expanded into multiple instructions");
484 *counter
+= 1; /* bump instruction counter */
486 r
= BFD_RELOC_UNUSED
;
487 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
488 assert (insn
.insn_mo
);
489 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
491 while (strcmp (fmt
, insn
.insn_mo
->args
) != 0)
494 assert (insn
.insn_mo
->name
);
495 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
497 assert (insn
.insn_mo
->pinfo
!= INSN_MACRO
);
498 insn
.insn_opcode
= insn
.insn_mo
->match
;
514 insn
.insn_opcode
|= va_arg (args
, int) << 16;
520 insn
.insn_opcode
|= va_arg (args
, int) << 16;
525 insn
.insn_opcode
|= va_arg (args
, int) << 11;
530 insn
.insn_opcode
|= va_arg (args
, int) << 11;
534 insn
.insn_opcode
|= va_arg (args
, int) << 6;
538 insn
.insn_opcode
|= va_arg (args
, int) << 6;
542 insn
.insn_opcode
|= va_arg (args
, int) << 6;
549 insn
.insn_opcode
|= va_arg (args
, int) << 21;
561 * This allows macro() to pass an immediate expression for
562 * creating short branches without creating a symbol.
563 * Note that the expression still might come from the assembly
564 * input, in which case the value is not checked for range nor
565 * is a relocation entry generated (yuck).
567 if (ep
->X_add_symbol
== NULL
&& ep
->X_seg
== &bfd_abs_section
)
569 insn
.insn_opcode
|= (ep
->X_add_number
>> 2) & 0xffff;
573 r
= BFD_RELOC_16_PCREL_S2
;
582 assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
584 /* Use GP relative addressing if possible. */
585 if (r
== BFD_RELOC_LO16
586 && gp_reference (ep
))
587 r
= BFD_RELOC_MIPS_GPREL
;
589 append_insn (&insn
, ep
, r
);
593 * Generate a "lui" instruction.
596 macro_build_lui (counter
, ep
, regnum
)
601 expressionS high_expr
;
602 struct mips_cl_insn insn
;
603 bfd_reloc_code_real_type r
;
604 CONST
char *name
= "lui";
605 CONST
char *fmt
= "t,u";
609 if (high_expr
.X_seg
== &bfd_abs_section
)
611 /* we can compute the instruction now without a relocation entry */
612 if (high_expr
.X_add_number
& 0x8000)
613 high_expr
.X_add_number
+= 0x10000;
614 high_expr
.X_add_number
=
615 ((unsigned long) high_expr
.X_add_number
>> 16) & 0xffff;
616 r
= BFD_RELOC_UNUSED
;
619 r
= BFD_RELOC_HI16_S
;
622 * If the macro is about to expand into a second instruction,
623 * print a warning if needed. We need to pass ip as a parameter
624 * to generate a better warning message here...
626 if (mips_warn_about_macros
&& *counter
== 1)
627 as_warn ("Macro instruction expanded into multiple instructions");
629 *counter
+= 1; /* bump instruction counter */
631 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
632 assert (insn
.insn_mo
);
633 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
634 assert (strcmp (fmt
, insn
.insn_mo
->args
) == 0);
636 insn
.insn_opcode
= insn
.insn_mo
->match
| (regnum
<< 16);
637 if (r
== BFD_RELOC_UNUSED
)
639 insn
.insn_opcode
|= high_expr
.X_add_number
;
640 append_insn (&insn
, NULL
, r
);
643 append_insn (&insn
, &high_expr
, r
);
647 * Generates code to set the $at register to true (one)
648 * if reg is less than the immediate expression.
651 set_at (counter
, reg
)
656 switch (imm_expr
.X_add_number
& 0xffff8000)
660 macro_build (counter
, &imm_expr
, "slti", "t,r,j", AT
, reg
);
664 macro_build (counter
, &imm_expr
, "ori", "t,r,i", AT
, 0);
668 macro_build_lui (counter
, &imm_expr
, AT
);
669 if (imm_expr
.X_add_number
& 0xffff)
670 macro_build (counter
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
672 macro_build (counter
, NULL
, "slt", "d,v,t", AT
, reg
, AT
);
676 * Generates code to set the $at register to true (one)
677 * if reg is less than the immediate expression.
678 * Unsigned comparison is perfomed.
681 set_at_unsigned (counter
, reg
)
686 switch (imm_expr
.X_add_number
& 0xffff8000)
690 macro_build (counter
, &imm_expr
, "sltiu", "t,r,j", AT
, reg
);
694 macro_build (counter
, &imm_expr
, "ori", "t,r,i", AT
, 0);
698 macro_build_lui (counter
, &imm_expr
, AT
);
699 if (imm_expr
.X_add_number
& 0xffff)
700 macro_build (counter
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
702 macro_build (counter
, NULL
, "sltu", "d,v,t", AT
, reg
, AT
);
706 check_absolute_expr (ip
, expr
)
707 struct mips_cl_insn
*ip
;
711 if (expr
->X_seg
!= &bfd_abs_section
)
712 as_warn ("Instruction %s requires absolute expression", ip
->insn_mo
->name
);
716 * This routine generates the least number of instructions neccessary to load
717 * an absolute expression value into a register.
720 load_register (counter
, ip
, reg
, ep
)
722 struct mips_cl_insn
*ip
;
726 switch (ep
->X_add_number
& 0xffff8000)
730 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, 0);
734 macro_build (counter
, ep
, "ori", "t,r,i", reg
, 0);
738 macro_build_lui (counter
, ep
, reg
);
739 if (ep
->X_add_number
& 0xffff)
740 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, reg
);
747 * This routine implements the seemingly endless macro or synthesized
748 * instructions and addressing modes in the mips assembly language. Many
749 * of these macros are simple and are similar to each other. These could
750 * probably be handled by some kind of table or grammer aproach instead of
751 * this verbose method. Others are not simple macros but are more like
752 * optimizing code generation.
753 * One interesting optimization is when several store macros appear
754 * consecutivly that would load AT with the upper half of the same address.
755 * The ensuing load upper instructions are ommited. This implies some kind
756 * of global optimization. We currently only optimize within a single macro.
757 * For many of the load and store macros if the address is specified as a
758 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
759 * first load register 'at' with zero and use it as the base register. The
760 * mips assembler simply uses register $zero. Just one tiny optimization
765 struct mips_cl_insn
*ip
;
767 register int treg
, sreg
, dreg
, breg
;
772 int save_reorder_condition
;
777 treg
= (ip
->insn_opcode
>> 16) & 0x1f;
778 dreg
= (ip
->insn_opcode
>> 11) & 0x1f;
779 sreg
= breg
= (ip
->insn_opcode
>> 21) & 0x1f;
780 mask
= ip
->insn_mo
->mask
;
782 expr1
.X_seg
= &bfd_abs_section
;
783 expr1
.X_subtract_symbol
= NULL
;
784 expr1
.X_add_symbol
= NULL
;
785 expr1
.X_add_number
= 1;
792 Note: mips algorithm requires the move in the delay slot.
793 <main>: bgez $a0,0x4001bc <main+12>
794 <main+4>: move v0,$a0
795 <main+8>: sub v0,$zero,$a0
799 save_reorder_condition
= mips_noreorder
;
802 expr1
.X_add_number
= 8;
803 macro_build (&icnt
, &expr1
, "bgez", "s,p", sreg
);
804 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
, 0);
805 macro_build (&icnt
, NULL
, mask
== M_ABS
? "sub" : "subu", "d,v,t",
808 mips_noreorder
= save_reorder_condition
;
813 switch (imm_expr
.X_add_number
& 0xffff8000)
817 macro_build (&icnt
, &imm_expr
,
818 mask
== M_ADD_I
? "addi" : "addiu", "t,r,j", treg
, sreg
);
822 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", AT
, 0);
826 macro_build_lui (&icnt
, &imm_expr
, AT
);
827 if (imm_expr
.X_add_number
& 0xffff)
828 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
831 macro_build (&icnt
, NULL
,
832 mask
== M_ADD_I
? "add" : "addu", "d,v,t", treg
, sreg
, AT
);
839 switch (imm_expr
.X_add_number
& 0xffff8000)
846 macro_build (&icnt
, &imm_expr
, "andi", "t,r,i", treg
, sreg
);
849 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
);
852 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
);
853 macro_build (&icnt
, &imm_expr
, "nor", "d,v,t", treg
, treg
, 0);
856 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", treg
, sreg
);
863 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, 0);
867 macro_build_lui (&icnt
, &imm_expr
, AT
);
868 if (imm_expr
.X_add_number
& 0xffff)
869 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
874 macro_build (&icnt
, NULL
, "and", "d,v,t", treg
, sreg
, AT
);
877 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, sreg
, AT
);
880 macro_build (&icnt
, NULL
, "nor", "d,v,t", treg
, sreg
, AT
);
883 macro_build (&icnt
, NULL
, "xor", "d,v,t", treg
, sreg
, AT
);
892 if (imm_expr
.X_add_number
== 0)
894 macro_build (&icnt
, &offset_expr
, mask
== M_BEQ_I
? "beq" : "bne",
898 load_register (&icnt
, ip
, AT
, &imm_expr
);
899 macro_build (&icnt
, &offset_expr
, mask
== M_BEQ_I
? "beq" : "bne",
906 macro_build (&icnt
, &offset_expr
, "bgez", "s,p", sreg
);
911 macro_build (&icnt
, &offset_expr
, "blez", "s,p", treg
);
914 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
915 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
919 /* check for > max integer */
920 if (imm_expr
.X_add_number
== 0x7fffffff)
923 /* result is always false */
924 as_warn ("Branch %s is always false (nop)", ip
->insn_mo
->name
);
925 macro_build (&icnt
, NULL
, "nop", "", 0);
928 imm_expr
.X_add_number
++;
932 if (imm_expr
.X_add_number
== 0)
934 macro_build (&icnt
, &offset_expr
, "bgez", "s,p", sreg
);
937 if (imm_expr
.X_add_number
== 1)
939 macro_build (&icnt
, &offset_expr
, "bgtz", "s,p", sreg
);
942 if (imm_expr
.X_add_number
== 0x80000000)
945 /* result is always true */
946 as_warn ("Branch %s is always true", ip
->insn_mo
->name
);
947 macro_build (&icnt
, &offset_expr
, "b", "p");
950 set_at (&icnt
, sreg
);
951 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
959 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", 0, treg
);
962 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
963 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
967 if (sreg
== 0 || imm_expr
.X_add_number
== 0xffffffff)
969 imm_expr
.X_add_number
++;
973 if (imm_expr
.X_add_number
== 0)
975 if (imm_expr
.X_add_number
== 1)
977 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", sreg
, 0);
980 set_at_unsigned (&icnt
, sreg
);
981 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
987 macro_build (&icnt
, &offset_expr
, "bgtz", "s,p", sreg
);
992 macro_build (&icnt
, &offset_expr
, "bltz", "s,p", treg
);
995 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
996 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1002 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", sreg
, 0);
1007 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1008 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1014 macro_build (&icnt
, &offset_expr
, "blez", "s,p", sreg
);
1019 macro_build (&icnt
, &offset_expr
, "bgez", "s,p", treg
);
1022 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1023 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
1027 if (imm_expr
.X_add_number
== 0x7fffffff)
1029 imm_expr
.X_add_number
++;
1033 if (imm_expr
.X_add_number
== 0)
1035 macro_build (&icnt
, &offset_expr
, "bltz", "s,p", sreg
);
1038 if (imm_expr
.X_add_number
== 1)
1040 macro_build (&icnt
, &offset_expr
, "blez", "s,p", sreg
);
1043 set_at (&icnt
, sreg
);
1044 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1050 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", sreg
, 0);
1055 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1056 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
1060 if (sreg
== 0 || imm_expr
.X_add_number
== 0xffffffff)
1062 imm_expr
.X_add_number
++;
1066 if (imm_expr
.X_add_number
== 0)
1068 if (imm_expr
.X_add_number
== 1)
1070 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", sreg
, 0);
1073 set_at_unsigned (&icnt
, sreg
);
1074 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1080 macro_build (&icnt
, &offset_expr
, "bltz", "s,p", sreg
);
1085 macro_build (&icnt
, &offset_expr
, "bgtz", "s,p", treg
);
1088 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1089 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1097 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", 0, treg
);
1100 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1101 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1108 as_warn ("Divide by zero.");
1109 macro_build (&icnt
, NULL
, "break", "c", 7);
1113 save_reorder_condition
= mips_noreorder
;
1115 macro_build (&icnt
, NULL
, "div", "s,t", sreg
, treg
);
1116 expr1
.X_add_number
= 8;
1117 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1118 macro_build (&icnt
, NULL
, "nop", "", 0);
1119 macro_build (&icnt
, NULL
, "break", "c", 7);
1120 expr1
.X_add_number
= -1;
1121 macro_build (&icnt
, &expr1
, "addiu", "t,r,j", AT
, 0);
1122 expr1
.X_add_number
= 16;
1123 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, AT
);
1124 expr1
.X_add_number
= 0x80000000;
1125 macro_build_lui (&icnt
, &expr1
, AT
);
1126 expr1
.X_add_number
= 8;
1127 macro_build (&icnt
, &expr1
, "bne", "s,t,p", sreg
, AT
);
1128 macro_build (&icnt
, NULL
, "nop", "", 0);
1129 macro_build (&icnt
, NULL
, "break", "c", 6);
1130 mips_noreorder
= save_reorder_condition
;
1131 macro_build (&icnt
, NULL
, mask
== M_DIV_3
? "mflo" : "mfhi", "d", dreg
);
1132 /* with reorder on there will be two implicit nop instructions here. */
1139 if (imm_expr
.X_add_number
== 0)
1141 as_warn ("Divide by zero.");
1142 macro_build (&icnt
, NULL
, "break", "c", 7);
1145 if (imm_expr
.X_add_number
== 1)
1147 if (mask
== (int) M_DIV_3I
|| mask
== (int) M_DIVU_3I
)
1148 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
);
1150 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1154 load_register (&icnt
, ip
, AT
, &imm_expr
);
1155 if (mask
== (int) M_DIV_3I
|| mask
== (int) M_REM_3I
)
1156 macro_build (&icnt
, NULL
, "div", "s,t", sreg
, AT
);
1158 macro_build (&icnt
, NULL
, "divu", "s,t", sreg
, AT
);
1160 if (mask
== (int) M_DIV_3I
|| mask
== (int) M_DIVU_3I
)
1161 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
1163 macro_build (&icnt
, NULL
, "mfhi", "d", dreg
);
1164 /* two implicit nop's required for mflo or mfhi */
1169 save_reorder_condition
= mips_noreorder
;
1171 macro_build (&icnt
, NULL
, "divu", "s,t", sreg
, treg
);
1172 expr1
.X_add_number
= 8;
1173 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1174 macro_build (&icnt
, NULL
, "nop", "", 0);
1175 macro_build (&icnt
, NULL
, "break", "c", 7);
1176 mips_noreorder
= save_reorder_condition
;
1177 macro_build (&icnt
, NULL
, mask
== M_DIVU_3
? "mflo" : "mfhi", "d", dreg
);
1178 /* with reorder on there will be two implicit nop instructions here. */
1182 if (offset_expr
.X_seg
== &bfd_abs_section
)
1184 load_register (&icnt
, ip
, treg
, &offset_expr
);
1187 if (gp_reference (&offset_expr
))
1188 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", treg
, GP
);
1191 macro_build_lui (&icnt
, &offset_expr
, treg
);
1192 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", treg
, treg
);
1197 tempreg
= (breg
== treg
) ? AT
: treg
;
1198 if (offset_expr
.X_seg
== &bfd_abs_section
)
1199 load_register (&icnt
, ip
, tempreg
, &offset_expr
);
1200 else if (gp_reference (&offset_expr
))
1201 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", tempreg
, GP
);
1204 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1205 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", tempreg
, tempreg
);
1208 macro_build (&icnt
, NULL
, "addu", "d,v,t", treg
, tempreg
, breg
);
1246 if (breg
== treg
|| mask
== M_LWC1_AB
)
1287 if (mask
== M_LWC1_AB
|| mask
== M_SWC1_AB
)
1291 if (gp_reference (&offset_expr
))
1295 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, GP
);
1298 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t",
1303 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1305 macro_build (&icnt
, NULL
, "addu", "d,v,t", tempreg
, tempreg
, breg
);
1307 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, tempreg
);
1313 load_register (&icnt
, ip
, treg
, &imm_expr
);
1318 0x400370 <main>: lui $at,%hi(foo)
1319 0x400374 <main+4>: lw $v0,%lo(foo)($at)
1320 0x400378 <main+8>: lw $v1,%lo(foo+4)($at)
1325 /* FIXME: I don't think this is used at present, because the 'F'
1326 format character is not supported. When this is supported,
1327 it should use the GP register. */
1328 macro_build_lui (&icnt
, &offset_expr
, AT
);
1329 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
, AT
);
1330 offset_expr
.X_add_number
= 4;
1331 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
+ 1, AT
);
1336 0x4003a0 <main>: lwc1 $f0,-32752($gp)
1337 0x4003a4 <main+4>: lwc1 $f1,-32748($gp)
1338 0x4003a8 <main+8>: nop
1340 /* FIXME: This is nonsense. It isn't used anyhow. */
1341 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* Fs reg */
1342 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)", treg
, AT
);
1343 offset_expr
.X_add_number
= 4;
1344 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)", treg
+ 1, AT
);
1348 /* Even on a big endian machine $fn comes before $fn+1. We have
1349 to adjust when loading from memory. */
1350 save_reorder_condition
= mips_noreorder
;
1352 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1353 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1355 /* unecessary implicit nop */
1356 mips_noreorder
= save_reorder_condition
;
1357 offset_expr
.X_add_number
+= 4;
1358 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1359 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1365 * The MIPS assembler seems to check for X_add_number not
1366 * being double aligned and generating:
1369 * addiu at,at,%lo(foo+1)
1372 * But, the resulting address is the same after relocation so why
1373 * generate the extra instruction?
1375 if (gp_reference (&offset_expr
))
1381 macro_build (&icnt
, &offset_expr
, "addu", "d,v,t", AT
, breg
, GP
);
1387 macro_build_lui (&icnt
, &offset_expr
, AT
);
1389 macro_build (&icnt
, NULL
, "addu", "d,v,t", AT
, AT
, breg
);
1392 /* Even on a big endian machine $fn comes before $fn+1. We have
1393 to adjust when loading from memory. */
1394 save_reorder_condition
= mips_noreorder
;
1396 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1397 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1399 /* unecessary implicit nop */
1400 mips_noreorder
= save_reorder_condition
;
1401 offset_expr
.X_add_number
+= 4;
1402 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1403 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1415 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
1416 offset_expr
.X_add_number
= 4;
1417 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, breg
);
1438 if (gp_reference (&offset_expr
))
1446 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t",
1451 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1453 macro_build (&icnt
, NULL
, "addu", "d,v,t", tempreg
, tempreg
, breg
);
1455 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, tempreg
);
1456 offset_expr
.X_add_number
+= 4;
1457 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, tempreg
);
1463 macro_build (&icnt
, NULL
, "multu", "s,t", sreg
, treg
);
1464 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
1465 /* two implicit nop's required for mflo */
1470 * The mips assembler some times generates shifts and adds.
1471 * Im not trying to be that fancy. GCC should do this for us
1474 load_register (&icnt
, ip
, AT
, &imm_expr
);
1475 macro_build (&icnt
, NULL
, "mult", "s,t", sreg
, AT
);
1476 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
1477 /* two implicit nop's required for mflo */
1481 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
1482 macro_build (&icnt
, NULL
, "srlv", "d,t,s", AT
, sreg
, AT
);
1483 macro_build (&icnt
, NULL
, "sllv", "d,t,s", dreg
, sreg
, treg
);
1484 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1488 macro_build (&icnt
, NULL
, "sll", "d,w,<", AT
, sreg
,
1489 imm_expr
.X_add_number
& 0x1f);
1490 macro_build (&icnt
, NULL
, "srl", "d,w,<", dreg
, sreg
,
1491 (0 - imm_expr
.X_add_number
) & 0x1f);
1492 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1496 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
1497 macro_build (&icnt
, NULL
, "sllv", "d,t,s", AT
, sreg
, AT
);
1498 macro_build (&icnt
, NULL
, "srlv", "d,t,s", dreg
, sreg
, treg
);
1499 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1503 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, sreg
,
1504 imm_expr
.X_add_number
& 0x1f);
1505 macro_build (&icnt
, NULL
, "sll", "d,w,<", dreg
, sreg
,
1506 (0 - imm_expr
.X_add_number
) & 0x1f);
1507 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1511 /* Even on a big endian machine $fn comes before $fn+1. We have
1512 to adjust when storing to memory. */
1513 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1514 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1516 offset_expr
.X_add_number
+= 4;
1517 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1518 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1523 if (gp_reference (&offset_expr
))
1529 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t",
1536 macro_build_lui (&icnt
, &offset_expr
, AT
);
1538 macro_build (&icnt
, NULL
, "addu", "d,v,t", AT
, AT
, breg
);
1541 /* Even on a big endian machine $fn comes before $fn+1. We have
1542 to adjust when storing to memory. */
1543 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1544 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1546 offset_expr
.X_add_number
+= 4;
1547 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1548 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1556 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, treg
);
1558 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
1561 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
1562 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
1567 if (imm_expr
.X_add_number
== 0)
1569 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
1574 as_warn ("Instruction %s: result is always false",
1576 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1579 switch (imm_expr
.X_add_number
& 0xffff8000)
1583 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
1588 if (imm_expr
.X_add_number
!= -32768)
1590 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1591 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", dreg
, sreg
);
1598 macro_build_lui (&icnt
, &imm_expr
, AT
);
1599 if (imm_expr
.X_add_number
& 0xffff)
1600 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
1601 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
1604 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
1609 case M_SGE
: /* sreg >= treg <==> not (sreg < treg) */
1615 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, sreg
, treg
);
1616 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1619 case M_SGE_I
: /* sreg >= I <==> not (sreg < I) */
1621 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32769)
1623 macro_build (&icnt
, &expr1
,
1624 mask
== M_SGE_I
? "slti" : "sltiu", "t,r,j", dreg
, sreg
);
1629 load_register (&icnt
, ip
, AT
, &imm_expr
);
1630 macro_build (&icnt
, NULL
,
1631 mask
== M_SGE_I
? "slt" : "sltu", "d,v,t", dreg
, sreg
, AT
);
1634 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1639 case M_SGT
: /* sreg > treg <==> treg < sreg */
1645 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
1648 case M_SGT_I
: /* sreg > I <==> I < sreg */
1654 load_register (&icnt
, ip
, AT
, &imm_expr
);
1655 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
1658 case M_SLE
: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
1664 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
1665 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1668 case M_SLE_I
: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
1674 load_register (&icnt
, ip
, AT
, &imm_expr
);
1675 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
1676 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1680 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32769)
1682 macro_build (&icnt
, &imm_expr
, "slti", "t,r,j", dreg
, sreg
);
1685 load_register (&icnt
, ip
, AT
, &imm_expr
);
1686 macro_build (&icnt
, NULL
, "slt", "d,v,t", dreg
, sreg
, AT
);
1690 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32769)
1692 macro_build (&icnt
, &imm_expr
, "sltiu", "t,r,j", dreg
, sreg
);
1695 load_register (&icnt
, ip
, AT
, &imm_expr
);
1696 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, sreg
, AT
);
1701 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, treg
);
1703 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
1706 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
1707 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
1712 if (imm_expr
.X_add_number
== 0)
1714 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
1719 as_warn ("Instruction %s: result is always true",
1721 macro_build (&icnt
, &expr1
, "addiu", "t,r,j", dreg
, 0);
1724 switch (imm_expr
.X_add_number
& 0xffff8000)
1728 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
1733 if (imm_expr
.X_add_number
!= -32768)
1735 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1736 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", dreg
, sreg
);
1743 macro_build_lui (&icnt
, &imm_expr
, AT
);
1744 if (imm_expr
.X_add_number
& 0xffff)
1745 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
1746 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
1749 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
1755 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32768)
1757 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1758 macro_build (&icnt
, &imm_expr
, "addi", "t,r,j", dreg
, sreg
);
1761 load_register (&icnt
, ip
, AT
, &imm_expr
);
1762 macro_build (&icnt
, NULL
, "sub", "d,v,t", dreg
, sreg
, AT
);
1766 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32768)
1768 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1769 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", dreg
, sreg
);
1772 load_register (&icnt
, ip
, AT
, &imm_expr
);
1773 macro_build (&icnt
, NULL
, "subu", "d,v,t", dreg
, sreg
, AT
);
1778 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* floating reg */
1779 dreg
= (ip
->insn_opcode
>> 06) & 0x1f; /* floating reg */
1782 * Is the double cfc1 instruction a bug in the mips assembler;
1783 * or is there a reason for it?
1785 save_reorder_condition
= mips_noreorder
;
1787 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
1788 macro_build (&icnt
, NULL
, "cfc1", "t,G", treg
, 31);
1789 macro_build (&icnt
, NULL
, "nop", "");
1790 expr1
.X_add_number
= 3;
1791 macro_build (&icnt
, &expr1
, "ori", "t,r,i", AT
, treg
);
1792 expr1
.X_add_number
= 2;
1793 macro_build (&icnt
, &expr1
, "xori", "t,r,i", AT
, AT
);
1794 macro_build (&icnt
, NULL
, "ctc1", "t,G", AT
, 31);
1795 macro_build (&icnt
, NULL
, "nop", "");
1796 macro_build (&icnt
, NULL
,
1797 mask
== M_TRUNCWD
? "cvt.w.d" : "cvt.w.s", "D,S", dreg
, sreg
);
1798 macro_build (&icnt
, NULL
, "ctc1", "t,G", treg
, 31);
1799 macro_build (&icnt
, NULL
, "nop", "");
1800 mips_noreorder
= save_reorder_condition
;
1809 /* avoid load delay */
1810 offset_expr
.X_add_number
+= 1;
1811 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
1812 offset_expr
.X_add_number
-= 1;
1813 macro_build (&icnt
, &offset_expr
, "lbu", "t,o(b)", AT
, breg
);
1814 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
1815 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
1819 /* does this work on a big endian machine? */
1820 offset_expr
.X_add_number
+= 3;
1821 macro_build (&icnt
, &offset_expr
, "lwl", "t,o(b)", treg
, breg
);
1822 offset_expr
.X_add_number
-= 3;
1823 macro_build (&icnt
, &offset_expr
, "lwr", "t,o(b)", treg
, breg
);
1829 if (offset_expr
.X_seg
== &bfd_abs_section
)
1830 load_register (&icnt
, ip
, AT
, &offset_expr
);
1831 else if (gp_reference (&offset_expr
))
1832 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, GP
);
1835 macro_build_lui (&icnt
, &offset_expr
, AT
);
1836 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, AT
);
1838 if (mask
== M_ULW_A
)
1840 expr1
.X_add_number
= 3;
1841 macro_build (&icnt
, &expr1
, "lwl", "t,o(b)", treg
, AT
);
1842 imm_expr
.X_add_number
= 0;
1843 macro_build (&icnt
, &expr1
, "lwr", "t,o(b)", treg
, AT
);
1847 macro_build (&icnt
, &expr1
,
1848 mask
== M_ULH_A
? "lb" : "lbu", "t,o(b)", treg
, AT
);
1849 imm_expr
.X_add_number
= 0;
1850 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
1851 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
1852 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
1857 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", treg
, breg
);
1858 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, treg
, 8);
1859 offset_expr
.X_add_number
+= 1;
1860 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", AT
, breg
);
1864 offset_expr
.X_add_number
+= 3;
1865 macro_build (&icnt
, &offset_expr
, "swl", "t,o(b)", treg
, breg
);
1866 offset_expr
.X_add_number
-= 3;
1867 macro_build (&icnt
, &offset_expr
, "swr", "t,o(b)", treg
, breg
);
1872 if (offset_expr
.X_seg
== &bfd_abs_section
)
1873 load_register (&icnt
, ip
, AT
, &offset_expr
);
1874 else if (gp_reference (&offset_expr
))
1875 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, GP
);
1878 macro_build_lui (&icnt
, &offset_expr
, AT
);
1879 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, AT
);
1881 if (mask
== M_USW_A
)
1883 expr1
.X_add_number
= 3;
1884 macro_build (&icnt
, &expr1
, "swl", "t,o(b)", treg
, AT
);
1885 expr1
.X_add_number
= 0;
1886 macro_build (&icnt
, &expr1
, "swr", "t,o(b)", treg
, AT
);
1890 expr1
.X_add_number
= 0;
1891 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
1892 macro_build (&icnt
, NULL
, "srl", "d,w,<", treg
, treg
, 8);
1893 expr1
.X_add_number
= 1;
1894 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
1895 expr1
.X_add_number
= 0;
1896 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
1897 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
1898 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
1903 as_bad ("Macro %s not implemented yet", ip
->insn_mo
->name
);
1906 as_warn ("Macro used $at after \".set noat\"");
1911 This routine assembles an instruction into its binary format. As a side
1912 effect it sets one of the global variables imm_reloc or offset_reloc to the
1913 type of relocation to do if one of the operands is an address expression.
1918 struct mips_cl_insn
*ip
;
1923 struct mips_opcode
*insn
;
1926 unsigned int lastregno
= 0;
1931 for (s
= str
; islower (*s
) || (*s
>= '0' && *s
<= '3') || *s
== '.'; ++s
)
1943 as_warn ("Unknown opcode: `%s'", str
);
1946 if ((insn
= (struct mips_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1948 as_warn ("`%s' not in hash table.", str
);
1949 insn_error
= "ERROR: Unrecognized opcode";
1955 assert (strcmp (insn
->name
, str
) == 0);
1957 ip
->insn_opcode
= insn
->match
;
1958 for (args
= insn
->args
;; ++args
)
1964 case '\0': /* end of args */
1977 ip
->insn_opcode
|= lastregno
<< 21;
1982 ip
->insn_opcode
|= lastregno
<< 16;
1986 ip
->insn_opcode
|= lastregno
<< 11;
1992 /* handle optional base register.
1993 Either the base register is omitted or
1994 we must have a left paren. */
1995 /* this is dependent on the next operand specifier
1996 is a 'b' for base register */
1997 assert (args
[1] == 'b');
2001 case ')': /* these must match exactly */
2006 case '<': /* must be at least one digit */
2008 * According to the manual, if the shift amount is greater
2009 * than 31 or less than 0 the the shift amount should be
2010 * mod 32. In reality the mips assembler issues an error.
2011 * We issue a warning and do the mod.
2013 my_getExpression (&imm_expr
, s
);
2014 check_absolute_expr (ip
, &imm_expr
);
2015 if ((unsigned long) imm_expr
.X_add_number
> 31)
2017 as_warn ("Improper shift amount (%d)",
2018 imm_expr
.X_add_number
);
2019 imm_expr
.X_add_number
= imm_expr
.X_add_number
% 32;
2021 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2022 imm_expr
.X_seg
= absent_section
;
2026 case 'c': /* break code */
2027 my_getExpression (&imm_expr
, s
);
2028 check_absolute_expr (ip
, &imm_expr
);
2029 if ((unsigned) imm_expr
.X_add_number
> 1023)
2030 as_warn ("Illegal break code (%d)", imm_expr
.X_add_number
);
2031 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 16;
2032 imm_expr
.X_seg
= absent_section
;
2036 case 'B': /* syscall code */
2037 my_getExpression (&imm_expr
, s
);
2038 check_absolute_expr (ip
, &imm_expr
);
2039 if ((unsigned) imm_expr
.X_add_number
> 0xfffff)
2040 as_warn ("Illegal syscall code (%d)", imm_expr
.X_add_number
);
2041 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2042 imm_expr
.X_seg
= absent_section
;
2046 case 'b': /* base register */
2047 case 'd': /* destination register */
2048 case 's': /* source register */
2049 case 't': /* target register */
2050 case 'r': /* both target and source */
2051 case 'v': /* both dest and source */
2052 case 'w': /* both dest and target */
2053 case 'E': /* coprocessor target register */
2054 case 'G': /* coprocessor destination register */
2068 while (isdigit (*s
));
2070 else if (s
[1] == 'f' && s
[2] == 'p')
2075 else if (s
[1] == 's' && s
[2] == 'p')
2080 else if (s
[1] == 'g' && s
[2] == 'p')
2085 else if (s
[1] == 'a' && s
[2] == 't')
2093 as_bad ("Invalid register number (%d)", regno
);
2094 if (regno
== AT
&& !mips_noat
)
2095 as_warn ("Used $at without \".set noat\"");
2101 if (c
== 'r' || c
== 'v' || c
== 'w')
2114 ip
->insn_opcode
|= regno
<< 21;
2118 ip
->insn_opcode
|= regno
<< 11;
2123 ip
->insn_opcode
|= regno
<< 16;
2133 ip
->insn_opcode
|= lastregno
<< 21;
2136 ip
->insn_opcode
|= lastregno
<< 16;
2141 case 'D': /* floating point destination register */
2142 case 'S': /* floating point source register */
2143 case 'T': /* floating point target register */
2147 if (s
[0] == '$' && s
[1] == 'f' && isdigit (s
[2]))
2157 while (isdigit (*s
));
2160 as_bad ("Invalid float register number (%d)", regno
);
2163 !(strcmp (str
, "mtc1") == 0 ||
2164 strcmp (str
, "mfc1") == 0 ||
2165 strcmp (str
, "lwc1") == 0 ||
2166 strcmp (str
, "swc1") == 0))
2167 as_warn ("Float register should be even, was %d",
2175 if (c
== 'V' || c
== 'W')
2185 ip
->insn_opcode
|= regno
<< 6;
2189 ip
->insn_opcode
|= regno
<< 11;
2193 ip
->insn_opcode
|= regno
<< 16;
2201 ip
->insn_opcode
|= lastregno
<< 11;
2204 ip
->insn_opcode
|= lastregno
<< 16;
2210 my_getExpression (&imm_expr
, s
);
2211 check_absolute_expr (ip
, &imm_expr
);
2216 my_getExpression (&offset_expr
, s
);
2217 imm_reloc
= BFD_RELOC_32
;
2222 as_bad ("Floating point constants only implemented for pseudo ops.");
2225 case 'i': /* 16 bit unsigned immediate */
2226 case 'j': /* 16 bit signed immediate */
2227 imm_reloc
= BFD_RELOC_LO16
;
2228 c
= my_getSmallExpression (&imm_expr
, s
);
2233 if (imm_expr
.X_seg
== &bfd_abs_section
)
2234 imm_expr
.X_add_number
=
2235 (imm_expr
.X_add_number
>> 16) & 0xffff;
2237 imm_reloc
= BFD_RELOC_HI16_S
;
2239 imm_reloc
= BFD_RELOC_HI16
;
2243 check_absolute_expr (ip
, &imm_expr
);
2246 if ((unsigned long) imm_expr
.X_add_number
> 65535)
2248 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
2249 !strcmp (insn
->name
, insn
[1].name
))
2251 as_bad ("16 bit expression not in range 0..65535");
2256 if (imm_expr
.X_add_number
< -32768 ||
2257 imm_expr
.X_add_number
> 32767)
2259 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
2260 !strcmp (insn
->name
, insn
[1].name
))
2262 as_bad ("16 bit expression not in range -32768..32767");
2268 case 'o': /* 16 bit offset */
2269 c
= my_getSmallExpression (&offset_expr
, s
);
2271 * If this value won't fit into a 16 bit offset, then
2272 * go find a macro that will generate the 32 bit offset
2275 if ((offset_expr
.X_add_symbol
2276 && offset_expr
.X_seg
!= &bfd_abs_section
)
2277 || offset_expr
.X_subtract_symbol
2278 || offset_expr
.X_add_number
> 32767
2279 || offset_expr
.X_add_number
< -32768)
2282 offset_reloc
= BFD_RELOC_LO16
;
2283 if (c
== 'h' || c
== 'H')
2284 offset_expr
.X_add_number
=
2285 (offset_expr
.X_add_number
>> 16) & 0xffff;
2289 case 'p': /* pc relative offset */
2290 offset_reloc
= BFD_RELOC_16_PCREL_S2
;
2291 my_getExpression (&offset_expr
, s
);
2295 case 'u': /* upper 16 bits */
2296 c
= my_getSmallExpression (&imm_expr
, s
);
2297 if ((unsigned long) imm_expr
.X_add_number
> 65535)
2298 as_bad ("lui expression not in range 0..65535");
2299 imm_reloc
= BFD_RELOC_LO16
;
2304 if (imm_expr
.X_seg
== &bfd_abs_section
)
2305 imm_expr
.X_add_number
=
2306 (imm_expr
.X_add_number
>> 16) & 0xffff;
2308 imm_reloc
= BFD_RELOC_HI16_S
;
2310 imm_reloc
= BFD_RELOC_HI16
;
2316 case 'a': /* 26 bit address */
2317 my_getExpression (&offset_expr
, s
);
2319 offset_reloc
= BFD_RELOC_MIPS_JMP
;
2323 fprintf (stderr
, "bad char = '%c'\n", *args
);
2328 /* Args don't match. */
2329 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
2330 !strcmp (insn
->name
, insn
[1].name
))
2336 insn_error
= "ERROR: Illegal operands";
2345 my_getSmallExpression (ep
, str
)
2356 ((str
[1] == 'h' && str
[2] == 'i')
2357 || (str
[1] == 'H' && str
[2] == 'I')
2358 || (str
[1] == 'l' && str
[2] == 'o'))
2370 * A small expression may be followed by a base register.
2371 * Scan to the end of this operand, and then back over a possible
2372 * base register. Then scan the small expression up to that
2373 * point. (Based on code in sparc.c...)
2375 for (sp
= str
; *sp
&& *sp
!= ','; sp
++)
2377 if (sp
- 4 >= str
&& sp
[-1] == RP
)
2379 if (isdigit (sp
[-2]))
2381 for (sp
-= 3; sp
>= str
&& isdigit (*sp
); sp
--)
2383 if (*sp
== '$' && sp
> str
&& sp
[-1] == LP
)
2389 else if (sp
- 5 >= str
2392 && ((sp
[-3] == 'f' && sp
[-2] == 'p')
2393 || (sp
[-3] == 's' && sp
[-2] == 'p')
2394 || (sp
[-3] == 'g' && sp
[-2] == 'p')
2395 || (sp
[-3] == 'a' && sp
[-2] == 't')))
2401 /* no expression means zero offset */
2404 /* %xx(reg) is an error */
2405 ep
->X_seg
= absent_section
;
2410 ep
->X_seg
= &bfd_abs_section
;
2413 ep
->X_add_symbol
= NULL
;
2414 ep
->X_subtract_symbol
= NULL
;
2415 ep
->X_add_number
= 0;
2420 my_getExpression (ep
, str
);
2427 my_getExpression (ep
, str
);
2428 return c
; /* => %hi or %lo encountered */
2432 my_getExpression (ep
, str
)
2439 save_in
= input_line_pointer
;
2440 input_line_pointer
= str
;
2441 seg
= expression (ep
);
2442 expr_end
= input_line_pointer
;
2443 input_line_pointer
= save_in
;
2447 md_atof (type
, litP
, sizeP
)
2457 md_number_to_chars (buf
, val
, n
)
2509 md_parse_option (argP
, cntP
, vecP
)
2514 /* Accept -nocpp but ignore it. */
2515 if (!strcmp (*argP
, "nocpp"))
2521 if (strcmp (*argP
, "EL") == 0
2522 || strcmp (*argP
, "EB") == 0)
2524 /* FIXME: This breaks -L -EL. */
2533 if ((*argP
)[1] != '\0')
2534 g_switch_value
= atoi (*argP
+ 1);
2537 **vecP
= (char *) NULL
;
2540 g_switch_value
= atoi (**vecP
);
2543 as_warn ("Number expected after -G");
2548 return 1; /* pretend you parsed the character */
2552 md_pcrel_from (fixP
)
2555 /* return the address of the delay slot */
2556 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2560 md_apply_fix (fixP
, valueP
)
2567 assert (fixP
->fx_size
== 4);
2570 fixP
->fx_addnumber
= value
; /* Remember value for tc_gen_reloc */
2572 switch (fixP
->fx_r_type
)
2575 case BFD_RELOC_MIPS_JMP
:
2576 case BFD_RELOC_HI16
:
2577 case BFD_RELOC_HI16_S
:
2578 case BFD_RELOC_LO16
:
2579 case BFD_RELOC_MIPS_GPREL
:
2580 /* Nothing needed to do. The value comes from the reloc entry */
2583 case BFD_RELOC_16_PCREL_S2
:
2585 * We need to save the bits in the instruction since fixup_segment()
2586 * might be deleting the relocation entry (i.e., a branch within
2587 * the current segment).
2590 as_warn ("Branch to odd address (%x)", value
);
2592 if ((value
& ~0xFFFF) && (value
& ~0xFFFF) != (-1 & ~0xFFFF))
2593 as_bad ("Relocation overflow");
2595 /* update old instruction data */
2596 buf
= (unsigned char *) (fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
);
2600 insn
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2604 insn
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | buf
[3];
2611 insn
|= value
& 0xFFFF;
2612 md_number_to_chars ((char *) buf
, insn
, 4);
2626 const struct mips_opcode
*p
;
2627 int treg
, sreg
, dreg
, shamt
;
2632 for (i
= 0; i
< NUMOPCODES
; ++i
)
2634 p
= &mips_opcodes
[i
];
2635 if (((oc
& p
->mask
) == p
->match
) && (p
->pinfo
!= INSN_MACRO
))
2637 printf ("%08lx %s\t", oc
, p
->name
);
2638 treg
= (oc
>> 16) & 0x1f;
2639 sreg
= (oc
>> 21) & 0x1f;
2640 dreg
= (oc
>> 11) & 0x1f;
2641 shamt
= (oc
>> 6) & 0x1f;
2643 for (args
= p
->args
;; ++args
)
2654 printf ("%c", *args
);
2658 assert (treg
== sreg
);
2659 printf ("$%d,$%d", treg
, sreg
);
2664 printf ("$%d", dreg
);
2669 printf ("$%d", treg
);
2674 printf ("$%d", sreg
);
2678 printf ("0x%08lx", oc
& 0x1ffffff);
2689 printf ("$%d", shamt
);
2700 printf ("%08lx UNDEFINED\n", oc
);
2711 name
= input_line_pointer
;
2712 c
= get_symbol_end ();
2713 p
= (symbolS
*) symbol_find_or_make (name
);
2714 *input_line_pointer
= c
;
2719 get_optional_absolute_expression ()
2724 s
= expression (&exp
);
2725 if (!(s
== &bfd_abs_section
|| s
== big_section
|| s
== absent_section
))
2727 as_bad ("Bad Absolute Expression.");
2729 return exp
.X_add_number
;
2737 register long temp_fill
;
2738 long max_alignment
= 15;
2742 o Note that the assembler pulls down any immediately preceeding label
2743 to the aligned address.
2744 o It's not documented but auto alignment is reinstated by
2745 a .align pseudo instruction.
2746 o Note also that after auto alignment is turned off the mips assembler
2747 issues an error on attempt to assemble an improperly aligned data item.
2752 temp
= get_absolute_expression ();
2753 if (temp
> max_alignment
)
2754 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
2757 as_warn ("Alignment negative: 0 assumed.");
2760 if (*input_line_pointer
== ',')
2762 input_line_pointer
++;
2763 temp_fill
= get_absolute_expression ();
2771 frag_align (temp
, (int) temp_fill
);
2778 record_alignment (now_seg
, temp
);
2780 demand_empty_rest_of_line ();
2794 subseg_new (".rdata", (subsegT
) get_absolute_expression ());
2803 #ifdef BFD_ASSEMBLER
2804 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
2806 subseg_new (bss_section
, (subsegT
) get_absolute_expression ());
2808 demand_empty_rest_of_line ();
2812 subseg_new (".sdata", (subsegT
) get_absolute_expression ());
2815 as_bad ("Global pointers not supported; recompile -G 0");
2827 if (log_size
> 0 && auto_align
)
2828 frag_align (log_size
, 0);
2829 cons (1 << log_size
);
2836 as_fatal ("Encountered `.err', aborting assembly");
2846 symbolP
= get_symbol ();
2847 if (*input_line_pointer
== ',')
2848 input_line_pointer
++;
2849 size
= get_optional_absolute_expression ();
2850 S_SET_VALUE (symbolP
, size
);
2851 S_SET_EXTERNAL (symbolP
);
2854 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
2855 so we use an additional ECOFF specific field. */
2856 symbolP
->ecoff_undefined
= 1;
2861 s_float_cons (is_double
)
2866 int error_code
, repeat
;
2867 extern FLONUM_TYPE generic_floating_point_number
;
2876 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2880 error_code
= atof_generic (&input_line_pointer
, ".", EXP_CHARS
,
2881 &generic_floating_point_number
);
2884 if (error_code
== ERROR_EXPONENT_OVERFLOW
)
2885 as_warn ("Bad floating-point constant: exponent overflow");
2887 as_warn ("Bad floating-point constant: unknown error code=%d.", error_code
);
2892 gen_to_words ((LITTLENUM_TYPE
*) words
,
2894 11 /* exponent_bits */ );
2898 gen_to_words ((LITTLENUM_TYPE
*) words
,
2900 8 /* exponent_bits */ );
2902 if (*input_line_pointer
== ':')
2904 input_line_pointer
++;
2905 repeat
= get_absolute_expression ();
2913 f
= frag_more (repeat
* 8);
2914 for (; repeat
--; f
+= 8)
2916 md_number_to_chars (f
+ 6, words
[0], 2);
2917 md_number_to_chars (f
+ 4, words
[1], 2);
2918 md_number_to_chars (f
+ 2, words
[2], 2);
2919 md_number_to_chars (f
, words
[3], 2);
2924 f
= frag_more (repeat
* 4);
2925 for (; repeat
--; f
+= 4)
2927 md_number_to_chars (f
+ 2, words
[0], 2);
2928 md_number_to_chars (f
, words
[1], 2);
2932 if (*input_line_pointer
!= ',')
2934 input_line_pointer
++;
2939 demand_empty_rest_of_line ();
2946 if (strcmp (input_line_pointer
, "O1") != 0
2947 && strcmp (input_line_pointer
, "O2") != 0)
2948 as_warn ("Unrecognized option");
2949 demand_empty_rest_of_line ();
2956 char *name
= input_line_pointer
, ch
;
2958 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2959 input_line_pointer
++;
2960 ch
= *input_line_pointer
;
2961 *input_line_pointer
= '\0';
2963 if (strcmp (name
, "reorder") == 0)
2967 else if (strcmp (name
, "noreorder") == 0)
2971 else if (strcmp (name
, "at") == 0)
2975 else if (strcmp (name
, "noat") == 0)
2979 else if (strcmp (name
, "macro") == 0)
2981 mips_warn_about_macros
= 0;
2983 else if (strcmp (name
, "nomacro") == 0)
2985 if (mips_noreorder
== 0)
2986 as_bad ("`noreorder' must be set before `nomacro'");
2987 mips_warn_about_macros
= 1;
2989 else if (strcmp (name
, "move") == 0 || strcmp (name
, "novolatile") == 0)
2993 else if (strcmp (name
, "nomove") == 0 || strcmp (name
, "volatile") == 0)
2997 else if (strcmp (name
, "bopt") == 0)
3001 else if (strcmp (name
, "nobopt") == 0)
3007 as_warn ("Tried to set unrecognized symbol: %s\n", name
);
3009 *input_line_pointer
= ch
;
3010 demand_empty_rest_of_line ();
3019 if (*input_line_pointer
++ != '$')
3021 as_warn ("expected `$'");
3024 if (isdigit ((unsigned char) *input_line_pointer
))
3026 reg
= get_absolute_expression ();
3027 if (reg
< 0 || reg
>= 32)
3029 as_warn ("Bad register number");
3035 if (strncmp (input_line_pointer
, "fp", 2) == 0)
3037 else if (strncmp (input_line_pointer
, "sp", 2) == 0)
3039 else if (strncmp (input_line_pointer
, "gp", 2) == 0)
3041 else if (strncmp (input_line_pointer
, "at", 2) == 0)
3045 as_warn ("Unrecognized register name");
3048 input_line_pointer
+= 2;
3054 * Translate internal representation of relocation info to BFD target format.
3057 tc_gen_reloc (section
, fixp
)
3063 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3064 assert (reloc
!= 0);
3066 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
3067 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3068 if (fixp
->fx_pcrel
== 0)
3069 reloc
->addend
= fixp
->fx_addnumber
;
3074 reloc
->addend
= -reloc
->address
;
3076 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3077 assert (reloc
->howto
!= 0);
3082 /* should never be called */
3084 md_section_align (seg
, addr
)
3088 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3090 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
3094 md_estimate_size_before_relax (fragP
, segtype
)
3098 as_fatal ("md_estimate_size_before_relax");
3100 } /* md_estimate_size_before_relax() */
3104 /* These functions should really be defined by the object file format,
3105 since they are related to debugging information. However, this
3106 code has to work for the a.out format, which does not define them,
3107 so we provide simple versions here. These don't actually generate
3108 any debugging information, but they do simple checking and someday
3109 somebody may make them useful. */
3113 struct loc
*loc_next
;
3114 unsigned long loc_fileno
;
3115 unsigned long loc_lineno
;
3116 unsigned long loc_offset
;
3117 unsigned short loc_delta
;
3118 unsigned short loc_count
;
3127 struct proc
*proc_next
;
3128 struct symbol
*proc_isym
;
3129 struct symbol
*proc_end
;
3130 unsigned long proc_reg_mask
;
3131 unsigned long proc_reg_offset
;
3132 unsigned long proc_fpreg_mask
;
3133 unsigned long proc_fpreg_offset
;
3134 unsigned long proc_frameoffset
;
3135 unsigned long proc_framereg
;
3136 unsigned long proc_pcreg
;
3138 struct file
*proc_file
;
3145 struct file
*file_next
;
3146 unsigned long file_fileno
;
3147 struct symbol
*file_symbol
;
3148 struct symbol
*file_end
;
3149 struct proc
*file_proc
;
3154 static struct obstack proc_frags
;
3155 static procS
*proc_lastP
;
3156 static procS
*proc_rootP
;
3157 static int numprocs
;
3162 obstack_begin (&proc_frags
, 0x2000);
3168 /* check for premature end, nesting errors, etc */
3169 if (proc_lastP
&& proc_lastP
->proc_end
== NULL
)
3170 as_warn ("missing `.end' at end of assembly");
3173 extern char hex_value
[];
3181 if (*input_line_pointer
== '-')
3183 ++input_line_pointer
;
3186 if (!isdigit (*input_line_pointer
))
3187 as_bad ("Expected simple number.");
3188 if (input_line_pointer
[0] == '0')
3190 if (input_line_pointer
[1] == 'x')
3192 input_line_pointer
+= 2;
3193 while (isxdigit (*input_line_pointer
))
3196 val
|= hex_value
[(int) *input_line_pointer
++];
3198 return negative
? -val
: val
;
3202 ++input_line_pointer
;
3203 while (isdigit (*input_line_pointer
))
3206 val
|= *input_line_pointer
++ - '0';
3208 return negative
? -val
: val
;
3211 if (!isdigit (*input_line_pointer
))
3213 printf (" *input_line_pointer == '%c' 0x%02x\n",
3214 *input_line_pointer
, *input_line_pointer
);
3215 as_warn ("Invalid number");
3218 while (isdigit (*input_line_pointer
))
3221 val
+= *input_line_pointer
++ - '0';
3223 return negative
? -val
: val
;
3226 /* The .file directive; just like the usual .file directive, but there
3227 is an initial number which is the ECOFF file index. */
3235 line
= get_number ();
3240 /* The .end directive. */
3248 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3251 demand_empty_rest_of_line ();
3255 if (now_seg
!= text_section
)
3256 as_warn (".end not in text section");
3259 as_warn (".end and no .ent seen yet.");
3265 assert (S_GET_NAME (p
));
3266 if (strcmp (S_GET_NAME (p
), S_GET_NAME (proc_lastP
->proc_isym
)))
3267 as_warn (".end symbol does not match .ent symbol.");
3270 proc_lastP
->proc_end
= (symbolS
*) 1;
3273 /* The .aent and .ent directives. */
3283 symbolP
= get_symbol ();
3284 if (*input_line_pointer
== ',')
3285 input_line_pointer
++;
3286 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
3287 number
= get_number ();
3288 if (now_seg
!= text_section
)
3289 as_warn (".ent or .aent not in text section.");
3291 if (!aent
&& proc_lastP
&& proc_lastP
->proc_end
== NULL
)
3292 as_warn ("missing `.end'");
3296 procP
= (procS
*) obstack_alloc (&proc_frags
, sizeof (*procP
));
3297 procP
->proc_isym
= symbolP
;
3298 procP
->proc_reg_mask
= 0;
3299 procP
->proc_reg_offset
= 0;
3300 procP
->proc_fpreg_mask
= 0;
3301 procP
->proc_fpreg_offset
= 0;
3302 procP
->proc_frameoffset
= 0;
3303 procP
->proc_framereg
= 0;
3304 procP
->proc_pcreg
= 0;
3305 procP
->proc_end
= NULL
;
3306 procP
->proc_next
= NULL
;
3308 proc_lastP
->proc_next
= procP
;
3314 demand_empty_rest_of_line ();
3317 /* The .frame directive. */
3330 frame_reg
= tc_get_register ();
3331 if (*input_line_pointer
== ',')
3332 input_line_pointer
++;
3333 frame_off
= get_optional_absolute_expression ();
3334 if (*input_line_pointer
== ',')
3335 input_line_pointer
++;
3336 pcreg
= tc_get_register ();
3339 assert (proc_rootP
);
3340 proc_rootP
->proc_framereg
= frame_reg
;
3341 proc_rootP
->proc_frameoffset
= frame_off
;
3342 proc_rootP
->proc_pcreg
= pcreg
;
3343 /* bob macho .frame */
3345 /* We don't have to write out a frame stab for unoptimized code. */
3346 if (!(frame_reg
== 30 && frame_off
== 0))
3349 as_warn ("No .ent for .frame to use.");
3350 (void) sprintf (str
, "R%d;%d", frame_reg
, frame_off
);
3351 symP
= symbol_new (str
, N_VFP
, 0, frag_now
);
3352 S_SET_TYPE (symP
, N_RMASK
);
3353 S_SET_OTHER (symP
, 0);
3354 S_SET_DESC (symP
, 0);
3355 symP
->sy_forward
= proc_lastP
->proc_isym
;
3356 /* bob perhaps I should have used pseudo set */
3358 demand_empty_rest_of_line ();
3362 /* The .fmask and .mask directives. */
3369 char str
[100], *strP
;
3375 mask
= get_number ();
3376 if (*input_line_pointer
== ',')
3377 input_line_pointer
++;
3378 off
= get_absolute_expression ();
3380 /* bob only for coff */
3381 assert (proc_rootP
);
3382 if (reg_type
== 'F')
3384 proc_rootP
->proc_fpreg_mask
= mask
;
3385 proc_rootP
->proc_fpreg_offset
= off
;
3389 proc_rootP
->proc_reg_mask
= mask
;
3390 proc_rootP
->proc_reg_offset
= off
;
3393 /* bob macho .mask + .fmask */
3395 /* We don't have to write out a mask stab if no saved regs. */
3399 as_warn ("No .ent for .mask to use.");
3401 for (i
= 0; i
< 32; i
++)
3405 sprintf (strP
, "%c%d,", reg_type
, i
);
3406 strP
+= strlen (strP
);
3410 sprintf (strP
, ";%d,", off
);
3411 symP
= symbol_new (str
, N_RMASK
, 0, frag_now
);
3412 S_SET_TYPE (symP
, N_RMASK
);
3413 S_SET_OTHER (symP
, 0);
3414 S_SET_DESC (symP
, 0);
3415 symP
->sy_forward
= proc_lastP
->proc_isym
;
3416 /* bob perhaps I should have used pseudo set */
3421 /* The .loc directive. */
3432 assert (now_seg
== text_section
);
3434 lineno
= get_number ();
3435 addroff
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
3437 symbolP
= symbol_new ("", N_SLINE
, addroff
, frag_now
);
3438 S_SET_TYPE (symbolP
, N_SLINE
);
3439 S_SET_OTHER (symbolP
, 0);
3440 S_SET_DESC (symbolP
, lineno
);
3441 symbolP
->sy_segment
= now_seg
;
3445 #endif /* ! defined (OBJ_ECOFF) */