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