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