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 146

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