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