1 | /* i386.c -- Assemble code for the Intel 80386
|
---|
2 | Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
---|
3 | 2000, 2001, 2002, 2003
|
---|
4 | Free Software Foundation, Inc.
|
---|
5 |
|
---|
6 | This file is part of GAS, the GNU Assembler.
|
---|
7 |
|
---|
8 | GAS is free software; you can redistribute it and/or modify
|
---|
9 | it under the terms of the GNU General Public License as published by
|
---|
10 | the Free Software Foundation; either version 2, or (at your option)
|
---|
11 | any later version.
|
---|
12 |
|
---|
13 | GAS is distributed in the hope that it will be useful,
|
---|
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | GNU General Public License for more details.
|
---|
17 |
|
---|
18 | You should have received a copy of the GNU General Public License
|
---|
19 | along with GAS; see the file COPYING. If not, write to the Free
|
---|
20 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
---|
21 | 02111-1307, USA. */
|
---|
22 |
|
---|
23 | /* Intel 80386 machine specific gas.
|
---|
24 | Written by Eliot Dresselhaus (eliot@mgm.mit.edu).
|
---|
25 | x86_64 support by Jan Hubicka (jh@suse.cz)
|
---|
26 | Bugs & suggestions are completely welcome. This is free software.
|
---|
27 | Please help us make it better. */
|
---|
28 |
|
---|
29 | #include "as.h"
|
---|
30 | #include "safe-ctype.h"
|
---|
31 | #include "subsegs.h"
|
---|
32 | #include "dwarf2dbg.h"
|
---|
33 | #include "opcode/i386.h"
|
---|
34 |
|
---|
35 | #ifndef REGISTER_WARNINGS
|
---|
36 | #define REGISTER_WARNINGS 1
|
---|
37 | #endif
|
---|
38 |
|
---|
39 | #ifndef INFER_ADDR_PREFIX
|
---|
40 | #define INFER_ADDR_PREFIX 1
|
---|
41 | #endif
|
---|
42 |
|
---|
43 | #ifndef SCALE1_WHEN_NO_INDEX
|
---|
44 | /* Specifying a scale factor besides 1 when there is no index is
|
---|
45 | futile. eg. `mov (%ebx,2),%al' does exactly the same as
|
---|
46 | `mov (%ebx),%al'. To slavishly follow what the programmer
|
---|
47 | specified, set SCALE1_WHEN_NO_INDEX to 0. */
|
---|
48 | #define SCALE1_WHEN_NO_INDEX 1
|
---|
49 | #endif
|
---|
50 |
|
---|
51 | #ifdef BFD_ASSEMBLER
|
---|
52 | #define RELOC_ENUM enum bfd_reloc_code_real
|
---|
53 | #else
|
---|
54 | #define RELOC_ENUM int
|
---|
55 | #endif
|
---|
56 |
|
---|
57 | #ifndef DEFAULT_ARCH
|
---|
58 | #define DEFAULT_ARCH "i386"
|
---|
59 | #endif
|
---|
60 |
|
---|
61 | #ifndef INLINE
|
---|
62 | #if __GNUC__ >= 2
|
---|
63 | #define INLINE __inline__
|
---|
64 | #else
|
---|
65 | #define INLINE
|
---|
66 | #endif
|
---|
67 | #endif
|
---|
68 |
|
---|
69 | static INLINE unsigned int mode_from_disp_size PARAMS ((unsigned int));
|
---|
70 | static INLINE int fits_in_signed_byte PARAMS ((offsetT));
|
---|
71 | static INLINE int fits_in_unsigned_byte PARAMS ((offsetT));
|
---|
72 | static INLINE int fits_in_unsigned_word PARAMS ((offsetT));
|
---|
73 | static INLINE int fits_in_signed_word PARAMS ((offsetT));
|
---|
74 | static INLINE int fits_in_unsigned_long PARAMS ((offsetT));
|
---|
75 | static INLINE int fits_in_signed_long PARAMS ((offsetT));
|
---|
76 | static int smallest_imm_type PARAMS ((offsetT));
|
---|
77 | static offsetT offset_in_range PARAMS ((offsetT, int));
|
---|
78 | static int add_prefix PARAMS ((unsigned int));
|
---|
79 | static void set_code_flag PARAMS ((int));
|
---|
80 | static void set_16bit_gcc_code_flag PARAMS ((int));
|
---|
81 | static void set_intel_syntax PARAMS ((int));
|
---|
82 | static void set_cpu_arch PARAMS ((int));
|
---|
83 | static char *output_invalid PARAMS ((int c));
|
---|
84 | static int i386_operand PARAMS ((char *operand_string));
|
---|
85 | static int i386_intel_operand PARAMS ((char *operand_string, int got_a_float));
|
---|
86 | static const reg_entry *parse_register PARAMS ((char *reg_string,
|
---|
87 | char **end_op));
|
---|
88 | static char *parse_insn PARAMS ((char *, char *));
|
---|
89 | static char *parse_operands PARAMS ((char *, const char *));
|
---|
90 | static void swap_operands PARAMS ((void));
|
---|
91 | static void optimize_imm PARAMS ((void));
|
---|
92 | static void optimize_disp PARAMS ((void));
|
---|
93 | static int match_template PARAMS ((void));
|
---|
94 | static int check_string PARAMS ((void));
|
---|
95 | static int process_suffix PARAMS ((void));
|
---|
96 | static int check_byte_reg PARAMS ((void));
|
---|
97 | static int check_long_reg PARAMS ((void));
|
---|
98 | static int check_qword_reg PARAMS ((void));
|
---|
99 | static int check_word_reg PARAMS ((void));
|
---|
100 | static int finalize_imm PARAMS ((void));
|
---|
101 | static int process_operands PARAMS ((void));
|
---|
102 | static const seg_entry *build_modrm_byte PARAMS ((void));
|
---|
103 | static void output_insn PARAMS ((void));
|
---|
104 | static void output_branch PARAMS ((void));
|
---|
105 | static void output_jump PARAMS ((void));
|
---|
106 | static void output_interseg_jump PARAMS ((void));
|
---|
107 | static void output_imm PARAMS ((fragS *insn_start_frag,
|
---|
108 | offsetT insn_start_off));
|
---|
109 | static void output_disp PARAMS ((fragS *insn_start_frag,
|
---|
110 | offsetT insn_start_off));
|
---|
111 | #ifndef I386COFF
|
---|
112 | static void s_bss PARAMS ((int));
|
---|
113 | #endif
|
---|
114 |
|
---|
115 | static const char *default_arch = DEFAULT_ARCH;
|
---|
116 |
|
---|
117 | /* 'md_assemble ()' gathers together information and puts it into a
|
---|
118 | i386_insn. */
|
---|
119 |
|
---|
120 | union i386_op
|
---|
121 | {
|
---|
122 | expressionS *disps;
|
---|
123 | expressionS *imms;
|
---|
124 | const reg_entry *regs;
|
---|
125 | };
|
---|
126 |
|
---|
127 | struct _i386_insn
|
---|
128 | {
|
---|
129 | /* TM holds the template for the insn were currently assembling. */
|
---|
130 | template tm;
|
---|
131 |
|
---|
132 | /* SUFFIX holds the instruction mnemonic suffix if given.
|
---|
133 | (e.g. 'l' for 'movl') */
|
---|
134 | char suffix;
|
---|
135 |
|
---|
136 | /* OPERANDS gives the number of given operands. */
|
---|
137 | unsigned int operands;
|
---|
138 |
|
---|
139 | /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number
|
---|
140 | of given register, displacement, memory operands and immediate
|
---|
141 | operands. */
|
---|
142 | unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
|
---|
143 |
|
---|
144 | /* TYPES [i] is the type (see above #defines) which tells us how to
|
---|
145 | use OP[i] for the corresponding operand. */
|
---|
146 | unsigned int types[MAX_OPERANDS];
|
---|
147 |
|
---|
148 | /* Displacement expression, immediate expression, or register for each
|
---|
149 | operand. */
|
---|
150 | union i386_op op[MAX_OPERANDS];
|
---|
151 |
|
---|
152 | /* Flags for operands. */
|
---|
153 | unsigned int flags[MAX_OPERANDS];
|
---|
154 | #define Operand_PCrel 1
|
---|
155 |
|
---|
156 | /* Relocation type for operand */
|
---|
157 | RELOC_ENUM reloc[MAX_OPERANDS];
|
---|
158 |
|
---|
159 | /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
|
---|
160 | the base index byte below. */
|
---|
161 | const reg_entry *base_reg;
|
---|
162 | const reg_entry *index_reg;
|
---|
163 | unsigned int log2_scale_factor;
|
---|
164 |
|
---|
165 | /* SEG gives the seg_entries of this insn. They are zero unless
|
---|
166 | explicit segment overrides are given. */
|
---|
167 | const seg_entry *seg[2];
|
---|
168 |
|
---|
169 | /* PREFIX holds all the given prefix opcodes (usually null).
|
---|
170 | PREFIXES is the number of prefix opcodes. */
|
---|
171 | unsigned int prefixes;
|
---|
172 | unsigned char prefix[MAX_PREFIXES];
|
---|
173 |
|
---|
174 | /* RM and SIB are the modrm byte and the sib byte where the
|
---|
175 | addressing modes of this insn are encoded. */
|
---|
176 |
|
---|
177 | modrm_byte rm;
|
---|
178 | rex_byte rex;
|
---|
179 | sib_byte sib;
|
---|
180 | };
|
---|
181 |
|
---|
182 | typedef struct _i386_insn i386_insn;
|
---|
183 |
|
---|
184 | /* List of chars besides those in app.c:symbol_chars that can start an
|
---|
185 | operand. Used to prevent the scrubber eating vital white-space. */
|
---|
186 | #ifdef LEX_AT
|
---|
187 | const char extra_symbol_chars[] = "*%-(@[";
|
---|
188 | #else
|
---|
189 | const char extra_symbol_chars[] = "*%-([";
|
---|
190 | #endif
|
---|
191 |
|
---|
192 | #if (defined (TE_I386AIX) \
|
---|
193 | || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
|
---|
194 | && !defined (TE_LINUX) \
|
---|
195 | && !defined (TE_FreeBSD) \
|
---|
196 | && !defined (TE_NetBSD)))
|
---|
197 | /* This array holds the chars that always start a comment. If the
|
---|
198 | pre-processor is disabled, these aren't very useful. */
|
---|
199 | const char comment_chars[] = "#/";
|
---|
200 | #define PREFIX_SEPARATOR '\\'
|
---|
201 |
|
---|
202 | /* This array holds the chars that only start a comment at the beginning of
|
---|
203 | a line. If the line seems to have the form '# 123 filename'
|
---|
204 | .line and .file directives will appear in the pre-processed output.
|
---|
205 | Note that input_file.c hand checks for '#' at the beginning of the
|
---|
206 | first line of the input file. This is because the compiler outputs
|
---|
207 | #NO_APP at the beginning of its output.
|
---|
208 | Also note that comments started like this one will always work if
|
---|
209 | '/' isn't otherwise defined. */
|
---|
210 | const char line_comment_chars[] = "#";
|
---|
211 |
|
---|
212 | #else
|
---|
213 | /* Putting '/' here makes it impossible to use the divide operator.
|
---|
214 | However, we need it for compatibility with SVR4 systems. */
|
---|
215 | const char comment_chars[] = "#";
|
---|
216 | #define PREFIX_SEPARATOR '/'
|
---|
217 |
|
---|
218 | const char line_comment_chars[] = "/#";
|
---|
219 | #endif
|
---|
220 |
|
---|
221 | const char line_separator_chars[] = ";";
|
---|
222 |
|
---|
223 | /* Chars that can be used to separate mant from exp in floating point
|
---|
224 | nums. */
|
---|
225 | const char EXP_CHARS[] = "eE";
|
---|
226 |
|
---|
227 | /* Chars that mean this number is a floating point constant
|
---|
228 | As in 0f12.456
|
---|
229 | or 0d1.2345e12. */
|
---|
230 | const char FLT_CHARS[] = "fFdDxX";
|
---|
231 |
|
---|
232 | /* Tables for lexical analysis. */
|
---|
233 | static char mnemonic_chars[256];
|
---|
234 | static char register_chars[256];
|
---|
235 | static char operand_chars[256];
|
---|
236 | static char identifier_chars[256];
|
---|
237 | static char digit_chars[256];
|
---|
238 |
|
---|
239 | /* Lexical macros. */
|
---|
240 | #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
|
---|
241 | #define is_operand_char(x) (operand_chars[(unsigned char) x])
|
---|
242 | #define is_register_char(x) (register_chars[(unsigned char) x])
|
---|
243 | #define is_space_char(x) ((x) == ' ')
|
---|
244 | #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
|
---|
245 | #define is_digit_char(x) (digit_chars[(unsigned char) x])
|
---|
246 |
|
---|
247 | /* All non-digit non-letter charcters that may occur in an operand. */
|
---|
248 | static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]";
|
---|
249 |
|
---|
250 | /* md_assemble() always leaves the strings it's passed unaltered. To
|
---|
251 | effect this we maintain a stack of saved characters that we've smashed
|
---|
252 | with '\0's (indicating end of strings for various sub-fields of the
|
---|
253 | assembler instruction). */
|
---|
254 | static char save_stack[32];
|
---|
255 | static char *save_stack_p;
|
---|
256 | #define END_STRING_AND_SAVE(s) \
|
---|
257 | do { *save_stack_p++ = *(s); *(s) = '\0'; } while (0)
|
---|
258 | #define RESTORE_END_STRING(s) \
|
---|
259 | do { *(s) = *--save_stack_p; } while (0)
|
---|
260 |
|
---|
261 | /* The instruction we're assembling. */
|
---|
262 | static i386_insn i;
|
---|
263 |
|
---|
264 | /* Possible templates for current insn. */
|
---|
265 | static const templates *current_templates;
|
---|
266 |
|
---|
267 | /* Per instruction expressionS buffers: 2 displacements & 2 immediate max. */
|
---|
268 | static expressionS disp_expressions[2], im_expressions[2];
|
---|
269 |
|
---|
270 | /* Current operand we are working on. */
|
---|
271 | static int this_operand;
|
---|
272 |
|
---|
273 | /* We support four different modes. FLAG_CODE variable is used to distinguish
|
---|
274 | these. */
|
---|
275 |
|
---|
276 | enum flag_code {
|
---|
277 | CODE_32BIT,
|
---|
278 | CODE_16BIT,
|
---|
279 | CODE_64BIT };
|
---|
280 | #define NUM_FLAG_CODE ((int) CODE_64BIT + 1)
|
---|
281 |
|
---|
282 | static enum flag_code flag_code;
|
---|
283 | static int use_rela_relocations = 0;
|
---|
284 |
|
---|
285 | /* The names used to print error messages. */
|
---|
286 | static const char *flag_code_names[] =
|
---|
287 | {
|
---|
288 | "32",
|
---|
289 | "16",
|
---|
290 | "64"
|
---|
291 | };
|
---|
292 |
|
---|
293 | /* 1 for intel syntax,
|
---|
294 | 0 if att syntax. */
|
---|
295 | static int intel_syntax = 0;
|
---|
296 |
|
---|
297 | /* 1 if register prefix % not required. */
|
---|
298 | static int allow_naked_reg = 0;
|
---|
299 |
|
---|
300 | /* Used in 16 bit gcc mode to add an l suffix to call, ret, enter,
|
---|
301 | leave, push, and pop instructions so that gcc has the same stack
|
---|
302 | frame as in 32 bit mode. */
|
---|
303 | static char stackop_size = '\0';
|
---|
304 |
|
---|
305 | /* Non-zero to quieten some warnings. */
|
---|
306 | static int quiet_warnings = 0;
|
---|
307 |
|
---|
308 | /* CPU name. */
|
---|
309 | static const char *cpu_arch_name = NULL;
|
---|
310 |
|
---|
311 | /* CPU feature flags. */
|
---|
312 | static unsigned int cpu_arch_flags = CpuUnknownFlags | CpuNo64;
|
---|
313 |
|
---|
314 | /* If set, conditional jumps are not automatically promoted to handle
|
---|
315 | larger than a byte offset. */
|
---|
316 | static unsigned int no_cond_jump_promotion = 0;
|
---|
317 |
|
---|
318 | /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
|
---|
319 | symbolS *GOT_symbol;
|
---|
320 |
|
---|
321 | /* Interface to relax_segment.
|
---|
322 | There are 3 major relax states for 386 jump insns because the
|
---|
323 | different types of jumps add different sizes to frags when we're
|
---|
324 | figuring out what sort of jump to choose to reach a given label. */
|
---|
325 |
|
---|
326 | /* Types. */
|
---|
327 | #define UNCOND_JUMP 0
|
---|
328 | #define COND_JUMP 1
|
---|
329 | #define COND_JUMP86 2
|
---|
330 |
|
---|
331 | /* Sizes. */
|
---|
332 | #define CODE16 1
|
---|
333 | #define SMALL 0
|
---|
334 | #define SMALL16 (SMALL | CODE16)
|
---|
335 | #define BIG 2
|
---|
336 | #define BIG16 (BIG | CODE16)
|
---|
337 |
|
---|
338 | #ifndef INLINE
|
---|
339 | #ifdef __GNUC__
|
---|
340 | #define INLINE __inline__
|
---|
341 | #else
|
---|
342 | #define INLINE
|
---|
343 | #endif
|
---|
344 | #endif
|
---|
345 |
|
---|
346 | #define ENCODE_RELAX_STATE(type, size) \
|
---|
347 | ((relax_substateT) (((type) << 2) | (size)))
|
---|
348 | #define TYPE_FROM_RELAX_STATE(s) \
|
---|
349 | ((s) >> 2)
|
---|
350 | #define DISP_SIZE_FROM_RELAX_STATE(s) \
|
---|
351 | ((((s) & 3) == BIG ? 4 : (((s) & 3) == BIG16 ? 2 : 1)))
|
---|
352 |
|
---|
353 | /* This table is used by relax_frag to promote short jumps to long
|
---|
354 | ones where necessary. SMALL (short) jumps may be promoted to BIG
|
---|
355 | (32 bit long) ones, and SMALL16 jumps to BIG16 (16 bit long). We
|
---|
356 | don't allow a short jump in a 32 bit code segment to be promoted to
|
---|
357 | a 16 bit offset jump because it's slower (requires data size
|
---|
358 | prefix), and doesn't work, unless the destination is in the bottom
|
---|
359 | 64k of the code segment (The top 16 bits of eip are zeroed). */
|
---|
360 |
|
---|
361 | const relax_typeS md_relax_table[] =
|
---|
362 | {
|
---|
363 | /* The fields are:
|
---|
364 | 1) most positive reach of this state,
|
---|
365 | 2) most negative reach of this state,
|
---|
366 | 3) how many bytes this mode will have in the variable part of the frag
|
---|
367 | 4) which index into the table to try if we can't fit into this one. */
|
---|
368 |
|
---|
369 | /* UNCOND_JUMP states. */
|
---|
370 | {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
|
---|
371 | {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
|
---|
372 | /* dword jmp adds 4 bytes to frag:
|
---|
373 | 0 extra opcode bytes, 4 displacement bytes. */
|
---|
374 | {0, 0, 4, 0},
|
---|
375 | /* word jmp adds 2 byte2 to frag:
|
---|
376 | 0 extra opcode bytes, 2 displacement bytes. */
|
---|
377 | {0, 0, 2, 0},
|
---|
378 |
|
---|
379 | /* COND_JUMP states. */
|
---|
380 | {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
|
---|
381 | {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
|
---|
382 | /* dword conditionals adds 5 bytes to frag:
|
---|
383 | 1 extra opcode byte, 4 displacement bytes. */
|
---|
384 | {0, 0, 5, 0},
|
---|
385 | /* word conditionals add 3 bytes to frag:
|
---|
386 | 1 extra opcode byte, 2 displacement bytes. */
|
---|
387 | {0, 0, 3, 0},
|
---|
388 |
|
---|
389 | /* COND_JUMP86 states. */
|
---|
390 | {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
|
---|
391 | {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
|
---|
392 | /* dword conditionals adds 5 bytes to frag:
|
---|
393 | 1 extra opcode byte, 4 displacement bytes. */
|
---|
394 | {0, 0, 5, 0},
|
---|
395 | /* word conditionals add 4 bytes to frag:
|
---|
396 | 1 displacement byte and a 3 byte long branch insn. */
|
---|
397 | {0, 0, 4, 0}
|
---|
398 | };
|
---|
399 |
|
---|
400 | static const arch_entry cpu_arch[] = {
|
---|
401 | {"i8086", Cpu086 },
|
---|
402 | {"i186", Cpu086|Cpu186 },
|
---|
403 | {"i286", Cpu086|Cpu186|Cpu286 },
|
---|
404 | {"i386", Cpu086|Cpu186|Cpu286|Cpu386 },
|
---|
405 | {"i486", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486 },
|
---|
406 | {"i586", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuMMX },
|
---|
407 | {"i686", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE },
|
---|
408 | {"pentium", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuMMX },
|
---|
409 | {"pentiumpro",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE },
|
---|
410 | {"pentium4", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2 },
|
---|
411 | {"k6", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow },
|
---|
412 | {"athlon", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuMMX|Cpu3dnow },
|
---|
413 | {"sledgehammer",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuSledgehammer|CpuMMX|Cpu3dnow|CpuSSE|CpuSSE2 },
|
---|
414 | {NULL, 0 }
|
---|
415 | };
|
---|
416 |
|
---|
417 | const pseudo_typeS md_pseudo_table[] =
|
---|
418 | {
|
---|
419 | #if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO)
|
---|
420 | {"align", s_align_bytes, 0},
|
---|
421 | #else
|
---|
422 | {"align", s_align_ptwo, 0},
|
---|
423 | #endif
|
---|
424 | {"arch", set_cpu_arch, 0},
|
---|
425 | #ifndef I386COFF
|
---|
426 | {"bss", s_bss, 0},
|
---|
427 | #endif
|
---|
428 | {"ffloat", float_cons, 'f'},
|
---|
429 | {"dfloat", float_cons, 'd'},
|
---|
430 | {"tfloat", float_cons, 'x'},
|
---|
431 | {"value", cons, 2},
|
---|
432 | {"noopt", s_ignore, 0},
|
---|
433 | {"optim", s_ignore, 0},
|
---|
434 | {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT},
|
---|
435 | {"code16", set_code_flag, CODE_16BIT},
|
---|
436 | {"code32", set_code_flag, CODE_32BIT},
|
---|
437 | {"code64", set_code_flag, CODE_64BIT},
|
---|
438 | {"intel_syntax", set_intel_syntax, 1},
|
---|
439 | {"att_syntax", set_intel_syntax, 0},
|
---|
440 | {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
|
---|
441 | {"loc", dwarf2_directive_loc, 0},
|
---|
442 | {0, 0, 0}
|
---|
443 | };
|
---|
444 |
|
---|
445 | /* For interface with expression (). */
|
---|
446 | extern char *input_line_pointer;
|
---|
447 |
|
---|
448 | /* Hash table for instruction mnemonic lookup. */
|
---|
449 | static struct hash_control *op_hash;
|
---|
450 |
|
---|
451 | /* Hash table for register lookup. */
|
---|
452 | static struct hash_control *reg_hash;
|
---|
453 | |
---|
454 |
|
---|
455 | void
|
---|
456 | i386_align_code (fragP, count)
|
---|
457 | fragS *fragP;
|
---|
458 | int count;
|
---|
459 | {
|
---|
460 | /* Various efficient no-op patterns for aligning code labels.
|
---|
461 | Note: Don't try to assemble the instructions in the comments.
|
---|
462 | 0L and 0w are not legal. */
|
---|
463 | static const char f32_1[] =
|
---|
464 | {0x90}; /* nop */
|
---|
465 | static const char f32_2[] =
|
---|
466 | {0x89,0xf6}; /* movl %esi,%esi */
|
---|
467 | static const char f32_3[] =
|
---|
468 | {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */
|
---|
469 | static const char f32_4[] =
|
---|
470 | {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
|
---|
471 | static const char f32_5[] =
|
---|
472 | {0x90, /* nop */
|
---|
473 | 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
|
---|
474 | static const char f32_6[] =
|
---|
475 | {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */
|
---|
476 | static const char f32_7[] =
|
---|
477 | {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
|
---|
478 | static const char f32_8[] =
|
---|
479 | {0x90, /* nop */
|
---|
480 | 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
|
---|
481 | static const char f32_9[] =
|
---|
482 | {0x89,0xf6, /* movl %esi,%esi */
|
---|
483 | 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
|
---|
484 | static const char f32_10[] =
|
---|
485 | {0x8d,0x76,0x00, /* leal 0(%esi),%esi */
|
---|
486 | 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
|
---|
487 | static const char f32_11[] =
|
---|
488 | {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */
|
---|
489 | 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
|
---|
490 | static const char f32_12[] =
|
---|
491 | {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
|
---|
492 | 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */
|
---|
493 | static const char f32_13[] =
|
---|
494 | {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
|
---|
495 | 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
|
---|
496 | static const char f32_14[] =
|
---|
497 | {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */
|
---|
498 | 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
|
---|
499 | static const char f32_15[] =
|
---|
500 | {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */
|
---|
501 | 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
|
---|
502 | static const char f16_3[] =
|
---|
503 | {0x8d,0x74,0x00}; /* lea 0(%esi),%esi */
|
---|
504 | static const char f16_4[] =
|
---|
505 | {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
|
---|
506 | static const char f16_5[] =
|
---|
507 | {0x90, /* nop */
|
---|
508 | 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
|
---|
509 | static const char f16_6[] =
|
---|
510 | {0x89,0xf6, /* mov %si,%si */
|
---|
511 | 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
|
---|
512 | static const char f16_7[] =
|
---|
513 | {0x8d,0x74,0x00, /* lea 0(%si),%si */
|
---|
514 | 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
|
---|
515 | static const char f16_8[] =
|
---|
516 | {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */
|
---|
517 | 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
|
---|
518 | static const char *const f32_patt[] = {
|
---|
519 | f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
|
---|
520 | f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
|
---|
521 | };
|
---|
522 | static const char *const f16_patt[] = {
|
---|
523 | f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8,
|
---|
524 | f32_15, f32_15, f32_15, f32_15, f32_15, f32_15, f32_15
|
---|
525 | };
|
---|
526 |
|
---|
527 | if (count <= 0 || count > 15)
|
---|
528 | return;
|
---|
529 |
|
---|
530 | /* The recommended way to pad 64bit code is to use NOPs preceded by
|
---|
531 | maximally four 0x66 prefixes. Balance the size of nops. */
|
---|
532 | if (flag_code == CODE_64BIT)
|
---|
533 | {
|
---|
534 | int i;
|
---|
535 | int nnops = (count + 3) / 4;
|
---|
536 | int len = count / nnops;
|
---|
537 | int remains = count - nnops * len;
|
---|
538 | int pos = 0;
|
---|
539 |
|
---|
540 | for (i = 0; i < remains; i++)
|
---|
541 | {
|
---|
542 | memset (fragP->fr_literal + fragP->fr_fix + pos, 0x66, len);
|
---|
543 | fragP->fr_literal[fragP->fr_fix + pos + len] = 0x90;
|
---|
544 | pos += len + 1;
|
---|
545 | }
|
---|
546 | for (; i < nnops; i++)
|
---|
547 | {
|
---|
548 | memset (fragP->fr_literal + fragP->fr_fix + pos, 0x66, len - 1);
|
---|
549 | fragP->fr_literal[fragP->fr_fix + pos + len - 1] = 0x90;
|
---|
550 | pos += len;
|
---|
551 | }
|
---|
552 | }
|
---|
553 | else
|
---|
554 | if (flag_code == CODE_16BIT)
|
---|
555 | {
|
---|
556 | memcpy (fragP->fr_literal + fragP->fr_fix,
|
---|
557 | f16_patt[count - 1], count);
|
---|
558 | if (count > 8)
|
---|
559 | /* Adjust jump offset. */
|
---|
560 | fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
|
---|
561 | }
|
---|
562 | else
|
---|
563 | memcpy (fragP->fr_literal + fragP->fr_fix,
|
---|
564 | f32_patt[count - 1], count);
|
---|
565 | fragP->fr_var = count;
|
---|
566 | }
|
---|
567 |
|
---|
568 | static INLINE unsigned int
|
---|
569 | mode_from_disp_size (t)
|
---|
570 | unsigned int t;
|
---|
571 | {
|
---|
572 | return (t & Disp8) ? 1 : (t & (Disp16 | Disp32 | Disp32S)) ? 2 : 0;
|
---|
573 | }
|
---|
574 |
|
---|
575 | static INLINE int
|
---|
576 | fits_in_signed_byte (num)
|
---|
577 | offsetT num;
|
---|
578 | {
|
---|
579 | return (num >= -128) && (num <= 127);
|
---|
580 | }
|
---|
581 |
|
---|
582 | static INLINE int
|
---|
583 | fits_in_unsigned_byte (num)
|
---|
584 | offsetT num;
|
---|
585 | {
|
---|
586 | return (num & 0xff) == num;
|
---|
587 | }
|
---|
588 |
|
---|
589 | static INLINE int
|
---|
590 | fits_in_unsigned_word (num)
|
---|
591 | offsetT num;
|
---|
592 | {
|
---|
593 | return (num & 0xffff) == num;
|
---|
594 | }
|
---|
595 |
|
---|
596 | static INLINE int
|
---|
597 | fits_in_signed_word (num)
|
---|
598 | offsetT num;
|
---|
599 | {
|
---|
600 | return (-32768 <= num) && (num <= 32767);
|
---|
601 | }
|
---|
602 | static INLINE int
|
---|
603 | fits_in_signed_long (num)
|
---|
604 | offsetT num ATTRIBUTE_UNUSED;
|
---|
605 | {
|
---|
606 | #ifndef BFD64
|
---|
607 | return 1;
|
---|
608 | #else
|
---|
609 | return (!(((offsetT) -1 << 31) & num)
|
---|
610 | || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));
|
---|
611 | #endif
|
---|
612 | } /* fits_in_signed_long() */
|
---|
613 | static INLINE int
|
---|
614 | fits_in_unsigned_long (num)
|
---|
615 | offsetT num ATTRIBUTE_UNUSED;
|
---|
616 | {
|
---|
617 | #ifndef BFD64
|
---|
618 | return 1;
|
---|
619 | #else
|
---|
620 | return (num & (((offsetT) 2 << 31) - 1)) == num;
|
---|
621 | #endif
|
---|
622 | } /* fits_in_unsigned_long() */
|
---|
623 |
|
---|
624 | static int
|
---|
625 | smallest_imm_type (num)
|
---|
626 | offsetT num;
|
---|
627 | {
|
---|
628 | if (cpu_arch_flags != (Cpu086 | Cpu186 | Cpu286 | Cpu386 | Cpu486 | CpuNo64))
|
---|
629 | {
|
---|
630 | /* This code is disabled on the 486 because all the Imm1 forms
|
---|
631 | in the opcode table are slower on the i486. They're the
|
---|
632 | versions with the implicitly specified single-position
|
---|
633 | displacement, which has another syntax if you really want to
|
---|
634 | use that form. */
|
---|
635 | if (num == 1)
|
---|
636 | return Imm1 | Imm8 | Imm8S | Imm16 | Imm32 | Imm32S | Imm64;
|
---|
637 | }
|
---|
638 | return (fits_in_signed_byte (num)
|
---|
639 | ? (Imm8S | Imm8 | Imm16 | Imm32 | Imm32S | Imm64)
|
---|
640 | : fits_in_unsigned_byte (num)
|
---|
641 | ? (Imm8 | Imm16 | Imm32 | Imm32S | Imm64)
|
---|
642 | : (fits_in_signed_word (num) || fits_in_unsigned_word (num))
|
---|
643 | ? (Imm16 | Imm32 | Imm32S | Imm64)
|
---|
644 | : fits_in_signed_long (num)
|
---|
645 | ? (Imm32 | Imm32S | Imm64)
|
---|
646 | : fits_in_unsigned_long (num)
|
---|
647 | ? (Imm32 | Imm64)
|
---|
648 | : Imm64);
|
---|
649 | }
|
---|
650 |
|
---|
651 | static offsetT
|
---|
652 | offset_in_range (val, size)
|
---|
653 | offsetT val;
|
---|
654 | int size;
|
---|
655 | {
|
---|
656 | addressT mask;
|
---|
657 |
|
---|
658 | switch (size)
|
---|
659 | {
|
---|
660 | case 1: mask = ((addressT) 1 << 8) - 1; break;
|
---|
661 | case 2: mask = ((addressT) 1 << 16) - 1; break;
|
---|
662 | case 4: mask = ((addressT) 2 << 31) - 1; break;
|
---|
663 | #ifdef BFD64
|
---|
664 | case 8: mask = ((addressT) 2 << 63) - 1; break;
|
---|
665 | #endif
|
---|
666 | default: abort ();
|
---|
667 | }
|
---|
668 |
|
---|
669 | /* If BFD64, sign extend val. */
|
---|
670 | if (!use_rela_relocations)
|
---|
671 | if ((val & ~(((addressT) 2 << 31) - 1)) == 0)
|
---|
672 | val = (val ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
|
---|
673 |
|
---|
674 | if ((val & ~mask) != 0 && (val & ~mask) != ~mask)
|
---|
675 | {
|
---|
676 | char buf1[40], buf2[40];
|
---|
677 |
|
---|
678 | sprint_value (buf1, val);
|
---|
679 | sprint_value (buf2, val & mask);
|
---|
680 | as_warn (_("%s shortened to %s"), buf1, buf2);
|
---|
681 | }
|
---|
682 | return val & mask;
|
---|
683 | }
|
---|
684 |
|
---|
685 | /* Returns 0 if attempting to add a prefix where one from the same
|
---|
686 | class already exists, 1 if non rep/repne added, 2 if rep/repne
|
---|
687 | added. */
|
---|
688 | static int
|
---|
689 | add_prefix (prefix)
|
---|
690 | unsigned int prefix;
|
---|
691 | {
|
---|
692 | int ret = 1;
|
---|
693 | int q;
|
---|
694 |
|
---|
695 | if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16
|
---|
696 | && flag_code == CODE_64BIT)
|
---|
697 | q = REX_PREFIX;
|
---|
698 | else
|
---|
699 | switch (prefix)
|
---|
700 | {
|
---|
701 | default:
|
---|
702 | abort ();
|
---|
703 |
|
---|
704 | case CS_PREFIX_OPCODE:
|
---|
705 | case DS_PREFIX_OPCODE:
|
---|
706 | case ES_PREFIX_OPCODE:
|
---|
707 | case FS_PREFIX_OPCODE:
|
---|
708 | case GS_PREFIX_OPCODE:
|
---|
709 | case SS_PREFIX_OPCODE:
|
---|
710 | q = SEG_PREFIX;
|
---|
711 | break;
|
---|
712 |
|
---|
713 | case REPNE_PREFIX_OPCODE:
|
---|
714 | case REPE_PREFIX_OPCODE:
|
---|
715 | ret = 2;
|
---|
716 | /* fall thru */
|
---|
717 | case LOCK_PREFIX_OPCODE:
|
---|
718 | q = LOCKREP_PREFIX;
|
---|
719 | break;
|
---|
720 |
|
---|
721 | case FWAIT_OPCODE:
|
---|
722 | q = WAIT_PREFIX;
|
---|
723 | break;
|
---|
724 |
|
---|
725 | case ADDR_PREFIX_OPCODE:
|
---|
726 | q = ADDR_PREFIX;
|
---|
727 | break;
|
---|
728 |
|
---|
729 | case DATA_PREFIX_OPCODE:
|
---|
730 | q = DATA_PREFIX;
|
---|
731 | break;
|
---|
732 | }
|
---|
733 |
|
---|
734 | if (i.prefix[q] != 0)
|
---|
735 | {
|
---|
736 | as_bad (_("same type of prefix used twice"));
|
---|
737 | return 0;
|
---|
738 | }
|
---|
739 |
|
---|
740 | i.prefixes += 1;
|
---|
741 | i.prefix[q] = prefix;
|
---|
742 | return ret;
|
---|
743 | }
|
---|
744 |
|
---|
745 | static void
|
---|
746 | set_code_flag (value)
|
---|
747 | int value;
|
---|
748 | {
|
---|
749 | flag_code = value;
|
---|
750 | cpu_arch_flags &= ~(Cpu64 | CpuNo64);
|
---|
751 | cpu_arch_flags |= (flag_code == CODE_64BIT ? Cpu64 : CpuNo64);
|
---|
752 | if (value == CODE_64BIT && !(cpu_arch_flags & CpuSledgehammer))
|
---|
753 | {
|
---|
754 | as_bad (_("64bit mode not supported on this CPU."));
|
---|
755 | }
|
---|
756 | if (value == CODE_32BIT && !(cpu_arch_flags & Cpu386))
|
---|
757 | {
|
---|
758 | as_bad (_("32bit mode not supported on this CPU."));
|
---|
759 | }
|
---|
760 | stackop_size = '\0';
|
---|
761 | }
|
---|
762 |
|
---|
763 | static void
|
---|
764 | set_16bit_gcc_code_flag (new_code_flag)
|
---|
765 | int new_code_flag;
|
---|
766 | {
|
---|
767 | flag_code = new_code_flag;
|
---|
768 | cpu_arch_flags &= ~(Cpu64 | CpuNo64);
|
---|
769 | cpu_arch_flags |= (flag_code == CODE_64BIT ? Cpu64 : CpuNo64);
|
---|
770 | stackop_size = 'l';
|
---|
771 | }
|
---|
772 |
|
---|
773 | static void
|
---|
774 | set_intel_syntax (syntax_flag)
|
---|
775 | int syntax_flag;
|
---|
776 | {
|
---|
777 | /* Find out if register prefixing is specified. */
|
---|
778 | int ask_naked_reg = 0;
|
---|
779 |
|
---|
780 | SKIP_WHITESPACE ();
|
---|
781 | if (!is_end_of_line[(unsigned char) *input_line_pointer])
|
---|
782 | {
|
---|
783 | char *string = input_line_pointer;
|
---|
784 | int e = get_symbol_end ();
|
---|
785 |
|
---|
786 | if (strcmp (string, "prefix") == 0)
|
---|
787 | ask_naked_reg = 1;
|
---|
788 | else if (strcmp (string, "noprefix") == 0)
|
---|
789 | ask_naked_reg = -1;
|
---|
790 | else
|
---|
791 | as_bad (_("bad argument to syntax directive."));
|
---|
792 | *input_line_pointer = e;
|
---|
793 | }
|
---|
794 | demand_empty_rest_of_line ();
|
---|
795 |
|
---|
796 | intel_syntax = syntax_flag;
|
---|
797 |
|
---|
798 | if (ask_naked_reg == 0)
|
---|
799 | {
|
---|
800 | #ifdef BFD_ASSEMBLER
|
---|
801 | allow_naked_reg = (intel_syntax
|
---|
802 | && (bfd_get_symbol_leading_char (stdoutput) != '\0'));
|
---|
803 | #else
|
---|
804 | /* Conservative default. */
|
---|
805 | allow_naked_reg = 0;
|
---|
806 | #endif
|
---|
807 | }
|
---|
808 | else
|
---|
809 | allow_naked_reg = (ask_naked_reg < 0);
|
---|
810 | }
|
---|
811 |
|
---|
812 | static void
|
---|
813 | set_cpu_arch (dummy)
|
---|
814 | int dummy ATTRIBUTE_UNUSED;
|
---|
815 | {
|
---|
816 | SKIP_WHITESPACE ();
|
---|
817 |
|
---|
818 | if (!is_end_of_line[(unsigned char) *input_line_pointer])
|
---|
819 | {
|
---|
820 | char *string = input_line_pointer;
|
---|
821 | int e = get_symbol_end ();
|
---|
822 | int i;
|
---|
823 |
|
---|
824 | for (i = 0; cpu_arch[i].name; i++)
|
---|
825 | {
|
---|
826 | if (strcmp (string, cpu_arch[i].name) == 0)
|
---|
827 | {
|
---|
828 | cpu_arch_name = cpu_arch[i].name;
|
---|
829 | cpu_arch_flags = (cpu_arch[i].flags
|
---|
830 | | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64));
|
---|
831 | break;
|
---|
832 | }
|
---|
833 | }
|
---|
834 | if (!cpu_arch[i].name)
|
---|
835 | as_bad (_("no such architecture: `%s'"), string);
|
---|
836 |
|
---|
837 | *input_line_pointer = e;
|
---|
838 | }
|
---|
839 | else
|
---|
840 | as_bad (_("missing cpu architecture"));
|
---|
841 |
|
---|
842 | no_cond_jump_promotion = 0;
|
---|
843 | if (*input_line_pointer == ','
|
---|
844 | && !is_end_of_line[(unsigned char) input_line_pointer[1]])
|
---|
845 | {
|
---|
846 | char *string = ++input_line_pointer;
|
---|
847 | int e = get_symbol_end ();
|
---|
848 |
|
---|
849 | if (strcmp (string, "nojumps") == 0)
|
---|
850 | no_cond_jump_promotion = 1;
|
---|
851 | else if (strcmp (string, "jumps") == 0)
|
---|
852 | ;
|
---|
853 | else
|
---|
854 | as_bad (_("no such architecture modifier: `%s'"), string);
|
---|
855 |
|
---|
856 | *input_line_pointer = e;
|
---|
857 | }
|
---|
858 |
|
---|
859 | demand_empty_rest_of_line ();
|
---|
860 | }
|
---|
861 |
|
---|
862 | #ifdef BFD_ASSEMBLER
|
---|
863 | unsigned long
|
---|
864 | i386_mach ()
|
---|
865 | {
|
---|
866 | if (!strcmp (default_arch, "x86_64"))
|
---|
867 | return bfd_mach_x86_64;
|
---|
868 | else if (!strcmp (default_arch, "i386"))
|
---|
869 | return bfd_mach_i386_i386;
|
---|
870 | else
|
---|
871 | as_fatal (_("Unknown architecture"));
|
---|
872 | }
|
---|
873 | #endif
|
---|
874 | |
---|
875 |
|
---|
876 | void
|
---|
877 | md_begin ()
|
---|
878 | {
|
---|
879 | const char *hash_err;
|
---|
880 |
|
---|
881 | /* Initialize op_hash hash table. */
|
---|
882 | op_hash = hash_new ();
|
---|
883 |
|
---|
884 | {
|
---|
885 | const template *optab;
|
---|
886 | templates *core_optab;
|
---|
887 |
|
---|
888 | /* Setup for loop. */
|
---|
889 | optab = i386_optab;
|
---|
890 | core_optab = (templates *) xmalloc (sizeof (templates));
|
---|
891 | core_optab->start = optab;
|
---|
892 |
|
---|
893 | while (1)
|
---|
894 | {
|
---|
895 | ++optab;
|
---|
896 | if (optab->name == NULL
|
---|
897 | || strcmp (optab->name, (optab - 1)->name) != 0)
|
---|
898 | {
|
---|
899 | /* different name --> ship out current template list;
|
---|
900 | add to hash table; & begin anew. */
|
---|
901 | core_optab->end = optab;
|
---|
902 | hash_err = hash_insert (op_hash,
|
---|
903 | (optab - 1)->name,
|
---|
904 | (PTR) core_optab);
|
---|
905 | if (hash_err)
|
---|
906 | {
|
---|
907 | as_fatal (_("Internal Error: Can't hash %s: %s"),
|
---|
908 | (optab - 1)->name,
|
---|
909 | hash_err);
|
---|
910 | }
|
---|
911 | if (optab->name == NULL)
|
---|
912 | break;
|
---|
913 | core_optab = (templates *) xmalloc (sizeof (templates));
|
---|
914 | core_optab->start = optab;
|
---|
915 | }
|
---|
916 | }
|
---|
917 | }
|
---|
918 |
|
---|
919 | /* Initialize reg_hash hash table. */
|
---|
920 | reg_hash = hash_new ();
|
---|
921 | {
|
---|
922 | const reg_entry *regtab;
|
---|
923 |
|
---|
924 | for (regtab = i386_regtab;
|
---|
925 | regtab < i386_regtab + sizeof (i386_regtab) / sizeof (i386_regtab[0]);
|
---|
926 | regtab++)
|
---|
927 | {
|
---|
928 | hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab);
|
---|
929 | if (hash_err)
|
---|
930 | as_fatal (_("Internal Error: Can't hash %s: %s"),
|
---|
931 | regtab->reg_name,
|
---|
932 | hash_err);
|
---|
933 | }
|
---|
934 | }
|
---|
935 |
|
---|
936 | /* Fill in lexical tables: mnemonic_chars, operand_chars. */
|
---|
937 | {
|
---|
938 | int c;
|
---|
939 | char *p;
|
---|
940 |
|
---|
941 | for (c = 0; c < 256; c++)
|
---|
942 | {
|
---|
943 | if (ISDIGIT (c))
|
---|
944 | {
|
---|
945 | digit_chars[c] = c;
|
---|
946 | mnemonic_chars[c] = c;
|
---|
947 | register_chars[c] = c;
|
---|
948 | operand_chars[c] = c;
|
---|
949 | }
|
---|
950 | else if (ISLOWER (c))
|
---|
951 | {
|
---|
952 | mnemonic_chars[c] = c;
|
---|
953 | register_chars[c] = c;
|
---|
954 | operand_chars[c] = c;
|
---|
955 | }
|
---|
956 | else if (ISUPPER (c))
|
---|
957 | {
|
---|
958 | mnemonic_chars[c] = TOLOWER (c);
|
---|
959 | register_chars[c] = mnemonic_chars[c];
|
---|
960 | operand_chars[c] = c;
|
---|
961 | }
|
---|
962 |
|
---|
963 | if (ISALPHA (c) || ISDIGIT (c))
|
---|
964 | identifier_chars[c] = c;
|
---|
965 | else if (c >= 128)
|
---|
966 | {
|
---|
967 | identifier_chars[c] = c;
|
---|
968 | operand_chars[c] = c;
|
---|
969 | }
|
---|
970 | }
|
---|
971 |
|
---|
972 | #ifdef LEX_AT
|
---|
973 | identifier_chars['@'] = '@';
|
---|
974 | #endif
|
---|
975 | digit_chars['-'] = '-';
|
---|
976 | identifier_chars['_'] = '_';
|
---|
977 | identifier_chars['.'] = '.';
|
---|
978 |
|
---|
979 | for (p = operand_special_chars; *p != '\0'; p++)
|
---|
980 | operand_chars[(unsigned char) *p] = *p;
|
---|
981 | }
|
---|
982 |
|
---|
983 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
984 | if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
---|
985 | {
|
---|
986 | record_alignment (text_section, 2);
|
---|
987 | record_alignment (data_section, 2);
|
---|
988 | record_alignment (bss_section, 2);
|
---|
989 | }
|
---|
990 | #endif
|
---|
991 | }
|
---|
992 |
|
---|
993 | void
|
---|
994 | i386_print_statistics (file)
|
---|
995 | FILE *file;
|
---|
996 | {
|
---|
997 | hash_print_statistics (file, "i386 opcode", op_hash);
|
---|
998 | hash_print_statistics (file, "i386 register", reg_hash);
|
---|
999 | }
|
---|
1000 | |
---|
1001 |
|
---|
1002 | #ifdef DEBUG386
|
---|
1003 |
|
---|
1004 | /* Debugging routines for md_assemble. */
|
---|
1005 | static void pi PARAMS ((char *, i386_insn *));
|
---|
1006 | static void pte PARAMS ((template *));
|
---|
1007 | static void pt PARAMS ((unsigned int));
|
---|
1008 | static void pe PARAMS ((expressionS *));
|
---|
1009 | static void ps PARAMS ((symbolS *));
|
---|
1010 |
|
---|
1011 | static void
|
---|
1012 | pi (line, x)
|
---|
1013 | char *line;
|
---|
1014 | i386_insn *x;
|
---|
1015 | {
|
---|
1016 | unsigned int i;
|
---|
1017 |
|
---|
1018 | fprintf (stdout, "%s: template ", line);
|
---|
1019 | pte (&x->tm);
|
---|
1020 | fprintf (stdout, " address: base %s index %s scale %x\n",
|
---|
1021 | x->base_reg ? x->base_reg->reg_name : "none",
|
---|
1022 | x->index_reg ? x->index_reg->reg_name : "none",
|
---|
1023 | x->log2_scale_factor);
|
---|
1024 | fprintf (stdout, " modrm: mode %x reg %x reg/mem %x\n",
|
---|
1025 | x->rm.mode, x->rm.reg, x->rm.regmem);
|
---|
1026 | fprintf (stdout, " sib: base %x index %x scale %x\n",
|
---|
1027 | x->sib.base, x->sib.index, x->sib.scale);
|
---|
1028 | fprintf (stdout, " rex: 64bit %x extX %x extY %x extZ %x\n",
|
---|
1029 | (x->rex & REX_MODE64) != 0,
|
---|
1030 | (x->rex & REX_EXTX) != 0,
|
---|
1031 | (x->rex & REX_EXTY) != 0,
|
---|
1032 | (x->rex & REX_EXTZ) != 0);
|
---|
1033 | for (i = 0; i < x->operands; i++)
|
---|
1034 | {
|
---|
1035 | fprintf (stdout, " #%d: ", i + 1);
|
---|
1036 | pt (x->types[i]);
|
---|
1037 | fprintf (stdout, "\n");
|
---|
1038 | if (x->types[i]
|
---|
1039 | & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX | RegXMM))
|
---|
1040 | fprintf (stdout, "%s\n", x->op[i].regs->reg_name);
|
---|
1041 | if (x->types[i] & Imm)
|
---|
1042 | pe (x->op[i].imms);
|
---|
1043 | if (x->types[i] & Disp)
|
---|
1044 | pe (x->op[i].disps);
|
---|
1045 | }
|
---|
1046 | }
|
---|
1047 |
|
---|
1048 | static void
|
---|
1049 | pte (t)
|
---|
1050 | template *t;
|
---|
1051 | {
|
---|
1052 | unsigned int i;
|
---|
1053 | fprintf (stdout, " %d operands ", t->operands);
|
---|
1054 | fprintf (stdout, "opcode %x ", t->base_opcode);
|
---|
1055 | if (t->extension_opcode != None)
|
---|
1056 | fprintf (stdout, "ext %x ", t->extension_opcode);
|
---|
1057 | if (t->opcode_modifier & D)
|
---|
1058 | fprintf (stdout, "D");
|
---|
1059 | if (t->opcode_modifier & W)
|
---|
1060 | fprintf (stdout, "W");
|
---|
1061 | fprintf (stdout, "\n");
|
---|
1062 | for (i = 0; i < t->operands; i++)
|
---|
1063 | {
|
---|
1064 | fprintf (stdout, " #%d type ", i + 1);
|
---|
1065 | pt (t->operand_types[i]);
|
---|
1066 | fprintf (stdout, "\n");
|
---|
1067 | }
|
---|
1068 | }
|
---|
1069 |
|
---|
1070 | static void
|
---|
1071 | pe (e)
|
---|
1072 | expressionS *e;
|
---|
1073 | {
|
---|
1074 | fprintf (stdout, " operation %d\n", e->X_op);
|
---|
1075 | fprintf (stdout, " add_number %ld (%lx)\n",
|
---|
1076 | (long) e->X_add_number, (long) e->X_add_number);
|
---|
1077 | if (e->X_add_symbol)
|
---|
1078 | {
|
---|
1079 | fprintf (stdout, " add_symbol ");
|
---|
1080 | ps (e->X_add_symbol);
|
---|
1081 | fprintf (stdout, "\n");
|
---|
1082 | }
|
---|
1083 | if (e->X_op_symbol)
|
---|
1084 | {
|
---|
1085 | fprintf (stdout, " op_symbol ");
|
---|
1086 | ps (e->X_op_symbol);
|
---|
1087 | fprintf (stdout, "\n");
|
---|
1088 | }
|
---|
1089 | }
|
---|
1090 |
|
---|
1091 | static void
|
---|
1092 | ps (s)
|
---|
1093 | symbolS *s;
|
---|
1094 | {
|
---|
1095 | fprintf (stdout, "%s type %s%s",
|
---|
1096 | S_GET_NAME (s),
|
---|
1097 | S_IS_EXTERNAL (s) ? "EXTERNAL " : "",
|
---|
1098 | segment_name (S_GET_SEGMENT (s)));
|
---|
1099 | }
|
---|
1100 |
|
---|
1101 | struct type_name
|
---|
1102 | {
|
---|
1103 | unsigned int mask;
|
---|
1104 | char *tname;
|
---|
1105 | }
|
---|
1106 |
|
---|
1107 | static const type_names[] =
|
---|
1108 | {
|
---|
1109 | { Reg8, "r8" },
|
---|
1110 | { Reg16, "r16" },
|
---|
1111 | { Reg32, "r32" },
|
---|
1112 | { Reg64, "r64" },
|
---|
1113 | { Imm8, "i8" },
|
---|
1114 | { Imm8S, "i8s" },
|
---|
1115 | { Imm16, "i16" },
|
---|
1116 | { Imm32, "i32" },
|
---|
1117 | { Imm32S, "i32s" },
|
---|
1118 | { Imm64, "i64" },
|
---|
1119 | { Imm1, "i1" },
|
---|
1120 | { BaseIndex, "BaseIndex" },
|
---|
1121 | { Disp8, "d8" },
|
---|
1122 | { Disp16, "d16" },
|
---|
1123 | { Disp32, "d32" },
|
---|
1124 | { Disp32S, "d32s" },
|
---|
1125 | { Disp64, "d64" },
|
---|
1126 | { InOutPortReg, "InOutPortReg" },
|
---|
1127 | { ShiftCount, "ShiftCount" },
|
---|
1128 | { Control, "control reg" },
|
---|
1129 | { Test, "test reg" },
|
---|
1130 | { Debug, "debug reg" },
|
---|
1131 | { FloatReg, "FReg" },
|
---|
1132 | { FloatAcc, "FAcc" },
|
---|
1133 | { SReg2, "SReg2" },
|
---|
1134 | { SReg3, "SReg3" },
|
---|
1135 | { Acc, "Acc" },
|
---|
1136 | { JumpAbsolute, "Jump Absolute" },
|
---|
1137 | { RegMMX, "rMMX" },
|
---|
1138 | { RegXMM, "rXMM" },
|
---|
1139 | { EsSeg, "es" },
|
---|
1140 | { 0, "" }
|
---|
1141 | };
|
---|
1142 |
|
---|
1143 | static void
|
---|
1144 | pt (t)
|
---|
1145 | unsigned int t;
|
---|
1146 | {
|
---|
1147 | const struct type_name *ty;
|
---|
1148 |
|
---|
1149 | for (ty = type_names; ty->mask; ty++)
|
---|
1150 | if (t & ty->mask)
|
---|
1151 | fprintf (stdout, "%s, ", ty->tname);
|
---|
1152 | fflush (stdout);
|
---|
1153 | }
|
---|
1154 |
|
---|
1155 | #endif /* DEBUG386 */
|
---|
1156 | |
---|
1157 |
|
---|
1158 | #ifdef BFD_ASSEMBLER
|
---|
1159 | static bfd_reloc_code_real_type reloc
|
---|
1160 | PARAMS ((int, int, int, bfd_reloc_code_real_type));
|
---|
1161 |
|
---|
1162 | static bfd_reloc_code_real_type
|
---|
1163 | reloc (size, pcrel, sign, other)
|
---|
1164 | int size;
|
---|
1165 | int pcrel;
|
---|
1166 | int sign;
|
---|
1167 | bfd_reloc_code_real_type other;
|
---|
1168 | {
|
---|
1169 | if (other != NO_RELOC)
|
---|
1170 | return other;
|
---|
1171 |
|
---|
1172 | if (pcrel)
|
---|
1173 | {
|
---|
1174 | if (!sign)
|
---|
1175 | as_bad (_("There are no unsigned pc-relative relocations"));
|
---|
1176 | switch (size)
|
---|
1177 | {
|
---|
1178 | case 1: return BFD_RELOC_8_PCREL;
|
---|
1179 | case 2: return BFD_RELOC_16_PCREL;
|
---|
1180 | case 4: return BFD_RELOC_32_PCREL;
|
---|
1181 | }
|
---|
1182 | as_bad (_("can not do %d byte pc-relative relocation"), size);
|
---|
1183 | }
|
---|
1184 | else
|
---|
1185 | {
|
---|
1186 | if (sign)
|
---|
1187 | switch (size)
|
---|
1188 | {
|
---|
1189 | case 4: return BFD_RELOC_X86_64_32S;
|
---|
1190 | }
|
---|
1191 | else
|
---|
1192 | switch (size)
|
---|
1193 | {
|
---|
1194 | case 1: return BFD_RELOC_8;
|
---|
1195 | case 2: return BFD_RELOC_16;
|
---|
1196 | case 4: return BFD_RELOC_32;
|
---|
1197 | case 8: return BFD_RELOC_64;
|
---|
1198 | }
|
---|
1199 | as_bad (_("can not do %s %d byte relocation"),
|
---|
1200 | sign ? "signed" : "unsigned", size);
|
---|
1201 | }
|
---|
1202 |
|
---|
1203 | abort ();
|
---|
1204 | return BFD_RELOC_NONE;
|
---|
1205 | }
|
---|
1206 |
|
---|
1207 | /* Here we decide which fixups can be adjusted to make them relative to
|
---|
1208 | the beginning of the section instead of the symbol. Basically we need
|
---|
1209 | to make sure that the dynamic relocations are done correctly, so in
|
---|
1210 | some cases we force the original symbol to be used. */
|
---|
1211 |
|
---|
1212 | int
|
---|
1213 | tc_i386_fix_adjustable (fixP)
|
---|
1214 | fixS *fixP ATTRIBUTE_UNUSED;
|
---|
1215 | {
|
---|
1216 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
1217 | if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
|
---|
1218 | return 1;
|
---|
1219 |
|
---|
1220 | /* Don't adjust pc-relative references to merge sections in 64-bit
|
---|
1221 | mode. */
|
---|
1222 | if (use_rela_relocations
|
---|
1223 | && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0
|
---|
1224 | && fixP->fx_pcrel)
|
---|
1225 | return 0;
|
---|
1226 |
|
---|
1227 | /* adjust_reloc_syms doesn't know about the GOT. */
|
---|
1228 | if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
|
---|
1229 | || fixP->fx_r_type == BFD_RELOC_386_PLT32
|
---|
1230 | || fixP->fx_r_type == BFD_RELOC_386_GOT32
|
---|
1231 | || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
|
---|
1232 | || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM
|
---|
1233 | || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32
|
---|
1234 | || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32
|
---|
1235 | || fixP->fx_r_type == BFD_RELOC_386_TLS_IE
|
---|
1236 | || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE
|
---|
1237 | || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
|
---|
1238 | || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
|
---|
1239 | || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
|
---|
1240 | || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
|
---|
1241 | || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
|
---|
1242 | || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD
|
---|
1243 | || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD
|
---|
1244 | || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
|
---|
1245 | || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
|
---|
1246 | || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
|
---|
1247 | || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
---|
1248 | || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
---|
1249 | return 0;
|
---|
1250 | #endif
|
---|
1251 | return 1;
|
---|
1252 | }
|
---|
1253 | #else
|
---|
1254 | #define reloc(SIZE,PCREL,SIGN,OTHER) 0
|
---|
1255 | #define BFD_RELOC_8 0
|
---|
1256 | #define BFD_RELOC_16 0
|
---|
1257 | #define BFD_RELOC_32 0
|
---|
1258 | #define BFD_RELOC_8_PCREL 0
|
---|
1259 | #define BFD_RELOC_16_PCREL 0
|
---|
1260 | #define BFD_RELOC_32_PCREL 0
|
---|
1261 | #define BFD_RELOC_386_PLT32 0
|
---|
1262 | #define BFD_RELOC_386_GOT32 0
|
---|
1263 | #define BFD_RELOC_386_GOTOFF 0
|
---|
1264 | #define BFD_RELOC_386_TLS_GD 0
|
---|
1265 | #define BFD_RELOC_386_TLS_LDM 0
|
---|
1266 | #define BFD_RELOC_386_TLS_LDO_32 0
|
---|
1267 | #define BFD_RELOC_386_TLS_IE_32 0
|
---|
1268 | #define BFD_RELOC_386_TLS_IE 0
|
---|
1269 | #define BFD_RELOC_386_TLS_GOTIE 0
|
---|
1270 | #define BFD_RELOC_386_TLS_LE_32 0
|
---|
1271 | #define BFD_RELOC_386_TLS_LE 0
|
---|
1272 | #define BFD_RELOC_X86_64_PLT32 0
|
---|
1273 | #define BFD_RELOC_X86_64_GOT32 0
|
---|
1274 | #define BFD_RELOC_X86_64_GOTPCREL 0
|
---|
1275 | #define BFD_RELOC_X86_64_TLSGD 0
|
---|
1276 | #define BFD_RELOC_X86_64_TLSLD 0
|
---|
1277 | #define BFD_RELOC_X86_64_DTPOFF32 0
|
---|
1278 | #define BFD_RELOC_X86_64_GOTTPOFF 0
|
---|
1279 | #define BFD_RELOC_X86_64_TPOFF32 0
|
---|
1280 | #endif
|
---|
1281 |
|
---|
1282 | static int intel_float_operand PARAMS ((const char *mnemonic));
|
---|
1283 |
|
---|
1284 | static int
|
---|
1285 | intel_float_operand (mnemonic)
|
---|
1286 | const char *mnemonic;
|
---|
1287 | {
|
---|
1288 | if (mnemonic[0] == 'f' && mnemonic[1] == 'i')
|
---|
1289 | return 2;
|
---|
1290 |
|
---|
1291 | if (mnemonic[0] == 'f')
|
---|
1292 | return 1;
|
---|
1293 |
|
---|
1294 | return 0;
|
---|
1295 | }
|
---|
1296 |
|
---|
1297 | /* This is the guts of the machine-dependent assembler. LINE points to a
|
---|
1298 | machine dependent instruction. This function is supposed to emit
|
---|
1299 | the frags/bytes it assembles to. */
|
---|
1300 |
|
---|
1301 | void
|
---|
1302 | md_assemble (line)
|
---|
1303 | char *line;
|
---|
1304 | {
|
---|
1305 | int j;
|
---|
1306 | char mnemonic[MAX_MNEM_SIZE];
|
---|
1307 |
|
---|
1308 | /* Initialize globals. */
|
---|
1309 | memset (&i, '\0', sizeof (i));
|
---|
1310 | for (j = 0; j < MAX_OPERANDS; j++)
|
---|
1311 | i.reloc[j] = NO_RELOC;
|
---|
1312 | memset (disp_expressions, '\0', sizeof (disp_expressions));
|
---|
1313 | memset (im_expressions, '\0', sizeof (im_expressions));
|
---|
1314 | save_stack_p = save_stack;
|
---|
1315 |
|
---|
1316 | /* First parse an instruction mnemonic & call i386_operand for the operands.
|
---|
1317 | We assume that the scrubber has arranged it so that line[0] is the valid
|
---|
1318 | start of a (possibly prefixed) mnemonic. */
|
---|
1319 |
|
---|
1320 | line = parse_insn (line, mnemonic);
|
---|
1321 | if (line == NULL)
|
---|
1322 | return;
|
---|
1323 |
|
---|
1324 | line = parse_operands (line, mnemonic);
|
---|
1325 | if (line == NULL)
|
---|
1326 | return;
|
---|
1327 |
|
---|
1328 | /* Now we've parsed the mnemonic into a set of templates, and have the
|
---|
1329 | operands at hand. */
|
---|
1330 |
|
---|
1331 | /* All intel opcodes have reversed operands except for "bound" and
|
---|
1332 | "enter". We also don't reverse intersegment "jmp" and "call"
|
---|
1333 | instructions with 2 immediate operands so that the immediate segment
|
---|
1334 | precedes the offset, as it does when in AT&T mode. "enter" and the
|
---|
1335 | intersegment "jmp" and "call" instructions are the only ones that
|
---|
1336 | have two immediate operands. */
|
---|
1337 | if (intel_syntax && i.operands > 1
|
---|
1338 | && (strcmp (mnemonic, "bound") != 0)
|
---|
1339 | && !((i.types[0] & Imm) && (i.types[1] & Imm)))
|
---|
1340 | swap_operands ();
|
---|
1341 |
|
---|
1342 | if (i.imm_operands)
|
---|
1343 | optimize_imm ();
|
---|
1344 |
|
---|
1345 | if (i.disp_operands)
|
---|
1346 | optimize_disp ();
|
---|
1347 |
|
---|
1348 | /* Next, we find a template that matches the given insn,
|
---|
1349 | making sure the overlap of the given operands types is consistent
|
---|
1350 | with the template operand types. */
|
---|
1351 |
|
---|
1352 | if (!match_template ())
|
---|
1353 | return;
|
---|
1354 |
|
---|
1355 | if (intel_syntax)
|
---|
1356 | {
|
---|
1357 | /* Undo SYSV386_COMPAT brokenness when in Intel mode. See i386.h */
|
---|
1358 | if (SYSV386_COMPAT
|
---|
1359 | && (i.tm.base_opcode & 0xfffffde0) == 0xdce0)
|
---|
1360 | i.tm.base_opcode ^= FloatR;
|
---|
1361 |
|
---|
1362 | /* Zap movzx and movsx suffix. The suffix may have been set from
|
---|
1363 | "word ptr" or "byte ptr" on the source operand, but we'll use
|
---|
1364 | the suffix later to choose the destination register. */
|
---|
1365 | if ((i.tm.base_opcode & ~9) == 0x0fb6)
|
---|
1366 | i.suffix = 0;
|
---|
1367 | }
|
---|
1368 |
|
---|
1369 | if (i.tm.opcode_modifier & FWait)
|
---|
1370 | if (!add_prefix (FWAIT_OPCODE))
|
---|
1371 | return;
|
---|
1372 |
|
---|
1373 | /* Check string instruction segment overrides. */
|
---|
1374 | if ((i.tm.opcode_modifier & IsString) != 0 && i.mem_operands != 0)
|
---|
1375 | {
|
---|
1376 | if (!check_string ())
|
---|
1377 | return;
|
---|
1378 | }
|
---|
1379 |
|
---|
1380 | if (!process_suffix ())
|
---|
1381 | return;
|
---|
1382 |
|
---|
1383 | /* Make still unresolved immediate matches conform to size of immediate
|
---|
1384 | given in i.suffix. */
|
---|
1385 | if (!finalize_imm ())
|
---|
1386 | return;
|
---|
1387 |
|
---|
1388 | if (i.types[0] & Imm1)
|
---|
1389 | i.imm_operands = 0; /* kludge for shift insns. */
|
---|
1390 | if (i.types[0] & ImplicitRegister)
|
---|
1391 | i.reg_operands--;
|
---|
1392 | if (i.types[1] & ImplicitRegister)
|
---|
1393 | i.reg_operands--;
|
---|
1394 | if (i.types[2] & ImplicitRegister)
|
---|
1395 | i.reg_operands--;
|
---|
1396 |
|
---|
1397 | if (i.tm.opcode_modifier & ImmExt)
|
---|
1398 | {
|
---|
1399 | /* These AMD 3DNow! and Intel Katmai New Instructions have an
|
---|
1400 | opcode suffix which is coded in the same place as an 8-bit
|
---|
1401 | immediate field would be. Here we fake an 8-bit immediate
|
---|
1402 | operand from the opcode suffix stored in tm.extension_opcode. */
|
---|
1403 |
|
---|
1404 | expressionS *exp;
|
---|
1405 |
|
---|
1406 | assert (i.imm_operands == 0 && i.operands <= 2 && 2 < MAX_OPERANDS);
|
---|
1407 |
|
---|
1408 | exp = &im_expressions[i.imm_operands++];
|
---|
1409 | i.op[i.operands].imms = exp;
|
---|
1410 | i.types[i.operands++] = Imm8;
|
---|
1411 | exp->X_op = O_constant;
|
---|
1412 | exp->X_add_number = i.tm.extension_opcode;
|
---|
1413 | i.tm.extension_opcode = None;
|
---|
1414 | }
|
---|
1415 |
|
---|
1416 | /* For insns with operands there are more diddles to do to the opcode. */
|
---|
1417 | if (i.operands)
|
---|
1418 | {
|
---|
1419 | if (!process_operands ())
|
---|
1420 | return;
|
---|
1421 | }
|
---|
1422 | else if (!quiet_warnings && (i.tm.opcode_modifier & Ugh) != 0)
|
---|
1423 | {
|
---|
1424 | /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc. */
|
---|
1425 | as_warn (_("translating to `%sp'"), i.tm.name);
|
---|
1426 | }
|
---|
1427 |
|
---|
1428 | /* Handle conversion of 'int $3' --> special int3 insn. */
|
---|
1429 | if (i.tm.base_opcode == INT_OPCODE && i.op[0].imms->X_add_number == 3)
|
---|
1430 | {
|
---|
1431 | i.tm.base_opcode = INT3_OPCODE;
|
---|
1432 | i.imm_operands = 0;
|
---|
1433 | }
|
---|
1434 |
|
---|
1435 | if ((i.tm.opcode_modifier & (Jump | JumpByte | JumpDword))
|
---|
1436 | && i.op[0].disps->X_op == O_constant)
|
---|
1437 | {
|
---|
1438 | /* Convert "jmp constant" (and "call constant") to a jump (call) to
|
---|
1439 | the absolute address given by the constant. Since ix86 jumps and
|
---|
1440 | calls are pc relative, we need to generate a reloc. */
|
---|
1441 | i.op[0].disps->X_add_symbol = &abs_symbol;
|
---|
1442 | i.op[0].disps->X_op = O_symbol;
|
---|
1443 | }
|
---|
1444 |
|
---|
1445 | if ((i.tm.opcode_modifier & Rex64) != 0)
|
---|
1446 | i.rex |= REX_MODE64;
|
---|
1447 |
|
---|
1448 | /* For 8 bit registers we need an empty rex prefix. Also if the
|
---|
1449 | instruction already has a prefix, we need to convert old
|
---|
1450 | registers to new ones. */
|
---|
1451 |
|
---|
1452 | if (((i.types[0] & Reg8) != 0
|
---|
1453 | && (i.op[0].regs->reg_flags & RegRex64) != 0)
|
---|
1454 | || ((i.types[1] & Reg8) != 0
|
---|
1455 | && (i.op[1].regs->reg_flags & RegRex64) != 0)
|
---|
1456 | || (((i.types[0] & Reg8) != 0 || (i.types[1] & Reg8) != 0)
|
---|
1457 | && i.rex != 0))
|
---|
1458 | {
|
---|
1459 | int x;
|
---|
1460 |
|
---|
1461 | i.rex |= REX_OPCODE;
|
---|
1462 | for (x = 0; x < 2; x++)
|
---|
1463 | {
|
---|
1464 | /* Look for 8 bit operand that uses old registers. */
|
---|
1465 | if ((i.types[x] & Reg8) != 0
|
---|
1466 | && (i.op[x].regs->reg_flags & RegRex64) == 0)
|
---|
1467 | {
|
---|
1468 | /* In case it is "hi" register, give up. */
|
---|
1469 | if (i.op[x].regs->reg_num > 3)
|
---|
1470 | as_bad (_("can't encode register '%%%s' in an instruction requiring REX prefix.\n"),
|
---|
1471 | i.op[x].regs->reg_name);
|
---|
1472 |
|
---|
1473 | /* Otherwise it is equivalent to the extended register.
|
---|
1474 | Since the encoding doesn't change this is merely
|
---|
1475 | cosmetic cleanup for debug output. */
|
---|
1476 |
|
---|
1477 | i.op[x].regs = i.op[x].regs + 8;
|
---|
1478 | }
|
---|
1479 | }
|
---|
1480 | }
|
---|
1481 |
|
---|
1482 | if (i.rex != 0)
|
---|
1483 | add_prefix (REX_OPCODE | i.rex);
|
---|
1484 |
|
---|
1485 | /* We are ready to output the insn. */
|
---|
1486 | output_insn ();
|
---|
1487 | }
|
---|
1488 |
|
---|
1489 | static char *
|
---|
1490 | parse_insn (line, mnemonic)
|
---|
1491 | char *line;
|
---|
1492 | char *mnemonic;
|
---|
1493 | {
|
---|
1494 | char *l = line;
|
---|
1495 | char *token_start = l;
|
---|
1496 | char *mnem_p;
|
---|
1497 |
|
---|
1498 | /* Non-zero if we found a prefix only acceptable with string insns. */
|
---|
1499 | const char *expecting_string_instruction = NULL;
|
---|
1500 |
|
---|
1501 | while (1)
|
---|
1502 | {
|
---|
1503 | mnem_p = mnemonic;
|
---|
1504 | while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
|
---|
1505 | {
|
---|
1506 | mnem_p++;
|
---|
1507 | if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
|
---|
1508 | {
|
---|
1509 | as_bad (_("no such instruction: `%s'"), token_start);
|
---|
1510 | return NULL;
|
---|
1511 | }
|
---|
1512 | l++;
|
---|
1513 | }
|
---|
1514 | if (!is_space_char (*l)
|
---|
1515 | && *l != END_OF_INSN
|
---|
1516 | && *l != PREFIX_SEPARATOR
|
---|
1517 | && *l != ',')
|
---|
1518 | {
|
---|
1519 | as_bad (_("invalid character %s in mnemonic"),
|
---|
1520 | output_invalid (*l));
|
---|
1521 | return NULL;
|
---|
1522 | }
|
---|
1523 | if (token_start == l)
|
---|
1524 | {
|
---|
1525 | if (*l == PREFIX_SEPARATOR)
|
---|
1526 | as_bad (_("expecting prefix; got nothing"));
|
---|
1527 | else
|
---|
1528 | as_bad (_("expecting mnemonic; got nothing"));
|
---|
1529 | return NULL;
|
---|
1530 | }
|
---|
1531 |
|
---|
1532 | /* Look up instruction (or prefix) via hash table. */
|
---|
1533 | current_templates = hash_find (op_hash, mnemonic);
|
---|
1534 |
|
---|
1535 | if (*l != END_OF_INSN
|
---|
1536 | && (!is_space_char (*l) || l[1] != END_OF_INSN)
|
---|
1537 | && current_templates
|
---|
1538 | && (current_templates->start->opcode_modifier & IsPrefix))
|
---|
1539 | {
|
---|
1540 | /* If we are in 16-bit mode, do not allow addr16 or data16.
|
---|
1541 | Similarly, in 32-bit mode, do not allow addr32 or data32. */
|
---|
1542 | if ((current_templates->start->opcode_modifier & (Size16 | Size32))
|
---|
1543 | && flag_code != CODE_64BIT
|
---|
1544 | && (((current_templates->start->opcode_modifier & Size32) != 0)
|
---|
1545 | ^ (flag_code == CODE_16BIT)))
|
---|
1546 | {
|
---|
1547 | as_bad (_("redundant %s prefix"),
|
---|
1548 | current_templates->start->name);
|
---|
1549 | return NULL;
|
---|
1550 | }
|
---|
1551 | /* Add prefix, checking for repeated prefixes. */
|
---|
1552 | switch (add_prefix (current_templates->start->base_opcode))
|
---|
1553 | {
|
---|
1554 | case 0:
|
---|
1555 | return NULL;
|
---|
1556 | case 2:
|
---|
1557 | expecting_string_instruction = current_templates->start->name;
|
---|
1558 | break;
|
---|
1559 | }
|
---|
1560 | /* Skip past PREFIX_SEPARATOR and reset token_start. */
|
---|
1561 | token_start = ++l;
|
---|
1562 | }
|
---|
1563 | else
|
---|
1564 | break;
|
---|
1565 | }
|
---|
1566 |
|
---|
1567 | if (!current_templates)
|
---|
1568 | {
|
---|
1569 | /* See if we can get a match by trimming off a suffix. */
|
---|
1570 | switch (mnem_p[-1])
|
---|
1571 | {
|
---|
1572 | case WORD_MNEM_SUFFIX:
|
---|
1573 | case BYTE_MNEM_SUFFIX:
|
---|
1574 | case QWORD_MNEM_SUFFIX:
|
---|
1575 | i.suffix = mnem_p[-1];
|
---|
1576 | mnem_p[-1] = '\0';
|
---|
1577 | current_templates = hash_find (op_hash, mnemonic);
|
---|
1578 | break;
|
---|
1579 | case SHORT_MNEM_SUFFIX:
|
---|
1580 | case LONG_MNEM_SUFFIX:
|
---|
1581 | if (!intel_syntax)
|
---|
1582 | {
|
---|
1583 | i.suffix = mnem_p[-1];
|
---|
1584 | mnem_p[-1] = '\0';
|
---|
1585 | current_templates = hash_find (op_hash, mnemonic);
|
---|
1586 | }
|
---|
1587 | break;
|
---|
1588 |
|
---|
1589 | /* Intel Syntax. */
|
---|
1590 | case 'd':
|
---|
1591 | if (intel_syntax)
|
---|
1592 | {
|
---|
1593 | if (intel_float_operand (mnemonic))
|
---|
1594 | i.suffix = SHORT_MNEM_SUFFIX;
|
---|
1595 | else
|
---|
1596 | i.suffix = LONG_MNEM_SUFFIX;
|
---|
1597 | mnem_p[-1] = '\0';
|
---|
1598 | current_templates = hash_find (op_hash, mnemonic);
|
---|
1599 | }
|
---|
1600 | break;
|
---|
1601 | }
|
---|
1602 | if (!current_templates)
|
---|
1603 | {
|
---|
1604 | as_bad (_("no such instruction: `%s'"), token_start);
|
---|
1605 | return NULL;
|
---|
1606 | }
|
---|
1607 | }
|
---|
1608 |
|
---|
1609 | if (current_templates->start->opcode_modifier & (Jump | JumpByte))
|
---|
1610 | {
|
---|
1611 | /* Check for a branch hint. We allow ",pt" and ",pn" for
|
---|
1612 | predict taken and predict not taken respectively.
|
---|
1613 | I'm not sure that branch hints actually do anything on loop
|
---|
1614 | and jcxz insns (JumpByte) for current Pentium4 chips. They
|
---|
1615 | may work in the future and it doesn't hurt to accept them
|
---|
1616 | now. */
|
---|
1617 | if (l[0] == ',' && l[1] == 'p')
|
---|
1618 | {
|
---|
1619 | if (l[2] == 't')
|
---|
1620 | {
|
---|
1621 | if (!add_prefix (DS_PREFIX_OPCODE))
|
---|
1622 | return NULL;
|
---|
1623 | l += 3;
|
---|
1624 | }
|
---|
1625 | else if (l[2] == 'n')
|
---|
1626 | {
|
---|
1627 | if (!add_prefix (CS_PREFIX_OPCODE))
|
---|
1628 | return NULL;
|
---|
1629 | l += 3;
|
---|
1630 | }
|
---|
1631 | }
|
---|
1632 | }
|
---|
1633 | /* Any other comma loses. */
|
---|
1634 | if (*l == ',')
|
---|
1635 | {
|
---|
1636 | as_bad (_("invalid character %s in mnemonic"),
|
---|
1637 | output_invalid (*l));
|
---|
1638 | return NULL;
|
---|
1639 | }
|
---|
1640 |
|
---|
1641 | /* Check if instruction is supported on specified architecture. */
|
---|
1642 | if ((current_templates->start->cpu_flags & ~(Cpu64 | CpuNo64))
|
---|
1643 | & ~(cpu_arch_flags & ~(Cpu64 | CpuNo64)))
|
---|
1644 | {
|
---|
1645 | as_warn (_("`%s' is not supported on `%s'"),
|
---|
1646 | current_templates->start->name, cpu_arch_name);
|
---|
1647 | }
|
---|
1648 | else if ((Cpu386 & ~cpu_arch_flags) && (flag_code != CODE_16BIT))
|
---|
1649 | {
|
---|
1650 | as_warn (_("use .code16 to ensure correct addressing mode"));
|
---|
1651 | }
|
---|
1652 |
|
---|
1653 | /* Check for rep/repne without a string instruction. */
|
---|
1654 | if (expecting_string_instruction
|
---|
1655 | && !(current_templates->start->opcode_modifier & IsString))
|
---|
1656 | {
|
---|
1657 | as_bad (_("expecting string instruction after `%s'"),
|
---|
1658 | expecting_string_instruction);
|
---|
1659 | return NULL;
|
---|
1660 | }
|
---|
1661 |
|
---|
1662 | return l;
|
---|
1663 | }
|
---|
1664 |
|
---|
1665 | static char *
|
---|
1666 | parse_operands (l, mnemonic)
|
---|
1667 | char *l;
|
---|
1668 | const char *mnemonic;
|
---|
1669 | {
|
---|
1670 | char *token_start;
|
---|
1671 |
|
---|
1672 | /* 1 if operand is pending after ','. */
|
---|
1673 | unsigned int expecting_operand = 0;
|
---|
1674 |
|
---|
1675 | /* Non-zero if operand parens not balanced. */
|
---|
1676 | unsigned int paren_not_balanced;
|
---|
1677 |
|
---|
1678 | while (*l != END_OF_INSN)
|
---|
1679 | {
|
---|
1680 | /* Skip optional white space before operand. */
|
---|
1681 | if (is_space_char (*l))
|
---|
1682 | ++l;
|
---|
1683 | if (!is_operand_char (*l) && *l != END_OF_INSN)
|
---|
1684 | {
|
---|
1685 | as_bad (_("invalid character %s before operand %d"),
|
---|
1686 | output_invalid (*l),
|
---|
1687 | i.operands + 1);
|
---|
1688 | return NULL;
|
---|
1689 | }
|
---|
1690 | token_start = l; /* after white space */
|
---|
1691 | paren_not_balanced = 0;
|
---|
1692 | while (paren_not_balanced || *l != ',')
|
---|
1693 | {
|
---|
1694 | if (*l == END_OF_INSN)
|
---|
1695 | {
|
---|
1696 | if (paren_not_balanced)
|
---|
1697 | {
|
---|
1698 | if (!intel_syntax)
|
---|
1699 | as_bad (_("unbalanced parenthesis in operand %d."),
|
---|
1700 | i.operands + 1);
|
---|
1701 | else
|
---|
1702 | as_bad (_("unbalanced brackets in operand %d."),
|
---|
1703 | i.operands + 1);
|
---|
1704 | return NULL;
|
---|
1705 | }
|
---|
1706 | else
|
---|
1707 | break; /* we are done */
|
---|
1708 | }
|
---|
1709 | else if (!is_operand_char (*l) && !is_space_char (*l))
|
---|
1710 | {
|
---|
1711 | as_bad (_("invalid character %s in operand %d"),
|
---|
1712 | output_invalid (*l),
|
---|
1713 | i.operands + 1);
|
---|
1714 | return NULL;
|
---|
1715 | }
|
---|
1716 | if (!intel_syntax)
|
---|
1717 | {
|
---|
1718 | if (*l == '(')
|
---|
1719 | ++paren_not_balanced;
|
---|
1720 | if (*l == ')')
|
---|
1721 | --paren_not_balanced;
|
---|
1722 | }
|
---|
1723 | else
|
---|
1724 | {
|
---|
1725 | if (*l == '[')
|
---|
1726 | ++paren_not_balanced;
|
---|
1727 | if (*l == ']')
|
---|
1728 | --paren_not_balanced;
|
---|
1729 | }
|
---|
1730 | l++;
|
---|
1731 | }
|
---|
1732 | if (l != token_start)
|
---|
1733 | { /* Yes, we've read in another operand. */
|
---|
1734 | unsigned int operand_ok;
|
---|
1735 | this_operand = i.operands++;
|
---|
1736 | if (i.operands > MAX_OPERANDS)
|
---|
1737 | {
|
---|
1738 | as_bad (_("spurious operands; (%d operands/instruction max)"),
|
---|
1739 | MAX_OPERANDS);
|
---|
1740 | return NULL;
|
---|
1741 | }
|
---|
1742 | /* Now parse operand adding info to 'i' as we go along. */
|
---|
1743 | END_STRING_AND_SAVE (l);
|
---|
1744 |
|
---|
1745 | if (intel_syntax)
|
---|
1746 | operand_ok =
|
---|
1747 | i386_intel_operand (token_start,
|
---|
1748 | intel_float_operand (mnemonic));
|
---|
1749 | else
|
---|
1750 | operand_ok = i386_operand (token_start);
|
---|
1751 |
|
---|
1752 | RESTORE_END_STRING (l);
|
---|
1753 | if (!operand_ok)
|
---|
1754 | return NULL;
|
---|
1755 | }
|
---|
1756 | else
|
---|
1757 | {
|
---|
1758 | if (expecting_operand)
|
---|
1759 | {
|
---|
1760 | expecting_operand_after_comma:
|
---|
1761 | as_bad (_("expecting operand after ','; got nothing"));
|
---|
1762 | return NULL;
|
---|
1763 | }
|
---|
1764 | if (*l == ',')
|
---|
1765 | {
|
---|
1766 | as_bad (_("expecting operand before ','; got nothing"));
|
---|
1767 | return NULL;
|
---|
1768 | }
|
---|
1769 | }
|
---|
1770 |
|
---|
1771 | /* Now *l must be either ',' or END_OF_INSN. */
|
---|
1772 | if (*l == ',')
|
---|
1773 | {
|
---|
1774 | if (*++l == END_OF_INSN)
|
---|
1775 | {
|
---|
1776 | /* Just skip it, if it's \n complain. */
|
---|
1777 | goto expecting_operand_after_comma;
|
---|
1778 | }
|
---|
1779 | expecting_operand = 1;
|
---|
1780 | }
|
---|
1781 | }
|
---|
1782 | return l;
|
---|
1783 | }
|
---|
1784 |
|
---|
1785 | static void
|
---|
1786 | swap_operands ()
|
---|
1787 | {
|
---|
1788 | union i386_op temp_op;
|
---|
1789 | unsigned int temp_type;
|
---|
1790 | RELOC_ENUM temp_reloc;
|
---|
1791 | int xchg1 = 0;
|
---|
1792 | int xchg2 = 0;
|
---|
1793 |
|
---|
1794 | if (i.operands == 2)
|
---|
1795 | {
|
---|
1796 | xchg1 = 0;
|
---|
1797 | xchg2 = 1;
|
---|
1798 | }
|
---|
1799 | else if (i.operands == 3)
|
---|
1800 | {
|
---|
1801 | xchg1 = 0;
|
---|
1802 | xchg2 = 2;
|
---|
1803 | }
|
---|
1804 | temp_type = i.types[xchg2];
|
---|
1805 | i.types[xchg2] = i.types[xchg1];
|
---|
1806 | i.types[xchg1] = temp_type;
|
---|
1807 | temp_op = i.op[xchg2];
|
---|
1808 | i.op[xchg2] = i.op[xchg1];
|
---|
1809 | i.op[xchg1] = temp_op;
|
---|
1810 | temp_reloc = i.reloc[xchg2];
|
---|
1811 | i.reloc[xchg2] = i.reloc[xchg1];
|
---|
1812 | i.reloc[xchg1] = temp_reloc;
|
---|
1813 |
|
---|
1814 | if (i.mem_operands == 2)
|
---|
1815 | {
|
---|
1816 | const seg_entry *temp_seg;
|
---|
1817 | temp_seg = i.seg[0];
|
---|
1818 | i.seg[0] = i.seg[1];
|
---|
1819 | i.seg[1] = temp_seg;
|
---|
1820 | }
|
---|
1821 | }
|
---|
1822 |
|
---|
1823 | /* Try to ensure constant immediates are represented in the smallest
|
---|
1824 | opcode possible. */
|
---|
1825 | static void
|
---|
1826 | optimize_imm ()
|
---|
1827 | {
|
---|
1828 | char guess_suffix = 0;
|
---|
1829 | int op;
|
---|
1830 |
|
---|
1831 | if (i.suffix)
|
---|
1832 | guess_suffix = i.suffix;
|
---|
1833 | else if (i.reg_operands)
|
---|
1834 | {
|
---|
1835 | /* Figure out a suffix from the last register operand specified.
|
---|
1836 | We can't do this properly yet, ie. excluding InOutPortReg,
|
---|
1837 | but the following works for instructions with immediates.
|
---|
1838 | In any case, we can't set i.suffix yet. */
|
---|
1839 | for (op = i.operands; --op >= 0;)
|
---|
1840 | if (i.types[op] & Reg)
|
---|
1841 | {
|
---|
1842 | if (i.types[op] & Reg8)
|
---|
1843 | guess_suffix = BYTE_MNEM_SUFFIX;
|
---|
1844 | else if (i.types[op] & Reg16)
|
---|
1845 | guess_suffix = WORD_MNEM_SUFFIX;
|
---|
1846 | else if (i.types[op] & Reg32)
|
---|
1847 | guess_suffix = LONG_MNEM_SUFFIX;
|
---|
1848 | else if (i.types[op] & Reg64)
|
---|
1849 | guess_suffix = QWORD_MNEM_SUFFIX;
|
---|
1850 | break;
|
---|
1851 | }
|
---|
1852 | }
|
---|
1853 | else if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
|
---|
1854 | guess_suffix = WORD_MNEM_SUFFIX;
|
---|
1855 |
|
---|
1856 | for (op = i.operands; --op >= 0;)
|
---|
1857 | if (i.types[op] & Imm)
|
---|
1858 | {
|
---|
1859 | switch (i.op[op].imms->X_op)
|
---|
1860 | {
|
---|
1861 | case O_constant:
|
---|
1862 | /* If a suffix is given, this operand may be shortened. */
|
---|
1863 | switch (guess_suffix)
|
---|
1864 | {
|
---|
1865 | case LONG_MNEM_SUFFIX:
|
---|
1866 | i.types[op] |= Imm32 | Imm64;
|
---|
1867 | break;
|
---|
1868 | case WORD_MNEM_SUFFIX:
|
---|
1869 | i.types[op] |= Imm16 | Imm32S | Imm32 | Imm64;
|
---|
1870 | break;
|
---|
1871 | case BYTE_MNEM_SUFFIX:
|
---|
1872 | i.types[op] |= Imm16 | Imm8 | Imm8S | Imm32S | Imm32 | Imm64;
|
---|
1873 | break;
|
---|
1874 | }
|
---|
1875 |
|
---|
1876 | /* If this operand is at most 16 bits, convert it
|
---|
1877 | to a signed 16 bit number before trying to see
|
---|
1878 | whether it will fit in an even smaller size.
|
---|
1879 | This allows a 16-bit operand such as $0xffe0 to
|
---|
1880 | be recognised as within Imm8S range. */
|
---|
1881 | if ((i.types[op] & Imm16)
|
---|
1882 | && (i.op[op].imms->X_add_number & ~(offsetT) 0xffff) == 0)
|
---|
1883 | {
|
---|
1884 | i.op[op].imms->X_add_number =
|
---|
1885 | (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000);
|
---|
1886 | }
|
---|
1887 | if ((i.types[op] & Imm32)
|
---|
1888 | && ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1))
|
---|
1889 | == 0))
|
---|
1890 | {
|
---|
1891 | i.op[op].imms->X_add_number = ((i.op[op].imms->X_add_number
|
---|
1892 | ^ ((offsetT) 1 << 31))
|
---|
1893 | - ((offsetT) 1 << 31));
|
---|
1894 | }
|
---|
1895 | i.types[op] |= smallest_imm_type (i.op[op].imms->X_add_number);
|
---|
1896 |
|
---|
1897 | /* We must avoid matching of Imm32 templates when 64bit
|
---|
1898 | only immediate is available. */
|
---|
1899 | if (guess_suffix == QWORD_MNEM_SUFFIX)
|
---|
1900 | i.types[op] &= ~Imm32;
|
---|
1901 | break;
|
---|
1902 |
|
---|
1903 | case O_absent:
|
---|
1904 | case O_register:
|
---|
1905 | abort ();
|
---|
1906 |
|
---|
1907 | /* Symbols and expressions. */
|
---|
1908 | default:
|
---|
1909 | /* Convert symbolic operand to proper sizes for matching. */
|
---|
1910 | switch (guess_suffix)
|
---|
1911 | {
|
---|
1912 | case QWORD_MNEM_SUFFIX:
|
---|
1913 | i.types[op] = Imm64 | Imm32S;
|
---|
1914 | break;
|
---|
1915 | case LONG_MNEM_SUFFIX:
|
---|
1916 | i.types[op] = Imm32 | Imm64;
|
---|
1917 | break;
|
---|
1918 | case WORD_MNEM_SUFFIX:
|
---|
1919 | i.types[op] = Imm16 | Imm32 | Imm64;
|
---|
1920 | break;
|
---|
1921 | break;
|
---|
1922 | case BYTE_MNEM_SUFFIX:
|
---|
1923 | i.types[op] = Imm8 | Imm8S | Imm16 | Imm32S | Imm32;
|
---|
1924 | break;
|
---|
1925 | break;
|
---|
1926 | }
|
---|
1927 | break;
|
---|
1928 | }
|
---|
1929 | }
|
---|
1930 | }
|
---|
1931 |
|
---|
1932 | /* Try to use the smallest displacement type too. */
|
---|
1933 | static void
|
---|
1934 | optimize_disp ()
|
---|
1935 | {
|
---|
1936 | int op;
|
---|
1937 |
|
---|
1938 | for (op = i.operands; --op >= 0;)
|
---|
1939 | if ((i.types[op] & Disp) && i.op[op].disps->X_op == O_constant)
|
---|
1940 | {
|
---|
1941 | offsetT disp = i.op[op].disps->X_add_number;
|
---|
1942 |
|
---|
1943 | if (i.types[op] & Disp16)
|
---|
1944 | {
|
---|
1945 | /* We know this operand is at most 16 bits, so
|
---|
1946 | convert to a signed 16 bit number before trying
|
---|
1947 | to see whether it will fit in an even smaller
|
---|
1948 | size. */
|
---|
1949 |
|
---|
1950 | disp = (((disp & 0xffff) ^ 0x8000) - 0x8000);
|
---|
1951 | }
|
---|
1952 | else if (i.types[op] & Disp32)
|
---|
1953 | {
|
---|
1954 | /* We know this operand is at most 32 bits, so convert to a
|
---|
1955 | signed 32 bit number before trying to see whether it will
|
---|
1956 | fit in an even smaller size. */
|
---|
1957 | disp &= (((offsetT) 2 << 31) - 1);
|
---|
1958 | disp = (disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31);
|
---|
1959 | }
|
---|
1960 | if (flag_code == CODE_64BIT)
|
---|
1961 | {
|
---|
1962 | if (fits_in_signed_long (disp))
|
---|
1963 | i.types[op] |= Disp32S;
|
---|
1964 | if (fits_in_unsigned_long (disp))
|
---|
1965 | i.types[op] |= Disp32;
|
---|
1966 | }
|
---|
1967 | if ((i.types[op] & (Disp32 | Disp32S | Disp16))
|
---|
1968 | && fits_in_signed_byte (disp))
|
---|
1969 | i.types[op] |= Disp8;
|
---|
1970 | }
|
---|
1971 | }
|
---|
1972 |
|
---|
1973 | static int
|
---|
1974 | match_template ()
|
---|
1975 | {
|
---|
1976 | /* Points to template once we've found it. */
|
---|
1977 | const template *t;
|
---|
1978 | unsigned int overlap0, overlap1, overlap2;
|
---|
1979 | unsigned int found_reverse_match;
|
---|
1980 | int suffix_check;
|
---|
1981 |
|
---|
1982 | #define MATCH(overlap, given, template) \
|
---|
1983 | ((overlap & ~JumpAbsolute) \
|
---|
1984 | && (((given) & (BaseIndex | JumpAbsolute)) \
|
---|
1985 | == ((overlap) & (BaseIndex | JumpAbsolute))))
|
---|
1986 |
|
---|
1987 | /* If given types r0 and r1 are registers they must be of the same type
|
---|
1988 | unless the expected operand type register overlap is null.
|
---|
1989 | Note that Acc in a template matches every size of reg. */
|
---|
1990 | #define CONSISTENT_REGISTER_MATCH(m0, g0, t0, m1, g1, t1) \
|
---|
1991 | (((g0) & Reg) == 0 || ((g1) & Reg) == 0 \
|
---|
1992 | || ((g0) & Reg) == ((g1) & Reg) \
|
---|
1993 | || ((((m0) & Acc) ? Reg : (t0)) & (((m1) & Acc) ? Reg : (t1)) & Reg) == 0 )
|
---|
1994 |
|
---|
1995 | overlap0 = 0;
|
---|
1996 | overlap1 = 0;
|
---|
1997 | overlap2 = 0;
|
---|
1998 | found_reverse_match = 0;
|
---|
1999 | suffix_check = (i.suffix == BYTE_MNEM_SUFFIX
|
---|
2000 | ? No_bSuf
|
---|
2001 | : (i.suffix == WORD_MNEM_SUFFIX
|
---|
2002 | ? No_wSuf
|
---|
2003 | : (i.suffix == SHORT_MNEM_SUFFIX
|
---|
2004 | ? No_sSuf
|
---|
2005 | : (i.suffix == LONG_MNEM_SUFFIX
|
---|
2006 | ? No_lSuf
|
---|
2007 | : (i.suffix == QWORD_MNEM_SUFFIX
|
---|
2008 | ? No_qSuf
|
---|
2009 | : (i.suffix == LONG_DOUBLE_MNEM_SUFFIX
|
---|
2010 | ? No_xSuf : 0))))));
|
---|
2011 |
|
---|
2012 | for (t = current_templates->start;
|
---|
2013 | t < current_templates->end;
|
---|
2014 | t++)
|
---|
2015 | {
|
---|
2016 | /* Must have right number of operands. */
|
---|
2017 | if (i.operands != t->operands)
|
---|
2018 | continue;
|
---|
2019 |
|
---|
2020 | /* Check the suffix, except for some instructions in intel mode. */
|
---|
2021 | if ((t->opcode_modifier & suffix_check)
|
---|
2022 | && !(intel_syntax
|
---|
2023 | && (t->opcode_modifier & IgnoreSize))
|
---|
2024 | && !(intel_syntax
|
---|
2025 | && t->base_opcode == 0xd9
|
---|
2026 | && (t->extension_opcode == 5 /* 0xd9,5 "fldcw" */
|
---|
2027 | || t->extension_opcode == 7))) /* 0xd9,7 "f{n}stcw" */
|
---|
2028 | continue;
|
---|
2029 |
|
---|
2030 | /* Do not verify operands when there are none. */
|
---|
2031 | else if (!t->operands)
|
---|
2032 | {
|
---|
2033 | if (t->cpu_flags & ~cpu_arch_flags)
|
---|
2034 | continue;
|
---|
2035 | /* We've found a match; break out of loop. */
|
---|
2036 | break;
|
---|
2037 | }
|
---|
2038 |
|
---|
2039 | overlap0 = i.types[0] & t->operand_types[0];
|
---|
2040 | switch (t->operands)
|
---|
2041 | {
|
---|
2042 | case 1:
|
---|
2043 | if (!MATCH (overlap0, i.types[0], t->operand_types[0]))
|
---|
2044 | continue;
|
---|
2045 | break;
|
---|
2046 | case 2:
|
---|
2047 | case 3:
|
---|
2048 | overlap1 = i.types[1] & t->operand_types[1];
|
---|
2049 | if (!MATCH (overlap0, i.types[0], t->operand_types[0])
|
---|
2050 | || !MATCH (overlap1, i.types[1], t->operand_types[1])
|
---|
2051 | || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
|
---|
2052 | t->operand_types[0],
|
---|
2053 | overlap1, i.types[1],
|
---|
2054 | t->operand_types[1]))
|
---|
2055 | {
|
---|
2056 | /* Check if other direction is valid ... */
|
---|
2057 | if ((t->opcode_modifier & (D | FloatD)) == 0)
|
---|
2058 | continue;
|
---|
2059 |
|
---|
2060 | /* Try reversing direction of operands. */
|
---|
2061 | overlap0 = i.types[0] & t->operand_types[1];
|
---|
2062 | overlap1 = i.types[1] & t->operand_types[0];
|
---|
2063 | if (!MATCH (overlap0, i.types[0], t->operand_types[1])
|
---|
2064 | || !MATCH (overlap1, i.types[1], t->operand_types[0])
|
---|
2065 | || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
|
---|
2066 | t->operand_types[1],
|
---|
2067 | overlap1, i.types[1],
|
---|
2068 | t->operand_types[0]))
|
---|
2069 | {
|
---|
2070 | /* Does not match either direction. */
|
---|
2071 | continue;
|
---|
2072 | }
|
---|
2073 | /* found_reverse_match holds which of D or FloatDR
|
---|
2074 | we've found. */
|
---|
2075 | found_reverse_match = t->opcode_modifier & (D | FloatDR);
|
---|
2076 | }
|
---|
2077 | /* Found a forward 2 operand match here. */
|
---|
2078 | else if (t->operands == 3)
|
---|
2079 | {
|
---|
2080 | /* Here we make use of the fact that there are no
|
---|
2081 | reverse match 3 operand instructions, and all 3
|
---|
2082 | operand instructions only need to be checked for
|
---|
2083 | register consistency between operands 2 and 3. */
|
---|
2084 | overlap2 = i.types[2] & t->operand_types[2];
|
---|
2085 | if (!MATCH (overlap2, i.types[2], t->operand_types[2])
|
---|
2086 | || !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1],
|
---|
2087 | t->operand_types[1],
|
---|
2088 | overlap2, i.types[2],
|
---|
2089 | t->operand_types[2]))
|
---|
2090 |
|
---|
2091 | continue;
|
---|
2092 | }
|
---|
2093 | /* Found either forward/reverse 2 or 3 operand match here:
|
---|
2094 | slip through to break. */
|
---|
2095 | }
|
---|
2096 | if (t->cpu_flags & ~cpu_arch_flags)
|
---|
2097 | {
|
---|
2098 | found_reverse_match = 0;
|
---|
2099 | continue;
|
---|
2100 | }
|
---|
2101 | /* We've found a match; break out of loop. */
|
---|
2102 | break;
|
---|
2103 | }
|
---|
2104 |
|
---|
2105 | if (t == current_templates->end)
|
---|
2106 | {
|
---|
2107 | /* We found no match. */
|
---|
2108 | as_bad (_("suffix or operands invalid for `%s'"),
|
---|
2109 | current_templates->start->name);
|
---|
2110 | return 0;
|
---|
2111 | }
|
---|
2112 |
|
---|
2113 | if (!quiet_warnings)
|
---|
2114 | {
|
---|
2115 | if (!intel_syntax
|
---|
2116 | && ((i.types[0] & JumpAbsolute)
|
---|
2117 | != (t->operand_types[0] & JumpAbsolute)))
|
---|
2118 | {
|
---|
2119 | as_warn (_("indirect %s without `*'"), t->name);
|
---|
2120 | }
|
---|
2121 |
|
---|
2122 | if ((t->opcode_modifier & (IsPrefix | IgnoreSize))
|
---|
2123 | == (IsPrefix | IgnoreSize))
|
---|
2124 | {
|
---|
2125 | /* Warn them that a data or address size prefix doesn't
|
---|
2126 | affect assembly of the next line of code. */
|
---|
2127 | as_warn (_("stand-alone `%s' prefix"), t->name);
|
---|
2128 | }
|
---|
2129 | }
|
---|
2130 |
|
---|
2131 | /* Copy the template we found. */
|
---|
2132 | i.tm = *t;
|
---|
2133 | if (found_reverse_match)
|
---|
2134 | {
|
---|
2135 | /* If we found a reverse match we must alter the opcode
|
---|
2136 | direction bit. found_reverse_match holds bits to change
|
---|
2137 | (different for int & float insns). */
|
---|
2138 |
|
---|
2139 | i.tm.base_opcode ^= found_reverse_match;
|
---|
2140 |
|
---|
2141 | i.tm.operand_types[0] = t->operand_types[1];
|
---|
2142 | i.tm.operand_types[1] = t->operand_types[0];
|
---|
2143 | }
|
---|
2144 |
|
---|
2145 | return 1;
|
---|
2146 | }
|
---|
2147 |
|
---|
2148 | static int
|
---|
2149 | check_string ()
|
---|
2150 | {
|
---|
2151 | int mem_op = (i.types[0] & AnyMem) ? 0 : 1;
|
---|
2152 | if ((i.tm.operand_types[mem_op] & EsSeg) != 0)
|
---|
2153 | {
|
---|
2154 | if (i.seg[0] != NULL && i.seg[0] != &es)
|
---|
2155 | {
|
---|
2156 | as_bad (_("`%s' operand %d must use `%%es' segment"),
|
---|
2157 | i.tm.name,
|
---|
2158 | mem_op + 1);
|
---|
2159 | return 0;
|
---|
2160 | }
|
---|
2161 | /* There's only ever one segment override allowed per instruction.
|
---|
2162 | This instruction possibly has a legal segment override on the
|
---|
2163 | second operand, so copy the segment to where non-string
|
---|
2164 | instructions store it, allowing common code. */
|
---|
2165 | i.seg[0] = i.seg[1];
|
---|
2166 | }
|
---|
2167 | else if ((i.tm.operand_types[mem_op + 1] & EsSeg) != 0)
|
---|
2168 | {
|
---|
2169 | if (i.seg[1] != NULL && i.seg[1] != &es)
|
---|
2170 | {
|
---|
2171 | as_bad (_("`%s' operand %d must use `%%es' segment"),
|
---|
2172 | i.tm.name,
|
---|
2173 | mem_op + 2);
|
---|
2174 | return 0;
|
---|
2175 | }
|
---|
2176 | }
|
---|
2177 | return 1;
|
---|
2178 | }
|
---|
2179 |
|
---|
2180 | static int
|
---|
2181 | process_suffix ()
|
---|
2182 | {
|
---|
2183 | /* If matched instruction specifies an explicit instruction mnemonic
|
---|
2184 | suffix, use it. */
|
---|
2185 | if (i.tm.opcode_modifier & (Size16 | Size32 | Size64))
|
---|
2186 | {
|
---|
2187 | if (i.tm.opcode_modifier & Size16)
|
---|
2188 | i.suffix = WORD_MNEM_SUFFIX;
|
---|
2189 | else if (i.tm.opcode_modifier & Size64)
|
---|
2190 | i.suffix = QWORD_MNEM_SUFFIX;
|
---|
2191 | else
|
---|
2192 | i.suffix = LONG_MNEM_SUFFIX;
|
---|
2193 | }
|
---|
2194 | else if (i.reg_operands)
|
---|
2195 | {
|
---|
2196 | /* If there's no instruction mnemonic suffix we try to invent one
|
---|
2197 | based on register operands. */
|
---|
2198 | if (!i.suffix)
|
---|
2199 | {
|
---|
2200 | /* We take i.suffix from the last register operand specified,
|
---|
2201 | Destination register type is more significant than source
|
---|
2202 | register type. */
|
---|
2203 | int op;
|
---|
2204 | for (op = i.operands; --op >= 0;)
|
---|
2205 | if ((i.types[op] & Reg)
|
---|
2206 | && !(i.tm.operand_types[op] & InOutPortReg))
|
---|
2207 | {
|
---|
2208 | i.suffix = ((i.types[op] & Reg8) ? BYTE_MNEM_SUFFIX :
|
---|
2209 | (i.types[op] & Reg16) ? WORD_MNEM_SUFFIX :
|
---|
2210 | (i.types[op] & Reg64) ? QWORD_MNEM_SUFFIX :
|
---|
2211 | LONG_MNEM_SUFFIX);
|
---|
2212 | break;
|
---|
2213 | }
|
---|
2214 | }
|
---|
2215 | else if (i.suffix == BYTE_MNEM_SUFFIX)
|
---|
2216 | {
|
---|
2217 | if (!check_byte_reg ())
|
---|
2218 | return 0;
|
---|
2219 | }
|
---|
2220 | else if (i.suffix == LONG_MNEM_SUFFIX)
|
---|
2221 | {
|
---|
2222 | if (!check_long_reg ())
|
---|
2223 | return 0;
|
---|
2224 | }
|
---|
2225 | else if (i.suffix == QWORD_MNEM_SUFFIX)
|
---|
2226 | {
|
---|
2227 | if (!check_qword_reg ())
|
---|
2228 | return 0;
|
---|
2229 | }
|
---|
2230 | else if (i.suffix == WORD_MNEM_SUFFIX)
|
---|
2231 | {
|
---|
2232 | if (!check_word_reg ())
|
---|
2233 | return 0;
|
---|
2234 | }
|
---|
2235 | else if (intel_syntax && (i.tm.opcode_modifier & IgnoreSize))
|
---|
2236 | /* Do nothing if the instruction is going to ignore the prefix. */
|
---|
2237 | ;
|
---|
2238 | else
|
---|
2239 | abort ();
|
---|
2240 | }
|
---|
2241 | else if ((i.tm.opcode_modifier & DefaultSize) && !i.suffix)
|
---|
2242 | {
|
---|
2243 | i.suffix = stackop_size;
|
---|
2244 | }
|
---|
2245 |
|
---|
2246 | /* Change the opcode based on the operand size given by i.suffix;
|
---|
2247 | We need not change things for byte insns. */
|
---|
2248 |
|
---|
2249 | if (!i.suffix && (i.tm.opcode_modifier & W))
|
---|
2250 | {
|
---|
2251 | as_bad (_("no instruction mnemonic suffix given and no register operands; can't size instruction"));
|
---|
2252 | return 0;
|
---|
2253 | }
|
---|
2254 |
|
---|
2255 | if (i.suffix && i.suffix != BYTE_MNEM_SUFFIX)
|
---|
2256 | {
|
---|
2257 | /* It's not a byte, select word/dword operation. */
|
---|
2258 | if (i.tm.opcode_modifier & W)
|
---|
2259 | {
|
---|
2260 | if (i.tm.opcode_modifier & ShortForm)
|
---|
2261 | i.tm.base_opcode |= 8;
|
---|
2262 | else
|
---|
2263 | i.tm.base_opcode |= 1;
|
---|
2264 | }
|
---|
2265 |
|
---|
2266 | /* Now select between word & dword operations via the operand
|
---|
2267 | size prefix, except for instructions that will ignore this
|
---|
2268 | prefix anyway. */
|
---|
2269 | if (i.suffix != QWORD_MNEM_SUFFIX
|
---|
2270 | && !(i.tm.opcode_modifier & IgnoreSize)
|
---|
2271 | && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
|
---|
2272 | || (flag_code == CODE_64BIT
|
---|
2273 | && (i.tm.opcode_modifier & JumpByte))))
|
---|
2274 | {
|
---|
2275 | unsigned int prefix = DATA_PREFIX_OPCODE;
|
---|
2276 | if (i.tm.opcode_modifier & JumpByte) /* jcxz, loop */
|
---|
2277 | prefix = ADDR_PREFIX_OPCODE;
|
---|
2278 |
|
---|
2279 | if (!add_prefix (prefix))
|
---|
2280 | return 0;
|
---|
2281 | }
|
---|
2282 |
|
---|
2283 | /* Set mode64 for an operand. */
|
---|
2284 | if (i.suffix == QWORD_MNEM_SUFFIX
|
---|
2285 | && flag_code == CODE_64BIT
|
---|
2286 | && (i.tm.opcode_modifier & NoRex64) == 0)
|
---|
2287 | i.rex |= REX_MODE64;
|
---|
2288 |
|
---|
2289 | /* Size floating point instruction. */
|
---|
2290 | if (i.suffix == LONG_MNEM_SUFFIX)
|
---|
2291 | {
|
---|
2292 | if (i.tm.opcode_modifier & FloatMF)
|
---|
2293 | i.tm.base_opcode ^= 4;
|
---|
2294 | }
|
---|
2295 | }
|
---|
2296 |
|
---|
2297 | return 1;
|
---|
2298 | }
|
---|
2299 |
|
---|
2300 | static int
|
---|
2301 | check_byte_reg ()
|
---|
2302 | {
|
---|
2303 | int op;
|
---|
2304 | for (op = i.operands; --op >= 0;)
|
---|
2305 | {
|
---|
2306 | /* If this is an eight bit register, it's OK. If it's the 16 or
|
---|
2307 | 32 bit version of an eight bit register, we will just use the
|
---|
2308 | low portion, and that's OK too. */
|
---|
2309 | if (i.types[op] & Reg8)
|
---|
2310 | continue;
|
---|
2311 |
|
---|
2312 | /* movzx and movsx should not generate this warning. */
|
---|
2313 | if (intel_syntax
|
---|
2314 | && (i.tm.base_opcode == 0xfb7
|
---|
2315 | || i.tm.base_opcode == 0xfb6
|
---|
2316 | || i.tm.base_opcode == 0x63
|
---|
2317 | || i.tm.base_opcode == 0xfbe
|
---|
2318 | || i.tm.base_opcode == 0xfbf))
|
---|
2319 | continue;
|
---|
2320 |
|
---|
2321 | if ((i.types[op] & WordReg) && i.op[op].regs->reg_num < 4
|
---|
2322 | #if 0
|
---|
2323 | /* Check that the template allows eight bit regs. This
|
---|
2324 | kills insns such as `orb $1,%edx', which maybe should be
|
---|
2325 | allowed. */
|
---|
2326 | && (i.tm.operand_types[op] & (Reg8 | InOutPortReg))
|
---|
2327 | #endif
|
---|
2328 | )
|
---|
2329 | {
|
---|
2330 | /* Prohibit these changes in the 64bit mode, since the
|
---|
2331 | lowering is more complicated. */
|
---|
2332 | if (flag_code == CODE_64BIT
|
---|
2333 | && (i.tm.operand_types[op] & InOutPortReg) == 0)
|
---|
2334 | {
|
---|
2335 | as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
|
---|
2336 | i.op[op].regs->reg_name,
|
---|
2337 | i.suffix);
|
---|
2338 | return 0;
|
---|
2339 | }
|
---|
2340 | #if REGISTER_WARNINGS
|
---|
2341 | if (!quiet_warnings
|
---|
2342 | && (i.tm.operand_types[op] & InOutPortReg) == 0)
|
---|
2343 | as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
|
---|
2344 | (i.op[op].regs + (i.types[op] & Reg16
|
---|
2345 | ? REGNAM_AL - REGNAM_AX
|
---|
2346 | : REGNAM_AL - REGNAM_EAX))->reg_name,
|
---|
2347 | i.op[op].regs->reg_name,
|
---|
2348 | i.suffix);
|
---|
2349 | #endif
|
---|
2350 | continue;
|
---|
2351 | }
|
---|
2352 | /* Any other register is bad. */
|
---|
2353 | if (i.types[op] & (Reg | RegMMX | RegXMM
|
---|
2354 | | SReg2 | SReg3
|
---|
2355 | | Control | Debug | Test
|
---|
2356 | | FloatReg | FloatAcc))
|
---|
2357 | {
|
---|
2358 | as_bad (_("`%%%s' not allowed with `%s%c'"),
|
---|
2359 | i.op[op].regs->reg_name,
|
---|
2360 | i.tm.name,
|
---|
2361 | i.suffix);
|
---|
2362 | return 0;
|
---|
2363 | }
|
---|
2364 | }
|
---|
2365 | return 1;
|
---|
2366 | }
|
---|
2367 |
|
---|
2368 | static int
|
---|
2369 | check_long_reg ()
|
---|
2370 | {
|
---|
2371 | int op;
|
---|
2372 |
|
---|
2373 | for (op = i.operands; --op >= 0;)
|
---|
2374 | /* Reject eight bit registers, except where the template requires
|
---|
2375 | them. (eg. movzb) */
|
---|
2376 | if ((i.types[op] & Reg8) != 0
|
---|
2377 | && (i.tm.operand_types[op] & (Reg16 | Reg32 | Acc)) != 0)
|
---|
2378 | {
|
---|
2379 | as_bad (_("`%%%s' not allowed with `%s%c'"),
|
---|
2380 | i.op[op].regs->reg_name,
|
---|
2381 | i.tm.name,
|
---|
2382 | i.suffix);
|
---|
2383 | return 0;
|
---|
2384 | }
|
---|
2385 | /* Warn if the e prefix on a general reg is missing. */
|
---|
2386 | else if ((!quiet_warnings || flag_code == CODE_64BIT)
|
---|
2387 | && (i.types[op] & Reg16) != 0
|
---|
2388 | && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
|
---|
2389 | {
|
---|
2390 | /* Prohibit these changes in the 64bit mode, since the
|
---|
2391 | lowering is more complicated. */
|
---|
2392 | if (flag_code == CODE_64BIT)
|
---|
2393 | {
|
---|
2394 | as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
|
---|
2395 | i.op[op].regs->reg_name,
|
---|
2396 | i.suffix);
|
---|
2397 | return 0;
|
---|
2398 | }
|
---|
2399 | #if REGISTER_WARNINGS
|
---|
2400 | else
|
---|
2401 | as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
|
---|
2402 | (i.op[op].regs + REGNAM_EAX - REGNAM_AX)->reg_name,
|
---|
2403 | i.op[op].regs->reg_name,
|
---|
2404 | i.suffix);
|
---|
2405 | #endif
|
---|
2406 | }
|
---|
2407 | /* Warn if the r prefix on a general reg is missing. */
|
---|
2408 | else if ((i.types[op] & Reg64) != 0
|
---|
2409 | && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
|
---|
2410 | {
|
---|
2411 | as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
|
---|
2412 | i.op[op].regs->reg_name,
|
---|
2413 | i.suffix);
|
---|
2414 | return 0;
|
---|
2415 | }
|
---|
2416 | return 1;
|
---|
2417 | }
|
---|
2418 |
|
---|
2419 | static int
|
---|
2420 | check_qword_reg ()
|
---|
2421 | {
|
---|
2422 | int op;
|
---|
2423 |
|
---|
2424 | for (op = i.operands; --op >= 0; )
|
---|
2425 | /* Reject eight bit registers, except where the template requires
|
---|
2426 | them. (eg. movzb) */
|
---|
2427 | if ((i.types[op] & Reg8) != 0
|
---|
2428 | && (i.tm.operand_types[op] & (Reg16 | Reg32 | Acc)) != 0)
|
---|
2429 | {
|
---|
2430 | as_bad (_("`%%%s' not allowed with `%s%c'"),
|
---|
2431 | i.op[op].regs->reg_name,
|
---|
2432 | i.tm.name,
|
---|
2433 | i.suffix);
|
---|
2434 | return 0;
|
---|
2435 | }
|
---|
2436 | /* Warn if the e prefix on a general reg is missing. */
|
---|
2437 | else if (((i.types[op] & Reg16) != 0
|
---|
2438 | || (i.types[op] & Reg32) != 0)
|
---|
2439 | && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
|
---|
2440 | {
|
---|
2441 | /* Prohibit these changes in the 64bit mode, since the
|
---|
2442 | lowering is more complicated. */
|
---|
2443 | as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
|
---|
2444 | i.op[op].regs->reg_name,
|
---|
2445 | i.suffix);
|
---|
2446 | return 0;
|
---|
2447 | }
|
---|
2448 | return 1;
|
---|
2449 | }
|
---|
2450 |
|
---|
2451 | static int
|
---|
2452 | check_word_reg ()
|
---|
2453 | {
|
---|
2454 | int op;
|
---|
2455 | for (op = i.operands; --op >= 0;)
|
---|
2456 | /* Reject eight bit registers, except where the template requires
|
---|
2457 | them. (eg. movzb) */
|
---|
2458 | if ((i.types[op] & Reg8) != 0
|
---|
2459 | && (i.tm.operand_types[op] & (Reg16 | Reg32 | Acc)) != 0)
|
---|
2460 | {
|
---|
2461 | as_bad (_("`%%%s' not allowed with `%s%c'"),
|
---|
2462 | i.op[op].regs->reg_name,
|
---|
2463 | i.tm.name,
|
---|
2464 | i.suffix);
|
---|
2465 | return 0;
|
---|
2466 | }
|
---|
2467 | /* Warn if the e prefix on a general reg is present. */
|
---|
2468 | else if ((!quiet_warnings || flag_code == CODE_64BIT)
|
---|
2469 | && (i.types[op] & Reg32) != 0
|
---|
2470 | && (i.tm.operand_types[op] & (Reg16 | Acc)) != 0)
|
---|
2471 | {
|
---|
2472 | /* Prohibit these changes in the 64bit mode, since the
|
---|
2473 | lowering is more complicated. */
|
---|
2474 | if (flag_code == CODE_64BIT)
|
---|
2475 | {
|
---|
2476 | as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
|
---|
2477 | i.op[op].regs->reg_name,
|
---|
2478 | i.suffix);
|
---|
2479 | return 0;
|
---|
2480 | }
|
---|
2481 | else
|
---|
2482 | #if REGISTER_WARNINGS
|
---|
2483 | as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
|
---|
2484 | (i.op[op].regs + REGNAM_AX - REGNAM_EAX)->reg_name,
|
---|
2485 | i.op[op].regs->reg_name,
|
---|
2486 | i.suffix);
|
---|
2487 | #endif
|
---|
2488 | }
|
---|
2489 | return 1;
|
---|
2490 | }
|
---|
2491 |
|
---|
2492 | static int
|
---|
2493 | finalize_imm ()
|
---|
2494 | {
|
---|
2495 | unsigned int overlap0, overlap1, overlap2;
|
---|
2496 |
|
---|
2497 | overlap0 = i.types[0] & i.tm.operand_types[0];
|
---|
2498 | if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S))
|
---|
2499 | && overlap0 != Imm8 && overlap0 != Imm8S
|
---|
2500 | && overlap0 != Imm16 && overlap0 != Imm32S
|
---|
2501 | && overlap0 != Imm32 && overlap0 != Imm64)
|
---|
2502 | {
|
---|
2503 | if (i.suffix)
|
---|
2504 | {
|
---|
2505 | overlap0 &= (i.suffix == BYTE_MNEM_SUFFIX
|
---|
2506 | ? Imm8 | Imm8S
|
---|
2507 | : (i.suffix == WORD_MNEM_SUFFIX
|
---|
2508 | ? Imm16
|
---|
2509 | : (i.suffix == QWORD_MNEM_SUFFIX
|
---|
2510 | ? Imm64 | Imm32S
|
---|
2511 | : Imm32)));
|
---|
2512 | }
|
---|
2513 | else if (overlap0 == (Imm16 | Imm32S | Imm32)
|
---|
2514 | || overlap0 == (Imm16 | Imm32)
|
---|
2515 | || overlap0 == (Imm16 | Imm32S))
|
---|
2516 | {
|
---|
2517 | overlap0 = ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)
|
---|
2518 | ? Imm16 : Imm32S);
|
---|
2519 | }
|
---|
2520 | if (overlap0 != Imm8 && overlap0 != Imm8S
|
---|
2521 | && overlap0 != Imm16 && overlap0 != Imm32S
|
---|
2522 | && overlap0 != Imm32 && overlap0 != Imm64)
|
---|
2523 | {
|
---|
2524 | as_bad (_("no instruction mnemonic suffix given; can't determine immediate size"));
|
---|
2525 | return 0;
|
---|
2526 | }
|
---|
2527 | }
|
---|
2528 | i.types[0] = overlap0;
|
---|
2529 |
|
---|
2530 | overlap1 = i.types[1] & i.tm.operand_types[1];
|
---|
2531 | if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32))
|
---|
2532 | && overlap1 != Imm8 && overlap1 != Imm8S
|
---|
2533 | && overlap1 != Imm16 && overlap1 != Imm32S
|
---|
2534 | && overlap1 != Imm32 && overlap1 != Imm64)
|
---|
2535 | {
|
---|
2536 | if (i.suffix)
|
---|
2537 | {
|
---|
2538 | overlap1 &= (i.suffix == BYTE_MNEM_SUFFIX
|
---|
2539 | ? Imm8 | Imm8S
|
---|
2540 | : (i.suffix == WORD_MNEM_SUFFIX
|
---|
2541 | ? Imm16
|
---|
2542 | : (i.suffix == QWORD_MNEM_SUFFIX
|
---|
2543 | ? Imm64 | Imm32S
|
---|
2544 | : Imm32)));
|
---|
2545 | }
|
---|
2546 | else if (overlap1 == (Imm16 | Imm32 | Imm32S)
|
---|
2547 | || overlap1 == (Imm16 | Imm32)
|
---|
2548 | || overlap1 == (Imm16 | Imm32S))
|
---|
2549 | {
|
---|
2550 | overlap1 = ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)
|
---|
2551 | ? Imm16 : Imm32S);
|
---|
2552 | }
|
---|
2553 | if (overlap1 != Imm8 && overlap1 != Imm8S
|
---|
2554 | && overlap1 != Imm16 && overlap1 != Imm32S
|
---|
2555 | && overlap1 != Imm32 && overlap1 != Imm64)
|
---|
2556 | {
|
---|
2557 | as_bad (_("no instruction mnemonic suffix given; can't determine immediate size %x %c"),overlap1, i.suffix);
|
---|
2558 | return 0;
|
---|
2559 | }
|
---|
2560 | }
|
---|
2561 | i.types[1] = overlap1;
|
---|
2562 |
|
---|
2563 | overlap2 = i.types[2] & i.tm.operand_types[2];
|
---|
2564 | assert ((overlap2 & Imm) == 0);
|
---|
2565 | i.types[2] = overlap2;
|
---|
2566 |
|
---|
2567 | return 1;
|
---|
2568 | }
|
---|
2569 |
|
---|
2570 | static int
|
---|
2571 | process_operands ()
|
---|
2572 | {
|
---|
2573 | /* Default segment register this instruction will use for memory
|
---|
2574 | accesses. 0 means unknown. This is only for optimizing out
|
---|
2575 | unnecessary segment overrides. */
|
---|
2576 | const seg_entry *default_seg = 0;
|
---|
2577 |
|
---|
2578 | /* The imul $imm, %reg instruction is converted into
|
---|
2579 | imul $imm, %reg, %reg, and the clr %reg instruction
|
---|
2580 | is converted into xor %reg, %reg. */
|
---|
2581 | if (i.tm.opcode_modifier & regKludge)
|
---|
2582 | {
|
---|
2583 | unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
|
---|
2584 | /* Pretend we saw the extra register operand. */
|
---|
2585 | assert (i.op[first_reg_op + 1].regs == 0);
|
---|
2586 | i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
|
---|
2587 | i.types[first_reg_op + 1] = i.types[first_reg_op];
|
---|
2588 | i.reg_operands = 2;
|
---|
2589 | }
|
---|
2590 |
|
---|
2591 | if (i.tm.opcode_modifier & ShortForm)
|
---|
2592 | {
|
---|
2593 | /* The register or float register operand is in operand 0 or 1. */
|
---|
2594 | unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
|
---|
2595 | /* Register goes in low 3 bits of opcode. */
|
---|
2596 | i.tm.base_opcode |= i.op[op].regs->reg_num;
|
---|
2597 | if ((i.op[op].regs->reg_flags & RegRex) != 0)
|
---|
2598 | i.rex |= REX_EXTZ;
|
---|
2599 | if (!quiet_warnings && (i.tm.opcode_modifier & Ugh) != 0)
|
---|
2600 | {
|
---|
2601 | /* Warn about some common errors, but press on regardless.
|
---|
2602 | The first case can be generated by gcc (<= 2.8.1). */
|
---|
2603 | if (i.operands == 2)
|
---|
2604 | {
|
---|
2605 | /* Reversed arguments on faddp, fsubp, etc. */
|
---|
2606 | as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name,
|
---|
2607 | i.op[1].regs->reg_name,
|
---|
2608 | i.op[0].regs->reg_name);
|
---|
2609 | }
|
---|
2610 | else
|
---|
2611 | {
|
---|
2612 | /* Extraneous `l' suffix on fp insn. */
|
---|
2613 | as_warn (_("translating to `%s %%%s'"), i.tm.name,
|
---|
2614 | i.op[0].regs->reg_name);
|
---|
2615 | }
|
---|
2616 | }
|
---|
2617 | }
|
---|
2618 | else if (i.tm.opcode_modifier & Modrm)
|
---|
2619 | {
|
---|
2620 | /* The opcode is completed (modulo i.tm.extension_opcode which
|
---|
2621 | must be put into the modrm byte). Now, we make the modrm and
|
---|
2622 | index base bytes based on all the info we've collected. */
|
---|
2623 |
|
---|
2624 | default_seg = build_modrm_byte ();
|
---|
2625 | }
|
---|
2626 | else if (i.tm.opcode_modifier & (Seg2ShortForm | Seg3ShortForm))
|
---|
2627 | {
|
---|
2628 | if (i.tm.base_opcode == POP_SEG_SHORT
|
---|
2629 | && i.op[0].regs->reg_num == 1)
|
---|
2630 | {
|
---|
2631 | as_bad (_("you can't `pop %%cs'"));
|
---|
2632 | return 0;
|
---|
2633 | }
|
---|
2634 | i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
|
---|
2635 | if ((i.op[0].regs->reg_flags & RegRex) != 0)
|
---|
2636 | i.rex |= REX_EXTZ;
|
---|
2637 | }
|
---|
2638 | else if ((i.tm.base_opcode & ~(D | W)) == MOV_AX_DISP32)
|
---|
2639 | {
|
---|
2640 | default_seg = &ds;
|
---|
2641 | }
|
---|
2642 | else if ((i.tm.opcode_modifier & IsString) != 0)
|
---|
2643 | {
|
---|
2644 | /* For the string instructions that allow a segment override
|
---|
2645 | on one of their operands, the default segment is ds. */
|
---|
2646 | default_seg = &ds;
|
---|
2647 | }
|
---|
2648 |
|
---|
2649 | if (i.tm.base_opcode == 0x8d /* lea */ && i.seg[0] && !quiet_warnings)
|
---|
2650 | as_warn (_("segment override on `lea' is ineffectual"));
|
---|
2651 |
|
---|
2652 | /* If a segment was explicitly specified, and the specified segment
|
---|
2653 | is not the default, use an opcode prefix to select it. If we
|
---|
2654 | never figured out what the default segment is, then default_seg
|
---|
2655 | will be zero at this point, and the specified segment prefix will
|
---|
2656 | always be used. */
|
---|
2657 | if ((i.seg[0]) && (i.seg[0] != default_seg))
|
---|
2658 | {
|
---|
2659 | if (!add_prefix (i.seg[0]->seg_prefix))
|
---|
2660 | return 0;
|
---|
2661 | }
|
---|
2662 | return 1;
|
---|
2663 | }
|
---|
2664 |
|
---|
2665 | static const seg_entry *
|
---|
2666 | build_modrm_byte ()
|
---|
2667 | {
|
---|
2668 | const seg_entry *default_seg = 0;
|
---|
2669 |
|
---|
2670 | /* i.reg_operands MUST be the number of real register operands;
|
---|
2671 | implicit registers do not count. */
|
---|
2672 | if (i.reg_operands == 2)
|
---|
2673 | {
|
---|
2674 | unsigned int source, dest;
|
---|
2675 | source = ((i.types[0]
|
---|
2676 | & (Reg | RegMMX | RegXMM
|
---|
2677 | | SReg2 | SReg3
|
---|
2678 | | Control | Debug | Test))
|
---|
2679 | ? 0 : 1);
|
---|
2680 | dest = source + 1;
|
---|
2681 |
|
---|
2682 | i.rm.mode = 3;
|
---|
2683 | /* One of the register operands will be encoded in the i.tm.reg
|
---|
2684 | field, the other in the combined i.tm.mode and i.tm.regmem
|
---|
2685 | fields. If no form of this instruction supports a memory
|
---|
2686 | destination operand, then we assume the source operand may
|
---|
2687 | sometimes be a memory operand and so we need to store the
|
---|
2688 | destination in the i.rm.reg field. */
|
---|
2689 | if ((i.tm.operand_types[dest] & AnyMem) == 0)
|
---|
2690 | {
|
---|
2691 | i.rm.reg = i.op[dest].regs->reg_num;
|
---|
2692 | i.rm.regmem = i.op[source].regs->reg_num;
|
---|
2693 | if ((i.op[dest].regs->reg_flags & RegRex) != 0)
|
---|
2694 | i.rex |= REX_EXTX;
|
---|
2695 | if ((i.op[source].regs->reg_flags & RegRex) != 0)
|
---|
2696 | i.rex |= REX_EXTZ;
|
---|
2697 | }
|
---|
2698 | else
|
---|
2699 | {
|
---|
2700 | i.rm.reg = i.op[source].regs->reg_num;
|
---|
2701 | i.rm.regmem = i.op[dest].regs->reg_num;
|
---|
2702 | if ((i.op[dest].regs->reg_flags & RegRex) != 0)
|
---|
2703 | i.rex |= REX_EXTZ;
|
---|
2704 | if ((i.op[source].regs->reg_flags & RegRex) != 0)
|
---|
2705 | i.rex |= REX_EXTX;
|
---|
2706 | }
|
---|
2707 | }
|
---|
2708 | else
|
---|
2709 | { /* If it's not 2 reg operands... */
|
---|
2710 | if (i.mem_operands)
|
---|
2711 | {
|
---|
2712 | unsigned int fake_zero_displacement = 0;
|
---|
2713 | unsigned int op = ((i.types[0] & AnyMem)
|
---|
2714 | ? 0
|
---|
2715 | : (i.types[1] & AnyMem) ? 1 : 2);
|
---|
2716 |
|
---|
2717 | default_seg = &ds;
|
---|
2718 |
|
---|
2719 | if (i.base_reg == 0)
|
---|
2720 | {
|
---|
2721 | i.rm.mode = 0;
|
---|
2722 | if (!i.disp_operands)
|
---|
2723 | fake_zero_displacement = 1;
|
---|
2724 | if (i.index_reg == 0)
|
---|
2725 | {
|
---|
2726 | /* Operand is just <disp> */
|
---|
2727 | if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)
|
---|
2728 | && (flag_code != CODE_64BIT))
|
---|
2729 | {
|
---|
2730 | i.rm.regmem = NO_BASE_REGISTER_16;
|
---|
2731 | i.types[op] &= ~Disp;
|
---|
2732 | i.types[op] |= Disp16;
|
---|
2733 | }
|
---|
2734 | else if (flag_code != CODE_64BIT
|
---|
2735 | || (i.prefix[ADDR_PREFIX] != 0))
|
---|
2736 | {
|
---|
2737 | i.rm.regmem = NO_BASE_REGISTER;
|
---|
2738 | i.types[op] &= ~Disp;
|
---|
2739 | i.types[op] |= Disp32;
|
---|
2740 | }
|
---|
2741 | else
|
---|
2742 | {
|
---|
2743 | /* 64bit mode overwrites the 32bit absolute
|
---|
2744 | addressing by RIP relative addressing and
|
---|
2745 | absolute addressing is encoded by one of the
|
---|
2746 | redundant SIB forms. */
|
---|
2747 | i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
---|
2748 | i.sib.base = NO_BASE_REGISTER;
|
---|
2749 | i.sib.index = NO_INDEX_REGISTER;
|
---|
2750 | i.types[op] &= ~Disp;
|
---|
2751 | i.types[op] |= Disp32S;
|
---|
2752 | }
|
---|
2753 | }
|
---|
2754 | else /* !i.base_reg && i.index_reg */
|
---|
2755 | {
|
---|
2756 | i.sib.index = i.index_reg->reg_num;
|
---|
2757 | i.sib.base = NO_BASE_REGISTER;
|
---|
2758 | i.sib.scale = i.log2_scale_factor;
|
---|
2759 | i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
---|
2760 | i.types[op] &= ~Disp;
|
---|
2761 | if (flag_code != CODE_64BIT)
|
---|
2762 | i.types[op] |= Disp32; /* Must be 32 bit */
|
---|
2763 | else
|
---|
2764 | i.types[op] |= Disp32S;
|
---|
2765 | if ((i.index_reg->reg_flags & RegRex) != 0)
|
---|
2766 | i.rex |= REX_EXTY;
|
---|
2767 | }
|
---|
2768 | }
|
---|
2769 | /* RIP addressing for 64bit mode. */
|
---|
2770 | else if (i.base_reg->reg_type == BaseIndex)
|
---|
2771 | {
|
---|
2772 | i.rm.regmem = NO_BASE_REGISTER;
|
---|
2773 | i.types[op] &= ~Disp;
|
---|
2774 | i.types[op] |= Disp32S;
|
---|
2775 | i.flags[op] = Operand_PCrel;
|
---|
2776 | }
|
---|
2777 | else if (i.base_reg->reg_type & Reg16)
|
---|
2778 | {
|
---|
2779 | switch (i.base_reg->reg_num)
|
---|
2780 | {
|
---|
2781 | case 3: /* (%bx) */
|
---|
2782 | if (i.index_reg == 0)
|
---|
2783 | i.rm.regmem = 7;
|
---|
2784 | else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */
|
---|
2785 | i.rm.regmem = i.index_reg->reg_num - 6;
|
---|
2786 | break;
|
---|
2787 | case 5: /* (%bp) */
|
---|
2788 | default_seg = &ss;
|
---|
2789 | if (i.index_reg == 0)
|
---|
2790 | {
|
---|
2791 | i.rm.regmem = 6;
|
---|
2792 | if ((i.types[op] & Disp) == 0)
|
---|
2793 | {
|
---|
2794 | /* fake (%bp) into 0(%bp) */
|
---|
2795 | i.types[op] |= Disp8;
|
---|
2796 | fake_zero_displacement = 1;
|
---|
2797 | }
|
---|
2798 | }
|
---|
2799 | else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */
|
---|
2800 | i.rm.regmem = i.index_reg->reg_num - 6 + 2;
|
---|
2801 | break;
|
---|
2802 | default: /* (%si) -> 4 or (%di) -> 5 */
|
---|
2803 | i.rm.regmem = i.base_reg->reg_num - 6 + 4;
|
---|
2804 | }
|
---|
2805 | i.rm.mode = mode_from_disp_size (i.types[op]);
|
---|
2806 | }
|
---|
2807 | else /* i.base_reg and 32/64 bit mode */
|
---|
2808 | {
|
---|
2809 | if (flag_code == CODE_64BIT
|
---|
2810 | && (i.types[op] & Disp))
|
---|
2811 | {
|
---|
2812 | if (i.types[op] & Disp8)
|
---|
2813 | i.types[op] = Disp8 | Disp32S;
|
---|
2814 | else
|
---|
2815 | i.types[op] = Disp32S;
|
---|
2816 | }
|
---|
2817 | i.rm.regmem = i.base_reg->reg_num;
|
---|
2818 | if ((i.base_reg->reg_flags & RegRex) != 0)
|
---|
2819 | i.rex |= REX_EXTZ;
|
---|
2820 | i.sib.base = i.base_reg->reg_num;
|
---|
2821 | /* x86-64 ignores REX prefix bit here to avoid decoder
|
---|
2822 | complications. */
|
---|
2823 | if ((i.base_reg->reg_num & 7) == EBP_REG_NUM)
|
---|
2824 | {
|
---|
2825 | default_seg = &ss;
|
---|
2826 | if (i.disp_operands == 0)
|
---|
2827 | {
|
---|
2828 | fake_zero_displacement = 1;
|
---|
2829 | i.types[op] |= Disp8;
|
---|
2830 | }
|
---|
2831 | }
|
---|
2832 | else if (i.base_reg->reg_num == ESP_REG_NUM)
|
---|
2833 | {
|
---|
2834 | default_seg = &ss;
|
---|
2835 | }
|
---|
2836 | i.sib.scale = i.log2_scale_factor;
|
---|
2837 | if (i.index_reg == 0)
|
---|
2838 | {
|
---|
2839 | /* <disp>(%esp) becomes two byte modrm with no index
|
---|
2840 | register. We've already stored the code for esp
|
---|
2841 | in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING.
|
---|
2842 | Any base register besides %esp will not use the
|
---|
2843 | extra modrm byte. */
|
---|
2844 | i.sib.index = NO_INDEX_REGISTER;
|
---|
2845 | #if !SCALE1_WHEN_NO_INDEX
|
---|
2846 | /* Another case where we force the second modrm byte. */
|
---|
2847 | if (i.log2_scale_factor)
|
---|
2848 | i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
---|
2849 | #endif
|
---|
2850 | }
|
---|
2851 | else
|
---|
2852 | {
|
---|
2853 | i.sib.index = i.index_reg->reg_num;
|
---|
2854 | i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
---|
2855 | if ((i.index_reg->reg_flags & RegRex) != 0)
|
---|
2856 | i.rex |= REX_EXTY;
|
---|
2857 | }
|
---|
2858 | i.rm.mode = mode_from_disp_size (i.types[op]);
|
---|
2859 | }
|
---|
2860 |
|
---|
2861 | if (fake_zero_displacement)
|
---|
2862 | {
|
---|
2863 | /* Fakes a zero displacement assuming that i.types[op]
|
---|
2864 | holds the correct displacement size. */
|
---|
2865 | expressionS *exp;
|
---|
2866 |
|
---|
2867 | assert (i.op[op].disps == 0);
|
---|
2868 | exp = &disp_expressions[i.disp_operands++];
|
---|
2869 | i.op[op].disps = exp;
|
---|
2870 | exp->X_op = O_constant;
|
---|
2871 | exp->X_add_number = 0;
|
---|
2872 | exp->X_add_symbol = (symbolS *) 0;
|
---|
2873 | exp->X_op_symbol = (symbolS *) 0;
|
---|
2874 | }
|
---|
2875 | }
|
---|
2876 |
|
---|
2877 | /* Fill in i.rm.reg or i.rm.regmem field with register operand
|
---|
2878 | (if any) based on i.tm.extension_opcode. Again, we must be
|
---|
2879 | careful to make sure that segment/control/debug/test/MMX
|
---|
2880 | registers are coded into the i.rm.reg field. */
|
---|
2881 | if (i.reg_operands)
|
---|
2882 | {
|
---|
2883 | unsigned int op =
|
---|
2884 | ((i.types[0]
|
---|
2885 | & (Reg | RegMMX | RegXMM
|
---|
2886 | | SReg2 | SReg3
|
---|
2887 | | Control | Debug | Test))
|
---|
2888 | ? 0
|
---|
2889 | : ((i.types[1]
|
---|
2890 | & (Reg | RegMMX | RegXMM
|
---|
2891 | | SReg2 | SReg3
|
---|
2892 | | Control | Debug | Test))
|
---|
2893 | ? 1
|
---|
2894 | : 2));
|
---|
2895 | /* If there is an extension opcode to put here, the register
|
---|
2896 | number must be put into the regmem field. */
|
---|
2897 | if (i.tm.extension_opcode != None)
|
---|
2898 | {
|
---|
2899 | i.rm.regmem = i.op[op].regs->reg_num;
|
---|
2900 | if ((i.op[op].regs->reg_flags & RegRex) != 0)
|
---|
2901 | i.rex |= REX_EXTZ;
|
---|
2902 | }
|
---|
2903 | else
|
---|
2904 | {
|
---|
2905 | i.rm.reg = i.op[op].regs->reg_num;
|
---|
2906 | if ((i.op[op].regs->reg_flags & RegRex) != 0)
|
---|
2907 | i.rex |= REX_EXTX;
|
---|
2908 | }
|
---|
2909 |
|
---|
2910 | /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we
|
---|
2911 | must set it to 3 to indicate this is a register operand
|
---|
2912 | in the regmem field. */
|
---|
2913 | if (!i.mem_operands)
|
---|
2914 | i.rm.mode = 3;
|
---|
2915 | }
|
---|
2916 |
|
---|
2917 | /* Fill in i.rm.reg field with extension opcode (if any). */
|
---|
2918 | if (i.tm.extension_opcode != None)
|
---|
2919 | i.rm.reg = i.tm.extension_opcode;
|
---|
2920 | }
|
---|
2921 | return default_seg;
|
---|
2922 | }
|
---|
2923 |
|
---|
2924 | static void
|
---|
2925 | output_branch ()
|
---|
2926 | {
|
---|
2927 | char *p;
|
---|
2928 | int code16;
|
---|
2929 | int prefix;
|
---|
2930 | relax_substateT subtype;
|
---|
2931 | symbolS *sym;
|
---|
2932 | offsetT off;
|
---|
2933 |
|
---|
2934 | code16 = 0;
|
---|
2935 | if (flag_code == CODE_16BIT)
|
---|
2936 | code16 = CODE16;
|
---|
2937 |
|
---|
2938 | prefix = 0;
|
---|
2939 | if (i.prefix[DATA_PREFIX] != 0)
|
---|
2940 | {
|
---|
2941 | prefix = 1;
|
---|
2942 | i.prefixes -= 1;
|
---|
2943 | code16 ^= CODE16;
|
---|
2944 | }
|
---|
2945 | /* Pentium4 branch hints. */
|
---|
2946 | if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
|
---|
2947 | || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
|
---|
2948 | {
|
---|
2949 | prefix++;
|
---|
2950 | i.prefixes--;
|
---|
2951 | }
|
---|
2952 | if (i.prefix[REX_PREFIX] != 0)
|
---|
2953 | {
|
---|
2954 | prefix++;
|
---|
2955 | i.prefixes--;
|
---|
2956 | }
|
---|
2957 |
|
---|
2958 | if (i.prefixes != 0 && !intel_syntax)
|
---|
2959 | as_warn (_("skipping prefixes on this instruction"));
|
---|
2960 |
|
---|
2961 | /* It's always a symbol; End frag & setup for relax.
|
---|
2962 | Make sure there is enough room in this frag for the largest
|
---|
2963 | instruction we may generate in md_convert_frag. This is 2
|
---|
2964 | bytes for the opcode and room for the prefix and largest
|
---|
2965 | displacement. */
|
---|
2966 | frag_grow (prefix + 2 + 4);
|
---|
2967 | /* Prefix and 1 opcode byte go in fr_fix. */
|
---|
2968 | p = frag_more (prefix + 1);
|
---|
2969 | if (i.prefix[DATA_PREFIX] != 0)
|
---|
2970 | *p++ = DATA_PREFIX_OPCODE;
|
---|
2971 | if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE
|
---|
2972 | || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE)
|
---|
2973 | *p++ = i.prefix[SEG_PREFIX];
|
---|
2974 | if (i.prefix[REX_PREFIX] != 0)
|
---|
2975 | *p++ = i.prefix[REX_PREFIX];
|
---|
2976 | *p = i.tm.base_opcode;
|
---|
2977 |
|
---|
2978 | if ((unsigned char) *p == JUMP_PC_RELATIVE)
|
---|
2979 | subtype = ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL);
|
---|
2980 | else if ((cpu_arch_flags & Cpu386) != 0)
|
---|
2981 | subtype = ENCODE_RELAX_STATE (COND_JUMP, SMALL);
|
---|
2982 | else
|
---|
2983 | subtype = ENCODE_RELAX_STATE (COND_JUMP86, SMALL);
|
---|
2984 | subtype |= code16;
|
---|
2985 |
|
---|
2986 | sym = i.op[0].disps->X_add_symbol;
|
---|
2987 | off = i.op[0].disps->X_add_number;
|
---|
2988 |
|
---|
2989 | if (i.op[0].disps->X_op != O_constant
|
---|
2990 | && i.op[0].disps->X_op != O_symbol)
|
---|
2991 | {
|
---|
2992 | /* Handle complex expressions. */
|
---|
2993 | sym = make_expr_symbol (i.op[0].disps);
|
---|
2994 | off = 0;
|
---|
2995 | }
|
---|
2996 |
|
---|
2997 | /* 1 possible extra opcode + 4 byte displacement go in var part.
|
---|
2998 | Pass reloc in fr_var. */
|
---|
2999 | frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p);
|
---|
3000 | }
|
---|
3001 |
|
---|
3002 | static void
|
---|
3003 | output_jump ()
|
---|
3004 | {
|
---|
3005 | char *p;
|
---|
3006 | int size;
|
---|
3007 | fixS *fixP;
|
---|
3008 |
|
---|
3009 | if (i.tm.opcode_modifier & JumpByte)
|
---|
3010 | {
|
---|
3011 | /* This is a loop or jecxz type instruction. */
|
---|
3012 | size = 1;
|
---|
3013 | if (i.prefix[ADDR_PREFIX] != 0)
|
---|
3014 | {
|
---|
3015 | FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
|
---|
3016 | i.prefixes -= 1;
|
---|
3017 | }
|
---|
3018 | /* Pentium4 branch hints. */
|
---|
3019 | if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
|
---|
3020 | || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
|
---|
3021 | {
|
---|
3022 | FRAG_APPEND_1_CHAR (i.prefix[SEG_PREFIX]);
|
---|
3023 | i.prefixes--;
|
---|
3024 | }
|
---|
3025 | }
|
---|
3026 | else
|
---|
3027 | {
|
---|
3028 | int code16;
|
---|
3029 |
|
---|
3030 | code16 = 0;
|
---|
3031 | if (flag_code == CODE_16BIT)
|
---|
3032 | code16 = CODE16;
|
---|
3033 |
|
---|
3034 | if (i.prefix[DATA_PREFIX] != 0)
|
---|
3035 | {
|
---|
3036 | FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
|
---|
3037 | i.prefixes -= 1;
|
---|
3038 | code16 ^= CODE16;
|
---|
3039 | }
|
---|
3040 |
|
---|
3041 | size = 4;
|
---|
3042 | if (code16)
|
---|
3043 | size = 2;
|
---|
3044 | }
|
---|
3045 |
|
---|
3046 | if (i.prefix[REX_PREFIX] != 0)
|
---|
3047 | {
|
---|
3048 | FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]);
|
---|
3049 | i.prefixes -= 1;
|
---|
3050 | }
|
---|
3051 |
|
---|
3052 | if (i.prefixes != 0 && !intel_syntax)
|
---|
3053 | as_warn (_("skipping prefixes on this instruction"));
|
---|
3054 |
|
---|
3055 | p = frag_more (1 + size);
|
---|
3056 | *p++ = i.tm.base_opcode;
|
---|
3057 |
|
---|
3058 | fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
|
---|
3059 | i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
|
---|
3060 |
|
---|
3061 | /* All jumps handled here are signed, but don't use a signed limit
|
---|
3062 | check for 32 and 16 bit jumps as we want to allow wrap around at
|
---|
3063 | 4G and 64k respectively. */
|
---|
3064 | if (size == 1)
|
---|
3065 | fixP->fx_signed = 1;
|
---|
3066 | }
|
---|
3067 |
|
---|
3068 | static void
|
---|
3069 | output_interseg_jump ()
|
---|
3070 | {
|
---|
3071 | char *p;
|
---|
3072 | int size;
|
---|
3073 | int prefix;
|
---|
3074 | int code16;
|
---|
3075 |
|
---|
3076 | code16 = 0;
|
---|
3077 | if (flag_code == CODE_16BIT)
|
---|
3078 | code16 = CODE16;
|
---|
3079 |
|
---|
3080 | prefix = 0;
|
---|
3081 | if (i.prefix[DATA_PREFIX] != 0)
|
---|
3082 | {
|
---|
3083 | prefix = 1;
|
---|
3084 | i.prefixes -= 1;
|
---|
3085 | code16 ^= CODE16;
|
---|
3086 | }
|
---|
3087 | if (i.prefix[REX_PREFIX] != 0)
|
---|
3088 | {
|
---|
3089 | prefix++;
|
---|
3090 | i.prefixes -= 1;
|
---|
3091 | }
|
---|
3092 |
|
---|
3093 | size = 4;
|
---|
3094 | if (code16)
|
---|
3095 | size = 2;
|
---|
3096 |
|
---|
3097 | if (i.prefixes != 0 && !intel_syntax)
|
---|
3098 | as_warn (_("skipping prefixes on this instruction"));
|
---|
3099 |
|
---|
3100 | /* 1 opcode; 2 segment; offset */
|
---|
3101 | p = frag_more (prefix + 1 + 2 + size);
|
---|
3102 |
|
---|
3103 | if (i.prefix[DATA_PREFIX] != 0)
|
---|
3104 | *p++ = DATA_PREFIX_OPCODE;
|
---|
3105 |
|
---|
3106 | if (i.prefix[REX_PREFIX] != 0)
|
---|
3107 | *p++ = i.prefix[REX_PREFIX];
|
---|
3108 |
|
---|
3109 | *p++ = i.tm.base_opcode;
|
---|
3110 | if (i.op[1].imms->X_op == O_constant)
|
---|
3111 | {
|
---|
3112 | offsetT n = i.op[1].imms->X_add_number;
|
---|
3113 |
|
---|
3114 | if (size == 2
|
---|
3115 | && !fits_in_unsigned_word (n)
|
---|
3116 | && !fits_in_signed_word (n))
|
---|
3117 | {
|
---|
3118 | as_bad (_("16-bit jump out of range"));
|
---|
3119 | return;
|
---|
3120 | }
|
---|
3121 | md_number_to_chars (p, n, size);
|
---|
3122 | }
|
---|
3123 | else
|
---|
3124 | fix_new_exp (frag_now, p - frag_now->fr_literal, size,
|
---|
3125 | i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
|
---|
3126 | if (i.op[0].imms->X_op != O_constant)
|
---|
3127 | as_bad (_("can't handle non absolute segment in `%s'"),
|
---|
3128 | i.tm.name);
|
---|
3129 | md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
|
---|
3130 | }
|
---|
3131 |
|
---|
3132 |
|
---|
3133 | static void
|
---|
3134 | output_insn ()
|
---|
3135 | {
|
---|
3136 | fragS *insn_start_frag;
|
---|
3137 | offsetT insn_start_off;
|
---|
3138 |
|
---|
3139 | /* Tie dwarf2 debug info to the address at the start of the insn.
|
---|
3140 | We can't do this after the insn has been output as the current
|
---|
3141 | frag may have been closed off. eg. by frag_var. */
|
---|
3142 | dwarf2_emit_insn (0);
|
---|
3143 |
|
---|
3144 | insn_start_frag = frag_now;
|
---|
3145 | insn_start_off = frag_now_fix ();
|
---|
3146 |
|
---|
3147 | /* Output jumps. */
|
---|
3148 | if (i.tm.opcode_modifier & Jump)
|
---|
3149 | output_branch ();
|
---|
3150 | else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
|
---|
3151 | output_jump ();
|
---|
3152 | else if (i.tm.opcode_modifier & JumpInterSegment)
|
---|
3153 | output_interseg_jump ();
|
---|
3154 | else
|
---|
3155 | {
|
---|
3156 | /* Output normal instructions here. */
|
---|
3157 | char *p;
|
---|
3158 | unsigned char *q;
|
---|
3159 |
|
---|
3160 | /* All opcodes on i386 have either 1 or 2 bytes. We may use third
|
---|
3161 | byte for the SSE instructions to specify a prefix they require. */
|
---|
3162 | if (i.tm.base_opcode & 0xff0000)
|
---|
3163 | add_prefix ((i.tm.base_opcode >> 16) & 0xff);
|
---|
3164 |
|
---|
3165 | /* The prefix bytes. */
|
---|
3166 | for (q = i.prefix;
|
---|
3167 | q < i.prefix + sizeof (i.prefix) / sizeof (i.prefix[0]);
|
---|
3168 | q++)
|
---|
3169 | {
|
---|
3170 | if (*q)
|
---|
3171 | {
|
---|
3172 | p = frag_more (1);
|
---|
3173 | md_number_to_chars (p, (valueT) *q, 1);
|
---|
3174 | }
|
---|
3175 | }
|
---|
3176 |
|
---|
3177 | /* Now the opcode; be careful about word order here! */
|
---|
3178 | if (fits_in_unsigned_byte (i.tm.base_opcode))
|
---|
3179 | {
|
---|
3180 | FRAG_APPEND_1_CHAR (i.tm.base_opcode);
|
---|
3181 | }
|
---|
3182 | else
|
---|
3183 | {
|
---|
3184 | p = frag_more (2);
|
---|
3185 | /* Put out high byte first: can't use md_number_to_chars! */
|
---|
3186 | *p++ = (i.tm.base_opcode >> 8) & 0xff;
|
---|
3187 | *p = i.tm.base_opcode & 0xff;
|
---|
3188 | }
|
---|
3189 |
|
---|
3190 | /* Now the modrm byte and sib byte (if present). */
|
---|
3191 | if (i.tm.opcode_modifier & Modrm)
|
---|
3192 | {
|
---|
3193 | p = frag_more (1);
|
---|
3194 | md_number_to_chars (p,
|
---|
3195 | (valueT) (i.rm.regmem << 0
|
---|
3196 | | i.rm.reg << 3
|
---|
3197 | | i.rm.mode << 6),
|
---|
3198 | 1);
|
---|
3199 | /* If i.rm.regmem == ESP (4)
|
---|
3200 | && i.rm.mode != (Register mode)
|
---|
3201 | && not 16 bit
|
---|
3202 | ==> need second modrm byte. */
|
---|
3203 | if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING
|
---|
3204 | && i.rm.mode != 3
|
---|
3205 | && !(i.base_reg && (i.base_reg->reg_type & Reg16) != 0))
|
---|
3206 | {
|
---|
3207 | p = frag_more (1);
|
---|
3208 | md_number_to_chars (p,
|
---|
3209 | (valueT) (i.sib.base << 0
|
---|
3210 | | i.sib.index << 3
|
---|
3211 | | i.sib.scale << 6),
|
---|
3212 | 1);
|
---|
3213 | }
|
---|
3214 | }
|
---|
3215 |
|
---|
3216 | if (i.disp_operands)
|
---|
3217 | output_disp (insn_start_frag, insn_start_off);
|
---|
3218 |
|
---|
3219 | if (i.imm_operands)
|
---|
3220 | output_imm (insn_start_frag, insn_start_off);
|
---|
3221 | }
|
---|
3222 |
|
---|
3223 | #ifdef DEBUG386
|
---|
3224 | if (flag_debug)
|
---|
3225 | {
|
---|
3226 | pi (line, &i);
|
---|
3227 | }
|
---|
3228 | #endif /* DEBUG386 */
|
---|
3229 | }
|
---|
3230 |
|
---|
3231 | static void
|
---|
3232 | output_disp (insn_start_frag, insn_start_off)
|
---|
3233 | fragS *insn_start_frag;
|
---|
3234 | offsetT insn_start_off;
|
---|
3235 | {
|
---|
3236 | char *p;
|
---|
3237 | unsigned int n;
|
---|
3238 |
|
---|
3239 | for (n = 0; n < i.operands; n++)
|
---|
3240 | {
|
---|
3241 | if (i.types[n] & Disp)
|
---|
3242 | {
|
---|
3243 | if (i.op[n].disps->X_op == O_constant)
|
---|
3244 | {
|
---|
3245 | int size;
|
---|
3246 | offsetT val;
|
---|
3247 |
|
---|
3248 | size = 4;
|
---|
3249 | if (i.types[n] & (Disp8 | Disp16 | Disp64))
|
---|
3250 | {
|
---|
3251 | size = 2;
|
---|
3252 | if (i.types[n] & Disp8)
|
---|
3253 | size = 1;
|
---|
3254 | if (i.types[n] & Disp64)
|
---|
3255 | size = 8;
|
---|
3256 | }
|
---|
3257 | val = offset_in_range (i.op[n].disps->X_add_number,
|
---|
3258 | size);
|
---|
3259 | p = frag_more (size);
|
---|
3260 | md_number_to_chars (p, val, size);
|
---|
3261 | }
|
---|
3262 | else
|
---|
3263 | {
|
---|
3264 | RELOC_ENUM reloc_type;
|
---|
3265 | int size = 4;
|
---|
3266 | int sign = 0;
|
---|
3267 | int pcrel = (i.flags[n] & Operand_PCrel) != 0;
|
---|
3268 |
|
---|
3269 | /* The PC relative address is computed relative
|
---|
3270 | to the instruction boundary, so in case immediate
|
---|
3271 | fields follows, we need to adjust the value. */
|
---|
3272 | if (pcrel && i.imm_operands)
|
---|
3273 | {
|
---|
3274 | int imm_size = 4;
|
---|
3275 | unsigned int n1;
|
---|
3276 |
|
---|
3277 | for (n1 = 0; n1 < i.operands; n1++)
|
---|
3278 | if (i.types[n1] & Imm)
|
---|
3279 | {
|
---|
3280 | if (i.types[n1] & (Imm8 | Imm8S | Imm16 | Imm64))
|
---|
3281 | {
|
---|
3282 | imm_size = 2;
|
---|
3283 | if (i.types[n1] & (Imm8 | Imm8S))
|
---|
3284 | imm_size = 1;
|
---|
3285 | if (i.types[n1] & Imm64)
|
---|
3286 | imm_size = 8;
|
---|
3287 | }
|
---|
3288 | break;
|
---|
3289 | }
|
---|
3290 | /* We should find the immediate. */
|
---|
3291 | if (n1 == i.operands)
|
---|
3292 | abort ();
|
---|
3293 | i.op[n].disps->X_add_number -= imm_size;
|
---|
3294 | }
|
---|
3295 |
|
---|
3296 | if (i.types[n] & Disp32S)
|
---|
3297 | sign = 1;
|
---|
3298 |
|
---|
3299 | if (i.types[n] & (Disp16 | Disp64))
|
---|
3300 | {
|
---|
3301 | size = 2;
|
---|
3302 | if (i.types[n] & Disp64)
|
---|
3303 | size = 8;
|
---|
3304 | }
|
---|
3305 |
|
---|
3306 | p = frag_more (size);
|
---|
3307 | reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
|
---|
3308 | #ifdef BFD_ASSEMBLER
|
---|
3309 | if (reloc_type == BFD_RELOC_32
|
---|
3310 | && GOT_symbol
|
---|
3311 | && GOT_symbol == i.op[n].disps->X_add_symbol
|
---|
3312 | && (i.op[n].disps->X_op == O_symbol
|
---|
3313 | || (i.op[n].disps->X_op == O_add
|
---|
3314 | && ((symbol_get_value_expression
|
---|
3315 | (i.op[n].disps->X_op_symbol)->X_op)
|
---|
3316 | == O_subtract))))
|
---|
3317 | {
|
---|
3318 | offsetT add;
|
---|
3319 |
|
---|
3320 | if (insn_start_frag == frag_now)
|
---|
3321 | add = (p - frag_now->fr_literal) - insn_start_off;
|
---|
3322 | else
|
---|
3323 | {
|
---|
3324 | fragS *fr;
|
---|
3325 |
|
---|
3326 | add = insn_start_frag->fr_fix - insn_start_off;
|
---|
3327 | for (fr = insn_start_frag->fr_next;
|
---|
3328 | fr && fr != frag_now; fr = fr->fr_next)
|
---|
3329 | add += fr->fr_fix;
|
---|
3330 | add += p - frag_now->fr_literal;
|
---|
3331 | }
|
---|
3332 |
|
---|
3333 | /* We don't support dynamic linking on x86-64 yet. */
|
---|
3334 | if (flag_code == CODE_64BIT)
|
---|
3335 | abort ();
|
---|
3336 | reloc_type = BFD_RELOC_386_GOTPC;
|
---|
3337 | i.op[n].disps->X_add_number += add;
|
---|
3338 | }
|
---|
3339 | #endif
|
---|
3340 | fix_new_exp (frag_now, p - frag_now->fr_literal, size,
|
---|
3341 | i.op[n].disps, pcrel, reloc_type);
|
---|
3342 | }
|
---|
3343 | }
|
---|
3344 | }
|
---|
3345 | }
|
---|
3346 |
|
---|
3347 | static void
|
---|
3348 | output_imm (insn_start_frag, insn_start_off)
|
---|
3349 | fragS *insn_start_frag;
|
---|
3350 | offsetT insn_start_off;
|
---|
3351 | {
|
---|
3352 | char *p;
|
---|
3353 | unsigned int n;
|
---|
3354 |
|
---|
3355 | for (n = 0; n < i.operands; n++)
|
---|
3356 | {
|
---|
3357 | if (i.types[n] & Imm)
|
---|
3358 | {
|
---|
3359 | if (i.op[n].imms->X_op == O_constant)
|
---|
3360 | {
|
---|
3361 | int size;
|
---|
3362 | offsetT val;
|
---|
3363 |
|
---|
3364 | size = 4;
|
---|
3365 | if (i.types[n] & (Imm8 | Imm8S | Imm16 | Imm64))
|
---|
3366 | {
|
---|
3367 | size = 2;
|
---|
3368 | if (i.types[n] & (Imm8 | Imm8S))
|
---|
3369 | size = 1;
|
---|
3370 | else if (i.types[n] & Imm64)
|
---|
3371 | size = 8;
|
---|
3372 | }
|
---|
3373 | val = offset_in_range (i.op[n].imms->X_add_number,
|
---|
3374 | size);
|
---|
3375 | p = frag_more (size);
|
---|
3376 | md_number_to_chars (p, val, size);
|
---|
3377 | }
|
---|
3378 | else
|
---|
3379 | {
|
---|
3380 | /* Not absolute_section.
|
---|
3381 | Need a 32-bit fixup (don't support 8bit
|
---|
3382 | non-absolute imms). Try to support other
|
---|
3383 | sizes ... */
|
---|
3384 | RELOC_ENUM reloc_type;
|
---|
3385 | int size = 4;
|
---|
3386 | int sign = 0;
|
---|
3387 |
|
---|
3388 | if ((i.types[n] & (Imm32S))
|
---|
3389 | && i.suffix == QWORD_MNEM_SUFFIX)
|
---|
3390 | sign = 1;
|
---|
3391 | if (i.types[n] & (Imm8 | Imm8S | Imm16 | Imm64))
|
---|
3392 | {
|
---|
3393 | size = 2;
|
---|
3394 | if (i.types[n] & (Imm8 | Imm8S))
|
---|
3395 | size = 1;
|
---|
3396 | if (i.types[n] & Imm64)
|
---|
3397 | size = 8;
|
---|
3398 | }
|
---|
3399 |
|
---|
3400 | p = frag_more (size);
|
---|
3401 | reloc_type = reloc (size, 0, sign, i.reloc[n]);
|
---|
3402 | #ifdef BFD_ASSEMBLER
|
---|
3403 | /* This is tough to explain. We end up with this one if we
|
---|
3404 | * have operands that look like
|
---|
3405 | * "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal here is to
|
---|
3406 | * obtain the absolute address of the GOT, and it is strongly
|
---|
3407 | * preferable from a performance point of view to avoid using
|
---|
3408 | * a runtime relocation for this. The actual sequence of
|
---|
3409 | * instructions often look something like:
|
---|
3410 | *
|
---|
3411 | * call .L66
|
---|
3412 | * .L66:
|
---|
3413 | * popl %ebx
|
---|
3414 | * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx
|
---|
3415 | *
|
---|
3416 | * The call and pop essentially return the absolute address
|
---|
3417 | * of the label .L66 and store it in %ebx. The linker itself
|
---|
3418 | * will ultimately change the first operand of the addl so
|
---|
3419 | * that %ebx points to the GOT, but to keep things simple, the
|
---|
3420 | * .o file must have this operand set so that it generates not
|
---|
3421 | * the absolute address of .L66, but the absolute address of
|
---|
3422 | * itself. This allows the linker itself simply treat a GOTPC
|
---|
3423 | * relocation as asking for a pcrel offset to the GOT to be
|
---|
3424 | * added in, and the addend of the relocation is stored in the
|
---|
3425 | * operand field for the instruction itself.
|
---|
3426 | *
|
---|
3427 | * Our job here is to fix the operand so that it would add
|
---|
3428 | * the correct offset so that %ebx would point to itself. The
|
---|
3429 | * thing that is tricky is that .-.L66 will point to the
|
---|
3430 | * beginning of the instruction, so we need to further modify
|
---|
3431 | * the operand so that it will point to itself. There are
|
---|
3432 | * other cases where you have something like:
|
---|
3433 | *
|
---|
3434 | * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66]
|
---|
3435 | *
|
---|
3436 | * and here no correction would be required. Internally in
|
---|
3437 | * the assembler we treat operands of this form as not being
|
---|
3438 | * pcrel since the '.' is explicitly mentioned, and I wonder
|
---|
3439 | * whether it would simplify matters to do it this way. Who
|
---|
3440 | * knows. In earlier versions of the PIC patches, the
|
---|
3441 | * pcrel_adjust field was used to store the correction, but
|
---|
3442 | * since the expression is not pcrel, I felt it would be
|
---|
3443 | * confusing to do it this way. */
|
---|
3444 |
|
---|
3445 | if (reloc_type == BFD_RELOC_32
|
---|
3446 | && GOT_symbol
|
---|
3447 | && GOT_symbol == i.op[n].imms->X_add_symbol
|
---|
3448 | && (i.op[n].imms->X_op == O_symbol
|
---|
3449 | || (i.op[n].imms->X_op == O_add
|
---|
3450 | && ((symbol_get_value_expression
|
---|
3451 | (i.op[n].imms->X_op_symbol)->X_op)
|
---|
3452 | == O_subtract))))
|
---|
3453 | {
|
---|
3454 | offsetT add;
|
---|
3455 |
|
---|
3456 | if (insn_start_frag == frag_now)
|
---|
3457 | add = (p - frag_now->fr_literal) - insn_start_off;
|
---|
3458 | else
|
---|
3459 | {
|
---|
3460 | fragS *fr;
|
---|
3461 |
|
---|
3462 | add = insn_start_frag->fr_fix - insn_start_off;
|
---|
3463 | for (fr = insn_start_frag->fr_next;
|
---|
3464 | fr && fr != frag_now; fr = fr->fr_next)
|
---|
3465 | add += fr->fr_fix;
|
---|
3466 | add += p - frag_now->fr_literal;
|
---|
3467 | }
|
---|
3468 |
|
---|
3469 | /* We don't support dynamic linking on x86-64 yet. */
|
---|
3470 | if (flag_code == CODE_64BIT)
|
---|
3471 | abort ();
|
---|
3472 | reloc_type = BFD_RELOC_386_GOTPC;
|
---|
3473 | i.op[n].imms->X_add_number += add;
|
---|
3474 | }
|
---|
3475 | #endif
|
---|
3476 | fix_new_exp (frag_now, p - frag_now->fr_literal, size,
|
---|
3477 | i.op[n].imms, 0, reloc_type);
|
---|
3478 | }
|
---|
3479 | }
|
---|
3480 | }
|
---|
3481 | }
|
---|
3482 | |
---|
3483 |
|
---|
3484 | #ifndef LEX_AT
|
---|
3485 | static char *lex_got PARAMS ((RELOC_ENUM *, int *));
|
---|
3486 |
|
---|
3487 | /* Parse operands of the form
|
---|
3488 | <symbol>@GOTOFF+<nnn>
|
---|
3489 | and similar .plt or .got references.
|
---|
3490 |
|
---|
3491 | If we find one, set up the correct relocation in RELOC and copy the
|
---|
3492 | input string, minus the `@GOTOFF' into a malloc'd buffer for
|
---|
3493 | parsing by the calling routine. Return this buffer, and if ADJUST
|
---|
3494 | is non-null set it to the length of the string we removed from the
|
---|
3495 | input line. Otherwise return NULL. */
|
---|
3496 | static char *
|
---|
3497 | lex_got (reloc, adjust)
|
---|
3498 | RELOC_ENUM *reloc;
|
---|
3499 | int *adjust;
|
---|
3500 | {
|
---|
3501 | static const char * const mode_name[NUM_FLAG_CODE] = { "32", "16", "64" };
|
---|
3502 | static const struct {
|
---|
3503 | const char *str;
|
---|
3504 | const RELOC_ENUM rel[NUM_FLAG_CODE];
|
---|
3505 | } gotrel[] = {
|
---|
3506 | { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
|
---|
3507 | { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
|
---|
3508 | { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
|
---|
3509 | { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, BFD_RELOC_X86_64_TLSGD } },
|
---|
3510 | { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } },
|
---|
3511 | { "TLSLD", { 0, 0, BFD_RELOC_X86_64_TLSLD } },
|
---|
3512 | { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, BFD_RELOC_X86_64_GOTTPOFF } },
|
---|
3513 | { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, BFD_RELOC_X86_64_TPOFF32 } },
|
---|
3514 | { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } },
|
---|
3515 | { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } },
|
---|
3516 | { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 } },
|
---|
3517 | { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 } },
|
---|
3518 | { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
|
---|
3519 | };
|
---|
3520 | char *cp;
|
---|
3521 | unsigned int j;
|
---|
3522 |
|
---|
3523 | for (cp = input_line_pointer; *cp != '@'; cp++)
|
---|
3524 | if (is_end_of_line[(unsigned char) *cp])
|
---|
3525 | return NULL;
|
---|
3526 |
|
---|
3527 | for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
|
---|
3528 | {
|
---|
3529 | int len;
|
---|
3530 |
|
---|
3531 | len = strlen (gotrel[j].str);
|
---|
3532 | if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
|
---|
3533 | {
|
---|
3534 | if (gotrel[j].rel[(unsigned int) flag_code] != 0)
|
---|
3535 | {
|
---|
3536 | int first, second;
|
---|
3537 | char *tmpbuf, *past_reloc;
|
---|
3538 |
|
---|
3539 | *reloc = gotrel[j].rel[(unsigned int) flag_code];
|
---|
3540 | if (adjust)
|
---|
3541 | *adjust = len;
|
---|
3542 |
|
---|
3543 | if (GOT_symbol == NULL)
|
---|
3544 | GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
|
---|
3545 |
|
---|
3546 | /* Replace the relocation token with ' ', so that
|
---|
3547 | errors like foo@GOTOFF1 will be detected. */
|
---|
3548 |
|
---|
3549 | /* The length of the first part of our input line. */
|
---|
3550 | first = cp - input_line_pointer;
|
---|
3551 |
|
---|
3552 | /* The second part goes from after the reloc token until
|
---|
3553 | (and including) an end_of_line char. Don't use strlen
|
---|
3554 | here as the end_of_line char may not be a NUL. */
|
---|
3555 | past_reloc = cp + 1 + len;
|
---|
3556 | for (cp = past_reloc; !is_end_of_line[(unsigned char) *cp++]; )
|
---|
3557 | ;
|
---|
3558 | second = cp - past_reloc;
|
---|
3559 |
|
---|
3560 | /* Allocate and copy string. The trailing NUL shouldn't
|
---|
3561 | be necessary, but be safe. */
|
---|
3562 | tmpbuf = xmalloc (first + second + 2);
|
---|
3563 | memcpy (tmpbuf, input_line_pointer, first);
|
---|
3564 | tmpbuf[first] = ' ';
|
---|
3565 | memcpy (tmpbuf + first + 1, past_reloc, second);
|
---|
3566 | tmpbuf[first + second + 1] = '\0';
|
---|
3567 | return tmpbuf;
|
---|
3568 | }
|
---|
3569 |
|
---|
3570 | as_bad (_("@%s reloc is not supported in %s bit mode"),
|
---|
3571 | gotrel[j].str, mode_name[(unsigned int) flag_code]);
|
---|
3572 | return NULL;
|
---|
3573 | }
|
---|
3574 | }
|
---|
3575 |
|
---|
3576 | /* Might be a symbol version string. Don't as_bad here. */
|
---|
3577 | return NULL;
|
---|
3578 | }
|
---|
3579 |
|
---|
3580 | /* x86_cons_fix_new is called via the expression parsing code when a
|
---|
3581 | reloc is needed. We use this hook to get the correct .got reloc. */
|
---|
3582 | static RELOC_ENUM got_reloc = NO_RELOC;
|
---|
3583 |
|
---|
3584 | void
|
---|
3585 | x86_cons_fix_new (frag, off, len, exp)
|
---|
3586 | fragS *frag;
|
---|
3587 | unsigned int off;
|
---|
3588 | unsigned int len;
|
---|
3589 | expressionS *exp;
|
---|
3590 | {
|
---|
3591 | RELOC_ENUM r = reloc (len, 0, 0, got_reloc);
|
---|
3592 | got_reloc = NO_RELOC;
|
---|
3593 | fix_new_exp (frag, off, len, exp, 0, r);
|
---|
3594 | }
|
---|
3595 |
|
---|
3596 | void
|
---|
3597 | x86_cons (exp, size)
|
---|
3598 | expressionS *exp;
|
---|
3599 | int size;
|
---|
3600 | {
|
---|
3601 | if (size == 4)
|
---|
3602 | {
|
---|
3603 | /* Handle @GOTOFF and the like in an expression. */
|
---|
3604 | char *save;
|
---|
3605 | char *gotfree_input_line;
|
---|
3606 | int adjust;
|
---|
3607 |
|
---|
3608 | save = input_line_pointer;
|
---|
3609 | gotfree_input_line = lex_got (&got_reloc, &adjust);
|
---|
3610 | if (gotfree_input_line)
|
---|
3611 | input_line_pointer = gotfree_input_line;
|
---|
3612 |
|
---|
3613 | expression (exp);
|
---|
3614 |
|
---|
3615 | if (gotfree_input_line)
|
---|
3616 | {
|
---|
3617 | /* expression () has merrily parsed up to the end of line,
|
---|
3618 | or a comma - in the wrong buffer. Transfer how far
|
---|
3619 | input_line_pointer has moved to the right buffer. */
|
---|
3620 | input_line_pointer = (save
|
---|
3621 | + (input_line_pointer - gotfree_input_line)
|
---|
3622 | + adjust);
|
---|
3623 | free (gotfree_input_line);
|
---|
3624 | }
|
---|
3625 | }
|
---|
3626 | else
|
---|
3627 | expression (exp);
|
---|
3628 | }
|
---|
3629 | #endif
|
---|
3630 |
|
---|
3631 | static int i386_immediate PARAMS ((char *));
|
---|
3632 |
|
---|
3633 | static int
|
---|
3634 | i386_immediate (imm_start)
|
---|
3635 | char *imm_start;
|
---|
3636 | {
|
---|
3637 | char *save_input_line_pointer;
|
---|
3638 | #ifndef LEX_AT
|
---|
3639 | char *gotfree_input_line;
|
---|
3640 | #endif
|
---|
3641 | segT exp_seg = 0;
|
---|
3642 | expressionS *exp;
|
---|
3643 |
|
---|
3644 | if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
|
---|
3645 | {
|
---|
3646 | as_bad (_("only 1 or 2 immediate operands are allowed"));
|
---|
3647 | return 0;
|
---|
3648 | }
|
---|
3649 |
|
---|
3650 | exp = &im_expressions[i.imm_operands++];
|
---|
3651 | i.op[this_operand].imms = exp;
|
---|
3652 |
|
---|
3653 | if (is_space_char (*imm_start))
|
---|
3654 | ++imm_start;
|
---|
3655 |
|
---|
3656 | save_input_line_pointer = input_line_pointer;
|
---|
3657 | input_line_pointer = imm_start;
|
---|
3658 |
|
---|
3659 | #ifndef LEX_AT
|
---|
3660 | gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
|
---|
3661 | if (gotfree_input_line)
|
---|
3662 | input_line_pointer = gotfree_input_line;
|
---|
3663 | #endif
|
---|
3664 |
|
---|
3665 | exp_seg = expression (exp);
|
---|
3666 |
|
---|
3667 | SKIP_WHITESPACE ();
|
---|
3668 | if (*input_line_pointer)
|
---|
3669 | as_bad (_("junk `%s' after expression"), input_line_pointer);
|
---|
3670 |
|
---|
3671 | input_line_pointer = save_input_line_pointer;
|
---|
3672 | #ifndef LEX_AT
|
---|
3673 | if (gotfree_input_line)
|
---|
3674 | free (gotfree_input_line);
|
---|
3675 | #endif
|
---|
3676 |
|
---|
3677 | if (exp->X_op == O_absent || exp->X_op == O_big)
|
---|
3678 | {
|
---|
3679 | /* Missing or bad expr becomes absolute 0. */
|
---|
3680 | as_bad (_("missing or invalid immediate expression `%s' taken as 0"),
|
---|
3681 | imm_start);
|
---|
3682 | exp->X_op = O_constant;
|
---|
3683 | exp->X_add_number = 0;
|
---|
3684 | exp->X_add_symbol = (symbolS *) 0;
|
---|
3685 | exp->X_op_symbol = (symbolS *) 0;
|
---|
3686 | }
|
---|
3687 | else if (exp->X_op == O_constant)
|
---|
3688 | {
|
---|
3689 | /* Size it properly later. */
|
---|
3690 | i.types[this_operand] |= Imm64;
|
---|
3691 | /* If BFD64, sign extend val. */
|
---|
3692 | if (!use_rela_relocations)
|
---|
3693 | if ((exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0)
|
---|
3694 | exp->X_add_number = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
|
---|
3695 | }
|
---|
3696 | #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
|
---|
3697 | else if (1
|
---|
3698 | #ifdef BFD_ASSEMBLER
|
---|
3699 | && OUTPUT_FLAVOR == bfd_target_aout_flavour
|
---|
3700 | #endif
|
---|
3701 | && exp_seg != absolute_section
|
---|
3702 | && exp_seg != text_section
|
---|
3703 | && exp_seg != data_section
|
---|
3704 | && exp_seg != bss_section
|
---|
3705 | && exp_seg != undefined_section
|
---|
3706 | #ifdef BFD_ASSEMBLER
|
---|
3707 | && !bfd_is_com_section (exp_seg)
|
---|
3708 | #endif
|
---|
3709 | )
|
---|
3710 | {
|
---|
3711 | #ifdef BFD_ASSEMBLER
|
---|
3712 | as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
|
---|
3713 | #else
|
---|
3714 | as_bad (_("unimplemented segment type %d in operand"), exp_seg);
|
---|
3715 | #endif
|
---|
3716 | return 0;
|
---|
3717 | }
|
---|
3718 | #endif
|
---|
3719 | else
|
---|
3720 | {
|
---|
3721 | /* This is an address. The size of the address will be
|
---|
3722 | determined later, depending on destination register,
|
---|
3723 | suffix, or the default for the section. */
|
---|
3724 | i.types[this_operand] |= Imm8 | Imm16 | Imm32 | Imm32S | Imm64;
|
---|
3725 | }
|
---|
3726 |
|
---|
3727 | return 1;
|
---|
3728 | }
|
---|
3729 |
|
---|
3730 | static char *i386_scale PARAMS ((char *));
|
---|
3731 |
|
---|
3732 | static char *
|
---|
3733 | i386_scale (scale)
|
---|
3734 | char *scale;
|
---|
3735 | {
|
---|
3736 | offsetT val;
|
---|
3737 | char *save = input_line_pointer;
|
---|
3738 |
|
---|
3739 | input_line_pointer = scale;
|
---|
3740 | val = get_absolute_expression ();
|
---|
3741 |
|
---|
3742 | switch (val)
|
---|
3743 | {
|
---|
3744 | case 0:
|
---|
3745 | case 1:
|
---|
3746 | i.log2_scale_factor = 0;
|
---|
3747 | break;
|
---|
3748 | case 2:
|
---|
3749 | i.log2_scale_factor = 1;
|
---|
3750 | break;
|
---|
3751 | case 4:
|
---|
3752 | i.log2_scale_factor = 2;
|
---|
3753 | break;
|
---|
3754 | case 8:
|
---|
3755 | i.log2_scale_factor = 3;
|
---|
3756 | break;
|
---|
3757 | default:
|
---|
3758 | as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
|
---|
3759 | scale);
|
---|
3760 | input_line_pointer = save;
|
---|
3761 | return NULL;
|
---|
3762 | }
|
---|
3763 | if (i.log2_scale_factor != 0 && i.index_reg == 0)
|
---|
3764 | {
|
---|
3765 | as_warn (_("scale factor of %d without an index register"),
|
---|
3766 | 1 << i.log2_scale_factor);
|
---|
3767 | #if SCALE1_WHEN_NO_INDEX
|
---|
3768 | i.log2_scale_factor = 0;
|
---|
3769 | #endif
|
---|
3770 | }
|
---|
3771 | scale = input_line_pointer;
|
---|
3772 | input_line_pointer = save;
|
---|
3773 | return scale;
|
---|
3774 | }
|
---|
3775 |
|
---|
3776 | static int i386_displacement PARAMS ((char *, char *));
|
---|
3777 |
|
---|
3778 | static int
|
---|
3779 | i386_displacement (disp_start, disp_end)
|
---|
3780 | char *disp_start;
|
---|
3781 | char *disp_end;
|
---|
3782 | {
|
---|
3783 | expressionS *exp;
|
---|
3784 | segT exp_seg = 0;
|
---|
3785 | char *save_input_line_pointer;
|
---|
3786 | #ifndef LEX_AT
|
---|
3787 | char *gotfree_input_line;
|
---|
3788 | #endif
|
---|
3789 | int bigdisp = Disp32;
|
---|
3790 |
|
---|
3791 | if (flag_code == CODE_64BIT)
|
---|
3792 | {
|
---|
3793 | if (i.prefix[ADDR_PREFIX] == 0)
|
---|
3794 | bigdisp = Disp64;
|
---|
3795 | }
|
---|
3796 | else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
|
---|
3797 | bigdisp = Disp16;
|
---|
3798 | i.types[this_operand] |= bigdisp;
|
---|
3799 |
|
---|
3800 | exp = &disp_expressions[i.disp_operands];
|
---|
3801 | i.op[this_operand].disps = exp;
|
---|
3802 | i.disp_operands++;
|
---|
3803 | save_input_line_pointer = input_line_pointer;
|
---|
3804 | input_line_pointer = disp_start;
|
---|
3805 | END_STRING_AND_SAVE (disp_end);
|
---|
3806 |
|
---|
3807 | #ifndef GCC_ASM_O_HACK
|
---|
3808 | #define GCC_ASM_O_HACK 0
|
---|
3809 | #endif
|
---|
3810 | #if GCC_ASM_O_HACK
|
---|
3811 | END_STRING_AND_SAVE (disp_end + 1);
|
---|
3812 | if ((i.types[this_operand] & BaseIndex) != 0
|
---|
3813 | && displacement_string_end[-1] == '+')
|
---|
3814 | {
|
---|
3815 | /* This hack is to avoid a warning when using the "o"
|
---|
3816 | constraint within gcc asm statements.
|
---|
3817 | For instance:
|
---|
3818 |
|
---|
3819 | #define _set_tssldt_desc(n,addr,limit,type) \
|
---|
3820 | __asm__ __volatile__ ( \
|
---|
3821 | "movw %w2,%0\n\t" \
|
---|
3822 | "movw %w1,2+%0\n\t" \
|
---|
3823 | "rorl $16,%1\n\t" \
|
---|
3824 | "movb %b1,4+%0\n\t" \
|
---|
3825 | "movb %4,5+%0\n\t" \
|
---|
3826 | "movb $0,6+%0\n\t" \
|
---|
3827 | "movb %h1,7+%0\n\t" \
|
---|
3828 | "rorl $16,%1" \
|
---|
3829 | : "=o"(*(n)) : "q" (addr), "ri"(limit), "i"(type))
|
---|
3830 |
|
---|
3831 | This works great except that the output assembler ends
|
---|
3832 | up looking a bit weird if it turns out that there is
|
---|
3833 | no offset. You end up producing code that looks like:
|
---|
3834 |
|
---|
3835 | #APP
|
---|
3836 | movw $235,(%eax)
|
---|
3837 | movw %dx,2+(%eax)
|
---|
3838 | rorl $16,%edx
|
---|
3839 | movb %dl,4+(%eax)
|
---|
3840 | movb $137,5+(%eax)
|
---|
3841 | movb $0,6+(%eax)
|
---|
3842 | movb %dh,7+(%eax)
|
---|
3843 | rorl $16,%edx
|
---|
3844 | #NO_APP
|
---|
3845 |
|
---|
3846 | So here we provide the missing zero. */
|
---|
3847 |
|
---|
3848 | *displacement_string_end = '0';
|
---|
3849 | }
|
---|
3850 | #endif
|
---|
3851 | #ifndef LEX_AT
|
---|
3852 | gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
|
---|
3853 | if (gotfree_input_line)
|
---|
3854 | input_line_pointer = gotfree_input_line;
|
---|
3855 | #endif
|
---|
3856 |
|
---|
3857 | exp_seg = expression (exp);
|
---|
3858 |
|
---|
3859 | SKIP_WHITESPACE ();
|
---|
3860 | if (*input_line_pointer)
|
---|
3861 | as_bad (_("junk `%s' after expression"), input_line_pointer);
|
---|
3862 | #if GCC_ASM_O_HACK
|
---|
3863 | RESTORE_END_STRING (disp_end + 1);
|
---|
3864 | #endif
|
---|
3865 | RESTORE_END_STRING (disp_end);
|
---|
3866 | input_line_pointer = save_input_line_pointer;
|
---|
3867 | #ifndef LEX_AT
|
---|
3868 | if (gotfree_input_line)
|
---|
3869 | free (gotfree_input_line);
|
---|
3870 | #endif
|
---|
3871 |
|
---|
3872 | #ifdef BFD_ASSEMBLER
|
---|
3873 | /* We do this to make sure that the section symbol is in
|
---|
3874 | the symbol table. We will ultimately change the relocation
|
---|
3875 | to be relative to the beginning of the section. */
|
---|
3876 | if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
|
---|
3877 | || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
|
---|
3878 | {
|
---|
3879 | if (exp->X_op != O_symbol)
|
---|
3880 | {
|
---|
3881 | as_bad (_("bad expression used with @%s"),
|
---|
3882 | (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
|
---|
3883 | ? "GOTPCREL"
|
---|
3884 | : "GOTOFF"));
|
---|
3885 | return 0;
|
---|
3886 | }
|
---|
3887 |
|
---|
3888 | if (S_IS_LOCAL (exp->X_add_symbol)
|
---|
3889 | && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
|
---|
3890 | section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
|
---|
3891 | exp->X_op = O_subtract;
|
---|
3892 | exp->X_op_symbol = GOT_symbol;
|
---|
3893 | if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
|
---|
3894 | i.reloc[this_operand] = BFD_RELOC_32_PCREL;
|
---|
3895 | else
|
---|
3896 | i.reloc[this_operand] = BFD_RELOC_32;
|
---|
3897 | }
|
---|
3898 | #endif
|
---|
3899 |
|
---|
3900 | if (exp->X_op == O_absent || exp->X_op == O_big)
|
---|
3901 | {
|
---|
3902 | /* Missing or bad expr becomes absolute 0. */
|
---|
3903 | as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
|
---|
3904 | disp_start);
|
---|
3905 | exp->X_op = O_constant;
|
---|
3906 | exp->X_add_number = 0;
|
---|
3907 | exp->X_add_symbol = (symbolS *) 0;
|
---|
3908 | exp->X_op_symbol = (symbolS *) 0;
|
---|
3909 | }
|
---|
3910 |
|
---|
3911 | #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
|
---|
3912 | if (exp->X_op != O_constant
|
---|
3913 | #ifdef BFD_ASSEMBLER
|
---|
3914 | && OUTPUT_FLAVOR == bfd_target_aout_flavour
|
---|
3915 | #endif
|
---|
3916 | && exp_seg != absolute_section
|
---|
3917 | && exp_seg != text_section
|
---|
3918 | && exp_seg != data_section
|
---|
3919 | && exp_seg != bss_section
|
---|
3920 | && exp_seg != undefined_section
|
---|
3921 | #ifdef BFD_ASSEMBLER
|
---|
3922 | && !bfd_is_com_section (exp_seg)
|
---|
3923 | #endif
|
---|
3924 | )
|
---|
3925 | {
|
---|
3926 | #ifdef BFD_ASSEMBLER
|
---|
3927 | as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
|
---|
3928 | #else
|
---|
3929 | as_bad (_("unimplemented segment type %d in operand"), exp_seg);
|
---|
3930 | #endif
|
---|
3931 | return 0;
|
---|
3932 | }
|
---|
3933 | #endif
|
---|
3934 | else if (flag_code == CODE_64BIT)
|
---|
3935 | i.types[this_operand] |= Disp32S | Disp32;
|
---|
3936 | return 1;
|
---|
3937 | }
|
---|
3938 |
|
---|
3939 | static int i386_index_check PARAMS ((const char *));
|
---|
3940 |
|
---|
3941 | /* Make sure the memory operand we've been dealt is valid.
|
---|
3942 | Return 1 on success, 0 on a failure. */
|
---|
3943 |
|
---|
3944 | static int
|
---|
3945 | i386_index_check (operand_string)
|
---|
3946 | const char *operand_string;
|
---|
3947 | {
|
---|
3948 | int ok;
|
---|
3949 | #if INFER_ADDR_PREFIX
|
---|
3950 | int fudged = 0;
|
---|
3951 |
|
---|
3952 | tryprefix:
|
---|
3953 | #endif
|
---|
3954 | ok = 1;
|
---|
3955 | if (flag_code == CODE_64BIT)
|
---|
3956 | {
|
---|
3957 | if (i.prefix[ADDR_PREFIX] == 0)
|
---|
3958 | {
|
---|
3959 | /* 64bit checks. */
|
---|
3960 | if ((i.base_reg
|
---|
3961 | && ((i.base_reg->reg_type & Reg64) == 0)
|
---|
3962 | && (i.base_reg->reg_type != BaseIndex
|
---|
3963 | || i.index_reg))
|
---|
3964 | || (i.index_reg
|
---|
3965 | && ((i.index_reg->reg_type & (Reg64 | BaseIndex))
|
---|
3966 | != (Reg64 | BaseIndex))))
|
---|
3967 | ok = 0;
|
---|
3968 | }
|
---|
3969 | else
|
---|
3970 | {
|
---|
3971 | /* 32bit checks. */
|
---|
3972 | if ((i.base_reg
|
---|
3973 | && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
|
---|
3974 | || (i.index_reg
|
---|
3975 | && ((i.index_reg->reg_type & (Reg32 | BaseIndex | RegRex))
|
---|
3976 | != (Reg32 | BaseIndex))))
|
---|
3977 | ok = 0;
|
---|
3978 | }
|
---|
3979 | }
|
---|
3980 | else
|
---|
3981 | {
|
---|
3982 | if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
|
---|
3983 | {
|
---|
3984 | /* 16bit checks. */
|
---|
3985 | if ((i.base_reg
|
---|
3986 | && ((i.base_reg->reg_type & (Reg16 | BaseIndex | RegRex))
|
---|
3987 | != (Reg16 | BaseIndex)))
|
---|
3988 | || (i.index_reg
|
---|
3989 | && (((i.index_reg->reg_type & (Reg16 | BaseIndex))
|
---|
3990 | != (Reg16 | BaseIndex))
|
---|
3991 | || !(i.base_reg
|
---|
3992 | && i.base_reg->reg_num < 6
|
---|
3993 | && i.index_reg->reg_num >= 6
|
---|
3994 | && i.log2_scale_factor == 0))))
|
---|
3995 | ok = 0;
|
---|
3996 | }
|
---|
3997 | else
|
---|
3998 | {
|
---|
3999 | /* 32bit checks. */
|
---|
4000 | if ((i.base_reg
|
---|
4001 | && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
|
---|
4002 | || (i.index_reg
|
---|
4003 | && ((i.index_reg->reg_type & (Reg32 | BaseIndex | RegRex))
|
---|
4004 | != (Reg32 | BaseIndex))))
|
---|
4005 | ok = 0;
|
---|
4006 | }
|
---|
4007 | }
|
---|
4008 | if (!ok)
|
---|
4009 | {
|
---|
4010 | #if INFER_ADDR_PREFIX
|
---|
4011 | if (flag_code != CODE_64BIT
|
---|
4012 | && i.prefix[ADDR_PREFIX] == 0 && stackop_size != '\0')
|
---|
4013 | {
|
---|
4014 | i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
|
---|
4015 | i.prefixes += 1;
|
---|
4016 | /* Change the size of any displacement too. At most one of
|
---|
4017 | Disp16 or Disp32 is set.
|
---|
4018 | FIXME. There doesn't seem to be any real need for separate
|
---|
4019 | Disp16 and Disp32 flags. The same goes for Imm16 and Imm32.
|
---|
4020 | Removing them would probably clean up the code quite a lot. */
|
---|
4021 | if (i.types[this_operand] & (Disp16 | Disp32))
|
---|
4022 | i.types[this_operand] ^= (Disp16 | Disp32);
|
---|
4023 | fudged = 1;
|
---|
4024 | goto tryprefix;
|
---|
4025 | }
|
---|
4026 | if (fudged)
|
---|
4027 | as_bad (_("`%s' is not a valid base/index expression"),
|
---|
4028 | operand_string);
|
---|
4029 | else
|
---|
4030 | #endif
|
---|
4031 | as_bad (_("`%s' is not a valid %s bit base/index expression"),
|
---|
4032 | operand_string,
|
---|
4033 | flag_code_names[flag_code]);
|
---|
4034 | return 0;
|
---|
4035 | }
|
---|
4036 | return 1;
|
---|
4037 | }
|
---|
4038 |
|
---|
4039 | /* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero
|
---|
4040 | on error. */
|
---|
4041 |
|
---|
4042 | static int
|
---|
4043 | i386_operand (operand_string)
|
---|
4044 | char *operand_string;
|
---|
4045 | {
|
---|
4046 | const reg_entry *r;
|
---|
4047 | char *end_op;
|
---|
4048 | char *op_string = operand_string;
|
---|
4049 |
|
---|
4050 | if (is_space_char (*op_string))
|
---|
4051 | ++op_string;
|
---|
4052 |
|
---|
4053 | /* We check for an absolute prefix (differentiating,
|
---|
4054 | for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
|
---|
4055 | if (*op_string == ABSOLUTE_PREFIX)
|
---|
4056 | {
|
---|
4057 | ++op_string;
|
---|
4058 | if (is_space_char (*op_string))
|
---|
4059 | ++op_string;
|
---|
4060 | i.types[this_operand] |= JumpAbsolute;
|
---|
4061 | }
|
---|
4062 |
|
---|
4063 | /* Check if operand is a register. */
|
---|
4064 | if ((*op_string == REGISTER_PREFIX || allow_naked_reg)
|
---|
4065 | && (r = parse_register (op_string, &end_op)) != NULL)
|
---|
4066 | {
|
---|
4067 | /* Check for a segment override by searching for ':' after a
|
---|
4068 | segment register. */
|
---|
4069 | op_string = end_op;
|
---|
4070 | if (is_space_char (*op_string))
|
---|
4071 | ++op_string;
|
---|
4072 | if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
|
---|
4073 | {
|
---|
4074 | switch (r->reg_num)
|
---|
4075 | {
|
---|
4076 | case 0:
|
---|
4077 | i.seg[i.mem_operands] = &es;
|
---|
4078 | break;
|
---|
4079 | case 1:
|
---|
4080 | i.seg[i.mem_operands] = &cs;
|
---|
4081 | break;
|
---|
4082 | case 2:
|
---|
4083 | i.seg[i.mem_operands] = &ss;
|
---|
4084 | break;
|
---|
4085 | case 3:
|
---|
4086 | i.seg[i.mem_operands] = &ds;
|
---|
4087 | break;
|
---|
4088 | case 4:
|
---|
4089 | i.seg[i.mem_operands] = &fs;
|
---|
4090 | break;
|
---|
4091 | case 5:
|
---|
4092 | i.seg[i.mem_operands] = &gs;
|
---|
4093 | break;
|
---|
4094 | }
|
---|
4095 |
|
---|
4096 | /* Skip the ':' and whitespace. */
|
---|
4097 | ++op_string;
|
---|
4098 | if (is_space_char (*op_string))
|
---|
4099 | ++op_string;
|
---|
4100 |
|
---|
4101 | if (!is_digit_char (*op_string)
|
---|
4102 | && !is_identifier_char (*op_string)
|
---|
4103 | && *op_string != '('
|
---|
4104 | && *op_string != ABSOLUTE_PREFIX)
|
---|
4105 | {
|
---|
4106 | as_bad (_("bad memory operand `%s'"), op_string);
|
---|
4107 | return 0;
|
---|
4108 | }
|
---|
4109 | /* Handle case of %es:*foo. */
|
---|
4110 | if (*op_string == ABSOLUTE_PREFIX)
|
---|
4111 | {
|
---|
4112 | ++op_string;
|
---|
4113 | if (is_space_char (*op_string))
|
---|
4114 | ++op_string;
|
---|
4115 | i.types[this_operand] |= JumpAbsolute;
|
---|
4116 | }
|
---|
4117 | goto do_memory_reference;
|
---|
4118 | }
|
---|
4119 | if (*op_string)
|
---|
4120 | {
|
---|
4121 | as_bad (_("junk `%s' after register"), op_string);
|
---|
4122 | return 0;
|
---|
4123 | }
|
---|
4124 | i.types[this_operand] |= r->reg_type & ~BaseIndex;
|
---|
4125 | i.op[this_operand].regs = r;
|
---|
4126 | i.reg_operands++;
|
---|
4127 | }
|
---|
4128 | else if (*op_string == REGISTER_PREFIX)
|
---|
4129 | {
|
---|
4130 | as_bad (_("bad register name `%s'"), op_string);
|
---|
4131 | return 0;
|
---|
4132 | }
|
---|
4133 | else if (*op_string == IMMEDIATE_PREFIX)
|
---|
4134 | {
|
---|
4135 | ++op_string;
|
---|
4136 | if (i.types[this_operand] & JumpAbsolute)
|
---|
4137 | {
|
---|
4138 | as_bad (_("immediate operand illegal with absolute jump"));
|
---|
4139 | return 0;
|
---|
4140 | }
|
---|
4141 | if (!i386_immediate (op_string))
|
---|
4142 | return 0;
|
---|
4143 | }
|
---|
4144 | else if (is_digit_char (*op_string)
|
---|
4145 | || is_identifier_char (*op_string)
|
---|
4146 | || *op_string == '(')
|
---|
4147 | {
|
---|
4148 | /* This is a memory reference of some sort. */
|
---|
4149 | char *base_string;
|
---|
4150 |
|
---|
4151 | /* Start and end of displacement string expression (if found). */
|
---|
4152 | char *displacement_string_start;
|
---|
4153 | char *displacement_string_end;
|
---|
4154 |
|
---|
4155 | do_memory_reference:
|
---|
4156 | if ((i.mem_operands == 1
|
---|
4157 | && (current_templates->start->opcode_modifier & IsString) == 0)
|
---|
4158 | || i.mem_operands == 2)
|
---|
4159 | {
|
---|
4160 | as_bad (_("too many memory references for `%s'"),
|
---|
4161 | current_templates->start->name);
|
---|
4162 | return 0;
|
---|
4163 | }
|
---|
4164 |
|
---|
4165 | /* Check for base index form. We detect the base index form by
|
---|
4166 | looking for an ')' at the end of the operand, searching
|
---|
4167 | for the '(' matching it, and finding a REGISTER_PREFIX or ','
|
---|
4168 | after the '('. */
|
---|
4169 | base_string = op_string + strlen (op_string);
|
---|
4170 |
|
---|
4171 | --base_string;
|
---|
4172 | if (is_space_char (*base_string))
|
---|
4173 | --base_string;
|
---|
4174 |
|
---|
4175 | /* If we only have a displacement, set-up for it to be parsed later. */
|
---|
4176 | displacement_string_start = op_string;
|
---|
4177 | displacement_string_end = base_string + 1;
|
---|
4178 |
|
---|
4179 | if (*base_string == ')')
|
---|
4180 | {
|
---|
4181 | char *temp_string;
|
---|
4182 | unsigned int parens_balanced = 1;
|
---|
4183 | /* We've already checked that the number of left & right ()'s are
|
---|
4184 | equal, so this loop will not be infinite. */
|
---|
4185 | do
|
---|
4186 | {
|
---|
4187 | base_string--;
|
---|
4188 | if (*base_string == ')')
|
---|
4189 | parens_balanced++;
|
---|
4190 | if (*base_string == '(')
|
---|
4191 | parens_balanced--;
|
---|
4192 | }
|
---|
4193 | while (parens_balanced);
|
---|
4194 |
|
---|
4195 | temp_string = base_string;
|
---|
4196 |
|
---|
4197 | /* Skip past '(' and whitespace. */
|
---|
4198 | ++base_string;
|
---|
4199 | if (is_space_char (*base_string))
|
---|
4200 | ++base_string;
|
---|
4201 |
|
---|
4202 | if (*base_string == ','
|
---|
4203 | || ((*base_string == REGISTER_PREFIX || allow_naked_reg)
|
---|
4204 | && (i.base_reg = parse_register (base_string, &end_op)) != NULL))
|
---|
4205 | {
|
---|
4206 | displacement_string_end = temp_string;
|
---|
4207 |
|
---|
4208 | i.types[this_operand] |= BaseIndex;
|
---|
4209 |
|
---|
4210 | if (i.base_reg)
|
---|
4211 | {
|
---|
4212 | base_string = end_op;
|
---|
4213 | if (is_space_char (*base_string))
|
---|
4214 | ++base_string;
|
---|
4215 | }
|
---|
4216 |
|
---|
4217 | /* There may be an index reg or scale factor here. */
|
---|
4218 | if (*base_string == ',')
|
---|
4219 | {
|
---|
4220 | ++base_string;
|
---|
4221 | if (is_space_char (*base_string))
|
---|
4222 | ++base_string;
|
---|
4223 |
|
---|
4224 | if ((*base_string == REGISTER_PREFIX || allow_naked_reg)
|
---|
4225 | && (i.index_reg = parse_register (base_string, &end_op)) != NULL)
|
---|
4226 | {
|
---|
4227 | base_string = end_op;
|
---|
4228 | if (is_space_char (*base_string))
|
---|
4229 | ++base_string;
|
---|
4230 | if (*base_string == ',')
|
---|
4231 | {
|
---|
4232 | ++base_string;
|
---|
4233 | if (is_space_char (*base_string))
|
---|
4234 | ++base_string;
|
---|
4235 | }
|
---|
4236 | else if (*base_string != ')')
|
---|
4237 | {
|
---|
4238 | as_bad (_("expecting `,' or `)' after index register in `%s'"),
|
---|
4239 | operand_string);
|
---|
4240 | return 0;
|
---|
4241 | }
|
---|
4242 | }
|
---|
4243 | else if (*base_string == REGISTER_PREFIX)
|
---|
4244 | {
|
---|
4245 | as_bad (_("bad register name `%s'"), base_string);
|
---|
4246 | return 0;
|
---|
4247 | }
|
---|
4248 |
|
---|
4249 | /* Check for scale factor. */
|
---|
4250 | if (*base_string != ')')
|
---|
4251 | {
|
---|
4252 | char *end_scale = i386_scale (base_string);
|
---|
4253 |
|
---|
4254 | if (!end_scale)
|
---|
4255 | return 0;
|
---|
4256 |
|
---|
4257 | base_string = end_scale;
|
---|
4258 | if (is_space_char (*base_string))
|
---|
4259 | ++base_string;
|
---|
4260 | if (*base_string != ')')
|
---|
4261 | {
|
---|
4262 | as_bad (_("expecting `)' after scale factor in `%s'"),
|
---|
4263 | operand_string);
|
---|
4264 | return 0;
|
---|
4265 | }
|
---|
4266 | }
|
---|
4267 | else if (!i.index_reg)
|
---|
4268 | {
|
---|
4269 | as_bad (_("expecting index register or scale factor after `,'; got '%c'"),
|
---|
4270 | *base_string);
|
---|
4271 | return 0;
|
---|
4272 | }
|
---|
4273 | }
|
---|
4274 | else if (*base_string != ')')
|
---|
4275 | {
|
---|
4276 | as_bad (_("expecting `,' or `)' after base register in `%s'"),
|
---|
4277 | operand_string);
|
---|
4278 | return 0;
|
---|
4279 | }
|
---|
4280 | }
|
---|
4281 | else if (*base_string == REGISTER_PREFIX)
|
---|
4282 | {
|
---|
4283 | as_bad (_("bad register name `%s'"), base_string);
|
---|
4284 | return 0;
|
---|
4285 | }
|
---|
4286 | }
|
---|
4287 |
|
---|
4288 | /* If there's an expression beginning the operand, parse it,
|
---|
4289 | assuming displacement_string_start and
|
---|
4290 | displacement_string_end are meaningful. */
|
---|
4291 | if (displacement_string_start != displacement_string_end)
|
---|
4292 | {
|
---|
4293 | if (!i386_displacement (displacement_string_start,
|
---|
4294 | displacement_string_end))
|
---|
4295 | return 0;
|
---|
4296 | }
|
---|
4297 |
|
---|
4298 | /* Special case for (%dx) while doing input/output op. */
|
---|
4299 | if (i.base_reg
|
---|
4300 | && i.base_reg->reg_type == (Reg16 | InOutPortReg)
|
---|
4301 | && i.index_reg == 0
|
---|
4302 | && i.log2_scale_factor == 0
|
---|
4303 | && i.seg[i.mem_operands] == 0
|
---|
4304 | && (i.types[this_operand] & Disp) == 0)
|
---|
4305 | {
|
---|
4306 | i.types[this_operand] = InOutPortReg;
|
---|
4307 | return 1;
|
---|
4308 | }
|
---|
4309 |
|
---|
4310 | if (i386_index_check (operand_string) == 0)
|
---|
4311 | return 0;
|
---|
4312 | i.mem_operands++;
|
---|
4313 | }
|
---|
4314 | else
|
---|
4315 | {
|
---|
4316 | /* It's not a memory operand; argh! */
|
---|
4317 | as_bad (_("invalid char %s beginning operand %d `%s'"),
|
---|
4318 | output_invalid (*op_string),
|
---|
4319 | this_operand + 1,
|
---|
4320 | op_string);
|
---|
4321 | return 0;
|
---|
4322 | }
|
---|
4323 | return 1; /* Normal return. */
|
---|
4324 | }
|
---|
4325 | |
---|
4326 |
|
---|
4327 | /* md_estimate_size_before_relax()
|
---|
4328 |
|
---|
4329 | Called just before relax() for rs_machine_dependent frags. The x86
|
---|
4330 | assembler uses these frags to handle variable size jump
|
---|
4331 | instructions.
|
---|
4332 |
|
---|
4333 | Any symbol that is now undefined will not become defined.
|
---|
4334 | Return the correct fr_subtype in the frag.
|
---|
4335 | Return the initial "guess for variable size of frag" to caller.
|
---|
4336 | The guess is actually the growth beyond the fixed part. Whatever
|
---|
4337 | we do to grow the fixed or variable part contributes to our
|
---|
4338 | returned value. */
|
---|
4339 |
|
---|
4340 | int
|
---|
4341 | md_estimate_size_before_relax (fragP, segment)
|
---|
4342 | fragS *fragP;
|
---|
4343 | segT segment;
|
---|
4344 | {
|
---|
4345 | /* We've already got fragP->fr_subtype right; all we have to do is
|
---|
4346 | check for un-relaxable symbols. On an ELF system, we can't relax
|
---|
4347 | an externally visible symbol, because it may be overridden by a
|
---|
4348 | shared library. */
|
---|
4349 | if (S_GET_SEGMENT (fragP->fr_symbol) != segment
|
---|
4350 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4351 | || (OUTPUT_FLAVOR == bfd_target_elf_flavour
|
---|
4352 | && (S_IS_EXTERNAL (fragP->fr_symbol)
|
---|
4353 | || S_IS_WEAK (fragP->fr_symbol)))
|
---|
4354 | #endif
|
---|
4355 | )
|
---|
4356 | {
|
---|
4357 | /* Symbol is undefined in this segment, or we need to keep a
|
---|
4358 | reloc so that weak symbols can be overridden. */
|
---|
4359 | int size = (fragP->fr_subtype & CODE16) ? 2 : 4;
|
---|
4360 | RELOC_ENUM reloc_type;
|
---|
4361 | unsigned char *opcode;
|
---|
4362 | int old_fr_fix;
|
---|
4363 |
|
---|
4364 | if (fragP->fr_var != NO_RELOC)
|
---|
4365 | reloc_type = fragP->fr_var;
|
---|
4366 | else if (size == 2)
|
---|
4367 | reloc_type = BFD_RELOC_16_PCREL;
|
---|
4368 | else
|
---|
4369 | reloc_type = BFD_RELOC_32_PCREL;
|
---|
4370 |
|
---|
4371 | old_fr_fix = fragP->fr_fix;
|
---|
4372 | opcode = (unsigned char *) fragP->fr_opcode;
|
---|
4373 |
|
---|
4374 | switch (TYPE_FROM_RELAX_STATE (fragP->fr_subtype))
|
---|
4375 | {
|
---|
4376 | case UNCOND_JUMP:
|
---|
4377 | /* Make jmp (0xeb) a (d)word displacement jump. */
|
---|
4378 | opcode[0] = 0xe9;
|
---|
4379 | fragP->fr_fix += size;
|
---|
4380 | fix_new (fragP, old_fr_fix, size,
|
---|
4381 | fragP->fr_symbol,
|
---|
4382 | fragP->fr_offset, 1,
|
---|
4383 | reloc_type);
|
---|
4384 | break;
|
---|
4385 |
|
---|
4386 | case COND_JUMP86:
|
---|
4387 | if (size == 2
|
---|
4388 | && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC))
|
---|
4389 | {
|
---|
4390 | /* Negate the condition, and branch past an
|
---|
4391 | unconditional jump. */
|
---|
4392 | opcode[0] ^= 1;
|
---|
4393 | opcode[1] = 3;
|
---|
4394 | /* Insert an unconditional jump. */
|
---|
4395 | opcode[2] = 0xe9;
|
---|
4396 | /* We added two extra opcode bytes, and have a two byte
|
---|
4397 | offset. */
|
---|
4398 | fragP->fr_fix += 2 + 2;
|
---|
4399 | fix_new (fragP, old_fr_fix + 2, 2,
|
---|
4400 | fragP->fr_symbol,
|
---|
4401 | fragP->fr_offset, 1,
|
---|
4402 | reloc_type);
|
---|
4403 | break;
|
---|
4404 | }
|
---|
4405 | /* Fall through. */
|
---|
4406 |
|
---|
4407 | case COND_JUMP:
|
---|
4408 | if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC)
|
---|
4409 | {
|
---|
4410 | fixS *fixP;
|
---|
4411 |
|
---|
4412 | fragP->fr_fix += 1;
|
---|
4413 | fixP = fix_new (fragP, old_fr_fix, 1,
|
---|
4414 | fragP->fr_symbol,
|
---|
4415 | fragP->fr_offset, 1,
|
---|
4416 | BFD_RELOC_8_PCREL);
|
---|
4417 | fixP->fx_signed = 1;
|
---|
4418 | break;
|
---|
4419 | }
|
---|
4420 |
|
---|
4421 | /* This changes the byte-displacement jump 0x7N
|
---|
4422 | to the (d)word-displacement jump 0x0f,0x8N. */
|
---|
4423 | opcode[1] = opcode[0] + 0x10;
|
---|
4424 | opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
|
---|
4425 | /* We've added an opcode byte. */
|
---|
4426 | fragP->fr_fix += 1 + size;
|
---|
4427 | fix_new (fragP, old_fr_fix + 1, size,
|
---|
4428 | fragP->fr_symbol,
|
---|
4429 | fragP->fr_offset, 1,
|
---|
4430 | reloc_type);
|
---|
4431 | break;
|
---|
4432 |
|
---|
4433 | default:
|
---|
4434 | BAD_CASE (fragP->fr_subtype);
|
---|
4435 | break;
|
---|
4436 | }
|
---|
4437 | frag_wane (fragP);
|
---|
4438 | return fragP->fr_fix - old_fr_fix;
|
---|
4439 | }
|
---|
4440 |
|
---|
4441 | /* Guess size depending on current relax state. Initially the relax
|
---|
4442 | state will correspond to a short jump and we return 1, because
|
---|
4443 | the variable part of the frag (the branch offset) is one byte
|
---|
4444 | long. However, we can relax a section more than once and in that
|
---|
4445 | case we must either set fr_subtype back to the unrelaxed state,
|
---|
4446 | or return the value for the appropriate branch. */
|
---|
4447 | return md_relax_table[fragP->fr_subtype].rlx_length;
|
---|
4448 | }
|
---|
4449 |
|
---|
4450 | /* Called after relax() is finished.
|
---|
4451 |
|
---|
4452 | In: Address of frag.
|
---|
4453 | fr_type == rs_machine_dependent.
|
---|
4454 | fr_subtype is what the address relaxed to.
|
---|
4455 |
|
---|
4456 | Out: Any fixSs and constants are set up.
|
---|
4457 | Caller will turn frag into a ".space 0". */
|
---|
4458 |
|
---|
4459 | #ifndef BFD_ASSEMBLER
|
---|
4460 | void
|
---|
4461 | md_convert_frag (headers, sec, fragP)
|
---|
4462 | object_headers *headers ATTRIBUTE_UNUSED;
|
---|
4463 | segT sec ATTRIBUTE_UNUSED;
|
---|
4464 | fragS *fragP;
|
---|
4465 | #else
|
---|
4466 | void
|
---|
4467 | md_convert_frag (abfd, sec, fragP)
|
---|
4468 | bfd *abfd ATTRIBUTE_UNUSED;
|
---|
4469 | segT sec ATTRIBUTE_UNUSED;
|
---|
4470 | fragS *fragP;
|
---|
4471 | #endif
|
---|
4472 | {
|
---|
4473 | unsigned char *opcode;
|
---|
4474 | unsigned char *where_to_put_displacement = NULL;
|
---|
4475 | offsetT target_address;
|
---|
4476 | offsetT opcode_address;
|
---|
4477 | unsigned int extension = 0;
|
---|
4478 | offsetT displacement_from_opcode_start;
|
---|
4479 |
|
---|
4480 | opcode = (unsigned char *) fragP->fr_opcode;
|
---|
4481 |
|
---|
4482 | /* Address we want to reach in file space. */
|
---|
4483 | target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
|
---|
4484 |
|
---|
4485 | /* Address opcode resides at in file space. */
|
---|
4486 | opcode_address = fragP->fr_address + fragP->fr_fix;
|
---|
4487 |
|
---|
4488 | /* Displacement from opcode start to fill into instruction. */
|
---|
4489 | displacement_from_opcode_start = target_address - opcode_address;
|
---|
4490 |
|
---|
4491 | if ((fragP->fr_subtype & BIG) == 0)
|
---|
4492 | {
|
---|
4493 | /* Don't have to change opcode. */
|
---|
4494 | extension = 1; /* 1 opcode + 1 displacement */
|
---|
4495 | where_to_put_displacement = &opcode[1];
|
---|
4496 | }
|
---|
4497 | else
|
---|
4498 | {
|
---|
4499 | if (no_cond_jump_promotion
|
---|
4500 | && TYPE_FROM_RELAX_STATE (fragP->fr_subtype) != UNCOND_JUMP)
|
---|
4501 | as_warn_where (fragP->fr_file, fragP->fr_line, _("long jump required"));
|
---|
4502 |
|
---|
4503 | switch (fragP->fr_subtype)
|
---|
4504 | {
|
---|
4505 | case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG):
|
---|
4506 | extension = 4; /* 1 opcode + 4 displacement */
|
---|
4507 | opcode[0] = 0xe9;
|
---|
4508 | where_to_put_displacement = &opcode[1];
|
---|
4509 | break;
|
---|
4510 |
|
---|
4511 | case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16):
|
---|
4512 | extension = 2; /* 1 opcode + 2 displacement */
|
---|
4513 | opcode[0] = 0xe9;
|
---|
4514 | where_to_put_displacement = &opcode[1];
|
---|
4515 | break;
|
---|
4516 |
|
---|
4517 | case ENCODE_RELAX_STATE (COND_JUMP, BIG):
|
---|
4518 | case ENCODE_RELAX_STATE (COND_JUMP86, BIG):
|
---|
4519 | extension = 5; /* 2 opcode + 4 displacement */
|
---|
4520 | opcode[1] = opcode[0] + 0x10;
|
---|
4521 | opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
|
---|
4522 | where_to_put_displacement = &opcode[2];
|
---|
4523 | break;
|
---|
4524 |
|
---|
4525 | case ENCODE_RELAX_STATE (COND_JUMP, BIG16):
|
---|
4526 | extension = 3; /* 2 opcode + 2 displacement */
|
---|
4527 | opcode[1] = opcode[0] + 0x10;
|
---|
4528 | opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
|
---|
4529 | where_to_put_displacement = &opcode[2];
|
---|
4530 | break;
|
---|
4531 |
|
---|
4532 | case ENCODE_RELAX_STATE (COND_JUMP86, BIG16):
|
---|
4533 | extension = 4;
|
---|
4534 | opcode[0] ^= 1;
|
---|
4535 | opcode[1] = 3;
|
---|
4536 | opcode[2] = 0xe9;
|
---|
4537 | where_to_put_displacement = &opcode[3];
|
---|
4538 | break;
|
---|
4539 |
|
---|
4540 | default:
|
---|
4541 | BAD_CASE (fragP->fr_subtype);
|
---|
4542 | break;
|
---|
4543 | }
|
---|
4544 | }
|
---|
4545 |
|
---|
4546 | /* Now put displacement after opcode. */
|
---|
4547 | md_number_to_chars ((char *) where_to_put_displacement,
|
---|
4548 | (valueT) (displacement_from_opcode_start - extension),
|
---|
4549 | DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
|
---|
4550 | fragP->fr_fix += extension;
|
---|
4551 | }
|
---|
4552 | |
---|
4553 |
|
---|
4554 | /* Size of byte displacement jmp. */
|
---|
4555 | int md_short_jump_size = 2;
|
---|
4556 |
|
---|
4557 | /* Size of dword displacement jmp. */
|
---|
4558 | int md_long_jump_size = 5;
|
---|
4559 |
|
---|
4560 | /* Size of relocation record. */
|
---|
4561 | const int md_reloc_size = 8;
|
---|
4562 |
|
---|
4563 | void
|
---|
4564 | md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
---|
4565 | char *ptr;
|
---|
4566 | addressT from_addr, to_addr;
|
---|
4567 | fragS *frag ATTRIBUTE_UNUSED;
|
---|
4568 | symbolS *to_symbol ATTRIBUTE_UNUSED;
|
---|
4569 | {
|
---|
4570 | offsetT offset;
|
---|
4571 |
|
---|
4572 | offset = to_addr - (from_addr + 2);
|
---|
4573 | /* Opcode for byte-disp jump. */
|
---|
4574 | md_number_to_chars (ptr, (valueT) 0xeb, 1);
|
---|
4575 | md_number_to_chars (ptr + 1, (valueT) offset, 1);
|
---|
4576 | }
|
---|
4577 |
|
---|
4578 | void
|
---|
4579 | md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
|
---|
4580 | char *ptr;
|
---|
4581 | addressT from_addr, to_addr;
|
---|
4582 | fragS *frag ATTRIBUTE_UNUSED;
|
---|
4583 | symbolS *to_symbol ATTRIBUTE_UNUSED;
|
---|
4584 | {
|
---|
4585 | offsetT offset;
|
---|
4586 |
|
---|
4587 | offset = to_addr - (from_addr + 5);
|
---|
4588 | md_number_to_chars (ptr, (valueT) 0xe9, 1);
|
---|
4589 | md_number_to_chars (ptr + 1, (valueT) offset, 4);
|
---|
4590 | }
|
---|
4591 | |
---|
4592 |
|
---|
4593 | /* Apply a fixup (fixS) to segment data, once it has been determined
|
---|
4594 | by our caller that we have all the info we need to fix it up.
|
---|
4595 |
|
---|
4596 | On the 386, immediates, displacements, and data pointers are all in
|
---|
4597 | the same (little-endian) format, so we don't need to care about which
|
---|
4598 | we are handling. */
|
---|
4599 |
|
---|
4600 | void
|
---|
4601 | md_apply_fix3 (fixP, valP, seg)
|
---|
4602 | /* The fix we're to put in. */
|
---|
4603 | fixS *fixP;
|
---|
4604 | /* Pointer to the value of the bits. */
|
---|
4605 | valueT *valP;
|
---|
4606 | /* Segment fix is from. */
|
---|
4607 | segT seg ATTRIBUTE_UNUSED;
|
---|
4608 | {
|
---|
4609 | char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
|
---|
4610 | valueT value = *valP;
|
---|
4611 |
|
---|
4612 | #if defined (BFD_ASSEMBLER) && !defined (TE_Mach)
|
---|
4613 | if (fixP->fx_pcrel)
|
---|
4614 | {
|
---|
4615 | switch (fixP->fx_r_type)
|
---|
4616 | {
|
---|
4617 | default:
|
---|
4618 | break;
|
---|
4619 |
|
---|
4620 | case BFD_RELOC_32:
|
---|
4621 | fixP->fx_r_type = BFD_RELOC_32_PCREL;
|
---|
4622 | break;
|
---|
4623 | case BFD_RELOC_16:
|
---|
4624 | fixP->fx_r_type = BFD_RELOC_16_PCREL;
|
---|
4625 | break;
|
---|
4626 | case BFD_RELOC_8:
|
---|
4627 | fixP->fx_r_type = BFD_RELOC_8_PCREL;
|
---|
4628 | break;
|
---|
4629 | }
|
---|
4630 | }
|
---|
4631 |
|
---|
4632 | if (fixP->fx_addsy != NULL
|
---|
4633 | && (fixP->fx_r_type == BFD_RELOC_32_PCREL
|
---|
4634 | || fixP->fx_r_type == BFD_RELOC_16_PCREL
|
---|
4635 | || fixP->fx_r_type == BFD_RELOC_8_PCREL)
|
---|
4636 | && !use_rela_relocations)
|
---|
4637 | {
|
---|
4638 | /* This is a hack. There should be a better way to handle this.
|
---|
4639 | This covers for the fact that bfd_install_relocation will
|
---|
4640 | subtract the current location (for partial_inplace, PC relative
|
---|
4641 | relocations); see more below. */
|
---|
4642 | #ifndef OBJ_AOUT
|
---|
4643 | if (OUTPUT_FLAVOR == bfd_target_elf_flavour
|
---|
4644 | #ifdef TE_PE
|
---|
4645 | || OUTPUT_FLAVOR == bfd_target_coff_flavour
|
---|
4646 | #endif
|
---|
4647 | )
|
---|
4648 | value += fixP->fx_where + fixP->fx_frag->fr_address;
|
---|
4649 | #endif
|
---|
4650 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4651 | if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
---|
4652 | {
|
---|
4653 | segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy);
|
---|
4654 |
|
---|
4655 | if ((sym_seg == seg
|
---|
4656 | || (symbol_section_p (fixP->fx_addsy)
|
---|
4657 | && sym_seg != absolute_section))
|
---|
4658 | && !generic_force_reloc (fixP))
|
---|
4659 | {
|
---|
4660 | /* Yes, we add the values in twice. This is because
|
---|
4661 | bfd_install_relocation subtracts them out again. I think
|
---|
4662 | bfd_install_relocation is broken, but I don't dare change
|
---|
4663 | it. FIXME. */
|
---|
4664 | value += fixP->fx_where + fixP->fx_frag->fr_address;
|
---|
4665 | }
|
---|
4666 | }
|
---|
4667 | #endif
|
---|
4668 | #if defined (OBJ_COFF) && defined (TE_PE)
|
---|
4669 | /* For some reason, the PE format does not store a section
|
---|
4670 | address offset for a PC relative symbol. */
|
---|
4671 | if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
---|
4672 | value += md_pcrel_from (fixP);
|
---|
4673 | #endif
|
---|
4674 | }
|
---|
4675 |
|
---|
4676 | /* Fix a few things - the dynamic linker expects certain values here,
|
---|
4677 | and we must not dissappoint it. */
|
---|
4678 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4679 | if (OUTPUT_FLAVOR == bfd_target_elf_flavour
|
---|
4680 | && fixP->fx_addsy)
|
---|
4681 | switch (fixP->fx_r_type)
|
---|
4682 | {
|
---|
4683 | case BFD_RELOC_386_PLT32:
|
---|
4684 | case BFD_RELOC_X86_64_PLT32:
|
---|
4685 | /* Make the jump instruction point to the address of the operand. At
|
---|
4686 | runtime we merely add the offset to the actual PLT entry. */
|
---|
4687 | value = -4;
|
---|
4688 | break;
|
---|
4689 |
|
---|
4690 | case BFD_RELOC_386_TLS_GD:
|
---|
4691 | case BFD_RELOC_386_TLS_LDM:
|
---|
4692 | case BFD_RELOC_386_TLS_IE_32:
|
---|
4693 | case BFD_RELOC_386_TLS_IE:
|
---|
4694 | case BFD_RELOC_386_TLS_GOTIE:
|
---|
4695 | case BFD_RELOC_X86_64_TLSGD:
|
---|
4696 | case BFD_RELOC_X86_64_TLSLD:
|
---|
4697 | case BFD_RELOC_X86_64_GOTTPOFF:
|
---|
4698 | value = 0; /* Fully resolved at runtime. No addend. */
|
---|
4699 | /* Fallthrough */
|
---|
4700 | case BFD_RELOC_386_TLS_LE:
|
---|
4701 | case BFD_RELOC_386_TLS_LDO_32:
|
---|
4702 | case BFD_RELOC_386_TLS_LE_32:
|
---|
4703 | case BFD_RELOC_X86_64_DTPOFF32:
|
---|
4704 | case BFD_RELOC_X86_64_TPOFF32:
|
---|
4705 | S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
---|
4706 | break;
|
---|
4707 |
|
---|
4708 | case BFD_RELOC_386_GOT32:
|
---|
4709 | case BFD_RELOC_X86_64_GOT32:
|
---|
4710 | value = 0; /* Fully resolved at runtime. No addend. */
|
---|
4711 | break;
|
---|
4712 |
|
---|
4713 | case BFD_RELOC_VTABLE_INHERIT:
|
---|
4714 | case BFD_RELOC_VTABLE_ENTRY:
|
---|
4715 | fixP->fx_done = 0;
|
---|
4716 | return;
|
---|
4717 |
|
---|
4718 | default:
|
---|
4719 | break;
|
---|
4720 | }
|
---|
4721 | #endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */
|
---|
4722 | *valP = value;
|
---|
4723 | #endif /* defined (BFD_ASSEMBLER) && !defined (TE_Mach) */
|
---|
4724 |
|
---|
4725 | /* Are we finished with this relocation now? */
|
---|
4726 | if (fixP->fx_addsy == NULL)
|
---|
4727 | fixP->fx_done = 1;
|
---|
4728 | #ifdef BFD_ASSEMBLER
|
---|
4729 | else if (use_rela_relocations)
|
---|
4730 | {
|
---|
4731 | fixP->fx_no_overflow = 1;
|
---|
4732 | /* Remember value for tc_gen_reloc. */
|
---|
4733 | fixP->fx_addnumber = value;
|
---|
4734 | value = 0;
|
---|
4735 | }
|
---|
4736 | #endif
|
---|
4737 | md_number_to_chars (p, value, fixP->fx_size);
|
---|
4738 | }
|
---|
4739 | |
---|
4740 |
|
---|
4741 | #define MAX_LITTLENUMS 6
|
---|
4742 |
|
---|
4743 | /* Turn the string pointed to by litP into a floating point constant
|
---|
4744 | of type TYPE, and emit the appropriate bytes. The number of
|
---|
4745 | LITTLENUMS emitted is stored in *SIZEP. An error message is
|
---|
4746 | returned, or NULL on OK. */
|
---|
4747 |
|
---|
4748 | char *
|
---|
4749 | md_atof (type, litP, sizeP)
|
---|
4750 | int type;
|
---|
4751 | char *litP;
|
---|
4752 | int *sizeP;
|
---|
4753 | {
|
---|
4754 | int prec;
|
---|
4755 | LITTLENUM_TYPE words[MAX_LITTLENUMS];
|
---|
4756 | LITTLENUM_TYPE *wordP;
|
---|
4757 | char *t;
|
---|
4758 |
|
---|
4759 | switch (type)
|
---|
4760 | {
|
---|
4761 | case 'f':
|
---|
4762 | case 'F':
|
---|
4763 | prec = 2;
|
---|
4764 | break;
|
---|
4765 |
|
---|
4766 | case 'd':
|
---|
4767 | case 'D':
|
---|
4768 | prec = 4;
|
---|
4769 | break;
|
---|
4770 |
|
---|
4771 | case 'x':
|
---|
4772 | case 'X':
|
---|
4773 | prec = 5;
|
---|
4774 | break;
|
---|
4775 |
|
---|
4776 | default:
|
---|
4777 | *sizeP = 0;
|
---|
4778 | return _("Bad call to md_atof ()");
|
---|
4779 | }
|
---|
4780 | t = atof_ieee (input_line_pointer, type, words);
|
---|
4781 | if (t)
|
---|
4782 | input_line_pointer = t;
|
---|
4783 |
|
---|
4784 | *sizeP = prec * sizeof (LITTLENUM_TYPE);
|
---|
4785 | /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
|
---|
4786 | the bigendian 386. */
|
---|
4787 | for (wordP = words + prec - 1; prec--;)
|
---|
4788 | {
|
---|
4789 | md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
|
---|
4790 | litP += sizeof (LITTLENUM_TYPE);
|
---|
4791 | }
|
---|
4792 | return 0;
|
---|
4793 | }
|
---|
4794 | |
---|
4795 |
|
---|
4796 | char output_invalid_buf[8];
|
---|
4797 |
|
---|
4798 | static char *
|
---|
4799 | output_invalid (c)
|
---|
4800 | int c;
|
---|
4801 | {
|
---|
4802 | if (ISPRINT (c))
|
---|
4803 | sprintf (output_invalid_buf, "'%c'", c);
|
---|
4804 | else
|
---|
4805 | sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
|
---|
4806 | return output_invalid_buf;
|
---|
4807 | }
|
---|
4808 |
|
---|
4809 | /* REG_STRING starts *before* REGISTER_PREFIX. */
|
---|
4810 |
|
---|
4811 | static const reg_entry *
|
---|
4812 | parse_register (reg_string, end_op)
|
---|
4813 | char *reg_string;
|
---|
4814 | char **end_op;
|
---|
4815 | {
|
---|
4816 | char *s = reg_string;
|
---|
4817 | char *p;
|
---|
4818 | char reg_name_given[MAX_REG_NAME_SIZE + 1];
|
---|
4819 | const reg_entry *r;
|
---|
4820 |
|
---|
4821 | /* Skip possible REGISTER_PREFIX and possible whitespace. */
|
---|
4822 | if (*s == REGISTER_PREFIX)
|
---|
4823 | ++s;
|
---|
4824 |
|
---|
4825 | if (is_space_char (*s))
|
---|
4826 | ++s;
|
---|
4827 |
|
---|
4828 | p = reg_name_given;
|
---|
4829 | while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
|
---|
4830 | {
|
---|
4831 | if (p >= reg_name_given + MAX_REG_NAME_SIZE)
|
---|
4832 | return (const reg_entry *) NULL;
|
---|
4833 | s++;
|
---|
4834 | }
|
---|
4835 |
|
---|
4836 | /* For naked regs, make sure that we are not dealing with an identifier.
|
---|
4837 | This prevents confusing an identifier like `eax_var' with register
|
---|
4838 | `eax'. */
|
---|
4839 | if (allow_naked_reg && identifier_chars[(unsigned char) *s])
|
---|
4840 | return (const reg_entry *) NULL;
|
---|
4841 |
|
---|
4842 | *end_op = s;
|
---|
4843 |
|
---|
4844 | r = (const reg_entry *) hash_find (reg_hash, reg_name_given);
|
---|
4845 |
|
---|
4846 | /* Handle floating point regs, allowing spaces in the (i) part. */
|
---|
4847 | if (r == i386_regtab /* %st is first entry of table */)
|
---|
4848 | {
|
---|
4849 | if (is_space_char (*s))
|
---|
4850 | ++s;
|
---|
4851 | if (*s == '(')
|
---|
4852 | {
|
---|
4853 | ++s;
|
---|
4854 | if (is_space_char (*s))
|
---|
4855 | ++s;
|
---|
4856 | if (*s >= '0' && *s <= '7')
|
---|
4857 | {
|
---|
4858 | r = &i386_float_regtab[*s - '0'];
|
---|
4859 | ++s;
|
---|
4860 | if (is_space_char (*s))
|
---|
4861 | ++s;
|
---|
4862 | if (*s == ')')
|
---|
4863 | {
|
---|
4864 | *end_op = s + 1;
|
---|
4865 | return r;
|
---|
4866 | }
|
---|
4867 | }
|
---|
4868 | /* We have "%st(" then garbage. */
|
---|
4869 | return (const reg_entry *) NULL;
|
---|
4870 | }
|
---|
4871 | }
|
---|
4872 |
|
---|
4873 | if (r != NULL
|
---|
4874 | && (r->reg_flags & (RegRex64 | RegRex)) != 0
|
---|
4875 | && flag_code != CODE_64BIT)
|
---|
4876 | {
|
---|
4877 | return (const reg_entry *) NULL;
|
---|
4878 | }
|
---|
4879 |
|
---|
4880 | return r;
|
---|
4881 | }
|
---|
4882 | |
---|
4883 |
|
---|
4884 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4885 | const char *md_shortopts = "kVQ:sq";
|
---|
4886 | #else
|
---|
4887 | const char *md_shortopts = "q";
|
---|
4888 | #endif
|
---|
4889 |
|
---|
4890 | struct option md_longopts[] = {
|
---|
4891 | #define OPTION_32 (OPTION_MD_BASE + 0)
|
---|
4892 | {"32", no_argument, NULL, OPTION_32},
|
---|
4893 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4894 | #define OPTION_64 (OPTION_MD_BASE + 1)
|
---|
4895 | {"64", no_argument, NULL, OPTION_64},
|
---|
4896 | #endif
|
---|
4897 | #ifdef EMX
|
---|
4898 | #define OPTION_ZOMF (OPTION_MD_BASE + 1)
|
---|
4899 | {"Zomf", no_argument, NULL, OPTION_ZOMF},
|
---|
4900 | #define OPTION_ZSTRIP (OPTION_MD_BASE + 2)
|
---|
4901 | {"Zstrip", no_argument, NULL, OPTION_ZSTRIP},
|
---|
4902 | #endif /* EMX */
|
---|
4903 | {NULL, no_argument, NULL, 0}
|
---|
4904 | };
|
---|
4905 | size_t md_longopts_size = sizeof (md_longopts);
|
---|
4906 |
|
---|
4907 | #ifdef EMX
|
---|
4908 | extern int emx_omf;
|
---|
4909 | extern int emx_strip;
|
---|
4910 | #endif /* EMX */
|
---|
4911 |
|
---|
4912 | int
|
---|
4913 | md_parse_option (c, arg)
|
---|
4914 | int c;
|
---|
4915 | char *arg ATTRIBUTE_UNUSED;
|
---|
4916 | {
|
---|
4917 | switch (c)
|
---|
4918 | {
|
---|
4919 | case 'q':
|
---|
4920 | quiet_warnings = 1;
|
---|
4921 | break;
|
---|
4922 |
|
---|
4923 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4924 | /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
|
---|
4925 | should be emitted or not. FIXME: Not implemented. */
|
---|
4926 | case 'Q':
|
---|
4927 | break;
|
---|
4928 |
|
---|
4929 | /* -V: SVR4 argument to print version ID. */
|
---|
4930 | case 'V':
|
---|
4931 | print_version_id ();
|
---|
4932 | break;
|
---|
4933 |
|
---|
4934 | /* -k: Ignore for FreeBSD compatibility. */
|
---|
4935 | case 'k':
|
---|
4936 | break;
|
---|
4937 |
|
---|
4938 | case 's':
|
---|
4939 | /* -s: On i386 Solaris, this tells the native assembler to use
|
---|
4940 | .stab instead of .stab.excl. We always use .stab anyhow. */
|
---|
4941 | break;
|
---|
4942 |
|
---|
4943 | case OPTION_64:
|
---|
4944 | {
|
---|
4945 | const char **list, **l;
|
---|
4946 |
|
---|
4947 | list = bfd_target_list ();
|
---|
4948 | for (l = list; *l != NULL; l++)
|
---|
4949 | if (strcmp (*l, "elf64-x86-64") == 0)
|
---|
4950 | {
|
---|
4951 | default_arch = "x86_64";
|
---|
4952 | break;
|
---|
4953 | }
|
---|
4954 | if (*l == NULL)
|
---|
4955 | as_fatal (_("No compiled in support for x86_64"));
|
---|
4956 | free (list);
|
---|
4957 | }
|
---|
4958 | break;
|
---|
4959 | #endif
|
---|
4960 |
|
---|
4961 | case OPTION_32:
|
---|
4962 | default_arch = "i386";
|
---|
4963 | break;
|
---|
4964 |
|
---|
4965 | #ifdef EMX
|
---|
4966 | case OPTION_ZOMF:
|
---|
4967 | emx_omf = 1;
|
---|
4968 | break;
|
---|
4969 |
|
---|
4970 | case OPTION_ZSTRIP:
|
---|
4971 | emx_strip = 1;
|
---|
4972 | break;
|
---|
4973 | #endif /* EMX */
|
---|
4974 |
|
---|
4975 | default:
|
---|
4976 | return 0;
|
---|
4977 | }
|
---|
4978 | return 1;
|
---|
4979 | }
|
---|
4980 |
|
---|
4981 | void
|
---|
4982 | md_show_usage (stream)
|
---|
4983 | FILE *stream;
|
---|
4984 | {
|
---|
4985 | #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
---|
4986 | fprintf (stream, _("\
|
---|
4987 | -Q ignored\n\
|
---|
4988 | -V print assembler version number\n\
|
---|
4989 | -k ignored\n\
|
---|
4990 | -q quieten some warnings\n\
|
---|
4991 | -s ignored\n"));
|
---|
4992 | #else
|
---|
4993 | fprintf (stream, _("\
|
---|
4994 | -q quieten some warnings\n"));
|
---|
4995 | #endif
|
---|
4996 | }
|
---|
4997 |
|
---|
4998 | #ifdef BFD_ASSEMBLER
|
---|
4999 | #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
|
---|
5000 | || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
|
---|
5001 |
|
---|
5002 | /* Pick the target format to use. */
|
---|
5003 |
|
---|
5004 | const char *
|
---|
5005 | i386_target_format ()
|
---|
5006 | {
|
---|
5007 | if (!strcmp (default_arch, "x86_64"))
|
---|
5008 | set_code_flag (CODE_64BIT);
|
---|
5009 | else if (!strcmp (default_arch, "i386"))
|
---|
5010 | set_code_flag (CODE_32BIT);
|
---|
5011 | else
|
---|
5012 | as_fatal (_("Unknown architecture"));
|
---|
5013 | switch (OUTPUT_FLAVOR)
|
---|
5014 | {
|
---|
5015 | #ifdef OBJ_MAYBE_AOUT
|
---|
5016 | case bfd_target_aout_flavour:
|
---|
5017 | return AOUT_TARGET_FORMAT;
|
---|
5018 | #endif
|
---|
5019 | #ifdef OBJ_MAYBE_COFF
|
---|
5020 | case bfd_target_coff_flavour:
|
---|
5021 | return "coff-i386";
|
---|
5022 | #endif
|
---|
5023 | #if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
|
---|
5024 | case bfd_target_elf_flavour:
|
---|
5025 | {
|
---|
5026 | if (flag_code == CODE_64BIT)
|
---|
5027 | use_rela_relocations = 1;
|
---|
5028 | return flag_code == CODE_64BIT ? "elf64-x86-64" : ELF_TARGET_FORMAT;
|
---|
5029 | }
|
---|
5030 | #endif
|
---|
5031 | default:
|
---|
5032 | abort ();
|
---|
5033 | return NULL;
|
---|
5034 | }
|
---|
5035 | }
|
---|
5036 |
|
---|
5037 | #endif /* OBJ_MAYBE_ more than one */
|
---|
5038 |
|
---|
5039 | #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
|
---|
5040 | void i386_elf_emit_arch_note ()
|
---|
5041 | {
|
---|
5042 | if (OUTPUT_FLAVOR == bfd_target_elf_flavour
|
---|
5043 | && cpu_arch_name != NULL)
|
---|
5044 | {
|
---|
5045 | char *p;
|
---|
5046 | asection *seg = now_seg;
|
---|
5047 | subsegT subseg = now_subseg;
|
---|
5048 | Elf_Internal_Note i_note;
|
---|
5049 | Elf_External_Note e_note;
|
---|
5050 | asection *note_secp;
|
---|
5051 | int len;
|
---|
5052 |
|
---|
5053 | /* Create the .note section. */
|
---|
5054 | note_secp = subseg_new (".note", 0);
|
---|
5055 | bfd_set_section_flags (stdoutput,
|
---|
5056 | note_secp,
|
---|
5057 | SEC_HAS_CONTENTS | SEC_READONLY);
|
---|
5058 |
|
---|
5059 | /* Process the arch string. */
|
---|
5060 | len = strlen (cpu_arch_name);
|
---|
5061 |
|
---|
5062 | i_note.namesz = len + 1;
|
---|
5063 | i_note.descsz = 0;
|
---|
5064 | i_note.type = NT_ARCH;
|
---|
5065 | p = frag_more (sizeof (e_note.namesz));
|
---|
5066 | md_number_to_chars (p, (valueT) i_note.namesz, sizeof (e_note.namesz));
|
---|
5067 | p = frag_more (sizeof (e_note.descsz));
|
---|
5068 | md_number_to_chars (p, (valueT) i_note.descsz, sizeof (e_note.descsz));
|
---|
5069 | p = frag_more (sizeof (e_note.type));
|
---|
5070 | md_number_to_chars (p, (valueT) i_note.type, sizeof (e_note.type));
|
---|
5071 | p = frag_more (len + 1);
|
---|
5072 | strcpy (p, cpu_arch_name);
|
---|
5073 |
|
---|
5074 | frag_align (2, 0, 0);
|
---|
5075 |
|
---|
5076 | subseg_set (seg, subseg);
|
---|
5077 | }
|
---|
5078 | }
|
---|
5079 | #endif
|
---|
5080 | #endif /* BFD_ASSEMBLER */
|
---|
5081 | |
---|
5082 |
|
---|
5083 | symbolS *
|
---|
5084 | md_undefined_symbol (name)
|
---|
5085 | char *name;
|
---|
5086 | {
|
---|
5087 | if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0]
|
---|
5088 | && name[1] == GLOBAL_OFFSET_TABLE_NAME[1]
|
---|
5089 | && name[2] == GLOBAL_OFFSET_TABLE_NAME[2]
|
---|
5090 | && strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)
|
---|
5091 | {
|
---|
5092 | if (!GOT_symbol)
|
---|
5093 | {
|
---|
5094 | if (symbol_find (name))
|
---|
5095 | as_bad (_("GOT already in symbol table"));
|
---|
5096 | GOT_symbol = symbol_new (name, undefined_section,
|
---|
5097 | (valueT) 0, &zero_address_frag);
|
---|
5098 | };
|
---|
5099 | return GOT_symbol;
|
---|
5100 | }
|
---|
5101 | return 0;
|
---|
5102 | }
|
---|
5103 |
|
---|
5104 | /* Round up a section size to the appropriate boundary. */
|
---|
5105 |
|
---|
5106 | valueT
|
---|
5107 | md_section_align (segment, size)
|
---|
5108 | segT segment ATTRIBUTE_UNUSED;
|
---|
5109 | valueT size;
|
---|
5110 | {
|
---|
5111 | #ifdef BFD_ASSEMBLER
|
---|
5112 | #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
|
---|
5113 | if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
|
---|
5114 | {
|
---|
5115 | /* For a.out, force the section size to be aligned. If we don't do
|
---|
5116 | this, BFD will align it for us, but it will not write out the
|
---|
5117 | final bytes of the section. This may be a bug in BFD, but it is
|
---|
5118 | easier to fix it here since that is how the other a.out targets
|
---|
5119 | work. */
|
---|
5120 | int align;
|
---|
5121 |
|
---|
5122 | align = bfd_get_section_alignment (stdoutput, segment);
|
---|
5123 | size = ((size + (1 << align) - 1) & ((valueT) -1 << align));
|
---|
5124 | }
|
---|
5125 | #endif
|
---|
5126 | #endif
|
---|
5127 |
|
---|
5128 | return size;
|
---|
5129 | }
|
---|
5130 |
|
---|
5131 | /* On the i386, PC-relative offsets are relative to the start of the
|
---|
5132 | next instruction. That is, the address of the offset, plus its
|
---|
5133 | size, since the offset is always the last part of the insn. */
|
---|
5134 |
|
---|
5135 | long
|
---|
5136 | md_pcrel_from (fixP)
|
---|
5137 | fixS *fixP;
|
---|
5138 | {
|
---|
5139 | return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
|
---|
5140 | }
|
---|
5141 |
|
---|
5142 | #ifndef I386COFF
|
---|
5143 |
|
---|
5144 | static void
|
---|
5145 | s_bss (ignore)
|
---|
5146 | int ignore ATTRIBUTE_UNUSED;
|
---|
5147 | {
|
---|
5148 | int temp;
|
---|
5149 |
|
---|
5150 | temp = get_absolute_expression ();
|
---|
5151 | subseg_set (bss_section, (subsegT) temp);
|
---|
5152 | demand_empty_rest_of_line ();
|
---|
5153 | }
|
---|
5154 |
|
---|
5155 | #endif
|
---|
5156 |
|
---|
5157 | #ifdef BFD_ASSEMBLER
|
---|
5158 |
|
---|
5159 | void
|
---|
5160 | i386_validate_fix (fixp)
|
---|
5161 | fixS *fixp;
|
---|
5162 | {
|
---|
5163 | if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol)
|
---|
5164 | {
|
---|
5165 | /* GOTOFF relocation are nonsense in 64bit mode. */
|
---|
5166 | if (fixp->fx_r_type == BFD_RELOC_32_PCREL)
|
---|
5167 | {
|
---|
5168 | if (flag_code != CODE_64BIT)
|
---|
5169 | abort ();
|
---|
5170 | fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL;
|
---|
5171 | }
|
---|
5172 | else
|
---|
5173 | {
|
---|
5174 | if (flag_code == CODE_64BIT)
|
---|
5175 | abort ();
|
---|
5176 | fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
|
---|
5177 | }
|
---|
5178 | fixp->fx_subsy = 0;
|
---|
5179 | }
|
---|
5180 | }
|
---|
5181 |
|
---|
5182 | arelent *
|
---|
5183 | tc_gen_reloc (section, fixp)
|
---|
5184 | asection *section ATTRIBUTE_UNUSED;
|
---|
5185 | fixS *fixp;
|
---|
5186 | {
|
---|
5187 | arelent *rel;
|
---|
5188 | bfd_reloc_code_real_type code;
|
---|
5189 |
|
---|
5190 | switch (fixp->fx_r_type)
|
---|
5191 | {
|
---|
5192 | case BFD_RELOC_X86_64_PLT32:
|
---|
5193 | case BFD_RELOC_X86_64_GOT32:
|
---|
5194 | case BFD_RELOC_X86_64_GOTPCREL:
|
---|
5195 | case BFD_RELOC_386_PLT32:
|
---|
5196 | case BFD_RELOC_386_GOT32:
|
---|
5197 | case BFD_RELOC_386_GOTOFF:
|
---|
5198 | case BFD_RELOC_386_GOTPC:
|
---|
5199 | case BFD_RELOC_386_TLS_GD:
|
---|
5200 | case BFD_RELOC_386_TLS_LDM:
|
---|
5201 | case BFD_RELOC_386_TLS_LDO_32:
|
---|
5202 | case BFD_RELOC_386_TLS_IE_32:
|
---|
5203 | case BFD_RELOC_386_TLS_IE:
|
---|
5204 | case BFD_RELOC_386_TLS_GOTIE:
|
---|
5205 | case BFD_RELOC_386_TLS_LE_32:
|
---|
5206 | case BFD_RELOC_386_TLS_LE:
|
---|
5207 | case BFD_RELOC_X86_64_32S:
|
---|
5208 | case BFD_RELOC_X86_64_TLSGD:
|
---|
5209 | case BFD_RELOC_X86_64_TLSLD:
|
---|
5210 | case BFD_RELOC_X86_64_DTPOFF32:
|
---|
5211 | case BFD_RELOC_X86_64_GOTTPOFF:
|
---|
5212 | case BFD_RELOC_X86_64_TPOFF32:
|
---|
5213 | case BFD_RELOC_RVA:
|
---|
5214 | case BFD_RELOC_VTABLE_ENTRY:
|
---|
5215 | case BFD_RELOC_VTABLE_INHERIT:
|
---|
5216 | code = fixp->fx_r_type;
|
---|
5217 | break;
|
---|
5218 | default:
|
---|
5219 | if (fixp->fx_pcrel)
|
---|
5220 | {
|
---|
5221 | switch (fixp->fx_size)
|
---|
5222 | {
|
---|
5223 | default:
|
---|
5224 | as_bad_where (fixp->fx_file, fixp->fx_line,
|
---|
5225 | _("can not do %d byte pc-relative relocation"),
|
---|
5226 | fixp->fx_size);
|
---|
5227 | code = BFD_RELOC_32_PCREL;
|
---|
5228 | break;
|
---|
5229 | case 1: code = BFD_RELOC_8_PCREL; break;
|
---|
5230 | case 2: code = BFD_RELOC_16_PCREL; break;
|
---|
5231 | case 4: code = BFD_RELOC_32_PCREL; break;
|
---|
5232 | }
|
---|
5233 | }
|
---|
5234 | else
|
---|
5235 | {
|
---|
5236 | switch (fixp->fx_size)
|
---|
5237 | {
|
---|
5238 | default:
|
---|
5239 | as_bad_where (fixp->fx_file, fixp->fx_line,
|
---|
5240 | _("can not do %d byte relocation"),
|
---|
5241 | fixp->fx_size);
|
---|
5242 | code = BFD_RELOC_32;
|
---|
5243 | break;
|
---|
5244 | case 1: code = BFD_RELOC_8; break;
|
---|
5245 | case 2: code = BFD_RELOC_16; break;
|
---|
5246 | case 4: code = BFD_RELOC_32; break;
|
---|
5247 | #ifdef BFD64
|
---|
5248 | case 8: code = BFD_RELOC_64; break;
|
---|
5249 | #endif
|
---|
5250 | }
|
---|
5251 | }
|
---|
5252 | break;
|
---|
5253 | }
|
---|
5254 |
|
---|
5255 | if (code == BFD_RELOC_32
|
---|
5256 | && GOT_symbol
|
---|
5257 | && fixp->fx_addsy == GOT_symbol)
|
---|
5258 | {
|
---|
5259 | /* We don't support GOTPC on 64bit targets. */
|
---|
5260 | if (flag_code == CODE_64BIT)
|
---|
5261 | abort ();
|
---|
5262 | code = BFD_RELOC_386_GOTPC;
|
---|
5263 | }
|
---|
5264 |
|
---|
5265 | rel = (arelent *) xmalloc (sizeof (arelent));
|
---|
5266 | rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
|
---|
5267 | *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
|
---|
5268 |
|
---|
5269 | rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
|
---|
5270 | if (!use_rela_relocations)
|
---|
5271 | {
|
---|
5272 | /* HACK: Since i386 ELF uses Rel instead of Rela, encode the
|
---|
5273 | vtable entry to be used in the relocation's section offset. */
|
---|
5274 | if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
---|
5275 | rel->address = fixp->fx_offset;
|
---|
5276 |
|
---|
5277 | rel->addend = 0;
|
---|
5278 | }
|
---|
5279 | /* Use the rela in 64bit mode. */
|
---|
5280 | else
|
---|
5281 | {
|
---|
5282 | if (!fixp->fx_pcrel)
|
---|
5283 | rel->addend = fixp->fx_offset;
|
---|
5284 | else
|
---|
5285 | switch (code)
|
---|
5286 | {
|
---|
5287 | case BFD_RELOC_X86_64_PLT32:
|
---|
5288 | case BFD_RELOC_X86_64_GOT32:
|
---|
5289 | case BFD_RELOC_X86_64_GOTPCREL:
|
---|
5290 | case BFD_RELOC_X86_64_TLSGD:
|
---|
5291 | case BFD_RELOC_X86_64_TLSLD:
|
---|
5292 | case BFD_RELOC_X86_64_GOTTPOFF:
|
---|
5293 | rel->addend = fixp->fx_offset - fixp->fx_size;
|
---|
5294 | break;
|
---|
5295 | default:
|
---|
5296 | rel->addend = (section->vma
|
---|
5297 | - fixp->fx_size
|
---|
5298 | + fixp->fx_addnumber
|
---|
5299 | + md_pcrel_from (fixp));
|
---|
5300 | break;
|
---|
5301 | }
|
---|
5302 | }
|
---|
5303 |
|
---|
5304 | rel->howto = bfd_reloc_type_lookup (stdoutput, code);
|
---|
5305 | if (rel->howto == NULL)
|
---|
5306 | {
|
---|
5307 | as_bad_where (fixp->fx_file, fixp->fx_line,
|
---|
5308 | _("cannot represent relocation type %s"),
|
---|
5309 | bfd_get_reloc_code_name (code));
|
---|
5310 | /* Set howto to a garbage value so that we can keep going. */
|
---|
5311 | rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
|
---|
5312 | assert (rel->howto != NULL);
|
---|
5313 | }
|
---|
5314 |
|
---|
5315 | return rel;
|
---|
5316 | }
|
---|
5317 |
|
---|
5318 | #else /* !BFD_ASSEMBLER */
|
---|
5319 |
|
---|
5320 | #if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
|
---|
5321 | void
|
---|
5322 | tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
|
---|
5323 | char *where;
|
---|
5324 | fixS *fixP;
|
---|
5325 | relax_addressT segment_address_in_file;
|
---|
5326 | {
|
---|
5327 | /* In: length of relocation (or of address) in chars: 1, 2 or 4.
|
---|
5328 | Out: GNU LD relocation length code: 0, 1, or 2. */
|
---|
5329 |
|
---|
5330 | static const unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
|
---|
5331 | long r_symbolnum;
|
---|
5332 |
|
---|
5333 | know (fixP->fx_addsy != NULL);
|
---|
5334 |
|
---|
5335 | md_number_to_chars (where,
|
---|
5336 | (valueT) (fixP->fx_frag->fr_address
|
---|
5337 | + fixP->fx_where - segment_address_in_file),
|
---|
5338 | 4);
|
---|
5339 |
|
---|
5340 | r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
|
---|
5341 | ? S_GET_TYPE (fixP->fx_addsy)
|
---|
5342 | : fixP->fx_addsy->sy_number);
|
---|
5343 |
|
---|
5344 | where[6] = (r_symbolnum >> 16) & 0x0ff;
|
---|
5345 | where[5] = (r_symbolnum >> 8) & 0x0ff;
|
---|
5346 | where[4] = r_symbolnum & 0x0ff;
|
---|
5347 | where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
|
---|
5348 | | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
|
---|
5349 | | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
|
---|
5350 | }
|
---|
5351 |
|
---|
5352 | #endif /* OBJ_AOUT or OBJ_BOUT. */
|
---|
5353 |
|
---|
5354 | #if defined (I386COFF)
|
---|
5355 |
|
---|
5356 | short
|
---|
5357 | tc_coff_fix2rtype (fixP)
|
---|
5358 | fixS *fixP;
|
---|
5359 | {
|
---|
5360 | if (fixP->fx_r_type == R_IMAGEBASE)
|
---|
5361 | return R_IMAGEBASE;
|
---|
5362 |
|
---|
5363 | return (fixP->fx_pcrel ?
|
---|
5364 | (fixP->fx_size == 1 ? R_PCRBYTE :
|
---|
5365 | fixP->fx_size == 2 ? R_PCRWORD :
|
---|
5366 | R_PCRLONG) :
|
---|
5367 | (fixP->fx_size == 1 ? R_RELBYTE :
|
---|
5368 | fixP->fx_size == 2 ? R_RELWORD :
|
---|
5369 | R_DIR32));
|
---|
5370 | }
|
---|
5371 |
|
---|
5372 | int
|
---|
5373 | tc_coff_sizemachdep (frag)
|
---|
5374 | fragS *frag;
|
---|
5375 | {
|
---|
5376 | if (frag->fr_next)
|
---|
5377 | return (frag->fr_next->fr_address - frag->fr_address);
|
---|
5378 | else
|
---|
5379 | return 0;
|
---|
5380 | }
|
---|
5381 |
|
---|
5382 | #endif /* I386COFF */
|
---|
5383 |
|
---|
5384 | #endif /* !BFD_ASSEMBLER */
|
---|
5385 | |
---|
5386 |
|
---|
5387 | /* Parse operands using Intel syntax. This implements a recursive descent
|
---|
5388 | parser based on the BNF grammar published in Appendix B of the MASM 6.1
|
---|
5389 | Programmer's Guide.
|
---|
5390 |
|
---|
5391 | FIXME: We do not recognize the full operand grammar defined in the MASM
|
---|
5392 | documentation. In particular, all the structure/union and
|
---|
5393 | high-level macro operands are missing.
|
---|
5394 |
|
---|
5395 | Uppercase words are terminals, lower case words are non-terminals.
|
---|
5396 | Objects surrounded by double brackets '[[' ']]' are optional. Vertical
|
---|
5397 | bars '|' denote choices. Most grammar productions are implemented in
|
---|
5398 | functions called 'intel_<production>'.
|
---|
5399 |
|
---|
5400 | Initial production is 'expr'.
|
---|
5401 |
|
---|
5402 | addOp + | -
|
---|
5403 |
|
---|
5404 | alpha [a-zA-Z]
|
---|
5405 |
|
---|
5406 | byteRegister AL | AH | BL | BH | CL | CH | DL | DH
|
---|
5407 |
|
---|
5408 | constant digits [[ radixOverride ]]
|
---|
5409 |
|
---|
5410 | dataType BYTE | WORD | DWORD | QWORD | XWORD
|
---|
5411 |
|
---|
5412 | digits decdigit
|
---|
5413 | | digits decdigit
|
---|
5414 | | digits hexdigit
|
---|
5415 |
|
---|
5416 | decdigit [0-9]
|
---|
5417 |
|
---|
5418 | e05 e05 addOp e06
|
---|
5419 | | e06
|
---|
5420 |
|
---|
5421 | e06 e06 mulOp e09
|
---|
5422 | | e09
|
---|
5423 |
|
---|
5424 | e09 OFFSET e10
|
---|
5425 | | e09 PTR e10
|
---|
5426 | | e09 : e10
|
---|
5427 | | e10
|
---|
5428 |
|
---|
5429 | e10 e10 [ expr ]
|
---|
5430 | | e11
|
---|
5431 |
|
---|
5432 | e11 ( expr )
|
---|
5433 | | [ expr ]
|
---|
5434 | | constant
|
---|
5435 | | dataType
|
---|
5436 | | id
|
---|
5437 | | $
|
---|
5438 | | register
|
---|
5439 |
|
---|
5440 | => expr SHORT e05
|
---|
5441 | | e05
|
---|
5442 |
|
---|
5443 | gpRegister AX | EAX | BX | EBX | CX | ECX | DX | EDX
|
---|
5444 | | BP | EBP | SP | ESP | DI | EDI | SI | ESI
|
---|
5445 |
|
---|
5446 | hexdigit a | b | c | d | e | f
|
---|
5447 | | A | B | C | D | E | F
|
---|
5448 |
|
---|
5449 | id alpha
|
---|
5450 | | id alpha
|
---|
5451 | | id decdigit
|
---|
5452 |
|
---|
5453 | mulOp * | / | MOD
|
---|
5454 |
|
---|
5455 | quote " | '
|
---|
5456 |
|
---|
5457 | register specialRegister
|
---|
5458 | | gpRegister
|
---|
5459 | | byteRegister
|
---|
5460 |
|
---|
5461 | segmentRegister CS | DS | ES | FS | GS | SS
|
---|
5462 |
|
---|
5463 | specialRegister CR0 | CR2 | CR3
|
---|
5464 | | DR0 | DR1 | DR2 | DR3 | DR6 | DR7
|
---|
5465 | | TR3 | TR4 | TR5 | TR6 | TR7
|
---|
5466 |
|
---|
5467 | We simplify the grammar in obvious places (e.g., register parsing is
|
---|
5468 | done by calling parse_register) and eliminate immediate left recursion
|
---|
5469 | to implement a recursive-descent parser.
|
---|
5470 |
|
---|
5471 | expr SHORT e05
|
---|
5472 | | e05
|
---|
5473 |
|
---|
5474 | e05 e06 e05'
|
---|
5475 |
|
---|
5476 | e05' addOp e06 e05'
|
---|
5477 | | Empty
|
---|
5478 |
|
---|
5479 | e06 e09 e06'
|
---|
5480 |
|
---|
5481 | e06' mulOp e09 e06'
|
---|
5482 | | Empty
|
---|
5483 |
|
---|
5484 | e09 OFFSET e10 e09'
|
---|
5485 | | e10 e09'
|
---|
5486 |
|
---|
5487 | e09' PTR e10 e09'
|
---|
5488 | | : e10 e09'
|
---|
5489 | | Empty
|
---|
5490 |
|
---|
5491 | e10 e11 e10'
|
---|
5492 |
|
---|
5493 | e10' [ expr ] e10'
|
---|
5494 | | Empty
|
---|
5495 |
|
---|
5496 | e11 ( expr )
|
---|
5497 | | [ expr ]
|
---|
5498 | | BYTE
|
---|
5499 | | WORD
|
---|
5500 | | DWORD
|
---|
5501 | | QWORD
|
---|
5502 | | XWORD
|
---|
5503 | | .
|
---|
5504 | | $
|
---|
5505 | | register
|
---|
5506 | | id
|
---|
5507 | | constant */
|
---|
5508 |
|
---|
5509 | /* Parsing structure for the intel syntax parser. Used to implement the
|
---|
5510 | semantic actions for the operand grammar. */
|
---|
5511 | struct intel_parser_s
|
---|
5512 | {
|
---|
5513 | char *op_string; /* The string being parsed. */
|
---|
5514 | int got_a_float; /* Whether the operand is a float. */
|
---|
5515 | int op_modifier; /* Operand modifier. */
|
---|
5516 | int is_mem; /* 1 if operand is memory reference. */
|
---|
5517 | const reg_entry *reg; /* Last register reference found. */
|
---|
5518 | char *disp; /* Displacement string being built. */
|
---|
5519 | };
|
---|
5520 |
|
---|
5521 | static struct intel_parser_s intel_parser;
|
---|
5522 |
|
---|
5523 | /* Token structure for parsing intel syntax. */
|
---|
5524 | struct intel_token
|
---|
5525 | {
|
---|
5526 | int code; /* Token code. */
|
---|
5527 | const reg_entry *reg; /* Register entry for register tokens. */
|
---|
5528 | char *str; /* String representation. */
|
---|
5529 | };
|
---|
5530 |
|
---|
5531 | static struct intel_token cur_token, prev_token;
|
---|
5532 |
|
---|
5533 | /* Token codes for the intel parser. Since T_SHORT is already used
|
---|
5534 | by COFF, undefine it first to prevent a warning. */
|
---|
5535 | #define T_NIL -1
|
---|
5536 | #define T_CONST 1
|
---|
5537 | #define T_REG 2
|
---|
5538 | #define T_BYTE 3
|
---|
5539 | #define T_WORD 4
|
---|
5540 | #define T_DWORD 5
|
---|
5541 | #define T_QWORD 6
|
---|
5542 | #define T_XWORD 7
|
---|
5543 | #undef T_SHORT
|
---|
5544 | #define T_SHORT 8
|
---|
5545 | #define T_OFFSET 9
|
---|
5546 | #define T_PTR 10
|
---|
5547 | #define T_ID 11
|
---|
5548 |
|
---|
5549 | /* Prototypes for intel parser functions. */
|
---|
5550 | static int intel_match_token PARAMS ((int code));
|
---|
5551 | static void intel_get_token PARAMS ((void));
|
---|
5552 | static void intel_putback_token PARAMS ((void));
|
---|
5553 | static int intel_expr PARAMS ((void));
|
---|
5554 | static int intel_e05 PARAMS ((void));
|
---|
5555 | static int intel_e05_1 PARAMS ((void));
|
---|
5556 | static int intel_e06 PARAMS ((void));
|
---|
5557 | static int intel_e06_1 PARAMS ((void));
|
---|
5558 | static int intel_e09 PARAMS ((void));
|
---|
5559 | static int intel_e09_1 PARAMS ((void));
|
---|
5560 | static int intel_e10 PARAMS ((void));
|
---|
5561 | static int intel_e10_1 PARAMS ((void));
|
---|
5562 | static int intel_e11 PARAMS ((void));
|
---|
5563 |
|
---|
5564 | static int
|
---|
5565 | i386_intel_operand (operand_string, got_a_float)
|
---|
5566 | char *operand_string;
|
---|
5567 | int got_a_float;
|
---|
5568 | {
|
---|
5569 | int ret;
|
---|
5570 | char *p;
|
---|
5571 |
|
---|
5572 | /* Initialize token holders. */
|
---|
5573 | cur_token.code = prev_token.code = T_NIL;
|
---|
5574 | cur_token.reg = prev_token.reg = NULL;
|
---|
5575 | cur_token.str = prev_token.str = NULL;
|
---|
5576 |
|
---|
5577 | /* Initialize parser structure. */
|
---|
5578 | p = intel_parser.op_string = (char *) malloc (strlen (operand_string) + 1);
|
---|
5579 | if (p == NULL)
|
---|
5580 | abort ();
|
---|
5581 | strcpy (intel_parser.op_string, operand_string);
|
---|
5582 | intel_parser.got_a_float = got_a_float;
|
---|
5583 | intel_parser.op_modifier = -1;
|
---|
5584 | intel_parser.is_mem = 0;
|
---|
5585 | intel_parser.reg = NULL;
|
---|
5586 | intel_parser.disp = (char *) malloc (strlen (operand_string) + 1);
|
---|
5587 | if (intel_parser.disp == NULL)
|
---|
5588 | abort ();
|
---|
5589 | intel_parser.disp[0] = '\0';
|
---|
5590 |
|
---|
5591 | /* Read the first token and start the parser. */
|
---|
5592 | intel_get_token ();
|
---|
5593 | ret = intel_expr ();
|
---|
5594 |
|
---|
5595 | if (ret)
|
---|
5596 | {
|
---|
5597 | /* If we found a memory reference, hand it over to i386_displacement
|
---|
5598 | to fill in the rest of the operand fields. */
|
---|
5599 | if (intel_parser.is_mem)
|
---|
5600 | {
|
---|
5601 | if ((i.mem_operands == 1
|
---|
5602 | && (current_templates->start->opcode_modifier & IsString) == 0)
|
---|
5603 | || i.mem_operands == 2)
|
---|
5604 | {
|
---|
5605 | as_bad (_("too many memory references for '%s'"),
|
---|
5606 | current_templates->start->name);
|
---|
5607 | ret = 0;
|
---|
5608 | }
|
---|
5609 | else
|
---|
5610 | {
|
---|
5611 | char *s = intel_parser.disp;
|
---|
5612 | i.mem_operands++;
|
---|
5613 |
|
---|
5614 | /* Add the displacement expression. */
|
---|
5615 | if (*s != '\0')
|
---|
5616 | ret = i386_displacement (s, s + strlen (s))
|
---|
5617 | && i386_index_check (s);
|
---|
5618 | }
|
---|
5619 | }
|
---|
5620 |
|
---|
5621 | /* Constant and OFFSET expressions are handled by i386_immediate. */
|
---|
5622 | else if (intel_parser.op_modifier == OFFSET_FLAT
|
---|
5623 | || intel_parser.reg == NULL)
|
---|
5624 | ret = i386_immediate (intel_parser.disp);
|
---|
5625 | }
|
---|
5626 |
|
---|
5627 | free (p);
|
---|
5628 | free (intel_parser.disp);
|
---|
5629 |
|
---|
5630 | return ret;
|
---|
5631 | }
|
---|
5632 |
|
---|
5633 | /* expr SHORT e05
|
---|
5634 | | e05 */
|
---|
5635 | static int
|
---|
5636 | intel_expr ()
|
---|
5637 | {
|
---|
5638 | /* expr SHORT e05 */
|
---|
5639 | if (cur_token.code == T_SHORT)
|
---|
5640 | {
|
---|
5641 | intel_parser.op_modifier = SHORT;
|
---|
5642 | intel_match_token (T_SHORT);
|
---|
5643 |
|
---|
5644 | return (intel_e05 ());
|
---|
5645 | }
|
---|
5646 |
|
---|
5647 | /* expr e05 */
|
---|
5648 | else
|
---|
5649 | return intel_e05 ();
|
---|
5650 | }
|
---|
5651 |
|
---|
5652 | /* e05 e06 e05'
|
---|
5653 |
|
---|
5654 | e05' addOp e06 e05'
|
---|
5655 | | Empty */
|
---|
5656 | static int
|
---|
5657 | intel_e05 ()
|
---|
5658 | {
|
---|
5659 | return (intel_e06 () && intel_e05_1 ());
|
---|
5660 | }
|
---|
5661 |
|
---|
5662 | static int
|
---|
5663 | intel_e05_1 ()
|
---|
5664 | {
|
---|
5665 | /* e05' addOp e06 e05' */
|
---|
5666 | if (cur_token.code == '+' || cur_token.code == '-')
|
---|
5667 | {
|
---|
5668 | strcat (intel_parser.disp, cur_token.str);
|
---|
5669 | intel_match_token (cur_token.code);
|
---|
5670 |
|
---|
5671 | return (intel_e06 () && intel_e05_1 ());
|
---|
5672 | }
|
---|
5673 |
|
---|
5674 | /* e05' Empty */
|
---|
5675 | else
|
---|
5676 | return 1;
|
---|
5677 | }
|
---|
5678 |
|
---|
5679 | /* e06 e09 e06'
|
---|
5680 |
|
---|
5681 | e06' mulOp e09 e06'
|
---|
5682 | | Empty */
|
---|
5683 | static int
|
---|
5684 | intel_e06 ()
|
---|
5685 | {
|
---|
5686 | return (intel_e09 () && intel_e06_1 ());
|
---|
5687 | }
|
---|
5688 |
|
---|
5689 | static int
|
---|
5690 | intel_e06_1 ()
|
---|
5691 | {
|
---|
5692 | /* e06' mulOp e09 e06' */
|
---|
5693 | if (cur_token.code == '*' || cur_token.code == '/')
|
---|
5694 | {
|
---|
5695 | strcat (intel_parser.disp, cur_token.str);
|
---|
5696 | intel_match_token (cur_token.code);
|
---|
5697 |
|
---|
5698 | return (intel_e09 () && intel_e06_1 ());
|
---|
5699 | }
|
---|
5700 |
|
---|
5701 | /* e06' Empty */
|
---|
5702 | else
|
---|
5703 | return 1;
|
---|
5704 | }
|
---|
5705 |
|
---|
5706 | /* e09 OFFSET e10 e09'
|
---|
5707 | | e10 e09'
|
---|
5708 |
|
---|
5709 | e09' PTR e10 e09'
|
---|
5710 | | : e10 e09'
|
---|
5711 | | Empty */
|
---|
5712 | static int
|
---|
5713 | intel_e09 ()
|
---|
5714 | {
|
---|
5715 | /* e09 OFFSET e10 e09' */
|
---|
5716 | if (cur_token.code == T_OFFSET)
|
---|
5717 | {
|
---|
5718 | intel_parser.is_mem = 0;
|
---|
5719 | intel_parser.op_modifier = OFFSET_FLAT;
|
---|
5720 | intel_match_token (T_OFFSET);
|
---|
5721 |
|
---|
5722 | return (intel_e10 () && intel_e09_1 ());
|
---|
5723 | }
|
---|
5724 |
|
---|
5725 | /* e09 e10 e09' */
|
---|
5726 | else
|
---|
5727 | return (intel_e10 () && intel_e09_1 ());
|
---|
5728 | }
|
---|
5729 |
|
---|
5730 | static int
|
---|
5731 | intel_e09_1 ()
|
---|
5732 | {
|
---|
5733 | /* e09' PTR e10 e09' */
|
---|
5734 | if (cur_token.code == T_PTR)
|
---|
5735 | {
|
---|
5736 | if (prev_token.code == T_BYTE)
|
---|
5737 | i.suffix = BYTE_MNEM_SUFFIX;
|
---|
5738 |
|
---|
5739 | else if (prev_token.code == T_WORD)
|
---|
5740 | {
|
---|
5741 | if (intel_parser.got_a_float == 2) /* "fi..." */
|
---|
5742 | i.suffix = SHORT_MNEM_SUFFIX;
|
---|
5743 | else
|
---|
5744 | i.suffix = WORD_MNEM_SUFFIX;
|
---|
5745 | }
|
---|
5746 |
|
---|
5747 | else if (prev_token.code == T_DWORD)
|
---|
5748 | {
|
---|
5749 | if (intel_parser.got_a_float == 1) /* "f..." */
|
---|
5750 | i.suffix = SHORT_MNEM_SUFFIX;
|
---|
5751 | else
|
---|
5752 | i.suffix = LONG_MNEM_SUFFIX;
|
---|
5753 | }
|
---|
5754 |
|
---|
5755 | else if (prev_token.code == T_QWORD)
|
---|
5756 | {
|
---|
5757 | if (intel_parser.got_a_float == 1) /* "f..." */
|
---|
5758 | i.suffix = LONG_MNEM_SUFFIX;
|
---|
5759 | else
|
---|
5760 | i.suffix = QWORD_MNEM_SUFFIX;
|
---|
5761 | }
|
---|
5762 |
|
---|
5763 | else if (prev_token.code == T_XWORD)
|
---|
5764 | i.suffix = LONG_DOUBLE_MNEM_SUFFIX;
|
---|
5765 |
|
---|
5766 | else
|
---|
5767 | {
|
---|
5768 | as_bad (_("Unknown operand modifier `%s'\n"), prev_token.str);
|
---|
5769 | return 0;
|
---|
5770 | }
|
---|
5771 |
|
---|
5772 | intel_match_token (T_PTR);
|
---|
5773 |
|
---|
5774 | return (intel_e10 () && intel_e09_1 ());
|
---|
5775 | }
|
---|
5776 |
|
---|
5777 | /* e09 : e10 e09' */
|
---|
5778 | else if (cur_token.code == ':')
|
---|
5779 | {
|
---|
5780 | /* Mark as a memory operand only if it's not already known to be an
|
---|
5781 | offset expression. */
|
---|
5782 | if (intel_parser.op_modifier != OFFSET_FLAT)
|
---|
5783 | intel_parser.is_mem = 1;
|
---|
5784 |
|
---|
5785 | return (intel_match_token (':') && intel_e10 () && intel_e09_1 ());
|
---|
5786 | }
|
---|
5787 |
|
---|
5788 | /* e09' Empty */
|
---|
5789 | else
|
---|
5790 | return 1;
|
---|
5791 | }
|
---|
5792 |
|
---|
5793 | /* e10 e11 e10'
|
---|
5794 |
|
---|
5795 | e10' [ expr ] e10'
|
---|
5796 | | Empty */
|
---|
5797 | static int
|
---|
5798 | intel_e10 ()
|
---|
5799 | {
|
---|
5800 | return (intel_e11 () && intel_e10_1 ());
|
---|
5801 | }
|
---|
5802 |
|
---|
5803 | static int
|
---|
5804 | intel_e10_1 ()
|
---|
5805 | {
|
---|
5806 | /* e10' [ expr ] e10' */
|
---|
5807 | if (cur_token.code == '[')
|
---|
5808 | {
|
---|
5809 | intel_match_token ('[');
|
---|
5810 |
|
---|
5811 | /* Mark as a memory operand only if it's not already known to be an
|
---|
5812 | offset expression. If it's an offset expression, we need to keep
|
---|
5813 | the brace in. */
|
---|
5814 | if (intel_parser.op_modifier != OFFSET_FLAT)
|
---|
5815 | intel_parser.is_mem = 1;
|
---|
5816 | else
|
---|
5817 | strcat (intel_parser.disp, "[");
|
---|
5818 |
|
---|
5819 | /* Add a '+' to the displacement string if necessary. */
|
---|
5820 | if (*intel_parser.disp != '\0'
|
---|
5821 | && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
|
---|
5822 | strcat (intel_parser.disp, "+");
|
---|
5823 |
|
---|
5824 | if (intel_expr () && intel_match_token (']'))
|
---|
5825 | {
|
---|
5826 | /* Preserve brackets when the operand is an offset expression. */
|
---|
5827 | if (intel_parser.op_modifier == OFFSET_FLAT)
|
---|
5828 | strcat (intel_parser.disp, "]");
|
---|
5829 |
|
---|
5830 | return intel_e10_1 ();
|
---|
5831 | }
|
---|
5832 | else
|
---|
5833 | return 0;
|
---|
5834 | }
|
---|
5835 |
|
---|
5836 | /* e10' Empty */
|
---|
5837 | else
|
---|
5838 | return 1;
|
---|
5839 | }
|
---|
5840 |
|
---|
5841 | /* e11 ( expr )
|
---|
5842 | | [ expr ]
|
---|
5843 | | BYTE
|
---|
5844 | | WORD
|
---|
5845 | | DWORD
|
---|
5846 | | QWORD
|
---|
5847 | | XWORD
|
---|
5848 | | $
|
---|
5849 | | .
|
---|
5850 | | register
|
---|
5851 | | id
|
---|
5852 | | constant */
|
---|
5853 | static int
|
---|
5854 | intel_e11 ()
|
---|
5855 | {
|
---|
5856 | /* e11 ( expr ) */
|
---|
5857 | if (cur_token.code == '(')
|
---|
5858 | {
|
---|
5859 | intel_match_token ('(');
|
---|
5860 | strcat (intel_parser.disp, "(");
|
---|
5861 |
|
---|
5862 | if (intel_expr () && intel_match_token (')'))
|
---|
5863 | {
|
---|
5864 | strcat (intel_parser.disp, ")");
|
---|
5865 | return 1;
|
---|
5866 | }
|
---|
5867 | else
|
---|
5868 | return 0;
|
---|
5869 | }
|
---|
5870 |
|
---|
5871 | /* e11 [ expr ] */
|
---|
5872 | else if (cur_token.code == '[')
|
---|
5873 | {
|
---|
5874 | intel_match_token ('[');
|
---|
5875 |
|
---|
5876 | /* Mark as a memory operand only if it's not already known to be an
|
---|
5877 | offset expression. If it's an offset expression, we need to keep
|
---|
5878 | the brace in. */
|
---|
5879 | if (intel_parser.op_modifier != OFFSET_FLAT)
|
---|
5880 | intel_parser.is_mem = 1;
|
---|
5881 | else
|
---|
5882 | strcat (intel_parser.disp, "[");
|
---|
5883 |
|
---|
5884 | /* Operands for jump/call inside brackets denote absolute addresses. */
|
---|
5885 | if (current_templates->start->opcode_modifier & Jump
|
---|
5886 | || current_templates->start->opcode_modifier & JumpDword
|
---|
5887 | || current_templates->start->opcode_modifier & JumpByte
|
---|
5888 | || current_templates->start->opcode_modifier & JumpInterSegment)
|
---|
5889 | i.types[this_operand] |= JumpAbsolute;
|
---|
5890 |
|
---|
5891 | /* Add a '+' to the displacement string if necessary. */
|
---|
5892 | if (*intel_parser.disp != '\0'
|
---|
5893 | && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
|
---|
5894 | strcat (intel_parser.disp, "+");
|
---|
5895 |
|
---|
5896 | if (intel_expr () && intel_match_token (']'))
|
---|
5897 | {
|
---|
5898 | /* Preserve brackets when the operand is an offset expression. */
|
---|
5899 | if (intel_parser.op_modifier == OFFSET_FLAT)
|
---|
5900 | strcat (intel_parser.disp, "]");
|
---|
5901 |
|
---|
5902 | return 1;
|
---|
5903 | }
|
---|
5904 | else
|
---|
5905 | return 0;
|
---|
5906 | }
|
---|
5907 |
|
---|
5908 | /* e11 BYTE
|
---|
5909 | | WORD
|
---|
5910 | | DWORD
|
---|
5911 | | QWORD
|
---|
5912 | | XWORD */
|
---|
5913 | else if (cur_token.code == T_BYTE
|
---|
5914 | || cur_token.code == T_WORD
|
---|
5915 | || cur_token.code == T_DWORD
|
---|
5916 | || cur_token.code == T_QWORD
|
---|
5917 | || cur_token.code == T_XWORD)
|
---|
5918 | {
|
---|
5919 | intel_match_token (cur_token.code);
|
---|
5920 |
|
---|
5921 | return 1;
|
---|
5922 | }
|
---|
5923 |
|
---|
5924 | /* e11 $
|
---|
5925 | | . */
|
---|
5926 | else if (cur_token.code == '$' || cur_token.code == '.')
|
---|
5927 | {
|
---|
5928 | strcat (intel_parser.disp, cur_token.str);
|
---|
5929 | intel_match_token (cur_token.code);
|
---|
5930 |
|
---|
5931 | /* Mark as a memory operand only if it's not already known to be an
|
---|
5932 | offset expression. */
|
---|
5933 | if (intel_parser.op_modifier != OFFSET_FLAT)
|
---|
5934 | intel_parser.is_mem = 1;
|
---|
5935 |
|
---|
5936 | return 1;
|
---|
5937 | }
|
---|
5938 |
|
---|
5939 | /* e11 register */
|
---|
5940 | else if (cur_token.code == T_REG)
|
---|
5941 | {
|
---|
5942 | const reg_entry *reg = intel_parser.reg = cur_token.reg;
|
---|
5943 |
|
---|
5944 | intel_match_token (T_REG);
|
---|
5945 |
|
---|
5946 | /* Check for segment change. */
|
---|
5947 | if (cur_token.code == ':')
|
---|
5948 | {
|
---|
5949 | if (reg->reg_type & (SReg2 | SReg3))
|
---|
5950 | {
|
---|
5951 | switch (reg->reg_num)
|
---|
5952 | {
|
---|
5953 | case 0:
|
---|
5954 | i.seg[i.mem_operands] = &es;
|
---|
5955 | break;
|
---|
5956 | case 1:
|
---|
5957 | i.seg[i.mem_operands] = &cs;
|
---|
5958 | break;
|
---|
5959 | case 2:
|
---|
5960 | i.seg[i.mem_operands] = &ss;
|
---|
5961 | break;
|
---|
5962 | case 3:
|
---|
5963 | i.seg[i.mem_operands] = &ds;
|
---|
5964 | break;
|
---|
5965 | case 4:
|
---|
5966 | i.seg[i.mem_operands] = &fs;
|
---|
5967 | break;
|
---|
5968 | case 5:
|
---|
5969 | i.seg[i.mem_operands] = &gs;
|
---|
5970 | break;
|
---|
5971 | }
|
---|
5972 | }
|
---|
5973 | else
|
---|
5974 | {
|
---|
5975 | as_bad (_("`%s' is not a valid segment register"), reg->reg_name);
|
---|
5976 | return 0;
|
---|
5977 | }
|
---|
5978 | }
|
---|
5979 |
|
---|
5980 | /* Not a segment register. Check for register scaling. */
|
---|
5981 | else if (cur_token.code == '*')
|
---|
5982 | {
|
---|
5983 | if (!intel_parser.is_mem)
|
---|
5984 | {
|
---|
5985 | as_bad (_("Register scaling only allowed in memory operands."));
|
---|
5986 | return 0;
|
---|
5987 | }
|
---|
5988 |
|
---|
5989 | /* What follows must be a valid scale. */
|
---|
5990 | if (intel_match_token ('*')
|
---|
5991 | && strchr ("01248", *cur_token.str))
|
---|
5992 | {
|
---|
5993 | i.index_reg = reg;
|
---|
5994 | i.types[this_operand] |= BaseIndex;
|
---|
5995 |
|
---|
5996 | /* Set the scale after setting the register (otherwise,
|
---|
5997 | i386_scale will complain) */
|
---|
5998 | i386_scale (cur_token.str);
|
---|
5999 | intel_match_token (T_CONST);
|
---|
6000 | }
|
---|
6001 | else
|
---|
6002 | {
|
---|
6003 | as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
|
---|
6004 | cur_token.str);
|
---|
6005 | return 0;
|
---|
6006 | }
|
---|
6007 | }
|
---|
6008 |
|
---|
6009 | /* No scaling. If this is a memory operand, the register is either a
|
---|
6010 | base register (first occurrence) or an index register (second
|
---|
6011 | occurrence). */
|
---|
6012 | else if (intel_parser.is_mem && !(reg->reg_type & (SReg2 | SReg3)))
|
---|
6013 | {
|
---|
6014 | if (i.base_reg && i.index_reg)
|
---|
6015 | {
|
---|
6016 | as_bad (_("Too many register references in memory operand.\n"));
|
---|
6017 | return 0;
|
---|
6018 | }
|
---|
6019 |
|
---|
6020 | if (i.base_reg == NULL)
|
---|
6021 | i.base_reg = reg;
|
---|
6022 | else
|
---|
6023 | i.index_reg = reg;
|
---|
6024 |
|
---|
6025 | i.types[this_operand] |= BaseIndex;
|
---|
6026 | }
|
---|
6027 |
|
---|
6028 | /* Offset modifier. Add the register to the displacement string to be
|
---|
6029 | parsed as an immediate expression after we're done. */
|
---|
6030 | else if (intel_parser.op_modifier == OFFSET_FLAT)
|
---|
6031 | strcat (intel_parser.disp, reg->reg_name);
|
---|
6032 |
|
---|
6033 | /* It's neither base nor index nor offset. */
|
---|
6034 | else
|
---|
6035 | {
|
---|
6036 | i.types[this_operand] |= reg->reg_type & ~BaseIndex;
|
---|
6037 | i.op[this_operand].regs = reg;
|
---|
6038 | i.reg_operands++;
|
---|
6039 | }
|
---|
6040 |
|
---|
6041 | /* Since registers are not part of the displacement string (except
|
---|
6042 | when we're parsing offset operands), we may need to remove any
|
---|
6043 | preceding '+' from the displacement string. */
|
---|
6044 | if (*intel_parser.disp != '\0'
|
---|
6045 | && intel_parser.op_modifier != OFFSET_FLAT)
|
---|
6046 | {
|
---|
6047 | char *s = intel_parser.disp;
|
---|
6048 | s += strlen (s) - 1;
|
---|
6049 | if (*s == '+')
|
---|
6050 | *s = '\0';
|
---|
6051 | }
|
---|
6052 |
|
---|
6053 | return 1;
|
---|
6054 | }
|
---|
6055 |
|
---|
6056 | /* e11 id */
|
---|
6057 | else if (cur_token.code == T_ID)
|
---|
6058 | {
|
---|
6059 | /* Add the identifier to the displacement string. */
|
---|
6060 | strcat (intel_parser.disp, cur_token.str);
|
---|
6061 | intel_match_token (T_ID);
|
---|
6062 |
|
---|
6063 | /* The identifier represents a memory reference only if it's not
|
---|
6064 | preceded by an offset modifier. */
|
---|
6065 | if (intel_parser.op_modifier != OFFSET_FLAT)
|
---|
6066 | intel_parser.is_mem = 1;
|
---|
6067 |
|
---|
6068 | return 1;
|
---|
6069 | }
|
---|
6070 |
|
---|
6071 | /* e11 constant */
|
---|
6072 | else if (cur_token.code == T_CONST
|
---|
6073 | || cur_token.code == '-'
|
---|
6074 | || cur_token.code == '+')
|
---|
6075 | {
|
---|
6076 | char *save_str;
|
---|
6077 |
|
---|
6078 | /* Allow constants that start with `+' or `-'. */
|
---|
6079 | if (cur_token.code == '-' || cur_token.code == '+')
|
---|
6080 | {
|
---|
6081 | strcat (intel_parser.disp, cur_token.str);
|
---|
6082 | intel_match_token (cur_token.code);
|
---|
6083 | if (cur_token.code != T_CONST)
|
---|
6084 | {
|
---|
6085 | as_bad (_("Syntax error. Expecting a constant. Got `%s'.\n"),
|
---|
6086 | cur_token.str);
|
---|
6087 | return 0;
|
---|
6088 | }
|
---|
6089 | }
|
---|
6090 |
|
---|
6091 | save_str = (char *) malloc (strlen (cur_token.str) + 1);
|
---|
6092 | if (save_str == NULL)
|
---|
6093 | abort ();
|
---|
6094 | strcpy (save_str, cur_token.str);
|
---|
6095 |
|
---|
6096 | /* Get the next token to check for register scaling. */
|
---|
6097 | intel_match_token (cur_token.code);
|
---|
6098 |
|
---|
6099 | /* Check if this constant is a scaling factor for an index register. */
|
---|
6100 | if (cur_token.code == '*')
|
---|
6101 | {
|
---|
6102 | if (intel_match_token ('*') && cur_token.code == T_REG)
|
---|
6103 | {
|
---|
6104 | if (!intel_parser.is_mem)
|
---|
6105 | {
|
---|
6106 | as_bad (_("Register scaling only allowed in memory operands."));
|
---|
6107 | return 0;
|
---|
6108 | }
|
---|
6109 |
|
---|
6110 | /* The constant is followed by `* reg', so it must be
|
---|
6111 | a valid scale. */
|
---|
6112 | if (strchr ("01248", *save_str))
|
---|
6113 | {
|
---|
6114 | i.index_reg = cur_token.reg;
|
---|
6115 | i.types[this_operand] |= BaseIndex;
|
---|
6116 |
|
---|
6117 | /* Set the scale after setting the register (otherwise,
|
---|
6118 | i386_scale will complain) */
|
---|
6119 | i386_scale (save_str);
|
---|
6120 | intel_match_token (T_REG);
|
---|
6121 |
|
---|
6122 | /* Since registers are not part of the displacement
|
---|
6123 | string, we may need to remove any preceding '+' from
|
---|
6124 | the displacement string. */
|
---|
6125 | if (*intel_parser.disp != '\0')
|
---|
6126 | {
|
---|
6127 | char *s = intel_parser.disp;
|
---|
6128 | s += strlen (s) - 1;
|
---|
6129 | if (*s == '+')
|
---|
6130 | *s = '\0';
|
---|
6131 | }
|
---|
6132 |
|
---|
6133 | free (save_str);
|
---|
6134 |
|
---|
6135 | return 1;
|
---|
6136 | }
|
---|
6137 | else
|
---|
6138 | return 0;
|
---|
6139 | }
|
---|
6140 |
|
---|
6141 | /* The constant was not used for register scaling. Since we have
|
---|
6142 | already consumed the token following `*' we now need to put it
|
---|
6143 | back in the stream. */
|
---|
6144 | else
|
---|
6145 | intel_putback_token ();
|
---|
6146 | }
|
---|
6147 |
|
---|
6148 | /* Add the constant to the displacement string. */
|
---|
6149 | strcat (intel_parser.disp, save_str);
|
---|
6150 | free (save_str);
|
---|
6151 |
|
---|
6152 | return 1;
|
---|
6153 | }
|
---|
6154 |
|
---|
6155 | as_bad (_("Unrecognized token '%s'"), cur_token.str);
|
---|
6156 | return 0;
|
---|
6157 | }
|
---|
6158 |
|
---|
6159 | /* Match the given token against cur_token. If they match, read the next
|
---|
6160 | token from the operand string. */
|
---|
6161 | static int
|
---|
6162 | intel_match_token (code)
|
---|
6163 | int code;
|
---|
6164 | {
|
---|
6165 | if (cur_token.code == code)
|
---|
6166 | {
|
---|
6167 | intel_get_token ();
|
---|
6168 | return 1;
|
---|
6169 | }
|
---|
6170 | else
|
---|
6171 | {
|
---|
6172 | as_bad (_("Unexpected token `%s'\n"), cur_token.str);
|
---|
6173 | return 0;
|
---|
6174 | }
|
---|
6175 | }
|
---|
6176 |
|
---|
6177 | /* Read a new token from intel_parser.op_string and store it in cur_token. */
|
---|
6178 | static void
|
---|
6179 | intel_get_token ()
|
---|
6180 | {
|
---|
6181 | char *end_op;
|
---|
6182 | const reg_entry *reg;
|
---|
6183 | struct intel_token new_token;
|
---|
6184 |
|
---|
6185 | new_token.code = T_NIL;
|
---|
6186 | new_token.reg = NULL;
|
---|
6187 | new_token.str = NULL;
|
---|
6188 |
|
---|
6189 | /* Free the memory allocated to the previous token and move
|
---|
6190 | cur_token to prev_token. */
|
---|
6191 | if (prev_token.str)
|
---|
6192 | free (prev_token.str);
|
---|
6193 |
|
---|
6194 | prev_token = cur_token;
|
---|
6195 |
|
---|
6196 | /* Skip whitespace. */
|
---|
6197 | while (is_space_char (*intel_parser.op_string))
|
---|
6198 | intel_parser.op_string++;
|
---|
6199 |
|
---|
6200 | /* Return an empty token if we find nothing else on the line. */
|
---|
6201 | if (*intel_parser.op_string == '\0')
|
---|
6202 | {
|
---|
6203 | cur_token = new_token;
|
---|
6204 | return;
|
---|
6205 | }
|
---|
6206 |
|
---|
6207 | /* The new token cannot be larger than the remainder of the operand
|
---|
6208 | string. */
|
---|
6209 | new_token.str = (char *) malloc (strlen (intel_parser.op_string) + 1);
|
---|
6210 | if (new_token.str == NULL)
|
---|
6211 | abort ();
|
---|
6212 | new_token.str[0] = '\0';
|
---|
6213 |
|
---|
6214 | if (strchr ("0123456789", *intel_parser.op_string))
|
---|
6215 | {
|
---|
6216 | char *p = new_token.str;
|
---|
6217 | char *q = intel_parser.op_string;
|
---|
6218 | new_token.code = T_CONST;
|
---|
6219 |
|
---|
6220 | /* Allow any kind of identifier char to encompass floating point and
|
---|
6221 | hexadecimal numbers. */
|
---|
6222 | while (is_identifier_char (*q))
|
---|
6223 | *p++ = *q++;
|
---|
6224 | *p = '\0';
|
---|
6225 |
|
---|
6226 | /* Recognize special symbol names [0-9][bf]. */
|
---|
6227 | if (strlen (intel_parser.op_string) == 2
|
---|
6228 | && (intel_parser.op_string[1] == 'b'
|
---|
6229 | || intel_parser.op_string[1] == 'f'))
|
---|
6230 | new_token.code = T_ID;
|
---|
6231 | }
|
---|
6232 |
|
---|
6233 | else if (strchr ("+-/*:[]()", *intel_parser.op_string))
|
---|
6234 | {
|
---|
6235 | new_token.code = *intel_parser.op_string;
|
---|
6236 | new_token.str[0] = *intel_parser.op_string;
|
---|
6237 | new_token.str[1] = '\0';
|
---|
6238 | }
|
---|
6239 |
|
---|
6240 | else if ((*intel_parser.op_string == REGISTER_PREFIX || allow_naked_reg)
|
---|
6241 | && ((reg = parse_register (intel_parser.op_string, &end_op)) != NULL))
|
---|
6242 | {
|
---|
6243 | new_token.code = T_REG;
|
---|
6244 | new_token.reg = reg;
|
---|
6245 |
|
---|
6246 | if (*intel_parser.op_string == REGISTER_PREFIX)
|
---|
6247 | {
|
---|
6248 | new_token.str[0] = REGISTER_PREFIX;
|
---|
6249 | new_token.str[1] = '\0';
|
---|
6250 | }
|
---|
6251 |
|
---|
6252 | strcat (new_token.str, reg->reg_name);
|
---|
6253 | }
|
---|
6254 |
|
---|
6255 | else if (is_identifier_char (*intel_parser.op_string))
|
---|
6256 | {
|
---|
6257 | char *p = new_token.str;
|
---|
6258 | char *q = intel_parser.op_string;
|
---|
6259 |
|
---|
6260 | /* A '.' or '$' followed by an identifier char is an identifier.
|
---|
6261 | Otherwise, it's operator '.' followed by an expression. */
|
---|
6262 | if ((*q == '.' || *q == '$') && !is_identifier_char (*(q + 1)))
|
---|
6263 | {
|
---|
6264 | new_token.code = *q;
|
---|
6265 | new_token.str[0] = *q;
|
---|
6266 | new_token.str[1] = '\0';
|
---|
6267 | }
|
---|
6268 | else
|
---|
6269 | {
|
---|
6270 | while (is_identifier_char (*q) || *q == '@')
|
---|
6271 | *p++ = *q++;
|
---|
6272 | *p = '\0';
|
---|
6273 |
|
---|
6274 | if (strcasecmp (new_token.str, "BYTE") == 0)
|
---|
6275 | new_token.code = T_BYTE;
|
---|
6276 |
|
---|
6277 | else if (strcasecmp (new_token.str, "WORD") == 0)
|
---|
6278 | new_token.code = T_WORD;
|
---|
6279 |
|
---|
6280 | else if (strcasecmp (new_token.str, "DWORD") == 0)
|
---|
6281 | new_token.code = T_DWORD;
|
---|
6282 |
|
---|
6283 | else if (strcasecmp (new_token.str, "QWORD") == 0)
|
---|
6284 | new_token.code = T_QWORD;
|
---|
6285 |
|
---|
6286 | else if (strcasecmp (new_token.str, "XWORD") == 0)
|
---|
6287 | new_token.code = T_XWORD;
|
---|
6288 |
|
---|
6289 | else if (strcasecmp (new_token.str, "PTR") == 0)
|
---|
6290 | new_token.code = T_PTR;
|
---|
6291 |
|
---|
6292 | else if (strcasecmp (new_token.str, "SHORT") == 0)
|
---|
6293 | new_token.code = T_SHORT;
|
---|
6294 |
|
---|
6295 | else if (strcasecmp (new_token.str, "OFFSET") == 0)
|
---|
6296 | {
|
---|
6297 | new_token.code = T_OFFSET;
|
---|
6298 |
|
---|
6299 | /* ??? This is not mentioned in the MASM grammar but gcc
|
---|
6300 | makes use of it with -mintel-syntax. OFFSET may be
|
---|
6301 | followed by FLAT: */
|
---|
6302 | if (strncasecmp (q, " FLAT:", 6) == 0)
|
---|
6303 | strcat (new_token.str, " FLAT:");
|
---|
6304 | }
|
---|
6305 |
|
---|
6306 | /* ??? This is not mentioned in the MASM grammar. */
|
---|
6307 | else if (strcasecmp (new_token.str, "FLAT") == 0)
|
---|
6308 | new_token.code = T_OFFSET;
|
---|
6309 |
|
---|
6310 | else
|
---|
6311 | new_token.code = T_ID;
|
---|
6312 | }
|
---|
6313 | }
|
---|
6314 |
|
---|
6315 | else
|
---|
6316 | as_bad (_("Unrecognized token `%s'\n"), intel_parser.op_string);
|
---|
6317 |
|
---|
6318 | intel_parser.op_string += strlen (new_token.str);
|
---|
6319 | cur_token = new_token;
|
---|
6320 | }
|
---|
6321 |
|
---|
6322 | /* Put cur_token back into the token stream and make cur_token point to
|
---|
6323 | prev_token. */
|
---|
6324 | static void
|
---|
6325 | intel_putback_token ()
|
---|
6326 | {
|
---|
6327 | intel_parser.op_string -= strlen (cur_token.str);
|
---|
6328 | free (cur_token.str);
|
---|
6329 | cur_token = prev_token;
|
---|
6330 |
|
---|
6331 | /* Forget prev_token. */
|
---|
6332 | prev_token.code = T_NIL;
|
---|
6333 | prev_token.reg = NULL;
|
---|
6334 | prev_token.str = NULL;
|
---|
6335 | }
|
---|