]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-mips.c
* symbols.c (S_IS_COMMON): Use bfd_is_com_section rather than
[thirdparty/binutils-gdb.git] / gas / config / tc-mips.c
CommitLineData
3d3c5039
ILT
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.
8358c818
ILT
5 Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
6 Support.
3d3c5039
ILT
7
8 This file is part of GAS.
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24#include "as.h"
8358c818 25#include "config.h"
3d3c5039
ILT
26
27#include <ctype.h>
28
29#ifndef __STDC__
30#ifndef NO_STDARG
31#define NO_STDARG
32#endif
33#endif
34
35#ifndef NO_STDARG
36#include <stdarg.h>
37#else
38#ifndef NO_VARARGS
39#include <varargs.h>
40#endif /* NO_VARARGS */
41#endif /* NO_STDARG */
42
918692a5 43#include "opcode/mips.h"
3d3c5039 44
f2a663d3
ILT
45#ifdef OBJ_ELF
46#include "elf/mips.h"
47
48static char *mips_regmask_frag;
49#endif
50
3d3c5039 51#define AT 1
9226253a 52#define PIC_CALL_REG 25
670a50eb 53#define GP 28
9226253a
ILT
54#define SP 29
55#define FP 30
3d3c5039
ILT
56#define RA 31
57
88225433
ILT
58/* Decide whether to do GP reference optimizations based on the object
59 file format. */
60#undef GPOPT
61#ifdef OBJ_ECOFF
62#define GPOPT
63#endif
64#ifdef OBJ_ELF
65#define GPOPT
66#endif
67
04cb3372
ILT
68/* The default target format to use. */
69#ifdef OBJ_AOUT
70#ifdef TARGET_BYTES_BIG_ENDIAN
71#define DEFAULT_TARGET_FORMAT "a.out-mips-big"
72#else
73#define DEFAULT_TARGET_FORMAT "a.out-mips-little"
74#endif
75#endif /* OBJ_AOUT */
76#ifdef OBJ_ECOFF
77#ifdef TARGET_BYTES_BIG_ENDIAN
78#define DEFAULT_TARGET_FORMAT "ecoff-bigmips"
79#else
80#define DEFAULT_TARGET_FORMAT "ecoff-littlemips"
81#endif
82#endif /* OBJ_ECOFF */
83#ifdef OBJ_ELF
84#ifdef TARGET_BYTES_BIG_ENDIAN
85#define DEFAULT_TARGET_FORMAT "elf32-bigmips"
86#else
87#define DEFAULT_TARGET_FORMAT "elf32-littlemips"
88#endif
89#endif /* OBJ_ELF */
90
91const char *mips_target_format = DEFAULT_TARGET_FORMAT;
92
1aa6938e
ILT
93/* These variables are filled in with the masks of registers used.
94 The object format code reads them and puts them in the appropriate
95 place. */
96unsigned long mips_gprmask;
97unsigned long mips_cprmask[4];
98
8358c818
ILT
99/* MIPS ISA (Instruction Set Architecture) level. */
100static int mips_isa = -1;
101
9226253a 102/* MIPS PIC level. 0 is normal, non-PIC code. 2 means to generate
0dd2d296 103 SVR4 ABI PIC calls. 1 doesn't mean anything. */
9226253a
ILT
104static int mips_pic;
105
3d3c5039
ILT
106static int mips_warn_about_macros;
107static int mips_noreorder;
0dd2d296 108static int mips_any_noreorder;
3d3c5039
ILT
109static int mips_nomove;
110static int mips_noat;
111static int mips_nobopt;
112
88225433 113#ifdef GPOPT
670a50eb
ILT
114/* The size of the small data section. */
115static int g_switch_value = 8;
116#endif
117
3d3c5039
ILT
118#define N_RMASK 0xc4
119#define N_VFP 0xd4
120
121/* handle of the OPCODE hash table */
122static struct hash_control *op_hash = NULL;
123
124/* This array holds the chars that always start a comment. If the
125 pre-processor is disabled, these aren't very useful */
126const char comment_chars[] = "#";
127
128/* This array holds the chars that only start a comment at the beginning of
129 a line. If the line seems to have the form '# 123 filename'
130 .line and .file directives will appear in the pre-processed output */
131/* Note that input_file.c hand checks for '#' at the beginning of the
132 first line of the input file. This is because the compiler outputs
133 #NO_APP at the beginning of its output. */
134/* Also note that C style comments are always supported. */
135const char line_comment_chars[] = "#";
136
137/* This array holds machine specific line separator characters. */
138const char line_separator_chars[] = "";
139
140/* Chars that can be used to separate mant from exp in floating point nums */
141const char EXP_CHARS[] = "eE";
142
143/* Chars that mean this number is a floating point constant */
144/* As in 0f12.456 */
145/* or 0d1.2345e12 */
146const char FLT_CHARS[] = "rRsSfFdDxXpP";
147
148/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
149 changed in read.c . Ideally it shouldn't have to know about it at all,
150 but nothing is ideal around here.
151 */
152
670a50eb 153static char *insn_error;
3d3c5039
ILT
154
155static int byte_order = BYTE_ORDER;
156
157static int auto_align = 1;
becfe05e
ILT
158
159/* Symbol labelling the current insn. */
160static symbolS *insn_label;
161
9226253a
ILT
162/* When outputting SVR4 PIC code, the assembler needs to know the
163 offset in the stack frame from which to restore the $gp register.
164 This is set by the .cprestore pseudo-op, and saved in this
165 variable. */
0dd2d296
ILT
166static offsetT mips_cprestore_offset = -1;
167
168/* This is the register which holds the stack frame, as set by the
169 .frame pseudo-op. This is needed to implement .cprestore. */
170static int mips_frame_reg = SP;
9226253a 171
becfe05e
ILT
172/* To output NOP instructions correctly, we need to keep information
173 about the previous two instructions. */
174
0aa07269
ILT
175/* Whether we are optimizing. The default value of 2 means to remove
176 unneeded NOPs and swap branch instructions when possible. A value
177 of 1 means to not swap branches. A value of 0 means to always
178 insert NOPs. */
179static int mips_optimize = 2;
4e95866e 180
becfe05e
ILT
181/* The previous instruction. */
182static struct mips_cl_insn prev_insn;
183
184/* The instruction before prev_insn. */
185static struct mips_cl_insn prev_prev_insn;
186
187/* If we don't want information for prev_insn or prev_prev_insn, we
188 point the insn_mo field at this dummy integer. */
189static const struct mips_opcode dummy_opcode = { 0 };
190
191/* Non-zero if prev_insn is valid. */
192static int prev_insn_valid;
193
194/* The frag for the previous instruction. */
195static struct frag *prev_insn_frag;
196
197/* The offset into prev_insn_frag for the previous instruction. */
198static long prev_insn_where;
199
200/* The reloc for the previous instruction, if any. */
201static fixS *prev_insn_fixp;
202
203/* Non-zero if the previous instruction was in a delay slot. */
204static int prev_insn_is_delay_slot;
4e95866e
ILT
205
206/* Non-zero if the previous instruction was in a .set noreorder. */
207static int prev_insn_unreordered;
208
209/* Non-zero if the previous previous instruction was in a .set
210 noreorder. */
211static int prev_prev_insn_unreordered;
3d3c5039 212\f
0dd2d296
ILT
213/* Since the MIPS does not have multiple forms of PC relative
214 instructions, we do not have to do relaxing as is done on other
215 platforms. However, we do have to handle GP relative addressing
216 correctly, which turns out to be a similar problem.
217
218 Every macro that refers to a symbol can occur in (at least) two
219 forms, one with GP relative addressing and one without. For
220 example, loading a global variable into a register generally uses
221 an macroinstruction like this:
222 lw $4,i
223 If i can be addressed off the GP register (this is true if it is in
224 the .sbss or .sdata section, or if it is known to be smaller than
225 the -G argument) this will generate the following instruction:
226 lw $4,i($gp)
227 This instruction will use a GPREL reloc. If i can not be addressed
228 off the GP register, the following instruction sequence will be used:
229 lui $at,i
230 lw $4,i($at)
231 In this case the first instruction will have a HI16 reloc, and the
232 second reloc will have a LO16 reloc. Both relocs will be against
233 the symbol i.
234
235 The issue here is that we may not know whether i is GP addressable
236 until after we see the instruction that uses it. Therefore, we
237 want to be able to choose the final instruction sequence only at
238 the end of the assembly. This is similar to the way other
239 platforms choose the form of a PC relative instruction only at the
240 end of assembly.
241
242 When generating position independent code we do not use GP
243 addressing in the same way, but the issue still arises as external
244 symbols and local symbols must be handled differently.
245
246 We handle these issues by actually generating both possible
247 instruction sequences. The longer one is put in a frag_var with
248 type rs_machine_dependent. We encode what to do with the frag in
249 the subtype field. We encode (1) the number of existing bytes to
250 replace, (2) the number of new bytes to use, (3) the offset from
251 the start of the existing bytes to the first reloc we must generate
252 (that is, the offset is applied from the start of the existing
253 bytes after they are replaced by the new bytes, if any), (4) the
254 offset from the start of the existing bytes to the second reloc,
255 (5) whether a third reloc is needed (the third reloc is always four
256 bytes after the second reloc), and (6) whether to warn if this
257 variant is used (this is sometimes needed if .set nomacro or .set
258 noat is in effect). All these numbers are reasonably small.
259
260 Generating two instruction sequences must be handled carefully to
261 ensure that delay slots are handled correctly. Fortunately, the
262 issue only arises in a restricted number of cases. When the second
263 instruction sequence is generated, append_insn is directed to
264 maintain the existing delay slot information, so it continues to
265 apply to any code after the second instruction sequence. This
266 means that the second instruction sequence must not impose any
267 requirements not required by the first instruction sequence.
268
269 These variant frags are then handled in functions called by the
270 machine independent code. md_estimate_size_before_relax returns
271 the final size of the frag. md_convert_frag sets up the final form
272 of the frag. tc_gen_reloc adjust the first reloc and adds a second
273 one if needed. */
274#define RELAX_ENCODE(old, new, reloc1, reloc2, reloc3, warn) \
275 ((relax_substateT) \
276 (((old) << 24) \
277 | ((new) << 16) \
278 | (((reloc1) + 64) << 9) \
279 | (((reloc2) + 64) << 2) \
280 | ((reloc3) ? (1 << 1) : 0) \
281 | ((warn) ? 1 : 0)))
282#define RELAX_OLD(i) (((i) >> 24) & 0xff)
283#define RELAX_NEW(i) (((i) >> 16) & 0xff)
284#define RELAX_RELOC1(i) ((((i) >> 9) & 0x7f) - 64)
285#define RELAX_RELOC2(i) ((((i) >> 2) & 0x7f) - 64)
286#define RELAX_RELOC3(i) (((i) >> 1) & 1)
287#define RELAX_WARN(i) ((i) & 1)
288\f
3d3c5039
ILT
289/* Prototypes for static functions. */
290
291#ifdef __STDC__
292#define internalError() \
293 as_fatal ("internal Error, line %d, %s", __LINE__, __FILE__)
294#else
295#define internalError() as_fatal ("MIPS internal Error");
296#endif
297
becfe05e 298static int insn_uses_reg PARAMS ((struct mips_cl_insn *ip,
604633ae 299 unsigned int reg, int fpr));
0dd2d296
ILT
300static void append_insn PARAMS ((char *place,
301 struct mips_cl_insn * ip,
670a50eb 302 expressionS * p,
3d3c5039 303 bfd_reloc_code_real_type r));
becfe05e
ILT
304static void mips_no_prev_insn PARAMS ((void));
305static void mips_emit_delays PARAMS ((void));
0dd2d296 306static void macro_build PARAMS ((char *place, int *counter, expressionS * ep,
3d3c5039
ILT
307 const char *name, const char *fmt,
308 ...));
0dd2d296
ILT
309static void macro_build_lui PARAMS ((char *place, int *counter,
310 expressionS * ep, int regnum));
6e8dda9c 311static void set_at PARAMS ((int *counter, int reg, int unsignedp));
670a50eb 312static void check_absolute_expr PARAMS ((struct mips_cl_insn * ip,
19ed8960 313 expressionS *));
0dd2d296
ILT
314static void load_register PARAMS ((int *counter, int reg, expressionS * ep));
315static void load_address PARAMS ((int *counter, int reg, expressionS *ep));
670a50eb 316static void macro PARAMS ((struct mips_cl_insn * ip));
917fae09
SS
317#ifdef LOSING_COMPILER
318static void macro2 PARAMS ((struct mips_cl_insn * ip));
319#endif
670a50eb
ILT
320static void mips_ip PARAMS ((char *str, struct mips_cl_insn * ip));
321static int my_getSmallExpression PARAMS ((expressionS * ep, char *str));
322static void my_getExpression PARAMS ((expressionS * ep, char *str));
3d3c5039 323static symbolS *get_symbol PARAMS ((void));
becfe05e 324static void mips_align PARAMS ((int to, int fill));
3d3c5039 325static void s_align PARAMS ((int));
becfe05e 326static void s_stringer PARAMS ((int));
3d3c5039
ILT
327static void s_change_sec PARAMS ((int));
328static void s_cons PARAMS ((int));
329static void s_err PARAMS ((int));
330static void s_extern PARAMS ((int));
331static void s_float_cons PARAMS ((int));
332static void s_option PARAMS ((int));
333static void s_mipsset PARAMS ((int));
becfe05e 334static void s_mips_space PARAMS ((int));
9226253a
ILT
335static void s_abicalls PARAMS ((int));
336static void s_cpload PARAMS ((int));
337static void s_cprestore PARAMS ((int));
0dd2d296
ILT
338static void s_gpword PARAMS ((int));
339static void s_cpadd PARAMS ((int));
340#ifndef ECOFF_DEBUGGING
3d3c5039
ILT
341static void md_obj_begin PARAMS ((void));
342static void md_obj_end PARAMS ((void));
343static long get_number PARAMS ((void));
344static void s_ent PARAMS ((int));
345static void s_mipsend PARAMS ((int));
346static void s_file PARAMS ((int));
88225433 347#if 0
3d3c5039
ILT
348static void s_frame PARAMS ((int));
349static void s_loc PARAMS ((int));
350static void s_mask PARAMS ((char));
351#endif
88225433 352#endif
3d3c5039
ILT
353\f
354/* Pseudo-op table.
355
356 The following pseudo-ops from the Kane and Heinrich MIPS book
357 should be defined here, but are currently unsupported: .alias,
358 .galive, .gjaldef, .gjrlive, .livereg, .noalias.
359
360 The following pseudo-ops from the Kane and Heinrich MIPS book are
361 specific to the type of debugging information being generated, and
362 should be defined by the object format: .aent, .begin, .bend,
363 .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
364 .vreg.
365
366 The following pseudo-ops from the Kane and Heinrich MIPS book are
367 not MIPS CPU specific, but are also not specific to the object file
368 format. This file is probably the best place to define them, but
369 they are not currently supported: .asm0, .endr, .lab, .repeat,
370 .struct, .weakext. */
371
372const pseudo_typeS md_pseudo_table[] =
373{
670a50eb
ILT
374 /* MIPS specific pseudo-ops. */
375 {"option", s_option, 0},
376 {"set", s_mipsset, 0},
dd3f1f76
ILT
377 {"rdata", s_change_sec, 'r'},
378 {"sdata", s_change_sec, 's'},
379 {"livereg", s_ignore, 0},
9226253a
ILT
380 { "abicalls", s_abicalls, 0},
381 { "cpload", s_cpload, 0},
382 { "cprestore", s_cprestore, 0},
0dd2d296
ILT
383 { "gpword", s_gpword, 0},
384 { "cpadd", s_cpadd, 0},
3d3c5039 385
670a50eb 386 /* Relatively generic pseudo-ops that happen to be used on MIPS
3d3c5039 387 chips. */
becfe05e 388 {"asciiz", s_stringer, 1},
670a50eb
ILT
389 {"bss", s_change_sec, 'b'},
390 {"err", s_err, 0},
391 {"half", s_cons, 1},
52aa70b5 392 {"dword", s_cons, 3},
3d3c5039 393
670a50eb 394 /* These pseudo-ops are defined in read.c, but must be overridden
3d3c5039 395 here for one reason or another. */
670a50eb 396 {"align", s_align, 0},
becfe05e
ILT
397 {"ascii", s_stringer, 0},
398 {"asciz", s_stringer, 1},
670a50eb
ILT
399 {"byte", s_cons, 0},
400 {"data", s_change_sec, 'd'},
becfe05e 401 {"double", s_float_cons, 'd'},
670a50eb 402 {"extern", s_extern, 0},
becfe05e 403 {"float", s_float_cons, 'f'},
eb8fd0e9
ILT
404 {"hword", s_cons, 1},
405 {"int", s_cons, 2},
406 {"long", s_cons, 2},
407 {"octa", s_cons, 4},
408 {"quad", s_cons, 3},
409 {"short", s_cons, 1},
410 {"single", s_float_cons, 'f'},
becfe05e 411 {"space", s_mips_space, 0},
670a50eb
ILT
412 {"text", s_change_sec, 't'},
413 {"word", s_cons, 2},
3d3c5039 414
0dd2d296 415#ifndef ECOFF_DEBUGGING
670a50eb 416 /* These pseudo-ops should be defined by the object file format.
0dd2d296 417 However, a.out doesn't support them, so we have versions here. */
670a50eb 418 {"aent", s_ent, 1},
9226253a 419 {"bgnb", s_ignore, 0},
670a50eb 420 {"end", s_mipsend, 0},
9226253a 421 {"endb", s_ignore, 0},
670a50eb
ILT
422 {"ent", s_ent, 0},
423 {"file", s_file, 0},
424 {"fmask", s_ignore, 'F'},
425 {"frame", s_ignore, 0},
426 {"loc", s_ignore, 0},
427 {"mask", s_ignore, 'R'},
428 {"verstamp", s_ignore, 0},
3d3c5039
ILT
429#endif
430
670a50eb
ILT
431 /* Sentinel. */
432 {NULL}
3d3c5039
ILT
433};
434\f
670a50eb
ILT
435const relax_typeS md_relax_table[] =
436{
918692a5 437 { 0 }
3d3c5039
ILT
438};
439
3d3c5039
ILT
440static char *expr_end;
441
442static expressionS imm_expr;
443static expressionS offset_expr;
444static bfd_reloc_code_real_type imm_reloc;
445static bfd_reloc_code_real_type offset_reloc;
446
abdad6bc
ILT
447/* FIXME: This should be handled in a different way. */
448extern int target_big_endian;
449
3d3c5039
ILT
450/*
451 * This function is called once, at assembler startup time. It should
452 * set up all the tables, etc. that the MD part of the assembler will need.
453 */
454void
670a50eb 455md_begin ()
3d3c5039 456{
0dd2d296 457 boolean ok = false;
604633ae 458 register const char *retval = NULL;
670a50eb 459 register unsigned int i = 0;
3d3c5039 460
8358c818
ILT
461 if (mips_isa == -1)
462 {
463 if (strcmp (TARGET_CPU, "mips") == 0)
464 mips_isa = 1;
465 else if (strcmp (TARGET_CPU, "r6000") == 0
466 || strcmp (TARGET_CPU, "mips2") == 0)
467 mips_isa = 2;
468 else if (strcmp (TARGET_CPU, "mips64") == 0
469 || strcmp (TARGET_CPU, "r4000") == 0
470 || strcmp (TARGET_CPU, "mips3") == 0)
471 mips_isa = 3;
472 else
473 mips_isa = 1;
474 }
475
97f99d11
ILT
476 switch (mips_isa)
477 {
478 case 1:
479 ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 3000);
480 break;
481 case 2:
482 ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 6000);
483 break;
484 case 3:
485 ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 4000);
486 break;
487 }
488 if (! ok)
489 as_warn ("Could not set architecture and machine");
490
13fe1379
ILT
491 op_hash = hash_new ();
492
670a50eb
ILT
493 for (i = 0; i < NUMOPCODES;)
494 {
495 const char *name = mips_opcodes[i].name;
496
604633ae 497 retval = hash_insert (op_hash, name, (PTR) &mips_opcodes[i]);
abdad6bc 498 if (retval != NULL)
670a50eb
ILT
499 {
500 fprintf (stderr, "internal error: can't hash `%s': %s\n",
501 mips_opcodes[i].name, retval);
502 as_fatal ("Broken assembler. No assembly attempted.");
503 }
504 do
505 {
8358c818
ILT
506 if (mips_opcodes[i].pinfo != INSN_MACRO
507 && ((mips_opcodes[i].match & mips_opcodes[i].mask)
508 != mips_opcodes[i].match))
670a50eb
ILT
509 {
510 fprintf (stderr, "internal error: bad opcode: `%s' \"%s\"\n",
511 mips_opcodes[i].name, mips_opcodes[i].args);
512 as_fatal ("Broken assembler. No assembly attempted.");
3d3c5039 513 }
670a50eb
ILT
514 ++i;
515 }
516 while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
3d3c5039
ILT
517 }
518
becfe05e
ILT
519 mips_no_prev_insn ();
520
1aa6938e
ILT
521 mips_gprmask = 0;
522 mips_cprmask[0] = 0;
523 mips_cprmask[1] = 0;
524 mips_cprmask[2] = 0;
525 mips_cprmask[3] = 0;
526
8358c818
ILT
527 /* set the default alignment for the text section (2**2) */
528 record_alignment (text_section, 2);
529
abdad6bc
ILT
530 /* FIXME: This should be handled in a different way. */
531 target_big_endian = byte_order == BIG_ENDIAN;
532
88225433 533#ifdef GPOPT
8358c818
ILT
534 bfd_set_gp_size (stdoutput, g_switch_value);
535#endif
536
f2a663d3 537#ifdef OBJ_ELF
0dd2d296
ILT
538 /* Sections must be aligned to 16 byte boundaries. */
539 (void) bfd_set_section_alignment (stdoutput, text_section, 4);
540 (void) bfd_set_section_alignment (stdoutput, data_section, 4);
541 (void) bfd_set_section_alignment (stdoutput, bss_section, 4);
542
543 /* Create a .reginfo section for register masks and a .mdebug
544 section for debugging information. */
f2a663d3
ILT
545 {
546 segT seg;
547 subsegT subseg;
0dd2d296 548 segT sec;
f2a663d3
ILT
549
550 seg = now_seg;
551 subseg = now_subseg;
0dd2d296 552 sec = subseg_new (".reginfo", (subsegT) 0);
f2a663d3 553
04cb3372
ILT
554 /* The ABI says this section should be loaded so that the running
555 program can access it. */
0dd2d296
ILT
556 (void) bfd_set_section_flags (stdoutput, sec,
557 (SEC_ALLOC | SEC_LOAD
558 | SEC_READONLY | SEC_DATA));
559 (void) bfd_set_section_alignment (stdoutput, sec, 2);
f2a663d3
ILT
560
561 mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
562
0dd2d296
ILT
563#ifdef ECOFF_DEBUGGING
564 sec = subseg_new (".mdebug", (subsegT) 0);
565 (void) bfd_set_section_flags (stdoutput, sec,
566 SEC_HAS_CONTENTS | SEC_READONLY);
567 (void) bfd_set_section_alignment (stdoutput, sec, 2);
568#endif
569
f2a663d3
ILT
570 subseg_set (seg, subseg);
571 }
572#endif /* OBJ_ELF */
573
0dd2d296 574#ifndef ECOFF_DEBUGGING
670a50eb 575 md_obj_begin ();
3d3c5039
ILT
576#endif
577}
578
579void
13fe1379 580md_mips_end ()
3d3c5039 581{
0dd2d296 582#ifndef ECOFF_DEBUGGING
3d3c5039
ILT
583 md_obj_end ();
584#endif
585}
586
587void
670a50eb
ILT
588md_assemble (str)
589 char *str;
3d3c5039 590{
670a50eb 591 struct mips_cl_insn insn;
3d3c5039 592
5ac34ac3
ILT
593 imm_expr.X_op = O_absent;
594 offset_expr.X_op = O_absent;
3d3c5039 595
670a50eb
ILT
596 mips_ip (str, &insn);
597 if (insn_error)
598 {
599 as_bad ("%s `%s'", insn_error, str);
600 return;
601 }
602 if (insn.insn_mo->pinfo == INSN_MACRO)
603 {
604 macro (&insn);
3d3c5039 605 }
670a50eb
ILT
606 else
607 {
5ac34ac3 608 if (imm_expr.X_op != O_absent)
0dd2d296 609 append_insn ((char *) NULL, &insn, &imm_expr, imm_reloc);
5ac34ac3 610 else if (offset_expr.X_op != O_absent)
0dd2d296 611 append_insn ((char *) NULL, &insn, &offset_expr, offset_reloc);
670a50eb 612 else
0dd2d296 613 append_insn ((char *) NULL, &insn, NULL, BFD_RELOC_UNUSED);
3d3c5039
ILT
614 }
615}
616
becfe05e
ILT
617/* See whether instruction IP reads register REG. If FPR is non-zero,
618 REG is a floating point register. */
619
620static int
621insn_uses_reg (ip, reg, fpr)
622 struct mips_cl_insn *ip;
604633ae 623 unsigned int reg;
becfe05e
ILT
624 int fpr;
625{
626 /* Don't report on general register 0, since it never changes. */
627 if (! fpr && reg == 0)
628 return 0;
629
630 if (fpr)
631 {
632 /* If we are called with either $f0 or $f1, we must check $f0.
633 This is not optimal, because it will introduce an unnecessary
634 NOP between "lwc1 $f0" and "swc1 $f1". To fix this we would
635 need to distinguish reading both $f0 and $f1 or just one of
636 them. Note that we don't have to check the other way,
637 because there is no instruction that sets both $f0 and $f1
638 and requires a delay. */
639 if ((ip->insn_mo->pinfo & INSN_READ_FPR_S)
604633ae
ILT
640 && (((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS)
641 == (reg &~ (unsigned) 1)))
becfe05e
ILT
642 return 1;
643 if ((ip->insn_mo->pinfo & INSN_READ_FPR_T)
604633ae
ILT
644 && (((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT)
645 == (reg &~ (unsigned) 1)))
becfe05e
ILT
646 return 1;
647 }
648 else
649 {
650 if ((ip->insn_mo->pinfo & INSN_READ_GPR_S)
651 && ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS) == reg)
652 return 1;
653 if ((ip->insn_mo->pinfo & INSN_READ_GPR_T)
654 && ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT) == reg)
655 return 1;
656 }
657
658 return 0;
659}
660
0dd2d296
ILT
661/* Output an instruction. PLACE is where to put the instruction; if
662 it is NULL, this uses frag_more to get room. IP is the instruction
663 information. ADDRESS_EXPR is an operand of the instruction to be
664 used with RELOC_TYPE. */
3d3c5039 665
3d3c5039 666static void
0dd2d296
ILT
667append_insn (place, ip, address_expr, reloc_type)
668 char *place;
670a50eb
ILT
669 struct mips_cl_insn *ip;
670 expressionS *address_expr;
671 bfd_reloc_code_real_type reloc_type;
3d3c5039 672{
1aa6938e 673 register unsigned long prev_pinfo, pinfo;
670a50eb 674 char *f;
becfe05e
ILT
675 fixS *fixp;
676 int nops = 0;
3d3c5039 677
1aa6938e
ILT
678 prev_pinfo = prev_insn.insn_mo->pinfo;
679 pinfo = ip->insn_mo->pinfo;
680
0dd2d296 681 if (place == NULL && ! mips_noreorder)
becfe05e
ILT
682 {
683 /* If the previous insn required any delay slots, see if we need
8358c818 684 to insert a NOP or two. There are eight kinds of possible
becfe05e 685 hazards, of which an instruction can have at most one type.
8358c818
ILT
686 (1) a load from memory delay
687 (2) a load from a coprocessor delay
688 (3) an unconditional branch delay
689 (4) a conditional branch delay
690 (5) a move to coprocessor register delay
691 (6) a load coprocessor register from memory delay
692 (7) a coprocessor condition code delay
693 (8) a HI/LO special register delay
becfe05e
ILT
694
695 There are a lot of optimizations we could do that we don't.
696 In particular, we do not, in general, reorder instructions.
697 If you use gcc with optimization, it will reorder
698 instructions and generally do much more optimization then we
699 do here; repeating all that work in the assembler would only
700 benefit hand written assembly code, and does not seem worth
701 it. */
702
703 /* This is how a NOP is emitted. */
704#define emit_nop() md_number_to_chars (frag_more (4), 0, 4)
705
706 /* The previous insn might require a delay slot, depending upon
707 the contents of the current insn. */
1aa6938e 708 if ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
8358c818 709 || (mips_isa < 2
1aa6938e 710 && (prev_pinfo & INSN_LOAD_MEMORY_DELAY)))
8358c818
ILT
711 {
712 /* A load from a coprocessor or from memory. All load
713 delays delay the use of general register rt for one
714 instruction on the r3000. The r6000 and r4000 use
715 interlocks. */
1aa6938e 716 know (prev_pinfo & INSN_WRITE_GPR_T);
0aa07269
ILT
717 if (mips_optimize == 0
718 || insn_uses_reg (ip,
719 ((prev_insn.insn_opcode >> OP_SH_RT)
720 & OP_MASK_RT),
721 0))
becfe05e
ILT
722 ++nops;
723 }
1aa6938e 724 else if ((prev_pinfo & INSN_COPROC_MOVE_DELAY)
8358c818 725 || (mips_isa < 2
1aa6938e 726 && (prev_pinfo & INSN_COPROC_MEMORY_DELAY)))
becfe05e
ILT
727 {
728 /* A generic coprocessor delay. The previous instruction
729 modified a coprocessor general or control register. If
730 it modified a control register, we need to avoid any
731 coprocessor instruction (this is probably not always
732 required, but it sometimes is). If it modified a general
733 register, we avoid using that register.
734
8358c818
ILT
735 On the r6000 and r4000 loading a coprocessor register
736 from memory is interlocked, and does not require a delay.
737
becfe05e
ILT
738 This case is not handled very well. There is no special
739 knowledge of CP0 handling, and the coprocessors other
740 than the floating point unit are not distinguished at
741 all. */
1aa6938e 742 if (prev_pinfo & INSN_WRITE_FPR_T)
becfe05e 743 {
0aa07269
ILT
744 if (mips_optimize == 0
745 || insn_uses_reg (ip,
8358c818
ILT
746 ((prev_insn.insn_opcode >> OP_SH_FT)
747 & OP_MASK_FT),
0aa07269 748 1))
becfe05e
ILT
749 ++nops;
750 }
1aa6938e 751 else if (prev_pinfo & INSN_WRITE_FPR_S)
becfe05e 752 {
0aa07269
ILT
753 if (mips_optimize == 0
754 || insn_uses_reg (ip,
8358c818
ILT
755 ((prev_insn.insn_opcode >> OP_SH_FS)
756 & OP_MASK_FS),
0aa07269 757 1))
becfe05e
ILT
758 ++nops;
759 }
760 else
761 {
762 /* We don't know exactly what the previous instruction
763 does. If the current instruction uses a coprocessor
764 register, we must insert a NOP. If previous
765 instruction may set the condition codes, and the
766 current instruction uses them, we must insert two
767 NOPS. */
0aa07269 768 if (mips_optimize == 0
1aa6938e
ILT
769 || ((prev_pinfo & INSN_WRITE_COND_CODE)
770 && (pinfo & INSN_READ_COND_CODE)))
becfe05e 771 nops += 2;
1aa6938e 772 else if (pinfo & INSN_COP)
becfe05e
ILT
773 ++nops;
774 }
775 }
1aa6938e 776 else if (prev_pinfo & INSN_WRITE_COND_CODE)
becfe05e
ILT
777 {
778 /* The previous instruction sets the coprocessor condition
779 codes, but does not require a general coprocessor delay
780 (this means it is a floating point comparison
781 instruction). If this instruction uses the condition
782 codes, we need to insert a single NOP. */
0aa07269 783 if (mips_optimize == 0
1aa6938e 784 || (pinfo & INSN_READ_COND_CODE))
becfe05e
ILT
785 ++nops;
786 }
1aa6938e 787 else if (prev_pinfo & INSN_READ_LO)
becfe05e
ILT
788 {
789 /* The previous instruction reads the LO register; if the
790 current instruction writes to the LO register, we must
791 insert two NOPS. */
0aa07269 792 if (mips_optimize == 0
1aa6938e 793 || (pinfo & INSN_WRITE_LO))
becfe05e
ILT
794 nops += 2;
795 }
796 else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)
797 {
798 /* The previous instruction reads the HI register; if the
799 current instruction writes to the HI register, we must
800 insert a NOP. */
0aa07269 801 if (mips_optimize == 0
1aa6938e 802 || (pinfo & INSN_WRITE_HI))
becfe05e
ILT
803 nops += 2;
804 }
805
806 /* There are two cases which require two intervening
807 instructions: 1) setting the condition codes using a move to
808 coprocessor instruction which requires a general coprocessor
809 delay and then reading the condition codes 2) reading the HI
810 or LO register and then writing to it. If we are not already
811 emitting a NOP instruction, we must check for these cases
812 compared to the instruction previous to the previous
813 instruction. */
814 if (nops == 0
8358c818 815 && (((prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
becfe05e 816 && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
1aa6938e 817 && (pinfo & INSN_READ_COND_CODE))
becfe05e 818 || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
1aa6938e 819 && (pinfo & INSN_WRITE_LO))
becfe05e 820 || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
1aa6938e 821 && (pinfo & INSN_WRITE_HI))))
becfe05e
ILT
822 ++nops;
823
0dd2d296
ILT
824 /* If we are being given a nop instruction, don't bother with
825 one of the nops we would otherwise output. This will only
826 happen when a nop instruction is used with mips_optimize set
827 to 0. */
828 if (nops > 0 && ip->insn_opcode == 0)
829 --nops;
830
becfe05e
ILT
831 /* Now emit the right number of NOP instructions. */
832 if (nops > 0)
833 {
834 emit_nop ();
835 if (nops > 1)
836 emit_nop ();
af255ca0
ILT
837 if (listing)
838 listing_prev_line ();
becfe05e
ILT
839 if (insn_label != NULL)
840 {
841 assert (S_GET_SEGMENT (insn_label) == now_seg);
842 insn_label->sy_frag = frag_now;
604633ae 843 S_SET_VALUE (insn_label, (valueT) frag_now_fix ());
becfe05e
ILT
844 }
845 }
846 }
847
0dd2d296
ILT
848 if (place == NULL)
849 f = frag_more (4);
850 else
851 f = place;
becfe05e 852 fixp = NULL;
670a50eb
ILT
853 if (address_expr != NULL)
854 {
5ac34ac3 855 if (address_expr->X_op == O_constant)
670a50eb
ILT
856 {
857 switch (reloc_type)
858 {
3d3c5039 859 case BFD_RELOC_32:
670a50eb
ILT
860 ip->insn_opcode |= address_expr->X_add_number;
861 break;
3d3c5039
ILT
862
863 case BFD_RELOC_LO16:
670a50eb
ILT
864 ip->insn_opcode |= address_expr->X_add_number & 0xffff;
865 break;
3d3c5039
ILT
866
867 case BFD_RELOC_MIPS_JMP:
868 case BFD_RELOC_16_PCREL_S2:
670a50eb 869 goto need_reloc;
3d3c5039
ILT
870
871 default:
670a50eb 872 internalError ();
3d3c5039 873 }
670a50eb
ILT
874 }
875 else
876 {
877 assert (reloc_type != BFD_RELOC_UNUSED);
3d3c5039 878 need_reloc:
0dd2d296
ILT
879 /* Don't generate a reloc if we are writing into a variant
880 frag. */
881 if (place == NULL)
882 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
883 address_expr,
884 reloc_type == BFD_RELOC_16_PCREL_S2,
885 reloc_type);
3d3c5039
ILT
886 }
887 }
becfe05e 888
670a50eb
ILT
889 md_number_to_chars (f, ip->insn_opcode, 4);
890
1aa6938e
ILT
891 /* Update the register mask information. */
892 if (pinfo & INSN_WRITE_GPR_D)
893 mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD);
894 if ((pinfo & (INSN_WRITE_GPR_T | INSN_READ_GPR_T)) != 0)
895 mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT);
896 if (pinfo & INSN_READ_GPR_S)
897 mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS);
898 if (pinfo & INSN_WRITE_GPR_31)
899 mips_gprmask |= 1 << 31;
900 if (pinfo & INSN_WRITE_FPR_D)
901 mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FD) & OP_MASK_FD);
902 if ((pinfo & (INSN_WRITE_FPR_S | INSN_READ_FPR_S)) != 0)
903 mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS);
904 if ((pinfo & (INSN_WRITE_FPR_T | INSN_READ_FPR_T)) != 0)
905 mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT);
906 if (pinfo & INSN_COP)
907 {
908 /* We don't keep enough information to sort these cases out. */
909 }
910 /* Never set the bit for $0, which is always zero. */
911 mips_gprmask &=~ 1 << 0;
912
0dd2d296 913 if (place == NULL && ! mips_noreorder)
670a50eb 914 {
becfe05e
ILT
915 /* Filling the branch delay slot is more complex. We try to
916 switch the branch with the previous instruction, which we can
917 do if the previous instruction does not set up a condition
918 that the branch tests and if the branch is not itself the
919 target of any branch. */
1aa6938e
ILT
920 if ((pinfo & INSN_UNCOND_BRANCH_DELAY)
921 || (pinfo & INSN_COND_BRANCH_DELAY))
becfe05e 922 {
0aa07269 923 if (mips_optimize < 2
19ed8960
ILT
924 /* If we have seen .set nobopt, don't optimize. */
925 || mips_nobopt != 0
926 /* If we have seen .set volatile or .set nomove, don't
927 optimize. */
928 || mips_nomove != 0
4e95866e
ILT
929 /* If we had to emit any NOP instructions, then we
930 already know we can not swap. */
931 || nops != 0
becfe05e
ILT
932 /* If we don't even know the previous insn, we can not
933 swap. */
934 || ! prev_insn_valid
935 /* If the previous insn is already in a branch delay
936 slot, then we can not swap. */
937 || prev_insn_is_delay_slot
4e95866e
ILT
938 /* If the previous previous insn was in a .set
939 noreorder, we can't swap. Actually, the MIPS
940 assembler will swap in this situation. However, gcc
941 configured -with-gnu-as will generate code like
942 .set noreorder
943 lw $4,XXX
944 .set reorder
945 INSN
946 bne $4,$0,foo
947 in which we can not swap the bne and INSN. If gcc is
948 not configured -with-gnu-as, it does not output the
949 .set pseudo-ops. We don't have to check
950 prev_insn_unreordered, because prev_insn_valid will
951 be 0 in that case. We don't want to use
952 prev_prev_insn_valid, because we do want to be able
953 to swap at the start of a function. */
954 || prev_prev_insn_unreordered
becfe05e
ILT
955 /* If the branch is itself the target of a branch, we
956 can not swap. We cheat on this; all we check for is
957 whether there is a label on this instruction. If
958 there are any branches to anything other than a
959 label, users must use .set noreorder. */
960 || insn_label != NULL
777ad64d
ILT
961 /* If the previous instruction is in a variant frag, we
962 can not do the swap. */
963 || prev_insn_frag->fr_type == rs_machine_dependent
becfe05e
ILT
964 /* If the branch reads the condition codes, we don't
965 even try to swap, because in the sequence
966 ctc1 $X,$31
967 INSN
968 INSN
969 bc1t LABEL
970 we can not swap, and I don't feel like handling that
971 case. */
1aa6938e 972 || (pinfo & INSN_READ_COND_CODE)
becfe05e
ILT
973 /* We can not swap with an instruction that requires a
974 delay slot, becase the target of the branch might
975 interfere with that instruction. */
1aa6938e 976 || (prev_pinfo
8358c818
ILT
977 & (INSN_LOAD_COPROC_DELAY
978 | INSN_COPROC_MOVE_DELAY
becfe05e
ILT
979 | INSN_WRITE_COND_CODE
980 | INSN_READ_LO
981 | INSN_READ_HI))
8358c818 982 || (mips_isa < 2
1aa6938e 983 && (prev_pinfo
8358c818
ILT
984 & (INSN_LOAD_MEMORY_DELAY
985 | INSN_COPROC_MEMORY_DELAY)))
becfe05e 986 /* We can not swap with a branch instruction. */
1aa6938e 987 || (prev_pinfo
6e8dda9c
ILT
988 & (INSN_UNCOND_BRANCH_DELAY
989 | INSN_COND_BRANCH_DELAY
990 | INSN_COND_BRANCH_LIKELY))
abdad6bc
ILT
991 /* We do not swap with a trap instruction, since it
992 complicates trap handlers to have the trap
993 instruction be in a delay slot. */
1aa6938e 994 || (prev_pinfo & INSN_TRAP)
becfe05e
ILT
995 /* If the branch reads a register that the previous
996 instruction sets, we can not swap. */
1aa6938e 997 || ((prev_pinfo & INSN_WRITE_GPR_T)
becfe05e
ILT
998 && insn_uses_reg (ip,
999 ((prev_insn.insn_opcode >> OP_SH_RT)
1000 & OP_MASK_RT),
1001 0))
1aa6938e 1002 || ((prev_pinfo & INSN_WRITE_GPR_D)
becfe05e
ILT
1003 && insn_uses_reg (ip,
1004 ((prev_insn.insn_opcode >> OP_SH_RD)
1005 & OP_MASK_RD),
1006 0))
1849d646
ILT
1007 /* If the branch writes a register that the previous
1008 instruction sets, we can not swap (we know that
1009 branches write only to RD or to $31). */
1aa6938e
ILT
1010 || ((prev_pinfo & INSN_WRITE_GPR_T)
1011 && (((pinfo & INSN_WRITE_GPR_D)
1849d646
ILT
1012 && (((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT)
1013 == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
1aa6938e 1014 || ((pinfo & INSN_WRITE_GPR_31)
1849d646
ILT
1015 && (((prev_insn.insn_opcode >> OP_SH_RT)
1016 & OP_MASK_RT)
1017 == 31))))
1aa6938e
ILT
1018 || ((prev_pinfo & INSN_WRITE_GPR_D)
1019 && (((pinfo & INSN_WRITE_GPR_D)
1849d646
ILT
1020 && (((prev_insn.insn_opcode >> OP_SH_RD) & OP_MASK_RD)
1021 == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
1aa6938e 1022 || ((pinfo & INSN_WRITE_GPR_31)
1849d646
ILT
1023 && (((prev_insn.insn_opcode >> OP_SH_RD)
1024 & OP_MASK_RD)
1025 == 31))))
becfe05e
ILT
1026 /* If the branch writes a register that the previous
1027 instruction reads, we can not swap (we know that
1028 branches only write to RD or to $31). */
1aa6938e 1029 || ((pinfo & INSN_WRITE_GPR_D)
becfe05e
ILT
1030 && insn_uses_reg (&prev_insn,
1031 ((ip->insn_opcode >> OP_SH_RD)
1032 & OP_MASK_RD),
1033 0))
1aa6938e 1034 || ((pinfo & INSN_WRITE_GPR_31)
becfe05e
ILT
1035 && insn_uses_reg (&prev_insn, 31, 0))
1036 /* If the previous previous instruction has a load
1037 delay, and sets a register that the branch reads, we
1038 can not swap. */
8358c818
ILT
1039 || (((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
1040 || (mips_isa < 2
1041 && (prev_prev_insn.insn_mo->pinfo
1042 & INSN_LOAD_MEMORY_DELAY)))
becfe05e
ILT
1043 && insn_uses_reg (ip,
1044 ((prev_prev_insn.insn_opcode >> OP_SH_RT)
1045 & OP_MASK_RT),
1046 0)))
1047 {
1048 /* We could do even better for unconditional branches to
1049 portions of this object file; we could pick up the
1050 instruction at the destination, put it in the delay
1051 slot, and bump the destination address. */
1052 emit_nop ();
1053 /* Update the previous insn information. */
1054 prev_prev_insn = *ip;
1055 prev_insn.insn_mo = &dummy_opcode;
1056 }
1057 else
1058 {
1059 char *prev_f;
1060 char temp[4];
1061
1062 /* It looks like we can actually do the swap. */
1063 prev_f = prev_insn_frag->fr_literal + prev_insn_where;
1064 memcpy (temp, prev_f, 4);
1065 memcpy (prev_f, f, 4);
1066 memcpy (f, temp, 4);
1067 if (prev_insn_fixp)
1068 {
1069 prev_insn_fixp->fx_frag = frag_now;
1070 prev_insn_fixp->fx_where = f - frag_now->fr_literal;
1071 }
1072 if (fixp)
1073 {
1074 fixp->fx_frag = prev_insn_frag;
1075 fixp->fx_where = prev_insn_where;
1076 }
1077 /* Update the previous insn information; leave prev_insn
1078 unchanged. */
1079 prev_prev_insn = *ip;
1080 }
1081 prev_insn_is_delay_slot = 1;
1082
1083 /* If that was an unconditional branch, forget the previous
1084 insn information. */
1aa6938e 1085 if (pinfo & INSN_UNCOND_BRANCH_DELAY)
becfe05e
ILT
1086 {
1087 prev_prev_insn.insn_mo = &dummy_opcode;
1088 prev_insn.insn_mo = &dummy_opcode;
1089 }
1090 }
1aa6938e 1091 else if (pinfo & INSN_COND_BRANCH_LIKELY)
8358c818
ILT
1092 {
1093 /* We don't yet optimize a branch likely. What we should do
1094 is look at the target, copy the instruction found there
1095 into the delay slot, and increment the branch to jump to
1096 the next instruction. */
1097 emit_nop ();
1098 /* Update the previous insn information. */
1099 prev_prev_insn = *ip;
1100 prev_insn.insn_mo = &dummy_opcode;
1101 }
becfe05e 1102 else
670a50eb 1103 {
becfe05e
ILT
1104 /* Update the previous insn information. */
1105 if (nops > 0)
1106 prev_prev_insn.insn_mo = &dummy_opcode;
1107 else
1108 prev_prev_insn = prev_insn;
1109 prev_insn = *ip;
1110
1111 /* Any time we see a branch, we always fill the delay slot
1112 immediately; since this insn is not a branch, we know it
1113 is not in a delay slot. */
1114 prev_insn_is_delay_slot = 0;
1115 }
1116
4e95866e
ILT
1117 prev_prev_insn_unreordered = prev_insn_unreordered;
1118 prev_insn_unreordered = 0;
becfe05e
ILT
1119 prev_insn_frag = frag_now;
1120 prev_insn_where = f - frag_now->fr_literal;
1121 prev_insn_fixp = fixp;
1122 prev_insn_valid = 1;
1123 }
3d3c5039 1124
becfe05e
ILT
1125 /* We just output an insn, so the next one doesn't have a label. */
1126 insn_label = NULL;
1127}
1128
1129/* This function forgets that there was any previous instruction or
1130 label. */
1131
1132static void
1133mips_no_prev_insn ()
1134{
1135 prev_insn.insn_mo = &dummy_opcode;
1136 prev_prev_insn.insn_mo = &dummy_opcode;
1137 prev_insn_valid = 0;
1138 prev_insn_is_delay_slot = 0;
4e95866e
ILT
1139 prev_insn_unreordered = 0;
1140 prev_prev_insn_unreordered = 0;
becfe05e
ILT
1141 insn_label = NULL;
1142}
1143
1144/* This function must be called whenever we turn on noreorder or emit
1145 something other than instructions. It inserts any NOPS which might
1146 be needed by the previous instruction, and clears the information
1147 kept for the previous instructions. */
1148
1149static void
1150mips_emit_delays ()
1151{
1152 if (! mips_noreorder)
1153 {
1154 int nop;
1155
1156 nop = 0;
8358c818
ILT
1157 if ((prev_insn.insn_mo->pinfo
1158 & (INSN_LOAD_COPROC_DELAY
1159 | INSN_COPROC_MOVE_DELAY
1160 | INSN_WRITE_COND_CODE
1161 | INSN_READ_LO
1162 | INSN_READ_HI))
1163 || (mips_isa < 2
1164 && (prev_insn.insn_mo->pinfo
1165 & (INSN_LOAD_MEMORY_DELAY
1166 | INSN_COPROC_MEMORY_DELAY))))
becfe05e
ILT
1167 {
1168 nop = 1;
1169 if ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
1170 || (prev_insn.insn_mo->pinfo & INSN_READ_HI)
1171 || (prev_insn.insn_mo->pinfo & INSN_READ_LO))
1172 emit_nop ();
1173 }
1174 else if ((prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
1175 || (prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
1176 || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))
1177 nop = 1;
1178 if (nop)
670a50eb 1179 {
becfe05e
ILT
1180 emit_nop ();
1181 if (insn_label != NULL)
1182 {
1183 assert (S_GET_SEGMENT (insn_label) == now_seg);
1184 insn_label->sy_frag = frag_now;
604633ae 1185 S_SET_VALUE (insn_label, (valueT) frag_now_fix ());
becfe05e 1186 }
3d3c5039 1187 }
becfe05e 1188 mips_no_prev_insn ();
3d3c5039
ILT
1189 }
1190}
1191
670a50eb
ILT
1192/* Build an instruction created by a macro expansion. This is passed
1193 a pointer to the count of instructions created so far, an
1194 expression, the name of the instruction to build, an operand format
1195 string, and corresponding arguments. */
1196
3d3c5039
ILT
1197#ifndef NO_STDARG
1198static void
0dd2d296
ILT
1199macro_build (char *place,
1200 int *counter,
670a50eb 1201 expressionS * ep,
3d3c5039
ILT
1202 const char *name,
1203 const char *fmt,
1204 ...)
1205#else /* ! defined (NO_STDARG) */
1206static void
0dd2d296
ILT
1207macro_build (place, counter, ep, name, fmt, va_alist)
1208 char *place;
3d3c5039
ILT
1209 int *counter;
1210 expressionS *ep;
1211 const char *name;
1212 const char *fmt;
1213 va_dcl
1214#endif /* ! defined (NO_STDARG) */
1215{
670a50eb
ILT
1216 struct mips_cl_insn insn;
1217 bfd_reloc_code_real_type r;
1218 va_list args;
3d3c5039
ILT
1219
1220#ifndef NO_STDARG
670a50eb 1221 va_start (args, fmt);
3d3c5039 1222#else
670a50eb 1223 va_start (args);
3d3c5039
ILT
1224#endif
1225
670a50eb
ILT
1226 /*
1227 * If the macro is about to expand into a second instruction,
1228 * print a warning if needed. We need to pass ip as a parameter
1229 * to generate a better warning message here...
1230 */
0dd2d296 1231 if (mips_warn_about_macros && place == NULL && *counter == 1)
670a50eb
ILT
1232 as_warn ("Macro instruction expanded into multiple instructions");
1233
0dd2d296
ILT
1234 if (place == NULL)
1235 *counter += 1; /* bump instruction counter */
670a50eb
ILT
1236
1237 r = BFD_RELOC_UNUSED;
1238 insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
1239 assert (insn.insn_mo);
1240 assert (strcmp (name, insn.insn_mo->name) == 0);
1241
9226253a
ILT
1242 while (strcmp (fmt, insn.insn_mo->args) != 0
1243 || insn.insn_mo->pinfo == INSN_MACRO)
670a50eb
ILT
1244 {
1245 ++insn.insn_mo;
1246 assert (insn.insn_mo->name);
1247 assert (strcmp (name, insn.insn_mo->name) == 0);
3d3c5039 1248 }
670a50eb
ILT
1249 insn.insn_opcode = insn.insn_mo->match;
1250 for (;;)
1251 {
1252 switch (*fmt++)
1253 {
3d3c5039 1254 case '\0':
670a50eb 1255 break;
3d3c5039
ILT
1256
1257 case ',':
1258 case '(':
1259 case ')':
670a50eb 1260 continue;
3d3c5039
ILT
1261
1262 case 't':
1263 case 'w':
918692a5 1264 case 'E':
670a50eb
ILT
1265 insn.insn_opcode |= va_arg (args, int) << 16;
1266 continue;
3d3c5039
ILT
1267
1268 case 'c':
1269 case 'T':
1270 case 'W':
670a50eb
ILT
1271 insn.insn_opcode |= va_arg (args, int) << 16;
1272 continue;
3d3c5039
ILT
1273
1274 case 'd':
918692a5 1275 case 'G':
670a50eb
ILT
1276 insn.insn_opcode |= va_arg (args, int) << 11;
1277 continue;
3d3c5039
ILT
1278
1279 case 'V':
1280 case 'S':
670a50eb
ILT
1281 insn.insn_opcode |= va_arg (args, int) << 11;
1282 continue;
3d3c5039 1283
ff3a5c18
ILT
1284 case 'z':
1285 continue;
1286
3d3c5039 1287 case '<':
670a50eb
ILT
1288 insn.insn_opcode |= va_arg (args, int) << 6;
1289 continue;
3d3c5039
ILT
1290
1291 case 'D':
670a50eb
ILT
1292 insn.insn_opcode |= va_arg (args, int) << 6;
1293 continue;
3d3c5039 1294
918692a5
ILT
1295 case 'B':
1296 insn.insn_opcode |= va_arg (args, int) << 6;
1297 continue;
1298
3d3c5039
ILT
1299 case 'b':
1300 case 's':
1301 case 'r':
1302 case 'v':
670a50eb
ILT
1303 insn.insn_opcode |= va_arg (args, int) << 21;
1304 continue;
3d3c5039
ILT
1305
1306 case 'i':
1307 case 'j':
1308 case 'o':
9226253a 1309 r = (bfd_reloc_code_real_type) va_arg (args, int);
0dd2d296
ILT
1310 assert (r == BFD_RELOC_MIPS_GPREL
1311 || r == BFD_RELOC_MIPS_LITERAL
1312 || r == BFD_RELOC_LO16
1313 || r == BFD_RELOC_MIPS_GOT16
04cb3372 1314 || r == BFD_RELOC_MIPS_CALL16);
670a50eb 1315 continue;
3d3c5039 1316
6e8dda9c
ILT
1317 case 'u':
1318 assert (ep != NULL && ep->X_op == O_constant);
1319 insn.insn_opcode |= (ep->X_add_number >> 16) & 0xffff;
1320 ep = NULL;
1321 continue;
1322
3d3c5039 1323 case 'p':
670a50eb
ILT
1324 assert (ep != NULL);
1325 /*
1326 * This allows macro() to pass an immediate expression for
1327 * creating short branches without creating a symbol.
1328 * Note that the expression still might come from the assembly
1329 * input, in which case the value is not checked for range nor
1330 * is a relocation entry generated (yuck).
1331 */
5ac34ac3 1332 if (ep->X_op == O_constant)
670a50eb
ILT
1333 {
1334 insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff;
1335 ep = NULL;
1336 }
1337 else
1338 r = BFD_RELOC_16_PCREL_S2;
1339 continue;
3d3c5039 1340
9226253a
ILT
1341 case 'a':
1342 assert (ep != NULL);
1343 r = BFD_RELOC_MIPS_JMP;
1344 continue;
1345
3d3c5039 1346 default:
670a50eb 1347 internalError ();
3d3c5039 1348 }
670a50eb 1349 break;
3d3c5039 1350 }
670a50eb
ILT
1351 va_end (args);
1352 assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
1353
0dd2d296 1354 append_insn (place, &insn, ep, r);
3d3c5039
ILT
1355}
1356
1357/*
1358 * Generate a "lui" instruction.
1359 */
1360static void
0dd2d296
ILT
1361macro_build_lui (place, counter, ep, regnum)
1362 char *place;
3d3c5039
ILT
1363 int *counter;
1364 expressionS *ep;
1365 int regnum;
1366{
670a50eb
ILT
1367 expressionS high_expr;
1368 struct mips_cl_insn insn;
1369 bfd_reloc_code_real_type r;
1370 CONST char *name = "lui";
1371 CONST char *fmt = "t,u";
1372
0dd2d296
ILT
1373 if (place == NULL)
1374 high_expr = *ep;
1375 else
1376 {
1377 high_expr.X_op = O_constant;
1378 high_expr.X_add_number = 0;
1379 }
670a50eb 1380
5ac34ac3 1381 if (high_expr.X_op == O_constant)
670a50eb
ILT
1382 {
1383 /* we can compute the instruction now without a relocation entry */
1384 if (high_expr.X_add_number & 0x8000)
1385 high_expr.X_add_number += 0x10000;
1386 high_expr.X_add_number =
1387 ((unsigned long) high_expr.X_add_number >> 16) & 0xffff;
1388 r = BFD_RELOC_UNUSED;
1389 }
1390 else
0dd2d296
ILT
1391 {
1392 assert (ep->X_op == O_symbol);
1393 /* _gp_disp is a special case, used from s_cpload. */
1394 assert (mips_pic == 0
1395 || strcmp (S_GET_NAME (ep->X_add_symbol), "_gp_disp") == 0);
1396 r = BFD_RELOC_HI16_S;
1397 }
670a50eb
ILT
1398
1399 /*
1400 * If the macro is about to expand into a second instruction,
1401 * print a warning if needed. We need to pass ip as a parameter
1402 * to generate a better warning message here...
1403 */
0dd2d296 1404 if (mips_warn_about_macros && place == NULL && *counter == 1)
670a50eb
ILT
1405 as_warn ("Macro instruction expanded into multiple instructions");
1406
0dd2d296
ILT
1407 if (place == NULL)
1408 *counter += 1; /* bump instruction counter */
670a50eb
ILT
1409
1410 insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
1411 assert (insn.insn_mo);
1412 assert (strcmp (name, insn.insn_mo->name) == 0);
1413 assert (strcmp (fmt, insn.insn_mo->args) == 0);
1414
0dd2d296 1415 insn.insn_opcode = insn.insn_mo->match | (regnum << OP_SH_RT);
670a50eb
ILT
1416 if (r == BFD_RELOC_UNUSED)
1417 {
1418 insn.insn_opcode |= high_expr.X_add_number;
0dd2d296 1419 append_insn (place, &insn, NULL, r);
670a50eb
ILT
1420 }
1421 else
0dd2d296 1422 append_insn (place, &insn, &high_expr, r);
3d3c5039
ILT
1423}
1424
1425/* set_at()
1426 * Generates code to set the $at register to true (one)
1427 * if reg is less than the immediate expression.
1428 */
1429static void
6e8dda9c 1430set_at (counter, reg, unsignedp)
3d3c5039
ILT
1431 int *counter;
1432 int reg;
6e8dda9c 1433 int unsignedp;
3d3c5039 1434{
6e8dda9c 1435 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
0dd2d296 1436 macro_build ((char *) NULL, counter, &imm_expr,
6e8dda9c 1437 unsignedp ? "sltiu" : "slti",
9226253a 1438 "t,r,j", AT, reg, (int) BFD_RELOC_LO16);
6e8dda9c 1439 else
670a50eb 1440 {
6e8dda9c 1441 load_register (counter, AT, &imm_expr);
0dd2d296 1442 macro_build ((char *) NULL, counter, NULL,
6e8dda9c
ILT
1443 unsignedp ? "sltu" : "slt",
1444 "d,v,t", AT, reg, AT);
670a50eb 1445 }
3d3c5039
ILT
1446}
1447
6e8dda9c 1448/* Warn if an expression is not a constant. */
3d3c5039
ILT
1449
1450static void
19ed8960 1451check_absolute_expr (ip, ex)
3d3c5039 1452 struct mips_cl_insn *ip;
19ed8960 1453 expressionS *ex;
3d3c5039 1454{
19ed8960 1455 if (ex->X_op != O_constant)
670a50eb 1456 as_warn ("Instruction %s requires absolute expression", ip->insn_mo->name);
3d3c5039
ILT
1457}
1458
1459/* load_register()
1460 * This routine generates the least number of instructions neccessary to load
1461 * an absolute expression value into a register.
1462 */
1463static void
6e8dda9c 1464load_register (counter, reg, ep)
670a50eb 1465 int *counter;
670a50eb
ILT
1466 int reg;
1467 expressionS *ep;
3d3c5039 1468{
6e8dda9c
ILT
1469 assert (ep->X_op == O_constant);
1470 if (ep->X_add_number >= -0x8000 && ep->X_add_number < 0x8000)
0dd2d296 1471 macro_build ((char *) NULL, counter, ep,
6e8dda9c 1472 mips_isa < 3 ? "addiu" : "daddiu",
9226253a 1473 "t,r,j", reg, 0, (int) BFD_RELOC_LO16);
6e8dda9c 1474 else if (ep->X_add_number >= 0 && ep->X_add_number < 0x10000)
0dd2d296
ILT
1475 macro_build ((char *) NULL, counter, ep, "ori", "t,r,i", reg, 0,
1476 (int) BFD_RELOC_LO16);
6e8dda9c
ILT
1477 else if ((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0
1478 || ((ep->X_add_number &~ (offsetT) 0x7fffffff)
1479 == ~ (offsetT) 0x7fffffff))
1480 {
0dd2d296 1481 macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg);
6e8dda9c 1482 if ((ep->X_add_number & 0xffff) != 0)
0dd2d296 1483 macro_build ((char *) NULL, counter, ep, "ori", "t,r,i", reg, reg,
9226253a 1484 (int) BFD_RELOC_LO16);
6e8dda9c
ILT
1485 }
1486 else if (mips_isa < 3)
670a50eb 1487 {
6e8dda9c 1488 as_bad ("Number larger than 32 bits");
0dd2d296 1489 macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,
9226253a 1490 (int) BFD_RELOC_LO16);
6e8dda9c
ILT
1491 }
1492 else
1493 {
1494 int shift;
1495 expressionS hi32, lo32;
1496
1497 hi32 = *ep;
1498 shift = 32;
1499 hi32.X_add_number >>= shift;
1500 hi32.X_add_number &= 0xffffffff;
1501 if ((hi32.X_add_number & 0x80000000) != 0)
1502 hi32.X_add_number |= ~ (offsetT) 0xffffffff;
1503 load_register (counter, reg, &hi32);
1504 lo32 = *ep;
1505 lo32.X_add_number &= 0xffffffff;
1506 if ((lo32.X_add_number & 0xffff0000) == 0)
0dd2d296
ILT
1507 macro_build ((char *) NULL, counter, NULL, "dsll32", "d,w,<", reg,
1508 reg, 0);
6e8dda9c
ILT
1509 else
1510 {
1511 expressionS mid16;
670a50eb 1512
0dd2d296
ILT
1513 macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,
1514 reg, 16);
6e8dda9c
ILT
1515 mid16 = lo32;
1516 mid16.X_add_number >>= 16;
0dd2d296
ILT
1517 macro_build ((char *) NULL, counter, &mid16, "ori", "t,r,i", reg,
1518 reg, (int) BFD_RELOC_LO16);
1519 macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,
1520 reg, 16);
6e8dda9c
ILT
1521 }
1522 if ((lo32.X_add_number & 0xffff) != 0)
0dd2d296 1523 macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i", reg, reg,
9226253a 1524 (int) BFD_RELOC_LO16);
670a50eb 1525 }
3d3c5039
ILT
1526}
1527
0dd2d296
ILT
1528/* Load an address into a register. */
1529
1530static void
1531load_address (counter, reg, ep)
1532 int *counter;
1533 int reg;
1534 expressionS *ep;
1535{
1536 char *p;
1537
1538 if (ep->X_op != O_constant
1539 && ep->X_op != O_symbol)
1540 {
1541 as_bad ("expression too complex");
1542 ep->X_op = O_constant;
1543 }
1544
1545 if (ep->X_op == O_constant)
1546 load_register (counter, reg, ep);
1547 else if (mips_pic == 0)
1548 {
1549 /* If this is a reference to a GP relative symbol, we want
1550 addiu $reg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
1551 Otherwise we want
04cb3372 1552 lui $reg,<sym> (BFD_RELOC_HI16_S)
0dd2d296
ILT
1553 addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
1554 If we have an addend, we always use the latter form. */
1555 if (ep->X_add_number != 0)
1556 p = NULL;
1557 else
1558 {
1559 frag_grow (12);
1560 macro_build ((char *) NULL, counter, ep,
1561 mips_isa < 3 ? "addiu" : "daddiu",
1562 "t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
1563 p = frag_var (rs_machine_dependent, 8, 0,
1564 RELAX_ENCODE (4, 8, -4, 0, 0, mips_warn_about_macros),
1565 ep->X_add_symbol, (long) 0, (char *) NULL);
1566 }
1567 macro_build_lui (p, counter, ep, reg);
1568 if (p != NULL)
1569 p += 4;
1570 macro_build (p, counter, ep,
1571 mips_isa < 3 ? "addiu" : "daddiu",
1572 "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
1573 }
1574 else
1575 {
1576 expressionS ex;
1577
1578 /* If this is a reference to an external symbol, we want
1579 lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
1580 Otherwise we want
1581 lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
1582 nop
1583 addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
1584 If there is a constant, it must be added in afterward. */
1585 ex.X_add_number = ep->X_add_number;
1586 ep->X_add_number = 0;
1587 frag_grow (12);
1588 macro_build ((char *) NULL, counter, ep,
1589 mips_isa < 3 ? "lw" : "ld",
1590 "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
1591 macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");
1592 p = frag_var (rs_machine_dependent, 4, 0,
1593 RELAX_ENCODE (0, 4, -8, 0, 0, mips_warn_about_macros),
1594 ep->X_add_symbol, (long) 0, (char *) NULL);
1595 macro_build (p, counter, ep,
1596 mips_isa < 3 ? "addiu" : "daddiu",
1597 "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
1598 if (ex.X_add_number != 0)
1599 {
1600 if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
1601 as_bad ("PIC code offset overflow (max 16 signed bits)");
1602 ex.X_op = O_constant;
1603 macro_build (p, counter, &ex,
1604 mips_isa < 3 ? "addiu" : "daddiu",
1605 "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
1606 }
1607 }
1608}
1609
3d3c5039
ILT
1610/*
1611 * Build macros
1612 * This routine implements the seemingly endless macro or synthesized
1613 * instructions and addressing modes in the mips assembly language. Many
1614 * of these macros are simple and are similar to each other. These could
1615 * probably be handled by some kind of table or grammer aproach instead of
1616 * this verbose method. Others are not simple macros but are more like
1617 * optimizing code generation.
1618 * One interesting optimization is when several store macros appear
1619 * consecutivly that would load AT with the upper half of the same address.
1620 * The ensuing load upper instructions are ommited. This implies some kind
1621 * of global optimization. We currently only optimize within a single macro.
1622 * For many of the load and store macros if the address is specified as a
1623 * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
1624 * first load register 'at' with zero and use it as the base register. The
1625 * mips assembler simply uses register $zero. Just one tiny optimization
1626 * we're missing.
1627 */
1628static void
1629macro (ip)
1630 struct mips_cl_insn *ip;
1631{
670a50eb
ILT
1632 register int treg, sreg, dreg, breg;
1633 int tempreg;
1634 int mask;
1635 int icnt = 0;
1636 int used_at;
670a50eb
ILT
1637 expressionS expr1;
1638 const char *s;
8358c818 1639 const char *s2;
670a50eb 1640 const char *fmt;
8358c818
ILT
1641 int likely = 0;
1642 int dbl = 0;
1643 int coproc = 0;
6e8dda9c 1644 offsetT maxnum;
9226253a 1645 bfd_reloc_code_real_type r;
0dd2d296 1646 char *p;
670a50eb
ILT
1647
1648 treg = (ip->insn_opcode >> 16) & 0x1f;
1649 dreg = (ip->insn_opcode >> 11) & 0x1f;
1650 sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
1651 mask = ip->insn_mo->mask;
1652
5ac34ac3
ILT
1653 expr1.X_op = O_constant;
1654 expr1.X_op_symbol = NULL;
670a50eb
ILT
1655 expr1.X_add_symbol = NULL;
1656 expr1.X_add_number = 1;
1657
1658 switch (mask)
1659 {
6e8dda9c
ILT
1660 case M_DABS:
1661 dbl = 1;
3d3c5039 1662 case M_ABS:
6e8dda9c
ILT
1663 /* bgez $a0,.+12
1664 move v0,$a0
1665 sub v0,$zero,$a0
1666 */
3d3c5039 1667
becfe05e
ILT
1668 mips_emit_delays ();
1669 ++mips_noreorder;
0dd2d296 1670 mips_any_noreorder = 1;
3d3c5039 1671
670a50eb 1672 expr1.X_add_number = 8;
0dd2d296 1673 macro_build ((char *) NULL, &icnt, &expr1, "bgez", "s,p", sreg);
6e8dda9c 1674 if (dreg == sreg)
0dd2d296 1675 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
6e8dda9c 1676 else
0dd2d296
ILT
1677 macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, sreg, 0);
1678 macro_build ((char *) NULL, &icnt, NULL,
6e8dda9c
ILT
1679 dbl ? "dsub" : "sub",
1680 "d,v,t", dreg, 0, sreg);
3d3c5039 1681
becfe05e 1682 --mips_noreorder;
670a50eb 1683 return;
3d3c5039
ILT
1684
1685 case M_ADD_I:
8358c818
ILT
1686 s = "addi";
1687 s2 = "add";
1688 goto do_addi;
3d3c5039 1689 case M_ADDU_I:
8358c818
ILT
1690 s = "addiu";
1691 s2 = "addu";
1692 goto do_addi;
1693 case M_DADD_I:
6e8dda9c 1694 dbl = 1;
8358c818
ILT
1695 s = "daddi";
1696 s2 = "dadd";
1697 goto do_addi;
1698 case M_DADDU_I:
6e8dda9c 1699 dbl = 1;
8358c818
ILT
1700 s = "daddiu";
1701 s2 = "daddu";
1702 do_addi:
6e8dda9c 1703 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
670a50eb 1704 {
0dd2d296 1705 macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,j", treg, sreg,
9226253a 1706 (int) BFD_RELOC_LO16);
670a50eb 1707 return;
3d3c5039 1708 }
6e8dda9c 1709 load_register (&icnt, AT, &imm_expr);
0dd2d296 1710 macro_build ((char *) NULL, &icnt, NULL, s2, "d,v,t", treg, sreg, AT);
670a50eb 1711 break;
3d3c5039
ILT
1712
1713 case M_AND_I:
6e8dda9c
ILT
1714 s = "andi";
1715 s2 = "and";
1716 goto do_bit;
3d3c5039 1717 case M_OR_I:
6e8dda9c
ILT
1718 s = "ori";
1719 s2 = "or";
1720 goto do_bit;
3d3c5039 1721 case M_NOR_I:
6e8dda9c
ILT
1722 s = "";
1723 s2 = "nor";
1724 goto do_bit;
3d3c5039 1725 case M_XOR_I:
6e8dda9c
ILT
1726 s = "xori";
1727 s2 = "xor";
1728 do_bit:
1729 if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
670a50eb 1730 {
6e8dda9c 1731 if (mask != M_NOR_I)
0dd2d296
ILT
1732 macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,i", treg,
1733 sreg, (int) BFD_RELOC_LO16);
6e8dda9c 1734 else
670a50eb 1735 {
0dd2d296
ILT
1736 macro_build ((char *) NULL, &icnt, &imm_expr, "ori", "t,r,i",
1737 treg, sreg, (int) BFD_RELOC_LO16);
1738 macro_build ((char *) NULL, &icnt, &imm_expr, "nor", "d,v,t",
1739 treg, treg, 0);
3d3c5039 1740 }
6e8dda9c 1741 return;
3d3c5039 1742 }
6e8dda9c
ILT
1743
1744 load_register (&icnt, AT, &imm_expr);
0dd2d296 1745 macro_build ((char *) NULL, &icnt, NULL, s2, "d,v,t", treg, sreg, AT);
670a50eb 1746 break;
3d3c5039
ILT
1747
1748 case M_BEQ_I:
8358c818
ILT
1749 s = "beq";
1750 goto beq_i;
1751 case M_BEQL_I:
1752 s = "beql";
1753 likely = 1;
1754 goto beq_i;
3d3c5039 1755 case M_BNE_I:
8358c818
ILT
1756 s = "bne";
1757 goto beq_i;
1758 case M_BNEL_I:
1759 s = "bnel";
1760 likely = 1;
1761 beq_i:
670a50eb
ILT
1762 if (imm_expr.X_add_number == 0)
1763 {
0dd2d296
ILT
1764 macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg,
1765 0);
670a50eb
ILT
1766 return;
1767 }
6e8dda9c 1768 load_register (&icnt, AT, &imm_expr);
0dd2d296 1769 macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg, AT);
670a50eb 1770 break;
3d3c5039 1771
8358c818
ILT
1772 case M_BGEL:
1773 likely = 1;
3d3c5039 1774 case M_BGE:
670a50eb
ILT
1775 if (treg == 0)
1776 {
0dd2d296 1777 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1778 likely ? "bgezl" : "bgez",
1779 "s,p", sreg);
670a50eb 1780 return;
3d3c5039 1781 }
9a7d824a
ILT
1782 if (sreg == 0)
1783 {
0dd2d296 1784 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1785 likely ? "blezl" : "blez",
1786 "s,p", treg);
9a7d824a
ILT
1787 return;
1788 }
0dd2d296
ILT
1789 macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
1790 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1791 likely ? "beql" : "beq",
1792 "s,t,p", AT, 0);
670a50eb 1793 break;
3d3c5039 1794
8358c818
ILT
1795 case M_BGTL_I:
1796 likely = 1;
3d3c5039 1797 case M_BGT_I:
9a7d824a 1798 /* check for > max integer */
6e8dda9c
ILT
1799 maxnum = 0x7fffffff;
1800 if (mips_isa >= 3)
1801 {
1802 maxnum <<= 16;
1803 maxnum |= 0xffff;
1804 maxnum <<= 16;
1805 maxnum |= 0xffff;
1806 }
1807 if (imm_expr.X_add_number >= maxnum)
9a7d824a
ILT
1808 {
1809 do_false:
1810 /* result is always false */
8358c818
ILT
1811 if (! likely)
1812 {
1813 as_warn ("Branch %s is always false (nop)", ip->insn_mo->name);
0dd2d296 1814 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
8358c818
ILT
1815 }
1816 else
1817 {
1818 as_warn ("Branch likely %s is always false", ip->insn_mo->name);
0dd2d296
ILT
1819 macro_build ((char *) NULL, &icnt, &offset_expr, "bnel",
1820 "s,t,p", 0, 0);
8358c818 1821 }
9a7d824a
ILT
1822 return;
1823 }
670a50eb
ILT
1824 imm_expr.X_add_number++;
1825 /* FALLTHROUGH */
3d3c5039 1826 case M_BGE_I:
8358c818
ILT
1827 case M_BGEL_I:
1828 if (mask == M_BGEL_I)
1829 likely = 1;
670a50eb
ILT
1830 if (imm_expr.X_add_number == 0)
1831 {
0dd2d296 1832 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1833 likely ? "bgezl" : "bgez",
1834 "s,p", sreg);
670a50eb 1835 return;
3d3c5039 1836 }
670a50eb
ILT
1837 if (imm_expr.X_add_number == 1)
1838 {
0dd2d296 1839 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1840 likely ? "bgtzl" : "bgtz",
1841 "s,p", sreg);
670a50eb 1842 return;
3d3c5039 1843 }
6e8dda9c
ILT
1844 maxnum = 0x7fffffff;
1845 if (mips_isa >= 3)
1846 {
1847 maxnum <<= 16;
1848 maxnum |= 0xffff;
1849 maxnum <<= 16;
1850 maxnum |= 0xffff;
1851 }
1852 maxnum = - maxnum - 1;
1853 if (imm_expr.X_add_number <= maxnum)
9a7d824a
ILT
1854 {
1855 do_true:
1856 /* result is always true */
1857 as_warn ("Branch %s is always true", ip->insn_mo->name);
0dd2d296 1858 macro_build ((char *) NULL, &icnt, &offset_expr, "b", "p");
9a7d824a
ILT
1859 return;
1860 }
6e8dda9c 1861 set_at (&icnt, sreg, 0);
0dd2d296 1862 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1863 likely ? "beql" : "beq",
1864 "s,t,p", AT, 0);
670a50eb 1865 break;
3d3c5039 1866
8358c818
ILT
1867 case M_BGEUL:
1868 likely = 1;
3d3c5039 1869 case M_BGEU:
670a50eb 1870 if (treg == 0)
9a7d824a
ILT
1871 goto do_true;
1872 if (sreg == 0)
670a50eb 1873 {
0dd2d296 1874 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1875 likely ? "beql" : "beq",
1876 "s,t,p", 0, treg);
670a50eb 1877 return;
3d3c5039 1878 }
0dd2d296
ILT
1879 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,
1880 treg);
1881 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1882 likely ? "beql" : "beq",
1883 "s,t,p", AT, 0);
670a50eb 1884 break;
3d3c5039 1885
8358c818
ILT
1886 case M_BGTUL_I:
1887 likely = 1;
9a7d824a 1888 case M_BGTU_I:
6e8dda9c 1889 if (sreg == 0 || imm_expr.X_add_number == -1)
9a7d824a
ILT
1890 goto do_false;
1891 imm_expr.X_add_number++;
1892 /* FALLTHROUGH */
3d3c5039 1893 case M_BGEU_I:
8358c818
ILT
1894 case M_BGEUL_I:
1895 if (mask == M_BGEUL_I)
1896 likely = 1;
670a50eb 1897 if (imm_expr.X_add_number == 0)
9a7d824a 1898 goto do_true;
670a50eb
ILT
1899 if (imm_expr.X_add_number == 1)
1900 {
0dd2d296 1901 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1902 likely ? "bnel" : "bne",
1903 "s,t,p", sreg, 0);
670a50eb 1904 return;
3d3c5039 1905 }
6e8dda9c 1906 set_at (&icnt, sreg, 1);
0dd2d296 1907 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1908 likely ? "beql" : "beq",
1909 "s,t,p", AT, 0);
670a50eb 1910 break;
3d3c5039 1911
8358c818
ILT
1912 case M_BGTL:
1913 likely = 1;
3d3c5039 1914 case M_BGT:
670a50eb
ILT
1915 if (treg == 0)
1916 {
0dd2d296 1917 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1918 likely ? "bgtzl" : "bgtz",
1919 "s,p", sreg);
670a50eb 1920 return;
3d3c5039 1921 }
9a7d824a
ILT
1922 if (sreg == 0)
1923 {
0dd2d296 1924 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1925 likely ? "bltzl" : "bltz",
1926 "s,p", treg);
9a7d824a
ILT
1927 return;
1928 }
0dd2d296
ILT
1929 macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
1930 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1931 likely ? "bnel" : "bne",
1932 "s,t,p", AT, 0);
670a50eb 1933 break;
3d3c5039 1934
8358c818
ILT
1935 case M_BGTUL:
1936 likely = 1;
3d3c5039 1937 case M_BGTU:
670a50eb
ILT
1938 if (treg == 0)
1939 {
0dd2d296 1940 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1941 likely ? "bnel" : "bne",
1942 "s,t,p", sreg, 0);
670a50eb 1943 return;
3d3c5039 1944 }
9a7d824a
ILT
1945 if (sreg == 0)
1946 goto do_false;
0dd2d296
ILT
1947 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,
1948 sreg);
1949 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1950 likely ? "bnel" : "bne",
1951 "s,t,p", AT, 0);
670a50eb 1952 break;
3d3c5039 1953
8358c818
ILT
1954 case M_BLEL:
1955 likely = 1;
3d3c5039 1956 case M_BLE:
670a50eb
ILT
1957 if (treg == 0)
1958 {
0dd2d296 1959 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1960 likely ? "blezl" : "blez",
1961 "s,p", sreg);
670a50eb
ILT
1962 return;
1963 }
9a7d824a
ILT
1964 if (sreg == 0)
1965 {
0dd2d296 1966 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1967 likely ? "bgezl" : "bgez",
1968 "s,p", treg);
9a7d824a
ILT
1969 return;
1970 }
0dd2d296
ILT
1971 macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
1972 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1973 likely ? "beql" : "beq",
1974 "s,t,p", AT, 0);
670a50eb 1975 break;
3d3c5039 1976
8358c818
ILT
1977 case M_BLEL_I:
1978 likely = 1;
3d3c5039 1979 case M_BLE_I:
6e8dda9c
ILT
1980 maxnum = 0x7fffffff;
1981 if (mips_isa >= 3)
1982 {
1983 maxnum <<= 16;
1984 maxnum |= 0xffff;
1985 maxnum <<= 16;
1986 maxnum |= 0xffff;
1987 }
1988 if (imm_expr.X_add_number >= maxnum)
9a7d824a
ILT
1989 goto do_true;
1990 imm_expr.X_add_number++;
1991 /* FALLTHROUGH */
9a7d824a 1992 case M_BLT_I:
8358c818
ILT
1993 case M_BLTL_I:
1994 if (mask == M_BLTL_I)
1995 likely = 1;
670a50eb
ILT
1996 if (imm_expr.X_add_number == 0)
1997 {
0dd2d296 1998 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
1999 likely ? "bltzl" : "bltz",
2000 "s,p", sreg);
670a50eb
ILT
2001 return;
2002 }
9a7d824a 2003 if (imm_expr.X_add_number == 1)
670a50eb 2004 {
0dd2d296 2005 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2006 likely ? "blezl" : "blez",
2007 "s,p", sreg);
670a50eb
ILT
2008 return;
2009 }
6e8dda9c 2010 set_at (&icnt, sreg, 0);
0dd2d296 2011 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2012 likely ? "bnel" : "bne",
2013 "s,t,p", AT, 0);
670a50eb 2014 break;
3d3c5039 2015
8358c818
ILT
2016 case M_BLEUL:
2017 likely = 1;
3d3c5039 2018 case M_BLEU:
670a50eb
ILT
2019 if (treg == 0)
2020 {
0dd2d296 2021 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2022 likely ? "beql" : "beq",
2023 "s,t,p", sreg, 0);
670a50eb 2024 return;
3d3c5039 2025 }
9a7d824a
ILT
2026 if (sreg == 0)
2027 goto do_true;
0dd2d296
ILT
2028 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,
2029 sreg);
2030 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2031 likely ? "beql" : "beq",
2032 "s,t,p", AT, 0);
670a50eb 2033 break;
3d3c5039 2034
8358c818
ILT
2035 case M_BLEUL_I:
2036 likely = 1;
3d3c5039 2037 case M_BLEU_I:
6e8dda9c 2038 if (sreg == 0 || imm_expr.X_add_number == -1)
9a7d824a
ILT
2039 goto do_true;
2040 imm_expr.X_add_number++;
2041 /* FALLTHROUGH */
9a7d824a 2042 case M_BLTU_I:
8358c818
ILT
2043 case M_BLTUL_I:
2044 if (mask == M_BLTUL_I)
2045 likely = 1;
670a50eb 2046 if (imm_expr.X_add_number == 0)
9a7d824a
ILT
2047 goto do_false;
2048 if (imm_expr.X_add_number == 1)
670a50eb 2049 {
0dd2d296 2050 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2051 likely ? "beql" : "beq",
2052 "s,t,p", sreg, 0);
670a50eb 2053 return;
3d3c5039 2054 }
6e8dda9c 2055 set_at (&icnt, sreg, 1);
0dd2d296 2056 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2057 likely ? "bnel" : "bne",
2058 "s,t,p", AT, 0);
670a50eb 2059 break;
3d3c5039 2060
8358c818
ILT
2061 case M_BLTL:
2062 likely = 1;
3d3c5039 2063 case M_BLT:
670a50eb
ILT
2064 if (treg == 0)
2065 {
0dd2d296 2066 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2067 likely ? "bltzl" : "bltz",
2068 "s,p", sreg);
670a50eb 2069 return;
3d3c5039 2070 }
9a7d824a 2071 if (sreg == 0)
670a50eb 2072 {
0dd2d296 2073 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2074 likely ? "bgtzl" : "bgtz",
2075 "s,p", treg);
670a50eb 2076 return;
3d3c5039 2077 }
0dd2d296
ILT
2078 macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
2079 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2080 likely ? "bnel" : "bne",
2081 "s,t,p", AT, 0);
670a50eb 2082 break;
3d3c5039 2083
8358c818
ILT
2084 case M_BLTUL:
2085 likely = 1;
3d3c5039 2086 case M_BLTU:
670a50eb 2087 if (treg == 0)
9a7d824a
ILT
2088 goto do_false;
2089 if (sreg == 0)
670a50eb 2090 {
0dd2d296 2091 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2092 likely ? "bnel" : "bne",
2093 "s,t,p", 0, treg);
670a50eb
ILT
2094 return;
2095 }
0dd2d296
ILT
2096 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,
2097 treg);
2098 macro_build ((char *) NULL, &icnt, &offset_expr,
8358c818
ILT
2099 likely ? "bnel" : "bne",
2100 "s,t,p", AT, 0);
670a50eb 2101 break;
3d3c5039 2102
8358c818
ILT
2103 case M_DDIV_3:
2104 dbl = 1;
3d3c5039 2105 case M_DIV_3:
8358c818
ILT
2106 s = "mflo";
2107 goto do_div3;
2108 case M_DREM_3:
2109 dbl = 1;
3d3c5039 2110 case M_REM_3:
8358c818
ILT
2111 s = "mfhi";
2112 do_div3:
670a50eb
ILT
2113 if (treg == 0)
2114 {
2115 as_warn ("Divide by zero.");
0dd2d296 2116 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
670a50eb
ILT
2117 return;
2118 }
2119
becfe05e
ILT
2120 mips_emit_delays ();
2121 ++mips_noreorder;
0dd2d296
ILT
2122 mips_any_noreorder = 1;
2123 macro_build ((char *) NULL, &icnt, NULL,
8358c818 2124 dbl ? "ddiv" : "div",
ff3a5c18 2125 "z,s,t", sreg, treg);
670a50eb 2126 expr1.X_add_number = 8;
0dd2d296
ILT
2127 macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);
2128 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
2129 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
670a50eb 2130 expr1.X_add_number = -1;
0dd2d296 2131 macro_build ((char *) NULL, &icnt, &expr1,
8358c818 2132 dbl ? "daddiu" : "addiu",
9226253a 2133 "t,r,j", AT, 0, (int) BFD_RELOC_LO16);
8358c818 2134 expr1.X_add_number = dbl ? 20 : 16;
0dd2d296 2135 macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, AT);
8358c818
ILT
2136 if (dbl)
2137 {
2138 expr1.X_add_number = 1;
0dd2d296 2139 macro_build ((char *) NULL, &icnt, &expr1, "daddiu", "t,r,j", AT, 0,
9226253a 2140 (int) BFD_RELOC_LO16);
0dd2d296
ILT
2141 macro_build ((char *) NULL, &icnt, NULL, "dsll32", "d,w,<", AT, AT,
2142 31);
8358c818
ILT
2143 }
2144 else
2145 {
2146 expr1.X_add_number = 0x80000000;
0dd2d296 2147 macro_build ((char *) NULL, &icnt, &expr1, "lui", "t,u", AT);
8358c818 2148 }
670a50eb 2149 expr1.X_add_number = 8;
0dd2d296
ILT
2150 macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", sreg, AT);
2151 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
2152 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
becfe05e 2153 --mips_noreorder;
0dd2d296 2154 macro_build ((char *) NULL, &icnt, NULL, s, "d", dreg);
670a50eb 2155 break;
3d3c5039
ILT
2156
2157 case M_DIV_3I:
8358c818
ILT
2158 s = "div";
2159 s2 = "mflo";
2160 goto do_divi;
3d3c5039 2161 case M_DIVU_3I:
8358c818
ILT
2162 s = "divu";
2163 s2 = "mflo";
2164 goto do_divi;
3d3c5039 2165 case M_REM_3I:
8358c818
ILT
2166 s = "div";
2167 s2 = "mfhi";
2168 goto do_divi;
3d3c5039 2169 case M_REMU_3I:
8358c818
ILT
2170 s = "divu";
2171 s2 = "mfhi";
2172 goto do_divi;
2173 case M_DDIV_3I:
2174 dbl = 1;
2175 s = "ddiv";
2176 s2 = "mflo";
2177 goto do_divi;
2178 case M_DDIVU_3I:
2179 dbl = 1;
2180 s = "ddivu";
2181 s2 = "mflo";
2182 goto do_divi;
2183 case M_DREM_3I:
2184 dbl = 1;
2185 s = "ddiv";
2186 s2 = "mfhi";
2187 goto do_divi;
2188 case M_DREMU_3I:
2189 dbl = 1;
2190 s = "ddivu";
2191 s2 = "mfhi";
2192 do_divi:
670a50eb
ILT
2193 if (imm_expr.X_add_number == 0)
2194 {
2195 as_warn ("Divide by zero.");
0dd2d296 2196 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
670a50eb
ILT
2197 return;
2198 }
2199 if (imm_expr.X_add_number == 1)
2200 {
8358c818 2201 if (strcmp (s2, "mflo") == 0)
0dd2d296
ILT
2202 macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg,
2203 sreg);
3d3c5039 2204 else
0dd2d296 2205 macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
3d3c5039
ILT
2206 return;
2207 }
8358c818
ILT
2208 if (imm_expr.X_add_number == -1
2209 && s[strlen (s) - 1] != 'u')
2210 {
2211 if (strcmp (s2, "mflo") == 0)
2212 {
2213 if (dbl)
0dd2d296
ILT
2214 macro_build ((char *) NULL, &icnt, NULL, "dneg", "d,w", dreg,
2215 sreg);
8358c818 2216 else
0dd2d296
ILT
2217 macro_build ((char *) NULL, &icnt, NULL, "neg", "d,w", dreg,
2218 sreg);
8358c818
ILT
2219 }
2220 else
0dd2d296 2221 macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
8358c818
ILT
2222 return;
2223 }
3d3c5039 2224
6e8dda9c 2225 load_register (&icnt, AT, &imm_expr);
0dd2d296
ILT
2226 macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, AT);
2227 macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);
670a50eb
ILT
2228 break;
2229
2230 case M_DIVU_3:
8358c818
ILT
2231 s = "divu";
2232 s2 = "mflo";
2233 goto do_divu3;
670a50eb 2234 case M_REMU_3:
8358c818
ILT
2235 s = "divu";
2236 s2 = "mfhi";
2237 goto do_divu3;
2238 case M_DDIVU_3:
2239 s = "ddivu";
2240 s2 = "mflo";
2241 goto do_divu3;
2242 case M_DREMU_3:
2243 s = "ddivu";
2244 s2 = "mfhi";
2245 do_divu3:
becfe05e
ILT
2246 mips_emit_delays ();
2247 ++mips_noreorder;
0dd2d296
ILT
2248 mips_any_noreorder = 1;
2249 macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);
670a50eb 2250 expr1.X_add_number = 8;
0dd2d296
ILT
2251 macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);
2252 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
2253 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
becfe05e 2254 --mips_noreorder;
0dd2d296 2255 macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);
670a50eb 2256 return;
3d3c5039 2257
0dd2d296
ILT
2258 case M_LA_AB:
2259 /* Load the address of a symbol into a register. If M_LA_AB, we
2260 then add a base register to it. */
2261 if (offset_expr.X_op != O_symbol
2262 && offset_expr.X_op != O_constant)
670a50eb 2263 {
0dd2d296
ILT
2264 as_bad ("expression too complex");
2265 offset_expr.X_op = O_constant;
2266 }
2267
2268 if (treg == breg)
2269 {
2270 tempreg = AT;
2271 used_at = 1;
3d3c5039 2272 }
670a50eb
ILT
2273 else
2274 {
0dd2d296
ILT
2275 tempreg = treg;
2276 used_at = 0;
670a50eb 2277 }
3d3c5039 2278
5ac34ac3 2279 if (offset_expr.X_op == O_constant)
6e8dda9c 2280 load_register (&icnt, tempreg, &offset_expr);
0dd2d296 2281 else if (mips_pic == 0)
670a50eb 2282 {
0dd2d296
ILT
2283 /* If this is a reference to an GP relative symbol, we want
2284 addiu $tempreg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
2285 Otherwise we want
2286 lui $tempreg,<sym> (BFD_RELOC_HI16_S)
2287 addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
2288 If we have a constant, we need two instructions anyhow,
2289 so we may as well always use the latter form. */
2290 if (offset_expr.X_add_number != 0)
2291 p = NULL;
2292 else
2293 {
2294 frag_grow (12);
2295 macro_build ((char *) NULL, &icnt, &offset_expr,
2296 mips_isa < 3 ? "addiu" : "daddiu",
2297 "t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
2298 p = frag_var (rs_machine_dependent, 8, 0,
2299 RELAX_ENCODE (4, 8, 0, 4, 0,
2300 mips_warn_about_macros),
2301 offset_expr.X_add_symbol, (long) 0,
2302 (char *) NULL);
2303 }
2304 macro_build_lui (p, &icnt, &offset_expr, tempreg);
2305 if (p != NULL)
2306 p += 4;
2307 macro_build (p, &icnt, &offset_expr,
6e8dda9c 2308 mips_isa < 3 ? "addiu" : "daddiu",
0dd2d296
ILT
2309 "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
2310 }
2311 else
2312 {
2313 /* If this is a reference to an external symbol, and there
2314 is no constant, we want
2315 lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2316 For a local symbol, we want
2317 lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2318 nop
2319 addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
2320
2321 If we have a small constant, and this is a reference to
2322 an external symbol, we want
2323 lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2324 nop
2325 addiu $tempreg,$tempreg,<constant>
2326 For a local symbol, we want the same instruction
2327 sequence, but we output a BFD_RELOC_LO16 reloc on the
2328 addiu instruction.
2329
2330 If we have a large constant, and this is a reference to
2331 an external symbol, we want
2332 lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2333 lui $at,<hiconstant>
2334 addiu $at,$at,<loconstant>
2335 addu $tempreg,$tempreg,$at
2336 For a local symbol, we want the same instruction
2337 sequence, but we output a BFD_RELOC_LO16 reloc on the
2338 addiu instruction. */
2339 expr1.X_add_number = offset_expr.X_add_number;
2340 offset_expr.X_add_number = 0;
2341 frag_grow (24);
2342 macro_build ((char *) NULL, &icnt, &offset_expr,
2343 mips_isa < 3 ? "lw" : "ld",
2344 "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
2345 if (expr1.X_add_number == 0)
2346 {
2347 int off;
2348
2349 if (breg == 0)
2350 off = 0;
2351 else
2352 {
2353 /* We're going to put in an addu instruction using
2354 tempreg, so we may as well insert the nop right
2355 now. */
2356 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2357 "nop", "");
2358 off = 4;
2359 }
2360 p = frag_var (rs_machine_dependent, 8 - off, 0,
2361 RELAX_ENCODE (0, 8 - off, -4 - off, 4 - off, 0,
2362 (breg == 0
2363 ? mips_warn_about_macros
2364 : 0)),
2365 offset_expr.X_add_symbol, (long) 0,
2366 (char *) NULL);
2367 if (breg == 0)
2368 {
2369 macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
2370 p += 4;
2371 }
2372 macro_build (p, &icnt, &expr1,
2373 mips_isa < 3 ? "addiu" : "daddiu",
2374 "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
2375 /* FIXME: If breg == 0, and the next instruction uses
2376 $tempreg, then if this variant case is used an extra
2377 nop will be generated. */
2378 }
2379 else if (expr1.X_add_number >= -0x8000
2380 && expr1.X_add_number < 0x8000)
2381 {
2382 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2383 "nop", "");
2384 macro_build ((char *) NULL, &icnt, &expr1,
2385 mips_isa < 3 ? "addiu" : "daddiu",
2386 "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
2387 (void) frag_var (rs_machine_dependent, 0, 0,
2388 RELAX_ENCODE (0, 0, -12, -4, 0, 0),
2389 offset_expr.X_add_symbol, (long) 0,
2390 (char *) NULL);
2391 }
2392 else
2393 {
2394 int off1;
2395
2396 /* If we are going to add in a base register, and the
2397 target register and the base register are the same,
2398 then we are using AT as a temporary register. Since
2399 we want to load the constant into AT, we add our
2400 current AT (from the global offset table) and the
2401 register into the register now, and pretend we were
2402 not using a base register. */
2403 if (breg != treg)
2404 off1 = 0;
2405 else
2406 {
2407 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2408 "nop", "");
2409 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2410 mips_isa < 3 ? "addu" : "daddu",
2411 "d,v,t", treg, AT, breg);
2412 breg = 0;
2413 tempreg = treg;
2414 off1 = -8;
2415 }
2416
2417 macro_build_lui ((char *) NULL, &icnt, &expr1, AT);
2418 macro_build ((char *) NULL, &icnt, &expr1,
2419 mips_isa < 3 ? "addiu" : "daddiu",
2420 "t,r,j", AT, AT, (int) BFD_RELOC_LO16);
2421 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2422 mips_isa < 3 ? "addu" : "daddu",
2423 "d,v,t", tempreg, tempreg, AT);
2424 (void) frag_var (rs_machine_dependent, 0, 0,
2425 RELAX_ENCODE (0, 0, -16 + off1, -8, 0, 0),
2426 offset_expr.X_add_symbol, (long) 0,
2427 (char *) NULL);
2428 used_at = 1;
2429 }
670a50eb 2430 }
0dd2d296 2431
670a50eb 2432 if (breg != 0)
0dd2d296
ILT
2433 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2434 mips_isa < 3 ? "addu" : "daddu",
2435 "d,v,t", treg, tempreg, breg);
2436
2437 if (! used_at)
2438 return;
2439
2440 break;
2441
2442 case M_J_A:
2443 /* The j instruction may not be used in PIC code, since it
2444 requires an absolute address. We convert it to a b
2445 instruction. */
2446 if (mips_pic == 0)
2447 macro_build ((char *) NULL, &icnt, &offset_expr, "j", "a");
2448 else
2449 macro_build ((char *) NULL, &icnt, &offset_expr, "b", "p");
670a50eb 2450 return;
3d3c5039 2451
9226253a
ILT
2452 /* The jal instructions must be handled as macros because when
2453 generating PIC code they expand to multi-instruction
2454 sequences. Normally they are simple instructions. */
2455 case M_JAL_1:
2456 dreg = RA;
2457 /* Fall through. */
2458 case M_JAL_2:
2459 if (mips_pic == 0)
2460 {
0dd2d296
ILT
2461 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr",
2462 "d,s", dreg, sreg);
9226253a
ILT
2463 return;
2464 }
2465
2466 /* I only know how to handle pic2. */
2467 assert (mips_pic == 2);
2468
0dd2d296 2469 if (sreg != PIC_CALL_REG)
9226253a
ILT
2470 as_warn ("MIPS PIC call to register other than $25");
2471
0dd2d296 2472 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr", "d,s",
9226253a 2473 dreg, sreg);
0dd2d296
ILT
2474 if (mips_cprestore_offset < 0)
2475 as_warn ("No .cprestore pseudo-op used in PIC code");
2476 else
2477 {
2478 expr1.X_add_number = mips_cprestore_offset;
2479 macro_build ((char *) NULL, &icnt, &expr1,
2480 mips_isa < 3 ? "lw" : "ld",
2481 "t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);
2482 }
9226253a
ILT
2483 return;
2484
2485 case M_JAL_A:
2486 if (mips_pic == 0)
2487 {
0dd2d296 2488 macro_build ((char *) NULL, &icnt, &offset_expr, "jal", "a");
9226253a
ILT
2489 return;
2490 }
2491
2492 /* I only know how to handle pic2. */
2493 assert (mips_pic == 2);
2494
0dd2d296
ILT
2495 /* If this is a reference to an external symbol, we want
2496 lw $25,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
2497 nop
2498 jalr $25
2499 nop
2500 lw $gp,cprestore($sp)
2501 The cprestore value is set using the .cprestore pseudo-op.
2502 If the symbol is not external, we want
2503 lw $25,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2504 nop
2505 addiu $25,$25,<sym> (BFD_RELOC_LO16)
2506 jalr $25
2507 nop
2508 lw $gp,cprestore($sp)
2509 */
2510 frag_grow (12);
2511 macro_build ((char *) NULL, &icnt, &offset_expr,
9226253a
ILT
2512 mips_isa < 3 ? "lw" : "ld",
2513 "t,o(b)", PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL16, GP);
0dd2d296
ILT
2514 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
2515 p = frag_var (rs_machine_dependent, 4, 0,
2516 RELAX_ENCODE (0, 4, -8, 0, 0, 0),
2517 offset_expr.X_add_symbol, (long) 0, (char *) NULL);
2518 macro_build (p, &icnt, &offset_expr,
2519 mips_isa < 3 ? "addiu" : "daddiu",
2520 "t,r,j", PIC_CALL_REG, PIC_CALL_REG,
2521 (int) BFD_RELOC_LO16);
2522 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr", "s",
2523 PIC_CALL_REG);
2524 if (mips_cprestore_offset < 0)
2525 as_warn ("No .cprestore pseudo-op used in PIC code");
2526 else
2527 {
2528 if (mips_noreorder)
2529 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2530 "nop", "");
2531 expr1.X_add_number = mips_cprestore_offset;
2532 macro_build ((char *) NULL, &icnt, &expr1,
2533 mips_isa < 3 ? "lw" : "ld",
2534 "t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);
2535 }
9226253a
ILT
2536 return;
2537
3d3c5039 2538 case M_LB_AB:
670a50eb
ILT
2539 s = "lb";
2540 goto ld;
3d3c5039 2541 case M_LBU_AB:
670a50eb
ILT
2542 s = "lbu";
2543 goto ld;
3d3c5039 2544 case M_LH_AB:
670a50eb
ILT
2545 s = "lh";
2546 goto ld;
3d3c5039 2547 case M_LHU_AB:
670a50eb
ILT
2548 s = "lhu";
2549 goto ld;
3d3c5039 2550 case M_LW_AB:
670a50eb
ILT
2551 s = "lw";
2552 goto ld;
3d3c5039 2553 case M_LWC0_AB:
670a50eb 2554 s = "lwc0";
8358c818 2555 coproc = 1;
670a50eb 2556 goto ld;
3d3c5039 2557 case M_LWC1_AB:
670a50eb 2558 s = "lwc1";
8358c818 2559 coproc = 1;
670a50eb 2560 goto ld;
3d3c5039 2561 case M_LWC2_AB:
670a50eb 2562 s = "lwc2";
8358c818 2563 coproc = 1;
670a50eb 2564 goto ld;
3d3c5039 2565 case M_LWC3_AB:
670a50eb 2566 s = "lwc3";
8358c818 2567 coproc = 1;
670a50eb 2568 goto ld;
3d3c5039 2569 case M_LWL_AB:
670a50eb
ILT
2570 s = "lwl";
2571 goto ld;
3d3c5039 2572 case M_LWR_AB:
670a50eb 2573 s = "lwr";
8358c818
ILT
2574 goto ld;
2575 case M_LDC1_AB:
2576 s = "ldc1";
2577 coproc = 1;
2578 goto ld;
2579 case M_LDC2_AB:
2580 s = "ldc2";
2581 coproc = 1;
2582 goto ld;
2583 case M_LDC3_AB:
2584 s = "ldc3";
2585 coproc = 1;
2586 goto ld;
2587 case M_LDL_AB:
2588 s = "ldl";
2589 goto ld;
2590 case M_LDR_AB:
2591 s = "ldr";
2592 goto ld;
2593 case M_LL_AB:
2594 s = "ll";
2595 goto ld;
2596 case M_LLD_AB:
2597 s = "lld";
2598 goto ld;
2599 case M_LWU_AB:
2600 s = "lwu";
3d3c5039 2601 ld:
8358c818 2602 if (breg == treg || coproc)
670a50eb
ILT
2603 {
2604 tempreg = AT;
2605 used_at = 1;
2606 }
2607 else
2608 {
2609 tempreg = treg;
2610 used_at = 0;
2611 }
2612 goto ld_st;
3d3c5039 2613 case M_SB_AB:
670a50eb
ILT
2614 s = "sb";
2615 goto st;
3d3c5039 2616 case M_SH_AB:
670a50eb
ILT
2617 s = "sh";
2618 goto st;
3d3c5039 2619 case M_SW_AB:
670a50eb
ILT
2620 s = "sw";
2621 goto st;
3d3c5039 2622 case M_SWC0_AB:
670a50eb 2623 s = "swc0";
8358c818 2624 coproc = 1;
670a50eb 2625 goto st;
3d3c5039 2626 case M_SWC1_AB:
670a50eb 2627 s = "swc1";
8358c818 2628 coproc = 1;
670a50eb 2629 goto st;
3d3c5039 2630 case M_SWC2_AB:
670a50eb 2631 s = "swc2";
8358c818 2632 coproc = 1;
670a50eb 2633 goto st;
3d3c5039 2634 case M_SWC3_AB:
670a50eb 2635 s = "swc3";
8358c818 2636 coproc = 1;
670a50eb 2637 goto st;
3d3c5039 2638 case M_SWL_AB:
670a50eb
ILT
2639 s = "swl";
2640 goto st;
3d3c5039 2641 case M_SWR_AB:
670a50eb 2642 s = "swr";
8358c818
ILT
2643 goto st;
2644 case M_SC_AB:
2645 s = "sc";
2646 goto st;
2647 case M_SCD_AB:
2648 s = "scd";
2649 goto st;
2650 case M_SDC1_AB:
2651 s = "sdc1";
2652 coproc = 1;
2653 goto st;
2654 case M_SDC2_AB:
2655 s = "sdc2";
2656 coproc = 1;
2657 goto st;
2658 case M_SDC3_AB:
2659 s = "sdc3";
2660 coproc = 1;
2661 goto st;
2662 case M_SDL_AB:
2663 s = "sdl";
2664 goto st;
2665 case M_SDR_AB:
2666 s = "sdr";
3d3c5039 2667 st:
670a50eb
ILT
2668 tempreg = AT;
2669 used_at = 1;
3d3c5039 2670 ld_st:
8358c818
ILT
2671 if (mask == M_LWC1_AB
2672 || mask == M_SWC1_AB
8358c818 2673 || mask == M_LDC1_AB
0dd2d296
ILT
2674 || mask == M_SDC1_AB
2675 || mask == M_L_DAB
2676 || mask == M_S_DAB)
670a50eb 2677 fmt = "T,o(b)";
8358c818 2678 else if (coproc)
19ed8960 2679 fmt = "E,o(b)";
670a50eb
ILT
2680 else
2681 fmt = "t,o(b)";
0dd2d296
ILT
2682
2683 if (offset_expr.X_op != O_constant
2684 && offset_expr.X_op != O_symbol)
2685 {
2686 as_bad ("expression too complex");
2687 offset_expr.X_op = O_constant;
2688 }
2689
2690 /* A constant expression in PIC code can be handled just as it
2691 is in non PIC code. */
2692 if (mips_pic == 0
2693 || offset_expr.X_op == O_constant)
670a50eb 2694 {
0dd2d296
ILT
2695 /* If this is a reference to a GP relative symbol, and there
2696 is no base register, we want
2697 <op> $treg,<sym>($gp) (BFD_RELOC_MIPS_GPREL)
2698 Otherwise we want
2699 lui $tempreg,<sym> (BFD_RELOC_HI16_S)
2700 <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
2701 If we have a constant, we need two instructions anyhow,
2702 so we always use the latter form.
2703
2704 If we have a base register, and this is a reference to a
2705 GP relative symbol, we want
2706 addu $tempreg,$breg,$gp
2707 <op> $treg,<sym>($tempreg) (BFD_RELOC_MIPS_GPREL)
2708 Otherwise we want
2709 lui $tempreg,<sym> (BFD_RELOC_HI16_S)
2710 addu $tempreg,$tempreg,$breg
2711 <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
2712 With a constant we always use the latter case. */
670a50eb
ILT
2713 if (breg == 0)
2714 {
0dd2d296
ILT
2715 if (offset_expr.X_add_number != 0)
2716 p = NULL;
2717 else
2718 {
2719 frag_grow (12);
2720 macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
2721 treg, (int) BFD_RELOC_MIPS_GPREL, GP);
2722 p = frag_var (rs_machine_dependent, 8, 0,
2723 RELAX_ENCODE (4, 8, 0, 4, 0,
8197b589
ILT
2724 (mips_warn_about_macros
2725 || (used_at && mips_noat))),
0dd2d296
ILT
2726 offset_expr.X_add_symbol, (long) 0,
2727 (char *) NULL);
8197b589 2728 used_at = 0;
0dd2d296
ILT
2729 }
2730 macro_build_lui (p, &icnt, &offset_expr, tempreg);
2731 if (p != NULL)
2732 p += 4;
2733 macro_build (p, &icnt, &offset_expr, s, fmt, treg,
2734 (int) BFD_RELOC_LO16, tempreg);
2735 }
2736 else
2737 {
2738 if (offset_expr.X_add_number != 0)
2739 p = NULL;
2740 else
2741 {
2742 frag_grow (20);
2743 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
2744 mips_isa < 3 ? "addu" : "daddu",
2745 "d,v,t", tempreg, breg, GP);
2746 macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
2747 treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
2748 p = frag_var (rs_machine_dependent, 12, 0,
2749 RELAX_ENCODE (8, 12, 0, 8, 0, 0),
2750 offset_expr.X_add_symbol, (long) 0,
2751 (char *) NULL);
2752 }
2753 macro_build_lui (p, &icnt, &offset_expr, tempreg);
2754 if (p != NULL)
2755 p += 4;
2756 macro_build (p, &icnt, (expressionS *) NULL,
2757 mips_isa < 3 ? "addu" : "daddu",
2758 "d,v,t", tempreg, tempreg, breg);
2759 if (p != NULL)
2760 p += 4;
2761 macro_build (p, &icnt, &offset_expr, s, fmt, treg,
2762 (int) BFD_RELOC_LO16, tempreg);
670a50eb 2763 }
670a50eb
ILT
2764 }
2765 else
2766 {
0dd2d296
ILT
2767 /* If this is a reference to an external symbol, we want
2768 lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2769 nop
2770 <op> $treg,0($tempreg)
2771 Otherwise we want
2772 lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
2773 nop
2774 addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
2775 <op> $treg,0($tempreg)
2776 If there is a base register, we add it to $tempreg before
2777 the <op>. If there is a constant, we stick it in the
2778 <op> instruction. We don't handle constants larger than
2779 16 bits, because we have no way to load the upper 16 bits
2780 (actually, we could handle them for the subset of cases
2781 in which we are not using $at). */
2782 assert (offset_expr.X_op == O_symbol);
2783 expr1.X_add_number = offset_expr.X_add_number;
2784 offset_expr.X_add_number = 0;
2785 if (expr1.X_add_number < -0x8000
2786 || expr1.X_add_number >= 0x8000)
2787 as_bad ("PIC code offset overflow (max 16 signed bits)");
2788 frag_grow (12);
2789 macro_build ((char *) NULL, &icnt, &offset_expr,
2790 mips_isa < 3 ? "lw" : "ld",
2791 "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
2792 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
2793 p = frag_var (rs_machine_dependent, 4, 0,
2794 RELAX_ENCODE (0, 4, -8, 0, 0, 0),
2795 offset_expr.X_add_symbol, (long) 0,
2796 (char *) NULL);
2797 macro_build (p, &icnt, &offset_expr,
2798 mips_isa < 3 ? "addiu" : "daddiu",
2799 "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
670a50eb 2800 if (breg != 0)
0dd2d296 2801 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
6e8dda9c
ILT
2802 mips_isa < 3 ? "addu" : "daddu",
2803 "d,v,t", tempreg, tempreg, breg);
0dd2d296
ILT
2804 macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
2805 (int) BFD_RELOC_LO16, tempreg);
670a50eb 2806 }
0dd2d296
ILT
2807
2808 if (! used_at)
2809 return;
2810
2811 break;
3d3c5039
ILT
2812
2813 case M_LI:
19ed8960 2814 case M_LI_S:
6e8dda9c 2815 load_register (&icnt, treg, &imm_expr);
670a50eb 2816 return;
3d3c5039 2817
0dd2d296
ILT
2818 case M_LI_SS:
2819 if (mips_pic == 0)
2820 {
2821 assert (offset_expr.X_op == O_symbol
2822 && strcmp (segment_name (S_GET_SEGMENT
2823 (offset_expr.X_add_symbol)),
2824 ".lit4") == 0
2825 && offset_expr.X_add_number == 0);
2826 macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
2827 treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
2828 }
2829 else
2830 {
2831 assert (imm_expr.X_op == O_constant);
2832 load_register (&icnt, treg, &imm_expr);
2833 }
2834 return;
2835
3d3c5039 2836 case M_LI_D:
0dd2d296
ILT
2837 /* We know that sym is in the .rdata instruction. First we get
2838 the upper 16 bits of the address. */
2839 if (mips_pic == 0)
2840 {
2841 /* FIXME: This won't work for a 64 bit address. */
2842 macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
2843 }
2844 else
2845 {
2846 macro_build ((char *) NULL, &icnt, &offset_expr,
2847 mips_isa < 3 ? "lw" : "ld",
2848 "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
2849 }
2850 /* Now we load the register(s). */
8358c818 2851 if (mips_isa >= 3)
0dd2d296
ILT
2852 macro_build ((char *) NULL, &icnt, &offset_expr, "ld", "t,o(b)",
2853 treg, (int) BFD_RELOC_LO16, AT);
8358c818
ILT
2854 else
2855 {
0dd2d296
ILT
2856 macro_build ((char *) NULL, &icnt, &offset_expr, "lw", "t,o(b)",
2857 treg, (int) BFD_RELOC_LO16, AT);
2858 if (treg != 31)
2859 {
2860 /* FIXME: How in the world do we deal with the possible
2861 overflow here? */
2862 offset_expr.X_add_number += 4;
2863 macro_build ((char *) NULL, &icnt, &offset_expr, "lw", "t,o(b)",
2864 treg + 1, (int) BFD_RELOC_LO16, AT);
2865 }
8358c818 2866 }
0dd2d296 2867
670a50eb 2868 break;
3d3c5039
ILT
2869
2870 case M_LI_DD:
0dd2d296 2871 if (mips_pic == 0)
8358c818 2872 {
0dd2d296
ILT
2873 /* Load a floating point number from the .lit8 section. */
2874 assert (offset_expr.X_op == O_symbol
2875 && strcmp (segment_name (S_GET_SEGMENT
2876 (offset_expr.X_add_symbol)),
2877 ".lit8") == 0
2878 && offset_expr.X_add_number == 0);
2879 if (mips_isa >= 2)
2880 {
2881 macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
2882 "T,o(b)", treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
2883 return;
2884 }
2885 breg = GP;
2886 r = BFD_RELOC_MIPS_LITERAL;
2887 goto dob;
2888 }
2889 else
2890 {
2891 /* Load the double from the .rdata section. */
2892 macro_build ((char *) NULL, &icnt, &offset_expr,
2893 mips_isa < 3 ? "lw" : "ld",
2894 "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
2895 if (mips_isa >= 2)
2896 {
2897 macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
2898 "T,o(b)", treg, (int) BFD_RELOC_LO16, GP);
2899 break;
2900 }
2901 breg = AT;
2902 r = BFD_RELOC_LO16;
2903 goto dob;
8358c818 2904 }
9226253a 2905
3d3c5039 2906 case M_L_DOB:
9a7d824a
ILT
2907 /* Even on a big endian machine $fn comes before $fn+1. We have
2908 to adjust when loading from memory. */
9226253a
ILT
2909 r = BFD_RELOC_LO16;
2910 dob:
8358c818 2911 assert (mips_isa < 2);
0dd2d296 2912 macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
9a7d824a 2913 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
9226253a 2914 (int) r, breg);
0dd2d296
ILT
2915 /* FIXME: A possible overflow which I don't know how to deal
2916 with. */
670a50eb 2917 offset_expr.X_add_number += 4;
0dd2d296 2918 macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
9a7d824a 2919 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
9226253a 2920 (int) r, breg);
0dd2d296
ILT
2921 if (breg != AT)
2922 return;
2923 break;
3d3c5039
ILT
2924
2925 case M_L_DAB:
670a50eb
ILT
2926 /*
2927 * The MIPS assembler seems to check for X_add_number not
2928 * being double aligned and generating:
2929 * lui at,%hi(foo+1)
2930 * addu at,at,v1
2931 * addiu at,at,%lo(foo+1)
2932 * lwc1 f2,0(at)
2933 * lwc1 f3,4(at)
2934 * But, the resulting address is the same after relocation so why
2935 * generate the extra instruction?
2936 */
4032d3f0 2937 coproc = 1;
0dd2d296 2938 if (mips_isa >= 2)
670a50eb 2939 {
0dd2d296
ILT
2940 s = "ldc1";
2941 goto ld;
670a50eb 2942 }
0dd2d296
ILT
2943
2944 s = "lwc1";
2945 fmt = "T,o(b)";
0dd2d296
ILT
2946 goto ldd_std;
2947
2948 case M_S_DAB:
8358c818 2949 if (mips_isa >= 2)
8358c818 2950 {
0dd2d296
ILT
2951 s = "sdc1";
2952 goto st;
8358c818 2953 }
3d3c5039 2954
0dd2d296
ILT
2955 s = "swc1";
2956 fmt = "T,o(b)";
2957 coproc = 1;
2958 goto ldd_std;
3d3c5039
ILT
2959
2960 case M_LD_AB:
0dd2d296 2961 if (mips_isa >= 3)
670a50eb 2962 {
0dd2d296
ILT
2963 s = "ld";
2964 goto ld;
670a50eb 2965 }
0dd2d296
ILT
2966
2967 s = "lw";
2968 fmt = "t,o(b)";
2969 goto ldd_std;
2970
2971 case M_SD_AB:
2972 if (mips_isa >= 3)
670a50eb 2973 {
0dd2d296
ILT
2974 s = "sd";
2975 goto st;
670a50eb 2976 }
0dd2d296 2977
670a50eb 2978 s = "sw";
0dd2d296
ILT
2979 fmt = "t,o(b)";
2980
2981 ldd_std:
2982 if (offset_expr.X_op != O_symbol
2983 && offset_expr.X_op != O_constant)
670a50eb 2984 {
0dd2d296
ILT
2985 as_bad ("expression too complex");
2986 offset_expr.X_op = O_constant;
2987 }
2988
2989 /* Even on a big endian machine $fn comes before $fn+1. We have
2990 to adjust when loading from memory. We set coproc if we must
2991 load $fn+1 first. */
2992 if (byte_order == LITTLE_ENDIAN)
2993 coproc = 0;
2994
2995 if (mips_pic == 0
2996 || offset_expr.X_op == O_constant)
2997 {
2998 /* If this is a reference to a GP relative symbol, we want
2999 <op> $treg,<sym>($gp) (BFD_RELOC_MIPS_GPREL)
3000 <op> $treg+1,<sym>+4($gp) (BFD_RELOC_MIPS_GPREL)
3001 If we have a base register, we use this
3002 addu $at,$breg,$gp
3003 <op> $treg,<sym>($at) (BFD_RELOC_MIPS_GPREL)
3004 <op> $treg+1,<sym>+4($at) (BFD_RELOC_MIPS_GPREL)
3005 If this is not a GP relative symbol, we want
3006 lui $at,<sym> (BFD_RELOC_HI16_S)
3007 <op> $treg,<sym>($at) (BFD_RELOC_LO16)
3008 <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
3009 If there is a base register, we add it to $at after the
3010 lui instruction. If there is a constant, we always use
3011 the last case. */
3012 if (offset_expr.X_add_number != 0)
670a50eb 3013 {
0dd2d296
ILT
3014 p = NULL;
3015 used_at = 1;
670a50eb
ILT
3016 }
3017 else
0dd2d296
ILT
3018 {
3019 int off;
3020
3021 if (breg == 0)
3022 {
3023 frag_grow (20);
3024 tempreg = GP;
3025 off = 0;
3026 used_at = 0;
3027 }
3028 else
3029 {
3030 frag_grow (28);
3031 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
3032 mips_isa < 3 ? "addu" : "daddu",
3033 "d,v,t", AT, breg, GP);
3034 tempreg = AT;
3035 off = 4;
3036 used_at = 1;
3037 }
3038
3039 macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
3040 coproc ? treg + 1 : treg,
3041 (int) BFD_RELOC_MIPS_GPREL, tempreg);
3042 offset_expr.X_add_number += 4;
3043 macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
3044 coproc ? treg : treg + 1,
3045 (int) BFD_RELOC_MIPS_GPREL, tempreg);
3046 p = frag_var (rs_machine_dependent, 12 + off, 0,
3047 RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,
8197b589 3048 used_at && mips_noat),
0dd2d296
ILT
3049 offset_expr.X_add_symbol, (long) 0,
3050 (char *) NULL);
777ad64d
ILT
3051
3052 /* We just generated two relocs. When tc_gen_reloc
3053 handles this case, it will skip the first reloc and
3054 handle the second. The second reloc already has an
3055 extra addend of 4, which we added above. We must
3056 subtract it out, and then subtract another 4 to make
3057 the first reloc come out right. The second reloc
3058 will come out right because we are going to add 4 to
3059 offset_expr when we build its instruction below. */
3060 offset_expr.X_add_number -= 8;
0dd2d296
ILT
3061 offset_expr.X_op = O_constant;
3062 }
3063 macro_build_lui (p, &icnt, &offset_expr, AT);
3064 if (p != NULL)
3065 p += 4;
3066 if (breg != 0)
3067 {
3068 macro_build (p, &icnt, (expressionS *) NULL,
3069 mips_isa < 3 ? "addu" : "daddu",
3070 "d,v,t", AT, breg, AT);
3071 if (p != NULL)
3072 p += 4;
3073 }
3074 macro_build (p, &icnt, &offset_expr, s, fmt,
3075 coproc ? treg + 1 : treg,
3076 (int) BFD_RELOC_LO16, AT);
3077 if (p != NULL)
3078 p += 4;
3079 /* FIXME: How do we handle overflow here? */
3080 offset_expr.X_add_number += 4;
3081 macro_build (p, &icnt, &offset_expr, s, fmt,
3082 coproc ? treg : treg + 1,
3083 (int) BFD_RELOC_LO16, AT);
3084 }
670a50eb
ILT
3085 else
3086 {
0dd2d296
ILT
3087 int off;
3088
3089 /* If this is a reference to an external symbol, we want
3090 lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
3091 nop
3092 <op> $treg,0($at)
3093 <op> $treg+1,4($at)
3094 Otherwise we want
3095 lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
3096 nop
3097 <op> $treg,<sym>($at) (BFD_RELOC_LO16)
3098 <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
3099 If there is a base register we add it to $at before the
3100 lwc1 instructions. If there is a constant we include it
3101 in the lwc1 instructions. */
3102 used_at = 1;
3103 expr1.X_add_number = offset_expr.X_add_number;
3104 offset_expr.X_add_number = 0;
3105 if (expr1.X_add_number < -0x8000
3106 || expr1.X_add_number >= 0x8000 - 4)
3107 as_bad ("PIC code offset overflow (max 16 signed bits)");
3108 if (breg == 0)
3109 off = 0;
3110 else
3111 off = 4;
3112 frag_grow (16 + off);
3113 macro_build ((char *) NULL, &icnt, &offset_expr,
3114 mips_isa < 3 ? "lw" : "ld",
3115 "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
3116 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
670a50eb 3117 if (breg != 0)
0dd2d296 3118 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
6e8dda9c 3119 mips_isa < 3 ? "addu" : "daddu",
0dd2d296
ILT
3120 "d,v,t", AT, breg, AT);
3121 macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
3122 coproc ? treg + 1 : treg,
3123 (int) BFD_RELOC_LO16, AT);
3124 expr1.X_add_number += 4;
3125 macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
3126 coproc ? treg : treg + 1,
3127 (int) BFD_RELOC_LO16, AT);
3128 (void) frag_var (rs_machine_dependent, 0, 0,
3129 RELAX_ENCODE (0, 0, -16 - off, -8, 1, 0),
3130 offset_expr.X_add_symbol, (long) 0,
3131 (char *) NULL);
8358c818 3132 }
0dd2d296
ILT
3133
3134 if (! used_at)
3135 return;
3136
3137 break;
3138
3139 case M_LD_OB:
3140 s = "lw";
3141 goto sd_ob;
3142 case M_SD_OB:
3143 s = "sw";
3144 sd_ob:
3145 assert (mips_isa < 3);
3146 macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
3147 (int) BFD_RELOC_LO16, breg);
3148 offset_expr.X_add_number += 4;
3149 macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg + 1,
3150 (int) BFD_RELOC_LO16, breg);
670a50eb 3151 return;
917fae09
SS
3152#ifdef LOSING_COMPILER
3153 default:
3154 macro2 (ip);
3155 return;
3156 }
3157 if (mips_noat)
3158 as_warn ("Macro used $at after \".set noat\"");
3159}
3160
3161static void
3162macro2 (ip)
3163 struct mips_cl_insn *ip;
3164{
3165 register int treg, sreg, dreg, breg;
3166 int tempreg;
3167 int mask;
3168 int icnt = 0;
3169 int used_at;
3170 expressionS expr1;
3171 const char *s;
3172 const char *s2;
3173 const char *fmt;
3174 int likely = 0;
3175 int dbl = 0;
3176 int coproc = 0;
3177 offsetT maxnum;
3178 bfd_reloc_code_real_type r;
3179 char *p;
3180
3181 treg = (ip->insn_opcode >> 16) & 0x1f;
3182 dreg = (ip->insn_opcode >> 11) & 0x1f;
3183 sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
3184 mask = ip->insn_mo->mask;
3185
3186 expr1.X_op = O_constant;
3187 expr1.X_op_symbol = NULL;
3188 expr1.X_add_symbol = NULL;
3189 expr1.X_add_number = 1;
3190
3191 switch (mask)
3192 {
3193#endif /* LOSING_COMPILER */
3d3c5039 3194
8358c818
ILT
3195 case M_DMUL:
3196 dbl = 1;
3d3c5039 3197 case M_MUL:
0dd2d296 3198 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3199 dbl ? "dmultu" : "multu",
3200 "s,t", sreg, treg);
0dd2d296 3201 macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
670a50eb 3202 return;
3d3c5039 3203
8358c818
ILT
3204 case M_DMUL_I:
3205 dbl = 1;
3d3c5039 3206 case M_MUL_I:
8358c818
ILT
3207 /* The MIPS assembler some times generates shifts and adds. I'm
3208 not trying to be that fancy. GCC should do this for us
3209 anyway. */
6e8dda9c 3210 load_register (&icnt, AT, &imm_expr);
0dd2d296 3211 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3212 dbl ? "dmult" : "mult",
3213 "s,t", sreg, AT);
0dd2d296 3214 macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
670a50eb 3215 break;
3d3c5039 3216
8358c818
ILT
3217 case M_DMULO:
3218 dbl = 1;
3219 case M_MULO:
3220 mips_emit_delays ();
3221 ++mips_noreorder;
0dd2d296
ILT
3222 mips_any_noreorder = 1;
3223 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3224 dbl ? "dmult" : "mult",
3225 "s,t", sreg, treg);
0dd2d296
ILT
3226 macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
3227 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3228 dbl ? "dsra32" : "sra",
3229 "d,w,<", dreg, dreg, 31);
0dd2d296 3230 macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);
8358c818 3231 expr1.X_add_number = 8;
0dd2d296
ILT
3232 macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", dreg, AT);
3233 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
3234 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
8358c818 3235 --mips_noreorder;
0dd2d296 3236 macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
8358c818
ILT
3237 break;
3238
3239 case M_DMULOU:
3240 dbl = 1;
3241 case M_MULOU:
3242 mips_emit_delays ();
3243 ++mips_noreorder;
0dd2d296
ILT
3244 mips_any_noreorder = 1;
3245 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3246 dbl ? "dmultu" : "multu",
3247 "s,t", sreg, treg);
0dd2d296
ILT
3248 macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);
3249 macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
8358c818 3250 expr1.X_add_number = 8;
0dd2d296
ILT
3251 macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", AT, 0);
3252 macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
3253 macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
8358c818
ILT
3254 --mips_noreorder;
3255 break;
3256
3d3c5039 3257 case M_ROL:
0dd2d296
ILT
3258 macro_build ((char *) NULL, &icnt, NULL, "subu", "d,v,t", AT, 0, treg);
3259 macro_build ((char *) NULL, &icnt, NULL, "srlv", "d,t,s", AT, sreg, AT);
3260 macro_build ((char *) NULL, &icnt, NULL, "sllv", "d,t,s", dreg, sreg,
3261 treg);
3262 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
670a50eb 3263 break;
3d3c5039
ILT
3264
3265 case M_ROL_I:
0dd2d296 3266 macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", AT, sreg,
670a50eb 3267 imm_expr.X_add_number & 0x1f);
0dd2d296 3268 macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", dreg, sreg,
670a50eb 3269 (0 - imm_expr.X_add_number) & 0x1f);
0dd2d296 3270 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
670a50eb 3271 break;
3d3c5039
ILT
3272
3273 case M_ROR:
0dd2d296
ILT
3274 macro_build ((char *) NULL, &icnt, NULL, "subu", "d,v,t", AT, 0, treg);
3275 macro_build ((char *) NULL, &icnt, NULL, "sllv", "d,t,s", AT, sreg, AT);
3276 macro_build ((char *) NULL, &icnt, NULL, "srlv", "d,t,s", dreg, sreg,
3277 treg);
3278 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
670a50eb 3279 break;
3d3c5039
ILT
3280
3281 case M_ROR_I:
0dd2d296 3282 macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, sreg,
670a50eb 3283 imm_expr.X_add_number & 0x1f);
0dd2d296 3284 macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", dreg, sreg,
670a50eb 3285 (0 - imm_expr.X_add_number) & 0x1f);
0dd2d296 3286 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
670a50eb 3287 break;
3d3c5039
ILT
3288
3289 case M_S_DOB:
8358c818 3290 assert (mips_isa < 2);
9a7d824a
ILT
3291 /* Even on a big endian machine $fn comes before $fn+1. We have
3292 to adjust when storing to memory. */
0dd2d296 3293 macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",
9a7d824a 3294 byte_order == LITTLE_ENDIAN ? treg : treg + 1,
9226253a 3295 (int) BFD_RELOC_LO16, breg);
670a50eb 3296 offset_expr.X_add_number += 4;
0dd2d296 3297 macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",
9a7d824a 3298 byte_order == LITTLE_ENDIAN ? treg + 1 : treg,
9226253a 3299 (int) BFD_RELOC_LO16, breg);
670a50eb 3300 return;
3d3c5039 3301
3d3c5039 3302 case M_SEQ:
670a50eb 3303 if (sreg == 0)
0dd2d296
ILT
3304 macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
3305 treg, (int) BFD_RELOC_LO16);
670a50eb 3306 else if (treg == 0)
0dd2d296
ILT
3307 macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
3308 sreg, (int) BFD_RELOC_LO16);
670a50eb
ILT
3309 else
3310 {
0dd2d296
ILT
3311 macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
3312 sreg, treg);
3313 macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
3314 dreg, (int) BFD_RELOC_LO16);
3d3c5039 3315 }
670a50eb 3316 return;
3d3c5039
ILT
3317
3318 case M_SEQ_I:
670a50eb
ILT
3319 if (imm_expr.X_add_number == 0)
3320 {
0dd2d296
ILT
3321 macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
3322 sreg, (int) BFD_RELOC_LO16);
670a50eb 3323 return;
3d3c5039 3324 }
670a50eb
ILT
3325 if (sreg == 0)
3326 {
9a7d824a 3327 as_warn ("Instruction %s: result is always false",
6e8dda9c 3328 ip->insn_mo->name);
0dd2d296 3329 macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
670a50eb 3330 return;
3d3c5039 3331 }
6e8dda9c 3332 if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
670a50eb 3333 {
0dd2d296
ILT
3334 macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i", dreg,
3335 sreg, (int) BFD_RELOC_LO16);
670a50eb 3336 used_at = 0;
6e8dda9c
ILT
3337 }
3338 else if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number < 0)
3339 {
3340 imm_expr.X_add_number = -imm_expr.X_add_number;
0dd2d296 3341 macro_build ((char *) NULL, &icnt, &imm_expr,
6e8dda9c 3342 mips_isa < 3 ? "addiu" : "daddiu",
9226253a
ILT
3343 "t,r,j", dreg, sreg,
3344 (int) BFD_RELOC_LO16);
6e8dda9c
ILT
3345 used_at = 0;
3346 }
3347 else
3348 {
3349 load_register (&icnt, AT, &imm_expr);
0dd2d296
ILT
3350 macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
3351 sreg, AT);
670a50eb
ILT
3352 used_at = 1;
3353 }
0dd2d296 3354 macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg, dreg,
9226253a 3355 (int) BFD_RELOC_LO16);
670a50eb
ILT
3356 if (used_at)
3357 break;
3358 return;
3d3c5039
ILT
3359
3360 case M_SGE: /* sreg >= treg <==> not (sreg < treg) */
670a50eb
ILT
3361 s = "slt";
3362 goto sge;
3d3c5039 3363 case M_SGEU:
670a50eb 3364 s = "sltu";
3d3c5039 3365 sge:
0dd2d296
ILT
3366 macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, sreg, treg);
3367 macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
9226253a 3368 (int) BFD_RELOC_LO16);
670a50eb 3369 return;
3d3c5039 3370
670a50eb 3371 case M_SGE_I: /* sreg >= I <==> not (sreg < I) */
3d3c5039 3372 case M_SGEU_I:
6e8dda9c 3373 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
670a50eb 3374 {
0dd2d296 3375 macro_build ((char *) NULL, &icnt, &expr1,
6e8dda9c 3376 mask == M_SGE_I ? "slti" : "sltiu",
9226253a 3377 "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
670a50eb
ILT
3378 used_at = 0;
3379 }
3380 else
3381 {
6e8dda9c 3382 load_register (&icnt, AT, &imm_expr);
0dd2d296 3383 macro_build ((char *) NULL, &icnt, NULL,
6e8dda9c
ILT
3384 mask == M_SGE_I ? "slt" : "sltu",
3385 "d,v,t", dreg, sreg, AT);
670a50eb
ILT
3386 used_at = 1;
3387 }
0dd2d296 3388 macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
9226253a 3389 (int) BFD_RELOC_LO16);
670a50eb
ILT
3390 if (used_at)
3391 break;
3392 return;
3d3c5039
ILT
3393
3394 case M_SGT: /* sreg > treg <==> treg < sreg */
670a50eb
ILT
3395 s = "slt";
3396 goto sgt;
3d3c5039 3397 case M_SGTU:
670a50eb 3398 s = "sltu";
3d3c5039 3399 sgt:
0dd2d296 3400 macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, treg, sreg);
670a50eb 3401 return;
3d3c5039 3402
670a50eb
ILT
3403 case M_SGT_I: /* sreg > I <==> I < sreg */
3404 s = "slt";
3405 goto sgti;
3d3c5039 3406 case M_SGTU_I:
670a50eb 3407 s = "sltu";
3d3c5039 3408 sgti:
6e8dda9c 3409 load_register (&icnt, AT, &imm_expr);
0dd2d296 3410 macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, AT, sreg);
670a50eb 3411 break;
3d3c5039 3412
670a50eb
ILT
3413 case M_SLE: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
3414 s = "slt";
3415 goto sle;
3d3c5039 3416 case M_SLEU:
670a50eb 3417 s = "sltu";
3d3c5039 3418 sle:
0dd2d296
ILT
3419 macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, treg, sreg);
3420 macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
9226253a 3421 (int) BFD_RELOC_LO16);
670a50eb 3422 return;
3d3c5039 3423
670a50eb
ILT
3424 case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
3425 s = "slt";
3426 goto slei;
3d3c5039 3427 case M_SLEU_I:
670a50eb 3428 s = "sltu";
3d3c5039 3429 slei:
6e8dda9c 3430 load_register (&icnt, AT, &imm_expr);
0dd2d296
ILT
3431 macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, AT, sreg);
3432 macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
9226253a 3433 (int) BFD_RELOC_LO16);
670a50eb 3434 break;
3d3c5039
ILT
3435
3436 case M_SLT_I:
6e8dda9c 3437 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
670a50eb 3438 {
0dd2d296
ILT
3439 macro_build ((char *) NULL, &icnt, &imm_expr, "slti", "t,r,j",
3440 dreg, sreg, (int) BFD_RELOC_LO16);
670a50eb 3441 return;
3d3c5039 3442 }
6e8dda9c 3443 load_register (&icnt, AT, &imm_expr);
0dd2d296 3444 macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", dreg, sreg, AT);
670a50eb 3445 break;
3d3c5039
ILT
3446
3447 case M_SLTU_I:
6e8dda9c 3448 if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
670a50eb 3449 {
0dd2d296
ILT
3450 macro_build ((char *) NULL, &icnt, &imm_expr, "sltiu", "t,r,j",
3451 dreg, sreg, (int) BFD_RELOC_LO16);
670a50eb 3452 return;
3d3c5039 3453 }
6e8dda9c 3454 load_register (&icnt, AT, &imm_expr);
0dd2d296
ILT
3455 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, sreg,
3456 AT);
670a50eb 3457 break;
3d3c5039
ILT
3458
3459 case M_SNE:
670a50eb 3460 if (sreg == 0)
0dd2d296
ILT
3461 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
3462 treg);
670a50eb 3463 else if (treg == 0)
0dd2d296
ILT
3464 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
3465 sreg);
670a50eb
ILT
3466 else
3467 {
0dd2d296
ILT
3468 macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
3469 sreg, treg);
3470 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
3471 dreg);
3d3c5039 3472 }
670a50eb 3473 return;
3d3c5039
ILT
3474
3475 case M_SNE_I:
670a50eb
ILT
3476 if (imm_expr.X_add_number == 0)
3477 {
0dd2d296
ILT
3478 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
3479 sreg);
670a50eb 3480 return;
3d3c5039 3481 }
670a50eb
ILT
3482 if (sreg == 0)
3483 {
9a7d824a 3484 as_warn ("Instruction %s: result is always true",
6e8dda9c 3485 ip->insn_mo->name);
0dd2d296 3486 macro_build ((char *) NULL, &icnt, &expr1,
6e8dda9c 3487 mips_isa < 3 ? "addiu" : "daddiu",
9226253a 3488 "t,r,j", dreg, 0, (int) BFD_RELOC_LO16);
670a50eb 3489 return;
3d3c5039 3490 }
6e8dda9c 3491 if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
670a50eb 3492 {
0dd2d296
ILT
3493 macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i",
3494 dreg, sreg, (int) BFD_RELOC_LO16);
670a50eb 3495 used_at = 0;
6e8dda9c
ILT
3496 }
3497 else if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number < 0)
3498 {
3499 imm_expr.X_add_number = -imm_expr.X_add_number;
0dd2d296 3500 macro_build ((char *) NULL, &icnt, &imm_expr,
6e8dda9c 3501 mips_isa < 3 ? "addiu" : "daddiu",
9226253a 3502 "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
6e8dda9c
ILT
3503 used_at = 0;
3504 }
3505 else
3506 {
3507 load_register (&icnt, AT, &imm_expr);
0dd2d296
ILT
3508 macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
3509 sreg, AT);
670a50eb
ILT
3510 used_at = 1;
3511 }
0dd2d296 3512 macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);
670a50eb
ILT
3513 if (used_at)
3514 break;
3515 return;
3d3c5039 3516
8358c818
ILT
3517 case M_DSUB_I:
3518 dbl = 1;
3d3c5039 3519 case M_SUB_I:
6e8dda9c 3520 if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number <= 0x8000)
670a50eb
ILT
3521 {
3522 imm_expr.X_add_number = -imm_expr.X_add_number;
0dd2d296 3523 macro_build ((char *) NULL, &icnt, &imm_expr,
8358c818 3524 dbl ? "daddi" : "addi",
9226253a 3525 "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
670a50eb 3526 return;
3d3c5039 3527 }
6e8dda9c 3528 load_register (&icnt, AT, &imm_expr);
0dd2d296 3529 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3530 dbl ? "dsub" : "sub",
3531 "d,v,t", dreg, sreg, AT);
670a50eb 3532 break;
3d3c5039 3533
8358c818
ILT
3534 case M_DSUBU_I:
3535 dbl = 1;
3d3c5039 3536 case M_SUBU_I:
6e8dda9c 3537 if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number <= 0x8000)
670a50eb
ILT
3538 {
3539 imm_expr.X_add_number = -imm_expr.X_add_number;
0dd2d296 3540 macro_build ((char *) NULL, &icnt, &imm_expr,
8358c818 3541 dbl ? "daddiu" : "addiu",
9226253a 3542 "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
670a50eb 3543 return;
3d3c5039 3544 }
6e8dda9c 3545 load_register (&icnt, AT, &imm_expr);
0dd2d296 3546 macro_build ((char *) NULL, &icnt, NULL,
8358c818
ILT
3547 dbl ? "dsubu" : "subu",
3548 "d,v,t", dreg, sreg, AT);
3549 break;
3550
3551 case M_TEQ_I:
3552 s = "teq";
3553 goto trap;
3554 case M_TGE_I:
3555 s = "tge";
3556 goto trap;
3557 case M_TGEU_I:
3558 s = "tgeu";
3559 goto trap;
3560 case M_TLT_I:
3561 s = "tlt";
3562 goto trap;
3563 case M_TLTU_I:
3564 s = "tltu";
3565 goto trap;
3566 case M_TNE_I:
3567 s = "tne";
3568 trap:
6e8dda9c 3569 load_register (&icnt, AT, &imm_expr);
0dd2d296 3570 macro_build ((char *) NULL, &icnt, NULL, s, "s,t", sreg, AT);
670a50eb 3571 break;
3d3c5039
ILT
3572
3573 case M_TRUNCWD:
3574 case M_TRUNCWS:
8358c818 3575 assert (mips_isa < 2);
670a50eb
ILT
3576 sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
3577 dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
3578
3579 /*
3580 * Is the double cfc1 instruction a bug in the mips assembler;
3581 * or is there a reason for it?
3582 */
becfe05e
ILT
3583 mips_emit_delays ();
3584 ++mips_noreorder;
0dd2d296
ILT
3585 mips_any_noreorder = 1;
3586 macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
3587 macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
3588 macro_build ((char *) NULL, &icnt, NULL, "nop", "");
670a50eb 3589 expr1.X_add_number = 3;
0dd2d296 3590 macro_build ((char *) NULL, &icnt, &expr1, "ori", "t,r,i", AT, treg,
9226253a 3591 (int) BFD_RELOC_LO16);
670a50eb 3592 expr1.X_add_number = 2;
0dd2d296 3593 macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", AT, AT,
9226253a 3594 (int) BFD_RELOC_LO16);
0dd2d296
ILT
3595 macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", AT, 31);
3596 macro_build ((char *) NULL, &icnt, NULL, "nop", "");
3597 macro_build ((char *) NULL, &icnt, NULL,
670a50eb 3598 mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg);
0dd2d296
ILT
3599 macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", treg, 31);
3600 macro_build ((char *) NULL, &icnt, NULL, "nop", "");
becfe05e 3601 --mips_noreorder;
670a50eb 3602 break;
3d3c5039
ILT
3603
3604 case M_ULH:
670a50eb
ILT
3605 s = "lb";
3606 goto ulh;
3d3c5039 3607 case M_ULHU:
670a50eb 3608 s = "lbu";
3d3c5039 3609 ulh:
670a50eb
ILT
3610 /* avoid load delay */
3611 offset_expr.X_add_number += 1;
0dd2d296 3612 macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
9226253a 3613 (int) BFD_RELOC_LO16, breg);
670a50eb 3614 offset_expr.X_add_number -= 1;
0dd2d296 3615 macro_build ((char *) NULL, &icnt, &offset_expr, "lbu", "t,o(b)", AT,
9226253a 3616 (int) BFD_RELOC_LO16, breg);
0dd2d296
ILT
3617 macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, treg, 8);
3618 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, treg, AT);
670a50eb 3619 break;
3d3c5039
ILT
3620
3621 case M_ULW:
670a50eb
ILT
3622 /* does this work on a big endian machine? */
3623 offset_expr.X_add_number += 3;
0dd2d296 3624 macro_build ((char *) NULL, &icnt, &offset_expr, "lwl", "t,o(b)", treg,
9226253a 3625 (int) BFD_RELOC_LO16, breg);
670a50eb 3626 offset_expr.X_add_number -= 3;
0dd2d296 3627 macro_build ((char *) NULL, &icnt, &offset_expr, "lwr", "t,o(b)", treg,
9226253a 3628 (int) BFD_RELOC_LO16, breg);
670a50eb 3629 return;
3d3c5039
ILT
3630
3631 case M_ULH_A:
3632 case M_ULHU_A:
3633 case M_ULW_A:
0dd2d296 3634 load_address (&icnt, AT, &offset_expr);
670a50eb
ILT
3635 if (mask == M_ULW_A)
3636 {
3637 expr1.X_add_number = 3;
0dd2d296 3638 macro_build ((char *) NULL, &icnt, &expr1, "lwl", "t,o(b)", treg,
9226253a 3639 (int) BFD_RELOC_LO16, AT);
0dd2d296
ILT
3640 expr1.X_add_number = 0;
3641 macro_build ((char *) NULL, &icnt, &expr1, "lwr", "t,o(b)", treg,
9226253a 3642 (int) BFD_RELOC_LO16, AT);
670a50eb
ILT
3643 }
3644 else
3645 {
0dd2d296 3646 macro_build ((char *) NULL, &icnt, &expr1,
9226253a
ILT
3647 mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg,
3648 (int) BFD_RELOC_LO16, AT);
0dd2d296
ILT
3649 expr1.X_add_number = 0;
3650 macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
9226253a 3651 (int) BFD_RELOC_LO16, AT);
0dd2d296
ILT
3652 macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
3653 treg, 8);
3654 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
3655 treg, AT);
670a50eb
ILT
3656 }
3657 break;
3d3c5039
ILT
3658
3659 case M_USH:
0dd2d296 3660 macro_build ((char *) NULL, &icnt, &offset_expr, "sb", "t,o(b)", treg,
9226253a 3661 (int) BFD_RELOC_LO16, breg);
0dd2d296 3662 macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, treg, 8);
670a50eb 3663 offset_expr.X_add_number += 1;
0dd2d296 3664 macro_build ((char *) NULL, &icnt, &offset_expr, "sb", "t,o(b)", AT,
9226253a 3665 (int) BFD_RELOC_LO16, breg);
670a50eb 3666 break;
3d3c5039
ILT
3667
3668 case M_USW:
670a50eb 3669 offset_expr.X_add_number += 3;
0dd2d296 3670 macro_build ((char *) NULL, &icnt, &offset_expr, "swl", "t,o(b)", treg,
9226253a 3671 (int) BFD_RELOC_LO16, breg);
670a50eb 3672 offset_expr.X_add_number -= 3;
0dd2d296 3673 macro_build ((char *) NULL, &icnt, &offset_expr, "swr", "t,o(b)", treg,
9226253a 3674 (int) BFD_RELOC_LO16, breg);
670a50eb 3675 return;
3d3c5039
ILT
3676
3677 case M_USH_A:
3678 case M_USW_A:
0dd2d296 3679 load_address (&icnt, AT, &offset_expr);
670a50eb
ILT
3680 if (mask == M_USW_A)
3681 {
3682 expr1.X_add_number = 3;
0dd2d296 3683 macro_build ((char *) NULL, &icnt, &expr1, "swl", "t,o(b)", treg,
9226253a 3684 (int) BFD_RELOC_LO16, AT);
670a50eb 3685 expr1.X_add_number = 0;
0dd2d296 3686 macro_build ((char *) NULL, &icnt, &expr1, "swr", "t,o(b)", treg,
9226253a 3687 (int) BFD_RELOC_LO16, AT);
670a50eb
ILT
3688 }
3689 else
3690 {
3691 expr1.X_add_number = 0;
0dd2d296 3692 macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
9226253a 3693 (int) BFD_RELOC_LO16, AT);
0dd2d296
ILT
3694 macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg,
3695 treg, 8);
670a50eb 3696 expr1.X_add_number = 1;
0dd2d296 3697 macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
9226253a 3698 (int) BFD_RELOC_LO16, AT);
670a50eb 3699 expr1.X_add_number = 0;
0dd2d296 3700 macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
9226253a 3701 (int) BFD_RELOC_LO16, AT);
0dd2d296
ILT
3702 macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
3703 treg, 8);
3704 macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
3705 treg, AT);
670a50eb
ILT
3706 }
3707 break;
3d3c5039
ILT
3708
3709 default:
670a50eb 3710 as_bad ("Macro %s not implemented yet", ip->insn_mo->name);
8358c818 3711 break;
3d3c5039 3712 }
670a50eb
ILT
3713 if (mips_noat)
3714 as_warn ("Macro used $at after \".set noat\"");
3d3c5039
ILT
3715}
3716
3717
3718/*
3719This routine assembles an instruction into its binary format. As a side
3720effect it sets one of the global variables imm_reloc or offset_reloc to the
3721type of relocation to do if one of the operands is an address expression.
3722*/
3723static void
3724mips_ip (str, ip)
3725 char *str;
3726 struct mips_cl_insn *ip;
3727{
670a50eb
ILT
3728 char *s;
3729 const char *args;
3730 char c;
3731 struct mips_opcode *insn;
3732 char *argsStart;
3733 unsigned int regno;
3734 unsigned int lastregno = 0;
3735 char *s_reset;
3736
3737 insn_error = NULL;
3738
3739 for (s = str; islower (*s) || (*s >= '0' && *s <= '3') || *s == '.'; ++s)
3740 continue;
3741 switch (*s)
3742 {
3d3c5039 3743 case '\0':
670a50eb 3744 break;
3d3c5039
ILT
3745
3746 case ' ':
670a50eb
ILT
3747 *s++ = '\0';
3748 break;
3d3c5039
ILT
3749
3750 default:
670a50eb
ILT
3751 as_warn ("Unknown opcode: `%s'", str);
3752 exit (1);
3d3c5039 3753 }
670a50eb
ILT
3754 if ((insn = (struct mips_opcode *) hash_find (op_hash, str)) == NULL)
3755 {
3756 as_warn ("`%s' not in hash table.", str);
3757 insn_error = "ERROR: Unrecognized opcode";
3758 return;
3d3c5039 3759 }
670a50eb
ILT
3760 argsStart = s;
3761 for (;;)
3762 {
8358c818
ILT
3763 int insn_isa;
3764
670a50eb 3765 assert (strcmp (insn->name, str) == 0);
8358c818
ILT
3766
3767 if (insn->pinfo == INSN_MACRO)
3768 insn_isa = insn->match;
3769 else if (insn->pinfo & INSN_ISA2)
3770 insn_isa = 2;
3771 else if (insn->pinfo & INSN_ISA3)
3772 insn_isa = 3;
3773 else
3774 insn_isa = 1;
3775
3776 if (insn_isa > mips_isa)
3777 {
3778 if (insn + 1 < &mips_opcodes[NUMOPCODES]
3779 && strcmp (insn->name, insn[1].name) == 0)
3780 {
3781 ++insn;
3782 continue;
3783 }
3784 insn_error = "ERROR: instruction not supported on this processor";
3785 return;
3786 }
3787
670a50eb
ILT
3788 ip->insn_mo = insn;
3789 ip->insn_opcode = insn->match;
3790 for (args = insn->args;; ++args)
3791 {
3792 if (*s == ' ')
3793 ++s;
3794 switch (*args)
3795 {
3796 case '\0': /* end of args */
3797 if (*s == '\0')
3798 return;
3799 break;
3d3c5039
ILT
3800
3801 case ',':
670a50eb
ILT
3802 if (*s++ == *args)
3803 continue;
3804 s--;
3805 switch (*++args)
3806 {
3d3c5039
ILT
3807 case 'r':
3808 case 'v':
670a50eb
ILT
3809 ip->insn_opcode |= lastregno << 21;
3810 continue;
3d3c5039
ILT
3811
3812 case 'w':
3813 case 'W':
670a50eb
ILT
3814 ip->insn_opcode |= lastregno << 16;
3815 continue;
3d3c5039
ILT
3816
3817 case 'V':
670a50eb
ILT
3818 ip->insn_opcode |= lastregno << 11;
3819 continue;
3d3c5039 3820 }
670a50eb 3821 break;
3d3c5039
ILT
3822
3823 case '(':
670a50eb
ILT
3824 /* handle optional base register.
3825 Either the base register is omitted or
3826 we must have a left paren. */
3827 /* this is dependent on the next operand specifier
3828 is a 'b' for base register */
3829 assert (args[1] == 'b');
3830 if (*s == '\0')
3831 return;
3d3c5039 3832
670a50eb
ILT
3833 case ')': /* these must match exactly */
3834 if (*s++ == *args)
3d3c5039 3835 continue;
670a50eb
ILT
3836 break;
3837
3838 case '<': /* must be at least one digit */
3839 /*
3840 * According to the manual, if the shift amount is greater
3841 * than 31 or less than 0 the the shift amount should be
3842 * mod 32. In reality the mips assembler issues an error.
9226253a 3843 * We issue a warning and mask out all but the low 5 bits.
670a50eb
ILT
3844 */
3845 my_getExpression (&imm_expr, s);
3846 check_absolute_expr (ip, &imm_expr);
3847 if ((unsigned long) imm_expr.X_add_number > 31)
3848 {
58d4951d
ILT
3849 as_warn ("Improper shift amount (%ld)",
3850 (long) imm_expr.X_add_number);
9226253a 3851 imm_expr.X_add_number = imm_expr.X_add_number & 0x1f;
670a50eb
ILT
3852 }
3853 ip->insn_opcode |= imm_expr.X_add_number << 6;
5ac34ac3 3854 imm_expr.X_op = O_absent;
670a50eb
ILT
3855 s = expr_end;
3856 continue;
3857
56c96faa
ILT
3858 case '>': /* shift amount minus 32 */
3859 my_getExpression (&imm_expr, s);
3860 check_absolute_expr (ip, &imm_expr);
3861 if ((unsigned long) imm_expr.X_add_number < 32
3862 || (unsigned long) imm_expr.X_add_number > 63)
3863 break;
3864 ip->insn_opcode |= (imm_expr.X_add_number - 32) << 6;
3865 imm_expr.X_op = O_absent;
3866 s = expr_end;
3867 continue;
3868
9226253a
ILT
3869 case 'k': /* cache code */
3870 my_getExpression (&imm_expr, s);
3871 check_absolute_expr (ip, &imm_expr);
3872 if ((unsigned long) imm_expr.X_add_number > 31)
3873 {
3874 as_warn ("Invalid cahce opcode (%lu)",
3875 (unsigned long) imm_expr.X_add_number);
3876 imm_expr.X_add_number &= 0x1f;
3877 }
3878 ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CACHE;
3879 imm_expr.X_op = O_absent;
3880 s = expr_end;
3881 continue;
3882
670a50eb
ILT
3883 case 'c': /* break code */
3884 my_getExpression (&imm_expr, s);
3885 check_absolute_expr (ip, &imm_expr);
3886 if ((unsigned) imm_expr.X_add_number > 1023)
58d4951d
ILT
3887 as_warn ("Illegal break code (%ld)",
3888 (long) imm_expr.X_add_number);
670a50eb 3889 ip->insn_opcode |= imm_expr.X_add_number << 16;
5ac34ac3 3890 imm_expr.X_op = O_absent;
670a50eb
ILT
3891 s = expr_end;
3892 continue;
3893
918692a5
ILT
3894 case 'B': /* syscall code */
3895 my_getExpression (&imm_expr, s);
3896 check_absolute_expr (ip, &imm_expr);
3897 if ((unsigned) imm_expr.X_add_number > 0xfffff)
58d4951d
ILT
3898 as_warn ("Illegal syscall code (%ld)",
3899 (long) imm_expr.X_add_number);
918692a5 3900 ip->insn_opcode |= imm_expr.X_add_number << 6;
5ac34ac3 3901 imm_expr.X_op = O_absent;
918692a5
ILT
3902 s = expr_end;
3903 continue;
3904
0aa07269
ILT
3905 case 'C': /* Coprocessor code */
3906 my_getExpression (&imm_expr, s);
3907 check_absolute_expr (ip, &imm_expr);
3908 if ((unsigned long) imm_expr.X_add_number >= (1<<25))
3909 {
58d4951d
ILT
3910 as_warn ("Coproccesor code > 25 bits (%ld)",
3911 (long) imm_expr.X_add_number);
0aa07269
ILT
3912 imm_expr.X_add_number &= ((1<<25) - 1);
3913 }
3914 ip->insn_opcode |= imm_expr.X_add_number;
3915 imm_expr.X_op = O_absent;
3916 s = expr_end;
3917 continue;
3918
670a50eb
ILT
3919 case 'b': /* base register */
3920 case 'd': /* destination register */
3921 case 's': /* source register */
3922 case 't': /* target register */
3923 case 'r': /* both target and source */
3924 case 'v': /* both dest and source */
3925 case 'w': /* both dest and target */
918692a5
ILT
3926 case 'E': /* coprocessor target register */
3927 case 'G': /* coprocessor destination register */
8358c818 3928 case 'x': /* ignore register name */
ff3a5c18 3929 case 'z': /* must be zero register */
670a50eb
ILT
3930 s_reset = s;
3931 if (s[0] == '$')
3932 {
3933 if (isdigit (s[1]))
3934 {
3935 ++s;
3936 regno = 0;
3937 do
3938 {
3939 regno *= 10;
3940 regno += *s - '0';
3941 ++s;
3942 }
3943 while (isdigit (*s));
0aa07269
ILT
3944 if (regno > 31)
3945 as_bad ("Invalid register number (%d)", regno);
670a50eb 3946 }
0dd2d296
ILT
3947 else if (*args == 'E' || *args == 'G')
3948 goto notreg;
3949 else
670a50eb 3950 {
0aa07269
ILT
3951 if (s[1] == 'f' && s[2] == 'p')
3952 {
3953 s += 3;
9226253a 3954 regno = FP;
0aa07269
ILT
3955 }
3956 else if (s[1] == 's' && s[2] == 'p')
3957 {
3958 s += 3;
9226253a 3959 regno = SP;
0aa07269
ILT
3960 }
3961 else if (s[1] == 'g' && s[2] == 'p')
3962 {
3963 s += 3;
9226253a 3964 regno = GP;
0aa07269
ILT
3965 }
3966 else if (s[1] == 'a' && s[2] == 't')
3967 {
3968 s += 3;
9226253a 3969 regno = AT;
0aa07269
ILT
3970 }
3971 else
3972 goto notreg;
670a50eb 3973 }
13fe1379
ILT
3974 if (regno == AT && ! mips_noat)
3975 as_warn ("Used $at without \".set noat\"");
670a50eb
ILT
3976 c = *args;
3977 if (*s == ' ')
3978 s++;
3979 if (args[1] != *s)
3980 {
3981 if (c == 'r' || c == 'v' || c == 'w')
3982 {
3983 regno = lastregno;
3984 s = s_reset;
3985 args++;
3986 }
3987 }
ff3a5c18
ILT
3988 /* 'z' only matches $0. */
3989 if (c == 'z' && regno != 0)
3990 break;
670a50eb
ILT
3991 switch (c)
3992 {
3d3c5039
ILT
3993 case 'r':
3994 case 's':
3995 case 'v':
3996 case 'b':
670a50eb
ILT
3997 ip->insn_opcode |= regno << 21;
3998 break;
3d3c5039 3999 case 'd':
918692a5 4000 case 'G':
670a50eb
ILT
4001 ip->insn_opcode |= regno << 11;
4002 break;
3d3c5039
ILT
4003 case 'w':
4004 case 't':
918692a5 4005 case 'E':
670a50eb 4006 ip->insn_opcode |= regno << 16;
8358c818
ILT
4007 break;
4008 case 'x':
4009 /* This case exists because on the r3000 trunc
4010 expands into a macro which requires a gp
4011 register. On the r6000 or r4000 it is
4012 assembled into a single instruction which
4013 ignores the register. Thus the insn version
4014 is MIPS_ISA2 and uses 'x', and the macro
4015 version is MIPS_ISA1 and uses 't'. */
4016 break;
ff3a5c18
ILT
4017 case 'z':
4018 /* This case is for the div instruction, which
4019 acts differently if the destination argument
4020 is $0. This only matches $0, and is checked
4021 outside the switch. */
4022 break;
3d3c5039 4023 }
670a50eb
ILT
4024 lastregno = regno;
4025 continue;
3d3c5039
ILT
4026 }
4027 notreg:
670a50eb
ILT
4028 switch (*args++)
4029 {
3d3c5039
ILT
4030 case 'r':
4031 case 'v':
670a50eb
ILT
4032 ip->insn_opcode |= lastregno << 21;
4033 continue;
3d3c5039 4034 case 'w':
670a50eb
ILT
4035 ip->insn_opcode |= lastregno << 16;
4036 continue;
3d3c5039 4037 }
670a50eb 4038 break;
3d3c5039 4039
670a50eb
ILT
4040 case 'D': /* floating point destination register */
4041 case 'S': /* floating point source register */
4042 case 'T': /* floating point target register */
3d3c5039
ILT
4043 case 'V':
4044 case 'W':
670a50eb
ILT
4045 s_reset = s;
4046 if (s[0] == '$' && s[1] == 'f' && isdigit (s[2]))
4047 {
4048 s += 2;
4049 regno = 0;
4050 do
4051 {
4052 regno *= 10;
4053 regno += *s - '0';
4054 ++s;
4055 }
4056 while (isdigit (*s));
4057
4058 if (regno > 31)
4059 as_bad ("Invalid float register number (%d)", regno);
4060
9226253a
ILT
4061 if ((regno & 1) != 0
4062 && mips_isa < 3
4063 && ! (strcmp (str, "mtc1") == 0 ||
4064 strcmp (str, "mfc1") == 0 ||
4065 strcmp (str, "lwc1") == 0 ||
4066 strcmp (str, "swc1") == 0))
670a50eb
ILT
4067 as_warn ("Float register should be even, was %d",
4068 regno);
4069
4070 c = *args;
4071 if (*s == ' ')
4072 s++;
4073 if (args[1] != *s)
4074 {
4075 if (c == 'V' || c == 'W')
4076 {
4077 regno = lastregno;
4078 s = s_reset;
4079 args++;
3d3c5039
ILT
4080 }
4081 }
670a50eb
ILT
4082 switch (c)
4083 {
3d3c5039 4084 case 'D':
670a50eb
ILT
4085 ip->insn_opcode |= regno << 6;
4086 break;
3d3c5039
ILT
4087 case 'V':
4088 case 'S':
670a50eb
ILT
4089 ip->insn_opcode |= regno << 11;
4090 break;
3d3c5039
ILT
4091 case 'W':
4092 case 'T':
670a50eb 4093 ip->insn_opcode |= regno << 16;
3d3c5039 4094 }
670a50eb
ILT
4095 lastregno = regno;
4096 continue;
3d3c5039 4097 }
670a50eb
ILT
4098 switch (*args++)
4099 {
3d3c5039 4100 case 'V':
670a50eb
ILT
4101 ip->insn_opcode |= lastregno << 11;
4102 continue;
3d3c5039 4103 case 'W':
670a50eb
ILT
4104 ip->insn_opcode |= lastregno << 16;
4105 continue;
3d3c5039 4106 }
670a50eb 4107 break;
3d3c5039
ILT
4108
4109 case 'I':
670a50eb
ILT
4110 my_getExpression (&imm_expr, s);
4111 check_absolute_expr (ip, &imm_expr);
4112 s = expr_end;
4113 continue;
3d3c5039
ILT
4114
4115 case 'A':
670a50eb
ILT
4116 my_getExpression (&offset_expr, s);
4117 imm_reloc = BFD_RELOC_32;
4118 s = expr_end;
4119 continue;
3d3c5039
ILT
4120
4121 case 'F':
19ed8960
ILT
4122 case 'L':
4123 case 'f':
4124 case 'l':
4125 {
4126 int f64;
4127 char *save_in;
4128 char *err;
4129 unsigned char temp[8];
604633ae
ILT
4130 int len;
4131 unsigned int length;
19ed8960
ILT
4132 segT seg;
4133 subsegT subseg;
4134 char *p;
4135
4136 /* These only appear as the last operand in an
4137 instruction, and every instruction that accepts
4138 them in any variant accepts them in all variants.
4139 This means we don't have to worry about backing out
4140 any changes if the instruction does not match.
4141
4142 The difference between them is the size of the
4143 floating point constant and where it goes. For 'F'
4144 and 'L' the constant is 64 bits; for 'f' and 'l' it
4145 is 32 bits. Where the constant is placed is based
4146 on how the MIPS assembler does things:
4147 F -- .rdata
4148 L -- .lit8
4149 f -- immediate value
4150 l -- .lit4
0dd2d296
ILT
4151
4152 When generating PIC code, we do not use the .lit8
4153 or .lit4 sections at all, in order to reserve the
4154 entire global offset table. */
19ed8960
ILT
4155
4156 f64 = *args == 'F' || *args == 'L';
4157
4158 save_in = input_line_pointer;
4159 input_line_pointer = s;
604633ae
ILT
4160 err = md_atof (f64 ? 'd' : 'f', (char *) temp, &len);
4161 length = len;
19ed8960
ILT
4162 s = input_line_pointer;
4163 input_line_pointer = save_in;
4164 if (err != NULL && *err != '\0')
4165 {
4166 as_bad ("Bad floating point constant: %s", err);
4167 memset (temp, '\0', sizeof temp);
4168 length = f64 ? 8 : 4;
4169 }
4170
4171 assert (length == (f64 ? 8 : 4));
4172
0dd2d296
ILT
4173 if (*args == 'f'
4174 || (mips_pic != 0 && *args == 'l'))
19ed8960
ILT
4175 {
4176 imm_expr.X_op = O_constant;
4177 if (byte_order == LITTLE_ENDIAN)
4178 imm_expr.X_add_number =
4179 (((((((int) temp[3] << 8)
4180 | temp[2]) << 8)
4181 | temp[1]) << 8)
4182 | temp[0]);
4183 else
4184 imm_expr.X_add_number =
4185 (((((((int) temp[0] << 8)
4186 | temp[1]) << 8)
4187 | temp[2]) << 8)
4188 | temp[3]);
4189 }
4190 else
4191 {
0dd2d296
ILT
4192 const char *newname;
4193 segT new_seg;
4194
19ed8960
ILT
4195 /* Switch to the right section. */
4196 seg = now_seg;
4197 subseg = now_subseg;
4198 switch (*args)
4199 {
0dd2d296 4200 default: /* unused default case avoids warnings. */
19ed8960 4201 case 'L':
0dd2d296
ILT
4202 newname = (mips_pic == 0 ? ".lit8" : ".rdata");
4203 break;
4204 case 'F':
4205 newname = ".rdata";
19ed8960
ILT
4206 break;
4207 case 'l':
0dd2d296
ILT
4208 assert (mips_pic == 0);
4209 newname = ".lit4";
19ed8960
ILT
4210 break;
4211 }
0dd2d296
ILT
4212 new_seg = subseg_new (newname, (subsegT) 0);
4213#ifdef OBJ_ELF
4214 bfd_set_section_alignment (stdoutput, new_seg, 4);
4215#endif
19ed8960
ILT
4216 if (seg == now_seg)
4217 as_bad ("Can't use floating point insn in this section");
4218
4219 /* Set the argument to the current address in the
6e8dda9c 4220 section. */
19ed8960
ILT
4221 offset_expr.X_op = O_symbol;
4222 offset_expr.X_add_symbol =
4223 symbol_new ("L0\001", now_seg,
4224 (valueT) frag_now_fix (), frag_now);
4225 offset_expr.X_add_number = 0;
4226
4227 /* Put the floating point number into the section. */
604633ae 4228 p = frag_more ((int) length);
19ed8960
ILT
4229 memcpy (p, temp, length);
4230
4231 /* Switch back to the original section. */
4232 subseg_set (seg, subseg);
4233 }
4234 }
670a50eb
ILT
4235 continue;
4236
4237 case 'i': /* 16 bit unsigned immediate */
4238 case 'j': /* 16 bit signed immediate */
4239 imm_reloc = BFD_RELOC_LO16;
4240 c = my_getSmallExpression (&imm_expr, s);
4241 if (c)
4242 {
4243 if (c != 'l')
4244 {
5ac34ac3 4245 if (imm_expr.X_op == O_constant)
670a50eb
ILT
4246 imm_expr.X_add_number =
4247 (imm_expr.X_add_number >> 16) & 0xffff;
4248 else if (c == 'h')
4249 imm_reloc = BFD_RELOC_HI16_S;
4250 else
4251 imm_reloc = BFD_RELOC_HI16;
3d3c5039 4252 }
670a50eb
ILT
4253 }
4254 else
4255 check_absolute_expr (ip, &imm_expr);
4256 if (*args == 'i')
4257 {
6e8dda9c
ILT
4258 if (imm_expr.X_add_number < 0
4259 || imm_expr.X_add_number >= 0x10000)
99c24539
ILT
4260 {
4261 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
4262 !strcmp (insn->name, insn[1].name))
4263 break;
4264 as_bad ("16 bit expression not in range 0..65535");
4265 }
670a50eb
ILT
4266 }
4267 else
4268 {
6e8dda9c
ILT
4269 if (imm_expr.X_add_number < -0x8000 ||
4270 imm_expr.X_add_number >= 0x8000)
99c24539
ILT
4271 {
4272 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
4273 !strcmp (insn->name, insn[1].name))
4274 break;
4275 as_bad ("16 bit expression not in range -32768..32767");
4276 }
3d3c5039 4277 }
670a50eb
ILT
4278 s = expr_end;
4279 continue;
4280
4281 case 'o': /* 16 bit offset */
4282 c = my_getSmallExpression (&offset_expr, s);
4283 /*
4284 * If this value won't fit into a 16 bit offset, then
4285 * go find a macro that will generate the 32 bit offset
4286 * code pattern.
4287 */
6e8dda9c
ILT
4288 if (offset_expr.X_op != O_constant
4289 || offset_expr.X_add_number >= 0x8000
4290 || offset_expr.X_add_number < -0x8000)
670a50eb 4291 break;
3d3c5039 4292
670a50eb
ILT
4293 offset_reloc = BFD_RELOC_LO16;
4294 if (c == 'h' || c == 'H')
6e8dda9c
ILT
4295 {
4296 assert (offset_expr.X_op == O_constant);
4297 offset_expr.X_add_number =
4298 (offset_expr.X_add_number >> 16) & 0xffff;
4299 }
670a50eb
ILT
4300 s = expr_end;
4301 continue;
4302
4303 case 'p': /* pc relative offset */
4304 offset_reloc = BFD_RELOC_16_PCREL_S2;
4305 my_getExpression (&offset_expr, s);
4306 s = expr_end;
4307 continue;
4308
4309 case 'u': /* upper 16 bits */
4310 c = my_getSmallExpression (&imm_expr, s);
6e8dda9c
ILT
4311 if (imm_expr.X_op != O_constant
4312 || imm_expr.X_add_number < 0
4313 || imm_expr.X_add_number >= 0x10000)
670a50eb
ILT
4314 as_bad ("lui expression not in range 0..65535");
4315 imm_reloc = BFD_RELOC_LO16;
4316 if (c)
4317 {
4318 if (c != 'l')
4319 {
5ac34ac3 4320 if (imm_expr.X_op == O_constant)
670a50eb
ILT
4321 imm_expr.X_add_number =
4322 (imm_expr.X_add_number >> 16) & 0xffff;
4323 else if (c == 'h')
4324 imm_reloc = BFD_RELOC_HI16_S;
4325 else
4326 imm_reloc = BFD_RELOC_HI16;
3d3c5039
ILT
4327 }
4328 }
670a50eb
ILT
4329 s = expr_end;
4330 continue;
3d3c5039 4331
670a50eb
ILT
4332 case 'a': /* 26 bit address */
4333 my_getExpression (&offset_expr, s);
4334 s = expr_end;
4335 offset_reloc = BFD_RELOC_MIPS_JMP;
4336 continue;
3d3c5039
ILT
4337
4338 default:
670a50eb
ILT
4339 fprintf (stderr, "bad char = '%c'\n", *args);
4340 internalError ();
3d3c5039 4341 }
670a50eb 4342 break;
3d3c5039 4343 }
670a50eb
ILT
4344 /* Args don't match. */
4345 if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
4346 !strcmp (insn->name, insn[1].name))
4347 {
4348 ++insn;
4349 s = argsStart;
4350 continue;
3d3c5039 4351 }
670a50eb
ILT
4352 insn_error = "ERROR: Illegal operands";
4353 return;
3d3c5039
ILT
4354 }
4355}
4356
4357#define LP '('
4358#define RP ')'
4359
4360static int
4361my_getSmallExpression (ep, str)
670a50eb
ILT
4362 expressionS *ep;
4363 char *str;
3d3c5039 4364{
670a50eb
ILT
4365 char *sp;
4366 int c = 0;
4367
4368 if (*str == ' ')
4369 str++;
4370 if (*str == LP
4371 || (*str == '%' &&
4372 ((str[1] == 'h' && str[2] == 'i')
4373 || (str[1] == 'H' && str[2] == 'I')
4374 || (str[1] == 'l' && str[2] == 'o'))
4375 && str[3] == LP))
4376 {
4377 if (*str == LP)
4378 c = 0;
4379 else
4380 {
4381 c = str[1];
4382 str += 3;
4383 }
4384
4385 /*
4386 * A small expression may be followed by a base register.
4387 * Scan to the end of this operand, and then back over a possible
4388 * base register. Then scan the small expression up to that
4389 * point. (Based on code in sparc.c...)
4390 */
4391 for (sp = str; *sp && *sp != ','; sp++)
4392 ;
4393 if (sp - 4 >= str && sp[-1] == RP)
4394 {
4395 if (isdigit (sp[-2]))
4396 {
4397 for (sp -= 3; sp >= str && isdigit (*sp); sp--)
4398 ;
4399 if (*sp == '$' && sp > str && sp[-1] == LP)
4400 {
4401 sp--;
4402 goto do_it;
3d3c5039 4403 }
670a50eb
ILT
4404 }
4405 else if (sp - 5 >= str
4406 && sp[-5] == LP
4407 && sp[-4] == '$'
4408 && ((sp[-3] == 'f' && sp[-2] == 'p')
4409 || (sp[-3] == 's' && sp[-2] == 'p')
4410 || (sp[-3] == 'g' && sp[-2] == 'p')
4411 || (sp[-3] == 'a' && sp[-2] == 't')))
4412 {
4413 sp -= 5;
3d3c5039 4414 do_it:
670a50eb
ILT
4415 if (sp == str)
4416 {
4417 /* no expression means zero offset */
4418 if (c)
4419 {
4420 /* %xx(reg) is an error */
5ac34ac3 4421 ep->X_op = O_absent;
670a50eb 4422 expr_end = str - 3;
3d3c5039 4423 }
670a50eb
ILT
4424 else
4425 {
52aa70b5 4426 ep->X_op = O_constant;
670a50eb
ILT
4427 expr_end = sp;
4428 }
4429 ep->X_add_symbol = NULL;
5ac34ac3 4430 ep->X_op_symbol = NULL;
670a50eb
ILT
4431 ep->X_add_number = 0;
4432 }
4433 else
4434 {
4435 *sp = '\0';
4436 my_getExpression (ep, str);
4437 *sp = LP;
3d3c5039 4438 }
670a50eb 4439 return c;
3d3c5039
ILT
4440 }
4441 }
4442 }
670a50eb
ILT
4443 my_getExpression (ep, str);
4444 return c; /* => %hi or %lo encountered */
3d3c5039
ILT
4445}
4446
4447static void
4448my_getExpression (ep, str)
670a50eb
ILT
4449 expressionS *ep;
4450 char *str;
3d3c5039 4451{
670a50eb 4452 char *save_in;
670a50eb
ILT
4453
4454 save_in = input_line_pointer;
4455 input_line_pointer = str;
5ac34ac3 4456 expression (ep);
670a50eb
ILT
4457 expr_end = input_line_pointer;
4458 input_line_pointer = save_in;
3d3c5039
ILT
4459}
4460
becfe05e
ILT
4461/* Turn a string in input_line_pointer into a floating point constant
4462 of type type, and store the appropriate bytes in *litP. The number
4463 of LITTLENUMS emitted is stored in *sizeP . An error message is
4464 returned, or NULL on OK. */
4465
3d3c5039 4466char *
670a50eb 4467md_atof (type, litP, sizeP)
becfe05e 4468 int type;
3d3c5039
ILT
4469 char *litP;
4470 int *sizeP;
4471{
becfe05e
ILT
4472 int prec;
4473 LITTLENUM_TYPE words[4];
4474 char *t;
4475 int i;
4476
4477 switch (type)
4478 {
4479 case 'f':
4480 prec = 2;
4481 break;
4482
4483 case 'd':
4484 prec = 4;
4485 break;
4486
4487 default:
4488 *sizeP = 0;
4489 return "bad call to md_atof";
4490 }
4491
4492 t = atof_ieee (input_line_pointer, type, words);
4493 if (t)
4494 input_line_pointer = t;
4495
4496 *sizeP = prec * 2;
4497
4498 if (byte_order == LITTLE_ENDIAN)
4499 {
4500 for (i = prec - 1; i >= 0; i--)
4501 {
4502 md_number_to_chars (litP, (valueT) words[i], 2);
4503 litP += 2;
4504 }
4505 }
4506 else
4507 {
4508 for (i = 0; i < prec; i++)
4509 {
4510 md_number_to_chars (litP, (valueT) words[i], 2);
4511 litP += 2;
4512 }
4513 }
4514
670a50eb 4515 return NULL;
3d3c5039
ILT
4516}
4517
4518void
4519md_number_to_chars (buf, val, n)
4520 char *buf;
918692a5 4521 valueT val;
3d3c5039
ILT
4522 int n;
4523{
670a50eb
ILT
4524 switch (byte_order)
4525 {
3d3c5039 4526 case LITTLE_ENDIAN:
13fe1379
ILT
4527 number_to_chars_littleendian (buf, val, n);
4528 break;
3d3c5039
ILT
4529
4530 case BIG_ENDIAN:
13fe1379
ILT
4531 number_to_chars_bigendian (buf, val, n);
4532 break;
3d3c5039
ILT
4533
4534 default:
670a50eb 4535 internalError ();
3d3c5039
ILT
4536 }
4537}
4538
4539int
4540md_parse_option (argP, cntP, vecP)
4541 char **argP;
4542 int *cntP;
4543 char ***vecP;
4544{
670a50eb 4545 /* Accept -nocpp but ignore it. */
8358c818 4546 if (strcmp (*argP, "nocpp") == 0)
670a50eb
ILT
4547 {
4548 *argP += 5;
4549 return 1;
4550 }
4551
4552 if (strcmp (*argP, "EL") == 0
4553 || strcmp (*argP, "EB") == 0)
4554 {
04cb3372
ILT
4555 if ((*argP)[1] == 'B')
4556 byte_order = BIG_ENDIAN;
4557 else
4558 byte_order = LITTLE_ENDIAN;
4559
4560#ifdef OBJ_AOUT
4561 if ((*argP)[1] == 'B')
4562 mips_target_format = "a.out-mips-big";
4563 else
4564 mips_target_format = "a.out-mips-little";
4565#endif
4566#ifdef OBJ_ECOFF
4567 if ((*argP)[1] == 'B')
4568 mips_target_format = "ecoff-bigmips";
4569 else
4570 mips_target_format = "ecoff-littlemips";
4571#endif
4572#ifdef OBJ_ELF
4573 if ((*argP)[1] == 'B')
4574 mips_target_format = "elf32-bigmips";
4575 else
4576 mips_target_format = "elf32-littlemips";
4577#endif
4578
670a50eb
ILT
4579 /* FIXME: This breaks -L -EL. */
4580 flagseen['L'] = 0;
4581 *argP = "";
4582 return 1;
4583 }
4584
4e95866e
ILT
4585 if (**argP == 'O')
4586 {
0aa07269
ILT
4587 if ((*argP)[1] == '0')
4588 mips_optimize = 1;
4589 else
4590 mips_optimize = 2;
4591 return 1;
4592 }
4593
4594 if (**argP == 'g')
4595 {
4596 if ((*argP)[1] == '\0' || (*argP)[1] == '2')
4597 mips_optimize = 0;
4e95866e
ILT
4598 return 1;
4599 }
4600
8358c818
ILT
4601 if (strncmp (*argP, "mips", 4) == 0)
4602 {
4603 mips_isa = atol (*argP + 4);
4604 if (mips_isa == 0)
4605 mips_isa = 1;
4606 else if (mips_isa < 1 || mips_isa > 3)
4607 {
4608 as_bad ("-mips%d not supported", mips_isa);
4609 mips_isa = 1;
4610 }
4611 *argP = "";
4612 return 1;
4613 }
4614
4615 if (strncmp (*argP, "mcpu=", 5) == 0)
4616 {
4617 char *p;
4618
4619 /* Identify the processor type */
4620 p = *argP + 5;
4621 if (strcmp (p, "default") == 0
4622 || strcmp (p, "DEFAULT") == 0)
4623 mips_isa = -1;
4624 else
4625 {
4626 if (*p == 'r' || *p == 'R')
4627 p++;
4628
4629 mips_isa = -1;
4630 switch (*p)
4631 {
4632 case '2':
4633 if (strcmp (p, "2000") == 0
4634 || strcmp (p, "2k") == 0
4635 || strcmp (p, "2K") == 0)
4636 mips_isa = 1;
4637 break;
4638
4639 case '3':
4640 if (strcmp (p, "3000") == 0
4641 || strcmp (p, "3k") == 0
4642 || strcmp (p, "3K") == 0)
4643 mips_isa = 1;
4644 break;
4645
4646 case '4':
4647 if (strcmp (p, "4000") == 0
4648 || strcmp (p, "4k") == 0
4649 || strcmp (p, "4K") == 0)
4650 mips_isa = 3;
4651 break;
4652
4653 case '6':
4654 if (strcmp (p, "6000") == 0
4655 || strcmp (p, "6k") == 0
4656 || strcmp (p, "6K") == 0)
4657 mips_isa = 2;
4658 break;
4659 }
4660
4661 if (mips_isa == -1)
4662 {
4663 as_bad ("bad value (%s) for -mcpu= switch", *argP + 5);
4664 mips_isa = 1;
4665 }
4666 }
4667
4668 *argP = "";
4669 return 1;
4670 }
4671
4672
88225433 4673#ifdef GPOPT
670a50eb
ILT
4674 if (**argP == 'G')
4675 {
4676 if ((*argP)[1] != '\0')
4677 g_switch_value = atoi (*argP + 1);
4678 else if (*cntP)
4679 {
4680 **vecP = (char *) NULL;
4681 (*cntP)--;
4682 (*vecP)++;
4683 g_switch_value = atoi (**vecP);
4684 }
4685 else
4686 as_warn ("Number expected after -G");
4687 *argP = "";
4688 return 1;
3d3c5039 4689 }
670a50eb 4690#endif
4e95866e 4691
670a50eb 4692 return 1; /* pretend you parsed the character */
3d3c5039
ILT
4693}
4694
4695long
4696md_pcrel_from (fixP)
4697 fixS *fixP;
4698{
670a50eb
ILT
4699 /* return the address of the delay slot */
4700 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
3d3c5039
ILT
4701}
4702
abdad6bc
ILT
4703/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
4704 reloc for a cons. We could use the definition there, except that
4705 we want to handle 64 bit relocs specially. */
4706
4707void
4708cons_fix_new_mips (frag, where, nbytes, exp)
4709 fragS *frag;
4710 int where;
4711 unsigned int nbytes;
4712 expressionS *exp;
4713{
4714 /* If we are assembling in 32 bit mode, turn an 8 byte reloc into a
4715 4 byte reloc.
4716 FIXME: There is no way to select anything but 32 bit mode right
4717 now. */
4718 if (nbytes == 8)
4719 {
4720 if (byte_order == BIG_ENDIAN)
4721 where += 4;
4722 nbytes = 4;
4723 }
4724
4725 if (nbytes != 2 && nbytes != 4)
4726 as_bad ("Unsupported reloc size %d", nbytes);
4727
4728 fix_new_exp (frag_now, where, (int) nbytes, exp, 0,
4729 nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32);
4730}
4731
3d3c5039
ILT
4732int
4733md_apply_fix (fixP, valueP)
4734 fixS *fixP;
918692a5 4735 valueT *valueP;
3d3c5039 4736{
670a50eb
ILT
4737 unsigned char *buf;
4738 long insn, value;
3d3c5039 4739
670a50eb 4740 assert (fixP->fx_size == 4);
3d3c5039 4741
670a50eb
ILT
4742 value = *valueP;
4743 fixP->fx_addnumber = value; /* Remember value for tc_gen_reloc */
3d3c5039 4744
670a50eb
ILT
4745 switch (fixP->fx_r_type)
4746 {
3d3c5039
ILT
4747 case BFD_RELOC_32:
4748 case BFD_RELOC_MIPS_JMP:
4749 case BFD_RELOC_HI16:
4750 case BFD_RELOC_HI16_S:
4751 case BFD_RELOC_LO16:
670a50eb 4752 case BFD_RELOC_MIPS_GPREL:
9226253a
ILT
4753 case BFD_RELOC_MIPS_LITERAL:
4754 case BFD_RELOC_MIPS_CALL16:
0dd2d296
ILT
4755 case BFD_RELOC_MIPS_GOT16:
4756 case BFD_RELOC_MIPS_GPREL32:
670a50eb
ILT
4757 /* Nothing needed to do. The value comes from the reloc entry */
4758 return 1;
3d3c5039
ILT
4759
4760 case BFD_RELOC_16_PCREL_S2:
670a50eb
ILT
4761 /*
4762 * We need to save the bits in the instruction since fixup_segment()
4763 * might be deleting the relocation entry (i.e., a branch within
4764 * the current segment).
4765 */
4766 if (value & 0x3)
58d4951d 4767 as_warn ("Branch to odd address (%lx)", value);
670a50eb
ILT
4768 value >>= 2;
4769 if ((value & ~0xFFFF) && (value & ~0xFFFF) != (-1 & ~0xFFFF))
4770 as_bad ("Relocation overflow");
4771
4772 /* update old instruction data */
4773 buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
4774 switch (byte_order)
4775 {
3d3c5039 4776 case LITTLE_ENDIAN:
670a50eb
ILT
4777 insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
4778 break;
3d3c5039
ILT
4779
4780 case BIG_ENDIAN:
670a50eb
ILT
4781 insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
4782 break;
3d3c5039
ILT
4783
4784 default:
670a50eb
ILT
4785 internalError ();
4786 return 0;
3d3c5039 4787 }
670a50eb 4788 insn |= value & 0xFFFF;
604633ae 4789 md_number_to_chars ((char *) buf, (valueT) insn, 4);
670a50eb 4790 break;
3d3c5039
ILT
4791
4792 default:
670a50eb 4793 internalError ();
3d3c5039 4794 }
670a50eb 4795 return 1;
3d3c5039
ILT
4796}
4797
4798#if 0
4799void
670a50eb
ILT
4800printInsn (oc)
4801 unsigned long oc;
3d3c5039 4802{
670a50eb
ILT
4803 const struct mips_opcode *p;
4804 int treg, sreg, dreg, shamt;
4805 short imm;
4806 const char *args;
4807 int i;
3d3c5039 4808
670a50eb
ILT
4809 for (i = 0; i < NUMOPCODES; ++i)
4810 {
4811 p = &mips_opcodes[i];
4812 if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))
4813 {
4814 printf ("%08lx %s\t", oc, p->name);
4815 treg = (oc >> 16) & 0x1f;
4816 sreg = (oc >> 21) & 0x1f;
4817 dreg = (oc >> 11) & 0x1f;
4818 shamt = (oc >> 6) & 0x1f;
4819 imm = oc;
4820 for (args = p->args;; ++args)
4821 {
4822 switch (*args)
4823 {
3d3c5039 4824 case '\0':
670a50eb
ILT
4825 printf ("\n");
4826 break;
3d3c5039
ILT
4827
4828 case ',':
4829 case '(':
4830 case ')':
670a50eb
ILT
4831 printf ("%c", *args);
4832 continue;
3d3c5039
ILT
4833
4834 case 'r':
670a50eb
ILT
4835 assert (treg == sreg);
4836 printf ("$%d,$%d", treg, sreg);
4837 continue;
3d3c5039
ILT
4838
4839 case 'd':
918692a5 4840 case 'G':
670a50eb
ILT
4841 printf ("$%d", dreg);
4842 continue;
3d3c5039
ILT
4843
4844 case 't':
918692a5 4845 case 'E':
670a50eb
ILT
4846 printf ("$%d", treg);
4847 continue;
3d3c5039 4848
9226253a
ILT
4849 case 'k':
4850 printf ("0x%x", treg);
4851 continue;
4852
3d3c5039
ILT
4853 case 'b':
4854 case 's':
670a50eb
ILT
4855 printf ("$%d", sreg);
4856 continue;
3d3c5039
ILT
4857
4858 case 'a':
670a50eb
ILT
4859 printf ("0x%08lx", oc & 0x1ffffff);
4860 continue;
3d3c5039
ILT
4861
4862 case 'i':
4863 case 'j':
4864 case 'o':
4865 case 'u':
670a50eb
ILT
4866 printf ("%d", imm);
4867 continue;
3d3c5039
ILT
4868
4869 case '<':
56c96faa 4870 case '>':
670a50eb
ILT
4871 printf ("$%d", shamt);
4872 continue;
3d3c5039
ILT
4873
4874 default:
670a50eb 4875 internalError ();
3d3c5039 4876 }
670a50eb 4877 break;
3d3c5039 4878 }
670a50eb 4879 return;
3d3c5039
ILT
4880 }
4881 }
670a50eb 4882 printf ("%08lx UNDEFINED\n", oc);
3d3c5039
ILT
4883}
4884#endif
4885
4886static symbolS *
4887get_symbol ()
4888{
670a50eb
ILT
4889 int c;
4890 char *name;
4891 symbolS *p;
4892
4893 name = input_line_pointer;
4894 c = get_symbol_end ();
4895 p = (symbolS *) symbol_find_or_make (name);
4896 *input_line_pointer = c;
4897 return p;
3d3c5039
ILT
4898}
4899
becfe05e
ILT
4900/* Align the current frag to a given power of two. The MIPS assembler
4901 also automatically adjusts any preceding label. */
4902
4903static void
4904mips_align (to, fill)
4905 int to;
4906 int fill;
4907{
4908 mips_emit_delays ();
4909 frag_align (to, fill);
4910 record_alignment (now_seg, to);
4911 if (insn_label != NULL)
4912 {
4913 assert (S_GET_SEGMENT (insn_label) == now_seg);
4914 insn_label->sy_frag = frag_now;
604633ae 4915 S_SET_VALUE (insn_label, (valueT) frag_now_fix ());
1849d646 4916 insn_label = NULL;
becfe05e
ILT
4917 }
4918}
4919
4920/* Align to a given power of two. .align 0 turns off the automatic
4921 alignment used by the data creating pseudo-ops. */
4922
3d3c5039
ILT
4923static void
4924s_align (x)
4925 int x;
4926{
670a50eb
ILT
4927 register int temp;
4928 register long temp_fill;
4929 long max_alignment = 15;
3d3c5039 4930
670a50eb 4931 /*
3d3c5039
ILT
4932
4933 o Note that the assembler pulls down any immediately preceeding label
4934 to the aligned address.
4935 o It's not documented but auto alignment is reinstated by
4936 a .align pseudo instruction.
4937 o Note also that after auto alignment is turned off the mips assembler
4938 issues an error on attempt to assemble an improperly aligned data item.
4939 We don't.
4940
4941 */
4942
670a50eb
ILT
4943 temp = get_absolute_expression ();
4944 if (temp > max_alignment)
4945 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
4946 else if (temp < 0)
4947 {
4948 as_warn ("Alignment negative: 0 assumed.");
4949 temp = 0;
4950 }
4951 if (*input_line_pointer == ',')
4952 {
4953 input_line_pointer++;
4954 temp_fill = get_absolute_expression ();
4955 }
4956 else
4957 temp_fill = 0;
4958 if (temp)
4959 {
4960 auto_align = 1;
becfe05e 4961 mips_align (temp, (int) temp_fill);
3d3c5039 4962 }
670a50eb
ILT
4963 else
4964 {
4965 auto_align = 0;
3d3c5039
ILT
4966 }
4967
670a50eb 4968 demand_empty_rest_of_line ();
3d3c5039
ILT
4969}
4970
becfe05e
ILT
4971/* Handle .ascii and .asciiz. This just calls stringer and forgets
4972 that there was a previous instruction. */
4973
4974static void
4975s_stringer (append_zero)
4976 int append_zero;
4977{
4978 mips_emit_delays ();
1849d646 4979 insn_label = NULL;
becfe05e
ILT
4980 stringer (append_zero);
4981}
4982
3d3c5039
ILT
4983static void
4984s_change_sec (sec)
4985 int sec;
4986{
88225433
ILT
4987#ifdef GPOPT
4988 segT seg;
4989#endif
becfe05e
ILT
4990
4991 mips_emit_delays ();
670a50eb
ILT
4992 switch (sec)
4993 {
3d3c5039 4994 case 't':
604633ae 4995 s_text (0);
670a50eb 4996 break;
3d3c5039 4997 case 'd':
604633ae 4998 s_data (0);
670a50eb 4999 break;
3d3c5039 5000 case 'b':
670a50eb 5001 subseg_set (bss_section, (subsegT) get_absolute_expression ());
670a50eb
ILT
5002 demand_empty_rest_of_line ();
5003 break;
88225433
ILT
5004
5005 case 'r':
670a50eb 5006#ifdef OBJ_ECOFF
88225433 5007 subseg_new (".rdata", (subsegT) get_absolute_expression ());
becfe05e 5008 demand_empty_rest_of_line ();
670a50eb 5009 break;
88225433
ILT
5010#else /* ! defined (OBJ_ECOFF) */
5011#ifdef OBJ_ELF
5012 seg = subseg_new (".rodata", (subsegT) get_absolute_expression ());
5013 bfd_set_section_flags (stdoutput, seg,
5014 (SEC_ALLOC
5015 | SEC_LOAD
5016 | SEC_READONLY
5017 | SEC_RELOC
5018 | SEC_DATA));
0dd2d296 5019 bfd_set_section_alignment (stdoutput, seg, 4);
88225433
ILT
5020 demand_empty_rest_of_line ();
5021 break;
5022#else /* ! defined (OBJ_ELF) */
5023 s_data (0);
5024 break;
5025#endif /* ! defined (OBJ_ELF) */
5026#endif /* ! defined (OBJ_ECOFF) */
5027
5028 case 's':
5029#ifdef GPOPT
5030 seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
5031#ifdef OBJ_ELF
5032 bfd_set_section_flags (stdoutput, seg,
5033 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
0dd2d296 5034 bfd_set_section_alignment (stdoutput, seg, 4);
88225433
ILT
5035#endif
5036 demand_empty_rest_of_line ();
5037 break;
5038#else /* ! defined (GPOPT) */
670a50eb 5039 as_bad ("Global pointers not supported; recompile -G 0");
becfe05e 5040 demand_empty_rest_of_line ();
670a50eb 5041 return;
88225433 5042#endif /* ! defined (GPOPT) */
3d3c5039 5043 }
88225433 5044
670a50eb 5045 auto_align = 1;
3d3c5039
ILT
5046}
5047
5048static void
5049s_cons (log_size)
5050 int log_size;
5051{
becfe05e 5052 mips_emit_delays ();
670a50eb 5053 if (log_size > 0 && auto_align)
becfe05e 5054 mips_align (log_size, 0);
1849d646 5055 insn_label = NULL;
670a50eb 5056 cons (1 << log_size);
3d3c5039
ILT
5057}
5058
5059static void
5060s_err (x)
5061 int x;
5062{
670a50eb 5063 as_fatal ("Encountered `.err', aborting assembly");
3d3c5039
ILT
5064}
5065
5066static void
5067s_extern (x)
5068 int x;
5069{
604633ae 5070 valueT size;
670a50eb
ILT
5071 symbolS *symbolP;
5072
5073 symbolP = get_symbol ();
5074 if (*input_line_pointer == ',')
5075 input_line_pointer++;
5ac34ac3 5076 size = get_absolute_expression ();
670a50eb
ILT
5077 S_SET_VALUE (symbolP, size);
5078 S_SET_EXTERNAL (symbolP);
5079
0dd2d296 5080#ifdef ECOFF_DEBUGGING
670a50eb
ILT
5081 /* ECOFF needs to distinguish a .comm symbol from a .extern symbol,
5082 so we use an additional ECOFF specific field. */
5083 symbolP->ecoff_undefined = 1;
5084#endif
3d3c5039
ILT
5085}
5086
5087static void
becfe05e
ILT
5088s_float_cons (type)
5089 int type;
3d3c5039 5090{
becfe05e 5091 mips_emit_delays ();
670a50eb
ILT
5092
5093 if (auto_align)
becfe05e
ILT
5094 if (type == 'd')
5095 mips_align (3, 0);
670a50eb 5096 else
becfe05e 5097 mips_align (2, 0);
670a50eb 5098
1849d646
ILT
5099 insn_label = NULL;
5100
becfe05e 5101 float_cons (type);
3d3c5039
ILT
5102}
5103
5104static void
5105s_option (x)
5106 int x;
5107{
dd3f1f76
ILT
5108 char *opt;
5109 char c;
5110
5111 opt = input_line_pointer;
5112 c = get_symbol_end ();
5113
dd3f1f76 5114 if (*opt == 'O')
9226253a
ILT
5115 {
5116 /* FIXME: What does this mean? */
5117 }
dd3f1f76 5118 else if (strncmp (opt, "pic", 3) == 0)
9226253a
ILT
5119 {
5120 mips_pic = atoi (opt + 3);
0dd2d296 5121 /* Supposedly no other values are used. */
9226253a
ILT
5122 assert (mips_pic == 0 || mips_pic == 2);
5123 }
dd3f1f76
ILT
5124 else
5125 as_warn ("Unrecognized option \"%s\"", opt);
5126
5127 *input_line_pointer = c;
670a50eb 5128 demand_empty_rest_of_line ();
3d3c5039
ILT
5129}
5130
5131static void
5132s_mipsset (x)
5133 int x;
5134{
670a50eb
ILT
5135 char *name = input_line_pointer, ch;
5136
5137 while (!is_end_of_line[(unsigned char) *input_line_pointer])
5138 input_line_pointer++;
5139 ch = *input_line_pointer;
5140 *input_line_pointer = '\0';
5141
5142 if (strcmp (name, "reorder") == 0)
5143 {
4e95866e
ILT
5144 if (mips_noreorder)
5145 {
5146 prev_insn_unreordered = 1;
5147 prev_prev_insn_unreordered = 1;
5148 }
670a50eb
ILT
5149 mips_noreorder = 0;
5150 }
5151 else if (strcmp (name, "noreorder") == 0)
5152 {
becfe05e 5153 mips_emit_delays ();
670a50eb 5154 mips_noreorder = 1;
0dd2d296 5155 mips_any_noreorder = 1;
670a50eb
ILT
5156 }
5157 else if (strcmp (name, "at") == 0)
5158 {
5159 mips_noat = 0;
5160 }
5161 else if (strcmp (name, "noat") == 0)
5162 {
5163 mips_noat = 1;
3d3c5039 5164 }
670a50eb
ILT
5165 else if (strcmp (name, "macro") == 0)
5166 {
5167 mips_warn_about_macros = 0;
5168 }
5169 else if (strcmp (name, "nomacro") == 0)
5170 {
5171 if (mips_noreorder == 0)
5172 as_bad ("`noreorder' must be set before `nomacro'");
5173 mips_warn_about_macros = 1;
5174 }
5175 else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
5176 {
5177 mips_nomove = 0;
5178 }
5179 else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
5180 {
5181 mips_nomove = 1;
5182 }
5183 else if (strcmp (name, "bopt") == 0)
5184 {
5185 mips_nobopt = 0;
5186 }
5187 else if (strcmp (name, "nobopt") == 0)
5188 {
5189 mips_nobopt = 1;
5190 }
5191 else
5192 {
5193 as_warn ("Tried to set unrecognized symbol: %s\n", name);
5194 }
5195 *input_line_pointer = ch;
5196 demand_empty_rest_of_line ();
3d3c5039
ILT
5197}
5198
becfe05e
ILT
5199/* The same as the usual .space directive, except that we have to
5200 forget about any previous instruction. */
5201
5202static void
5203s_mips_space (param)
5204 int param;
5205{
5206 mips_emit_delays ();
1849d646 5207 insn_label = NULL;
becfe05e
ILT
5208 s_space (param);
5209}
5210
9226253a
ILT
5211/* Handle the .abicalls pseudo-op. I believe this is equivalent to
5212 .option pic2. It means to generate SVR4 PIC calls. */
5213
5214static void
5215s_abicalls (ignore)
5216 int ignore;
5217{
5218 mips_pic = 2;
5219 demand_empty_rest_of_line ();
5220}
5221
5222/* Handle the .cpload pseudo-op. This is used when generating SVR4
5223 PIC code. It sets the $gp register for the function based on the
5224 function address, which is in the register named in the argument.
5225 This uses a relocation against _gp_disp, which is handled specially
5226 by the linker. The result is:
5227 lui $gp,%hi(_gp_disp)
5228 addiu $gp,$gp,%lo(_gp_disp)
5229 addu $gp,$gp,.cpload argument
0dd2d296 5230 The .cpload argument is normally $25 == $t9. */
9226253a
ILT
5231
5232static void
5233s_cpload (ignore)
5234 int ignore;
5235{
5236 expressionS ex;
5237 int icnt = 0;
5238
0dd2d296
ILT
5239 /* If we are not generating PIC code, .cpload is ignored. */
5240 if (mips_pic == 0)
5241 {
5242 s_ignore (0);
5243 return;
5244 }
5245
5246 /* .cpload should be a in .set noreorder section. */
5247 if (mips_noreorder == 0)
5248 as_warn (".cpload not in noreorder section");
5249
9226253a
ILT
5250 ex.X_op = O_symbol;
5251 ex.X_add_symbol = symbol_find_or_make ("_gp_disp");
5252 ex.X_op_symbol = NULL;
5253 ex.X_add_number = 0;
5254
0dd2d296
ILT
5255 macro_build_lui ((char *) NULL, &icnt, &ex, GP);
5256 macro_build ((char *) NULL, &icnt, &ex, "addiu", "t,r,j", GP, GP,
9226253a
ILT
5257 (int) BFD_RELOC_LO16);
5258
0dd2d296
ILT
5259 macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "addu", "d,v,t",
5260 GP, GP, tc_get_register (0));
9226253a
ILT
5261
5262 demand_empty_rest_of_line ();
5263}
5264
5265/* Handle the .cprestore pseudo-op. This stores $gp into a given
5266 offset from $sp. The offset is remembered, and after making a PIC
5267 call $gp is restored from that location. */
5268
5269static void
5270s_cprestore (ignore)
5271 int ignore;
5272{
5273 expressionS ex;
5274 int icnt = 0;
5275
0dd2d296
ILT
5276 /* If we are not generating PIC code, .cprestore is ignored. */
5277 if (mips_pic == 0)
5278 {
5279 s_ignore (0);
5280 return;
5281 }
5282
9226253a
ILT
5283 mips_cprestore_offset = get_absolute_expression ();
5284
5285 ex.X_op = O_constant;
5286 ex.X_add_symbol = NULL;
5287 ex.X_op_symbol = NULL;
5288 ex.X_add_number = mips_cprestore_offset;
5289
0dd2d296 5290 macro_build ((char *) NULL, &icnt, &ex,
9226253a
ILT
5291 mips_isa < 3 ? "sw" : "sd",
5292 "t,o(b)", GP, (int) BFD_RELOC_LO16, SP);
5293
5294 demand_empty_rest_of_line ();
5295}
5296
0dd2d296
ILT
5297/* Handle the .gpword pseudo-op. This is used when generating PIC
5298 code. It generates a 32 bit GP relative reloc. */
5299
5300static void
5301s_gpword (ignore)
5302 int ignore;
5303{
5304 expressionS ex;
5305 char *p;
5306
5307 /* When not generating PIC code, this is treated as .word. */
5308 if (mips_pic == 0)
5309 {
5310 s_cons (2);
5311 return;
5312 }
5313
5314 mips_emit_delays ();
5315 if (auto_align)
5316 mips_align (2, 0);
5317 insn_label = NULL;
5318
5319 expression (&ex);
5320
5321 if (ex.X_op != O_symbol || ex.X_add_number != 0)
5322 {
5323 as_bad ("Unsupported use of .gpword");
5324 ignore_rest_of_line ();
5325 }
5326
5327 p = frag_more (4);
5328 md_number_to_chars (p, (valueT) 0, 4);
5329 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, 0,
5330 BFD_RELOC_MIPS_GPREL32);
5331
5332 demand_empty_rest_of_line ();
5333}
5334
5335/* Handle the .cpadd pseudo-op. This is used when dealing with switch
5336 tables in SVR4 PIC code. */
5337
5338static void
5339s_cpadd (ignore)
5340 int ignore;
5341{
5342 int icnt = 0;
5343 int reg;
5344
5345 /* This is ignored when not generating SVR4 PIC code. */
5346 if (mips_pic == 0)
5347 {
5348 s_ignore (0);
5349 return;
5350 }
5351
5352 /* Add $gp to the register named as an argument. */
5353 reg = tc_get_register (0);
5354 macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
5355 mips_isa < 3 ? "addu" : "daddu",
5356 "d,v,t", reg, reg, GP);
5357
5358 demand_empty_rest_of_line ();
5359}
5360
9226253a 5361/* Parse a register string into a number. Called from the ECOFF code
0dd2d296
ILT
5362 to parse .frame. The argument is non-zero if this is the frame
5363 register, so that we can record it in mips_frame_reg. */
9226253a 5364
3d3c5039 5365int
0dd2d296
ILT
5366tc_get_register (frame)
5367 int frame;
3d3c5039
ILT
5368{
5369 int reg;
5370
5371 SKIP_WHITESPACE ();
5372 if (*input_line_pointer++ != '$')
5373 {
5374 as_warn ("expected `$'");
0dd2d296 5375 reg = 0;
3d3c5039 5376 }
0dd2d296 5377 else if (isdigit ((unsigned char) *input_line_pointer))
3d3c5039
ILT
5378 {
5379 reg = get_absolute_expression ();
5380 if (reg < 0 || reg >= 32)
5381 {
5382 as_warn ("Bad register number");
5383 reg = 0;
5384 }
5385 }
5386 else
5387 {
5388 if (strncmp (input_line_pointer, "fp", 2) == 0)
9226253a 5389 reg = FP;
3d3c5039 5390 else if (strncmp (input_line_pointer, "sp", 2) == 0)
9226253a 5391 reg = SP;
3d3c5039 5392 else if (strncmp (input_line_pointer, "gp", 2) == 0)
9226253a 5393 reg = GP;
3d3c5039 5394 else if (strncmp (input_line_pointer, "at", 2) == 0)
9226253a 5395 reg = AT;
3d3c5039
ILT
5396 else
5397 {
5398 as_warn ("Unrecognized register name");
0dd2d296 5399 reg = 0;
3d3c5039
ILT
5400 }
5401 input_line_pointer += 2;
5402 }
0dd2d296
ILT
5403 if (frame)
5404 mips_frame_reg = reg != 0 ? reg : SP;
3d3c5039
ILT
5405 return reg;
5406}
5407
0dd2d296
ILT
5408valueT
5409md_section_align (seg, addr)
5410 asection *seg;
5411 valueT addr;
5412{
5413 int align = bfd_get_section_alignment (stdoutput, seg);
5414
5415 return ((addr + (1 << align) - 1) & (-1 << align));
5416}
5417
5418/* Estimate the size of a frag before relaxing. We are not really
5419 relaxing here, and the final size is encoded in the subtype
5420 information. */
5421
5422/*ARGSUSED*/
5423int
5424md_estimate_size_before_relax (fragp, segtype)
5425 fragS *fragp;
5426 asection *segtype;
5427{
5428 int change;
5429
5430 if (mips_pic == 0)
5431 {
5432#ifdef GPOPT
5433 const char *symname;
5434
5435 /* Find out whether this symbol can be referenced off the GP
5436 register. It can be if it is smaller than the -G size or if
5437 it is in the .sdata or .sbss section. Certain symbols can
5438 not be referenced off the GP, although it appears as though
5439 they can. */
5440 symname = S_GET_NAME (fragp->fr_symbol);
5441 if (symname != (const char *) NULL
5442 && (strcmp (symname, "eprol") == 0
5443 || strcmp (symname, "etext") == 0
5444 || strcmp (symname, "_gp") == 0
5445 || strcmp (symname, "edata") == 0
5446 || strcmp (symname, "_fbss") == 0
5447 || strcmp (symname, "_fdata") == 0
5448 || strcmp (symname, "_ftext") == 0
5449 || strcmp (symname, "end") == 0
5450 || strcmp (symname, "_gp_disp") == 0))
5451 change = 1;
5452 else if (! S_IS_DEFINED (fragp->fr_symbol)
5453 && S_GET_VALUE (fragp->fr_symbol) != 0
5454 && S_GET_VALUE (fragp->fr_symbol) <= g_switch_value)
5455 change = 0;
5456 else
5457 {
5458 const char *segname;
5459
5460 segname = segment_name (S_GET_SEGMENT (fragp->fr_symbol));
5461 assert (strcmp (segname, ".lit8") != 0
5462 && strcmp (segname, ".lit4") != 0);
5463 change = (strcmp (segname, ".sdata") != 0
5464 && strcmp (segname, ".sbss") != 0);
5465 }
5466#else /* ! defined (GPOPT) */
5467 /* We are not optimizing for the GP register. */
5468 change = 1;
5469#endif /* ! defined (GPOPT) */
5470 }
5471 else
5472 {
5473 asection *symsec = fragp->fr_symbol->bsym->section;
5474
5475 /* This must duplicate the test in adjust_reloc_syms. */
5476 change = (symsec != &bfd_und_section
5477 && symsec != &bfd_abs_section
5478 && ! bfd_is_com_section (symsec));
5479 }
5480
5481 if (change)
5482 {
5483 /* Record the offset to the first reloc in the fr_opcode field.
5484 This lets md_convert_frag and tc_gen_reloc know that the code
5485 must be expanded. */
5486 fragp->fr_opcode = (fragp->fr_literal
5487 + fragp->fr_fix
5488 - RELAX_OLD (fragp->fr_subtype)
5489 + RELAX_RELOC1 (fragp->fr_subtype));
5490 /* FIXME: This really needs as_warn_where. */
5491 if (RELAX_WARN (fragp->fr_subtype))
5492 as_warn ("AT used after \".set noat\" or macro used after \".set nomacro\"");
5493 }
5494
5495 if (! change)
5496 return 0;
5497 else
5498 return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
5499}
5500
5501/* Translate internal representation of relocation info to BFD target
5502 format. */
5503
5504arelent **
3d3c5039
ILT
5505tc_gen_reloc (section, fixp)
5506 asection *section;
5507 fixS *fixp;
5508{
0dd2d296 5509 static arelent *retval[4];
3d3c5039
ILT
5510 arelent *reloc;
5511
0dd2d296
ILT
5512 reloc = retval[0] = (arelent *) xmalloc (sizeof (arelent));
5513 retval[1] = NULL;
3d3c5039
ILT
5514
5515 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5516 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5517 if (fixp->fx_pcrel == 0)
5518 reloc->addend = fixp->fx_addnumber;
5519 else
5520#ifdef OBJ_ELF
5521 reloc->addend = 0;
5522#else
670a50eb 5523 reloc->addend = -reloc->address;
3d3c5039 5524#endif
0dd2d296
ILT
5525
5526 /* If this is a variant frag, we may need to adjust the existing
5527 reloc and generate a new one. */
5528 if (fixp->fx_frag->fr_opcode != NULL
5529 && (fixp->fx_r_type == BFD_RELOC_MIPS_GPREL
5530 || fixp->fx_r_type == BFD_RELOC_MIPS_GOT16
5531 || fixp->fx_r_type == BFD_RELOC_MIPS_CALL16))
5532 {
5533 arelent *reloc2;
5534
5535 /* If this is not the last reloc in this frag, then we have two
5536 GPREL relocs, both of which are being replaced. Let the
5537 second one handle all of them. */
5538 if (fixp->fx_next != NULL
5539 && fixp->fx_frag == fixp->fx_next->fx_frag)
5540 {
5541 assert (fixp->fx_r_type == BFD_RELOC_MIPS_GPREL
5542 && fixp->fx_next->fx_r_type == BFD_RELOC_MIPS_GPREL);
5543 retval[0] = NULL;
5544 return retval;
5545 }
5546
5547 fixp->fx_where = fixp->fx_frag->fr_opcode - fixp->fx_frag->fr_literal;
5548 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5549 reloc2 = retval[1] = (arelent *) xmalloc (sizeof (arelent));
5550 retval[2] = NULL;
5551 reloc2->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5552 reloc2->address = (reloc->address
5553 + (RELAX_RELOC2 (fixp->fx_frag->fr_subtype)
5554 - RELAX_RELOC1 (fixp->fx_frag->fr_subtype)));
5555 reloc2->addend = fixp->fx_addnumber;
5556 reloc2->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
5557 assert (reloc2->howto != NULL);
5558
5559 if (RELAX_RELOC3 (fixp->fx_frag->fr_subtype))
5560 {
5561 arelent *reloc3;
5562
5563 reloc3 = retval[2] = (arelent *) xmalloc (sizeof (arelent));
5564 retval[3] = NULL;
5565 *reloc3 = *reloc2;
5566 reloc3->address += 4;
5567 }
5568
5569 if (mips_pic == 0)
5570 {
5571 assert (fixp->fx_r_type == BFD_RELOC_MIPS_GPREL);
5572 fixp->fx_r_type = BFD_RELOC_HI16_S;
5573 }
5574 else
5575 {
5576 if (fixp->fx_r_type != BFD_RELOC_MIPS_GOT16)
5577 {
5578 assert (fixp->fx_r_type == BFD_RELOC_MIPS_CALL16);
5579 fixp->fx_r_type = BFD_RELOC_MIPS_GOT16;
5580 }
5581 }
5582 }
5583
3d3c5039 5584 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
0dd2d296 5585
52aa70b5
JW
5586 if (reloc->howto == NULL)
5587 {
5588 as_bad_where (fixp->fx_file, fixp->fx_line,
5589 "Can not represent relocation in this object file format");
0dd2d296 5590 retval[0] = NULL;
52aa70b5 5591 }
3d3c5039 5592
0dd2d296 5593 return retval;
3d3c5039
ILT
5594}
5595
0dd2d296
ILT
5596/* Convert a machine dependent frag. */
5597
5598void
5599md_convert_frag (abfd, asec, fragp)
5600 bfd *abfd;
5601 segT asec;
5602 fragS *fragp;
3d3c5039 5603{
0dd2d296
ILT
5604 int old, new;
5605 char *fixptr;
3d3c5039 5606
0dd2d296
ILT
5607 if (fragp->fr_opcode == NULL)
5608 return;
3d3c5039 5609
0dd2d296
ILT
5610 old = RELAX_OLD (fragp->fr_subtype);
5611 new = RELAX_NEW (fragp->fr_subtype);
5612 fixptr = fragp->fr_literal + fragp->fr_fix;
5613
5614 if (new > 0)
5615 memcpy (fixptr - old, fixptr, new);
5616
5617 fragp->fr_fix += new - old;
5618}
becfe05e
ILT
5619
5620/* This function is called whenever a label is defined. It is used
5621 when handling branch delays; if a branch has a label, we assume we
5622 can not move it. */
5623
5624void
5625mips_define_label (sym)
5626 symbolS *sym;
5627{
5628 insn_label = sym;
5629}
3d3c5039 5630\f
f2a663d3
ILT
5631#ifdef OBJ_ELF
5632
0dd2d296 5633/* Some special processing for a MIPS ELF file. */
f2a663d3
ILT
5634
5635void
5636mips_elf_final_processing ()
5637{
5638 Elf32_RegInfo s;
5639
0dd2d296 5640 /* Write out the .reginfo section. */
f2a663d3
ILT
5641 s.ri_gprmask = mips_gprmask;
5642 s.ri_cprmask[0] = mips_cprmask[0];
5643 s.ri_cprmask[1] = mips_cprmask[1];
5644 s.ri_cprmask[2] = mips_cprmask[2];
5645 s.ri_cprmask[3] = mips_cprmask[3];
5646 /* The gp_value field is set by the MIPS ELF backend. */
5647
5648 bfd_mips_elf32_swap_reginfo_out (stdoutput, &s,
5649 ((Elf32_External_RegInfo *)
5650 mips_regmask_frag));
0dd2d296
ILT
5651
5652 /* Set the MIPS ELF flag bits. FIXME: There should probably be some
5653 sort of BFD interface for this. */
5654 if (mips_any_noreorder)
5655 elf_elfheader (stdoutput)->e_flags |= EF_MIPS_NOREORDER;
5656 if (mips_pic != 0)
5657 elf_elfheader (stdoutput)->e_flags |= EF_MIPS_PIC;
f2a663d3
ILT
5658}
5659
5660#endif /* OBJ_ELF */
5661\f
0dd2d296 5662#ifndef ECOFF_DEBUGGING
3d3c5039
ILT
5663
5664/* These functions should really be defined by the object file format,
5665 since they are related to debugging information. However, this
5666 code has to work for the a.out format, which does not define them,
5667 so we provide simple versions here. These don't actually generate
5668 any debugging information, but they do simple checking and someday
5669 somebody may make them useful. */
5670
670a50eb
ILT
5671typedef struct loc
5672{
5673 struct loc *loc_next;
5674 unsigned long loc_fileno;
5675 unsigned long loc_lineno;
5676 unsigned long loc_offset;
5677 unsigned short loc_delta;
5678 unsigned short loc_count;
3d3c5039 5679#if 0
670a50eb 5680 fragS *loc_frag;
3d3c5039 5681#endif
670a50eb
ILT
5682}
5683locS;
3d3c5039 5684
670a50eb
ILT
5685typedef struct proc
5686 {
3d3c5039
ILT
5687 struct proc *proc_next;
5688 struct symbol *proc_isym;
5689 struct symbol *proc_end;
5690 unsigned long proc_reg_mask;
5691 unsigned long proc_reg_offset;
5692 unsigned long proc_fpreg_mask;
5693 unsigned long proc_fpreg_offset;
5694 unsigned long proc_frameoffset;
5695 unsigned long proc_framereg;
5696 unsigned long proc_pcreg;
5697 locS *proc_iline;
5698 struct file *proc_file;
5699 int proc_index;
670a50eb
ILT
5700 }
5701procS;
3d3c5039 5702
670a50eb
ILT
5703typedef struct file
5704 {
3d3c5039
ILT
5705 struct file *file_next;
5706 unsigned long file_fileno;
5707 struct symbol *file_symbol;
5708 struct symbol *file_end;
5709 struct proc *file_proc;
5710 int file_numprocs;
670a50eb
ILT
5711 }
5712fileS;
3d3c5039
ILT
5713
5714static struct obstack proc_frags;
5715static procS *proc_lastP;
5716static procS *proc_rootP;
5717static int numprocs;
5718
5719static void
5720md_obj_begin ()
5721{
670a50eb 5722 obstack_begin (&proc_frags, 0x2000);
3d3c5039
ILT
5723}
5724
5725static void
5726md_obj_end ()
5727{
5728 /* check for premature end, nesting errors, etc */
5729 if (proc_lastP && proc_lastP->proc_end == NULL)
670a50eb 5730 as_warn ("missing `.end' at end of assembly");
3d3c5039
ILT
5731}
5732
5733extern char hex_value[];
5734
5735static long
5736get_number ()
5737{
670a50eb
ILT
5738 int negative = 0;
5739 long val = 0;
3d3c5039 5740
670a50eb
ILT
5741 if (*input_line_pointer == '-')
5742 {
5743 ++input_line_pointer;
5744 negative = 1;
3d3c5039 5745 }
670a50eb
ILT
5746 if (!isdigit (*input_line_pointer))
5747 as_bad ("Expected simple number.");
5748 if (input_line_pointer[0] == '0')
5749 {
5750 if (input_line_pointer[1] == 'x')
5751 {
5752 input_line_pointer += 2;
5753 while (isxdigit (*input_line_pointer))
5754 {
5755 val <<= 4;
5756 val |= hex_value[(int) *input_line_pointer++];
3d3c5039 5757 }
670a50eb
ILT
5758 return negative ? -val : val;
5759 }
5760 else
5761 {
5762 ++input_line_pointer;
5763 while (isdigit (*input_line_pointer))
5764 {
5765 val <<= 3;
5766 val |= *input_line_pointer++ - '0';
3d3c5039 5767 }
670a50eb 5768 return negative ? -val : val;
3d3c5039
ILT
5769 }
5770 }
670a50eb
ILT
5771 if (!isdigit (*input_line_pointer))
5772 {
5773 printf (" *input_line_pointer == '%c' 0x%02x\n",
5774 *input_line_pointer, *input_line_pointer);
5775 as_warn ("Invalid number");
5776 return -1;
3d3c5039 5777 }
670a50eb
ILT
5778 while (isdigit (*input_line_pointer))
5779 {
5780 val *= 10;
5781 val += *input_line_pointer++ - '0';
3d3c5039 5782 }
670a50eb 5783 return negative ? -val : val;
3d3c5039
ILT
5784}
5785
5786/* The .file directive; just like the usual .file directive, but there
5787 is an initial number which is the ECOFF file index. */
5788
5789static void
5790s_file (x)
5791 int x;
5792{
670a50eb 5793 int line;
3d3c5039 5794
670a50eb 5795 line = get_number ();
9a7d824a 5796 s_app_file (0);
3d3c5039
ILT
5797}
5798
5799
5800/* The .end directive. */
5801
5802static void
5803s_mipsend (x)
5804 int x;
5805{
670a50eb
ILT
5806 symbolS *p;
5807
5808 if (!is_end_of_line[(unsigned char) *input_line_pointer])
5809 {
5810 p = get_symbol ();
5811 demand_empty_rest_of_line ();
5812 }
5813 else
5814 p = NULL;
5815 if (now_seg != text_section)
5816 as_warn (".end not in text section");
5817 if (!proc_lastP)
5818 {
5819 as_warn (".end and no .ent seen yet.");
5820 return;
3d3c5039
ILT
5821 }
5822
670a50eb
ILT
5823 if (p != NULL)
5824 {
5825 assert (S_GET_NAME (p));
5826 if (strcmp (S_GET_NAME (p), S_GET_NAME (proc_lastP->proc_isym)))
5827 as_warn (".end symbol does not match .ent symbol.");
3d3c5039
ILT
5828 }
5829
670a50eb 5830 proc_lastP->proc_end = (symbolS *) 1;
3d3c5039
ILT
5831}
5832
5833/* The .aent and .ent directives. */
5834
5835static void
5836s_ent (aent)
5837 int aent;
5838{
670a50eb
ILT
5839 int number = 0;
5840 procS *procP;
5841 symbolS *symbolP;
5842
5843 symbolP = get_symbol ();
5844 if (*input_line_pointer == ',')
5845 input_line_pointer++;
dd3f1f76 5846 SKIP_WHITESPACE ();
670a50eb
ILT
5847 if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
5848 number = get_number ();
5849 if (now_seg != text_section)
5850 as_warn (".ent or .aent not in text section.");
5851
5852 if (!aent && proc_lastP && proc_lastP->proc_end == NULL)
5853 as_warn ("missing `.end'");
5854
5855 if (!aent)
5856 {
5857 procP = (procS *) obstack_alloc (&proc_frags, sizeof (*procP));
5858 procP->proc_isym = symbolP;
5859 procP->proc_reg_mask = 0;
5860 procP->proc_reg_offset = 0;
5861 procP->proc_fpreg_mask = 0;
5862 procP->proc_fpreg_offset = 0;
5863 procP->proc_frameoffset = 0;
5864 procP->proc_framereg = 0;
5865 procP->proc_pcreg = 0;
5866 procP->proc_end = NULL;
5867 procP->proc_next = NULL;
5868 if (proc_lastP)
5869 proc_lastP->proc_next = procP;
5870 else
5871 proc_rootP = procP;
5872 proc_lastP = procP;
5873 numprocs++;
3d3c5039 5874 }
670a50eb 5875 demand_empty_rest_of_line ();
3d3c5039
ILT
5876}
5877
5878/* The .frame directive. */
5879
88225433 5880#if 0
3d3c5039
ILT
5881static void
5882s_frame (x)
670a50eb 5883 int x;
3d3c5039 5884{
670a50eb
ILT
5885 char str[100];
5886 symbolS *symP;
5887 int frame_reg;
5888 int frame_off;
5889 int pcreg;
5890
0dd2d296 5891 frame_reg = tc_get_register (1);
670a50eb
ILT
5892 if (*input_line_pointer == ',')
5893 input_line_pointer++;
5ac34ac3 5894 frame_off = get_absolute_expression ();
670a50eb
ILT
5895 if (*input_line_pointer == ',')
5896 input_line_pointer++;
0dd2d296 5897 pcreg = tc_get_register (0);
670a50eb
ILT
5898
5899 /* bob third eye */
5900 assert (proc_rootP);
5901 proc_rootP->proc_framereg = frame_reg;
5902 proc_rootP->proc_frameoffset = frame_off;
5903 proc_rootP->proc_pcreg = pcreg;
5904 /* bob macho .frame */
5905
5906 /* We don't have to write out a frame stab for unoptimized code. */
9226253a 5907 if (!(frame_reg == FP && frame_off == 0))
670a50eb
ILT
5908 {
5909 if (!proc_lastP)
5910 as_warn ("No .ent for .frame to use.");
5911 (void) sprintf (str, "R%d;%d", frame_reg, frame_off);
5912 symP = symbol_new (str, N_VFP, 0, frag_now);
5913 S_SET_TYPE (symP, N_RMASK);
5914 S_SET_OTHER (symP, 0);
5915 S_SET_DESC (symP, 0);
5916 symP->sy_forward = proc_lastP->proc_isym;
5917 /* bob perhaps I should have used pseudo set */
3d3c5039 5918 }
670a50eb 5919 demand_empty_rest_of_line ();
3d3c5039 5920}
88225433 5921#endif
3d3c5039
ILT
5922
5923/* The .fmask and .mask directives. */
5924
88225433 5925#if 0
3d3c5039
ILT
5926static void
5927s_mask (reg_type)
5928 char reg_type;
5929{
670a50eb
ILT
5930 char str[100], *strP;
5931 symbolS *symP;
5932 int i;
5933 unsigned int mask;
5934 int off;
5935
5936 mask = get_number ();
5937 if (*input_line_pointer == ',')
5938 input_line_pointer++;
5939 off = get_absolute_expression ();
5940
5941 /* bob only for coff */
5942 assert (proc_rootP);
5943 if (reg_type == 'F')
5944 {
5945 proc_rootP->proc_fpreg_mask = mask;
5946 proc_rootP->proc_fpreg_offset = off;
3d3c5039 5947 }
670a50eb
ILT
5948 else
5949 {
5950 proc_rootP->proc_reg_mask = mask;
5951 proc_rootP->proc_reg_offset = off;
5952 }
5953
5954 /* bob macho .mask + .fmask */
3d3c5039 5955
670a50eb
ILT
5956 /* We don't have to write out a mask stab if no saved regs. */
5957 if (!(mask == 0))
5958 {
5959 if (!proc_lastP)
5960 as_warn ("No .ent for .mask to use.");
5961 strP = str;
5962 for (i = 0; i < 32; i++)
5963 {
5964 if (mask % 2)
5965 {
5966 sprintf (strP, "%c%d,", reg_type, i);
5967 strP += strlen (strP);
5968 }
3d3c5039 5969 mask /= 2;
670a50eb
ILT
5970 }
5971 sprintf (strP, ";%d,", off);
5972 symP = symbol_new (str, N_RMASK, 0, frag_now);
5973 S_SET_TYPE (symP, N_RMASK);
5974 S_SET_OTHER (symP, 0);
5975 S_SET_DESC (symP, 0);
5976 symP->sy_forward = proc_lastP->proc_isym;
5977 /* bob perhaps I should have used pseudo set */
3d3c5039 5978 }
3d3c5039 5979}
88225433 5980#endif
3d3c5039
ILT
5981
5982/* The .loc directive. */
5983
88225433 5984#if 0
3d3c5039
ILT
5985static void
5986s_loc (x)
5987 int x;
5988{
670a50eb
ILT
5989 symbolS *symbolP;
5990 int lineno;
5991 int addroff;
3d3c5039 5992
670a50eb 5993 assert (now_seg == text_section);
3d3c5039 5994
670a50eb
ILT
5995 lineno = get_number ();
5996 addroff = obstack_next_free (&frags) - frag_now->fr_literal;
3d3c5039 5997
670a50eb
ILT
5998 symbolP = symbol_new ("", N_SLINE, addroff, frag_now);
5999 S_SET_TYPE (symbolP, N_SLINE);
6000 S_SET_OTHER (symbolP, 0);
6001 S_SET_DESC (symbolP, lineno);
6002 symbolP->sy_segment = now_seg;
3d3c5039 6003}
88225433 6004#endif
3d3c5039 6005
0dd2d296 6006#endif /* ! defined (ECOFF_DEBUGGING) */