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