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