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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-alpha.c] - Blame information for rev 205

Details | Compare with Previous | View Log

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