1*a9fa9459Szrj /* tc-i386.c -- Assemble code for the Intel 80386
2*a9fa9459Szrj Copyright (C) 1989-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj
4*a9fa9459Szrj This file is part of GAS, the GNU Assembler.
5*a9fa9459Szrj
6*a9fa9459Szrj GAS is free software; you can redistribute it and/or modify
7*a9fa9459Szrj it under the terms of the GNU General Public License as published by
8*a9fa9459Szrj the Free Software Foundation; either version 3, or (at your option)
9*a9fa9459Szrj any later version.
10*a9fa9459Szrj
11*a9fa9459Szrj GAS is distributed in the hope that it will be useful,
12*a9fa9459Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a9fa9459Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*a9fa9459Szrj GNU General Public License for more details.
15*a9fa9459Szrj
16*a9fa9459Szrj You should have received a copy of the GNU General Public License
17*a9fa9459Szrj along with GAS; see the file COPYING. If not, write to the Free
18*a9fa9459Szrj Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19*a9fa9459Szrj 02110-1301, USA. */
20*a9fa9459Szrj
21*a9fa9459Szrj /* Intel 80386 machine specific gas.
22*a9fa9459Szrj Written by Eliot Dresselhaus (eliot@mgm.mit.edu).
23*a9fa9459Szrj x86_64 support by Jan Hubicka (jh@suse.cz)
24*a9fa9459Szrj VIA PadLock support by Michal Ludvig (mludvig@suse.cz)
25*a9fa9459Szrj Bugs & suggestions are completely welcome. This is free software.
26*a9fa9459Szrj Please help us make it better. */
27*a9fa9459Szrj
28*a9fa9459Szrj #include "as.h"
29*a9fa9459Szrj #include "safe-ctype.h"
30*a9fa9459Szrj #include "subsegs.h"
31*a9fa9459Szrj #include "dwarf2dbg.h"
32*a9fa9459Szrj #include "dw2gencfi.h"
33*a9fa9459Szrj #include "elf/x86-64.h"
34*a9fa9459Szrj #include "opcodes/i386-init.h"
35*a9fa9459Szrj
36*a9fa9459Szrj #ifndef REGISTER_WARNINGS
37*a9fa9459Szrj #define REGISTER_WARNINGS 1
38*a9fa9459Szrj #endif
39*a9fa9459Szrj
40*a9fa9459Szrj #ifndef INFER_ADDR_PREFIX
41*a9fa9459Szrj #define INFER_ADDR_PREFIX 1
42*a9fa9459Szrj #endif
43*a9fa9459Szrj
44*a9fa9459Szrj #ifndef DEFAULT_ARCH
45*a9fa9459Szrj #define DEFAULT_ARCH "i386"
46*a9fa9459Szrj #endif
47*a9fa9459Szrj
48*a9fa9459Szrj #ifndef INLINE
49*a9fa9459Szrj #if __GNUC__ >= 2
50*a9fa9459Szrj #define INLINE __inline__
51*a9fa9459Szrj #else
52*a9fa9459Szrj #define INLINE
53*a9fa9459Szrj #endif
54*a9fa9459Szrj #endif
55*a9fa9459Szrj
56*a9fa9459Szrj /* Prefixes will be emitted in the order defined below.
57*a9fa9459Szrj WAIT_PREFIX must be the first prefix since FWAIT is really is an
58*a9fa9459Szrj instruction, and so must come before any prefixes.
59*a9fa9459Szrj The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX,
60*a9fa9459Szrj REP_PREFIX/HLE_PREFIX, LOCK_PREFIX. */
61*a9fa9459Szrj #define WAIT_PREFIX 0
62*a9fa9459Szrj #define SEG_PREFIX 1
63*a9fa9459Szrj #define ADDR_PREFIX 2
64*a9fa9459Szrj #define DATA_PREFIX 3
65*a9fa9459Szrj #define REP_PREFIX 4
66*a9fa9459Szrj #define HLE_PREFIX REP_PREFIX
67*a9fa9459Szrj #define BND_PREFIX REP_PREFIX
68*a9fa9459Szrj #define LOCK_PREFIX 5
69*a9fa9459Szrj #define REX_PREFIX 6 /* must come last. */
70*a9fa9459Szrj #define MAX_PREFIXES 7 /* max prefixes per opcode */
71*a9fa9459Szrj
72*a9fa9459Szrj /* we define the syntax here (modulo base,index,scale syntax) */
73*a9fa9459Szrj #define REGISTER_PREFIX '%'
74*a9fa9459Szrj #define IMMEDIATE_PREFIX '$'
75*a9fa9459Szrj #define ABSOLUTE_PREFIX '*'
76*a9fa9459Szrj
77*a9fa9459Szrj /* these are the instruction mnemonic suffixes in AT&T syntax or
78*a9fa9459Szrj memory operand size in Intel syntax. */
79*a9fa9459Szrj #define WORD_MNEM_SUFFIX 'w'
80*a9fa9459Szrj #define BYTE_MNEM_SUFFIX 'b'
81*a9fa9459Szrj #define SHORT_MNEM_SUFFIX 's'
82*a9fa9459Szrj #define LONG_MNEM_SUFFIX 'l'
83*a9fa9459Szrj #define QWORD_MNEM_SUFFIX 'q'
84*a9fa9459Szrj #define XMMWORD_MNEM_SUFFIX 'x'
85*a9fa9459Szrj #define YMMWORD_MNEM_SUFFIX 'y'
86*a9fa9459Szrj #define ZMMWORD_MNEM_SUFFIX 'z'
87*a9fa9459Szrj /* Intel Syntax. Use a non-ascii letter since since it never appears
88*a9fa9459Szrj in instructions. */
89*a9fa9459Szrj #define LONG_DOUBLE_MNEM_SUFFIX '\1'
90*a9fa9459Szrj
91*a9fa9459Szrj #define END_OF_INSN '\0'
92*a9fa9459Szrj
93*a9fa9459Szrj /*
94*a9fa9459Szrj 'templates' is for grouping together 'template' structures for opcodes
95*a9fa9459Szrj of the same name. This is only used for storing the insns in the grand
96*a9fa9459Szrj ole hash table of insns.
97*a9fa9459Szrj The templates themselves start at START and range up to (but not including)
98*a9fa9459Szrj END.
99*a9fa9459Szrj */
100*a9fa9459Szrj typedef struct
101*a9fa9459Szrj {
102*a9fa9459Szrj const insn_template *start;
103*a9fa9459Szrj const insn_template *end;
104*a9fa9459Szrj }
105*a9fa9459Szrj templates;
106*a9fa9459Szrj
107*a9fa9459Szrj /* 386 operand encoding bytes: see 386 book for details of this. */
108*a9fa9459Szrj typedef struct
109*a9fa9459Szrj {
110*a9fa9459Szrj unsigned int regmem; /* codes register or memory operand */
111*a9fa9459Szrj unsigned int reg; /* codes register operand (or extended opcode) */
112*a9fa9459Szrj unsigned int mode; /* how to interpret regmem & reg */
113*a9fa9459Szrj }
114*a9fa9459Szrj modrm_byte;
115*a9fa9459Szrj
116*a9fa9459Szrj /* x86-64 extension prefix. */
117*a9fa9459Szrj typedef int rex_byte;
118*a9fa9459Szrj
119*a9fa9459Szrj /* 386 opcode byte to code indirect addressing. */
120*a9fa9459Szrj typedef struct
121*a9fa9459Szrj {
122*a9fa9459Szrj unsigned base;
123*a9fa9459Szrj unsigned index;
124*a9fa9459Szrj unsigned scale;
125*a9fa9459Szrj }
126*a9fa9459Szrj sib_byte;
127*a9fa9459Szrj
128*a9fa9459Szrj /* x86 arch names, types and features */
129*a9fa9459Szrj typedef struct
130*a9fa9459Szrj {
131*a9fa9459Szrj const char *name; /* arch name */
132*a9fa9459Szrj unsigned int len; /* arch string length */
133*a9fa9459Szrj enum processor_type type; /* arch type */
134*a9fa9459Szrj i386_cpu_flags flags; /* cpu feature flags */
135*a9fa9459Szrj unsigned int skip; /* show_arch should skip this. */
136*a9fa9459Szrj }
137*a9fa9459Szrj arch_entry;
138*a9fa9459Szrj
139*a9fa9459Szrj /* Used to turn off indicated flags. */
140*a9fa9459Szrj typedef struct
141*a9fa9459Szrj {
142*a9fa9459Szrj const char *name; /* arch name */
143*a9fa9459Szrj unsigned int len; /* arch string length */
144*a9fa9459Szrj i386_cpu_flags flags; /* cpu feature flags */
145*a9fa9459Szrj }
146*a9fa9459Szrj noarch_entry;
147*a9fa9459Szrj
148*a9fa9459Szrj static void update_code_flag (int, int);
149*a9fa9459Szrj static void set_code_flag (int);
150*a9fa9459Szrj static void set_16bit_gcc_code_flag (int);
151*a9fa9459Szrj static void set_intel_syntax (int);
152*a9fa9459Szrj static void set_intel_mnemonic (int);
153*a9fa9459Szrj static void set_allow_index_reg (int);
154*a9fa9459Szrj static void set_check (int);
155*a9fa9459Szrj static void set_cpu_arch (int);
156*a9fa9459Szrj #ifdef TE_PE
157*a9fa9459Szrj static void pe_directive_secrel (int);
158*a9fa9459Szrj #endif
159*a9fa9459Szrj static void signed_cons (int);
160*a9fa9459Szrj static char *output_invalid (int c);
161*a9fa9459Szrj static int i386_finalize_immediate (segT, expressionS *, i386_operand_type,
162*a9fa9459Szrj const char *);
163*a9fa9459Szrj static int i386_finalize_displacement (segT, expressionS *, i386_operand_type,
164*a9fa9459Szrj const char *);
165*a9fa9459Szrj static int i386_att_operand (char *);
166*a9fa9459Szrj static int i386_intel_operand (char *, int);
167*a9fa9459Szrj static int i386_intel_simplify (expressionS *);
168*a9fa9459Szrj static int i386_intel_parse_name (const char *, expressionS *);
169*a9fa9459Szrj static const reg_entry *parse_register (char *, char **);
170*a9fa9459Szrj static char *parse_insn (char *, char *);
171*a9fa9459Szrj static char *parse_operands (char *, const char *);
172*a9fa9459Szrj static void swap_operands (void);
173*a9fa9459Szrj static void swap_2_operands (int, int);
174*a9fa9459Szrj static void optimize_imm (void);
175*a9fa9459Szrj static void optimize_disp (void);
176*a9fa9459Szrj static const insn_template *match_template (char);
177*a9fa9459Szrj static int check_string (void);
178*a9fa9459Szrj static int process_suffix (void);
179*a9fa9459Szrj static int check_byte_reg (void);
180*a9fa9459Szrj static int check_long_reg (void);
181*a9fa9459Szrj static int check_qword_reg (void);
182*a9fa9459Szrj static int check_word_reg (void);
183*a9fa9459Szrj static int finalize_imm (void);
184*a9fa9459Szrj static int process_operands (void);
185*a9fa9459Szrj static const seg_entry *build_modrm_byte (void);
186*a9fa9459Szrj static void output_insn (void);
187*a9fa9459Szrj static void output_imm (fragS *, offsetT);
188*a9fa9459Szrj static void output_disp (fragS *, offsetT);
189*a9fa9459Szrj #ifndef I386COFF
190*a9fa9459Szrj static void s_bss (int);
191*a9fa9459Szrj #endif
192*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
193*a9fa9459Szrj static void handle_large_common (int small ATTRIBUTE_UNUSED);
194*a9fa9459Szrj #endif
195*a9fa9459Szrj
196*a9fa9459Szrj static const char *default_arch = DEFAULT_ARCH;
197*a9fa9459Szrj
198*a9fa9459Szrj /* This struct describes rounding control and SAE in the instruction. */
199*a9fa9459Szrj struct RC_Operation
200*a9fa9459Szrj {
201*a9fa9459Szrj enum rc_type
202*a9fa9459Szrj {
203*a9fa9459Szrj rne = 0,
204*a9fa9459Szrj rd,
205*a9fa9459Szrj ru,
206*a9fa9459Szrj rz,
207*a9fa9459Szrj saeonly
208*a9fa9459Szrj } type;
209*a9fa9459Szrj int operand;
210*a9fa9459Szrj };
211*a9fa9459Szrj
212*a9fa9459Szrj static struct RC_Operation rc_op;
213*a9fa9459Szrj
214*a9fa9459Szrj /* The struct describes masking, applied to OPERAND in the instruction.
215*a9fa9459Szrj MASK is a pointer to the corresponding mask register. ZEROING tells
216*a9fa9459Szrj whether merging or zeroing mask is used. */
217*a9fa9459Szrj struct Mask_Operation
218*a9fa9459Szrj {
219*a9fa9459Szrj const reg_entry *mask;
220*a9fa9459Szrj unsigned int zeroing;
221*a9fa9459Szrj /* The operand where this operation is associated. */
222*a9fa9459Szrj int operand;
223*a9fa9459Szrj };
224*a9fa9459Szrj
225*a9fa9459Szrj static struct Mask_Operation mask_op;
226*a9fa9459Szrj
227*a9fa9459Szrj /* The struct describes broadcasting, applied to OPERAND. FACTOR is
228*a9fa9459Szrj broadcast factor. */
229*a9fa9459Szrj struct Broadcast_Operation
230*a9fa9459Szrj {
231*a9fa9459Szrj /* Type of broadcast: no broadcast, {1to8}, or {1to16}. */
232*a9fa9459Szrj int type;
233*a9fa9459Szrj
234*a9fa9459Szrj /* Index of broadcasted operand. */
235*a9fa9459Szrj int operand;
236*a9fa9459Szrj };
237*a9fa9459Szrj
238*a9fa9459Szrj static struct Broadcast_Operation broadcast_op;
239*a9fa9459Szrj
240*a9fa9459Szrj /* VEX prefix. */
241*a9fa9459Szrj typedef struct
242*a9fa9459Szrj {
243*a9fa9459Szrj /* VEX prefix is either 2 byte or 3 byte. EVEX is 4 byte. */
244*a9fa9459Szrj unsigned char bytes[4];
245*a9fa9459Szrj unsigned int length;
246*a9fa9459Szrj /* Destination or source register specifier. */
247*a9fa9459Szrj const reg_entry *register_specifier;
248*a9fa9459Szrj } vex_prefix;
249*a9fa9459Szrj
250*a9fa9459Szrj /* 'md_assemble ()' gathers together information and puts it into a
251*a9fa9459Szrj i386_insn. */
252*a9fa9459Szrj
253*a9fa9459Szrj union i386_op
254*a9fa9459Szrj {
255*a9fa9459Szrj expressionS *disps;
256*a9fa9459Szrj expressionS *imms;
257*a9fa9459Szrj const reg_entry *regs;
258*a9fa9459Szrj };
259*a9fa9459Szrj
260*a9fa9459Szrj enum i386_error
261*a9fa9459Szrj {
262*a9fa9459Szrj operand_size_mismatch,
263*a9fa9459Szrj operand_type_mismatch,
264*a9fa9459Szrj register_type_mismatch,
265*a9fa9459Szrj number_of_operands_mismatch,
266*a9fa9459Szrj invalid_instruction_suffix,
267*a9fa9459Szrj bad_imm4,
268*a9fa9459Szrj old_gcc_only,
269*a9fa9459Szrj unsupported_with_intel_mnemonic,
270*a9fa9459Szrj unsupported_syntax,
271*a9fa9459Szrj unsupported,
272*a9fa9459Szrj invalid_vsib_address,
273*a9fa9459Szrj invalid_vector_register_set,
274*a9fa9459Szrj unsupported_vector_index_register,
275*a9fa9459Szrj unsupported_broadcast,
276*a9fa9459Szrj broadcast_not_on_src_operand,
277*a9fa9459Szrj broadcast_needed,
278*a9fa9459Szrj unsupported_masking,
279*a9fa9459Szrj mask_not_on_destination,
280*a9fa9459Szrj no_default_mask,
281*a9fa9459Szrj unsupported_rc_sae,
282*a9fa9459Szrj rc_sae_operand_not_last_imm,
283*a9fa9459Szrj invalid_register_operand,
284*a9fa9459Szrj try_vector_disp8
285*a9fa9459Szrj };
286*a9fa9459Szrj
287*a9fa9459Szrj struct _i386_insn
288*a9fa9459Szrj {
289*a9fa9459Szrj /* TM holds the template for the insn were currently assembling. */
290*a9fa9459Szrj insn_template tm;
291*a9fa9459Szrj
292*a9fa9459Szrj /* SUFFIX holds the instruction size suffix for byte, word, dword
293*a9fa9459Szrj or qword, if given. */
294*a9fa9459Szrj char suffix;
295*a9fa9459Szrj
296*a9fa9459Szrj /* OPERANDS gives the number of given operands. */
297*a9fa9459Szrj unsigned int operands;
298*a9fa9459Szrj
299*a9fa9459Szrj /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number
300*a9fa9459Szrj of given register, displacement, memory operands and immediate
301*a9fa9459Szrj operands. */
302*a9fa9459Szrj unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
303*a9fa9459Szrj
304*a9fa9459Szrj /* TYPES [i] is the type (see above #defines) which tells us how to
305*a9fa9459Szrj use OP[i] for the corresponding operand. */
306*a9fa9459Szrj i386_operand_type types[MAX_OPERANDS];
307*a9fa9459Szrj
308*a9fa9459Szrj /* Displacement expression, immediate expression, or register for each
309*a9fa9459Szrj operand. */
310*a9fa9459Szrj union i386_op op[MAX_OPERANDS];
311*a9fa9459Szrj
312*a9fa9459Szrj /* Flags for operands. */
313*a9fa9459Szrj unsigned int flags[MAX_OPERANDS];
314*a9fa9459Szrj #define Operand_PCrel 1
315*a9fa9459Szrj
316*a9fa9459Szrj /* Relocation type for operand */
317*a9fa9459Szrj enum bfd_reloc_code_real reloc[MAX_OPERANDS];
318*a9fa9459Szrj
319*a9fa9459Szrj /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
320*a9fa9459Szrj the base index byte below. */
321*a9fa9459Szrj const reg_entry *base_reg;
322*a9fa9459Szrj const reg_entry *index_reg;
323*a9fa9459Szrj unsigned int log2_scale_factor;
324*a9fa9459Szrj
325*a9fa9459Szrj /* SEG gives the seg_entries of this insn. They are zero unless
326*a9fa9459Szrj explicit segment overrides are given. */
327*a9fa9459Szrj const seg_entry *seg[2];
328*a9fa9459Szrj
329*a9fa9459Szrj /* Copied first memory operand string, for re-checking. */
330*a9fa9459Szrj char *memop1_string;
331*a9fa9459Szrj
332*a9fa9459Szrj /* PREFIX holds all the given prefix opcodes (usually null).
333*a9fa9459Szrj PREFIXES is the number of prefix opcodes. */
334*a9fa9459Szrj unsigned int prefixes;
335*a9fa9459Szrj unsigned char prefix[MAX_PREFIXES];
336*a9fa9459Szrj
337*a9fa9459Szrj /* RM and SIB are the modrm byte and the sib byte where the
338*a9fa9459Szrj addressing modes of this insn are encoded. */
339*a9fa9459Szrj modrm_byte rm;
340*a9fa9459Szrj rex_byte rex;
341*a9fa9459Szrj rex_byte vrex;
342*a9fa9459Szrj sib_byte sib;
343*a9fa9459Szrj vex_prefix vex;
344*a9fa9459Szrj
345*a9fa9459Szrj /* Masking attributes. */
346*a9fa9459Szrj struct Mask_Operation *mask;
347*a9fa9459Szrj
348*a9fa9459Szrj /* Rounding control and SAE attributes. */
349*a9fa9459Szrj struct RC_Operation *rounding;
350*a9fa9459Szrj
351*a9fa9459Szrj /* Broadcasting attributes. */
352*a9fa9459Szrj struct Broadcast_Operation *broadcast;
353*a9fa9459Szrj
354*a9fa9459Szrj /* Compressed disp8*N attribute. */
355*a9fa9459Szrj unsigned int memshift;
356*a9fa9459Szrj
357*a9fa9459Szrj /* Swap operand in encoding. */
358*a9fa9459Szrj unsigned int swap_operand;
359*a9fa9459Szrj
360*a9fa9459Szrj /* Prefer 8bit or 32bit displacement in encoding. */
361*a9fa9459Szrj enum
362*a9fa9459Szrj {
363*a9fa9459Szrj disp_encoding_default = 0,
364*a9fa9459Szrj disp_encoding_8bit,
365*a9fa9459Szrj disp_encoding_32bit
366*a9fa9459Szrj } disp_encoding;
367*a9fa9459Szrj
368*a9fa9459Szrj /* REP prefix. */
369*a9fa9459Szrj const char *rep_prefix;
370*a9fa9459Szrj
371*a9fa9459Szrj /* HLE prefix. */
372*a9fa9459Szrj const char *hle_prefix;
373*a9fa9459Szrj
374*a9fa9459Szrj /* Have BND prefix. */
375*a9fa9459Szrj const char *bnd_prefix;
376*a9fa9459Szrj
377*a9fa9459Szrj /* Need VREX to support upper 16 registers. */
378*a9fa9459Szrj int need_vrex;
379*a9fa9459Szrj
380*a9fa9459Szrj /* Error message. */
381*a9fa9459Szrj enum i386_error error;
382*a9fa9459Szrj };
383*a9fa9459Szrj
384*a9fa9459Szrj typedef struct _i386_insn i386_insn;
385*a9fa9459Szrj
386*a9fa9459Szrj /* Link RC type with corresponding string, that'll be looked for in
387*a9fa9459Szrj asm. */
388*a9fa9459Szrj struct RC_name
389*a9fa9459Szrj {
390*a9fa9459Szrj enum rc_type type;
391*a9fa9459Szrj const char *name;
392*a9fa9459Szrj unsigned int len;
393*a9fa9459Szrj };
394*a9fa9459Szrj
395*a9fa9459Szrj static const struct RC_name RC_NamesTable[] =
396*a9fa9459Szrj {
397*a9fa9459Szrj { rne, STRING_COMMA_LEN ("rn-sae") },
398*a9fa9459Szrj { rd, STRING_COMMA_LEN ("rd-sae") },
399*a9fa9459Szrj { ru, STRING_COMMA_LEN ("ru-sae") },
400*a9fa9459Szrj { rz, STRING_COMMA_LEN ("rz-sae") },
401*a9fa9459Szrj { saeonly, STRING_COMMA_LEN ("sae") },
402*a9fa9459Szrj };
403*a9fa9459Szrj
404*a9fa9459Szrj /* List of chars besides those in app.c:symbol_chars that can start an
405*a9fa9459Szrj operand. Used to prevent the scrubber eating vital white-space. */
406*a9fa9459Szrj const char extra_symbol_chars[] = "*%-([{"
407*a9fa9459Szrj #ifdef LEX_AT
408*a9fa9459Szrj "@"
409*a9fa9459Szrj #endif
410*a9fa9459Szrj #ifdef LEX_QM
411*a9fa9459Szrj "?"
412*a9fa9459Szrj #endif
413*a9fa9459Szrj ;
414*a9fa9459Szrj
415*a9fa9459Szrj #if (defined (TE_I386AIX) \
416*a9fa9459Szrj || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
417*a9fa9459Szrj && !defined (TE_GNU) \
418*a9fa9459Szrj && !defined (TE_LINUX) \
419*a9fa9459Szrj && !defined (TE_NACL) \
420*a9fa9459Szrj && !defined (TE_NETWARE) \
421*a9fa9459Szrj && !defined (TE_FreeBSD) \
422*a9fa9459Szrj && !defined (TE_DragonFly) \
423*a9fa9459Szrj && !defined (TE_NetBSD)))
424*a9fa9459Szrj /* This array holds the chars that always start a comment. If the
425*a9fa9459Szrj pre-processor is disabled, these aren't very useful. The option
426*a9fa9459Szrj --divide will remove '/' from this list. */
427*a9fa9459Szrj const char *i386_comment_chars = "#/";
428*a9fa9459Szrj #define SVR4_COMMENT_CHARS 1
429*a9fa9459Szrj #define PREFIX_SEPARATOR '\\'
430*a9fa9459Szrj
431*a9fa9459Szrj #else
432*a9fa9459Szrj const char *i386_comment_chars = "#";
433*a9fa9459Szrj #define PREFIX_SEPARATOR '/'
434*a9fa9459Szrj #endif
435*a9fa9459Szrj
436*a9fa9459Szrj /* This array holds the chars that only start a comment at the beginning of
437*a9fa9459Szrj a line. If the line seems to have the form '# 123 filename'
438*a9fa9459Szrj .line and .file directives will appear in the pre-processed output.
439*a9fa9459Szrj Note that input_file.c hand checks for '#' at the beginning of the
440*a9fa9459Szrj first line of the input file. This is because the compiler outputs
441*a9fa9459Szrj #NO_APP at the beginning of its output.
442*a9fa9459Szrj Also note that comments started like this one will always work if
443*a9fa9459Szrj '/' isn't otherwise defined. */
444*a9fa9459Szrj const char line_comment_chars[] = "#/";
445*a9fa9459Szrj
446*a9fa9459Szrj const char line_separator_chars[] = ";";
447*a9fa9459Szrj
448*a9fa9459Szrj /* Chars that can be used to separate mant from exp in floating point
449*a9fa9459Szrj nums. */
450*a9fa9459Szrj const char EXP_CHARS[] = "eE";
451*a9fa9459Szrj
452*a9fa9459Szrj /* Chars that mean this number is a floating point constant
453*a9fa9459Szrj As in 0f12.456
454*a9fa9459Szrj or 0d1.2345e12. */
455*a9fa9459Szrj const char FLT_CHARS[] = "fFdDxX";
456*a9fa9459Szrj
457*a9fa9459Szrj /* Tables for lexical analysis. */
458*a9fa9459Szrj static char mnemonic_chars[256];
459*a9fa9459Szrj static char register_chars[256];
460*a9fa9459Szrj static char operand_chars[256];
461*a9fa9459Szrj static char identifier_chars[256];
462*a9fa9459Szrj static char digit_chars[256];
463*a9fa9459Szrj
464*a9fa9459Szrj /* Lexical macros. */
465*a9fa9459Szrj #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
466*a9fa9459Szrj #define is_operand_char(x) (operand_chars[(unsigned char) x])
467*a9fa9459Szrj #define is_register_char(x) (register_chars[(unsigned char) x])
468*a9fa9459Szrj #define is_space_char(x) ((x) == ' ')
469*a9fa9459Szrj #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
470*a9fa9459Szrj #define is_digit_char(x) (digit_chars[(unsigned char) x])
471*a9fa9459Szrj
472*a9fa9459Szrj /* All non-digit non-letter characters that may occur in an operand. */
473*a9fa9459Szrj static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]";
474*a9fa9459Szrj
475*a9fa9459Szrj /* md_assemble() always leaves the strings it's passed unaltered. To
476*a9fa9459Szrj effect this we maintain a stack of saved characters that we've smashed
477*a9fa9459Szrj with '\0's (indicating end of strings for various sub-fields of the
478*a9fa9459Szrj assembler instruction). */
479*a9fa9459Szrj static char save_stack[32];
480*a9fa9459Szrj static char *save_stack_p;
481*a9fa9459Szrj #define END_STRING_AND_SAVE(s) \
482*a9fa9459Szrj do { *save_stack_p++ = *(s); *(s) = '\0'; } while (0)
483*a9fa9459Szrj #define RESTORE_END_STRING(s) \
484*a9fa9459Szrj do { *(s) = *--save_stack_p; } while (0)
485*a9fa9459Szrj
486*a9fa9459Szrj /* The instruction we're assembling. */
487*a9fa9459Szrj static i386_insn i;
488*a9fa9459Szrj
489*a9fa9459Szrj /* Possible templates for current insn. */
490*a9fa9459Szrj static const templates *current_templates;
491*a9fa9459Szrj
492*a9fa9459Szrj /* Per instruction expressionS buffers: max displacements & immediates. */
493*a9fa9459Szrj static expressionS disp_expressions[MAX_MEMORY_OPERANDS];
494*a9fa9459Szrj static expressionS im_expressions[MAX_IMMEDIATE_OPERANDS];
495*a9fa9459Szrj
496*a9fa9459Szrj /* Current operand we are working on. */
497*a9fa9459Szrj static int this_operand = -1;
498*a9fa9459Szrj
499*a9fa9459Szrj /* We support four different modes. FLAG_CODE variable is used to distinguish
500*a9fa9459Szrj these. */
501*a9fa9459Szrj
502*a9fa9459Szrj enum flag_code {
503*a9fa9459Szrj CODE_32BIT,
504*a9fa9459Szrj CODE_16BIT,
505*a9fa9459Szrj CODE_64BIT };
506*a9fa9459Szrj
507*a9fa9459Szrj static enum flag_code flag_code;
508*a9fa9459Szrj static unsigned int object_64bit;
509*a9fa9459Szrj static unsigned int disallow_64bit_reloc;
510*a9fa9459Szrj static int use_rela_relocations = 0;
511*a9fa9459Szrj
512*a9fa9459Szrj #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
513*a9fa9459Szrj || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
514*a9fa9459Szrj || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
515*a9fa9459Szrj
516*a9fa9459Szrj /* The ELF ABI to use. */
517*a9fa9459Szrj enum x86_elf_abi
518*a9fa9459Szrj {
519*a9fa9459Szrj I386_ABI,
520*a9fa9459Szrj X86_64_ABI,
521*a9fa9459Szrj X86_64_X32_ABI
522*a9fa9459Szrj };
523*a9fa9459Szrj
524*a9fa9459Szrj static enum x86_elf_abi x86_elf_abi = I386_ABI;
525*a9fa9459Szrj #endif
526*a9fa9459Szrj
527*a9fa9459Szrj #if defined (TE_PE) || defined (TE_PEP)
528*a9fa9459Szrj /* Use big object file format. */
529*a9fa9459Szrj static int use_big_obj = 0;
530*a9fa9459Szrj #endif
531*a9fa9459Szrj
532*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
533*a9fa9459Szrj /* 1 if generating code for a shared library. */
534*a9fa9459Szrj static int shared = 0;
535*a9fa9459Szrj #endif
536*a9fa9459Szrj
537*a9fa9459Szrj /* 1 for intel syntax,
538*a9fa9459Szrj 0 if att syntax. */
539*a9fa9459Szrj static int intel_syntax = 0;
540*a9fa9459Szrj
541*a9fa9459Szrj /* 1 for Intel64 ISA,
542*a9fa9459Szrj 0 if AMD64 ISA. */
543*a9fa9459Szrj static int intel64;
544*a9fa9459Szrj
545*a9fa9459Szrj /* 1 for intel mnemonic,
546*a9fa9459Szrj 0 if att mnemonic. */
547*a9fa9459Szrj static int intel_mnemonic = !SYSV386_COMPAT;
548*a9fa9459Szrj
549*a9fa9459Szrj /* 1 if support old (<= 2.8.1) versions of gcc. */
550*a9fa9459Szrj static int old_gcc = OLDGCC_COMPAT;
551*a9fa9459Szrj
552*a9fa9459Szrj /* 1 if pseudo registers are permitted. */
553*a9fa9459Szrj static int allow_pseudo_reg = 0;
554*a9fa9459Szrj
555*a9fa9459Szrj /* 1 if register prefix % not required. */
556*a9fa9459Szrj static int allow_naked_reg = 0;
557*a9fa9459Szrj
558*a9fa9459Szrj /* 1 if the assembler should add BND prefix for all control-tranferring
559*a9fa9459Szrj instructions supporting it, even if this prefix wasn't specified
560*a9fa9459Szrj explicitly. */
561*a9fa9459Szrj static int add_bnd_prefix = 0;
562*a9fa9459Szrj
563*a9fa9459Szrj /* 1 if pseudo index register, eiz/riz, is allowed . */
564*a9fa9459Szrj static int allow_index_reg = 0;
565*a9fa9459Szrj
566*a9fa9459Szrj /* 1 if the assembler should ignore LOCK prefix, even if it was
567*a9fa9459Szrj specified explicitly. */
568*a9fa9459Szrj static int omit_lock_prefix = 0;
569*a9fa9459Szrj
570*a9fa9459Szrj /* 1 if the assembler should encode lfence, mfence, and sfence as
571*a9fa9459Szrj "lock addl $0, (%{re}sp)". */
572*a9fa9459Szrj static int avoid_fence = 0;
573*a9fa9459Szrj
574*a9fa9459Szrj /* 1 if the assembler should generate relax relocations. */
575*a9fa9459Szrj
576*a9fa9459Szrj static int generate_relax_relocations
577*a9fa9459Szrj = DEFAULT_GENERATE_X86_RELAX_RELOCATIONS;
578*a9fa9459Szrj
579*a9fa9459Szrj static enum check_kind
580*a9fa9459Szrj {
581*a9fa9459Szrj check_none = 0,
582*a9fa9459Szrj check_warning,
583*a9fa9459Szrj check_error
584*a9fa9459Szrj }
585*a9fa9459Szrj sse_check, operand_check = check_warning;
586*a9fa9459Szrj
587*a9fa9459Szrj /* Register prefix used for error message. */
588*a9fa9459Szrj static const char *register_prefix = "%";
589*a9fa9459Szrj
590*a9fa9459Szrj /* Used in 16 bit gcc mode to add an l suffix to call, ret, enter,
591*a9fa9459Szrj leave, push, and pop instructions so that gcc has the same stack
592*a9fa9459Szrj frame as in 32 bit mode. */
593*a9fa9459Szrj static char stackop_size = '\0';
594*a9fa9459Szrj
595*a9fa9459Szrj /* Non-zero to optimize code alignment. */
596*a9fa9459Szrj int optimize_align_code = 1;
597*a9fa9459Szrj
598*a9fa9459Szrj /* Non-zero to quieten some warnings. */
599*a9fa9459Szrj static int quiet_warnings = 0;
600*a9fa9459Szrj
601*a9fa9459Szrj /* CPU name. */
602*a9fa9459Szrj static const char *cpu_arch_name = NULL;
603*a9fa9459Szrj static char *cpu_sub_arch_name = NULL;
604*a9fa9459Szrj
605*a9fa9459Szrj /* CPU feature flags. */
606*a9fa9459Szrj static i386_cpu_flags cpu_arch_flags = CPU_UNKNOWN_FLAGS;
607*a9fa9459Szrj
608*a9fa9459Szrj /* If we have selected a cpu we are generating instructions for. */
609*a9fa9459Szrj static int cpu_arch_tune_set = 0;
610*a9fa9459Szrj
611*a9fa9459Szrj /* Cpu we are generating instructions for. */
612*a9fa9459Szrj enum processor_type cpu_arch_tune = PROCESSOR_UNKNOWN;
613*a9fa9459Szrj
614*a9fa9459Szrj /* CPU feature flags of cpu we are generating instructions for. */
615*a9fa9459Szrj static i386_cpu_flags cpu_arch_tune_flags;
616*a9fa9459Szrj
617*a9fa9459Szrj /* CPU instruction set architecture used. */
618*a9fa9459Szrj enum processor_type cpu_arch_isa = PROCESSOR_UNKNOWN;
619*a9fa9459Szrj
620*a9fa9459Szrj /* CPU feature flags of instruction set architecture used. */
621*a9fa9459Szrj i386_cpu_flags cpu_arch_isa_flags;
622*a9fa9459Szrj
623*a9fa9459Szrj /* If set, conditional jumps are not automatically promoted to handle
624*a9fa9459Szrj larger than a byte offset. */
625*a9fa9459Szrj static unsigned int no_cond_jump_promotion = 0;
626*a9fa9459Szrj
627*a9fa9459Szrj /* Encode SSE instructions with VEX prefix. */
628*a9fa9459Szrj static unsigned int sse2avx;
629*a9fa9459Szrj
630*a9fa9459Szrj /* Encode scalar AVX instructions with specific vector length. */
631*a9fa9459Szrj static enum
632*a9fa9459Szrj {
633*a9fa9459Szrj vex128 = 0,
634*a9fa9459Szrj vex256
635*a9fa9459Szrj } avxscalar;
636*a9fa9459Szrj
637*a9fa9459Szrj /* Encode scalar EVEX LIG instructions with specific vector length. */
638*a9fa9459Szrj static enum
639*a9fa9459Szrj {
640*a9fa9459Szrj evexl128 = 0,
641*a9fa9459Szrj evexl256,
642*a9fa9459Szrj evexl512
643*a9fa9459Szrj } evexlig;
644*a9fa9459Szrj
645*a9fa9459Szrj /* Encode EVEX WIG instructions with specific evex.w. */
646*a9fa9459Szrj static enum
647*a9fa9459Szrj {
648*a9fa9459Szrj evexw0 = 0,
649*a9fa9459Szrj evexw1
650*a9fa9459Szrj } evexwig;
651*a9fa9459Szrj
652*a9fa9459Szrj /* Value to encode in EVEX RC bits, for SAE-only instructions. */
653*a9fa9459Szrj static enum rc_type evexrcig = rne;
654*a9fa9459Szrj
655*a9fa9459Szrj /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
656*a9fa9459Szrj static symbolS *GOT_symbol;
657*a9fa9459Szrj
658*a9fa9459Szrj /* The dwarf2 return column, adjusted for 32 or 64 bit. */
659*a9fa9459Szrj unsigned int x86_dwarf2_return_column;
660*a9fa9459Szrj
661*a9fa9459Szrj /* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
662*a9fa9459Szrj int x86_cie_data_alignment;
663*a9fa9459Szrj
664*a9fa9459Szrj /* Interface to relax_segment.
665*a9fa9459Szrj There are 3 major relax states for 386 jump insns because the
666*a9fa9459Szrj different types of jumps add different sizes to frags when we're
667*a9fa9459Szrj figuring out what sort of jump to choose to reach a given label. */
668*a9fa9459Szrj
669*a9fa9459Szrj /* Types. */
670*a9fa9459Szrj #define UNCOND_JUMP 0
671*a9fa9459Szrj #define COND_JUMP 1
672*a9fa9459Szrj #define COND_JUMP86 2
673*a9fa9459Szrj
674*a9fa9459Szrj /* Sizes. */
675*a9fa9459Szrj #define CODE16 1
676*a9fa9459Szrj #define SMALL 0
677*a9fa9459Szrj #define SMALL16 (SMALL | CODE16)
678*a9fa9459Szrj #define BIG 2
679*a9fa9459Szrj #define BIG16 (BIG | CODE16)
680*a9fa9459Szrj
681*a9fa9459Szrj #ifndef INLINE
682*a9fa9459Szrj #ifdef __GNUC__
683*a9fa9459Szrj #define INLINE __inline__
684*a9fa9459Szrj #else
685*a9fa9459Szrj #define INLINE
686*a9fa9459Szrj #endif
687*a9fa9459Szrj #endif
688*a9fa9459Szrj
689*a9fa9459Szrj #define ENCODE_RELAX_STATE(type, size) \
690*a9fa9459Szrj ((relax_substateT) (((type) << 2) | (size)))
691*a9fa9459Szrj #define TYPE_FROM_RELAX_STATE(s) \
692*a9fa9459Szrj ((s) >> 2)
693*a9fa9459Szrj #define DISP_SIZE_FROM_RELAX_STATE(s) \
694*a9fa9459Szrj ((((s) & 3) == BIG ? 4 : (((s) & 3) == BIG16 ? 2 : 1)))
695*a9fa9459Szrj
696*a9fa9459Szrj /* This table is used by relax_frag to promote short jumps to long
697*a9fa9459Szrj ones where necessary. SMALL (short) jumps may be promoted to BIG
698*a9fa9459Szrj (32 bit long) ones, and SMALL16 jumps to BIG16 (16 bit long). We
699*a9fa9459Szrj don't allow a short jump in a 32 bit code segment to be promoted to
700*a9fa9459Szrj a 16 bit offset jump because it's slower (requires data size
701*a9fa9459Szrj prefix), and doesn't work, unless the destination is in the bottom
702*a9fa9459Szrj 64k of the code segment (The top 16 bits of eip are zeroed). */
703*a9fa9459Szrj
704*a9fa9459Szrj const relax_typeS md_relax_table[] =
705*a9fa9459Szrj {
706*a9fa9459Szrj /* The fields are:
707*a9fa9459Szrj 1) most positive reach of this state,
708*a9fa9459Szrj 2) most negative reach of this state,
709*a9fa9459Szrj 3) how many bytes this mode will have in the variable part of the frag
710*a9fa9459Szrj 4) which index into the table to try if we can't fit into this one. */
711*a9fa9459Szrj
712*a9fa9459Szrj /* UNCOND_JUMP states. */
713*a9fa9459Szrj {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
714*a9fa9459Szrj {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
715*a9fa9459Szrj /* dword jmp adds 4 bytes to frag:
716*a9fa9459Szrj 0 extra opcode bytes, 4 displacement bytes. */
717*a9fa9459Szrj {0, 0, 4, 0},
718*a9fa9459Szrj /* word jmp adds 2 byte2 to frag:
719*a9fa9459Szrj 0 extra opcode bytes, 2 displacement bytes. */
720*a9fa9459Szrj {0, 0, 2, 0},
721*a9fa9459Szrj
722*a9fa9459Szrj /* COND_JUMP states. */
723*a9fa9459Szrj {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
724*a9fa9459Szrj {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
725*a9fa9459Szrj /* dword conditionals adds 5 bytes to frag:
726*a9fa9459Szrj 1 extra opcode byte, 4 displacement bytes. */
727*a9fa9459Szrj {0, 0, 5, 0},
728*a9fa9459Szrj /* word conditionals add 3 bytes to frag:
729*a9fa9459Szrj 1 extra opcode byte, 2 displacement bytes. */
730*a9fa9459Szrj {0, 0, 3, 0},
731*a9fa9459Szrj
732*a9fa9459Szrj /* COND_JUMP86 states. */
733*a9fa9459Szrj {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
734*a9fa9459Szrj {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
735*a9fa9459Szrj /* dword conditionals adds 5 bytes to frag:
736*a9fa9459Szrj 1 extra opcode byte, 4 displacement bytes. */
737*a9fa9459Szrj {0, 0, 5, 0},
738*a9fa9459Szrj /* word conditionals add 4 bytes to frag:
739*a9fa9459Szrj 1 displacement byte and a 3 byte long branch insn. */
740*a9fa9459Szrj {0, 0, 4, 0}
741*a9fa9459Szrj };
742*a9fa9459Szrj
743*a9fa9459Szrj static const arch_entry cpu_arch[] =
744*a9fa9459Szrj {
745*a9fa9459Szrj /* Do not replace the first two entries - i386_target_format()
746*a9fa9459Szrj relies on them being there in this order. */
747*a9fa9459Szrj { STRING_COMMA_LEN ("generic32"), PROCESSOR_GENERIC32,
748*a9fa9459Szrj CPU_GENERIC32_FLAGS, 0 },
749*a9fa9459Szrj { STRING_COMMA_LEN ("generic64"), PROCESSOR_GENERIC64,
750*a9fa9459Szrj CPU_GENERIC64_FLAGS, 0 },
751*a9fa9459Szrj { STRING_COMMA_LEN ("i8086"), PROCESSOR_UNKNOWN,
752*a9fa9459Szrj CPU_NONE_FLAGS, 0 },
753*a9fa9459Szrj { STRING_COMMA_LEN ("i186"), PROCESSOR_UNKNOWN,
754*a9fa9459Szrj CPU_I186_FLAGS, 0 },
755*a9fa9459Szrj { STRING_COMMA_LEN ("i286"), PROCESSOR_UNKNOWN,
756*a9fa9459Szrj CPU_I286_FLAGS, 0 },
757*a9fa9459Szrj { STRING_COMMA_LEN ("i386"), PROCESSOR_I386,
758*a9fa9459Szrj CPU_I386_FLAGS, 0 },
759*a9fa9459Szrj { STRING_COMMA_LEN ("i486"), PROCESSOR_I486,
760*a9fa9459Szrj CPU_I486_FLAGS, 0 },
761*a9fa9459Szrj { STRING_COMMA_LEN ("i586"), PROCESSOR_PENTIUM,
762*a9fa9459Szrj CPU_I586_FLAGS, 0 },
763*a9fa9459Szrj { STRING_COMMA_LEN ("i686"), PROCESSOR_PENTIUMPRO,
764*a9fa9459Szrj CPU_I686_FLAGS, 0 },
765*a9fa9459Szrj { STRING_COMMA_LEN ("pentium"), PROCESSOR_PENTIUM,
766*a9fa9459Szrj CPU_I586_FLAGS, 0 },
767*a9fa9459Szrj { STRING_COMMA_LEN ("pentiumpro"), PROCESSOR_PENTIUMPRO,
768*a9fa9459Szrj CPU_PENTIUMPRO_FLAGS, 0 },
769*a9fa9459Szrj { STRING_COMMA_LEN ("pentiumii"), PROCESSOR_PENTIUMPRO,
770*a9fa9459Szrj CPU_P2_FLAGS, 0 },
771*a9fa9459Szrj { STRING_COMMA_LEN ("pentiumiii"),PROCESSOR_PENTIUMPRO,
772*a9fa9459Szrj CPU_P3_FLAGS, 0 },
773*a9fa9459Szrj { STRING_COMMA_LEN ("pentium4"), PROCESSOR_PENTIUM4,
774*a9fa9459Szrj CPU_P4_FLAGS, 0 },
775*a9fa9459Szrj { STRING_COMMA_LEN ("prescott"), PROCESSOR_NOCONA,
776*a9fa9459Szrj CPU_CORE_FLAGS, 0 },
777*a9fa9459Szrj { STRING_COMMA_LEN ("nocona"), PROCESSOR_NOCONA,
778*a9fa9459Szrj CPU_NOCONA_FLAGS, 0 },
779*a9fa9459Szrj { STRING_COMMA_LEN ("yonah"), PROCESSOR_CORE,
780*a9fa9459Szrj CPU_CORE_FLAGS, 1 },
781*a9fa9459Szrj { STRING_COMMA_LEN ("core"), PROCESSOR_CORE,
782*a9fa9459Szrj CPU_CORE_FLAGS, 0 },
783*a9fa9459Szrj { STRING_COMMA_LEN ("merom"), PROCESSOR_CORE2,
784*a9fa9459Szrj CPU_CORE2_FLAGS, 1 },
785*a9fa9459Szrj { STRING_COMMA_LEN ("core2"), PROCESSOR_CORE2,
786*a9fa9459Szrj CPU_CORE2_FLAGS, 0 },
787*a9fa9459Szrj { STRING_COMMA_LEN ("corei7"), PROCESSOR_COREI7,
788*a9fa9459Szrj CPU_COREI7_FLAGS, 0 },
789*a9fa9459Szrj { STRING_COMMA_LEN ("l1om"), PROCESSOR_L1OM,
790*a9fa9459Szrj CPU_L1OM_FLAGS, 0 },
791*a9fa9459Szrj { STRING_COMMA_LEN ("k1om"), PROCESSOR_K1OM,
792*a9fa9459Szrj CPU_K1OM_FLAGS, 0 },
793*a9fa9459Szrj { STRING_COMMA_LEN ("iamcu"), PROCESSOR_IAMCU,
794*a9fa9459Szrj CPU_IAMCU_FLAGS, 0 },
795*a9fa9459Szrj { STRING_COMMA_LEN ("k6"), PROCESSOR_K6,
796*a9fa9459Szrj CPU_K6_FLAGS, 0 },
797*a9fa9459Szrj { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6,
798*a9fa9459Szrj CPU_K6_2_FLAGS, 0 },
799*a9fa9459Szrj { STRING_COMMA_LEN ("athlon"), PROCESSOR_ATHLON,
800*a9fa9459Szrj CPU_ATHLON_FLAGS, 0 },
801*a9fa9459Szrj { STRING_COMMA_LEN ("sledgehammer"), PROCESSOR_K8,
802*a9fa9459Szrj CPU_K8_FLAGS, 1 },
803*a9fa9459Szrj { STRING_COMMA_LEN ("opteron"), PROCESSOR_K8,
804*a9fa9459Szrj CPU_K8_FLAGS, 0 },
805*a9fa9459Szrj { STRING_COMMA_LEN ("k8"), PROCESSOR_K8,
806*a9fa9459Szrj CPU_K8_FLAGS, 0 },
807*a9fa9459Szrj { STRING_COMMA_LEN ("amdfam10"), PROCESSOR_AMDFAM10,
808*a9fa9459Szrj CPU_AMDFAM10_FLAGS, 0 },
809*a9fa9459Szrj { STRING_COMMA_LEN ("bdver1"), PROCESSOR_BD,
810*a9fa9459Szrj CPU_BDVER1_FLAGS, 0 },
811*a9fa9459Szrj { STRING_COMMA_LEN ("bdver2"), PROCESSOR_BD,
812*a9fa9459Szrj CPU_BDVER2_FLAGS, 0 },
813*a9fa9459Szrj { STRING_COMMA_LEN ("bdver3"), PROCESSOR_BD,
814*a9fa9459Szrj CPU_BDVER3_FLAGS, 0 },
815*a9fa9459Szrj { STRING_COMMA_LEN ("bdver4"), PROCESSOR_BD,
816*a9fa9459Szrj CPU_BDVER4_FLAGS, 0 },
817*a9fa9459Szrj { STRING_COMMA_LEN ("znver1"), PROCESSOR_ZNVER,
818*a9fa9459Szrj CPU_ZNVER1_FLAGS, 0 },
819*a9fa9459Szrj { STRING_COMMA_LEN ("btver1"), PROCESSOR_BT,
820*a9fa9459Szrj CPU_BTVER1_FLAGS, 0 },
821*a9fa9459Szrj { STRING_COMMA_LEN ("btver2"), PROCESSOR_BT,
822*a9fa9459Szrj CPU_BTVER2_FLAGS, 0 },
823*a9fa9459Szrj { STRING_COMMA_LEN (".8087"), PROCESSOR_UNKNOWN,
824*a9fa9459Szrj CPU_8087_FLAGS, 0 },
825*a9fa9459Szrj { STRING_COMMA_LEN (".287"), PROCESSOR_UNKNOWN,
826*a9fa9459Szrj CPU_287_FLAGS, 0 },
827*a9fa9459Szrj { STRING_COMMA_LEN (".387"), PROCESSOR_UNKNOWN,
828*a9fa9459Szrj CPU_387_FLAGS, 0 },
829*a9fa9459Szrj { STRING_COMMA_LEN (".687"), PROCESSOR_UNKNOWN,
830*a9fa9459Szrj CPU_687_FLAGS, 0 },
831*a9fa9459Szrj { STRING_COMMA_LEN (".mmx"), PROCESSOR_UNKNOWN,
832*a9fa9459Szrj CPU_MMX_FLAGS, 0 },
833*a9fa9459Szrj { STRING_COMMA_LEN (".sse"), PROCESSOR_UNKNOWN,
834*a9fa9459Szrj CPU_SSE_FLAGS, 0 },
835*a9fa9459Szrj { STRING_COMMA_LEN (".sse2"), PROCESSOR_UNKNOWN,
836*a9fa9459Szrj CPU_SSE2_FLAGS, 0 },
837*a9fa9459Szrj { STRING_COMMA_LEN (".sse3"), PROCESSOR_UNKNOWN,
838*a9fa9459Szrj CPU_SSE3_FLAGS, 0 },
839*a9fa9459Szrj { STRING_COMMA_LEN (".ssse3"), PROCESSOR_UNKNOWN,
840*a9fa9459Szrj CPU_SSSE3_FLAGS, 0 },
841*a9fa9459Szrj { STRING_COMMA_LEN (".sse4.1"), PROCESSOR_UNKNOWN,
842*a9fa9459Szrj CPU_SSE4_1_FLAGS, 0 },
843*a9fa9459Szrj { STRING_COMMA_LEN (".sse4.2"), PROCESSOR_UNKNOWN,
844*a9fa9459Szrj CPU_SSE4_2_FLAGS, 0 },
845*a9fa9459Szrj { STRING_COMMA_LEN (".sse4"), PROCESSOR_UNKNOWN,
846*a9fa9459Szrj CPU_SSE4_2_FLAGS, 0 },
847*a9fa9459Szrj { STRING_COMMA_LEN (".avx"), PROCESSOR_UNKNOWN,
848*a9fa9459Szrj CPU_AVX_FLAGS, 0 },
849*a9fa9459Szrj { STRING_COMMA_LEN (".avx2"), PROCESSOR_UNKNOWN,
850*a9fa9459Szrj CPU_AVX2_FLAGS, 0 },
851*a9fa9459Szrj { STRING_COMMA_LEN (".avx512f"), PROCESSOR_UNKNOWN,
852*a9fa9459Szrj CPU_AVX512F_FLAGS, 0 },
853*a9fa9459Szrj { STRING_COMMA_LEN (".avx512cd"), PROCESSOR_UNKNOWN,
854*a9fa9459Szrj CPU_AVX512CD_FLAGS, 0 },
855*a9fa9459Szrj { STRING_COMMA_LEN (".avx512er"), PROCESSOR_UNKNOWN,
856*a9fa9459Szrj CPU_AVX512ER_FLAGS, 0 },
857*a9fa9459Szrj { STRING_COMMA_LEN (".avx512pf"), PROCESSOR_UNKNOWN,
858*a9fa9459Szrj CPU_AVX512PF_FLAGS, 0 },
859*a9fa9459Szrj { STRING_COMMA_LEN (".avx512dq"), PROCESSOR_UNKNOWN,
860*a9fa9459Szrj CPU_AVX512DQ_FLAGS, 0 },
861*a9fa9459Szrj { STRING_COMMA_LEN (".avx512bw"), PROCESSOR_UNKNOWN,
862*a9fa9459Szrj CPU_AVX512BW_FLAGS, 0 },
863*a9fa9459Szrj { STRING_COMMA_LEN (".avx512vl"), PROCESSOR_UNKNOWN,
864*a9fa9459Szrj CPU_AVX512VL_FLAGS, 0 },
865*a9fa9459Szrj { STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN,
866*a9fa9459Szrj CPU_VMX_FLAGS, 0 },
867*a9fa9459Szrj { STRING_COMMA_LEN (".vmfunc"), PROCESSOR_UNKNOWN,
868*a9fa9459Szrj CPU_VMFUNC_FLAGS, 0 },
869*a9fa9459Szrj { STRING_COMMA_LEN (".smx"), PROCESSOR_UNKNOWN,
870*a9fa9459Szrj CPU_SMX_FLAGS, 0 },
871*a9fa9459Szrj { STRING_COMMA_LEN (".xsave"), PROCESSOR_UNKNOWN,
872*a9fa9459Szrj CPU_XSAVE_FLAGS, 0 },
873*a9fa9459Szrj { STRING_COMMA_LEN (".xsaveopt"), PROCESSOR_UNKNOWN,
874*a9fa9459Szrj CPU_XSAVEOPT_FLAGS, 0 },
875*a9fa9459Szrj { STRING_COMMA_LEN (".xsavec"), PROCESSOR_UNKNOWN,
876*a9fa9459Szrj CPU_XSAVEC_FLAGS, 0 },
877*a9fa9459Szrj { STRING_COMMA_LEN (".xsaves"), PROCESSOR_UNKNOWN,
878*a9fa9459Szrj CPU_XSAVES_FLAGS, 0 },
879*a9fa9459Szrj { STRING_COMMA_LEN (".aes"), PROCESSOR_UNKNOWN,
880*a9fa9459Szrj CPU_AES_FLAGS, 0 },
881*a9fa9459Szrj { STRING_COMMA_LEN (".pclmul"), PROCESSOR_UNKNOWN,
882*a9fa9459Szrj CPU_PCLMUL_FLAGS, 0 },
883*a9fa9459Szrj { STRING_COMMA_LEN (".clmul"), PROCESSOR_UNKNOWN,
884*a9fa9459Szrj CPU_PCLMUL_FLAGS, 1 },
885*a9fa9459Szrj { STRING_COMMA_LEN (".fsgsbase"), PROCESSOR_UNKNOWN,
886*a9fa9459Szrj CPU_FSGSBASE_FLAGS, 0 },
887*a9fa9459Szrj { STRING_COMMA_LEN (".rdrnd"), PROCESSOR_UNKNOWN,
888*a9fa9459Szrj CPU_RDRND_FLAGS, 0 },
889*a9fa9459Szrj { STRING_COMMA_LEN (".f16c"), PROCESSOR_UNKNOWN,
890*a9fa9459Szrj CPU_F16C_FLAGS, 0 },
891*a9fa9459Szrj { STRING_COMMA_LEN (".bmi2"), PROCESSOR_UNKNOWN,
892*a9fa9459Szrj CPU_BMI2_FLAGS, 0 },
893*a9fa9459Szrj { STRING_COMMA_LEN (".fma"), PROCESSOR_UNKNOWN,
894*a9fa9459Szrj CPU_FMA_FLAGS, 0 },
895*a9fa9459Szrj { STRING_COMMA_LEN (".fma4"), PROCESSOR_UNKNOWN,
896*a9fa9459Szrj CPU_FMA4_FLAGS, 0 },
897*a9fa9459Szrj { STRING_COMMA_LEN (".xop"), PROCESSOR_UNKNOWN,
898*a9fa9459Szrj CPU_XOP_FLAGS, 0 },
899*a9fa9459Szrj { STRING_COMMA_LEN (".lwp"), PROCESSOR_UNKNOWN,
900*a9fa9459Szrj CPU_LWP_FLAGS, 0 },
901*a9fa9459Szrj { STRING_COMMA_LEN (".movbe"), PROCESSOR_UNKNOWN,
902*a9fa9459Szrj CPU_MOVBE_FLAGS, 0 },
903*a9fa9459Szrj { STRING_COMMA_LEN (".cx16"), PROCESSOR_UNKNOWN,
904*a9fa9459Szrj CPU_CX16_FLAGS, 0 },
905*a9fa9459Szrj { STRING_COMMA_LEN (".ept"), PROCESSOR_UNKNOWN,
906*a9fa9459Szrj CPU_EPT_FLAGS, 0 },
907*a9fa9459Szrj { STRING_COMMA_LEN (".lzcnt"), PROCESSOR_UNKNOWN,
908*a9fa9459Szrj CPU_LZCNT_FLAGS, 0 },
909*a9fa9459Szrj { STRING_COMMA_LEN (".hle"), PROCESSOR_UNKNOWN,
910*a9fa9459Szrj CPU_HLE_FLAGS, 0 },
911*a9fa9459Szrj { STRING_COMMA_LEN (".rtm"), PROCESSOR_UNKNOWN,
912*a9fa9459Szrj CPU_RTM_FLAGS, 0 },
913*a9fa9459Szrj { STRING_COMMA_LEN (".invpcid"), PROCESSOR_UNKNOWN,
914*a9fa9459Szrj CPU_INVPCID_FLAGS, 0 },
915*a9fa9459Szrj { STRING_COMMA_LEN (".clflush"), PROCESSOR_UNKNOWN,
916*a9fa9459Szrj CPU_CLFLUSH_FLAGS, 0 },
917*a9fa9459Szrj { STRING_COMMA_LEN (".nop"), PROCESSOR_UNKNOWN,
918*a9fa9459Szrj CPU_NOP_FLAGS, 0 },
919*a9fa9459Szrj { STRING_COMMA_LEN (".syscall"), PROCESSOR_UNKNOWN,
920*a9fa9459Szrj CPU_SYSCALL_FLAGS, 0 },
921*a9fa9459Szrj { STRING_COMMA_LEN (".rdtscp"), PROCESSOR_UNKNOWN,
922*a9fa9459Szrj CPU_RDTSCP_FLAGS, 0 },
923*a9fa9459Szrj { STRING_COMMA_LEN (".3dnow"), PROCESSOR_UNKNOWN,
924*a9fa9459Szrj CPU_3DNOW_FLAGS, 0 },
925*a9fa9459Szrj { STRING_COMMA_LEN (".3dnowa"), PROCESSOR_UNKNOWN,
926*a9fa9459Szrj CPU_3DNOWA_FLAGS, 0 },
927*a9fa9459Szrj { STRING_COMMA_LEN (".padlock"), PROCESSOR_UNKNOWN,
928*a9fa9459Szrj CPU_PADLOCK_FLAGS, 0 },
929*a9fa9459Szrj { STRING_COMMA_LEN (".pacifica"), PROCESSOR_UNKNOWN,
930*a9fa9459Szrj CPU_SVME_FLAGS, 1 },
931*a9fa9459Szrj { STRING_COMMA_LEN (".svme"), PROCESSOR_UNKNOWN,
932*a9fa9459Szrj CPU_SVME_FLAGS, 0 },
933*a9fa9459Szrj { STRING_COMMA_LEN (".sse4a"), PROCESSOR_UNKNOWN,
934*a9fa9459Szrj CPU_SSE4A_FLAGS, 0 },
935*a9fa9459Szrj { STRING_COMMA_LEN (".abm"), PROCESSOR_UNKNOWN,
936*a9fa9459Szrj CPU_ABM_FLAGS, 0 },
937*a9fa9459Szrj { STRING_COMMA_LEN (".bmi"), PROCESSOR_UNKNOWN,
938*a9fa9459Szrj CPU_BMI_FLAGS, 0 },
939*a9fa9459Szrj { STRING_COMMA_LEN (".tbm"), PROCESSOR_UNKNOWN,
940*a9fa9459Szrj CPU_TBM_FLAGS, 0 },
941*a9fa9459Szrj { STRING_COMMA_LEN (".adx"), PROCESSOR_UNKNOWN,
942*a9fa9459Szrj CPU_ADX_FLAGS, 0 },
943*a9fa9459Szrj { STRING_COMMA_LEN (".rdseed"), PROCESSOR_UNKNOWN,
944*a9fa9459Szrj CPU_RDSEED_FLAGS, 0 },
945*a9fa9459Szrj { STRING_COMMA_LEN (".prfchw"), PROCESSOR_UNKNOWN,
946*a9fa9459Szrj CPU_PRFCHW_FLAGS, 0 },
947*a9fa9459Szrj { STRING_COMMA_LEN (".smap"), PROCESSOR_UNKNOWN,
948*a9fa9459Szrj CPU_SMAP_FLAGS, 0 },
949*a9fa9459Szrj { STRING_COMMA_LEN (".mpx"), PROCESSOR_UNKNOWN,
950*a9fa9459Szrj CPU_MPX_FLAGS, 0 },
951*a9fa9459Szrj { STRING_COMMA_LEN (".sha"), PROCESSOR_UNKNOWN,
952*a9fa9459Szrj CPU_SHA_FLAGS, 0 },
953*a9fa9459Szrj { STRING_COMMA_LEN (".clflushopt"), PROCESSOR_UNKNOWN,
954*a9fa9459Szrj CPU_CLFLUSHOPT_FLAGS, 0 },
955*a9fa9459Szrj { STRING_COMMA_LEN (".prefetchwt1"), PROCESSOR_UNKNOWN,
956*a9fa9459Szrj CPU_PREFETCHWT1_FLAGS, 0 },
957*a9fa9459Szrj { STRING_COMMA_LEN (".se1"), PROCESSOR_UNKNOWN,
958*a9fa9459Szrj CPU_SE1_FLAGS, 0 },
959*a9fa9459Szrj { STRING_COMMA_LEN (".clwb"), PROCESSOR_UNKNOWN,
960*a9fa9459Szrj CPU_CLWB_FLAGS, 0 },
961*a9fa9459Szrj { STRING_COMMA_LEN (".pcommit"), PROCESSOR_UNKNOWN,
962*a9fa9459Szrj CPU_PCOMMIT_FLAGS, 0 },
963*a9fa9459Szrj { STRING_COMMA_LEN (".avx512ifma"), PROCESSOR_UNKNOWN,
964*a9fa9459Szrj CPU_AVX512IFMA_FLAGS, 0 },
965*a9fa9459Szrj { STRING_COMMA_LEN (".avx512vbmi"), PROCESSOR_UNKNOWN,
966*a9fa9459Szrj CPU_AVX512VBMI_FLAGS, 0 },
967*a9fa9459Szrj { STRING_COMMA_LEN (".clzero"), PROCESSOR_UNKNOWN,
968*a9fa9459Szrj CPU_CLZERO_FLAGS, 0 },
969*a9fa9459Szrj { STRING_COMMA_LEN (".mwaitx"), PROCESSOR_UNKNOWN,
970*a9fa9459Szrj CPU_MWAITX_FLAGS, 0 },
971*a9fa9459Szrj { STRING_COMMA_LEN (".ospke"), PROCESSOR_UNKNOWN,
972*a9fa9459Szrj CPU_OSPKE_FLAGS, 0 },
973*a9fa9459Szrj { STRING_COMMA_LEN (".rdpid"), PROCESSOR_UNKNOWN,
974*a9fa9459Szrj CPU_RDPID_FLAGS, 0 },
975*a9fa9459Szrj };
976*a9fa9459Szrj
977*a9fa9459Szrj static const noarch_entry cpu_noarch[] =
978*a9fa9459Szrj {
979*a9fa9459Szrj { STRING_COMMA_LEN ("no87"), CPU_ANY_X87_FLAGS },
980*a9fa9459Szrj { STRING_COMMA_LEN ("no287"), CPU_ANY_287_FLAGS },
981*a9fa9459Szrj { STRING_COMMA_LEN ("no387"), CPU_ANY_387_FLAGS },
982*a9fa9459Szrj { STRING_COMMA_LEN ("no687"), CPU_ANY_687_FLAGS },
983*a9fa9459Szrj { STRING_COMMA_LEN ("nommx"), CPU_ANY_MMX_FLAGS },
984*a9fa9459Szrj { STRING_COMMA_LEN ("nosse"), CPU_ANY_SSE_FLAGS },
985*a9fa9459Szrj { STRING_COMMA_LEN ("nosse2"), CPU_ANY_SSE2_FLAGS },
986*a9fa9459Szrj { STRING_COMMA_LEN ("nosse3"), CPU_ANY_SSE3_FLAGS },
987*a9fa9459Szrj { STRING_COMMA_LEN ("nossse3"), CPU_ANY_SSSE3_FLAGS },
988*a9fa9459Szrj { STRING_COMMA_LEN ("nosse4.1"), CPU_ANY_SSE4_1_FLAGS },
989*a9fa9459Szrj { STRING_COMMA_LEN ("nosse4.2"), CPU_ANY_SSE4_2_FLAGS },
990*a9fa9459Szrj { STRING_COMMA_LEN ("nosse4"), CPU_ANY_SSE4_1_FLAGS },
991*a9fa9459Szrj { STRING_COMMA_LEN ("noavx"), CPU_ANY_AVX_FLAGS },
992*a9fa9459Szrj { STRING_COMMA_LEN ("noavx2"), CPU_ANY_AVX2_FLAGS },
993*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512f"), CPU_ANY_AVX512F_FLAGS },
994*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512cd"), CPU_ANY_AVX512CD_FLAGS },
995*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512er"), CPU_ANY_AVX512ER_FLAGS },
996*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512pf"), CPU_ANY_AVX512PF_FLAGS },
997*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512dq"), CPU_ANY_AVX512DQ_FLAGS },
998*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512bw"), CPU_ANY_AVX512BW_FLAGS },
999*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512vl"), CPU_ANY_AVX512VL_FLAGS },
1000*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512ifma"), CPU_ANY_AVX512IFMA_FLAGS },
1001*a9fa9459Szrj { STRING_COMMA_LEN ("noavx512vbmi"), CPU_ANY_AVX512VBMI_FLAGS },
1002*a9fa9459Szrj };
1003*a9fa9459Szrj
1004*a9fa9459Szrj #ifdef I386COFF
1005*a9fa9459Szrj /* Like s_lcomm_internal in gas/read.c but the alignment string
1006*a9fa9459Szrj is allowed to be optional. */
1007*a9fa9459Szrj
1008*a9fa9459Szrj static symbolS *
pe_lcomm_internal(int needs_align,symbolS * symbolP,addressT size)1009*a9fa9459Szrj pe_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
1010*a9fa9459Szrj {
1011*a9fa9459Szrj addressT align = 0;
1012*a9fa9459Szrj
1013*a9fa9459Szrj SKIP_WHITESPACE ();
1014*a9fa9459Szrj
1015*a9fa9459Szrj if (needs_align
1016*a9fa9459Szrj && *input_line_pointer == ',')
1017*a9fa9459Szrj {
1018*a9fa9459Szrj align = parse_align (needs_align - 1);
1019*a9fa9459Szrj
1020*a9fa9459Szrj if (align == (addressT) -1)
1021*a9fa9459Szrj return NULL;
1022*a9fa9459Szrj }
1023*a9fa9459Szrj else
1024*a9fa9459Szrj {
1025*a9fa9459Szrj if (size >= 8)
1026*a9fa9459Szrj align = 3;
1027*a9fa9459Szrj else if (size >= 4)
1028*a9fa9459Szrj align = 2;
1029*a9fa9459Szrj else if (size >= 2)
1030*a9fa9459Szrj align = 1;
1031*a9fa9459Szrj else
1032*a9fa9459Szrj align = 0;
1033*a9fa9459Szrj }
1034*a9fa9459Szrj
1035*a9fa9459Szrj bss_alloc (symbolP, size, align);
1036*a9fa9459Szrj return symbolP;
1037*a9fa9459Szrj }
1038*a9fa9459Szrj
1039*a9fa9459Szrj static void
pe_lcomm(int needs_align)1040*a9fa9459Szrj pe_lcomm (int needs_align)
1041*a9fa9459Szrj {
1042*a9fa9459Szrj s_comm_internal (needs_align * 2, pe_lcomm_internal);
1043*a9fa9459Szrj }
1044*a9fa9459Szrj #endif
1045*a9fa9459Szrj
1046*a9fa9459Szrj const pseudo_typeS md_pseudo_table[] =
1047*a9fa9459Szrj {
1048*a9fa9459Szrj #if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO)
1049*a9fa9459Szrj {"align", s_align_bytes, 0},
1050*a9fa9459Szrj #else
1051*a9fa9459Szrj {"align", s_align_ptwo, 0},
1052*a9fa9459Szrj #endif
1053*a9fa9459Szrj {"arch", set_cpu_arch, 0},
1054*a9fa9459Szrj #ifndef I386COFF
1055*a9fa9459Szrj {"bss", s_bss, 0},
1056*a9fa9459Szrj #else
1057*a9fa9459Szrj {"lcomm", pe_lcomm, 1},
1058*a9fa9459Szrj #endif
1059*a9fa9459Szrj {"ffloat", float_cons, 'f'},
1060*a9fa9459Szrj {"dfloat", float_cons, 'd'},
1061*a9fa9459Szrj {"tfloat", float_cons, 'x'},
1062*a9fa9459Szrj {"value", cons, 2},
1063*a9fa9459Szrj {"slong", signed_cons, 4},
1064*a9fa9459Szrj {"noopt", s_ignore, 0},
1065*a9fa9459Szrj {"optim", s_ignore, 0},
1066*a9fa9459Szrj {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT},
1067*a9fa9459Szrj {"code16", set_code_flag, CODE_16BIT},
1068*a9fa9459Szrj {"code32", set_code_flag, CODE_32BIT},
1069*a9fa9459Szrj {"code64", set_code_flag, CODE_64BIT},
1070*a9fa9459Szrj {"intel_syntax", set_intel_syntax, 1},
1071*a9fa9459Szrj {"att_syntax", set_intel_syntax, 0},
1072*a9fa9459Szrj {"intel_mnemonic", set_intel_mnemonic, 1},
1073*a9fa9459Szrj {"att_mnemonic", set_intel_mnemonic, 0},
1074*a9fa9459Szrj {"allow_index_reg", set_allow_index_reg, 1},
1075*a9fa9459Szrj {"disallow_index_reg", set_allow_index_reg, 0},
1076*a9fa9459Szrj {"sse_check", set_check, 0},
1077*a9fa9459Szrj {"operand_check", set_check, 1},
1078*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
1079*a9fa9459Szrj {"largecomm", handle_large_common, 0},
1080*a9fa9459Szrj #else
1081*a9fa9459Szrj {"file", (void (*) (int)) dwarf2_directive_file, 0},
1082*a9fa9459Szrj {"loc", dwarf2_directive_loc, 0},
1083*a9fa9459Szrj {"loc_mark_labels", dwarf2_directive_loc_mark_labels, 0},
1084*a9fa9459Szrj #endif
1085*a9fa9459Szrj #ifdef TE_PE
1086*a9fa9459Szrj {"secrel32", pe_directive_secrel, 0},
1087*a9fa9459Szrj #endif
1088*a9fa9459Szrj {0, 0, 0}
1089*a9fa9459Szrj };
1090*a9fa9459Szrj
1091*a9fa9459Szrj /* For interface with expression (). */
1092*a9fa9459Szrj extern char *input_line_pointer;
1093*a9fa9459Szrj
1094*a9fa9459Szrj /* Hash table for instruction mnemonic lookup. */
1095*a9fa9459Szrj static struct hash_control *op_hash;
1096*a9fa9459Szrj
1097*a9fa9459Szrj /* Hash table for register lookup. */
1098*a9fa9459Szrj static struct hash_control *reg_hash;
1099*a9fa9459Szrj
1100*a9fa9459Szrj void
i386_align_code(fragS * fragP,int count)1101*a9fa9459Szrj i386_align_code (fragS *fragP, int count)
1102*a9fa9459Szrj {
1103*a9fa9459Szrj /* Various efficient no-op patterns for aligning code labels.
1104*a9fa9459Szrj Note: Don't try to assemble the instructions in the comments.
1105*a9fa9459Szrj 0L and 0w are not legal. */
1106*a9fa9459Szrj static const unsigned char f32_1[] =
1107*a9fa9459Szrj {0x90}; /* nop */
1108*a9fa9459Szrj static const unsigned char f32_2[] =
1109*a9fa9459Szrj {0x66,0x90}; /* xchg %ax,%ax */
1110*a9fa9459Szrj static const unsigned char f32_3[] =
1111*a9fa9459Szrj {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */
1112*a9fa9459Szrj static const unsigned char f32_4[] =
1113*a9fa9459Szrj {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
1114*a9fa9459Szrj static const unsigned char f32_5[] =
1115*a9fa9459Szrj {0x90, /* nop */
1116*a9fa9459Szrj 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
1117*a9fa9459Szrj static const unsigned char f32_6[] =
1118*a9fa9459Szrj {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */
1119*a9fa9459Szrj static const unsigned char f32_7[] =
1120*a9fa9459Szrj {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
1121*a9fa9459Szrj static const unsigned char f32_8[] =
1122*a9fa9459Szrj {0x90, /* nop */
1123*a9fa9459Szrj 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
1124*a9fa9459Szrj static const unsigned char f32_9[] =
1125*a9fa9459Szrj {0x89,0xf6, /* movl %esi,%esi */
1126*a9fa9459Szrj 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
1127*a9fa9459Szrj static const unsigned char f32_10[] =
1128*a9fa9459Szrj {0x8d,0x76,0x00, /* leal 0(%esi),%esi */
1129*a9fa9459Szrj 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
1130*a9fa9459Szrj static const unsigned char f32_11[] =
1131*a9fa9459Szrj {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */
1132*a9fa9459Szrj 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
1133*a9fa9459Szrj static const unsigned char f32_12[] =
1134*a9fa9459Szrj {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
1135*a9fa9459Szrj 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */
1136*a9fa9459Szrj static const unsigned char f32_13[] =
1137*a9fa9459Szrj {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
1138*a9fa9459Szrj 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
1139*a9fa9459Szrj static const unsigned char f32_14[] =
1140*a9fa9459Szrj {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */
1141*a9fa9459Szrj 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
1142*a9fa9459Szrj static const unsigned char f16_3[] =
1143*a9fa9459Szrj {0x8d,0x74,0x00}; /* lea 0(%esi),%esi */
1144*a9fa9459Szrj static const unsigned char f16_4[] =
1145*a9fa9459Szrj {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
1146*a9fa9459Szrj static const unsigned char f16_5[] =
1147*a9fa9459Szrj {0x90, /* nop */
1148*a9fa9459Szrj 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
1149*a9fa9459Szrj static const unsigned char f16_6[] =
1150*a9fa9459Szrj {0x89,0xf6, /* mov %si,%si */
1151*a9fa9459Szrj 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
1152*a9fa9459Szrj static const unsigned char f16_7[] =
1153*a9fa9459Szrj {0x8d,0x74,0x00, /* lea 0(%si),%si */
1154*a9fa9459Szrj 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
1155*a9fa9459Szrj static const unsigned char f16_8[] =
1156*a9fa9459Szrj {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */
1157*a9fa9459Szrj 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
1158*a9fa9459Szrj static const unsigned char jump_31[] =
1159*a9fa9459Szrj {0xeb,0x1d,0x90,0x90,0x90,0x90,0x90, /* jmp .+31; lotsa nops */
1160*a9fa9459Szrj 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
1161*a9fa9459Szrj 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
1162*a9fa9459Szrj 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
1163*a9fa9459Szrj static const unsigned char *const f32_patt[] = {
1164*a9fa9459Szrj f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
1165*a9fa9459Szrj f32_9, f32_10, f32_11, f32_12, f32_13, f32_14
1166*a9fa9459Szrj };
1167*a9fa9459Szrj static const unsigned char *const f16_patt[] = {
1168*a9fa9459Szrj f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8
1169*a9fa9459Szrj };
1170*a9fa9459Szrj /* nopl (%[re]ax) */
1171*a9fa9459Szrj static const unsigned char alt_3[] =
1172*a9fa9459Szrj {0x0f,0x1f,0x00};
1173*a9fa9459Szrj /* nopl 0(%[re]ax) */
1174*a9fa9459Szrj static const unsigned char alt_4[] =
1175*a9fa9459Szrj {0x0f,0x1f,0x40,0x00};
1176*a9fa9459Szrj /* nopl 0(%[re]ax,%[re]ax,1) */
1177*a9fa9459Szrj static const unsigned char alt_5[] =
1178*a9fa9459Szrj {0x0f,0x1f,0x44,0x00,0x00};
1179*a9fa9459Szrj /* nopw 0(%[re]ax,%[re]ax,1) */
1180*a9fa9459Szrj static const unsigned char alt_6[] =
1181*a9fa9459Szrj {0x66,0x0f,0x1f,0x44,0x00,0x00};
1182*a9fa9459Szrj /* nopl 0L(%[re]ax) */
1183*a9fa9459Szrj static const unsigned char alt_7[] =
1184*a9fa9459Szrj {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
1185*a9fa9459Szrj /* nopl 0L(%[re]ax,%[re]ax,1) */
1186*a9fa9459Szrj static const unsigned char alt_8[] =
1187*a9fa9459Szrj {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
1188*a9fa9459Szrj /* nopw 0L(%[re]ax,%[re]ax,1) */
1189*a9fa9459Szrj static const unsigned char alt_9[] =
1190*a9fa9459Szrj {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
1191*a9fa9459Szrj /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
1192*a9fa9459Szrj static const unsigned char alt_10[] =
1193*a9fa9459Szrj {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
1194*a9fa9459Szrj static const unsigned char *const alt_patt[] = {
1195*a9fa9459Szrj f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8,
1196*a9fa9459Szrj alt_9, alt_10
1197*a9fa9459Szrj };
1198*a9fa9459Szrj
1199*a9fa9459Szrj /* Only align for at least a positive non-zero boundary. */
1200*a9fa9459Szrj if (count <= 0 || count > MAX_MEM_FOR_RS_ALIGN_CODE)
1201*a9fa9459Szrj return;
1202*a9fa9459Szrj
1203*a9fa9459Szrj /* We need to decide which NOP sequence to use for 32bit and
1204*a9fa9459Szrj 64bit. When -mtune= is used:
1205*a9fa9459Szrj
1206*a9fa9459Szrj 1. For PROCESSOR_I386, PROCESSOR_I486, PROCESSOR_PENTIUM and
1207*a9fa9459Szrj PROCESSOR_GENERIC32, f32_patt will be used.
1208*a9fa9459Szrj 2. For the rest, alt_patt will be used.
1209*a9fa9459Szrj
1210*a9fa9459Szrj When -mtune= isn't used, alt_patt will be used if
1211*a9fa9459Szrj cpu_arch_isa_flags has CpuNop. Otherwise, f32_patt will
1212*a9fa9459Szrj be used.
1213*a9fa9459Szrj
1214*a9fa9459Szrj When -march= or .arch is used, we can't use anything beyond
1215*a9fa9459Szrj cpu_arch_isa_flags. */
1216*a9fa9459Szrj
1217*a9fa9459Szrj if (flag_code == CODE_16BIT)
1218*a9fa9459Szrj {
1219*a9fa9459Szrj if (count > 8)
1220*a9fa9459Szrj {
1221*a9fa9459Szrj memcpy (fragP->fr_literal + fragP->fr_fix,
1222*a9fa9459Szrj jump_31, count);
1223*a9fa9459Szrj /* Adjust jump offset. */
1224*a9fa9459Szrj fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
1225*a9fa9459Szrj }
1226*a9fa9459Szrj else
1227*a9fa9459Szrj memcpy (fragP->fr_literal + fragP->fr_fix,
1228*a9fa9459Szrj f16_patt[count - 1], count);
1229*a9fa9459Szrj }
1230*a9fa9459Szrj else
1231*a9fa9459Szrj {
1232*a9fa9459Szrj const unsigned char *const *patt = NULL;
1233*a9fa9459Szrj
1234*a9fa9459Szrj if (fragP->tc_frag_data.isa == PROCESSOR_UNKNOWN)
1235*a9fa9459Szrj {
1236*a9fa9459Szrj /* PROCESSOR_UNKNOWN means that all ISAs may be used. */
1237*a9fa9459Szrj switch (cpu_arch_tune)
1238*a9fa9459Szrj {
1239*a9fa9459Szrj case PROCESSOR_UNKNOWN:
1240*a9fa9459Szrj /* We use cpu_arch_isa_flags to check if we SHOULD
1241*a9fa9459Szrj optimize with nops. */
1242*a9fa9459Szrj if (fragP->tc_frag_data.isa_flags.bitfield.cpunop)
1243*a9fa9459Szrj patt = alt_patt;
1244*a9fa9459Szrj else
1245*a9fa9459Szrj patt = f32_patt;
1246*a9fa9459Szrj break;
1247*a9fa9459Szrj case PROCESSOR_PENTIUM4:
1248*a9fa9459Szrj case PROCESSOR_NOCONA:
1249*a9fa9459Szrj case PROCESSOR_CORE:
1250*a9fa9459Szrj case PROCESSOR_CORE2:
1251*a9fa9459Szrj case PROCESSOR_COREI7:
1252*a9fa9459Szrj case PROCESSOR_L1OM:
1253*a9fa9459Szrj case PROCESSOR_K1OM:
1254*a9fa9459Szrj case PROCESSOR_GENERIC64:
1255*a9fa9459Szrj case PROCESSOR_K6:
1256*a9fa9459Szrj case PROCESSOR_ATHLON:
1257*a9fa9459Szrj case PROCESSOR_K8:
1258*a9fa9459Szrj case PROCESSOR_AMDFAM10:
1259*a9fa9459Szrj case PROCESSOR_BD:
1260*a9fa9459Szrj case PROCESSOR_ZNVER:
1261*a9fa9459Szrj case PROCESSOR_BT:
1262*a9fa9459Szrj patt = alt_patt;
1263*a9fa9459Szrj break;
1264*a9fa9459Szrj case PROCESSOR_I386:
1265*a9fa9459Szrj case PROCESSOR_I486:
1266*a9fa9459Szrj case PROCESSOR_PENTIUM:
1267*a9fa9459Szrj case PROCESSOR_PENTIUMPRO:
1268*a9fa9459Szrj case PROCESSOR_IAMCU:
1269*a9fa9459Szrj case PROCESSOR_GENERIC32:
1270*a9fa9459Szrj patt = f32_patt;
1271*a9fa9459Szrj break;
1272*a9fa9459Szrj }
1273*a9fa9459Szrj }
1274*a9fa9459Szrj else
1275*a9fa9459Szrj {
1276*a9fa9459Szrj switch (fragP->tc_frag_data.tune)
1277*a9fa9459Szrj {
1278*a9fa9459Szrj case PROCESSOR_UNKNOWN:
1279*a9fa9459Szrj /* When cpu_arch_isa is set, cpu_arch_tune shouldn't be
1280*a9fa9459Szrj PROCESSOR_UNKNOWN. */
1281*a9fa9459Szrj abort ();
1282*a9fa9459Szrj break;
1283*a9fa9459Szrj
1284*a9fa9459Szrj case PROCESSOR_I386:
1285*a9fa9459Szrj case PROCESSOR_I486:
1286*a9fa9459Szrj case PROCESSOR_PENTIUM:
1287*a9fa9459Szrj case PROCESSOR_IAMCU:
1288*a9fa9459Szrj case PROCESSOR_K6:
1289*a9fa9459Szrj case PROCESSOR_ATHLON:
1290*a9fa9459Szrj case PROCESSOR_K8:
1291*a9fa9459Szrj case PROCESSOR_AMDFAM10:
1292*a9fa9459Szrj case PROCESSOR_BD:
1293*a9fa9459Szrj case PROCESSOR_ZNVER:
1294*a9fa9459Szrj case PROCESSOR_BT:
1295*a9fa9459Szrj case PROCESSOR_GENERIC32:
1296*a9fa9459Szrj /* We use cpu_arch_isa_flags to check if we CAN optimize
1297*a9fa9459Szrj with nops. */
1298*a9fa9459Szrj if (fragP->tc_frag_data.isa_flags.bitfield.cpunop)
1299*a9fa9459Szrj patt = alt_patt;
1300*a9fa9459Szrj else
1301*a9fa9459Szrj patt = f32_patt;
1302*a9fa9459Szrj break;
1303*a9fa9459Szrj case PROCESSOR_PENTIUMPRO:
1304*a9fa9459Szrj case PROCESSOR_PENTIUM4:
1305*a9fa9459Szrj case PROCESSOR_NOCONA:
1306*a9fa9459Szrj case PROCESSOR_CORE:
1307*a9fa9459Szrj case PROCESSOR_CORE2:
1308*a9fa9459Szrj case PROCESSOR_COREI7:
1309*a9fa9459Szrj case PROCESSOR_L1OM:
1310*a9fa9459Szrj case PROCESSOR_K1OM:
1311*a9fa9459Szrj if (fragP->tc_frag_data.isa_flags.bitfield.cpunop)
1312*a9fa9459Szrj patt = alt_patt;
1313*a9fa9459Szrj else
1314*a9fa9459Szrj patt = f32_patt;
1315*a9fa9459Szrj break;
1316*a9fa9459Szrj case PROCESSOR_GENERIC64:
1317*a9fa9459Szrj patt = alt_patt;
1318*a9fa9459Szrj break;
1319*a9fa9459Szrj }
1320*a9fa9459Szrj }
1321*a9fa9459Szrj
1322*a9fa9459Szrj if (patt == f32_patt)
1323*a9fa9459Szrj {
1324*a9fa9459Szrj /* If the padding is less than 15 bytes, we use the normal
1325*a9fa9459Szrj ones. Otherwise, we use a jump instruction and adjust
1326*a9fa9459Szrj its offset. */
1327*a9fa9459Szrj int limit;
1328*a9fa9459Szrj
1329*a9fa9459Szrj /* For 64bit, the limit is 3 bytes. */
1330*a9fa9459Szrj if (flag_code == CODE_64BIT
1331*a9fa9459Szrj && fragP->tc_frag_data.isa_flags.bitfield.cpulm)
1332*a9fa9459Szrj limit = 3;
1333*a9fa9459Szrj else
1334*a9fa9459Szrj limit = 15;
1335*a9fa9459Szrj if (count < limit)
1336*a9fa9459Szrj memcpy (fragP->fr_literal + fragP->fr_fix,
1337*a9fa9459Szrj patt[count - 1], count);
1338*a9fa9459Szrj else
1339*a9fa9459Szrj {
1340*a9fa9459Szrj memcpy (fragP->fr_literal + fragP->fr_fix,
1341*a9fa9459Szrj jump_31, count);
1342*a9fa9459Szrj /* Adjust jump offset. */
1343*a9fa9459Szrj fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
1344*a9fa9459Szrj }
1345*a9fa9459Szrj }
1346*a9fa9459Szrj else
1347*a9fa9459Szrj {
1348*a9fa9459Szrj /* Maximum length of an instruction is 10 byte. If the
1349*a9fa9459Szrj padding is greater than 10 bytes and we don't use jump,
1350*a9fa9459Szrj we have to break it into smaller pieces. */
1351*a9fa9459Szrj int padding = count;
1352*a9fa9459Szrj while (padding > 10)
1353*a9fa9459Szrj {
1354*a9fa9459Szrj padding -= 10;
1355*a9fa9459Szrj memcpy (fragP->fr_literal + fragP->fr_fix + padding,
1356*a9fa9459Szrj patt [9], 10);
1357*a9fa9459Szrj }
1358*a9fa9459Szrj
1359*a9fa9459Szrj if (padding)
1360*a9fa9459Szrj memcpy (fragP->fr_literal + fragP->fr_fix,
1361*a9fa9459Szrj patt [padding - 1], padding);
1362*a9fa9459Szrj }
1363*a9fa9459Szrj }
1364*a9fa9459Szrj fragP->fr_var = count;
1365*a9fa9459Szrj }
1366*a9fa9459Szrj
1367*a9fa9459Szrj static INLINE int
operand_type_all_zero(const union i386_operand_type * x)1368*a9fa9459Szrj operand_type_all_zero (const union i386_operand_type *x)
1369*a9fa9459Szrj {
1370*a9fa9459Szrj switch (ARRAY_SIZE(x->array))
1371*a9fa9459Szrj {
1372*a9fa9459Szrj case 3:
1373*a9fa9459Szrj if (x->array[2])
1374*a9fa9459Szrj return 0;
1375*a9fa9459Szrj case 2:
1376*a9fa9459Szrj if (x->array[1])
1377*a9fa9459Szrj return 0;
1378*a9fa9459Szrj case 1:
1379*a9fa9459Szrj return !x->array[0];
1380*a9fa9459Szrj default:
1381*a9fa9459Szrj abort ();
1382*a9fa9459Szrj }
1383*a9fa9459Szrj }
1384*a9fa9459Szrj
1385*a9fa9459Szrj static INLINE void
operand_type_set(union i386_operand_type * x,unsigned int v)1386*a9fa9459Szrj operand_type_set (union i386_operand_type *x, unsigned int v)
1387*a9fa9459Szrj {
1388*a9fa9459Szrj switch (ARRAY_SIZE(x->array))
1389*a9fa9459Szrj {
1390*a9fa9459Szrj case 3:
1391*a9fa9459Szrj x->array[2] = v;
1392*a9fa9459Szrj case 2:
1393*a9fa9459Szrj x->array[1] = v;
1394*a9fa9459Szrj case 1:
1395*a9fa9459Szrj x->array[0] = v;
1396*a9fa9459Szrj break;
1397*a9fa9459Szrj default:
1398*a9fa9459Szrj abort ();
1399*a9fa9459Szrj }
1400*a9fa9459Szrj }
1401*a9fa9459Szrj
1402*a9fa9459Szrj static INLINE int
operand_type_equal(const union i386_operand_type * x,const union i386_operand_type * y)1403*a9fa9459Szrj operand_type_equal (const union i386_operand_type *x,
1404*a9fa9459Szrj const union i386_operand_type *y)
1405*a9fa9459Szrj {
1406*a9fa9459Szrj switch (ARRAY_SIZE(x->array))
1407*a9fa9459Szrj {
1408*a9fa9459Szrj case 3:
1409*a9fa9459Szrj if (x->array[2] != y->array[2])
1410*a9fa9459Szrj return 0;
1411*a9fa9459Szrj case 2:
1412*a9fa9459Szrj if (x->array[1] != y->array[1])
1413*a9fa9459Szrj return 0;
1414*a9fa9459Szrj case 1:
1415*a9fa9459Szrj return x->array[0] == y->array[0];
1416*a9fa9459Szrj break;
1417*a9fa9459Szrj default:
1418*a9fa9459Szrj abort ();
1419*a9fa9459Szrj }
1420*a9fa9459Szrj }
1421*a9fa9459Szrj
1422*a9fa9459Szrj static INLINE int
cpu_flags_all_zero(const union i386_cpu_flags * x)1423*a9fa9459Szrj cpu_flags_all_zero (const union i386_cpu_flags *x)
1424*a9fa9459Szrj {
1425*a9fa9459Szrj switch (ARRAY_SIZE(x->array))
1426*a9fa9459Szrj {
1427*a9fa9459Szrj case 3:
1428*a9fa9459Szrj if (x->array[2])
1429*a9fa9459Szrj return 0;
1430*a9fa9459Szrj case 2:
1431*a9fa9459Szrj if (x->array[1])
1432*a9fa9459Szrj return 0;
1433*a9fa9459Szrj case 1:
1434*a9fa9459Szrj return !x->array[0];
1435*a9fa9459Szrj default:
1436*a9fa9459Szrj abort ();
1437*a9fa9459Szrj }
1438*a9fa9459Szrj }
1439*a9fa9459Szrj
1440*a9fa9459Szrj static INLINE int
cpu_flags_equal(const union i386_cpu_flags * x,const union i386_cpu_flags * y)1441*a9fa9459Szrj cpu_flags_equal (const union i386_cpu_flags *x,
1442*a9fa9459Szrj const union i386_cpu_flags *y)
1443*a9fa9459Szrj {
1444*a9fa9459Szrj switch (ARRAY_SIZE(x->array))
1445*a9fa9459Szrj {
1446*a9fa9459Szrj case 3:
1447*a9fa9459Szrj if (x->array[2] != y->array[2])
1448*a9fa9459Szrj return 0;
1449*a9fa9459Szrj case 2:
1450*a9fa9459Szrj if (x->array[1] != y->array[1])
1451*a9fa9459Szrj return 0;
1452*a9fa9459Szrj case 1:
1453*a9fa9459Szrj return x->array[0] == y->array[0];
1454*a9fa9459Szrj break;
1455*a9fa9459Szrj default:
1456*a9fa9459Szrj abort ();
1457*a9fa9459Szrj }
1458*a9fa9459Szrj }
1459*a9fa9459Szrj
1460*a9fa9459Szrj static INLINE int
cpu_flags_check_cpu64(i386_cpu_flags f)1461*a9fa9459Szrj cpu_flags_check_cpu64 (i386_cpu_flags f)
1462*a9fa9459Szrj {
1463*a9fa9459Szrj return !((flag_code == CODE_64BIT && f.bitfield.cpuno64)
1464*a9fa9459Szrj || (flag_code != CODE_64BIT && f.bitfield.cpu64));
1465*a9fa9459Szrj }
1466*a9fa9459Szrj
1467*a9fa9459Szrj static INLINE i386_cpu_flags
cpu_flags_and(i386_cpu_flags x,i386_cpu_flags y)1468*a9fa9459Szrj cpu_flags_and (i386_cpu_flags x, i386_cpu_flags y)
1469*a9fa9459Szrj {
1470*a9fa9459Szrj switch (ARRAY_SIZE (x.array))
1471*a9fa9459Szrj {
1472*a9fa9459Szrj case 3:
1473*a9fa9459Szrj x.array [2] &= y.array [2];
1474*a9fa9459Szrj case 2:
1475*a9fa9459Szrj x.array [1] &= y.array [1];
1476*a9fa9459Szrj case 1:
1477*a9fa9459Szrj x.array [0] &= y.array [0];
1478*a9fa9459Szrj break;
1479*a9fa9459Szrj default:
1480*a9fa9459Szrj abort ();
1481*a9fa9459Szrj }
1482*a9fa9459Szrj return x;
1483*a9fa9459Szrj }
1484*a9fa9459Szrj
1485*a9fa9459Szrj static INLINE i386_cpu_flags
cpu_flags_or(i386_cpu_flags x,i386_cpu_flags y)1486*a9fa9459Szrj cpu_flags_or (i386_cpu_flags x, i386_cpu_flags y)
1487*a9fa9459Szrj {
1488*a9fa9459Szrj switch (ARRAY_SIZE (x.array))
1489*a9fa9459Szrj {
1490*a9fa9459Szrj case 3:
1491*a9fa9459Szrj x.array [2] |= y.array [2];
1492*a9fa9459Szrj case 2:
1493*a9fa9459Szrj x.array [1] |= y.array [1];
1494*a9fa9459Szrj case 1:
1495*a9fa9459Szrj x.array [0] |= y.array [0];
1496*a9fa9459Szrj break;
1497*a9fa9459Szrj default:
1498*a9fa9459Szrj abort ();
1499*a9fa9459Szrj }
1500*a9fa9459Szrj return x;
1501*a9fa9459Szrj }
1502*a9fa9459Szrj
1503*a9fa9459Szrj static INLINE i386_cpu_flags
cpu_flags_and_not(i386_cpu_flags x,i386_cpu_flags y)1504*a9fa9459Szrj cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y)
1505*a9fa9459Szrj {
1506*a9fa9459Szrj switch (ARRAY_SIZE (x.array))
1507*a9fa9459Szrj {
1508*a9fa9459Szrj case 3:
1509*a9fa9459Szrj x.array [2] &= ~y.array [2];
1510*a9fa9459Szrj case 2:
1511*a9fa9459Szrj x.array [1] &= ~y.array [1];
1512*a9fa9459Szrj case 1:
1513*a9fa9459Szrj x.array [0] &= ~y.array [0];
1514*a9fa9459Szrj break;
1515*a9fa9459Szrj default:
1516*a9fa9459Szrj abort ();
1517*a9fa9459Szrj }
1518*a9fa9459Szrj return x;
1519*a9fa9459Szrj }
1520*a9fa9459Szrj
1521*a9fa9459Szrj static int
valid_iamcu_cpu_flags(const i386_cpu_flags * flags)1522*a9fa9459Szrj valid_iamcu_cpu_flags (const i386_cpu_flags *flags)
1523*a9fa9459Szrj {
1524*a9fa9459Szrj if (cpu_arch_isa == PROCESSOR_IAMCU)
1525*a9fa9459Szrj {
1526*a9fa9459Szrj static const i386_cpu_flags iamcu_flags = CPU_IAMCU_COMPAT_FLAGS;
1527*a9fa9459Szrj i386_cpu_flags compat_flags;
1528*a9fa9459Szrj compat_flags = cpu_flags_and_not (*flags, iamcu_flags);
1529*a9fa9459Szrj return cpu_flags_all_zero (&compat_flags);
1530*a9fa9459Szrj }
1531*a9fa9459Szrj else
1532*a9fa9459Szrj return 1;
1533*a9fa9459Szrj }
1534*a9fa9459Szrj
1535*a9fa9459Szrj #define CPU_FLAGS_ARCH_MATCH 0x1
1536*a9fa9459Szrj #define CPU_FLAGS_64BIT_MATCH 0x2
1537*a9fa9459Szrj #define CPU_FLAGS_AES_MATCH 0x4
1538*a9fa9459Szrj #define CPU_FLAGS_PCLMUL_MATCH 0x8
1539*a9fa9459Szrj #define CPU_FLAGS_AVX_MATCH 0x10
1540*a9fa9459Szrj
1541*a9fa9459Szrj #define CPU_FLAGS_32BIT_MATCH \
1542*a9fa9459Szrj (CPU_FLAGS_ARCH_MATCH | CPU_FLAGS_AES_MATCH \
1543*a9fa9459Szrj | CPU_FLAGS_PCLMUL_MATCH | CPU_FLAGS_AVX_MATCH)
1544*a9fa9459Szrj #define CPU_FLAGS_PERFECT_MATCH \
1545*a9fa9459Szrj (CPU_FLAGS_32BIT_MATCH | CPU_FLAGS_64BIT_MATCH)
1546*a9fa9459Szrj
1547*a9fa9459Szrj /* Return CPU flags match bits. */
1548*a9fa9459Szrj
1549*a9fa9459Szrj static int
cpu_flags_match(const insn_template * t)1550*a9fa9459Szrj cpu_flags_match (const insn_template *t)
1551*a9fa9459Szrj {
1552*a9fa9459Szrj i386_cpu_flags x = t->cpu_flags;
1553*a9fa9459Szrj int match = cpu_flags_check_cpu64 (x) ? CPU_FLAGS_64BIT_MATCH : 0;
1554*a9fa9459Szrj
1555*a9fa9459Szrj x.bitfield.cpu64 = 0;
1556*a9fa9459Szrj x.bitfield.cpuno64 = 0;
1557*a9fa9459Szrj
1558*a9fa9459Szrj if (cpu_flags_all_zero (&x))
1559*a9fa9459Szrj {
1560*a9fa9459Szrj /* This instruction is available on all archs. */
1561*a9fa9459Szrj match |= CPU_FLAGS_32BIT_MATCH;
1562*a9fa9459Szrj }
1563*a9fa9459Szrj else
1564*a9fa9459Szrj {
1565*a9fa9459Szrj /* This instruction is available only on some archs. */
1566*a9fa9459Szrj i386_cpu_flags cpu = cpu_arch_flags;
1567*a9fa9459Szrj
1568*a9fa9459Szrj cpu = cpu_flags_and (x, cpu);
1569*a9fa9459Szrj if (!cpu_flags_all_zero (&cpu))
1570*a9fa9459Szrj {
1571*a9fa9459Szrj if (x.bitfield.cpuavx)
1572*a9fa9459Szrj {
1573*a9fa9459Szrj /* We only need to check AES/PCLMUL/SSE2AVX with AVX. */
1574*a9fa9459Szrj if (cpu.bitfield.cpuavx)
1575*a9fa9459Szrj {
1576*a9fa9459Szrj /* Check SSE2AVX. */
1577*a9fa9459Szrj if (!t->opcode_modifier.sse2avx|| sse2avx)
1578*a9fa9459Szrj {
1579*a9fa9459Szrj match |= (CPU_FLAGS_ARCH_MATCH
1580*a9fa9459Szrj | CPU_FLAGS_AVX_MATCH);
1581*a9fa9459Szrj /* Check AES. */
1582*a9fa9459Szrj if (!x.bitfield.cpuaes || cpu.bitfield.cpuaes)
1583*a9fa9459Szrj match |= CPU_FLAGS_AES_MATCH;
1584*a9fa9459Szrj /* Check PCLMUL. */
1585*a9fa9459Szrj if (!x.bitfield.cpupclmul
1586*a9fa9459Szrj || cpu.bitfield.cpupclmul)
1587*a9fa9459Szrj match |= CPU_FLAGS_PCLMUL_MATCH;
1588*a9fa9459Szrj }
1589*a9fa9459Szrj }
1590*a9fa9459Szrj else
1591*a9fa9459Szrj match |= CPU_FLAGS_ARCH_MATCH;
1592*a9fa9459Szrj }
1593*a9fa9459Szrj else if (x.bitfield.cpuavx512vl)
1594*a9fa9459Szrj {
1595*a9fa9459Szrj /* Match AVX512VL. */
1596*a9fa9459Szrj if (cpu.bitfield.cpuavx512vl)
1597*a9fa9459Szrj {
1598*a9fa9459Szrj /* Need another match. */
1599*a9fa9459Szrj cpu.bitfield.cpuavx512vl = 0;
1600*a9fa9459Szrj if (!cpu_flags_all_zero (&cpu))
1601*a9fa9459Szrj match |= CPU_FLAGS_32BIT_MATCH;
1602*a9fa9459Szrj else
1603*a9fa9459Szrj match |= CPU_FLAGS_ARCH_MATCH;
1604*a9fa9459Szrj }
1605*a9fa9459Szrj else
1606*a9fa9459Szrj match |= CPU_FLAGS_ARCH_MATCH;
1607*a9fa9459Szrj }
1608*a9fa9459Szrj else
1609*a9fa9459Szrj match |= CPU_FLAGS_32BIT_MATCH;
1610*a9fa9459Szrj }
1611*a9fa9459Szrj }
1612*a9fa9459Szrj return match;
1613*a9fa9459Szrj }
1614*a9fa9459Szrj
1615*a9fa9459Szrj static INLINE i386_operand_type
operand_type_and(i386_operand_type x,i386_operand_type y)1616*a9fa9459Szrj operand_type_and (i386_operand_type x, i386_operand_type y)
1617*a9fa9459Szrj {
1618*a9fa9459Szrj switch (ARRAY_SIZE (x.array))
1619*a9fa9459Szrj {
1620*a9fa9459Szrj case 3:
1621*a9fa9459Szrj x.array [2] &= y.array [2];
1622*a9fa9459Szrj case 2:
1623*a9fa9459Szrj x.array [1] &= y.array [1];
1624*a9fa9459Szrj case 1:
1625*a9fa9459Szrj x.array [0] &= y.array [0];
1626*a9fa9459Szrj break;
1627*a9fa9459Szrj default:
1628*a9fa9459Szrj abort ();
1629*a9fa9459Szrj }
1630*a9fa9459Szrj return x;
1631*a9fa9459Szrj }
1632*a9fa9459Szrj
1633*a9fa9459Szrj static INLINE i386_operand_type
operand_type_or(i386_operand_type x,i386_operand_type y)1634*a9fa9459Szrj operand_type_or (i386_operand_type x, i386_operand_type y)
1635*a9fa9459Szrj {
1636*a9fa9459Szrj switch (ARRAY_SIZE (x.array))
1637*a9fa9459Szrj {
1638*a9fa9459Szrj case 3:
1639*a9fa9459Szrj x.array [2] |= y.array [2];
1640*a9fa9459Szrj case 2:
1641*a9fa9459Szrj x.array [1] |= y.array [1];
1642*a9fa9459Szrj case 1:
1643*a9fa9459Szrj x.array [0] |= y.array [0];
1644*a9fa9459Szrj break;
1645*a9fa9459Szrj default:
1646*a9fa9459Szrj abort ();
1647*a9fa9459Szrj }
1648*a9fa9459Szrj return x;
1649*a9fa9459Szrj }
1650*a9fa9459Szrj
1651*a9fa9459Szrj static INLINE i386_operand_type
operand_type_xor(i386_operand_type x,i386_operand_type y)1652*a9fa9459Szrj operand_type_xor (i386_operand_type x, i386_operand_type y)
1653*a9fa9459Szrj {
1654*a9fa9459Szrj switch (ARRAY_SIZE (x.array))
1655*a9fa9459Szrj {
1656*a9fa9459Szrj case 3:
1657*a9fa9459Szrj x.array [2] ^= y.array [2];
1658*a9fa9459Szrj case 2:
1659*a9fa9459Szrj x.array [1] ^= y.array [1];
1660*a9fa9459Szrj case 1:
1661*a9fa9459Szrj x.array [0] ^= y.array [0];
1662*a9fa9459Szrj break;
1663*a9fa9459Szrj default:
1664*a9fa9459Szrj abort ();
1665*a9fa9459Szrj }
1666*a9fa9459Szrj return x;
1667*a9fa9459Szrj }
1668*a9fa9459Szrj
1669*a9fa9459Szrj static const i386_operand_type acc32 = OPERAND_TYPE_ACC32;
1670*a9fa9459Szrj static const i386_operand_type acc64 = OPERAND_TYPE_ACC64;
1671*a9fa9459Szrj static const i386_operand_type control = OPERAND_TYPE_CONTROL;
1672*a9fa9459Szrj static const i386_operand_type inoutportreg
1673*a9fa9459Szrj = OPERAND_TYPE_INOUTPORTREG;
1674*a9fa9459Szrj static const i386_operand_type reg16_inoutportreg
1675*a9fa9459Szrj = OPERAND_TYPE_REG16_INOUTPORTREG;
1676*a9fa9459Szrj static const i386_operand_type disp16 = OPERAND_TYPE_DISP16;
1677*a9fa9459Szrj static const i386_operand_type disp32 = OPERAND_TYPE_DISP32;
1678*a9fa9459Szrj static const i386_operand_type disp32s = OPERAND_TYPE_DISP32S;
1679*a9fa9459Szrj static const i386_operand_type disp16_32 = OPERAND_TYPE_DISP16_32;
1680*a9fa9459Szrj static const i386_operand_type anydisp
1681*a9fa9459Szrj = OPERAND_TYPE_ANYDISP;
1682*a9fa9459Szrj static const i386_operand_type regxmm = OPERAND_TYPE_REGXMM;
1683*a9fa9459Szrj static const i386_operand_type regymm = OPERAND_TYPE_REGYMM;
1684*a9fa9459Szrj static const i386_operand_type regzmm = OPERAND_TYPE_REGZMM;
1685*a9fa9459Szrj static const i386_operand_type regmask = OPERAND_TYPE_REGMASK;
1686*a9fa9459Szrj static const i386_operand_type imm8 = OPERAND_TYPE_IMM8;
1687*a9fa9459Szrj static const i386_operand_type imm8s = OPERAND_TYPE_IMM8S;
1688*a9fa9459Szrj static const i386_operand_type imm16 = OPERAND_TYPE_IMM16;
1689*a9fa9459Szrj static const i386_operand_type imm32 = OPERAND_TYPE_IMM32;
1690*a9fa9459Szrj static const i386_operand_type imm32s = OPERAND_TYPE_IMM32S;
1691*a9fa9459Szrj static const i386_operand_type imm64 = OPERAND_TYPE_IMM64;
1692*a9fa9459Szrj static const i386_operand_type imm16_32 = OPERAND_TYPE_IMM16_32;
1693*a9fa9459Szrj static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S;
1694*a9fa9459Szrj static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S;
1695*a9fa9459Szrj static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4;
1696*a9fa9459Szrj
1697*a9fa9459Szrj enum operand_type
1698*a9fa9459Szrj {
1699*a9fa9459Szrj reg,
1700*a9fa9459Szrj imm,
1701*a9fa9459Szrj disp,
1702*a9fa9459Szrj anymem
1703*a9fa9459Szrj };
1704*a9fa9459Szrj
1705*a9fa9459Szrj static INLINE int
operand_type_check(i386_operand_type t,enum operand_type c)1706*a9fa9459Szrj operand_type_check (i386_operand_type t, enum operand_type c)
1707*a9fa9459Szrj {
1708*a9fa9459Szrj switch (c)
1709*a9fa9459Szrj {
1710*a9fa9459Szrj case reg:
1711*a9fa9459Szrj return (t.bitfield.reg8
1712*a9fa9459Szrj || t.bitfield.reg16
1713*a9fa9459Szrj || t.bitfield.reg32
1714*a9fa9459Szrj || t.bitfield.reg64);
1715*a9fa9459Szrj
1716*a9fa9459Szrj case imm:
1717*a9fa9459Szrj return (t.bitfield.imm8
1718*a9fa9459Szrj || t.bitfield.imm8s
1719*a9fa9459Szrj || t.bitfield.imm16
1720*a9fa9459Szrj || t.bitfield.imm32
1721*a9fa9459Szrj || t.bitfield.imm32s
1722*a9fa9459Szrj || t.bitfield.imm64);
1723*a9fa9459Szrj
1724*a9fa9459Szrj case disp:
1725*a9fa9459Szrj return (t.bitfield.disp8
1726*a9fa9459Szrj || t.bitfield.disp16
1727*a9fa9459Szrj || t.bitfield.disp32
1728*a9fa9459Szrj || t.bitfield.disp32s
1729*a9fa9459Szrj || t.bitfield.disp64);
1730*a9fa9459Szrj
1731*a9fa9459Szrj case anymem:
1732*a9fa9459Szrj return (t.bitfield.disp8
1733*a9fa9459Szrj || t.bitfield.disp16
1734*a9fa9459Szrj || t.bitfield.disp32
1735*a9fa9459Szrj || t.bitfield.disp32s
1736*a9fa9459Szrj || t.bitfield.disp64
1737*a9fa9459Szrj || t.bitfield.baseindex);
1738*a9fa9459Szrj
1739*a9fa9459Szrj default:
1740*a9fa9459Szrj abort ();
1741*a9fa9459Szrj }
1742*a9fa9459Szrj
1743*a9fa9459Szrj return 0;
1744*a9fa9459Szrj }
1745*a9fa9459Szrj
1746*a9fa9459Szrj /* Return 1 if there is no conflict in 8bit/16bit/32bit/64bit on
1747*a9fa9459Szrj operand J for instruction template T. */
1748*a9fa9459Szrj
1749*a9fa9459Szrj static INLINE int
match_reg_size(const insn_template * t,unsigned int j)1750*a9fa9459Szrj match_reg_size (const insn_template *t, unsigned int j)
1751*a9fa9459Szrj {
1752*a9fa9459Szrj return !((i.types[j].bitfield.byte
1753*a9fa9459Szrj && !t->operand_types[j].bitfield.byte)
1754*a9fa9459Szrj || (i.types[j].bitfield.word
1755*a9fa9459Szrj && !t->operand_types[j].bitfield.word)
1756*a9fa9459Szrj || (i.types[j].bitfield.dword
1757*a9fa9459Szrj && !t->operand_types[j].bitfield.dword)
1758*a9fa9459Szrj || (i.types[j].bitfield.qword
1759*a9fa9459Szrj && !t->operand_types[j].bitfield.qword));
1760*a9fa9459Szrj }
1761*a9fa9459Szrj
1762*a9fa9459Szrj /* Return 1 if there is no conflict in any size on operand J for
1763*a9fa9459Szrj instruction template T. */
1764*a9fa9459Szrj
1765*a9fa9459Szrj static INLINE int
match_mem_size(const insn_template * t,unsigned int j)1766*a9fa9459Szrj match_mem_size (const insn_template *t, unsigned int j)
1767*a9fa9459Szrj {
1768*a9fa9459Szrj return (match_reg_size (t, j)
1769*a9fa9459Szrj && !((i.types[j].bitfield.unspecified
1770*a9fa9459Szrj && !i.broadcast
1771*a9fa9459Szrj && !t->operand_types[j].bitfield.unspecified)
1772*a9fa9459Szrj || (i.types[j].bitfield.fword
1773*a9fa9459Szrj && !t->operand_types[j].bitfield.fword)
1774*a9fa9459Szrj || (i.types[j].bitfield.tbyte
1775*a9fa9459Szrj && !t->operand_types[j].bitfield.tbyte)
1776*a9fa9459Szrj || (i.types[j].bitfield.xmmword
1777*a9fa9459Szrj && !t->operand_types[j].bitfield.xmmword)
1778*a9fa9459Szrj || (i.types[j].bitfield.ymmword
1779*a9fa9459Szrj && !t->operand_types[j].bitfield.ymmword)
1780*a9fa9459Szrj || (i.types[j].bitfield.zmmword
1781*a9fa9459Szrj && !t->operand_types[j].bitfield.zmmword)));
1782*a9fa9459Szrj }
1783*a9fa9459Szrj
1784*a9fa9459Szrj /* Return 1 if there is no size conflict on any operands for
1785*a9fa9459Szrj instruction template T. */
1786*a9fa9459Szrj
1787*a9fa9459Szrj static INLINE int
operand_size_match(const insn_template * t)1788*a9fa9459Szrj operand_size_match (const insn_template *t)
1789*a9fa9459Szrj {
1790*a9fa9459Szrj unsigned int j;
1791*a9fa9459Szrj int match = 1;
1792*a9fa9459Szrj
1793*a9fa9459Szrj /* Don't check jump instructions. */
1794*a9fa9459Szrj if (t->opcode_modifier.jump
1795*a9fa9459Szrj || t->opcode_modifier.jumpbyte
1796*a9fa9459Szrj || t->opcode_modifier.jumpdword
1797*a9fa9459Szrj || t->opcode_modifier.jumpintersegment)
1798*a9fa9459Szrj return match;
1799*a9fa9459Szrj
1800*a9fa9459Szrj /* Check memory and accumulator operand size. */
1801*a9fa9459Szrj for (j = 0; j < i.operands; j++)
1802*a9fa9459Szrj {
1803*a9fa9459Szrj if (t->operand_types[j].bitfield.anysize)
1804*a9fa9459Szrj continue;
1805*a9fa9459Szrj
1806*a9fa9459Szrj if (t->operand_types[j].bitfield.acc && !match_reg_size (t, j))
1807*a9fa9459Szrj {
1808*a9fa9459Szrj match = 0;
1809*a9fa9459Szrj break;
1810*a9fa9459Szrj }
1811*a9fa9459Szrj
1812*a9fa9459Szrj if (i.types[j].bitfield.mem && !match_mem_size (t, j))
1813*a9fa9459Szrj {
1814*a9fa9459Szrj match = 0;
1815*a9fa9459Szrj break;
1816*a9fa9459Szrj }
1817*a9fa9459Szrj }
1818*a9fa9459Szrj
1819*a9fa9459Szrj if (match)
1820*a9fa9459Szrj return match;
1821*a9fa9459Szrj else if (!t->opcode_modifier.d && !t->opcode_modifier.floatd)
1822*a9fa9459Szrj {
1823*a9fa9459Szrj mismatch:
1824*a9fa9459Szrj i.error = operand_size_mismatch;
1825*a9fa9459Szrj return 0;
1826*a9fa9459Szrj }
1827*a9fa9459Szrj
1828*a9fa9459Szrj /* Check reverse. */
1829*a9fa9459Szrj gas_assert (i.operands == 2);
1830*a9fa9459Szrj
1831*a9fa9459Szrj match = 1;
1832*a9fa9459Szrj for (j = 0; j < 2; j++)
1833*a9fa9459Szrj {
1834*a9fa9459Szrj if (t->operand_types[j].bitfield.acc
1835*a9fa9459Szrj && !match_reg_size (t, j ? 0 : 1))
1836*a9fa9459Szrj goto mismatch;
1837*a9fa9459Szrj
1838*a9fa9459Szrj if (i.types[j].bitfield.mem
1839*a9fa9459Szrj && !match_mem_size (t, j ? 0 : 1))
1840*a9fa9459Szrj goto mismatch;
1841*a9fa9459Szrj }
1842*a9fa9459Szrj
1843*a9fa9459Szrj return match;
1844*a9fa9459Szrj }
1845*a9fa9459Szrj
1846*a9fa9459Szrj static INLINE int
operand_type_match(i386_operand_type overlap,i386_operand_type given)1847*a9fa9459Szrj operand_type_match (i386_operand_type overlap,
1848*a9fa9459Szrj i386_operand_type given)
1849*a9fa9459Szrj {
1850*a9fa9459Szrj i386_operand_type temp = overlap;
1851*a9fa9459Szrj
1852*a9fa9459Szrj temp.bitfield.jumpabsolute = 0;
1853*a9fa9459Szrj temp.bitfield.unspecified = 0;
1854*a9fa9459Szrj temp.bitfield.byte = 0;
1855*a9fa9459Szrj temp.bitfield.word = 0;
1856*a9fa9459Szrj temp.bitfield.dword = 0;
1857*a9fa9459Szrj temp.bitfield.fword = 0;
1858*a9fa9459Szrj temp.bitfield.qword = 0;
1859*a9fa9459Szrj temp.bitfield.tbyte = 0;
1860*a9fa9459Szrj temp.bitfield.xmmword = 0;
1861*a9fa9459Szrj temp.bitfield.ymmword = 0;
1862*a9fa9459Szrj temp.bitfield.zmmword = 0;
1863*a9fa9459Szrj if (operand_type_all_zero (&temp))
1864*a9fa9459Szrj goto mismatch;
1865*a9fa9459Szrj
1866*a9fa9459Szrj if (given.bitfield.baseindex == overlap.bitfield.baseindex
1867*a9fa9459Szrj && given.bitfield.jumpabsolute == overlap.bitfield.jumpabsolute)
1868*a9fa9459Szrj return 1;
1869*a9fa9459Szrj
1870*a9fa9459Szrj mismatch:
1871*a9fa9459Szrj i.error = operand_type_mismatch;
1872*a9fa9459Szrj return 0;
1873*a9fa9459Szrj }
1874*a9fa9459Szrj
1875*a9fa9459Szrj /* If given types g0 and g1 are registers they must be of the same type
1876*a9fa9459Szrj unless the expected operand type register overlap is null.
1877*a9fa9459Szrj Note that Acc in a template matches every size of reg. */
1878*a9fa9459Szrj
1879*a9fa9459Szrj static INLINE int
operand_type_register_match(i386_operand_type m0,i386_operand_type g0,i386_operand_type t0,i386_operand_type m1,i386_operand_type g1,i386_operand_type t1)1880*a9fa9459Szrj operand_type_register_match (i386_operand_type m0,
1881*a9fa9459Szrj i386_operand_type g0,
1882*a9fa9459Szrj i386_operand_type t0,
1883*a9fa9459Szrj i386_operand_type m1,
1884*a9fa9459Szrj i386_operand_type g1,
1885*a9fa9459Szrj i386_operand_type t1)
1886*a9fa9459Szrj {
1887*a9fa9459Szrj if (!operand_type_check (g0, reg))
1888*a9fa9459Szrj return 1;
1889*a9fa9459Szrj
1890*a9fa9459Szrj if (!operand_type_check (g1, reg))
1891*a9fa9459Szrj return 1;
1892*a9fa9459Szrj
1893*a9fa9459Szrj if (g0.bitfield.reg8 == g1.bitfield.reg8
1894*a9fa9459Szrj && g0.bitfield.reg16 == g1.bitfield.reg16
1895*a9fa9459Szrj && g0.bitfield.reg32 == g1.bitfield.reg32
1896*a9fa9459Szrj && g0.bitfield.reg64 == g1.bitfield.reg64)
1897*a9fa9459Szrj return 1;
1898*a9fa9459Szrj
1899*a9fa9459Szrj if (m0.bitfield.acc)
1900*a9fa9459Szrj {
1901*a9fa9459Szrj t0.bitfield.reg8 = 1;
1902*a9fa9459Szrj t0.bitfield.reg16 = 1;
1903*a9fa9459Szrj t0.bitfield.reg32 = 1;
1904*a9fa9459Szrj t0.bitfield.reg64 = 1;
1905*a9fa9459Szrj }
1906*a9fa9459Szrj
1907*a9fa9459Szrj if (m1.bitfield.acc)
1908*a9fa9459Szrj {
1909*a9fa9459Szrj t1.bitfield.reg8 = 1;
1910*a9fa9459Szrj t1.bitfield.reg16 = 1;
1911*a9fa9459Szrj t1.bitfield.reg32 = 1;
1912*a9fa9459Szrj t1.bitfield.reg64 = 1;
1913*a9fa9459Szrj }
1914*a9fa9459Szrj
1915*a9fa9459Szrj if (!(t0.bitfield.reg8 & t1.bitfield.reg8)
1916*a9fa9459Szrj && !(t0.bitfield.reg16 & t1.bitfield.reg16)
1917*a9fa9459Szrj && !(t0.bitfield.reg32 & t1.bitfield.reg32)
1918*a9fa9459Szrj && !(t0.bitfield.reg64 & t1.bitfield.reg64))
1919*a9fa9459Szrj return 1;
1920*a9fa9459Szrj
1921*a9fa9459Szrj i.error = register_type_mismatch;
1922*a9fa9459Szrj
1923*a9fa9459Szrj return 0;
1924*a9fa9459Szrj }
1925*a9fa9459Szrj
1926*a9fa9459Szrj static INLINE unsigned int
register_number(const reg_entry * r)1927*a9fa9459Szrj register_number (const reg_entry *r)
1928*a9fa9459Szrj {
1929*a9fa9459Szrj unsigned int nr = r->reg_num;
1930*a9fa9459Szrj
1931*a9fa9459Szrj if (r->reg_flags & RegRex)
1932*a9fa9459Szrj nr += 8;
1933*a9fa9459Szrj
1934*a9fa9459Szrj if (r->reg_flags & RegVRex)
1935*a9fa9459Szrj nr += 16;
1936*a9fa9459Szrj
1937*a9fa9459Szrj return nr;
1938*a9fa9459Szrj }
1939*a9fa9459Szrj
1940*a9fa9459Szrj static INLINE unsigned int
mode_from_disp_size(i386_operand_type t)1941*a9fa9459Szrj mode_from_disp_size (i386_operand_type t)
1942*a9fa9459Szrj {
1943*a9fa9459Szrj if (t.bitfield.disp8 || t.bitfield.vec_disp8)
1944*a9fa9459Szrj return 1;
1945*a9fa9459Szrj else if (t.bitfield.disp16
1946*a9fa9459Szrj || t.bitfield.disp32
1947*a9fa9459Szrj || t.bitfield.disp32s)
1948*a9fa9459Szrj return 2;
1949*a9fa9459Szrj else
1950*a9fa9459Szrj return 0;
1951*a9fa9459Szrj }
1952*a9fa9459Szrj
1953*a9fa9459Szrj static INLINE int
fits_in_signed_byte(addressT num)1954*a9fa9459Szrj fits_in_signed_byte (addressT num)
1955*a9fa9459Szrj {
1956*a9fa9459Szrj return num + 0x80 <= 0xff;
1957*a9fa9459Szrj }
1958*a9fa9459Szrj
1959*a9fa9459Szrj static INLINE int
fits_in_unsigned_byte(addressT num)1960*a9fa9459Szrj fits_in_unsigned_byte (addressT num)
1961*a9fa9459Szrj {
1962*a9fa9459Szrj return num <= 0xff;
1963*a9fa9459Szrj }
1964*a9fa9459Szrj
1965*a9fa9459Szrj static INLINE int
fits_in_unsigned_word(addressT num)1966*a9fa9459Szrj fits_in_unsigned_word (addressT num)
1967*a9fa9459Szrj {
1968*a9fa9459Szrj return num <= 0xffff;
1969*a9fa9459Szrj }
1970*a9fa9459Szrj
1971*a9fa9459Szrj static INLINE int
fits_in_signed_word(addressT num)1972*a9fa9459Szrj fits_in_signed_word (addressT num)
1973*a9fa9459Szrj {
1974*a9fa9459Szrj return num + 0x8000 <= 0xffff;
1975*a9fa9459Szrj }
1976*a9fa9459Szrj
1977*a9fa9459Szrj static INLINE int
fits_in_signed_long(addressT num ATTRIBUTE_UNUSED)1978*a9fa9459Szrj fits_in_signed_long (addressT num ATTRIBUTE_UNUSED)
1979*a9fa9459Szrj {
1980*a9fa9459Szrj #ifndef BFD64
1981*a9fa9459Szrj return 1;
1982*a9fa9459Szrj #else
1983*a9fa9459Szrj return num + 0x80000000 <= 0xffffffff;
1984*a9fa9459Szrj #endif
1985*a9fa9459Szrj } /* fits_in_signed_long() */
1986*a9fa9459Szrj
1987*a9fa9459Szrj static INLINE int
fits_in_unsigned_long(addressT num ATTRIBUTE_UNUSED)1988*a9fa9459Szrj fits_in_unsigned_long (addressT num ATTRIBUTE_UNUSED)
1989*a9fa9459Szrj {
1990*a9fa9459Szrj #ifndef BFD64
1991*a9fa9459Szrj return 1;
1992*a9fa9459Szrj #else
1993*a9fa9459Szrj return num <= 0xffffffff;
1994*a9fa9459Szrj #endif
1995*a9fa9459Szrj } /* fits_in_unsigned_long() */
1996*a9fa9459Szrj
1997*a9fa9459Szrj static INLINE int
fits_in_vec_disp8(offsetT num)1998*a9fa9459Szrj fits_in_vec_disp8 (offsetT num)
1999*a9fa9459Szrj {
2000*a9fa9459Szrj int shift = i.memshift;
2001*a9fa9459Szrj unsigned int mask;
2002*a9fa9459Szrj
2003*a9fa9459Szrj if (shift == -1)
2004*a9fa9459Szrj abort ();
2005*a9fa9459Szrj
2006*a9fa9459Szrj mask = (1 << shift) - 1;
2007*a9fa9459Szrj
2008*a9fa9459Szrj /* Return 0 if NUM isn't properly aligned. */
2009*a9fa9459Szrj if ((num & mask))
2010*a9fa9459Szrj return 0;
2011*a9fa9459Szrj
2012*a9fa9459Szrj /* Check if NUM will fit in 8bit after shift. */
2013*a9fa9459Szrj return fits_in_signed_byte (num >> shift);
2014*a9fa9459Szrj }
2015*a9fa9459Szrj
2016*a9fa9459Szrj static INLINE int
fits_in_imm4(offsetT num)2017*a9fa9459Szrj fits_in_imm4 (offsetT num)
2018*a9fa9459Szrj {
2019*a9fa9459Szrj return (num & 0xf) == num;
2020*a9fa9459Szrj }
2021*a9fa9459Szrj
2022*a9fa9459Szrj static i386_operand_type
smallest_imm_type(offsetT num)2023*a9fa9459Szrj smallest_imm_type (offsetT num)
2024*a9fa9459Szrj {
2025*a9fa9459Szrj i386_operand_type t;
2026*a9fa9459Szrj
2027*a9fa9459Szrj operand_type_set (&t, 0);
2028*a9fa9459Szrj t.bitfield.imm64 = 1;
2029*a9fa9459Szrj
2030*a9fa9459Szrj if (cpu_arch_tune != PROCESSOR_I486 && num == 1)
2031*a9fa9459Szrj {
2032*a9fa9459Szrj /* This code is disabled on the 486 because all the Imm1 forms
2033*a9fa9459Szrj in the opcode table are slower on the i486. They're the
2034*a9fa9459Szrj versions with the implicitly specified single-position
2035*a9fa9459Szrj displacement, which has another syntax if you really want to
2036*a9fa9459Szrj use that form. */
2037*a9fa9459Szrj t.bitfield.imm1 = 1;
2038*a9fa9459Szrj t.bitfield.imm8 = 1;
2039*a9fa9459Szrj t.bitfield.imm8s = 1;
2040*a9fa9459Szrj t.bitfield.imm16 = 1;
2041*a9fa9459Szrj t.bitfield.imm32 = 1;
2042*a9fa9459Szrj t.bitfield.imm32s = 1;
2043*a9fa9459Szrj }
2044*a9fa9459Szrj else if (fits_in_signed_byte (num))
2045*a9fa9459Szrj {
2046*a9fa9459Szrj t.bitfield.imm8 = 1;
2047*a9fa9459Szrj t.bitfield.imm8s = 1;
2048*a9fa9459Szrj t.bitfield.imm16 = 1;
2049*a9fa9459Szrj t.bitfield.imm32 = 1;
2050*a9fa9459Szrj t.bitfield.imm32s = 1;
2051*a9fa9459Szrj }
2052*a9fa9459Szrj else if (fits_in_unsigned_byte (num))
2053*a9fa9459Szrj {
2054*a9fa9459Szrj t.bitfield.imm8 = 1;
2055*a9fa9459Szrj t.bitfield.imm16 = 1;
2056*a9fa9459Szrj t.bitfield.imm32 = 1;
2057*a9fa9459Szrj t.bitfield.imm32s = 1;
2058*a9fa9459Szrj }
2059*a9fa9459Szrj else if (fits_in_signed_word (num) || fits_in_unsigned_word (num))
2060*a9fa9459Szrj {
2061*a9fa9459Szrj t.bitfield.imm16 = 1;
2062*a9fa9459Szrj t.bitfield.imm32 = 1;
2063*a9fa9459Szrj t.bitfield.imm32s = 1;
2064*a9fa9459Szrj }
2065*a9fa9459Szrj else if (fits_in_signed_long (num))
2066*a9fa9459Szrj {
2067*a9fa9459Szrj t.bitfield.imm32 = 1;
2068*a9fa9459Szrj t.bitfield.imm32s = 1;
2069*a9fa9459Szrj }
2070*a9fa9459Szrj else if (fits_in_unsigned_long (num))
2071*a9fa9459Szrj t.bitfield.imm32 = 1;
2072*a9fa9459Szrj
2073*a9fa9459Szrj return t;
2074*a9fa9459Szrj }
2075*a9fa9459Szrj
2076*a9fa9459Szrj static offsetT
offset_in_range(offsetT val,int size)2077*a9fa9459Szrj offset_in_range (offsetT val, int size)
2078*a9fa9459Szrj {
2079*a9fa9459Szrj addressT mask;
2080*a9fa9459Szrj
2081*a9fa9459Szrj switch (size)
2082*a9fa9459Szrj {
2083*a9fa9459Szrj case 1: mask = ((addressT) 1 << 8) - 1; break;
2084*a9fa9459Szrj case 2: mask = ((addressT) 1 << 16) - 1; break;
2085*a9fa9459Szrj case 4: mask = ((addressT) 2 << 31) - 1; break;
2086*a9fa9459Szrj #ifdef BFD64
2087*a9fa9459Szrj case 8: mask = ((addressT) 2 << 63) - 1; break;
2088*a9fa9459Szrj #endif
2089*a9fa9459Szrj default: abort ();
2090*a9fa9459Szrj }
2091*a9fa9459Szrj
2092*a9fa9459Szrj #ifdef BFD64
2093*a9fa9459Szrj /* If BFD64, sign extend val for 32bit address mode. */
2094*a9fa9459Szrj if (flag_code != CODE_64BIT
2095*a9fa9459Szrj || i.prefix[ADDR_PREFIX])
2096*a9fa9459Szrj if ((val & ~(((addressT) 2 << 31) - 1)) == 0)
2097*a9fa9459Szrj val = (val ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
2098*a9fa9459Szrj #endif
2099*a9fa9459Szrj
2100*a9fa9459Szrj if ((val & ~mask) != 0 && (val & ~mask) != ~mask)
2101*a9fa9459Szrj {
2102*a9fa9459Szrj char buf1[40], buf2[40];
2103*a9fa9459Szrj
2104*a9fa9459Szrj sprint_value (buf1, val);
2105*a9fa9459Szrj sprint_value (buf2, val & mask);
2106*a9fa9459Szrj as_warn (_("%s shortened to %s"), buf1, buf2);
2107*a9fa9459Szrj }
2108*a9fa9459Szrj return val & mask;
2109*a9fa9459Szrj }
2110*a9fa9459Szrj
2111*a9fa9459Szrj enum PREFIX_GROUP
2112*a9fa9459Szrj {
2113*a9fa9459Szrj PREFIX_EXIST = 0,
2114*a9fa9459Szrj PREFIX_LOCK,
2115*a9fa9459Szrj PREFIX_REP,
2116*a9fa9459Szrj PREFIX_OTHER
2117*a9fa9459Szrj };
2118*a9fa9459Szrj
2119*a9fa9459Szrj /* Returns
2120*a9fa9459Szrj a. PREFIX_EXIST if attempting to add a prefix where one from the
2121*a9fa9459Szrj same class already exists.
2122*a9fa9459Szrj b. PREFIX_LOCK if lock prefix is added.
2123*a9fa9459Szrj c. PREFIX_REP if rep/repne prefix is added.
2124*a9fa9459Szrj d. PREFIX_OTHER if other prefix is added.
2125*a9fa9459Szrj */
2126*a9fa9459Szrj
2127*a9fa9459Szrj static enum PREFIX_GROUP
add_prefix(unsigned int prefix)2128*a9fa9459Szrj add_prefix (unsigned int prefix)
2129*a9fa9459Szrj {
2130*a9fa9459Szrj enum PREFIX_GROUP ret = PREFIX_OTHER;
2131*a9fa9459Szrj unsigned int q;
2132*a9fa9459Szrj
2133*a9fa9459Szrj if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16
2134*a9fa9459Szrj && flag_code == CODE_64BIT)
2135*a9fa9459Szrj {
2136*a9fa9459Szrj if ((i.prefix[REX_PREFIX] & prefix & REX_W)
2137*a9fa9459Szrj || ((i.prefix[REX_PREFIX] & (REX_R | REX_X | REX_B))
2138*a9fa9459Szrj && (prefix & (REX_R | REX_X | REX_B))))
2139*a9fa9459Szrj ret = PREFIX_EXIST;
2140*a9fa9459Szrj q = REX_PREFIX;
2141*a9fa9459Szrj }
2142*a9fa9459Szrj else
2143*a9fa9459Szrj {
2144*a9fa9459Szrj switch (prefix)
2145*a9fa9459Szrj {
2146*a9fa9459Szrj default:
2147*a9fa9459Szrj abort ();
2148*a9fa9459Szrj
2149*a9fa9459Szrj case CS_PREFIX_OPCODE:
2150*a9fa9459Szrj case DS_PREFIX_OPCODE:
2151*a9fa9459Szrj case ES_PREFIX_OPCODE:
2152*a9fa9459Szrj case FS_PREFIX_OPCODE:
2153*a9fa9459Szrj case GS_PREFIX_OPCODE:
2154*a9fa9459Szrj case SS_PREFIX_OPCODE:
2155*a9fa9459Szrj q = SEG_PREFIX;
2156*a9fa9459Szrj break;
2157*a9fa9459Szrj
2158*a9fa9459Szrj case REPNE_PREFIX_OPCODE:
2159*a9fa9459Szrj case REPE_PREFIX_OPCODE:
2160*a9fa9459Szrj q = REP_PREFIX;
2161*a9fa9459Szrj ret = PREFIX_REP;
2162*a9fa9459Szrj break;
2163*a9fa9459Szrj
2164*a9fa9459Szrj case LOCK_PREFIX_OPCODE:
2165*a9fa9459Szrj q = LOCK_PREFIX;
2166*a9fa9459Szrj ret = PREFIX_LOCK;
2167*a9fa9459Szrj break;
2168*a9fa9459Szrj
2169*a9fa9459Szrj case FWAIT_OPCODE:
2170*a9fa9459Szrj q = WAIT_PREFIX;
2171*a9fa9459Szrj break;
2172*a9fa9459Szrj
2173*a9fa9459Szrj case ADDR_PREFIX_OPCODE:
2174*a9fa9459Szrj q = ADDR_PREFIX;
2175*a9fa9459Szrj break;
2176*a9fa9459Szrj
2177*a9fa9459Szrj case DATA_PREFIX_OPCODE:
2178*a9fa9459Szrj q = DATA_PREFIX;
2179*a9fa9459Szrj break;
2180*a9fa9459Szrj }
2181*a9fa9459Szrj if (i.prefix[q] != 0)
2182*a9fa9459Szrj ret = PREFIX_EXIST;
2183*a9fa9459Szrj }
2184*a9fa9459Szrj
2185*a9fa9459Szrj if (ret)
2186*a9fa9459Szrj {
2187*a9fa9459Szrj if (!i.prefix[q])
2188*a9fa9459Szrj ++i.prefixes;
2189*a9fa9459Szrj i.prefix[q] |= prefix;
2190*a9fa9459Szrj }
2191*a9fa9459Szrj else
2192*a9fa9459Szrj as_bad (_("same type of prefix used twice"));
2193*a9fa9459Szrj
2194*a9fa9459Szrj return ret;
2195*a9fa9459Szrj }
2196*a9fa9459Szrj
2197*a9fa9459Szrj static void
update_code_flag(int value,int check)2198*a9fa9459Szrj update_code_flag (int value, int check)
2199*a9fa9459Szrj {
2200*a9fa9459Szrj PRINTF_LIKE ((*as_error));
2201*a9fa9459Szrj
2202*a9fa9459Szrj flag_code = (enum flag_code) value;
2203*a9fa9459Szrj if (flag_code == CODE_64BIT)
2204*a9fa9459Szrj {
2205*a9fa9459Szrj cpu_arch_flags.bitfield.cpu64 = 1;
2206*a9fa9459Szrj cpu_arch_flags.bitfield.cpuno64 = 0;
2207*a9fa9459Szrj }
2208*a9fa9459Szrj else
2209*a9fa9459Szrj {
2210*a9fa9459Szrj cpu_arch_flags.bitfield.cpu64 = 0;
2211*a9fa9459Szrj cpu_arch_flags.bitfield.cpuno64 = 1;
2212*a9fa9459Szrj }
2213*a9fa9459Szrj if (value == CODE_64BIT && !cpu_arch_flags.bitfield.cpulm )
2214*a9fa9459Szrj {
2215*a9fa9459Szrj if (check)
2216*a9fa9459Szrj as_error = as_fatal;
2217*a9fa9459Szrj else
2218*a9fa9459Szrj as_error = as_bad;
2219*a9fa9459Szrj (*as_error) (_("64bit mode not supported on `%s'."),
2220*a9fa9459Szrj cpu_arch_name ? cpu_arch_name : default_arch);
2221*a9fa9459Szrj }
2222*a9fa9459Szrj if (value == CODE_32BIT && !cpu_arch_flags.bitfield.cpui386)
2223*a9fa9459Szrj {
2224*a9fa9459Szrj if (check)
2225*a9fa9459Szrj as_error = as_fatal;
2226*a9fa9459Szrj else
2227*a9fa9459Szrj as_error = as_bad;
2228*a9fa9459Szrj (*as_error) (_("32bit mode not supported on `%s'."),
2229*a9fa9459Szrj cpu_arch_name ? cpu_arch_name : default_arch);
2230*a9fa9459Szrj }
2231*a9fa9459Szrj stackop_size = '\0';
2232*a9fa9459Szrj }
2233*a9fa9459Szrj
2234*a9fa9459Szrj static void
set_code_flag(int value)2235*a9fa9459Szrj set_code_flag (int value)
2236*a9fa9459Szrj {
2237*a9fa9459Szrj update_code_flag (value, 0);
2238*a9fa9459Szrj }
2239*a9fa9459Szrj
2240*a9fa9459Szrj static void
set_16bit_gcc_code_flag(int new_code_flag)2241*a9fa9459Szrj set_16bit_gcc_code_flag (int new_code_flag)
2242*a9fa9459Szrj {
2243*a9fa9459Szrj flag_code = (enum flag_code) new_code_flag;
2244*a9fa9459Szrj if (flag_code != CODE_16BIT)
2245*a9fa9459Szrj abort ();
2246*a9fa9459Szrj cpu_arch_flags.bitfield.cpu64 = 0;
2247*a9fa9459Szrj cpu_arch_flags.bitfield.cpuno64 = 1;
2248*a9fa9459Szrj stackop_size = LONG_MNEM_SUFFIX;
2249*a9fa9459Szrj }
2250*a9fa9459Szrj
2251*a9fa9459Szrj static void
set_intel_syntax(int syntax_flag)2252*a9fa9459Szrj set_intel_syntax (int syntax_flag)
2253*a9fa9459Szrj {
2254*a9fa9459Szrj /* Find out if register prefixing is specified. */
2255*a9fa9459Szrj int ask_naked_reg = 0;
2256*a9fa9459Szrj
2257*a9fa9459Szrj SKIP_WHITESPACE ();
2258*a9fa9459Szrj if (!is_end_of_line[(unsigned char) *input_line_pointer])
2259*a9fa9459Szrj {
2260*a9fa9459Szrj char *string;
2261*a9fa9459Szrj int e = get_symbol_name (&string);
2262*a9fa9459Szrj
2263*a9fa9459Szrj if (strcmp (string, "prefix") == 0)
2264*a9fa9459Szrj ask_naked_reg = 1;
2265*a9fa9459Szrj else if (strcmp (string, "noprefix") == 0)
2266*a9fa9459Szrj ask_naked_reg = -1;
2267*a9fa9459Szrj else
2268*a9fa9459Szrj as_bad (_("bad argument to syntax directive."));
2269*a9fa9459Szrj (void) restore_line_pointer (e);
2270*a9fa9459Szrj }
2271*a9fa9459Szrj demand_empty_rest_of_line ();
2272*a9fa9459Szrj
2273*a9fa9459Szrj intel_syntax = syntax_flag;
2274*a9fa9459Szrj
2275*a9fa9459Szrj if (ask_naked_reg == 0)
2276*a9fa9459Szrj allow_naked_reg = (intel_syntax
2277*a9fa9459Szrj && (bfd_get_symbol_leading_char (stdoutput) != '\0'));
2278*a9fa9459Szrj else
2279*a9fa9459Szrj allow_naked_reg = (ask_naked_reg < 0);
2280*a9fa9459Szrj
2281*a9fa9459Szrj expr_set_rank (O_full_ptr, syntax_flag ? 10 : 0);
2282*a9fa9459Szrj
2283*a9fa9459Szrj identifier_chars['%'] = intel_syntax && allow_naked_reg ? '%' : 0;
2284*a9fa9459Szrj identifier_chars['$'] = intel_syntax ? '$' : 0;
2285*a9fa9459Szrj register_prefix = allow_naked_reg ? "" : "%";
2286*a9fa9459Szrj }
2287*a9fa9459Szrj
2288*a9fa9459Szrj static void
set_intel_mnemonic(int mnemonic_flag)2289*a9fa9459Szrj set_intel_mnemonic (int mnemonic_flag)
2290*a9fa9459Szrj {
2291*a9fa9459Szrj intel_mnemonic = mnemonic_flag;
2292*a9fa9459Szrj }
2293*a9fa9459Szrj
2294*a9fa9459Szrj static void
set_allow_index_reg(int flag)2295*a9fa9459Szrj set_allow_index_reg (int flag)
2296*a9fa9459Szrj {
2297*a9fa9459Szrj allow_index_reg = flag;
2298*a9fa9459Szrj }
2299*a9fa9459Szrj
2300*a9fa9459Szrj static void
set_check(int what)2301*a9fa9459Szrj set_check (int what)
2302*a9fa9459Szrj {
2303*a9fa9459Szrj enum check_kind *kind;
2304*a9fa9459Szrj const char *str;
2305*a9fa9459Szrj
2306*a9fa9459Szrj if (what)
2307*a9fa9459Szrj {
2308*a9fa9459Szrj kind = &operand_check;
2309*a9fa9459Szrj str = "operand";
2310*a9fa9459Szrj }
2311*a9fa9459Szrj else
2312*a9fa9459Szrj {
2313*a9fa9459Szrj kind = &sse_check;
2314*a9fa9459Szrj str = "sse";
2315*a9fa9459Szrj }
2316*a9fa9459Szrj
2317*a9fa9459Szrj SKIP_WHITESPACE ();
2318*a9fa9459Szrj
2319*a9fa9459Szrj if (!is_end_of_line[(unsigned char) *input_line_pointer])
2320*a9fa9459Szrj {
2321*a9fa9459Szrj char *string;
2322*a9fa9459Szrj int e = get_symbol_name (&string);
2323*a9fa9459Szrj
2324*a9fa9459Szrj if (strcmp (string, "none") == 0)
2325*a9fa9459Szrj *kind = check_none;
2326*a9fa9459Szrj else if (strcmp (string, "warning") == 0)
2327*a9fa9459Szrj *kind = check_warning;
2328*a9fa9459Szrj else if (strcmp (string, "error") == 0)
2329*a9fa9459Szrj *kind = check_error;
2330*a9fa9459Szrj else
2331*a9fa9459Szrj as_bad (_("bad argument to %s_check directive."), str);
2332*a9fa9459Szrj (void) restore_line_pointer (e);
2333*a9fa9459Szrj }
2334*a9fa9459Szrj else
2335*a9fa9459Szrj as_bad (_("missing argument for %s_check directive"), str);
2336*a9fa9459Szrj
2337*a9fa9459Szrj demand_empty_rest_of_line ();
2338*a9fa9459Szrj }
2339*a9fa9459Szrj
2340*a9fa9459Szrj static void
check_cpu_arch_compatible(const char * name ATTRIBUTE_UNUSED,i386_cpu_flags new_flag ATTRIBUTE_UNUSED)2341*a9fa9459Szrj check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED,
2342*a9fa9459Szrj i386_cpu_flags new_flag ATTRIBUTE_UNUSED)
2343*a9fa9459Szrj {
2344*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
2345*a9fa9459Szrj static const char *arch;
2346*a9fa9459Szrj
2347*a9fa9459Szrj /* Intel LIOM is only supported on ELF. */
2348*a9fa9459Szrj if (!IS_ELF)
2349*a9fa9459Szrj return;
2350*a9fa9459Szrj
2351*a9fa9459Szrj if (!arch)
2352*a9fa9459Szrj {
2353*a9fa9459Szrj /* Use cpu_arch_name if it is set in md_parse_option. Otherwise
2354*a9fa9459Szrj use default_arch. */
2355*a9fa9459Szrj arch = cpu_arch_name;
2356*a9fa9459Szrj if (!arch)
2357*a9fa9459Szrj arch = default_arch;
2358*a9fa9459Szrj }
2359*a9fa9459Szrj
2360*a9fa9459Szrj /* If we are targeting Intel MCU, we must enable it. */
2361*a9fa9459Szrj if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_IAMCU
2362*a9fa9459Szrj || new_flag.bitfield.cpuiamcu)
2363*a9fa9459Szrj return;
2364*a9fa9459Szrj
2365*a9fa9459Szrj /* If we are targeting Intel L1OM, we must enable it. */
2366*a9fa9459Szrj if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_L1OM
2367*a9fa9459Szrj || new_flag.bitfield.cpul1om)
2368*a9fa9459Szrj return;
2369*a9fa9459Szrj
2370*a9fa9459Szrj /* If we are targeting Intel K1OM, we must enable it. */
2371*a9fa9459Szrj if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_K1OM
2372*a9fa9459Szrj || new_flag.bitfield.cpuk1om)
2373*a9fa9459Szrj return;
2374*a9fa9459Szrj
2375*a9fa9459Szrj as_bad (_("`%s' is not supported on `%s'"), name, arch);
2376*a9fa9459Szrj #endif
2377*a9fa9459Szrj }
2378*a9fa9459Szrj
2379*a9fa9459Szrj static void
set_cpu_arch(int dummy ATTRIBUTE_UNUSED)2380*a9fa9459Szrj set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
2381*a9fa9459Szrj {
2382*a9fa9459Szrj SKIP_WHITESPACE ();
2383*a9fa9459Szrj
2384*a9fa9459Szrj if (!is_end_of_line[(unsigned char) *input_line_pointer])
2385*a9fa9459Szrj {
2386*a9fa9459Szrj char *string;
2387*a9fa9459Szrj int e = get_symbol_name (&string);
2388*a9fa9459Szrj unsigned int j;
2389*a9fa9459Szrj i386_cpu_flags flags;
2390*a9fa9459Szrj
2391*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_arch); j++)
2392*a9fa9459Szrj {
2393*a9fa9459Szrj if (strcmp (string, cpu_arch[j].name) == 0)
2394*a9fa9459Szrj {
2395*a9fa9459Szrj check_cpu_arch_compatible (string, cpu_arch[j].flags);
2396*a9fa9459Szrj
2397*a9fa9459Szrj if (*string != '.')
2398*a9fa9459Szrj {
2399*a9fa9459Szrj cpu_arch_name = cpu_arch[j].name;
2400*a9fa9459Szrj cpu_sub_arch_name = NULL;
2401*a9fa9459Szrj cpu_arch_flags = cpu_arch[j].flags;
2402*a9fa9459Szrj if (flag_code == CODE_64BIT)
2403*a9fa9459Szrj {
2404*a9fa9459Szrj cpu_arch_flags.bitfield.cpu64 = 1;
2405*a9fa9459Szrj cpu_arch_flags.bitfield.cpuno64 = 0;
2406*a9fa9459Szrj }
2407*a9fa9459Szrj else
2408*a9fa9459Szrj {
2409*a9fa9459Szrj cpu_arch_flags.bitfield.cpu64 = 0;
2410*a9fa9459Szrj cpu_arch_flags.bitfield.cpuno64 = 1;
2411*a9fa9459Szrj }
2412*a9fa9459Szrj cpu_arch_isa = cpu_arch[j].type;
2413*a9fa9459Szrj cpu_arch_isa_flags = cpu_arch[j].flags;
2414*a9fa9459Szrj if (!cpu_arch_tune_set)
2415*a9fa9459Szrj {
2416*a9fa9459Szrj cpu_arch_tune = cpu_arch_isa;
2417*a9fa9459Szrj cpu_arch_tune_flags = cpu_arch_isa_flags;
2418*a9fa9459Szrj }
2419*a9fa9459Szrj break;
2420*a9fa9459Szrj }
2421*a9fa9459Szrj
2422*a9fa9459Szrj flags = cpu_flags_or (cpu_arch_flags,
2423*a9fa9459Szrj cpu_arch[j].flags);
2424*a9fa9459Szrj
2425*a9fa9459Szrj if (!valid_iamcu_cpu_flags (&flags))
2426*a9fa9459Szrj as_fatal (_("`%s' isn't valid for Intel MCU"),
2427*a9fa9459Szrj cpu_arch[j].name);
2428*a9fa9459Szrj else if (!cpu_flags_equal (&flags, &cpu_arch_flags))
2429*a9fa9459Szrj {
2430*a9fa9459Szrj if (cpu_sub_arch_name)
2431*a9fa9459Szrj {
2432*a9fa9459Szrj char *name = cpu_sub_arch_name;
2433*a9fa9459Szrj cpu_sub_arch_name = concat (name,
2434*a9fa9459Szrj cpu_arch[j].name,
2435*a9fa9459Szrj (const char *) NULL);
2436*a9fa9459Szrj free (name);
2437*a9fa9459Szrj }
2438*a9fa9459Szrj else
2439*a9fa9459Szrj cpu_sub_arch_name = xstrdup (cpu_arch[j].name);
2440*a9fa9459Szrj cpu_arch_flags = flags;
2441*a9fa9459Szrj cpu_arch_isa_flags = flags;
2442*a9fa9459Szrj }
2443*a9fa9459Szrj (void) restore_line_pointer (e);
2444*a9fa9459Szrj demand_empty_rest_of_line ();
2445*a9fa9459Szrj return;
2446*a9fa9459Szrj }
2447*a9fa9459Szrj }
2448*a9fa9459Szrj
2449*a9fa9459Szrj if (*string == '.' && j >= ARRAY_SIZE (cpu_arch))
2450*a9fa9459Szrj {
2451*a9fa9459Szrj /* Disable an ISA entension. */
2452*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_noarch); j++)
2453*a9fa9459Szrj if (strcmp (string + 1, cpu_noarch [j].name) == 0)
2454*a9fa9459Szrj {
2455*a9fa9459Szrj flags = cpu_flags_and_not (cpu_arch_flags,
2456*a9fa9459Szrj cpu_noarch[j].flags);
2457*a9fa9459Szrj if (!cpu_flags_equal (&flags, &cpu_arch_flags))
2458*a9fa9459Szrj {
2459*a9fa9459Szrj if (cpu_sub_arch_name)
2460*a9fa9459Szrj {
2461*a9fa9459Szrj char *name = cpu_sub_arch_name;
2462*a9fa9459Szrj cpu_sub_arch_name = concat (name, string,
2463*a9fa9459Szrj (const char *) NULL);
2464*a9fa9459Szrj free (name);
2465*a9fa9459Szrj }
2466*a9fa9459Szrj else
2467*a9fa9459Szrj cpu_sub_arch_name = xstrdup (string);
2468*a9fa9459Szrj cpu_arch_flags = flags;
2469*a9fa9459Szrj cpu_arch_isa_flags = flags;
2470*a9fa9459Szrj }
2471*a9fa9459Szrj (void) restore_line_pointer (e);
2472*a9fa9459Szrj demand_empty_rest_of_line ();
2473*a9fa9459Szrj return;
2474*a9fa9459Szrj }
2475*a9fa9459Szrj
2476*a9fa9459Szrj j = ARRAY_SIZE (cpu_arch);
2477*a9fa9459Szrj }
2478*a9fa9459Szrj
2479*a9fa9459Szrj if (j >= ARRAY_SIZE (cpu_arch))
2480*a9fa9459Szrj as_bad (_("no such architecture: `%s'"), string);
2481*a9fa9459Szrj
2482*a9fa9459Szrj *input_line_pointer = e;
2483*a9fa9459Szrj }
2484*a9fa9459Szrj else
2485*a9fa9459Szrj as_bad (_("missing cpu architecture"));
2486*a9fa9459Szrj
2487*a9fa9459Szrj no_cond_jump_promotion = 0;
2488*a9fa9459Szrj if (*input_line_pointer == ','
2489*a9fa9459Szrj && !is_end_of_line[(unsigned char) input_line_pointer[1]])
2490*a9fa9459Szrj {
2491*a9fa9459Szrj char *string;
2492*a9fa9459Szrj char e;
2493*a9fa9459Szrj
2494*a9fa9459Szrj ++input_line_pointer;
2495*a9fa9459Szrj e = get_symbol_name (&string);
2496*a9fa9459Szrj
2497*a9fa9459Szrj if (strcmp (string, "nojumps") == 0)
2498*a9fa9459Szrj no_cond_jump_promotion = 1;
2499*a9fa9459Szrj else if (strcmp (string, "jumps") == 0)
2500*a9fa9459Szrj ;
2501*a9fa9459Szrj else
2502*a9fa9459Szrj as_bad (_("no such architecture modifier: `%s'"), string);
2503*a9fa9459Szrj
2504*a9fa9459Szrj (void) restore_line_pointer (e);
2505*a9fa9459Szrj }
2506*a9fa9459Szrj
2507*a9fa9459Szrj demand_empty_rest_of_line ();
2508*a9fa9459Szrj }
2509*a9fa9459Szrj
2510*a9fa9459Szrj enum bfd_architecture
i386_arch(void)2511*a9fa9459Szrj i386_arch (void)
2512*a9fa9459Szrj {
2513*a9fa9459Szrj if (cpu_arch_isa == PROCESSOR_L1OM)
2514*a9fa9459Szrj {
2515*a9fa9459Szrj if (OUTPUT_FLAVOR != bfd_target_elf_flavour
2516*a9fa9459Szrj || flag_code != CODE_64BIT)
2517*a9fa9459Szrj as_fatal (_("Intel L1OM is 64bit ELF only"));
2518*a9fa9459Szrj return bfd_arch_l1om;
2519*a9fa9459Szrj }
2520*a9fa9459Szrj else if (cpu_arch_isa == PROCESSOR_K1OM)
2521*a9fa9459Szrj {
2522*a9fa9459Szrj if (OUTPUT_FLAVOR != bfd_target_elf_flavour
2523*a9fa9459Szrj || flag_code != CODE_64BIT)
2524*a9fa9459Szrj as_fatal (_("Intel K1OM is 64bit ELF only"));
2525*a9fa9459Szrj return bfd_arch_k1om;
2526*a9fa9459Szrj }
2527*a9fa9459Szrj else if (cpu_arch_isa == PROCESSOR_IAMCU)
2528*a9fa9459Szrj {
2529*a9fa9459Szrj if (OUTPUT_FLAVOR != bfd_target_elf_flavour
2530*a9fa9459Szrj || flag_code == CODE_64BIT)
2531*a9fa9459Szrj as_fatal (_("Intel MCU is 32bit ELF only"));
2532*a9fa9459Szrj return bfd_arch_iamcu;
2533*a9fa9459Szrj }
2534*a9fa9459Szrj else
2535*a9fa9459Szrj return bfd_arch_i386;
2536*a9fa9459Szrj }
2537*a9fa9459Szrj
2538*a9fa9459Szrj unsigned long
i386_mach(void)2539*a9fa9459Szrj i386_mach (void)
2540*a9fa9459Szrj {
2541*a9fa9459Szrj if (!strncmp (default_arch, "x86_64", 6))
2542*a9fa9459Szrj {
2543*a9fa9459Szrj if (cpu_arch_isa == PROCESSOR_L1OM)
2544*a9fa9459Szrj {
2545*a9fa9459Szrj if (OUTPUT_FLAVOR != bfd_target_elf_flavour
2546*a9fa9459Szrj || default_arch[6] != '\0')
2547*a9fa9459Szrj as_fatal (_("Intel L1OM is 64bit ELF only"));
2548*a9fa9459Szrj return bfd_mach_l1om;
2549*a9fa9459Szrj }
2550*a9fa9459Szrj else if (cpu_arch_isa == PROCESSOR_K1OM)
2551*a9fa9459Szrj {
2552*a9fa9459Szrj if (OUTPUT_FLAVOR != bfd_target_elf_flavour
2553*a9fa9459Szrj || default_arch[6] != '\0')
2554*a9fa9459Szrj as_fatal (_("Intel K1OM is 64bit ELF only"));
2555*a9fa9459Szrj return bfd_mach_k1om;
2556*a9fa9459Szrj }
2557*a9fa9459Szrj else if (default_arch[6] == '\0')
2558*a9fa9459Szrj return bfd_mach_x86_64;
2559*a9fa9459Szrj else
2560*a9fa9459Szrj return bfd_mach_x64_32;
2561*a9fa9459Szrj }
2562*a9fa9459Szrj else if (!strcmp (default_arch, "i386")
2563*a9fa9459Szrj || !strcmp (default_arch, "iamcu"))
2564*a9fa9459Szrj {
2565*a9fa9459Szrj if (cpu_arch_isa == PROCESSOR_IAMCU)
2566*a9fa9459Szrj {
2567*a9fa9459Szrj if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
2568*a9fa9459Szrj as_fatal (_("Intel MCU is 32bit ELF only"));
2569*a9fa9459Szrj return bfd_mach_i386_iamcu;
2570*a9fa9459Szrj }
2571*a9fa9459Szrj else
2572*a9fa9459Szrj return bfd_mach_i386_i386;
2573*a9fa9459Szrj }
2574*a9fa9459Szrj else
2575*a9fa9459Szrj as_fatal (_("unknown architecture"));
2576*a9fa9459Szrj }
2577*a9fa9459Szrj
2578*a9fa9459Szrj void
md_begin(void)2579*a9fa9459Szrj md_begin (void)
2580*a9fa9459Szrj {
2581*a9fa9459Szrj const char *hash_err;
2582*a9fa9459Szrj
2583*a9fa9459Szrj /* Initialize op_hash hash table. */
2584*a9fa9459Szrj op_hash = hash_new ();
2585*a9fa9459Szrj
2586*a9fa9459Szrj {
2587*a9fa9459Szrj const insn_template *optab;
2588*a9fa9459Szrj templates *core_optab;
2589*a9fa9459Szrj
2590*a9fa9459Szrj /* Setup for loop. */
2591*a9fa9459Szrj optab = i386_optab;
2592*a9fa9459Szrj core_optab = XNEW (templates);
2593*a9fa9459Szrj core_optab->start = optab;
2594*a9fa9459Szrj
2595*a9fa9459Szrj while (1)
2596*a9fa9459Szrj {
2597*a9fa9459Szrj ++optab;
2598*a9fa9459Szrj if (optab->name == NULL
2599*a9fa9459Szrj || strcmp (optab->name, (optab - 1)->name) != 0)
2600*a9fa9459Szrj {
2601*a9fa9459Szrj /* different name --> ship out current template list;
2602*a9fa9459Szrj add to hash table; & begin anew. */
2603*a9fa9459Szrj core_optab->end = optab;
2604*a9fa9459Szrj hash_err = hash_insert (op_hash,
2605*a9fa9459Szrj (optab - 1)->name,
2606*a9fa9459Szrj (void *) core_optab);
2607*a9fa9459Szrj if (hash_err)
2608*a9fa9459Szrj {
2609*a9fa9459Szrj as_fatal (_("can't hash %s: %s"),
2610*a9fa9459Szrj (optab - 1)->name,
2611*a9fa9459Szrj hash_err);
2612*a9fa9459Szrj }
2613*a9fa9459Szrj if (optab->name == NULL)
2614*a9fa9459Szrj break;
2615*a9fa9459Szrj core_optab = XNEW (templates);
2616*a9fa9459Szrj core_optab->start = optab;
2617*a9fa9459Szrj }
2618*a9fa9459Szrj }
2619*a9fa9459Szrj }
2620*a9fa9459Szrj
2621*a9fa9459Szrj /* Initialize reg_hash hash table. */
2622*a9fa9459Szrj reg_hash = hash_new ();
2623*a9fa9459Szrj {
2624*a9fa9459Szrj const reg_entry *regtab;
2625*a9fa9459Szrj unsigned int regtab_size = i386_regtab_size;
2626*a9fa9459Szrj
2627*a9fa9459Szrj for (regtab = i386_regtab; regtab_size--; regtab++)
2628*a9fa9459Szrj {
2629*a9fa9459Szrj hash_err = hash_insert (reg_hash, regtab->reg_name, (void *) regtab);
2630*a9fa9459Szrj if (hash_err)
2631*a9fa9459Szrj as_fatal (_("can't hash %s: %s"),
2632*a9fa9459Szrj regtab->reg_name,
2633*a9fa9459Szrj hash_err);
2634*a9fa9459Szrj }
2635*a9fa9459Szrj }
2636*a9fa9459Szrj
2637*a9fa9459Szrj /* Fill in lexical tables: mnemonic_chars, operand_chars. */
2638*a9fa9459Szrj {
2639*a9fa9459Szrj int c;
2640*a9fa9459Szrj char *p;
2641*a9fa9459Szrj
2642*a9fa9459Szrj for (c = 0; c < 256; c++)
2643*a9fa9459Szrj {
2644*a9fa9459Szrj if (ISDIGIT (c))
2645*a9fa9459Szrj {
2646*a9fa9459Szrj digit_chars[c] = c;
2647*a9fa9459Szrj mnemonic_chars[c] = c;
2648*a9fa9459Szrj register_chars[c] = c;
2649*a9fa9459Szrj operand_chars[c] = c;
2650*a9fa9459Szrj }
2651*a9fa9459Szrj else if (ISLOWER (c))
2652*a9fa9459Szrj {
2653*a9fa9459Szrj mnemonic_chars[c] = c;
2654*a9fa9459Szrj register_chars[c] = c;
2655*a9fa9459Szrj operand_chars[c] = c;
2656*a9fa9459Szrj }
2657*a9fa9459Szrj else if (ISUPPER (c))
2658*a9fa9459Szrj {
2659*a9fa9459Szrj mnemonic_chars[c] = TOLOWER (c);
2660*a9fa9459Szrj register_chars[c] = mnemonic_chars[c];
2661*a9fa9459Szrj operand_chars[c] = c;
2662*a9fa9459Szrj }
2663*a9fa9459Szrj else if (c == '{' || c == '}')
2664*a9fa9459Szrj operand_chars[c] = c;
2665*a9fa9459Szrj
2666*a9fa9459Szrj if (ISALPHA (c) || ISDIGIT (c))
2667*a9fa9459Szrj identifier_chars[c] = c;
2668*a9fa9459Szrj else if (c >= 128)
2669*a9fa9459Szrj {
2670*a9fa9459Szrj identifier_chars[c] = c;
2671*a9fa9459Szrj operand_chars[c] = c;
2672*a9fa9459Szrj }
2673*a9fa9459Szrj }
2674*a9fa9459Szrj
2675*a9fa9459Szrj #ifdef LEX_AT
2676*a9fa9459Szrj identifier_chars['@'] = '@';
2677*a9fa9459Szrj #endif
2678*a9fa9459Szrj #ifdef LEX_QM
2679*a9fa9459Szrj identifier_chars['?'] = '?';
2680*a9fa9459Szrj operand_chars['?'] = '?';
2681*a9fa9459Szrj #endif
2682*a9fa9459Szrj digit_chars['-'] = '-';
2683*a9fa9459Szrj mnemonic_chars['_'] = '_';
2684*a9fa9459Szrj mnemonic_chars['-'] = '-';
2685*a9fa9459Szrj mnemonic_chars['.'] = '.';
2686*a9fa9459Szrj identifier_chars['_'] = '_';
2687*a9fa9459Szrj identifier_chars['.'] = '.';
2688*a9fa9459Szrj
2689*a9fa9459Szrj for (p = operand_special_chars; *p != '\0'; p++)
2690*a9fa9459Szrj operand_chars[(unsigned char) *p] = *p;
2691*a9fa9459Szrj }
2692*a9fa9459Szrj
2693*a9fa9459Szrj if (flag_code == CODE_64BIT)
2694*a9fa9459Szrj {
2695*a9fa9459Szrj #if defined (OBJ_COFF) && defined (TE_PE)
2696*a9fa9459Szrj x86_dwarf2_return_column = (OUTPUT_FLAVOR == bfd_target_coff_flavour
2697*a9fa9459Szrj ? 32 : 16);
2698*a9fa9459Szrj #else
2699*a9fa9459Szrj x86_dwarf2_return_column = 16;
2700*a9fa9459Szrj #endif
2701*a9fa9459Szrj x86_cie_data_alignment = -8;
2702*a9fa9459Szrj }
2703*a9fa9459Szrj else
2704*a9fa9459Szrj {
2705*a9fa9459Szrj x86_dwarf2_return_column = 8;
2706*a9fa9459Szrj x86_cie_data_alignment = -4;
2707*a9fa9459Szrj }
2708*a9fa9459Szrj }
2709*a9fa9459Szrj
2710*a9fa9459Szrj void
i386_print_statistics(FILE * file)2711*a9fa9459Szrj i386_print_statistics (FILE *file)
2712*a9fa9459Szrj {
2713*a9fa9459Szrj hash_print_statistics (file, "i386 opcode", op_hash);
2714*a9fa9459Szrj hash_print_statistics (file, "i386 register", reg_hash);
2715*a9fa9459Szrj }
2716*a9fa9459Szrj
2717*a9fa9459Szrj #ifdef DEBUG386
2718*a9fa9459Szrj
2719*a9fa9459Szrj /* Debugging routines for md_assemble. */
2720*a9fa9459Szrj static void pte (insn_template *);
2721*a9fa9459Szrj static void pt (i386_operand_type);
2722*a9fa9459Szrj static void pe (expressionS *);
2723*a9fa9459Szrj static void ps (symbolS *);
2724*a9fa9459Szrj
2725*a9fa9459Szrj static void
pi(char * line,i386_insn * x)2726*a9fa9459Szrj pi (char *line, i386_insn *x)
2727*a9fa9459Szrj {
2728*a9fa9459Szrj unsigned int j;
2729*a9fa9459Szrj
2730*a9fa9459Szrj fprintf (stdout, "%s: template ", line);
2731*a9fa9459Szrj pte (&x->tm);
2732*a9fa9459Szrj fprintf (stdout, " address: base %s index %s scale %x\n",
2733*a9fa9459Szrj x->base_reg ? x->base_reg->reg_name : "none",
2734*a9fa9459Szrj x->index_reg ? x->index_reg->reg_name : "none",
2735*a9fa9459Szrj x->log2_scale_factor);
2736*a9fa9459Szrj fprintf (stdout, " modrm: mode %x reg %x reg/mem %x\n",
2737*a9fa9459Szrj x->rm.mode, x->rm.reg, x->rm.regmem);
2738*a9fa9459Szrj fprintf (stdout, " sib: base %x index %x scale %x\n",
2739*a9fa9459Szrj x->sib.base, x->sib.index, x->sib.scale);
2740*a9fa9459Szrj fprintf (stdout, " rex: 64bit %x extX %x extY %x extZ %x\n",
2741*a9fa9459Szrj (x->rex & REX_W) != 0,
2742*a9fa9459Szrj (x->rex & REX_R) != 0,
2743*a9fa9459Szrj (x->rex & REX_X) != 0,
2744*a9fa9459Szrj (x->rex & REX_B) != 0);
2745*a9fa9459Szrj for (j = 0; j < x->operands; j++)
2746*a9fa9459Szrj {
2747*a9fa9459Szrj fprintf (stdout, " #%d: ", j + 1);
2748*a9fa9459Szrj pt (x->types[j]);
2749*a9fa9459Szrj fprintf (stdout, "\n");
2750*a9fa9459Szrj if (x->types[j].bitfield.reg8
2751*a9fa9459Szrj || x->types[j].bitfield.reg16
2752*a9fa9459Szrj || x->types[j].bitfield.reg32
2753*a9fa9459Szrj || x->types[j].bitfield.reg64
2754*a9fa9459Szrj || x->types[j].bitfield.regmmx
2755*a9fa9459Szrj || x->types[j].bitfield.regxmm
2756*a9fa9459Szrj || x->types[j].bitfield.regymm
2757*a9fa9459Szrj || x->types[j].bitfield.regzmm
2758*a9fa9459Szrj || x->types[j].bitfield.sreg2
2759*a9fa9459Szrj || x->types[j].bitfield.sreg3
2760*a9fa9459Szrj || x->types[j].bitfield.control
2761*a9fa9459Szrj || x->types[j].bitfield.debug
2762*a9fa9459Szrj || x->types[j].bitfield.test)
2763*a9fa9459Szrj fprintf (stdout, "%s\n", x->op[j].regs->reg_name);
2764*a9fa9459Szrj if (operand_type_check (x->types[j], imm))
2765*a9fa9459Szrj pe (x->op[j].imms);
2766*a9fa9459Szrj if (operand_type_check (x->types[j], disp))
2767*a9fa9459Szrj pe (x->op[j].disps);
2768*a9fa9459Szrj }
2769*a9fa9459Szrj }
2770*a9fa9459Szrj
2771*a9fa9459Szrj static void
pte(insn_template * t)2772*a9fa9459Szrj pte (insn_template *t)
2773*a9fa9459Szrj {
2774*a9fa9459Szrj unsigned int j;
2775*a9fa9459Szrj fprintf (stdout, " %d operands ", t->operands);
2776*a9fa9459Szrj fprintf (stdout, "opcode %x ", t->base_opcode);
2777*a9fa9459Szrj if (t->extension_opcode != None)
2778*a9fa9459Szrj fprintf (stdout, "ext %x ", t->extension_opcode);
2779*a9fa9459Szrj if (t->opcode_modifier.d)
2780*a9fa9459Szrj fprintf (stdout, "D");
2781*a9fa9459Szrj if (t->opcode_modifier.w)
2782*a9fa9459Szrj fprintf (stdout, "W");
2783*a9fa9459Szrj fprintf (stdout, "\n");
2784*a9fa9459Szrj for (j = 0; j < t->operands; j++)
2785*a9fa9459Szrj {
2786*a9fa9459Szrj fprintf (stdout, " #%d type ", j + 1);
2787*a9fa9459Szrj pt (t->operand_types[j]);
2788*a9fa9459Szrj fprintf (stdout, "\n");
2789*a9fa9459Szrj }
2790*a9fa9459Szrj }
2791*a9fa9459Szrj
2792*a9fa9459Szrj static void
pe(expressionS * e)2793*a9fa9459Szrj pe (expressionS *e)
2794*a9fa9459Szrj {
2795*a9fa9459Szrj fprintf (stdout, " operation %d\n", e->X_op);
2796*a9fa9459Szrj fprintf (stdout, " add_number %ld (%lx)\n",
2797*a9fa9459Szrj (long) e->X_add_number, (long) e->X_add_number);
2798*a9fa9459Szrj if (e->X_add_symbol)
2799*a9fa9459Szrj {
2800*a9fa9459Szrj fprintf (stdout, " add_symbol ");
2801*a9fa9459Szrj ps (e->X_add_symbol);
2802*a9fa9459Szrj fprintf (stdout, "\n");
2803*a9fa9459Szrj }
2804*a9fa9459Szrj if (e->X_op_symbol)
2805*a9fa9459Szrj {
2806*a9fa9459Szrj fprintf (stdout, " op_symbol ");
2807*a9fa9459Szrj ps (e->X_op_symbol);
2808*a9fa9459Szrj fprintf (stdout, "\n");
2809*a9fa9459Szrj }
2810*a9fa9459Szrj }
2811*a9fa9459Szrj
2812*a9fa9459Szrj static void
ps(symbolS * s)2813*a9fa9459Szrj ps (symbolS *s)
2814*a9fa9459Szrj {
2815*a9fa9459Szrj fprintf (stdout, "%s type %s%s",
2816*a9fa9459Szrj S_GET_NAME (s),
2817*a9fa9459Szrj S_IS_EXTERNAL (s) ? "EXTERNAL " : "",
2818*a9fa9459Szrj segment_name (S_GET_SEGMENT (s)));
2819*a9fa9459Szrj }
2820*a9fa9459Szrj
2821*a9fa9459Szrj static struct type_name
2822*a9fa9459Szrj {
2823*a9fa9459Szrj i386_operand_type mask;
2824*a9fa9459Szrj const char *name;
2825*a9fa9459Szrj }
2826*a9fa9459Szrj const type_names[] =
2827*a9fa9459Szrj {
2828*a9fa9459Szrj { OPERAND_TYPE_REG8, "r8" },
2829*a9fa9459Szrj { OPERAND_TYPE_REG16, "r16" },
2830*a9fa9459Szrj { OPERAND_TYPE_REG32, "r32" },
2831*a9fa9459Szrj { OPERAND_TYPE_REG64, "r64" },
2832*a9fa9459Szrj { OPERAND_TYPE_IMM8, "i8" },
2833*a9fa9459Szrj { OPERAND_TYPE_IMM8, "i8s" },
2834*a9fa9459Szrj { OPERAND_TYPE_IMM16, "i16" },
2835*a9fa9459Szrj { OPERAND_TYPE_IMM32, "i32" },
2836*a9fa9459Szrj { OPERAND_TYPE_IMM32S, "i32s" },
2837*a9fa9459Szrj { OPERAND_TYPE_IMM64, "i64" },
2838*a9fa9459Szrj { OPERAND_TYPE_IMM1, "i1" },
2839*a9fa9459Szrj { OPERAND_TYPE_BASEINDEX, "BaseIndex" },
2840*a9fa9459Szrj { OPERAND_TYPE_DISP8, "d8" },
2841*a9fa9459Szrj { OPERAND_TYPE_DISP16, "d16" },
2842*a9fa9459Szrj { OPERAND_TYPE_DISP32, "d32" },
2843*a9fa9459Szrj { OPERAND_TYPE_DISP32S, "d32s" },
2844*a9fa9459Szrj { OPERAND_TYPE_DISP64, "d64" },
2845*a9fa9459Szrj { OPERAND_TYPE_VEC_DISP8, "Vector d8" },
2846*a9fa9459Szrj { OPERAND_TYPE_INOUTPORTREG, "InOutPortReg" },
2847*a9fa9459Szrj { OPERAND_TYPE_SHIFTCOUNT, "ShiftCount" },
2848*a9fa9459Szrj { OPERAND_TYPE_CONTROL, "control reg" },
2849*a9fa9459Szrj { OPERAND_TYPE_TEST, "test reg" },
2850*a9fa9459Szrj { OPERAND_TYPE_DEBUG, "debug reg" },
2851*a9fa9459Szrj { OPERAND_TYPE_FLOATREG, "FReg" },
2852*a9fa9459Szrj { OPERAND_TYPE_FLOATACC, "FAcc" },
2853*a9fa9459Szrj { OPERAND_TYPE_SREG2, "SReg2" },
2854*a9fa9459Szrj { OPERAND_TYPE_SREG3, "SReg3" },
2855*a9fa9459Szrj { OPERAND_TYPE_ACC, "Acc" },
2856*a9fa9459Szrj { OPERAND_TYPE_JUMPABSOLUTE, "Jump Absolute" },
2857*a9fa9459Szrj { OPERAND_TYPE_REGMMX, "rMMX" },
2858*a9fa9459Szrj { OPERAND_TYPE_REGXMM, "rXMM" },
2859*a9fa9459Szrj { OPERAND_TYPE_REGYMM, "rYMM" },
2860*a9fa9459Szrj { OPERAND_TYPE_REGZMM, "rZMM" },
2861*a9fa9459Szrj { OPERAND_TYPE_REGMASK, "Mask reg" },
2862*a9fa9459Szrj { OPERAND_TYPE_ESSEG, "es" },
2863*a9fa9459Szrj };
2864*a9fa9459Szrj
2865*a9fa9459Szrj static void
pt(i386_operand_type t)2866*a9fa9459Szrj pt (i386_operand_type t)
2867*a9fa9459Szrj {
2868*a9fa9459Szrj unsigned int j;
2869*a9fa9459Szrj i386_operand_type a;
2870*a9fa9459Szrj
2871*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (type_names); j++)
2872*a9fa9459Szrj {
2873*a9fa9459Szrj a = operand_type_and (t, type_names[j].mask);
2874*a9fa9459Szrj if (!operand_type_all_zero (&a))
2875*a9fa9459Szrj fprintf (stdout, "%s, ", type_names[j].name);
2876*a9fa9459Szrj }
2877*a9fa9459Szrj fflush (stdout);
2878*a9fa9459Szrj }
2879*a9fa9459Szrj
2880*a9fa9459Szrj #endif /* DEBUG386 */
2881*a9fa9459Szrj
2882*a9fa9459Szrj static bfd_reloc_code_real_type
reloc(unsigned int size,int pcrel,int sign,bfd_reloc_code_real_type other)2883*a9fa9459Szrj reloc (unsigned int size,
2884*a9fa9459Szrj int pcrel,
2885*a9fa9459Szrj int sign,
2886*a9fa9459Szrj bfd_reloc_code_real_type other)
2887*a9fa9459Szrj {
2888*a9fa9459Szrj if (other != NO_RELOC)
2889*a9fa9459Szrj {
2890*a9fa9459Szrj reloc_howto_type *rel;
2891*a9fa9459Szrj
2892*a9fa9459Szrj if (size == 8)
2893*a9fa9459Szrj switch (other)
2894*a9fa9459Szrj {
2895*a9fa9459Szrj case BFD_RELOC_X86_64_GOT32:
2896*a9fa9459Szrj return BFD_RELOC_X86_64_GOT64;
2897*a9fa9459Szrj break;
2898*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPLT64:
2899*a9fa9459Szrj return BFD_RELOC_X86_64_GOTPLT64;
2900*a9fa9459Szrj break;
2901*a9fa9459Szrj case BFD_RELOC_X86_64_PLTOFF64:
2902*a9fa9459Szrj return BFD_RELOC_X86_64_PLTOFF64;
2903*a9fa9459Szrj break;
2904*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC32:
2905*a9fa9459Szrj other = BFD_RELOC_X86_64_GOTPC64;
2906*a9fa9459Szrj break;
2907*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCREL:
2908*a9fa9459Szrj other = BFD_RELOC_X86_64_GOTPCREL64;
2909*a9fa9459Szrj break;
2910*a9fa9459Szrj case BFD_RELOC_X86_64_TPOFF32:
2911*a9fa9459Szrj other = BFD_RELOC_X86_64_TPOFF64;
2912*a9fa9459Szrj break;
2913*a9fa9459Szrj case BFD_RELOC_X86_64_DTPOFF32:
2914*a9fa9459Szrj other = BFD_RELOC_X86_64_DTPOFF64;
2915*a9fa9459Szrj break;
2916*a9fa9459Szrj default:
2917*a9fa9459Szrj break;
2918*a9fa9459Szrj }
2919*a9fa9459Szrj
2920*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
2921*a9fa9459Szrj if (other == BFD_RELOC_SIZE32)
2922*a9fa9459Szrj {
2923*a9fa9459Szrj if (size == 8)
2924*a9fa9459Szrj other = BFD_RELOC_SIZE64;
2925*a9fa9459Szrj if (pcrel)
2926*a9fa9459Szrj {
2927*a9fa9459Szrj as_bad (_("there are no pc-relative size relocations"));
2928*a9fa9459Szrj return NO_RELOC;
2929*a9fa9459Szrj }
2930*a9fa9459Szrj }
2931*a9fa9459Szrj #endif
2932*a9fa9459Szrj
2933*a9fa9459Szrj /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless. */
2934*a9fa9459Szrj if (size == 4 && (flag_code != CODE_64BIT || disallow_64bit_reloc))
2935*a9fa9459Szrj sign = -1;
2936*a9fa9459Szrj
2937*a9fa9459Szrj rel = bfd_reloc_type_lookup (stdoutput, other);
2938*a9fa9459Szrj if (!rel)
2939*a9fa9459Szrj as_bad (_("unknown relocation (%u)"), other);
2940*a9fa9459Szrj else if (size != bfd_get_reloc_size (rel))
2941*a9fa9459Szrj as_bad (_("%u-byte relocation cannot be applied to %u-byte field"),
2942*a9fa9459Szrj bfd_get_reloc_size (rel),
2943*a9fa9459Szrj size);
2944*a9fa9459Szrj else if (pcrel && !rel->pc_relative)
2945*a9fa9459Szrj as_bad (_("non-pc-relative relocation for pc-relative field"));
2946*a9fa9459Szrj else if ((rel->complain_on_overflow == complain_overflow_signed
2947*a9fa9459Szrj && !sign)
2948*a9fa9459Szrj || (rel->complain_on_overflow == complain_overflow_unsigned
2949*a9fa9459Szrj && sign > 0))
2950*a9fa9459Szrj as_bad (_("relocated field and relocation type differ in signedness"));
2951*a9fa9459Szrj else
2952*a9fa9459Szrj return other;
2953*a9fa9459Szrj return NO_RELOC;
2954*a9fa9459Szrj }
2955*a9fa9459Szrj
2956*a9fa9459Szrj if (pcrel)
2957*a9fa9459Szrj {
2958*a9fa9459Szrj if (!sign)
2959*a9fa9459Szrj as_bad (_("there are no unsigned pc-relative relocations"));
2960*a9fa9459Szrj switch (size)
2961*a9fa9459Szrj {
2962*a9fa9459Szrj case 1: return BFD_RELOC_8_PCREL;
2963*a9fa9459Szrj case 2: return BFD_RELOC_16_PCREL;
2964*a9fa9459Szrj case 4: return BFD_RELOC_32_PCREL;
2965*a9fa9459Szrj case 8: return BFD_RELOC_64_PCREL;
2966*a9fa9459Szrj }
2967*a9fa9459Szrj as_bad (_("cannot do %u byte pc-relative relocation"), size);
2968*a9fa9459Szrj }
2969*a9fa9459Szrj else
2970*a9fa9459Szrj {
2971*a9fa9459Szrj if (sign > 0)
2972*a9fa9459Szrj switch (size)
2973*a9fa9459Szrj {
2974*a9fa9459Szrj case 4: return BFD_RELOC_X86_64_32S;
2975*a9fa9459Szrj }
2976*a9fa9459Szrj else
2977*a9fa9459Szrj switch (size)
2978*a9fa9459Szrj {
2979*a9fa9459Szrj case 1: return BFD_RELOC_8;
2980*a9fa9459Szrj case 2: return BFD_RELOC_16;
2981*a9fa9459Szrj case 4: return BFD_RELOC_32;
2982*a9fa9459Szrj case 8: return BFD_RELOC_64;
2983*a9fa9459Szrj }
2984*a9fa9459Szrj as_bad (_("cannot do %s %u byte relocation"),
2985*a9fa9459Szrj sign > 0 ? "signed" : "unsigned", size);
2986*a9fa9459Szrj }
2987*a9fa9459Szrj
2988*a9fa9459Szrj return NO_RELOC;
2989*a9fa9459Szrj }
2990*a9fa9459Szrj
2991*a9fa9459Szrj /* Here we decide which fixups can be adjusted to make them relative to
2992*a9fa9459Szrj the beginning of the section instead of the symbol. Basically we need
2993*a9fa9459Szrj to make sure that the dynamic relocations are done correctly, so in
2994*a9fa9459Szrj some cases we force the original symbol to be used. */
2995*a9fa9459Szrj
2996*a9fa9459Szrj int
tc_i386_fix_adjustable(fixS * fixP ATTRIBUTE_UNUSED)2997*a9fa9459Szrj tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED)
2998*a9fa9459Szrj {
2999*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
3000*a9fa9459Szrj if (!IS_ELF)
3001*a9fa9459Szrj return 1;
3002*a9fa9459Szrj
3003*a9fa9459Szrj /* Don't adjust pc-relative references to merge sections in 64-bit
3004*a9fa9459Szrj mode. */
3005*a9fa9459Szrj if (use_rela_relocations
3006*a9fa9459Szrj && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0
3007*a9fa9459Szrj && fixP->fx_pcrel)
3008*a9fa9459Szrj return 0;
3009*a9fa9459Szrj
3010*a9fa9459Szrj /* The x86_64 GOTPCREL are represented as 32bit PCrel relocations
3011*a9fa9459Szrj and changed later by validate_fix. */
3012*a9fa9459Szrj if (GOT_symbol && fixP->fx_subsy == GOT_symbol
3013*a9fa9459Szrj && fixP->fx_r_type == BFD_RELOC_32_PCREL)
3014*a9fa9459Szrj return 0;
3015*a9fa9459Szrj
3016*a9fa9459Szrj /* Adjust_reloc_syms doesn't know about the GOT. Need to keep symbol
3017*a9fa9459Szrj for size relocations. */
3018*a9fa9459Szrj if (fixP->fx_r_type == BFD_RELOC_SIZE32
3019*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_SIZE64
3020*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_GOTOFF
3021*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_PLT32
3022*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_GOT32
3023*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_GOT32X
3024*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
3025*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM
3026*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32
3027*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32
3028*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_IE
3029*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE
3030*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
3031*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
3032*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTDESC
3033*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_386_TLS_DESC_CALL
3034*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
3035*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
3036*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
3037*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCRELX
3038*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_REX_GOTPCRELX
3039*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD
3040*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD
3041*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
3042*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64
3043*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
3044*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
3045*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64
3046*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64
3047*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC
3048*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_X86_64_TLSDESC_CALL
3049*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3050*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3051*a9fa9459Szrj return 0;
3052*a9fa9459Szrj #endif
3053*a9fa9459Szrj return 1;
3054*a9fa9459Szrj }
3055*a9fa9459Szrj
3056*a9fa9459Szrj static int
intel_float_operand(const char * mnemonic)3057*a9fa9459Szrj intel_float_operand (const char *mnemonic)
3058*a9fa9459Szrj {
3059*a9fa9459Szrj /* Note that the value returned is meaningful only for opcodes with (memory)
3060*a9fa9459Szrj operands, hence the code here is free to improperly handle opcodes that
3061*a9fa9459Szrj have no operands (for better performance and smaller code). */
3062*a9fa9459Szrj
3063*a9fa9459Szrj if (mnemonic[0] != 'f')
3064*a9fa9459Szrj return 0; /* non-math */
3065*a9fa9459Szrj
3066*a9fa9459Szrj switch (mnemonic[1])
3067*a9fa9459Szrj {
3068*a9fa9459Szrj /* fclex, fdecstp, fdisi, femms, feni, fincstp, finit, fsetpm, and
3069*a9fa9459Szrj the fs segment override prefix not currently handled because no
3070*a9fa9459Szrj call path can make opcodes without operands get here */
3071*a9fa9459Szrj case 'i':
3072*a9fa9459Szrj return 2 /* integer op */;
3073*a9fa9459Szrj case 'l':
3074*a9fa9459Szrj if (mnemonic[2] == 'd' && (mnemonic[3] == 'c' || mnemonic[3] == 'e'))
3075*a9fa9459Szrj return 3; /* fldcw/fldenv */
3076*a9fa9459Szrj break;
3077*a9fa9459Szrj case 'n':
3078*a9fa9459Szrj if (mnemonic[2] != 'o' /* fnop */)
3079*a9fa9459Szrj return 3; /* non-waiting control op */
3080*a9fa9459Szrj break;
3081*a9fa9459Szrj case 'r':
3082*a9fa9459Szrj if (mnemonic[2] == 's')
3083*a9fa9459Szrj return 3; /* frstor/frstpm */
3084*a9fa9459Szrj break;
3085*a9fa9459Szrj case 's':
3086*a9fa9459Szrj if (mnemonic[2] == 'a')
3087*a9fa9459Szrj return 3; /* fsave */
3088*a9fa9459Szrj if (mnemonic[2] == 't')
3089*a9fa9459Szrj {
3090*a9fa9459Szrj switch (mnemonic[3])
3091*a9fa9459Szrj {
3092*a9fa9459Szrj case 'c': /* fstcw */
3093*a9fa9459Szrj case 'd': /* fstdw */
3094*a9fa9459Szrj case 'e': /* fstenv */
3095*a9fa9459Szrj case 's': /* fsts[gw] */
3096*a9fa9459Szrj return 3;
3097*a9fa9459Szrj }
3098*a9fa9459Szrj }
3099*a9fa9459Szrj break;
3100*a9fa9459Szrj case 'x':
3101*a9fa9459Szrj if (mnemonic[2] == 'r' || mnemonic[2] == 's')
3102*a9fa9459Szrj return 0; /* fxsave/fxrstor are not really math ops */
3103*a9fa9459Szrj break;
3104*a9fa9459Szrj }
3105*a9fa9459Szrj
3106*a9fa9459Szrj return 1;
3107*a9fa9459Szrj }
3108*a9fa9459Szrj
3109*a9fa9459Szrj /* Build the VEX prefix. */
3110*a9fa9459Szrj
3111*a9fa9459Szrj static void
build_vex_prefix(const insn_template * t)3112*a9fa9459Szrj build_vex_prefix (const insn_template *t)
3113*a9fa9459Szrj {
3114*a9fa9459Szrj unsigned int register_specifier;
3115*a9fa9459Szrj unsigned int implied_prefix;
3116*a9fa9459Szrj unsigned int vector_length;
3117*a9fa9459Szrj
3118*a9fa9459Szrj /* Check register specifier. */
3119*a9fa9459Szrj if (i.vex.register_specifier)
3120*a9fa9459Szrj {
3121*a9fa9459Szrj register_specifier =
3122*a9fa9459Szrj ~register_number (i.vex.register_specifier) & 0xf;
3123*a9fa9459Szrj gas_assert ((i.vex.register_specifier->reg_flags & RegVRex) == 0);
3124*a9fa9459Szrj }
3125*a9fa9459Szrj else
3126*a9fa9459Szrj register_specifier = 0xf;
3127*a9fa9459Szrj
3128*a9fa9459Szrj /* Use 2-byte VEX prefix by swappping destination and source
3129*a9fa9459Szrj operand. */
3130*a9fa9459Szrj if (!i.swap_operand
3131*a9fa9459Szrj && i.operands == i.reg_operands
3132*a9fa9459Szrj && i.tm.opcode_modifier.vexopcode == VEX0F
3133*a9fa9459Szrj && i.tm.opcode_modifier.s
3134*a9fa9459Szrj && i.rex == REX_B)
3135*a9fa9459Szrj {
3136*a9fa9459Szrj unsigned int xchg = i.operands - 1;
3137*a9fa9459Szrj union i386_op temp_op;
3138*a9fa9459Szrj i386_operand_type temp_type;
3139*a9fa9459Szrj
3140*a9fa9459Szrj temp_type = i.types[xchg];
3141*a9fa9459Szrj i.types[xchg] = i.types[0];
3142*a9fa9459Szrj i.types[0] = temp_type;
3143*a9fa9459Szrj temp_op = i.op[xchg];
3144*a9fa9459Szrj i.op[xchg] = i.op[0];
3145*a9fa9459Szrj i.op[0] = temp_op;
3146*a9fa9459Szrj
3147*a9fa9459Szrj gas_assert (i.rm.mode == 3);
3148*a9fa9459Szrj
3149*a9fa9459Szrj i.rex = REX_R;
3150*a9fa9459Szrj xchg = i.rm.regmem;
3151*a9fa9459Szrj i.rm.regmem = i.rm.reg;
3152*a9fa9459Szrj i.rm.reg = xchg;
3153*a9fa9459Szrj
3154*a9fa9459Szrj /* Use the next insn. */
3155*a9fa9459Szrj i.tm = t[1];
3156*a9fa9459Szrj }
3157*a9fa9459Szrj
3158*a9fa9459Szrj if (i.tm.opcode_modifier.vex == VEXScalar)
3159*a9fa9459Szrj vector_length = avxscalar;
3160*a9fa9459Szrj else
3161*a9fa9459Szrj vector_length = i.tm.opcode_modifier.vex == VEX256 ? 1 : 0;
3162*a9fa9459Szrj
3163*a9fa9459Szrj switch ((i.tm.base_opcode >> 8) & 0xff)
3164*a9fa9459Szrj {
3165*a9fa9459Szrj case 0:
3166*a9fa9459Szrj implied_prefix = 0;
3167*a9fa9459Szrj break;
3168*a9fa9459Szrj case DATA_PREFIX_OPCODE:
3169*a9fa9459Szrj implied_prefix = 1;
3170*a9fa9459Szrj break;
3171*a9fa9459Szrj case REPE_PREFIX_OPCODE:
3172*a9fa9459Szrj implied_prefix = 2;
3173*a9fa9459Szrj break;
3174*a9fa9459Szrj case REPNE_PREFIX_OPCODE:
3175*a9fa9459Szrj implied_prefix = 3;
3176*a9fa9459Szrj break;
3177*a9fa9459Szrj default:
3178*a9fa9459Szrj abort ();
3179*a9fa9459Szrj }
3180*a9fa9459Szrj
3181*a9fa9459Szrj /* Use 2-byte VEX prefix if possible. */
3182*a9fa9459Szrj if (i.tm.opcode_modifier.vexopcode == VEX0F
3183*a9fa9459Szrj && i.tm.opcode_modifier.vexw != VEXW1
3184*a9fa9459Szrj && (i.rex & (REX_W | REX_X | REX_B)) == 0)
3185*a9fa9459Szrj {
3186*a9fa9459Szrj /* 2-byte VEX prefix. */
3187*a9fa9459Szrj unsigned int r;
3188*a9fa9459Szrj
3189*a9fa9459Szrj i.vex.length = 2;
3190*a9fa9459Szrj i.vex.bytes[0] = 0xc5;
3191*a9fa9459Szrj
3192*a9fa9459Szrj /* Check the REX.R bit. */
3193*a9fa9459Szrj r = (i.rex & REX_R) ? 0 : 1;
3194*a9fa9459Szrj i.vex.bytes[1] = (r << 7
3195*a9fa9459Szrj | register_specifier << 3
3196*a9fa9459Szrj | vector_length << 2
3197*a9fa9459Szrj | implied_prefix);
3198*a9fa9459Szrj }
3199*a9fa9459Szrj else
3200*a9fa9459Szrj {
3201*a9fa9459Szrj /* 3-byte VEX prefix. */
3202*a9fa9459Szrj unsigned int m, w;
3203*a9fa9459Szrj
3204*a9fa9459Szrj i.vex.length = 3;
3205*a9fa9459Szrj
3206*a9fa9459Szrj switch (i.tm.opcode_modifier.vexopcode)
3207*a9fa9459Szrj {
3208*a9fa9459Szrj case VEX0F:
3209*a9fa9459Szrj m = 0x1;
3210*a9fa9459Szrj i.vex.bytes[0] = 0xc4;
3211*a9fa9459Szrj break;
3212*a9fa9459Szrj case VEX0F38:
3213*a9fa9459Szrj m = 0x2;
3214*a9fa9459Szrj i.vex.bytes[0] = 0xc4;
3215*a9fa9459Szrj break;
3216*a9fa9459Szrj case VEX0F3A:
3217*a9fa9459Szrj m = 0x3;
3218*a9fa9459Szrj i.vex.bytes[0] = 0xc4;
3219*a9fa9459Szrj break;
3220*a9fa9459Szrj case XOP08:
3221*a9fa9459Szrj m = 0x8;
3222*a9fa9459Szrj i.vex.bytes[0] = 0x8f;
3223*a9fa9459Szrj break;
3224*a9fa9459Szrj case XOP09:
3225*a9fa9459Szrj m = 0x9;
3226*a9fa9459Szrj i.vex.bytes[0] = 0x8f;
3227*a9fa9459Szrj break;
3228*a9fa9459Szrj case XOP0A:
3229*a9fa9459Szrj m = 0xa;
3230*a9fa9459Szrj i.vex.bytes[0] = 0x8f;
3231*a9fa9459Szrj break;
3232*a9fa9459Szrj default:
3233*a9fa9459Szrj abort ();
3234*a9fa9459Szrj }
3235*a9fa9459Szrj
3236*a9fa9459Szrj /* The high 3 bits of the second VEX byte are 1's compliment
3237*a9fa9459Szrj of RXB bits from REX. */
3238*a9fa9459Szrj i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m;
3239*a9fa9459Szrj
3240*a9fa9459Szrj /* Check the REX.W bit. */
3241*a9fa9459Szrj w = (i.rex & REX_W) ? 1 : 0;
3242*a9fa9459Szrj if (i.tm.opcode_modifier.vexw == VEXW1)
3243*a9fa9459Szrj w = 1;
3244*a9fa9459Szrj
3245*a9fa9459Szrj i.vex.bytes[2] = (w << 7
3246*a9fa9459Szrj | register_specifier << 3
3247*a9fa9459Szrj | vector_length << 2
3248*a9fa9459Szrj | implied_prefix);
3249*a9fa9459Szrj }
3250*a9fa9459Szrj }
3251*a9fa9459Szrj
3252*a9fa9459Szrj /* Build the EVEX prefix. */
3253*a9fa9459Szrj
3254*a9fa9459Szrj static void
build_evex_prefix(void)3255*a9fa9459Szrj build_evex_prefix (void)
3256*a9fa9459Szrj {
3257*a9fa9459Szrj unsigned int register_specifier;
3258*a9fa9459Szrj unsigned int implied_prefix;
3259*a9fa9459Szrj unsigned int m, w;
3260*a9fa9459Szrj rex_byte vrex_used = 0;
3261*a9fa9459Szrj
3262*a9fa9459Szrj /* Check register specifier. */
3263*a9fa9459Szrj if (i.vex.register_specifier)
3264*a9fa9459Szrj {
3265*a9fa9459Szrj gas_assert ((i.vrex & REX_X) == 0);
3266*a9fa9459Szrj
3267*a9fa9459Szrj register_specifier = i.vex.register_specifier->reg_num;
3268*a9fa9459Szrj if ((i.vex.register_specifier->reg_flags & RegRex))
3269*a9fa9459Szrj register_specifier += 8;
3270*a9fa9459Szrj /* The upper 16 registers are encoded in the fourth byte of the
3271*a9fa9459Szrj EVEX prefix. */
3272*a9fa9459Szrj if (!(i.vex.register_specifier->reg_flags & RegVRex))
3273*a9fa9459Szrj i.vex.bytes[3] = 0x8;
3274*a9fa9459Szrj register_specifier = ~register_specifier & 0xf;
3275*a9fa9459Szrj }
3276*a9fa9459Szrj else
3277*a9fa9459Szrj {
3278*a9fa9459Szrj register_specifier = 0xf;
3279*a9fa9459Szrj
3280*a9fa9459Szrj /* Encode upper 16 vector index register in the fourth byte of
3281*a9fa9459Szrj the EVEX prefix. */
3282*a9fa9459Szrj if (!(i.vrex & REX_X))
3283*a9fa9459Szrj i.vex.bytes[3] = 0x8;
3284*a9fa9459Szrj else
3285*a9fa9459Szrj vrex_used |= REX_X;
3286*a9fa9459Szrj }
3287*a9fa9459Szrj
3288*a9fa9459Szrj switch ((i.tm.base_opcode >> 8) & 0xff)
3289*a9fa9459Szrj {
3290*a9fa9459Szrj case 0:
3291*a9fa9459Szrj implied_prefix = 0;
3292*a9fa9459Szrj break;
3293*a9fa9459Szrj case DATA_PREFIX_OPCODE:
3294*a9fa9459Szrj implied_prefix = 1;
3295*a9fa9459Szrj break;
3296*a9fa9459Szrj case REPE_PREFIX_OPCODE:
3297*a9fa9459Szrj implied_prefix = 2;
3298*a9fa9459Szrj break;
3299*a9fa9459Szrj case REPNE_PREFIX_OPCODE:
3300*a9fa9459Szrj implied_prefix = 3;
3301*a9fa9459Szrj break;
3302*a9fa9459Szrj default:
3303*a9fa9459Szrj abort ();
3304*a9fa9459Szrj }
3305*a9fa9459Szrj
3306*a9fa9459Szrj /* 4 byte EVEX prefix. */
3307*a9fa9459Szrj i.vex.length = 4;
3308*a9fa9459Szrj i.vex.bytes[0] = 0x62;
3309*a9fa9459Szrj
3310*a9fa9459Szrj /* mmmm bits. */
3311*a9fa9459Szrj switch (i.tm.opcode_modifier.vexopcode)
3312*a9fa9459Szrj {
3313*a9fa9459Szrj case VEX0F:
3314*a9fa9459Szrj m = 1;
3315*a9fa9459Szrj break;
3316*a9fa9459Szrj case VEX0F38:
3317*a9fa9459Szrj m = 2;
3318*a9fa9459Szrj break;
3319*a9fa9459Szrj case VEX0F3A:
3320*a9fa9459Szrj m = 3;
3321*a9fa9459Szrj break;
3322*a9fa9459Szrj default:
3323*a9fa9459Szrj abort ();
3324*a9fa9459Szrj break;
3325*a9fa9459Szrj }
3326*a9fa9459Szrj
3327*a9fa9459Szrj /* The high 3 bits of the second EVEX byte are 1's compliment of RXB
3328*a9fa9459Szrj bits from REX. */
3329*a9fa9459Szrj i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m;
3330*a9fa9459Szrj
3331*a9fa9459Szrj /* The fifth bit of the second EVEX byte is 1's compliment of the
3332*a9fa9459Szrj REX_R bit in VREX. */
3333*a9fa9459Szrj if (!(i.vrex & REX_R))
3334*a9fa9459Szrj i.vex.bytes[1] |= 0x10;
3335*a9fa9459Szrj else
3336*a9fa9459Szrj vrex_used |= REX_R;
3337*a9fa9459Szrj
3338*a9fa9459Szrj if ((i.reg_operands + i.imm_operands) == i.operands)
3339*a9fa9459Szrj {
3340*a9fa9459Szrj /* When all operands are registers, the REX_X bit in REX is not
3341*a9fa9459Szrj used. We reuse it to encode the upper 16 registers, which is
3342*a9fa9459Szrj indicated by the REX_B bit in VREX. The REX_X bit is encoded
3343*a9fa9459Szrj as 1's compliment. */
3344*a9fa9459Szrj if ((i.vrex & REX_B))
3345*a9fa9459Szrj {
3346*a9fa9459Szrj vrex_used |= REX_B;
3347*a9fa9459Szrj i.vex.bytes[1] &= ~0x40;
3348*a9fa9459Szrj }
3349*a9fa9459Szrj }
3350*a9fa9459Szrj
3351*a9fa9459Szrj /* EVEX instructions shouldn't need the REX prefix. */
3352*a9fa9459Szrj i.vrex &= ~vrex_used;
3353*a9fa9459Szrj gas_assert (i.vrex == 0);
3354*a9fa9459Szrj
3355*a9fa9459Szrj /* Check the REX.W bit. */
3356*a9fa9459Szrj w = (i.rex & REX_W) ? 1 : 0;
3357*a9fa9459Szrj if (i.tm.opcode_modifier.vexw)
3358*a9fa9459Szrj {
3359*a9fa9459Szrj if (i.tm.opcode_modifier.vexw == VEXW1)
3360*a9fa9459Szrj w = 1;
3361*a9fa9459Szrj }
3362*a9fa9459Szrj /* If w is not set it means we are dealing with WIG instruction. */
3363*a9fa9459Szrj else if (!w)
3364*a9fa9459Szrj {
3365*a9fa9459Szrj if (evexwig == evexw1)
3366*a9fa9459Szrj w = 1;
3367*a9fa9459Szrj }
3368*a9fa9459Szrj
3369*a9fa9459Szrj /* Encode the U bit. */
3370*a9fa9459Szrj implied_prefix |= 0x4;
3371*a9fa9459Szrj
3372*a9fa9459Szrj /* The third byte of the EVEX prefix. */
3373*a9fa9459Szrj i.vex.bytes[2] = (w << 7 | register_specifier << 3 | implied_prefix);
3374*a9fa9459Szrj
3375*a9fa9459Szrj /* The fourth byte of the EVEX prefix. */
3376*a9fa9459Szrj /* The zeroing-masking bit. */
3377*a9fa9459Szrj if (i.mask && i.mask->zeroing)
3378*a9fa9459Szrj i.vex.bytes[3] |= 0x80;
3379*a9fa9459Szrj
3380*a9fa9459Szrj /* Don't always set the broadcast bit if there is no RC. */
3381*a9fa9459Szrj if (!i.rounding)
3382*a9fa9459Szrj {
3383*a9fa9459Szrj /* Encode the vector length. */
3384*a9fa9459Szrj unsigned int vec_length;
3385*a9fa9459Szrj
3386*a9fa9459Szrj switch (i.tm.opcode_modifier.evex)
3387*a9fa9459Szrj {
3388*a9fa9459Szrj case EVEXLIG: /* LL' is ignored */
3389*a9fa9459Szrj vec_length = evexlig << 5;
3390*a9fa9459Szrj break;
3391*a9fa9459Szrj case EVEX128:
3392*a9fa9459Szrj vec_length = 0 << 5;
3393*a9fa9459Szrj break;
3394*a9fa9459Szrj case EVEX256:
3395*a9fa9459Szrj vec_length = 1 << 5;
3396*a9fa9459Szrj break;
3397*a9fa9459Szrj case EVEX512:
3398*a9fa9459Szrj vec_length = 2 << 5;
3399*a9fa9459Szrj break;
3400*a9fa9459Szrj default:
3401*a9fa9459Szrj abort ();
3402*a9fa9459Szrj break;
3403*a9fa9459Szrj }
3404*a9fa9459Szrj i.vex.bytes[3] |= vec_length;
3405*a9fa9459Szrj /* Encode the broadcast bit. */
3406*a9fa9459Szrj if (i.broadcast)
3407*a9fa9459Szrj i.vex.bytes[3] |= 0x10;
3408*a9fa9459Szrj }
3409*a9fa9459Szrj else
3410*a9fa9459Szrj {
3411*a9fa9459Szrj if (i.rounding->type != saeonly)
3412*a9fa9459Szrj i.vex.bytes[3] |= 0x10 | (i.rounding->type << 5);
3413*a9fa9459Szrj else
3414*a9fa9459Szrj i.vex.bytes[3] |= 0x10 | (evexrcig << 5);
3415*a9fa9459Szrj }
3416*a9fa9459Szrj
3417*a9fa9459Szrj if (i.mask && i.mask->mask)
3418*a9fa9459Szrj i.vex.bytes[3] |= i.mask->mask->reg_num;
3419*a9fa9459Szrj }
3420*a9fa9459Szrj
3421*a9fa9459Szrj static void
process_immext(void)3422*a9fa9459Szrj process_immext (void)
3423*a9fa9459Szrj {
3424*a9fa9459Szrj expressionS *exp;
3425*a9fa9459Szrj
3426*a9fa9459Szrj if ((i.tm.cpu_flags.bitfield.cpusse3 || i.tm.cpu_flags.bitfield.cpusvme)
3427*a9fa9459Szrj && i.operands > 0)
3428*a9fa9459Szrj {
3429*a9fa9459Szrj /* MONITOR/MWAIT as well as SVME instructions have fixed operands
3430*a9fa9459Szrj with an opcode suffix which is coded in the same place as an
3431*a9fa9459Szrj 8-bit immediate field would be.
3432*a9fa9459Szrj Here we check those operands and remove them afterwards. */
3433*a9fa9459Szrj unsigned int x;
3434*a9fa9459Szrj
3435*a9fa9459Szrj for (x = 0; x < i.operands; x++)
3436*a9fa9459Szrj if (register_number (i.op[x].regs) != x)
3437*a9fa9459Szrj as_bad (_("can't use register '%s%s' as operand %d in '%s'."),
3438*a9fa9459Szrj register_prefix, i.op[x].regs->reg_name, x + 1,
3439*a9fa9459Szrj i.tm.name);
3440*a9fa9459Szrj
3441*a9fa9459Szrj i.operands = 0;
3442*a9fa9459Szrj }
3443*a9fa9459Szrj
3444*a9fa9459Szrj if (i.tm.cpu_flags.bitfield.cpumwaitx && i.operands > 0)
3445*a9fa9459Szrj {
3446*a9fa9459Szrj /* MONITORX/MWAITX instructions have fixed operands with an opcode
3447*a9fa9459Szrj suffix which is coded in the same place as an 8-bit immediate
3448*a9fa9459Szrj field would be.
3449*a9fa9459Szrj Here we check those operands and remove them afterwards. */
3450*a9fa9459Szrj unsigned int x;
3451*a9fa9459Szrj
3452*a9fa9459Szrj if (i.operands != 3)
3453*a9fa9459Szrj abort();
3454*a9fa9459Szrj
3455*a9fa9459Szrj for (x = 0; x < 2; x++)
3456*a9fa9459Szrj if (register_number (i.op[x].regs) != x)
3457*a9fa9459Szrj goto bad_register_operand;
3458*a9fa9459Szrj
3459*a9fa9459Szrj /* Check for third operand for mwaitx/monitorx insn. */
3460*a9fa9459Szrj if (register_number (i.op[x].regs)
3461*a9fa9459Szrj != (x + (i.tm.extension_opcode == 0xfb)))
3462*a9fa9459Szrj {
3463*a9fa9459Szrj bad_register_operand:
3464*a9fa9459Szrj as_bad (_("can't use register '%s%s' as operand %d in '%s'."),
3465*a9fa9459Szrj register_prefix, i.op[x].regs->reg_name, x+1,
3466*a9fa9459Szrj i.tm.name);
3467*a9fa9459Szrj }
3468*a9fa9459Szrj
3469*a9fa9459Szrj i.operands = 0;
3470*a9fa9459Szrj }
3471*a9fa9459Szrj
3472*a9fa9459Szrj /* These AMD 3DNow! and SSE2 instructions have an opcode suffix
3473*a9fa9459Szrj which is coded in the same place as an 8-bit immediate field
3474*a9fa9459Szrj would be. Here we fake an 8-bit immediate operand from the
3475*a9fa9459Szrj opcode suffix stored in tm.extension_opcode.
3476*a9fa9459Szrj
3477*a9fa9459Szrj AVX instructions also use this encoding, for some of
3478*a9fa9459Szrj 3 argument instructions. */
3479*a9fa9459Szrj
3480*a9fa9459Szrj gas_assert (i.imm_operands <= 1
3481*a9fa9459Szrj && (i.operands <= 2
3482*a9fa9459Szrj || ((i.tm.opcode_modifier.vex
3483*a9fa9459Szrj || i.tm.opcode_modifier.evex)
3484*a9fa9459Szrj && i.operands <= 4)));
3485*a9fa9459Szrj
3486*a9fa9459Szrj exp = &im_expressions[i.imm_operands++];
3487*a9fa9459Szrj i.op[i.operands].imms = exp;
3488*a9fa9459Szrj i.types[i.operands] = imm8;
3489*a9fa9459Szrj i.operands++;
3490*a9fa9459Szrj exp->X_op = O_constant;
3491*a9fa9459Szrj exp->X_add_number = i.tm.extension_opcode;
3492*a9fa9459Szrj i.tm.extension_opcode = None;
3493*a9fa9459Szrj }
3494*a9fa9459Szrj
3495*a9fa9459Szrj
3496*a9fa9459Szrj static int
check_hle(void)3497*a9fa9459Szrj check_hle (void)
3498*a9fa9459Szrj {
3499*a9fa9459Szrj switch (i.tm.opcode_modifier.hleprefixok)
3500*a9fa9459Szrj {
3501*a9fa9459Szrj default:
3502*a9fa9459Szrj abort ();
3503*a9fa9459Szrj case HLEPrefixNone:
3504*a9fa9459Szrj as_bad (_("invalid instruction `%s' after `%s'"),
3505*a9fa9459Szrj i.tm.name, i.hle_prefix);
3506*a9fa9459Szrj return 0;
3507*a9fa9459Szrj case HLEPrefixLock:
3508*a9fa9459Szrj if (i.prefix[LOCK_PREFIX])
3509*a9fa9459Szrj return 1;
3510*a9fa9459Szrj as_bad (_("missing `lock' with `%s'"), i.hle_prefix);
3511*a9fa9459Szrj return 0;
3512*a9fa9459Szrj case HLEPrefixAny:
3513*a9fa9459Szrj return 1;
3514*a9fa9459Szrj case HLEPrefixRelease:
3515*a9fa9459Szrj if (i.prefix[HLE_PREFIX] != XRELEASE_PREFIX_OPCODE)
3516*a9fa9459Szrj {
3517*a9fa9459Szrj as_bad (_("instruction `%s' after `xacquire' not allowed"),
3518*a9fa9459Szrj i.tm.name);
3519*a9fa9459Szrj return 0;
3520*a9fa9459Szrj }
3521*a9fa9459Szrj if (i.mem_operands == 0
3522*a9fa9459Szrj || !operand_type_check (i.types[i.operands - 1], anymem))
3523*a9fa9459Szrj {
3524*a9fa9459Szrj as_bad (_("memory destination needed for instruction `%s'"
3525*a9fa9459Szrj " after `xrelease'"), i.tm.name);
3526*a9fa9459Szrj return 0;
3527*a9fa9459Szrj }
3528*a9fa9459Szrj return 1;
3529*a9fa9459Szrj }
3530*a9fa9459Szrj }
3531*a9fa9459Szrj
3532*a9fa9459Szrj /* This is the guts of the machine-dependent assembler. LINE points to a
3533*a9fa9459Szrj machine dependent instruction. This function is supposed to emit
3534*a9fa9459Szrj the frags/bytes it assembles to. */
3535*a9fa9459Szrj
3536*a9fa9459Szrj void
md_assemble(char * line)3537*a9fa9459Szrj md_assemble (char *line)
3538*a9fa9459Szrj {
3539*a9fa9459Szrj unsigned int j;
3540*a9fa9459Szrj char mnemonic[MAX_MNEM_SIZE], mnem_suffix;
3541*a9fa9459Szrj const insn_template *t;
3542*a9fa9459Szrj
3543*a9fa9459Szrj /* Initialize globals. */
3544*a9fa9459Szrj memset (&i, '\0', sizeof (i));
3545*a9fa9459Szrj for (j = 0; j < MAX_OPERANDS; j++)
3546*a9fa9459Szrj i.reloc[j] = NO_RELOC;
3547*a9fa9459Szrj memset (disp_expressions, '\0', sizeof (disp_expressions));
3548*a9fa9459Szrj memset (im_expressions, '\0', sizeof (im_expressions));
3549*a9fa9459Szrj save_stack_p = save_stack;
3550*a9fa9459Szrj
3551*a9fa9459Szrj /* First parse an instruction mnemonic & call i386_operand for the operands.
3552*a9fa9459Szrj We assume that the scrubber has arranged it so that line[0] is the valid
3553*a9fa9459Szrj start of a (possibly prefixed) mnemonic. */
3554*a9fa9459Szrj
3555*a9fa9459Szrj line = parse_insn (line, mnemonic);
3556*a9fa9459Szrj if (line == NULL)
3557*a9fa9459Szrj return;
3558*a9fa9459Szrj mnem_suffix = i.suffix;
3559*a9fa9459Szrj
3560*a9fa9459Szrj line = parse_operands (line, mnemonic);
3561*a9fa9459Szrj this_operand = -1;
3562*a9fa9459Szrj xfree (i.memop1_string);
3563*a9fa9459Szrj i.memop1_string = NULL;
3564*a9fa9459Szrj if (line == NULL)
3565*a9fa9459Szrj return;
3566*a9fa9459Szrj
3567*a9fa9459Szrj /* Now we've parsed the mnemonic into a set of templates, and have the
3568*a9fa9459Szrj operands at hand. */
3569*a9fa9459Szrj
3570*a9fa9459Szrj /* All intel opcodes have reversed operands except for "bound" and
3571*a9fa9459Szrj "enter". We also don't reverse intersegment "jmp" and "call"
3572*a9fa9459Szrj instructions with 2 immediate operands so that the immediate segment
3573*a9fa9459Szrj precedes the offset, as it does when in AT&T mode. */
3574*a9fa9459Szrj if (intel_syntax
3575*a9fa9459Szrj && i.operands > 1
3576*a9fa9459Szrj && (strcmp (mnemonic, "bound") != 0)
3577*a9fa9459Szrj && (strcmp (mnemonic, "invlpga") != 0)
3578*a9fa9459Szrj && !(operand_type_check (i.types[0], imm)
3579*a9fa9459Szrj && operand_type_check (i.types[1], imm)))
3580*a9fa9459Szrj swap_operands ();
3581*a9fa9459Szrj
3582*a9fa9459Szrj /* The order of the immediates should be reversed
3583*a9fa9459Szrj for 2 immediates extrq and insertq instructions */
3584*a9fa9459Szrj if (i.imm_operands == 2
3585*a9fa9459Szrj && (strcmp (mnemonic, "extrq") == 0
3586*a9fa9459Szrj || strcmp (mnemonic, "insertq") == 0))
3587*a9fa9459Szrj swap_2_operands (0, 1);
3588*a9fa9459Szrj
3589*a9fa9459Szrj if (i.imm_operands)
3590*a9fa9459Szrj optimize_imm ();
3591*a9fa9459Szrj
3592*a9fa9459Szrj /* Don't optimize displacement for movabs since it only takes 64bit
3593*a9fa9459Szrj displacement. */
3594*a9fa9459Szrj if (i.disp_operands
3595*a9fa9459Szrj && i.disp_encoding != disp_encoding_32bit
3596*a9fa9459Szrj && (flag_code != CODE_64BIT
3597*a9fa9459Szrj || strcmp (mnemonic, "movabs") != 0))
3598*a9fa9459Szrj optimize_disp ();
3599*a9fa9459Szrj
3600*a9fa9459Szrj /* Next, we find a template that matches the given insn,
3601*a9fa9459Szrj making sure the overlap of the given operands types is consistent
3602*a9fa9459Szrj with the template operand types. */
3603*a9fa9459Szrj
3604*a9fa9459Szrj if (!(t = match_template (mnem_suffix)))
3605*a9fa9459Szrj return;
3606*a9fa9459Szrj
3607*a9fa9459Szrj if (sse_check != check_none
3608*a9fa9459Szrj && !i.tm.opcode_modifier.noavx
3609*a9fa9459Szrj && (i.tm.cpu_flags.bitfield.cpusse
3610*a9fa9459Szrj || i.tm.cpu_flags.bitfield.cpusse2
3611*a9fa9459Szrj || i.tm.cpu_flags.bitfield.cpusse3
3612*a9fa9459Szrj || i.tm.cpu_flags.bitfield.cpussse3
3613*a9fa9459Szrj || i.tm.cpu_flags.bitfield.cpusse4_1
3614*a9fa9459Szrj || i.tm.cpu_flags.bitfield.cpusse4_2))
3615*a9fa9459Szrj {
3616*a9fa9459Szrj (sse_check == check_warning
3617*a9fa9459Szrj ? as_warn
3618*a9fa9459Szrj : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
3619*a9fa9459Szrj }
3620*a9fa9459Szrj
3621*a9fa9459Szrj /* Zap movzx and movsx suffix. The suffix has been set from
3622*a9fa9459Szrj "word ptr" or "byte ptr" on the source operand in Intel syntax
3623*a9fa9459Szrj or extracted from mnemonic in AT&T syntax. But we'll use
3624*a9fa9459Szrj the destination register to choose the suffix for encoding. */
3625*a9fa9459Szrj if ((i.tm.base_opcode & ~9) == 0x0fb6)
3626*a9fa9459Szrj {
3627*a9fa9459Szrj /* In Intel syntax, there must be a suffix. In AT&T syntax, if
3628*a9fa9459Szrj there is no suffix, the default will be byte extension. */
3629*a9fa9459Szrj if (i.reg_operands != 2
3630*a9fa9459Szrj && !i.suffix
3631*a9fa9459Szrj && intel_syntax)
3632*a9fa9459Szrj as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
3633*a9fa9459Szrj
3634*a9fa9459Szrj i.suffix = 0;
3635*a9fa9459Szrj }
3636*a9fa9459Szrj
3637*a9fa9459Szrj if (i.tm.opcode_modifier.fwait)
3638*a9fa9459Szrj if (!add_prefix (FWAIT_OPCODE))
3639*a9fa9459Szrj return;
3640*a9fa9459Szrj
3641*a9fa9459Szrj /* Check if REP prefix is OK. */
3642*a9fa9459Szrj if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok)
3643*a9fa9459Szrj {
3644*a9fa9459Szrj as_bad (_("invalid instruction `%s' after `%s'"),
3645*a9fa9459Szrj i.tm.name, i.rep_prefix);
3646*a9fa9459Szrj return;
3647*a9fa9459Szrj }
3648*a9fa9459Szrj
3649*a9fa9459Szrj /* Check for lock without a lockable instruction. Destination operand
3650*a9fa9459Szrj must be memory unless it is xchg (0x86). */
3651*a9fa9459Szrj if (i.prefix[LOCK_PREFIX]
3652*a9fa9459Szrj && (!i.tm.opcode_modifier.islockable
3653*a9fa9459Szrj || i.mem_operands == 0
3654*a9fa9459Szrj || (i.tm.base_opcode != 0x86
3655*a9fa9459Szrj && !operand_type_check (i.types[i.operands - 1], anymem))))
3656*a9fa9459Szrj {
3657*a9fa9459Szrj as_bad (_("expecting lockable instruction after `lock'"));
3658*a9fa9459Szrj return;
3659*a9fa9459Szrj }
3660*a9fa9459Szrj
3661*a9fa9459Szrj /* Check if HLE prefix is OK. */
3662*a9fa9459Szrj if (i.hle_prefix && !check_hle ())
3663*a9fa9459Szrj return;
3664*a9fa9459Szrj
3665*a9fa9459Szrj /* Check BND prefix. */
3666*a9fa9459Szrj if (i.bnd_prefix && !i.tm.opcode_modifier.bndprefixok)
3667*a9fa9459Szrj as_bad (_("expecting valid branch instruction after `bnd'"));
3668*a9fa9459Szrj
3669*a9fa9459Szrj if (i.tm.cpu_flags.bitfield.cpumpx)
3670*a9fa9459Szrj {
3671*a9fa9459Szrj if (flag_code == CODE_64BIT && i.prefix[ADDR_PREFIX])
3672*a9fa9459Szrj as_bad (_("32-bit address isn't allowed in 64-bit MPX instructions."));
3673*a9fa9459Szrj else if (flag_code != CODE_16BIT
3674*a9fa9459Szrj ? i.prefix[ADDR_PREFIX]
3675*a9fa9459Szrj : i.mem_operands && !i.prefix[ADDR_PREFIX])
3676*a9fa9459Szrj as_bad (_("16-bit address isn't allowed in MPX instructions"));
3677*a9fa9459Szrj }
3678*a9fa9459Szrj
3679*a9fa9459Szrj /* Insert BND prefix. */
3680*a9fa9459Szrj if (add_bnd_prefix
3681*a9fa9459Szrj && i.tm.opcode_modifier.bndprefixok
3682*a9fa9459Szrj && !i.prefix[BND_PREFIX])
3683*a9fa9459Szrj add_prefix (BND_PREFIX_OPCODE);
3684*a9fa9459Szrj
3685*a9fa9459Szrj /* Check string instruction segment overrides. */
3686*a9fa9459Szrj if (i.tm.opcode_modifier.isstring && i.mem_operands != 0)
3687*a9fa9459Szrj {
3688*a9fa9459Szrj if (!check_string ())
3689*a9fa9459Szrj return;
3690*a9fa9459Szrj i.disp_operands = 0;
3691*a9fa9459Szrj }
3692*a9fa9459Szrj
3693*a9fa9459Szrj if (!process_suffix ())
3694*a9fa9459Szrj return;
3695*a9fa9459Szrj
3696*a9fa9459Szrj /* Update operand types. */
3697*a9fa9459Szrj for (j = 0; j < i.operands; j++)
3698*a9fa9459Szrj i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]);
3699*a9fa9459Szrj
3700*a9fa9459Szrj /* Make still unresolved immediate matches conform to size of immediate
3701*a9fa9459Szrj given in i.suffix. */
3702*a9fa9459Szrj if (!finalize_imm ())
3703*a9fa9459Szrj return;
3704*a9fa9459Szrj
3705*a9fa9459Szrj if (i.types[0].bitfield.imm1)
3706*a9fa9459Szrj i.imm_operands = 0; /* kludge for shift insns. */
3707*a9fa9459Szrj
3708*a9fa9459Szrj /* We only need to check those implicit registers for instructions
3709*a9fa9459Szrj with 3 operands or less. */
3710*a9fa9459Szrj if (i.operands <= 3)
3711*a9fa9459Szrj for (j = 0; j < i.operands; j++)
3712*a9fa9459Szrj if (i.types[j].bitfield.inoutportreg
3713*a9fa9459Szrj || i.types[j].bitfield.shiftcount
3714*a9fa9459Szrj || i.types[j].bitfield.acc
3715*a9fa9459Szrj || i.types[j].bitfield.floatacc)
3716*a9fa9459Szrj i.reg_operands--;
3717*a9fa9459Szrj
3718*a9fa9459Szrj /* ImmExt should be processed after SSE2AVX. */
3719*a9fa9459Szrj if (!i.tm.opcode_modifier.sse2avx
3720*a9fa9459Szrj && i.tm.opcode_modifier.immext)
3721*a9fa9459Szrj process_immext ();
3722*a9fa9459Szrj
3723*a9fa9459Szrj /* For insns with operands there are more diddles to do to the opcode. */
3724*a9fa9459Szrj if (i.operands)
3725*a9fa9459Szrj {
3726*a9fa9459Szrj if (!process_operands ())
3727*a9fa9459Szrj return;
3728*a9fa9459Szrj }
3729*a9fa9459Szrj else if (!quiet_warnings && i.tm.opcode_modifier.ugh)
3730*a9fa9459Szrj {
3731*a9fa9459Szrj /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc. */
3732*a9fa9459Szrj as_warn (_("translating to `%sp'"), i.tm.name);
3733*a9fa9459Szrj }
3734*a9fa9459Szrj
3735*a9fa9459Szrj if (i.tm.opcode_modifier.vex || i.tm.opcode_modifier.evex)
3736*a9fa9459Szrj {
3737*a9fa9459Szrj if (flag_code == CODE_16BIT)
3738*a9fa9459Szrj {
3739*a9fa9459Szrj as_bad (_("instruction `%s' isn't supported in 16-bit mode."),
3740*a9fa9459Szrj i.tm.name);
3741*a9fa9459Szrj return;
3742*a9fa9459Szrj }
3743*a9fa9459Szrj
3744*a9fa9459Szrj if (i.tm.opcode_modifier.vex)
3745*a9fa9459Szrj build_vex_prefix (t);
3746*a9fa9459Szrj else
3747*a9fa9459Szrj build_evex_prefix ();
3748*a9fa9459Szrj }
3749*a9fa9459Szrj
3750*a9fa9459Szrj /* Handle conversion of 'int $3' --> special int3 insn. XOP or FMA4
3751*a9fa9459Szrj instructions may define INT_OPCODE as well, so avoid this corner
3752*a9fa9459Szrj case for those instructions that use MODRM. */
3753*a9fa9459Szrj if (i.tm.base_opcode == INT_OPCODE
3754*a9fa9459Szrj && !i.tm.opcode_modifier.modrm
3755*a9fa9459Szrj && i.op[0].imms->X_add_number == 3)
3756*a9fa9459Szrj {
3757*a9fa9459Szrj i.tm.base_opcode = INT3_OPCODE;
3758*a9fa9459Szrj i.imm_operands = 0;
3759*a9fa9459Szrj }
3760*a9fa9459Szrj
3761*a9fa9459Szrj if ((i.tm.opcode_modifier.jump
3762*a9fa9459Szrj || i.tm.opcode_modifier.jumpbyte
3763*a9fa9459Szrj || i.tm.opcode_modifier.jumpdword)
3764*a9fa9459Szrj && i.op[0].disps->X_op == O_constant)
3765*a9fa9459Szrj {
3766*a9fa9459Szrj /* Convert "jmp constant" (and "call constant") to a jump (call) to
3767*a9fa9459Szrj the absolute address given by the constant. Since ix86 jumps and
3768*a9fa9459Szrj calls are pc relative, we need to generate a reloc. */
3769*a9fa9459Szrj i.op[0].disps->X_add_symbol = &abs_symbol;
3770*a9fa9459Szrj i.op[0].disps->X_op = O_symbol;
3771*a9fa9459Szrj }
3772*a9fa9459Szrj
3773*a9fa9459Szrj if (i.tm.opcode_modifier.rex64)
3774*a9fa9459Szrj i.rex |= REX_W;
3775*a9fa9459Szrj
3776*a9fa9459Szrj /* For 8 bit registers we need an empty rex prefix. Also if the
3777*a9fa9459Szrj instruction already has a prefix, we need to convert old
3778*a9fa9459Szrj registers to new ones. */
3779*a9fa9459Szrj
3780*a9fa9459Szrj if ((i.types[0].bitfield.reg8
3781*a9fa9459Szrj && (i.op[0].regs->reg_flags & RegRex64) != 0)
3782*a9fa9459Szrj || (i.types[1].bitfield.reg8
3783*a9fa9459Szrj && (i.op[1].regs->reg_flags & RegRex64) != 0)
3784*a9fa9459Szrj || ((i.types[0].bitfield.reg8
3785*a9fa9459Szrj || i.types[1].bitfield.reg8)
3786*a9fa9459Szrj && i.rex != 0))
3787*a9fa9459Szrj {
3788*a9fa9459Szrj int x;
3789*a9fa9459Szrj
3790*a9fa9459Szrj i.rex |= REX_OPCODE;
3791*a9fa9459Szrj for (x = 0; x < 2; x++)
3792*a9fa9459Szrj {
3793*a9fa9459Szrj /* Look for 8 bit operand that uses old registers. */
3794*a9fa9459Szrj if (i.types[x].bitfield.reg8
3795*a9fa9459Szrj && (i.op[x].regs->reg_flags & RegRex64) == 0)
3796*a9fa9459Szrj {
3797*a9fa9459Szrj /* In case it is "hi" register, give up. */
3798*a9fa9459Szrj if (i.op[x].regs->reg_num > 3)
3799*a9fa9459Szrj as_bad (_("can't encode register '%s%s' in an "
3800*a9fa9459Szrj "instruction requiring REX prefix."),
3801*a9fa9459Szrj register_prefix, i.op[x].regs->reg_name);
3802*a9fa9459Szrj
3803*a9fa9459Szrj /* Otherwise it is equivalent to the extended register.
3804*a9fa9459Szrj Since the encoding doesn't change this is merely
3805*a9fa9459Szrj cosmetic cleanup for debug output. */
3806*a9fa9459Szrj
3807*a9fa9459Szrj i.op[x].regs = i.op[x].regs + 8;
3808*a9fa9459Szrj }
3809*a9fa9459Szrj }
3810*a9fa9459Szrj }
3811*a9fa9459Szrj
3812*a9fa9459Szrj if (i.rex != 0)
3813*a9fa9459Szrj add_prefix (REX_OPCODE | i.rex);
3814*a9fa9459Szrj
3815*a9fa9459Szrj /* We are ready to output the insn. */
3816*a9fa9459Szrj output_insn ();
3817*a9fa9459Szrj }
3818*a9fa9459Szrj
3819*a9fa9459Szrj static char *
parse_insn(char * line,char * mnemonic)3820*a9fa9459Szrj parse_insn (char *line, char *mnemonic)
3821*a9fa9459Szrj {
3822*a9fa9459Szrj char *l = line;
3823*a9fa9459Szrj char *token_start = l;
3824*a9fa9459Szrj char *mnem_p;
3825*a9fa9459Szrj int supported;
3826*a9fa9459Szrj const insn_template *t;
3827*a9fa9459Szrj char *dot_p = NULL;
3828*a9fa9459Szrj
3829*a9fa9459Szrj while (1)
3830*a9fa9459Szrj {
3831*a9fa9459Szrj mnem_p = mnemonic;
3832*a9fa9459Szrj while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
3833*a9fa9459Szrj {
3834*a9fa9459Szrj if (*mnem_p == '.')
3835*a9fa9459Szrj dot_p = mnem_p;
3836*a9fa9459Szrj mnem_p++;
3837*a9fa9459Szrj if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
3838*a9fa9459Szrj {
3839*a9fa9459Szrj as_bad (_("no such instruction: `%s'"), token_start);
3840*a9fa9459Szrj return NULL;
3841*a9fa9459Szrj }
3842*a9fa9459Szrj l++;
3843*a9fa9459Szrj }
3844*a9fa9459Szrj if (!is_space_char (*l)
3845*a9fa9459Szrj && *l != END_OF_INSN
3846*a9fa9459Szrj && (intel_syntax
3847*a9fa9459Szrj || (*l != PREFIX_SEPARATOR
3848*a9fa9459Szrj && *l != ',')))
3849*a9fa9459Szrj {
3850*a9fa9459Szrj as_bad (_("invalid character %s in mnemonic"),
3851*a9fa9459Szrj output_invalid (*l));
3852*a9fa9459Szrj return NULL;
3853*a9fa9459Szrj }
3854*a9fa9459Szrj if (token_start == l)
3855*a9fa9459Szrj {
3856*a9fa9459Szrj if (!intel_syntax && *l == PREFIX_SEPARATOR)
3857*a9fa9459Szrj as_bad (_("expecting prefix; got nothing"));
3858*a9fa9459Szrj else
3859*a9fa9459Szrj as_bad (_("expecting mnemonic; got nothing"));
3860*a9fa9459Szrj return NULL;
3861*a9fa9459Szrj }
3862*a9fa9459Szrj
3863*a9fa9459Szrj /* Look up instruction (or prefix) via hash table. */
3864*a9fa9459Szrj current_templates = (const templates *) hash_find (op_hash, mnemonic);
3865*a9fa9459Szrj
3866*a9fa9459Szrj if (*l != END_OF_INSN
3867*a9fa9459Szrj && (!is_space_char (*l) || l[1] != END_OF_INSN)
3868*a9fa9459Szrj && current_templates
3869*a9fa9459Szrj && current_templates->start->opcode_modifier.isprefix)
3870*a9fa9459Szrj {
3871*a9fa9459Szrj if (!cpu_flags_check_cpu64 (current_templates->start->cpu_flags))
3872*a9fa9459Szrj {
3873*a9fa9459Szrj as_bad ((flag_code != CODE_64BIT
3874*a9fa9459Szrj ? _("`%s' is only supported in 64-bit mode")
3875*a9fa9459Szrj : _("`%s' is not supported in 64-bit mode")),
3876*a9fa9459Szrj current_templates->start->name);
3877*a9fa9459Szrj return NULL;
3878*a9fa9459Szrj }
3879*a9fa9459Szrj /* If we are in 16-bit mode, do not allow addr16 or data16.
3880*a9fa9459Szrj Similarly, in 32-bit mode, do not allow addr32 or data32. */
3881*a9fa9459Szrj if ((current_templates->start->opcode_modifier.size16
3882*a9fa9459Szrj || current_templates->start->opcode_modifier.size32)
3883*a9fa9459Szrj && flag_code != CODE_64BIT
3884*a9fa9459Szrj && (current_templates->start->opcode_modifier.size32
3885*a9fa9459Szrj ^ (flag_code == CODE_16BIT)))
3886*a9fa9459Szrj {
3887*a9fa9459Szrj as_bad (_("redundant %s prefix"),
3888*a9fa9459Szrj current_templates->start->name);
3889*a9fa9459Szrj return NULL;
3890*a9fa9459Szrj }
3891*a9fa9459Szrj /* Add prefix, checking for repeated prefixes. */
3892*a9fa9459Szrj switch (add_prefix (current_templates->start->base_opcode))
3893*a9fa9459Szrj {
3894*a9fa9459Szrj case PREFIX_EXIST:
3895*a9fa9459Szrj return NULL;
3896*a9fa9459Szrj case PREFIX_REP:
3897*a9fa9459Szrj if (current_templates->start->cpu_flags.bitfield.cpuhle)
3898*a9fa9459Szrj i.hle_prefix = current_templates->start->name;
3899*a9fa9459Szrj else if (current_templates->start->cpu_flags.bitfield.cpumpx)
3900*a9fa9459Szrj i.bnd_prefix = current_templates->start->name;
3901*a9fa9459Szrj else
3902*a9fa9459Szrj i.rep_prefix = current_templates->start->name;
3903*a9fa9459Szrj break;
3904*a9fa9459Szrj default:
3905*a9fa9459Szrj break;
3906*a9fa9459Szrj }
3907*a9fa9459Szrj /* Skip past PREFIX_SEPARATOR and reset token_start. */
3908*a9fa9459Szrj token_start = ++l;
3909*a9fa9459Szrj }
3910*a9fa9459Szrj else
3911*a9fa9459Szrj break;
3912*a9fa9459Szrj }
3913*a9fa9459Szrj
3914*a9fa9459Szrj if (!current_templates)
3915*a9fa9459Szrj {
3916*a9fa9459Szrj /* Check if we should swap operand or force 32bit displacement in
3917*a9fa9459Szrj encoding. */
3918*a9fa9459Szrj if (mnem_p - 2 == dot_p && dot_p[1] == 's')
3919*a9fa9459Szrj i.swap_operand = 1;
3920*a9fa9459Szrj else if (mnem_p - 3 == dot_p
3921*a9fa9459Szrj && dot_p[1] == 'd'
3922*a9fa9459Szrj && dot_p[2] == '8')
3923*a9fa9459Szrj i.disp_encoding = disp_encoding_8bit;
3924*a9fa9459Szrj else if (mnem_p - 4 == dot_p
3925*a9fa9459Szrj && dot_p[1] == 'd'
3926*a9fa9459Szrj && dot_p[2] == '3'
3927*a9fa9459Szrj && dot_p[3] == '2')
3928*a9fa9459Szrj i.disp_encoding = disp_encoding_32bit;
3929*a9fa9459Szrj else
3930*a9fa9459Szrj goto check_suffix;
3931*a9fa9459Szrj mnem_p = dot_p;
3932*a9fa9459Szrj *dot_p = '\0';
3933*a9fa9459Szrj current_templates = (const templates *) hash_find (op_hash, mnemonic);
3934*a9fa9459Szrj }
3935*a9fa9459Szrj
3936*a9fa9459Szrj if (!current_templates)
3937*a9fa9459Szrj {
3938*a9fa9459Szrj check_suffix:
3939*a9fa9459Szrj /* See if we can get a match by trimming off a suffix. */
3940*a9fa9459Szrj switch (mnem_p[-1])
3941*a9fa9459Szrj {
3942*a9fa9459Szrj case WORD_MNEM_SUFFIX:
3943*a9fa9459Szrj if (intel_syntax && (intel_float_operand (mnemonic) & 2))
3944*a9fa9459Szrj i.suffix = SHORT_MNEM_SUFFIX;
3945*a9fa9459Szrj else
3946*a9fa9459Szrj case BYTE_MNEM_SUFFIX:
3947*a9fa9459Szrj case QWORD_MNEM_SUFFIX:
3948*a9fa9459Szrj i.suffix = mnem_p[-1];
3949*a9fa9459Szrj mnem_p[-1] = '\0';
3950*a9fa9459Szrj current_templates = (const templates *) hash_find (op_hash,
3951*a9fa9459Szrj mnemonic);
3952*a9fa9459Szrj break;
3953*a9fa9459Szrj case SHORT_MNEM_SUFFIX:
3954*a9fa9459Szrj case LONG_MNEM_SUFFIX:
3955*a9fa9459Szrj if (!intel_syntax)
3956*a9fa9459Szrj {
3957*a9fa9459Szrj i.suffix = mnem_p[-1];
3958*a9fa9459Szrj mnem_p[-1] = '\0';
3959*a9fa9459Szrj current_templates = (const templates *) hash_find (op_hash,
3960*a9fa9459Szrj mnemonic);
3961*a9fa9459Szrj }
3962*a9fa9459Szrj break;
3963*a9fa9459Szrj
3964*a9fa9459Szrj /* Intel Syntax. */
3965*a9fa9459Szrj case 'd':
3966*a9fa9459Szrj if (intel_syntax)
3967*a9fa9459Szrj {
3968*a9fa9459Szrj if (intel_float_operand (mnemonic) == 1)
3969*a9fa9459Szrj i.suffix = SHORT_MNEM_SUFFIX;
3970*a9fa9459Szrj else
3971*a9fa9459Szrj i.suffix = LONG_MNEM_SUFFIX;
3972*a9fa9459Szrj mnem_p[-1] = '\0';
3973*a9fa9459Szrj current_templates = (const templates *) hash_find (op_hash,
3974*a9fa9459Szrj mnemonic);
3975*a9fa9459Szrj }
3976*a9fa9459Szrj break;
3977*a9fa9459Szrj }
3978*a9fa9459Szrj if (!current_templates)
3979*a9fa9459Szrj {
3980*a9fa9459Szrj as_bad (_("no such instruction: `%s'"), token_start);
3981*a9fa9459Szrj return NULL;
3982*a9fa9459Szrj }
3983*a9fa9459Szrj }
3984*a9fa9459Szrj
3985*a9fa9459Szrj if (current_templates->start->opcode_modifier.jump
3986*a9fa9459Szrj || current_templates->start->opcode_modifier.jumpbyte)
3987*a9fa9459Szrj {
3988*a9fa9459Szrj /* Check for a branch hint. We allow ",pt" and ",pn" for
3989*a9fa9459Szrj predict taken and predict not taken respectively.
3990*a9fa9459Szrj I'm not sure that branch hints actually do anything on loop
3991*a9fa9459Szrj and jcxz insns (JumpByte) for current Pentium4 chips. They
3992*a9fa9459Szrj may work in the future and it doesn't hurt to accept them
3993*a9fa9459Szrj now. */
3994*a9fa9459Szrj if (l[0] == ',' && l[1] == 'p')
3995*a9fa9459Szrj {
3996*a9fa9459Szrj if (l[2] == 't')
3997*a9fa9459Szrj {
3998*a9fa9459Szrj if (!add_prefix (DS_PREFIX_OPCODE))
3999*a9fa9459Szrj return NULL;
4000*a9fa9459Szrj l += 3;
4001*a9fa9459Szrj }
4002*a9fa9459Szrj else if (l[2] == 'n')
4003*a9fa9459Szrj {
4004*a9fa9459Szrj if (!add_prefix (CS_PREFIX_OPCODE))
4005*a9fa9459Szrj return NULL;
4006*a9fa9459Szrj l += 3;
4007*a9fa9459Szrj }
4008*a9fa9459Szrj }
4009*a9fa9459Szrj }
4010*a9fa9459Szrj /* Any other comma loses. */
4011*a9fa9459Szrj if (*l == ',')
4012*a9fa9459Szrj {
4013*a9fa9459Szrj as_bad (_("invalid character %s in mnemonic"),
4014*a9fa9459Szrj output_invalid (*l));
4015*a9fa9459Szrj return NULL;
4016*a9fa9459Szrj }
4017*a9fa9459Szrj
4018*a9fa9459Szrj /* Check if instruction is supported on specified architecture. */
4019*a9fa9459Szrj supported = 0;
4020*a9fa9459Szrj for (t = current_templates->start; t < current_templates->end; ++t)
4021*a9fa9459Szrj {
4022*a9fa9459Szrj supported |= cpu_flags_match (t);
4023*a9fa9459Szrj if (supported == CPU_FLAGS_PERFECT_MATCH)
4024*a9fa9459Szrj goto skip;
4025*a9fa9459Szrj }
4026*a9fa9459Szrj
4027*a9fa9459Szrj if (!(supported & CPU_FLAGS_64BIT_MATCH))
4028*a9fa9459Szrj {
4029*a9fa9459Szrj as_bad (flag_code == CODE_64BIT
4030*a9fa9459Szrj ? _("`%s' is not supported in 64-bit mode")
4031*a9fa9459Szrj : _("`%s' is only supported in 64-bit mode"),
4032*a9fa9459Szrj current_templates->start->name);
4033*a9fa9459Szrj return NULL;
4034*a9fa9459Szrj }
4035*a9fa9459Szrj if (supported != CPU_FLAGS_PERFECT_MATCH)
4036*a9fa9459Szrj {
4037*a9fa9459Szrj as_bad (_("`%s' is not supported on `%s%s'"),
4038*a9fa9459Szrj current_templates->start->name,
4039*a9fa9459Szrj cpu_arch_name ? cpu_arch_name : default_arch,
4040*a9fa9459Szrj cpu_sub_arch_name ? cpu_sub_arch_name : "");
4041*a9fa9459Szrj return NULL;
4042*a9fa9459Szrj }
4043*a9fa9459Szrj
4044*a9fa9459Szrj skip:
4045*a9fa9459Szrj if (!cpu_arch_flags.bitfield.cpui386
4046*a9fa9459Szrj && (flag_code != CODE_16BIT))
4047*a9fa9459Szrj {
4048*a9fa9459Szrj as_warn (_("use .code16 to ensure correct addressing mode"));
4049*a9fa9459Szrj }
4050*a9fa9459Szrj
4051*a9fa9459Szrj return l;
4052*a9fa9459Szrj }
4053*a9fa9459Szrj
4054*a9fa9459Szrj static char *
parse_operands(char * l,const char * mnemonic)4055*a9fa9459Szrj parse_operands (char *l, const char *mnemonic)
4056*a9fa9459Szrj {
4057*a9fa9459Szrj char *token_start;
4058*a9fa9459Szrj
4059*a9fa9459Szrj /* 1 if operand is pending after ','. */
4060*a9fa9459Szrj unsigned int expecting_operand = 0;
4061*a9fa9459Szrj
4062*a9fa9459Szrj /* Non-zero if operand parens not balanced. */
4063*a9fa9459Szrj unsigned int paren_not_balanced;
4064*a9fa9459Szrj
4065*a9fa9459Szrj while (*l != END_OF_INSN)
4066*a9fa9459Szrj {
4067*a9fa9459Szrj /* Skip optional white space before operand. */
4068*a9fa9459Szrj if (is_space_char (*l))
4069*a9fa9459Szrj ++l;
4070*a9fa9459Szrj if (!is_operand_char (*l) && *l != END_OF_INSN && *l != '"')
4071*a9fa9459Szrj {
4072*a9fa9459Szrj as_bad (_("invalid character %s before operand %d"),
4073*a9fa9459Szrj output_invalid (*l),
4074*a9fa9459Szrj i.operands + 1);
4075*a9fa9459Szrj return NULL;
4076*a9fa9459Szrj }
4077*a9fa9459Szrj token_start = l; /* After white space. */
4078*a9fa9459Szrj paren_not_balanced = 0;
4079*a9fa9459Szrj while (paren_not_balanced || *l != ',')
4080*a9fa9459Szrj {
4081*a9fa9459Szrj if (*l == END_OF_INSN)
4082*a9fa9459Szrj {
4083*a9fa9459Szrj if (paren_not_balanced)
4084*a9fa9459Szrj {
4085*a9fa9459Szrj if (!intel_syntax)
4086*a9fa9459Szrj as_bad (_("unbalanced parenthesis in operand %d."),
4087*a9fa9459Szrj i.operands + 1);
4088*a9fa9459Szrj else
4089*a9fa9459Szrj as_bad (_("unbalanced brackets in operand %d."),
4090*a9fa9459Szrj i.operands + 1);
4091*a9fa9459Szrj return NULL;
4092*a9fa9459Szrj }
4093*a9fa9459Szrj else
4094*a9fa9459Szrj break; /* we are done */
4095*a9fa9459Szrj }
4096*a9fa9459Szrj else if (!is_operand_char (*l) && !is_space_char (*l) && *l != '"')
4097*a9fa9459Szrj {
4098*a9fa9459Szrj as_bad (_("invalid character %s in operand %d"),
4099*a9fa9459Szrj output_invalid (*l),
4100*a9fa9459Szrj i.operands + 1);
4101*a9fa9459Szrj return NULL;
4102*a9fa9459Szrj }
4103*a9fa9459Szrj if (!intel_syntax)
4104*a9fa9459Szrj {
4105*a9fa9459Szrj if (*l == '(')
4106*a9fa9459Szrj ++paren_not_balanced;
4107*a9fa9459Szrj if (*l == ')')
4108*a9fa9459Szrj --paren_not_balanced;
4109*a9fa9459Szrj }
4110*a9fa9459Szrj else
4111*a9fa9459Szrj {
4112*a9fa9459Szrj if (*l == '[')
4113*a9fa9459Szrj ++paren_not_balanced;
4114*a9fa9459Szrj if (*l == ']')
4115*a9fa9459Szrj --paren_not_balanced;
4116*a9fa9459Szrj }
4117*a9fa9459Szrj l++;
4118*a9fa9459Szrj }
4119*a9fa9459Szrj if (l != token_start)
4120*a9fa9459Szrj { /* Yes, we've read in another operand. */
4121*a9fa9459Szrj unsigned int operand_ok;
4122*a9fa9459Szrj this_operand = i.operands++;
4123*a9fa9459Szrj i.types[this_operand].bitfield.unspecified = 1;
4124*a9fa9459Szrj if (i.operands > MAX_OPERANDS)
4125*a9fa9459Szrj {
4126*a9fa9459Szrj as_bad (_("spurious operands; (%d operands/instruction max)"),
4127*a9fa9459Szrj MAX_OPERANDS);
4128*a9fa9459Szrj return NULL;
4129*a9fa9459Szrj }
4130*a9fa9459Szrj /* Now parse operand adding info to 'i' as we go along. */
4131*a9fa9459Szrj END_STRING_AND_SAVE (l);
4132*a9fa9459Szrj
4133*a9fa9459Szrj if (intel_syntax)
4134*a9fa9459Szrj operand_ok =
4135*a9fa9459Szrj i386_intel_operand (token_start,
4136*a9fa9459Szrj intel_float_operand (mnemonic));
4137*a9fa9459Szrj else
4138*a9fa9459Szrj operand_ok = i386_att_operand (token_start);
4139*a9fa9459Szrj
4140*a9fa9459Szrj RESTORE_END_STRING (l);
4141*a9fa9459Szrj if (!operand_ok)
4142*a9fa9459Szrj return NULL;
4143*a9fa9459Szrj }
4144*a9fa9459Szrj else
4145*a9fa9459Szrj {
4146*a9fa9459Szrj if (expecting_operand)
4147*a9fa9459Szrj {
4148*a9fa9459Szrj expecting_operand_after_comma:
4149*a9fa9459Szrj as_bad (_("expecting operand after ','; got nothing"));
4150*a9fa9459Szrj return NULL;
4151*a9fa9459Szrj }
4152*a9fa9459Szrj if (*l == ',')
4153*a9fa9459Szrj {
4154*a9fa9459Szrj as_bad (_("expecting operand before ','; got nothing"));
4155*a9fa9459Szrj return NULL;
4156*a9fa9459Szrj }
4157*a9fa9459Szrj }
4158*a9fa9459Szrj
4159*a9fa9459Szrj /* Now *l must be either ',' or END_OF_INSN. */
4160*a9fa9459Szrj if (*l == ',')
4161*a9fa9459Szrj {
4162*a9fa9459Szrj if (*++l == END_OF_INSN)
4163*a9fa9459Szrj {
4164*a9fa9459Szrj /* Just skip it, if it's \n complain. */
4165*a9fa9459Szrj goto expecting_operand_after_comma;
4166*a9fa9459Szrj }
4167*a9fa9459Szrj expecting_operand = 1;
4168*a9fa9459Szrj }
4169*a9fa9459Szrj }
4170*a9fa9459Szrj return l;
4171*a9fa9459Szrj }
4172*a9fa9459Szrj
4173*a9fa9459Szrj static void
swap_2_operands(int xchg1,int xchg2)4174*a9fa9459Szrj swap_2_operands (int xchg1, int xchg2)
4175*a9fa9459Szrj {
4176*a9fa9459Szrj union i386_op temp_op;
4177*a9fa9459Szrj i386_operand_type temp_type;
4178*a9fa9459Szrj enum bfd_reloc_code_real temp_reloc;
4179*a9fa9459Szrj
4180*a9fa9459Szrj temp_type = i.types[xchg2];
4181*a9fa9459Szrj i.types[xchg2] = i.types[xchg1];
4182*a9fa9459Szrj i.types[xchg1] = temp_type;
4183*a9fa9459Szrj temp_op = i.op[xchg2];
4184*a9fa9459Szrj i.op[xchg2] = i.op[xchg1];
4185*a9fa9459Szrj i.op[xchg1] = temp_op;
4186*a9fa9459Szrj temp_reloc = i.reloc[xchg2];
4187*a9fa9459Szrj i.reloc[xchg2] = i.reloc[xchg1];
4188*a9fa9459Szrj i.reloc[xchg1] = temp_reloc;
4189*a9fa9459Szrj
4190*a9fa9459Szrj if (i.mask)
4191*a9fa9459Szrj {
4192*a9fa9459Szrj if (i.mask->operand == xchg1)
4193*a9fa9459Szrj i.mask->operand = xchg2;
4194*a9fa9459Szrj else if (i.mask->operand == xchg2)
4195*a9fa9459Szrj i.mask->operand = xchg1;
4196*a9fa9459Szrj }
4197*a9fa9459Szrj if (i.broadcast)
4198*a9fa9459Szrj {
4199*a9fa9459Szrj if (i.broadcast->operand == xchg1)
4200*a9fa9459Szrj i.broadcast->operand = xchg2;
4201*a9fa9459Szrj else if (i.broadcast->operand == xchg2)
4202*a9fa9459Szrj i.broadcast->operand = xchg1;
4203*a9fa9459Szrj }
4204*a9fa9459Szrj if (i.rounding)
4205*a9fa9459Szrj {
4206*a9fa9459Szrj if (i.rounding->operand == xchg1)
4207*a9fa9459Szrj i.rounding->operand = xchg2;
4208*a9fa9459Szrj else if (i.rounding->operand == xchg2)
4209*a9fa9459Szrj i.rounding->operand = xchg1;
4210*a9fa9459Szrj }
4211*a9fa9459Szrj }
4212*a9fa9459Szrj
4213*a9fa9459Szrj static void
swap_operands(void)4214*a9fa9459Szrj swap_operands (void)
4215*a9fa9459Szrj {
4216*a9fa9459Szrj switch (i.operands)
4217*a9fa9459Szrj {
4218*a9fa9459Szrj case 5:
4219*a9fa9459Szrj case 4:
4220*a9fa9459Szrj swap_2_operands (1, i.operands - 2);
4221*a9fa9459Szrj case 3:
4222*a9fa9459Szrj case 2:
4223*a9fa9459Szrj swap_2_operands (0, i.operands - 1);
4224*a9fa9459Szrj break;
4225*a9fa9459Szrj default:
4226*a9fa9459Szrj abort ();
4227*a9fa9459Szrj }
4228*a9fa9459Szrj
4229*a9fa9459Szrj if (i.mem_operands == 2)
4230*a9fa9459Szrj {
4231*a9fa9459Szrj const seg_entry *temp_seg;
4232*a9fa9459Szrj temp_seg = i.seg[0];
4233*a9fa9459Szrj i.seg[0] = i.seg[1];
4234*a9fa9459Szrj i.seg[1] = temp_seg;
4235*a9fa9459Szrj }
4236*a9fa9459Szrj }
4237*a9fa9459Szrj
4238*a9fa9459Szrj /* Try to ensure constant immediates are represented in the smallest
4239*a9fa9459Szrj opcode possible. */
4240*a9fa9459Szrj static void
optimize_imm(void)4241*a9fa9459Szrj optimize_imm (void)
4242*a9fa9459Szrj {
4243*a9fa9459Szrj char guess_suffix = 0;
4244*a9fa9459Szrj int op;
4245*a9fa9459Szrj
4246*a9fa9459Szrj if (i.suffix)
4247*a9fa9459Szrj guess_suffix = i.suffix;
4248*a9fa9459Szrj else if (i.reg_operands)
4249*a9fa9459Szrj {
4250*a9fa9459Szrj /* Figure out a suffix from the last register operand specified.
4251*a9fa9459Szrj We can't do this properly yet, ie. excluding InOutPortReg,
4252*a9fa9459Szrj but the following works for instructions with immediates.
4253*a9fa9459Szrj In any case, we can't set i.suffix yet. */
4254*a9fa9459Szrj for (op = i.operands; --op >= 0;)
4255*a9fa9459Szrj if (i.types[op].bitfield.reg8)
4256*a9fa9459Szrj {
4257*a9fa9459Szrj guess_suffix = BYTE_MNEM_SUFFIX;
4258*a9fa9459Szrj break;
4259*a9fa9459Szrj }
4260*a9fa9459Szrj else if (i.types[op].bitfield.reg16)
4261*a9fa9459Szrj {
4262*a9fa9459Szrj guess_suffix = WORD_MNEM_SUFFIX;
4263*a9fa9459Szrj break;
4264*a9fa9459Szrj }
4265*a9fa9459Szrj else if (i.types[op].bitfield.reg32)
4266*a9fa9459Szrj {
4267*a9fa9459Szrj guess_suffix = LONG_MNEM_SUFFIX;
4268*a9fa9459Szrj break;
4269*a9fa9459Szrj }
4270*a9fa9459Szrj else if (i.types[op].bitfield.reg64)
4271*a9fa9459Szrj {
4272*a9fa9459Szrj guess_suffix = QWORD_MNEM_SUFFIX;
4273*a9fa9459Szrj break;
4274*a9fa9459Szrj }
4275*a9fa9459Szrj }
4276*a9fa9459Szrj else if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
4277*a9fa9459Szrj guess_suffix = WORD_MNEM_SUFFIX;
4278*a9fa9459Szrj
4279*a9fa9459Szrj for (op = i.operands; --op >= 0;)
4280*a9fa9459Szrj if (operand_type_check (i.types[op], imm))
4281*a9fa9459Szrj {
4282*a9fa9459Szrj switch (i.op[op].imms->X_op)
4283*a9fa9459Szrj {
4284*a9fa9459Szrj case O_constant:
4285*a9fa9459Szrj /* If a suffix is given, this operand may be shortened. */
4286*a9fa9459Szrj switch (guess_suffix)
4287*a9fa9459Szrj {
4288*a9fa9459Szrj case LONG_MNEM_SUFFIX:
4289*a9fa9459Szrj i.types[op].bitfield.imm32 = 1;
4290*a9fa9459Szrj i.types[op].bitfield.imm64 = 1;
4291*a9fa9459Szrj break;
4292*a9fa9459Szrj case WORD_MNEM_SUFFIX:
4293*a9fa9459Szrj i.types[op].bitfield.imm16 = 1;
4294*a9fa9459Szrj i.types[op].bitfield.imm32 = 1;
4295*a9fa9459Szrj i.types[op].bitfield.imm32s = 1;
4296*a9fa9459Szrj i.types[op].bitfield.imm64 = 1;
4297*a9fa9459Szrj break;
4298*a9fa9459Szrj case BYTE_MNEM_SUFFIX:
4299*a9fa9459Szrj i.types[op].bitfield.imm8 = 1;
4300*a9fa9459Szrj i.types[op].bitfield.imm8s = 1;
4301*a9fa9459Szrj i.types[op].bitfield.imm16 = 1;
4302*a9fa9459Szrj i.types[op].bitfield.imm32 = 1;
4303*a9fa9459Szrj i.types[op].bitfield.imm32s = 1;
4304*a9fa9459Szrj i.types[op].bitfield.imm64 = 1;
4305*a9fa9459Szrj break;
4306*a9fa9459Szrj }
4307*a9fa9459Szrj
4308*a9fa9459Szrj /* If this operand is at most 16 bits, convert it
4309*a9fa9459Szrj to a signed 16 bit number before trying to see
4310*a9fa9459Szrj whether it will fit in an even smaller size.
4311*a9fa9459Szrj This allows a 16-bit operand such as $0xffe0 to
4312*a9fa9459Szrj be recognised as within Imm8S range. */
4313*a9fa9459Szrj if ((i.types[op].bitfield.imm16)
4314*a9fa9459Szrj && (i.op[op].imms->X_add_number & ~(offsetT) 0xffff) == 0)
4315*a9fa9459Szrj {
4316*a9fa9459Szrj i.op[op].imms->X_add_number =
4317*a9fa9459Szrj (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000);
4318*a9fa9459Szrj }
4319*a9fa9459Szrj #ifdef BFD64
4320*a9fa9459Szrj /* Store 32-bit immediate in 64-bit for 64-bit BFD. */
4321*a9fa9459Szrj if ((i.types[op].bitfield.imm32)
4322*a9fa9459Szrj && ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1))
4323*a9fa9459Szrj == 0))
4324*a9fa9459Szrj {
4325*a9fa9459Szrj i.op[op].imms->X_add_number = ((i.op[op].imms->X_add_number
4326*a9fa9459Szrj ^ ((offsetT) 1 << 31))
4327*a9fa9459Szrj - ((offsetT) 1 << 31));
4328*a9fa9459Szrj }
4329*a9fa9459Szrj #endif
4330*a9fa9459Szrj i.types[op]
4331*a9fa9459Szrj = operand_type_or (i.types[op],
4332*a9fa9459Szrj smallest_imm_type (i.op[op].imms->X_add_number));
4333*a9fa9459Szrj
4334*a9fa9459Szrj /* We must avoid matching of Imm32 templates when 64bit
4335*a9fa9459Szrj only immediate is available. */
4336*a9fa9459Szrj if (guess_suffix == QWORD_MNEM_SUFFIX)
4337*a9fa9459Szrj i.types[op].bitfield.imm32 = 0;
4338*a9fa9459Szrj break;
4339*a9fa9459Szrj
4340*a9fa9459Szrj case O_absent:
4341*a9fa9459Szrj case O_register:
4342*a9fa9459Szrj abort ();
4343*a9fa9459Szrj
4344*a9fa9459Szrj /* Symbols and expressions. */
4345*a9fa9459Szrj default:
4346*a9fa9459Szrj /* Convert symbolic operand to proper sizes for matching, but don't
4347*a9fa9459Szrj prevent matching a set of insns that only supports sizes other
4348*a9fa9459Szrj than those matching the insn suffix. */
4349*a9fa9459Szrj {
4350*a9fa9459Szrj i386_operand_type mask, allowed;
4351*a9fa9459Szrj const insn_template *t;
4352*a9fa9459Szrj
4353*a9fa9459Szrj operand_type_set (&mask, 0);
4354*a9fa9459Szrj operand_type_set (&allowed, 0);
4355*a9fa9459Szrj
4356*a9fa9459Szrj for (t = current_templates->start;
4357*a9fa9459Szrj t < current_templates->end;
4358*a9fa9459Szrj ++t)
4359*a9fa9459Szrj allowed = operand_type_or (allowed,
4360*a9fa9459Szrj t->operand_types[op]);
4361*a9fa9459Szrj switch (guess_suffix)
4362*a9fa9459Szrj {
4363*a9fa9459Szrj case QWORD_MNEM_SUFFIX:
4364*a9fa9459Szrj mask.bitfield.imm64 = 1;
4365*a9fa9459Szrj mask.bitfield.imm32s = 1;
4366*a9fa9459Szrj break;
4367*a9fa9459Szrj case LONG_MNEM_SUFFIX:
4368*a9fa9459Szrj mask.bitfield.imm32 = 1;
4369*a9fa9459Szrj break;
4370*a9fa9459Szrj case WORD_MNEM_SUFFIX:
4371*a9fa9459Szrj mask.bitfield.imm16 = 1;
4372*a9fa9459Szrj break;
4373*a9fa9459Szrj case BYTE_MNEM_SUFFIX:
4374*a9fa9459Szrj mask.bitfield.imm8 = 1;
4375*a9fa9459Szrj break;
4376*a9fa9459Szrj default:
4377*a9fa9459Szrj break;
4378*a9fa9459Szrj }
4379*a9fa9459Szrj allowed = operand_type_and (mask, allowed);
4380*a9fa9459Szrj if (!operand_type_all_zero (&allowed))
4381*a9fa9459Szrj i.types[op] = operand_type_and (i.types[op], mask);
4382*a9fa9459Szrj }
4383*a9fa9459Szrj break;
4384*a9fa9459Szrj }
4385*a9fa9459Szrj }
4386*a9fa9459Szrj }
4387*a9fa9459Szrj
4388*a9fa9459Szrj /* Try to use the smallest displacement type too. */
4389*a9fa9459Szrj static void
optimize_disp(void)4390*a9fa9459Szrj optimize_disp (void)
4391*a9fa9459Szrj {
4392*a9fa9459Szrj int op;
4393*a9fa9459Szrj
4394*a9fa9459Szrj for (op = i.operands; --op >= 0;)
4395*a9fa9459Szrj if (operand_type_check (i.types[op], disp))
4396*a9fa9459Szrj {
4397*a9fa9459Szrj if (i.op[op].disps->X_op == O_constant)
4398*a9fa9459Szrj {
4399*a9fa9459Szrj offsetT op_disp = i.op[op].disps->X_add_number;
4400*a9fa9459Szrj
4401*a9fa9459Szrj if (i.types[op].bitfield.disp16
4402*a9fa9459Szrj && (op_disp & ~(offsetT) 0xffff) == 0)
4403*a9fa9459Szrj {
4404*a9fa9459Szrj /* If this operand is at most 16 bits, convert
4405*a9fa9459Szrj to a signed 16 bit number and don't use 64bit
4406*a9fa9459Szrj displacement. */
4407*a9fa9459Szrj op_disp = (((op_disp & 0xffff) ^ 0x8000) - 0x8000);
4408*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
4409*a9fa9459Szrj }
4410*a9fa9459Szrj #ifdef BFD64
4411*a9fa9459Szrj /* Optimize 64-bit displacement to 32-bit for 64-bit BFD. */
4412*a9fa9459Szrj if (i.types[op].bitfield.disp32
4413*a9fa9459Szrj && (op_disp & ~(((offsetT) 2 << 31) - 1)) == 0)
4414*a9fa9459Szrj {
4415*a9fa9459Szrj /* If this operand is at most 32 bits, convert
4416*a9fa9459Szrj to a signed 32 bit number and don't use 64bit
4417*a9fa9459Szrj displacement. */
4418*a9fa9459Szrj op_disp &= (((offsetT) 2 << 31) - 1);
4419*a9fa9459Szrj op_disp = (op_disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31);
4420*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
4421*a9fa9459Szrj }
4422*a9fa9459Szrj #endif
4423*a9fa9459Szrj if (!op_disp && i.types[op].bitfield.baseindex)
4424*a9fa9459Szrj {
4425*a9fa9459Szrj i.types[op].bitfield.disp8 = 0;
4426*a9fa9459Szrj i.types[op].bitfield.disp16 = 0;
4427*a9fa9459Szrj i.types[op].bitfield.disp32 = 0;
4428*a9fa9459Szrj i.types[op].bitfield.disp32s = 0;
4429*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
4430*a9fa9459Szrj i.op[op].disps = 0;
4431*a9fa9459Szrj i.disp_operands--;
4432*a9fa9459Szrj }
4433*a9fa9459Szrj else if (flag_code == CODE_64BIT)
4434*a9fa9459Szrj {
4435*a9fa9459Szrj if (fits_in_signed_long (op_disp))
4436*a9fa9459Szrj {
4437*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
4438*a9fa9459Szrj i.types[op].bitfield.disp32s = 1;
4439*a9fa9459Szrj }
4440*a9fa9459Szrj if (i.prefix[ADDR_PREFIX]
4441*a9fa9459Szrj && fits_in_unsigned_long (op_disp))
4442*a9fa9459Szrj i.types[op].bitfield.disp32 = 1;
4443*a9fa9459Szrj }
4444*a9fa9459Szrj if ((i.types[op].bitfield.disp32
4445*a9fa9459Szrj || i.types[op].bitfield.disp32s
4446*a9fa9459Szrj || i.types[op].bitfield.disp16)
4447*a9fa9459Szrj && fits_in_signed_byte (op_disp))
4448*a9fa9459Szrj i.types[op].bitfield.disp8 = 1;
4449*a9fa9459Szrj }
4450*a9fa9459Szrj else if (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL
4451*a9fa9459Szrj || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL)
4452*a9fa9459Szrj {
4453*a9fa9459Szrj fix_new_exp (frag_now, frag_more (0) - frag_now->fr_literal, 0,
4454*a9fa9459Szrj i.op[op].disps, 0, i.reloc[op]);
4455*a9fa9459Szrj i.types[op].bitfield.disp8 = 0;
4456*a9fa9459Szrj i.types[op].bitfield.disp16 = 0;
4457*a9fa9459Szrj i.types[op].bitfield.disp32 = 0;
4458*a9fa9459Szrj i.types[op].bitfield.disp32s = 0;
4459*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
4460*a9fa9459Szrj }
4461*a9fa9459Szrj else
4462*a9fa9459Szrj /* We only support 64bit displacement on constants. */
4463*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
4464*a9fa9459Szrj }
4465*a9fa9459Szrj }
4466*a9fa9459Szrj
4467*a9fa9459Szrj /* Check if operands are valid for the instruction. */
4468*a9fa9459Szrj
4469*a9fa9459Szrj static int
check_VecOperands(const insn_template * t)4470*a9fa9459Szrj check_VecOperands (const insn_template *t)
4471*a9fa9459Szrj {
4472*a9fa9459Szrj unsigned int op;
4473*a9fa9459Szrj
4474*a9fa9459Szrj /* Without VSIB byte, we can't have a vector register for index. */
4475*a9fa9459Szrj if (!t->opcode_modifier.vecsib
4476*a9fa9459Szrj && i.index_reg
4477*a9fa9459Szrj && (i.index_reg->reg_type.bitfield.regxmm
4478*a9fa9459Szrj || i.index_reg->reg_type.bitfield.regymm
4479*a9fa9459Szrj || i.index_reg->reg_type.bitfield.regzmm))
4480*a9fa9459Szrj {
4481*a9fa9459Szrj i.error = unsupported_vector_index_register;
4482*a9fa9459Szrj return 1;
4483*a9fa9459Szrj }
4484*a9fa9459Szrj
4485*a9fa9459Szrj /* Check if default mask is allowed. */
4486*a9fa9459Szrj if (t->opcode_modifier.nodefmask
4487*a9fa9459Szrj && (!i.mask || i.mask->mask->reg_num == 0))
4488*a9fa9459Szrj {
4489*a9fa9459Szrj i.error = no_default_mask;
4490*a9fa9459Szrj return 1;
4491*a9fa9459Szrj }
4492*a9fa9459Szrj
4493*a9fa9459Szrj /* For VSIB byte, we need a vector register for index, and all vector
4494*a9fa9459Szrj registers must be distinct. */
4495*a9fa9459Szrj if (t->opcode_modifier.vecsib)
4496*a9fa9459Szrj {
4497*a9fa9459Szrj if (!i.index_reg
4498*a9fa9459Szrj || !((t->opcode_modifier.vecsib == VecSIB128
4499*a9fa9459Szrj && i.index_reg->reg_type.bitfield.regxmm)
4500*a9fa9459Szrj || (t->opcode_modifier.vecsib == VecSIB256
4501*a9fa9459Szrj && i.index_reg->reg_type.bitfield.regymm)
4502*a9fa9459Szrj || (t->opcode_modifier.vecsib == VecSIB512
4503*a9fa9459Szrj && i.index_reg->reg_type.bitfield.regzmm)))
4504*a9fa9459Szrj {
4505*a9fa9459Szrj i.error = invalid_vsib_address;
4506*a9fa9459Szrj return 1;
4507*a9fa9459Szrj }
4508*a9fa9459Szrj
4509*a9fa9459Szrj gas_assert (i.reg_operands == 2 || i.mask);
4510*a9fa9459Szrj if (i.reg_operands == 2 && !i.mask)
4511*a9fa9459Szrj {
4512*a9fa9459Szrj gas_assert (i.types[0].bitfield.regxmm
4513*a9fa9459Szrj || i.types[0].bitfield.regymm);
4514*a9fa9459Szrj gas_assert (i.types[2].bitfield.regxmm
4515*a9fa9459Szrj || i.types[2].bitfield.regymm);
4516*a9fa9459Szrj if (operand_check == check_none)
4517*a9fa9459Szrj return 0;
4518*a9fa9459Szrj if (register_number (i.op[0].regs)
4519*a9fa9459Szrj != register_number (i.index_reg)
4520*a9fa9459Szrj && register_number (i.op[2].regs)
4521*a9fa9459Szrj != register_number (i.index_reg)
4522*a9fa9459Szrj && register_number (i.op[0].regs)
4523*a9fa9459Szrj != register_number (i.op[2].regs))
4524*a9fa9459Szrj return 0;
4525*a9fa9459Szrj if (operand_check == check_error)
4526*a9fa9459Szrj {
4527*a9fa9459Szrj i.error = invalid_vector_register_set;
4528*a9fa9459Szrj return 1;
4529*a9fa9459Szrj }
4530*a9fa9459Szrj as_warn (_("mask, index, and destination registers should be distinct"));
4531*a9fa9459Szrj }
4532*a9fa9459Szrj else if (i.reg_operands == 1 && i.mask)
4533*a9fa9459Szrj {
4534*a9fa9459Szrj if ((i.types[1].bitfield.regymm
4535*a9fa9459Szrj || i.types[1].bitfield.regzmm)
4536*a9fa9459Szrj && (register_number (i.op[1].regs)
4537*a9fa9459Szrj == register_number (i.index_reg)))
4538*a9fa9459Szrj {
4539*a9fa9459Szrj if (operand_check == check_error)
4540*a9fa9459Szrj {
4541*a9fa9459Szrj i.error = invalid_vector_register_set;
4542*a9fa9459Szrj return 1;
4543*a9fa9459Szrj }
4544*a9fa9459Szrj if (operand_check != check_none)
4545*a9fa9459Szrj as_warn (_("index and destination registers should be distinct"));
4546*a9fa9459Szrj }
4547*a9fa9459Szrj }
4548*a9fa9459Szrj }
4549*a9fa9459Szrj
4550*a9fa9459Szrj /* Check if broadcast is supported by the instruction and is applied
4551*a9fa9459Szrj to the memory operand. */
4552*a9fa9459Szrj if (i.broadcast)
4553*a9fa9459Szrj {
4554*a9fa9459Szrj int broadcasted_opnd_size;
4555*a9fa9459Szrj
4556*a9fa9459Szrj /* Check if specified broadcast is supported in this instruction,
4557*a9fa9459Szrj and it's applied to memory operand of DWORD or QWORD type,
4558*a9fa9459Szrj depending on VecESize. */
4559*a9fa9459Szrj if (i.broadcast->type != t->opcode_modifier.broadcast
4560*a9fa9459Szrj || !i.types[i.broadcast->operand].bitfield.mem
4561*a9fa9459Szrj || (t->opcode_modifier.vecesize == 0
4562*a9fa9459Szrj && !i.types[i.broadcast->operand].bitfield.dword
4563*a9fa9459Szrj && !i.types[i.broadcast->operand].bitfield.unspecified)
4564*a9fa9459Szrj || (t->opcode_modifier.vecesize == 1
4565*a9fa9459Szrj && !i.types[i.broadcast->operand].bitfield.qword
4566*a9fa9459Szrj && !i.types[i.broadcast->operand].bitfield.unspecified))
4567*a9fa9459Szrj goto bad_broadcast;
4568*a9fa9459Szrj
4569*a9fa9459Szrj broadcasted_opnd_size = t->opcode_modifier.vecesize ? 64 : 32;
4570*a9fa9459Szrj if (i.broadcast->type == BROADCAST_1TO16)
4571*a9fa9459Szrj broadcasted_opnd_size <<= 4; /* Broadcast 1to16. */
4572*a9fa9459Szrj else if (i.broadcast->type == BROADCAST_1TO8)
4573*a9fa9459Szrj broadcasted_opnd_size <<= 3; /* Broadcast 1to8. */
4574*a9fa9459Szrj else if (i.broadcast->type == BROADCAST_1TO4)
4575*a9fa9459Szrj broadcasted_opnd_size <<= 2; /* Broadcast 1to4. */
4576*a9fa9459Szrj else if (i.broadcast->type == BROADCAST_1TO2)
4577*a9fa9459Szrj broadcasted_opnd_size <<= 1; /* Broadcast 1to2. */
4578*a9fa9459Szrj else
4579*a9fa9459Szrj goto bad_broadcast;
4580*a9fa9459Szrj
4581*a9fa9459Szrj if ((broadcasted_opnd_size == 256
4582*a9fa9459Szrj && !t->operand_types[i.broadcast->operand].bitfield.ymmword)
4583*a9fa9459Szrj || (broadcasted_opnd_size == 512
4584*a9fa9459Szrj && !t->operand_types[i.broadcast->operand].bitfield.zmmword))
4585*a9fa9459Szrj {
4586*a9fa9459Szrj bad_broadcast:
4587*a9fa9459Szrj i.error = unsupported_broadcast;
4588*a9fa9459Szrj return 1;
4589*a9fa9459Szrj }
4590*a9fa9459Szrj }
4591*a9fa9459Szrj /* If broadcast is supported in this instruction, we need to check if
4592*a9fa9459Szrj operand of one-element size isn't specified without broadcast. */
4593*a9fa9459Szrj else if (t->opcode_modifier.broadcast && i.mem_operands)
4594*a9fa9459Szrj {
4595*a9fa9459Szrj /* Find memory operand. */
4596*a9fa9459Szrj for (op = 0; op < i.operands; op++)
4597*a9fa9459Szrj if (operand_type_check (i.types[op], anymem))
4598*a9fa9459Szrj break;
4599*a9fa9459Szrj gas_assert (op < i.operands);
4600*a9fa9459Szrj /* Check size of the memory operand. */
4601*a9fa9459Szrj if ((t->opcode_modifier.vecesize == 0
4602*a9fa9459Szrj && i.types[op].bitfield.dword)
4603*a9fa9459Szrj || (t->opcode_modifier.vecesize == 1
4604*a9fa9459Szrj && i.types[op].bitfield.qword))
4605*a9fa9459Szrj {
4606*a9fa9459Szrj i.error = broadcast_needed;
4607*a9fa9459Szrj return 1;
4608*a9fa9459Szrj }
4609*a9fa9459Szrj }
4610*a9fa9459Szrj
4611*a9fa9459Szrj /* Check if requested masking is supported. */
4612*a9fa9459Szrj if (i.mask
4613*a9fa9459Szrj && (!t->opcode_modifier.masking
4614*a9fa9459Szrj || (i.mask->zeroing
4615*a9fa9459Szrj && t->opcode_modifier.masking == MERGING_MASKING)))
4616*a9fa9459Szrj {
4617*a9fa9459Szrj i.error = unsupported_masking;
4618*a9fa9459Szrj return 1;
4619*a9fa9459Szrj }
4620*a9fa9459Szrj
4621*a9fa9459Szrj /* Check if masking is applied to dest operand. */
4622*a9fa9459Szrj if (i.mask && (i.mask->operand != (int) (i.operands - 1)))
4623*a9fa9459Szrj {
4624*a9fa9459Szrj i.error = mask_not_on_destination;
4625*a9fa9459Szrj return 1;
4626*a9fa9459Szrj }
4627*a9fa9459Szrj
4628*a9fa9459Szrj /* Check RC/SAE. */
4629*a9fa9459Szrj if (i.rounding)
4630*a9fa9459Szrj {
4631*a9fa9459Szrj if ((i.rounding->type != saeonly
4632*a9fa9459Szrj && !t->opcode_modifier.staticrounding)
4633*a9fa9459Szrj || (i.rounding->type == saeonly
4634*a9fa9459Szrj && (t->opcode_modifier.staticrounding
4635*a9fa9459Szrj || !t->opcode_modifier.sae)))
4636*a9fa9459Szrj {
4637*a9fa9459Szrj i.error = unsupported_rc_sae;
4638*a9fa9459Szrj return 1;
4639*a9fa9459Szrj }
4640*a9fa9459Szrj /* If the instruction has several immediate operands and one of
4641*a9fa9459Szrj them is rounding, the rounding operand should be the last
4642*a9fa9459Szrj immediate operand. */
4643*a9fa9459Szrj if (i.imm_operands > 1
4644*a9fa9459Szrj && i.rounding->operand != (int) (i.imm_operands - 1))
4645*a9fa9459Szrj {
4646*a9fa9459Szrj i.error = rc_sae_operand_not_last_imm;
4647*a9fa9459Szrj return 1;
4648*a9fa9459Szrj }
4649*a9fa9459Szrj }
4650*a9fa9459Szrj
4651*a9fa9459Szrj /* Check vector Disp8 operand. */
4652*a9fa9459Szrj if (t->opcode_modifier.disp8memshift)
4653*a9fa9459Szrj {
4654*a9fa9459Szrj if (i.broadcast)
4655*a9fa9459Szrj i.memshift = t->opcode_modifier.vecesize ? 3 : 2;
4656*a9fa9459Szrj else
4657*a9fa9459Szrj i.memshift = t->opcode_modifier.disp8memshift;
4658*a9fa9459Szrj
4659*a9fa9459Szrj for (op = 0; op < i.operands; op++)
4660*a9fa9459Szrj if (operand_type_check (i.types[op], disp)
4661*a9fa9459Szrj && i.op[op].disps->X_op == O_constant)
4662*a9fa9459Szrj {
4663*a9fa9459Szrj offsetT value = i.op[op].disps->X_add_number;
4664*a9fa9459Szrj int vec_disp8_ok
4665*a9fa9459Szrj = (i.disp_encoding != disp_encoding_32bit
4666*a9fa9459Szrj && fits_in_vec_disp8 (value));
4667*a9fa9459Szrj if (t->operand_types [op].bitfield.vec_disp8)
4668*a9fa9459Szrj {
4669*a9fa9459Szrj if (vec_disp8_ok)
4670*a9fa9459Szrj i.types[op].bitfield.vec_disp8 = 1;
4671*a9fa9459Szrj else
4672*a9fa9459Szrj {
4673*a9fa9459Szrj /* Vector insn can only have Vec_Disp8/Disp32 in
4674*a9fa9459Szrj 32/64bit modes, and Vec_Disp8/Disp16 in 16bit
4675*a9fa9459Szrj mode. */
4676*a9fa9459Szrj i.types[op].bitfield.disp8 = 0;
4677*a9fa9459Szrj if (flag_code != CODE_16BIT)
4678*a9fa9459Szrj i.types[op].bitfield.disp16 = 0;
4679*a9fa9459Szrj }
4680*a9fa9459Szrj }
4681*a9fa9459Szrj else if (flag_code != CODE_16BIT)
4682*a9fa9459Szrj {
4683*a9fa9459Szrj /* One form of this instruction supports vector Disp8.
4684*a9fa9459Szrj Try vector Disp8 if we need to use Disp32. */
4685*a9fa9459Szrj if (vec_disp8_ok && !fits_in_signed_byte (value))
4686*a9fa9459Szrj {
4687*a9fa9459Szrj i.error = try_vector_disp8;
4688*a9fa9459Szrj return 1;
4689*a9fa9459Szrj }
4690*a9fa9459Szrj }
4691*a9fa9459Szrj }
4692*a9fa9459Szrj }
4693*a9fa9459Szrj else
4694*a9fa9459Szrj i.memshift = -1;
4695*a9fa9459Szrj
4696*a9fa9459Szrj return 0;
4697*a9fa9459Szrj }
4698*a9fa9459Szrj
4699*a9fa9459Szrj /* Check if operands are valid for the instruction. Update VEX
4700*a9fa9459Szrj operand types. */
4701*a9fa9459Szrj
4702*a9fa9459Szrj static int
VEX_check_operands(const insn_template * t)4703*a9fa9459Szrj VEX_check_operands (const insn_template *t)
4704*a9fa9459Szrj {
4705*a9fa9459Szrj /* VREX is only valid with EVEX prefix. */
4706*a9fa9459Szrj if (i.need_vrex && !t->opcode_modifier.evex)
4707*a9fa9459Szrj {
4708*a9fa9459Szrj i.error = invalid_register_operand;
4709*a9fa9459Szrj return 1;
4710*a9fa9459Szrj }
4711*a9fa9459Szrj
4712*a9fa9459Szrj if (!t->opcode_modifier.vex)
4713*a9fa9459Szrj return 0;
4714*a9fa9459Szrj
4715*a9fa9459Szrj /* Only check VEX_Imm4, which must be the first operand. */
4716*a9fa9459Szrj if (t->operand_types[0].bitfield.vec_imm4)
4717*a9fa9459Szrj {
4718*a9fa9459Szrj if (i.op[0].imms->X_op != O_constant
4719*a9fa9459Szrj || !fits_in_imm4 (i.op[0].imms->X_add_number))
4720*a9fa9459Szrj {
4721*a9fa9459Szrj i.error = bad_imm4;
4722*a9fa9459Szrj return 1;
4723*a9fa9459Szrj }
4724*a9fa9459Szrj
4725*a9fa9459Szrj /* Turn off Imm8 so that update_imm won't complain. */
4726*a9fa9459Szrj i.types[0] = vec_imm4;
4727*a9fa9459Szrj }
4728*a9fa9459Szrj
4729*a9fa9459Szrj return 0;
4730*a9fa9459Szrj }
4731*a9fa9459Szrj
4732*a9fa9459Szrj static const insn_template *
match_template(char mnem_suffix)4733*a9fa9459Szrj match_template (char mnem_suffix)
4734*a9fa9459Szrj {
4735*a9fa9459Szrj /* Points to template once we've found it. */
4736*a9fa9459Szrj const insn_template *t;
4737*a9fa9459Szrj i386_operand_type overlap0, overlap1, overlap2, overlap3;
4738*a9fa9459Szrj i386_operand_type overlap4;
4739*a9fa9459Szrj unsigned int found_reverse_match;
4740*a9fa9459Szrj i386_opcode_modifier suffix_check, mnemsuf_check;
4741*a9fa9459Szrj i386_operand_type operand_types [MAX_OPERANDS];
4742*a9fa9459Szrj int addr_prefix_disp;
4743*a9fa9459Szrj unsigned int j;
4744*a9fa9459Szrj unsigned int found_cpu_match;
4745*a9fa9459Szrj unsigned int check_register;
4746*a9fa9459Szrj enum i386_error specific_error = 0;
4747*a9fa9459Szrj
4748*a9fa9459Szrj #if MAX_OPERANDS != 5
4749*a9fa9459Szrj # error "MAX_OPERANDS must be 5."
4750*a9fa9459Szrj #endif
4751*a9fa9459Szrj
4752*a9fa9459Szrj found_reverse_match = 0;
4753*a9fa9459Szrj addr_prefix_disp = -1;
4754*a9fa9459Szrj
4755*a9fa9459Szrj memset (&suffix_check, 0, sizeof (suffix_check));
4756*a9fa9459Szrj if (i.suffix == BYTE_MNEM_SUFFIX)
4757*a9fa9459Szrj suffix_check.no_bsuf = 1;
4758*a9fa9459Szrj else if (i.suffix == WORD_MNEM_SUFFIX)
4759*a9fa9459Szrj suffix_check.no_wsuf = 1;
4760*a9fa9459Szrj else if (i.suffix == SHORT_MNEM_SUFFIX)
4761*a9fa9459Szrj suffix_check.no_ssuf = 1;
4762*a9fa9459Szrj else if (i.suffix == LONG_MNEM_SUFFIX)
4763*a9fa9459Szrj suffix_check.no_lsuf = 1;
4764*a9fa9459Szrj else if (i.suffix == QWORD_MNEM_SUFFIX)
4765*a9fa9459Szrj suffix_check.no_qsuf = 1;
4766*a9fa9459Szrj else if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX)
4767*a9fa9459Szrj suffix_check.no_ldsuf = 1;
4768*a9fa9459Szrj
4769*a9fa9459Szrj memset (&mnemsuf_check, 0, sizeof (mnemsuf_check));
4770*a9fa9459Szrj if (intel_syntax)
4771*a9fa9459Szrj {
4772*a9fa9459Szrj switch (mnem_suffix)
4773*a9fa9459Szrj {
4774*a9fa9459Szrj case BYTE_MNEM_SUFFIX: mnemsuf_check.no_bsuf = 1; break;
4775*a9fa9459Szrj case WORD_MNEM_SUFFIX: mnemsuf_check.no_wsuf = 1; break;
4776*a9fa9459Szrj case SHORT_MNEM_SUFFIX: mnemsuf_check.no_ssuf = 1; break;
4777*a9fa9459Szrj case LONG_MNEM_SUFFIX: mnemsuf_check.no_lsuf = 1; break;
4778*a9fa9459Szrj case QWORD_MNEM_SUFFIX: mnemsuf_check.no_qsuf = 1; break;
4779*a9fa9459Szrj }
4780*a9fa9459Szrj }
4781*a9fa9459Szrj
4782*a9fa9459Szrj /* Must have right number of operands. */
4783*a9fa9459Szrj i.error = number_of_operands_mismatch;
4784*a9fa9459Szrj
4785*a9fa9459Szrj for (t = current_templates->start; t < current_templates->end; t++)
4786*a9fa9459Szrj {
4787*a9fa9459Szrj addr_prefix_disp = -1;
4788*a9fa9459Szrj
4789*a9fa9459Szrj if (i.operands != t->operands)
4790*a9fa9459Szrj continue;
4791*a9fa9459Szrj
4792*a9fa9459Szrj /* Check processor support. */
4793*a9fa9459Szrj i.error = unsupported;
4794*a9fa9459Szrj found_cpu_match = (cpu_flags_match (t)
4795*a9fa9459Szrj == CPU_FLAGS_PERFECT_MATCH);
4796*a9fa9459Szrj if (!found_cpu_match)
4797*a9fa9459Szrj continue;
4798*a9fa9459Szrj
4799*a9fa9459Szrj /* Check old gcc support. */
4800*a9fa9459Szrj i.error = old_gcc_only;
4801*a9fa9459Szrj if (!old_gcc && t->opcode_modifier.oldgcc)
4802*a9fa9459Szrj continue;
4803*a9fa9459Szrj
4804*a9fa9459Szrj /* Check AT&T mnemonic. */
4805*a9fa9459Szrj i.error = unsupported_with_intel_mnemonic;
4806*a9fa9459Szrj if (intel_mnemonic && t->opcode_modifier.attmnemonic)
4807*a9fa9459Szrj continue;
4808*a9fa9459Szrj
4809*a9fa9459Szrj /* Check AT&T/Intel syntax and Intel64/AMD64 ISA. */
4810*a9fa9459Szrj i.error = unsupported_syntax;
4811*a9fa9459Szrj if ((intel_syntax && t->opcode_modifier.attsyntax)
4812*a9fa9459Szrj || (!intel_syntax && t->opcode_modifier.intelsyntax)
4813*a9fa9459Szrj || (intel64 && t->opcode_modifier.amd64)
4814*a9fa9459Szrj || (!intel64 && t->opcode_modifier.intel64))
4815*a9fa9459Szrj continue;
4816*a9fa9459Szrj
4817*a9fa9459Szrj /* Check the suffix, except for some instructions in intel mode. */
4818*a9fa9459Szrj i.error = invalid_instruction_suffix;
4819*a9fa9459Szrj if ((!intel_syntax || !t->opcode_modifier.ignoresize)
4820*a9fa9459Szrj && ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
4821*a9fa9459Szrj || (t->opcode_modifier.no_wsuf && suffix_check.no_wsuf)
4822*a9fa9459Szrj || (t->opcode_modifier.no_lsuf && suffix_check.no_lsuf)
4823*a9fa9459Szrj || (t->opcode_modifier.no_ssuf && suffix_check.no_ssuf)
4824*a9fa9459Szrj || (t->opcode_modifier.no_qsuf && suffix_check.no_qsuf)
4825*a9fa9459Szrj || (t->opcode_modifier.no_ldsuf && suffix_check.no_ldsuf)))
4826*a9fa9459Szrj continue;
4827*a9fa9459Szrj /* In Intel mode all mnemonic suffixes must be explicitly allowed. */
4828*a9fa9459Szrj if ((t->opcode_modifier.no_bsuf && mnemsuf_check.no_bsuf)
4829*a9fa9459Szrj || (t->opcode_modifier.no_wsuf && mnemsuf_check.no_wsuf)
4830*a9fa9459Szrj || (t->opcode_modifier.no_lsuf && mnemsuf_check.no_lsuf)
4831*a9fa9459Szrj || (t->opcode_modifier.no_ssuf && mnemsuf_check.no_ssuf)
4832*a9fa9459Szrj || (t->opcode_modifier.no_qsuf && mnemsuf_check.no_qsuf)
4833*a9fa9459Szrj || (t->opcode_modifier.no_ldsuf && mnemsuf_check.no_ldsuf))
4834*a9fa9459Szrj continue;
4835*a9fa9459Szrj
4836*a9fa9459Szrj if (!operand_size_match (t))
4837*a9fa9459Szrj continue;
4838*a9fa9459Szrj
4839*a9fa9459Szrj for (j = 0; j < MAX_OPERANDS; j++)
4840*a9fa9459Szrj operand_types[j] = t->operand_types[j];
4841*a9fa9459Szrj
4842*a9fa9459Szrj /* In general, don't allow 64-bit operands in 32-bit mode. */
4843*a9fa9459Szrj if (i.suffix == QWORD_MNEM_SUFFIX
4844*a9fa9459Szrj && flag_code != CODE_64BIT
4845*a9fa9459Szrj && (intel_syntax
4846*a9fa9459Szrj ? (!t->opcode_modifier.ignoresize
4847*a9fa9459Szrj && !intel_float_operand (t->name))
4848*a9fa9459Szrj : intel_float_operand (t->name) != 2)
4849*a9fa9459Szrj && ((!operand_types[0].bitfield.regmmx
4850*a9fa9459Szrj && !operand_types[0].bitfield.regxmm
4851*a9fa9459Szrj && !operand_types[0].bitfield.regymm
4852*a9fa9459Szrj && !operand_types[0].bitfield.regzmm)
4853*a9fa9459Szrj || (!operand_types[t->operands > 1].bitfield.regmmx
4854*a9fa9459Szrj && operand_types[t->operands > 1].bitfield.regxmm
4855*a9fa9459Szrj && operand_types[t->operands > 1].bitfield.regymm
4856*a9fa9459Szrj && operand_types[t->operands > 1].bitfield.regzmm))
4857*a9fa9459Szrj && (t->base_opcode != 0x0fc7
4858*a9fa9459Szrj || t->extension_opcode != 1 /* cmpxchg8b */))
4859*a9fa9459Szrj continue;
4860*a9fa9459Szrj
4861*a9fa9459Szrj /* In general, don't allow 32-bit operands on pre-386. */
4862*a9fa9459Szrj else if (i.suffix == LONG_MNEM_SUFFIX
4863*a9fa9459Szrj && !cpu_arch_flags.bitfield.cpui386
4864*a9fa9459Szrj && (intel_syntax
4865*a9fa9459Szrj ? (!t->opcode_modifier.ignoresize
4866*a9fa9459Szrj && !intel_float_operand (t->name))
4867*a9fa9459Szrj : intel_float_operand (t->name) != 2)
4868*a9fa9459Szrj && ((!operand_types[0].bitfield.regmmx
4869*a9fa9459Szrj && !operand_types[0].bitfield.regxmm)
4870*a9fa9459Szrj || (!operand_types[t->operands > 1].bitfield.regmmx
4871*a9fa9459Szrj && operand_types[t->operands > 1].bitfield.regxmm)))
4872*a9fa9459Szrj continue;
4873*a9fa9459Szrj
4874*a9fa9459Szrj /* Do not verify operands when there are none. */
4875*a9fa9459Szrj else
4876*a9fa9459Szrj {
4877*a9fa9459Szrj if (!t->operands)
4878*a9fa9459Szrj /* We've found a match; break out of loop. */
4879*a9fa9459Szrj break;
4880*a9fa9459Szrj }
4881*a9fa9459Szrj
4882*a9fa9459Szrj /* Address size prefix will turn Disp64/Disp32/Disp16 operand
4883*a9fa9459Szrj into Disp32/Disp16/Disp32 operand. */
4884*a9fa9459Szrj if (i.prefix[ADDR_PREFIX] != 0)
4885*a9fa9459Szrj {
4886*a9fa9459Szrj /* There should be only one Disp operand. */
4887*a9fa9459Szrj switch (flag_code)
4888*a9fa9459Szrj {
4889*a9fa9459Szrj case CODE_16BIT:
4890*a9fa9459Szrj for (j = 0; j < MAX_OPERANDS; j++)
4891*a9fa9459Szrj {
4892*a9fa9459Szrj if (operand_types[j].bitfield.disp16)
4893*a9fa9459Szrj {
4894*a9fa9459Szrj addr_prefix_disp = j;
4895*a9fa9459Szrj operand_types[j].bitfield.disp32 = 1;
4896*a9fa9459Szrj operand_types[j].bitfield.disp16 = 0;
4897*a9fa9459Szrj break;
4898*a9fa9459Szrj }
4899*a9fa9459Szrj }
4900*a9fa9459Szrj break;
4901*a9fa9459Szrj case CODE_32BIT:
4902*a9fa9459Szrj for (j = 0; j < MAX_OPERANDS; j++)
4903*a9fa9459Szrj {
4904*a9fa9459Szrj if (operand_types[j].bitfield.disp32)
4905*a9fa9459Szrj {
4906*a9fa9459Szrj addr_prefix_disp = j;
4907*a9fa9459Szrj operand_types[j].bitfield.disp32 = 0;
4908*a9fa9459Szrj operand_types[j].bitfield.disp16 = 1;
4909*a9fa9459Szrj break;
4910*a9fa9459Szrj }
4911*a9fa9459Szrj }
4912*a9fa9459Szrj break;
4913*a9fa9459Szrj case CODE_64BIT:
4914*a9fa9459Szrj for (j = 0; j < MAX_OPERANDS; j++)
4915*a9fa9459Szrj {
4916*a9fa9459Szrj if (operand_types[j].bitfield.disp64)
4917*a9fa9459Szrj {
4918*a9fa9459Szrj addr_prefix_disp = j;
4919*a9fa9459Szrj operand_types[j].bitfield.disp64 = 0;
4920*a9fa9459Szrj operand_types[j].bitfield.disp32 = 1;
4921*a9fa9459Szrj break;
4922*a9fa9459Szrj }
4923*a9fa9459Szrj }
4924*a9fa9459Szrj break;
4925*a9fa9459Szrj }
4926*a9fa9459Szrj }
4927*a9fa9459Szrj
4928*a9fa9459Szrj /* Force 0x8b encoding for "mov foo@GOT, %eax". */
4929*a9fa9459Szrj if (i.reloc[0] == BFD_RELOC_386_GOT32 && t->base_opcode == 0xa0)
4930*a9fa9459Szrj continue;
4931*a9fa9459Szrj
4932*a9fa9459Szrj /* We check register size if needed. */
4933*a9fa9459Szrj check_register = t->opcode_modifier.checkregsize;
4934*a9fa9459Szrj overlap0 = operand_type_and (i.types[0], operand_types[0]);
4935*a9fa9459Szrj switch (t->operands)
4936*a9fa9459Szrj {
4937*a9fa9459Szrj case 1:
4938*a9fa9459Szrj if (!operand_type_match (overlap0, i.types[0]))
4939*a9fa9459Szrj continue;
4940*a9fa9459Szrj break;
4941*a9fa9459Szrj case 2:
4942*a9fa9459Szrj /* xchg %eax, %eax is a special case. It is an aliase for nop
4943*a9fa9459Szrj only in 32bit mode and we can use opcode 0x90. In 64bit
4944*a9fa9459Szrj mode, we can't use 0x90 for xchg %eax, %eax since it should
4945*a9fa9459Szrj zero-extend %eax to %rax. */
4946*a9fa9459Szrj if (flag_code == CODE_64BIT
4947*a9fa9459Szrj && t->base_opcode == 0x90
4948*a9fa9459Szrj && operand_type_equal (&i.types [0], &acc32)
4949*a9fa9459Szrj && operand_type_equal (&i.types [1], &acc32))
4950*a9fa9459Szrj continue;
4951*a9fa9459Szrj if (i.swap_operand)
4952*a9fa9459Szrj {
4953*a9fa9459Szrj /* If we swap operand in encoding, we either match
4954*a9fa9459Szrj the next one or reverse direction of operands. */
4955*a9fa9459Szrj if (t->opcode_modifier.s)
4956*a9fa9459Szrj continue;
4957*a9fa9459Szrj else if (t->opcode_modifier.d)
4958*a9fa9459Szrj goto check_reverse;
4959*a9fa9459Szrj }
4960*a9fa9459Szrj
4961*a9fa9459Szrj case 3:
4962*a9fa9459Szrj /* If we swap operand in encoding, we match the next one. */
4963*a9fa9459Szrj if (i.swap_operand && t->opcode_modifier.s)
4964*a9fa9459Szrj continue;
4965*a9fa9459Szrj case 4:
4966*a9fa9459Szrj case 5:
4967*a9fa9459Szrj overlap1 = operand_type_and (i.types[1], operand_types[1]);
4968*a9fa9459Szrj if (!operand_type_match (overlap0, i.types[0])
4969*a9fa9459Szrj || !operand_type_match (overlap1, i.types[1])
4970*a9fa9459Szrj || (check_register
4971*a9fa9459Szrj && !operand_type_register_match (overlap0, i.types[0],
4972*a9fa9459Szrj operand_types[0],
4973*a9fa9459Szrj overlap1, i.types[1],
4974*a9fa9459Szrj operand_types[1])))
4975*a9fa9459Szrj {
4976*a9fa9459Szrj /* Check if other direction is valid ... */
4977*a9fa9459Szrj if (!t->opcode_modifier.d && !t->opcode_modifier.floatd)
4978*a9fa9459Szrj continue;
4979*a9fa9459Szrj
4980*a9fa9459Szrj check_reverse:
4981*a9fa9459Szrj /* Try reversing direction of operands. */
4982*a9fa9459Szrj overlap0 = operand_type_and (i.types[0], operand_types[1]);
4983*a9fa9459Szrj overlap1 = operand_type_and (i.types[1], operand_types[0]);
4984*a9fa9459Szrj if (!operand_type_match (overlap0, i.types[0])
4985*a9fa9459Szrj || !operand_type_match (overlap1, i.types[1])
4986*a9fa9459Szrj || (check_register
4987*a9fa9459Szrj && !operand_type_register_match (overlap0,
4988*a9fa9459Szrj i.types[0],
4989*a9fa9459Szrj operand_types[1],
4990*a9fa9459Szrj overlap1,
4991*a9fa9459Szrj i.types[1],
4992*a9fa9459Szrj operand_types[0])))
4993*a9fa9459Szrj {
4994*a9fa9459Szrj /* Does not match either direction. */
4995*a9fa9459Szrj continue;
4996*a9fa9459Szrj }
4997*a9fa9459Szrj /* found_reverse_match holds which of D or FloatDR
4998*a9fa9459Szrj we've found. */
4999*a9fa9459Szrj if (t->opcode_modifier.d)
5000*a9fa9459Szrj found_reverse_match = Opcode_D;
5001*a9fa9459Szrj else if (t->opcode_modifier.floatd)
5002*a9fa9459Szrj found_reverse_match = Opcode_FloatD;
5003*a9fa9459Szrj else
5004*a9fa9459Szrj found_reverse_match = 0;
5005*a9fa9459Szrj if (t->opcode_modifier.floatr)
5006*a9fa9459Szrj found_reverse_match |= Opcode_FloatR;
5007*a9fa9459Szrj }
5008*a9fa9459Szrj else
5009*a9fa9459Szrj {
5010*a9fa9459Szrj /* Found a forward 2 operand match here. */
5011*a9fa9459Szrj switch (t->operands)
5012*a9fa9459Szrj {
5013*a9fa9459Szrj case 5:
5014*a9fa9459Szrj overlap4 = operand_type_and (i.types[4],
5015*a9fa9459Szrj operand_types[4]);
5016*a9fa9459Szrj case 4:
5017*a9fa9459Szrj overlap3 = operand_type_and (i.types[3],
5018*a9fa9459Szrj operand_types[3]);
5019*a9fa9459Szrj case 3:
5020*a9fa9459Szrj overlap2 = operand_type_and (i.types[2],
5021*a9fa9459Szrj operand_types[2]);
5022*a9fa9459Szrj break;
5023*a9fa9459Szrj }
5024*a9fa9459Szrj
5025*a9fa9459Szrj switch (t->operands)
5026*a9fa9459Szrj {
5027*a9fa9459Szrj case 5:
5028*a9fa9459Szrj if (!operand_type_match (overlap4, i.types[4])
5029*a9fa9459Szrj || !operand_type_register_match (overlap3,
5030*a9fa9459Szrj i.types[3],
5031*a9fa9459Szrj operand_types[3],
5032*a9fa9459Szrj overlap4,
5033*a9fa9459Szrj i.types[4],
5034*a9fa9459Szrj operand_types[4]))
5035*a9fa9459Szrj continue;
5036*a9fa9459Szrj case 4:
5037*a9fa9459Szrj if (!operand_type_match (overlap3, i.types[3])
5038*a9fa9459Szrj || (check_register
5039*a9fa9459Szrj && !operand_type_register_match (overlap2,
5040*a9fa9459Szrj i.types[2],
5041*a9fa9459Szrj operand_types[2],
5042*a9fa9459Szrj overlap3,
5043*a9fa9459Szrj i.types[3],
5044*a9fa9459Szrj operand_types[3])))
5045*a9fa9459Szrj continue;
5046*a9fa9459Szrj case 3:
5047*a9fa9459Szrj /* Here we make use of the fact that there are no
5048*a9fa9459Szrj reverse match 3 operand instructions, and all 3
5049*a9fa9459Szrj operand instructions only need to be checked for
5050*a9fa9459Szrj register consistency between operands 2 and 3. */
5051*a9fa9459Szrj if (!operand_type_match (overlap2, i.types[2])
5052*a9fa9459Szrj || (check_register
5053*a9fa9459Szrj && !operand_type_register_match (overlap1,
5054*a9fa9459Szrj i.types[1],
5055*a9fa9459Szrj operand_types[1],
5056*a9fa9459Szrj overlap2,
5057*a9fa9459Szrj i.types[2],
5058*a9fa9459Szrj operand_types[2])))
5059*a9fa9459Szrj continue;
5060*a9fa9459Szrj break;
5061*a9fa9459Szrj }
5062*a9fa9459Szrj }
5063*a9fa9459Szrj /* Found either forward/reverse 2, 3 or 4 operand match here:
5064*a9fa9459Szrj slip through to break. */
5065*a9fa9459Szrj }
5066*a9fa9459Szrj if (!found_cpu_match)
5067*a9fa9459Szrj {
5068*a9fa9459Szrj found_reverse_match = 0;
5069*a9fa9459Szrj continue;
5070*a9fa9459Szrj }
5071*a9fa9459Szrj
5072*a9fa9459Szrj /* Check if vector and VEX operands are valid. */
5073*a9fa9459Szrj if (check_VecOperands (t) || VEX_check_operands (t))
5074*a9fa9459Szrj {
5075*a9fa9459Szrj specific_error = i.error;
5076*a9fa9459Szrj continue;
5077*a9fa9459Szrj }
5078*a9fa9459Szrj
5079*a9fa9459Szrj /* We've found a match; break out of loop. */
5080*a9fa9459Szrj break;
5081*a9fa9459Szrj }
5082*a9fa9459Szrj
5083*a9fa9459Szrj if (t == current_templates->end)
5084*a9fa9459Szrj {
5085*a9fa9459Szrj /* We found no match. */
5086*a9fa9459Szrj const char *err_msg;
5087*a9fa9459Szrj switch (specific_error ? specific_error : i.error)
5088*a9fa9459Szrj {
5089*a9fa9459Szrj default:
5090*a9fa9459Szrj abort ();
5091*a9fa9459Szrj case operand_size_mismatch:
5092*a9fa9459Szrj err_msg = _("operand size mismatch");
5093*a9fa9459Szrj break;
5094*a9fa9459Szrj case operand_type_mismatch:
5095*a9fa9459Szrj err_msg = _("operand type mismatch");
5096*a9fa9459Szrj break;
5097*a9fa9459Szrj case register_type_mismatch:
5098*a9fa9459Szrj err_msg = _("register type mismatch");
5099*a9fa9459Szrj break;
5100*a9fa9459Szrj case number_of_operands_mismatch:
5101*a9fa9459Szrj err_msg = _("number of operands mismatch");
5102*a9fa9459Szrj break;
5103*a9fa9459Szrj case invalid_instruction_suffix:
5104*a9fa9459Szrj err_msg = _("invalid instruction suffix");
5105*a9fa9459Szrj break;
5106*a9fa9459Szrj case bad_imm4:
5107*a9fa9459Szrj err_msg = _("constant doesn't fit in 4 bits");
5108*a9fa9459Szrj break;
5109*a9fa9459Szrj case old_gcc_only:
5110*a9fa9459Szrj err_msg = _("only supported with old gcc");
5111*a9fa9459Szrj break;
5112*a9fa9459Szrj case unsupported_with_intel_mnemonic:
5113*a9fa9459Szrj err_msg = _("unsupported with Intel mnemonic");
5114*a9fa9459Szrj break;
5115*a9fa9459Szrj case unsupported_syntax:
5116*a9fa9459Szrj err_msg = _("unsupported syntax");
5117*a9fa9459Szrj break;
5118*a9fa9459Szrj case unsupported:
5119*a9fa9459Szrj as_bad (_("unsupported instruction `%s'"),
5120*a9fa9459Szrj current_templates->start->name);
5121*a9fa9459Szrj return NULL;
5122*a9fa9459Szrj case invalid_vsib_address:
5123*a9fa9459Szrj err_msg = _("invalid VSIB address");
5124*a9fa9459Szrj break;
5125*a9fa9459Szrj case invalid_vector_register_set:
5126*a9fa9459Szrj err_msg = _("mask, index, and destination registers must be distinct");
5127*a9fa9459Szrj break;
5128*a9fa9459Szrj case unsupported_vector_index_register:
5129*a9fa9459Szrj err_msg = _("unsupported vector index register");
5130*a9fa9459Szrj break;
5131*a9fa9459Szrj case unsupported_broadcast:
5132*a9fa9459Szrj err_msg = _("unsupported broadcast");
5133*a9fa9459Szrj break;
5134*a9fa9459Szrj case broadcast_not_on_src_operand:
5135*a9fa9459Szrj err_msg = _("broadcast not on source memory operand");
5136*a9fa9459Szrj break;
5137*a9fa9459Szrj case broadcast_needed:
5138*a9fa9459Szrj err_msg = _("broadcast is needed for operand of such type");
5139*a9fa9459Szrj break;
5140*a9fa9459Szrj case unsupported_masking:
5141*a9fa9459Szrj err_msg = _("unsupported masking");
5142*a9fa9459Szrj break;
5143*a9fa9459Szrj case mask_not_on_destination:
5144*a9fa9459Szrj err_msg = _("mask not on destination operand");
5145*a9fa9459Szrj break;
5146*a9fa9459Szrj case no_default_mask:
5147*a9fa9459Szrj err_msg = _("default mask isn't allowed");
5148*a9fa9459Szrj break;
5149*a9fa9459Szrj case unsupported_rc_sae:
5150*a9fa9459Szrj err_msg = _("unsupported static rounding/sae");
5151*a9fa9459Szrj break;
5152*a9fa9459Szrj case rc_sae_operand_not_last_imm:
5153*a9fa9459Szrj if (intel_syntax)
5154*a9fa9459Szrj err_msg = _("RC/SAE operand must precede immediate operands");
5155*a9fa9459Szrj else
5156*a9fa9459Szrj err_msg = _("RC/SAE operand must follow immediate operands");
5157*a9fa9459Szrj break;
5158*a9fa9459Szrj case invalid_register_operand:
5159*a9fa9459Szrj err_msg = _("invalid register operand");
5160*a9fa9459Szrj break;
5161*a9fa9459Szrj }
5162*a9fa9459Szrj as_bad (_("%s for `%s'"), err_msg,
5163*a9fa9459Szrj current_templates->start->name);
5164*a9fa9459Szrj return NULL;
5165*a9fa9459Szrj }
5166*a9fa9459Szrj
5167*a9fa9459Szrj if (!quiet_warnings)
5168*a9fa9459Szrj {
5169*a9fa9459Szrj if (!intel_syntax
5170*a9fa9459Szrj && (i.types[0].bitfield.jumpabsolute
5171*a9fa9459Szrj != operand_types[0].bitfield.jumpabsolute))
5172*a9fa9459Szrj {
5173*a9fa9459Szrj as_warn (_("indirect %s without `*'"), t->name);
5174*a9fa9459Szrj }
5175*a9fa9459Szrj
5176*a9fa9459Szrj if (t->opcode_modifier.isprefix
5177*a9fa9459Szrj && t->opcode_modifier.ignoresize)
5178*a9fa9459Szrj {
5179*a9fa9459Szrj /* Warn them that a data or address size prefix doesn't
5180*a9fa9459Szrj affect assembly of the next line of code. */
5181*a9fa9459Szrj as_warn (_("stand-alone `%s' prefix"), t->name);
5182*a9fa9459Szrj }
5183*a9fa9459Szrj }
5184*a9fa9459Szrj
5185*a9fa9459Szrj /* Copy the template we found. */
5186*a9fa9459Szrj i.tm = *t;
5187*a9fa9459Szrj
5188*a9fa9459Szrj if (addr_prefix_disp != -1)
5189*a9fa9459Szrj i.tm.operand_types[addr_prefix_disp]
5190*a9fa9459Szrj = operand_types[addr_prefix_disp];
5191*a9fa9459Szrj
5192*a9fa9459Szrj if (found_reverse_match)
5193*a9fa9459Szrj {
5194*a9fa9459Szrj /* If we found a reverse match we must alter the opcode
5195*a9fa9459Szrj direction bit. found_reverse_match holds bits to change
5196*a9fa9459Szrj (different for int & float insns). */
5197*a9fa9459Szrj
5198*a9fa9459Szrj i.tm.base_opcode ^= found_reverse_match;
5199*a9fa9459Szrj
5200*a9fa9459Szrj i.tm.operand_types[0] = operand_types[1];
5201*a9fa9459Szrj i.tm.operand_types[1] = operand_types[0];
5202*a9fa9459Szrj }
5203*a9fa9459Szrj
5204*a9fa9459Szrj return t;
5205*a9fa9459Szrj }
5206*a9fa9459Szrj
5207*a9fa9459Szrj static int
check_string(void)5208*a9fa9459Szrj check_string (void)
5209*a9fa9459Szrj {
5210*a9fa9459Szrj int mem_op = operand_type_check (i.types[0], anymem) ? 0 : 1;
5211*a9fa9459Szrj if (i.tm.operand_types[mem_op].bitfield.esseg)
5212*a9fa9459Szrj {
5213*a9fa9459Szrj if (i.seg[0] != NULL && i.seg[0] != &es)
5214*a9fa9459Szrj {
5215*a9fa9459Szrj as_bad (_("`%s' operand %d must use `%ses' segment"),
5216*a9fa9459Szrj i.tm.name,
5217*a9fa9459Szrj mem_op + 1,
5218*a9fa9459Szrj register_prefix);
5219*a9fa9459Szrj return 0;
5220*a9fa9459Szrj }
5221*a9fa9459Szrj /* There's only ever one segment override allowed per instruction.
5222*a9fa9459Szrj This instruction possibly has a legal segment override on the
5223*a9fa9459Szrj second operand, so copy the segment to where non-string
5224*a9fa9459Szrj instructions store it, allowing common code. */
5225*a9fa9459Szrj i.seg[0] = i.seg[1];
5226*a9fa9459Szrj }
5227*a9fa9459Szrj else if (i.tm.operand_types[mem_op + 1].bitfield.esseg)
5228*a9fa9459Szrj {
5229*a9fa9459Szrj if (i.seg[1] != NULL && i.seg[1] != &es)
5230*a9fa9459Szrj {
5231*a9fa9459Szrj as_bad (_("`%s' operand %d must use `%ses' segment"),
5232*a9fa9459Szrj i.tm.name,
5233*a9fa9459Szrj mem_op + 2,
5234*a9fa9459Szrj register_prefix);
5235*a9fa9459Szrj return 0;
5236*a9fa9459Szrj }
5237*a9fa9459Szrj }
5238*a9fa9459Szrj return 1;
5239*a9fa9459Szrj }
5240*a9fa9459Szrj
5241*a9fa9459Szrj static int
process_suffix(void)5242*a9fa9459Szrj process_suffix (void)
5243*a9fa9459Szrj {
5244*a9fa9459Szrj /* If matched instruction specifies an explicit instruction mnemonic
5245*a9fa9459Szrj suffix, use it. */
5246*a9fa9459Szrj if (i.tm.opcode_modifier.size16)
5247*a9fa9459Szrj i.suffix = WORD_MNEM_SUFFIX;
5248*a9fa9459Szrj else if (i.tm.opcode_modifier.size32)
5249*a9fa9459Szrj i.suffix = LONG_MNEM_SUFFIX;
5250*a9fa9459Szrj else if (i.tm.opcode_modifier.size64)
5251*a9fa9459Szrj i.suffix = QWORD_MNEM_SUFFIX;
5252*a9fa9459Szrj else if (i.reg_operands)
5253*a9fa9459Szrj {
5254*a9fa9459Szrj /* If there's no instruction mnemonic suffix we try to invent one
5255*a9fa9459Szrj based on register operands. */
5256*a9fa9459Szrj if (!i.suffix)
5257*a9fa9459Szrj {
5258*a9fa9459Szrj /* We take i.suffix from the last register operand specified,
5259*a9fa9459Szrj Destination register type is more significant than source
5260*a9fa9459Szrj register type. crc32 in SSE4.2 prefers source register
5261*a9fa9459Szrj type. */
5262*a9fa9459Szrj if (i.tm.base_opcode == 0xf20f38f1)
5263*a9fa9459Szrj {
5264*a9fa9459Szrj if (i.types[0].bitfield.reg16)
5265*a9fa9459Szrj i.suffix = WORD_MNEM_SUFFIX;
5266*a9fa9459Szrj else if (i.types[0].bitfield.reg32)
5267*a9fa9459Szrj i.suffix = LONG_MNEM_SUFFIX;
5268*a9fa9459Szrj else if (i.types[0].bitfield.reg64)
5269*a9fa9459Szrj i.suffix = QWORD_MNEM_SUFFIX;
5270*a9fa9459Szrj }
5271*a9fa9459Szrj else if (i.tm.base_opcode == 0xf20f38f0)
5272*a9fa9459Szrj {
5273*a9fa9459Szrj if (i.types[0].bitfield.reg8)
5274*a9fa9459Szrj i.suffix = BYTE_MNEM_SUFFIX;
5275*a9fa9459Szrj }
5276*a9fa9459Szrj
5277*a9fa9459Szrj if (!i.suffix)
5278*a9fa9459Szrj {
5279*a9fa9459Szrj int op;
5280*a9fa9459Szrj
5281*a9fa9459Szrj if (i.tm.base_opcode == 0xf20f38f1
5282*a9fa9459Szrj || i.tm.base_opcode == 0xf20f38f0)
5283*a9fa9459Szrj {
5284*a9fa9459Szrj /* We have to know the operand size for crc32. */
5285*a9fa9459Szrj as_bad (_("ambiguous memory operand size for `%s`"),
5286*a9fa9459Szrj i.tm.name);
5287*a9fa9459Szrj return 0;
5288*a9fa9459Szrj }
5289*a9fa9459Szrj
5290*a9fa9459Szrj for (op = i.operands; --op >= 0;)
5291*a9fa9459Szrj if (!i.tm.operand_types[op].bitfield.inoutportreg)
5292*a9fa9459Szrj {
5293*a9fa9459Szrj if (i.types[op].bitfield.reg8)
5294*a9fa9459Szrj {
5295*a9fa9459Szrj i.suffix = BYTE_MNEM_SUFFIX;
5296*a9fa9459Szrj break;
5297*a9fa9459Szrj }
5298*a9fa9459Szrj else if (i.types[op].bitfield.reg16)
5299*a9fa9459Szrj {
5300*a9fa9459Szrj i.suffix = WORD_MNEM_SUFFIX;
5301*a9fa9459Szrj break;
5302*a9fa9459Szrj }
5303*a9fa9459Szrj else if (i.types[op].bitfield.reg32)
5304*a9fa9459Szrj {
5305*a9fa9459Szrj i.suffix = LONG_MNEM_SUFFIX;
5306*a9fa9459Szrj break;
5307*a9fa9459Szrj }
5308*a9fa9459Szrj else if (i.types[op].bitfield.reg64)
5309*a9fa9459Szrj {
5310*a9fa9459Szrj i.suffix = QWORD_MNEM_SUFFIX;
5311*a9fa9459Szrj break;
5312*a9fa9459Szrj }
5313*a9fa9459Szrj }
5314*a9fa9459Szrj }
5315*a9fa9459Szrj }
5316*a9fa9459Szrj else if (i.suffix == BYTE_MNEM_SUFFIX)
5317*a9fa9459Szrj {
5318*a9fa9459Szrj if (intel_syntax
5319*a9fa9459Szrj && i.tm.opcode_modifier.ignoresize
5320*a9fa9459Szrj && i.tm.opcode_modifier.no_bsuf)
5321*a9fa9459Szrj i.suffix = 0;
5322*a9fa9459Szrj else if (!check_byte_reg ())
5323*a9fa9459Szrj return 0;
5324*a9fa9459Szrj }
5325*a9fa9459Szrj else if (i.suffix == LONG_MNEM_SUFFIX)
5326*a9fa9459Szrj {
5327*a9fa9459Szrj if (intel_syntax
5328*a9fa9459Szrj && i.tm.opcode_modifier.ignoresize
5329*a9fa9459Szrj && i.tm.opcode_modifier.no_lsuf)
5330*a9fa9459Szrj i.suffix = 0;
5331*a9fa9459Szrj else if (!check_long_reg ())
5332*a9fa9459Szrj return 0;
5333*a9fa9459Szrj }
5334*a9fa9459Szrj else if (i.suffix == QWORD_MNEM_SUFFIX)
5335*a9fa9459Szrj {
5336*a9fa9459Szrj if (intel_syntax
5337*a9fa9459Szrj && i.tm.opcode_modifier.ignoresize
5338*a9fa9459Szrj && i.tm.opcode_modifier.no_qsuf)
5339*a9fa9459Szrj i.suffix = 0;
5340*a9fa9459Szrj else if (!check_qword_reg ())
5341*a9fa9459Szrj return 0;
5342*a9fa9459Szrj }
5343*a9fa9459Szrj else if (i.suffix == WORD_MNEM_SUFFIX)
5344*a9fa9459Szrj {
5345*a9fa9459Szrj if (intel_syntax
5346*a9fa9459Szrj && i.tm.opcode_modifier.ignoresize
5347*a9fa9459Szrj && i.tm.opcode_modifier.no_wsuf)
5348*a9fa9459Szrj i.suffix = 0;
5349*a9fa9459Szrj else if (!check_word_reg ())
5350*a9fa9459Szrj return 0;
5351*a9fa9459Szrj }
5352*a9fa9459Szrj else if (i.suffix == XMMWORD_MNEM_SUFFIX
5353*a9fa9459Szrj || i.suffix == YMMWORD_MNEM_SUFFIX
5354*a9fa9459Szrj || i.suffix == ZMMWORD_MNEM_SUFFIX)
5355*a9fa9459Szrj {
5356*a9fa9459Szrj /* Skip if the instruction has x/y/z suffix. match_template
5357*a9fa9459Szrj should check if it is a valid suffix. */
5358*a9fa9459Szrj }
5359*a9fa9459Szrj else if (intel_syntax && i.tm.opcode_modifier.ignoresize)
5360*a9fa9459Szrj /* Do nothing if the instruction is going to ignore the prefix. */
5361*a9fa9459Szrj ;
5362*a9fa9459Szrj else
5363*a9fa9459Szrj abort ();
5364*a9fa9459Szrj }
5365*a9fa9459Szrj else if (i.tm.opcode_modifier.defaultsize
5366*a9fa9459Szrj && !i.suffix
5367*a9fa9459Szrj /* exclude fldenv/frstor/fsave/fstenv */
5368*a9fa9459Szrj && i.tm.opcode_modifier.no_ssuf)
5369*a9fa9459Szrj {
5370*a9fa9459Szrj i.suffix = stackop_size;
5371*a9fa9459Szrj }
5372*a9fa9459Szrj else if (intel_syntax
5373*a9fa9459Szrj && !i.suffix
5374*a9fa9459Szrj && (i.tm.operand_types[0].bitfield.jumpabsolute
5375*a9fa9459Szrj || i.tm.opcode_modifier.jumpbyte
5376*a9fa9459Szrj || i.tm.opcode_modifier.jumpintersegment
5377*a9fa9459Szrj || (i.tm.base_opcode == 0x0f01 /* [ls][gi]dt */
5378*a9fa9459Szrj && i.tm.extension_opcode <= 3)))
5379*a9fa9459Szrj {
5380*a9fa9459Szrj switch (flag_code)
5381*a9fa9459Szrj {
5382*a9fa9459Szrj case CODE_64BIT:
5383*a9fa9459Szrj if (!i.tm.opcode_modifier.no_qsuf)
5384*a9fa9459Szrj {
5385*a9fa9459Szrj i.suffix = QWORD_MNEM_SUFFIX;
5386*a9fa9459Szrj break;
5387*a9fa9459Szrj }
5388*a9fa9459Szrj case CODE_32BIT:
5389*a9fa9459Szrj if (!i.tm.opcode_modifier.no_lsuf)
5390*a9fa9459Szrj i.suffix = LONG_MNEM_SUFFIX;
5391*a9fa9459Szrj break;
5392*a9fa9459Szrj case CODE_16BIT:
5393*a9fa9459Szrj if (!i.tm.opcode_modifier.no_wsuf)
5394*a9fa9459Szrj i.suffix = WORD_MNEM_SUFFIX;
5395*a9fa9459Szrj break;
5396*a9fa9459Szrj }
5397*a9fa9459Szrj }
5398*a9fa9459Szrj
5399*a9fa9459Szrj if (!i.suffix)
5400*a9fa9459Szrj {
5401*a9fa9459Szrj if (!intel_syntax)
5402*a9fa9459Szrj {
5403*a9fa9459Szrj if (i.tm.opcode_modifier.w)
5404*a9fa9459Szrj {
5405*a9fa9459Szrj as_bad (_("no instruction mnemonic suffix given and "
5406*a9fa9459Szrj "no register operands; can't size instruction"));
5407*a9fa9459Szrj return 0;
5408*a9fa9459Szrj }
5409*a9fa9459Szrj }
5410*a9fa9459Szrj else
5411*a9fa9459Szrj {
5412*a9fa9459Szrj unsigned int suffixes;
5413*a9fa9459Szrj
5414*a9fa9459Szrj suffixes = !i.tm.opcode_modifier.no_bsuf;
5415*a9fa9459Szrj if (!i.tm.opcode_modifier.no_wsuf)
5416*a9fa9459Szrj suffixes |= 1 << 1;
5417*a9fa9459Szrj if (!i.tm.opcode_modifier.no_lsuf)
5418*a9fa9459Szrj suffixes |= 1 << 2;
5419*a9fa9459Szrj if (!i.tm.opcode_modifier.no_ldsuf)
5420*a9fa9459Szrj suffixes |= 1 << 3;
5421*a9fa9459Szrj if (!i.tm.opcode_modifier.no_ssuf)
5422*a9fa9459Szrj suffixes |= 1 << 4;
5423*a9fa9459Szrj if (!i.tm.opcode_modifier.no_qsuf)
5424*a9fa9459Szrj suffixes |= 1 << 5;
5425*a9fa9459Szrj
5426*a9fa9459Szrj /* There are more than suffix matches. */
5427*a9fa9459Szrj if (i.tm.opcode_modifier.w
5428*a9fa9459Szrj || ((suffixes & (suffixes - 1))
5429*a9fa9459Szrj && !i.tm.opcode_modifier.defaultsize
5430*a9fa9459Szrj && !i.tm.opcode_modifier.ignoresize))
5431*a9fa9459Szrj {
5432*a9fa9459Szrj as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
5433*a9fa9459Szrj return 0;
5434*a9fa9459Szrj }
5435*a9fa9459Szrj }
5436*a9fa9459Szrj }
5437*a9fa9459Szrj
5438*a9fa9459Szrj /* Change the opcode based on the operand size given by i.suffix;
5439*a9fa9459Szrj We don't need to change things for byte insns. */
5440*a9fa9459Szrj
5441*a9fa9459Szrj if (i.suffix
5442*a9fa9459Szrj && i.suffix != BYTE_MNEM_SUFFIX
5443*a9fa9459Szrj && i.suffix != XMMWORD_MNEM_SUFFIX
5444*a9fa9459Szrj && i.suffix != YMMWORD_MNEM_SUFFIX
5445*a9fa9459Szrj && i.suffix != ZMMWORD_MNEM_SUFFIX)
5446*a9fa9459Szrj {
5447*a9fa9459Szrj /* It's not a byte, select word/dword operation. */
5448*a9fa9459Szrj if (i.tm.opcode_modifier.w)
5449*a9fa9459Szrj {
5450*a9fa9459Szrj if (i.tm.opcode_modifier.shortform)
5451*a9fa9459Szrj i.tm.base_opcode |= 8;
5452*a9fa9459Szrj else
5453*a9fa9459Szrj i.tm.base_opcode |= 1;
5454*a9fa9459Szrj }
5455*a9fa9459Szrj
5456*a9fa9459Szrj /* Now select between word & dword operations via the operand
5457*a9fa9459Szrj size prefix, except for instructions that will ignore this
5458*a9fa9459Szrj prefix anyway. */
5459*a9fa9459Szrj if (i.tm.opcode_modifier.addrprefixop0)
5460*a9fa9459Szrj {
5461*a9fa9459Szrj /* The address size override prefix changes the size of the
5462*a9fa9459Szrj first operand. */
5463*a9fa9459Szrj if ((flag_code == CODE_32BIT
5464*a9fa9459Szrj && i.op->regs[0].reg_type.bitfield.reg16)
5465*a9fa9459Szrj || (flag_code != CODE_32BIT
5466*a9fa9459Szrj && i.op->regs[0].reg_type.bitfield.reg32))
5467*a9fa9459Szrj if (!add_prefix (ADDR_PREFIX_OPCODE))
5468*a9fa9459Szrj return 0;
5469*a9fa9459Szrj }
5470*a9fa9459Szrj else if (i.suffix != QWORD_MNEM_SUFFIX
5471*a9fa9459Szrj && i.suffix != LONG_DOUBLE_MNEM_SUFFIX
5472*a9fa9459Szrj && !i.tm.opcode_modifier.ignoresize
5473*a9fa9459Szrj && !i.tm.opcode_modifier.floatmf
5474*a9fa9459Szrj && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
5475*a9fa9459Szrj || (flag_code == CODE_64BIT
5476*a9fa9459Szrj && i.tm.opcode_modifier.jumpbyte)))
5477*a9fa9459Szrj {
5478*a9fa9459Szrj unsigned int prefix = DATA_PREFIX_OPCODE;
5479*a9fa9459Szrj
5480*a9fa9459Szrj if (i.tm.opcode_modifier.jumpbyte) /* jcxz, loop */
5481*a9fa9459Szrj prefix = ADDR_PREFIX_OPCODE;
5482*a9fa9459Szrj
5483*a9fa9459Szrj if (!add_prefix (prefix))
5484*a9fa9459Szrj return 0;
5485*a9fa9459Szrj }
5486*a9fa9459Szrj
5487*a9fa9459Szrj /* Set mode64 for an operand. */
5488*a9fa9459Szrj if (i.suffix == QWORD_MNEM_SUFFIX
5489*a9fa9459Szrj && flag_code == CODE_64BIT
5490*a9fa9459Szrj && !i.tm.opcode_modifier.norex64)
5491*a9fa9459Szrj {
5492*a9fa9459Szrj /* Special case for xchg %rax,%rax. It is NOP and doesn't
5493*a9fa9459Szrj need rex64. cmpxchg8b is also a special case. */
5494*a9fa9459Szrj if (! (i.operands == 2
5495*a9fa9459Szrj && i.tm.base_opcode == 0x90
5496*a9fa9459Szrj && i.tm.extension_opcode == None
5497*a9fa9459Szrj && operand_type_equal (&i.types [0], &acc64)
5498*a9fa9459Szrj && operand_type_equal (&i.types [1], &acc64))
5499*a9fa9459Szrj && ! (i.operands == 1
5500*a9fa9459Szrj && i.tm.base_opcode == 0xfc7
5501*a9fa9459Szrj && i.tm.extension_opcode == 1
5502*a9fa9459Szrj && !operand_type_check (i.types [0], reg)
5503*a9fa9459Szrj && operand_type_check (i.types [0], anymem)))
5504*a9fa9459Szrj i.rex |= REX_W;
5505*a9fa9459Szrj }
5506*a9fa9459Szrj
5507*a9fa9459Szrj /* Size floating point instruction. */
5508*a9fa9459Szrj if (i.suffix == LONG_MNEM_SUFFIX)
5509*a9fa9459Szrj if (i.tm.opcode_modifier.floatmf)
5510*a9fa9459Szrj i.tm.base_opcode ^= 4;
5511*a9fa9459Szrj }
5512*a9fa9459Szrj
5513*a9fa9459Szrj return 1;
5514*a9fa9459Szrj }
5515*a9fa9459Szrj
5516*a9fa9459Szrj static int
check_byte_reg(void)5517*a9fa9459Szrj check_byte_reg (void)
5518*a9fa9459Szrj {
5519*a9fa9459Szrj int op;
5520*a9fa9459Szrj
5521*a9fa9459Szrj for (op = i.operands; --op >= 0;)
5522*a9fa9459Szrj {
5523*a9fa9459Szrj /* If this is an eight bit register, it's OK. If it's the 16 or
5524*a9fa9459Szrj 32 bit version of an eight bit register, we will just use the
5525*a9fa9459Szrj low portion, and that's OK too. */
5526*a9fa9459Szrj if (i.types[op].bitfield.reg8)
5527*a9fa9459Szrj continue;
5528*a9fa9459Szrj
5529*a9fa9459Szrj /* I/O port address operands are OK too. */
5530*a9fa9459Szrj if (i.tm.operand_types[op].bitfield.inoutportreg)
5531*a9fa9459Szrj continue;
5532*a9fa9459Szrj
5533*a9fa9459Szrj /* crc32 doesn't generate this warning. */
5534*a9fa9459Szrj if (i.tm.base_opcode == 0xf20f38f0)
5535*a9fa9459Szrj continue;
5536*a9fa9459Szrj
5537*a9fa9459Szrj if ((i.types[op].bitfield.reg16
5538*a9fa9459Szrj || i.types[op].bitfield.reg32
5539*a9fa9459Szrj || i.types[op].bitfield.reg64)
5540*a9fa9459Szrj && i.op[op].regs->reg_num < 4
5541*a9fa9459Szrj /* Prohibit these changes in 64bit mode, since the lowering
5542*a9fa9459Szrj would be more complicated. */
5543*a9fa9459Szrj && flag_code != CODE_64BIT)
5544*a9fa9459Szrj {
5545*a9fa9459Szrj #if REGISTER_WARNINGS
5546*a9fa9459Szrj if (!quiet_warnings)
5547*a9fa9459Szrj as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
5548*a9fa9459Szrj register_prefix,
5549*a9fa9459Szrj (i.op[op].regs + (i.types[op].bitfield.reg16
5550*a9fa9459Szrj ? REGNAM_AL - REGNAM_AX
5551*a9fa9459Szrj : REGNAM_AL - REGNAM_EAX))->reg_name,
5552*a9fa9459Szrj register_prefix,
5553*a9fa9459Szrj i.op[op].regs->reg_name,
5554*a9fa9459Szrj i.suffix);
5555*a9fa9459Szrj #endif
5556*a9fa9459Szrj continue;
5557*a9fa9459Szrj }
5558*a9fa9459Szrj /* Any other register is bad. */
5559*a9fa9459Szrj if (i.types[op].bitfield.reg16
5560*a9fa9459Szrj || i.types[op].bitfield.reg32
5561*a9fa9459Szrj || i.types[op].bitfield.reg64
5562*a9fa9459Szrj || i.types[op].bitfield.regmmx
5563*a9fa9459Szrj || i.types[op].bitfield.regxmm
5564*a9fa9459Szrj || i.types[op].bitfield.regymm
5565*a9fa9459Szrj || i.types[op].bitfield.regzmm
5566*a9fa9459Szrj || i.types[op].bitfield.sreg2
5567*a9fa9459Szrj || i.types[op].bitfield.sreg3
5568*a9fa9459Szrj || i.types[op].bitfield.control
5569*a9fa9459Szrj || i.types[op].bitfield.debug
5570*a9fa9459Szrj || i.types[op].bitfield.test
5571*a9fa9459Szrj || i.types[op].bitfield.floatreg
5572*a9fa9459Szrj || i.types[op].bitfield.floatacc)
5573*a9fa9459Szrj {
5574*a9fa9459Szrj as_bad (_("`%s%s' not allowed with `%s%c'"),
5575*a9fa9459Szrj register_prefix,
5576*a9fa9459Szrj i.op[op].regs->reg_name,
5577*a9fa9459Szrj i.tm.name,
5578*a9fa9459Szrj i.suffix);
5579*a9fa9459Szrj return 0;
5580*a9fa9459Szrj }
5581*a9fa9459Szrj }
5582*a9fa9459Szrj return 1;
5583*a9fa9459Szrj }
5584*a9fa9459Szrj
5585*a9fa9459Szrj static int
check_long_reg(void)5586*a9fa9459Szrj check_long_reg (void)
5587*a9fa9459Szrj {
5588*a9fa9459Szrj int op;
5589*a9fa9459Szrj
5590*a9fa9459Szrj for (op = i.operands; --op >= 0;)
5591*a9fa9459Szrj /* Reject eight bit registers, except where the template requires
5592*a9fa9459Szrj them. (eg. movzb) */
5593*a9fa9459Szrj if (i.types[op].bitfield.reg8
5594*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg16
5595*a9fa9459Szrj || i.tm.operand_types[op].bitfield.reg32
5596*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5597*a9fa9459Szrj {
5598*a9fa9459Szrj as_bad (_("`%s%s' not allowed with `%s%c'"),
5599*a9fa9459Szrj register_prefix,
5600*a9fa9459Szrj i.op[op].regs->reg_name,
5601*a9fa9459Szrj i.tm.name,
5602*a9fa9459Szrj i.suffix);
5603*a9fa9459Szrj return 0;
5604*a9fa9459Szrj }
5605*a9fa9459Szrj /* Warn if the e prefix on a general reg is missing. */
5606*a9fa9459Szrj else if ((!quiet_warnings || flag_code == CODE_64BIT)
5607*a9fa9459Szrj && i.types[op].bitfield.reg16
5608*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg32
5609*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5610*a9fa9459Szrj {
5611*a9fa9459Szrj /* Prohibit these changes in the 64bit mode, since the
5612*a9fa9459Szrj lowering is more complicated. */
5613*a9fa9459Szrj if (flag_code == CODE_64BIT)
5614*a9fa9459Szrj {
5615*a9fa9459Szrj as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
5616*a9fa9459Szrj register_prefix, i.op[op].regs->reg_name,
5617*a9fa9459Szrj i.suffix);
5618*a9fa9459Szrj return 0;
5619*a9fa9459Szrj }
5620*a9fa9459Szrj #if REGISTER_WARNINGS
5621*a9fa9459Szrj as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
5622*a9fa9459Szrj register_prefix,
5623*a9fa9459Szrj (i.op[op].regs + REGNAM_EAX - REGNAM_AX)->reg_name,
5624*a9fa9459Szrj register_prefix, i.op[op].regs->reg_name, i.suffix);
5625*a9fa9459Szrj #endif
5626*a9fa9459Szrj }
5627*a9fa9459Szrj /* Warn if the r prefix on a general reg is present. */
5628*a9fa9459Szrj else if (i.types[op].bitfield.reg64
5629*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg32
5630*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5631*a9fa9459Szrj {
5632*a9fa9459Szrj if (intel_syntax
5633*a9fa9459Szrj && i.tm.opcode_modifier.toqword
5634*a9fa9459Szrj && !i.types[0].bitfield.regxmm)
5635*a9fa9459Szrj {
5636*a9fa9459Szrj /* Convert to QWORD. We want REX byte. */
5637*a9fa9459Szrj i.suffix = QWORD_MNEM_SUFFIX;
5638*a9fa9459Szrj }
5639*a9fa9459Szrj else
5640*a9fa9459Szrj {
5641*a9fa9459Szrj as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
5642*a9fa9459Szrj register_prefix, i.op[op].regs->reg_name,
5643*a9fa9459Szrj i.suffix);
5644*a9fa9459Szrj return 0;
5645*a9fa9459Szrj }
5646*a9fa9459Szrj }
5647*a9fa9459Szrj return 1;
5648*a9fa9459Szrj }
5649*a9fa9459Szrj
5650*a9fa9459Szrj static int
check_qword_reg(void)5651*a9fa9459Szrj check_qword_reg (void)
5652*a9fa9459Szrj {
5653*a9fa9459Szrj int op;
5654*a9fa9459Szrj
5655*a9fa9459Szrj for (op = i.operands; --op >= 0; )
5656*a9fa9459Szrj /* Reject eight bit registers, except where the template requires
5657*a9fa9459Szrj them. (eg. movzb) */
5658*a9fa9459Szrj if (i.types[op].bitfield.reg8
5659*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg16
5660*a9fa9459Szrj || i.tm.operand_types[op].bitfield.reg32
5661*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5662*a9fa9459Szrj {
5663*a9fa9459Szrj as_bad (_("`%s%s' not allowed with `%s%c'"),
5664*a9fa9459Szrj register_prefix,
5665*a9fa9459Szrj i.op[op].regs->reg_name,
5666*a9fa9459Szrj i.tm.name,
5667*a9fa9459Szrj i.suffix);
5668*a9fa9459Szrj return 0;
5669*a9fa9459Szrj }
5670*a9fa9459Szrj /* Warn if the r prefix on a general reg is missing. */
5671*a9fa9459Szrj else if ((i.types[op].bitfield.reg16
5672*a9fa9459Szrj || i.types[op].bitfield.reg32)
5673*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg32
5674*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5675*a9fa9459Szrj {
5676*a9fa9459Szrj /* Prohibit these changes in the 64bit mode, since the
5677*a9fa9459Szrj lowering is more complicated. */
5678*a9fa9459Szrj if (intel_syntax
5679*a9fa9459Szrj && i.tm.opcode_modifier.todword
5680*a9fa9459Szrj && !i.types[0].bitfield.regxmm)
5681*a9fa9459Szrj {
5682*a9fa9459Szrj /* Convert to DWORD. We don't want REX byte. */
5683*a9fa9459Szrj i.suffix = LONG_MNEM_SUFFIX;
5684*a9fa9459Szrj }
5685*a9fa9459Szrj else
5686*a9fa9459Szrj {
5687*a9fa9459Szrj as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
5688*a9fa9459Szrj register_prefix, i.op[op].regs->reg_name,
5689*a9fa9459Szrj i.suffix);
5690*a9fa9459Szrj return 0;
5691*a9fa9459Szrj }
5692*a9fa9459Szrj }
5693*a9fa9459Szrj return 1;
5694*a9fa9459Szrj }
5695*a9fa9459Szrj
5696*a9fa9459Szrj static int
check_word_reg(void)5697*a9fa9459Szrj check_word_reg (void)
5698*a9fa9459Szrj {
5699*a9fa9459Szrj int op;
5700*a9fa9459Szrj for (op = i.operands; --op >= 0;)
5701*a9fa9459Szrj /* Reject eight bit registers, except where the template requires
5702*a9fa9459Szrj them. (eg. movzb) */
5703*a9fa9459Szrj if (i.types[op].bitfield.reg8
5704*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg16
5705*a9fa9459Szrj || i.tm.operand_types[op].bitfield.reg32
5706*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5707*a9fa9459Szrj {
5708*a9fa9459Szrj as_bad (_("`%s%s' not allowed with `%s%c'"),
5709*a9fa9459Szrj register_prefix,
5710*a9fa9459Szrj i.op[op].regs->reg_name,
5711*a9fa9459Szrj i.tm.name,
5712*a9fa9459Szrj i.suffix);
5713*a9fa9459Szrj return 0;
5714*a9fa9459Szrj }
5715*a9fa9459Szrj /* Warn if the e or r prefix on a general reg is present. */
5716*a9fa9459Szrj else if ((!quiet_warnings || flag_code == CODE_64BIT)
5717*a9fa9459Szrj && (i.types[op].bitfield.reg32
5718*a9fa9459Szrj || i.types[op].bitfield.reg64)
5719*a9fa9459Szrj && (i.tm.operand_types[op].bitfield.reg16
5720*a9fa9459Szrj || i.tm.operand_types[op].bitfield.acc))
5721*a9fa9459Szrj {
5722*a9fa9459Szrj /* Prohibit these changes in the 64bit mode, since the
5723*a9fa9459Szrj lowering is more complicated. */
5724*a9fa9459Szrj if (flag_code == CODE_64BIT)
5725*a9fa9459Szrj {
5726*a9fa9459Szrj as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
5727*a9fa9459Szrj register_prefix, i.op[op].regs->reg_name,
5728*a9fa9459Szrj i.suffix);
5729*a9fa9459Szrj return 0;
5730*a9fa9459Szrj }
5731*a9fa9459Szrj #if REGISTER_WARNINGS
5732*a9fa9459Szrj as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
5733*a9fa9459Szrj register_prefix,
5734*a9fa9459Szrj (i.op[op].regs + REGNAM_AX - REGNAM_EAX)->reg_name,
5735*a9fa9459Szrj register_prefix, i.op[op].regs->reg_name, i.suffix);
5736*a9fa9459Szrj #endif
5737*a9fa9459Szrj }
5738*a9fa9459Szrj return 1;
5739*a9fa9459Szrj }
5740*a9fa9459Szrj
5741*a9fa9459Szrj static int
update_imm(unsigned int j)5742*a9fa9459Szrj update_imm (unsigned int j)
5743*a9fa9459Szrj {
5744*a9fa9459Szrj i386_operand_type overlap = i.types[j];
5745*a9fa9459Szrj if ((overlap.bitfield.imm8
5746*a9fa9459Szrj || overlap.bitfield.imm8s
5747*a9fa9459Szrj || overlap.bitfield.imm16
5748*a9fa9459Szrj || overlap.bitfield.imm32
5749*a9fa9459Szrj || overlap.bitfield.imm32s
5750*a9fa9459Szrj || overlap.bitfield.imm64)
5751*a9fa9459Szrj && !operand_type_equal (&overlap, &imm8)
5752*a9fa9459Szrj && !operand_type_equal (&overlap, &imm8s)
5753*a9fa9459Szrj && !operand_type_equal (&overlap, &imm16)
5754*a9fa9459Szrj && !operand_type_equal (&overlap, &imm32)
5755*a9fa9459Szrj && !operand_type_equal (&overlap, &imm32s)
5756*a9fa9459Szrj && !operand_type_equal (&overlap, &imm64))
5757*a9fa9459Szrj {
5758*a9fa9459Szrj if (i.suffix)
5759*a9fa9459Szrj {
5760*a9fa9459Szrj i386_operand_type temp;
5761*a9fa9459Szrj
5762*a9fa9459Szrj operand_type_set (&temp, 0);
5763*a9fa9459Szrj if (i.suffix == BYTE_MNEM_SUFFIX)
5764*a9fa9459Szrj {
5765*a9fa9459Szrj temp.bitfield.imm8 = overlap.bitfield.imm8;
5766*a9fa9459Szrj temp.bitfield.imm8s = overlap.bitfield.imm8s;
5767*a9fa9459Szrj }
5768*a9fa9459Szrj else if (i.suffix == WORD_MNEM_SUFFIX)
5769*a9fa9459Szrj temp.bitfield.imm16 = overlap.bitfield.imm16;
5770*a9fa9459Szrj else if (i.suffix == QWORD_MNEM_SUFFIX)
5771*a9fa9459Szrj {
5772*a9fa9459Szrj temp.bitfield.imm64 = overlap.bitfield.imm64;
5773*a9fa9459Szrj temp.bitfield.imm32s = overlap.bitfield.imm32s;
5774*a9fa9459Szrj }
5775*a9fa9459Szrj else
5776*a9fa9459Szrj temp.bitfield.imm32 = overlap.bitfield.imm32;
5777*a9fa9459Szrj overlap = temp;
5778*a9fa9459Szrj }
5779*a9fa9459Szrj else if (operand_type_equal (&overlap, &imm16_32_32s)
5780*a9fa9459Szrj || operand_type_equal (&overlap, &imm16_32)
5781*a9fa9459Szrj || operand_type_equal (&overlap, &imm16_32s))
5782*a9fa9459Szrj {
5783*a9fa9459Szrj if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
5784*a9fa9459Szrj overlap = imm16;
5785*a9fa9459Szrj else
5786*a9fa9459Szrj overlap = imm32s;
5787*a9fa9459Szrj }
5788*a9fa9459Szrj if (!operand_type_equal (&overlap, &imm8)
5789*a9fa9459Szrj && !operand_type_equal (&overlap, &imm8s)
5790*a9fa9459Szrj && !operand_type_equal (&overlap, &imm16)
5791*a9fa9459Szrj && !operand_type_equal (&overlap, &imm32)
5792*a9fa9459Szrj && !operand_type_equal (&overlap, &imm32s)
5793*a9fa9459Szrj && !operand_type_equal (&overlap, &imm64))
5794*a9fa9459Szrj {
5795*a9fa9459Szrj as_bad (_("no instruction mnemonic suffix given; "
5796*a9fa9459Szrj "can't determine immediate size"));
5797*a9fa9459Szrj return 0;
5798*a9fa9459Szrj }
5799*a9fa9459Szrj }
5800*a9fa9459Szrj i.types[j] = overlap;
5801*a9fa9459Szrj
5802*a9fa9459Szrj return 1;
5803*a9fa9459Szrj }
5804*a9fa9459Szrj
5805*a9fa9459Szrj static int
finalize_imm(void)5806*a9fa9459Szrj finalize_imm (void)
5807*a9fa9459Szrj {
5808*a9fa9459Szrj unsigned int j, n;
5809*a9fa9459Szrj
5810*a9fa9459Szrj /* Update the first 2 immediate operands. */
5811*a9fa9459Szrj n = i.operands > 2 ? 2 : i.operands;
5812*a9fa9459Szrj if (n)
5813*a9fa9459Szrj {
5814*a9fa9459Szrj for (j = 0; j < n; j++)
5815*a9fa9459Szrj if (update_imm (j) == 0)
5816*a9fa9459Szrj return 0;
5817*a9fa9459Szrj
5818*a9fa9459Szrj /* The 3rd operand can't be immediate operand. */
5819*a9fa9459Szrj gas_assert (operand_type_check (i.types[2], imm) == 0);
5820*a9fa9459Szrj }
5821*a9fa9459Szrj
5822*a9fa9459Szrj return 1;
5823*a9fa9459Szrj }
5824*a9fa9459Szrj
5825*a9fa9459Szrj static int
bad_implicit_operand(int xmm)5826*a9fa9459Szrj bad_implicit_operand (int xmm)
5827*a9fa9459Szrj {
5828*a9fa9459Szrj const char *ireg = xmm ? "xmm0" : "ymm0";
5829*a9fa9459Szrj
5830*a9fa9459Szrj if (intel_syntax)
5831*a9fa9459Szrj as_bad (_("the last operand of `%s' must be `%s%s'"),
5832*a9fa9459Szrj i.tm.name, register_prefix, ireg);
5833*a9fa9459Szrj else
5834*a9fa9459Szrj as_bad (_("the first operand of `%s' must be `%s%s'"),
5835*a9fa9459Szrj i.tm.name, register_prefix, ireg);
5836*a9fa9459Szrj return 0;
5837*a9fa9459Szrj }
5838*a9fa9459Szrj
5839*a9fa9459Szrj static int
process_operands(void)5840*a9fa9459Szrj process_operands (void)
5841*a9fa9459Szrj {
5842*a9fa9459Szrj /* Default segment register this instruction will use for memory
5843*a9fa9459Szrj accesses. 0 means unknown. This is only for optimizing out
5844*a9fa9459Szrj unnecessary segment overrides. */
5845*a9fa9459Szrj const seg_entry *default_seg = 0;
5846*a9fa9459Szrj
5847*a9fa9459Szrj if (i.tm.opcode_modifier.sse2avx && i.tm.opcode_modifier.vexvvvv)
5848*a9fa9459Szrj {
5849*a9fa9459Szrj unsigned int dupl = i.operands;
5850*a9fa9459Szrj unsigned int dest = dupl - 1;
5851*a9fa9459Szrj unsigned int j;
5852*a9fa9459Szrj
5853*a9fa9459Szrj /* The destination must be an xmm register. */
5854*a9fa9459Szrj gas_assert (i.reg_operands
5855*a9fa9459Szrj && MAX_OPERANDS > dupl
5856*a9fa9459Szrj && operand_type_equal (&i.types[dest], ®xmm));
5857*a9fa9459Szrj
5858*a9fa9459Szrj if (i.tm.opcode_modifier.firstxmm0)
5859*a9fa9459Szrj {
5860*a9fa9459Szrj /* The first operand is implicit and must be xmm0. */
5861*a9fa9459Szrj gas_assert (operand_type_equal (&i.types[0], ®xmm));
5862*a9fa9459Szrj if (register_number (i.op[0].regs) != 0)
5863*a9fa9459Szrj return bad_implicit_operand (1);
5864*a9fa9459Szrj
5865*a9fa9459Szrj if (i.tm.opcode_modifier.vexsources == VEX3SOURCES)
5866*a9fa9459Szrj {
5867*a9fa9459Szrj /* Keep xmm0 for instructions with VEX prefix and 3
5868*a9fa9459Szrj sources. */
5869*a9fa9459Szrj goto duplicate;
5870*a9fa9459Szrj }
5871*a9fa9459Szrj else
5872*a9fa9459Szrj {
5873*a9fa9459Szrj /* We remove the first xmm0 and keep the number of
5874*a9fa9459Szrj operands unchanged, which in fact duplicates the
5875*a9fa9459Szrj destination. */
5876*a9fa9459Szrj for (j = 1; j < i.operands; j++)
5877*a9fa9459Szrj {
5878*a9fa9459Szrj i.op[j - 1] = i.op[j];
5879*a9fa9459Szrj i.types[j - 1] = i.types[j];
5880*a9fa9459Szrj i.tm.operand_types[j - 1] = i.tm.operand_types[j];
5881*a9fa9459Szrj }
5882*a9fa9459Szrj }
5883*a9fa9459Szrj }
5884*a9fa9459Szrj else if (i.tm.opcode_modifier.implicit1stxmm0)
5885*a9fa9459Szrj {
5886*a9fa9459Szrj gas_assert ((MAX_OPERANDS - 1) > dupl
5887*a9fa9459Szrj && (i.tm.opcode_modifier.vexsources
5888*a9fa9459Szrj == VEX3SOURCES));
5889*a9fa9459Szrj
5890*a9fa9459Szrj /* Add the implicit xmm0 for instructions with VEX prefix
5891*a9fa9459Szrj and 3 sources. */
5892*a9fa9459Szrj for (j = i.operands; j > 0; j--)
5893*a9fa9459Szrj {
5894*a9fa9459Szrj i.op[j] = i.op[j - 1];
5895*a9fa9459Szrj i.types[j] = i.types[j - 1];
5896*a9fa9459Szrj i.tm.operand_types[j] = i.tm.operand_types[j - 1];
5897*a9fa9459Szrj }
5898*a9fa9459Szrj i.op[0].regs
5899*a9fa9459Szrj = (const reg_entry *) hash_find (reg_hash, "xmm0");
5900*a9fa9459Szrj i.types[0] = regxmm;
5901*a9fa9459Szrj i.tm.operand_types[0] = regxmm;
5902*a9fa9459Szrj
5903*a9fa9459Szrj i.operands += 2;
5904*a9fa9459Szrj i.reg_operands += 2;
5905*a9fa9459Szrj i.tm.operands += 2;
5906*a9fa9459Szrj
5907*a9fa9459Szrj dupl++;
5908*a9fa9459Szrj dest++;
5909*a9fa9459Szrj i.op[dupl] = i.op[dest];
5910*a9fa9459Szrj i.types[dupl] = i.types[dest];
5911*a9fa9459Szrj i.tm.operand_types[dupl] = i.tm.operand_types[dest];
5912*a9fa9459Szrj }
5913*a9fa9459Szrj else
5914*a9fa9459Szrj {
5915*a9fa9459Szrj duplicate:
5916*a9fa9459Szrj i.operands++;
5917*a9fa9459Szrj i.reg_operands++;
5918*a9fa9459Szrj i.tm.operands++;
5919*a9fa9459Szrj
5920*a9fa9459Szrj i.op[dupl] = i.op[dest];
5921*a9fa9459Szrj i.types[dupl] = i.types[dest];
5922*a9fa9459Szrj i.tm.operand_types[dupl] = i.tm.operand_types[dest];
5923*a9fa9459Szrj }
5924*a9fa9459Szrj
5925*a9fa9459Szrj if (i.tm.opcode_modifier.immext)
5926*a9fa9459Szrj process_immext ();
5927*a9fa9459Szrj }
5928*a9fa9459Szrj else if (i.tm.opcode_modifier.firstxmm0)
5929*a9fa9459Szrj {
5930*a9fa9459Szrj unsigned int j;
5931*a9fa9459Szrj
5932*a9fa9459Szrj /* The first operand is implicit and must be xmm0/ymm0/zmm0. */
5933*a9fa9459Szrj gas_assert (i.reg_operands
5934*a9fa9459Szrj && (operand_type_equal (&i.types[0], ®xmm)
5935*a9fa9459Szrj || operand_type_equal (&i.types[0], ®ymm)
5936*a9fa9459Szrj || operand_type_equal (&i.types[0], ®zmm)));
5937*a9fa9459Szrj if (register_number (i.op[0].regs) != 0)
5938*a9fa9459Szrj return bad_implicit_operand (i.types[0].bitfield.regxmm);
5939*a9fa9459Szrj
5940*a9fa9459Szrj for (j = 1; j < i.operands; j++)
5941*a9fa9459Szrj {
5942*a9fa9459Szrj i.op[j - 1] = i.op[j];
5943*a9fa9459Szrj i.types[j - 1] = i.types[j];
5944*a9fa9459Szrj
5945*a9fa9459Szrj /* We need to adjust fields in i.tm since they are used by
5946*a9fa9459Szrj build_modrm_byte. */
5947*a9fa9459Szrj i.tm.operand_types [j - 1] = i.tm.operand_types [j];
5948*a9fa9459Szrj }
5949*a9fa9459Szrj
5950*a9fa9459Szrj i.operands--;
5951*a9fa9459Szrj i.reg_operands--;
5952*a9fa9459Szrj i.tm.operands--;
5953*a9fa9459Szrj }
5954*a9fa9459Szrj else if (i.tm.opcode_modifier.regkludge)
5955*a9fa9459Szrj {
5956*a9fa9459Szrj /* The imul $imm, %reg instruction is converted into
5957*a9fa9459Szrj imul $imm, %reg, %reg, and the clr %reg instruction
5958*a9fa9459Szrj is converted into xor %reg, %reg. */
5959*a9fa9459Szrj
5960*a9fa9459Szrj unsigned int first_reg_op;
5961*a9fa9459Szrj
5962*a9fa9459Szrj if (operand_type_check (i.types[0], reg))
5963*a9fa9459Szrj first_reg_op = 0;
5964*a9fa9459Szrj else
5965*a9fa9459Szrj first_reg_op = 1;
5966*a9fa9459Szrj /* Pretend we saw the extra register operand. */
5967*a9fa9459Szrj gas_assert (i.reg_operands == 1
5968*a9fa9459Szrj && i.op[first_reg_op + 1].regs == 0);
5969*a9fa9459Szrj i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
5970*a9fa9459Szrj i.types[first_reg_op + 1] = i.types[first_reg_op];
5971*a9fa9459Szrj i.operands++;
5972*a9fa9459Szrj i.reg_operands++;
5973*a9fa9459Szrj }
5974*a9fa9459Szrj
5975*a9fa9459Szrj if (i.tm.opcode_modifier.shortform)
5976*a9fa9459Szrj {
5977*a9fa9459Szrj if (i.types[0].bitfield.sreg2
5978*a9fa9459Szrj || i.types[0].bitfield.sreg3)
5979*a9fa9459Szrj {
5980*a9fa9459Szrj if (i.tm.base_opcode == POP_SEG_SHORT
5981*a9fa9459Szrj && i.op[0].regs->reg_num == 1)
5982*a9fa9459Szrj {
5983*a9fa9459Szrj as_bad (_("you can't `pop %scs'"), register_prefix);
5984*a9fa9459Szrj return 0;
5985*a9fa9459Szrj }
5986*a9fa9459Szrj i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
5987*a9fa9459Szrj if ((i.op[0].regs->reg_flags & RegRex) != 0)
5988*a9fa9459Szrj i.rex |= REX_B;
5989*a9fa9459Szrj }
5990*a9fa9459Szrj else
5991*a9fa9459Szrj {
5992*a9fa9459Szrj /* The register or float register operand is in operand
5993*a9fa9459Szrj 0 or 1. */
5994*a9fa9459Szrj unsigned int op;
5995*a9fa9459Szrj
5996*a9fa9459Szrj if (i.types[0].bitfield.floatreg
5997*a9fa9459Szrj || operand_type_check (i.types[0], reg))
5998*a9fa9459Szrj op = 0;
5999*a9fa9459Szrj else
6000*a9fa9459Szrj op = 1;
6001*a9fa9459Szrj /* Register goes in low 3 bits of opcode. */
6002*a9fa9459Szrj i.tm.base_opcode |= i.op[op].regs->reg_num;
6003*a9fa9459Szrj if ((i.op[op].regs->reg_flags & RegRex) != 0)
6004*a9fa9459Szrj i.rex |= REX_B;
6005*a9fa9459Szrj if (!quiet_warnings && i.tm.opcode_modifier.ugh)
6006*a9fa9459Szrj {
6007*a9fa9459Szrj /* Warn about some common errors, but press on regardless.
6008*a9fa9459Szrj The first case can be generated by gcc (<= 2.8.1). */
6009*a9fa9459Szrj if (i.operands == 2)
6010*a9fa9459Szrj {
6011*a9fa9459Szrj /* Reversed arguments on faddp, fsubp, etc. */
6012*a9fa9459Szrj as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name,
6013*a9fa9459Szrj register_prefix, i.op[!intel_syntax].regs->reg_name,
6014*a9fa9459Szrj register_prefix, i.op[intel_syntax].regs->reg_name);
6015*a9fa9459Szrj }
6016*a9fa9459Szrj else
6017*a9fa9459Szrj {
6018*a9fa9459Szrj /* Extraneous `l' suffix on fp insn. */
6019*a9fa9459Szrj as_warn (_("translating to `%s %s%s'"), i.tm.name,
6020*a9fa9459Szrj register_prefix, i.op[0].regs->reg_name);
6021*a9fa9459Szrj }
6022*a9fa9459Szrj }
6023*a9fa9459Szrj }
6024*a9fa9459Szrj }
6025*a9fa9459Szrj else if (i.tm.opcode_modifier.modrm)
6026*a9fa9459Szrj {
6027*a9fa9459Szrj /* The opcode is completed (modulo i.tm.extension_opcode which
6028*a9fa9459Szrj must be put into the modrm byte). Now, we make the modrm and
6029*a9fa9459Szrj index base bytes based on all the info we've collected. */
6030*a9fa9459Szrj
6031*a9fa9459Szrj default_seg = build_modrm_byte ();
6032*a9fa9459Szrj }
6033*a9fa9459Szrj else if ((i.tm.base_opcode & ~0x3) == MOV_AX_DISP32)
6034*a9fa9459Szrj {
6035*a9fa9459Szrj default_seg = &ds;
6036*a9fa9459Szrj }
6037*a9fa9459Szrj else if (i.tm.opcode_modifier.isstring)
6038*a9fa9459Szrj {
6039*a9fa9459Szrj /* For the string instructions that allow a segment override
6040*a9fa9459Szrj on one of their operands, the default segment is ds. */
6041*a9fa9459Szrj default_seg = &ds;
6042*a9fa9459Szrj }
6043*a9fa9459Szrj
6044*a9fa9459Szrj if (i.tm.base_opcode == 0x8d /* lea */
6045*a9fa9459Szrj && i.seg[0]
6046*a9fa9459Szrj && !quiet_warnings)
6047*a9fa9459Szrj as_warn (_("segment override on `%s' is ineffectual"), i.tm.name);
6048*a9fa9459Szrj
6049*a9fa9459Szrj /* If a segment was explicitly specified, and the specified segment
6050*a9fa9459Szrj is not the default, use an opcode prefix to select it. If we
6051*a9fa9459Szrj never figured out what the default segment is, then default_seg
6052*a9fa9459Szrj will be zero at this point, and the specified segment prefix will
6053*a9fa9459Szrj always be used. */
6054*a9fa9459Szrj if ((i.seg[0]) && (i.seg[0] != default_seg))
6055*a9fa9459Szrj {
6056*a9fa9459Szrj if (!add_prefix (i.seg[0]->seg_prefix))
6057*a9fa9459Szrj return 0;
6058*a9fa9459Szrj }
6059*a9fa9459Szrj return 1;
6060*a9fa9459Szrj }
6061*a9fa9459Szrj
6062*a9fa9459Szrj static const seg_entry *
build_modrm_byte(void)6063*a9fa9459Szrj build_modrm_byte (void)
6064*a9fa9459Szrj {
6065*a9fa9459Szrj const seg_entry *default_seg = 0;
6066*a9fa9459Szrj unsigned int source, dest;
6067*a9fa9459Szrj int vex_3_sources;
6068*a9fa9459Szrj
6069*a9fa9459Szrj /* The first operand of instructions with VEX prefix and 3 sources
6070*a9fa9459Szrj must be VEX_Imm4. */
6071*a9fa9459Szrj vex_3_sources = i.tm.opcode_modifier.vexsources == VEX3SOURCES;
6072*a9fa9459Szrj if (vex_3_sources)
6073*a9fa9459Szrj {
6074*a9fa9459Szrj unsigned int nds, reg_slot;
6075*a9fa9459Szrj expressionS *exp;
6076*a9fa9459Szrj
6077*a9fa9459Szrj if (i.tm.opcode_modifier.veximmext
6078*a9fa9459Szrj && i.tm.opcode_modifier.immext)
6079*a9fa9459Szrj {
6080*a9fa9459Szrj dest = i.operands - 2;
6081*a9fa9459Szrj gas_assert (dest == 3);
6082*a9fa9459Szrj }
6083*a9fa9459Szrj else
6084*a9fa9459Szrj dest = i.operands - 1;
6085*a9fa9459Szrj nds = dest - 1;
6086*a9fa9459Szrj
6087*a9fa9459Szrj /* There are 2 kinds of instructions:
6088*a9fa9459Szrj 1. 5 operands: 4 register operands or 3 register operands
6089*a9fa9459Szrj plus 1 memory operand plus one Vec_Imm4 operand, VexXDS, and
6090*a9fa9459Szrj VexW0 or VexW1. The destination must be either XMM, YMM or
6091*a9fa9459Szrj ZMM register.
6092*a9fa9459Szrj 2. 4 operands: 4 register operands or 3 register operands
6093*a9fa9459Szrj plus 1 memory operand, VexXDS, and VexImmExt */
6094*a9fa9459Szrj gas_assert ((i.reg_operands == 4
6095*a9fa9459Szrj || (i.reg_operands == 3 && i.mem_operands == 1))
6096*a9fa9459Szrj && i.tm.opcode_modifier.vexvvvv == VEXXDS
6097*a9fa9459Szrj && (i.tm.opcode_modifier.veximmext
6098*a9fa9459Szrj || (i.imm_operands == 1
6099*a9fa9459Szrj && i.types[0].bitfield.vec_imm4
6100*a9fa9459Szrj && (i.tm.opcode_modifier.vexw == VEXW0
6101*a9fa9459Szrj || i.tm.opcode_modifier.vexw == VEXW1)
6102*a9fa9459Szrj && (operand_type_equal (&i.tm.operand_types[dest], ®xmm)
6103*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[dest], ®ymm)
6104*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[dest], ®zmm)))));
6105*a9fa9459Szrj
6106*a9fa9459Szrj if (i.imm_operands == 0)
6107*a9fa9459Szrj {
6108*a9fa9459Szrj /* When there is no immediate operand, generate an 8bit
6109*a9fa9459Szrj immediate operand to encode the first operand. */
6110*a9fa9459Szrj exp = &im_expressions[i.imm_operands++];
6111*a9fa9459Szrj i.op[i.operands].imms = exp;
6112*a9fa9459Szrj i.types[i.operands] = imm8;
6113*a9fa9459Szrj i.operands++;
6114*a9fa9459Szrj /* If VexW1 is set, the first operand is the source and
6115*a9fa9459Szrj the second operand is encoded in the immediate operand. */
6116*a9fa9459Szrj if (i.tm.opcode_modifier.vexw == VEXW1)
6117*a9fa9459Szrj {
6118*a9fa9459Szrj source = 0;
6119*a9fa9459Szrj reg_slot = 1;
6120*a9fa9459Szrj }
6121*a9fa9459Szrj else
6122*a9fa9459Szrj {
6123*a9fa9459Szrj source = 1;
6124*a9fa9459Szrj reg_slot = 0;
6125*a9fa9459Szrj }
6126*a9fa9459Szrj
6127*a9fa9459Szrj /* FMA swaps REG and NDS. */
6128*a9fa9459Szrj if (i.tm.cpu_flags.bitfield.cpufma)
6129*a9fa9459Szrj {
6130*a9fa9459Szrj unsigned int tmp;
6131*a9fa9459Szrj tmp = reg_slot;
6132*a9fa9459Szrj reg_slot = nds;
6133*a9fa9459Szrj nds = tmp;
6134*a9fa9459Szrj }
6135*a9fa9459Szrj
6136*a9fa9459Szrj gas_assert (operand_type_equal (&i.tm.operand_types[reg_slot],
6137*a9fa9459Szrj ®xmm)
6138*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[reg_slot],
6139*a9fa9459Szrj ®ymm)
6140*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[reg_slot],
6141*a9fa9459Szrj ®zmm));
6142*a9fa9459Szrj exp->X_op = O_constant;
6143*a9fa9459Szrj exp->X_add_number = register_number (i.op[reg_slot].regs) << 4;
6144*a9fa9459Szrj gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0);
6145*a9fa9459Szrj }
6146*a9fa9459Szrj else
6147*a9fa9459Szrj {
6148*a9fa9459Szrj unsigned int imm_slot;
6149*a9fa9459Szrj
6150*a9fa9459Szrj if (i.tm.opcode_modifier.vexw == VEXW0)
6151*a9fa9459Szrj {
6152*a9fa9459Szrj /* If VexW0 is set, the third operand is the source and
6153*a9fa9459Szrj the second operand is encoded in the immediate
6154*a9fa9459Szrj operand. */
6155*a9fa9459Szrj source = 2;
6156*a9fa9459Szrj reg_slot = 1;
6157*a9fa9459Szrj }
6158*a9fa9459Szrj else
6159*a9fa9459Szrj {
6160*a9fa9459Szrj /* VexW1 is set, the second operand is the source and
6161*a9fa9459Szrj the third operand is encoded in the immediate
6162*a9fa9459Szrj operand. */
6163*a9fa9459Szrj source = 1;
6164*a9fa9459Szrj reg_slot = 2;
6165*a9fa9459Szrj }
6166*a9fa9459Szrj
6167*a9fa9459Szrj if (i.tm.opcode_modifier.immext)
6168*a9fa9459Szrj {
6169*a9fa9459Szrj /* When ImmExt is set, the immdiate byte is the last
6170*a9fa9459Szrj operand. */
6171*a9fa9459Szrj imm_slot = i.operands - 1;
6172*a9fa9459Szrj source--;
6173*a9fa9459Szrj reg_slot--;
6174*a9fa9459Szrj }
6175*a9fa9459Szrj else
6176*a9fa9459Szrj {
6177*a9fa9459Szrj imm_slot = 0;
6178*a9fa9459Szrj
6179*a9fa9459Szrj /* Turn on Imm8 so that output_imm will generate it. */
6180*a9fa9459Szrj i.types[imm_slot].bitfield.imm8 = 1;
6181*a9fa9459Szrj }
6182*a9fa9459Szrj
6183*a9fa9459Szrj gas_assert (operand_type_equal (&i.tm.operand_types[reg_slot],
6184*a9fa9459Szrj ®xmm)
6185*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[reg_slot],
6186*a9fa9459Szrj ®ymm)
6187*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[reg_slot],
6188*a9fa9459Szrj ®zmm));
6189*a9fa9459Szrj i.op[imm_slot].imms->X_add_number
6190*a9fa9459Szrj |= register_number (i.op[reg_slot].regs) << 4;
6191*a9fa9459Szrj gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0);
6192*a9fa9459Szrj }
6193*a9fa9459Szrj
6194*a9fa9459Szrj gas_assert (operand_type_equal (&i.tm.operand_types[nds], ®xmm)
6195*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[nds],
6196*a9fa9459Szrj ®ymm)
6197*a9fa9459Szrj || operand_type_equal (&i.tm.operand_types[nds],
6198*a9fa9459Szrj ®zmm));
6199*a9fa9459Szrj i.vex.register_specifier = i.op[nds].regs;
6200*a9fa9459Szrj }
6201*a9fa9459Szrj else
6202*a9fa9459Szrj source = dest = 0;
6203*a9fa9459Szrj
6204*a9fa9459Szrj /* i.reg_operands MUST be the number of real register operands;
6205*a9fa9459Szrj implicit registers do not count. If there are 3 register
6206*a9fa9459Szrj operands, it must be a instruction with VexNDS. For a
6207*a9fa9459Szrj instruction with VexNDD, the destination register is encoded
6208*a9fa9459Szrj in VEX prefix. If there are 4 register operands, it must be
6209*a9fa9459Szrj a instruction with VEX prefix and 3 sources. */
6210*a9fa9459Szrj if (i.mem_operands == 0
6211*a9fa9459Szrj && ((i.reg_operands == 2
6212*a9fa9459Szrj && i.tm.opcode_modifier.vexvvvv <= VEXXDS)
6213*a9fa9459Szrj || (i.reg_operands == 3
6214*a9fa9459Szrj && i.tm.opcode_modifier.vexvvvv == VEXXDS)
6215*a9fa9459Szrj || (i.reg_operands == 4 && vex_3_sources)))
6216*a9fa9459Szrj {
6217*a9fa9459Szrj switch (i.operands)
6218*a9fa9459Szrj {
6219*a9fa9459Szrj case 2:
6220*a9fa9459Szrj source = 0;
6221*a9fa9459Szrj break;
6222*a9fa9459Szrj case 3:
6223*a9fa9459Szrj /* When there are 3 operands, one of them may be immediate,
6224*a9fa9459Szrj which may be the first or the last operand. Otherwise,
6225*a9fa9459Szrj the first operand must be shift count register (cl) or it
6226*a9fa9459Szrj is an instruction with VexNDS. */
6227*a9fa9459Szrj gas_assert (i.imm_operands == 1
6228*a9fa9459Szrj || (i.imm_operands == 0
6229*a9fa9459Szrj && (i.tm.opcode_modifier.vexvvvv == VEXXDS
6230*a9fa9459Szrj || i.types[0].bitfield.shiftcount)));
6231*a9fa9459Szrj if (operand_type_check (i.types[0], imm)
6232*a9fa9459Szrj || i.types[0].bitfield.shiftcount)
6233*a9fa9459Szrj source = 1;
6234*a9fa9459Szrj else
6235*a9fa9459Szrj source = 0;
6236*a9fa9459Szrj break;
6237*a9fa9459Szrj case 4:
6238*a9fa9459Szrj /* When there are 4 operands, the first two must be 8bit
6239*a9fa9459Szrj immediate operands. The source operand will be the 3rd
6240*a9fa9459Szrj one.
6241*a9fa9459Szrj
6242*a9fa9459Szrj For instructions with VexNDS, if the first operand
6243*a9fa9459Szrj an imm8, the source operand is the 2nd one. If the last
6244*a9fa9459Szrj operand is imm8, the source operand is the first one. */
6245*a9fa9459Szrj gas_assert ((i.imm_operands == 2
6246*a9fa9459Szrj && i.types[0].bitfield.imm8
6247*a9fa9459Szrj && i.types[1].bitfield.imm8)
6248*a9fa9459Szrj || (i.tm.opcode_modifier.vexvvvv == VEXXDS
6249*a9fa9459Szrj && i.imm_operands == 1
6250*a9fa9459Szrj && (i.types[0].bitfield.imm8
6251*a9fa9459Szrj || i.types[i.operands - 1].bitfield.imm8
6252*a9fa9459Szrj || i.rounding)));
6253*a9fa9459Szrj if (i.imm_operands == 2)
6254*a9fa9459Szrj source = 2;
6255*a9fa9459Szrj else
6256*a9fa9459Szrj {
6257*a9fa9459Szrj if (i.types[0].bitfield.imm8)
6258*a9fa9459Szrj source = 1;
6259*a9fa9459Szrj else
6260*a9fa9459Szrj source = 0;
6261*a9fa9459Szrj }
6262*a9fa9459Szrj break;
6263*a9fa9459Szrj case 5:
6264*a9fa9459Szrj if (i.tm.opcode_modifier.evex)
6265*a9fa9459Szrj {
6266*a9fa9459Szrj /* For EVEX instructions, when there are 5 operands, the
6267*a9fa9459Szrj first one must be immediate operand. If the second one
6268*a9fa9459Szrj is immediate operand, the source operand is the 3th
6269*a9fa9459Szrj one. If the last one is immediate operand, the source
6270*a9fa9459Szrj operand is the 2nd one. */
6271*a9fa9459Szrj gas_assert (i.imm_operands == 2
6272*a9fa9459Szrj && i.tm.opcode_modifier.sae
6273*a9fa9459Szrj && operand_type_check (i.types[0], imm));
6274*a9fa9459Szrj if (operand_type_check (i.types[1], imm))
6275*a9fa9459Szrj source = 2;
6276*a9fa9459Szrj else if (operand_type_check (i.types[4], imm))
6277*a9fa9459Szrj source = 1;
6278*a9fa9459Szrj else
6279*a9fa9459Szrj abort ();
6280*a9fa9459Szrj }
6281*a9fa9459Szrj break;
6282*a9fa9459Szrj default:
6283*a9fa9459Szrj abort ();
6284*a9fa9459Szrj }
6285*a9fa9459Szrj
6286*a9fa9459Szrj if (!vex_3_sources)
6287*a9fa9459Szrj {
6288*a9fa9459Szrj dest = source + 1;
6289*a9fa9459Szrj
6290*a9fa9459Szrj /* RC/SAE operand could be between DEST and SRC. That happens
6291*a9fa9459Szrj when one operand is GPR and the other one is XMM/YMM/ZMM
6292*a9fa9459Szrj register. */
6293*a9fa9459Szrj if (i.rounding && i.rounding->operand == (int) dest)
6294*a9fa9459Szrj dest++;
6295*a9fa9459Szrj
6296*a9fa9459Szrj if (i.tm.opcode_modifier.vexvvvv == VEXXDS)
6297*a9fa9459Szrj {
6298*a9fa9459Szrj /* For instructions with VexNDS, the register-only source
6299*a9fa9459Szrj operand must be 32/64bit integer, XMM, YMM or ZMM
6300*a9fa9459Szrj register. It is encoded in VEX prefix. We need to
6301*a9fa9459Szrj clear RegMem bit before calling operand_type_equal. */
6302*a9fa9459Szrj
6303*a9fa9459Szrj i386_operand_type op;
6304*a9fa9459Szrj unsigned int vvvv;
6305*a9fa9459Szrj
6306*a9fa9459Szrj /* Check register-only source operand when two source
6307*a9fa9459Szrj operands are swapped. */
6308*a9fa9459Szrj if (!i.tm.operand_types[source].bitfield.baseindex
6309*a9fa9459Szrj && i.tm.operand_types[dest].bitfield.baseindex)
6310*a9fa9459Szrj {
6311*a9fa9459Szrj vvvv = source;
6312*a9fa9459Szrj source = dest;
6313*a9fa9459Szrj }
6314*a9fa9459Szrj else
6315*a9fa9459Szrj vvvv = dest;
6316*a9fa9459Szrj
6317*a9fa9459Szrj op = i.tm.operand_types[vvvv];
6318*a9fa9459Szrj op.bitfield.regmem = 0;
6319*a9fa9459Szrj if ((dest + 1) >= i.operands
6320*a9fa9459Szrj || (!op.bitfield.reg32
6321*a9fa9459Szrj && op.bitfield.reg64
6322*a9fa9459Szrj && !operand_type_equal (&op, ®xmm)
6323*a9fa9459Szrj && !operand_type_equal (&op, ®ymm)
6324*a9fa9459Szrj && !operand_type_equal (&op, ®zmm)
6325*a9fa9459Szrj && !operand_type_equal (&op, ®mask)))
6326*a9fa9459Szrj abort ();
6327*a9fa9459Szrj i.vex.register_specifier = i.op[vvvv].regs;
6328*a9fa9459Szrj dest++;
6329*a9fa9459Szrj }
6330*a9fa9459Szrj }
6331*a9fa9459Szrj
6332*a9fa9459Szrj i.rm.mode = 3;
6333*a9fa9459Szrj /* One of the register operands will be encoded in the i.tm.reg
6334*a9fa9459Szrj field, the other in the combined i.tm.mode and i.tm.regmem
6335*a9fa9459Szrj fields. If no form of this instruction supports a memory
6336*a9fa9459Szrj destination operand, then we assume the source operand may
6337*a9fa9459Szrj sometimes be a memory operand and so we need to store the
6338*a9fa9459Szrj destination in the i.rm.reg field. */
6339*a9fa9459Szrj if (!i.tm.operand_types[dest].bitfield.regmem
6340*a9fa9459Szrj && operand_type_check (i.tm.operand_types[dest], anymem) == 0)
6341*a9fa9459Szrj {
6342*a9fa9459Szrj i.rm.reg = i.op[dest].regs->reg_num;
6343*a9fa9459Szrj i.rm.regmem = i.op[source].regs->reg_num;
6344*a9fa9459Szrj if ((i.op[dest].regs->reg_flags & RegRex) != 0)
6345*a9fa9459Szrj i.rex |= REX_R;
6346*a9fa9459Szrj if ((i.op[dest].regs->reg_flags & RegVRex) != 0)
6347*a9fa9459Szrj i.vrex |= REX_R;
6348*a9fa9459Szrj if ((i.op[source].regs->reg_flags & RegRex) != 0)
6349*a9fa9459Szrj i.rex |= REX_B;
6350*a9fa9459Szrj if ((i.op[source].regs->reg_flags & RegVRex) != 0)
6351*a9fa9459Szrj i.vrex |= REX_B;
6352*a9fa9459Szrj }
6353*a9fa9459Szrj else
6354*a9fa9459Szrj {
6355*a9fa9459Szrj i.rm.reg = i.op[source].regs->reg_num;
6356*a9fa9459Szrj i.rm.regmem = i.op[dest].regs->reg_num;
6357*a9fa9459Szrj if ((i.op[dest].regs->reg_flags & RegRex) != 0)
6358*a9fa9459Szrj i.rex |= REX_B;
6359*a9fa9459Szrj if ((i.op[dest].regs->reg_flags & RegVRex) != 0)
6360*a9fa9459Szrj i.vrex |= REX_B;
6361*a9fa9459Szrj if ((i.op[source].regs->reg_flags & RegRex) != 0)
6362*a9fa9459Szrj i.rex |= REX_R;
6363*a9fa9459Szrj if ((i.op[source].regs->reg_flags & RegVRex) != 0)
6364*a9fa9459Szrj i.vrex |= REX_R;
6365*a9fa9459Szrj }
6366*a9fa9459Szrj if (flag_code != CODE_64BIT && (i.rex & (REX_R | REX_B)))
6367*a9fa9459Szrj {
6368*a9fa9459Szrj if (!i.types[0].bitfield.control
6369*a9fa9459Szrj && !i.types[1].bitfield.control)
6370*a9fa9459Szrj abort ();
6371*a9fa9459Szrj i.rex &= ~(REX_R | REX_B);
6372*a9fa9459Szrj add_prefix (LOCK_PREFIX_OPCODE);
6373*a9fa9459Szrj }
6374*a9fa9459Szrj }
6375*a9fa9459Szrj else
6376*a9fa9459Szrj { /* If it's not 2 reg operands... */
6377*a9fa9459Szrj unsigned int mem;
6378*a9fa9459Szrj
6379*a9fa9459Szrj if (i.mem_operands)
6380*a9fa9459Szrj {
6381*a9fa9459Szrj unsigned int fake_zero_displacement = 0;
6382*a9fa9459Szrj unsigned int op;
6383*a9fa9459Szrj
6384*a9fa9459Szrj for (op = 0; op < i.operands; op++)
6385*a9fa9459Szrj if (operand_type_check (i.types[op], anymem))
6386*a9fa9459Szrj break;
6387*a9fa9459Szrj gas_assert (op < i.operands);
6388*a9fa9459Szrj
6389*a9fa9459Szrj if (i.tm.opcode_modifier.vecsib)
6390*a9fa9459Szrj {
6391*a9fa9459Szrj if (i.index_reg->reg_num == RegEiz
6392*a9fa9459Szrj || i.index_reg->reg_num == RegRiz)
6393*a9fa9459Szrj abort ();
6394*a9fa9459Szrj
6395*a9fa9459Szrj i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
6396*a9fa9459Szrj if (!i.base_reg)
6397*a9fa9459Szrj {
6398*a9fa9459Szrj i.sib.base = NO_BASE_REGISTER;
6399*a9fa9459Szrj i.sib.scale = i.log2_scale_factor;
6400*a9fa9459Szrj /* No Vec_Disp8 if there is no base. */
6401*a9fa9459Szrj i.types[op].bitfield.vec_disp8 = 0;
6402*a9fa9459Szrj i.types[op].bitfield.disp8 = 0;
6403*a9fa9459Szrj i.types[op].bitfield.disp16 = 0;
6404*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
6405*a9fa9459Szrj if (flag_code != CODE_64BIT)
6406*a9fa9459Szrj {
6407*a9fa9459Szrj /* Must be 32 bit */
6408*a9fa9459Szrj i.types[op].bitfield.disp32 = 1;
6409*a9fa9459Szrj i.types[op].bitfield.disp32s = 0;
6410*a9fa9459Szrj }
6411*a9fa9459Szrj else
6412*a9fa9459Szrj {
6413*a9fa9459Szrj i.types[op].bitfield.disp32 = 0;
6414*a9fa9459Szrj i.types[op].bitfield.disp32s = 1;
6415*a9fa9459Szrj }
6416*a9fa9459Szrj }
6417*a9fa9459Szrj i.sib.index = i.index_reg->reg_num;
6418*a9fa9459Szrj if ((i.index_reg->reg_flags & RegRex) != 0)
6419*a9fa9459Szrj i.rex |= REX_X;
6420*a9fa9459Szrj if ((i.index_reg->reg_flags & RegVRex) != 0)
6421*a9fa9459Szrj i.vrex |= REX_X;
6422*a9fa9459Szrj }
6423*a9fa9459Szrj
6424*a9fa9459Szrj default_seg = &ds;
6425*a9fa9459Szrj
6426*a9fa9459Szrj if (i.base_reg == 0)
6427*a9fa9459Szrj {
6428*a9fa9459Szrj i.rm.mode = 0;
6429*a9fa9459Szrj if (!i.disp_operands)
6430*a9fa9459Szrj {
6431*a9fa9459Szrj fake_zero_displacement = 1;
6432*a9fa9459Szrj /* Instructions with VSIB byte need 32bit displacement
6433*a9fa9459Szrj if there is no base register. */
6434*a9fa9459Szrj if (i.tm.opcode_modifier.vecsib)
6435*a9fa9459Szrj i.types[op].bitfield.disp32 = 1;
6436*a9fa9459Szrj }
6437*a9fa9459Szrj if (i.index_reg == 0)
6438*a9fa9459Szrj {
6439*a9fa9459Szrj gas_assert (!i.tm.opcode_modifier.vecsib);
6440*a9fa9459Szrj /* Operand is just <disp> */
6441*a9fa9459Szrj if (flag_code == CODE_64BIT)
6442*a9fa9459Szrj {
6443*a9fa9459Szrj /* 64bit mode overwrites the 32bit absolute
6444*a9fa9459Szrj addressing by RIP relative addressing and
6445*a9fa9459Szrj absolute addressing is encoded by one of the
6446*a9fa9459Szrj redundant SIB forms. */
6447*a9fa9459Szrj i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
6448*a9fa9459Szrj i.sib.base = NO_BASE_REGISTER;
6449*a9fa9459Szrj i.sib.index = NO_INDEX_REGISTER;
6450*a9fa9459Szrj i.types[op] = ((i.prefix[ADDR_PREFIX] == 0)
6451*a9fa9459Szrj ? disp32s : disp32);
6452*a9fa9459Szrj }
6453*a9fa9459Szrj else if ((flag_code == CODE_16BIT)
6454*a9fa9459Szrj ^ (i.prefix[ADDR_PREFIX] != 0))
6455*a9fa9459Szrj {
6456*a9fa9459Szrj i.rm.regmem = NO_BASE_REGISTER_16;
6457*a9fa9459Szrj i.types[op] = disp16;
6458*a9fa9459Szrj }
6459*a9fa9459Szrj else
6460*a9fa9459Szrj {
6461*a9fa9459Szrj i.rm.regmem = NO_BASE_REGISTER;
6462*a9fa9459Szrj i.types[op] = disp32;
6463*a9fa9459Szrj }
6464*a9fa9459Szrj }
6465*a9fa9459Szrj else if (!i.tm.opcode_modifier.vecsib)
6466*a9fa9459Szrj {
6467*a9fa9459Szrj /* !i.base_reg && i.index_reg */
6468*a9fa9459Szrj if (i.index_reg->reg_num == RegEiz
6469*a9fa9459Szrj || i.index_reg->reg_num == RegRiz)
6470*a9fa9459Szrj i.sib.index = NO_INDEX_REGISTER;
6471*a9fa9459Szrj else
6472*a9fa9459Szrj i.sib.index = i.index_reg->reg_num;
6473*a9fa9459Szrj i.sib.base = NO_BASE_REGISTER;
6474*a9fa9459Szrj i.sib.scale = i.log2_scale_factor;
6475*a9fa9459Szrj i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
6476*a9fa9459Szrj /* No Vec_Disp8 if there is no base. */
6477*a9fa9459Szrj i.types[op].bitfield.vec_disp8 = 0;
6478*a9fa9459Szrj i.types[op].bitfield.disp8 = 0;
6479*a9fa9459Szrj i.types[op].bitfield.disp16 = 0;
6480*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
6481*a9fa9459Szrj if (flag_code != CODE_64BIT)
6482*a9fa9459Szrj {
6483*a9fa9459Szrj /* Must be 32 bit */
6484*a9fa9459Szrj i.types[op].bitfield.disp32 = 1;
6485*a9fa9459Szrj i.types[op].bitfield.disp32s = 0;
6486*a9fa9459Szrj }
6487*a9fa9459Szrj else
6488*a9fa9459Szrj {
6489*a9fa9459Szrj i.types[op].bitfield.disp32 = 0;
6490*a9fa9459Szrj i.types[op].bitfield.disp32s = 1;
6491*a9fa9459Szrj }
6492*a9fa9459Szrj if ((i.index_reg->reg_flags & RegRex) != 0)
6493*a9fa9459Szrj i.rex |= REX_X;
6494*a9fa9459Szrj }
6495*a9fa9459Szrj }
6496*a9fa9459Szrj /* RIP addressing for 64bit mode. */
6497*a9fa9459Szrj else if (i.base_reg->reg_num == RegRip ||
6498*a9fa9459Szrj i.base_reg->reg_num == RegEip)
6499*a9fa9459Szrj {
6500*a9fa9459Szrj gas_assert (!i.tm.opcode_modifier.vecsib);
6501*a9fa9459Szrj i.rm.regmem = NO_BASE_REGISTER;
6502*a9fa9459Szrj i.types[op].bitfield.disp8 = 0;
6503*a9fa9459Szrj i.types[op].bitfield.disp16 = 0;
6504*a9fa9459Szrj i.types[op].bitfield.disp32 = 0;
6505*a9fa9459Szrj i.types[op].bitfield.disp32s = 1;
6506*a9fa9459Szrj i.types[op].bitfield.disp64 = 0;
6507*a9fa9459Szrj i.types[op].bitfield.vec_disp8 = 0;
6508*a9fa9459Szrj i.flags[op] |= Operand_PCrel;
6509*a9fa9459Szrj if (! i.disp_operands)
6510*a9fa9459Szrj fake_zero_displacement = 1;
6511*a9fa9459Szrj }
6512*a9fa9459Szrj else if (i.base_reg->reg_type.bitfield.reg16)
6513*a9fa9459Szrj {
6514*a9fa9459Szrj gas_assert (!i.tm.opcode_modifier.vecsib);
6515*a9fa9459Szrj switch (i.base_reg->reg_num)
6516*a9fa9459Szrj {
6517*a9fa9459Szrj case 3: /* (%bx) */
6518*a9fa9459Szrj if (i.index_reg == 0)
6519*a9fa9459Szrj i.rm.regmem = 7;
6520*a9fa9459Szrj else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */
6521*a9fa9459Szrj i.rm.regmem = i.index_reg->reg_num - 6;
6522*a9fa9459Szrj break;
6523*a9fa9459Szrj case 5: /* (%bp) */
6524*a9fa9459Szrj default_seg = &ss;
6525*a9fa9459Szrj if (i.index_reg == 0)
6526*a9fa9459Szrj {
6527*a9fa9459Szrj i.rm.regmem = 6;
6528*a9fa9459Szrj if (operand_type_check (i.types[op], disp) == 0)
6529*a9fa9459Szrj {
6530*a9fa9459Szrj /* fake (%bp) into 0(%bp) */
6531*a9fa9459Szrj if (i.tm.operand_types[op].bitfield.vec_disp8)
6532*a9fa9459Szrj i.types[op].bitfield.vec_disp8 = 1;
6533*a9fa9459Szrj else
6534*a9fa9459Szrj i.types[op].bitfield.disp8 = 1;
6535*a9fa9459Szrj fake_zero_displacement = 1;
6536*a9fa9459Szrj }
6537*a9fa9459Szrj }
6538*a9fa9459Szrj else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */
6539*a9fa9459Szrj i.rm.regmem = i.index_reg->reg_num - 6 + 2;
6540*a9fa9459Szrj break;
6541*a9fa9459Szrj default: /* (%si) -> 4 or (%di) -> 5 */
6542*a9fa9459Szrj i.rm.regmem = i.base_reg->reg_num - 6 + 4;
6543*a9fa9459Szrj }
6544*a9fa9459Szrj i.rm.mode = mode_from_disp_size (i.types[op]);
6545*a9fa9459Szrj }
6546*a9fa9459Szrj else /* i.base_reg and 32/64 bit mode */
6547*a9fa9459Szrj {
6548*a9fa9459Szrj if (flag_code == CODE_64BIT
6549*a9fa9459Szrj && operand_type_check (i.types[op], disp))
6550*a9fa9459Szrj {
6551*a9fa9459Szrj i386_operand_type temp;
6552*a9fa9459Szrj operand_type_set (&temp, 0);
6553*a9fa9459Szrj temp.bitfield.disp8 = i.types[op].bitfield.disp8;
6554*a9fa9459Szrj temp.bitfield.vec_disp8
6555*a9fa9459Szrj = i.types[op].bitfield.vec_disp8;
6556*a9fa9459Szrj i.types[op] = temp;
6557*a9fa9459Szrj if (i.prefix[ADDR_PREFIX] == 0)
6558*a9fa9459Szrj i.types[op].bitfield.disp32s = 1;
6559*a9fa9459Szrj else
6560*a9fa9459Szrj i.types[op].bitfield.disp32 = 1;
6561*a9fa9459Szrj }
6562*a9fa9459Szrj
6563*a9fa9459Szrj if (!i.tm.opcode_modifier.vecsib)
6564*a9fa9459Szrj i.rm.regmem = i.base_reg->reg_num;
6565*a9fa9459Szrj if ((i.base_reg->reg_flags & RegRex) != 0)
6566*a9fa9459Szrj i.rex |= REX_B;
6567*a9fa9459Szrj i.sib.base = i.base_reg->reg_num;
6568*a9fa9459Szrj /* x86-64 ignores REX prefix bit here to avoid decoder
6569*a9fa9459Szrj complications. */
6570*a9fa9459Szrj if (!(i.base_reg->reg_flags & RegRex)
6571*a9fa9459Szrj && (i.base_reg->reg_num == EBP_REG_NUM
6572*a9fa9459Szrj || i.base_reg->reg_num == ESP_REG_NUM))
6573*a9fa9459Szrj default_seg = &ss;
6574*a9fa9459Szrj if (i.base_reg->reg_num == 5 && i.disp_operands == 0)
6575*a9fa9459Szrj {
6576*a9fa9459Szrj fake_zero_displacement = 1;
6577*a9fa9459Szrj if (i.tm.operand_types [op].bitfield.vec_disp8)
6578*a9fa9459Szrj i.types[op].bitfield.vec_disp8 = 1;
6579*a9fa9459Szrj else
6580*a9fa9459Szrj i.types[op].bitfield.disp8 = 1;
6581*a9fa9459Szrj }
6582*a9fa9459Szrj i.sib.scale = i.log2_scale_factor;
6583*a9fa9459Szrj if (i.index_reg == 0)
6584*a9fa9459Szrj {
6585*a9fa9459Szrj gas_assert (!i.tm.opcode_modifier.vecsib);
6586*a9fa9459Szrj /* <disp>(%esp) becomes two byte modrm with no index
6587*a9fa9459Szrj register. We've already stored the code for esp
6588*a9fa9459Szrj in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING.
6589*a9fa9459Szrj Any base register besides %esp will not use the
6590*a9fa9459Szrj extra modrm byte. */
6591*a9fa9459Szrj i.sib.index = NO_INDEX_REGISTER;
6592*a9fa9459Szrj }
6593*a9fa9459Szrj else if (!i.tm.opcode_modifier.vecsib)
6594*a9fa9459Szrj {
6595*a9fa9459Szrj if (i.index_reg->reg_num == RegEiz
6596*a9fa9459Szrj || i.index_reg->reg_num == RegRiz)
6597*a9fa9459Szrj i.sib.index = NO_INDEX_REGISTER;
6598*a9fa9459Szrj else
6599*a9fa9459Szrj i.sib.index = i.index_reg->reg_num;
6600*a9fa9459Szrj i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
6601*a9fa9459Szrj if ((i.index_reg->reg_flags & RegRex) != 0)
6602*a9fa9459Szrj i.rex |= REX_X;
6603*a9fa9459Szrj }
6604*a9fa9459Szrj
6605*a9fa9459Szrj if (i.disp_operands
6606*a9fa9459Szrj && (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL
6607*a9fa9459Szrj || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL))
6608*a9fa9459Szrj i.rm.mode = 0;
6609*a9fa9459Szrj else
6610*a9fa9459Szrj {
6611*a9fa9459Szrj if (!fake_zero_displacement
6612*a9fa9459Szrj && !i.disp_operands
6613*a9fa9459Szrj && i.disp_encoding)
6614*a9fa9459Szrj {
6615*a9fa9459Szrj fake_zero_displacement = 1;
6616*a9fa9459Szrj if (i.disp_encoding == disp_encoding_8bit)
6617*a9fa9459Szrj i.types[op].bitfield.disp8 = 1;
6618*a9fa9459Szrj else
6619*a9fa9459Szrj i.types[op].bitfield.disp32 = 1;
6620*a9fa9459Szrj }
6621*a9fa9459Szrj i.rm.mode = mode_from_disp_size (i.types[op]);
6622*a9fa9459Szrj }
6623*a9fa9459Szrj }
6624*a9fa9459Szrj
6625*a9fa9459Szrj if (fake_zero_displacement)
6626*a9fa9459Szrj {
6627*a9fa9459Szrj /* Fakes a zero displacement assuming that i.types[op]
6628*a9fa9459Szrj holds the correct displacement size. */
6629*a9fa9459Szrj expressionS *exp;
6630*a9fa9459Szrj
6631*a9fa9459Szrj gas_assert (i.op[op].disps == 0);
6632*a9fa9459Szrj exp = &disp_expressions[i.disp_operands++];
6633*a9fa9459Szrj i.op[op].disps = exp;
6634*a9fa9459Szrj exp->X_op = O_constant;
6635*a9fa9459Szrj exp->X_add_number = 0;
6636*a9fa9459Szrj exp->X_add_symbol = (symbolS *) 0;
6637*a9fa9459Szrj exp->X_op_symbol = (symbolS *) 0;
6638*a9fa9459Szrj }
6639*a9fa9459Szrj
6640*a9fa9459Szrj mem = op;
6641*a9fa9459Szrj }
6642*a9fa9459Szrj else
6643*a9fa9459Szrj mem = ~0;
6644*a9fa9459Szrj
6645*a9fa9459Szrj if (i.tm.opcode_modifier.vexsources == XOP2SOURCES)
6646*a9fa9459Szrj {
6647*a9fa9459Szrj if (operand_type_check (i.types[0], imm))
6648*a9fa9459Szrj i.vex.register_specifier = NULL;
6649*a9fa9459Szrj else
6650*a9fa9459Szrj {
6651*a9fa9459Szrj /* VEX.vvvv encodes one of the sources when the first
6652*a9fa9459Szrj operand is not an immediate. */
6653*a9fa9459Szrj if (i.tm.opcode_modifier.vexw == VEXW0)
6654*a9fa9459Szrj i.vex.register_specifier = i.op[0].regs;
6655*a9fa9459Szrj else
6656*a9fa9459Szrj i.vex.register_specifier = i.op[1].regs;
6657*a9fa9459Szrj }
6658*a9fa9459Szrj
6659*a9fa9459Szrj /* Destination is a XMM register encoded in the ModRM.reg
6660*a9fa9459Szrj and VEX.R bit. */
6661*a9fa9459Szrj i.rm.reg = i.op[2].regs->reg_num;
6662*a9fa9459Szrj if ((i.op[2].regs->reg_flags & RegRex) != 0)
6663*a9fa9459Szrj i.rex |= REX_R;
6664*a9fa9459Szrj
6665*a9fa9459Szrj /* ModRM.rm and VEX.B encodes the other source. */
6666*a9fa9459Szrj if (!i.mem_operands)
6667*a9fa9459Szrj {
6668*a9fa9459Szrj i.rm.mode = 3;
6669*a9fa9459Szrj
6670*a9fa9459Szrj if (i.tm.opcode_modifier.vexw == VEXW0)
6671*a9fa9459Szrj i.rm.regmem = i.op[1].regs->reg_num;
6672*a9fa9459Szrj else
6673*a9fa9459Szrj i.rm.regmem = i.op[0].regs->reg_num;
6674*a9fa9459Szrj
6675*a9fa9459Szrj if ((i.op[1].regs->reg_flags & RegRex) != 0)
6676*a9fa9459Szrj i.rex |= REX_B;
6677*a9fa9459Szrj }
6678*a9fa9459Szrj }
6679*a9fa9459Szrj else if (i.tm.opcode_modifier.vexvvvv == VEXLWP)
6680*a9fa9459Szrj {
6681*a9fa9459Szrj i.vex.register_specifier = i.op[2].regs;
6682*a9fa9459Szrj if (!i.mem_operands)
6683*a9fa9459Szrj {
6684*a9fa9459Szrj i.rm.mode = 3;
6685*a9fa9459Szrj i.rm.regmem = i.op[1].regs->reg_num;
6686*a9fa9459Szrj if ((i.op[1].regs->reg_flags & RegRex) != 0)
6687*a9fa9459Szrj i.rex |= REX_B;
6688*a9fa9459Szrj }
6689*a9fa9459Szrj }
6690*a9fa9459Szrj /* Fill in i.rm.reg or i.rm.regmem field with register operand
6691*a9fa9459Szrj (if any) based on i.tm.extension_opcode. Again, we must be
6692*a9fa9459Szrj careful to make sure that segment/control/debug/test/MMX
6693*a9fa9459Szrj registers are coded into the i.rm.reg field. */
6694*a9fa9459Szrj else if (i.reg_operands)
6695*a9fa9459Szrj {
6696*a9fa9459Szrj unsigned int op;
6697*a9fa9459Szrj unsigned int vex_reg = ~0;
6698*a9fa9459Szrj
6699*a9fa9459Szrj for (op = 0; op < i.operands; op++)
6700*a9fa9459Szrj if (i.types[op].bitfield.reg8
6701*a9fa9459Szrj || i.types[op].bitfield.reg16
6702*a9fa9459Szrj || i.types[op].bitfield.reg32
6703*a9fa9459Szrj || i.types[op].bitfield.reg64
6704*a9fa9459Szrj || i.types[op].bitfield.regmmx
6705*a9fa9459Szrj || i.types[op].bitfield.regxmm
6706*a9fa9459Szrj || i.types[op].bitfield.regymm
6707*a9fa9459Szrj || i.types[op].bitfield.regbnd
6708*a9fa9459Szrj || i.types[op].bitfield.regzmm
6709*a9fa9459Szrj || i.types[op].bitfield.regmask
6710*a9fa9459Szrj || i.types[op].bitfield.sreg2
6711*a9fa9459Szrj || i.types[op].bitfield.sreg3
6712*a9fa9459Szrj || i.types[op].bitfield.control
6713*a9fa9459Szrj || i.types[op].bitfield.debug
6714*a9fa9459Szrj || i.types[op].bitfield.test)
6715*a9fa9459Szrj break;
6716*a9fa9459Szrj
6717*a9fa9459Szrj if (vex_3_sources)
6718*a9fa9459Szrj op = dest;
6719*a9fa9459Szrj else if (i.tm.opcode_modifier.vexvvvv == VEXXDS)
6720*a9fa9459Szrj {
6721*a9fa9459Szrj /* For instructions with VexNDS, the register-only
6722*a9fa9459Szrj source operand is encoded in VEX prefix. */
6723*a9fa9459Szrj gas_assert (mem != (unsigned int) ~0);
6724*a9fa9459Szrj
6725*a9fa9459Szrj if (op > mem)
6726*a9fa9459Szrj {
6727*a9fa9459Szrj vex_reg = op++;
6728*a9fa9459Szrj gas_assert (op < i.operands);
6729*a9fa9459Szrj }
6730*a9fa9459Szrj else
6731*a9fa9459Szrj {
6732*a9fa9459Szrj /* Check register-only source operand when two source
6733*a9fa9459Szrj operands are swapped. */
6734*a9fa9459Szrj if (!i.tm.operand_types[op].bitfield.baseindex
6735*a9fa9459Szrj && i.tm.operand_types[op + 1].bitfield.baseindex)
6736*a9fa9459Szrj {
6737*a9fa9459Szrj vex_reg = op;
6738*a9fa9459Szrj op += 2;
6739*a9fa9459Szrj gas_assert (mem == (vex_reg + 1)
6740*a9fa9459Szrj && op < i.operands);
6741*a9fa9459Szrj }
6742*a9fa9459Szrj else
6743*a9fa9459Szrj {
6744*a9fa9459Szrj vex_reg = op + 1;
6745*a9fa9459Szrj gas_assert (vex_reg < i.operands);
6746*a9fa9459Szrj }
6747*a9fa9459Szrj }
6748*a9fa9459Szrj }
6749*a9fa9459Szrj else if (i.tm.opcode_modifier.vexvvvv == VEXNDD)
6750*a9fa9459Szrj {
6751*a9fa9459Szrj /* For instructions with VexNDD, the register destination
6752*a9fa9459Szrj is encoded in VEX prefix. */
6753*a9fa9459Szrj if (i.mem_operands == 0)
6754*a9fa9459Szrj {
6755*a9fa9459Szrj /* There is no memory operand. */
6756*a9fa9459Szrj gas_assert ((op + 2) == i.operands);
6757*a9fa9459Szrj vex_reg = op + 1;
6758*a9fa9459Szrj }
6759*a9fa9459Szrj else
6760*a9fa9459Szrj {
6761*a9fa9459Szrj /* There are only 2 operands. */
6762*a9fa9459Szrj gas_assert (op < 2 && i.operands == 2);
6763*a9fa9459Szrj vex_reg = 1;
6764*a9fa9459Szrj }
6765*a9fa9459Szrj }
6766*a9fa9459Szrj else
6767*a9fa9459Szrj gas_assert (op < i.operands);
6768*a9fa9459Szrj
6769*a9fa9459Szrj if (vex_reg != (unsigned int) ~0)
6770*a9fa9459Szrj {
6771*a9fa9459Szrj i386_operand_type *type = &i.tm.operand_types[vex_reg];
6772*a9fa9459Szrj
6773*a9fa9459Szrj if (type->bitfield.reg32 != 1
6774*a9fa9459Szrj && type->bitfield.reg64 != 1
6775*a9fa9459Szrj && !operand_type_equal (type, ®xmm)
6776*a9fa9459Szrj && !operand_type_equal (type, ®ymm)
6777*a9fa9459Szrj && !operand_type_equal (type, ®zmm)
6778*a9fa9459Szrj && !operand_type_equal (type, ®mask))
6779*a9fa9459Szrj abort ();
6780*a9fa9459Szrj
6781*a9fa9459Szrj i.vex.register_specifier = i.op[vex_reg].regs;
6782*a9fa9459Szrj }
6783*a9fa9459Szrj
6784*a9fa9459Szrj /* Don't set OP operand twice. */
6785*a9fa9459Szrj if (vex_reg != op)
6786*a9fa9459Szrj {
6787*a9fa9459Szrj /* If there is an extension opcode to put here, the
6788*a9fa9459Szrj register number must be put into the regmem field. */
6789*a9fa9459Szrj if (i.tm.extension_opcode != None)
6790*a9fa9459Szrj {
6791*a9fa9459Szrj i.rm.regmem = i.op[op].regs->reg_num;
6792*a9fa9459Szrj if ((i.op[op].regs->reg_flags & RegRex) != 0)
6793*a9fa9459Szrj i.rex |= REX_B;
6794*a9fa9459Szrj if ((i.op[op].regs->reg_flags & RegVRex) != 0)
6795*a9fa9459Szrj i.vrex |= REX_B;
6796*a9fa9459Szrj }
6797*a9fa9459Szrj else
6798*a9fa9459Szrj {
6799*a9fa9459Szrj i.rm.reg = i.op[op].regs->reg_num;
6800*a9fa9459Szrj if ((i.op[op].regs->reg_flags & RegRex) != 0)
6801*a9fa9459Szrj i.rex |= REX_R;
6802*a9fa9459Szrj if ((i.op[op].regs->reg_flags & RegVRex) != 0)
6803*a9fa9459Szrj i.vrex |= REX_R;
6804*a9fa9459Szrj }
6805*a9fa9459Szrj }
6806*a9fa9459Szrj
6807*a9fa9459Szrj /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we
6808*a9fa9459Szrj must set it to 3 to indicate this is a register operand
6809*a9fa9459Szrj in the regmem field. */
6810*a9fa9459Szrj if (!i.mem_operands)
6811*a9fa9459Szrj i.rm.mode = 3;
6812*a9fa9459Szrj }
6813*a9fa9459Szrj
6814*a9fa9459Szrj /* Fill in i.rm.reg field with extension opcode (if any). */
6815*a9fa9459Szrj if (i.tm.extension_opcode != None)
6816*a9fa9459Szrj i.rm.reg = i.tm.extension_opcode;
6817*a9fa9459Szrj }
6818*a9fa9459Szrj return default_seg;
6819*a9fa9459Szrj }
6820*a9fa9459Szrj
6821*a9fa9459Szrj static void
output_branch(void)6822*a9fa9459Szrj output_branch (void)
6823*a9fa9459Szrj {
6824*a9fa9459Szrj char *p;
6825*a9fa9459Szrj int size;
6826*a9fa9459Szrj int code16;
6827*a9fa9459Szrj int prefix;
6828*a9fa9459Szrj relax_substateT subtype;
6829*a9fa9459Szrj symbolS *sym;
6830*a9fa9459Szrj offsetT off;
6831*a9fa9459Szrj
6832*a9fa9459Szrj code16 = flag_code == CODE_16BIT ? CODE16 : 0;
6833*a9fa9459Szrj size = i.disp_encoding == disp_encoding_32bit ? BIG : SMALL;
6834*a9fa9459Szrj
6835*a9fa9459Szrj prefix = 0;
6836*a9fa9459Szrj if (i.prefix[DATA_PREFIX] != 0)
6837*a9fa9459Szrj {
6838*a9fa9459Szrj prefix = 1;
6839*a9fa9459Szrj i.prefixes -= 1;
6840*a9fa9459Szrj code16 ^= CODE16;
6841*a9fa9459Szrj }
6842*a9fa9459Szrj /* Pentium4 branch hints. */
6843*a9fa9459Szrj if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
6844*a9fa9459Szrj || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
6845*a9fa9459Szrj {
6846*a9fa9459Szrj prefix++;
6847*a9fa9459Szrj i.prefixes--;
6848*a9fa9459Szrj }
6849*a9fa9459Szrj if (i.prefix[REX_PREFIX] != 0)
6850*a9fa9459Szrj {
6851*a9fa9459Szrj prefix++;
6852*a9fa9459Szrj i.prefixes--;
6853*a9fa9459Szrj }
6854*a9fa9459Szrj
6855*a9fa9459Szrj /* BND prefixed jump. */
6856*a9fa9459Szrj if (i.prefix[BND_PREFIX] != 0)
6857*a9fa9459Szrj {
6858*a9fa9459Szrj FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
6859*a9fa9459Szrj i.prefixes -= 1;
6860*a9fa9459Szrj }
6861*a9fa9459Szrj
6862*a9fa9459Szrj if (i.prefixes != 0 && !intel_syntax)
6863*a9fa9459Szrj as_warn (_("skipping prefixes on this instruction"));
6864*a9fa9459Szrj
6865*a9fa9459Szrj /* It's always a symbol; End frag & setup for relax.
6866*a9fa9459Szrj Make sure there is enough room in this frag for the largest
6867*a9fa9459Szrj instruction we may generate in md_convert_frag. This is 2
6868*a9fa9459Szrj bytes for the opcode and room for the prefix and largest
6869*a9fa9459Szrj displacement. */
6870*a9fa9459Szrj frag_grow (prefix + 2 + 4);
6871*a9fa9459Szrj /* Prefix and 1 opcode byte go in fr_fix. */
6872*a9fa9459Szrj p = frag_more (prefix + 1);
6873*a9fa9459Szrj if (i.prefix[DATA_PREFIX] != 0)
6874*a9fa9459Szrj *p++ = DATA_PREFIX_OPCODE;
6875*a9fa9459Szrj if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE
6876*a9fa9459Szrj || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE)
6877*a9fa9459Szrj *p++ = i.prefix[SEG_PREFIX];
6878*a9fa9459Szrj if (i.prefix[REX_PREFIX] != 0)
6879*a9fa9459Szrj *p++ = i.prefix[REX_PREFIX];
6880*a9fa9459Szrj *p = i.tm.base_opcode;
6881*a9fa9459Szrj
6882*a9fa9459Szrj if ((unsigned char) *p == JUMP_PC_RELATIVE)
6883*a9fa9459Szrj subtype = ENCODE_RELAX_STATE (UNCOND_JUMP, size);
6884*a9fa9459Szrj else if (cpu_arch_flags.bitfield.cpui386)
6885*a9fa9459Szrj subtype = ENCODE_RELAX_STATE (COND_JUMP, size);
6886*a9fa9459Szrj else
6887*a9fa9459Szrj subtype = ENCODE_RELAX_STATE (COND_JUMP86, size);
6888*a9fa9459Szrj subtype |= code16;
6889*a9fa9459Szrj
6890*a9fa9459Szrj sym = i.op[0].disps->X_add_symbol;
6891*a9fa9459Szrj off = i.op[0].disps->X_add_number;
6892*a9fa9459Szrj
6893*a9fa9459Szrj if (i.op[0].disps->X_op != O_constant
6894*a9fa9459Szrj && i.op[0].disps->X_op != O_symbol)
6895*a9fa9459Szrj {
6896*a9fa9459Szrj /* Handle complex expressions. */
6897*a9fa9459Szrj sym = make_expr_symbol (i.op[0].disps);
6898*a9fa9459Szrj off = 0;
6899*a9fa9459Szrj }
6900*a9fa9459Szrj
6901*a9fa9459Szrj /* 1 possible extra opcode + 4 byte displacement go in var part.
6902*a9fa9459Szrj Pass reloc in fr_var. */
6903*a9fa9459Szrj frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p);
6904*a9fa9459Szrj }
6905*a9fa9459Szrj
6906*a9fa9459Szrj static void
output_jump(void)6907*a9fa9459Szrj output_jump (void)
6908*a9fa9459Szrj {
6909*a9fa9459Szrj char *p;
6910*a9fa9459Szrj int size;
6911*a9fa9459Szrj fixS *fixP;
6912*a9fa9459Szrj
6913*a9fa9459Szrj if (i.tm.opcode_modifier.jumpbyte)
6914*a9fa9459Szrj {
6915*a9fa9459Szrj /* This is a loop or jecxz type instruction. */
6916*a9fa9459Szrj size = 1;
6917*a9fa9459Szrj if (i.prefix[ADDR_PREFIX] != 0)
6918*a9fa9459Szrj {
6919*a9fa9459Szrj FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
6920*a9fa9459Szrj i.prefixes -= 1;
6921*a9fa9459Szrj }
6922*a9fa9459Szrj /* Pentium4 branch hints. */
6923*a9fa9459Szrj if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
6924*a9fa9459Szrj || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
6925*a9fa9459Szrj {
6926*a9fa9459Szrj FRAG_APPEND_1_CHAR (i.prefix[SEG_PREFIX]);
6927*a9fa9459Szrj i.prefixes--;
6928*a9fa9459Szrj }
6929*a9fa9459Szrj }
6930*a9fa9459Szrj else
6931*a9fa9459Szrj {
6932*a9fa9459Szrj int code16;
6933*a9fa9459Szrj
6934*a9fa9459Szrj code16 = 0;
6935*a9fa9459Szrj if (flag_code == CODE_16BIT)
6936*a9fa9459Szrj code16 = CODE16;
6937*a9fa9459Szrj
6938*a9fa9459Szrj if (i.prefix[DATA_PREFIX] != 0)
6939*a9fa9459Szrj {
6940*a9fa9459Szrj FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
6941*a9fa9459Szrj i.prefixes -= 1;
6942*a9fa9459Szrj code16 ^= CODE16;
6943*a9fa9459Szrj }
6944*a9fa9459Szrj
6945*a9fa9459Szrj size = 4;
6946*a9fa9459Szrj if (code16)
6947*a9fa9459Szrj size = 2;
6948*a9fa9459Szrj }
6949*a9fa9459Szrj
6950*a9fa9459Szrj if (i.prefix[REX_PREFIX] != 0)
6951*a9fa9459Szrj {
6952*a9fa9459Szrj FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]);
6953*a9fa9459Szrj i.prefixes -= 1;
6954*a9fa9459Szrj }
6955*a9fa9459Szrj
6956*a9fa9459Szrj /* BND prefixed jump. */
6957*a9fa9459Szrj if (i.prefix[BND_PREFIX] != 0)
6958*a9fa9459Szrj {
6959*a9fa9459Szrj FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
6960*a9fa9459Szrj i.prefixes -= 1;
6961*a9fa9459Szrj }
6962*a9fa9459Szrj
6963*a9fa9459Szrj if (i.prefixes != 0 && !intel_syntax)
6964*a9fa9459Szrj as_warn (_("skipping prefixes on this instruction"));
6965*a9fa9459Szrj
6966*a9fa9459Szrj p = frag_more (i.tm.opcode_length + size);
6967*a9fa9459Szrj switch (i.tm.opcode_length)
6968*a9fa9459Szrj {
6969*a9fa9459Szrj case 2:
6970*a9fa9459Szrj *p++ = i.tm.base_opcode >> 8;
6971*a9fa9459Szrj case 1:
6972*a9fa9459Szrj *p++ = i.tm.base_opcode;
6973*a9fa9459Szrj break;
6974*a9fa9459Szrj default:
6975*a9fa9459Szrj abort ();
6976*a9fa9459Szrj }
6977*a9fa9459Szrj
6978*a9fa9459Szrj fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
6979*a9fa9459Szrj i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
6980*a9fa9459Szrj
6981*a9fa9459Szrj /* All jumps handled here are signed, but don't use a signed limit
6982*a9fa9459Szrj check for 32 and 16 bit jumps as we want to allow wrap around at
6983*a9fa9459Szrj 4G and 64k respectively. */
6984*a9fa9459Szrj if (size == 1)
6985*a9fa9459Szrj fixP->fx_signed = 1;
6986*a9fa9459Szrj }
6987*a9fa9459Szrj
6988*a9fa9459Szrj static void
output_interseg_jump(void)6989*a9fa9459Szrj output_interseg_jump (void)
6990*a9fa9459Szrj {
6991*a9fa9459Szrj char *p;
6992*a9fa9459Szrj int size;
6993*a9fa9459Szrj int prefix;
6994*a9fa9459Szrj int code16;
6995*a9fa9459Szrj
6996*a9fa9459Szrj code16 = 0;
6997*a9fa9459Szrj if (flag_code == CODE_16BIT)
6998*a9fa9459Szrj code16 = CODE16;
6999*a9fa9459Szrj
7000*a9fa9459Szrj prefix = 0;
7001*a9fa9459Szrj if (i.prefix[DATA_PREFIX] != 0)
7002*a9fa9459Szrj {
7003*a9fa9459Szrj prefix = 1;
7004*a9fa9459Szrj i.prefixes -= 1;
7005*a9fa9459Szrj code16 ^= CODE16;
7006*a9fa9459Szrj }
7007*a9fa9459Szrj if (i.prefix[REX_PREFIX] != 0)
7008*a9fa9459Szrj {
7009*a9fa9459Szrj prefix++;
7010*a9fa9459Szrj i.prefixes -= 1;
7011*a9fa9459Szrj }
7012*a9fa9459Szrj
7013*a9fa9459Szrj size = 4;
7014*a9fa9459Szrj if (code16)
7015*a9fa9459Szrj size = 2;
7016*a9fa9459Szrj
7017*a9fa9459Szrj if (i.prefixes != 0 && !intel_syntax)
7018*a9fa9459Szrj as_warn (_("skipping prefixes on this instruction"));
7019*a9fa9459Szrj
7020*a9fa9459Szrj /* 1 opcode; 2 segment; offset */
7021*a9fa9459Szrj p = frag_more (prefix + 1 + 2 + size);
7022*a9fa9459Szrj
7023*a9fa9459Szrj if (i.prefix[DATA_PREFIX] != 0)
7024*a9fa9459Szrj *p++ = DATA_PREFIX_OPCODE;
7025*a9fa9459Szrj
7026*a9fa9459Szrj if (i.prefix[REX_PREFIX] != 0)
7027*a9fa9459Szrj *p++ = i.prefix[REX_PREFIX];
7028*a9fa9459Szrj
7029*a9fa9459Szrj *p++ = i.tm.base_opcode;
7030*a9fa9459Szrj if (i.op[1].imms->X_op == O_constant)
7031*a9fa9459Szrj {
7032*a9fa9459Szrj offsetT n = i.op[1].imms->X_add_number;
7033*a9fa9459Szrj
7034*a9fa9459Szrj if (size == 2
7035*a9fa9459Szrj && !fits_in_unsigned_word (n)
7036*a9fa9459Szrj && !fits_in_signed_word (n))
7037*a9fa9459Szrj {
7038*a9fa9459Szrj as_bad (_("16-bit jump out of range"));
7039*a9fa9459Szrj return;
7040*a9fa9459Szrj }
7041*a9fa9459Szrj md_number_to_chars (p, n, size);
7042*a9fa9459Szrj }
7043*a9fa9459Szrj else
7044*a9fa9459Szrj fix_new_exp (frag_now, p - frag_now->fr_literal, size,
7045*a9fa9459Szrj i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
7046*a9fa9459Szrj if (i.op[0].imms->X_op != O_constant)
7047*a9fa9459Szrj as_bad (_("can't handle non absolute segment in `%s'"),
7048*a9fa9459Szrj i.tm.name);
7049*a9fa9459Szrj md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
7050*a9fa9459Szrj }
7051*a9fa9459Szrj
7052*a9fa9459Szrj static void
output_insn(void)7053*a9fa9459Szrj output_insn (void)
7054*a9fa9459Szrj {
7055*a9fa9459Szrj fragS *insn_start_frag;
7056*a9fa9459Szrj offsetT insn_start_off;
7057*a9fa9459Szrj
7058*a9fa9459Szrj /* Tie dwarf2 debug info to the address at the start of the insn.
7059*a9fa9459Szrj We can't do this after the insn has been output as the current
7060*a9fa9459Szrj frag may have been closed off. eg. by frag_var. */
7061*a9fa9459Szrj dwarf2_emit_insn (0);
7062*a9fa9459Szrj
7063*a9fa9459Szrj insn_start_frag = frag_now;
7064*a9fa9459Szrj insn_start_off = frag_now_fix ();
7065*a9fa9459Szrj
7066*a9fa9459Szrj /* Output jumps. */
7067*a9fa9459Szrj if (i.tm.opcode_modifier.jump)
7068*a9fa9459Szrj output_branch ();
7069*a9fa9459Szrj else if (i.tm.opcode_modifier.jumpbyte
7070*a9fa9459Szrj || i.tm.opcode_modifier.jumpdword)
7071*a9fa9459Szrj output_jump ();
7072*a9fa9459Szrj else if (i.tm.opcode_modifier.jumpintersegment)
7073*a9fa9459Szrj output_interseg_jump ();
7074*a9fa9459Szrj else
7075*a9fa9459Szrj {
7076*a9fa9459Szrj /* Output normal instructions here. */
7077*a9fa9459Szrj char *p;
7078*a9fa9459Szrj unsigned char *q;
7079*a9fa9459Szrj unsigned int j;
7080*a9fa9459Szrj unsigned int prefix;
7081*a9fa9459Szrj
7082*a9fa9459Szrj if (avoid_fence
7083*a9fa9459Szrj && i.tm.base_opcode == 0xfae
7084*a9fa9459Szrj && i.operands == 1
7085*a9fa9459Szrj && i.imm_operands == 1
7086*a9fa9459Szrj && (i.op[0].imms->X_add_number == 0xe8
7087*a9fa9459Szrj || i.op[0].imms->X_add_number == 0xf0
7088*a9fa9459Szrj || i.op[0].imms->X_add_number == 0xf8))
7089*a9fa9459Szrj {
7090*a9fa9459Szrj /* Encode lfence, mfence, and sfence as
7091*a9fa9459Szrj f0 83 04 24 00 lock addl $0x0, (%{re}sp). */
7092*a9fa9459Szrj offsetT val = 0x240483f0ULL;
7093*a9fa9459Szrj p = frag_more (5);
7094*a9fa9459Szrj md_number_to_chars (p, val, 5);
7095*a9fa9459Szrj return;
7096*a9fa9459Szrj }
7097*a9fa9459Szrj
7098*a9fa9459Szrj /* Some processors fail on LOCK prefix. This options makes
7099*a9fa9459Szrj assembler ignore LOCK prefix and serves as a workaround. */
7100*a9fa9459Szrj if (omit_lock_prefix)
7101*a9fa9459Szrj {
7102*a9fa9459Szrj if (i.tm.base_opcode == LOCK_PREFIX_OPCODE)
7103*a9fa9459Szrj return;
7104*a9fa9459Szrj i.prefix[LOCK_PREFIX] = 0;
7105*a9fa9459Szrj }
7106*a9fa9459Szrj
7107*a9fa9459Szrj /* Since the VEX/EVEX prefix contains the implicit prefix, we
7108*a9fa9459Szrj don't need the explicit prefix. */
7109*a9fa9459Szrj if (!i.tm.opcode_modifier.vex && !i.tm.opcode_modifier.evex)
7110*a9fa9459Szrj {
7111*a9fa9459Szrj switch (i.tm.opcode_length)
7112*a9fa9459Szrj {
7113*a9fa9459Szrj case 3:
7114*a9fa9459Szrj if (i.tm.base_opcode & 0xff000000)
7115*a9fa9459Szrj {
7116*a9fa9459Szrj prefix = (i.tm.base_opcode >> 24) & 0xff;
7117*a9fa9459Szrj goto check_prefix;
7118*a9fa9459Szrj }
7119*a9fa9459Szrj break;
7120*a9fa9459Szrj case 2:
7121*a9fa9459Szrj if ((i.tm.base_opcode & 0xff0000) != 0)
7122*a9fa9459Szrj {
7123*a9fa9459Szrj prefix = (i.tm.base_opcode >> 16) & 0xff;
7124*a9fa9459Szrj if (i.tm.cpu_flags.bitfield.cpupadlock)
7125*a9fa9459Szrj {
7126*a9fa9459Szrj check_prefix:
7127*a9fa9459Szrj if (prefix != REPE_PREFIX_OPCODE
7128*a9fa9459Szrj || (i.prefix[REP_PREFIX]
7129*a9fa9459Szrj != REPE_PREFIX_OPCODE))
7130*a9fa9459Szrj add_prefix (prefix);
7131*a9fa9459Szrj }
7132*a9fa9459Szrj else
7133*a9fa9459Szrj add_prefix (prefix);
7134*a9fa9459Szrj }
7135*a9fa9459Szrj break;
7136*a9fa9459Szrj case 1:
7137*a9fa9459Szrj break;
7138*a9fa9459Szrj default:
7139*a9fa9459Szrj abort ();
7140*a9fa9459Szrj }
7141*a9fa9459Szrj
7142*a9fa9459Szrj #if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
7143*a9fa9459Szrj /* For x32, add a dummy REX_OPCODE prefix for mov/add with
7144*a9fa9459Szrj R_X86_64_GOTTPOFF relocation so that linker can safely
7145*a9fa9459Szrj perform IE->LE optimization. */
7146*a9fa9459Szrj if (x86_elf_abi == X86_64_X32_ABI
7147*a9fa9459Szrj && i.operands == 2
7148*a9fa9459Szrj && i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
7149*a9fa9459Szrj && i.prefix[REX_PREFIX] == 0)
7150*a9fa9459Szrj add_prefix (REX_OPCODE);
7151*a9fa9459Szrj #endif
7152*a9fa9459Szrj
7153*a9fa9459Szrj /* The prefix bytes. */
7154*a9fa9459Szrj for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
7155*a9fa9459Szrj if (*q)
7156*a9fa9459Szrj FRAG_APPEND_1_CHAR (*q);
7157*a9fa9459Szrj }
7158*a9fa9459Szrj else
7159*a9fa9459Szrj {
7160*a9fa9459Szrj for (j = 0, q = i.prefix; j < ARRAY_SIZE (i.prefix); j++, q++)
7161*a9fa9459Szrj if (*q)
7162*a9fa9459Szrj switch (j)
7163*a9fa9459Szrj {
7164*a9fa9459Szrj case REX_PREFIX:
7165*a9fa9459Szrj /* REX byte is encoded in VEX prefix. */
7166*a9fa9459Szrj break;
7167*a9fa9459Szrj case SEG_PREFIX:
7168*a9fa9459Szrj case ADDR_PREFIX:
7169*a9fa9459Szrj FRAG_APPEND_1_CHAR (*q);
7170*a9fa9459Szrj break;
7171*a9fa9459Szrj default:
7172*a9fa9459Szrj /* There should be no other prefixes for instructions
7173*a9fa9459Szrj with VEX prefix. */
7174*a9fa9459Szrj abort ();
7175*a9fa9459Szrj }
7176*a9fa9459Szrj
7177*a9fa9459Szrj /* For EVEX instructions i.vrex should become 0 after
7178*a9fa9459Szrj build_evex_prefix. For VEX instructions upper 16 registers
7179*a9fa9459Szrj aren't available, so VREX should be 0. */
7180*a9fa9459Szrj if (i.vrex)
7181*a9fa9459Szrj abort ();
7182*a9fa9459Szrj /* Now the VEX prefix. */
7183*a9fa9459Szrj p = frag_more (i.vex.length);
7184*a9fa9459Szrj for (j = 0; j < i.vex.length; j++)
7185*a9fa9459Szrj p[j] = i.vex.bytes[j];
7186*a9fa9459Szrj }
7187*a9fa9459Szrj
7188*a9fa9459Szrj /* Now the opcode; be careful about word order here! */
7189*a9fa9459Szrj if (i.tm.opcode_length == 1)
7190*a9fa9459Szrj {
7191*a9fa9459Szrj FRAG_APPEND_1_CHAR (i.tm.base_opcode);
7192*a9fa9459Szrj }
7193*a9fa9459Szrj else
7194*a9fa9459Szrj {
7195*a9fa9459Szrj switch (i.tm.opcode_length)
7196*a9fa9459Szrj {
7197*a9fa9459Szrj case 4:
7198*a9fa9459Szrj p = frag_more (4);
7199*a9fa9459Szrj *p++ = (i.tm.base_opcode >> 24) & 0xff;
7200*a9fa9459Szrj *p++ = (i.tm.base_opcode >> 16) & 0xff;
7201*a9fa9459Szrj break;
7202*a9fa9459Szrj case 3:
7203*a9fa9459Szrj p = frag_more (3);
7204*a9fa9459Szrj *p++ = (i.tm.base_opcode >> 16) & 0xff;
7205*a9fa9459Szrj break;
7206*a9fa9459Szrj case 2:
7207*a9fa9459Szrj p = frag_more (2);
7208*a9fa9459Szrj break;
7209*a9fa9459Szrj default:
7210*a9fa9459Szrj abort ();
7211*a9fa9459Szrj break;
7212*a9fa9459Szrj }
7213*a9fa9459Szrj
7214*a9fa9459Szrj /* Put out high byte first: can't use md_number_to_chars! */
7215*a9fa9459Szrj *p++ = (i.tm.base_opcode >> 8) & 0xff;
7216*a9fa9459Szrj *p = i.tm.base_opcode & 0xff;
7217*a9fa9459Szrj }
7218*a9fa9459Szrj
7219*a9fa9459Szrj /* Now the modrm byte and sib byte (if present). */
7220*a9fa9459Szrj if (i.tm.opcode_modifier.modrm)
7221*a9fa9459Szrj {
7222*a9fa9459Szrj FRAG_APPEND_1_CHAR ((i.rm.regmem << 0
7223*a9fa9459Szrj | i.rm.reg << 3
7224*a9fa9459Szrj | i.rm.mode << 6));
7225*a9fa9459Szrj /* If i.rm.regmem == ESP (4)
7226*a9fa9459Szrj && i.rm.mode != (Register mode)
7227*a9fa9459Szrj && not 16 bit
7228*a9fa9459Szrj ==> need second modrm byte. */
7229*a9fa9459Szrj if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING
7230*a9fa9459Szrj && i.rm.mode != 3
7231*a9fa9459Szrj && !(i.base_reg && i.base_reg->reg_type.bitfield.reg16))
7232*a9fa9459Szrj FRAG_APPEND_1_CHAR ((i.sib.base << 0
7233*a9fa9459Szrj | i.sib.index << 3
7234*a9fa9459Szrj | i.sib.scale << 6));
7235*a9fa9459Szrj }
7236*a9fa9459Szrj
7237*a9fa9459Szrj if (i.disp_operands)
7238*a9fa9459Szrj output_disp (insn_start_frag, insn_start_off);
7239*a9fa9459Szrj
7240*a9fa9459Szrj if (i.imm_operands)
7241*a9fa9459Szrj output_imm (insn_start_frag, insn_start_off);
7242*a9fa9459Szrj }
7243*a9fa9459Szrj
7244*a9fa9459Szrj #ifdef DEBUG386
7245*a9fa9459Szrj if (flag_debug)
7246*a9fa9459Szrj {
7247*a9fa9459Szrj pi ("" /*line*/, &i);
7248*a9fa9459Szrj }
7249*a9fa9459Szrj #endif /* DEBUG386 */
7250*a9fa9459Szrj }
7251*a9fa9459Szrj
7252*a9fa9459Szrj /* Return the size of the displacement operand N. */
7253*a9fa9459Szrj
7254*a9fa9459Szrj static int
disp_size(unsigned int n)7255*a9fa9459Szrj disp_size (unsigned int n)
7256*a9fa9459Szrj {
7257*a9fa9459Szrj int size = 4;
7258*a9fa9459Szrj
7259*a9fa9459Szrj /* Vec_Disp8 has to be 8bit. */
7260*a9fa9459Szrj if (i.types[n].bitfield.vec_disp8)
7261*a9fa9459Szrj size = 1;
7262*a9fa9459Szrj else if (i.types[n].bitfield.disp64)
7263*a9fa9459Szrj size = 8;
7264*a9fa9459Szrj else if (i.types[n].bitfield.disp8)
7265*a9fa9459Szrj size = 1;
7266*a9fa9459Szrj else if (i.types[n].bitfield.disp16)
7267*a9fa9459Szrj size = 2;
7268*a9fa9459Szrj return size;
7269*a9fa9459Szrj }
7270*a9fa9459Szrj
7271*a9fa9459Szrj /* Return the size of the immediate operand N. */
7272*a9fa9459Szrj
7273*a9fa9459Szrj static int
imm_size(unsigned int n)7274*a9fa9459Szrj imm_size (unsigned int n)
7275*a9fa9459Szrj {
7276*a9fa9459Szrj int size = 4;
7277*a9fa9459Szrj if (i.types[n].bitfield.imm64)
7278*a9fa9459Szrj size = 8;
7279*a9fa9459Szrj else if (i.types[n].bitfield.imm8 || i.types[n].bitfield.imm8s)
7280*a9fa9459Szrj size = 1;
7281*a9fa9459Szrj else if (i.types[n].bitfield.imm16)
7282*a9fa9459Szrj size = 2;
7283*a9fa9459Szrj return size;
7284*a9fa9459Szrj }
7285*a9fa9459Szrj
7286*a9fa9459Szrj static void
output_disp(fragS * insn_start_frag,offsetT insn_start_off)7287*a9fa9459Szrj output_disp (fragS *insn_start_frag, offsetT insn_start_off)
7288*a9fa9459Szrj {
7289*a9fa9459Szrj char *p;
7290*a9fa9459Szrj unsigned int n;
7291*a9fa9459Szrj
7292*a9fa9459Szrj for (n = 0; n < i.operands; n++)
7293*a9fa9459Szrj {
7294*a9fa9459Szrj if (i.types[n].bitfield.vec_disp8
7295*a9fa9459Szrj || operand_type_check (i.types[n], disp))
7296*a9fa9459Szrj {
7297*a9fa9459Szrj if (i.op[n].disps->X_op == O_constant)
7298*a9fa9459Szrj {
7299*a9fa9459Szrj int size = disp_size (n);
7300*a9fa9459Szrj offsetT val = i.op[n].disps->X_add_number;
7301*a9fa9459Szrj
7302*a9fa9459Szrj if (i.types[n].bitfield.vec_disp8)
7303*a9fa9459Szrj val >>= i.memshift;
7304*a9fa9459Szrj val = offset_in_range (val, size);
7305*a9fa9459Szrj p = frag_more (size);
7306*a9fa9459Szrj md_number_to_chars (p, val, size);
7307*a9fa9459Szrj }
7308*a9fa9459Szrj else
7309*a9fa9459Szrj {
7310*a9fa9459Szrj enum bfd_reloc_code_real reloc_type;
7311*a9fa9459Szrj int size = disp_size (n);
7312*a9fa9459Szrj int sign = i.types[n].bitfield.disp32s;
7313*a9fa9459Szrj int pcrel = (i.flags[n] & Operand_PCrel) != 0;
7314*a9fa9459Szrj fixS *fixP;
7315*a9fa9459Szrj
7316*a9fa9459Szrj /* We can't have 8 bit displacement here. */
7317*a9fa9459Szrj gas_assert (!i.types[n].bitfield.disp8);
7318*a9fa9459Szrj
7319*a9fa9459Szrj /* The PC relative address is computed relative
7320*a9fa9459Szrj to the instruction boundary, so in case immediate
7321*a9fa9459Szrj fields follows, we need to adjust the value. */
7322*a9fa9459Szrj if (pcrel && i.imm_operands)
7323*a9fa9459Szrj {
7324*a9fa9459Szrj unsigned int n1;
7325*a9fa9459Szrj int sz = 0;
7326*a9fa9459Szrj
7327*a9fa9459Szrj for (n1 = 0; n1 < i.operands; n1++)
7328*a9fa9459Szrj if (operand_type_check (i.types[n1], imm))
7329*a9fa9459Szrj {
7330*a9fa9459Szrj /* Only one immediate is allowed for PC
7331*a9fa9459Szrj relative address. */
7332*a9fa9459Szrj gas_assert (sz == 0);
7333*a9fa9459Szrj sz = imm_size (n1);
7334*a9fa9459Szrj i.op[n].disps->X_add_number -= sz;
7335*a9fa9459Szrj }
7336*a9fa9459Szrj /* We should find the immediate. */
7337*a9fa9459Szrj gas_assert (sz != 0);
7338*a9fa9459Szrj }
7339*a9fa9459Szrj
7340*a9fa9459Szrj p = frag_more (size);
7341*a9fa9459Szrj reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
7342*a9fa9459Szrj if (GOT_symbol
7343*a9fa9459Szrj && GOT_symbol == i.op[n].disps->X_add_symbol
7344*a9fa9459Szrj && (((reloc_type == BFD_RELOC_32
7345*a9fa9459Szrj || reloc_type == BFD_RELOC_X86_64_32S
7346*a9fa9459Szrj || (reloc_type == BFD_RELOC_64
7347*a9fa9459Szrj && object_64bit))
7348*a9fa9459Szrj && (i.op[n].disps->X_op == O_symbol
7349*a9fa9459Szrj || (i.op[n].disps->X_op == O_add
7350*a9fa9459Szrj && ((symbol_get_value_expression
7351*a9fa9459Szrj (i.op[n].disps->X_op_symbol)->X_op)
7352*a9fa9459Szrj == O_subtract))))
7353*a9fa9459Szrj || reloc_type == BFD_RELOC_32_PCREL))
7354*a9fa9459Szrj {
7355*a9fa9459Szrj offsetT add;
7356*a9fa9459Szrj
7357*a9fa9459Szrj if (insn_start_frag == frag_now)
7358*a9fa9459Szrj add = (p - frag_now->fr_literal) - insn_start_off;
7359*a9fa9459Szrj else
7360*a9fa9459Szrj {
7361*a9fa9459Szrj fragS *fr;
7362*a9fa9459Szrj
7363*a9fa9459Szrj add = insn_start_frag->fr_fix - insn_start_off;
7364*a9fa9459Szrj for (fr = insn_start_frag->fr_next;
7365*a9fa9459Szrj fr && fr != frag_now; fr = fr->fr_next)
7366*a9fa9459Szrj add += fr->fr_fix;
7367*a9fa9459Szrj add += p - frag_now->fr_literal;
7368*a9fa9459Szrj }
7369*a9fa9459Szrj
7370*a9fa9459Szrj if (!object_64bit)
7371*a9fa9459Szrj {
7372*a9fa9459Szrj reloc_type = BFD_RELOC_386_GOTPC;
7373*a9fa9459Szrj i.op[n].imms->X_add_number += add;
7374*a9fa9459Szrj }
7375*a9fa9459Szrj else if (reloc_type == BFD_RELOC_64)
7376*a9fa9459Szrj reloc_type = BFD_RELOC_X86_64_GOTPC64;
7377*a9fa9459Szrj else
7378*a9fa9459Szrj /* Don't do the adjustment for x86-64, as there
7379*a9fa9459Szrj the pcrel addressing is relative to the _next_
7380*a9fa9459Szrj insn, and that is taken care of in other code. */
7381*a9fa9459Szrj reloc_type = BFD_RELOC_X86_64_GOTPC32;
7382*a9fa9459Szrj }
7383*a9fa9459Szrj fixP = fix_new_exp (frag_now, p - frag_now->fr_literal,
7384*a9fa9459Szrj size, i.op[n].disps, pcrel,
7385*a9fa9459Szrj reloc_type);
7386*a9fa9459Szrj /* Check for "call/jmp *mem", "mov mem, %reg",
7387*a9fa9459Szrj "test %reg, mem" and "binop mem, %reg" where binop
7388*a9fa9459Szrj is one of adc, add, and, cmp, or, sbb, sub, xor
7389*a9fa9459Szrj instructions. Always generate R_386_GOT32X for
7390*a9fa9459Szrj "sym*GOT" operand in 32-bit mode. */
7391*a9fa9459Szrj if ((generate_relax_relocations
7392*a9fa9459Szrj || (!object_64bit
7393*a9fa9459Szrj && i.rm.mode == 0
7394*a9fa9459Szrj && i.rm.regmem == 5))
7395*a9fa9459Szrj && (i.rm.mode == 2
7396*a9fa9459Szrj || (i.rm.mode == 0 && i.rm.regmem == 5))
7397*a9fa9459Szrj && ((i.operands == 1
7398*a9fa9459Szrj && i.tm.base_opcode == 0xff
7399*a9fa9459Szrj && (i.rm.reg == 2 || i.rm.reg == 4))
7400*a9fa9459Szrj || (i.operands == 2
7401*a9fa9459Szrj && (i.tm.base_opcode == 0x8b
7402*a9fa9459Szrj || i.tm.base_opcode == 0x85
7403*a9fa9459Szrj || (i.tm.base_opcode & 0xc7) == 0x03))))
7404*a9fa9459Szrj {
7405*a9fa9459Szrj if (object_64bit)
7406*a9fa9459Szrj {
7407*a9fa9459Szrj fixP->fx_tcbit = i.rex != 0;
7408*a9fa9459Szrj if (i.base_reg
7409*a9fa9459Szrj && (i.base_reg->reg_num == RegRip
7410*a9fa9459Szrj || i.base_reg->reg_num == RegEip))
7411*a9fa9459Szrj fixP->fx_tcbit2 = 1;
7412*a9fa9459Szrj }
7413*a9fa9459Szrj else
7414*a9fa9459Szrj fixP->fx_tcbit2 = 1;
7415*a9fa9459Szrj }
7416*a9fa9459Szrj }
7417*a9fa9459Szrj }
7418*a9fa9459Szrj }
7419*a9fa9459Szrj }
7420*a9fa9459Szrj
7421*a9fa9459Szrj static void
output_imm(fragS * insn_start_frag,offsetT insn_start_off)7422*a9fa9459Szrj output_imm (fragS *insn_start_frag, offsetT insn_start_off)
7423*a9fa9459Szrj {
7424*a9fa9459Szrj char *p;
7425*a9fa9459Szrj unsigned int n;
7426*a9fa9459Szrj
7427*a9fa9459Szrj for (n = 0; n < i.operands; n++)
7428*a9fa9459Szrj {
7429*a9fa9459Szrj /* Skip SAE/RC Imm operand in EVEX. They are already handled. */
7430*a9fa9459Szrj if (i.rounding && (int) n == i.rounding->operand)
7431*a9fa9459Szrj continue;
7432*a9fa9459Szrj
7433*a9fa9459Szrj if (operand_type_check (i.types[n], imm))
7434*a9fa9459Szrj {
7435*a9fa9459Szrj if (i.op[n].imms->X_op == O_constant)
7436*a9fa9459Szrj {
7437*a9fa9459Szrj int size = imm_size (n);
7438*a9fa9459Szrj offsetT val;
7439*a9fa9459Szrj
7440*a9fa9459Szrj val = offset_in_range (i.op[n].imms->X_add_number,
7441*a9fa9459Szrj size);
7442*a9fa9459Szrj p = frag_more (size);
7443*a9fa9459Szrj md_number_to_chars (p, val, size);
7444*a9fa9459Szrj }
7445*a9fa9459Szrj else
7446*a9fa9459Szrj {
7447*a9fa9459Szrj /* Not absolute_section.
7448*a9fa9459Szrj Need a 32-bit fixup (don't support 8bit
7449*a9fa9459Szrj non-absolute imms). Try to support other
7450*a9fa9459Szrj sizes ... */
7451*a9fa9459Szrj enum bfd_reloc_code_real reloc_type;
7452*a9fa9459Szrj int size = imm_size (n);
7453*a9fa9459Szrj int sign;
7454*a9fa9459Szrj
7455*a9fa9459Szrj if (i.types[n].bitfield.imm32s
7456*a9fa9459Szrj && (i.suffix == QWORD_MNEM_SUFFIX
7457*a9fa9459Szrj || (!i.suffix && i.tm.opcode_modifier.no_lsuf)))
7458*a9fa9459Szrj sign = 1;
7459*a9fa9459Szrj else
7460*a9fa9459Szrj sign = 0;
7461*a9fa9459Szrj
7462*a9fa9459Szrj p = frag_more (size);
7463*a9fa9459Szrj reloc_type = reloc (size, 0, sign, i.reloc[n]);
7464*a9fa9459Szrj
7465*a9fa9459Szrj /* This is tough to explain. We end up with this one if we
7466*a9fa9459Szrj * have operands that look like
7467*a9fa9459Szrj * "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal here is to
7468*a9fa9459Szrj * obtain the absolute address of the GOT, and it is strongly
7469*a9fa9459Szrj * preferable from a performance point of view to avoid using
7470*a9fa9459Szrj * a runtime relocation for this. The actual sequence of
7471*a9fa9459Szrj * instructions often look something like:
7472*a9fa9459Szrj *
7473*a9fa9459Szrj * call .L66
7474*a9fa9459Szrj * .L66:
7475*a9fa9459Szrj * popl %ebx
7476*a9fa9459Szrj * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx
7477*a9fa9459Szrj *
7478*a9fa9459Szrj * The call and pop essentially return the absolute address
7479*a9fa9459Szrj * of the label .L66 and store it in %ebx. The linker itself
7480*a9fa9459Szrj * will ultimately change the first operand of the addl so
7481*a9fa9459Szrj * that %ebx points to the GOT, but to keep things simple, the
7482*a9fa9459Szrj * .o file must have this operand set so that it generates not
7483*a9fa9459Szrj * the absolute address of .L66, but the absolute address of
7484*a9fa9459Szrj * itself. This allows the linker itself simply treat a GOTPC
7485*a9fa9459Szrj * relocation as asking for a pcrel offset to the GOT to be
7486*a9fa9459Szrj * added in, and the addend of the relocation is stored in the
7487*a9fa9459Szrj * operand field for the instruction itself.
7488*a9fa9459Szrj *
7489*a9fa9459Szrj * Our job here is to fix the operand so that it would add
7490*a9fa9459Szrj * the correct offset so that %ebx would point to itself. The
7491*a9fa9459Szrj * thing that is tricky is that .-.L66 will point to the
7492*a9fa9459Szrj * beginning of the instruction, so we need to further modify
7493*a9fa9459Szrj * the operand so that it will point to itself. There are
7494*a9fa9459Szrj * other cases where you have something like:
7495*a9fa9459Szrj *
7496*a9fa9459Szrj * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66]
7497*a9fa9459Szrj *
7498*a9fa9459Szrj * and here no correction would be required. Internally in
7499*a9fa9459Szrj * the assembler we treat operands of this form as not being
7500*a9fa9459Szrj * pcrel since the '.' is explicitly mentioned, and I wonder
7501*a9fa9459Szrj * whether it would simplify matters to do it this way. Who
7502*a9fa9459Szrj * knows. In earlier versions of the PIC patches, the
7503*a9fa9459Szrj * pcrel_adjust field was used to store the correction, but
7504*a9fa9459Szrj * since the expression is not pcrel, I felt it would be
7505*a9fa9459Szrj * confusing to do it this way. */
7506*a9fa9459Szrj
7507*a9fa9459Szrj if ((reloc_type == BFD_RELOC_32
7508*a9fa9459Szrj || reloc_type == BFD_RELOC_X86_64_32S
7509*a9fa9459Szrj || reloc_type == BFD_RELOC_64)
7510*a9fa9459Szrj && GOT_symbol
7511*a9fa9459Szrj && GOT_symbol == i.op[n].imms->X_add_symbol
7512*a9fa9459Szrj && (i.op[n].imms->X_op == O_symbol
7513*a9fa9459Szrj || (i.op[n].imms->X_op == O_add
7514*a9fa9459Szrj && ((symbol_get_value_expression
7515*a9fa9459Szrj (i.op[n].imms->X_op_symbol)->X_op)
7516*a9fa9459Szrj == O_subtract))))
7517*a9fa9459Szrj {
7518*a9fa9459Szrj offsetT add;
7519*a9fa9459Szrj
7520*a9fa9459Szrj if (insn_start_frag == frag_now)
7521*a9fa9459Szrj add = (p - frag_now->fr_literal) - insn_start_off;
7522*a9fa9459Szrj else
7523*a9fa9459Szrj {
7524*a9fa9459Szrj fragS *fr;
7525*a9fa9459Szrj
7526*a9fa9459Szrj add = insn_start_frag->fr_fix - insn_start_off;
7527*a9fa9459Szrj for (fr = insn_start_frag->fr_next;
7528*a9fa9459Szrj fr && fr != frag_now; fr = fr->fr_next)
7529*a9fa9459Szrj add += fr->fr_fix;
7530*a9fa9459Szrj add += p - frag_now->fr_literal;
7531*a9fa9459Szrj }
7532*a9fa9459Szrj
7533*a9fa9459Szrj if (!object_64bit)
7534*a9fa9459Szrj reloc_type = BFD_RELOC_386_GOTPC;
7535*a9fa9459Szrj else if (size == 4)
7536*a9fa9459Szrj reloc_type = BFD_RELOC_X86_64_GOTPC32;
7537*a9fa9459Szrj else if (size == 8)
7538*a9fa9459Szrj reloc_type = BFD_RELOC_X86_64_GOTPC64;
7539*a9fa9459Szrj i.op[n].imms->X_add_number += add;
7540*a9fa9459Szrj }
7541*a9fa9459Szrj fix_new_exp (frag_now, p - frag_now->fr_literal, size,
7542*a9fa9459Szrj i.op[n].imms, 0, reloc_type);
7543*a9fa9459Szrj }
7544*a9fa9459Szrj }
7545*a9fa9459Szrj }
7546*a9fa9459Szrj }
7547*a9fa9459Szrj
7548*a9fa9459Szrj /* x86_cons_fix_new is called via the expression parsing code when a
7549*a9fa9459Szrj reloc is needed. We use this hook to get the correct .got reloc. */
7550*a9fa9459Szrj static int cons_sign = -1;
7551*a9fa9459Szrj
7552*a9fa9459Szrj void
x86_cons_fix_new(fragS * frag,unsigned int off,unsigned int len,expressionS * exp,bfd_reloc_code_real_type r)7553*a9fa9459Szrj x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
7554*a9fa9459Szrj expressionS *exp, bfd_reloc_code_real_type r)
7555*a9fa9459Szrj {
7556*a9fa9459Szrj r = reloc (len, 0, cons_sign, r);
7557*a9fa9459Szrj
7558*a9fa9459Szrj #ifdef TE_PE
7559*a9fa9459Szrj if (exp->X_op == O_secrel)
7560*a9fa9459Szrj {
7561*a9fa9459Szrj exp->X_op = O_symbol;
7562*a9fa9459Szrj r = BFD_RELOC_32_SECREL;
7563*a9fa9459Szrj }
7564*a9fa9459Szrj #endif
7565*a9fa9459Szrj
7566*a9fa9459Szrj fix_new_exp (frag, off, len, exp, 0, r);
7567*a9fa9459Szrj }
7568*a9fa9459Szrj
7569*a9fa9459Szrj /* Export the ABI address size for use by TC_ADDRESS_BYTES for the
7570*a9fa9459Szrj purpose of the `.dc.a' internal pseudo-op. */
7571*a9fa9459Szrj
7572*a9fa9459Szrj int
x86_address_bytes(void)7573*a9fa9459Szrj x86_address_bytes (void)
7574*a9fa9459Szrj {
7575*a9fa9459Szrj if ((stdoutput->arch_info->mach & bfd_mach_x64_32))
7576*a9fa9459Szrj return 4;
7577*a9fa9459Szrj return stdoutput->arch_info->bits_per_address / 8;
7578*a9fa9459Szrj }
7579*a9fa9459Szrj
7580*a9fa9459Szrj #if !(defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (OBJ_MACH_O)) \
7581*a9fa9459Szrj || defined (LEX_AT)
7582*a9fa9459Szrj # define lex_got(reloc, adjust, types) NULL
7583*a9fa9459Szrj #else
7584*a9fa9459Szrj /* Parse operands of the form
7585*a9fa9459Szrj <symbol>@GOTOFF+<nnn>
7586*a9fa9459Szrj and similar .plt or .got references.
7587*a9fa9459Szrj
7588*a9fa9459Szrj If we find one, set up the correct relocation in RELOC and copy the
7589*a9fa9459Szrj input string, minus the `@GOTOFF' into a malloc'd buffer for
7590*a9fa9459Szrj parsing by the calling routine. Return this buffer, and if ADJUST
7591*a9fa9459Szrj is non-null set it to the length of the string we removed from the
7592*a9fa9459Szrj input line. Otherwise return NULL. */
7593*a9fa9459Szrj static char *
lex_got(enum bfd_reloc_code_real * rel,int * adjust,i386_operand_type * types)7594*a9fa9459Szrj lex_got (enum bfd_reloc_code_real *rel,
7595*a9fa9459Szrj int *adjust,
7596*a9fa9459Szrj i386_operand_type *types)
7597*a9fa9459Szrj {
7598*a9fa9459Szrj /* Some of the relocations depend on the size of what field is to
7599*a9fa9459Szrj be relocated. But in our callers i386_immediate and i386_displacement
7600*a9fa9459Szrj we don't yet know the operand size (this will be set by insn
7601*a9fa9459Szrj matching). Hence we record the word32 relocation here,
7602*a9fa9459Szrj and adjust the reloc according to the real size in reloc(). */
7603*a9fa9459Szrj static const struct {
7604*a9fa9459Szrj const char *str;
7605*a9fa9459Szrj int len;
7606*a9fa9459Szrj const enum bfd_reloc_code_real rel[2];
7607*a9fa9459Szrj const i386_operand_type types64;
7608*a9fa9459Szrj } gotrel[] = {
7609*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
7610*a9fa9459Szrj { STRING_COMMA_LEN ("SIZE"), { BFD_RELOC_SIZE32,
7611*a9fa9459Szrj BFD_RELOC_SIZE32 },
7612*a9fa9459Szrj OPERAND_TYPE_IMM32_64 },
7613*a9fa9459Szrj #endif
7614*a9fa9459Szrj { STRING_COMMA_LEN ("PLTOFF"), { _dummy_first_bfd_reloc_code_real,
7615*a9fa9459Szrj BFD_RELOC_X86_64_PLTOFF64 },
7616*a9fa9459Szrj OPERAND_TYPE_IMM64 },
7617*a9fa9459Szrj { STRING_COMMA_LEN ("PLT"), { BFD_RELOC_386_PLT32,
7618*a9fa9459Szrj BFD_RELOC_X86_64_PLT32 },
7619*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7620*a9fa9459Szrj { STRING_COMMA_LEN ("GOTPLT"), { _dummy_first_bfd_reloc_code_real,
7621*a9fa9459Szrj BFD_RELOC_X86_64_GOTPLT64 },
7622*a9fa9459Szrj OPERAND_TYPE_IMM64_DISP64 },
7623*a9fa9459Szrj { STRING_COMMA_LEN ("GOTOFF"), { BFD_RELOC_386_GOTOFF,
7624*a9fa9459Szrj BFD_RELOC_X86_64_GOTOFF64 },
7625*a9fa9459Szrj OPERAND_TYPE_IMM64_DISP64 },
7626*a9fa9459Szrj { STRING_COMMA_LEN ("GOTPCREL"), { _dummy_first_bfd_reloc_code_real,
7627*a9fa9459Szrj BFD_RELOC_X86_64_GOTPCREL },
7628*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7629*a9fa9459Szrj { STRING_COMMA_LEN ("TLSGD"), { BFD_RELOC_386_TLS_GD,
7630*a9fa9459Szrj BFD_RELOC_X86_64_TLSGD },
7631*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7632*a9fa9459Szrj { STRING_COMMA_LEN ("TLSLDM"), { BFD_RELOC_386_TLS_LDM,
7633*a9fa9459Szrj _dummy_first_bfd_reloc_code_real },
7634*a9fa9459Szrj OPERAND_TYPE_NONE },
7635*a9fa9459Szrj { STRING_COMMA_LEN ("TLSLD"), { _dummy_first_bfd_reloc_code_real,
7636*a9fa9459Szrj BFD_RELOC_X86_64_TLSLD },
7637*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7638*a9fa9459Szrj { STRING_COMMA_LEN ("GOTTPOFF"), { BFD_RELOC_386_TLS_IE_32,
7639*a9fa9459Szrj BFD_RELOC_X86_64_GOTTPOFF },
7640*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7641*a9fa9459Szrj { STRING_COMMA_LEN ("TPOFF"), { BFD_RELOC_386_TLS_LE_32,
7642*a9fa9459Szrj BFD_RELOC_X86_64_TPOFF32 },
7643*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
7644*a9fa9459Szrj { STRING_COMMA_LEN ("NTPOFF"), { BFD_RELOC_386_TLS_LE,
7645*a9fa9459Szrj _dummy_first_bfd_reloc_code_real },
7646*a9fa9459Szrj OPERAND_TYPE_NONE },
7647*a9fa9459Szrj { STRING_COMMA_LEN ("DTPOFF"), { BFD_RELOC_386_TLS_LDO_32,
7648*a9fa9459Szrj BFD_RELOC_X86_64_DTPOFF32 },
7649*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
7650*a9fa9459Szrj { STRING_COMMA_LEN ("GOTNTPOFF"),{ BFD_RELOC_386_TLS_GOTIE,
7651*a9fa9459Szrj _dummy_first_bfd_reloc_code_real },
7652*a9fa9459Szrj OPERAND_TYPE_NONE },
7653*a9fa9459Szrj { STRING_COMMA_LEN ("INDNTPOFF"),{ BFD_RELOC_386_TLS_IE,
7654*a9fa9459Szrj _dummy_first_bfd_reloc_code_real },
7655*a9fa9459Szrj OPERAND_TYPE_NONE },
7656*a9fa9459Szrj { STRING_COMMA_LEN ("GOT"), { BFD_RELOC_386_GOT32,
7657*a9fa9459Szrj BFD_RELOC_X86_64_GOT32 },
7658*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_64_DISP32 },
7659*a9fa9459Szrj { STRING_COMMA_LEN ("TLSDESC"), { BFD_RELOC_386_TLS_GOTDESC,
7660*a9fa9459Szrj BFD_RELOC_X86_64_GOTPC32_TLSDESC },
7661*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7662*a9fa9459Szrj { STRING_COMMA_LEN ("TLSCALL"), { BFD_RELOC_386_TLS_DESC_CALL,
7663*a9fa9459Szrj BFD_RELOC_X86_64_TLSDESC_CALL },
7664*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_DISP32 },
7665*a9fa9459Szrj };
7666*a9fa9459Szrj char *cp;
7667*a9fa9459Szrj unsigned int j;
7668*a9fa9459Szrj
7669*a9fa9459Szrj #if defined (OBJ_MAYBE_ELF)
7670*a9fa9459Szrj if (!IS_ELF)
7671*a9fa9459Szrj return NULL;
7672*a9fa9459Szrj #endif
7673*a9fa9459Szrj
7674*a9fa9459Szrj for (cp = input_line_pointer; *cp != '@'; cp++)
7675*a9fa9459Szrj if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
7676*a9fa9459Szrj return NULL;
7677*a9fa9459Szrj
7678*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (gotrel); j++)
7679*a9fa9459Szrj {
7680*a9fa9459Szrj int len = gotrel[j].len;
7681*a9fa9459Szrj if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
7682*a9fa9459Szrj {
7683*a9fa9459Szrj if (gotrel[j].rel[object_64bit] != 0)
7684*a9fa9459Szrj {
7685*a9fa9459Szrj int first, second;
7686*a9fa9459Szrj char *tmpbuf, *past_reloc;
7687*a9fa9459Szrj
7688*a9fa9459Szrj *rel = gotrel[j].rel[object_64bit];
7689*a9fa9459Szrj
7690*a9fa9459Szrj if (types)
7691*a9fa9459Szrj {
7692*a9fa9459Szrj if (flag_code != CODE_64BIT)
7693*a9fa9459Szrj {
7694*a9fa9459Szrj types->bitfield.imm32 = 1;
7695*a9fa9459Szrj types->bitfield.disp32 = 1;
7696*a9fa9459Szrj }
7697*a9fa9459Szrj else
7698*a9fa9459Szrj *types = gotrel[j].types64;
7699*a9fa9459Szrj }
7700*a9fa9459Szrj
7701*a9fa9459Szrj if (j != 0 && GOT_symbol == NULL)
7702*a9fa9459Szrj GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
7703*a9fa9459Szrj
7704*a9fa9459Szrj /* The length of the first part of our input line. */
7705*a9fa9459Szrj first = cp - input_line_pointer;
7706*a9fa9459Szrj
7707*a9fa9459Szrj /* The second part goes from after the reloc token until
7708*a9fa9459Szrj (and including) an end_of_line char or comma. */
7709*a9fa9459Szrj past_reloc = cp + 1 + len;
7710*a9fa9459Szrj cp = past_reloc;
7711*a9fa9459Szrj while (!is_end_of_line[(unsigned char) *cp] && *cp != ',')
7712*a9fa9459Szrj ++cp;
7713*a9fa9459Szrj second = cp + 1 - past_reloc;
7714*a9fa9459Szrj
7715*a9fa9459Szrj /* Allocate and copy string. The trailing NUL shouldn't
7716*a9fa9459Szrj be necessary, but be safe. */
7717*a9fa9459Szrj tmpbuf = XNEWVEC (char, first + second + 2);
7718*a9fa9459Szrj memcpy (tmpbuf, input_line_pointer, first);
7719*a9fa9459Szrj if (second != 0 && *past_reloc != ' ')
7720*a9fa9459Szrj /* Replace the relocation token with ' ', so that
7721*a9fa9459Szrj errors like foo@GOTOFF1 will be detected. */
7722*a9fa9459Szrj tmpbuf[first++] = ' ';
7723*a9fa9459Szrj else
7724*a9fa9459Szrj /* Increment length by 1 if the relocation token is
7725*a9fa9459Szrj removed. */
7726*a9fa9459Szrj len++;
7727*a9fa9459Szrj if (adjust)
7728*a9fa9459Szrj *adjust = len;
7729*a9fa9459Szrj memcpy (tmpbuf + first, past_reloc, second);
7730*a9fa9459Szrj tmpbuf[first + second] = '\0';
7731*a9fa9459Szrj return tmpbuf;
7732*a9fa9459Szrj }
7733*a9fa9459Szrj
7734*a9fa9459Szrj as_bad (_("@%s reloc is not supported with %d-bit output format"),
7735*a9fa9459Szrj gotrel[j].str, 1 << (5 + object_64bit));
7736*a9fa9459Szrj return NULL;
7737*a9fa9459Szrj }
7738*a9fa9459Szrj }
7739*a9fa9459Szrj
7740*a9fa9459Szrj /* Might be a symbol version string. Don't as_bad here. */
7741*a9fa9459Szrj return NULL;
7742*a9fa9459Szrj }
7743*a9fa9459Szrj #endif
7744*a9fa9459Szrj
7745*a9fa9459Szrj #ifdef TE_PE
7746*a9fa9459Szrj #ifdef lex_got
7747*a9fa9459Szrj #undef lex_got
7748*a9fa9459Szrj #endif
7749*a9fa9459Szrj /* Parse operands of the form
7750*a9fa9459Szrj <symbol>@SECREL32+<nnn>
7751*a9fa9459Szrj
7752*a9fa9459Szrj If we find one, set up the correct relocation in RELOC and copy the
7753*a9fa9459Szrj input string, minus the `@SECREL32' into a malloc'd buffer for
7754*a9fa9459Szrj parsing by the calling routine. Return this buffer, and if ADJUST
7755*a9fa9459Szrj is non-null set it to the length of the string we removed from the
7756*a9fa9459Szrj input line. Otherwise return NULL.
7757*a9fa9459Szrj
7758*a9fa9459Szrj This function is copied from the ELF version above adjusted for PE targets. */
7759*a9fa9459Szrj
7760*a9fa9459Szrj static char *
lex_got(enum bfd_reloc_code_real * rel ATTRIBUTE_UNUSED,int * adjust ATTRIBUTE_UNUSED,i386_operand_type * types)7761*a9fa9459Szrj lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
7762*a9fa9459Szrj int *adjust ATTRIBUTE_UNUSED,
7763*a9fa9459Szrj i386_operand_type *types)
7764*a9fa9459Szrj {
7765*a9fa9459Szrj static const struct
7766*a9fa9459Szrj {
7767*a9fa9459Szrj const char *str;
7768*a9fa9459Szrj int len;
7769*a9fa9459Szrj const enum bfd_reloc_code_real rel[2];
7770*a9fa9459Szrj const i386_operand_type types64;
7771*a9fa9459Szrj }
7772*a9fa9459Szrj gotrel[] =
7773*a9fa9459Szrj {
7774*a9fa9459Szrj { STRING_COMMA_LEN ("SECREL32"), { BFD_RELOC_32_SECREL,
7775*a9fa9459Szrj BFD_RELOC_32_SECREL },
7776*a9fa9459Szrj OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
7777*a9fa9459Szrj };
7778*a9fa9459Szrj
7779*a9fa9459Szrj char *cp;
7780*a9fa9459Szrj unsigned j;
7781*a9fa9459Szrj
7782*a9fa9459Szrj for (cp = input_line_pointer; *cp != '@'; cp++)
7783*a9fa9459Szrj if (is_end_of_line[(unsigned char) *cp] || *cp == ',')
7784*a9fa9459Szrj return NULL;
7785*a9fa9459Szrj
7786*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (gotrel); j++)
7787*a9fa9459Szrj {
7788*a9fa9459Szrj int len = gotrel[j].len;
7789*a9fa9459Szrj
7790*a9fa9459Szrj if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
7791*a9fa9459Szrj {
7792*a9fa9459Szrj if (gotrel[j].rel[object_64bit] != 0)
7793*a9fa9459Szrj {
7794*a9fa9459Szrj int first, second;
7795*a9fa9459Szrj char *tmpbuf, *past_reloc;
7796*a9fa9459Szrj
7797*a9fa9459Szrj *rel = gotrel[j].rel[object_64bit];
7798*a9fa9459Szrj if (adjust)
7799*a9fa9459Szrj *adjust = len;
7800*a9fa9459Szrj
7801*a9fa9459Szrj if (types)
7802*a9fa9459Szrj {
7803*a9fa9459Szrj if (flag_code != CODE_64BIT)
7804*a9fa9459Szrj {
7805*a9fa9459Szrj types->bitfield.imm32 = 1;
7806*a9fa9459Szrj types->bitfield.disp32 = 1;
7807*a9fa9459Szrj }
7808*a9fa9459Szrj else
7809*a9fa9459Szrj *types = gotrel[j].types64;
7810*a9fa9459Szrj }
7811*a9fa9459Szrj
7812*a9fa9459Szrj /* The length of the first part of our input line. */
7813*a9fa9459Szrj first = cp - input_line_pointer;
7814*a9fa9459Szrj
7815*a9fa9459Szrj /* The second part goes from after the reloc token until
7816*a9fa9459Szrj (and including) an end_of_line char or comma. */
7817*a9fa9459Szrj past_reloc = cp + 1 + len;
7818*a9fa9459Szrj cp = past_reloc;
7819*a9fa9459Szrj while (!is_end_of_line[(unsigned char) *cp] && *cp != ',')
7820*a9fa9459Szrj ++cp;
7821*a9fa9459Szrj second = cp + 1 - past_reloc;
7822*a9fa9459Szrj
7823*a9fa9459Szrj /* Allocate and copy string. The trailing NUL shouldn't
7824*a9fa9459Szrj be necessary, but be safe. */
7825*a9fa9459Szrj tmpbuf = XNEWVEC (char, first + second + 2);
7826*a9fa9459Szrj memcpy (tmpbuf, input_line_pointer, first);
7827*a9fa9459Szrj if (second != 0 && *past_reloc != ' ')
7828*a9fa9459Szrj /* Replace the relocation token with ' ', so that
7829*a9fa9459Szrj errors like foo@SECLREL321 will be detected. */
7830*a9fa9459Szrj tmpbuf[first++] = ' ';
7831*a9fa9459Szrj memcpy (tmpbuf + first, past_reloc, second);
7832*a9fa9459Szrj tmpbuf[first + second] = '\0';
7833*a9fa9459Szrj return tmpbuf;
7834*a9fa9459Szrj }
7835*a9fa9459Szrj
7836*a9fa9459Szrj as_bad (_("@%s reloc is not supported with %d-bit output format"),
7837*a9fa9459Szrj gotrel[j].str, 1 << (5 + object_64bit));
7838*a9fa9459Szrj return NULL;
7839*a9fa9459Szrj }
7840*a9fa9459Szrj }
7841*a9fa9459Szrj
7842*a9fa9459Szrj /* Might be a symbol version string. Don't as_bad here. */
7843*a9fa9459Szrj return NULL;
7844*a9fa9459Szrj }
7845*a9fa9459Szrj
7846*a9fa9459Szrj #endif /* TE_PE */
7847*a9fa9459Szrj
7848*a9fa9459Szrj bfd_reloc_code_real_type
x86_cons(expressionS * exp,int size)7849*a9fa9459Szrj x86_cons (expressionS *exp, int size)
7850*a9fa9459Szrj {
7851*a9fa9459Szrj bfd_reloc_code_real_type got_reloc = NO_RELOC;
7852*a9fa9459Szrj
7853*a9fa9459Szrj intel_syntax = -intel_syntax;
7854*a9fa9459Szrj
7855*a9fa9459Szrj exp->X_md = 0;
7856*a9fa9459Szrj if (size == 4 || (object_64bit && size == 8))
7857*a9fa9459Szrj {
7858*a9fa9459Szrj /* Handle @GOTOFF and the like in an expression. */
7859*a9fa9459Szrj char *save;
7860*a9fa9459Szrj char *gotfree_input_line;
7861*a9fa9459Szrj int adjust = 0;
7862*a9fa9459Szrj
7863*a9fa9459Szrj save = input_line_pointer;
7864*a9fa9459Szrj gotfree_input_line = lex_got (&got_reloc, &adjust, NULL);
7865*a9fa9459Szrj if (gotfree_input_line)
7866*a9fa9459Szrj input_line_pointer = gotfree_input_line;
7867*a9fa9459Szrj
7868*a9fa9459Szrj expression (exp);
7869*a9fa9459Szrj
7870*a9fa9459Szrj if (gotfree_input_line)
7871*a9fa9459Szrj {
7872*a9fa9459Szrj /* expression () has merrily parsed up to the end of line,
7873*a9fa9459Szrj or a comma - in the wrong buffer. Transfer how far
7874*a9fa9459Szrj input_line_pointer has moved to the right buffer. */
7875*a9fa9459Szrj input_line_pointer = (save
7876*a9fa9459Szrj + (input_line_pointer - gotfree_input_line)
7877*a9fa9459Szrj + adjust);
7878*a9fa9459Szrj free (gotfree_input_line);
7879*a9fa9459Szrj if (exp->X_op == O_constant
7880*a9fa9459Szrj || exp->X_op == O_absent
7881*a9fa9459Szrj || exp->X_op == O_illegal
7882*a9fa9459Szrj || exp->X_op == O_register
7883*a9fa9459Szrj || exp->X_op == O_big)
7884*a9fa9459Szrj {
7885*a9fa9459Szrj char c = *input_line_pointer;
7886*a9fa9459Szrj *input_line_pointer = 0;
7887*a9fa9459Szrj as_bad (_("missing or invalid expression `%s'"), save);
7888*a9fa9459Szrj *input_line_pointer = c;
7889*a9fa9459Szrj }
7890*a9fa9459Szrj }
7891*a9fa9459Szrj }
7892*a9fa9459Szrj else
7893*a9fa9459Szrj expression (exp);
7894*a9fa9459Szrj
7895*a9fa9459Szrj intel_syntax = -intel_syntax;
7896*a9fa9459Szrj
7897*a9fa9459Szrj if (intel_syntax)
7898*a9fa9459Szrj i386_intel_simplify (exp);
7899*a9fa9459Szrj
7900*a9fa9459Szrj return got_reloc;
7901*a9fa9459Szrj }
7902*a9fa9459Szrj
7903*a9fa9459Szrj static void
signed_cons(int size)7904*a9fa9459Szrj signed_cons (int size)
7905*a9fa9459Szrj {
7906*a9fa9459Szrj if (flag_code == CODE_64BIT)
7907*a9fa9459Szrj cons_sign = 1;
7908*a9fa9459Szrj cons (size);
7909*a9fa9459Szrj cons_sign = -1;
7910*a9fa9459Szrj }
7911*a9fa9459Szrj
7912*a9fa9459Szrj #ifdef TE_PE
7913*a9fa9459Szrj static void
pe_directive_secrel(int dummy ATTRIBUTE_UNUSED)7914*a9fa9459Szrj pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
7915*a9fa9459Szrj {
7916*a9fa9459Szrj expressionS exp;
7917*a9fa9459Szrj
7918*a9fa9459Szrj do
7919*a9fa9459Szrj {
7920*a9fa9459Szrj expression (&exp);
7921*a9fa9459Szrj if (exp.X_op == O_symbol)
7922*a9fa9459Szrj exp.X_op = O_secrel;
7923*a9fa9459Szrj
7924*a9fa9459Szrj emit_expr (&exp, 4);
7925*a9fa9459Szrj }
7926*a9fa9459Szrj while (*input_line_pointer++ == ',');
7927*a9fa9459Szrj
7928*a9fa9459Szrj input_line_pointer--;
7929*a9fa9459Szrj demand_empty_rest_of_line ();
7930*a9fa9459Szrj }
7931*a9fa9459Szrj #endif
7932*a9fa9459Szrj
7933*a9fa9459Szrj /* Handle Vector operations. */
7934*a9fa9459Szrj
7935*a9fa9459Szrj static char *
check_VecOperations(char * op_string,char * op_end)7936*a9fa9459Szrj check_VecOperations (char *op_string, char *op_end)
7937*a9fa9459Szrj {
7938*a9fa9459Szrj const reg_entry *mask;
7939*a9fa9459Szrj const char *saved;
7940*a9fa9459Szrj char *end_op;
7941*a9fa9459Szrj
7942*a9fa9459Szrj while (*op_string
7943*a9fa9459Szrj && (op_end == NULL || op_string < op_end))
7944*a9fa9459Szrj {
7945*a9fa9459Szrj saved = op_string;
7946*a9fa9459Szrj if (*op_string == '{')
7947*a9fa9459Szrj {
7948*a9fa9459Szrj op_string++;
7949*a9fa9459Szrj
7950*a9fa9459Szrj /* Check broadcasts. */
7951*a9fa9459Szrj if (strncmp (op_string, "1to", 3) == 0)
7952*a9fa9459Szrj {
7953*a9fa9459Szrj int bcst_type;
7954*a9fa9459Szrj
7955*a9fa9459Szrj if (i.broadcast)
7956*a9fa9459Szrj goto duplicated_vec_op;
7957*a9fa9459Szrj
7958*a9fa9459Szrj op_string += 3;
7959*a9fa9459Szrj if (*op_string == '8')
7960*a9fa9459Szrj bcst_type = BROADCAST_1TO8;
7961*a9fa9459Szrj else if (*op_string == '4')
7962*a9fa9459Szrj bcst_type = BROADCAST_1TO4;
7963*a9fa9459Szrj else if (*op_string == '2')
7964*a9fa9459Szrj bcst_type = BROADCAST_1TO2;
7965*a9fa9459Szrj else if (*op_string == '1'
7966*a9fa9459Szrj && *(op_string+1) == '6')
7967*a9fa9459Szrj {
7968*a9fa9459Szrj bcst_type = BROADCAST_1TO16;
7969*a9fa9459Szrj op_string++;
7970*a9fa9459Szrj }
7971*a9fa9459Szrj else
7972*a9fa9459Szrj {
7973*a9fa9459Szrj as_bad (_("Unsupported broadcast: `%s'"), saved);
7974*a9fa9459Szrj return NULL;
7975*a9fa9459Szrj }
7976*a9fa9459Szrj op_string++;
7977*a9fa9459Szrj
7978*a9fa9459Szrj broadcast_op.type = bcst_type;
7979*a9fa9459Szrj broadcast_op.operand = this_operand;
7980*a9fa9459Szrj i.broadcast = &broadcast_op;
7981*a9fa9459Szrj }
7982*a9fa9459Szrj /* Check masking operation. */
7983*a9fa9459Szrj else if ((mask = parse_register (op_string, &end_op)) != NULL)
7984*a9fa9459Szrj {
7985*a9fa9459Szrj /* k0 can't be used for write mask. */
7986*a9fa9459Szrj if (mask->reg_num == 0)
7987*a9fa9459Szrj {
7988*a9fa9459Szrj as_bad (_("`%s' can't be used for write mask"),
7989*a9fa9459Szrj op_string);
7990*a9fa9459Szrj return NULL;
7991*a9fa9459Szrj }
7992*a9fa9459Szrj
7993*a9fa9459Szrj if (!i.mask)
7994*a9fa9459Szrj {
7995*a9fa9459Szrj mask_op.mask = mask;
7996*a9fa9459Szrj mask_op.zeroing = 0;
7997*a9fa9459Szrj mask_op.operand = this_operand;
7998*a9fa9459Szrj i.mask = &mask_op;
7999*a9fa9459Szrj }
8000*a9fa9459Szrj else
8001*a9fa9459Szrj {
8002*a9fa9459Szrj if (i.mask->mask)
8003*a9fa9459Szrj goto duplicated_vec_op;
8004*a9fa9459Szrj
8005*a9fa9459Szrj i.mask->mask = mask;
8006*a9fa9459Szrj
8007*a9fa9459Szrj /* Only "{z}" is allowed here. No need to check
8008*a9fa9459Szrj zeroing mask explicitly. */
8009*a9fa9459Szrj if (i.mask->operand != this_operand)
8010*a9fa9459Szrj {
8011*a9fa9459Szrj as_bad (_("invalid write mask `%s'"), saved);
8012*a9fa9459Szrj return NULL;
8013*a9fa9459Szrj }
8014*a9fa9459Szrj }
8015*a9fa9459Szrj
8016*a9fa9459Szrj op_string = end_op;
8017*a9fa9459Szrj }
8018*a9fa9459Szrj /* Check zeroing-flag for masking operation. */
8019*a9fa9459Szrj else if (*op_string == 'z')
8020*a9fa9459Szrj {
8021*a9fa9459Szrj if (!i.mask)
8022*a9fa9459Szrj {
8023*a9fa9459Szrj mask_op.mask = NULL;
8024*a9fa9459Szrj mask_op.zeroing = 1;
8025*a9fa9459Szrj mask_op.operand = this_operand;
8026*a9fa9459Szrj i.mask = &mask_op;
8027*a9fa9459Szrj }
8028*a9fa9459Szrj else
8029*a9fa9459Szrj {
8030*a9fa9459Szrj if (i.mask->zeroing)
8031*a9fa9459Szrj {
8032*a9fa9459Szrj duplicated_vec_op:
8033*a9fa9459Szrj as_bad (_("duplicated `%s'"), saved);
8034*a9fa9459Szrj return NULL;
8035*a9fa9459Szrj }
8036*a9fa9459Szrj
8037*a9fa9459Szrj i.mask->zeroing = 1;
8038*a9fa9459Szrj
8039*a9fa9459Szrj /* Only "{%k}" is allowed here. No need to check mask
8040*a9fa9459Szrj register explicitly. */
8041*a9fa9459Szrj if (i.mask->operand != this_operand)
8042*a9fa9459Szrj {
8043*a9fa9459Szrj as_bad (_("invalid zeroing-masking `%s'"),
8044*a9fa9459Szrj saved);
8045*a9fa9459Szrj return NULL;
8046*a9fa9459Szrj }
8047*a9fa9459Szrj }
8048*a9fa9459Szrj
8049*a9fa9459Szrj op_string++;
8050*a9fa9459Szrj }
8051*a9fa9459Szrj else
8052*a9fa9459Szrj goto unknown_vec_op;
8053*a9fa9459Szrj
8054*a9fa9459Szrj if (*op_string != '}')
8055*a9fa9459Szrj {
8056*a9fa9459Szrj as_bad (_("missing `}' in `%s'"), saved);
8057*a9fa9459Szrj return NULL;
8058*a9fa9459Szrj }
8059*a9fa9459Szrj op_string++;
8060*a9fa9459Szrj continue;
8061*a9fa9459Szrj }
8062*a9fa9459Szrj unknown_vec_op:
8063*a9fa9459Szrj /* We don't know this one. */
8064*a9fa9459Szrj as_bad (_("unknown vector operation: `%s'"), saved);
8065*a9fa9459Szrj return NULL;
8066*a9fa9459Szrj }
8067*a9fa9459Szrj
8068*a9fa9459Szrj return op_string;
8069*a9fa9459Szrj }
8070*a9fa9459Szrj
8071*a9fa9459Szrj static int
i386_immediate(char * imm_start)8072*a9fa9459Szrj i386_immediate (char *imm_start)
8073*a9fa9459Szrj {
8074*a9fa9459Szrj char *save_input_line_pointer;
8075*a9fa9459Szrj char *gotfree_input_line;
8076*a9fa9459Szrj segT exp_seg = 0;
8077*a9fa9459Szrj expressionS *exp;
8078*a9fa9459Szrj i386_operand_type types;
8079*a9fa9459Szrj
8080*a9fa9459Szrj operand_type_set (&types, ~0);
8081*a9fa9459Szrj
8082*a9fa9459Szrj if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
8083*a9fa9459Szrj {
8084*a9fa9459Szrj as_bad (_("at most %d immediate operands are allowed"),
8085*a9fa9459Szrj MAX_IMMEDIATE_OPERANDS);
8086*a9fa9459Szrj return 0;
8087*a9fa9459Szrj }
8088*a9fa9459Szrj
8089*a9fa9459Szrj exp = &im_expressions[i.imm_operands++];
8090*a9fa9459Szrj i.op[this_operand].imms = exp;
8091*a9fa9459Szrj
8092*a9fa9459Szrj if (is_space_char (*imm_start))
8093*a9fa9459Szrj ++imm_start;
8094*a9fa9459Szrj
8095*a9fa9459Szrj save_input_line_pointer = input_line_pointer;
8096*a9fa9459Szrj input_line_pointer = imm_start;
8097*a9fa9459Szrj
8098*a9fa9459Szrj gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types);
8099*a9fa9459Szrj if (gotfree_input_line)
8100*a9fa9459Szrj input_line_pointer = gotfree_input_line;
8101*a9fa9459Szrj
8102*a9fa9459Szrj exp_seg = expression (exp);
8103*a9fa9459Szrj
8104*a9fa9459Szrj SKIP_WHITESPACE ();
8105*a9fa9459Szrj
8106*a9fa9459Szrj /* Handle vector operations. */
8107*a9fa9459Szrj if (*input_line_pointer == '{')
8108*a9fa9459Szrj {
8109*a9fa9459Szrj input_line_pointer = check_VecOperations (input_line_pointer,
8110*a9fa9459Szrj NULL);
8111*a9fa9459Szrj if (input_line_pointer == NULL)
8112*a9fa9459Szrj return 0;
8113*a9fa9459Szrj }
8114*a9fa9459Szrj
8115*a9fa9459Szrj if (*input_line_pointer)
8116*a9fa9459Szrj as_bad (_("junk `%s' after expression"), input_line_pointer);
8117*a9fa9459Szrj
8118*a9fa9459Szrj input_line_pointer = save_input_line_pointer;
8119*a9fa9459Szrj if (gotfree_input_line)
8120*a9fa9459Szrj {
8121*a9fa9459Szrj free (gotfree_input_line);
8122*a9fa9459Szrj
8123*a9fa9459Szrj if (exp->X_op == O_constant || exp->X_op == O_register)
8124*a9fa9459Szrj exp->X_op = O_illegal;
8125*a9fa9459Szrj }
8126*a9fa9459Szrj
8127*a9fa9459Szrj return i386_finalize_immediate (exp_seg, exp, types, imm_start);
8128*a9fa9459Szrj }
8129*a9fa9459Szrj
8130*a9fa9459Szrj static int
i386_finalize_immediate(segT exp_seg ATTRIBUTE_UNUSED,expressionS * exp,i386_operand_type types,const char * imm_start)8131*a9fa9459Szrj i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
8132*a9fa9459Szrj i386_operand_type types, const char *imm_start)
8133*a9fa9459Szrj {
8134*a9fa9459Szrj if (exp->X_op == O_absent || exp->X_op == O_illegal || exp->X_op == O_big)
8135*a9fa9459Szrj {
8136*a9fa9459Szrj if (imm_start)
8137*a9fa9459Szrj as_bad (_("missing or invalid immediate expression `%s'"),
8138*a9fa9459Szrj imm_start);
8139*a9fa9459Szrj return 0;
8140*a9fa9459Szrj }
8141*a9fa9459Szrj else if (exp->X_op == O_constant)
8142*a9fa9459Szrj {
8143*a9fa9459Szrj /* Size it properly later. */
8144*a9fa9459Szrj i.types[this_operand].bitfield.imm64 = 1;
8145*a9fa9459Szrj /* If not 64bit, sign extend val. */
8146*a9fa9459Szrj if (flag_code != CODE_64BIT
8147*a9fa9459Szrj && (exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0)
8148*a9fa9459Szrj exp->X_add_number
8149*a9fa9459Szrj = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
8150*a9fa9459Szrj }
8151*a9fa9459Szrj #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
8152*a9fa9459Szrj else if (OUTPUT_FLAVOR == bfd_target_aout_flavour
8153*a9fa9459Szrj && exp_seg != absolute_section
8154*a9fa9459Szrj && exp_seg != text_section
8155*a9fa9459Szrj && exp_seg != data_section
8156*a9fa9459Szrj && exp_seg != bss_section
8157*a9fa9459Szrj && exp_seg != undefined_section
8158*a9fa9459Szrj && !bfd_is_com_section (exp_seg))
8159*a9fa9459Szrj {
8160*a9fa9459Szrj as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
8161*a9fa9459Szrj return 0;
8162*a9fa9459Szrj }
8163*a9fa9459Szrj #endif
8164*a9fa9459Szrj else if (!intel_syntax && exp_seg == reg_section)
8165*a9fa9459Szrj {
8166*a9fa9459Szrj if (imm_start)
8167*a9fa9459Szrj as_bad (_("illegal immediate register operand %s"), imm_start);
8168*a9fa9459Szrj return 0;
8169*a9fa9459Szrj }
8170*a9fa9459Szrj else
8171*a9fa9459Szrj {
8172*a9fa9459Szrj /* This is an address. The size of the address will be
8173*a9fa9459Szrj determined later, depending on destination register,
8174*a9fa9459Szrj suffix, or the default for the section. */
8175*a9fa9459Szrj i.types[this_operand].bitfield.imm8 = 1;
8176*a9fa9459Szrj i.types[this_operand].bitfield.imm16 = 1;
8177*a9fa9459Szrj i.types[this_operand].bitfield.imm32 = 1;
8178*a9fa9459Szrj i.types[this_operand].bitfield.imm32s = 1;
8179*a9fa9459Szrj i.types[this_operand].bitfield.imm64 = 1;
8180*a9fa9459Szrj i.types[this_operand] = operand_type_and (i.types[this_operand],
8181*a9fa9459Szrj types);
8182*a9fa9459Szrj }
8183*a9fa9459Szrj
8184*a9fa9459Szrj return 1;
8185*a9fa9459Szrj }
8186*a9fa9459Szrj
8187*a9fa9459Szrj static char *
i386_scale(char * scale)8188*a9fa9459Szrj i386_scale (char *scale)
8189*a9fa9459Szrj {
8190*a9fa9459Szrj offsetT val;
8191*a9fa9459Szrj char *save = input_line_pointer;
8192*a9fa9459Szrj
8193*a9fa9459Szrj input_line_pointer = scale;
8194*a9fa9459Szrj val = get_absolute_expression ();
8195*a9fa9459Szrj
8196*a9fa9459Szrj switch (val)
8197*a9fa9459Szrj {
8198*a9fa9459Szrj case 1:
8199*a9fa9459Szrj i.log2_scale_factor = 0;
8200*a9fa9459Szrj break;
8201*a9fa9459Szrj case 2:
8202*a9fa9459Szrj i.log2_scale_factor = 1;
8203*a9fa9459Szrj break;
8204*a9fa9459Szrj case 4:
8205*a9fa9459Szrj i.log2_scale_factor = 2;
8206*a9fa9459Szrj break;
8207*a9fa9459Szrj case 8:
8208*a9fa9459Szrj i.log2_scale_factor = 3;
8209*a9fa9459Szrj break;
8210*a9fa9459Szrj default:
8211*a9fa9459Szrj {
8212*a9fa9459Szrj char sep = *input_line_pointer;
8213*a9fa9459Szrj
8214*a9fa9459Szrj *input_line_pointer = '\0';
8215*a9fa9459Szrj as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
8216*a9fa9459Szrj scale);
8217*a9fa9459Szrj *input_line_pointer = sep;
8218*a9fa9459Szrj input_line_pointer = save;
8219*a9fa9459Szrj return NULL;
8220*a9fa9459Szrj }
8221*a9fa9459Szrj }
8222*a9fa9459Szrj if (i.log2_scale_factor != 0 && i.index_reg == 0)
8223*a9fa9459Szrj {
8224*a9fa9459Szrj as_warn (_("scale factor of %d without an index register"),
8225*a9fa9459Szrj 1 << i.log2_scale_factor);
8226*a9fa9459Szrj i.log2_scale_factor = 0;
8227*a9fa9459Szrj }
8228*a9fa9459Szrj scale = input_line_pointer;
8229*a9fa9459Szrj input_line_pointer = save;
8230*a9fa9459Szrj return scale;
8231*a9fa9459Szrj }
8232*a9fa9459Szrj
8233*a9fa9459Szrj static int
i386_displacement(char * disp_start,char * disp_end)8234*a9fa9459Szrj i386_displacement (char *disp_start, char *disp_end)
8235*a9fa9459Szrj {
8236*a9fa9459Szrj expressionS *exp;
8237*a9fa9459Szrj segT exp_seg = 0;
8238*a9fa9459Szrj char *save_input_line_pointer;
8239*a9fa9459Szrj char *gotfree_input_line;
8240*a9fa9459Szrj int override;
8241*a9fa9459Szrj i386_operand_type bigdisp, types = anydisp;
8242*a9fa9459Szrj int ret;
8243*a9fa9459Szrj
8244*a9fa9459Szrj if (i.disp_operands == MAX_MEMORY_OPERANDS)
8245*a9fa9459Szrj {
8246*a9fa9459Szrj as_bad (_("at most %d displacement operands are allowed"),
8247*a9fa9459Szrj MAX_MEMORY_OPERANDS);
8248*a9fa9459Szrj return 0;
8249*a9fa9459Szrj }
8250*a9fa9459Szrj
8251*a9fa9459Szrj operand_type_set (&bigdisp, 0);
8252*a9fa9459Szrj if ((i.types[this_operand].bitfield.jumpabsolute)
8253*a9fa9459Szrj || (!current_templates->start->opcode_modifier.jump
8254*a9fa9459Szrj && !current_templates->start->opcode_modifier.jumpdword))
8255*a9fa9459Szrj {
8256*a9fa9459Szrj bigdisp.bitfield.disp32 = 1;
8257*a9fa9459Szrj override = (i.prefix[ADDR_PREFIX] != 0);
8258*a9fa9459Szrj if (flag_code == CODE_64BIT)
8259*a9fa9459Szrj {
8260*a9fa9459Szrj if (!override)
8261*a9fa9459Szrj {
8262*a9fa9459Szrj bigdisp.bitfield.disp32s = 1;
8263*a9fa9459Szrj bigdisp.bitfield.disp64 = 1;
8264*a9fa9459Szrj }
8265*a9fa9459Szrj }
8266*a9fa9459Szrj else if ((flag_code == CODE_16BIT) ^ override)
8267*a9fa9459Szrj {
8268*a9fa9459Szrj bigdisp.bitfield.disp32 = 0;
8269*a9fa9459Szrj bigdisp.bitfield.disp16 = 1;
8270*a9fa9459Szrj }
8271*a9fa9459Szrj }
8272*a9fa9459Szrj else
8273*a9fa9459Szrj {
8274*a9fa9459Szrj /* For PC-relative branches, the width of the displacement
8275*a9fa9459Szrj is dependent upon data size, not address size. */
8276*a9fa9459Szrj override = (i.prefix[DATA_PREFIX] != 0);
8277*a9fa9459Szrj if (flag_code == CODE_64BIT)
8278*a9fa9459Szrj {
8279*a9fa9459Szrj if (override || i.suffix == WORD_MNEM_SUFFIX)
8280*a9fa9459Szrj bigdisp.bitfield.disp16 = 1;
8281*a9fa9459Szrj else
8282*a9fa9459Szrj {
8283*a9fa9459Szrj bigdisp.bitfield.disp32 = 1;
8284*a9fa9459Szrj bigdisp.bitfield.disp32s = 1;
8285*a9fa9459Szrj }
8286*a9fa9459Szrj }
8287*a9fa9459Szrj else
8288*a9fa9459Szrj {
8289*a9fa9459Szrj if (!override)
8290*a9fa9459Szrj override = (i.suffix == (flag_code != CODE_16BIT
8291*a9fa9459Szrj ? WORD_MNEM_SUFFIX
8292*a9fa9459Szrj : LONG_MNEM_SUFFIX));
8293*a9fa9459Szrj bigdisp.bitfield.disp32 = 1;
8294*a9fa9459Szrj if ((flag_code == CODE_16BIT) ^ override)
8295*a9fa9459Szrj {
8296*a9fa9459Szrj bigdisp.bitfield.disp32 = 0;
8297*a9fa9459Szrj bigdisp.bitfield.disp16 = 1;
8298*a9fa9459Szrj }
8299*a9fa9459Szrj }
8300*a9fa9459Szrj }
8301*a9fa9459Szrj i.types[this_operand] = operand_type_or (i.types[this_operand],
8302*a9fa9459Szrj bigdisp);
8303*a9fa9459Szrj
8304*a9fa9459Szrj exp = &disp_expressions[i.disp_operands];
8305*a9fa9459Szrj i.op[this_operand].disps = exp;
8306*a9fa9459Szrj i.disp_operands++;
8307*a9fa9459Szrj save_input_line_pointer = input_line_pointer;
8308*a9fa9459Szrj input_line_pointer = disp_start;
8309*a9fa9459Szrj END_STRING_AND_SAVE (disp_end);
8310*a9fa9459Szrj
8311*a9fa9459Szrj #ifndef GCC_ASM_O_HACK
8312*a9fa9459Szrj #define GCC_ASM_O_HACK 0
8313*a9fa9459Szrj #endif
8314*a9fa9459Szrj #if GCC_ASM_O_HACK
8315*a9fa9459Szrj END_STRING_AND_SAVE (disp_end + 1);
8316*a9fa9459Szrj if (i.types[this_operand].bitfield.baseIndex
8317*a9fa9459Szrj && displacement_string_end[-1] == '+')
8318*a9fa9459Szrj {
8319*a9fa9459Szrj /* This hack is to avoid a warning when using the "o"
8320*a9fa9459Szrj constraint within gcc asm statements.
8321*a9fa9459Szrj For instance:
8322*a9fa9459Szrj
8323*a9fa9459Szrj #define _set_tssldt_desc(n,addr,limit,type) \
8324*a9fa9459Szrj __asm__ __volatile__ ( \
8325*a9fa9459Szrj "movw %w2,%0\n\t" \
8326*a9fa9459Szrj "movw %w1,2+%0\n\t" \
8327*a9fa9459Szrj "rorl $16,%1\n\t" \
8328*a9fa9459Szrj "movb %b1,4+%0\n\t" \
8329*a9fa9459Szrj "movb %4,5+%0\n\t" \
8330*a9fa9459Szrj "movb $0,6+%0\n\t" \
8331*a9fa9459Szrj "movb %h1,7+%0\n\t" \
8332*a9fa9459Szrj "rorl $16,%1" \
8333*a9fa9459Szrj : "=o"(*(n)) : "q" (addr), "ri"(limit), "i"(type))
8334*a9fa9459Szrj
8335*a9fa9459Szrj This works great except that the output assembler ends
8336*a9fa9459Szrj up looking a bit weird if it turns out that there is
8337*a9fa9459Szrj no offset. You end up producing code that looks like:
8338*a9fa9459Szrj
8339*a9fa9459Szrj #APP
8340*a9fa9459Szrj movw $235,(%eax)
8341*a9fa9459Szrj movw %dx,2+(%eax)
8342*a9fa9459Szrj rorl $16,%edx
8343*a9fa9459Szrj movb %dl,4+(%eax)
8344*a9fa9459Szrj movb $137,5+(%eax)
8345*a9fa9459Szrj movb $0,6+(%eax)
8346*a9fa9459Szrj movb %dh,7+(%eax)
8347*a9fa9459Szrj rorl $16,%edx
8348*a9fa9459Szrj #NO_APP
8349*a9fa9459Szrj
8350*a9fa9459Szrj So here we provide the missing zero. */
8351*a9fa9459Szrj
8352*a9fa9459Szrj *displacement_string_end = '0';
8353*a9fa9459Szrj }
8354*a9fa9459Szrj #endif
8355*a9fa9459Szrj gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types);
8356*a9fa9459Szrj if (gotfree_input_line)
8357*a9fa9459Szrj input_line_pointer = gotfree_input_line;
8358*a9fa9459Szrj
8359*a9fa9459Szrj exp_seg = expression (exp);
8360*a9fa9459Szrj
8361*a9fa9459Szrj SKIP_WHITESPACE ();
8362*a9fa9459Szrj if (*input_line_pointer)
8363*a9fa9459Szrj as_bad (_("junk `%s' after expression"), input_line_pointer);
8364*a9fa9459Szrj #if GCC_ASM_O_HACK
8365*a9fa9459Szrj RESTORE_END_STRING (disp_end + 1);
8366*a9fa9459Szrj #endif
8367*a9fa9459Szrj input_line_pointer = save_input_line_pointer;
8368*a9fa9459Szrj if (gotfree_input_line)
8369*a9fa9459Szrj {
8370*a9fa9459Szrj free (gotfree_input_line);
8371*a9fa9459Szrj
8372*a9fa9459Szrj if (exp->X_op == O_constant || exp->X_op == O_register)
8373*a9fa9459Szrj exp->X_op = O_illegal;
8374*a9fa9459Szrj }
8375*a9fa9459Szrj
8376*a9fa9459Szrj ret = i386_finalize_displacement (exp_seg, exp, types, disp_start);
8377*a9fa9459Szrj
8378*a9fa9459Szrj RESTORE_END_STRING (disp_end);
8379*a9fa9459Szrj
8380*a9fa9459Szrj return ret;
8381*a9fa9459Szrj }
8382*a9fa9459Szrj
8383*a9fa9459Szrj static int
i386_finalize_displacement(segT exp_seg ATTRIBUTE_UNUSED,expressionS * exp,i386_operand_type types,const char * disp_start)8384*a9fa9459Szrj i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
8385*a9fa9459Szrj i386_operand_type types, const char *disp_start)
8386*a9fa9459Szrj {
8387*a9fa9459Szrj i386_operand_type bigdisp;
8388*a9fa9459Szrj int ret = 1;
8389*a9fa9459Szrj
8390*a9fa9459Szrj /* We do this to make sure that the section symbol is in
8391*a9fa9459Szrj the symbol table. We will ultimately change the relocation
8392*a9fa9459Szrj to be relative to the beginning of the section. */
8393*a9fa9459Szrj if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
8394*a9fa9459Szrj || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
8395*a9fa9459Szrj || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64)
8396*a9fa9459Szrj {
8397*a9fa9459Szrj if (exp->X_op != O_symbol)
8398*a9fa9459Szrj goto inv_disp;
8399*a9fa9459Szrj
8400*a9fa9459Szrj if (S_IS_LOCAL (exp->X_add_symbol)
8401*a9fa9459Szrj && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section
8402*a9fa9459Szrj && S_GET_SEGMENT (exp->X_add_symbol) != expr_section)
8403*a9fa9459Szrj section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
8404*a9fa9459Szrj exp->X_op = O_subtract;
8405*a9fa9459Szrj exp->X_op_symbol = GOT_symbol;
8406*a9fa9459Szrj if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
8407*a9fa9459Szrj i.reloc[this_operand] = BFD_RELOC_32_PCREL;
8408*a9fa9459Szrj else if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64)
8409*a9fa9459Szrj i.reloc[this_operand] = BFD_RELOC_64;
8410*a9fa9459Szrj else
8411*a9fa9459Szrj i.reloc[this_operand] = BFD_RELOC_32;
8412*a9fa9459Szrj }
8413*a9fa9459Szrj
8414*a9fa9459Szrj else if (exp->X_op == O_absent
8415*a9fa9459Szrj || exp->X_op == O_illegal
8416*a9fa9459Szrj || exp->X_op == O_big)
8417*a9fa9459Szrj {
8418*a9fa9459Szrj inv_disp:
8419*a9fa9459Szrj as_bad (_("missing or invalid displacement expression `%s'"),
8420*a9fa9459Szrj disp_start);
8421*a9fa9459Szrj ret = 0;
8422*a9fa9459Szrj }
8423*a9fa9459Szrj
8424*a9fa9459Szrj else if (flag_code == CODE_64BIT
8425*a9fa9459Szrj && !i.prefix[ADDR_PREFIX]
8426*a9fa9459Szrj && exp->X_op == O_constant)
8427*a9fa9459Szrj {
8428*a9fa9459Szrj /* Since displacement is signed extended to 64bit, don't allow
8429*a9fa9459Szrj disp32 and turn off disp32s if they are out of range. */
8430*a9fa9459Szrj i.types[this_operand].bitfield.disp32 = 0;
8431*a9fa9459Szrj if (!fits_in_signed_long (exp->X_add_number))
8432*a9fa9459Szrj {
8433*a9fa9459Szrj i.types[this_operand].bitfield.disp32s = 0;
8434*a9fa9459Szrj if (i.types[this_operand].bitfield.baseindex)
8435*a9fa9459Szrj {
8436*a9fa9459Szrj as_bad (_("0x%lx out range of signed 32bit displacement"),
8437*a9fa9459Szrj (long) exp->X_add_number);
8438*a9fa9459Szrj ret = 0;
8439*a9fa9459Szrj }
8440*a9fa9459Szrj }
8441*a9fa9459Szrj }
8442*a9fa9459Szrj
8443*a9fa9459Szrj #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
8444*a9fa9459Szrj else if (exp->X_op != O_constant
8445*a9fa9459Szrj && OUTPUT_FLAVOR == bfd_target_aout_flavour
8446*a9fa9459Szrj && exp_seg != absolute_section
8447*a9fa9459Szrj && exp_seg != text_section
8448*a9fa9459Szrj && exp_seg != data_section
8449*a9fa9459Szrj && exp_seg != bss_section
8450*a9fa9459Szrj && exp_seg != undefined_section
8451*a9fa9459Szrj && !bfd_is_com_section (exp_seg))
8452*a9fa9459Szrj {
8453*a9fa9459Szrj as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
8454*a9fa9459Szrj ret = 0;
8455*a9fa9459Szrj }
8456*a9fa9459Szrj #endif
8457*a9fa9459Szrj
8458*a9fa9459Szrj /* Check if this is a displacement only operand. */
8459*a9fa9459Szrj bigdisp = i.types[this_operand];
8460*a9fa9459Szrj bigdisp.bitfield.disp8 = 0;
8461*a9fa9459Szrj bigdisp.bitfield.disp16 = 0;
8462*a9fa9459Szrj bigdisp.bitfield.disp32 = 0;
8463*a9fa9459Szrj bigdisp.bitfield.disp32s = 0;
8464*a9fa9459Szrj bigdisp.bitfield.disp64 = 0;
8465*a9fa9459Szrj if (operand_type_all_zero (&bigdisp))
8466*a9fa9459Szrj i.types[this_operand] = operand_type_and (i.types[this_operand],
8467*a9fa9459Szrj types);
8468*a9fa9459Szrj
8469*a9fa9459Szrj return ret;
8470*a9fa9459Szrj }
8471*a9fa9459Szrj
8472*a9fa9459Szrj /* Make sure the memory operand we've been dealt is valid.
8473*a9fa9459Szrj Return 1 on success, 0 on a failure. */
8474*a9fa9459Szrj
8475*a9fa9459Szrj static int
i386_index_check(const char * operand_string)8476*a9fa9459Szrj i386_index_check (const char *operand_string)
8477*a9fa9459Szrj {
8478*a9fa9459Szrj const char *kind = "base/index";
8479*a9fa9459Szrj enum flag_code addr_mode;
8480*a9fa9459Szrj
8481*a9fa9459Szrj if (i.prefix[ADDR_PREFIX])
8482*a9fa9459Szrj addr_mode = flag_code == CODE_32BIT ? CODE_16BIT : CODE_32BIT;
8483*a9fa9459Szrj else
8484*a9fa9459Szrj {
8485*a9fa9459Szrj addr_mode = flag_code;
8486*a9fa9459Szrj
8487*a9fa9459Szrj #if INFER_ADDR_PREFIX
8488*a9fa9459Szrj if (i.mem_operands == 0)
8489*a9fa9459Szrj {
8490*a9fa9459Szrj /* Infer address prefix from the first memory operand. */
8491*a9fa9459Szrj const reg_entry *addr_reg = i.base_reg;
8492*a9fa9459Szrj
8493*a9fa9459Szrj if (addr_reg == NULL)
8494*a9fa9459Szrj addr_reg = i.index_reg;
8495*a9fa9459Szrj
8496*a9fa9459Szrj if (addr_reg)
8497*a9fa9459Szrj {
8498*a9fa9459Szrj if (addr_reg->reg_num == RegEip
8499*a9fa9459Szrj || addr_reg->reg_num == RegEiz
8500*a9fa9459Szrj || addr_reg->reg_type.bitfield.reg32)
8501*a9fa9459Szrj addr_mode = CODE_32BIT;
8502*a9fa9459Szrj else if (flag_code != CODE_64BIT
8503*a9fa9459Szrj && addr_reg->reg_type.bitfield.reg16)
8504*a9fa9459Szrj addr_mode = CODE_16BIT;
8505*a9fa9459Szrj
8506*a9fa9459Szrj if (addr_mode != flag_code)
8507*a9fa9459Szrj {
8508*a9fa9459Szrj i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
8509*a9fa9459Szrj i.prefixes += 1;
8510*a9fa9459Szrj /* Change the size of any displacement too. At most one
8511*a9fa9459Szrj of Disp16 or Disp32 is set.
8512*a9fa9459Szrj FIXME. There doesn't seem to be any real need for
8513*a9fa9459Szrj separate Disp16 and Disp32 flags. The same goes for
8514*a9fa9459Szrj Imm16 and Imm32. Removing them would probably clean
8515*a9fa9459Szrj up the code quite a lot. */
8516*a9fa9459Szrj if (flag_code != CODE_64BIT
8517*a9fa9459Szrj && (i.types[this_operand].bitfield.disp16
8518*a9fa9459Szrj || i.types[this_operand].bitfield.disp32))
8519*a9fa9459Szrj i.types[this_operand]
8520*a9fa9459Szrj = operand_type_xor (i.types[this_operand], disp16_32);
8521*a9fa9459Szrj }
8522*a9fa9459Szrj }
8523*a9fa9459Szrj }
8524*a9fa9459Szrj #endif
8525*a9fa9459Szrj }
8526*a9fa9459Szrj
8527*a9fa9459Szrj if (current_templates->start->opcode_modifier.isstring
8528*a9fa9459Szrj && !current_templates->start->opcode_modifier.immext
8529*a9fa9459Szrj && (current_templates->end[-1].opcode_modifier.isstring
8530*a9fa9459Szrj || i.mem_operands))
8531*a9fa9459Szrj {
8532*a9fa9459Szrj /* Memory operands of string insns are special in that they only allow
8533*a9fa9459Szrj a single register (rDI, rSI, or rBX) as their memory address. */
8534*a9fa9459Szrj const reg_entry *expected_reg;
8535*a9fa9459Szrj static const char *di_si[][2] =
8536*a9fa9459Szrj {
8537*a9fa9459Szrj { "esi", "edi" },
8538*a9fa9459Szrj { "si", "di" },
8539*a9fa9459Szrj { "rsi", "rdi" }
8540*a9fa9459Szrj };
8541*a9fa9459Szrj static const char *bx[] = { "ebx", "bx", "rbx" };
8542*a9fa9459Szrj
8543*a9fa9459Szrj kind = "string address";
8544*a9fa9459Szrj
8545*a9fa9459Szrj if (current_templates->start->opcode_modifier.repprefixok)
8546*a9fa9459Szrj {
8547*a9fa9459Szrj i386_operand_type type = current_templates->end[-1].operand_types[0];
8548*a9fa9459Szrj
8549*a9fa9459Szrj if (!type.bitfield.baseindex
8550*a9fa9459Szrj || ((!i.mem_operands != !intel_syntax)
8551*a9fa9459Szrj && current_templates->end[-1].operand_types[1]
8552*a9fa9459Szrj .bitfield.baseindex))
8553*a9fa9459Szrj type = current_templates->end[-1].operand_types[1];
8554*a9fa9459Szrj expected_reg = hash_find (reg_hash,
8555*a9fa9459Szrj di_si[addr_mode][type.bitfield.esseg]);
8556*a9fa9459Szrj
8557*a9fa9459Szrj }
8558*a9fa9459Szrj else
8559*a9fa9459Szrj expected_reg = hash_find (reg_hash, bx[addr_mode]);
8560*a9fa9459Szrj
8561*a9fa9459Szrj if (i.base_reg != expected_reg
8562*a9fa9459Szrj || i.index_reg
8563*a9fa9459Szrj || operand_type_check (i.types[this_operand], disp))
8564*a9fa9459Szrj {
8565*a9fa9459Szrj /* The second memory operand must have the same size as
8566*a9fa9459Szrj the first one. */
8567*a9fa9459Szrj if (i.mem_operands
8568*a9fa9459Szrj && i.base_reg
8569*a9fa9459Szrj && !((addr_mode == CODE_64BIT
8570*a9fa9459Szrj && i.base_reg->reg_type.bitfield.reg64)
8571*a9fa9459Szrj || (addr_mode == CODE_32BIT
8572*a9fa9459Szrj ? i.base_reg->reg_type.bitfield.reg32
8573*a9fa9459Szrj : i.base_reg->reg_type.bitfield.reg16)))
8574*a9fa9459Szrj goto bad_address;
8575*a9fa9459Szrj
8576*a9fa9459Szrj as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"),
8577*a9fa9459Szrj operand_string,
8578*a9fa9459Szrj intel_syntax ? '[' : '(',
8579*a9fa9459Szrj register_prefix,
8580*a9fa9459Szrj expected_reg->reg_name,
8581*a9fa9459Szrj intel_syntax ? ']' : ')');
8582*a9fa9459Szrj return 1;
8583*a9fa9459Szrj }
8584*a9fa9459Szrj else
8585*a9fa9459Szrj return 1;
8586*a9fa9459Szrj
8587*a9fa9459Szrj bad_address:
8588*a9fa9459Szrj as_bad (_("`%s' is not a valid %s expression"),
8589*a9fa9459Szrj operand_string, kind);
8590*a9fa9459Szrj return 0;
8591*a9fa9459Szrj }
8592*a9fa9459Szrj else
8593*a9fa9459Szrj {
8594*a9fa9459Szrj if (addr_mode != CODE_16BIT)
8595*a9fa9459Szrj {
8596*a9fa9459Szrj /* 32-bit/64-bit checks. */
8597*a9fa9459Szrj if ((i.base_reg
8598*a9fa9459Szrj && (addr_mode == CODE_64BIT
8599*a9fa9459Szrj ? !i.base_reg->reg_type.bitfield.reg64
8600*a9fa9459Szrj : !i.base_reg->reg_type.bitfield.reg32)
8601*a9fa9459Szrj && (i.index_reg
8602*a9fa9459Szrj || (i.base_reg->reg_num
8603*a9fa9459Szrj != (addr_mode == CODE_64BIT ? RegRip : RegEip))))
8604*a9fa9459Szrj || (i.index_reg
8605*a9fa9459Szrj && !i.index_reg->reg_type.bitfield.regxmm
8606*a9fa9459Szrj && !i.index_reg->reg_type.bitfield.regymm
8607*a9fa9459Szrj && !i.index_reg->reg_type.bitfield.regzmm
8608*a9fa9459Szrj && ((addr_mode == CODE_64BIT
8609*a9fa9459Szrj ? !(i.index_reg->reg_type.bitfield.reg64
8610*a9fa9459Szrj || i.index_reg->reg_num == RegRiz)
8611*a9fa9459Szrj : !(i.index_reg->reg_type.bitfield.reg32
8612*a9fa9459Szrj || i.index_reg->reg_num == RegEiz))
8613*a9fa9459Szrj || !i.index_reg->reg_type.bitfield.baseindex)))
8614*a9fa9459Szrj goto bad_address;
8615*a9fa9459Szrj
8616*a9fa9459Szrj /* bndmk, bndldx, and bndstx have special restrictions. */
8617*a9fa9459Szrj if (current_templates->start->base_opcode == 0xf30f1b
8618*a9fa9459Szrj || (current_templates->start->base_opcode & ~1) == 0x0f1a)
8619*a9fa9459Szrj {
8620*a9fa9459Szrj /* They cannot use RIP-relative addressing. */
8621*a9fa9459Szrj if (i.base_reg && i.base_reg->reg_num == RegRip)
8622*a9fa9459Szrj {
8623*a9fa9459Szrj as_bad (_("`%s' cannot be used here"), operand_string);
8624*a9fa9459Szrj return 0;
8625*a9fa9459Szrj }
8626*a9fa9459Szrj
8627*a9fa9459Szrj /* bndldx and bndstx ignore their scale factor. */
8628*a9fa9459Szrj if (current_templates->start->base_opcode != 0xf30f1b
8629*a9fa9459Szrj && i.log2_scale_factor)
8630*a9fa9459Szrj as_warn (_("register scaling is being ignored here"));
8631*a9fa9459Szrj }
8632*a9fa9459Szrj }
8633*a9fa9459Szrj else
8634*a9fa9459Szrj {
8635*a9fa9459Szrj /* 16-bit checks. */
8636*a9fa9459Szrj if ((i.base_reg
8637*a9fa9459Szrj && (!i.base_reg->reg_type.bitfield.reg16
8638*a9fa9459Szrj || !i.base_reg->reg_type.bitfield.baseindex))
8639*a9fa9459Szrj || (i.index_reg
8640*a9fa9459Szrj && (!i.index_reg->reg_type.bitfield.reg16
8641*a9fa9459Szrj || !i.index_reg->reg_type.bitfield.baseindex
8642*a9fa9459Szrj || !(i.base_reg
8643*a9fa9459Szrj && i.base_reg->reg_num < 6
8644*a9fa9459Szrj && i.index_reg->reg_num >= 6
8645*a9fa9459Szrj && i.log2_scale_factor == 0))))
8646*a9fa9459Szrj goto bad_address;
8647*a9fa9459Szrj }
8648*a9fa9459Szrj }
8649*a9fa9459Szrj return 1;
8650*a9fa9459Szrj }
8651*a9fa9459Szrj
8652*a9fa9459Szrj /* Handle vector immediates. */
8653*a9fa9459Szrj
8654*a9fa9459Szrj static int
RC_SAE_immediate(const char * imm_start)8655*a9fa9459Szrj RC_SAE_immediate (const char *imm_start)
8656*a9fa9459Szrj {
8657*a9fa9459Szrj unsigned int match_found, j;
8658*a9fa9459Szrj const char *pstr = imm_start;
8659*a9fa9459Szrj expressionS *exp;
8660*a9fa9459Szrj
8661*a9fa9459Szrj if (*pstr != '{')
8662*a9fa9459Szrj return 0;
8663*a9fa9459Szrj
8664*a9fa9459Szrj pstr++;
8665*a9fa9459Szrj match_found = 0;
8666*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (RC_NamesTable); j++)
8667*a9fa9459Szrj {
8668*a9fa9459Szrj if (!strncmp (pstr, RC_NamesTable[j].name, RC_NamesTable[j].len))
8669*a9fa9459Szrj {
8670*a9fa9459Szrj if (!i.rounding)
8671*a9fa9459Szrj {
8672*a9fa9459Szrj rc_op.type = RC_NamesTable[j].type;
8673*a9fa9459Szrj rc_op.operand = this_operand;
8674*a9fa9459Szrj i.rounding = &rc_op;
8675*a9fa9459Szrj }
8676*a9fa9459Szrj else
8677*a9fa9459Szrj {
8678*a9fa9459Szrj as_bad (_("duplicated `%s'"), imm_start);
8679*a9fa9459Szrj return 0;
8680*a9fa9459Szrj }
8681*a9fa9459Szrj pstr += RC_NamesTable[j].len;
8682*a9fa9459Szrj match_found = 1;
8683*a9fa9459Szrj break;
8684*a9fa9459Szrj }
8685*a9fa9459Szrj }
8686*a9fa9459Szrj if (!match_found)
8687*a9fa9459Szrj return 0;
8688*a9fa9459Szrj
8689*a9fa9459Szrj if (*pstr++ != '}')
8690*a9fa9459Szrj {
8691*a9fa9459Szrj as_bad (_("Missing '}': '%s'"), imm_start);
8692*a9fa9459Szrj return 0;
8693*a9fa9459Szrj }
8694*a9fa9459Szrj /* RC/SAE immediate string should contain nothing more. */;
8695*a9fa9459Szrj if (*pstr != 0)
8696*a9fa9459Szrj {
8697*a9fa9459Szrj as_bad (_("Junk after '}': '%s'"), imm_start);
8698*a9fa9459Szrj return 0;
8699*a9fa9459Szrj }
8700*a9fa9459Szrj
8701*a9fa9459Szrj exp = &im_expressions[i.imm_operands++];
8702*a9fa9459Szrj i.op[this_operand].imms = exp;
8703*a9fa9459Szrj
8704*a9fa9459Szrj exp->X_op = O_constant;
8705*a9fa9459Szrj exp->X_add_number = 0;
8706*a9fa9459Szrj exp->X_add_symbol = (symbolS *) 0;
8707*a9fa9459Szrj exp->X_op_symbol = (symbolS *) 0;
8708*a9fa9459Szrj
8709*a9fa9459Szrj i.types[this_operand].bitfield.imm8 = 1;
8710*a9fa9459Szrj return 1;
8711*a9fa9459Szrj }
8712*a9fa9459Szrj
8713*a9fa9459Szrj /* Only string instructions can have a second memory operand, so
8714*a9fa9459Szrj reduce current_templates to just those if it contains any. */
8715*a9fa9459Szrj static int
maybe_adjust_templates(void)8716*a9fa9459Szrj maybe_adjust_templates (void)
8717*a9fa9459Szrj {
8718*a9fa9459Szrj const insn_template *t;
8719*a9fa9459Szrj
8720*a9fa9459Szrj gas_assert (i.mem_operands == 1);
8721*a9fa9459Szrj
8722*a9fa9459Szrj for (t = current_templates->start; t < current_templates->end; ++t)
8723*a9fa9459Szrj if (t->opcode_modifier.isstring)
8724*a9fa9459Szrj break;
8725*a9fa9459Szrj
8726*a9fa9459Szrj if (t < current_templates->end)
8727*a9fa9459Szrj {
8728*a9fa9459Szrj static templates aux_templates;
8729*a9fa9459Szrj bfd_boolean recheck;
8730*a9fa9459Szrj
8731*a9fa9459Szrj aux_templates.start = t;
8732*a9fa9459Szrj for (; t < current_templates->end; ++t)
8733*a9fa9459Szrj if (!t->opcode_modifier.isstring)
8734*a9fa9459Szrj break;
8735*a9fa9459Szrj aux_templates.end = t;
8736*a9fa9459Szrj
8737*a9fa9459Szrj /* Determine whether to re-check the first memory operand. */
8738*a9fa9459Szrj recheck = (aux_templates.start != current_templates->start
8739*a9fa9459Szrj || t != current_templates->end);
8740*a9fa9459Szrj
8741*a9fa9459Szrj current_templates = &aux_templates;
8742*a9fa9459Szrj
8743*a9fa9459Szrj if (recheck)
8744*a9fa9459Szrj {
8745*a9fa9459Szrj i.mem_operands = 0;
8746*a9fa9459Szrj if (i.memop1_string != NULL
8747*a9fa9459Szrj && i386_index_check (i.memop1_string) == 0)
8748*a9fa9459Szrj return 0;
8749*a9fa9459Szrj i.mem_operands = 1;
8750*a9fa9459Szrj }
8751*a9fa9459Szrj }
8752*a9fa9459Szrj
8753*a9fa9459Szrj return 1;
8754*a9fa9459Szrj }
8755*a9fa9459Szrj
8756*a9fa9459Szrj /* Parse OPERAND_STRING into the i386_insn structure I. Returns zero
8757*a9fa9459Szrj on error. */
8758*a9fa9459Szrj
8759*a9fa9459Szrj static int
i386_att_operand(char * operand_string)8760*a9fa9459Szrj i386_att_operand (char *operand_string)
8761*a9fa9459Szrj {
8762*a9fa9459Szrj const reg_entry *r;
8763*a9fa9459Szrj char *end_op;
8764*a9fa9459Szrj char *op_string = operand_string;
8765*a9fa9459Szrj
8766*a9fa9459Szrj if (is_space_char (*op_string))
8767*a9fa9459Szrj ++op_string;
8768*a9fa9459Szrj
8769*a9fa9459Szrj /* We check for an absolute prefix (differentiating,
8770*a9fa9459Szrj for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
8771*a9fa9459Szrj if (*op_string == ABSOLUTE_PREFIX)
8772*a9fa9459Szrj {
8773*a9fa9459Szrj ++op_string;
8774*a9fa9459Szrj if (is_space_char (*op_string))
8775*a9fa9459Szrj ++op_string;
8776*a9fa9459Szrj i.types[this_operand].bitfield.jumpabsolute = 1;
8777*a9fa9459Szrj }
8778*a9fa9459Szrj
8779*a9fa9459Szrj /* Check if operand is a register. */
8780*a9fa9459Szrj if ((r = parse_register (op_string, &end_op)) != NULL)
8781*a9fa9459Szrj {
8782*a9fa9459Szrj i386_operand_type temp;
8783*a9fa9459Szrj
8784*a9fa9459Szrj /* Check for a segment override by searching for ':' after a
8785*a9fa9459Szrj segment register. */
8786*a9fa9459Szrj op_string = end_op;
8787*a9fa9459Szrj if (is_space_char (*op_string))
8788*a9fa9459Szrj ++op_string;
8789*a9fa9459Szrj if (*op_string == ':'
8790*a9fa9459Szrj && (r->reg_type.bitfield.sreg2
8791*a9fa9459Szrj || r->reg_type.bitfield.sreg3))
8792*a9fa9459Szrj {
8793*a9fa9459Szrj switch (r->reg_num)
8794*a9fa9459Szrj {
8795*a9fa9459Szrj case 0:
8796*a9fa9459Szrj i.seg[i.mem_operands] = &es;
8797*a9fa9459Szrj break;
8798*a9fa9459Szrj case 1:
8799*a9fa9459Szrj i.seg[i.mem_operands] = &cs;
8800*a9fa9459Szrj break;
8801*a9fa9459Szrj case 2:
8802*a9fa9459Szrj i.seg[i.mem_operands] = &ss;
8803*a9fa9459Szrj break;
8804*a9fa9459Szrj case 3:
8805*a9fa9459Szrj i.seg[i.mem_operands] = &ds;
8806*a9fa9459Szrj break;
8807*a9fa9459Szrj case 4:
8808*a9fa9459Szrj i.seg[i.mem_operands] = &fs;
8809*a9fa9459Szrj break;
8810*a9fa9459Szrj case 5:
8811*a9fa9459Szrj i.seg[i.mem_operands] = &gs;
8812*a9fa9459Szrj break;
8813*a9fa9459Szrj }
8814*a9fa9459Szrj
8815*a9fa9459Szrj /* Skip the ':' and whitespace. */
8816*a9fa9459Szrj ++op_string;
8817*a9fa9459Szrj if (is_space_char (*op_string))
8818*a9fa9459Szrj ++op_string;
8819*a9fa9459Szrj
8820*a9fa9459Szrj if (!is_digit_char (*op_string)
8821*a9fa9459Szrj && !is_identifier_char (*op_string)
8822*a9fa9459Szrj && *op_string != '('
8823*a9fa9459Szrj && *op_string != ABSOLUTE_PREFIX)
8824*a9fa9459Szrj {
8825*a9fa9459Szrj as_bad (_("bad memory operand `%s'"), op_string);
8826*a9fa9459Szrj return 0;
8827*a9fa9459Szrj }
8828*a9fa9459Szrj /* Handle case of %es:*foo. */
8829*a9fa9459Szrj if (*op_string == ABSOLUTE_PREFIX)
8830*a9fa9459Szrj {
8831*a9fa9459Szrj ++op_string;
8832*a9fa9459Szrj if (is_space_char (*op_string))
8833*a9fa9459Szrj ++op_string;
8834*a9fa9459Szrj i.types[this_operand].bitfield.jumpabsolute = 1;
8835*a9fa9459Szrj }
8836*a9fa9459Szrj goto do_memory_reference;
8837*a9fa9459Szrj }
8838*a9fa9459Szrj
8839*a9fa9459Szrj /* Handle vector operations. */
8840*a9fa9459Szrj if (*op_string == '{')
8841*a9fa9459Szrj {
8842*a9fa9459Szrj op_string = check_VecOperations (op_string, NULL);
8843*a9fa9459Szrj if (op_string == NULL)
8844*a9fa9459Szrj return 0;
8845*a9fa9459Szrj }
8846*a9fa9459Szrj
8847*a9fa9459Szrj if (*op_string)
8848*a9fa9459Szrj {
8849*a9fa9459Szrj as_bad (_("junk `%s' after register"), op_string);
8850*a9fa9459Szrj return 0;
8851*a9fa9459Szrj }
8852*a9fa9459Szrj temp = r->reg_type;
8853*a9fa9459Szrj temp.bitfield.baseindex = 0;
8854*a9fa9459Szrj i.types[this_operand] = operand_type_or (i.types[this_operand],
8855*a9fa9459Szrj temp);
8856*a9fa9459Szrj i.types[this_operand].bitfield.unspecified = 0;
8857*a9fa9459Szrj i.op[this_operand].regs = r;
8858*a9fa9459Szrj i.reg_operands++;
8859*a9fa9459Szrj }
8860*a9fa9459Szrj else if (*op_string == REGISTER_PREFIX)
8861*a9fa9459Szrj {
8862*a9fa9459Szrj as_bad (_("bad register name `%s'"), op_string);
8863*a9fa9459Szrj return 0;
8864*a9fa9459Szrj }
8865*a9fa9459Szrj else if (*op_string == IMMEDIATE_PREFIX)
8866*a9fa9459Szrj {
8867*a9fa9459Szrj ++op_string;
8868*a9fa9459Szrj if (i.types[this_operand].bitfield.jumpabsolute)
8869*a9fa9459Szrj {
8870*a9fa9459Szrj as_bad (_("immediate operand illegal with absolute jump"));
8871*a9fa9459Szrj return 0;
8872*a9fa9459Szrj }
8873*a9fa9459Szrj if (!i386_immediate (op_string))
8874*a9fa9459Szrj return 0;
8875*a9fa9459Szrj }
8876*a9fa9459Szrj else if (RC_SAE_immediate (operand_string))
8877*a9fa9459Szrj {
8878*a9fa9459Szrj /* If it is a RC or SAE immediate, do nothing. */
8879*a9fa9459Szrj ;
8880*a9fa9459Szrj }
8881*a9fa9459Szrj else if (is_digit_char (*op_string)
8882*a9fa9459Szrj || is_identifier_char (*op_string)
8883*a9fa9459Szrj || *op_string == '"'
8884*a9fa9459Szrj || *op_string == '(')
8885*a9fa9459Szrj {
8886*a9fa9459Szrj /* This is a memory reference of some sort. */
8887*a9fa9459Szrj char *base_string;
8888*a9fa9459Szrj
8889*a9fa9459Szrj /* Start and end of displacement string expression (if found). */
8890*a9fa9459Szrj char *displacement_string_start;
8891*a9fa9459Szrj char *displacement_string_end;
8892*a9fa9459Szrj char *vop_start;
8893*a9fa9459Szrj
8894*a9fa9459Szrj do_memory_reference:
8895*a9fa9459Szrj if (i.mem_operands == 1 && !maybe_adjust_templates ())
8896*a9fa9459Szrj return 0;
8897*a9fa9459Szrj if ((i.mem_operands == 1
8898*a9fa9459Szrj && !current_templates->start->opcode_modifier.isstring)
8899*a9fa9459Szrj || i.mem_operands == 2)
8900*a9fa9459Szrj {
8901*a9fa9459Szrj as_bad (_("too many memory references for `%s'"),
8902*a9fa9459Szrj current_templates->start->name);
8903*a9fa9459Szrj return 0;
8904*a9fa9459Szrj }
8905*a9fa9459Szrj
8906*a9fa9459Szrj /* Check for base index form. We detect the base index form by
8907*a9fa9459Szrj looking for an ')' at the end of the operand, searching
8908*a9fa9459Szrj for the '(' matching it, and finding a REGISTER_PREFIX or ','
8909*a9fa9459Szrj after the '('. */
8910*a9fa9459Szrj base_string = op_string + strlen (op_string);
8911*a9fa9459Szrj
8912*a9fa9459Szrj /* Handle vector operations. */
8913*a9fa9459Szrj vop_start = strchr (op_string, '{');
8914*a9fa9459Szrj if (vop_start && vop_start < base_string)
8915*a9fa9459Szrj {
8916*a9fa9459Szrj if (check_VecOperations (vop_start, base_string) == NULL)
8917*a9fa9459Szrj return 0;
8918*a9fa9459Szrj base_string = vop_start;
8919*a9fa9459Szrj }
8920*a9fa9459Szrj
8921*a9fa9459Szrj --base_string;
8922*a9fa9459Szrj if (is_space_char (*base_string))
8923*a9fa9459Szrj --base_string;
8924*a9fa9459Szrj
8925*a9fa9459Szrj /* If we only have a displacement, set-up for it to be parsed later. */
8926*a9fa9459Szrj displacement_string_start = op_string;
8927*a9fa9459Szrj displacement_string_end = base_string + 1;
8928*a9fa9459Szrj
8929*a9fa9459Szrj if (*base_string == ')')
8930*a9fa9459Szrj {
8931*a9fa9459Szrj char *temp_string;
8932*a9fa9459Szrj unsigned int parens_balanced = 1;
8933*a9fa9459Szrj /* We've already checked that the number of left & right ()'s are
8934*a9fa9459Szrj equal, so this loop will not be infinite. */
8935*a9fa9459Szrj do
8936*a9fa9459Szrj {
8937*a9fa9459Szrj base_string--;
8938*a9fa9459Szrj if (*base_string == ')')
8939*a9fa9459Szrj parens_balanced++;
8940*a9fa9459Szrj if (*base_string == '(')
8941*a9fa9459Szrj parens_balanced--;
8942*a9fa9459Szrj }
8943*a9fa9459Szrj while (parens_balanced);
8944*a9fa9459Szrj
8945*a9fa9459Szrj temp_string = base_string;
8946*a9fa9459Szrj
8947*a9fa9459Szrj /* Skip past '(' and whitespace. */
8948*a9fa9459Szrj ++base_string;
8949*a9fa9459Szrj if (is_space_char (*base_string))
8950*a9fa9459Szrj ++base_string;
8951*a9fa9459Szrj
8952*a9fa9459Szrj if (*base_string == ','
8953*a9fa9459Szrj || ((i.base_reg = parse_register (base_string, &end_op))
8954*a9fa9459Szrj != NULL))
8955*a9fa9459Szrj {
8956*a9fa9459Szrj displacement_string_end = temp_string;
8957*a9fa9459Szrj
8958*a9fa9459Szrj i.types[this_operand].bitfield.baseindex = 1;
8959*a9fa9459Szrj
8960*a9fa9459Szrj if (i.base_reg)
8961*a9fa9459Szrj {
8962*a9fa9459Szrj base_string = end_op;
8963*a9fa9459Szrj if (is_space_char (*base_string))
8964*a9fa9459Szrj ++base_string;
8965*a9fa9459Szrj }
8966*a9fa9459Szrj
8967*a9fa9459Szrj /* There may be an index reg or scale factor here. */
8968*a9fa9459Szrj if (*base_string == ',')
8969*a9fa9459Szrj {
8970*a9fa9459Szrj ++base_string;
8971*a9fa9459Szrj if (is_space_char (*base_string))
8972*a9fa9459Szrj ++base_string;
8973*a9fa9459Szrj
8974*a9fa9459Szrj if ((i.index_reg = parse_register (base_string, &end_op))
8975*a9fa9459Szrj != NULL)
8976*a9fa9459Szrj {
8977*a9fa9459Szrj base_string = end_op;
8978*a9fa9459Szrj if (is_space_char (*base_string))
8979*a9fa9459Szrj ++base_string;
8980*a9fa9459Szrj if (*base_string == ',')
8981*a9fa9459Szrj {
8982*a9fa9459Szrj ++base_string;
8983*a9fa9459Szrj if (is_space_char (*base_string))
8984*a9fa9459Szrj ++base_string;
8985*a9fa9459Szrj }
8986*a9fa9459Szrj else if (*base_string != ')')
8987*a9fa9459Szrj {
8988*a9fa9459Szrj as_bad (_("expecting `,' or `)' "
8989*a9fa9459Szrj "after index register in `%s'"),
8990*a9fa9459Szrj operand_string);
8991*a9fa9459Szrj return 0;
8992*a9fa9459Szrj }
8993*a9fa9459Szrj }
8994*a9fa9459Szrj else if (*base_string == REGISTER_PREFIX)
8995*a9fa9459Szrj {
8996*a9fa9459Szrj end_op = strchr (base_string, ',');
8997*a9fa9459Szrj if (end_op)
8998*a9fa9459Szrj *end_op = '\0';
8999*a9fa9459Szrj as_bad (_("bad register name `%s'"), base_string);
9000*a9fa9459Szrj return 0;
9001*a9fa9459Szrj }
9002*a9fa9459Szrj
9003*a9fa9459Szrj /* Check for scale factor. */
9004*a9fa9459Szrj if (*base_string != ')')
9005*a9fa9459Szrj {
9006*a9fa9459Szrj char *end_scale = i386_scale (base_string);
9007*a9fa9459Szrj
9008*a9fa9459Szrj if (!end_scale)
9009*a9fa9459Szrj return 0;
9010*a9fa9459Szrj
9011*a9fa9459Szrj base_string = end_scale;
9012*a9fa9459Szrj if (is_space_char (*base_string))
9013*a9fa9459Szrj ++base_string;
9014*a9fa9459Szrj if (*base_string != ')')
9015*a9fa9459Szrj {
9016*a9fa9459Szrj as_bad (_("expecting `)' "
9017*a9fa9459Szrj "after scale factor in `%s'"),
9018*a9fa9459Szrj operand_string);
9019*a9fa9459Szrj return 0;
9020*a9fa9459Szrj }
9021*a9fa9459Szrj }
9022*a9fa9459Szrj else if (!i.index_reg)
9023*a9fa9459Szrj {
9024*a9fa9459Szrj as_bad (_("expecting index register or scale factor "
9025*a9fa9459Szrj "after `,'; got '%c'"),
9026*a9fa9459Szrj *base_string);
9027*a9fa9459Szrj return 0;
9028*a9fa9459Szrj }
9029*a9fa9459Szrj }
9030*a9fa9459Szrj else if (*base_string != ')')
9031*a9fa9459Szrj {
9032*a9fa9459Szrj as_bad (_("expecting `,' or `)' "
9033*a9fa9459Szrj "after base register in `%s'"),
9034*a9fa9459Szrj operand_string);
9035*a9fa9459Szrj return 0;
9036*a9fa9459Szrj }
9037*a9fa9459Szrj }
9038*a9fa9459Szrj else if (*base_string == REGISTER_PREFIX)
9039*a9fa9459Szrj {
9040*a9fa9459Szrj end_op = strchr (base_string, ',');
9041*a9fa9459Szrj if (end_op)
9042*a9fa9459Szrj *end_op = '\0';
9043*a9fa9459Szrj as_bad (_("bad register name `%s'"), base_string);
9044*a9fa9459Szrj return 0;
9045*a9fa9459Szrj }
9046*a9fa9459Szrj }
9047*a9fa9459Szrj
9048*a9fa9459Szrj /* If there's an expression beginning the operand, parse it,
9049*a9fa9459Szrj assuming displacement_string_start and
9050*a9fa9459Szrj displacement_string_end are meaningful. */
9051*a9fa9459Szrj if (displacement_string_start != displacement_string_end)
9052*a9fa9459Szrj {
9053*a9fa9459Szrj if (!i386_displacement (displacement_string_start,
9054*a9fa9459Szrj displacement_string_end))
9055*a9fa9459Szrj return 0;
9056*a9fa9459Szrj }
9057*a9fa9459Szrj
9058*a9fa9459Szrj /* Special case for (%dx) while doing input/output op. */
9059*a9fa9459Szrj if (i.base_reg
9060*a9fa9459Szrj && operand_type_equal (&i.base_reg->reg_type,
9061*a9fa9459Szrj ®16_inoutportreg)
9062*a9fa9459Szrj && i.index_reg == 0
9063*a9fa9459Szrj && i.log2_scale_factor == 0
9064*a9fa9459Szrj && i.seg[i.mem_operands] == 0
9065*a9fa9459Szrj && !operand_type_check (i.types[this_operand], disp))
9066*a9fa9459Szrj {
9067*a9fa9459Szrj i.types[this_operand] = inoutportreg;
9068*a9fa9459Szrj return 1;
9069*a9fa9459Szrj }
9070*a9fa9459Szrj
9071*a9fa9459Szrj if (i386_index_check (operand_string) == 0)
9072*a9fa9459Szrj return 0;
9073*a9fa9459Szrj i.types[this_operand].bitfield.mem = 1;
9074*a9fa9459Szrj if (i.mem_operands == 0)
9075*a9fa9459Szrj i.memop1_string = xstrdup (operand_string);
9076*a9fa9459Szrj i.mem_operands++;
9077*a9fa9459Szrj }
9078*a9fa9459Szrj else
9079*a9fa9459Szrj {
9080*a9fa9459Szrj /* It's not a memory operand; argh! */
9081*a9fa9459Szrj as_bad (_("invalid char %s beginning operand %d `%s'"),
9082*a9fa9459Szrj output_invalid (*op_string),
9083*a9fa9459Szrj this_operand + 1,
9084*a9fa9459Szrj op_string);
9085*a9fa9459Szrj return 0;
9086*a9fa9459Szrj }
9087*a9fa9459Szrj return 1; /* Normal return. */
9088*a9fa9459Szrj }
9089*a9fa9459Szrj
9090*a9fa9459Szrj /* Calculate the maximum variable size (i.e., excluding fr_fix)
9091*a9fa9459Szrj that an rs_machine_dependent frag may reach. */
9092*a9fa9459Szrj
9093*a9fa9459Szrj unsigned int
i386_frag_max_var(fragS * frag)9094*a9fa9459Szrj i386_frag_max_var (fragS *frag)
9095*a9fa9459Szrj {
9096*a9fa9459Szrj /* The only relaxable frags are for jumps.
9097*a9fa9459Szrj Unconditional jumps can grow by 4 bytes and others by 5 bytes. */
9098*a9fa9459Szrj gas_assert (frag->fr_type == rs_machine_dependent);
9099*a9fa9459Szrj return TYPE_FROM_RELAX_STATE (frag->fr_subtype) == UNCOND_JUMP ? 4 : 5;
9100*a9fa9459Szrj }
9101*a9fa9459Szrj
9102*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9103*a9fa9459Szrj static int
elf_symbol_resolved_in_segment_p(symbolS * fr_symbol,offsetT fr_var)9104*a9fa9459Szrj elf_symbol_resolved_in_segment_p (symbolS *fr_symbol, offsetT fr_var)
9105*a9fa9459Szrj {
9106*a9fa9459Szrj /* STT_GNU_IFUNC symbol must go through PLT. */
9107*a9fa9459Szrj if ((symbol_get_bfdsym (fr_symbol)->flags
9108*a9fa9459Szrj & BSF_GNU_INDIRECT_FUNCTION) != 0)
9109*a9fa9459Szrj return 0;
9110*a9fa9459Szrj
9111*a9fa9459Szrj if (!S_IS_EXTERNAL (fr_symbol))
9112*a9fa9459Szrj /* Symbol may be weak or local. */
9113*a9fa9459Szrj return !S_IS_WEAK (fr_symbol);
9114*a9fa9459Szrj
9115*a9fa9459Szrj /* Global symbols with non-default visibility can't be preempted. */
9116*a9fa9459Szrj if (ELF_ST_VISIBILITY (S_GET_OTHER (fr_symbol)) != STV_DEFAULT)
9117*a9fa9459Szrj return 1;
9118*a9fa9459Szrj
9119*a9fa9459Szrj if (fr_var != NO_RELOC)
9120*a9fa9459Szrj switch ((enum bfd_reloc_code_real) fr_var)
9121*a9fa9459Szrj {
9122*a9fa9459Szrj case BFD_RELOC_386_PLT32:
9123*a9fa9459Szrj case BFD_RELOC_X86_64_PLT32:
9124*a9fa9459Szrj /* Symbol with PLT relocatin may be preempted. */
9125*a9fa9459Szrj return 0;
9126*a9fa9459Szrj default:
9127*a9fa9459Szrj abort ();
9128*a9fa9459Szrj }
9129*a9fa9459Szrj
9130*a9fa9459Szrj /* Global symbols with default visibility in a shared library may be
9131*a9fa9459Szrj preempted by another definition. */
9132*a9fa9459Szrj return !shared;
9133*a9fa9459Szrj }
9134*a9fa9459Szrj #endif
9135*a9fa9459Szrj
9136*a9fa9459Szrj /* md_estimate_size_before_relax()
9137*a9fa9459Szrj
9138*a9fa9459Szrj Called just before relax() for rs_machine_dependent frags. The x86
9139*a9fa9459Szrj assembler uses these frags to handle variable size jump
9140*a9fa9459Szrj instructions.
9141*a9fa9459Szrj
9142*a9fa9459Szrj Any symbol that is now undefined will not become defined.
9143*a9fa9459Szrj Return the correct fr_subtype in the frag.
9144*a9fa9459Szrj Return the initial "guess for variable size of frag" to caller.
9145*a9fa9459Szrj The guess is actually the growth beyond the fixed part. Whatever
9146*a9fa9459Szrj we do to grow the fixed or variable part contributes to our
9147*a9fa9459Szrj returned value. */
9148*a9fa9459Szrj
9149*a9fa9459Szrj int
md_estimate_size_before_relax(fragS * fragP,segT segment)9150*a9fa9459Szrj md_estimate_size_before_relax (fragS *fragP, segT segment)
9151*a9fa9459Szrj {
9152*a9fa9459Szrj /* We've already got fragP->fr_subtype right; all we have to do is
9153*a9fa9459Szrj check for un-relaxable symbols. On an ELF system, we can't relax
9154*a9fa9459Szrj an externally visible symbol, because it may be overridden by a
9155*a9fa9459Szrj shared library. */
9156*a9fa9459Szrj if (S_GET_SEGMENT (fragP->fr_symbol) != segment
9157*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9158*a9fa9459Szrj || (IS_ELF
9159*a9fa9459Szrj && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol,
9160*a9fa9459Szrj fragP->fr_var))
9161*a9fa9459Szrj #endif
9162*a9fa9459Szrj #if defined (OBJ_COFF) && defined (TE_PE)
9163*a9fa9459Szrj || (OUTPUT_FLAVOR == bfd_target_coff_flavour
9164*a9fa9459Szrj && S_IS_WEAK (fragP->fr_symbol))
9165*a9fa9459Szrj #endif
9166*a9fa9459Szrj )
9167*a9fa9459Szrj {
9168*a9fa9459Szrj /* Symbol is undefined in this segment, or we need to keep a
9169*a9fa9459Szrj reloc so that weak symbols can be overridden. */
9170*a9fa9459Szrj int size = (fragP->fr_subtype & CODE16) ? 2 : 4;
9171*a9fa9459Szrj enum bfd_reloc_code_real reloc_type;
9172*a9fa9459Szrj unsigned char *opcode;
9173*a9fa9459Szrj int old_fr_fix;
9174*a9fa9459Szrj
9175*a9fa9459Szrj if (fragP->fr_var != NO_RELOC)
9176*a9fa9459Szrj reloc_type = (enum bfd_reloc_code_real) fragP->fr_var;
9177*a9fa9459Szrj else if (size == 2)
9178*a9fa9459Szrj reloc_type = BFD_RELOC_16_PCREL;
9179*a9fa9459Szrj else
9180*a9fa9459Szrj reloc_type = BFD_RELOC_32_PCREL;
9181*a9fa9459Szrj
9182*a9fa9459Szrj old_fr_fix = fragP->fr_fix;
9183*a9fa9459Szrj opcode = (unsigned char *) fragP->fr_opcode;
9184*a9fa9459Szrj
9185*a9fa9459Szrj switch (TYPE_FROM_RELAX_STATE (fragP->fr_subtype))
9186*a9fa9459Szrj {
9187*a9fa9459Szrj case UNCOND_JUMP:
9188*a9fa9459Szrj /* Make jmp (0xeb) a (d)word displacement jump. */
9189*a9fa9459Szrj opcode[0] = 0xe9;
9190*a9fa9459Szrj fragP->fr_fix += size;
9191*a9fa9459Szrj fix_new (fragP, old_fr_fix, size,
9192*a9fa9459Szrj fragP->fr_symbol,
9193*a9fa9459Szrj fragP->fr_offset, 1,
9194*a9fa9459Szrj reloc_type);
9195*a9fa9459Szrj break;
9196*a9fa9459Szrj
9197*a9fa9459Szrj case COND_JUMP86:
9198*a9fa9459Szrj if (size == 2
9199*a9fa9459Szrj && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC))
9200*a9fa9459Szrj {
9201*a9fa9459Szrj /* Negate the condition, and branch past an
9202*a9fa9459Szrj unconditional jump. */
9203*a9fa9459Szrj opcode[0] ^= 1;
9204*a9fa9459Szrj opcode[1] = 3;
9205*a9fa9459Szrj /* Insert an unconditional jump. */
9206*a9fa9459Szrj opcode[2] = 0xe9;
9207*a9fa9459Szrj /* We added two extra opcode bytes, and have a two byte
9208*a9fa9459Szrj offset. */
9209*a9fa9459Szrj fragP->fr_fix += 2 + 2;
9210*a9fa9459Szrj fix_new (fragP, old_fr_fix + 2, 2,
9211*a9fa9459Szrj fragP->fr_symbol,
9212*a9fa9459Szrj fragP->fr_offset, 1,
9213*a9fa9459Szrj reloc_type);
9214*a9fa9459Szrj break;
9215*a9fa9459Szrj }
9216*a9fa9459Szrj /* Fall through. */
9217*a9fa9459Szrj
9218*a9fa9459Szrj case COND_JUMP:
9219*a9fa9459Szrj if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC)
9220*a9fa9459Szrj {
9221*a9fa9459Szrj fixS *fixP;
9222*a9fa9459Szrj
9223*a9fa9459Szrj fragP->fr_fix += 1;
9224*a9fa9459Szrj fixP = fix_new (fragP, old_fr_fix, 1,
9225*a9fa9459Szrj fragP->fr_symbol,
9226*a9fa9459Szrj fragP->fr_offset, 1,
9227*a9fa9459Szrj BFD_RELOC_8_PCREL);
9228*a9fa9459Szrj fixP->fx_signed = 1;
9229*a9fa9459Szrj break;
9230*a9fa9459Szrj }
9231*a9fa9459Szrj
9232*a9fa9459Szrj /* This changes the byte-displacement jump 0x7N
9233*a9fa9459Szrj to the (d)word-displacement jump 0x0f,0x8N. */
9234*a9fa9459Szrj opcode[1] = opcode[0] + 0x10;
9235*a9fa9459Szrj opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
9236*a9fa9459Szrj /* We've added an opcode byte. */
9237*a9fa9459Szrj fragP->fr_fix += 1 + size;
9238*a9fa9459Szrj fix_new (fragP, old_fr_fix + 1, size,
9239*a9fa9459Szrj fragP->fr_symbol,
9240*a9fa9459Szrj fragP->fr_offset, 1,
9241*a9fa9459Szrj reloc_type);
9242*a9fa9459Szrj break;
9243*a9fa9459Szrj
9244*a9fa9459Szrj default:
9245*a9fa9459Szrj BAD_CASE (fragP->fr_subtype);
9246*a9fa9459Szrj break;
9247*a9fa9459Szrj }
9248*a9fa9459Szrj frag_wane (fragP);
9249*a9fa9459Szrj return fragP->fr_fix - old_fr_fix;
9250*a9fa9459Szrj }
9251*a9fa9459Szrj
9252*a9fa9459Szrj /* Guess size depending on current relax state. Initially the relax
9253*a9fa9459Szrj state will correspond to a short jump and we return 1, because
9254*a9fa9459Szrj the variable part of the frag (the branch offset) is one byte
9255*a9fa9459Szrj long. However, we can relax a section more than once and in that
9256*a9fa9459Szrj case we must either set fr_subtype back to the unrelaxed state,
9257*a9fa9459Szrj or return the value for the appropriate branch. */
9258*a9fa9459Szrj return md_relax_table[fragP->fr_subtype].rlx_length;
9259*a9fa9459Szrj }
9260*a9fa9459Szrj
9261*a9fa9459Szrj /* Called after relax() is finished.
9262*a9fa9459Szrj
9263*a9fa9459Szrj In: Address of frag.
9264*a9fa9459Szrj fr_type == rs_machine_dependent.
9265*a9fa9459Szrj fr_subtype is what the address relaxed to.
9266*a9fa9459Szrj
9267*a9fa9459Szrj Out: Any fixSs and constants are set up.
9268*a9fa9459Szrj Caller will turn frag into a ".space 0". */
9269*a9fa9459Szrj
9270*a9fa9459Szrj void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec ATTRIBUTE_UNUSED,fragS * fragP)9271*a9fa9459Szrj md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
9272*a9fa9459Szrj fragS *fragP)
9273*a9fa9459Szrj {
9274*a9fa9459Szrj unsigned char *opcode;
9275*a9fa9459Szrj unsigned char *where_to_put_displacement = NULL;
9276*a9fa9459Szrj offsetT target_address;
9277*a9fa9459Szrj offsetT opcode_address;
9278*a9fa9459Szrj unsigned int extension = 0;
9279*a9fa9459Szrj offsetT displacement_from_opcode_start;
9280*a9fa9459Szrj
9281*a9fa9459Szrj opcode = (unsigned char *) fragP->fr_opcode;
9282*a9fa9459Szrj
9283*a9fa9459Szrj /* Address we want to reach in file space. */
9284*a9fa9459Szrj target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
9285*a9fa9459Szrj
9286*a9fa9459Szrj /* Address opcode resides at in file space. */
9287*a9fa9459Szrj opcode_address = fragP->fr_address + fragP->fr_fix;
9288*a9fa9459Szrj
9289*a9fa9459Szrj /* Displacement from opcode start to fill into instruction. */
9290*a9fa9459Szrj displacement_from_opcode_start = target_address - opcode_address;
9291*a9fa9459Szrj
9292*a9fa9459Szrj if ((fragP->fr_subtype & BIG) == 0)
9293*a9fa9459Szrj {
9294*a9fa9459Szrj /* Don't have to change opcode. */
9295*a9fa9459Szrj extension = 1; /* 1 opcode + 1 displacement */
9296*a9fa9459Szrj where_to_put_displacement = &opcode[1];
9297*a9fa9459Szrj }
9298*a9fa9459Szrj else
9299*a9fa9459Szrj {
9300*a9fa9459Szrj if (no_cond_jump_promotion
9301*a9fa9459Szrj && TYPE_FROM_RELAX_STATE (fragP->fr_subtype) != UNCOND_JUMP)
9302*a9fa9459Szrj as_warn_where (fragP->fr_file, fragP->fr_line,
9303*a9fa9459Szrj _("long jump required"));
9304*a9fa9459Szrj
9305*a9fa9459Szrj switch (fragP->fr_subtype)
9306*a9fa9459Szrj {
9307*a9fa9459Szrj case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG):
9308*a9fa9459Szrj extension = 4; /* 1 opcode + 4 displacement */
9309*a9fa9459Szrj opcode[0] = 0xe9;
9310*a9fa9459Szrj where_to_put_displacement = &opcode[1];
9311*a9fa9459Szrj break;
9312*a9fa9459Szrj
9313*a9fa9459Szrj case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16):
9314*a9fa9459Szrj extension = 2; /* 1 opcode + 2 displacement */
9315*a9fa9459Szrj opcode[0] = 0xe9;
9316*a9fa9459Szrj where_to_put_displacement = &opcode[1];
9317*a9fa9459Szrj break;
9318*a9fa9459Szrj
9319*a9fa9459Szrj case ENCODE_RELAX_STATE (COND_JUMP, BIG):
9320*a9fa9459Szrj case ENCODE_RELAX_STATE (COND_JUMP86, BIG):
9321*a9fa9459Szrj extension = 5; /* 2 opcode + 4 displacement */
9322*a9fa9459Szrj opcode[1] = opcode[0] + 0x10;
9323*a9fa9459Szrj opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
9324*a9fa9459Szrj where_to_put_displacement = &opcode[2];
9325*a9fa9459Szrj break;
9326*a9fa9459Szrj
9327*a9fa9459Szrj case ENCODE_RELAX_STATE (COND_JUMP, BIG16):
9328*a9fa9459Szrj extension = 3; /* 2 opcode + 2 displacement */
9329*a9fa9459Szrj opcode[1] = opcode[0] + 0x10;
9330*a9fa9459Szrj opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
9331*a9fa9459Szrj where_to_put_displacement = &opcode[2];
9332*a9fa9459Szrj break;
9333*a9fa9459Szrj
9334*a9fa9459Szrj case ENCODE_RELAX_STATE (COND_JUMP86, BIG16):
9335*a9fa9459Szrj extension = 4;
9336*a9fa9459Szrj opcode[0] ^= 1;
9337*a9fa9459Szrj opcode[1] = 3;
9338*a9fa9459Szrj opcode[2] = 0xe9;
9339*a9fa9459Szrj where_to_put_displacement = &opcode[3];
9340*a9fa9459Szrj break;
9341*a9fa9459Szrj
9342*a9fa9459Szrj default:
9343*a9fa9459Szrj BAD_CASE (fragP->fr_subtype);
9344*a9fa9459Szrj break;
9345*a9fa9459Szrj }
9346*a9fa9459Szrj }
9347*a9fa9459Szrj
9348*a9fa9459Szrj /* If size if less then four we are sure that the operand fits,
9349*a9fa9459Szrj but if it's 4, then it could be that the displacement is larger
9350*a9fa9459Szrj then -/+ 2GB. */
9351*a9fa9459Szrj if (DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype) == 4
9352*a9fa9459Szrj && object_64bit
9353*a9fa9459Szrj && ((addressT) (displacement_from_opcode_start - extension
9354*a9fa9459Szrj + ((addressT) 1 << 31))
9355*a9fa9459Szrj > (((addressT) 2 << 31) - 1)))
9356*a9fa9459Szrj {
9357*a9fa9459Szrj as_bad_where (fragP->fr_file, fragP->fr_line,
9358*a9fa9459Szrj _("jump target out of range"));
9359*a9fa9459Szrj /* Make us emit 0. */
9360*a9fa9459Szrj displacement_from_opcode_start = extension;
9361*a9fa9459Szrj }
9362*a9fa9459Szrj /* Now put displacement after opcode. */
9363*a9fa9459Szrj md_number_to_chars ((char *) where_to_put_displacement,
9364*a9fa9459Szrj (valueT) (displacement_from_opcode_start - extension),
9365*a9fa9459Szrj DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
9366*a9fa9459Szrj fragP->fr_fix += extension;
9367*a9fa9459Szrj }
9368*a9fa9459Szrj
9369*a9fa9459Szrj /* Apply a fixup (fixP) to segment data, once it has been determined
9370*a9fa9459Szrj by our caller that we have all the info we need to fix it up.
9371*a9fa9459Szrj
9372*a9fa9459Szrj Parameter valP is the pointer to the value of the bits.
9373*a9fa9459Szrj
9374*a9fa9459Szrj On the 386, immediates, displacements, and data pointers are all in
9375*a9fa9459Szrj the same (little-endian) format, so we don't need to care about which
9376*a9fa9459Szrj we are handling. */
9377*a9fa9459Szrj
9378*a9fa9459Szrj void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)9379*a9fa9459Szrj md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
9380*a9fa9459Szrj {
9381*a9fa9459Szrj char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
9382*a9fa9459Szrj valueT value = *valP;
9383*a9fa9459Szrj
9384*a9fa9459Szrj #if !defined (TE_Mach)
9385*a9fa9459Szrj if (fixP->fx_pcrel)
9386*a9fa9459Szrj {
9387*a9fa9459Szrj switch (fixP->fx_r_type)
9388*a9fa9459Szrj {
9389*a9fa9459Szrj default:
9390*a9fa9459Szrj break;
9391*a9fa9459Szrj
9392*a9fa9459Szrj case BFD_RELOC_64:
9393*a9fa9459Szrj fixP->fx_r_type = BFD_RELOC_64_PCREL;
9394*a9fa9459Szrj break;
9395*a9fa9459Szrj case BFD_RELOC_32:
9396*a9fa9459Szrj case BFD_RELOC_X86_64_32S:
9397*a9fa9459Szrj fixP->fx_r_type = BFD_RELOC_32_PCREL;
9398*a9fa9459Szrj break;
9399*a9fa9459Szrj case BFD_RELOC_16:
9400*a9fa9459Szrj fixP->fx_r_type = BFD_RELOC_16_PCREL;
9401*a9fa9459Szrj break;
9402*a9fa9459Szrj case BFD_RELOC_8:
9403*a9fa9459Szrj fixP->fx_r_type = BFD_RELOC_8_PCREL;
9404*a9fa9459Szrj break;
9405*a9fa9459Szrj }
9406*a9fa9459Szrj }
9407*a9fa9459Szrj
9408*a9fa9459Szrj if (fixP->fx_addsy != NULL
9409*a9fa9459Szrj && (fixP->fx_r_type == BFD_RELOC_32_PCREL
9410*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_64_PCREL
9411*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_16_PCREL
9412*a9fa9459Szrj || fixP->fx_r_type == BFD_RELOC_8_PCREL)
9413*a9fa9459Szrj && !use_rela_relocations)
9414*a9fa9459Szrj {
9415*a9fa9459Szrj /* This is a hack. There should be a better way to handle this.
9416*a9fa9459Szrj This covers for the fact that bfd_install_relocation will
9417*a9fa9459Szrj subtract the current location (for partial_inplace, PC relative
9418*a9fa9459Szrj relocations); see more below. */
9419*a9fa9459Szrj #ifndef OBJ_AOUT
9420*a9fa9459Szrj if (IS_ELF
9421*a9fa9459Szrj #ifdef TE_PE
9422*a9fa9459Szrj || OUTPUT_FLAVOR == bfd_target_coff_flavour
9423*a9fa9459Szrj #endif
9424*a9fa9459Szrj )
9425*a9fa9459Szrj value += fixP->fx_where + fixP->fx_frag->fr_address;
9426*a9fa9459Szrj #endif
9427*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9428*a9fa9459Szrj if (IS_ELF)
9429*a9fa9459Szrj {
9430*a9fa9459Szrj segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy);
9431*a9fa9459Szrj
9432*a9fa9459Szrj if ((sym_seg == seg
9433*a9fa9459Szrj || (symbol_section_p (fixP->fx_addsy)
9434*a9fa9459Szrj && sym_seg != absolute_section))
9435*a9fa9459Szrj && !generic_force_reloc (fixP))
9436*a9fa9459Szrj {
9437*a9fa9459Szrj /* Yes, we add the values in twice. This is because
9438*a9fa9459Szrj bfd_install_relocation subtracts them out again. I think
9439*a9fa9459Szrj bfd_install_relocation is broken, but I don't dare change
9440*a9fa9459Szrj it. FIXME. */
9441*a9fa9459Szrj value += fixP->fx_where + fixP->fx_frag->fr_address;
9442*a9fa9459Szrj }
9443*a9fa9459Szrj }
9444*a9fa9459Szrj #endif
9445*a9fa9459Szrj #if defined (OBJ_COFF) && defined (TE_PE)
9446*a9fa9459Szrj /* For some reason, the PE format does not store a
9447*a9fa9459Szrj section address offset for a PC relative symbol. */
9448*a9fa9459Szrj if (S_GET_SEGMENT (fixP->fx_addsy) != seg
9449*a9fa9459Szrj || S_IS_WEAK (fixP->fx_addsy))
9450*a9fa9459Szrj value += md_pcrel_from (fixP);
9451*a9fa9459Szrj #endif
9452*a9fa9459Szrj }
9453*a9fa9459Szrj #if defined (OBJ_COFF) && defined (TE_PE)
9454*a9fa9459Szrj if (fixP->fx_addsy != NULL
9455*a9fa9459Szrj && S_IS_WEAK (fixP->fx_addsy)
9456*a9fa9459Szrj /* PR 16858: Do not modify weak function references. */
9457*a9fa9459Szrj && ! fixP->fx_pcrel)
9458*a9fa9459Szrj {
9459*a9fa9459Szrj #if !defined (TE_PEP)
9460*a9fa9459Szrj /* For x86 PE weak function symbols are neither PC-relative
9461*a9fa9459Szrj nor do they set S_IS_FUNCTION. So the only reliable way
9462*a9fa9459Szrj to detect them is to check the flags of their containing
9463*a9fa9459Szrj section. */
9464*a9fa9459Szrj if (S_GET_SEGMENT (fixP->fx_addsy) != NULL
9465*a9fa9459Szrj && S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_CODE)
9466*a9fa9459Szrj ;
9467*a9fa9459Szrj else
9468*a9fa9459Szrj #endif
9469*a9fa9459Szrj value -= S_GET_VALUE (fixP->fx_addsy);
9470*a9fa9459Szrj }
9471*a9fa9459Szrj #endif
9472*a9fa9459Szrj
9473*a9fa9459Szrj /* Fix a few things - the dynamic linker expects certain values here,
9474*a9fa9459Szrj and we must not disappoint it. */
9475*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9476*a9fa9459Szrj if (IS_ELF && fixP->fx_addsy)
9477*a9fa9459Szrj switch (fixP->fx_r_type)
9478*a9fa9459Szrj {
9479*a9fa9459Szrj case BFD_RELOC_386_PLT32:
9480*a9fa9459Szrj case BFD_RELOC_X86_64_PLT32:
9481*a9fa9459Szrj /* Make the jump instruction point to the address of the operand. At
9482*a9fa9459Szrj runtime we merely add the offset to the actual PLT entry. */
9483*a9fa9459Szrj value = -4;
9484*a9fa9459Szrj break;
9485*a9fa9459Szrj
9486*a9fa9459Szrj case BFD_RELOC_386_TLS_GD:
9487*a9fa9459Szrj case BFD_RELOC_386_TLS_LDM:
9488*a9fa9459Szrj case BFD_RELOC_386_TLS_IE_32:
9489*a9fa9459Szrj case BFD_RELOC_386_TLS_IE:
9490*a9fa9459Szrj case BFD_RELOC_386_TLS_GOTIE:
9491*a9fa9459Szrj case BFD_RELOC_386_TLS_GOTDESC:
9492*a9fa9459Szrj case BFD_RELOC_X86_64_TLSGD:
9493*a9fa9459Szrj case BFD_RELOC_X86_64_TLSLD:
9494*a9fa9459Szrj case BFD_RELOC_X86_64_GOTTPOFF:
9495*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
9496*a9fa9459Szrj value = 0; /* Fully resolved at runtime. No addend. */
9497*a9fa9459Szrj /* Fallthrough */
9498*a9fa9459Szrj case BFD_RELOC_386_TLS_LE:
9499*a9fa9459Szrj case BFD_RELOC_386_TLS_LDO_32:
9500*a9fa9459Szrj case BFD_RELOC_386_TLS_LE_32:
9501*a9fa9459Szrj case BFD_RELOC_X86_64_DTPOFF32:
9502*a9fa9459Szrj case BFD_RELOC_X86_64_DTPOFF64:
9503*a9fa9459Szrj case BFD_RELOC_X86_64_TPOFF32:
9504*a9fa9459Szrj case BFD_RELOC_X86_64_TPOFF64:
9505*a9fa9459Szrj S_SET_THREAD_LOCAL (fixP->fx_addsy);
9506*a9fa9459Szrj break;
9507*a9fa9459Szrj
9508*a9fa9459Szrj case BFD_RELOC_386_TLS_DESC_CALL:
9509*a9fa9459Szrj case BFD_RELOC_X86_64_TLSDESC_CALL:
9510*a9fa9459Szrj value = 0; /* Fully resolved at runtime. No addend. */
9511*a9fa9459Szrj S_SET_THREAD_LOCAL (fixP->fx_addsy);
9512*a9fa9459Szrj fixP->fx_done = 0;
9513*a9fa9459Szrj return;
9514*a9fa9459Szrj
9515*a9fa9459Szrj case BFD_RELOC_VTABLE_INHERIT:
9516*a9fa9459Szrj case BFD_RELOC_VTABLE_ENTRY:
9517*a9fa9459Szrj fixP->fx_done = 0;
9518*a9fa9459Szrj return;
9519*a9fa9459Szrj
9520*a9fa9459Szrj default:
9521*a9fa9459Szrj break;
9522*a9fa9459Szrj }
9523*a9fa9459Szrj #endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */
9524*a9fa9459Szrj *valP = value;
9525*a9fa9459Szrj #endif /* !defined (TE_Mach) */
9526*a9fa9459Szrj
9527*a9fa9459Szrj /* Are we finished with this relocation now? */
9528*a9fa9459Szrj if (fixP->fx_addsy == NULL)
9529*a9fa9459Szrj fixP->fx_done = 1;
9530*a9fa9459Szrj #if defined (OBJ_COFF) && defined (TE_PE)
9531*a9fa9459Szrj else if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
9532*a9fa9459Szrj {
9533*a9fa9459Szrj fixP->fx_done = 0;
9534*a9fa9459Szrj /* Remember value for tc_gen_reloc. */
9535*a9fa9459Szrj fixP->fx_addnumber = value;
9536*a9fa9459Szrj /* Clear out the frag for now. */
9537*a9fa9459Szrj value = 0;
9538*a9fa9459Szrj }
9539*a9fa9459Szrj #endif
9540*a9fa9459Szrj else if (use_rela_relocations)
9541*a9fa9459Szrj {
9542*a9fa9459Szrj fixP->fx_no_overflow = 1;
9543*a9fa9459Szrj /* Remember value for tc_gen_reloc. */
9544*a9fa9459Szrj fixP->fx_addnumber = value;
9545*a9fa9459Szrj value = 0;
9546*a9fa9459Szrj }
9547*a9fa9459Szrj
9548*a9fa9459Szrj md_number_to_chars (p, value, fixP->fx_size);
9549*a9fa9459Szrj }
9550*a9fa9459Szrj
9551*a9fa9459Szrj const char *
md_atof(int type,char * litP,int * sizeP)9552*a9fa9459Szrj md_atof (int type, char *litP, int *sizeP)
9553*a9fa9459Szrj {
9554*a9fa9459Szrj /* This outputs the LITTLENUMs in REVERSE order;
9555*a9fa9459Szrj in accord with the bigendian 386. */
9556*a9fa9459Szrj return ieee_md_atof (type, litP, sizeP, FALSE);
9557*a9fa9459Szrj }
9558*a9fa9459Szrj
9559*a9fa9459Szrj static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
9560*a9fa9459Szrj
9561*a9fa9459Szrj static char *
output_invalid(int c)9562*a9fa9459Szrj output_invalid (int c)
9563*a9fa9459Szrj {
9564*a9fa9459Szrj if (ISPRINT (c))
9565*a9fa9459Szrj snprintf (output_invalid_buf, sizeof (output_invalid_buf),
9566*a9fa9459Szrj "'%c'", c);
9567*a9fa9459Szrj else
9568*a9fa9459Szrj snprintf (output_invalid_buf, sizeof (output_invalid_buf),
9569*a9fa9459Szrj "(0x%x)", (unsigned char) c);
9570*a9fa9459Szrj return output_invalid_buf;
9571*a9fa9459Szrj }
9572*a9fa9459Szrj
9573*a9fa9459Szrj /* REG_STRING starts *before* REGISTER_PREFIX. */
9574*a9fa9459Szrj
9575*a9fa9459Szrj static const reg_entry *
parse_real_register(char * reg_string,char ** end_op)9576*a9fa9459Szrj parse_real_register (char *reg_string, char **end_op)
9577*a9fa9459Szrj {
9578*a9fa9459Szrj char *s = reg_string;
9579*a9fa9459Szrj char *p;
9580*a9fa9459Szrj char reg_name_given[MAX_REG_NAME_SIZE + 1];
9581*a9fa9459Szrj const reg_entry *r;
9582*a9fa9459Szrj
9583*a9fa9459Szrj /* Skip possible REGISTER_PREFIX and possible whitespace. */
9584*a9fa9459Szrj if (*s == REGISTER_PREFIX)
9585*a9fa9459Szrj ++s;
9586*a9fa9459Szrj
9587*a9fa9459Szrj if (is_space_char (*s))
9588*a9fa9459Szrj ++s;
9589*a9fa9459Szrj
9590*a9fa9459Szrj p = reg_name_given;
9591*a9fa9459Szrj while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
9592*a9fa9459Szrj {
9593*a9fa9459Szrj if (p >= reg_name_given + MAX_REG_NAME_SIZE)
9594*a9fa9459Szrj return (const reg_entry *) NULL;
9595*a9fa9459Szrj s++;
9596*a9fa9459Szrj }
9597*a9fa9459Szrj
9598*a9fa9459Szrj /* For naked regs, make sure that we are not dealing with an identifier.
9599*a9fa9459Szrj This prevents confusing an identifier like `eax_var' with register
9600*a9fa9459Szrj `eax'. */
9601*a9fa9459Szrj if (allow_naked_reg && identifier_chars[(unsigned char) *s])
9602*a9fa9459Szrj return (const reg_entry *) NULL;
9603*a9fa9459Szrj
9604*a9fa9459Szrj *end_op = s;
9605*a9fa9459Szrj
9606*a9fa9459Szrj r = (const reg_entry *) hash_find (reg_hash, reg_name_given);
9607*a9fa9459Szrj
9608*a9fa9459Szrj /* Handle floating point regs, allowing spaces in the (i) part. */
9609*a9fa9459Szrj if (r == i386_regtab /* %st is first entry of table */)
9610*a9fa9459Szrj {
9611*a9fa9459Szrj if (is_space_char (*s))
9612*a9fa9459Szrj ++s;
9613*a9fa9459Szrj if (*s == '(')
9614*a9fa9459Szrj {
9615*a9fa9459Szrj ++s;
9616*a9fa9459Szrj if (is_space_char (*s))
9617*a9fa9459Szrj ++s;
9618*a9fa9459Szrj if (*s >= '0' && *s <= '7')
9619*a9fa9459Szrj {
9620*a9fa9459Szrj int fpr = *s - '0';
9621*a9fa9459Szrj ++s;
9622*a9fa9459Szrj if (is_space_char (*s))
9623*a9fa9459Szrj ++s;
9624*a9fa9459Szrj if (*s == ')')
9625*a9fa9459Szrj {
9626*a9fa9459Szrj *end_op = s + 1;
9627*a9fa9459Szrj r = (const reg_entry *) hash_find (reg_hash, "st(0)");
9628*a9fa9459Szrj know (r);
9629*a9fa9459Szrj return r + fpr;
9630*a9fa9459Szrj }
9631*a9fa9459Szrj }
9632*a9fa9459Szrj /* We have "%st(" then garbage. */
9633*a9fa9459Szrj return (const reg_entry *) NULL;
9634*a9fa9459Szrj }
9635*a9fa9459Szrj }
9636*a9fa9459Szrj
9637*a9fa9459Szrj if (r == NULL || allow_pseudo_reg)
9638*a9fa9459Szrj return r;
9639*a9fa9459Szrj
9640*a9fa9459Szrj if (operand_type_all_zero (&r->reg_type))
9641*a9fa9459Szrj return (const reg_entry *) NULL;
9642*a9fa9459Szrj
9643*a9fa9459Szrj if ((r->reg_type.bitfield.reg32
9644*a9fa9459Szrj || r->reg_type.bitfield.sreg3
9645*a9fa9459Szrj || r->reg_type.bitfield.control
9646*a9fa9459Szrj || r->reg_type.bitfield.debug
9647*a9fa9459Szrj || r->reg_type.bitfield.test)
9648*a9fa9459Szrj && !cpu_arch_flags.bitfield.cpui386)
9649*a9fa9459Szrj return (const reg_entry *) NULL;
9650*a9fa9459Szrj
9651*a9fa9459Szrj if (r->reg_type.bitfield.floatreg
9652*a9fa9459Szrj && !cpu_arch_flags.bitfield.cpu8087
9653*a9fa9459Szrj && !cpu_arch_flags.bitfield.cpu287
9654*a9fa9459Szrj && !cpu_arch_flags.bitfield.cpu387)
9655*a9fa9459Szrj return (const reg_entry *) NULL;
9656*a9fa9459Szrj
9657*a9fa9459Szrj if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpuregmmx)
9658*a9fa9459Szrj return (const reg_entry *) NULL;
9659*a9fa9459Szrj
9660*a9fa9459Szrj if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpuregxmm)
9661*a9fa9459Szrj return (const reg_entry *) NULL;
9662*a9fa9459Szrj
9663*a9fa9459Szrj if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuregymm)
9664*a9fa9459Szrj return (const reg_entry *) NULL;
9665*a9fa9459Szrj
9666*a9fa9459Szrj if (r->reg_type.bitfield.regzmm && !cpu_arch_flags.bitfield.cpuregzmm)
9667*a9fa9459Szrj return (const reg_entry *) NULL;
9668*a9fa9459Szrj
9669*a9fa9459Szrj if (r->reg_type.bitfield.regmask
9670*a9fa9459Szrj && !cpu_arch_flags.bitfield.cpuregmask)
9671*a9fa9459Szrj return (const reg_entry *) NULL;
9672*a9fa9459Szrj
9673*a9fa9459Szrj /* Don't allow fake index register unless allow_index_reg isn't 0. */
9674*a9fa9459Szrj if (!allow_index_reg
9675*a9fa9459Szrj && (r->reg_num == RegEiz || r->reg_num == RegRiz))
9676*a9fa9459Szrj return (const reg_entry *) NULL;
9677*a9fa9459Szrj
9678*a9fa9459Szrj /* Upper 16 vector register is only available with VREX in 64bit
9679*a9fa9459Szrj mode. */
9680*a9fa9459Szrj if ((r->reg_flags & RegVRex))
9681*a9fa9459Szrj {
9682*a9fa9459Szrj if (!cpu_arch_flags.bitfield.cpuvrex
9683*a9fa9459Szrj || flag_code != CODE_64BIT)
9684*a9fa9459Szrj return (const reg_entry *) NULL;
9685*a9fa9459Szrj
9686*a9fa9459Szrj i.need_vrex = 1;
9687*a9fa9459Szrj }
9688*a9fa9459Szrj
9689*a9fa9459Szrj if (((r->reg_flags & (RegRex64 | RegRex))
9690*a9fa9459Szrj || r->reg_type.bitfield.reg64)
9691*a9fa9459Szrj && (!cpu_arch_flags.bitfield.cpulm
9692*a9fa9459Szrj || !operand_type_equal (&r->reg_type, &control))
9693*a9fa9459Szrj && flag_code != CODE_64BIT)
9694*a9fa9459Szrj return (const reg_entry *) NULL;
9695*a9fa9459Szrj
9696*a9fa9459Szrj if (r->reg_type.bitfield.sreg3 && r->reg_num == RegFlat && !intel_syntax)
9697*a9fa9459Szrj return (const reg_entry *) NULL;
9698*a9fa9459Szrj
9699*a9fa9459Szrj return r;
9700*a9fa9459Szrj }
9701*a9fa9459Szrj
9702*a9fa9459Szrj /* REG_STRING starts *before* REGISTER_PREFIX. */
9703*a9fa9459Szrj
9704*a9fa9459Szrj static const reg_entry *
parse_register(char * reg_string,char ** end_op)9705*a9fa9459Szrj parse_register (char *reg_string, char **end_op)
9706*a9fa9459Szrj {
9707*a9fa9459Szrj const reg_entry *r;
9708*a9fa9459Szrj
9709*a9fa9459Szrj if (*reg_string == REGISTER_PREFIX || allow_naked_reg)
9710*a9fa9459Szrj r = parse_real_register (reg_string, end_op);
9711*a9fa9459Szrj else
9712*a9fa9459Szrj r = NULL;
9713*a9fa9459Szrj if (!r)
9714*a9fa9459Szrj {
9715*a9fa9459Szrj char *save = input_line_pointer;
9716*a9fa9459Szrj char c;
9717*a9fa9459Szrj symbolS *symbolP;
9718*a9fa9459Szrj
9719*a9fa9459Szrj input_line_pointer = reg_string;
9720*a9fa9459Szrj c = get_symbol_name (®_string);
9721*a9fa9459Szrj symbolP = symbol_find (reg_string);
9722*a9fa9459Szrj if (symbolP && S_GET_SEGMENT (symbolP) == reg_section)
9723*a9fa9459Szrj {
9724*a9fa9459Szrj const expressionS *e = symbol_get_value_expression (symbolP);
9725*a9fa9459Szrj
9726*a9fa9459Szrj know (e->X_op == O_register);
9727*a9fa9459Szrj know (e->X_add_number >= 0
9728*a9fa9459Szrj && (valueT) e->X_add_number < i386_regtab_size);
9729*a9fa9459Szrj r = i386_regtab + e->X_add_number;
9730*a9fa9459Szrj if ((r->reg_flags & RegVRex))
9731*a9fa9459Szrj i.need_vrex = 1;
9732*a9fa9459Szrj *end_op = input_line_pointer;
9733*a9fa9459Szrj }
9734*a9fa9459Szrj *input_line_pointer = c;
9735*a9fa9459Szrj input_line_pointer = save;
9736*a9fa9459Szrj }
9737*a9fa9459Szrj return r;
9738*a9fa9459Szrj }
9739*a9fa9459Szrj
9740*a9fa9459Szrj int
i386_parse_name(char * name,expressionS * e,char * nextcharP)9741*a9fa9459Szrj i386_parse_name (char *name, expressionS *e, char *nextcharP)
9742*a9fa9459Szrj {
9743*a9fa9459Szrj const reg_entry *r;
9744*a9fa9459Szrj char *end = input_line_pointer;
9745*a9fa9459Szrj
9746*a9fa9459Szrj *end = *nextcharP;
9747*a9fa9459Szrj r = parse_register (name, &input_line_pointer);
9748*a9fa9459Szrj if (r && end <= input_line_pointer)
9749*a9fa9459Szrj {
9750*a9fa9459Szrj *nextcharP = *input_line_pointer;
9751*a9fa9459Szrj *input_line_pointer = 0;
9752*a9fa9459Szrj e->X_op = O_register;
9753*a9fa9459Szrj e->X_add_number = r - i386_regtab;
9754*a9fa9459Szrj return 1;
9755*a9fa9459Szrj }
9756*a9fa9459Szrj input_line_pointer = end;
9757*a9fa9459Szrj *end = 0;
9758*a9fa9459Szrj return intel_syntax ? i386_intel_parse_name (name, e) : 0;
9759*a9fa9459Szrj }
9760*a9fa9459Szrj
9761*a9fa9459Szrj void
md_operand(expressionS * e)9762*a9fa9459Szrj md_operand (expressionS *e)
9763*a9fa9459Szrj {
9764*a9fa9459Szrj char *end;
9765*a9fa9459Szrj const reg_entry *r;
9766*a9fa9459Szrj
9767*a9fa9459Szrj switch (*input_line_pointer)
9768*a9fa9459Szrj {
9769*a9fa9459Szrj case REGISTER_PREFIX:
9770*a9fa9459Szrj r = parse_real_register (input_line_pointer, &end);
9771*a9fa9459Szrj if (r)
9772*a9fa9459Szrj {
9773*a9fa9459Szrj e->X_op = O_register;
9774*a9fa9459Szrj e->X_add_number = r - i386_regtab;
9775*a9fa9459Szrj input_line_pointer = end;
9776*a9fa9459Szrj }
9777*a9fa9459Szrj break;
9778*a9fa9459Szrj
9779*a9fa9459Szrj case '[':
9780*a9fa9459Szrj gas_assert (intel_syntax);
9781*a9fa9459Szrj end = input_line_pointer++;
9782*a9fa9459Szrj expression (e);
9783*a9fa9459Szrj if (*input_line_pointer == ']')
9784*a9fa9459Szrj {
9785*a9fa9459Szrj ++input_line_pointer;
9786*a9fa9459Szrj e->X_op_symbol = make_expr_symbol (e);
9787*a9fa9459Szrj e->X_add_symbol = NULL;
9788*a9fa9459Szrj e->X_add_number = 0;
9789*a9fa9459Szrj e->X_op = O_index;
9790*a9fa9459Szrj }
9791*a9fa9459Szrj else
9792*a9fa9459Szrj {
9793*a9fa9459Szrj e->X_op = O_absent;
9794*a9fa9459Szrj input_line_pointer = end;
9795*a9fa9459Szrj }
9796*a9fa9459Szrj break;
9797*a9fa9459Szrj }
9798*a9fa9459Szrj }
9799*a9fa9459Szrj
9800*a9fa9459Szrj
9801*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9802*a9fa9459Szrj const char *md_shortopts = "kVQ:sqn";
9803*a9fa9459Szrj #else
9804*a9fa9459Szrj const char *md_shortopts = "qn";
9805*a9fa9459Szrj #endif
9806*a9fa9459Szrj
9807*a9fa9459Szrj #define OPTION_32 (OPTION_MD_BASE + 0)
9808*a9fa9459Szrj #define OPTION_64 (OPTION_MD_BASE + 1)
9809*a9fa9459Szrj #define OPTION_DIVIDE (OPTION_MD_BASE + 2)
9810*a9fa9459Szrj #define OPTION_MARCH (OPTION_MD_BASE + 3)
9811*a9fa9459Szrj #define OPTION_MTUNE (OPTION_MD_BASE + 4)
9812*a9fa9459Szrj #define OPTION_MMNEMONIC (OPTION_MD_BASE + 5)
9813*a9fa9459Szrj #define OPTION_MSYNTAX (OPTION_MD_BASE + 6)
9814*a9fa9459Szrj #define OPTION_MINDEX_REG (OPTION_MD_BASE + 7)
9815*a9fa9459Szrj #define OPTION_MNAKED_REG (OPTION_MD_BASE + 8)
9816*a9fa9459Szrj #define OPTION_MOLD_GCC (OPTION_MD_BASE + 9)
9817*a9fa9459Szrj #define OPTION_MSSE2AVX (OPTION_MD_BASE + 10)
9818*a9fa9459Szrj #define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11)
9819*a9fa9459Szrj #define OPTION_MOPERAND_CHECK (OPTION_MD_BASE + 12)
9820*a9fa9459Szrj #define OPTION_MAVXSCALAR (OPTION_MD_BASE + 13)
9821*a9fa9459Szrj #define OPTION_X32 (OPTION_MD_BASE + 14)
9822*a9fa9459Szrj #define OPTION_MADD_BND_PREFIX (OPTION_MD_BASE + 15)
9823*a9fa9459Szrj #define OPTION_MEVEXLIG (OPTION_MD_BASE + 16)
9824*a9fa9459Szrj #define OPTION_MEVEXWIG (OPTION_MD_BASE + 17)
9825*a9fa9459Szrj #define OPTION_MBIG_OBJ (OPTION_MD_BASE + 18)
9826*a9fa9459Szrj #define OPTION_MOMIT_LOCK_PREFIX (OPTION_MD_BASE + 19)
9827*a9fa9459Szrj #define OPTION_MEVEXRCIG (OPTION_MD_BASE + 20)
9828*a9fa9459Szrj #define OPTION_MSHARED (OPTION_MD_BASE + 21)
9829*a9fa9459Szrj #define OPTION_MAMD64 (OPTION_MD_BASE + 22)
9830*a9fa9459Szrj #define OPTION_MINTEL64 (OPTION_MD_BASE + 23)
9831*a9fa9459Szrj #define OPTION_MFENCE_AS_LOCK_ADD (OPTION_MD_BASE + 24)
9832*a9fa9459Szrj #define OPTION_MRELAX_RELOCATIONS (OPTION_MD_BASE + 25)
9833*a9fa9459Szrj
9834*a9fa9459Szrj struct option md_longopts[] =
9835*a9fa9459Szrj {
9836*a9fa9459Szrj {"32", no_argument, NULL, OPTION_32},
9837*a9fa9459Szrj #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
9838*a9fa9459Szrj || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
9839*a9fa9459Szrj {"64", no_argument, NULL, OPTION_64},
9840*a9fa9459Szrj #endif
9841*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9842*a9fa9459Szrj {"x32", no_argument, NULL, OPTION_X32},
9843*a9fa9459Szrj {"mshared", no_argument, NULL, OPTION_MSHARED},
9844*a9fa9459Szrj #endif
9845*a9fa9459Szrj {"divide", no_argument, NULL, OPTION_DIVIDE},
9846*a9fa9459Szrj {"march", required_argument, NULL, OPTION_MARCH},
9847*a9fa9459Szrj {"mtune", required_argument, NULL, OPTION_MTUNE},
9848*a9fa9459Szrj {"mmnemonic", required_argument, NULL, OPTION_MMNEMONIC},
9849*a9fa9459Szrj {"msyntax", required_argument, NULL, OPTION_MSYNTAX},
9850*a9fa9459Szrj {"mindex-reg", no_argument, NULL, OPTION_MINDEX_REG},
9851*a9fa9459Szrj {"mnaked-reg", no_argument, NULL, OPTION_MNAKED_REG},
9852*a9fa9459Szrj {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
9853*a9fa9459Szrj {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
9854*a9fa9459Szrj {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
9855*a9fa9459Szrj {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK},
9856*a9fa9459Szrj {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR},
9857*a9fa9459Szrj {"madd-bnd-prefix", no_argument, NULL, OPTION_MADD_BND_PREFIX},
9858*a9fa9459Szrj {"mevexlig", required_argument, NULL, OPTION_MEVEXLIG},
9859*a9fa9459Szrj {"mevexwig", required_argument, NULL, OPTION_MEVEXWIG},
9860*a9fa9459Szrj # if defined (TE_PE) || defined (TE_PEP)
9861*a9fa9459Szrj {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ},
9862*a9fa9459Szrj #endif
9863*a9fa9459Szrj {"momit-lock-prefix", required_argument, NULL, OPTION_MOMIT_LOCK_PREFIX},
9864*a9fa9459Szrj {"mfence-as-lock-add", required_argument, NULL, OPTION_MFENCE_AS_LOCK_ADD},
9865*a9fa9459Szrj {"mrelax-relocations", required_argument, NULL, OPTION_MRELAX_RELOCATIONS},
9866*a9fa9459Szrj {"mevexrcig", required_argument, NULL, OPTION_MEVEXRCIG},
9867*a9fa9459Szrj {"mamd64", no_argument, NULL, OPTION_MAMD64},
9868*a9fa9459Szrj {"mintel64", no_argument, NULL, OPTION_MINTEL64},
9869*a9fa9459Szrj {NULL, no_argument, NULL, 0}
9870*a9fa9459Szrj };
9871*a9fa9459Szrj size_t md_longopts_size = sizeof (md_longopts);
9872*a9fa9459Szrj
9873*a9fa9459Szrj int
md_parse_option(int c,const char * arg)9874*a9fa9459Szrj md_parse_option (int c, const char *arg)
9875*a9fa9459Szrj {
9876*a9fa9459Szrj unsigned int j;
9877*a9fa9459Szrj char *arch, *next, *saved;
9878*a9fa9459Szrj
9879*a9fa9459Szrj switch (c)
9880*a9fa9459Szrj {
9881*a9fa9459Szrj case 'n':
9882*a9fa9459Szrj optimize_align_code = 0;
9883*a9fa9459Szrj break;
9884*a9fa9459Szrj
9885*a9fa9459Szrj case 'q':
9886*a9fa9459Szrj quiet_warnings = 1;
9887*a9fa9459Szrj break;
9888*a9fa9459Szrj
9889*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9890*a9fa9459Szrj /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
9891*a9fa9459Szrj should be emitted or not. FIXME: Not implemented. */
9892*a9fa9459Szrj case 'Q':
9893*a9fa9459Szrj break;
9894*a9fa9459Szrj
9895*a9fa9459Szrj /* -V: SVR4 argument to print version ID. */
9896*a9fa9459Szrj case 'V':
9897*a9fa9459Szrj print_version_id ();
9898*a9fa9459Szrj break;
9899*a9fa9459Szrj
9900*a9fa9459Szrj /* -k: Ignore for FreeBSD compatibility. */
9901*a9fa9459Szrj case 'k':
9902*a9fa9459Szrj break;
9903*a9fa9459Szrj
9904*a9fa9459Szrj case 's':
9905*a9fa9459Szrj /* -s: On i386 Solaris, this tells the native assembler to use
9906*a9fa9459Szrj .stab instead of .stab.excl. We always use .stab anyhow. */
9907*a9fa9459Szrj break;
9908*a9fa9459Szrj
9909*a9fa9459Szrj case OPTION_MSHARED:
9910*a9fa9459Szrj shared = 1;
9911*a9fa9459Szrj break;
9912*a9fa9459Szrj #endif
9913*a9fa9459Szrj #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
9914*a9fa9459Szrj || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
9915*a9fa9459Szrj case OPTION_64:
9916*a9fa9459Szrj {
9917*a9fa9459Szrj const char **list, **l;
9918*a9fa9459Szrj
9919*a9fa9459Szrj list = bfd_target_list ();
9920*a9fa9459Szrj for (l = list; *l != NULL; l++)
9921*a9fa9459Szrj if (CONST_STRNEQ (*l, "elf64-x86-64")
9922*a9fa9459Szrj || strcmp (*l, "coff-x86-64") == 0
9923*a9fa9459Szrj || strcmp (*l, "pe-x86-64") == 0
9924*a9fa9459Szrj || strcmp (*l, "pei-x86-64") == 0
9925*a9fa9459Szrj || strcmp (*l, "mach-o-x86-64") == 0)
9926*a9fa9459Szrj {
9927*a9fa9459Szrj default_arch = "x86_64";
9928*a9fa9459Szrj break;
9929*a9fa9459Szrj }
9930*a9fa9459Szrj if (*l == NULL)
9931*a9fa9459Szrj as_fatal (_("no compiled in support for x86_64"));
9932*a9fa9459Szrj free (list);
9933*a9fa9459Szrj }
9934*a9fa9459Szrj break;
9935*a9fa9459Szrj #endif
9936*a9fa9459Szrj
9937*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
9938*a9fa9459Szrj case OPTION_X32:
9939*a9fa9459Szrj if (IS_ELF)
9940*a9fa9459Szrj {
9941*a9fa9459Szrj const char **list, **l;
9942*a9fa9459Szrj
9943*a9fa9459Szrj list = bfd_target_list ();
9944*a9fa9459Szrj for (l = list; *l != NULL; l++)
9945*a9fa9459Szrj if (CONST_STRNEQ (*l, "elf32-x86-64"))
9946*a9fa9459Szrj {
9947*a9fa9459Szrj default_arch = "x86_64:32";
9948*a9fa9459Szrj break;
9949*a9fa9459Szrj }
9950*a9fa9459Szrj if (*l == NULL)
9951*a9fa9459Szrj as_fatal (_("no compiled in support for 32bit x86_64"));
9952*a9fa9459Szrj free (list);
9953*a9fa9459Szrj }
9954*a9fa9459Szrj else
9955*a9fa9459Szrj as_fatal (_("32bit x86_64 is only supported for ELF"));
9956*a9fa9459Szrj break;
9957*a9fa9459Szrj #endif
9958*a9fa9459Szrj
9959*a9fa9459Szrj case OPTION_32:
9960*a9fa9459Szrj default_arch = "i386";
9961*a9fa9459Szrj break;
9962*a9fa9459Szrj
9963*a9fa9459Szrj case OPTION_DIVIDE:
9964*a9fa9459Szrj #ifdef SVR4_COMMENT_CHARS
9965*a9fa9459Szrj {
9966*a9fa9459Szrj char *n, *t;
9967*a9fa9459Szrj const char *s;
9968*a9fa9459Szrj
9969*a9fa9459Szrj n = XNEWVEC (char, strlen (i386_comment_chars) + 1);
9970*a9fa9459Szrj t = n;
9971*a9fa9459Szrj for (s = i386_comment_chars; *s != '\0'; s++)
9972*a9fa9459Szrj if (*s != '/')
9973*a9fa9459Szrj *t++ = *s;
9974*a9fa9459Szrj *t = '\0';
9975*a9fa9459Szrj i386_comment_chars = n;
9976*a9fa9459Szrj }
9977*a9fa9459Szrj #endif
9978*a9fa9459Szrj break;
9979*a9fa9459Szrj
9980*a9fa9459Szrj case OPTION_MARCH:
9981*a9fa9459Szrj saved = xstrdup (arg);
9982*a9fa9459Szrj arch = saved;
9983*a9fa9459Szrj /* Allow -march=+nosse. */
9984*a9fa9459Szrj if (*arch == '+')
9985*a9fa9459Szrj arch++;
9986*a9fa9459Szrj do
9987*a9fa9459Szrj {
9988*a9fa9459Szrj if (*arch == '.')
9989*a9fa9459Szrj as_fatal (_("invalid -march= option: `%s'"), arg);
9990*a9fa9459Szrj next = strchr (arch, '+');
9991*a9fa9459Szrj if (next)
9992*a9fa9459Szrj *next++ = '\0';
9993*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_arch); j++)
9994*a9fa9459Szrj {
9995*a9fa9459Szrj if (strcmp (arch, cpu_arch [j].name) == 0)
9996*a9fa9459Szrj {
9997*a9fa9459Szrj /* Processor. */
9998*a9fa9459Szrj if (! cpu_arch[j].flags.bitfield.cpui386)
9999*a9fa9459Szrj continue;
10000*a9fa9459Szrj
10001*a9fa9459Szrj cpu_arch_name = cpu_arch[j].name;
10002*a9fa9459Szrj cpu_sub_arch_name = NULL;
10003*a9fa9459Szrj cpu_arch_flags = cpu_arch[j].flags;
10004*a9fa9459Szrj cpu_arch_isa = cpu_arch[j].type;
10005*a9fa9459Szrj cpu_arch_isa_flags = cpu_arch[j].flags;
10006*a9fa9459Szrj if (!cpu_arch_tune_set)
10007*a9fa9459Szrj {
10008*a9fa9459Szrj cpu_arch_tune = cpu_arch_isa;
10009*a9fa9459Szrj cpu_arch_tune_flags = cpu_arch_isa_flags;
10010*a9fa9459Szrj }
10011*a9fa9459Szrj break;
10012*a9fa9459Szrj }
10013*a9fa9459Szrj else if (*cpu_arch [j].name == '.'
10014*a9fa9459Szrj && strcmp (arch, cpu_arch [j].name + 1) == 0)
10015*a9fa9459Szrj {
10016*a9fa9459Szrj /* ISA entension. */
10017*a9fa9459Szrj i386_cpu_flags flags;
10018*a9fa9459Szrj
10019*a9fa9459Szrj flags = cpu_flags_or (cpu_arch_flags,
10020*a9fa9459Szrj cpu_arch[j].flags);
10021*a9fa9459Szrj
10022*a9fa9459Szrj if (!valid_iamcu_cpu_flags (&flags))
10023*a9fa9459Szrj as_fatal (_("`%s' isn't valid for Intel MCU"), arch);
10024*a9fa9459Szrj else if (!cpu_flags_equal (&flags, &cpu_arch_flags))
10025*a9fa9459Szrj {
10026*a9fa9459Szrj if (cpu_sub_arch_name)
10027*a9fa9459Szrj {
10028*a9fa9459Szrj char *name = cpu_sub_arch_name;
10029*a9fa9459Szrj cpu_sub_arch_name = concat (name,
10030*a9fa9459Szrj cpu_arch[j].name,
10031*a9fa9459Szrj (const char *) NULL);
10032*a9fa9459Szrj free (name);
10033*a9fa9459Szrj }
10034*a9fa9459Szrj else
10035*a9fa9459Szrj cpu_sub_arch_name = xstrdup (cpu_arch[j].name);
10036*a9fa9459Szrj cpu_arch_flags = flags;
10037*a9fa9459Szrj cpu_arch_isa_flags = flags;
10038*a9fa9459Szrj }
10039*a9fa9459Szrj break;
10040*a9fa9459Szrj }
10041*a9fa9459Szrj }
10042*a9fa9459Szrj
10043*a9fa9459Szrj if (j >= ARRAY_SIZE (cpu_arch))
10044*a9fa9459Szrj {
10045*a9fa9459Szrj /* Disable an ISA entension. */
10046*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_noarch); j++)
10047*a9fa9459Szrj if (strcmp (arch, cpu_noarch [j].name) == 0)
10048*a9fa9459Szrj {
10049*a9fa9459Szrj i386_cpu_flags flags;
10050*a9fa9459Szrj
10051*a9fa9459Szrj flags = cpu_flags_and_not (cpu_arch_flags,
10052*a9fa9459Szrj cpu_noarch[j].flags);
10053*a9fa9459Szrj if (!cpu_flags_equal (&flags, &cpu_arch_flags))
10054*a9fa9459Szrj {
10055*a9fa9459Szrj if (cpu_sub_arch_name)
10056*a9fa9459Szrj {
10057*a9fa9459Szrj char *name = cpu_sub_arch_name;
10058*a9fa9459Szrj cpu_sub_arch_name = concat (arch,
10059*a9fa9459Szrj (const char *) NULL);
10060*a9fa9459Szrj free (name);
10061*a9fa9459Szrj }
10062*a9fa9459Szrj else
10063*a9fa9459Szrj cpu_sub_arch_name = xstrdup (arch);
10064*a9fa9459Szrj cpu_arch_flags = flags;
10065*a9fa9459Szrj cpu_arch_isa_flags = flags;
10066*a9fa9459Szrj }
10067*a9fa9459Szrj break;
10068*a9fa9459Szrj }
10069*a9fa9459Szrj
10070*a9fa9459Szrj if (j >= ARRAY_SIZE (cpu_noarch))
10071*a9fa9459Szrj j = ARRAY_SIZE (cpu_arch);
10072*a9fa9459Szrj }
10073*a9fa9459Szrj
10074*a9fa9459Szrj if (j >= ARRAY_SIZE (cpu_arch))
10075*a9fa9459Szrj as_fatal (_("invalid -march= option: `%s'"), arg);
10076*a9fa9459Szrj
10077*a9fa9459Szrj arch = next;
10078*a9fa9459Szrj }
10079*a9fa9459Szrj while (next != NULL);
10080*a9fa9459Szrj free (saved);
10081*a9fa9459Szrj break;
10082*a9fa9459Szrj
10083*a9fa9459Szrj case OPTION_MTUNE:
10084*a9fa9459Szrj if (*arg == '.')
10085*a9fa9459Szrj as_fatal (_("invalid -mtune= option: `%s'"), arg);
10086*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_arch); j++)
10087*a9fa9459Szrj {
10088*a9fa9459Szrj if (strcmp (arg, cpu_arch [j].name) == 0)
10089*a9fa9459Szrj {
10090*a9fa9459Szrj cpu_arch_tune_set = 1;
10091*a9fa9459Szrj cpu_arch_tune = cpu_arch [j].type;
10092*a9fa9459Szrj cpu_arch_tune_flags = cpu_arch[j].flags;
10093*a9fa9459Szrj break;
10094*a9fa9459Szrj }
10095*a9fa9459Szrj }
10096*a9fa9459Szrj if (j >= ARRAY_SIZE (cpu_arch))
10097*a9fa9459Szrj as_fatal (_("invalid -mtune= option: `%s'"), arg);
10098*a9fa9459Szrj break;
10099*a9fa9459Szrj
10100*a9fa9459Szrj case OPTION_MMNEMONIC:
10101*a9fa9459Szrj if (strcasecmp (arg, "att") == 0)
10102*a9fa9459Szrj intel_mnemonic = 0;
10103*a9fa9459Szrj else if (strcasecmp (arg, "intel") == 0)
10104*a9fa9459Szrj intel_mnemonic = 1;
10105*a9fa9459Szrj else
10106*a9fa9459Szrj as_fatal (_("invalid -mmnemonic= option: `%s'"), arg);
10107*a9fa9459Szrj break;
10108*a9fa9459Szrj
10109*a9fa9459Szrj case OPTION_MSYNTAX:
10110*a9fa9459Szrj if (strcasecmp (arg, "att") == 0)
10111*a9fa9459Szrj intel_syntax = 0;
10112*a9fa9459Szrj else if (strcasecmp (arg, "intel") == 0)
10113*a9fa9459Szrj intel_syntax = 1;
10114*a9fa9459Szrj else
10115*a9fa9459Szrj as_fatal (_("invalid -msyntax= option: `%s'"), arg);
10116*a9fa9459Szrj break;
10117*a9fa9459Szrj
10118*a9fa9459Szrj case OPTION_MINDEX_REG:
10119*a9fa9459Szrj allow_index_reg = 1;
10120*a9fa9459Szrj break;
10121*a9fa9459Szrj
10122*a9fa9459Szrj case OPTION_MNAKED_REG:
10123*a9fa9459Szrj allow_naked_reg = 1;
10124*a9fa9459Szrj break;
10125*a9fa9459Szrj
10126*a9fa9459Szrj case OPTION_MOLD_GCC:
10127*a9fa9459Szrj old_gcc = 1;
10128*a9fa9459Szrj break;
10129*a9fa9459Szrj
10130*a9fa9459Szrj case OPTION_MSSE2AVX:
10131*a9fa9459Szrj sse2avx = 1;
10132*a9fa9459Szrj break;
10133*a9fa9459Szrj
10134*a9fa9459Szrj case OPTION_MSSE_CHECK:
10135*a9fa9459Szrj if (strcasecmp (arg, "error") == 0)
10136*a9fa9459Szrj sse_check = check_error;
10137*a9fa9459Szrj else if (strcasecmp (arg, "warning") == 0)
10138*a9fa9459Szrj sse_check = check_warning;
10139*a9fa9459Szrj else if (strcasecmp (arg, "none") == 0)
10140*a9fa9459Szrj sse_check = check_none;
10141*a9fa9459Szrj else
10142*a9fa9459Szrj as_fatal (_("invalid -msse-check= option: `%s'"), arg);
10143*a9fa9459Szrj break;
10144*a9fa9459Szrj
10145*a9fa9459Szrj case OPTION_MOPERAND_CHECK:
10146*a9fa9459Szrj if (strcasecmp (arg, "error") == 0)
10147*a9fa9459Szrj operand_check = check_error;
10148*a9fa9459Szrj else if (strcasecmp (arg, "warning") == 0)
10149*a9fa9459Szrj operand_check = check_warning;
10150*a9fa9459Szrj else if (strcasecmp (arg, "none") == 0)
10151*a9fa9459Szrj operand_check = check_none;
10152*a9fa9459Szrj else
10153*a9fa9459Szrj as_fatal (_("invalid -moperand-check= option: `%s'"), arg);
10154*a9fa9459Szrj break;
10155*a9fa9459Szrj
10156*a9fa9459Szrj case OPTION_MAVXSCALAR:
10157*a9fa9459Szrj if (strcasecmp (arg, "128") == 0)
10158*a9fa9459Szrj avxscalar = vex128;
10159*a9fa9459Szrj else if (strcasecmp (arg, "256") == 0)
10160*a9fa9459Szrj avxscalar = vex256;
10161*a9fa9459Szrj else
10162*a9fa9459Szrj as_fatal (_("invalid -mavxscalar= option: `%s'"), arg);
10163*a9fa9459Szrj break;
10164*a9fa9459Szrj
10165*a9fa9459Szrj case OPTION_MADD_BND_PREFIX:
10166*a9fa9459Szrj add_bnd_prefix = 1;
10167*a9fa9459Szrj break;
10168*a9fa9459Szrj
10169*a9fa9459Szrj case OPTION_MEVEXLIG:
10170*a9fa9459Szrj if (strcmp (arg, "128") == 0)
10171*a9fa9459Szrj evexlig = evexl128;
10172*a9fa9459Szrj else if (strcmp (arg, "256") == 0)
10173*a9fa9459Szrj evexlig = evexl256;
10174*a9fa9459Szrj else if (strcmp (arg, "512") == 0)
10175*a9fa9459Szrj evexlig = evexl512;
10176*a9fa9459Szrj else
10177*a9fa9459Szrj as_fatal (_("invalid -mevexlig= option: `%s'"), arg);
10178*a9fa9459Szrj break;
10179*a9fa9459Szrj
10180*a9fa9459Szrj case OPTION_MEVEXRCIG:
10181*a9fa9459Szrj if (strcmp (arg, "rne") == 0)
10182*a9fa9459Szrj evexrcig = rne;
10183*a9fa9459Szrj else if (strcmp (arg, "rd") == 0)
10184*a9fa9459Szrj evexrcig = rd;
10185*a9fa9459Szrj else if (strcmp (arg, "ru") == 0)
10186*a9fa9459Szrj evexrcig = ru;
10187*a9fa9459Szrj else if (strcmp (arg, "rz") == 0)
10188*a9fa9459Szrj evexrcig = rz;
10189*a9fa9459Szrj else
10190*a9fa9459Szrj as_fatal (_("invalid -mevexrcig= option: `%s'"), arg);
10191*a9fa9459Szrj break;
10192*a9fa9459Szrj
10193*a9fa9459Szrj case OPTION_MEVEXWIG:
10194*a9fa9459Szrj if (strcmp (arg, "0") == 0)
10195*a9fa9459Szrj evexwig = evexw0;
10196*a9fa9459Szrj else if (strcmp (arg, "1") == 0)
10197*a9fa9459Szrj evexwig = evexw1;
10198*a9fa9459Szrj else
10199*a9fa9459Szrj as_fatal (_("invalid -mevexwig= option: `%s'"), arg);
10200*a9fa9459Szrj break;
10201*a9fa9459Szrj
10202*a9fa9459Szrj # if defined (TE_PE) || defined (TE_PEP)
10203*a9fa9459Szrj case OPTION_MBIG_OBJ:
10204*a9fa9459Szrj use_big_obj = 1;
10205*a9fa9459Szrj break;
10206*a9fa9459Szrj #endif
10207*a9fa9459Szrj
10208*a9fa9459Szrj case OPTION_MOMIT_LOCK_PREFIX:
10209*a9fa9459Szrj if (strcasecmp (arg, "yes") == 0)
10210*a9fa9459Szrj omit_lock_prefix = 1;
10211*a9fa9459Szrj else if (strcasecmp (arg, "no") == 0)
10212*a9fa9459Szrj omit_lock_prefix = 0;
10213*a9fa9459Szrj else
10214*a9fa9459Szrj as_fatal (_("invalid -momit-lock-prefix= option: `%s'"), arg);
10215*a9fa9459Szrj break;
10216*a9fa9459Szrj
10217*a9fa9459Szrj case OPTION_MFENCE_AS_LOCK_ADD:
10218*a9fa9459Szrj if (strcasecmp (arg, "yes") == 0)
10219*a9fa9459Szrj avoid_fence = 1;
10220*a9fa9459Szrj else if (strcasecmp (arg, "no") == 0)
10221*a9fa9459Szrj avoid_fence = 0;
10222*a9fa9459Szrj else
10223*a9fa9459Szrj as_fatal (_("invalid -mfence-as-lock-add= option: `%s'"), arg);
10224*a9fa9459Szrj break;
10225*a9fa9459Szrj
10226*a9fa9459Szrj case OPTION_MRELAX_RELOCATIONS:
10227*a9fa9459Szrj if (strcasecmp (arg, "yes") == 0)
10228*a9fa9459Szrj generate_relax_relocations = 1;
10229*a9fa9459Szrj else if (strcasecmp (arg, "no") == 0)
10230*a9fa9459Szrj generate_relax_relocations = 0;
10231*a9fa9459Szrj else
10232*a9fa9459Szrj as_fatal (_("invalid -mrelax-relocations= option: `%s'"), arg);
10233*a9fa9459Szrj break;
10234*a9fa9459Szrj
10235*a9fa9459Szrj case OPTION_MAMD64:
10236*a9fa9459Szrj intel64 = 0;
10237*a9fa9459Szrj break;
10238*a9fa9459Szrj
10239*a9fa9459Szrj case OPTION_MINTEL64:
10240*a9fa9459Szrj intel64 = 1;
10241*a9fa9459Szrj break;
10242*a9fa9459Szrj
10243*a9fa9459Szrj default:
10244*a9fa9459Szrj return 0;
10245*a9fa9459Szrj }
10246*a9fa9459Szrj return 1;
10247*a9fa9459Szrj }
10248*a9fa9459Szrj
10249*a9fa9459Szrj #define MESSAGE_TEMPLATE \
10250*a9fa9459Szrj " "
10251*a9fa9459Szrj
10252*a9fa9459Szrj static char *
output_message(FILE * stream,char * p,char * message,char * start,int * left_p,const char * name,int len)10253*a9fa9459Szrj output_message (FILE *stream, char *p, char *message, char *start,
10254*a9fa9459Szrj int *left_p, const char *name, int len)
10255*a9fa9459Szrj {
10256*a9fa9459Szrj int size = sizeof (MESSAGE_TEMPLATE);
10257*a9fa9459Szrj int left = *left_p;
10258*a9fa9459Szrj
10259*a9fa9459Szrj /* Reserve 2 spaces for ", " or ",\0" */
10260*a9fa9459Szrj left -= len + 2;
10261*a9fa9459Szrj
10262*a9fa9459Szrj /* Check if there is any room. */
10263*a9fa9459Szrj if (left >= 0)
10264*a9fa9459Szrj {
10265*a9fa9459Szrj if (p != start)
10266*a9fa9459Szrj {
10267*a9fa9459Szrj *p++ = ',';
10268*a9fa9459Szrj *p++ = ' ';
10269*a9fa9459Szrj }
10270*a9fa9459Szrj p = mempcpy (p, name, len);
10271*a9fa9459Szrj }
10272*a9fa9459Szrj else
10273*a9fa9459Szrj {
10274*a9fa9459Szrj /* Output the current message now and start a new one. */
10275*a9fa9459Szrj *p++ = ',';
10276*a9fa9459Szrj *p = '\0';
10277*a9fa9459Szrj fprintf (stream, "%s\n", message);
10278*a9fa9459Szrj p = start;
10279*a9fa9459Szrj left = size - (start - message) - len - 2;
10280*a9fa9459Szrj
10281*a9fa9459Szrj gas_assert (left >= 0);
10282*a9fa9459Szrj
10283*a9fa9459Szrj p = mempcpy (p, name, len);
10284*a9fa9459Szrj }
10285*a9fa9459Szrj
10286*a9fa9459Szrj *left_p = left;
10287*a9fa9459Szrj return p;
10288*a9fa9459Szrj }
10289*a9fa9459Szrj
10290*a9fa9459Szrj static void
show_arch(FILE * stream,int ext,int check)10291*a9fa9459Szrj show_arch (FILE *stream, int ext, int check)
10292*a9fa9459Szrj {
10293*a9fa9459Szrj static char message[] = MESSAGE_TEMPLATE;
10294*a9fa9459Szrj char *start = message + 27;
10295*a9fa9459Szrj char *p;
10296*a9fa9459Szrj int size = sizeof (MESSAGE_TEMPLATE);
10297*a9fa9459Szrj int left;
10298*a9fa9459Szrj const char *name;
10299*a9fa9459Szrj int len;
10300*a9fa9459Szrj unsigned int j;
10301*a9fa9459Szrj
10302*a9fa9459Szrj p = start;
10303*a9fa9459Szrj left = size - (start - message);
10304*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_arch); j++)
10305*a9fa9459Szrj {
10306*a9fa9459Szrj /* Should it be skipped? */
10307*a9fa9459Szrj if (cpu_arch [j].skip)
10308*a9fa9459Szrj continue;
10309*a9fa9459Szrj
10310*a9fa9459Szrj name = cpu_arch [j].name;
10311*a9fa9459Szrj len = cpu_arch [j].len;
10312*a9fa9459Szrj if (*name == '.')
10313*a9fa9459Szrj {
10314*a9fa9459Szrj /* It is an extension. Skip if we aren't asked to show it. */
10315*a9fa9459Szrj if (ext)
10316*a9fa9459Szrj {
10317*a9fa9459Szrj name++;
10318*a9fa9459Szrj len--;
10319*a9fa9459Szrj }
10320*a9fa9459Szrj else
10321*a9fa9459Szrj continue;
10322*a9fa9459Szrj }
10323*a9fa9459Szrj else if (ext)
10324*a9fa9459Szrj {
10325*a9fa9459Szrj /* It is an processor. Skip if we show only extension. */
10326*a9fa9459Szrj continue;
10327*a9fa9459Szrj }
10328*a9fa9459Szrj else if (check && ! cpu_arch[j].flags.bitfield.cpui386)
10329*a9fa9459Szrj {
10330*a9fa9459Szrj /* It is an impossible processor - skip. */
10331*a9fa9459Szrj continue;
10332*a9fa9459Szrj }
10333*a9fa9459Szrj
10334*a9fa9459Szrj p = output_message (stream, p, message, start, &left, name, len);
10335*a9fa9459Szrj }
10336*a9fa9459Szrj
10337*a9fa9459Szrj /* Display disabled extensions. */
10338*a9fa9459Szrj if (ext)
10339*a9fa9459Szrj for (j = 0; j < ARRAY_SIZE (cpu_noarch); j++)
10340*a9fa9459Szrj {
10341*a9fa9459Szrj name = cpu_noarch [j].name;
10342*a9fa9459Szrj len = cpu_noarch [j].len;
10343*a9fa9459Szrj p = output_message (stream, p, message, start, &left, name,
10344*a9fa9459Szrj len);
10345*a9fa9459Szrj }
10346*a9fa9459Szrj
10347*a9fa9459Szrj *p = '\0';
10348*a9fa9459Szrj fprintf (stream, "%s\n", message);
10349*a9fa9459Szrj }
10350*a9fa9459Szrj
10351*a9fa9459Szrj void
md_show_usage(FILE * stream)10352*a9fa9459Szrj md_show_usage (FILE *stream)
10353*a9fa9459Szrj {
10354*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
10355*a9fa9459Szrj fprintf (stream, _("\
10356*a9fa9459Szrj -Q ignored\n\
10357*a9fa9459Szrj -V print assembler version number\n\
10358*a9fa9459Szrj -k ignored\n"));
10359*a9fa9459Szrj #endif
10360*a9fa9459Szrj fprintf (stream, _("\
10361*a9fa9459Szrj -n Do not optimize code alignment\n\
10362*a9fa9459Szrj -q quieten some warnings\n"));
10363*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
10364*a9fa9459Szrj fprintf (stream, _("\
10365*a9fa9459Szrj -s ignored\n"));
10366*a9fa9459Szrj #endif
10367*a9fa9459Szrj #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
10368*a9fa9459Szrj || defined (TE_PE) || defined (TE_PEP))
10369*a9fa9459Szrj fprintf (stream, _("\
10370*a9fa9459Szrj --32/--64/--x32 generate 32bit/64bit/x32 code\n"));
10371*a9fa9459Szrj #endif
10372*a9fa9459Szrj #ifdef SVR4_COMMENT_CHARS
10373*a9fa9459Szrj fprintf (stream, _("\
10374*a9fa9459Szrj --divide do not treat `/' as a comment character\n"));
10375*a9fa9459Szrj #else
10376*a9fa9459Szrj fprintf (stream, _("\
10377*a9fa9459Szrj --divide ignored\n"));
10378*a9fa9459Szrj #endif
10379*a9fa9459Szrj fprintf (stream, _("\
10380*a9fa9459Szrj -march=CPU[,+EXTENSION...]\n\
10381*a9fa9459Szrj generate code for CPU and EXTENSION, CPU is one of:\n"));
10382*a9fa9459Szrj show_arch (stream, 0, 1);
10383*a9fa9459Szrj fprintf (stream, _("\
10384*a9fa9459Szrj EXTENSION is combination of:\n"));
10385*a9fa9459Szrj show_arch (stream, 1, 0);
10386*a9fa9459Szrj fprintf (stream, _("\
10387*a9fa9459Szrj -mtune=CPU optimize for CPU, CPU is one of:\n"));
10388*a9fa9459Szrj show_arch (stream, 0, 0);
10389*a9fa9459Szrj fprintf (stream, _("\
10390*a9fa9459Szrj -msse2avx encode SSE instructions with VEX prefix\n"));
10391*a9fa9459Szrj fprintf (stream, _("\
10392*a9fa9459Szrj -msse-check=[none|error|warning]\n\
10393*a9fa9459Szrj check SSE instructions\n"));
10394*a9fa9459Szrj fprintf (stream, _("\
10395*a9fa9459Szrj -moperand-check=[none|error|warning]\n\
10396*a9fa9459Szrj check operand combinations for validity\n"));
10397*a9fa9459Szrj fprintf (stream, _("\
10398*a9fa9459Szrj -mavxscalar=[128|256] encode scalar AVX instructions with specific vector\n\
10399*a9fa9459Szrj length\n"));
10400*a9fa9459Szrj fprintf (stream, _("\
10401*a9fa9459Szrj -mevexlig=[128|256|512] encode scalar EVEX instructions with specific vector\n\
10402*a9fa9459Szrj length\n"));
10403*a9fa9459Szrj fprintf (stream, _("\
10404*a9fa9459Szrj -mevexwig=[0|1] encode EVEX instructions with specific EVEX.W value\n\
10405*a9fa9459Szrj for EVEX.W bit ignored instructions\n"));
10406*a9fa9459Szrj fprintf (stream, _("\
10407*a9fa9459Szrj -mevexrcig=[rne|rd|ru|rz]\n\
10408*a9fa9459Szrj encode EVEX instructions with specific EVEX.RC value\n\
10409*a9fa9459Szrj for SAE-only ignored instructions\n"));
10410*a9fa9459Szrj fprintf (stream, _("\
10411*a9fa9459Szrj -mmnemonic=[att|intel] use AT&T/Intel mnemonic\n"));
10412*a9fa9459Szrj fprintf (stream, _("\
10413*a9fa9459Szrj -msyntax=[att|intel] use AT&T/Intel syntax\n"));
10414*a9fa9459Szrj fprintf (stream, _("\
10415*a9fa9459Szrj -mindex-reg support pseudo index registers\n"));
10416*a9fa9459Szrj fprintf (stream, _("\
10417*a9fa9459Szrj -mnaked-reg don't require `%%' prefix for registers\n"));
10418*a9fa9459Szrj fprintf (stream, _("\
10419*a9fa9459Szrj -mold-gcc support old (<= 2.8.1) versions of gcc\n"));
10420*a9fa9459Szrj fprintf (stream, _("\
10421*a9fa9459Szrj -madd-bnd-prefix add BND prefix for all valid branches\n"));
10422*a9fa9459Szrj fprintf (stream, _("\
10423*a9fa9459Szrj -mshared disable branch optimization for shared code\n"));
10424*a9fa9459Szrj # if defined (TE_PE) || defined (TE_PEP)
10425*a9fa9459Szrj fprintf (stream, _("\
10426*a9fa9459Szrj -mbig-obj generate big object files\n"));
10427*a9fa9459Szrj #endif
10428*a9fa9459Szrj fprintf (stream, _("\
10429*a9fa9459Szrj -momit-lock-prefix=[no|yes]\n\
10430*a9fa9459Szrj strip all lock prefixes\n"));
10431*a9fa9459Szrj fprintf (stream, _("\
10432*a9fa9459Szrj -mfence-as-lock-add=[no|yes]\n\
10433*a9fa9459Szrj encode lfence, mfence and sfence as\n\
10434*a9fa9459Szrj lock addl $0x0, (%%{re}sp)\n"));
10435*a9fa9459Szrj fprintf (stream, _("\
10436*a9fa9459Szrj -mrelax-relocations=[no|yes]\n\
10437*a9fa9459Szrj generate relax relocations\n"));
10438*a9fa9459Szrj fprintf (stream, _("\
10439*a9fa9459Szrj -mamd64 accept only AMD64 ISA\n"));
10440*a9fa9459Szrj fprintf (stream, _("\
10441*a9fa9459Szrj -mintel64 accept only Intel64 ISA\n"));
10442*a9fa9459Szrj }
10443*a9fa9459Szrj
10444*a9fa9459Szrj #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
10445*a9fa9459Szrj || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
10446*a9fa9459Szrj || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
10447*a9fa9459Szrj
10448*a9fa9459Szrj /* Pick the target format to use. */
10449*a9fa9459Szrj
10450*a9fa9459Szrj const char *
i386_target_format(void)10451*a9fa9459Szrj i386_target_format (void)
10452*a9fa9459Szrj {
10453*a9fa9459Szrj if (!strncmp (default_arch, "x86_64", 6))
10454*a9fa9459Szrj {
10455*a9fa9459Szrj update_code_flag (CODE_64BIT, 1);
10456*a9fa9459Szrj if (default_arch[6] == '\0')
10457*a9fa9459Szrj x86_elf_abi = X86_64_ABI;
10458*a9fa9459Szrj else
10459*a9fa9459Szrj x86_elf_abi = X86_64_X32_ABI;
10460*a9fa9459Szrj }
10461*a9fa9459Szrj else if (!strcmp (default_arch, "i386"))
10462*a9fa9459Szrj update_code_flag (CODE_32BIT, 1);
10463*a9fa9459Szrj else if (!strcmp (default_arch, "iamcu"))
10464*a9fa9459Szrj {
10465*a9fa9459Szrj update_code_flag (CODE_32BIT, 1);
10466*a9fa9459Szrj if (cpu_arch_isa == PROCESSOR_UNKNOWN)
10467*a9fa9459Szrj {
10468*a9fa9459Szrj static const i386_cpu_flags iamcu_flags = CPU_IAMCU_FLAGS;
10469*a9fa9459Szrj cpu_arch_name = "iamcu";
10470*a9fa9459Szrj cpu_sub_arch_name = NULL;
10471*a9fa9459Szrj cpu_arch_flags = iamcu_flags;
10472*a9fa9459Szrj cpu_arch_isa = PROCESSOR_IAMCU;
10473*a9fa9459Szrj cpu_arch_isa_flags = iamcu_flags;
10474*a9fa9459Szrj if (!cpu_arch_tune_set)
10475*a9fa9459Szrj {
10476*a9fa9459Szrj cpu_arch_tune = cpu_arch_isa;
10477*a9fa9459Szrj cpu_arch_tune_flags = cpu_arch_isa_flags;
10478*a9fa9459Szrj }
10479*a9fa9459Szrj }
10480*a9fa9459Szrj else
10481*a9fa9459Szrj as_fatal (_("Intel MCU doesn't support `%s' architecture"),
10482*a9fa9459Szrj cpu_arch_name);
10483*a9fa9459Szrj }
10484*a9fa9459Szrj else
10485*a9fa9459Szrj as_fatal (_("unknown architecture"));
10486*a9fa9459Szrj
10487*a9fa9459Szrj if (cpu_flags_all_zero (&cpu_arch_isa_flags))
10488*a9fa9459Szrj cpu_arch_isa_flags = cpu_arch[flag_code == CODE_64BIT].flags;
10489*a9fa9459Szrj if (cpu_flags_all_zero (&cpu_arch_tune_flags))
10490*a9fa9459Szrj cpu_arch_tune_flags = cpu_arch[flag_code == CODE_64BIT].flags;
10491*a9fa9459Szrj
10492*a9fa9459Szrj switch (OUTPUT_FLAVOR)
10493*a9fa9459Szrj {
10494*a9fa9459Szrj #if defined (OBJ_MAYBE_AOUT) || defined (OBJ_AOUT)
10495*a9fa9459Szrj case bfd_target_aout_flavour:
10496*a9fa9459Szrj return AOUT_TARGET_FORMAT;
10497*a9fa9459Szrj #endif
10498*a9fa9459Szrj #if defined (OBJ_MAYBE_COFF) || defined (OBJ_COFF)
10499*a9fa9459Szrj # if defined (TE_PE) || defined (TE_PEP)
10500*a9fa9459Szrj case bfd_target_coff_flavour:
10501*a9fa9459Szrj if (flag_code == CODE_64BIT)
10502*a9fa9459Szrj return use_big_obj ? "pe-bigobj-x86-64" : "pe-x86-64";
10503*a9fa9459Szrj else
10504*a9fa9459Szrj return "pe-i386";
10505*a9fa9459Szrj # elif defined (TE_GO32)
10506*a9fa9459Szrj case bfd_target_coff_flavour:
10507*a9fa9459Szrj return "coff-go32";
10508*a9fa9459Szrj # else
10509*a9fa9459Szrj case bfd_target_coff_flavour:
10510*a9fa9459Szrj return "coff-i386";
10511*a9fa9459Szrj # endif
10512*a9fa9459Szrj #endif
10513*a9fa9459Szrj #if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
10514*a9fa9459Szrj case bfd_target_elf_flavour:
10515*a9fa9459Szrj {
10516*a9fa9459Szrj const char *format;
10517*a9fa9459Szrj
10518*a9fa9459Szrj switch (x86_elf_abi)
10519*a9fa9459Szrj {
10520*a9fa9459Szrj default:
10521*a9fa9459Szrj format = ELF_TARGET_FORMAT;
10522*a9fa9459Szrj break;
10523*a9fa9459Szrj case X86_64_ABI:
10524*a9fa9459Szrj use_rela_relocations = 1;
10525*a9fa9459Szrj object_64bit = 1;
10526*a9fa9459Szrj format = ELF_TARGET_FORMAT64;
10527*a9fa9459Szrj break;
10528*a9fa9459Szrj case X86_64_X32_ABI:
10529*a9fa9459Szrj use_rela_relocations = 1;
10530*a9fa9459Szrj object_64bit = 1;
10531*a9fa9459Szrj disallow_64bit_reloc = 1;
10532*a9fa9459Szrj format = ELF_TARGET_FORMAT32;
10533*a9fa9459Szrj break;
10534*a9fa9459Szrj }
10535*a9fa9459Szrj if (cpu_arch_isa == PROCESSOR_L1OM)
10536*a9fa9459Szrj {
10537*a9fa9459Szrj if (x86_elf_abi != X86_64_ABI)
10538*a9fa9459Szrj as_fatal (_("Intel L1OM is 64bit only"));
10539*a9fa9459Szrj return ELF_TARGET_L1OM_FORMAT;
10540*a9fa9459Szrj }
10541*a9fa9459Szrj else if (cpu_arch_isa == PROCESSOR_K1OM)
10542*a9fa9459Szrj {
10543*a9fa9459Szrj if (x86_elf_abi != X86_64_ABI)
10544*a9fa9459Szrj as_fatal (_("Intel K1OM is 64bit only"));
10545*a9fa9459Szrj return ELF_TARGET_K1OM_FORMAT;
10546*a9fa9459Szrj }
10547*a9fa9459Szrj else if (cpu_arch_isa == PROCESSOR_IAMCU)
10548*a9fa9459Szrj {
10549*a9fa9459Szrj if (x86_elf_abi != I386_ABI)
10550*a9fa9459Szrj as_fatal (_("Intel MCU is 32bit only"));
10551*a9fa9459Szrj return ELF_TARGET_IAMCU_FORMAT;
10552*a9fa9459Szrj }
10553*a9fa9459Szrj else
10554*a9fa9459Szrj return format;
10555*a9fa9459Szrj }
10556*a9fa9459Szrj #endif
10557*a9fa9459Szrj #if defined (OBJ_MACH_O)
10558*a9fa9459Szrj case bfd_target_mach_o_flavour:
10559*a9fa9459Szrj if (flag_code == CODE_64BIT)
10560*a9fa9459Szrj {
10561*a9fa9459Szrj use_rela_relocations = 1;
10562*a9fa9459Szrj object_64bit = 1;
10563*a9fa9459Szrj return "mach-o-x86-64";
10564*a9fa9459Szrj }
10565*a9fa9459Szrj else
10566*a9fa9459Szrj return "mach-o-i386";
10567*a9fa9459Szrj #endif
10568*a9fa9459Szrj default:
10569*a9fa9459Szrj abort ();
10570*a9fa9459Szrj return NULL;
10571*a9fa9459Szrj }
10572*a9fa9459Szrj }
10573*a9fa9459Szrj
10574*a9fa9459Szrj #endif /* OBJ_MAYBE_ more than one */
10575*a9fa9459Szrj
10576*a9fa9459Szrj symbolS *
md_undefined_symbol(char * name)10577*a9fa9459Szrj md_undefined_symbol (char *name)
10578*a9fa9459Szrj {
10579*a9fa9459Szrj if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0]
10580*a9fa9459Szrj && name[1] == GLOBAL_OFFSET_TABLE_NAME[1]
10581*a9fa9459Szrj && name[2] == GLOBAL_OFFSET_TABLE_NAME[2]
10582*a9fa9459Szrj && strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)
10583*a9fa9459Szrj {
10584*a9fa9459Szrj if (!GOT_symbol)
10585*a9fa9459Szrj {
10586*a9fa9459Szrj if (symbol_find (name))
10587*a9fa9459Szrj as_bad (_("GOT already in symbol table"));
10588*a9fa9459Szrj GOT_symbol = symbol_new (name, undefined_section,
10589*a9fa9459Szrj (valueT) 0, &zero_address_frag);
10590*a9fa9459Szrj };
10591*a9fa9459Szrj return GOT_symbol;
10592*a9fa9459Szrj }
10593*a9fa9459Szrj return 0;
10594*a9fa9459Szrj }
10595*a9fa9459Szrj
10596*a9fa9459Szrj /* Round up a section size to the appropriate boundary. */
10597*a9fa9459Szrj
10598*a9fa9459Szrj valueT
md_section_align(segT segment ATTRIBUTE_UNUSED,valueT size)10599*a9fa9459Szrj md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
10600*a9fa9459Szrj {
10601*a9fa9459Szrj #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
10602*a9fa9459Szrj if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
10603*a9fa9459Szrj {
10604*a9fa9459Szrj /* For a.out, force the section size to be aligned. If we don't do
10605*a9fa9459Szrj this, BFD will align it for us, but it will not write out the
10606*a9fa9459Szrj final bytes of the section. This may be a bug in BFD, but it is
10607*a9fa9459Szrj easier to fix it here since that is how the other a.out targets
10608*a9fa9459Szrj work. */
10609*a9fa9459Szrj int align;
10610*a9fa9459Szrj
10611*a9fa9459Szrj align = bfd_get_section_alignment (stdoutput, segment);
10612*a9fa9459Szrj size = ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
10613*a9fa9459Szrj }
10614*a9fa9459Szrj #endif
10615*a9fa9459Szrj
10616*a9fa9459Szrj return size;
10617*a9fa9459Szrj }
10618*a9fa9459Szrj
10619*a9fa9459Szrj /* On the i386, PC-relative offsets are relative to the start of the
10620*a9fa9459Szrj next instruction. That is, the address of the offset, plus its
10621*a9fa9459Szrj size, since the offset is always the last part of the insn. */
10622*a9fa9459Szrj
10623*a9fa9459Szrj long
md_pcrel_from(fixS * fixP)10624*a9fa9459Szrj md_pcrel_from (fixS *fixP)
10625*a9fa9459Szrj {
10626*a9fa9459Szrj return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
10627*a9fa9459Szrj }
10628*a9fa9459Szrj
10629*a9fa9459Szrj #ifndef I386COFF
10630*a9fa9459Szrj
10631*a9fa9459Szrj static void
s_bss(int ignore ATTRIBUTE_UNUSED)10632*a9fa9459Szrj s_bss (int ignore ATTRIBUTE_UNUSED)
10633*a9fa9459Szrj {
10634*a9fa9459Szrj int temp;
10635*a9fa9459Szrj
10636*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
10637*a9fa9459Szrj if (IS_ELF)
10638*a9fa9459Szrj obj_elf_section_change_hook ();
10639*a9fa9459Szrj #endif
10640*a9fa9459Szrj temp = get_absolute_expression ();
10641*a9fa9459Szrj subseg_set (bss_section, (subsegT) temp);
10642*a9fa9459Szrj demand_empty_rest_of_line ();
10643*a9fa9459Szrj }
10644*a9fa9459Szrj
10645*a9fa9459Szrj #endif
10646*a9fa9459Szrj
10647*a9fa9459Szrj void
i386_validate_fix(fixS * fixp)10648*a9fa9459Szrj i386_validate_fix (fixS *fixp)
10649*a9fa9459Szrj {
10650*a9fa9459Szrj if (fixp->fx_subsy)
10651*a9fa9459Szrj {
10652*a9fa9459Szrj if (fixp->fx_subsy == GOT_symbol)
10653*a9fa9459Szrj {
10654*a9fa9459Szrj if (fixp->fx_r_type == BFD_RELOC_32_PCREL)
10655*a9fa9459Szrj {
10656*a9fa9459Szrj if (!object_64bit)
10657*a9fa9459Szrj abort ();
10658*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
10659*a9fa9459Szrj if (fixp->fx_tcbit2)
10660*a9fa9459Szrj fixp->fx_r_type = (fixp->fx_tcbit
10661*a9fa9459Szrj ? BFD_RELOC_X86_64_REX_GOTPCRELX
10662*a9fa9459Szrj : BFD_RELOC_X86_64_GOTPCRELX);
10663*a9fa9459Szrj else
10664*a9fa9459Szrj #endif
10665*a9fa9459Szrj fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL;
10666*a9fa9459Szrj }
10667*a9fa9459Szrj else
10668*a9fa9459Szrj {
10669*a9fa9459Szrj if (!object_64bit)
10670*a9fa9459Szrj fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
10671*a9fa9459Szrj else
10672*a9fa9459Szrj fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64;
10673*a9fa9459Szrj }
10674*a9fa9459Szrj fixp->fx_subsy = 0;
10675*a9fa9459Szrj }
10676*a9fa9459Szrj }
10677*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
10678*a9fa9459Szrj else if (!object_64bit)
10679*a9fa9459Szrj {
10680*a9fa9459Szrj if (fixp->fx_r_type == BFD_RELOC_386_GOT32
10681*a9fa9459Szrj && fixp->fx_tcbit2)
10682*a9fa9459Szrj fixp->fx_r_type = BFD_RELOC_386_GOT32X;
10683*a9fa9459Szrj }
10684*a9fa9459Szrj #endif
10685*a9fa9459Szrj }
10686*a9fa9459Szrj
10687*a9fa9459Szrj arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixp)10688*a9fa9459Szrj tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
10689*a9fa9459Szrj {
10690*a9fa9459Szrj arelent *rel;
10691*a9fa9459Szrj bfd_reloc_code_real_type code;
10692*a9fa9459Szrj
10693*a9fa9459Szrj switch (fixp->fx_r_type)
10694*a9fa9459Szrj {
10695*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
10696*a9fa9459Szrj case BFD_RELOC_SIZE32:
10697*a9fa9459Szrj case BFD_RELOC_SIZE64:
10698*a9fa9459Szrj if (S_IS_DEFINED (fixp->fx_addsy)
10699*a9fa9459Szrj && !S_IS_EXTERNAL (fixp->fx_addsy))
10700*a9fa9459Szrj {
10701*a9fa9459Szrj /* Resolve size relocation against local symbol to size of
10702*a9fa9459Szrj the symbol plus addend. */
10703*a9fa9459Szrj valueT value = S_GET_SIZE (fixp->fx_addsy) + fixp->fx_offset;
10704*a9fa9459Szrj if (fixp->fx_r_type == BFD_RELOC_SIZE32
10705*a9fa9459Szrj && !fits_in_unsigned_long (value))
10706*a9fa9459Szrj as_bad_where (fixp->fx_file, fixp->fx_line,
10707*a9fa9459Szrj _("symbol size computation overflow"));
10708*a9fa9459Szrj fixp->fx_addsy = NULL;
10709*a9fa9459Szrj fixp->fx_subsy = NULL;
10710*a9fa9459Szrj md_apply_fix (fixp, (valueT *) &value, NULL);
10711*a9fa9459Szrj return NULL;
10712*a9fa9459Szrj }
10713*a9fa9459Szrj #endif
10714*a9fa9459Szrj
10715*a9fa9459Szrj case BFD_RELOC_X86_64_PLT32:
10716*a9fa9459Szrj case BFD_RELOC_X86_64_GOT32:
10717*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCREL:
10718*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCRELX:
10719*a9fa9459Szrj case BFD_RELOC_X86_64_REX_GOTPCRELX:
10720*a9fa9459Szrj case BFD_RELOC_386_PLT32:
10721*a9fa9459Szrj case BFD_RELOC_386_GOT32:
10722*a9fa9459Szrj case BFD_RELOC_386_GOT32X:
10723*a9fa9459Szrj case BFD_RELOC_386_GOTOFF:
10724*a9fa9459Szrj case BFD_RELOC_386_GOTPC:
10725*a9fa9459Szrj case BFD_RELOC_386_TLS_GD:
10726*a9fa9459Szrj case BFD_RELOC_386_TLS_LDM:
10727*a9fa9459Szrj case BFD_RELOC_386_TLS_LDO_32:
10728*a9fa9459Szrj case BFD_RELOC_386_TLS_IE_32:
10729*a9fa9459Szrj case BFD_RELOC_386_TLS_IE:
10730*a9fa9459Szrj case BFD_RELOC_386_TLS_GOTIE:
10731*a9fa9459Szrj case BFD_RELOC_386_TLS_LE_32:
10732*a9fa9459Szrj case BFD_RELOC_386_TLS_LE:
10733*a9fa9459Szrj case BFD_RELOC_386_TLS_GOTDESC:
10734*a9fa9459Szrj case BFD_RELOC_386_TLS_DESC_CALL:
10735*a9fa9459Szrj case BFD_RELOC_X86_64_TLSGD:
10736*a9fa9459Szrj case BFD_RELOC_X86_64_TLSLD:
10737*a9fa9459Szrj case BFD_RELOC_X86_64_DTPOFF32:
10738*a9fa9459Szrj case BFD_RELOC_X86_64_DTPOFF64:
10739*a9fa9459Szrj case BFD_RELOC_X86_64_GOTTPOFF:
10740*a9fa9459Szrj case BFD_RELOC_X86_64_TPOFF32:
10741*a9fa9459Szrj case BFD_RELOC_X86_64_TPOFF64:
10742*a9fa9459Szrj case BFD_RELOC_X86_64_GOTOFF64:
10743*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC32:
10744*a9fa9459Szrj case BFD_RELOC_X86_64_GOT64:
10745*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCREL64:
10746*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC64:
10747*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPLT64:
10748*a9fa9459Szrj case BFD_RELOC_X86_64_PLTOFF64:
10749*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
10750*a9fa9459Szrj case BFD_RELOC_X86_64_TLSDESC_CALL:
10751*a9fa9459Szrj case BFD_RELOC_RVA:
10752*a9fa9459Szrj case BFD_RELOC_VTABLE_ENTRY:
10753*a9fa9459Szrj case BFD_RELOC_VTABLE_INHERIT:
10754*a9fa9459Szrj #ifdef TE_PE
10755*a9fa9459Szrj case BFD_RELOC_32_SECREL:
10756*a9fa9459Szrj #endif
10757*a9fa9459Szrj code = fixp->fx_r_type;
10758*a9fa9459Szrj break;
10759*a9fa9459Szrj case BFD_RELOC_X86_64_32S:
10760*a9fa9459Szrj if (!fixp->fx_pcrel)
10761*a9fa9459Szrj {
10762*a9fa9459Szrj /* Don't turn BFD_RELOC_X86_64_32S into BFD_RELOC_32. */
10763*a9fa9459Szrj code = fixp->fx_r_type;
10764*a9fa9459Szrj break;
10765*a9fa9459Szrj }
10766*a9fa9459Szrj default:
10767*a9fa9459Szrj if (fixp->fx_pcrel)
10768*a9fa9459Szrj {
10769*a9fa9459Szrj switch (fixp->fx_size)
10770*a9fa9459Szrj {
10771*a9fa9459Szrj default:
10772*a9fa9459Szrj as_bad_where (fixp->fx_file, fixp->fx_line,
10773*a9fa9459Szrj _("can not do %d byte pc-relative relocation"),
10774*a9fa9459Szrj fixp->fx_size);
10775*a9fa9459Szrj code = BFD_RELOC_32_PCREL;
10776*a9fa9459Szrj break;
10777*a9fa9459Szrj case 1: code = BFD_RELOC_8_PCREL; break;
10778*a9fa9459Szrj case 2: code = BFD_RELOC_16_PCREL; break;
10779*a9fa9459Szrj case 4: code = BFD_RELOC_32_PCREL; break;
10780*a9fa9459Szrj #ifdef BFD64
10781*a9fa9459Szrj case 8: code = BFD_RELOC_64_PCREL; break;
10782*a9fa9459Szrj #endif
10783*a9fa9459Szrj }
10784*a9fa9459Szrj }
10785*a9fa9459Szrj else
10786*a9fa9459Szrj {
10787*a9fa9459Szrj switch (fixp->fx_size)
10788*a9fa9459Szrj {
10789*a9fa9459Szrj default:
10790*a9fa9459Szrj as_bad_where (fixp->fx_file, fixp->fx_line,
10791*a9fa9459Szrj _("can not do %d byte relocation"),
10792*a9fa9459Szrj fixp->fx_size);
10793*a9fa9459Szrj code = BFD_RELOC_32;
10794*a9fa9459Szrj break;
10795*a9fa9459Szrj case 1: code = BFD_RELOC_8; break;
10796*a9fa9459Szrj case 2: code = BFD_RELOC_16; break;
10797*a9fa9459Szrj case 4: code = BFD_RELOC_32; break;
10798*a9fa9459Szrj #ifdef BFD64
10799*a9fa9459Szrj case 8: code = BFD_RELOC_64; break;
10800*a9fa9459Szrj #endif
10801*a9fa9459Szrj }
10802*a9fa9459Szrj }
10803*a9fa9459Szrj break;
10804*a9fa9459Szrj }
10805*a9fa9459Szrj
10806*a9fa9459Szrj if ((code == BFD_RELOC_32
10807*a9fa9459Szrj || code == BFD_RELOC_32_PCREL
10808*a9fa9459Szrj || code == BFD_RELOC_X86_64_32S)
10809*a9fa9459Szrj && GOT_symbol
10810*a9fa9459Szrj && fixp->fx_addsy == GOT_symbol)
10811*a9fa9459Szrj {
10812*a9fa9459Szrj if (!object_64bit)
10813*a9fa9459Szrj code = BFD_RELOC_386_GOTPC;
10814*a9fa9459Szrj else
10815*a9fa9459Szrj code = BFD_RELOC_X86_64_GOTPC32;
10816*a9fa9459Szrj }
10817*a9fa9459Szrj if ((code == BFD_RELOC_64 || code == BFD_RELOC_64_PCREL)
10818*a9fa9459Szrj && GOT_symbol
10819*a9fa9459Szrj && fixp->fx_addsy == GOT_symbol)
10820*a9fa9459Szrj {
10821*a9fa9459Szrj code = BFD_RELOC_X86_64_GOTPC64;
10822*a9fa9459Szrj }
10823*a9fa9459Szrj
10824*a9fa9459Szrj rel = XNEW (arelent);
10825*a9fa9459Szrj rel->sym_ptr_ptr = XNEW (asymbol *);
10826*a9fa9459Szrj *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
10827*a9fa9459Szrj
10828*a9fa9459Szrj rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
10829*a9fa9459Szrj
10830*a9fa9459Szrj if (!use_rela_relocations)
10831*a9fa9459Szrj {
10832*a9fa9459Szrj /* HACK: Since i386 ELF uses Rel instead of Rela, encode the
10833*a9fa9459Szrj vtable entry to be used in the relocation's section offset. */
10834*a9fa9459Szrj if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
10835*a9fa9459Szrj rel->address = fixp->fx_offset;
10836*a9fa9459Szrj #if defined (OBJ_COFF) && defined (TE_PE)
10837*a9fa9459Szrj else if (fixp->fx_addsy && S_IS_WEAK (fixp->fx_addsy))
10838*a9fa9459Szrj rel->addend = fixp->fx_addnumber - (S_GET_VALUE (fixp->fx_addsy) * 2);
10839*a9fa9459Szrj else
10840*a9fa9459Szrj #endif
10841*a9fa9459Szrj rel->addend = 0;
10842*a9fa9459Szrj }
10843*a9fa9459Szrj /* Use the rela in 64bit mode. */
10844*a9fa9459Szrj else
10845*a9fa9459Szrj {
10846*a9fa9459Szrj if (disallow_64bit_reloc)
10847*a9fa9459Szrj switch (code)
10848*a9fa9459Szrj {
10849*a9fa9459Szrj case BFD_RELOC_X86_64_DTPOFF64:
10850*a9fa9459Szrj case BFD_RELOC_X86_64_TPOFF64:
10851*a9fa9459Szrj case BFD_RELOC_64_PCREL:
10852*a9fa9459Szrj case BFD_RELOC_X86_64_GOTOFF64:
10853*a9fa9459Szrj case BFD_RELOC_X86_64_GOT64:
10854*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCREL64:
10855*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC64:
10856*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPLT64:
10857*a9fa9459Szrj case BFD_RELOC_X86_64_PLTOFF64:
10858*a9fa9459Szrj as_bad_where (fixp->fx_file, fixp->fx_line,
10859*a9fa9459Szrj _("cannot represent relocation type %s in x32 mode"),
10860*a9fa9459Szrj bfd_get_reloc_code_name (code));
10861*a9fa9459Szrj break;
10862*a9fa9459Szrj default:
10863*a9fa9459Szrj break;
10864*a9fa9459Szrj }
10865*a9fa9459Szrj
10866*a9fa9459Szrj if (!fixp->fx_pcrel)
10867*a9fa9459Szrj rel->addend = fixp->fx_offset;
10868*a9fa9459Szrj else
10869*a9fa9459Szrj switch (code)
10870*a9fa9459Szrj {
10871*a9fa9459Szrj case BFD_RELOC_X86_64_PLT32:
10872*a9fa9459Szrj case BFD_RELOC_X86_64_GOT32:
10873*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCREL:
10874*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPCRELX:
10875*a9fa9459Szrj case BFD_RELOC_X86_64_REX_GOTPCRELX:
10876*a9fa9459Szrj case BFD_RELOC_X86_64_TLSGD:
10877*a9fa9459Szrj case BFD_RELOC_X86_64_TLSLD:
10878*a9fa9459Szrj case BFD_RELOC_X86_64_GOTTPOFF:
10879*a9fa9459Szrj case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
10880*a9fa9459Szrj case BFD_RELOC_X86_64_TLSDESC_CALL:
10881*a9fa9459Szrj rel->addend = fixp->fx_offset - fixp->fx_size;
10882*a9fa9459Szrj break;
10883*a9fa9459Szrj default:
10884*a9fa9459Szrj rel->addend = (section->vma
10885*a9fa9459Szrj - fixp->fx_size
10886*a9fa9459Szrj + fixp->fx_addnumber
10887*a9fa9459Szrj + md_pcrel_from (fixp));
10888*a9fa9459Szrj break;
10889*a9fa9459Szrj }
10890*a9fa9459Szrj }
10891*a9fa9459Szrj
10892*a9fa9459Szrj rel->howto = bfd_reloc_type_lookup (stdoutput, code);
10893*a9fa9459Szrj if (rel->howto == NULL)
10894*a9fa9459Szrj {
10895*a9fa9459Szrj as_bad_where (fixp->fx_file, fixp->fx_line,
10896*a9fa9459Szrj _("cannot represent relocation type %s"),
10897*a9fa9459Szrj bfd_get_reloc_code_name (code));
10898*a9fa9459Szrj /* Set howto to a garbage value so that we can keep going. */
10899*a9fa9459Szrj rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
10900*a9fa9459Szrj gas_assert (rel->howto != NULL);
10901*a9fa9459Szrj }
10902*a9fa9459Szrj
10903*a9fa9459Szrj return rel;
10904*a9fa9459Szrj }
10905*a9fa9459Szrj
10906*a9fa9459Szrj #include "tc-i386-intel.c"
10907*a9fa9459Szrj
10908*a9fa9459Szrj void
tc_x86_parse_to_dw2regnum(expressionS * exp)10909*a9fa9459Szrj tc_x86_parse_to_dw2regnum (expressionS *exp)
10910*a9fa9459Szrj {
10911*a9fa9459Szrj int saved_naked_reg;
10912*a9fa9459Szrj char saved_register_dot;
10913*a9fa9459Szrj
10914*a9fa9459Szrj saved_naked_reg = allow_naked_reg;
10915*a9fa9459Szrj allow_naked_reg = 1;
10916*a9fa9459Szrj saved_register_dot = register_chars['.'];
10917*a9fa9459Szrj register_chars['.'] = '.';
10918*a9fa9459Szrj allow_pseudo_reg = 1;
10919*a9fa9459Szrj expression_and_evaluate (exp);
10920*a9fa9459Szrj allow_pseudo_reg = 0;
10921*a9fa9459Szrj register_chars['.'] = saved_register_dot;
10922*a9fa9459Szrj allow_naked_reg = saved_naked_reg;
10923*a9fa9459Szrj
10924*a9fa9459Szrj if (exp->X_op == O_register && exp->X_add_number >= 0)
10925*a9fa9459Szrj {
10926*a9fa9459Szrj if ((addressT) exp->X_add_number < i386_regtab_size)
10927*a9fa9459Szrj {
10928*a9fa9459Szrj exp->X_op = O_constant;
10929*a9fa9459Szrj exp->X_add_number = i386_regtab[exp->X_add_number]
10930*a9fa9459Szrj .dw2_regnum[flag_code >> 1];
10931*a9fa9459Szrj }
10932*a9fa9459Szrj else
10933*a9fa9459Szrj exp->X_op = O_illegal;
10934*a9fa9459Szrj }
10935*a9fa9459Szrj }
10936*a9fa9459Szrj
10937*a9fa9459Szrj void
tc_x86_frame_initial_instructions(void)10938*a9fa9459Szrj tc_x86_frame_initial_instructions (void)
10939*a9fa9459Szrj {
10940*a9fa9459Szrj static unsigned int sp_regno[2];
10941*a9fa9459Szrj
10942*a9fa9459Szrj if (!sp_regno[flag_code >> 1])
10943*a9fa9459Szrj {
10944*a9fa9459Szrj char *saved_input = input_line_pointer;
10945*a9fa9459Szrj char sp[][4] = {"esp", "rsp"};
10946*a9fa9459Szrj expressionS exp;
10947*a9fa9459Szrj
10948*a9fa9459Szrj input_line_pointer = sp[flag_code >> 1];
10949*a9fa9459Szrj tc_x86_parse_to_dw2regnum (&exp);
10950*a9fa9459Szrj gas_assert (exp.X_op == O_constant);
10951*a9fa9459Szrj sp_regno[flag_code >> 1] = exp.X_add_number;
10952*a9fa9459Szrj input_line_pointer = saved_input;
10953*a9fa9459Szrj }
10954*a9fa9459Szrj
10955*a9fa9459Szrj cfi_add_CFA_def_cfa (sp_regno[flag_code >> 1], -x86_cie_data_alignment);
10956*a9fa9459Szrj cfi_add_CFA_offset (x86_dwarf2_return_column, x86_cie_data_alignment);
10957*a9fa9459Szrj }
10958*a9fa9459Szrj
10959*a9fa9459Szrj int
x86_dwarf2_addr_size(void)10960*a9fa9459Szrj x86_dwarf2_addr_size (void)
10961*a9fa9459Szrj {
10962*a9fa9459Szrj #if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
10963*a9fa9459Szrj if (x86_elf_abi == X86_64_X32_ABI)
10964*a9fa9459Szrj return 4;
10965*a9fa9459Szrj #endif
10966*a9fa9459Szrj return bfd_arch_bits_per_address (stdoutput) / 8;
10967*a9fa9459Szrj }
10968*a9fa9459Szrj
10969*a9fa9459Szrj int
i386_elf_section_type(const char * str,size_t len)10970*a9fa9459Szrj i386_elf_section_type (const char *str, size_t len)
10971*a9fa9459Szrj {
10972*a9fa9459Szrj if (flag_code == CODE_64BIT
10973*a9fa9459Szrj && len == sizeof ("unwind") - 1
10974*a9fa9459Szrj && strncmp (str, "unwind", 6) == 0)
10975*a9fa9459Szrj return SHT_X86_64_UNWIND;
10976*a9fa9459Szrj
10977*a9fa9459Szrj return -1;
10978*a9fa9459Szrj }
10979*a9fa9459Szrj
10980*a9fa9459Szrj #ifdef TE_SOLARIS
10981*a9fa9459Szrj void
i386_solaris_fix_up_eh_frame(segT sec)10982*a9fa9459Szrj i386_solaris_fix_up_eh_frame (segT sec)
10983*a9fa9459Szrj {
10984*a9fa9459Szrj if (flag_code == CODE_64BIT)
10985*a9fa9459Szrj elf_section_type (sec) = SHT_X86_64_UNWIND;
10986*a9fa9459Szrj }
10987*a9fa9459Szrj #endif
10988*a9fa9459Szrj
10989*a9fa9459Szrj #ifdef TE_PE
10990*a9fa9459Szrj void
tc_pe_dwarf2_emit_offset(symbolS * symbol,unsigned int size)10991*a9fa9459Szrj tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
10992*a9fa9459Szrj {
10993*a9fa9459Szrj expressionS exp;
10994*a9fa9459Szrj
10995*a9fa9459Szrj exp.X_op = O_secrel;
10996*a9fa9459Szrj exp.X_add_symbol = symbol;
10997*a9fa9459Szrj exp.X_add_number = 0;
10998*a9fa9459Szrj emit_expr (&exp, size);
10999*a9fa9459Szrj }
11000*a9fa9459Szrj #endif
11001*a9fa9459Szrj
11002*a9fa9459Szrj #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
11003*a9fa9459Szrj /* For ELF on x86-64, add support for SHF_X86_64_LARGE. */
11004*a9fa9459Szrj
11005*a9fa9459Szrj bfd_vma
x86_64_section_letter(int letter,const char ** ptr_msg)11006*a9fa9459Szrj x86_64_section_letter (int letter, const char **ptr_msg)
11007*a9fa9459Szrj {
11008*a9fa9459Szrj if (flag_code == CODE_64BIT)
11009*a9fa9459Szrj {
11010*a9fa9459Szrj if (letter == 'l')
11011*a9fa9459Szrj return SHF_X86_64_LARGE;
11012*a9fa9459Szrj
11013*a9fa9459Szrj *ptr_msg = _("bad .section directive: want a,l,w,x,M,S,G,T in string");
11014*a9fa9459Szrj }
11015*a9fa9459Szrj else
11016*a9fa9459Szrj *ptr_msg = _("bad .section directive: want a,w,x,M,S,G,T in string");
11017*a9fa9459Szrj return -1;
11018*a9fa9459Szrj }
11019*a9fa9459Szrj
11020*a9fa9459Szrj bfd_vma
x86_64_section_word(char * str,size_t len)11021*a9fa9459Szrj x86_64_section_word (char *str, size_t len)
11022*a9fa9459Szrj {
11023*a9fa9459Szrj if (len == 5 && flag_code == CODE_64BIT && CONST_STRNEQ (str, "large"))
11024*a9fa9459Szrj return SHF_X86_64_LARGE;
11025*a9fa9459Szrj
11026*a9fa9459Szrj return -1;
11027*a9fa9459Szrj }
11028*a9fa9459Szrj
11029*a9fa9459Szrj static void
handle_large_common(int small ATTRIBUTE_UNUSED)11030*a9fa9459Szrj handle_large_common (int small ATTRIBUTE_UNUSED)
11031*a9fa9459Szrj {
11032*a9fa9459Szrj if (flag_code != CODE_64BIT)
11033*a9fa9459Szrj {
11034*a9fa9459Szrj s_comm_internal (0, elf_common_parse);
11035*a9fa9459Szrj as_warn (_(".largecomm supported only in 64bit mode, producing .comm"));
11036*a9fa9459Szrj }
11037*a9fa9459Szrj else
11038*a9fa9459Szrj {
11039*a9fa9459Szrj static segT lbss_section;
11040*a9fa9459Szrj asection *saved_com_section_ptr = elf_com_section_ptr;
11041*a9fa9459Szrj asection *saved_bss_section = bss_section;
11042*a9fa9459Szrj
11043*a9fa9459Szrj if (lbss_section == NULL)
11044*a9fa9459Szrj {
11045*a9fa9459Szrj flagword applicable;
11046*a9fa9459Szrj segT seg = now_seg;
11047*a9fa9459Szrj subsegT subseg = now_subseg;
11048*a9fa9459Szrj
11049*a9fa9459Szrj /* The .lbss section is for local .largecomm symbols. */
11050*a9fa9459Szrj lbss_section = subseg_new (".lbss", 0);
11051*a9fa9459Szrj applicable = bfd_applicable_section_flags (stdoutput);
11052*a9fa9459Szrj bfd_set_section_flags (stdoutput, lbss_section,
11053*a9fa9459Szrj applicable & SEC_ALLOC);
11054*a9fa9459Szrj seg_info (lbss_section)->bss = 1;
11055*a9fa9459Szrj
11056*a9fa9459Szrj subseg_set (seg, subseg);
11057*a9fa9459Szrj }
11058*a9fa9459Szrj
11059*a9fa9459Szrj elf_com_section_ptr = &_bfd_elf_large_com_section;
11060*a9fa9459Szrj bss_section = lbss_section;
11061*a9fa9459Szrj
11062*a9fa9459Szrj s_comm_internal (0, elf_common_parse);
11063*a9fa9459Szrj
11064*a9fa9459Szrj elf_com_section_ptr = saved_com_section_ptr;
11065*a9fa9459Szrj bss_section = saved_bss_section;
11066*a9fa9459Szrj }
11067*a9fa9459Szrj }
11068*a9fa9459Szrj #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
11069