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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-alpha.c] - Blame information for rev 160

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

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