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