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 "mips-opcode.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);
290 bfd_set_gp_size (stdoutput
, g_switch_value
);
294 imm_expr
.X_seg
= absent_section
;
295 offset_expr
.X_seg
= absent_section
;
297 mips_ip (str
, &insn
);
300 as_bad ("%s `%s'", insn_error
, str
);
303 if (insn
.insn_mo
->pinfo
== INSN_MACRO
)
309 if (imm_expr
.X_seg
!= absent_section
)
310 append_insn (&insn
, &imm_expr
, imm_reloc
);
311 else if (offset_expr
.X_seg
!= absent_section
)
312 append_insn (&insn
, &offset_expr
, offset_reloc
);
314 append_insn (&insn
, NULL
, BFD_RELOC_UNUSED
);
318 #define ALIGN_ERR "Attempt to assemble instruction onto non word boundary."
319 #define ALIGN_ERR2 "GAS doesn't do implicit alignment; use .align directive."
323 * Output an instruction.
326 append_insn (ip
, address_expr
, reloc_type
)
327 struct mips_cl_insn
*ip
;
328 expressionS
*address_expr
;
329 bfd_reloc_code_real_type reloc_type
;
334 #if 0 /* This is testing the address of the frag, not the alignment of
335 the instruction in the current section. */
342 if (address_expr
!= NULL
)
346 if (address_expr
->X_seg
== &bfd_abs_section
)
351 ip
->insn_opcode
|= address_expr
->X_add_number
;
355 ip
->insn_opcode
|= address_expr
->X_add_number
& 0xffff;
358 case BFD_RELOC_MIPS_JMP
:
359 case BFD_RELOC_16_PCREL_S2
:
368 assert (reloc_type
!= BFD_RELOC_UNUSED
);
370 fixP
= fix_new (frag_now
, f
- frag_now
->fr_literal
, 4,
371 address_expr
->X_add_symbol
,
372 address_expr
->X_subtract_symbol
,
373 address_expr
->X_add_number
,
374 reloc_type
== BFD_RELOC_16_PCREL_S2
,
378 md_number_to_chars (f
, ip
->insn_opcode
, 4);
381 * Fill all delay slots with nops.
385 if (ip
->insn_mo
->pinfo
& ANY_DELAY
)
388 md_number_to_chars (f
, 0, 4);
392 if (ip
->insn_mo
->pinfo
& INSN_EXTRA_DELAY
)
395 md_number_to_chars (f
, 0, 4);
400 /* Return 1 if an expression can be accessed via the GP register. */
411 sym
= ep
->X_add_symbol
;
412 if (sym
== (symbolS
*) NULL
413 || ep
->X_subtract_symbol
!= (symbolS
*) NULL
)
416 /* Certain symbols can not be referenced off the GP, although it
417 appears as though they can. */
418 symname
= S_GET_NAME (sym
);
419 if (symname
!= (const char *) NULL
420 && (strcmp (symname
, "eprol") == 0
421 || strcmp (symname
, "etext") == 0
422 || strcmp (symname
, "_gp") == 0
423 || strcmp (symname
, "edata") == 0
424 || strcmp (symname
, "_fbss") == 0
425 || strcmp (symname
, "_fdata") == 0
426 || strcmp (symname
, "_ftext") == 0
427 || strcmp (symname
, "end") == 0))
429 if (! S_IS_DEFINED (sym
)
430 && S_GET_VALUE (sym
) != 0
431 && S_GET_VALUE (sym
) <= g_switch_value
)
433 segname
= segment_name (S_GET_SEGMENT (ep
->X_add_symbol
));
434 return (strcmp (segname
, ".sdata") == 0
435 || strcmp (segname
, ".sbss") == 0);
436 #else /* ! defined (OBJ_ECOFF) */
437 /* The GP register is only used for ECOFF. */
439 #endif /* ! defined (OBJ_ECOFF) */
442 /* Build an instruction created by a macro expansion. This is passed
443 a pointer to the count of instructions created so far, an
444 expression, the name of the instruction to build, an operand format
445 string, and corresponding arguments. */
449 macro_build (int *counter
,
454 #else /* ! defined (NO_STDARG) */
456 macro_build (counter
, ep
, name
, fmt
, va_alist
)
462 #endif /* ! defined (NO_STDARG) */
464 struct mips_cl_insn insn
;
465 bfd_reloc_code_real_type r
;
469 va_start (args
, fmt
);
475 * If the macro is about to expand into a second instruction,
476 * print a warning if needed. We need to pass ip as a parameter
477 * to generate a better warning message here...
479 if (mips_warn_about_macros
&& *counter
== 1)
480 as_warn ("Macro instruction expanded into multiple instructions");
482 *counter
+= 1; /* bump instruction counter */
484 r
= BFD_RELOC_UNUSED
;
485 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
486 assert (insn
.insn_mo
);
487 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
489 while (strcmp (fmt
, insn
.insn_mo
->args
) != 0)
492 assert (insn
.insn_mo
->name
);
493 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
495 assert (insn
.insn_mo
->pinfo
!= INSN_MACRO
);
496 insn
.insn_opcode
= insn
.insn_mo
->match
;
511 insn
.insn_opcode
|= va_arg (args
, int) << 16;
517 insn
.insn_opcode
|= va_arg (args
, int) << 16;
521 insn
.insn_opcode
|= va_arg (args
, int) << 11;
526 insn
.insn_opcode
|= va_arg (args
, int) << 11;
530 insn
.insn_opcode
|= va_arg (args
, int) << 6;
534 insn
.insn_opcode
|= va_arg (args
, int) << 6;
541 insn
.insn_opcode
|= va_arg (args
, int) << 21;
553 * This allows macro() to pass an immediate expression for
554 * creating short branches without creating a symbol.
555 * Note that the expression still might come from the assembly
556 * input, in which case the value is not checked for range nor
557 * is a relocation entry generated (yuck).
559 if (ep
->X_add_symbol
== NULL
&& ep
->X_seg
== &bfd_abs_section
)
561 insn
.insn_opcode
|= (ep
->X_add_number
>> 2) & 0xffff;
565 r
= BFD_RELOC_16_PCREL_S2
;
574 assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
576 /* Use GP relative addressing if possible. */
577 if (r
== BFD_RELOC_LO16
578 && gp_reference (ep
))
579 r
= BFD_RELOC_MIPS_GPREL
;
581 append_insn (&insn
, ep
, r
);
585 * Generate a "lui" instruction.
588 macro_build_lui (counter
, ep
, regnum
)
593 expressionS high_expr
;
594 struct mips_cl_insn insn
;
595 bfd_reloc_code_real_type r
;
596 CONST
char *name
= "lui";
597 CONST
char *fmt
= "t,u";
601 if (high_expr
.X_seg
== &bfd_abs_section
)
603 /* we can compute the instruction now without a relocation entry */
604 if (high_expr
.X_add_number
& 0x8000)
605 high_expr
.X_add_number
+= 0x10000;
606 high_expr
.X_add_number
=
607 ((unsigned long) high_expr
.X_add_number
>> 16) & 0xffff;
608 r
= BFD_RELOC_UNUSED
;
611 r
= BFD_RELOC_HI16_S
;
614 * If the macro is about to expand into a second instruction,
615 * print a warning if needed. We need to pass ip as a parameter
616 * to generate a better warning message here...
618 if (mips_warn_about_macros
&& *counter
== 1)
619 as_warn ("Macro instruction expanded into multiple instructions");
621 *counter
+= 1; /* bump instruction counter */
623 insn
.insn_mo
= (struct mips_opcode
*) hash_find (op_hash
, name
);
624 assert (insn
.insn_mo
);
625 assert (strcmp (name
, insn
.insn_mo
->name
) == 0);
626 assert (strcmp (fmt
, insn
.insn_mo
->args
) == 0);
628 insn
.insn_opcode
= insn
.insn_mo
->match
| (regnum
<< 16);
629 if (r
== BFD_RELOC_UNUSED
)
631 insn
.insn_opcode
|= high_expr
.X_add_number
;
632 append_insn (&insn
, NULL
, r
);
635 append_insn (&insn
, &high_expr
, r
);
639 * Generates code to set the $at register to true (one)
640 * if reg is less than the immediate expression.
643 set_at (counter
, reg
)
648 switch (imm_expr
.X_add_number
& 0xffff8000)
652 macro_build (counter
, &imm_expr
, "slti", "t,r,j", AT
, reg
);
656 macro_build (counter
, &imm_expr
, "ori", "t,r,i", AT
, 0);
660 macro_build_lui (counter
, &imm_expr
, AT
);
661 if (imm_expr
.X_add_number
& 0xffff)
662 macro_build (counter
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
664 macro_build (counter
, NULL
, "slt", "d,v,t", AT
, reg
, AT
);
668 * Generates code to set the $at register to true (one)
669 * if reg is less than the immediate expression.
670 * Unsigned comparison is perfomed.
673 set_at_unsigned (counter
, reg
)
678 switch (imm_expr
.X_add_number
& 0xffff8000)
682 macro_build (counter
, &imm_expr
, "sltiu", "t,r,j", AT
, reg
);
686 macro_build (counter
, &imm_expr
, "ori", "t,r,i", AT
, 0);
690 macro_build_lui (counter
, &imm_expr
, AT
);
691 if (imm_expr
.X_add_number
& 0xffff)
692 macro_build (counter
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
694 macro_build (counter
, NULL
, "sltu", "d,v,t", AT
, reg
, AT
);
698 check_absolute_expr (ip
, expr
)
699 struct mips_cl_insn
*ip
;
703 if (expr
->X_seg
!= &bfd_abs_section
)
704 as_warn ("Instruction %s requires absolute expression", ip
->insn_mo
->name
);
708 * This routine generates the least number of instructions neccessary to load
709 * an absolute expression value into a register.
712 load_register (counter
, ip
, reg
, ep
)
714 struct mips_cl_insn
*ip
;
718 switch (ep
->X_add_number
& 0xffff8000)
722 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, 0);
726 macro_build (counter
, ep
, "ori", "t,r,i", reg
, 0);
730 macro_build_lui (counter
, ep
, reg
);
731 if (ep
->X_add_number
& 0xffff)
732 macro_build (counter
, ep
, "addiu", "t,r,j", reg
, reg
);
739 * This routine implements the seemingly endless macro or synthesized
740 * instructions and addressing modes in the mips assembly language. Many
741 * of these macros are simple and are similar to each other. These could
742 * probably be handled by some kind of table or grammer aproach instead of
743 * this verbose method. Others are not simple macros but are more like
744 * optimizing code generation.
745 * One interesting optimization is when several store macros appear
746 * consecutivly that would load AT with the upper half of the same address.
747 * The ensuing load upper instructions are ommited. This implies some kind
748 * of global optimization. We currently only optimize within a single macro.
749 * For many of the load and store macros if the address is specified as a
750 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
751 * first load register 'at' with zero and use it as the base register. The
752 * mips assembler simply uses register $zero. Just one tiny optimization
757 struct mips_cl_insn
*ip
;
759 register int treg
, sreg
, dreg
, breg
;
764 int save_reorder_condition
;
769 treg
= (ip
->insn_opcode
>> 16) & 0x1f;
770 dreg
= (ip
->insn_opcode
>> 11) & 0x1f;
771 sreg
= breg
= (ip
->insn_opcode
>> 21) & 0x1f;
772 mask
= ip
->insn_mo
->mask
;
774 expr1
.X_seg
= &bfd_abs_section
;
775 expr1
.X_subtract_symbol
= NULL
;
776 expr1
.X_add_symbol
= NULL
;
777 expr1
.X_add_number
= 1;
784 Note: mips algorithm requires the move in the delay slot.
785 <main>: bgez $a0,0x4001bc <main+12>
786 <main+4>: move v0,$a0
787 <main+8>: sub v0,$zero,$a0
791 save_reorder_condition
= mips_noreorder
;
794 expr1
.X_add_number
= 8;
795 macro_build (&icnt
, &expr1
, "bgez", "s,p", sreg
);
796 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
, 0);
797 macro_build (&icnt
, NULL
, mask
== M_ABS
? "sub" : "subu", "d,v,t",
800 mips_noreorder
= save_reorder_condition
;
805 switch (imm_expr
.X_add_number
& 0xffff8000)
809 macro_build (&icnt
, &imm_expr
,
810 mask
== M_ADD_I
? "addi" : "addiu", "t,r,j", treg
, sreg
);
814 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", AT
, 0);
818 macro_build_lui (&icnt
, &imm_expr
, AT
);
819 if (imm_expr
.X_add_number
& 0xffff)
820 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
823 macro_build (&icnt
, NULL
,
824 mask
== M_ADD_I
? "add" : "addu", "d,v,t", treg
, sreg
, AT
);
831 switch (imm_expr
.X_add_number
& 0xffff8000)
838 macro_build (&icnt
, &imm_expr
, "andi", "t,r,i", treg
, sreg
);
841 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
);
844 macro_build (&icnt
, &imm_expr
, "ori", "t,r,i", treg
, sreg
);
845 macro_build (&icnt
, &imm_expr
, "nor", "d,v,t", treg
, treg
, 0);
848 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", treg
, sreg
);
855 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, 0);
859 macro_build_lui (&icnt
, &imm_expr
, AT
);
860 if (imm_expr
.X_add_number
& 0xffff)
861 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
866 macro_build (&icnt
, NULL
, "and", "d,v,t", treg
, sreg
, AT
);
869 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, sreg
, AT
);
872 macro_build (&icnt
, NULL
, "nor", "d,v,t", treg
, sreg
, AT
);
875 macro_build (&icnt
, NULL
, "xor", "d,v,t", treg
, sreg
, AT
);
884 if (imm_expr
.X_add_number
== 0)
886 macro_build (&icnt
, &offset_expr
, mask
== M_BEQ_I
? "beq" : "bne",
890 load_register (&icnt
, ip
, AT
, &imm_expr
);
891 macro_build (&icnt
, &offset_expr
, mask
== M_BEQ_I
? "beq" : "bne",
898 macro_build (&icnt
, &offset_expr
, "bgez", "s,p", sreg
);
903 macro_build (&icnt
, &offset_expr
, "blez", "s,p", treg
);
906 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
907 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
911 /* check for > max integer */
912 if (imm_expr
.X_add_number
== 0x7fffffff)
915 /* result is always false */
916 as_warn ("Branch %s is always false (nop)", ip
->insn_mo
->name
);
917 macro_build (&icnt
, NULL
, "nop", "", 0);
920 imm_expr
.X_add_number
++;
924 if (imm_expr
.X_add_number
== 0)
926 macro_build (&icnt
, &offset_expr
, "bgez", "s,p", sreg
);
929 if (imm_expr
.X_add_number
== 1)
931 macro_build (&icnt
, &offset_expr
, "bgtz", "s,p", sreg
);
934 if (imm_expr
.X_add_number
== 0x80000000)
937 /* result is always true */
938 as_warn ("Branch %s is always true", ip
->insn_mo
->name
);
939 macro_build (&icnt
, &offset_expr
, "b", "p");
942 set_at (&icnt
, sreg
);
943 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
951 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", 0, treg
);
954 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
955 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
959 if (sreg
== 0 || imm_expr
.X_add_number
== 0xffffffff)
961 imm_expr
.X_add_number
++;
965 if (imm_expr
.X_add_number
== 0)
967 if (imm_expr
.X_add_number
== 1)
969 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", sreg
, 0);
972 set_at_unsigned (&icnt
, sreg
);
973 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
979 macro_build (&icnt
, &offset_expr
, "bgtz", "s,p", sreg
);
984 macro_build (&icnt
, &offset_expr
, "bltz", "s,p", treg
);
987 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
988 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
994 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", sreg
, 0);
999 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1000 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1006 macro_build (&icnt
, &offset_expr
, "blez", "s,p", sreg
);
1011 macro_build (&icnt
, &offset_expr
, "bgez", "s,p", treg
);
1014 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, treg
, sreg
);
1015 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
1019 if (imm_expr
.X_add_number
== 0x7fffffff)
1021 imm_expr
.X_add_number
++;
1025 if (imm_expr
.X_add_number
== 0)
1027 macro_build (&icnt
, &offset_expr
, "bltz", "s,p", sreg
);
1030 if (imm_expr
.X_add_number
== 1)
1032 macro_build (&icnt
, &offset_expr
, "blez", "s,p", sreg
);
1035 set_at (&icnt
, sreg
);
1036 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1042 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", sreg
, 0);
1047 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, treg
, sreg
);
1048 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", AT
, 0);
1052 if (sreg
== 0 || imm_expr
.X_add_number
== 0xffffffff)
1054 imm_expr
.X_add_number
++;
1058 if (imm_expr
.X_add_number
== 0)
1060 if (imm_expr
.X_add_number
== 1)
1062 macro_build (&icnt
, &offset_expr
, "beq", "s,t,p", sreg
, 0);
1065 set_at_unsigned (&icnt
, sreg
);
1066 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1072 macro_build (&icnt
, &offset_expr
, "bltz", "s,p", sreg
);
1077 macro_build (&icnt
, &offset_expr
, "bgtz", "s,p", treg
);
1080 macro_build (&icnt
, NULL
, "slt", "d,v,t", AT
, sreg
, treg
);
1081 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1089 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", 0, treg
);
1092 macro_build (&icnt
, NULL
, "sltu", "d,v,t", AT
, sreg
, treg
);
1093 macro_build (&icnt
, &offset_expr
, "bne", "s,t,p", AT
, 0);
1100 as_warn ("Divide by zero.");
1101 macro_build (&icnt
, NULL
, "break", "c", 7);
1105 save_reorder_condition
= mips_noreorder
;
1107 macro_build (&icnt
, NULL
, "div", "s,t", sreg
, treg
);
1108 expr1
.X_add_number
= 8;
1109 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1110 macro_build (&icnt
, NULL
, "nop", "", 0);
1111 macro_build (&icnt
, NULL
, "break", "c", 7);
1112 expr1
.X_add_number
= -1;
1113 macro_build (&icnt
, &expr1
, "addiu", "t,r,j", AT
, 0);
1114 expr1
.X_add_number
= 16;
1115 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, AT
);
1116 expr1
.X_add_number
= 0x80000000;
1117 macro_build_lui (&icnt
, &expr1
, AT
);
1118 expr1
.X_add_number
= 8;
1119 macro_build (&icnt
, &expr1
, "bne", "s,t,p", sreg
, AT
);
1120 macro_build (&icnt
, NULL
, "nop", "", 0);
1121 macro_build (&icnt
, NULL
, "break", "c", 6);
1122 mips_noreorder
= save_reorder_condition
;
1123 macro_build (&icnt
, NULL
, mask
== M_DIV_3
? "mflo" : "mfhi", "d", dreg
);
1124 /* with reorder on there will be two implicit nop instructions here. */
1131 if (imm_expr
.X_add_number
== 0)
1133 as_warn ("Divide by zero.");
1134 macro_build (&icnt
, NULL
, "break", "c", 7);
1137 if (imm_expr
.X_add_number
== 1)
1139 if (mask
== (int) M_DIV_3I
|| mask
== (int) M_DIVU_3I
)
1140 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, sreg
);
1142 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1146 load_register (&icnt
, ip
, AT
, &imm_expr
);
1147 if (mask
== (int) M_DIV_3I
|| mask
== (int) M_REM_3I
)
1148 macro_build (&icnt
, NULL
, "div", "s,t", sreg
, AT
);
1150 macro_build (&icnt
, NULL
, "divu", "s,t", sreg
, AT
);
1152 if (mask
== (int) M_DIV_3I
|| mask
== (int) M_DIVU_3I
)
1153 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
1155 macro_build (&icnt
, NULL
, "mfhi", "d", dreg
);
1156 /* two implicit nop's required for mflo or mfhi */
1161 save_reorder_condition
= mips_noreorder
;
1163 macro_build (&icnt
, NULL
, "divu", "s,t", sreg
, treg
);
1164 expr1
.X_add_number
= 8;
1165 macro_build (&icnt
, &expr1
, "bne", "s,t,p", treg
, 0);
1166 macro_build (&icnt
, NULL
, "nop", "", 0);
1167 macro_build (&icnt
, NULL
, "break", "c", 7);
1168 mips_noreorder
= save_reorder_condition
;
1169 macro_build (&icnt
, NULL
, mask
== M_DIVU_3
? "mflo" : "mfhi", "d", dreg
);
1170 /* with reorder on there will be two implicit nop instructions here. */
1174 if (offset_expr
.X_seg
== &bfd_abs_section
)
1176 load_register (&icnt
, ip
, treg
, &offset_expr
);
1179 if (gp_reference (&offset_expr
))
1180 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", treg
, GP
);
1183 macro_build_lui (&icnt
, &offset_expr
, treg
);
1184 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", treg
, treg
);
1189 tempreg
= (breg
== treg
) ? AT
: treg
;
1190 if (offset_expr
.X_seg
== &bfd_abs_section
)
1191 load_register (&icnt
, ip
, tempreg
, &offset_expr
);
1192 else if (gp_reference (&offset_expr
))
1193 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", tempreg
, GP
);
1196 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1197 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", tempreg
, tempreg
);
1200 macro_build (&icnt
, NULL
, "addu", "d,v,t", treg
, tempreg
, breg
);
1238 if (breg
== treg
|| mask
== M_LWC1_AB
)
1279 if (mask
== M_LWC1_AB
|| mask
== M_SWC1_AB
)
1283 if (gp_reference (&offset_expr
))
1287 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, GP
);
1290 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t",
1295 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1297 macro_build (&icnt
, NULL
, "addu", "d,v,t", tempreg
, tempreg
, breg
);
1299 macro_build (&icnt
, &offset_expr
, s
, fmt
, treg
, tempreg
);
1305 load_register (&icnt
, ip
, treg
, &imm_expr
);
1310 0x400370 <main>: lui $at,%hi(foo)
1311 0x400374 <main+4>: lw $v0,%lo(foo)($at)
1312 0x400378 <main+8>: lw $v1,%lo(foo+4)($at)
1317 /* FIXME: I don't think this is used at present, because the 'F'
1318 format character is not supported. When this is supported,
1319 it should use the GP register. */
1320 macro_build_lui (&icnt
, &offset_expr
, AT
);
1321 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
, AT
);
1322 offset_expr
.X_add_number
= 4;
1323 macro_build (&icnt
, &offset_expr
, "lw", "t,o(b)", treg
+ 1, AT
);
1328 0x4003a0 <main>: lwc1 $f0,-32752($gp)
1329 0x4003a4 <main+4>: lwc1 $f1,-32748($gp)
1330 0x4003a8 <main+8>: nop
1332 /* FIXME: This is nonsense. It isn't used anyhow. */
1333 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* Fs reg */
1334 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)", treg
, AT
);
1335 offset_expr
.X_add_number
= 4;
1336 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)", treg
+ 1, AT
);
1340 /* Even on a big endian machine $fn comes before $fn+1. We have
1341 to adjust when loading from memory. */
1342 save_reorder_condition
= mips_noreorder
;
1344 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1345 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1347 /* unecessary implicit nop */
1348 mips_noreorder
= save_reorder_condition
;
1349 offset_expr
.X_add_number
+= 4;
1350 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1351 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1357 * The MIPS assembler seems to check for X_add_number not
1358 * being double aligned and generating:
1361 * addiu at,at,%lo(foo+1)
1364 * But, the resulting address is the same after relocation so why
1365 * generate the extra instruction?
1367 if (gp_reference (&offset_expr
))
1373 macro_build (&icnt
, &offset_expr
, "addu", "d,v,t", AT
, breg
, GP
);
1379 macro_build_lui (&icnt
, &offset_expr
, AT
);
1381 macro_build (&icnt
, NULL
, "addu", "d,v,t", AT
, AT
, breg
);
1384 /* Even on a big endian machine $fn comes before $fn+1. We have
1385 to adjust when loading from memory. */
1386 save_reorder_condition
= mips_noreorder
;
1388 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1389 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1391 /* unecessary implicit nop */
1392 mips_noreorder
= save_reorder_condition
;
1393 offset_expr
.X_add_number
+= 4;
1394 macro_build (&icnt
, &offset_expr
, "lwc1", "T,o(b)",
1395 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1407 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
1408 offset_expr
.X_add_number
= 4;
1409 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, breg
);
1430 if (gp_reference (&offset_expr
))
1438 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t",
1443 macro_build_lui (&icnt
, &offset_expr
, tempreg
);
1445 macro_build (&icnt
, NULL
, "addu", "d,v,t", tempreg
, tempreg
, breg
);
1447 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, tempreg
);
1448 offset_expr
.X_add_number
+= 4;
1449 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
+ 1, tempreg
);
1455 macro_build (&icnt
, NULL
, "multu", "s,t", sreg
, treg
);
1456 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
1457 /* two implicit nop's required for mflo */
1462 * The mips assembler some times generates shifts and adds.
1463 * Im not trying to be that fancy. GCC should do this for us
1466 load_register (&icnt
, ip
, AT
, &imm_expr
);
1467 macro_build (&icnt
, NULL
, "mult", "s,t", sreg
, AT
);
1468 macro_build (&icnt
, NULL
, "mflo", "d", dreg
);
1469 /* two implicit nop's required for mflo */
1473 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
1474 macro_build (&icnt
, NULL
, "srlv", "d,t,s", AT
, sreg
, AT
);
1475 macro_build (&icnt
, NULL
, "sllv", "d,t,s", dreg
, sreg
, treg
);
1476 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1480 macro_build (&icnt
, NULL
, "sll", "d,w,<", AT
, sreg
,
1481 imm_expr
.X_add_number
& 0x1f);
1482 macro_build (&icnt
, NULL
, "srl", "d,w,<", dreg
, sreg
,
1483 (0 - imm_expr
.X_add_number
) & 0x1f);
1484 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1488 macro_build (&icnt
, NULL
, "subu", "d,v,t", AT
, 0, treg
);
1489 macro_build (&icnt
, NULL
, "sllv", "d,t,s", AT
, sreg
, AT
);
1490 macro_build (&icnt
, NULL
, "srlv", "d,t,s", dreg
, sreg
, treg
);
1491 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1495 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, sreg
,
1496 imm_expr
.X_add_number
& 0x1f);
1497 macro_build (&icnt
, NULL
, "sll", "d,w,<", dreg
, sreg
,
1498 (0 - imm_expr
.X_add_number
) & 0x1f);
1499 macro_build (&icnt
, NULL
, "or", "d,v,t", dreg
, dreg
, AT
);
1503 /* Even on a big endian machine $fn comes before $fn+1. We have
1504 to adjust when storing to memory. */
1505 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1506 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1508 offset_expr
.X_add_number
+= 4;
1509 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1510 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1515 if (gp_reference (&offset_expr
))
1521 macro_build (&icnt
, (expressionS
*) NULL
, "addu", "d,v,t",
1528 macro_build_lui (&icnt
, &offset_expr
, AT
);
1530 macro_build (&icnt
, NULL
, "addu", "d,v,t", AT
, AT
, breg
);
1533 /* Even on a big endian machine $fn comes before $fn+1. We have
1534 to adjust when storing to memory. */
1535 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1536 byte_order
== LITTLE_ENDIAN
? treg
: treg
+ 1,
1538 offset_expr
.X_add_number
+= 4;
1539 macro_build (&icnt
, &offset_expr
, "swc1", "T,o(b)",
1540 byte_order
== LITTLE_ENDIAN
? treg
+ 1 : treg
,
1548 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, treg
);
1550 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
1553 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
1554 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
1559 if (imm_expr
.X_add_number
== 0)
1561 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, sreg
);
1566 as_warn ("Instruction %s: result is always false",
1568 macro_build (&icnt
, NULL
, "move", "d,s", dreg
, 0);
1571 switch (imm_expr
.X_add_number
& 0xffff8000)
1575 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
1580 if (imm_expr
.X_add_number
!= -32768)
1582 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1583 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", dreg
, sreg
);
1590 macro_build_lui (&icnt
, &imm_expr
, AT
);
1591 if (imm_expr
.X_add_number
& 0xffff)
1592 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
1593 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
1596 macro_build (&icnt
, &expr1
, "sltiu", "t,r,j", dreg
, dreg
);
1601 case M_SGE
: /* sreg >= treg <==> not (sreg < treg) */
1607 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, sreg
, treg
);
1608 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1611 case M_SGE_I
: /* sreg >= I <==> not (sreg < I) */
1613 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32769)
1615 macro_build (&icnt
, &expr1
,
1616 mask
== M_SGE_I
? "slti" : "sltiu", "t,r,j", dreg
, sreg
);
1621 load_register (&icnt
, ip
, AT
, &imm_expr
);
1622 macro_build (&icnt
, NULL
,
1623 mask
== M_SGE_I
? "slt" : "sltu", "d,v,t", dreg
, sreg
, AT
);
1626 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1631 case M_SGT
: /* sreg > treg <==> treg < sreg */
1637 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
1640 case M_SGT_I
: /* sreg > I <==> I < sreg */
1646 load_register (&icnt
, ip
, AT
, &imm_expr
);
1647 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
1650 case M_SLE
: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
1656 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, treg
, sreg
);
1657 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1660 case M_SLE_I
: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
1666 load_register (&icnt
, ip
, AT
, &imm_expr
);
1667 macro_build (&icnt
, NULL
, s
, "d,v,t", dreg
, AT
, sreg
);
1668 macro_build (&icnt
, &expr1
, "xori", "t,r,i", dreg
, dreg
);
1672 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32769)
1674 macro_build (&icnt
, &imm_expr
, "slti", "t,r,j", dreg
, sreg
);
1677 load_register (&icnt
, ip
, AT
, &imm_expr
);
1678 macro_build (&icnt
, NULL
, "slt", "d,v,t", dreg
, sreg
, AT
);
1682 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32769)
1684 macro_build (&icnt
, &imm_expr
, "sltiu", "t,r,j", dreg
, sreg
);
1687 load_register (&icnt
, ip
, AT
, &imm_expr
);
1688 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, sreg
, AT
);
1693 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, treg
);
1695 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
1698 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, treg
);
1699 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
1704 if (imm_expr
.X_add_number
== 0)
1706 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, sreg
);
1711 as_warn ("Instruction %s: result is always true",
1713 macro_build (&icnt
, &expr1
, "addiu", "t,r,j", dreg
, 0);
1716 switch (imm_expr
.X_add_number
& 0xffff8000)
1720 macro_build (&icnt
, &imm_expr
, "xori", "t,r,i", dreg
, sreg
);
1725 if (imm_expr
.X_add_number
!= -32768)
1727 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1728 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", dreg
, sreg
);
1735 macro_build_lui (&icnt
, &imm_expr
, AT
);
1736 if (imm_expr
.X_add_number
& 0xffff)
1737 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", AT
, AT
);
1738 macro_build (&icnt
, NULL
, "xor", "d,v,t", dreg
, sreg
, AT
);
1741 macro_build (&icnt
, NULL
, "sltu", "d,v,t", dreg
, 0, dreg
);
1747 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32768)
1749 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1750 macro_build (&icnt
, &imm_expr
, "addi", "t,r,j", dreg
, sreg
);
1753 load_register (&icnt
, ip
, AT
, &imm_expr
);
1754 macro_build (&icnt
, NULL
, "sub", "d,v,t", dreg
, sreg
, AT
);
1758 if (imm_expr
.X_add_number
< 32768 && imm_expr
.X_add_number
> -32768)
1760 imm_expr
.X_add_number
= -imm_expr
.X_add_number
;
1761 macro_build (&icnt
, &imm_expr
, "addiu", "t,r,j", dreg
, sreg
);
1764 load_register (&icnt
, ip
, AT
, &imm_expr
);
1765 macro_build (&icnt
, NULL
, "subu", "d,v,t", dreg
, sreg
, AT
);
1770 sreg
= (ip
->insn_opcode
>> 11) & 0x1f; /* floating reg */
1771 dreg
= (ip
->insn_opcode
>> 06) & 0x1f; /* floating reg */
1774 * Is the double cfc1 instruction a bug in the mips assembler;
1775 * or is there a reason for it?
1777 save_reorder_condition
= mips_noreorder
;
1779 macro_build (&icnt
, NULL
, "cfc1", "t,d", treg
, 31);
1780 macro_build (&icnt
, NULL
, "cfc1", "t,d", treg
, 31);
1781 macro_build (&icnt
, NULL
, "nop", "");
1782 expr1
.X_add_number
= 3;
1783 macro_build (&icnt
, &expr1
, "ori", "t,r,i", AT
, treg
);
1784 expr1
.X_add_number
= 2;
1785 macro_build (&icnt
, &expr1
, "xori", "t,r,i", AT
, AT
);
1786 macro_build (&icnt
, NULL
, "ctc1", "t,d", AT
, 31);
1787 macro_build (&icnt
, NULL
, "nop", "");
1788 macro_build (&icnt
, NULL
,
1789 mask
== M_TRUNCWD
? "cvt.w.d" : "cvt.w.s", "D,S", dreg
, sreg
);
1790 macro_build (&icnt
, NULL
, "ctc1", "t,d", treg
, 31);
1791 macro_build (&icnt
, NULL
, "nop", "");
1792 mips_noreorder
= save_reorder_condition
;
1801 /* avoid load delay */
1802 offset_expr
.X_add_number
+= 1;
1803 macro_build (&icnt
, &offset_expr
, s
, "t,o(b)", treg
, breg
);
1804 offset_expr
.X_add_number
-= 1;
1805 macro_build (&icnt
, &offset_expr
, "lbu", "t,o(b)", AT
, breg
);
1806 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
1807 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
1811 /* does this work on a big endian machine? */
1812 offset_expr
.X_add_number
+= 3;
1813 macro_build (&icnt
, &offset_expr
, "lwl", "t,o(b)", treg
, breg
);
1814 offset_expr
.X_add_number
-= 3;
1815 macro_build (&icnt
, &offset_expr
, "lwr", "t,o(b)", treg
, breg
);
1821 if (offset_expr
.X_seg
== &bfd_abs_section
)
1822 load_register (&icnt
, ip
, AT
, &offset_expr
);
1823 else if (gp_reference (&offset_expr
))
1824 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, GP
);
1827 macro_build_lui (&icnt
, &offset_expr
, AT
);
1828 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, AT
);
1830 if (mask
== M_ULW_A
)
1832 expr1
.X_add_number
= 3;
1833 macro_build (&icnt
, &expr1
, "lwl", "t,o(b)", treg
, AT
);
1834 imm_expr
.X_add_number
= 0;
1835 macro_build (&icnt
, &expr1
, "lwr", "t,o(b)", treg
, AT
);
1839 macro_build (&icnt
, &expr1
,
1840 mask
== M_ULH_A
? "lb" : "lbu", "t,o(b)", treg
, AT
);
1841 imm_expr
.X_add_number
= 0;
1842 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
1843 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
1844 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
1849 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", treg
, breg
);
1850 macro_build (&icnt
, NULL
, "srl", "d,w,<", AT
, treg
, 8);
1851 offset_expr
.X_add_number
+= 1;
1852 macro_build (&icnt
, &offset_expr
, "sb", "t,o(b)", AT
, breg
);
1856 offset_expr
.X_add_number
+= 3;
1857 macro_build (&icnt
, &offset_expr
, "swl", "t,o(b)", treg
, breg
);
1858 offset_expr
.X_add_number
-= 3;
1859 macro_build (&icnt
, &offset_expr
, "swr", "t,o(b)", treg
, breg
);
1864 if (offset_expr
.X_seg
== &bfd_abs_section
)
1865 load_register (&icnt
, ip
, AT
, &offset_expr
);
1866 else if (gp_reference (&offset_expr
))
1867 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, GP
);
1870 macro_build_lui (&icnt
, &offset_expr
, AT
);
1871 macro_build (&icnt
, &offset_expr
, "addiu", "t,r,j", AT
, AT
);
1873 if (mask
== M_USW_A
)
1875 expr1
.X_add_number
= 3;
1876 macro_build (&icnt
, &expr1
, "swl", "t,o(b)", treg
, AT
);
1877 expr1
.X_add_number
= 0;
1878 macro_build (&icnt
, &expr1
, "swr", "t,o(b)", treg
, AT
);
1882 expr1
.X_add_number
= 0;
1883 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
1884 macro_build (&icnt
, NULL
, "srl", "d,w,<", treg
, treg
, 8);
1885 expr1
.X_add_number
= 1;
1886 macro_build (&icnt
, &expr1
, "sb", "t,o(b)", treg
, AT
);
1887 expr1
.X_add_number
= 0;
1888 macro_build (&icnt
, &expr1
, "lbu", "t,o(b)", AT
, AT
);
1889 macro_build (&icnt
, NULL
, "sll", "d,w,<", treg
, treg
, 8);
1890 macro_build (&icnt
, NULL
, "or", "d,v,t", treg
, treg
, AT
);
1895 as_bad ("Macro %s not implemented yet", ip
->insn_mo
->name
);
1898 as_warn ("Macro used $at after \".set noat\"");
1903 This routine assembles an instruction into its binary format. As a side
1904 effect it sets one of the global variables imm_reloc or offset_reloc to the
1905 type of relocation to do if one of the operands is an address expression.
1910 struct mips_cl_insn
*ip
;
1915 struct mips_opcode
*insn
;
1918 unsigned int lastregno
= 0;
1923 for (s
= str
; islower (*s
) || (*s
>= '0' && *s
<= '3') || *s
== '.'; ++s
)
1935 as_warn ("Unknown opcode: `%s'", str
);
1938 if ((insn
= (struct mips_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1940 as_warn ("`%s' not in hash table.", str
);
1941 insn_error
= "ERROR: Unrecognized opcode";
1947 assert (strcmp (insn
->name
, str
) == 0);
1949 ip
->insn_opcode
= insn
->match
;
1950 for (args
= insn
->args
;; ++args
)
1956 case '\0': /* end of args */
1969 ip
->insn_opcode
|= lastregno
<< 21;
1974 ip
->insn_opcode
|= lastregno
<< 16;
1978 ip
->insn_opcode
|= lastregno
<< 11;
1984 /* handle optional base register.
1985 Either the base register is omitted or
1986 we must have a left paren. */
1987 /* this is dependent on the next operand specifier
1988 is a 'b' for base register */
1989 assert (args
[1] == 'b');
1993 case ')': /* these must match exactly */
1998 case '<': /* must be at least one digit */
2000 * According to the manual, if the shift amount is greater
2001 * than 31 or less than 0 the the shift amount should be
2002 * mod 32. In reality the mips assembler issues an error.
2003 * We issue a warning and do the mod.
2005 my_getExpression (&imm_expr
, s
);
2006 check_absolute_expr (ip
, &imm_expr
);
2007 if ((unsigned long) imm_expr
.X_add_number
> 31)
2009 as_warn ("Improper shift amount (%d)",
2010 imm_expr
.X_add_number
);
2011 imm_expr
.X_add_number
= imm_expr
.X_add_number
% 32;
2013 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 6;
2014 imm_expr
.X_seg
= absent_section
;
2018 case 'c': /* break code */
2019 my_getExpression (&imm_expr
, s
);
2020 check_absolute_expr (ip
, &imm_expr
);
2021 if ((unsigned) imm_expr
.X_add_number
> 1023)
2022 as_warn ("Illegal break code (%d)", imm_expr
.X_add_number
);
2023 ip
->insn_opcode
|= imm_expr
.X_add_number
<< 16;
2024 imm_expr
.X_seg
= absent_section
;
2028 case 'b': /* base register */
2029 case 'd': /* destination register */
2030 case 's': /* source register */
2031 case 't': /* target register */
2032 case 'r': /* both target and source */
2033 case 'v': /* both dest and source */
2034 case 'w': /* both dest and target */
2048 while (isdigit (*s
));
2050 else if (s
[1] == 'f' && s
[2] == 'p')
2055 else if (s
[1] == 's' && s
[2] == 'p')
2060 else if (s
[1] == 'g' && s
[2] == 'p')
2065 else if (s
[1] == 'a' && s
[2] == 't')
2073 as_bad ("Invalid register number (%d)", regno
);
2074 if (regno
== AT
&& !mips_noat
)
2075 as_warn ("Used $at without \".set noat\"");
2081 if (c
== 'r' || c
== 'v' || c
== 'w')
2094 ip
->insn_opcode
|= regno
<< 21;
2097 ip
->insn_opcode
|= regno
<< 11;
2101 ip
->insn_opcode
|= regno
<< 16;
2111 ip
->insn_opcode
|= lastregno
<< 21;
2114 ip
->insn_opcode
|= lastregno
<< 16;
2119 case 'D': /* floating point destination register */
2120 case 'S': /* floating point source register */
2121 case 'T': /* floating point target register */
2125 if (s
[0] == '$' && s
[1] == 'f' && isdigit (s
[2]))
2135 while (isdigit (*s
));
2138 as_bad ("Invalid float register number (%d)", regno
);
2141 !(strcmp (str
, "mtc1") == 0 ||
2142 strcmp (str
, "mfc1") == 0 ||
2143 strcmp (str
, "lwc1") == 0 ||
2144 strcmp (str
, "swc1") == 0))
2145 as_warn ("Float register should be even, was %d",
2153 if (c
== 'V' || c
== 'W')
2163 ip
->insn_opcode
|= regno
<< 6;
2167 ip
->insn_opcode
|= regno
<< 11;
2171 ip
->insn_opcode
|= regno
<< 16;
2179 ip
->insn_opcode
|= lastregno
<< 11;
2182 ip
->insn_opcode
|= lastregno
<< 16;
2188 my_getExpression (&imm_expr
, s
);
2189 check_absolute_expr (ip
, &imm_expr
);
2194 my_getExpression (&offset_expr
, s
);
2195 imm_reloc
= BFD_RELOC_32
;
2200 as_bad ("Floating point constants only implemented for pseudo ops.");
2203 case 'i': /* 16 bit unsigned immediate */
2204 case 'j': /* 16 bit signed immediate */
2205 imm_reloc
= BFD_RELOC_LO16
;
2206 c
= my_getSmallExpression (&imm_expr
, s
);
2211 if (imm_expr
.X_seg
== &bfd_abs_section
)
2212 imm_expr
.X_add_number
=
2213 (imm_expr
.X_add_number
>> 16) & 0xffff;
2215 imm_reloc
= BFD_RELOC_HI16_S
;
2217 imm_reloc
= BFD_RELOC_HI16
;
2221 check_absolute_expr (ip
, &imm_expr
);
2224 if ((unsigned long) imm_expr
.X_add_number
> 65535)
2225 as_bad ("16 bit expression not in range 0..65535");
2229 if (imm_expr
.X_add_number
< -32768 ||
2230 imm_expr
.X_add_number
> 32767)
2231 as_bad ("16 bit expression not in range -32768..32767");
2236 case 'o': /* 16 bit offset */
2237 c
= my_getSmallExpression (&offset_expr
, s
);
2239 * If this value won't fit into a 16 bit offset, then
2240 * go find a macro that will generate the 32 bit offset
2243 if ((offset_expr
.X_add_symbol
2244 && offset_expr
.X_seg
!= &bfd_abs_section
)
2245 || offset_expr
.X_subtract_symbol
2246 || offset_expr
.X_add_number
> 32767
2247 || offset_expr
.X_add_number
< -32768)
2250 offset_reloc
= BFD_RELOC_LO16
;
2251 if (c
== 'h' || c
== 'H')
2252 offset_expr
.X_add_number
=
2253 (offset_expr
.X_add_number
>> 16) & 0xffff;
2257 case 'p': /* pc relative offset */
2258 offset_reloc
= BFD_RELOC_16_PCREL_S2
;
2259 my_getExpression (&offset_expr
, s
);
2263 case 'u': /* upper 16 bits */
2264 c
= my_getSmallExpression (&imm_expr
, s
);
2265 if ((unsigned long) imm_expr
.X_add_number
> 65535)
2266 as_bad ("lui expression not in range 0..65535");
2267 imm_reloc
= BFD_RELOC_LO16
;
2272 if (imm_expr
.X_seg
== &bfd_abs_section
)
2273 imm_expr
.X_add_number
=
2274 (imm_expr
.X_add_number
>> 16) & 0xffff;
2276 imm_reloc
= BFD_RELOC_HI16_S
;
2278 imm_reloc
= BFD_RELOC_HI16
;
2284 case 'a': /* 26 bit address */
2285 my_getExpression (&offset_expr
, s
);
2287 offset_reloc
= BFD_RELOC_MIPS_JMP
;
2291 fprintf (stderr
, "bad char = '%c'\n", *args
);
2296 /* Args don't match. */
2297 if (insn
+ 1 < &mips_opcodes
[NUMOPCODES
] &&
2298 !strcmp (insn
->name
, insn
[1].name
))
2304 insn_error
= "ERROR: Illegal operands";
2313 my_getSmallExpression (ep
, str
)
2324 ((str
[1] == 'h' && str
[2] == 'i')
2325 || (str
[1] == 'H' && str
[2] == 'I')
2326 || (str
[1] == 'l' && str
[2] == 'o'))
2338 * A small expression may be followed by a base register.
2339 * Scan to the end of this operand, and then back over a possible
2340 * base register. Then scan the small expression up to that
2341 * point. (Based on code in sparc.c...)
2343 for (sp
= str
; *sp
&& *sp
!= ','; sp
++)
2345 if (sp
- 4 >= str
&& sp
[-1] == RP
)
2347 if (isdigit (sp
[-2]))
2349 for (sp
-= 3; sp
>= str
&& isdigit (*sp
); sp
--)
2351 if (*sp
== '$' && sp
> str
&& sp
[-1] == LP
)
2357 else if (sp
- 5 >= str
2360 && ((sp
[-3] == 'f' && sp
[-2] == 'p')
2361 || (sp
[-3] == 's' && sp
[-2] == 'p')
2362 || (sp
[-3] == 'g' && sp
[-2] == 'p')
2363 || (sp
[-3] == 'a' && sp
[-2] == 't')))
2369 /* no expression means zero offset */
2372 /* %xx(reg) is an error */
2373 ep
->X_seg
= absent_section
;
2378 ep
->X_seg
= &bfd_abs_section
;
2381 ep
->X_add_symbol
= NULL
;
2382 ep
->X_subtract_symbol
= NULL
;
2383 ep
->X_add_number
= 0;
2388 my_getExpression (ep
, str
);
2395 my_getExpression (ep
, str
);
2396 return c
; /* => %hi or %lo encountered */
2400 my_getExpression (ep
, str
)
2407 save_in
= input_line_pointer
;
2408 input_line_pointer
= str
;
2409 seg
= expression (ep
);
2410 expr_end
= input_line_pointer
;
2411 input_line_pointer
= save_in
;
2415 md_atof (type
, litP
, sizeP
)
2425 md_number_to_chars (buf
, val
, n
)
2477 md_parse_option (argP
, cntP
, vecP
)
2482 /* Accept -nocpp but ignore it. */
2483 if (!strcmp (*argP
, "nocpp"))
2489 if (strcmp (*argP
, "EL") == 0
2490 || strcmp (*argP
, "EB") == 0)
2492 /* FIXME: This breaks -L -EL. */
2501 if ((*argP
)[1] != '\0')
2502 g_switch_value
= atoi (*argP
+ 1);
2505 **vecP
= (char *) NULL
;
2508 g_switch_value
= atoi (**vecP
);
2511 as_warn ("Number expected after -G");
2516 return 1; /* pretend you parsed the character */
2520 md_pcrel_from (fixP
)
2523 /* return the address of the delay slot */
2524 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2528 md_apply_fix (fixP
, valueP
)
2535 assert (fixP
->fx_size
== 4);
2538 fixP
->fx_addnumber
= value
; /* Remember value for tc_gen_reloc */
2540 switch (fixP
->fx_r_type
)
2543 case BFD_RELOC_MIPS_JMP
:
2544 case BFD_RELOC_HI16
:
2545 case BFD_RELOC_HI16_S
:
2546 case BFD_RELOC_LO16
:
2547 case BFD_RELOC_MIPS_GPREL
:
2548 /* Nothing needed to do. The value comes from the reloc entry */
2551 case BFD_RELOC_16_PCREL_S2
:
2553 * We need to save the bits in the instruction since fixup_segment()
2554 * might be deleting the relocation entry (i.e., a branch within
2555 * the current segment).
2558 as_warn ("Branch to odd address (%x)", value
);
2560 if ((value
& ~0xFFFF) && (value
& ~0xFFFF) != (-1 & ~0xFFFF))
2561 as_bad ("Relocation overflow");
2563 /* update old instruction data */
2564 buf
= (unsigned char *) (fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
);
2568 insn
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2572 insn
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | buf
[3];
2579 insn
|= value
& 0xFFFF;
2580 md_number_to_chars (buf
, insn
, 4);
2594 const struct mips_opcode
*p
;
2595 int treg
, sreg
, dreg
, shamt
;
2600 for (i
= 0; i
< NUMOPCODES
; ++i
)
2602 p
= &mips_opcodes
[i
];
2603 if (((oc
& p
->mask
) == p
->match
) && (p
->pinfo
!= INSN_MACRO
))
2605 printf ("%08lx %s\t", oc
, p
->name
);
2606 treg
= (oc
>> 16) & 0x1f;
2607 sreg
= (oc
>> 21) & 0x1f;
2608 dreg
= (oc
>> 11) & 0x1f;
2609 shamt
= (oc
>> 6) & 0x1f;
2611 for (args
= p
->args
;; ++args
)
2622 printf ("%c", *args
);
2626 assert (treg
== sreg
);
2627 printf ("$%d,$%d", treg
, sreg
);
2631 printf ("$%d", dreg
);
2635 printf ("$%d", treg
);
2640 printf ("$%d", sreg
);
2644 printf ("0x%08lx", oc
& 0x1ffffff);
2655 printf ("$%d", shamt
);
2666 printf ("%08lx UNDEFINED\n", oc
);
2677 name
= input_line_pointer
;
2678 c
= get_symbol_end ();
2679 p
= (symbolS
*) symbol_find_or_make (name
);
2680 *input_line_pointer
= c
;
2685 get_optional_absolute_expression ()
2690 s
= expression (&exp
);
2691 if (!(s
== &bfd_abs_section
|| s
== big_section
|| s
== absent_section
))
2693 as_bad ("Bad Absolute Expression.");
2695 return exp
.X_add_number
;
2703 register long temp_fill
;
2704 long max_alignment
= 15;
2708 o Note that the assembler pulls down any immediately preceeding label
2709 to the aligned address.
2710 o It's not documented but auto alignment is reinstated by
2711 a .align pseudo instruction.
2712 o Note also that after auto alignment is turned off the mips assembler
2713 issues an error on attempt to assemble an improperly aligned data item.
2718 temp
= get_absolute_expression ();
2719 if (temp
> max_alignment
)
2720 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
2723 as_warn ("Alignment negative: 0 assumed.");
2726 if (*input_line_pointer
== ',')
2728 input_line_pointer
++;
2729 temp_fill
= get_absolute_expression ();
2737 frag_align (temp
, (int) temp_fill
);
2744 record_alignment (now_seg
, temp
);
2746 demand_empty_rest_of_line ();
2760 subseg_new (".rdata", (subsegT
) get_absolute_expression ());
2769 #ifdef BFD_ASSEMBLER
2770 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
2772 subseg_new (bss_section
, (subsegT
) get_absolute_expression ());
2774 demand_empty_rest_of_line ();
2778 subseg_new (".sdata", (subsegT
) get_absolute_expression ());
2781 as_bad ("Global pointers not supported; recompile -G 0");
2793 if (log_size
> 0 && auto_align
)
2794 frag_align (log_size
, 0);
2795 cons (1 << log_size
);
2802 as_fatal ("Encountered `.err', aborting assembly");
2812 symbolP
= get_symbol ();
2813 if (*input_line_pointer
== ',')
2814 input_line_pointer
++;
2815 size
= get_optional_absolute_expression ();
2816 S_SET_VALUE (symbolP
, size
);
2817 S_SET_EXTERNAL (symbolP
);
2820 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
2821 so we use an additional ECOFF specific field. */
2822 symbolP
->ecoff_undefined
= 1;
2827 s_float_cons (is_double
)
2832 int error_code
, repeat
;
2833 extern FLONUM_TYPE generic_floating_point_number
;
2842 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2846 error_code
= atof_generic (&input_line_pointer
, ".", EXP_CHARS
,
2847 &generic_floating_point_number
);
2850 if (error_code
== ERROR_EXPONENT_OVERFLOW
)
2851 as_warn ("Bad floating-point constant: exponent overflow");
2853 as_warn ("Bad floating-point constant: unknown error code=%d.", error_code
);
2858 gen_to_words ((LITTLENUM_TYPE
*) words
,
2860 11 /* exponent_bits */ );
2864 gen_to_words ((LITTLENUM_TYPE
*) words
,
2866 8 /* exponent_bits */ );
2868 if (*input_line_pointer
== ':')
2870 input_line_pointer
++;
2871 repeat
= get_absolute_expression ();
2879 f
= frag_more (repeat
* 8);
2880 for (; repeat
--; f
+= 8)
2882 md_number_to_chars (f
+ 6, words
[0], 2);
2883 md_number_to_chars (f
+ 4, words
[1], 2);
2884 md_number_to_chars (f
+ 2, words
[2], 2);
2885 md_number_to_chars (f
, words
[3], 2);
2890 f
= frag_more (repeat
* 4);
2891 for (; repeat
--; f
+= 4)
2893 md_number_to_chars (f
+ 2, words
[0], 2);
2894 md_number_to_chars (f
, words
[1], 2);
2898 if (*input_line_pointer
!= ',')
2900 input_line_pointer
++;
2905 demand_empty_rest_of_line ();
2912 if (strcmp (input_line_pointer
, "O1") != 0
2913 && strcmp (input_line_pointer
, "O2") != 0)
2914 as_warn ("Unrecognized option");
2915 demand_empty_rest_of_line ();
2922 char *name
= input_line_pointer
, ch
;
2924 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2925 input_line_pointer
++;
2926 ch
= *input_line_pointer
;
2927 *input_line_pointer
= '\0';
2929 if (strcmp (name
, "reorder") == 0)
2933 else if (strcmp (name
, "noreorder") == 0)
2937 else if (strcmp (name
, "at") == 0)
2941 else if (strcmp (name
, "noat") == 0)
2945 else if (strcmp (name
, "macro") == 0)
2947 mips_warn_about_macros
= 0;
2949 else if (strcmp (name
, "nomacro") == 0)
2951 if (mips_noreorder
== 0)
2952 as_bad ("`noreorder' must be set before `nomacro'");
2953 mips_warn_about_macros
= 1;
2955 else if (strcmp (name
, "move") == 0 || strcmp (name
, "novolatile") == 0)
2959 else if (strcmp (name
, "nomove") == 0 || strcmp (name
, "volatile") == 0)
2963 else if (strcmp (name
, "bopt") == 0)
2967 else if (strcmp (name
, "nobopt") == 0)
2973 as_warn ("Tried to set unrecognized symbol: %s\n", name
);
2975 *input_line_pointer
= ch
;
2976 demand_empty_rest_of_line ();
2985 if (*input_line_pointer
++ != '$')
2987 as_warn ("expected `$'");
2990 if (isdigit ((unsigned char) *input_line_pointer
))
2992 reg
= get_absolute_expression ();
2993 if (reg
< 0 || reg
>= 32)
2995 as_warn ("Bad register number");
3001 if (strncmp (input_line_pointer
, "fp", 2) == 0)
3003 else if (strncmp (input_line_pointer
, "sp", 2) == 0)
3005 else if (strncmp (input_line_pointer
, "gp", 2) == 0)
3007 else if (strncmp (input_line_pointer
, "at", 2) == 0)
3011 as_warn ("Unrecognized register name");
3014 input_line_pointer
+= 2;
3020 * Translate internal representation of relocation info to BFD target format.
3023 tc_gen_reloc (section
, fixp
)
3029 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3030 assert (reloc
!= 0);
3032 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
3033 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3034 if (fixp
->fx_pcrel
== 0)
3035 reloc
->addend
= fixp
->fx_addnumber
;
3040 reloc
->addend
= -reloc
->address
;
3042 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3043 assert (reloc
->howto
!= 0);
3046 /* FIXME: This does the right thing, but it's confusing. There
3047 should be a more coherent approach, but I don't know what it
3050 bfd_get_section_vma (stdoutput
,
3051 bfd_get_section (fixp
->fx_addsy
->bsym
));
3057 /* should never be called */
3059 md_section_align (seg
, addr
)
3063 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3065 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
3069 md_estimate_size_before_relax (fragP
, segtype
)
3073 as_fatal ("md_estimate_size_before_relax");
3075 } /* md_estimate_size_before_relax() */
3079 /* These functions should really be defined by the object file format,
3080 since they are related to debugging information. However, this
3081 code has to work for the a.out format, which does not define them,
3082 so we provide simple versions here. These don't actually generate
3083 any debugging information, but they do simple checking and someday
3084 somebody may make them useful. */
3088 struct loc
*loc_next
;
3089 unsigned long loc_fileno
;
3090 unsigned long loc_lineno
;
3091 unsigned long loc_offset
;
3092 unsigned short loc_delta
;
3093 unsigned short loc_count
;
3102 struct proc
*proc_next
;
3103 struct symbol
*proc_isym
;
3104 struct symbol
*proc_end
;
3105 unsigned long proc_reg_mask
;
3106 unsigned long proc_reg_offset
;
3107 unsigned long proc_fpreg_mask
;
3108 unsigned long proc_fpreg_offset
;
3109 unsigned long proc_frameoffset
;
3110 unsigned long proc_framereg
;
3111 unsigned long proc_pcreg
;
3113 struct file
*proc_file
;
3120 struct file
*file_next
;
3121 unsigned long file_fileno
;
3122 struct symbol
*file_symbol
;
3123 struct symbol
*file_end
;
3124 struct proc
*file_proc
;
3129 static struct obstack proc_frags
;
3130 static procS
*proc_lastP
;
3131 static procS
*proc_rootP
;
3132 static int numprocs
;
3137 obstack_begin (&proc_frags
, 0x2000);
3143 /* check for premature end, nesting errors, etc */
3144 if (proc_lastP
&& proc_lastP
->proc_end
== NULL
)
3145 as_warn ("missing `.end' at end of assembly");
3148 extern char hex_value
[];
3156 if (*input_line_pointer
== '-')
3158 ++input_line_pointer
;
3161 if (!isdigit (*input_line_pointer
))
3162 as_bad ("Expected simple number.");
3163 if (input_line_pointer
[0] == '0')
3165 if (input_line_pointer
[1] == 'x')
3167 input_line_pointer
+= 2;
3168 while (isxdigit (*input_line_pointer
))
3171 val
|= hex_value
[(int) *input_line_pointer
++];
3173 return negative
? -val
: val
;
3177 ++input_line_pointer
;
3178 while (isdigit (*input_line_pointer
))
3181 val
|= *input_line_pointer
++ - '0';
3183 return negative
? -val
: val
;
3186 if (!isdigit (*input_line_pointer
))
3188 printf (" *input_line_pointer == '%c' 0x%02x\n",
3189 *input_line_pointer
, *input_line_pointer
);
3190 as_warn ("Invalid number");
3193 while (isdigit (*input_line_pointer
))
3196 val
+= *input_line_pointer
++ - '0';
3198 return negative
? -val
: val
;
3201 /* The .file directive; just like the usual .file directive, but there
3202 is an initial number which is the ECOFF file index. */
3210 line
= get_number ();
3215 /* The .end directive. */
3223 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3226 demand_empty_rest_of_line ();
3230 if (now_seg
!= text_section
)
3231 as_warn (".end not in text section");
3234 as_warn (".end and no .ent seen yet.");
3240 assert (S_GET_NAME (p
));
3241 if (strcmp (S_GET_NAME (p
), S_GET_NAME (proc_lastP
->proc_isym
)))
3242 as_warn (".end symbol does not match .ent symbol.");
3245 proc_lastP
->proc_end
= (symbolS
*) 1;
3248 /* The .aent and .ent directives. */
3258 symbolP
= get_symbol ();
3259 if (*input_line_pointer
== ',')
3260 input_line_pointer
++;
3261 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
3262 number
= get_number ();
3263 if (now_seg
!= text_section
)
3264 as_warn (".ent or .aent not in text section.");
3266 if (!aent
&& proc_lastP
&& proc_lastP
->proc_end
== NULL
)
3267 as_warn ("missing `.end'");
3271 procP
= (procS
*) obstack_alloc (&proc_frags
, sizeof (*procP
));
3272 procP
->proc_isym
= symbolP
;
3273 procP
->proc_reg_mask
= 0;
3274 procP
->proc_reg_offset
= 0;
3275 procP
->proc_fpreg_mask
= 0;
3276 procP
->proc_fpreg_offset
= 0;
3277 procP
->proc_frameoffset
= 0;
3278 procP
->proc_framereg
= 0;
3279 procP
->proc_pcreg
= 0;
3280 procP
->proc_end
= NULL
;
3281 procP
->proc_next
= NULL
;
3283 proc_lastP
->proc_next
= procP
;
3289 demand_empty_rest_of_line ();
3292 /* The .frame directive. */
3305 frame_reg
= tc_get_register ();
3306 if (*input_line_pointer
== ',')
3307 input_line_pointer
++;
3308 frame_off
= get_optional_absolute_expression ();
3309 if (*input_line_pointer
== ',')
3310 input_line_pointer
++;
3311 pcreg
= tc_get_register ();
3314 assert (proc_rootP
);
3315 proc_rootP
->proc_framereg
= frame_reg
;
3316 proc_rootP
->proc_frameoffset
= frame_off
;
3317 proc_rootP
->proc_pcreg
= pcreg
;
3318 /* bob macho .frame */
3320 /* We don't have to write out a frame stab for unoptimized code. */
3321 if (!(frame_reg
== 30 && frame_off
== 0))
3324 as_warn ("No .ent for .frame to use.");
3325 (void) sprintf (str
, "R%d;%d", frame_reg
, frame_off
);
3326 symP
= symbol_new (str
, N_VFP
, 0, frag_now
);
3327 S_SET_TYPE (symP
, N_RMASK
);
3328 S_SET_OTHER (symP
, 0);
3329 S_SET_DESC (symP
, 0);
3330 symP
->sy_forward
= proc_lastP
->proc_isym
;
3331 /* bob perhaps I should have used pseudo set */
3333 demand_empty_rest_of_line ();
3337 /* The .fmask and .mask directives. */
3344 char str
[100], *strP
;
3350 mask
= get_number ();
3351 if (*input_line_pointer
== ',')
3352 input_line_pointer
++;
3353 off
= get_absolute_expression ();
3355 /* bob only for coff */
3356 assert (proc_rootP
);
3357 if (reg_type
== 'F')
3359 proc_rootP
->proc_fpreg_mask
= mask
;
3360 proc_rootP
->proc_fpreg_offset
= off
;
3364 proc_rootP
->proc_reg_mask
= mask
;
3365 proc_rootP
->proc_reg_offset
= off
;
3368 /* bob macho .mask + .fmask */
3370 /* We don't have to write out a mask stab if no saved regs. */
3374 as_warn ("No .ent for .mask to use.");
3376 for (i
= 0; i
< 32; i
++)
3380 sprintf (strP
, "%c%d,", reg_type
, i
);
3381 strP
+= strlen (strP
);
3385 sprintf (strP
, ";%d,", off
);
3386 symP
= symbol_new (str
, N_RMASK
, 0, frag_now
);
3387 S_SET_TYPE (symP
, N_RMASK
);
3388 S_SET_OTHER (symP
, 0);
3389 S_SET_DESC (symP
, 0);
3390 symP
->sy_forward
= proc_lastP
->proc_isym
;
3391 /* bob perhaps I should have used pseudo set */
3396 /* The .loc directive. */
3407 assert (now_seg
== text_section
);
3409 lineno
= get_number ();
3410 addroff
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
3412 symbolP
= symbol_new ("", N_SLINE
, addroff
, frag_now
);
3413 S_SET_TYPE (symbolP
, N_SLINE
);
3414 S_SET_OTHER (symbolP
, 0);
3415 S_SET_DESC (symbolP
, lineno
);
3416 symbolP
->sy_segment
= now_seg
;
3420 #endif /* ! defined (OBJ_ECOFF) */