OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [config/] [tc-alpha.c] - Blame information for rev 825

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2
   Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4
   Contributed by Carnegie Mellon University, 1993.
5
   Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6
   Modified by Ken Raeburn for gas-2.x and ECOFF support.
7
   Modified by Richard Henderson for ELF support.
8
   Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
9
 
10
   This file is part of GAS, the GNU Assembler.
11
 
12
   GAS is free software; you can redistribute it and/or modify
13
   it under the terms of the GNU General Public License as published by
14
   the Free Software Foundation; either version 3, or (at your option)
15
   any later version.
16
 
17
   GAS is distributed in the hope that it will be useful,
18
   but WITHOUT ANY WARRANTY; without even the implied warranty of
19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
   GNU General Public License for more details.
21
 
22
   You should have received a copy of the GNU General Public License
23
   along with GAS; see the file COPYING.  If not, write to the Free
24
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25
   02110-1301, USA.  */
26
 
27
/* Mach Operating System
28
   Copyright (c) 1993 Carnegie Mellon University
29
   All Rights Reserved.
30
 
31
   Permission to use, copy, modify and distribute this software and its
32
   documentation is hereby granted, provided that both the copyright
33
   notice and this permission notice appear in all copies of the
34
   software, derivative works or modified versions, and any portions
35
   thereof, and that both notices appear in supporting documentation.
36
 
37
   CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38
   CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39
   ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40
 
41
   Carnegie Mellon requests users of this software to return to
42
 
43
    Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
44
    School of Computer Science
45
    Carnegie Mellon University
46
    Pittsburgh PA 15213-3890
47
 
48
   any improvements or extensions that they make and grant Carnegie the
49
   rights to redistribute these changes.  */
50
 
51
#include "as.h"
52
#include "subsegs.h"
53
#include "struc-symbol.h"
54
#include "ecoff.h"
55
 
56
#include "opcode/alpha.h"
57
 
58
#ifdef OBJ_ELF
59
#include "elf/alpha.h"
60
#include "dwarf2dbg.h"
61
#endif
62
 
63
#include "dw2gencfi.h"
64
#include "safe-ctype.h"
65
 
66
/* Local types.  */
67
 
68
#define TOKENIZE_ERROR          -1
69
#define TOKENIZE_ERROR_REPORT   -2
70
#define MAX_INSN_FIXUPS          2
71
#define MAX_INSN_ARGS            5
72
 
73
struct alpha_fixup
74
{
75
  expressionS exp;
76
  bfd_reloc_code_real_type reloc;
77
};
78
 
79
struct alpha_insn
80
{
81
  unsigned insn;
82
  int nfixups;
83
  struct alpha_fixup fixups[MAX_INSN_FIXUPS];
84
  long sequence;
85
};
86
 
87
enum alpha_macro_arg
88
  {
89
    MACRO_EOA = 1,
90
    MACRO_IR,
91
    MACRO_PIR,
92
    MACRO_OPIR,
93
    MACRO_CPIR,
94
    MACRO_FPR,
95
    MACRO_EXP,
96
  };
97
 
98
struct alpha_macro
99
{
100
  const char *name;
101
  void (*emit) (const expressionS *, int, const void *);
102
  const void * arg;
103
  enum alpha_macro_arg argsets[16];
104
};
105
 
106
/* Extra expression types.  */
107
 
108
#define O_pregister     O_md1   /* O_register, in parentheses.  */
109
#define O_cpregister    O_md2   /* + a leading comma.  */
110
 
111
/* The alpha_reloc_op table below depends on the ordering of these.  */
112
#define O_literal       O_md3           /* !literal relocation.  */
113
#define O_lituse_addr   O_md4           /* !lituse_addr relocation.  */
114
#define O_lituse_base   O_md5           /* !lituse_base relocation.  */
115
#define O_lituse_bytoff O_md6           /* !lituse_bytoff relocation.  */
116
#define O_lituse_jsr    O_md7           /* !lituse_jsr relocation.  */
117
#define O_lituse_tlsgd  O_md8           /* !lituse_tlsgd relocation.  */
118
#define O_lituse_tlsldm O_md9           /* !lituse_tlsldm relocation.  */
119
#define O_lituse_jsrdirect O_md10       /* !lituse_jsrdirect relocation.  */
120
#define O_gpdisp        O_md11          /* !gpdisp relocation.  */
121
#define O_gprelhigh     O_md12          /* !gprelhigh relocation.  */
122
#define O_gprellow      O_md13          /* !gprellow relocation.  */
123
#define O_gprel         O_md14          /* !gprel relocation.  */
124
#define O_samegp        O_md15          /* !samegp relocation.  */
125
#define O_tlsgd         O_md16          /* !tlsgd relocation.  */
126
#define O_tlsldm        O_md17          /* !tlsldm relocation.  */
127
#define O_gotdtprel     O_md18          /* !gotdtprel relocation.  */
128
#define O_dtprelhi      O_md19          /* !dtprelhi relocation.  */
129
#define O_dtprello      O_md20          /* !dtprello relocation.  */
130
#define O_dtprel        O_md21          /* !dtprel relocation.  */
131
#define O_gottprel      O_md22          /* !gottprel relocation.  */
132
#define O_tprelhi       O_md23          /* !tprelhi relocation.  */
133
#define O_tprello       O_md24          /* !tprello relocation.  */
134
#define O_tprel         O_md25          /* !tprel relocation.  */
135
 
136
#define DUMMY_RELOC_LITUSE_ADDR         (BFD_RELOC_UNUSED + 1)
137
#define DUMMY_RELOC_LITUSE_BASE         (BFD_RELOC_UNUSED + 2)
138
#define DUMMY_RELOC_LITUSE_BYTOFF       (BFD_RELOC_UNUSED + 3)
139
#define DUMMY_RELOC_LITUSE_JSR          (BFD_RELOC_UNUSED + 4)
140
#define DUMMY_RELOC_LITUSE_TLSGD        (BFD_RELOC_UNUSED + 5)
141
#define DUMMY_RELOC_LITUSE_TLSLDM       (BFD_RELOC_UNUSED + 6)
142
#define DUMMY_RELOC_LITUSE_JSRDIRECT    (BFD_RELOC_UNUSED + 7)
143
 
144
#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
145
 
146
/* Macros for extracting the type and number of encoded register tokens.  */
147
 
148
#define is_ir_num(x)            (((x) & 32) == 0)
149
#define is_fpr_num(x)           (((x) & 32) != 0)
150
#define regno(x)                ((x) & 31)
151
 
152
/* Something odd inherited from the old assembler.  */
153
 
154
#define note_gpreg(R)           (alpha_gprmask |= (1 << (R)))
155
#define note_fpreg(R)           (alpha_fprmask |= (1 << (R)))
156
 
157
/* Predicates for 16- and 32-bit ranges */
158
/* XXX: The non-shift version appears to trigger a compiler bug when
159
   cross-assembling from x86 w/ gcc 2.7.2.  */
160
 
161
#if 1
162
#define range_signed_16(x) \
163
        (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
164
#define range_signed_32(x) \
165
        (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
166
#else
167
#define range_signed_16(x)      ((offsetT) (x) >= -(offsetT) 0x8000 &&  \
168
                                 (offsetT) (x) <=  (offsetT) 0x7FFF)
169
#define range_signed_32(x)      ((offsetT) (x) >= -(offsetT) 0x80000000 && \
170
                                 (offsetT) (x) <=  (offsetT) 0x7FFFFFFF)
171
#endif
172
 
173
/* Macros for sign extending from 16- and 32-bits.  */
174
/* XXX: The cast macros will work on all the systems that I care about,
175
   but really a predicate should be found to use the non-cast forms.  */
176
 
177
#if 1
178
#define sign_extend_16(x)       ((short) (x))
179
#define sign_extend_32(x)       ((int) (x))
180
#else
181
#define sign_extend_16(x)       ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
182
#define sign_extend_32(x)       ((offsetT) (((x) & 0xFFFFFFFF) \
183
                                           ^ 0x80000000) - 0x80000000)
184
#endif
185
 
186
/* Macros to build tokens.  */
187
 
188
#define set_tok_reg(t, r)       (memset (&(t), 0, sizeof (t)),          \
189
                                 (t).X_op = O_register,                 \
190
                                 (t).X_add_number = (r))
191
#define set_tok_preg(t, r)      (memset (&(t), 0, sizeof (t)),          \
192
                                 (t).X_op = O_pregister,                \
193
                                 (t).X_add_number = (r))
194
#define set_tok_cpreg(t, r)     (memset (&(t), 0, sizeof (t)),          \
195
                                 (t).X_op = O_cpregister,               \
196
                                 (t).X_add_number = (r))
197
#define set_tok_freg(t, r)      (memset (&(t), 0, sizeof (t)),          \
198
                                 (t).X_op = O_register,                 \
199
                                 (t).X_add_number = (r) + 32)
200
#define set_tok_sym(t, s, a)    (memset (&(t), 0, sizeof (t)),          \
201
                                 (t).X_op = O_symbol,                   \
202
                                 (t).X_add_symbol = (s),                \
203
                                 (t).X_add_number = (a))
204
#define set_tok_const(t, n)     (memset (&(t), 0, sizeof (t)),          \
205
                                 (t).X_op = O_constant,                 \
206
                                 (t).X_add_number = (n))
207
 
208
/* Generic assembler global variables which must be defined by all
209
   targets.  */
210
 
211
/* Characters which always start a comment.  */
212
const char comment_chars[] = "#";
213
 
214
/* Characters which start a comment at the beginning of a line.  */
215
const char line_comment_chars[] = "#";
216
 
217
/* Characters which may be used to separate multiple commands on a
218
   single line.  */
219
const char line_separator_chars[] = ";";
220
 
221
/* Characters which are used to indicate an exponent in a floating
222
   point number.  */
223
const char EXP_CHARS[] = "eE";
224
 
225
/* Characters which mean that a number is a floating point constant,
226
   as in 0d1.0.  */
227
/* XXX: Do all of these really get used on the alpha??  */
228
char FLT_CHARS[] = "rRsSfFdDxXpP";
229
 
230
#ifdef OBJ_EVAX
231
const char *md_shortopts = "Fm:g+1h:HG:";
232
#else
233
const char *md_shortopts = "Fm:gG:";
234
#endif
235
 
236
struct option md_longopts[] =
237
  {
238
#define OPTION_32ADDR (OPTION_MD_BASE)
239
    { "32addr", no_argument, NULL, OPTION_32ADDR },
240
#define OPTION_RELAX (OPTION_32ADDR + 1)
241
    { "relax", no_argument, NULL, OPTION_RELAX },
242
#ifdef OBJ_ELF
243
#define OPTION_MDEBUG (OPTION_RELAX + 1)
244
#define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
245
    { "mdebug", no_argument, NULL, OPTION_MDEBUG },
246
    { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
247
#endif
248
    { NULL, no_argument, NULL, 0 }
249
  };
250
 
251
size_t md_longopts_size = sizeof (md_longopts);
252
 
253
#ifdef OBJ_EVAX
254
#define AXP_REG_R0     0
255
#define AXP_REG_R16    16
256
#define AXP_REG_R17    17
257
#undef AXP_REG_T9
258
#define AXP_REG_T9     22
259
#undef AXP_REG_T10
260
#define AXP_REG_T10    23
261
#undef AXP_REG_T11
262
#define AXP_REG_T11    24
263
#undef AXP_REG_T12
264
#define AXP_REG_T12    25
265
#define AXP_REG_AI     25
266
#undef AXP_REG_FP
267
#define AXP_REG_FP     29
268
 
269
#undef AXP_REG_GP
270
#define AXP_REG_GP AXP_REG_PV
271
#endif /* OBJ_EVAX  */
272
 
273
/* The cpu for which we are generating code.  */
274
static unsigned alpha_target = AXP_OPCODE_BASE;
275
static const char *alpha_target_name = "<all>";
276
 
277
/* The hash table of instruction opcodes.  */
278
static struct hash_control *alpha_opcode_hash;
279
 
280
/* The hash table of macro opcodes.  */
281
static struct hash_control *alpha_macro_hash;
282
 
283
#ifdef OBJ_ECOFF
284
/* The $gp relocation symbol.  */
285
static symbolS *alpha_gp_symbol;
286
 
287
/* XXX: what is this, and why is it exported? */
288
valueT alpha_gp_value;
289
#endif
290
 
291
/* The current $gp register.  */
292
static int alpha_gp_register = AXP_REG_GP;
293
 
294
/* A table of the register symbols.  */
295
static symbolS *alpha_register_table[64];
296
 
297
/* Constant sections, or sections of constants.  */
298
#ifdef OBJ_ECOFF
299
static segT alpha_lita_section;
300
#endif
301
#ifdef OBJ_EVAX
302
static segT alpha_link_section;
303
static segT alpha_ctors_section;
304
static segT alpha_dtors_section;
305
#endif
306
static segT alpha_lit8_section;
307
 
308
/* Symbols referring to said sections.  */
309
#ifdef OBJ_ECOFF
310
static symbolS *alpha_lita_symbol;
311
#endif
312
#ifdef OBJ_EVAX
313
static symbolS *alpha_link_symbol;
314
static symbolS *alpha_ctors_symbol;
315
static symbolS *alpha_dtors_symbol;
316
#endif
317
static symbolS *alpha_lit8_symbol;
318
 
319
/* Literal for .litX+0x8000 within .lita.  */
320
#ifdef OBJ_ECOFF
321
static offsetT alpha_lit8_literal;
322
#endif
323
 
324
/* Is the assembler not allowed to use $at?  */
325
static int alpha_noat_on = 0;
326
 
327
/* Are macros enabled?  */
328
static int alpha_macros_on = 1;
329
 
330
/* Are floats disabled?  */
331
static int alpha_nofloats_on = 0;
332
 
333
/* Are addresses 32 bit?  */
334
static int alpha_addr32_on = 0;
335
 
336
/* Symbol labelling the current insn.  When the Alpha gas sees
337
     foo:
338
       .quad 0
339
   and the section happens to not be on an eight byte boundary, it
340
   will align both the symbol and the .quad to an eight byte boundary.  */
341
static symbolS *alpha_insn_label;
342
 
343
/* Whether we should automatically align data generation pseudo-ops.
344
   .align 0 will turn this off.  */
345
static int alpha_auto_align_on = 1;
346
 
347
/* The known current alignment of the current section.  */
348
static int alpha_current_align;
349
 
350
/* These are exported to ECOFF code.  */
351
unsigned long alpha_gprmask, alpha_fprmask;
352
 
353
/* Whether the debugging option was seen.  */
354
static int alpha_debug;
355
 
356
#ifdef OBJ_ELF
357
/* Whether we are emitting an mdebug section.  */
358
int alpha_flag_mdebug = -1;
359
#endif
360
 
361
/* Don't fully resolve relocations, allowing code movement in the linker.  */
362
static int alpha_flag_relax;
363
 
364
/* What value to give to bfd_set_gp_size.  */
365
static int g_switch_value = 8;
366
 
367
#ifdef OBJ_EVAX
368
/* Collect information about current procedure here.  */
369
static struct
370
{
371
  symbolS *symbol;      /* Proc pdesc symbol.  */
372
  int pdsckind;
373
  int framereg;         /* Register for frame pointer.  */
374
  int framesize;        /* Size of frame.  */
375
  int rsa_offset;
376
  int ra_save;
377
  int fp_save;
378
  long imask;
379
  long fmask;
380
  int type;
381
  int prologue;
382
} alpha_evax_proc;
383
 
384
static int alpha_flag_hash_long_names = 0;               /* -+ */
385
static int alpha_flag_show_after_trunc = 0;              /* -H */
386
 
387
/* If the -+ switch is given, then a hash is appended to any name that is
388
   longer than 64 characters, else longer symbol names are truncated.  */
389
 
390
#endif
391
 
392
#ifdef RELOC_OP_P
393
/* A table to map the spelling of a relocation operand into an appropriate
394
   bfd_reloc_code_real_type type.  The table is assumed to be ordered such
395
   that op-O_literal indexes into it.  */
396
 
397
#define ALPHA_RELOC_TABLE(op)                                           \
398
(&alpha_reloc_op[ ((!USER_RELOC_P (op))                                 \
399
                  ? (abort (), 0)                                        \
400
                  : (int) (op) - (int) O_literal) ])
401
 
402
#define DEF(NAME, RELOC, REQ, ALLOW) \
403
 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
404
 
405
static const struct alpha_reloc_op_tag
406
{
407
  const char *name;                             /* String to lookup.  */
408
  size_t length;                                /* Size of the string.  */
409
  operatorT op;                                 /* Which operator to use.  */
410
  bfd_reloc_code_real_type reloc;               /* Relocation before frob.  */
411
  unsigned int require_seq : 1;                 /* Require a sequence number.  */
412
  unsigned int allow_seq : 1;                   /* Allow a sequence number.  */
413
}
414
alpha_reloc_op[] =
415
{
416
  DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
417
  DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
418
  DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
419
  DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
420
  DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
421
  DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
422
  DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
423
  DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
424
  DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
425
  DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
426
  DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
427
  DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
428
  DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
429
  DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
430
  DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
431
  DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
432
  DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
433
  DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
434
  DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
435
  DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
436
  DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
437
  DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
438
  DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
439
};
440
 
441
#undef DEF
442
 
443
static const int alpha_num_reloc_op
444
  = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
445
#endif /* RELOC_OP_P */
446
 
447
/* Maximum # digits needed to hold the largest sequence #.  */
448
#define ALPHA_RELOC_DIGITS 25
449
 
450
/* Structure to hold explicit sequence information.  */
451
struct alpha_reloc_tag
452
{
453
  fixS *master;                 /* The literal reloc.  */
454
  fixS *slaves;                 /* Head of linked list of lituses.  */
455
  segT segment;                 /* Segment relocs are in or undefined_section.  */
456
  long sequence;                /* Sequence #.  */
457
  unsigned n_master;            /* # of literals.  */
458
  unsigned n_slaves;            /* # of lituses.  */
459
  unsigned saw_tlsgd : 1;       /* True if ...  */
460
  unsigned saw_tlsldm : 1;
461
  unsigned saw_lu_tlsgd : 1;
462
  unsigned saw_lu_tlsldm : 1;
463
  unsigned multi_section_p : 1; /* True if more than one section was used.  */
464
  char string[1];               /* Printable form of sequence to hash with.  */
465
};
466
 
467
/* Hash table to link up literals with the appropriate lituse.  */
468
static struct hash_control *alpha_literal_hash;
469
 
470
/* Sequence numbers for internal use by macros.  */
471
static long next_sequence_num = -1;
472
 
473
/* A table of CPU names and opcode sets.  */
474
 
475
static const struct cpu_type
476
{
477
  const char *name;
478
  unsigned flags;
479
}
480
cpu_types[] =
481
{
482
  /* Ad hoc convention: cpu number gets palcode, process code doesn't.
483
     This supports usage under DU 4.0b that does ".arch ev4", and
484
     usage in MILO that does -m21064.  Probably something more
485
     specific like -m21064-pal should be used, but oh well.  */
486
 
487
  { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
488
  { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
489
  { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
490
  { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
491
  { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
492
  { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
493
  { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
494
                |AXP_OPCODE_MAX) },
495
  { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
496
              |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
497
  { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
498
              |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
499
  { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
500
              |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
501
 
502
  { "ev4", AXP_OPCODE_BASE },
503
  { "ev45", AXP_OPCODE_BASE },
504
  { "lca45", AXP_OPCODE_BASE },
505
  { "ev5", AXP_OPCODE_BASE },
506
  { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
507
  { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
508
  { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
509
  { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
510
  { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
511
 
512
  { "all", AXP_OPCODE_BASE },
513
  { 0, 0 }
514
};
515
 
516
/* Some instruction sets indexed by lg(size).  */
517
static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
518
static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
519
static const char * const insXh_op[] = { NULL,    "inswh", "inslh", "insqh" };
520
static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
521
static const char * const extXh_op[] = { NULL,    "extwh", "extlh", "extqh" };
522
static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
523
static const char * const mskXh_op[] = { NULL,    "mskwh", "msklh", "mskqh" };
524
static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
525
static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
526
 
527
static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type);
528
static void emit_insn (struct alpha_insn *);
529
static void assemble_tokens (const char *, const expressionS *, int, int);
530
 
531
static struct alpha_reloc_tag *
532
get_alpha_reloc_tag (long sequence)
533
{
534
  char buffer[ALPHA_RELOC_DIGITS];
535
  struct alpha_reloc_tag *info;
536
 
537
  sprintf (buffer, "!%ld", sequence);
538
 
539
  info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
540
  if (! info)
541
    {
542
      size_t len = strlen (buffer);
543
      const char *errmsg;
544
 
545
      info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
546
 
547
      info->segment = now_seg;
548
      info->sequence = sequence;
549
      strcpy (info->string, buffer);
550
      errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
551
      if (errmsg)
552
        as_fatal (errmsg);
553
    }
554
 
555
  return info;
556
}
557
 
558
static void
559
alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
560
                     asection *sec,
561
                     void * ptr ATTRIBUTE_UNUSED)
562
{
563
  segment_info_type *seginfo = seg_info (sec);
564
  fixS **prevP;
565
  fixS *fixp;
566
  fixS *next;
567
  fixS *slave;
568
 
569
  /* If seginfo is NULL, we did not create this section; don't do
570
     anything with it.  By using a pointer to a pointer, we can update
571
     the links in place.  */
572
  if (seginfo == NULL)
573
    return;
574
 
575
  /* If there are no relocations, skip the section.  */
576
  if (! seginfo->fix_root)
577
    return;
578
 
579
  /* First rebuild the fixup chain without the explicit lituse and
580
     gpdisp_lo16 relocs.  */
581
  prevP = &seginfo->fix_root;
582
  for (fixp = seginfo->fix_root; fixp; fixp = next)
583
    {
584
      next = fixp->fx_next;
585
      fixp->fx_next = (fixS *) 0;
586
 
587
      switch (fixp->fx_r_type)
588
        {
589
        case BFD_RELOC_ALPHA_LITUSE:
590
          if (fixp->tc_fix_data.info->n_master == 0)
591
            as_bad_where (fixp->fx_file, fixp->fx_line,
592
                          _("No !literal!%ld was found"),
593
                          fixp->tc_fix_data.info->sequence);
594
#ifdef RELOC_OP_P
595
          if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
596
            {
597
              if (! fixp->tc_fix_data.info->saw_tlsgd)
598
                as_bad_where (fixp->fx_file, fixp->fx_line,
599
                              _("No !tlsgd!%ld was found"),
600
                              fixp->tc_fix_data.info->sequence);
601
            }
602
          else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
603
            {
604
              if (! fixp->tc_fix_data.info->saw_tlsldm)
605
                as_bad_where (fixp->fx_file, fixp->fx_line,
606
                              _("No !tlsldm!%ld was found"),
607
                              fixp->tc_fix_data.info->sequence);
608
            }
609
#endif
610
          break;
611
 
612
        case BFD_RELOC_ALPHA_GPDISP_LO16:
613
          if (fixp->tc_fix_data.info->n_master == 0)
614
            as_bad_where (fixp->fx_file, fixp->fx_line,
615
                          _("No ldah !gpdisp!%ld was found"),
616
                          fixp->tc_fix_data.info->sequence);
617
          break;
618
 
619
        case BFD_RELOC_ALPHA_ELF_LITERAL:
620
          if (fixp->tc_fix_data.info
621
              && (fixp->tc_fix_data.info->saw_tlsgd
622
                  || fixp->tc_fix_data.info->saw_tlsldm))
623
            break;
624
          /* FALLTHRU */
625
 
626
        default:
627
          *prevP = fixp;
628
          prevP = &fixp->fx_next;
629
          break;
630
        }
631
    }
632
 
633
  /* Go back and re-chain dependent relocations.  They are currently
634
     linked through the next_reloc field in reverse order, so as we
635
     go through the next_reloc chain, we effectively reverse the chain
636
     once again.
637
 
638
     Except if there is more than one !literal for a given sequence
639
     number.  In that case, the programmer and/or compiler is not sure
640
     how control flows from literal to lituse, and we can't be sure to
641
     get the relaxation correct.
642
 
643
     ??? Well, actually we could, if there are enough lituses such that
644
     we can make each literal have at least one of each lituse type
645
     present.  Not implemented.
646
 
647
     Also suppress the optimization if the !literals/!lituses are spread
648
     in different segments.  This can happen with "intersting" uses of
649
     inline assembly; examples are present in the Linux kernel semaphores.  */
650
 
651
  for (fixp = seginfo->fix_root; fixp; fixp = next)
652
    {
653
      next = fixp->fx_next;
654
      switch (fixp->fx_r_type)
655
        {
656
        case BFD_RELOC_ALPHA_TLSGD:
657
        case BFD_RELOC_ALPHA_TLSLDM:
658
          if (!fixp->tc_fix_data.info)
659
            break;
660
          if (fixp->tc_fix_data.info->n_master == 0)
661
            break;
662
          else if (fixp->tc_fix_data.info->n_master > 1)
663
            {
664
              as_bad_where (fixp->fx_file, fixp->fx_line,
665
                            _("too many !literal!%ld for %s"),
666
                            fixp->tc_fix_data.info->sequence,
667
                            (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
668
                             ? "!tlsgd" : "!tlsldm"));
669
              break;
670
            }
671
 
672
          fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
673
          fixp->fx_next = fixp->tc_fix_data.info->master;
674
          fixp = fixp->fx_next;
675
          /* Fall through.  */
676
 
677
        case BFD_RELOC_ALPHA_ELF_LITERAL:
678
          if (fixp->tc_fix_data.info
679
              && fixp->tc_fix_data.info->n_master == 1
680
              && ! fixp->tc_fix_data.info->multi_section_p)
681
            {
682
              for (slave = fixp->tc_fix_data.info->slaves;
683
                   slave != (fixS *) 0;
684
                   slave = slave->tc_fix_data.next_reloc)
685
                {
686
                  slave->fx_next = fixp->fx_next;
687
                  fixp->fx_next = slave;
688
                }
689
            }
690
          break;
691
 
692
        case BFD_RELOC_ALPHA_GPDISP_HI16:
693
          if (fixp->tc_fix_data.info->n_slaves == 0)
694
            as_bad_where (fixp->fx_file, fixp->fx_line,
695
                          _("No lda !gpdisp!%ld was found"),
696
                          fixp->tc_fix_data.info->sequence);
697
          else
698
            {
699
              slave = fixp->tc_fix_data.info->slaves;
700
              slave->fx_next = next;
701
              fixp->fx_next = slave;
702
            }
703
          break;
704
 
705
        default:
706
          break;
707
        }
708
    }
709
}
710
 
711
/* Before the relocations are written, reorder them, so that user
712
   supplied !lituse relocations follow the appropriate !literal
713
   relocations, and similarly for !gpdisp relocations.  */
714
 
715
void
716
alpha_before_fix (void)
717
{
718
  if (alpha_literal_hash)
719
    bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
720
}
721
 
722
#ifdef DEBUG_ALPHA
723
static void
724
debug_exp (expressionS tok[], int ntok)
725
{
726
  int i;
727
 
728
  fprintf (stderr, "debug_exp: %d tokens", ntok);
729
  for (i = 0; i < ntok; i++)
730
    {
731
      expressionS *t = &tok[i];
732
      const char *name;
733
 
734
      switch (t->X_op)
735
        {
736
        default:                        name = "unknown";               break;
737
        case O_illegal:                 name = "O_illegal";             break;
738
        case O_absent:                  name = "O_absent";              break;
739
        case O_constant:                name = "O_constant";            break;
740
        case O_symbol:                  name = "O_symbol";              break;
741
        case O_symbol_rva:              name = "O_symbol_rva";          break;
742
        case O_register:                name = "O_register";            break;
743
        case O_big:                     name = "O_big";                 break;
744
        case O_uminus:                  name = "O_uminus";              break;
745
        case O_bit_not:                 name = "O_bit_not";             break;
746
        case O_logical_not:             name = "O_logical_not";         break;
747
        case O_multiply:                name = "O_multiply";            break;
748
        case O_divide:                  name = "O_divide";              break;
749
        case O_modulus:                 name = "O_modulus";             break;
750
        case O_left_shift:              name = "O_left_shift";          break;
751
        case O_right_shift:             name = "O_right_shift";         break;
752
        case O_bit_inclusive_or:        name = "O_bit_inclusive_or";    break;
753
        case O_bit_or_not:              name = "O_bit_or_not";          break;
754
        case O_bit_exclusive_or:        name = "O_bit_exclusive_or";    break;
755
        case O_bit_and:                 name = "O_bit_and";             break;
756
        case O_add:                     name = "O_add";                 break;
757
        case O_subtract:                name = "O_subtract";            break;
758
        case O_eq:                      name = "O_eq";                  break;
759
        case O_ne:                      name = "O_ne";                  break;
760
        case O_lt:                      name = "O_lt";                  break;
761
        case O_le:                      name = "O_le";                  break;
762
        case O_ge:                      name = "O_ge";                  break;
763
        case O_gt:                      name = "O_gt";                  break;
764
        case O_logical_and:             name = "O_logical_and";         break;
765
        case O_logical_or:              name = "O_logical_or";          break;
766
        case O_index:                   name = "O_index";               break;
767
        case O_pregister:               name = "O_pregister";           break;
768
        case O_cpregister:              name = "O_cpregister";          break;
769
        case O_literal:                 name = "O_literal";             break;
770
        case O_lituse_addr:             name = "O_lituse_addr";         break;
771
        case O_lituse_base:             name = "O_lituse_base";         break;
772
        case O_lituse_bytoff:           name = "O_lituse_bytoff";       break;
773
        case O_lituse_jsr:              name = "O_lituse_jsr";          break;
774
        case O_lituse_tlsgd:            name = "O_lituse_tlsgd";        break;
775
        case O_lituse_tlsldm:           name = "O_lituse_tlsldm";       break;
776
        case O_lituse_jsrdirect:        name = "O_lituse_jsrdirect";    break;
777
        case O_gpdisp:                  name = "O_gpdisp";              break;
778
        case O_gprelhigh:               name = "O_gprelhigh";           break;
779
        case O_gprellow:                name = "O_gprellow";            break;
780
        case O_gprel:                   name = "O_gprel";               break;
781
        case O_samegp:                  name = "O_samegp";              break;
782
        case O_tlsgd:                   name = "O_tlsgd";               break;
783
        case O_tlsldm:                  name = "O_tlsldm";              break;
784
        case O_gotdtprel:               name = "O_gotdtprel";           break;
785
        case O_dtprelhi:                name = "O_dtprelhi";            break;
786
        case O_dtprello:                name = "O_dtprello";            break;
787
        case O_dtprel:                  name = "O_dtprel";              break;
788
        case O_gottprel:                name = "O_gottprel";            break;
789
        case O_tprelhi:                 name = "O_tprelhi";             break;
790
        case O_tprello:                 name = "O_tprello";             break;
791
        case O_tprel:                   name = "O_tprel";               break;
792
        }
793
 
794
      fprintf (stderr, ", %s(%s, %s, %d)", name,
795
               (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
796
               (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
797
               (int) t->X_add_number);
798
    }
799
  fprintf (stderr, "\n");
800
  fflush (stderr);
801
}
802
#endif
803
 
804
/* Parse the arguments to an opcode.  */
805
 
806
static int
807
tokenize_arguments (char *str,
808
                    expressionS tok[],
809
                    int ntok)
810
{
811
  expressionS *end_tok = tok + ntok;
812
  char *old_input_line_pointer;
813
  int saw_comma = 0, saw_arg = 0;
814
#ifdef DEBUG_ALPHA
815
  expressionS *orig_tok = tok;
816
#endif
817
#ifdef RELOC_OP_P
818
  char *p;
819
  const struct alpha_reloc_op_tag *r;
820
  int c, i;
821
  size_t len;
822
  int reloc_found_p = 0;
823
#endif
824
 
825
  memset (tok, 0, sizeof (*tok) * ntok);
826
 
827
  /* Save and restore input_line_pointer around this function.  */
828
  old_input_line_pointer = input_line_pointer;
829
  input_line_pointer = str;
830
 
831
#ifdef RELOC_OP_P
832
  /* ??? Wrest control of ! away from the regular expression parser.  */
833
  is_end_of_line[(unsigned char) '!'] = 1;
834
#endif
835
 
836
  while (tok < end_tok && *input_line_pointer)
837
    {
838
      SKIP_WHITESPACE ();
839
      switch (*input_line_pointer)
840
        {
841
        case '\0':
842
          goto fini;
843
 
844
#ifdef RELOC_OP_P
845
        case '!':
846
          /* A relocation operand can be placed after the normal operand on an
847
             assembly language statement, and has the following form:
848
                !relocation_type!sequence_number.  */
849
          if (reloc_found_p)
850
            {
851
              /* Only support one relocation op per insn.  */
852
              as_bad (_("More than one relocation op per insn"));
853
              goto err_report;
854
            }
855
 
856
          if (!saw_arg)
857
            goto err;
858
 
859
          ++input_line_pointer;
860
          SKIP_WHITESPACE ();
861
          p = input_line_pointer;
862
          c = get_symbol_end ();
863
 
864
          /* Parse !relocation_type.  */
865
          len = input_line_pointer - p;
866
          if (len == 0)
867
            {
868
              as_bad (_("No relocation operand"));
869
              goto err_report;
870
            }
871
 
872
          r = &alpha_reloc_op[0];
873
          for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
874
            if (len == r->length && memcmp (p, r->name, len) == 0)
875
              break;
876
          if (i < 0)
877
            {
878
              as_bad (_("Unknown relocation operand: !%s"), p);
879
              goto err_report;
880
            }
881
 
882
          *input_line_pointer = c;
883
          SKIP_WHITESPACE ();
884
          if (*input_line_pointer != '!')
885
            {
886
              if (r->require_seq)
887
                {
888
                  as_bad (_("no sequence number after !%s"), p);
889
                  goto err_report;
890
                }
891
 
892
              tok->X_add_number = 0;
893
            }
894
          else
895
            {
896
              if (! r->allow_seq)
897
                {
898
                  as_bad (_("!%s does not use a sequence number"), p);
899
                  goto err_report;
900
                }
901
 
902
              input_line_pointer++;
903
 
904
              /* Parse !sequence_number.  */
905
              expression (tok);
906
              if (tok->X_op != O_constant || tok->X_add_number <= 0)
907
                {
908
                  as_bad (_("Bad sequence number: !%s!%s"),
909
                          r->name, input_line_pointer);
910
                  goto err_report;
911
                }
912
            }
913
 
914
          tok->X_op = r->op;
915
          reloc_found_p = 1;
916
          ++tok;
917
          break;
918
#endif /* RELOC_OP_P */
919
 
920
        case ',':
921
          ++input_line_pointer;
922
          if (saw_comma || !saw_arg)
923
            goto err;
924
          saw_comma = 1;
925
          break;
926
 
927
        case '(':
928
          {
929
            char *hold = input_line_pointer++;
930
 
931
            /* First try for parenthesized register ...  */
932
            expression (tok);
933
            if (*input_line_pointer == ')' && tok->X_op == O_register)
934
              {
935
                tok->X_op = (saw_comma ? O_cpregister : O_pregister);
936
                saw_comma = 0;
937
                saw_arg = 1;
938
                ++input_line_pointer;
939
                ++tok;
940
                break;
941
              }
942
 
943
            /* ... then fall through to plain expression.  */
944
            input_line_pointer = hold;
945
          }
946
 
947
        default:
948
          if (saw_arg && !saw_comma)
949
            goto err;
950
 
951
          expression (tok);
952
          if (tok->X_op == O_illegal || tok->X_op == O_absent)
953
            goto err;
954
 
955
          saw_comma = 0;
956
          saw_arg = 1;
957
          ++tok;
958
          break;
959
        }
960
    }
961
 
962
fini:
963
  if (saw_comma)
964
    goto err;
965
  input_line_pointer = old_input_line_pointer;
966
 
967
#ifdef DEBUG_ALPHA
968
  debug_exp (orig_tok, ntok - (end_tok - tok));
969
#endif
970
#ifdef RELOC_OP_P
971
  is_end_of_line[(unsigned char) '!'] = 0;
972
#endif
973
 
974
  return ntok - (end_tok - tok);
975
 
976
err:
977
#ifdef RELOC_OP_P
978
  is_end_of_line[(unsigned char) '!'] = 0;
979
#endif
980
  input_line_pointer = old_input_line_pointer;
981
  return TOKENIZE_ERROR;
982
 
983
#ifdef RELOC_OP_P
984
err_report:
985
  is_end_of_line[(unsigned char) '!'] = 0;
986
#endif
987
  input_line_pointer = old_input_line_pointer;
988
  return TOKENIZE_ERROR_REPORT;
989
}
990
 
991
/* Search forward through all variants of an opcode looking for a
992
   syntax match.  */
993
 
994
static const struct alpha_opcode *
995
find_opcode_match (const struct alpha_opcode *first_opcode,
996
                   const expressionS *tok,
997
                   int *pntok,
998
                   int *pcpumatch)
999
{
1000
  const struct alpha_opcode *opcode = first_opcode;
1001
  int ntok = *pntok;
1002
  int got_cpu_match = 0;
1003
 
1004
  do
1005
    {
1006
      const unsigned char *opidx;
1007
      int tokidx = 0;
1008
 
1009
      /* Don't match opcodes that don't exist on this architecture.  */
1010
      if (!(opcode->flags & alpha_target))
1011
        goto match_failed;
1012
 
1013
      got_cpu_match = 1;
1014
 
1015
      for (opidx = opcode->operands; *opidx; ++opidx)
1016
        {
1017
          const struct alpha_operand *operand = &alpha_operands[*opidx];
1018
 
1019
          /* Only take input from real operands.  */
1020
          if (operand->flags & AXP_OPERAND_FAKE)
1021
            continue;
1022
 
1023
          /* When we expect input, make sure we have it.  */
1024
          if (tokidx >= ntok)
1025
            {
1026
              if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1027
                goto match_failed;
1028
              continue;
1029
            }
1030
 
1031
          /* Match operand type with expression type.  */
1032
          switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1033
            {
1034
            case AXP_OPERAND_IR:
1035
              if (tok[tokidx].X_op != O_register
1036
                  || !is_ir_num (tok[tokidx].X_add_number))
1037
                goto match_failed;
1038
              break;
1039
            case AXP_OPERAND_FPR:
1040
              if (tok[tokidx].X_op != O_register
1041
                  || !is_fpr_num (tok[tokidx].X_add_number))
1042
                goto match_failed;
1043
              break;
1044
            case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1045
              if (tok[tokidx].X_op != O_pregister
1046
                  || !is_ir_num (tok[tokidx].X_add_number))
1047
                goto match_failed;
1048
              break;
1049
            case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1050
              if (tok[tokidx].X_op != O_cpregister
1051
                  || !is_ir_num (tok[tokidx].X_add_number))
1052
                goto match_failed;
1053
              break;
1054
 
1055
            case AXP_OPERAND_RELATIVE:
1056
            case AXP_OPERAND_SIGNED:
1057
            case AXP_OPERAND_UNSIGNED:
1058
              switch (tok[tokidx].X_op)
1059
                {
1060
                case O_illegal:
1061
                case O_absent:
1062
                case O_register:
1063
                case O_pregister:
1064
                case O_cpregister:
1065
                  goto match_failed;
1066
 
1067
                default:
1068
                  break;
1069
                }
1070
              break;
1071
 
1072
            default:
1073
              /* Everything else should have been fake.  */
1074
              abort ();
1075
            }
1076
          ++tokidx;
1077
        }
1078
 
1079
      /* Possible match -- did we use all of our input?  */
1080
      if (tokidx == ntok)
1081
        {
1082
          *pntok = ntok;
1083
          return opcode;
1084
        }
1085
 
1086
    match_failed:;
1087
    }
1088
  while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1089
         && !strcmp (opcode->name, first_opcode->name));
1090
 
1091
  if (*pcpumatch)
1092
    *pcpumatch = got_cpu_match;
1093
 
1094
  return NULL;
1095
}
1096
 
1097
/* Given an opcode name and a pre-tokenized set of arguments, assemble
1098
   the insn, but do not emit it.
1099
 
1100
   Note that this implies no macros allowed, since we can't store more
1101
   than one insn in an insn structure.  */
1102
 
1103
static void
1104
assemble_tokens_to_insn (const char *opname,
1105
                         const expressionS *tok,
1106
                         int ntok,
1107
                         struct alpha_insn *insn)
1108
{
1109
  const struct alpha_opcode *opcode;
1110
 
1111
  /* Search opcodes.  */
1112
  opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1113
  if (opcode)
1114
    {
1115
      int cpumatch;
1116
      opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1117
      if (opcode)
1118
        {
1119
          assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1120
          return;
1121
        }
1122
      else if (cpumatch)
1123
        as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1124
      else
1125
        as_bad (_("opcode `%s' not supported for target %s"), opname,
1126
                alpha_target_name);
1127
    }
1128
  else
1129
    as_bad (_("unknown opcode `%s'"), opname);
1130
}
1131
 
1132
/* Build a BFD section with its flags set appropriately for the .lita,
1133
   .lit8, or .lit4 sections.  */
1134
 
1135
static void
1136
create_literal_section (const char *name,
1137
                        segT *secp,
1138
                        symbolS **symp)
1139
{
1140
  segT current_section = now_seg;
1141
  int current_subsec = now_subseg;
1142
  segT new_sec;
1143
 
1144
  *secp = new_sec = subseg_new (name, 0);
1145
  subseg_set (current_section, current_subsec);
1146
  bfd_set_section_alignment (stdoutput, new_sec, 4);
1147
  bfd_set_section_flags (stdoutput, new_sec,
1148
                         SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1149
                         | SEC_DATA);
1150
 
1151
  S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1152
}
1153
 
1154
/* Load a (partial) expression into a target register.
1155
 
1156
   If poffset is not null, after the call it will either contain
1157
   O_constant 0, or a 16-bit offset appropriate for any MEM format
1158
   instruction.  In addition, pbasereg will be modified to point to
1159
   the base register to use in that MEM format instruction.
1160
 
1161
   In any case, *pbasereg should contain a base register to add to the
1162
   expression.  This will normally be either AXP_REG_ZERO or
1163
   alpha_gp_register.  Symbol addresses will always be loaded via $gp,
1164
   so "foo($0)" is interpreted as adding the address of foo to $0;
1165
   i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ".  Odd, perhaps,
1166
   but this is what OSF/1 does.
1167
 
1168
   If explicit relocations of the form !literal!<number> are allowed,
1169
   and used, then explicit_reloc with be an expression pointer.
1170
 
1171
   Finally, the return value is nonzero if the calling macro may emit
1172
   a LITUSE reloc if otherwise appropriate; the return value is the
1173
   sequence number to use.  */
1174
 
1175
static long
1176
load_expression (int targreg,
1177
                 const expressionS *exp,
1178
                 int *pbasereg,
1179
                 expressionS *poffset)
1180
{
1181
  long emit_lituse = 0;
1182
  offsetT addend = exp->X_add_number;
1183
  int basereg = *pbasereg;
1184
  struct alpha_insn insn;
1185
  expressionS newtok[3];
1186
 
1187
  switch (exp->X_op)
1188
    {
1189
    case O_symbol:
1190
      {
1191
#ifdef OBJ_ECOFF
1192
        offsetT lit;
1193
 
1194
        /* Attempt to reduce .lit load by splitting the offset from
1195
           its symbol when possible, but don't create a situation in
1196
           which we'd fail.  */
1197
        if (!range_signed_32 (addend) &&
1198
            (alpha_noat_on || targreg == AXP_REG_AT))
1199
          {
1200
            lit = add_to_literal_pool (exp->X_add_symbol, addend,
1201
                                       alpha_lita_section, 8);
1202
            addend = 0;
1203
          }
1204
        else
1205
          lit = add_to_literal_pool (exp->X_add_symbol, 0,
1206
                                     alpha_lita_section, 8);
1207
 
1208
        if (lit >= 0x8000)
1209
          as_fatal (_("overflow in literal (.lita) table"));
1210
 
1211
        /* Emit "ldq r, lit(gp)".  */
1212
 
1213
        if (basereg != alpha_gp_register && targreg == basereg)
1214
          {
1215
            if (alpha_noat_on)
1216
              as_bad (_("macro requires $at register while noat in effect"));
1217
            if (targreg == AXP_REG_AT)
1218
              as_bad (_("macro requires $at while $at in use"));
1219
 
1220
            set_tok_reg (newtok[0], AXP_REG_AT);
1221
          }
1222
        else
1223
          set_tok_reg (newtok[0], targreg);
1224
 
1225
        set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1226
        set_tok_preg (newtok[2], alpha_gp_register);
1227
 
1228
        assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1229
 
1230
        assert (insn.nfixups == 1);
1231
        insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1232
        insn.sequence = emit_lituse = next_sequence_num--;
1233
#endif /* OBJ_ECOFF */
1234
#ifdef OBJ_ELF
1235
        /* Emit "ldq r, gotoff(gp)".  */
1236
 
1237
        if (basereg != alpha_gp_register && targreg == basereg)
1238
          {
1239
            if (alpha_noat_on)
1240
              as_bad (_("macro requires $at register while noat in effect"));
1241
            if (targreg == AXP_REG_AT)
1242
              as_bad (_("macro requires $at while $at in use"));
1243
 
1244
            set_tok_reg (newtok[0], AXP_REG_AT);
1245
          }
1246
        else
1247
          set_tok_reg (newtok[0], targreg);
1248
 
1249
        /* XXX: Disable this .got minimizing optimization so that we can get
1250
           better instruction offset knowledge in the compiler.  This happens
1251
           very infrequently anyway.  */
1252
        if (1
1253
            || (!range_signed_32 (addend)
1254
                && (alpha_noat_on || targreg == AXP_REG_AT)))
1255
          {
1256
            newtok[1] = *exp;
1257
            addend = 0;
1258
          }
1259
        else
1260
          set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1261
 
1262
        set_tok_preg (newtok[2], alpha_gp_register);
1263
 
1264
        assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1265
 
1266
        assert (insn.nfixups == 1);
1267
        insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1268
        insn.sequence = emit_lituse = next_sequence_num--;
1269
#endif /* OBJ_ELF */
1270
#ifdef OBJ_EVAX
1271
        offsetT link;
1272
 
1273
        /* Find symbol or symbol pointer in link section.  */
1274
 
1275
        if (exp->X_add_symbol == alpha_evax_proc.symbol)
1276
          {
1277
            if (range_signed_16 (addend))
1278
              {
1279
                set_tok_reg (newtok[0], targreg);
1280
                set_tok_const (newtok[1], addend);
1281
                set_tok_preg (newtok[2], basereg);
1282
                assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1283
                addend = 0;
1284
              }
1285
            else
1286
              {
1287
                set_tok_reg (newtok[0], targreg);
1288
                set_tok_const (newtok[1], 0);
1289
                set_tok_preg (newtok[2], basereg);
1290
                assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1291
              }
1292
          }
1293
        else
1294
          {
1295
            if (!range_signed_32 (addend))
1296
              {
1297
                link = add_to_link_pool (alpha_evax_proc.symbol,
1298
                                         exp->X_add_symbol, addend);
1299
                addend = 0;
1300
              }
1301
            else
1302
              link = add_to_link_pool (alpha_evax_proc.symbol,
1303
                                       exp->X_add_symbol, 0);
1304
 
1305
            set_tok_reg (newtok[0], targreg);
1306
            set_tok_const (newtok[1], link);
1307
            set_tok_preg (newtok[2], basereg);
1308
            assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1309
          }
1310
#endif /* OBJ_EVAX */
1311
 
1312
        emit_insn (&insn);
1313
 
1314
#ifndef OBJ_EVAX
1315
        if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1316
          {
1317
            /* Emit "addq r, base, r".  */
1318
 
1319
            set_tok_reg (newtok[1], basereg);
1320
            set_tok_reg (newtok[2], targreg);
1321
            assemble_tokens ("addq", newtok, 3, 0);
1322
          }
1323
#endif
1324
        basereg = targreg;
1325
      }
1326
      break;
1327
 
1328
    case O_constant:
1329
      break;
1330
 
1331
    case O_subtract:
1332
      /* Assume that this difference expression will be resolved to an
1333
         absolute value and that that value will fit in 16 bits.  */
1334
 
1335
      set_tok_reg (newtok[0], targreg);
1336
      newtok[1] = *exp;
1337
      set_tok_preg (newtok[2], basereg);
1338
      assemble_tokens ("lda", newtok, 3, 0);
1339
 
1340
      if (poffset)
1341
        set_tok_const (*poffset, 0);
1342
      return 0;
1343
 
1344
    case O_big:
1345
      if (exp->X_add_number > 0)
1346
        as_bad (_("bignum invalid; zero assumed"));
1347
      else
1348
        as_bad (_("floating point number invalid; zero assumed"));
1349
      addend = 0;
1350
      break;
1351
 
1352
    default:
1353
      as_bad (_("can't handle expression"));
1354
      addend = 0;
1355
      break;
1356
    }
1357
 
1358
  if (!range_signed_32 (addend))
1359
    {
1360
      offsetT lit;
1361
      long seq_num = next_sequence_num--;
1362
 
1363
      /* For 64-bit addends, just put it in the literal pool.  */
1364
#ifdef OBJ_EVAX
1365
      /* Emit "ldq targreg, lit(basereg)".  */
1366
      lit = add_to_link_pool (alpha_evax_proc.symbol,
1367
                              section_symbol (absolute_section), addend);
1368
      set_tok_reg (newtok[0], targreg);
1369
      set_tok_const (newtok[1], lit);
1370
      set_tok_preg (newtok[2], alpha_gp_register);
1371
      assemble_tokens ("ldq", newtok, 3, 0);
1372
#else
1373
 
1374
      if (alpha_lit8_section == NULL)
1375
        {
1376
          create_literal_section (".lit8",
1377
                                  &alpha_lit8_section,
1378
                                  &alpha_lit8_symbol);
1379
 
1380
#ifdef OBJ_ECOFF
1381
          alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1382
                                                    alpha_lita_section, 8);
1383
          if (alpha_lit8_literal >= 0x8000)
1384
            as_fatal (_("overflow in literal (.lita) table"));
1385
#endif
1386
        }
1387
 
1388
      lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1389
      if (lit >= 0x8000)
1390
        as_fatal (_("overflow in literal (.lit8) table"));
1391
 
1392
      /* Emit "lda litreg, .lit8+0x8000".  */
1393
 
1394
      if (targreg == basereg)
1395
        {
1396
          if (alpha_noat_on)
1397
            as_bad (_("macro requires $at register while noat in effect"));
1398
          if (targreg == AXP_REG_AT)
1399
            as_bad (_("macro requires $at while $at in use"));
1400
 
1401
          set_tok_reg (newtok[0], AXP_REG_AT);
1402
        }
1403
      else
1404
        set_tok_reg (newtok[0], targreg);
1405
#ifdef OBJ_ECOFF
1406
      set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1407
#endif
1408
#ifdef OBJ_ELF
1409
      set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1410
#endif
1411
      set_tok_preg (newtok[2], alpha_gp_register);
1412
 
1413
      assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1414
 
1415
      assert (insn.nfixups == 1);
1416
#ifdef OBJ_ECOFF
1417
      insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1418
#endif
1419
#ifdef OBJ_ELF
1420
      insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1421
#endif
1422
      insn.sequence = seq_num;
1423
 
1424
      emit_insn (&insn);
1425
 
1426
      /* Emit "ldq litreg, lit(litreg)".  */
1427
 
1428
      set_tok_const (newtok[1], lit);
1429
      set_tok_preg (newtok[2], newtok[0].X_add_number);
1430
 
1431
      assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1432
 
1433
      assert (insn.nfixups < MAX_INSN_FIXUPS);
1434
      insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1435
      insn.fixups[insn.nfixups].exp.X_op = O_absent;
1436
      insn.nfixups++;
1437
      insn.sequence = seq_num;
1438
      emit_lituse = 0;
1439
 
1440
      emit_insn (&insn);
1441
 
1442
      /* Emit "addq litreg, base, target".  */
1443
 
1444
      if (basereg != AXP_REG_ZERO)
1445
        {
1446
          set_tok_reg (newtok[1], basereg);
1447
          set_tok_reg (newtok[2], targreg);
1448
          assemble_tokens ("addq", newtok, 3, 0);
1449
        }
1450
#endif /* !OBJ_EVAX */
1451
 
1452
      if (poffset)
1453
        set_tok_const (*poffset, 0);
1454
      *pbasereg = targreg;
1455
    }
1456
  else
1457
    {
1458
      offsetT low, high, extra, tmp;
1459
 
1460
      /* For 32-bit operands, break up the addend.  */
1461
 
1462
      low = sign_extend_16 (addend);
1463
      tmp = addend - low;
1464
      high = sign_extend_16 (tmp >> 16);
1465
 
1466
      if (tmp - (high << 16))
1467
        {
1468
          extra = 0x4000;
1469
          tmp -= 0x40000000;
1470
          high = sign_extend_16 (tmp >> 16);
1471
        }
1472
      else
1473
        extra = 0;
1474
 
1475
      set_tok_reg (newtok[0], targreg);
1476
      set_tok_preg (newtok[2], basereg);
1477
 
1478
      if (extra)
1479
        {
1480
          /* Emit "ldah r, extra(r).  */
1481
          set_tok_const (newtok[1], extra);
1482
          assemble_tokens ("ldah", newtok, 3, 0);
1483
          set_tok_preg (newtok[2], basereg = targreg);
1484
        }
1485
 
1486
      if (high)
1487
        {
1488
          /* Emit "ldah r, high(r).  */
1489
          set_tok_const (newtok[1], high);
1490
          assemble_tokens ("ldah", newtok, 3, 0);
1491
          basereg = targreg;
1492
          set_tok_preg (newtok[2], basereg);
1493
        }
1494
 
1495
      if ((low && !poffset) || (!poffset && basereg != targreg))
1496
        {
1497
          /* Emit "lda r, low(base)".  */
1498
          set_tok_const (newtok[1], low);
1499
          assemble_tokens ("lda", newtok, 3, 0);
1500
          basereg = targreg;
1501
          low = 0;
1502
        }
1503
 
1504
      if (poffset)
1505
        set_tok_const (*poffset, low);
1506
      *pbasereg = basereg;
1507
    }
1508
 
1509
  return emit_lituse;
1510
}
1511
 
1512
/* The lda macro differs from the lda instruction in that it handles
1513
   most simple expressions, particularly symbol address loads and
1514
   large constants.  */
1515
 
1516
static void
1517
emit_lda (const expressionS *tok,
1518
          int ntok,
1519
          const void * unused ATTRIBUTE_UNUSED)
1520
{
1521
  int basereg;
1522
 
1523
  if (ntok == 2)
1524
    basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1525
  else
1526
    basereg = tok[2].X_add_number;
1527
 
1528
  (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
1529
}
1530
 
1531
/* The ldah macro differs from the ldah instruction in that it has $31
1532
   as an implied base register.  */
1533
 
1534
static void
1535
emit_ldah (const expressionS *tok,
1536
           int ntok ATTRIBUTE_UNUSED,
1537
           const void * unused ATTRIBUTE_UNUSED)
1538
{
1539
  expressionS newtok[3];
1540
 
1541
  newtok[0] = tok[0];
1542
  newtok[1] = tok[1];
1543
  set_tok_preg (newtok[2], AXP_REG_ZERO);
1544
 
1545
  assemble_tokens ("ldah", newtok, 3, 0);
1546
}
1547
 
1548
/* Called internally to handle all alignment needs.  This takes care
1549
   of eliding calls to frag_align if'n the cached current alignment
1550
   says we've already got it, as well as taking care of the auto-align
1551
   feature wrt labels.  */
1552
 
1553
static void
1554
alpha_align (int n,
1555
             char *pfill,
1556
             symbolS *label,
1557
             int force ATTRIBUTE_UNUSED)
1558
{
1559
  if (alpha_current_align >= n)
1560
    return;
1561
 
1562
  if (pfill == NULL)
1563
    {
1564
      if (subseg_text_p (now_seg))
1565
        frag_align_code (n, 0);
1566
      else
1567
        frag_align (n, 0, 0);
1568
    }
1569
  else
1570
    frag_align (n, *pfill, 0);
1571
 
1572
  alpha_current_align = n;
1573
 
1574
  if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1575
    {
1576
      symbol_set_frag (label, frag_now);
1577
      S_SET_VALUE (label, (valueT) frag_now_fix ());
1578
    }
1579
 
1580
  record_alignment (now_seg, n);
1581
 
1582
  /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1583
     in a reloc for the linker to see.  */
1584
}
1585
 
1586
/* Actually output an instruction with its fixup.  */
1587
 
1588
static void
1589
emit_insn (struct alpha_insn *insn)
1590
{
1591
  char *f;
1592
  int i;
1593
 
1594
  /* Take care of alignment duties.  */
1595
  if (alpha_auto_align_on && alpha_current_align < 2)
1596
    alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1597
  if (alpha_current_align > 2)
1598
    alpha_current_align = 2;
1599
  alpha_insn_label = NULL;
1600
 
1601
  /* Write out the instruction.  */
1602
  f = frag_more (4);
1603
  md_number_to_chars (f, insn->insn, 4);
1604
 
1605
#ifdef OBJ_ELF
1606
  dwarf2_emit_insn (4);
1607
#endif
1608
 
1609
  /* Apply the fixups in order.  */
1610
  for (i = 0; i < insn->nfixups; ++i)
1611
    {
1612
      const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1613
      struct alpha_fixup *fixup = &insn->fixups[i];
1614
      struct alpha_reloc_tag *info = NULL;
1615
      int size, pcrel;
1616
      fixS *fixP;
1617
 
1618
      /* Some fixups are only used internally and so have no howto.  */
1619
      if ((int) fixup->reloc < 0)
1620
        {
1621
          operand = &alpha_operands[-(int) fixup->reloc];
1622
          size = 4;
1623
          pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1624
        }
1625
      else if (fixup->reloc > BFD_RELOC_UNUSED
1626
               || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1627
               || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1628
        {
1629
          size = 2;
1630
          pcrel = 0;
1631
        }
1632
      else
1633
        {
1634
          reloc_howto_type *reloc_howto
1635
            = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1636
          assert (reloc_howto);
1637
 
1638
          size = bfd_get_reloc_size (reloc_howto);
1639
          assert (size >= 1 && size <= 4);
1640
 
1641
          pcrel = reloc_howto->pc_relative;
1642
        }
1643
 
1644
      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1645
                          &fixup->exp, pcrel, fixup->reloc);
1646
 
1647
      /* Turn off complaints that the addend is too large for some fixups,
1648
         and copy in the sequence number for the explicit relocations.  */
1649
      switch (fixup->reloc)
1650
        {
1651
        case BFD_RELOC_ALPHA_HINT:
1652
        case BFD_RELOC_GPREL32:
1653
        case BFD_RELOC_GPREL16:
1654
        case BFD_RELOC_ALPHA_GPREL_HI16:
1655
        case BFD_RELOC_ALPHA_GPREL_LO16:
1656
        case BFD_RELOC_ALPHA_GOTDTPREL16:
1657
        case BFD_RELOC_ALPHA_DTPREL_HI16:
1658
        case BFD_RELOC_ALPHA_DTPREL_LO16:
1659
        case BFD_RELOC_ALPHA_DTPREL16:
1660
        case BFD_RELOC_ALPHA_GOTTPREL16:
1661
        case BFD_RELOC_ALPHA_TPREL_HI16:
1662
        case BFD_RELOC_ALPHA_TPREL_LO16:
1663
        case BFD_RELOC_ALPHA_TPREL16:
1664
          fixP->fx_no_overflow = 1;
1665
          break;
1666
 
1667
        case BFD_RELOC_ALPHA_GPDISP_HI16:
1668
          fixP->fx_no_overflow = 1;
1669
          fixP->fx_addsy = section_symbol (now_seg);
1670
          fixP->fx_offset = 0;
1671
 
1672
          info = get_alpha_reloc_tag (insn->sequence);
1673
          if (++info->n_master > 1)
1674
            as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1675
          if (info->segment != now_seg)
1676
            as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1677
                    insn->sequence);
1678
          fixP->tc_fix_data.info = info;
1679
          break;
1680
 
1681
        case BFD_RELOC_ALPHA_GPDISP_LO16:
1682
          fixP->fx_no_overflow = 1;
1683
 
1684
          info = get_alpha_reloc_tag (insn->sequence);
1685
          if (++info->n_slaves > 1)
1686
            as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1687
          if (info->segment != now_seg)
1688
            as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1689
                    insn->sequence);
1690
          fixP->tc_fix_data.info = info;
1691
          info->slaves = fixP;
1692
          break;
1693
 
1694
        case BFD_RELOC_ALPHA_LITERAL:
1695
        case BFD_RELOC_ALPHA_ELF_LITERAL:
1696
          fixP->fx_no_overflow = 1;
1697
 
1698
          if (insn->sequence == 0)
1699
            break;
1700
          info = get_alpha_reloc_tag (insn->sequence);
1701
          info->master = fixP;
1702
          info->n_master++;
1703
          if (info->segment != now_seg)
1704
            info->multi_section_p = 1;
1705
          fixP->tc_fix_data.info = info;
1706
          break;
1707
 
1708
#ifdef RELOC_OP_P
1709
        case DUMMY_RELOC_LITUSE_ADDR:
1710
          fixP->fx_offset = LITUSE_ALPHA_ADDR;
1711
          goto do_lituse;
1712
        case DUMMY_RELOC_LITUSE_BASE:
1713
          fixP->fx_offset = LITUSE_ALPHA_BASE;
1714
          goto do_lituse;
1715
        case DUMMY_RELOC_LITUSE_BYTOFF:
1716
          fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1717
          goto do_lituse;
1718
        case DUMMY_RELOC_LITUSE_JSR:
1719
          fixP->fx_offset = LITUSE_ALPHA_JSR;
1720
          goto do_lituse;
1721
        case DUMMY_RELOC_LITUSE_TLSGD:
1722
          fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1723
          goto do_lituse;
1724
        case DUMMY_RELOC_LITUSE_TLSLDM:
1725
          fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1726
          goto do_lituse;
1727
        case DUMMY_RELOC_LITUSE_JSRDIRECT:
1728
          fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
1729
          goto do_lituse;
1730
        do_lituse:
1731
          fixP->fx_addsy = section_symbol (now_seg);
1732
          fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1733
 
1734
          info = get_alpha_reloc_tag (insn->sequence);
1735
          if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1736
            info->saw_lu_tlsgd = 1;
1737
          else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1738
            info->saw_lu_tlsldm = 1;
1739
          if (++info->n_slaves > 1)
1740
            {
1741
              if (info->saw_lu_tlsgd)
1742
                as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1743
                        insn->sequence);
1744
              else if (info->saw_lu_tlsldm)
1745
                as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1746
                        insn->sequence);
1747
            }
1748
          fixP->tc_fix_data.info = info;
1749
          fixP->tc_fix_data.next_reloc = info->slaves;
1750
          info->slaves = fixP;
1751
          if (info->segment != now_seg)
1752
            info->multi_section_p = 1;
1753
          break;
1754
 
1755
        case BFD_RELOC_ALPHA_TLSGD:
1756
          fixP->fx_no_overflow = 1;
1757
 
1758
          if (insn->sequence == 0)
1759
            break;
1760
          info = get_alpha_reloc_tag (insn->sequence);
1761
          if (info->saw_tlsgd)
1762
            as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1763
          else if (info->saw_tlsldm)
1764
            as_bad (_("sequence number in use for !tlsldm!%ld"),
1765
                    insn->sequence);
1766
          else
1767
            info->saw_tlsgd = 1;
1768
          fixP->tc_fix_data.info = info;
1769
          break;
1770
 
1771
        case BFD_RELOC_ALPHA_TLSLDM:
1772
          fixP->fx_no_overflow = 1;
1773
 
1774
          if (insn->sequence == 0)
1775
            break;
1776
          info = get_alpha_reloc_tag (insn->sequence);
1777
          if (info->saw_tlsldm)
1778
            as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1779
          else if (info->saw_tlsgd)
1780
            as_bad (_("sequence number in use for !tlsgd!%ld"),
1781
                    insn->sequence);
1782
          else
1783
            info->saw_tlsldm = 1;
1784
          fixP->tc_fix_data.info = info;
1785
          break;
1786
#endif
1787
        default:
1788
          if ((int) fixup->reloc < 0)
1789
            {
1790
              if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1791
                fixP->fx_no_overflow = 1;
1792
            }
1793
          break;
1794
        }
1795
    }
1796
}
1797
 
1798
/* Insert an operand value into an instruction.  */
1799
 
1800
static unsigned
1801
insert_operand (unsigned insn,
1802
                const struct alpha_operand *operand,
1803
                offsetT val,
1804
                char *file,
1805
                unsigned line)
1806
{
1807
  if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1808
    {
1809
      offsetT min, max;
1810
 
1811
      if (operand->flags & AXP_OPERAND_SIGNED)
1812
        {
1813
          max = (1 << (operand->bits - 1)) - 1;
1814
          min = -(1 << (operand->bits - 1));
1815
        }
1816
      else
1817
        {
1818
          max = (1 << operand->bits) - 1;
1819
          min = 0;
1820
        }
1821
 
1822
      if (val < min || val > max)
1823
        as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
1824
    }
1825
 
1826
  if (operand->insert)
1827
    {
1828
      const char *errmsg = NULL;
1829
 
1830
      insn = (*operand->insert) (insn, val, &errmsg);
1831
      if (errmsg)
1832
        as_warn (errmsg);
1833
    }
1834
  else
1835
    insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1836
 
1837
  return insn;
1838
}
1839
 
1840
/* Turn an opcode description and a set of arguments into
1841
   an instruction and a fixup.  */
1842
 
1843
static void
1844
assemble_insn (const struct alpha_opcode *opcode,
1845
               const expressionS *tok,
1846
               int ntok,
1847
               struct alpha_insn *insn,
1848
               bfd_reloc_code_real_type reloc)
1849
{
1850
  const struct alpha_operand *reloc_operand = NULL;
1851
  const expressionS *reloc_exp = NULL;
1852
  const unsigned char *argidx;
1853
  unsigned image;
1854
  int tokidx = 0;
1855
 
1856
  memset (insn, 0, sizeof (*insn));
1857
  image = opcode->opcode;
1858
 
1859
  for (argidx = opcode->operands; *argidx; ++argidx)
1860
    {
1861
      const struct alpha_operand *operand = &alpha_operands[*argidx];
1862
      const expressionS *t = (const expressionS *) 0;
1863
 
1864
      if (operand->flags & AXP_OPERAND_FAKE)
1865
        {
1866
          /* Fake operands take no value and generate no fixup.  */
1867
          image = insert_operand (image, operand, 0, NULL, 0);
1868
          continue;
1869
        }
1870
 
1871
      if (tokidx >= ntok)
1872
        {
1873
          switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1874
            {
1875
            case AXP_OPERAND_DEFAULT_FIRST:
1876
              t = &tok[0];
1877
              break;
1878
            case AXP_OPERAND_DEFAULT_SECOND:
1879
              t = &tok[1];
1880
              break;
1881
            case AXP_OPERAND_DEFAULT_ZERO:
1882
              {
1883
                static expressionS zero_exp;
1884
                t = &zero_exp;
1885
                zero_exp.X_op = O_constant;
1886
                zero_exp.X_unsigned = 1;
1887
              }
1888
              break;
1889
            default:
1890
              abort ();
1891
            }
1892
        }
1893
      else
1894
        t = &tok[tokidx++];
1895
 
1896
      switch (t->X_op)
1897
        {
1898
        case O_register:
1899
        case O_pregister:
1900
        case O_cpregister:
1901
          image = insert_operand (image, operand, regno (t->X_add_number),
1902
                                  NULL, 0);
1903
          break;
1904
 
1905
        case O_constant:
1906
          image = insert_operand (image, operand, t->X_add_number, NULL, 0);
1907
          assert (reloc_operand == NULL);
1908
          reloc_operand = operand;
1909
          reloc_exp = t;
1910
          break;
1911
 
1912
        default:
1913
          /* This is only 0 for fields that should contain registers,
1914
             which means this pattern shouldn't have matched.  */
1915
          if (operand->default_reloc == 0)
1916
            abort ();
1917
 
1918
          /* There is one special case for which an insn receives two
1919
             relocations, and thus the user-supplied reloc does not
1920
             override the operand reloc.  */
1921
          if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
1922
            {
1923
              struct alpha_fixup *fixup;
1924
 
1925
              if (insn->nfixups >= MAX_INSN_FIXUPS)
1926
                as_fatal (_("too many fixups"));
1927
 
1928
              fixup = &insn->fixups[insn->nfixups++];
1929
              fixup->exp = *t;
1930
              fixup->reloc = BFD_RELOC_ALPHA_HINT;
1931
            }
1932
          else
1933
            {
1934
              if (reloc == BFD_RELOC_UNUSED)
1935
                reloc = operand->default_reloc;
1936
 
1937
              assert (reloc_operand == NULL);
1938
              reloc_operand = operand;
1939
              reloc_exp = t;
1940
            }
1941
          break;
1942
        }
1943
    }
1944
 
1945
  if (reloc != BFD_RELOC_UNUSED)
1946
    {
1947
      struct alpha_fixup *fixup;
1948
 
1949
      if (insn->nfixups >= MAX_INSN_FIXUPS)
1950
        as_fatal (_("too many fixups"));
1951
 
1952
      /* ??? My but this is hacky.  But the OSF/1 assembler uses the same
1953
         relocation tag for both ldah and lda with gpdisp.  Choose the
1954
         correct internal relocation based on the opcode.  */
1955
      if (reloc == BFD_RELOC_ALPHA_GPDISP)
1956
        {
1957
          if (strcmp (opcode->name, "ldah") == 0)
1958
            reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
1959
          else if (strcmp (opcode->name, "lda") == 0)
1960
            reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
1961
          else
1962
            as_bad (_("invalid relocation for instruction"));
1963
        }
1964
 
1965
      /* If this is a real relocation (as opposed to a lituse hint), then
1966
         the relocation width should match the operand width.  */
1967
      else if (reloc < BFD_RELOC_UNUSED)
1968
        {
1969
          reloc_howto_type *reloc_howto
1970
            = bfd_reloc_type_lookup (stdoutput, reloc);
1971
          if (reloc_operand == NULL
1972
              || reloc_howto->bitsize != reloc_operand->bits)
1973
            {
1974
              as_bad (_("invalid relocation for field"));
1975
              return;
1976
            }
1977
        }
1978
 
1979
      fixup = &insn->fixups[insn->nfixups++];
1980
      if (reloc_exp)
1981
        fixup->exp = *reloc_exp;
1982
      else
1983
        fixup->exp.X_op = O_absent;
1984
      fixup->reloc = reloc;
1985
    }
1986
 
1987
  insn->insn = image;
1988
}
1989
 
1990
/* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
1991
   etc.  They differ from the real instructions in that they do simple
1992
   expressions like the lda macro.  */
1993
 
1994
static void
1995
emit_ir_load (const expressionS *tok,
1996
              int ntok,
1997
              const void * opname)
1998
{
1999
  int basereg;
2000
  long lituse;
2001
  expressionS newtok[3];
2002
  struct alpha_insn insn;
2003
 
2004
  if (ntok == 2)
2005
    basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2006
  else
2007
    basereg = tok[2].X_add_number;
2008
 
2009
  lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2010
                            &newtok[1]);
2011
 
2012
  newtok[0] = tok[0];
2013
  set_tok_preg (newtok[2], basereg);
2014
 
2015
  assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2016
 
2017
  if (lituse)
2018
    {
2019
      assert (insn.nfixups < MAX_INSN_FIXUPS);
2020
      insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2021
      insn.fixups[insn.nfixups].exp.X_op = O_absent;
2022
      insn.nfixups++;
2023
      insn.sequence = lituse;
2024
    }
2025
 
2026
  emit_insn (&insn);
2027
}
2028
 
2029
/* Handle fp register loads, and both integer and fp register stores.
2030
   Again, we handle simple expressions.  */
2031
 
2032
static void
2033
emit_loadstore (const expressionS *tok,
2034
                int ntok,
2035
                const void * opname)
2036
{
2037
  int basereg;
2038
  long lituse;
2039
  expressionS newtok[3];
2040
  struct alpha_insn insn;
2041
 
2042
  if (ntok == 2)
2043
    basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2044
  else
2045
    basereg = tok[2].X_add_number;
2046
 
2047
  if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2048
    {
2049
      if (alpha_noat_on)
2050
        as_bad (_("macro requires $at register while noat in effect"));
2051
 
2052
      lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2053
    }
2054
  else
2055
    {
2056
      newtok[1] = tok[1];
2057
      lituse = 0;
2058
    }
2059
 
2060
  newtok[0] = tok[0];
2061
  set_tok_preg (newtok[2], basereg);
2062
 
2063
  assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2064
 
2065
  if (lituse)
2066
    {
2067
      assert (insn.nfixups < MAX_INSN_FIXUPS);
2068
      insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2069
      insn.fixups[insn.nfixups].exp.X_op = O_absent;
2070
      insn.nfixups++;
2071
      insn.sequence = lituse;
2072
    }
2073
 
2074
  emit_insn (&insn);
2075
}
2076
 
2077
/* Load a half-word or byte as an unsigned value.  */
2078
 
2079
static void
2080
emit_ldXu (const expressionS *tok,
2081
           int ntok,
2082
           const void * vlgsize)
2083
{
2084
  if (alpha_target & AXP_OPCODE_BWX)
2085
    emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2086
  else
2087
    {
2088
      expressionS newtok[3];
2089
      struct alpha_insn insn;
2090
      int basereg;
2091
      long lituse;
2092
 
2093
      if (alpha_noat_on)
2094
        as_bad (_("macro requires $at register while noat in effect"));
2095
 
2096
      if (ntok == 2)
2097
        basereg = (tok[1].X_op == O_constant
2098
                   ? AXP_REG_ZERO : alpha_gp_register);
2099
      else
2100
        basereg = tok[2].X_add_number;
2101
 
2102
      /* Emit "lda $at, exp".  */
2103
      lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
2104
 
2105
      /* Emit "ldq_u targ, 0($at)".  */
2106
      newtok[0] = tok[0];
2107
      set_tok_const (newtok[1], 0);
2108
      set_tok_preg (newtok[2], basereg);
2109
      assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2110
 
2111
      if (lituse)
2112
        {
2113
          assert (insn.nfixups < MAX_INSN_FIXUPS);
2114
          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2115
          insn.fixups[insn.nfixups].exp.X_op = O_absent;
2116
          insn.nfixups++;
2117
          insn.sequence = lituse;
2118
        }
2119
 
2120
      emit_insn (&insn);
2121
 
2122
      /* Emit "extXl targ, $at, targ".  */
2123
      set_tok_reg (newtok[1], basereg);
2124
      newtok[2] = newtok[0];
2125
      assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2126
 
2127
      if (lituse)
2128
        {
2129
          assert (insn.nfixups < MAX_INSN_FIXUPS);
2130
          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2131
          insn.fixups[insn.nfixups].exp.X_op = O_absent;
2132
          insn.nfixups++;
2133
          insn.sequence = lituse;
2134
        }
2135
 
2136
      emit_insn (&insn);
2137
    }
2138
}
2139
 
2140
/* Load a half-word or byte as a signed value.  */
2141
 
2142
static void
2143
emit_ldX (const expressionS *tok,
2144
          int ntok,
2145
          const void * vlgsize)
2146
{
2147
  emit_ldXu (tok, ntok, vlgsize);
2148
  assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2149
}
2150
 
2151
/* Load an integral value from an unaligned address as an unsigned
2152
   value.  */
2153
 
2154
static void
2155
emit_uldXu (const expressionS *tok,
2156
            int ntok,
2157
            const void * vlgsize)
2158
{
2159
  long lgsize = (long) vlgsize;
2160
  expressionS newtok[3];
2161
 
2162
  if (alpha_noat_on)
2163
    as_bad (_("macro requires $at register while noat in effect"));
2164
 
2165
  /* Emit "lda $at, exp".  */
2166
  memcpy (newtok, tok, sizeof (expressionS) * ntok);
2167
  newtok[0].X_add_number = AXP_REG_AT;
2168
  assemble_tokens ("lda", newtok, ntok, 1);
2169
 
2170
  /* Emit "ldq_u $t9, 0($at)".  */
2171
  set_tok_reg (newtok[0], AXP_REG_T9);
2172
  set_tok_const (newtok[1], 0);
2173
  set_tok_preg (newtok[2], AXP_REG_AT);
2174
  assemble_tokens ("ldq_u", newtok, 3, 1);
2175
 
2176
  /* Emit "ldq_u $t10, size-1($at)".  */
2177
  set_tok_reg (newtok[0], AXP_REG_T10);
2178
  set_tok_const (newtok[1], (1 << lgsize) - 1);
2179
  assemble_tokens ("ldq_u", newtok, 3, 1);
2180
 
2181
  /* Emit "extXl $t9, $at, $t9".  */
2182
  set_tok_reg (newtok[0], AXP_REG_T9);
2183
  set_tok_reg (newtok[1], AXP_REG_AT);
2184
  set_tok_reg (newtok[2], AXP_REG_T9);
2185
  assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2186
 
2187
  /* Emit "extXh $t10, $at, $t10".  */
2188
  set_tok_reg (newtok[0], AXP_REG_T10);
2189
  set_tok_reg (newtok[2], AXP_REG_T10);
2190
  assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2191
 
2192
  /* Emit "or $t9, $t10, targ".  */
2193
  set_tok_reg (newtok[0], AXP_REG_T9);
2194
  set_tok_reg (newtok[1], AXP_REG_T10);
2195
  newtok[2] = tok[0];
2196
  assemble_tokens ("or", newtok, 3, 1);
2197
}
2198
 
2199
/* Load an integral value from an unaligned address as a signed value.
2200
   Note that quads should get funneled to the unsigned load since we
2201
   don't have to do the sign extension.  */
2202
 
2203
static void
2204
emit_uldX (const expressionS *tok,
2205
           int ntok,
2206
           const void * vlgsize)
2207
{
2208
  emit_uldXu (tok, ntok, vlgsize);
2209
  assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2210
}
2211
 
2212
/* Implement the ldil macro.  */
2213
 
2214
static void
2215
emit_ldil (const expressionS *tok,
2216
           int ntok,
2217
           const void * unused ATTRIBUTE_UNUSED)
2218
{
2219
  expressionS newtok[2];
2220
 
2221
  memcpy (newtok, tok, sizeof (newtok));
2222
  newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2223
 
2224
  assemble_tokens ("lda", newtok, ntok, 1);
2225
}
2226
 
2227
/* Store a half-word or byte.  */
2228
 
2229
static void
2230
emit_stX (const expressionS *tok,
2231
          int ntok,
2232
          const void * vlgsize)
2233
{
2234
  int lgsize = (int) (long) vlgsize;
2235
 
2236
  if (alpha_target & AXP_OPCODE_BWX)
2237
    emit_loadstore (tok, ntok, stX_op[lgsize]);
2238
  else
2239
    {
2240
      expressionS newtok[3];
2241
      struct alpha_insn insn;
2242
      int basereg;
2243
      long lituse;
2244
 
2245
      if (alpha_noat_on)
2246
        as_bad (_("macro requires $at register while noat in effect"));
2247
 
2248
      if (ntok == 2)
2249
        basereg = (tok[1].X_op == O_constant
2250
                   ? AXP_REG_ZERO : alpha_gp_register);
2251
      else
2252
        basereg = tok[2].X_add_number;
2253
 
2254
      /* Emit "lda $at, exp".  */
2255
      lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
2256
 
2257
      /* Emit "ldq_u $t9, 0($at)".  */
2258
      set_tok_reg (newtok[0], AXP_REG_T9);
2259
      set_tok_const (newtok[1], 0);
2260
      set_tok_preg (newtok[2], basereg);
2261
      assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2262
 
2263
      if (lituse)
2264
        {
2265
          assert (insn.nfixups < MAX_INSN_FIXUPS);
2266
          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2267
          insn.fixups[insn.nfixups].exp.X_op = O_absent;
2268
          insn.nfixups++;
2269
          insn.sequence = lituse;
2270
        }
2271
 
2272
      emit_insn (&insn);
2273
 
2274
      /* Emit "insXl src, $at, $t10".  */
2275
      newtok[0] = tok[0];
2276
      set_tok_reg (newtok[1], basereg);
2277
      set_tok_reg (newtok[2], AXP_REG_T10);
2278
      assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2279
 
2280
      if (lituse)
2281
        {
2282
          assert (insn.nfixups < MAX_INSN_FIXUPS);
2283
          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2284
          insn.fixups[insn.nfixups].exp.X_op = O_absent;
2285
          insn.nfixups++;
2286
          insn.sequence = lituse;
2287
        }
2288
 
2289
      emit_insn (&insn);
2290
 
2291
      /* Emit "mskXl $t9, $at, $t9".  */
2292
      set_tok_reg (newtok[0], AXP_REG_T9);
2293
      newtok[2] = newtok[0];
2294
      assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2295
 
2296
      if (lituse)
2297
        {
2298
          assert (insn.nfixups < MAX_INSN_FIXUPS);
2299
          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2300
          insn.fixups[insn.nfixups].exp.X_op = O_absent;
2301
          insn.nfixups++;
2302
          insn.sequence = lituse;
2303
        }
2304
 
2305
      emit_insn (&insn);
2306
 
2307
      /* Emit "or $t9, $t10, $t9".  */
2308
      set_tok_reg (newtok[1], AXP_REG_T10);
2309
      assemble_tokens ("or", newtok, 3, 1);
2310
 
2311
      /* Emit "stq_u $t9, 0($at).  */
2312
      set_tok_const(newtok[1], 0);
2313
      set_tok_preg (newtok[2], AXP_REG_AT);
2314
      assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2315
 
2316
      if (lituse)
2317
        {
2318
          assert (insn.nfixups < MAX_INSN_FIXUPS);
2319
          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2320
          insn.fixups[insn.nfixups].exp.X_op = O_absent;
2321
          insn.nfixups++;
2322
          insn.sequence = lituse;
2323
        }
2324
 
2325
      emit_insn (&insn);
2326
    }
2327
}
2328
 
2329
/* Store an integer to an unaligned address.  */
2330
 
2331
static void
2332
emit_ustX (const expressionS *tok,
2333
           int ntok,
2334
           const void * vlgsize)
2335
{
2336
  int lgsize = (int) (long) vlgsize;
2337
  expressionS newtok[3];
2338
 
2339
  /* Emit "lda $at, exp".  */
2340
  memcpy (newtok, tok, sizeof (expressionS) * ntok);
2341
  newtok[0].X_add_number = AXP_REG_AT;
2342
  assemble_tokens ("lda", newtok, ntok, 1);
2343
 
2344
  /* Emit "ldq_u $9, 0($at)".  */
2345
  set_tok_reg (newtok[0], AXP_REG_T9);
2346
  set_tok_const (newtok[1], 0);
2347
  set_tok_preg (newtok[2], AXP_REG_AT);
2348
  assemble_tokens ("ldq_u", newtok, 3, 1);
2349
 
2350
  /* Emit "ldq_u $10, size-1($at)".  */
2351
  set_tok_reg (newtok[0], AXP_REG_T10);
2352
  set_tok_const (newtok[1], (1 << lgsize) - 1);
2353
  assemble_tokens ("ldq_u", newtok, 3, 1);
2354
 
2355
  /* Emit "insXl src, $at, $t11".  */
2356
  newtok[0] = tok[0];
2357
  set_tok_reg (newtok[1], AXP_REG_AT);
2358
  set_tok_reg (newtok[2], AXP_REG_T11);
2359
  assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2360
 
2361
  /* Emit "insXh src, $at, $t12".  */
2362
  set_tok_reg (newtok[2], AXP_REG_T12);
2363
  assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2364
 
2365
  /* Emit "mskXl $t9, $at, $t9".  */
2366
  set_tok_reg (newtok[0], AXP_REG_T9);
2367
  newtok[2] = newtok[0];
2368
  assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2369
 
2370
  /* Emit "mskXh $t10, $at, $t10".  */
2371
  set_tok_reg (newtok[0], AXP_REG_T10);
2372
  newtok[2] = newtok[0];
2373
  assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2374
 
2375
  /* Emit "or $t9, $t11, $t9".  */
2376
  set_tok_reg (newtok[0], AXP_REG_T9);
2377
  set_tok_reg (newtok[1], AXP_REG_T11);
2378
  newtok[2] = newtok[0];
2379
  assemble_tokens ("or", newtok, 3, 1);
2380
 
2381
  /* Emit "or $t10, $t12, $t10".  */
2382
  set_tok_reg (newtok[0], AXP_REG_T10);
2383
  set_tok_reg (newtok[1], AXP_REG_T12);
2384
  newtok[2] = newtok[0];
2385
  assemble_tokens ("or", newtok, 3, 1);
2386
 
2387
  /* Emit "stq_u $t10, size-1($at)".  */
2388
  set_tok_reg (newtok[0], AXP_REG_T10);
2389
  set_tok_const (newtok[1], (1 << lgsize) - 1);
2390
  set_tok_preg (newtok[2], AXP_REG_AT);
2391
  assemble_tokens ("stq_u", newtok, 3, 1);
2392
 
2393
  /* Emit "stq_u $t9, 0($at)".  */
2394
  set_tok_reg (newtok[0], AXP_REG_T9);
2395
  set_tok_const (newtok[1], 0);
2396
  assemble_tokens ("stq_u", newtok, 3, 1);
2397
}
2398
 
2399
/* Sign extend a half-word or byte.  The 32-bit sign extend is
2400
   implemented as "addl $31, $r, $t" in the opcode table.  */
2401
 
2402
static void
2403
emit_sextX (const expressionS *tok,
2404
            int ntok,
2405
            const void * vlgsize)
2406
{
2407
  long lgsize = (long) vlgsize;
2408
 
2409
  if (alpha_target & AXP_OPCODE_BWX)
2410
    assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2411
  else
2412
    {
2413
      int bitshift = 64 - 8 * (1 << lgsize);
2414
      expressionS newtok[3];
2415
 
2416
      /* Emit "sll src,bits,dst".  */
2417
      newtok[0] = tok[0];
2418
      set_tok_const (newtok[1], bitshift);
2419
      newtok[2] = tok[ntok - 1];
2420
      assemble_tokens ("sll", newtok, 3, 1);
2421
 
2422
      /* Emit "sra dst,bits,dst".  */
2423
      newtok[0] = newtok[2];
2424
      assemble_tokens ("sra", newtok, 3, 1);
2425
    }
2426
}
2427
 
2428
/* Implement the division and modulus macros.  */
2429
 
2430
#ifdef OBJ_EVAX
2431
 
2432
/* Make register usage like in normal procedure call.
2433
   Don't clobber PV and RA.  */
2434
 
2435
static void
2436
emit_division (const expressionS *tok,
2437
               int ntok,
2438
               const void * symname)
2439
{
2440
  /* DIVISION and MODULUS. Yech.
2441
 
2442
     Convert
2443
        OP x,y,result
2444
     to
2445
        mov x,R16       # if x != R16
2446
        mov y,R17       # if y != R17
2447
        lda AT,__OP
2448
        jsr AT,(AT),0
2449
        mov R0,result
2450
 
2451
     with appropriate optimizations if R0,R16,R17 are the registers
2452
     specified by the compiler.  */
2453
 
2454
  int xr, yr, rr;
2455
  symbolS *sym;
2456
  expressionS newtok[3];
2457
 
2458
  xr = regno (tok[0].X_add_number);
2459
  yr = regno (tok[1].X_add_number);
2460
 
2461
  if (ntok < 3)
2462
    rr = xr;
2463
  else
2464
    rr = regno (tok[2].X_add_number);
2465
 
2466
  /* Move the operands into the right place.  */
2467
  if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2468
    {
2469
      /* They are in exactly the wrong order -- swap through AT.  */
2470
      if (alpha_noat_on)
2471
        as_bad (_("macro requires $at register while noat in effect"));
2472
 
2473
      set_tok_reg (newtok[0], AXP_REG_R16);
2474
      set_tok_reg (newtok[1], AXP_REG_AT);
2475
      assemble_tokens ("mov", newtok, 2, 1);
2476
 
2477
      set_tok_reg (newtok[0], AXP_REG_R17);
2478
      set_tok_reg (newtok[1], AXP_REG_R16);
2479
      assemble_tokens ("mov", newtok, 2, 1);
2480
 
2481
      set_tok_reg (newtok[0], AXP_REG_AT);
2482
      set_tok_reg (newtok[1], AXP_REG_R17);
2483
      assemble_tokens ("mov", newtok, 2, 1);
2484
    }
2485
  else
2486
    {
2487
      if (yr == AXP_REG_R16)
2488
        {
2489
          set_tok_reg (newtok[0], AXP_REG_R16);
2490
          set_tok_reg (newtok[1], AXP_REG_R17);
2491
          assemble_tokens ("mov", newtok, 2, 1);
2492
        }
2493
 
2494
      if (xr != AXP_REG_R16)
2495
        {
2496
          set_tok_reg (newtok[0], xr);
2497
          set_tok_reg (newtok[1], AXP_REG_R16);
2498
          assemble_tokens ("mov", newtok, 2, 1);
2499
        }
2500
 
2501
      if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2502
        {
2503
          set_tok_reg (newtok[0], yr);
2504
          set_tok_reg (newtok[1], AXP_REG_R17);
2505
          assemble_tokens ("mov", newtok, 2, 1);
2506
        }
2507
    }
2508
 
2509
  sym = symbol_find_or_make ((const char *) symname);
2510
 
2511
  set_tok_reg (newtok[0], AXP_REG_AT);
2512
  set_tok_sym (newtok[1], sym, 0);
2513
  assemble_tokens ("lda", newtok, 2, 1);
2514
 
2515
  /* Call the division routine.  */
2516
  set_tok_reg (newtok[0], AXP_REG_AT);
2517
  set_tok_cpreg (newtok[1], AXP_REG_AT);
2518
  set_tok_const (newtok[2], 0);
2519
  assemble_tokens ("jsr", newtok, 3, 1);
2520
 
2521
  /* Move the result to the right place.  */
2522
  if (rr != AXP_REG_R0)
2523
    {
2524
      set_tok_reg (newtok[0], AXP_REG_R0);
2525
      set_tok_reg (newtok[1], rr);
2526
      assemble_tokens ("mov", newtok, 2, 1);
2527
    }
2528
}
2529
 
2530
#else /* !OBJ_EVAX */
2531
 
2532
static void
2533
emit_division (const expressionS *tok,
2534
               int ntok,
2535
               const void * symname)
2536
{
2537
  /* DIVISION and MODULUS. Yech.
2538
     Convert
2539
        OP x,y,result
2540
     to
2541
        lda pv,__OP
2542
        mov x,t10
2543
        mov y,t11
2544
        jsr t9,(pv),__OP
2545
        mov t12,result
2546
 
2547
     with appropriate optimizations if t10,t11,t12 are the registers
2548
     specified by the compiler.  */
2549
 
2550
  int xr, yr, rr;
2551
  symbolS *sym;
2552
  expressionS newtok[3];
2553
 
2554
  xr = regno (tok[0].X_add_number);
2555
  yr = regno (tok[1].X_add_number);
2556
 
2557
  if (ntok < 3)
2558
    rr = xr;
2559
  else
2560
    rr = regno (tok[2].X_add_number);
2561
 
2562
  sym = symbol_find_or_make ((const char *) symname);
2563
 
2564
  /* Move the operands into the right place.  */
2565
  if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2566
    {
2567
      /* They are in exactly the wrong order -- swap through AT.  */
2568
      if (alpha_noat_on)
2569
        as_bad (_("macro requires $at register while noat in effect"));
2570
 
2571
      set_tok_reg (newtok[0], AXP_REG_T10);
2572
      set_tok_reg (newtok[1], AXP_REG_AT);
2573
      assemble_tokens ("mov", newtok, 2, 1);
2574
 
2575
      set_tok_reg (newtok[0], AXP_REG_T11);
2576
      set_tok_reg (newtok[1], AXP_REG_T10);
2577
      assemble_tokens ("mov", newtok, 2, 1);
2578
 
2579
      set_tok_reg (newtok[0], AXP_REG_AT);
2580
      set_tok_reg (newtok[1], AXP_REG_T11);
2581
      assemble_tokens ("mov", newtok, 2, 1);
2582
    }
2583
  else
2584
    {
2585
      if (yr == AXP_REG_T10)
2586
        {
2587
          set_tok_reg (newtok[0], AXP_REG_T10);
2588
          set_tok_reg (newtok[1], AXP_REG_T11);
2589
          assemble_tokens ("mov", newtok, 2, 1);
2590
        }
2591
 
2592
      if (xr != AXP_REG_T10)
2593
        {
2594
          set_tok_reg (newtok[0], xr);
2595
          set_tok_reg (newtok[1], AXP_REG_T10);
2596
          assemble_tokens ("mov", newtok, 2, 1);
2597
        }
2598
 
2599
      if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2600
        {
2601
          set_tok_reg (newtok[0], yr);
2602
          set_tok_reg (newtok[1], AXP_REG_T11);
2603
          assemble_tokens ("mov", newtok, 2, 1);
2604
        }
2605
    }
2606
 
2607
  /* Call the division routine.  */
2608
  set_tok_reg (newtok[0], AXP_REG_T9);
2609
  set_tok_sym (newtok[1], sym, 0);
2610
  assemble_tokens ("jsr", newtok, 2, 1);
2611
 
2612
  /* Reload the GP register.  */
2613
#ifdef OBJ_AOUT
2614
FIXME
2615
#endif
2616
#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2617
  set_tok_reg (newtok[0], alpha_gp_register);
2618
  set_tok_const (newtok[1], 0);
2619
  set_tok_preg (newtok[2], AXP_REG_T9);
2620
  assemble_tokens ("ldgp", newtok, 3, 1);
2621
#endif
2622
 
2623
  /* Move the result to the right place.  */
2624
  if (rr != AXP_REG_T12)
2625
    {
2626
      set_tok_reg (newtok[0], AXP_REG_T12);
2627
      set_tok_reg (newtok[1], rr);
2628
      assemble_tokens ("mov", newtok, 2, 1);
2629
    }
2630
}
2631
 
2632
#endif /* !OBJ_EVAX */
2633
 
2634
/* The jsr and jmp macros differ from their instruction counterparts
2635
   in that they can load the target address and default most
2636
   everything.  */
2637
 
2638
static void
2639
emit_jsrjmp (const expressionS *tok,
2640
             int ntok,
2641
             const void * vopname)
2642
{
2643
  const char *opname = (const char *) vopname;
2644
  struct alpha_insn insn;
2645
  expressionS newtok[3];
2646
  int r, tokidx = 0;
2647
  long lituse = 0;
2648
 
2649
  if (tokidx < ntok && tok[tokidx].X_op == O_register)
2650
    r = regno (tok[tokidx++].X_add_number);
2651
  else
2652
    r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2653
 
2654
  set_tok_reg (newtok[0], r);
2655
 
2656
  if (tokidx < ntok &&
2657
      (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2658
    r = regno (tok[tokidx++].X_add_number);
2659
#ifdef OBJ_EVAX
2660
  /* Keep register if jsr $n.<sym>.  */
2661
#else
2662
  else
2663
    {
2664
      int basereg = alpha_gp_register;
2665
      lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
2666
    }
2667
#endif
2668
 
2669
  set_tok_cpreg (newtok[1], r);
2670
 
2671
#ifdef OBJ_EVAX
2672
  /* FIXME: Add hint relocs to BFD for evax.  */
2673
#else
2674
  if (tokidx < ntok)
2675
    newtok[2] = tok[tokidx];
2676
  else
2677
#endif
2678
    set_tok_const (newtok[2], 0);
2679
 
2680
  assemble_tokens_to_insn (opname, newtok, 3, &insn);
2681
 
2682
  if (lituse)
2683
    {
2684
      assert (insn.nfixups < MAX_INSN_FIXUPS);
2685
      insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2686
      insn.fixups[insn.nfixups].exp.X_op = O_absent;
2687
      insn.nfixups++;
2688
      insn.sequence = lituse;
2689
    }
2690
 
2691
  emit_insn (&insn);
2692
}
2693
 
2694
/* The ret and jcr instructions differ from their instruction
2695
   counterparts in that everything can be defaulted.  */
2696
 
2697
static void
2698
emit_retjcr (const expressionS *tok,
2699
             int ntok,
2700
             const void * vopname)
2701
{
2702
  const char *opname = (const char *) vopname;
2703
  expressionS newtok[3];
2704
  int r, tokidx = 0;
2705
 
2706
  if (tokidx < ntok && tok[tokidx].X_op == O_register)
2707
    r = regno (tok[tokidx++].X_add_number);
2708
  else
2709
    r = AXP_REG_ZERO;
2710
 
2711
  set_tok_reg (newtok[0], r);
2712
 
2713
  if (tokidx < ntok &&
2714
      (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2715
    r = regno (tok[tokidx++].X_add_number);
2716
  else
2717
    r = AXP_REG_RA;
2718
 
2719
  set_tok_cpreg (newtok[1], r);
2720
 
2721
  if (tokidx < ntok)
2722
    newtok[2] = tok[tokidx];
2723
  else
2724
    set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
2725
 
2726
  assemble_tokens (opname, newtok, 3, 0);
2727
}
2728
 
2729
/* Implement the ldgp macro.  */
2730
 
2731
static void
2732
emit_ldgp (const expressionS *tok,
2733
           int ntok ATTRIBUTE_UNUSED,
2734
           const void * unused ATTRIBUTE_UNUSED)
2735
{
2736
#ifdef OBJ_AOUT
2737
FIXME
2738
#endif
2739
#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2740
  /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2741
     with appropriate constants and relocations.  */
2742
  struct alpha_insn insn;
2743
  expressionS newtok[3];
2744
  expressionS addend;
2745
 
2746
#ifdef OBJ_ECOFF
2747
  if (regno (tok[2].X_add_number) == AXP_REG_PV)
2748
    ecoff_set_gp_prolog_size (0);
2749
#endif
2750
 
2751
  newtok[0] = tok[0];
2752
  set_tok_const (newtok[1], 0);
2753
  newtok[2] = tok[2];
2754
 
2755
  assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2756
 
2757
  addend = tok[1];
2758
 
2759
#ifdef OBJ_ECOFF
2760
  if (addend.X_op != O_constant)
2761
    as_bad (_("can not resolve expression"));
2762
  addend.X_op = O_symbol;
2763
  addend.X_add_symbol = alpha_gp_symbol;
2764
#endif
2765
 
2766
  insn.nfixups = 1;
2767
  insn.fixups[0].exp = addend;
2768
  insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2769
  insn.sequence = next_sequence_num;
2770
 
2771
  emit_insn (&insn);
2772
 
2773
  set_tok_preg (newtok[2], tok[0].X_add_number);
2774
 
2775
  assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2776
 
2777
#ifdef OBJ_ECOFF
2778
  addend.X_add_number += 4;
2779
#endif
2780
 
2781
  insn.nfixups = 1;
2782
  insn.fixups[0].exp = addend;
2783
  insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2784
  insn.sequence = next_sequence_num--;
2785
 
2786
  emit_insn (&insn);
2787
#endif /* OBJ_ECOFF || OBJ_ELF */
2788
}
2789
 
2790
/* The macro table.  */
2791
 
2792
static const struct alpha_macro alpha_macros[] =
2793
{
2794
/* Load/Store macros.  */
2795
  { "lda",      emit_lda, NULL,
2796
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2797
  { "ldah",     emit_ldah, NULL,
2798
    { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2799
 
2800
  { "ldl",      emit_ir_load, "ldl",
2801
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2802
  { "ldl_l",    emit_ir_load, "ldl_l",
2803
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2804
  { "ldq",      emit_ir_load, "ldq",
2805
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2806
  { "ldq_l",    emit_ir_load, "ldq_l",
2807
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2808
  { "ldq_u",    emit_ir_load, "ldq_u",
2809
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2810
  { "ldf",      emit_loadstore, "ldf",
2811
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2812
  { "ldg",      emit_loadstore, "ldg",
2813
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2814
  { "lds",      emit_loadstore, "lds",
2815
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2816
  { "ldt",      emit_loadstore, "ldt",
2817
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2818
 
2819
  { "ldb",      emit_ldX, (void *) 0,
2820
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2821
  { "ldbu",     emit_ldXu, (void *) 0,
2822
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2823
  { "ldw",      emit_ldX, (void *) 1,
2824
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2825
  { "ldwu",     emit_ldXu, (void *) 1,
2826
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2827
 
2828
  { "uldw",     emit_uldX, (void *) 1,
2829
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2830
  { "uldwu",    emit_uldXu, (void *) 1,
2831
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2832
  { "uldl",     emit_uldX, (void *) 2,
2833
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2834
  { "uldlu",    emit_uldXu, (void *) 2,
2835
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2836
  { "uldq",     emit_uldXu, (void *) 3,
2837
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2838
 
2839
  { "ldgp",     emit_ldgp, NULL,
2840
    { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
2841
 
2842
  { "ldi",      emit_lda, NULL,
2843
    { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2844
  { "ldil",     emit_ldil, NULL,
2845
    { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2846
  { "ldiq",     emit_lda, NULL,
2847
    { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2848
 
2849
  { "stl",      emit_loadstore, "stl",
2850
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2851
  { "stl_c",    emit_loadstore, "stl_c",
2852
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2853
  { "stq",      emit_loadstore, "stq",
2854
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2855
  { "stq_c",    emit_loadstore, "stq_c",
2856
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2857
  { "stq_u",    emit_loadstore, "stq_u",
2858
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2859
  { "stf",      emit_loadstore, "stf",
2860
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2861
  { "stg",      emit_loadstore, "stg",
2862
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2863
  { "sts",      emit_loadstore, "sts",
2864
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2865
  { "stt",      emit_loadstore, "stt",
2866
    { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2867
 
2868
  { "stb",      emit_stX, (void *) 0,
2869
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2870
  { "stw",      emit_stX, (void *) 1,
2871
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2872
  { "ustw",     emit_ustX, (void *) 1,
2873
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2874
  { "ustl",     emit_ustX, (void *) 2,
2875
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2876
  { "ustq",     emit_ustX, (void *) 3,
2877
    { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2878
 
2879
/* Arithmetic macros.  */
2880
 
2881
  { "sextb",    emit_sextX, (void *) 0,
2882
    { MACRO_IR, MACRO_IR, MACRO_EOA,
2883
      MACRO_IR, MACRO_EOA,
2884
      /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2885
  { "sextw",    emit_sextX, (void *) 1,
2886
    { MACRO_IR, MACRO_IR, MACRO_EOA,
2887
      MACRO_IR, MACRO_EOA,
2888
      /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2889
 
2890
  { "divl",     emit_division, "__divl",
2891
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2892
      MACRO_IR, MACRO_IR, MACRO_EOA,
2893
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2894
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2895
  { "divlu",    emit_division, "__divlu",
2896
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2897
      MACRO_IR, MACRO_IR, MACRO_EOA,
2898
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2899
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2900
  { "divq",     emit_division, "__divq",
2901
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2902
      MACRO_IR, MACRO_IR, MACRO_EOA,
2903
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2904
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2905
  { "divqu",    emit_division, "__divqu",
2906
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2907
      MACRO_IR, MACRO_IR, MACRO_EOA,
2908
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2909
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2910
  { "reml",     emit_division, "__reml",
2911
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2912
      MACRO_IR, MACRO_IR, MACRO_EOA,
2913
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2914
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2915
  { "remlu",    emit_division, "__remlu",
2916
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2917
      MACRO_IR, MACRO_IR, MACRO_EOA,
2918
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2919
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2920
  { "remq",     emit_division, "__remq",
2921
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2922
      MACRO_IR, MACRO_IR, MACRO_EOA,
2923
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2924
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2925
  { "remqu",    emit_division, "__remqu",
2926
    { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2927
      MACRO_IR, MACRO_IR, MACRO_EOA,
2928
      /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2929
      MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2930
 
2931
  { "jsr",      emit_jsrjmp, "jsr",
2932
    { MACRO_PIR, MACRO_EXP, MACRO_EOA,
2933
      MACRO_PIR, MACRO_EOA,
2934
      MACRO_IR,  MACRO_EXP, MACRO_EOA,
2935
      MACRO_EXP, MACRO_EOA } },
2936
  { "jmp",      emit_jsrjmp, "jmp",
2937
    { MACRO_PIR, MACRO_EXP, MACRO_EOA,
2938
      MACRO_PIR, MACRO_EOA,
2939
      MACRO_IR,  MACRO_EXP, MACRO_EOA,
2940
      MACRO_EXP, MACRO_EOA } },
2941
  { "ret",      emit_retjcr, "ret",
2942
    { MACRO_IR, MACRO_EXP, MACRO_EOA,
2943
      MACRO_IR, MACRO_EOA,
2944
      MACRO_PIR, MACRO_EXP, MACRO_EOA,
2945
      MACRO_PIR, MACRO_EOA,
2946
      MACRO_EXP, MACRO_EOA,
2947
      MACRO_EOA } },
2948
  { "jcr",      emit_retjcr, "jcr",
2949
    { MACRO_IR,  MACRO_EXP, MACRO_EOA,
2950
      MACRO_IR,  MACRO_EOA,
2951
      MACRO_PIR, MACRO_EXP, MACRO_EOA,
2952
      MACRO_PIR, MACRO_EOA,
2953
      MACRO_EXP, MACRO_EOA,
2954
      MACRO_EOA } },
2955
  { "jsr_coroutine",    emit_retjcr, "jcr",
2956
    { MACRO_IR,  MACRO_EXP, MACRO_EOA,
2957
      MACRO_IR,  MACRO_EOA,
2958
      MACRO_PIR, MACRO_EXP, MACRO_EOA,
2959
      MACRO_PIR, MACRO_EOA,
2960
      MACRO_EXP, MACRO_EOA,
2961
      MACRO_EOA } },
2962
};
2963
 
2964
static const unsigned int alpha_num_macros
2965
  = sizeof (alpha_macros) / sizeof (*alpha_macros);
2966
 
2967
/* Search forward through all variants of a macro looking for a syntax
2968
   match.  */
2969
 
2970
static const struct alpha_macro *
2971
find_macro_match (const struct alpha_macro *first_macro,
2972
                  const expressionS *tok,
2973
                  int *pntok)
2974
 
2975
{
2976
  const struct alpha_macro *macro = first_macro;
2977
  int ntok = *pntok;
2978
 
2979
  do
2980
    {
2981
      const enum alpha_macro_arg *arg = macro->argsets;
2982
      int tokidx = 0;
2983
 
2984
      while (*arg)
2985
        {
2986
          switch (*arg)
2987
            {
2988
            case MACRO_EOA:
2989
              if (tokidx == ntok)
2990
                return macro;
2991
              else
2992
                tokidx = 0;
2993
              break;
2994
 
2995
              /* Index register.  */
2996
            case MACRO_IR:
2997
              if (tokidx >= ntok || tok[tokidx].X_op != O_register
2998
                  || !is_ir_num (tok[tokidx].X_add_number))
2999
                goto match_failed;
3000
              ++tokidx;
3001
              break;
3002
 
3003
              /* Parenthesized index register.  */
3004
            case MACRO_PIR:
3005
              if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
3006
                  || !is_ir_num (tok[tokidx].X_add_number))
3007
                goto match_failed;
3008
              ++tokidx;
3009
              break;
3010
 
3011
              /* Optional parenthesized index register.  */
3012
            case MACRO_OPIR:
3013
              if (tokidx < ntok && tok[tokidx].X_op == O_pregister
3014
                  && is_ir_num (tok[tokidx].X_add_number))
3015
                ++tokidx;
3016
              break;
3017
 
3018
              /* Leading comma with a parenthesized index register.  */
3019
            case MACRO_CPIR:
3020
              if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
3021
                  || !is_ir_num (tok[tokidx].X_add_number))
3022
                goto match_failed;
3023
              ++tokidx;
3024
              break;
3025
 
3026
              /* Floating point register.  */
3027
            case MACRO_FPR:
3028
              if (tokidx >= ntok || tok[tokidx].X_op != O_register
3029
                  || !is_fpr_num (tok[tokidx].X_add_number))
3030
                goto match_failed;
3031
              ++tokidx;
3032
              break;
3033
 
3034
              /* Normal expression.  */
3035
            case MACRO_EXP:
3036
              if (tokidx >= ntok)
3037
                goto match_failed;
3038
              switch (tok[tokidx].X_op)
3039
                {
3040
                case O_illegal:
3041
                case O_absent:
3042
                case O_register:
3043
                case O_pregister:
3044
                case O_cpregister:
3045
                case O_literal:
3046
                case O_lituse_base:
3047
                case O_lituse_bytoff:
3048
                case O_lituse_jsr:
3049
                case O_gpdisp:
3050
                case O_gprelhigh:
3051
                case O_gprellow:
3052
                case O_gprel:
3053
                case O_samegp:
3054
                  goto match_failed;
3055
 
3056
                default:
3057
                  break;
3058
                }
3059
              ++tokidx;
3060
              break;
3061
 
3062
            match_failed:
3063
              while (*arg != MACRO_EOA)
3064
                ++arg;
3065
              tokidx = 0;
3066
              break;
3067
            }
3068
          ++arg;
3069
        }
3070
    }
3071
  while (++macro - alpha_macros < (int) alpha_num_macros
3072
         && !strcmp (macro->name, first_macro->name));
3073
 
3074
  return NULL;
3075
}
3076
 
3077
/* Given an opcode name and a pre-tokenized set of arguments, take the
3078
   opcode all the way through emission.  */
3079
 
3080
static void
3081
assemble_tokens (const char *opname,
3082
                 const expressionS *tok,
3083
                 int ntok,
3084
                 int local_macros_on)
3085
{
3086
  int found_something = 0;
3087
  const struct alpha_opcode *opcode;
3088
  const struct alpha_macro *macro;
3089
  int cpumatch = 1;
3090
  bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3091
 
3092
#ifdef RELOC_OP_P
3093
  /* If a user-specified relocation is present, this is not a macro.  */
3094
  if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
3095
    {
3096
      reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
3097
      ntok--;
3098
    }
3099
  else
3100
#endif
3101
  if (local_macros_on)
3102
    {
3103
      macro = ((const struct alpha_macro *)
3104
               hash_find (alpha_macro_hash, opname));
3105
      if (macro)
3106
        {
3107
          found_something = 1;
3108
          macro = find_macro_match (macro, tok, &ntok);
3109
          if (macro)
3110
            {
3111
              (*macro->emit) (tok, ntok, macro->arg);
3112
              return;
3113
            }
3114
        }
3115
    }
3116
 
3117
  /* Search opcodes.  */
3118
  opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
3119
  if (opcode)
3120
    {
3121
      found_something = 1;
3122
      opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
3123
      if (opcode)
3124
        {
3125
          struct alpha_insn insn;
3126
          assemble_insn (opcode, tok, ntok, &insn, reloc);
3127
 
3128
          /* Copy the sequence number for the reloc from the reloc token.  */
3129
          if (reloc != BFD_RELOC_UNUSED)
3130
            insn.sequence = tok[ntok].X_add_number;
3131
 
3132
          emit_insn (&insn);
3133
          return;
3134
        }
3135
    }
3136
 
3137
  if (found_something)
3138
    {
3139
      if (cpumatch)
3140
        as_bad (_("inappropriate arguments for opcode `%s'"), opname);
3141
      else
3142
        as_bad (_("opcode `%s' not supported for target %s"), opname,
3143
                alpha_target_name);
3144
    }
3145
  else
3146
    as_bad (_("unknown opcode `%s'"), opname);
3147
}
3148
 
3149
#ifdef OBJ_EVAX
3150
 
3151
/* Add symbol+addend to link pool.
3152
   Return offset from basesym to entry in link pool.
3153
 
3154
   Add new fixup only if offset isn't 16bit.  */
3155
 
3156
valueT
3157
add_to_link_pool (symbolS *basesym,
3158
                  symbolS *sym,
3159
                  offsetT addend)
3160
{
3161
  segT current_section = now_seg;
3162
  int current_subsec = now_subseg;
3163
  valueT offset;
3164
  bfd_reloc_code_real_type reloc_type;
3165
  char *p;
3166
  segment_info_type *seginfo = seg_info (alpha_link_section);
3167
  fixS *fixp;
3168
 
3169
  offset = - *symbol_get_obj (basesym);
3170
 
3171
  /* @@ This assumes all entries in a given section will be of the same
3172
     size...  Probably correct, but unwise to rely on.  */
3173
  /* This must always be called with the same subsegment.  */
3174
 
3175
  if (seginfo->frchainP)
3176
    for (fixp = seginfo->frchainP->fix_root;
3177
         fixp != (fixS *) NULL;
3178
         fixp = fixp->fx_next, offset += 8)
3179
      {
3180
        if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
3181
          {
3182
            if (range_signed_16 (offset))
3183
              {
3184
                return offset;
3185
              }
3186
          }
3187
      }
3188
 
3189
  /* Not found in 16bit signed range.  */
3190
 
3191
  subseg_set (alpha_link_section, 0);
3192
  p = frag_more (8);
3193
  memset (p, 0, 8);
3194
 
3195
  fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
3196
           BFD_RELOC_64);
3197
 
3198
  subseg_set (current_section, current_subsec);
3199
  seginfo->literal_pool_size += 8;
3200
  return offset;
3201
}
3202
 
3203
#endif /* OBJ_EVAX */
3204
 
3205
/* Assembler directives.  */
3206
 
3207
/* Handle the .text pseudo-op.  This is like the usual one, but it
3208
   clears alpha_insn_label and restores auto alignment.  */
3209
 
3210
static void
3211
s_alpha_text (int i)
3212
 
3213
{
3214
#ifdef OBJ_ELF
3215
  obj_elf_text (i);
3216
#else
3217
  s_text (i);
3218
#endif
3219
  alpha_insn_label = NULL;
3220
  alpha_auto_align_on = 1;
3221
  alpha_current_align = 0;
3222
}
3223
 
3224
/* Handle the .data pseudo-op.  This is like the usual one, but it
3225
   clears alpha_insn_label and restores auto alignment.  */
3226
 
3227
static void
3228
s_alpha_data (int i)
3229
{
3230
#ifdef OBJ_ELF
3231
  obj_elf_data (i);
3232
#else
3233
  s_data (i);
3234
#endif
3235
  alpha_insn_label = NULL;
3236
  alpha_auto_align_on = 1;
3237
  alpha_current_align = 0;
3238
}
3239
 
3240
#if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3241
 
3242
/* Handle the OSF/1 and openVMS .comm pseudo quirks.
3243
   openVMS constructs a section for every common symbol.  */
3244
 
3245
static void
3246
s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
3247
{
3248
  char *name;
3249
  char c;
3250
  char *p;
3251
  offsetT temp;
3252
  symbolS *symbolP;
3253
#ifdef OBJ_EVAX
3254
  segT current_section = now_seg;
3255
  int current_subsec = now_subseg;
3256
  segT new_seg;
3257
#endif
3258
 
3259
  name = input_line_pointer;
3260
  c = get_symbol_end ();
3261
 
3262
  /* Just after name is now '\0'.  */
3263
  p = input_line_pointer;
3264
  *p = c;
3265
 
3266
  SKIP_WHITESPACE ();
3267
 
3268
  /* Alpha OSF/1 compiler doesn't provide the comma, gcc does.  */
3269
  if (*input_line_pointer == ',')
3270
    {
3271
      input_line_pointer++;
3272
      SKIP_WHITESPACE ();
3273
    }
3274
  if ((temp = get_absolute_expression ()) < 0)
3275
    {
3276
      as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
3277
      ignore_rest_of_line ();
3278
      return;
3279
    }
3280
 
3281
  *p = 0;
3282
  symbolP = symbol_find_or_make (name);
3283
 
3284
#ifdef OBJ_EVAX
3285
  /* Make a section for the common symbol.  */
3286
  new_seg = subseg_new (xstrdup (name), 0);
3287
#endif
3288
 
3289
  *p = c;
3290
 
3291
#ifdef OBJ_EVAX
3292
  /* Alignment might follow.  */
3293
  if (*input_line_pointer == ',')
3294
    {
3295
      offsetT align;
3296
 
3297
      input_line_pointer++;
3298
      align = get_absolute_expression ();
3299
      bfd_set_section_alignment (stdoutput, new_seg, align);
3300
    }
3301
#endif
3302
 
3303
  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3304
    {
3305
      as_bad (_("Ignoring attempt to re-define symbol"));
3306
      ignore_rest_of_line ();
3307
      return;
3308
    }
3309
 
3310
#ifdef OBJ_EVAX
3311
  if (bfd_section_size (stdoutput, new_seg) > 0)
3312
    {
3313
      if (bfd_section_size (stdoutput, new_seg) != temp)
3314
        as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3315
                S_GET_NAME (symbolP),
3316
                (long) bfd_section_size (stdoutput, new_seg),
3317
                (long) temp);
3318
    }
3319
#else
3320
  if (S_GET_VALUE (symbolP))
3321
    {
3322
      if (S_GET_VALUE (symbolP) != (valueT) temp)
3323
        as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3324
                S_GET_NAME (symbolP),
3325
                (long) S_GET_VALUE (symbolP),
3326
                (long) temp);
3327
    }
3328
#endif
3329
  else
3330
    {
3331
#ifdef OBJ_EVAX
3332
      subseg_set (new_seg, 0);
3333
      p = frag_more (temp);
3334
      new_seg->flags |= SEC_IS_COMMON;
3335
      S_SET_SEGMENT (symbolP, new_seg);
3336
#else
3337
      S_SET_VALUE (symbolP, (valueT) temp);
3338
      S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
3339
#endif
3340
      S_SET_EXTERNAL (symbolP);
3341
    }
3342
 
3343
#ifdef OBJ_EVAX
3344
  subseg_set (current_section, current_subsec);
3345
#endif
3346
 
3347
  know (symbol_get_frag (symbolP) == &zero_address_frag);
3348
 
3349
  demand_empty_rest_of_line ();
3350
}
3351
 
3352
#endif /* ! OBJ_ELF */
3353
 
3354
#ifdef OBJ_ECOFF
3355
 
3356
/* Handle the .rdata pseudo-op.  This is like the usual one, but it
3357
   clears alpha_insn_label and restores auto alignment.  */
3358
 
3359
static void
3360
s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3361
{
3362
  int temp;
3363
 
3364
  temp = get_absolute_expression ();
3365
  subseg_new (".rdata", 0);
3366
  demand_empty_rest_of_line ();
3367
  alpha_insn_label = NULL;
3368
  alpha_auto_align_on = 1;
3369
  alpha_current_align = 0;
3370
}
3371
 
3372
#endif
3373
 
3374
#ifdef OBJ_ECOFF
3375
 
3376
/* Handle the .sdata pseudo-op.  This is like the usual one, but it
3377
   clears alpha_insn_label and restores auto alignment.  */
3378
 
3379
static void
3380
s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3381
{
3382
  int temp;
3383
 
3384
  temp = get_absolute_expression ();
3385
  subseg_new (".sdata", 0);
3386
  demand_empty_rest_of_line ();
3387
  alpha_insn_label = NULL;
3388
  alpha_auto_align_on = 1;
3389
  alpha_current_align = 0;
3390
}
3391
#endif
3392
 
3393
#ifdef OBJ_ELF
3394
struct alpha_elf_frame_data
3395
{
3396
  symbolS *func_sym;
3397
  symbolS *func_end_sym;
3398
  symbolS *prologue_sym;
3399
  unsigned int mask;
3400
  unsigned int fmask;
3401
  int fp_regno;
3402
  int ra_regno;
3403
  offsetT frame_size;
3404
  offsetT mask_offset;
3405
  offsetT fmask_offset;
3406
 
3407
  struct alpha_elf_frame_data *next;
3408
};
3409
 
3410
static struct alpha_elf_frame_data *all_frame_data;
3411
static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3412
static struct alpha_elf_frame_data *cur_frame_data;
3413
 
3414
/* Handle the .section pseudo-op.  This is like the usual one, but it
3415
   clears alpha_insn_label and restores auto alignment.  */
3416
 
3417
static void
3418
s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3419
{
3420
  obj_elf_section (ignore);
3421
 
3422
  alpha_insn_label = NULL;
3423
  alpha_auto_align_on = 1;
3424
  alpha_current_align = 0;
3425
}
3426
 
3427
static void
3428
s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3429
{
3430
  if (ECOFF_DEBUGGING)
3431
    ecoff_directive_ent (0);
3432
  else
3433
    {
3434
      char *name, name_end;
3435
      name = input_line_pointer;
3436
      name_end = get_symbol_end ();
3437
 
3438
      if (! is_name_beginner (*name))
3439
        {
3440
          as_warn (_(".ent directive has no name"));
3441
          *input_line_pointer = name_end;
3442
        }
3443
      else
3444
        {
3445
          symbolS *sym;
3446
 
3447
          if (cur_frame_data)
3448
            as_warn (_("nested .ent directives"));
3449
 
3450
          sym = symbol_find_or_make (name);
3451
          symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3452
 
3453
          cur_frame_data = calloc (1, sizeof (*cur_frame_data));
3454
          cur_frame_data->func_sym = sym;
3455
 
3456
          /* Provide sensible defaults.  */
3457
          cur_frame_data->fp_regno = 30;        /* sp */
3458
          cur_frame_data->ra_regno = 26;        /* ra */
3459
 
3460
          *plast_frame_data = cur_frame_data;
3461
          plast_frame_data = &cur_frame_data->next;
3462
 
3463
          /* The .ent directive is sometimes followed by a number.  Not sure
3464
             what it really means, but ignore it.  */
3465
          *input_line_pointer = name_end;
3466
          SKIP_WHITESPACE ();
3467
          if (*input_line_pointer == ',')
3468
            {
3469
              input_line_pointer++;
3470
              SKIP_WHITESPACE ();
3471
            }
3472
          if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3473
            (void) get_absolute_expression ();
3474
        }
3475
      demand_empty_rest_of_line ();
3476
    }
3477
}
3478
 
3479
static void
3480
s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3481
{
3482
  if (ECOFF_DEBUGGING)
3483
    ecoff_directive_end (0);
3484
  else
3485
    {
3486
      char *name, name_end;
3487
      name = input_line_pointer;
3488
      name_end = get_symbol_end ();
3489
 
3490
      if (! is_name_beginner (*name))
3491
        {
3492
          as_warn (_(".end directive has no name"));
3493
          *input_line_pointer = name_end;
3494
        }
3495
      else
3496
        {
3497
          symbolS *sym;
3498
 
3499
          sym = symbol_find (name);
3500
          if (!cur_frame_data)
3501
            as_warn (_(".end directive without matching .ent"));
3502
          else if (sym != cur_frame_data->func_sym)
3503
            as_warn (_(".end directive names different symbol than .ent"));
3504
 
3505
          /* Create an expression to calculate the size of the function.  */
3506
          if (sym && cur_frame_data)
3507
            {
3508
              OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3509
              expressionS *exp = xmalloc (sizeof (expressionS));
3510
 
3511
              obj->size = exp;
3512
              exp->X_op = O_subtract;
3513
              exp->X_add_symbol = symbol_temp_new_now ();
3514
              exp->X_op_symbol = sym;
3515
              exp->X_add_number = 0;
3516
 
3517
              cur_frame_data->func_end_sym = exp->X_add_symbol;
3518
            }
3519
 
3520
          cur_frame_data = NULL;
3521
 
3522
          *input_line_pointer = name_end;
3523
        }
3524
      demand_empty_rest_of_line ();
3525
    }
3526
}
3527
 
3528
static void
3529
s_alpha_mask (int fp)
3530
{
3531
  if (ECOFF_DEBUGGING)
3532
    {
3533
      if (fp)
3534
        ecoff_directive_fmask (0);
3535
      else
3536
        ecoff_directive_mask (0);
3537
    }
3538
  else
3539
    {
3540
      long val;
3541
      offsetT offset;
3542
 
3543
      if (!cur_frame_data)
3544
        {
3545
          if (fp)
3546
            as_warn (_(".fmask outside of .ent"));
3547
          else
3548
            as_warn (_(".mask outside of .ent"));
3549
          discard_rest_of_line ();
3550
          return;
3551
        }
3552
 
3553
      if (get_absolute_expression_and_terminator (&val) != ',')
3554
        {
3555
          if (fp)
3556
            as_warn (_("bad .fmask directive"));
3557
          else
3558
            as_warn (_("bad .mask directive"));
3559
          --input_line_pointer;
3560
          discard_rest_of_line ();
3561
          return;
3562
        }
3563
 
3564
      offset = get_absolute_expression ();
3565
      demand_empty_rest_of_line ();
3566
 
3567
      if (fp)
3568
        {
3569
          cur_frame_data->fmask = val;
3570
          cur_frame_data->fmask_offset = offset;
3571
        }
3572
      else
3573
        {
3574
          cur_frame_data->mask = val;
3575
          cur_frame_data->mask_offset = offset;
3576
        }
3577
    }
3578
}
3579
 
3580
static void
3581
s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3582
{
3583
  if (ECOFF_DEBUGGING)
3584
    ecoff_directive_frame (0);
3585
  else
3586
    {
3587
      long val;
3588
 
3589
      if (!cur_frame_data)
3590
        {
3591
          as_warn (_(".frame outside of .ent"));
3592
          discard_rest_of_line ();
3593
          return;
3594
        }
3595
 
3596
      cur_frame_data->fp_regno = tc_get_register (1);
3597
 
3598
      SKIP_WHITESPACE ();
3599
      if (*input_line_pointer++ != ','
3600
          || get_absolute_expression_and_terminator (&val) != ',')
3601
        {
3602
          as_warn (_("bad .frame directive"));
3603
          --input_line_pointer;
3604
          discard_rest_of_line ();
3605
          return;
3606
        }
3607
      cur_frame_data->frame_size = val;
3608
 
3609
      cur_frame_data->ra_regno = tc_get_register (0);
3610
 
3611
      /* Next comes the "offset of saved $a0 from $sp".  In gcc terms
3612
         this is current_function_pretend_args_size.  There's no place
3613
         to put this value, so ignore it.  */
3614
      s_ignore (42);
3615
    }
3616
}
3617
 
3618
static void
3619
s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3620
{
3621
  symbolS *sym;
3622
  int arg;
3623
 
3624
  arg = get_absolute_expression ();
3625
  demand_empty_rest_of_line ();
3626
 
3627
  if (ECOFF_DEBUGGING)
3628
    sym = ecoff_get_cur_proc_sym ();
3629
  else
3630
    sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3631
 
3632
  if (sym == NULL)
3633
    {
3634
      as_bad (_(".prologue directive without a preceding .ent directive"));
3635
      return;
3636
    }
3637
 
3638
  switch (arg)
3639
    {
3640
    case 0: /* No PV required.  */
3641
      S_SET_OTHER (sym, STO_ALPHA_NOPV
3642
                   | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3643
      break;
3644
    case 1: /* Std GP load.  */
3645
      S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3646
                   | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3647
      break;
3648
    case 2: /* Non-std use of PV.  */
3649
      break;
3650
 
3651
    default:
3652
      as_bad (_("Invalid argument %d to .prologue."), arg);
3653
      break;
3654
    }
3655
 
3656
  if (cur_frame_data)
3657
    cur_frame_data->prologue_sym = symbol_temp_new_now ();
3658
}
3659
 
3660
static char *first_file_directive;
3661
 
3662
static void
3663
s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3664
{
3665
  /* Save the first .file directive we see, so that we can change our
3666
     minds about whether ecoff debugging should or shouldn't be enabled.  */
3667
  if (alpha_flag_mdebug < 0 && ! first_file_directive)
3668
    {
3669
      char *start = input_line_pointer;
3670
      size_t len;
3671
 
3672
      discard_rest_of_line ();
3673
 
3674
      len = input_line_pointer - start;
3675
      first_file_directive = xmalloc (len + 1);
3676
      memcpy (first_file_directive, start, len);
3677
      first_file_directive[len] = '\0';
3678
 
3679
      input_line_pointer = start;
3680
    }
3681
 
3682
  if (ECOFF_DEBUGGING)
3683
    ecoff_directive_file (0);
3684
  else
3685
    dwarf2_directive_file (0);
3686
}
3687
 
3688
static void
3689
s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3690
{
3691
  if (ECOFF_DEBUGGING)
3692
    ecoff_directive_loc (0);
3693
  else
3694
    dwarf2_directive_loc (0);
3695
}
3696
 
3697
static void
3698
s_alpha_stab (int n)
3699
{
3700
  /* If we've been undecided about mdebug, make up our minds in favour.  */
3701
  if (alpha_flag_mdebug < 0)
3702
    {
3703
      segT sec = subseg_new (".mdebug", 0);
3704
      bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
3705
      bfd_set_section_alignment (stdoutput, sec, 3);
3706
 
3707
      ecoff_read_begin_hook ();
3708
 
3709
      if (first_file_directive)
3710
        {
3711
          char *save_ilp = input_line_pointer;
3712
          input_line_pointer = first_file_directive;
3713
          ecoff_directive_file (0);
3714
          input_line_pointer = save_ilp;
3715
          free (first_file_directive);
3716
        }
3717
 
3718
      alpha_flag_mdebug = 1;
3719
    }
3720
  s_stab (n);
3721
}
3722
 
3723
static void
3724
s_alpha_coff_wrapper (int which)
3725
{
3726
  static void (* const fns[]) PARAMS ((int)) = {
3727
    ecoff_directive_begin,
3728
    ecoff_directive_bend,
3729
    ecoff_directive_def,
3730
    ecoff_directive_dim,
3731
    ecoff_directive_endef,
3732
    ecoff_directive_scl,
3733
    ecoff_directive_tag,
3734
    ecoff_directive_val,
3735
  };
3736
 
3737
  assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
3738
 
3739
  if (ECOFF_DEBUGGING)
3740
    (*fns[which]) (0);
3741
  else
3742
    {
3743
      as_bad (_("ECOFF debugging is disabled."));
3744
      ignore_rest_of_line ();
3745
    }
3746
}
3747
 
3748
/* Called at the end of assembly.  Here we emit unwind info for frames
3749
   unless the compiler has done it for us.  */
3750
 
3751
void
3752
alpha_elf_md_end (void)
3753
{
3754
  struct alpha_elf_frame_data *p;
3755
 
3756
  if (cur_frame_data)
3757
    as_warn (_(".ent directive without matching .end"));
3758
 
3759
  /* If someone has generated the unwind info themselves, great.  */
3760
  if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
3761
    return;
3762
 
3763
  /* Generate .eh_frame data for the unwind directives specified.  */
3764
  for (p = all_frame_data; p ; p = p->next)
3765
    if (p->prologue_sym)
3766
      {
3767
        /* Create a temporary symbol at the same location as our
3768
           function symbol.  This prevents problems with globals.  */
3769
        cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
3770
                                      S_GET_VALUE (p->func_sym),
3771
                                      symbol_get_frag (p->func_sym)));
3772
 
3773
        cfi_set_return_column (p->ra_regno);
3774
        cfi_add_CFA_def_cfa_register (30);
3775
        if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
3776
          {
3777
            unsigned int mask;
3778
            offsetT offset;
3779
 
3780
            cfi_add_advance_loc (p->prologue_sym);
3781
 
3782
            if (p->fp_regno != 30)
3783
              if (p->frame_size != 0)
3784
                cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
3785
              else
3786
                cfi_add_CFA_def_cfa_register (p->fp_regno);
3787
            else if (p->frame_size != 0)
3788
              cfi_add_CFA_def_cfa_offset (p->frame_size);
3789
 
3790
            mask = p->mask;
3791
            offset = p->mask_offset;
3792
 
3793
            /* Recall that $26 is special-cased and stored first.  */
3794
            if ((mask >> 26) & 1)
3795
              {
3796
                cfi_add_CFA_offset (26, offset);
3797
                offset += 8;
3798
                mask &= ~(1 << 26);
3799
              }
3800
            while (mask)
3801
              {
3802
                unsigned int i;
3803
                i = mask & -mask;
3804
                mask ^= i;
3805
                i = ffs (i) - 1;
3806
 
3807
                cfi_add_CFA_offset (i, offset);
3808
                offset += 8;
3809
              }
3810
 
3811
            mask = p->fmask;
3812
            offset = p->fmask_offset;
3813
            while (mask)
3814
              {
3815
                unsigned int i;
3816
                i = mask & -mask;
3817
                mask ^= i;
3818
                i = ffs (i) - 1;
3819
 
3820
                cfi_add_CFA_offset (i + 32, offset);
3821
                offset += 8;
3822
              }
3823
          }
3824
 
3825
        cfi_end_fde (p->func_end_sym);
3826
      }
3827
}
3828
 
3829
static void
3830
s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
3831
{
3832
  char *name, name_end;
3833
  char *which, which_end;
3834
  symbolS *sym;
3835
  int other;
3836
 
3837
  name = input_line_pointer;
3838
  name_end = get_symbol_end ();
3839
 
3840
  if (! is_name_beginner (*name))
3841
    {
3842
      as_bad (_(".usepv directive has no name"));
3843
      *input_line_pointer = name_end;
3844
      ignore_rest_of_line ();
3845
      return;
3846
    }
3847
 
3848
  sym = symbol_find_or_make (name);
3849
  *input_line_pointer++ = name_end;
3850
 
3851
  if (name_end != ',')
3852
    {
3853
      as_bad (_(".usepv directive has no type"));
3854
      ignore_rest_of_line ();
3855
      return;
3856
    }
3857
 
3858
  SKIP_WHITESPACE ();
3859
  which = input_line_pointer;
3860
  which_end = get_symbol_end ();
3861
 
3862
  if (strcmp (which, "no") == 0)
3863
    other = STO_ALPHA_NOPV;
3864
  else if (strcmp (which, "std") == 0)
3865
    other = STO_ALPHA_STD_GPLOAD;
3866
  else
3867
    {
3868
      as_bad (_("unknown argument for .usepv"));
3869
      other = 0;
3870
    }
3871
 
3872
  *input_line_pointer = which_end;
3873
  demand_empty_rest_of_line ();
3874
 
3875
  S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3876
}
3877
#endif /* OBJ_ELF */
3878
 
3879
/* Standard calling conventions leaves the CFA at $30 on entry.  */
3880
 
3881
void
3882
alpha_cfi_frame_initial_instructions (void)
3883
{
3884
  cfi_add_CFA_def_cfa_register (30);
3885
}
3886
 
3887
#ifdef OBJ_EVAX
3888
 
3889
/* Handle the section specific pseudo-op.  */
3890
 
3891
static void
3892
s_alpha_section (int secid)
3893
{
3894
  int temp;
3895
#define EVAX_SECTION_COUNT 5
3896
  static char *section_name[EVAX_SECTION_COUNT + 1] =
3897
    { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3898
 
3899
  if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3900
    {
3901
      as_fatal (_("Unknown section directive"));
3902
      demand_empty_rest_of_line ();
3903
      return;
3904
    }
3905
  temp = get_absolute_expression ();
3906
  subseg_new (section_name[secid], 0);
3907
  demand_empty_rest_of_line ();
3908
  alpha_insn_label = NULL;
3909
  alpha_auto_align_on = 1;
3910
  alpha_current_align = 0;
3911
}
3912
 
3913
/* Parse .ent directives.  */
3914
 
3915
static void
3916
s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
3917
{
3918
  symbolS *symbol;
3919
  expressionS symexpr;
3920
 
3921
  alpha_evax_proc.pdsckind = 0;
3922
  alpha_evax_proc.framereg = -1;
3923
  alpha_evax_proc.framesize = 0;
3924
  alpha_evax_proc.rsa_offset = 0;
3925
  alpha_evax_proc.ra_save = AXP_REG_RA;
3926
  alpha_evax_proc.fp_save = -1;
3927
  alpha_evax_proc.imask = 0;
3928
  alpha_evax_proc.fmask = 0;
3929
  alpha_evax_proc.prologue = 0;
3930
  alpha_evax_proc.type = 0;
3931
 
3932
  expression (&symexpr);
3933
 
3934
  if (symexpr.X_op != O_symbol)
3935
    {
3936
      as_fatal (_(".ent directive has no symbol"));
3937
      demand_empty_rest_of_line ();
3938
      return;
3939
    }
3940
 
3941
  symbol = make_expr_symbol (&symexpr);
3942
  symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
3943
  alpha_evax_proc.symbol = symbol;
3944
 
3945
  demand_empty_rest_of_line ();
3946
}
3947
 
3948
/* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives.  */
3949
 
3950
static void
3951
s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
3952
{
3953
  long val;
3954
 
3955
  alpha_evax_proc.framereg = tc_get_register (1);
3956
 
3957
  SKIP_WHITESPACE ();
3958
  if (*input_line_pointer++ != ','
3959
      || get_absolute_expression_and_terminator (&val) != ',')
3960
    {
3961
      as_warn (_("Bad .frame directive 1./2. param"));
3962
      --input_line_pointer;
3963
      demand_empty_rest_of_line ();
3964
      return;
3965
    }
3966
 
3967
  alpha_evax_proc.framesize = val;
3968
 
3969
  (void) tc_get_register (1);
3970
  SKIP_WHITESPACE ();
3971
  if (*input_line_pointer++ != ',')
3972
    {
3973
      as_warn (_("Bad .frame directive 3./4. param"));
3974
      --input_line_pointer;
3975
      demand_empty_rest_of_line ();
3976
      return;
3977
    }
3978
  alpha_evax_proc.rsa_offset = get_absolute_expression ();
3979
}
3980
 
3981
static void
3982
s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
3983
{
3984
  char *name;
3985
  char name_end;
3986
  long val;
3987
  register char *p;
3988
  expressionS exp;
3989
  symbolS *entry_sym;
3990
  fixS *fixp;
3991
  segment_info_type *seginfo = seg_info (alpha_link_section);
3992
 
3993
  if (now_seg != alpha_link_section)
3994
    {
3995
      as_bad (_(".pdesc directive not in link (.link) section"));
3996
      demand_empty_rest_of_line ();
3997
      return;
3998
    }
3999
 
4000
  if ((alpha_evax_proc.symbol == 0)
4001
      || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4002
    {
4003
      as_fatal (_(".pdesc has no matching .ent"));
4004
      demand_empty_rest_of_line ();
4005
      return;
4006
    }
4007
 
4008
  *symbol_get_obj (alpha_evax_proc.symbol) =
4009
    (valueT) seginfo->literal_pool_size;
4010
 
4011
  expression (&exp);
4012
  if (exp.X_op != O_symbol)
4013
    {
4014
      as_warn (_(".pdesc directive has no entry symbol"));
4015
      demand_empty_rest_of_line ();
4016
      return;
4017
    }
4018
 
4019
  entry_sym = make_expr_symbol (&exp);
4020
  /* Save bfd symbol of proc desc in function symbol.  */
4021
  symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4022
    = symbol_get_bfdsym (entry_sym);
4023
 
4024
  SKIP_WHITESPACE ();
4025
  if (*input_line_pointer++ != ',')
4026
    {
4027
      as_warn (_("No comma after .pdesc <entryname>"));
4028
      demand_empty_rest_of_line ();
4029
      return;
4030
    }
4031
 
4032
  SKIP_WHITESPACE ();
4033
  name = input_line_pointer;
4034
  name_end = get_symbol_end ();
4035
 
4036
  if (strncmp (name, "stack", 5) == 0)
4037
    alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4038
 
4039
  else if (strncmp (name, "reg", 3) == 0)
4040
    alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4041
 
4042
  else if (strncmp (name, "null", 4) == 0)
4043
    alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4044
 
4045
  else
4046
    {
4047
      as_fatal (_("unknown procedure kind"));
4048
      demand_empty_rest_of_line ();
4049
      return;
4050
    }
4051
 
4052
  *input_line_pointer = name_end;
4053
  demand_empty_rest_of_line ();
4054
 
4055
#ifdef md_flush_pending_output
4056
  md_flush_pending_output ();
4057
#endif
4058
 
4059
  frag_align (3, 0, 0);
4060
  p = frag_more (16);
4061
  fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4062
  fixp->fx_done = 1;
4063
  seginfo->literal_pool_size += 16;
4064
 
4065
  *p = alpha_evax_proc.pdsckind
4066
    | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4067
  *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4068
 
4069
  switch (alpha_evax_proc.pdsckind)
4070
    {
4071
    case PDSC_S_K_KIND_NULL:
4072
      *(p + 2) = 0;
4073
      *(p + 3) = 0;
4074
      break;
4075
    case PDSC_S_K_KIND_FP_REGISTER:
4076
      *(p + 2) = alpha_evax_proc.fp_save;
4077
      *(p + 3) = alpha_evax_proc.ra_save;
4078
      break;
4079
    case PDSC_S_K_KIND_FP_STACK:
4080
      md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4081
      break;
4082
    default:            /* impossible */
4083
      break;
4084
    }
4085
 
4086
  *(p + 4) = 0;
4087
  *(p + 5) = alpha_evax_proc.type & 0x0f;
4088
 
4089
  /* Signature offset.  */
4090
  md_number_to_chars (p + 6, (valueT) 0, 2);
4091
 
4092
  fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4093
 
4094
  if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4095
    return;
4096
 
4097
  /* Add dummy fix to make add_to_link_pool work.  */
4098
  p = frag_more (8);
4099
  fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4100
  fixp->fx_done = 1;
4101
  seginfo->literal_pool_size += 8;
4102
 
4103
  /* pdesc+16: Size.  */
4104
  md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4105
 
4106
  md_number_to_chars (p + 4, (valueT) 0, 2);
4107
 
4108
  /* Entry length.  */
4109
  md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4110
 
4111
  if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4112
    return;
4113
 
4114
  /* Add dummy fix to make add_to_link_pool work.  */
4115
  p = frag_more (8);
4116
  fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4117
  fixp->fx_done = 1;
4118
  seginfo->literal_pool_size += 8;
4119
 
4120
  /* pdesc+24: register masks.  */
4121
 
4122
  md_number_to_chars (p, alpha_evax_proc.imask, 4);
4123
  md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4124
}
4125
 
4126
/* Support for crash debug on vms.  */
4127
 
4128
static void
4129
s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4130
{
4131
  char *p;
4132
  expressionS exp;
4133
  segment_info_type *seginfo = seg_info (alpha_link_section);
4134
 
4135
  if (now_seg != alpha_link_section)
4136
    {
4137
      as_bad (_(".name directive not in link (.link) section"));
4138
      demand_empty_rest_of_line ();
4139
      return;
4140
    }
4141
 
4142
  expression (&exp);
4143
  if (exp.X_op != O_symbol)
4144
    {
4145
      as_warn (_(".name directive has no symbol"));
4146
      demand_empty_rest_of_line ();
4147
      return;
4148
    }
4149
 
4150
  demand_empty_rest_of_line ();
4151
 
4152
#ifdef md_flush_pending_output
4153
  md_flush_pending_output ();
4154
#endif
4155
 
4156
  frag_align (3, 0, 0);
4157
  p = frag_more (8);
4158
  seginfo->literal_pool_size += 8;
4159
 
4160
  fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4161
}
4162
 
4163
static void
4164
s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4165
{
4166
  expressionS exp;
4167
  char *p;
4168
 
4169
#ifdef md_flush_pending_output
4170
  md_flush_pending_output ();
4171
#endif
4172
 
4173
  expression (&exp);
4174
  if (exp.X_op != O_symbol)
4175
    {
4176
      as_fatal (_("No symbol after .linkage"));
4177
    }
4178
  else
4179
    {
4180
      p = frag_more (LKP_S_K_SIZE);
4181
      memset (p, 0, LKP_S_K_SIZE);
4182
      fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4183
                   BFD_RELOC_ALPHA_LINKAGE);
4184
    }
4185
  demand_empty_rest_of_line ();
4186
}
4187
 
4188
static void
4189
s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
4190
{
4191
  expressionS exp;
4192
  char *p;
4193
 
4194
#ifdef md_flush_pending_output
4195
  md_flush_pending_output ();
4196
#endif
4197
 
4198
  expression (&exp);
4199
  if (exp.X_op != O_symbol)
4200
    as_fatal (_("No symbol after .code_address"));
4201
  else
4202
    {
4203
      p = frag_more (8);
4204
      memset (p, 0, 8);
4205
      fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4206
                   BFD_RELOC_ALPHA_CODEADDR);
4207
    }
4208
  demand_empty_rest_of_line ();
4209
}
4210
 
4211
static void
4212
s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
4213
{
4214
 
4215
  alpha_evax_proc.fp_save = tc_get_register (1);
4216
 
4217
  demand_empty_rest_of_line ();
4218
}
4219
 
4220
static void
4221
s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
4222
{
4223
  long val;
4224
 
4225
  if (get_absolute_expression_and_terminator (&val) != ',')
4226
    {
4227
      as_warn (_("Bad .mask directive"));
4228
      --input_line_pointer;
4229
    }
4230
  else
4231
    {
4232
      alpha_evax_proc.imask = val;
4233
      (void) get_absolute_expression ();
4234
    }
4235
  demand_empty_rest_of_line ();
4236
}
4237
 
4238
static void
4239
s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
4240
{
4241
  long val;
4242
 
4243
  if (get_absolute_expression_and_terminator (&val) != ',')
4244
    {
4245
      as_warn (_("Bad .fmask directive"));
4246
      --input_line_pointer;
4247
    }
4248
  else
4249
    {
4250
      alpha_evax_proc.fmask = val;
4251
      (void) get_absolute_expression ();
4252
    }
4253
  demand_empty_rest_of_line ();
4254
}
4255
 
4256
static void
4257
s_alpha_end (int ignore ATTRIBUTE_UNUSED)
4258
{
4259
  char c;
4260
 
4261
  c = get_symbol_end ();
4262
  *input_line_pointer = c;
4263
  demand_empty_rest_of_line ();
4264
  alpha_evax_proc.symbol = 0;
4265
}
4266
 
4267
static void
4268
s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4269
{
4270
  symbolS *s;
4271
  int length;
4272
  static char case_hack[32];
4273
 
4274
  sprintf (case_hack, "<CASE:%01d%01d>",
4275
           alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4276
 
4277
  s = symbol_find_or_make (case_hack);
4278
  symbol_get_bfdsym (s)->flags |= BSF_FILE;
4279
 
4280
  get_absolute_expression ();
4281
  s = symbol_find_or_make (demand_copy_string (&length));
4282
  symbol_get_bfdsym (s)->flags |= BSF_FILE;
4283
  demand_empty_rest_of_line ();
4284
}
4285
#endif /* OBJ_EVAX  */
4286
 
4287
/* Handle the .gprel32 pseudo op.  */
4288
 
4289
static void
4290
s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4291
{
4292
  expressionS e;
4293
  char *p;
4294
 
4295
  SKIP_WHITESPACE ();
4296
  expression (&e);
4297
 
4298
#ifdef OBJ_ELF
4299
  switch (e.X_op)
4300
    {
4301
    case O_constant:
4302
      e.X_add_symbol = section_symbol (absolute_section);
4303
      e.X_op = O_symbol;
4304
      /* FALLTHRU */
4305
    case O_symbol:
4306
      break;
4307
    default:
4308
      abort ();
4309
    }
4310
#else
4311
#ifdef OBJ_ECOFF
4312
  switch (e.X_op)
4313
    {
4314
    case O_constant:
4315
      e.X_add_symbol = section_symbol (absolute_section);
4316
      /* fall through */
4317
    case O_symbol:
4318
      e.X_op = O_subtract;
4319
      e.X_op_symbol = alpha_gp_symbol;
4320
      break;
4321
    default:
4322
      abort ();
4323
    }
4324
#endif
4325
#endif
4326
 
4327
  if (alpha_auto_align_on && alpha_current_align < 2)
4328
    alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4329
  if (alpha_current_align > 2)
4330
    alpha_current_align = 2;
4331
  alpha_insn_label = NULL;
4332
 
4333
  p = frag_more (4);
4334
  memset (p, 0, 4);
4335
  fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4336
               &e, 0, BFD_RELOC_GPREL32);
4337
}
4338
 
4339
/* Handle floating point allocation pseudo-ops.  This is like the
4340
   generic vresion, but it makes sure the current label, if any, is
4341
   correctly aligned.  */
4342
 
4343
static void
4344
s_alpha_float_cons (int type)
4345
{
4346
  int log_size;
4347
 
4348
  switch (type)
4349
    {
4350
    default:
4351
    case 'f':
4352
    case 'F':
4353
      log_size = 2;
4354
      break;
4355
 
4356
    case 'd':
4357
    case 'D':
4358
    case 'G':
4359
      log_size = 3;
4360
      break;
4361
 
4362
    case 'x':
4363
    case 'X':
4364
    case 'p':
4365
    case 'P':
4366
      log_size = 4;
4367
      break;
4368
    }
4369
 
4370
  if (alpha_auto_align_on && alpha_current_align < log_size)
4371
    alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4372
  if (alpha_current_align > log_size)
4373
    alpha_current_align = log_size;
4374
  alpha_insn_label = NULL;
4375
 
4376
  float_cons (type);
4377
}
4378
 
4379
/* Handle the .proc pseudo op.  We don't really do much with it except
4380
   parse it.  */
4381
 
4382
static void
4383
s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4384
{
4385
  char *name;
4386
  char c;
4387
  char *p;
4388
  symbolS *symbolP;
4389
  int temp;
4390
 
4391
  /* Takes ".proc name,nargs".  */
4392
  SKIP_WHITESPACE ();
4393
  name = input_line_pointer;
4394
  c = get_symbol_end ();
4395
  p = input_line_pointer;
4396
  symbolP = symbol_find_or_make (name);
4397
  *p = c;
4398
  SKIP_WHITESPACE ();
4399
  if (*input_line_pointer != ',')
4400
    {
4401
      *p = 0;
4402
      as_warn (_("Expected comma after name \"%s\""), name);
4403
      *p = c;
4404
      temp = 0;
4405
      ignore_rest_of_line ();
4406
    }
4407
  else
4408
    {
4409
      input_line_pointer++;
4410
      temp = get_absolute_expression ();
4411
    }
4412
  /*  *symbol_get_obj (symbolP) = (signed char) temp; */
4413
  as_warn (_("unhandled: .proc %s,%d"), name, temp);
4414
  demand_empty_rest_of_line ();
4415
}
4416
 
4417
/* Handle the .set pseudo op.  This is used to turn on and off most of
4418
   the assembler features.  */
4419
 
4420
static void
4421
s_alpha_set (int x ATTRIBUTE_UNUSED)
4422
{
4423
  char *name, ch, *s;
4424
  int yesno = 1;
4425
 
4426
  SKIP_WHITESPACE ();
4427
  name = input_line_pointer;
4428
  ch = get_symbol_end ();
4429
 
4430
  s = name;
4431
  if (s[0] == 'n' && s[1] == 'o')
4432
    {
4433
      yesno = 0;
4434
      s += 2;
4435
    }
4436
  if (!strcmp ("reorder", s))
4437
    /* ignore */ ;
4438
  else if (!strcmp ("at", s))
4439
    alpha_noat_on = !yesno;
4440
  else if (!strcmp ("macro", s))
4441
    alpha_macros_on = yesno;
4442
  else if (!strcmp ("move", s))
4443
    /* ignore */ ;
4444
  else if (!strcmp ("volatile", s))
4445
    /* ignore */ ;
4446
  else
4447
    as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4448
 
4449
  *input_line_pointer = ch;
4450
  demand_empty_rest_of_line ();
4451
}
4452
 
4453
/* Handle the .base pseudo op.  This changes the assembler's notion of
4454
   the $gp register.  */
4455
 
4456
static void
4457
s_alpha_base (int ignore ATTRIBUTE_UNUSED)
4458
{
4459
  SKIP_WHITESPACE ();
4460
 
4461
  if (*input_line_pointer == '$')
4462
    {
4463
      /* $rNN form.  */
4464
      input_line_pointer++;
4465
      if (*input_line_pointer == 'r')
4466
        input_line_pointer++;
4467
    }
4468
 
4469
  alpha_gp_register = get_absolute_expression ();
4470
  if (alpha_gp_register < 0 || alpha_gp_register > 31)
4471
    {
4472
      alpha_gp_register = AXP_REG_GP;
4473
      as_warn (_("Bad base register, using $%d."), alpha_gp_register);
4474
    }
4475
 
4476
  demand_empty_rest_of_line ();
4477
}
4478
 
4479
/* Handle the .align pseudo-op.  This aligns to a power of two.  It
4480
   also adjusts any current instruction label.  We treat this the same
4481
   way the MIPS port does: .align 0 turns off auto alignment.  */
4482
 
4483
static void
4484
s_alpha_align (int ignore ATTRIBUTE_UNUSED)
4485
{
4486
  int align;
4487
  char fill, *pfill;
4488
  long max_alignment = 15;
4489
 
4490
  align = get_absolute_expression ();
4491
  if (align > max_alignment)
4492
    {
4493
      align = max_alignment;
4494
      as_bad (_("Alignment too large: %d. assumed"), align);
4495
    }
4496
  else if (align < 0)
4497
    {
4498
      as_warn (_("Alignment negative: 0 assumed"));
4499
      align = 0;
4500
    }
4501
 
4502
  if (*input_line_pointer == ',')
4503
    {
4504
      input_line_pointer++;
4505
      fill = get_absolute_expression ();
4506
      pfill = &fill;
4507
    }
4508
  else
4509
    pfill = NULL;
4510
 
4511
  if (align != 0)
4512
    {
4513
      alpha_auto_align_on = 1;
4514
      alpha_align (align, pfill, alpha_insn_label, 1);
4515
    }
4516
  else
4517
    {
4518
      alpha_auto_align_on = 0;
4519
    }
4520
 
4521
  demand_empty_rest_of_line ();
4522
}
4523
 
4524
/* Hook the normal string processor to reset known alignment.  */
4525
 
4526
static void
4527
s_alpha_stringer (int terminate)
4528
{
4529
  alpha_current_align = 0;
4530
  alpha_insn_label = NULL;
4531
  stringer (8 + terminate);
4532
}
4533
 
4534
/* Hook the normal space processing to reset known alignment.  */
4535
 
4536
static void
4537
s_alpha_space (int ignore)
4538
{
4539
  alpha_current_align = 0;
4540
  alpha_insn_label = NULL;
4541
  s_space (ignore);
4542
}
4543
 
4544
/* Hook into cons for auto-alignment.  */
4545
 
4546
void
4547
alpha_cons_align (int size)
4548
{
4549
  int log_size;
4550
 
4551
  log_size = 0;
4552
  while ((size >>= 1) != 0)
4553
    ++log_size;
4554
 
4555
  if (alpha_auto_align_on && alpha_current_align < log_size)
4556
    alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4557
  if (alpha_current_align > log_size)
4558
    alpha_current_align = log_size;
4559
  alpha_insn_label = NULL;
4560
}
4561
 
4562
/* Here come the .uword, .ulong, and .uquad explicitly unaligned
4563
   pseudos.  We just turn off auto-alignment and call down to cons.  */
4564
 
4565
static void
4566
s_alpha_ucons (int bytes)
4567
{
4568
  int hold = alpha_auto_align_on;
4569
  alpha_auto_align_on = 0;
4570
  cons (bytes);
4571
  alpha_auto_align_on = hold;
4572
}
4573
 
4574
/* Switch the working cpu type.  */
4575
 
4576
static void
4577
s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
4578
{
4579
  char *name, ch;
4580
  const struct cpu_type *p;
4581
 
4582
  SKIP_WHITESPACE ();
4583
  name = input_line_pointer;
4584
  ch = get_symbol_end ();
4585
 
4586
  for (p = cpu_types; p->name; ++p)
4587
    if (strcmp (name, p->name) == 0)
4588
      {
4589
        alpha_target_name = p->name, alpha_target = p->flags;
4590
        goto found;
4591
      }
4592
  as_warn ("Unknown CPU identifier `%s'", name);
4593
 
4594
found:
4595
  *input_line_pointer = ch;
4596
  demand_empty_rest_of_line ();
4597
}
4598
 
4599
#ifdef DEBUG1
4600
/* print token expression with alpha specific extension.  */
4601
 
4602
static void
4603
alpha_print_token (FILE *f, const expressionS *exp)
4604
{
4605
  switch (exp->X_op)
4606
    {
4607
    case O_cpregister:
4608
      putc (',', f);
4609
      /* FALLTHRU */
4610
    case O_pregister:
4611
      putc ('(', f);
4612
      {
4613
        expressionS nexp = *exp;
4614
        nexp.X_op = O_register;
4615
        print_expr (f, &nexp);
4616
      }
4617
      putc (')', f);
4618
      break;
4619
    default:
4620
      print_expr (f, exp);
4621
      break;
4622
    }
4623
}
4624
#endif
4625
 
4626
/* The target specific pseudo-ops which we support.  */
4627
 
4628
const pseudo_typeS md_pseudo_table[] =
4629
{
4630
#ifdef OBJ_ECOFF
4631
  {"comm", s_alpha_comm, 0},     /* OSF1 compiler does this.  */
4632
  {"rdata", s_alpha_rdata, 0},
4633
#endif
4634
  {"text", s_alpha_text, 0},
4635
  {"data", s_alpha_data, 0},
4636
#ifdef OBJ_ECOFF
4637
  {"sdata", s_alpha_sdata, 0},
4638
#endif
4639
#ifdef OBJ_ELF
4640
  {"section", s_alpha_section, 0},
4641
  {"section.s", s_alpha_section, 0},
4642
  {"sect", s_alpha_section, 0},
4643
  {"sect.s", s_alpha_section, 0},
4644
#endif
4645
#ifdef OBJ_EVAX
4646
  { "pdesc", s_alpha_pdesc, 0},
4647
  { "name", s_alpha_name, 0},
4648
  { "linkage", s_alpha_linkage, 0},
4649
  { "code_address", s_alpha_code_address, 0},
4650
  { "ent", s_alpha_ent, 0},
4651
  { "frame", s_alpha_frame, 0},
4652
  { "fp_save", s_alpha_fp_save, 0},
4653
  { "mask", s_alpha_mask, 0},
4654
  { "fmask", s_alpha_fmask, 0},
4655
  { "end", s_alpha_end, 0},
4656
  { "file", s_alpha_file, 0},
4657
  { "rdata", s_alpha_section, 1},
4658
  { "comm", s_alpha_comm, 0},
4659
  { "link", s_alpha_section, 3},
4660
  { "ctors", s_alpha_section, 4},
4661
  { "dtors", s_alpha_section, 5},
4662
#endif
4663
#ifdef OBJ_ELF
4664
  /* Frame related pseudos.  */
4665
  {"ent", s_alpha_ent, 0},
4666
  {"end", s_alpha_end, 0},
4667
  {"mask", s_alpha_mask, 0},
4668
  {"fmask", s_alpha_mask, 1},
4669
  {"frame", s_alpha_frame, 0},
4670
  {"prologue", s_alpha_prologue, 0},
4671
  {"file", s_alpha_file, 5},
4672
  {"loc", s_alpha_loc, 9},
4673
  {"stabs", s_alpha_stab, 's'},
4674
  {"stabn", s_alpha_stab, 'n'},
4675
  {"usepv", s_alpha_usepv, 0},
4676
  /* COFF debugging related pseudos.  */
4677
  {"begin", s_alpha_coff_wrapper, 0},
4678
  {"bend", s_alpha_coff_wrapper, 1},
4679
  {"def", s_alpha_coff_wrapper, 2},
4680
  {"dim", s_alpha_coff_wrapper, 3},
4681
  {"endef", s_alpha_coff_wrapper, 4},
4682
  {"scl", s_alpha_coff_wrapper, 5},
4683
  {"tag", s_alpha_coff_wrapper, 6},
4684
  {"val", s_alpha_coff_wrapper, 7},
4685
#else
4686
  {"prologue", s_ignore, 0},
4687
#endif
4688
  {"gprel32", s_alpha_gprel32, 0},
4689
  {"t_floating", s_alpha_float_cons, 'd'},
4690
  {"s_floating", s_alpha_float_cons, 'f'},
4691
  {"f_floating", s_alpha_float_cons, 'F'},
4692
  {"g_floating", s_alpha_float_cons, 'G'},
4693
  {"d_floating", s_alpha_float_cons, 'D'},
4694
 
4695
  {"proc", s_alpha_proc, 0},
4696
  {"aproc", s_alpha_proc, 1},
4697
  {"set", s_alpha_set, 0},
4698
  {"reguse", s_ignore, 0},
4699
  {"livereg", s_ignore, 0},
4700
  {"base", s_alpha_base, 0},             /*??*/
4701
  {"option", s_ignore, 0},
4702
  {"aent", s_ignore, 0},
4703
  {"ugen", s_ignore, 0},
4704
  {"eflag", s_ignore, 0},
4705
 
4706
  {"align", s_alpha_align, 0},
4707
  {"double", s_alpha_float_cons, 'd'},
4708
  {"float", s_alpha_float_cons, 'f'},
4709
  {"single", s_alpha_float_cons, 'f'},
4710
  {"ascii", s_alpha_stringer, 0},
4711
  {"asciz", s_alpha_stringer, 1},
4712
  {"string", s_alpha_stringer, 1},
4713
  {"space", s_alpha_space, 0},
4714
  {"skip", s_alpha_space, 0},
4715
  {"zero", s_alpha_space, 0},
4716
 
4717
/* Unaligned data pseudos.  */
4718
  {"uword", s_alpha_ucons, 2},
4719
  {"ulong", s_alpha_ucons, 4},
4720
  {"uquad", s_alpha_ucons, 8},
4721
 
4722
#ifdef OBJ_ELF
4723
/* Dwarf wants these versions of unaligned.  */
4724
  {"2byte", s_alpha_ucons, 2},
4725
  {"4byte", s_alpha_ucons, 4},
4726
  {"8byte", s_alpha_ucons, 8},
4727
#endif
4728
 
4729
/* We don't do any optimizing, so we can safely ignore these.  */
4730
  {"noalias", s_ignore, 0},
4731
  {"alias", s_ignore, 0},
4732
 
4733
  {"arch", s_alpha_arch, 0},
4734
 
4735
  {NULL, 0, 0},
4736
};
4737
 
4738
#ifdef OBJ_ECOFF
4739
 
4740
/* @@@ GP selection voodoo.  All of this seems overly complicated and
4741
   unnecessary; which is the primary reason it's for ECOFF only.  */
4742
static inline void maybe_set_gp PARAMS ((asection *));
4743
 
4744
static inline void
4745
maybe_set_gp (asection *sec)
4746
{
4747
  bfd_vma vma;
4748
 
4749
  if (!sec)
4750
    return;
4751
  vma = bfd_get_section_vma (foo, sec);
4752
  if (vma && vma < alpha_gp_value)
4753
    alpha_gp_value = vma;
4754
}
4755
 
4756
static void
4757
select_gp_value (void)
4758
{
4759
  assert (alpha_gp_value == 0);
4760
 
4761
  /* Get minus-one in whatever width...  */
4762
  alpha_gp_value = 0;
4763
  alpha_gp_value--;
4764
 
4765
  /* Select the smallest VMA of these existing sections.  */
4766
  maybe_set_gp (alpha_lita_section);
4767
 
4768
/* @@ Will a simple 0x8000 work here?  If not, why not?  */
4769
#define GP_ADJUSTMENT   (0x8000 - 0x10)
4770
 
4771
  alpha_gp_value += GP_ADJUSTMENT;
4772
 
4773
  S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4774
 
4775
#ifdef DEBUG1
4776
  printf (_("Chose GP value of %lx\n"), alpha_gp_value);
4777
#endif
4778
}
4779
#endif /* OBJ_ECOFF */
4780
 
4781
#ifdef OBJ_ELF
4782
/* Map 's' to SHF_ALPHA_GPREL.  */
4783
 
4784
int
4785
alpha_elf_section_letter (int letter, char **ptr_msg)
4786
{
4787
  if (letter == 's')
4788
    return SHF_ALPHA_GPREL;
4789
 
4790
  *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
4791
  return -1;
4792
}
4793
 
4794
/* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA.  */
4795
 
4796
flagword
4797
alpha_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
4798
{
4799
  if (attr & SHF_ALPHA_GPREL)
4800
    flags |= SEC_SMALL_DATA;
4801
  return flags;
4802
}
4803
#endif /* OBJ_ELF */
4804
 
4805
/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
4806
   of an rs_align_code fragment.  */
4807
 
4808
void
4809
alpha_handle_align (fragS *fragp)
4810
{
4811
  static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
4812
  static char const nopunop[8] =
4813
  {
4814
    0x1f, 0x04, 0xff, 0x47,
4815
    0x00, 0x00, 0xfe, 0x2f
4816
  };
4817
 
4818
  int bytes, fix;
4819
  char *p;
4820
 
4821
  if (fragp->fr_type != rs_align_code)
4822
    return;
4823
 
4824
  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4825
  p = fragp->fr_literal + fragp->fr_fix;
4826
  fix = 0;
4827
 
4828
  if (bytes & 3)
4829
    {
4830
      fix = bytes & 3;
4831
      memset (p, 0, fix);
4832
      p += fix;
4833
      bytes -= fix;
4834
    }
4835
 
4836
  if (bytes & 4)
4837
    {
4838
      memcpy (p, unop, 4);
4839
      p += 4;
4840
      bytes -= 4;
4841
      fix += 4;
4842
    }
4843
 
4844
  memcpy (p, nopunop, 8);
4845
 
4846
  fragp->fr_fix += fix;
4847
  fragp->fr_var = 8;
4848
}
4849
 
4850
/* Public interface functions.  */
4851
 
4852
/* This function is called once, at assembler startup time.  It sets
4853
   up all the tables, etc. that the MD part of the assembler will
4854
   need, that can be determined before arguments are parsed.  */
4855
 
4856
void
4857
md_begin (void)
4858
{
4859
  unsigned int i;
4860
 
4861
  /* Verify that X_op field is wide enough.  */
4862
  {
4863
    expressionS e;
4864
 
4865
    e.X_op = O_max;
4866
    assert (e.X_op == O_max);
4867
  }
4868
 
4869
  /* Create the opcode hash table.  */
4870
  alpha_opcode_hash = hash_new ();
4871
 
4872
  for (i = 0; i < alpha_num_opcodes;)
4873
    {
4874
      const char *name, *retval, *slash;
4875
 
4876
      name = alpha_opcodes[i].name;
4877
      retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
4878
      if (retval)
4879
        as_fatal (_("internal error: can't hash opcode `%s': %s"),
4880
                  name, retval);
4881
 
4882
      /* Some opcodes include modifiers of various sorts with a "/mod"
4883
         syntax, like the architecture manual suggests.  However, for
4884
         use with gcc at least, we also need access to those same opcodes
4885
         without the "/".  */
4886
 
4887
      if ((slash = strchr (name, '/')) != NULL)
4888
        {
4889
          char *p = xmalloc (strlen (name));
4890
 
4891
          memcpy (p, name, slash - name);
4892
          strcpy (p + (slash - name), slash + 1);
4893
 
4894
          (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
4895
          /* Ignore failures -- the opcode table does duplicate some
4896
             variants in different forms, like "hw_stq" and "hw_st/q".  */
4897
        }
4898
 
4899
      while (++i < alpha_num_opcodes
4900
             && (alpha_opcodes[i].name == name
4901
                 || !strcmp (alpha_opcodes[i].name, name)))
4902
        continue;
4903
    }
4904
 
4905
  /* Create the macro hash table.  */
4906
  alpha_macro_hash = hash_new ();
4907
 
4908
  for (i = 0; i < alpha_num_macros;)
4909
    {
4910
      const char *name, *retval;
4911
 
4912
      name = alpha_macros[i].name;
4913
      retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
4914
      if (retval)
4915
        as_fatal (_("internal error: can't hash macro `%s': %s"),
4916
                  name, retval);
4917
 
4918
      while (++i < alpha_num_macros
4919
             && (alpha_macros[i].name == name
4920
                 || !strcmp (alpha_macros[i].name, name)))
4921
        continue;
4922
    }
4923
 
4924
  /* Construct symbols for each of the registers.  */
4925
  for (i = 0; i < 32; ++i)
4926
    {
4927
      char name[4];
4928
 
4929
      sprintf (name, "$%d", i);
4930
      alpha_register_table[i] = symbol_create (name, reg_section, i,
4931
                                               &zero_address_frag);
4932
    }
4933
 
4934
  for (; i < 64; ++i)
4935
    {
4936
      char name[5];
4937
 
4938
      sprintf (name, "$f%d", i - 32);
4939
      alpha_register_table[i] = symbol_create (name, reg_section, i,
4940
                                               &zero_address_frag);
4941
    }
4942
 
4943
  /* Create the special symbols and sections we'll be using.  */
4944
 
4945
  /* So .sbss will get used for tiny objects.  */
4946
  bfd_set_gp_size (stdoutput, g_switch_value);
4947
 
4948
#ifdef OBJ_ECOFF
4949
  create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
4950
 
4951
  /* For handling the GP, create a symbol that won't be output in the
4952
     symbol table.  We'll edit it out of relocs later.  */
4953
  alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
4954
                                   &zero_address_frag);
4955
#endif
4956
 
4957
#ifdef OBJ_EVAX
4958
  create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
4959
#endif
4960
 
4961
#ifdef OBJ_ELF
4962
  if (ECOFF_DEBUGGING)
4963
    {
4964
      segT sec = subseg_new (".mdebug", (subsegT) 0);
4965
      bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4966
      bfd_set_section_alignment (stdoutput, sec, 3);
4967
    }
4968
#endif
4969
 
4970
  /* Create literal lookup hash table.  */
4971
  alpha_literal_hash = hash_new ();
4972
 
4973
  subseg_set (text_section, 0);
4974
}
4975
 
4976
/* The public interface to the instruction assembler.  */
4977
 
4978
void
4979
md_assemble (char *str)
4980
{
4981
  /* Current maximum is 13.  */
4982
  char opname[32];
4983
  expressionS tok[MAX_INSN_ARGS];
4984
  int ntok, trunclen;
4985
  size_t opnamelen;
4986
 
4987
  /* Split off the opcode.  */
4988
  opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
4989
  trunclen = (opnamelen < sizeof (opname) - 1
4990
              ? opnamelen
4991
              : sizeof (opname) - 1);
4992
  memcpy (opname, str, trunclen);
4993
  opname[trunclen] = '\0';
4994
 
4995
  /* Tokenize the rest of the line.  */
4996
  if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
4997
    {
4998
      if (ntok != TOKENIZE_ERROR_REPORT)
4999
        as_bad (_("syntax error"));
5000
 
5001
      return;
5002
    }
5003
 
5004
  /* Finish it off.  */
5005
  assemble_tokens (opname, tok, ntok, alpha_macros_on);
5006
}
5007
 
5008
/* Round up a section's size to the appropriate boundary.  */
5009
 
5010
valueT
5011
md_section_align (segT seg, valueT size)
5012
{
5013
  int align = bfd_get_section_alignment (stdoutput, seg);
5014
  valueT mask = ((valueT) 1 << align) - 1;
5015
 
5016
  return (size + mask) & ~mask;
5017
}
5018
 
5019
/* Turn a string in input_line_pointer into a floating point constant
5020
   of type TYPE, and store the appropriate bytes in *LITP.  The number
5021
   of LITTLENUMS emitted is stored in *SIZEP.  An error message is
5022
   returned, or NULL on OK.  */
5023
 
5024
char *
5025
md_atof (int type, char *litP, int *sizeP)
5026
{
5027
  extern char *vax_md_atof (int, char *, int *);
5028
 
5029
  switch (type)
5030
    {
5031
      /* VAX floats.  */
5032
    case 'G':
5033
      /* vax_md_atof() doesn't like "G" for some reason.  */
5034
      type = 'g';
5035
    case 'F':
5036
    case 'D':
5037
      return vax_md_atof (type, litP, sizeP);
5038
 
5039
    default:
5040
      return ieee_md_atof (type, litP, sizeP, FALSE);
5041
    }
5042
}
5043
 
5044
/* Take care of the target-specific command-line options.  */
5045
 
5046
int
5047
md_parse_option (int c, char *arg)
5048
{
5049
  switch (c)
5050
    {
5051
    case 'F':
5052
      alpha_nofloats_on = 1;
5053
      break;
5054
 
5055
    case OPTION_32ADDR:
5056
      alpha_addr32_on = 1;
5057
      break;
5058
 
5059
    case 'g':
5060
      alpha_debug = 1;
5061
      break;
5062
 
5063
    case 'G':
5064
      g_switch_value = atoi (arg);
5065
      break;
5066
 
5067
    case 'm':
5068
      {
5069
        const struct cpu_type *p;
5070
 
5071
        for (p = cpu_types; p->name; ++p)
5072
          if (strcmp (arg, p->name) == 0)
5073
            {
5074
              alpha_target_name = p->name, alpha_target = p->flags;
5075
              goto found;
5076
            }
5077
        as_warn (_("Unknown CPU identifier `%s'"), arg);
5078
      found:;
5079
      }
5080
      break;
5081
 
5082
#ifdef OBJ_EVAX
5083
    case '+':                   /* For g++.  Hash any name > 63 chars long.  */
5084
      alpha_flag_hash_long_names = 1;
5085
      break;
5086
 
5087
    case 'H':                   /* Show new symbol after hash truncation.  */
5088
      alpha_flag_show_after_trunc = 1;
5089
      break;
5090
 
5091
    case 'h':                   /* For gnu-c/vax compatibility.  */
5092
      break;
5093
#endif
5094
 
5095
    case OPTION_RELAX:
5096
      alpha_flag_relax = 1;
5097
      break;
5098
 
5099
#ifdef OBJ_ELF
5100
    case OPTION_MDEBUG:
5101
      alpha_flag_mdebug = 1;
5102
      break;
5103
    case OPTION_NO_MDEBUG:
5104
      alpha_flag_mdebug = 0;
5105
      break;
5106
#endif
5107
 
5108
    default:
5109
      return 0;
5110
    }
5111
 
5112
  return 1;
5113
}
5114
 
5115
/* Print a description of the command-line options that we accept.  */
5116
 
5117
void
5118
md_show_usage (FILE *stream)
5119
{
5120
  fputs (_("\
5121
Alpha options:\n\
5122
-32addr                 treat addresses as 32-bit values\n\
5123
-F                      lack floating point instructions support\n\
5124
-mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5125
                        specify variant of Alpha architecture\n\
5126
-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5127
                        these variants include PALcode opcodes\n"),
5128
        stream);
5129
#ifdef OBJ_EVAX
5130
  fputs (_("\
5131
VMS options:\n\
5132
-+                      hash encode (don't truncate) names longer than 64 characters\n\
5133
-H                      show new symbol after hash truncation\n"),
5134
        stream);
5135
#endif
5136
}
5137
 
5138
/* Decide from what point a pc-relative relocation is relative to,
5139
   relative to the pc-relative fixup.  Er, relatively speaking.  */
5140
 
5141
long
5142
md_pcrel_from (fixS *fixP)
5143
{
5144
  valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5145
 
5146
  switch (fixP->fx_r_type)
5147
    {
5148
    case BFD_RELOC_23_PCREL_S2:
5149
    case BFD_RELOC_ALPHA_HINT:
5150
    case BFD_RELOC_ALPHA_BRSGP:
5151
      return addr + 4;
5152
    default:
5153
      return addr;
5154
    }
5155
}
5156
 
5157
/* Attempt to simplify or even eliminate a fixup.  The return value is
5158
   ignored; perhaps it was once meaningful, but now it is historical.
5159
   To indicate that a fixup has been eliminated, set fixP->fx_done.
5160
 
5161
   For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5162
   internally into the GPDISP reloc used externally.  We had to do
5163
   this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5164
   the distance to the "lda" instruction for setting the addend to
5165
   GPDISP.  */
5166
 
5167
void
5168
md_apply_fix (fixS *fixP, valueT * valP, segT seg)
5169
{
5170
  char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5171
  valueT value = * valP;
5172
  unsigned image, size;
5173
 
5174
  switch (fixP->fx_r_type)
5175
    {
5176
      /* The GPDISP relocations are processed internally with a symbol
5177
         referring to the current function's section;  we need to drop
5178
         in a value which, when added to the address of the start of
5179
         the function, gives the desired GP.  */
5180
    case BFD_RELOC_ALPHA_GPDISP_HI16:
5181
      {
5182
        fixS *next = fixP->fx_next;
5183
 
5184
        /* With user-specified !gpdisp relocations, we can be missing
5185
           the matching LO16 reloc.  We will have already issued an
5186
           error message.  */
5187
        if (next)
5188
          fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5189
                             - fixP->fx_frag->fr_address - fixP->fx_where);
5190
 
5191
        value = (value - sign_extend_16 (value)) >> 16;
5192
      }
5193
#ifdef OBJ_ELF
5194
      fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5195
#endif
5196
      goto do_reloc_gp;
5197
 
5198
    case BFD_RELOC_ALPHA_GPDISP_LO16:
5199
      value = sign_extend_16 (value);
5200
      fixP->fx_offset = 0;
5201
#ifdef OBJ_ELF
5202
      fixP->fx_done = 1;
5203
#endif
5204
 
5205
    do_reloc_gp:
5206
      fixP->fx_addsy = section_symbol (seg);
5207
      md_number_to_chars (fixpos, value, 2);
5208
      break;
5209
 
5210
    case BFD_RELOC_16:
5211
      if (fixP->fx_pcrel)
5212
        fixP->fx_r_type = BFD_RELOC_16_PCREL;
5213
      size = 2;
5214
      goto do_reloc_xx;
5215
 
5216
    case BFD_RELOC_32:
5217
      if (fixP->fx_pcrel)
5218
        fixP->fx_r_type = BFD_RELOC_32_PCREL;
5219
      size = 4;
5220
      goto do_reloc_xx;
5221
 
5222
    case BFD_RELOC_64:
5223
      if (fixP->fx_pcrel)
5224
        fixP->fx_r_type = BFD_RELOC_64_PCREL;
5225
      size = 8;
5226
 
5227
    do_reloc_xx:
5228
      if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5229
        {
5230
          md_number_to_chars (fixpos, value, size);
5231
          goto done;
5232
        }
5233
      return;
5234
 
5235
#ifdef OBJ_ECOFF
5236
    case BFD_RELOC_GPREL32:
5237
      assert (fixP->fx_subsy == alpha_gp_symbol);
5238
      fixP->fx_subsy = 0;
5239
      /* FIXME: inherited this obliviousness of `value' -- why?  */
5240
      md_number_to_chars (fixpos, -alpha_gp_value, 4);
5241
      break;
5242
#else
5243
    case BFD_RELOC_GPREL32:
5244
#endif
5245
    case BFD_RELOC_GPREL16:
5246
    case BFD_RELOC_ALPHA_GPREL_HI16:
5247
    case BFD_RELOC_ALPHA_GPREL_LO16:
5248
      return;
5249
 
5250
    case BFD_RELOC_23_PCREL_S2:
5251
      if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5252
        {
5253
          image = bfd_getl32 (fixpos);
5254
          image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5255
          goto write_done;
5256
        }
5257
      return;
5258
 
5259
    case BFD_RELOC_ALPHA_HINT:
5260
      if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5261
        {
5262
          image = bfd_getl32 (fixpos);
5263
          image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5264
          goto write_done;
5265
        }
5266
      return;
5267
 
5268
#ifdef OBJ_ELF
5269
    case BFD_RELOC_ALPHA_BRSGP:
5270
      return;
5271
 
5272
    case BFD_RELOC_ALPHA_TLSGD:
5273
    case BFD_RELOC_ALPHA_TLSLDM:
5274
    case BFD_RELOC_ALPHA_GOTDTPREL16:
5275
    case BFD_RELOC_ALPHA_DTPREL_HI16:
5276
    case BFD_RELOC_ALPHA_DTPREL_LO16:
5277
    case BFD_RELOC_ALPHA_DTPREL16:
5278
    case BFD_RELOC_ALPHA_GOTTPREL16:
5279
    case BFD_RELOC_ALPHA_TPREL_HI16:
5280
    case BFD_RELOC_ALPHA_TPREL_LO16:
5281
    case BFD_RELOC_ALPHA_TPREL16:
5282
      if (fixP->fx_addsy)
5283
        S_SET_THREAD_LOCAL (fixP->fx_addsy);
5284
      return;
5285
#endif
5286
 
5287
#ifdef OBJ_ECOFF
5288
    case BFD_RELOC_ALPHA_LITERAL:
5289
      md_number_to_chars (fixpos, value, 2);
5290
      return;
5291
#endif
5292
    case BFD_RELOC_ALPHA_ELF_LITERAL:
5293
    case BFD_RELOC_ALPHA_LITUSE:
5294
    case BFD_RELOC_ALPHA_LINKAGE:
5295
    case BFD_RELOC_ALPHA_CODEADDR:
5296
      return;
5297
 
5298
    case BFD_RELOC_VTABLE_INHERIT:
5299
    case BFD_RELOC_VTABLE_ENTRY:
5300
      return;
5301
 
5302
    default:
5303
      {
5304
        const struct alpha_operand *operand;
5305
 
5306
        if ((int) fixP->fx_r_type >= 0)
5307
          as_fatal (_("unhandled relocation type %s"),
5308
                    bfd_get_reloc_code_name (fixP->fx_r_type));
5309
 
5310
        assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5311
        operand = &alpha_operands[-(int) fixP->fx_r_type];
5312
 
5313
        /* The rest of these fixups only exist internally during symbol
5314
           resolution and have no representation in the object file.
5315
           Therefore they must be completely resolved as constants.  */
5316
 
5317
        if (fixP->fx_addsy != 0
5318
            && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5319
          as_bad_where (fixP->fx_file, fixP->fx_line,
5320
                        _("non-absolute expression in constant field"));
5321
 
5322
        image = bfd_getl32 (fixpos);
5323
        image = insert_operand (image, operand, (offsetT) value,
5324
                                fixP->fx_file, fixP->fx_line);
5325
      }
5326
      goto write_done;
5327
    }
5328
 
5329
  if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
5330
    return;
5331
  else
5332
    {
5333
      as_warn_where (fixP->fx_file, fixP->fx_line,
5334
                     _("type %d reloc done?\n"), (int) fixP->fx_r_type);
5335
      goto done;
5336
    }
5337
 
5338
write_done:
5339
  md_number_to_chars (fixpos, image, 4);
5340
 
5341
done:
5342
  fixP->fx_done = 1;
5343
}
5344
 
5345
/* Look for a register name in the given symbol.  */
5346
 
5347
symbolS *
5348
md_undefined_symbol (char *name)
5349
{
5350
  if (*name == '$')
5351
    {
5352
      int is_float = 0, num;
5353
 
5354
      switch (*++name)
5355
        {
5356
        case 'f':
5357
          if (name[1] == 'p' && name[2] == '\0')
5358
            return alpha_register_table[AXP_REG_FP];
5359
          is_float = 32;
5360
          /* Fall through.  */
5361
 
5362
        case 'r':
5363
          if (!ISDIGIT (*++name))
5364
            break;
5365
          /* Fall through.  */
5366
 
5367
        case '0': case '1': case '2': case '3': case '4':
5368
        case '5': case '6': case '7': case '8': case '9':
5369
          if (name[1] == '\0')
5370
            num = name[0] - '0';
5371
          else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
5372
            {
5373
              num = (name[0] - '0') * 10 + name[1] - '0';
5374
              if (num >= 32)
5375
                break;
5376
            }
5377
          else
5378
            break;
5379
 
5380
          if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
5381
            as_warn (_("Used $at without \".set noat\""));
5382
          return alpha_register_table[num + is_float];
5383
 
5384
        case 'a':
5385
          if (name[1] == 't' && name[2] == '\0')
5386
            {
5387
              if (!alpha_noat_on)
5388
                as_warn (_("Used $at without \".set noat\""));
5389
              return alpha_register_table[AXP_REG_AT];
5390
            }
5391
          break;
5392
 
5393
        case 'g':
5394
          if (name[1] == 'p' && name[2] == '\0')
5395
            return alpha_register_table[alpha_gp_register];
5396
          break;
5397
 
5398
        case 's':
5399
          if (name[1] == 'p' && name[2] == '\0')
5400
            return alpha_register_table[AXP_REG_SP];
5401
          break;
5402
        }
5403
    }
5404
  return NULL;
5405
}
5406
 
5407
#ifdef OBJ_ECOFF
5408
/* @@@ Magic ECOFF bits.  */
5409
 
5410
void
5411
alpha_frob_ecoff_data (void)
5412
{
5413
  select_gp_value ();
5414
  /* $zero and $f31 are read-only.  */
5415
  alpha_gprmask &= ~1;
5416
  alpha_fprmask &= ~1;
5417
}
5418
#endif
5419
 
5420
/* Hook to remember a recently defined label so that the auto-align
5421
   code can adjust the symbol after we know what alignment will be
5422
   required.  */
5423
 
5424
void
5425
alpha_define_label (symbolS *sym)
5426
{
5427
  alpha_insn_label = sym;
5428
#ifdef OBJ_ELF
5429
  dwarf2_emit_label (sym);
5430
#endif
5431
}
5432
 
5433
/* Return true if we must always emit a reloc for a type and false if
5434
   there is some hope of resolving it at assembly time.  */
5435
 
5436
int
5437
alpha_force_relocation (fixS *f)
5438
{
5439
  if (alpha_flag_relax)
5440
    return 1;
5441
 
5442
  switch (f->fx_r_type)
5443
    {
5444
    case BFD_RELOC_ALPHA_GPDISP_HI16:
5445
    case BFD_RELOC_ALPHA_GPDISP_LO16:
5446
    case BFD_RELOC_ALPHA_GPDISP:
5447
    case BFD_RELOC_ALPHA_LITERAL:
5448
    case BFD_RELOC_ALPHA_ELF_LITERAL:
5449
    case BFD_RELOC_ALPHA_LITUSE:
5450
    case BFD_RELOC_GPREL16:
5451
    case BFD_RELOC_GPREL32:
5452
    case BFD_RELOC_ALPHA_GPREL_HI16:
5453
    case BFD_RELOC_ALPHA_GPREL_LO16:
5454
    case BFD_RELOC_ALPHA_LINKAGE:
5455
    case BFD_RELOC_ALPHA_CODEADDR:
5456
    case BFD_RELOC_ALPHA_BRSGP:
5457
    case BFD_RELOC_ALPHA_TLSGD:
5458
    case BFD_RELOC_ALPHA_TLSLDM:
5459
    case BFD_RELOC_ALPHA_GOTDTPREL16:
5460
    case BFD_RELOC_ALPHA_DTPREL_HI16:
5461
    case BFD_RELOC_ALPHA_DTPREL_LO16:
5462
    case BFD_RELOC_ALPHA_DTPREL16:
5463
    case BFD_RELOC_ALPHA_GOTTPREL16:
5464
    case BFD_RELOC_ALPHA_TPREL_HI16:
5465
    case BFD_RELOC_ALPHA_TPREL_LO16:
5466
    case BFD_RELOC_ALPHA_TPREL16:
5467
      return 1;
5468
 
5469
    default:
5470
      break;
5471
    }
5472
 
5473
  return generic_force_reloc (f);
5474
}
5475
 
5476
/* Return true if we can partially resolve a relocation now.  */
5477
 
5478
int
5479
alpha_fix_adjustable (fixS *f)
5480
{
5481
  /* Are there any relocation types for which we must generate a
5482
     reloc but we can adjust the values contained within it?   */
5483
  switch (f->fx_r_type)
5484
    {
5485
    case BFD_RELOC_ALPHA_GPDISP_HI16:
5486
    case BFD_RELOC_ALPHA_GPDISP_LO16:
5487
    case BFD_RELOC_ALPHA_GPDISP:
5488
      return 0;
5489
 
5490
    case BFD_RELOC_ALPHA_LITERAL:
5491
    case BFD_RELOC_ALPHA_ELF_LITERAL:
5492
    case BFD_RELOC_ALPHA_LITUSE:
5493
    case BFD_RELOC_ALPHA_LINKAGE:
5494
    case BFD_RELOC_ALPHA_CODEADDR:
5495
      return 1;
5496
 
5497
    case BFD_RELOC_VTABLE_ENTRY:
5498
    case BFD_RELOC_VTABLE_INHERIT:
5499
      return 0;
5500
 
5501
    case BFD_RELOC_GPREL16:
5502
    case BFD_RELOC_GPREL32:
5503
    case BFD_RELOC_ALPHA_GPREL_HI16:
5504
    case BFD_RELOC_ALPHA_GPREL_LO16:
5505
    case BFD_RELOC_23_PCREL_S2:
5506
    case BFD_RELOC_32:
5507
    case BFD_RELOC_64:
5508
    case BFD_RELOC_ALPHA_HINT:
5509
      return 1;
5510
 
5511
    case BFD_RELOC_ALPHA_TLSGD:
5512
    case BFD_RELOC_ALPHA_TLSLDM:
5513
    case BFD_RELOC_ALPHA_GOTDTPREL16:
5514
    case BFD_RELOC_ALPHA_DTPREL_HI16:
5515
    case BFD_RELOC_ALPHA_DTPREL_LO16:
5516
    case BFD_RELOC_ALPHA_DTPREL16:
5517
    case BFD_RELOC_ALPHA_GOTTPREL16:
5518
    case BFD_RELOC_ALPHA_TPREL_HI16:
5519
    case BFD_RELOC_ALPHA_TPREL_LO16:
5520
    case BFD_RELOC_ALPHA_TPREL16:
5521
      /* ??? No idea why we can't return a reference to .tbss+10, but
5522
         we're preventing this in the other assemblers.  Follow for now.  */
5523
      return 0;
5524
 
5525
#ifdef OBJ_ELF
5526
    case BFD_RELOC_ALPHA_BRSGP:
5527
      /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
5528
         let it get resolved at assembly time.  */
5529
      {
5530
        symbolS *sym = f->fx_addsy;
5531
        const char *name;
5532
        int offset = 0;
5533
 
5534
        if (generic_force_reloc (f))
5535
          return 0;
5536
 
5537
        switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
5538
          {
5539
          case STO_ALPHA_NOPV:
5540
            break;
5541
          case STO_ALPHA_STD_GPLOAD:
5542
            offset = 8;
5543
            break;
5544
          default:
5545
            if (S_IS_LOCAL (sym))
5546
              name = "<local>";
5547
            else
5548
              name = S_GET_NAME (sym);
5549
            as_bad_where (f->fx_file, f->fx_line,
5550
                _("!samegp reloc against symbol without .prologue: %s"),
5551
                name);
5552
            break;
5553
          }
5554
        f->fx_r_type = BFD_RELOC_23_PCREL_S2;
5555
        f->fx_offset += offset;
5556
        return 1;
5557
      }
5558
#endif
5559
 
5560
    default:
5561
      return 1;
5562
    }
5563
}
5564
 
5565
/* Generate the BFD reloc to be stuck in the object file from the
5566
   fixup used internally in the assembler.  */
5567
 
5568
arelent *
5569
tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
5570
              fixS *fixp)
5571
{
5572
  arelent *reloc;
5573
 
5574
  reloc = xmalloc (sizeof (* reloc));
5575
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5576
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5577
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5578
 
5579
  /* Make sure none of our internal relocations make it this far.
5580
     They'd better have been fully resolved by this point.  */
5581
  assert ((int) fixp->fx_r_type > 0);
5582
 
5583
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
5584
  if (reloc->howto == NULL)
5585
    {
5586
      as_bad_where (fixp->fx_file, fixp->fx_line,
5587
                    _("cannot represent `%s' relocation in object file"),
5588
                    bfd_get_reloc_code_name (fixp->fx_r_type));
5589
      return NULL;
5590
    }
5591
 
5592
  if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
5593
    as_fatal (_("internal error? cannot generate `%s' relocation"),
5594
              bfd_get_reloc_code_name (fixp->fx_r_type));
5595
 
5596
  assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
5597
 
5598
#ifdef OBJ_ECOFF
5599
  if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
5600
    /* Fake out bfd_perform_relocation. sigh.  */
5601
    reloc->addend = -alpha_gp_value;
5602
  else
5603
#endif
5604
    {
5605
      reloc->addend = fixp->fx_offset;
5606
#ifdef OBJ_ELF
5607
      /* Ohhh, this is ugly.  The problem is that if this is a local global
5608
         symbol, the relocation will entirely be performed at link time, not
5609
         at assembly time.  bfd_perform_reloc doesn't know about this sort
5610
         of thing, and as a result we need to fake it out here.  */
5611
      if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
5612
           || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
5613
           || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
5614
          && !S_IS_COMMON (fixp->fx_addsy))
5615
        reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
5616
#endif
5617
    }
5618
 
5619
  return reloc;
5620
}
5621
 
5622
/* Parse a register name off of the input_line and return a register
5623
   number.  Gets md_undefined_symbol above to do the register name
5624
   matching for us.
5625
 
5626
   Only called as a part of processing the ECOFF .frame directive.  */
5627
 
5628
int
5629
tc_get_register (int frame ATTRIBUTE_UNUSED)
5630
{
5631
  int framereg = AXP_REG_SP;
5632
 
5633
  SKIP_WHITESPACE ();
5634
  if (*input_line_pointer == '$')
5635
    {
5636
      char *s = input_line_pointer;
5637
      char c = get_symbol_end ();
5638
      symbolS *sym = md_undefined_symbol (s);
5639
 
5640
      *strchr (s, '\0') = c;
5641
      if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
5642
        goto found;
5643
    }
5644
  as_warn (_("frame reg expected, using $%d."), framereg);
5645
 
5646
found:
5647
  note_gpreg (framereg);
5648
  return framereg;
5649
}
5650
 
5651
/* This is called before the symbol table is processed.  In order to
5652
   work with gcc when using mips-tfile, we must keep all local labels.
5653
   However, in other cases, we want to discard them.  If we were
5654
   called with -g, but we didn't see any debugging information, it may
5655
   mean that gcc is smuggling debugging information through to
5656
   mips-tfile, in which case we must generate all local labels.  */
5657
 
5658
#ifdef OBJ_ECOFF
5659
 
5660
void
5661
alpha_frob_file_before_adjust (void)
5662
{
5663
  if (alpha_debug != 0
5664
      && ! ecoff_debugging_seen)
5665
    flag_keep_locals = 1;
5666
}
5667
 
5668
#endif /* OBJ_ECOFF */
5669
 
5670
/* The Alpha has support for some VAX floating point types, as well as for
5671
   IEEE floating point.  We consider IEEE to be the primary floating point
5672
   format, and sneak in the VAX floating point support here.  */
5673
#include "config/atof-vax.c"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.