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 166

Details | Compare with Previous | View Log

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