]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/perf/tinycc.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / perf / tinycc.c
1 /*
2  *  TCC - Tiny C Compiler
3  * 
4  *  Copyright (c) 2001-2004 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #define _GNU_SOURCE
21
22 // njn: inlined config.h
23 //#include "config.h"
24 //---------------------------------------------------------------------------
25 /* Automatically generated by configure - do not modify */
26 #define CONFIG_TCCDIR "tinycc-extras"
27 #define GCC_MAJOR 3
28 #define HOST_I386 1
29 #define TCC_VERSION "0.9.23"
30 //---------------------------------------------------------------------------
31
32 // njn: comment out CONFIG_TCCBOOT branch
33 //#ifdef CONFIG_TCCBOOT
34 //
35 //#include "tccboot.h"
36 //#define CONFIG_TCC_STATIC
37 //
38 //#else
39
40 #include <assert.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <stdarg.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <math.h>
47 #include <unistd.h>
48 #include <signal.h>
49 #include <fcntl.h>
50 #include <setjmp.h>
51 #include <time.h>
52 #ifdef WIN32
53 #include <sys/timeb.h>
54 #endif
55 #ifndef WIN32
56 #include <sys/time.h>
57 #include <sys/ucontext.h>
58 #endif
59
60 //#endif /* !CONFIG_TCCBOOT */
61
62 // Dummy variables used to avoid warnings like these: 
63 // warning: ignoring return value of ‘fwrite’, declared with attribute
64 //    warn_unused_result
65 char* dummy_char_star;
66 size_t dummy_size_t;
67
68 // njn: inlined elf.h
69 //#include "elf.h"
70 //---------------------------------------------------------------------------
71 /* This file defines standard ELF types, structures, and macros.
72    Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
73    This file is part of the GNU C Library.
74    Contributed by Ian Lance Taylor <ian@cygnus.com>.
75
76    The GNU C Library is free software; you can redistribute it and/or
77    modify it under the terms of the GNU Library General Public License as
78    published by the Free Software Foundation; either version 2 of the
79    License, or (at your option) any later version.
80
81    The GNU C Library is distributed in the hope that it will be useful,
82    but WITHOUT ANY WARRANTY; without even the implied warranty of
83    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
84    Library General Public License for more details.
85
86    You should have received a copy of the GNU Library General Public
87    License along with the GNU C Library; see the file COPYING.LIB.  If not,
88    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
89    Boston, MA 02111-1307, USA.  */
90
91 #ifndef _ELF_H
92 #define _ELF_H 1
93
94 #ifndef WIN32
95 #include <inttypes.h>
96 #else
97 #ifndef __int8_t_defined
98 #define __int8_t_defined
99 typedef signed char int8_t;
100 typedef short int int16_t;
101 typedef int int32_t;
102 typedef long long int int64_t;
103 #endif
104
105 typedef unsigned char           uint8_t;
106 typedef unsigned short int      uint16_t;
107 typedef unsigned int            uint32_t;
108 typedef unsigned long long int  uint64_t;
109 #endif
110
111 /* Standard ELF types.  */
112
113 /* Type for a 16-bit quantity.  */
114 typedef uint16_t Elf32_Half;
115 typedef uint16_t Elf64_Half;
116
117 /* Types for signed and unsigned 32-bit quantities.  */
118 typedef uint32_t Elf32_Word;
119 typedef int32_t  Elf32_Sword;
120 typedef uint32_t Elf64_Word;
121 typedef int32_t  Elf64_Sword;
122
123 /* Types for signed and unsigned 64-bit quantities.  */
124 typedef uint64_t Elf32_Xword;
125 typedef int64_t  Elf32_Sxword;
126 typedef uint64_t Elf64_Xword;
127 typedef int64_t  Elf64_Sxword;
128
129 /* Type of addresses.  */
130 typedef uint32_t Elf32_Addr;
131 typedef uint64_t Elf64_Addr;
132
133 /* Type of file offsets.  */
134 typedef uint32_t Elf32_Off;
135 typedef uint64_t Elf64_Off;
136
137 /* Type for section indices, which are 16-bit quantities.  */
138 typedef uint16_t Elf32_Section;
139 typedef uint16_t Elf64_Section;
140
141 /* Type of symbol indices.  */
142 typedef uint32_t Elf32_Symndx;
143 typedef uint64_t Elf64_Symndx;
144
145
146 /* The ELF file header.  This appears at the start of every ELF file.  */
147
148 #define EI_NIDENT (16)
149
150 typedef struct
151 {
152   unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
153   Elf32_Half    e_type;                 /* Object file type */
154   Elf32_Half    e_machine;              /* Architecture */
155   Elf32_Word    e_version;              /* Object file version */
156   Elf32_Addr    e_entry;                /* Entry point virtual address */
157   Elf32_Off     e_phoff;                /* Program header table file offset */
158   Elf32_Off     e_shoff;                /* Section header table file offset */
159   Elf32_Word    e_flags;                /* Processor-specific flags */
160   Elf32_Half    e_ehsize;               /* ELF header size in bytes */
161   Elf32_Half    e_phentsize;            /* Program header table entry size */
162   Elf32_Half    e_phnum;                /* Program header table entry count */
163   Elf32_Half    e_shentsize;            /* Section header table entry size */
164   Elf32_Half    e_shnum;                /* Section header table entry count */
165   Elf32_Half    e_shstrndx;             /* Section header string table index */
166 } Elf32_Ehdr;
167
168 typedef struct
169 {
170   unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
171   Elf64_Half    e_type;                 /* Object file type */
172   Elf64_Half    e_machine;              /* Architecture */
173   Elf64_Word    e_version;              /* Object file version */
174   Elf64_Addr    e_entry;                /* Entry point virtual address */
175   Elf64_Off     e_phoff;                /* Program header table file offset */
176   Elf64_Off     e_shoff;                /* Section header table file offset */
177   Elf64_Word    e_flags;                /* Processor-specific flags */
178   Elf64_Half    e_ehsize;               /* ELF header size in bytes */
179   Elf64_Half    e_phentsize;            /* Program header table entry size */
180   Elf64_Half    e_phnum;                /* Program header table entry count */
181   Elf64_Half    e_shentsize;            /* Section header table entry size */
182   Elf64_Half    e_shnum;                /* Section header table entry count */
183   Elf64_Half    e_shstrndx;             /* Section header string table index */
184 } Elf64_Ehdr;
185
186 /* Fields in the e_ident array.  The EI_* macros are indices into the
187    array.  The macros under each EI_* macro are the values the byte
188    may have.  */
189
190 #define EI_MAG0         0               /* File identification byte 0 index */
191 #define ELFMAG0         0x7f            /* Magic number byte 0 */
192
193 #define EI_MAG1         1               /* File identification byte 1 index */
194 #define ELFMAG1         'E'             /* Magic number byte 1 */
195
196 #define EI_MAG2         2               /* File identification byte 2 index */
197 #define ELFMAG2         'L'             /* Magic number byte 2 */
198
199 #define EI_MAG3         3               /* File identification byte 3 index */
200 #define ELFMAG3         'F'             /* Magic number byte 3 */
201
202 /* Conglomeration of the identification bytes, for easy testing as a word.  */
203 #define ELFMAG          "\177ELF"
204 #define SELFMAG         4
205
206 #define EI_CLASS        4               /* File class byte index */
207 #define ELFCLASSNONE    0               /* Invalid class */
208 #define ELFCLASS32      1               /* 32-bit objects */
209 #define ELFCLASS64      2               /* 64-bit objects */
210 #define ELFCLASSNUM     3
211
212 #define EI_DATA         5               /* Data encoding byte index */
213 #define ELFDATANONE     0               /* Invalid data encoding */
214 #define ELFDATA2LSB     1               /* 2's complement, little endian */
215 #define ELFDATA2MSB     2               /* 2's complement, big endian */
216 #define ELFDATANUM      3
217
218 #define EI_VERSION      6               /* File version byte index */
219                                         /* Value must be EV_CURRENT */
220
221 #define EI_OSABI        7               /* OS ABI identification */
222 #define ELFOSABI_SYSV           0       /* UNIX System V ABI */
223 #define ELFOSABI_HPUX           1       /* HP-UX */
224 #define ELFOSABI_FREEBSD        9       /* Free BSD */
225 #define ELFOSABI_ARM            97      /* ARM */
226 #define ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
227
228 #define EI_ABIVERSION   8               /* ABI version */
229
230 #define EI_PAD          9               /* Byte index of padding bytes */
231
232 /* Legal values for e_type (object file type).  */
233
234 #define ET_NONE         0               /* No file type */
235 #define ET_REL          1               /* Relocatable file */
236 #define ET_EXEC         2               /* Executable file */
237 #define ET_DYN          3               /* Shared object file */
238 #define ET_CORE         4               /* Core file */
239 #define ET_NUM          5               /* Number of defined types */
240 #define ET_LOPROC       0xff00          /* Processor-specific */
241 #define ET_HIPROC       0xffff          /* Processor-specific */
242
243 /* Legal values for e_machine (architecture).  */
244
245 #define EM_NONE          0              /* No machine */
246 #define EM_M32           1              /* AT&T WE 32100 */
247 #define EM_SPARC         2              /* SUN SPARC */
248 #define EM_386           3              /* Intel 80386 */
249 #define EM_68K           4              /* Motorola m68k family */
250 #define EM_88K           5              /* Motorola m88k family */
251 #define EM_486           6              /* Intel 80486 */
252 #define EM_860           7              /* Intel 80860 */
253 #define EM_MIPS          8              /* MIPS R3000 big-endian */
254 #define EM_S370          9              /* Amdahl */
255 #define EM_MIPS_RS4_BE  10              /* MIPS R4000 big-endian */
256 #define EM_RS6000       11              /* RS6000 */
257
258 #define EM_PARISC       15              /* HPPA */
259 #define EM_nCUBE        16              /* nCUBE */
260 #define EM_VPP500       17              /* Fujitsu VPP500 */
261 #define EM_SPARC32PLUS  18              /* Sun's "v8plus" */
262 #define EM_960          19              /* Intel 80960 */
263 #define EM_PPC          20              /* PowerPC */
264
265 #define EM_V800         36              /* NEC V800 series */
266 #define EM_FR20         37              /* Fujitsu FR20 */
267 #define EM_RH32         38              /* TRW RH32 */
268 #define EM_MMA          39              /* Fujitsu MMA */
269 #define EM_ARM          40              /* ARM */
270 #define EM_FAKE_ALPHA   41              /* Digital Alpha */
271 #define EM_SH           42              /* Hitachi SH */
272 #define EM_SPARCV9      43              /* SPARC v9 64-bit */
273 #define EM_TRICORE      44              /* Siemens Tricore */
274 #define EM_ARC          45              /* Argonaut RISC Core */
275 #define EM_H8_300       46              /* Hitachi H8/300 */
276 #define EM_H8_300H      47              /* Hitachi H8/300H */
277 #define EM_H8S          48              /* Hitachi H8S */
278 #define EM_H8_500       49              /* Hitachi H8/500 */
279 #define EM_IA_64        50              /* Intel Merced */
280 #define EM_MIPS_X       51              /* Stanford MIPS-X */
281 #define EM_COLDFIRE     52              /* Motorola Coldfire */
282 #define EM_68HC12       53              /* Motorola M68HC12 */
283 #define EM_NUM          54
284
285 /* If it is necessary to assign new unofficial EM_* values, please
286    pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
287    chances of collision with official or non-GNU unofficial values.  */
288
289 #define EM_ALPHA        0x9026
290 #define EM_C60          0x9c60
291
292 /* Legal values for e_version (version).  */
293
294 #define EV_NONE         0               /* Invalid ELF version */
295 #define EV_CURRENT      1               /* Current version */
296 #define EV_NUM          2
297
298 /* Section header.  */
299
300 typedef struct
301 {
302   Elf32_Word    sh_name;                /* Section name (string tbl index) */
303   Elf32_Word    sh_type;                /* Section type */
304   Elf32_Word    sh_flags;               /* Section flags */
305   Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
306   Elf32_Off     sh_offset;              /* Section file offset */
307   Elf32_Word    sh_size;                /* Section size in bytes */
308   Elf32_Word    sh_link;                /* Link to another section */
309   Elf32_Word    sh_info;                /* Additional section information */
310   Elf32_Word    sh_addralign;           /* Section alignment */
311   Elf32_Word    sh_entsize;             /* Entry size if section holds table */
312 } Elf32_Shdr;
313
314 typedef struct
315 {
316   Elf64_Word    sh_name;                /* Section name (string tbl index) */
317   Elf64_Word    sh_type;                /* Section type */
318   Elf64_Xword   sh_flags;               /* Section flags */
319   Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
320   Elf64_Off     sh_offset;              /* Section file offset */
321   Elf64_Xword   sh_size;                /* Section size in bytes */
322   Elf64_Word    sh_link;                /* Link to another section */
323   Elf64_Word    sh_info;                /* Additional section information */
324   Elf64_Xword   sh_addralign;           /* Section alignment */
325   Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
326 } Elf64_Shdr;
327
328 /* Special section indices.  */
329
330 #define SHN_UNDEF       0               /* Undefined section */
331 #define SHN_LORESERVE   0xff00          /* Start of reserved indices */
332 #define SHN_LOPROC      0xff00          /* Start of processor-specific */
333 #define SHN_HIPROC      0xff1f          /* End of processor-specific */
334 #define SHN_ABS         0xfff1          /* Associated symbol is absolute */
335 #define SHN_COMMON      0xfff2          /* Associated symbol is common */
336 #define SHN_HIRESERVE   0xffff          /* End of reserved indices */
337
338 /* Legal values for sh_type (section type).  */
339
340 #define SHT_NULL         0              /* Section header table entry unused */
341 #define SHT_PROGBITS     1              /* Program data */
342 #define SHT_SYMTAB       2              /* Symbol table */
343 #define SHT_STRTAB       3              /* String table */
344 #define SHT_RELA         4              /* Relocation entries with addends */
345 #define SHT_HASH         5              /* Symbol hash table */
346 #define SHT_DYNAMIC      6              /* Dynamic linking information */
347 #define SHT_NOTE         7              /* Notes */
348 #define SHT_NOBITS       8              /* Program space with no data (bss) */
349 #define SHT_REL          9              /* Relocation entries, no addends */
350 #define SHT_SHLIB        10             /* Reserved */
351 #define SHT_DYNSYM       11             /* Dynamic linker symbol table */
352 #define SHT_NUM          12             /* Number of defined types.  */
353 #define SHT_LOOS         0x60000000     /* Start OS-specific */
354 #define SHT_LOSUNW       0x6ffffffb     /* Sun-specific low bound.  */
355 #define SHT_SUNW_COMDAT  0x6ffffffb
356 #define SHT_SUNW_syminfo 0x6ffffffc
357 #define SHT_GNU_verdef   0x6ffffffd     /* Version definition section.  */
358 #define SHT_GNU_verneed  0x6ffffffe     /* Version needs section.  */
359 #define SHT_GNU_versym   0x6fffffff     /* Version symbol table.  */
360 #define SHT_HISUNW       0x6fffffff     /* Sun-specific high bound.  */
361 #define SHT_HIOS         0x6fffffff     /* End OS-specific type */
362 #define SHT_LOPROC       0x70000000     /* Start of processor-specific */
363 #define SHT_HIPROC       0x7fffffff     /* End of processor-specific */
364 #define SHT_LOUSER       0x80000000     /* Start of application-specific */
365 #define SHT_HIUSER       0x8fffffff     /* End of application-specific */
366
367 /* Legal values for sh_flags (section flags).  */
368
369 #define SHF_WRITE       (1 << 0)        /* Writable */
370 #define SHF_ALLOC       (1 << 1)        /* Occupies memory during execution */
371 #define SHF_EXECINSTR   (1 << 2)        /* Executable */
372 #define SHF_MASKPROC    0xf0000000      /* Processor-specific */
373
374 /* Symbol table entry.  */
375
376 typedef struct
377 {
378   Elf32_Word    st_name;                /* Symbol name (string tbl index) */
379   Elf32_Addr    st_value;               /* Symbol value */
380   Elf32_Word    st_size;                /* Symbol size */
381   unsigned char st_info;                /* Symbol type and binding */
382   unsigned char st_other;               /* No defined meaning, 0 */
383   Elf32_Section st_shndx;               /* Section index */
384 } Elf32_Sym;
385
386 typedef struct
387 {
388   Elf64_Word    st_name;                /* Symbol name (string tbl index) */
389   unsigned char st_info;                /* Symbol type and binding */
390   unsigned char st_other;               /* No defined meaning, 0 */
391   Elf64_Section st_shndx;               /* Section index */
392   Elf64_Addr    st_value;               /* Symbol value */
393   Elf64_Xword   st_size;                /* Symbol size */
394 } Elf64_Sym;
395
396 /* The syminfo section if available contains additional information about
397    every dynamic symbol.  */
398
399 typedef struct
400 {
401   Elf32_Half si_boundto;                /* Direct bindings, symbol bound to */
402   Elf32_Half si_flags;                  /* Per symbol flags */
403 } Elf32_Syminfo;
404
405 typedef struct
406 {
407   Elf64_Half si_boundto;                /* Direct bindings, symbol bound to */
408   Elf64_Half si_flags;                  /* Per symbol flags */
409 } Elf64_Syminfo;
410
411 /* Possible values for si_boundto.  */
412 #define SYMINFO_BT_SELF         0xffff  /* Symbol bound to self */
413 #define SYMINFO_BT_PARENT       0xfffe  /* Symbol bound to parent */
414 #define SYMINFO_BT_LOWRESERVE   0xff00  /* Beginning of reserved entries */
415
416 /* Possible bitmasks for si_flags.  */
417 #define SYMINFO_FLG_DIRECT      0x0001  /* Direct bound symbol */
418 #define SYMINFO_FLG_PASSTHRU    0x0002  /* Pass-thru symbol for translator */
419 #define SYMINFO_FLG_COPY        0x0004  /* Symbol is a copy-reloc */
420 #define SYMINFO_FLG_LAZYLOAD    0x0008  /* Symbol bound to object to be lazy
421                                            loaded */
422 /* Syminfo version values.  */
423 #define SYMINFO_NONE            0
424 #define SYMINFO_CURRENT         1
425 #define SYMINFO_NUM             2
426
427
428 /* Special section index.  */
429
430 #define SHN_UNDEF       0               /* No section, undefined symbol.  */
431
432 /* How to extract and insert information held in the st_info field.  */
433
434 #define ELF32_ST_BIND(val)              (((unsigned char) (val)) >> 4)
435 #define ELF32_ST_TYPE(val)              ((val) & 0xf)
436 #define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
437
438 /* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
439 #define ELF64_ST_BIND(val)              ELF32_ST_BIND (val)
440 #define ELF64_ST_TYPE(val)              ELF32_ST_TYPE (val)
441 #define ELF64_ST_INFO(bind, type)       ELF32_ST_INFO ((bind), (type))
442
443 /* Legal values for ST_BIND subfield of st_info (symbol binding).  */
444
445 #define STB_LOCAL       0               /* Local symbol */
446 #define STB_GLOBAL      1               /* Global symbol */
447 #define STB_WEAK        2               /* Weak symbol */
448 #define STB_NUM         3               /* Number of defined types.  */
449 #define STB_LOOS        10              /* Start of OS-specific */
450 #define STB_HIOS        12              /* End of OS-specific */
451 #define STB_LOPROC      13              /* Start of processor-specific */
452 #define STB_HIPROC      15              /* End of processor-specific */
453
454 /* Legal values for ST_TYPE subfield of st_info (symbol type).  */
455
456 #define STT_NOTYPE      0               /* Symbol type is unspecified */
457 #define STT_OBJECT      1               /* Symbol is a data object */
458 #define STT_FUNC        2               /* Symbol is a code object */
459 #define STT_SECTION     3               /* Symbol associated with a section */
460 #define STT_FILE        4               /* Symbol's name is file name */
461 #define STT_NUM         5               /* Number of defined types.  */
462 #define STT_LOOS        11              /* Start of OS-specific */
463 #define STT_HIOS        12              /* End of OS-specific */
464 #define STT_LOPROC      13              /* Start of processor-specific */
465 #define STT_HIPROC      15              /* End of processor-specific */
466
467
468 /* Symbol table indices are found in the hash buckets and chain table
469    of a symbol hash table section.  This special index value indicates
470    the end of a chain, meaning no further symbols are found in that bucket.  */
471
472 #define STN_UNDEF       0               /* End of a chain.  */
473
474
475 /* How to extract and insert information held in the st_other field.  */
476
477 #define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
478
479 /* For ELF64 the definitions are the same.  */
480 #define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
481
482 /* Symbol visibility specification encoded in the st_other field.  */
483 #define STV_DEFAULT     0               /* Default symbol visibility rules */
484 #define STV_INTERNAL    1               /* Processor specific hidden class */
485 #define STV_HIDDEN      2               /* Sym unavailable in other modules */
486 #define STV_PROTECTED   3               /* Not preemptible, not exported */
487
488
489 /* Relocation table entry without addend (in section of type SHT_REL).  */
490
491 typedef struct
492 {
493   Elf32_Addr    r_offset;               /* Address */
494   Elf32_Word    r_info;                 /* Relocation type and symbol index */
495 } Elf32_Rel;
496
497 /* I have seen two different definitions of the Elf64_Rel and
498    Elf64_Rela structures, so we'll leave them out until Novell (or
499    whoever) gets their act together.  */
500 /* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
501
502 typedef struct
503 {
504   Elf64_Addr    r_offset;               /* Address */
505   Elf64_Xword   r_info;                 /* Relocation type and symbol index */
506 } Elf64_Rel;
507
508 /* Relocation table entry with addend (in section of type SHT_RELA).  */
509
510 typedef struct
511 {
512   Elf32_Addr    r_offset;               /* Address */
513   Elf32_Word    r_info;                 /* Relocation type and symbol index */
514   Elf32_Sword   r_addend;               /* Addend */
515 } Elf32_Rela;
516
517 typedef struct
518 {
519   Elf64_Addr    r_offset;               /* Address */
520   Elf64_Xword   r_info;                 /* Relocation type and symbol index */
521   Elf64_Sxword  r_addend;               /* Addend */
522 } Elf64_Rela;
523
524 /* How to extract and insert information held in the r_info field.  */
525
526 #define ELF32_R_SYM(val)                ((val) >> 8)
527 #define ELF32_R_TYPE(val)               ((val) & 0xff)
528 #define ELF32_R_INFO(sym, type)         (((sym) << 8) + ((type) & 0xff))
529
530 #define ELF64_R_SYM(i)                  ((i) >> 32)
531 #define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
532 #define ELF64_R_INFO(sym,type)          (((sym) << 32) + (type))
533
534 /* Program segment header.  */
535
536 typedef struct
537 {
538   Elf32_Word    p_type;                 /* Segment type */
539   Elf32_Off     p_offset;               /* Segment file offset */
540   Elf32_Addr    p_vaddr;                /* Segment virtual address */
541   Elf32_Addr    p_paddr;                /* Segment physical address */
542   Elf32_Word    p_filesz;               /* Segment size in file */
543   Elf32_Word    p_memsz;                /* Segment size in memory */
544   Elf32_Word    p_flags;                /* Segment flags */
545   Elf32_Word    p_align;                /* Segment alignment */
546 } Elf32_Phdr;
547
548 typedef struct
549 {
550   Elf64_Word    p_type;                 /* Segment type */
551   Elf64_Word    p_flags;                /* Segment flags */
552   Elf64_Off     p_offset;               /* Segment file offset */
553   Elf64_Addr    p_vaddr;                /* Segment virtual address */
554   Elf64_Addr    p_paddr;                /* Segment physical address */
555   Elf64_Xword   p_filesz;               /* Segment size in file */
556   Elf64_Xword   p_memsz;                /* Segment size in memory */
557   Elf64_Xword   p_align;                /* Segment alignment */
558 } Elf64_Phdr;
559
560 /* Legal values for p_type (segment type).  */
561
562 #define PT_NULL         0               /* Program header table entry unused */
563 #define PT_LOAD         1               /* Loadable program segment */
564 #define PT_DYNAMIC      2               /* Dynamic linking information */
565 #define PT_INTERP       3               /* Program interpreter */
566 #define PT_NOTE         4               /* Auxiliary information */
567 #define PT_SHLIB        5               /* Reserved */
568 #define PT_PHDR         6               /* Entry for header table itself */
569 #define PT_NUM          7               /* Number of defined types.  */
570 #define PT_LOOS         0x60000000      /* Start of OS-specific */
571 #define PT_HIOS         0x6fffffff      /* End of OS-specific */
572 #define PT_LOPROC       0x70000000      /* Start of processor-specific */
573 #define PT_HIPROC       0x7fffffff      /* End of processor-specific */
574
575 /* Legal values for p_flags (segment flags).  */
576
577 #define PF_X            (1 << 0)        /* Segment is executable */
578 #define PF_W            (1 << 1)        /* Segment is writable */
579 #define PF_R            (1 << 2)        /* Segment is readable */
580 #define PF_MASKPROC     0xf0000000      /* Processor-specific */
581
582 /* Legal values for note segment descriptor types for core files. */
583
584 #define NT_PRSTATUS     1               /* Contains copy of prstatus struct */
585 #define NT_FPREGSET     2               /* Contains copy of fpregset struct */
586 #define NT_PRPSINFO     3               /* Contains copy of prpsinfo struct */
587 #define NT_PRXREG       4               /* Contains copy of prxregset struct */
588 #define NT_PLATFORM     5               /* String from sysinfo(SI_PLATFORM) */
589 #define NT_AUXV         6               /* Contains copy of auxv array */
590 #define NT_GWINDOWS     7               /* Contains copy of gwindows struct */
591 #define NT_PSTATUS      10              /* Contains copy of pstatus struct */
592 #define NT_PSINFO       13              /* Contains copy of psinfo struct */
593 #define NT_PRCRED       14              /* Contains copy of prcred struct */
594 #define NT_UTSNAME      15              /* Contains copy of utsname struct */
595 #define NT_LWPSTATUS    16              /* Contains copy of lwpstatus struct */
596 #define NT_LWPSINFO     17              /* Contains copy of lwpinfo struct */
597
598 /* Legal values for the  note segment descriptor types for object files.  */
599
600 #define NT_VERSION      1               /* Contains a version string.  */
601
602
603 /* Dynamic section entry.  */
604
605 typedef struct
606 {
607   Elf32_Sword   d_tag;                  /* Dynamic entry type */
608   union
609     {
610       Elf32_Word d_val;                 /* Integer value */
611       Elf32_Addr d_ptr;                 /* Address value */
612     } d_un;
613 } Elf32_Dyn;
614
615 typedef struct
616 {
617   Elf64_Sxword  d_tag;                  /* Dynamic entry type */
618   union
619     {
620       Elf64_Xword d_val;                /* Integer value */
621       Elf64_Addr d_ptr;                 /* Address value */
622     } d_un;
623 } Elf64_Dyn;
624
625 /* Legal values for d_tag (dynamic entry type).  */
626
627 #define DT_NULL         0               /* Marks end of dynamic section */
628 #define DT_NEEDED       1               /* Name of needed library */
629 #define DT_PLTRELSZ     2               /* Size in bytes of PLT relocs */
630 #define DT_PLTGOT       3               /* Processor defined value */
631 #define DT_HASH         4               /* Address of symbol hash table */
632 #define DT_STRTAB       5               /* Address of string table */
633 #define DT_SYMTAB       6               /* Address of symbol table */
634 #define DT_RELA         7               /* Address of Rela relocs */
635 #define DT_RELASZ       8               /* Total size of Rela relocs */
636 #define DT_RELAENT      9               /* Size of one Rela reloc */
637 #define DT_STRSZ        10              /* Size of string table */
638 #define DT_SYMENT       11              /* Size of one symbol table entry */
639 #define DT_INIT         12              /* Address of init function */
640 #define DT_FINI         13              /* Address of termination function */
641 #define DT_SONAME       14              /* Name of shared object */
642 #define DT_RPATH        15              /* Library search path */
643 #define DT_SYMBOLIC     16              /* Start symbol search here */
644 #define DT_REL          17              /* Address of Rel relocs */
645 #define DT_RELSZ        18              /* Total size of Rel relocs */
646 #define DT_RELENT       19              /* Size of one Rel reloc */
647 #define DT_PLTREL       20              /* Type of reloc in PLT */
648 #define DT_DEBUG        21              /* For debugging; unspecified */
649 #define DT_TEXTREL      22              /* Reloc might modify .text */
650 #define DT_JMPREL       23              /* Address of PLT relocs */
651 #define DT_BIND_NOW     24              /* Process relocations of object */
652 #define DT_INIT_ARRAY   25              /* Array with addresses of init fct */
653 #define DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
654 #define DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
655 #define DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
656 #define DT_NUM          29              /* Number used */
657 #define DT_LOOS         0x60000000      /* Start of OS-specific */
658 #define DT_HIOS         0x6fffffff      /* End of OS-specific */
659 #define DT_LOPROC       0x70000000      /* Start of processor-specific */
660 #define DT_HIPROC       0x7fffffff      /* End of processor-specific */
661 #define DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
662
663 /* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
664    Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
665    approach.  */
666 #define DT_VALRNGLO     0x6ffffd00
667 #define DT_POSFLAG_1    0x6ffffdfd      /* Flags for DT_* entries, effecting
668                                            the following DT_* entry.  */
669 #define DT_SYMINSZ      0x6ffffdfe      /* Size of syminfo table (in bytes) */
670 #define DT_SYMINENT     0x6ffffdff      /* Entry size of syminfo */
671 #define DT_VALRNGHI     0x6ffffdff
672
673 /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
674    Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
675
676    If any adjustment is made to the ELF object after it has been
677    built these entries will need to be adjusted.  */
678 #define DT_ADDRRNGLO    0x6ffffe00
679 #define DT_SYMINFO      0x6ffffeff      /* syminfo table */
680 #define DT_ADDRRNGHI    0x6ffffeff
681
682 /* The versioning entry types.  The next are defined as part of the
683    GNU extension.  */
684 #define DT_VERSYM       0x6ffffff0
685
686 /* These were chosen by Sun.  */
687 #define DT_FLAGS_1      0x6ffffffb      /* State flags, see DF_1_* below.  */
688 #define DT_VERDEF       0x6ffffffc      /* Address of version definition
689                                            table */
690 #define DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
691 #define DT_VERNEED      0x6ffffffe      /* Address of table with needed
692                                            versions */
693 #define DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
694 #define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
695 #define DT_VERSIONTAGNUM 16
696
697 /* Sun added these machine-independent extensions in the "processor-specific"
698    range.  Be compatible.  */
699 #define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
700 #define DT_FILTER       0x7fffffff      /* Shared object to get values from */
701 #define DT_EXTRATAGIDX(tag)     ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
702 #define DT_EXTRANUM     3
703
704 /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
705    entry in the dynamic section.  */
706 #define DF_1_NOW        0x00000001      /* Set RTLD_NOW for this object.  */
707 #define DF_1_GLOBAL     0x00000002      /* Set RTLD_GLOBAL for this object.  */
708 #define DF_1_GROUP      0x00000004      /* Set RTLD_GROUP for this object.  */
709 #define DF_1_NODELETE   0x00000008      /* Set RTLD_NODELETE for this object.*/
710 #define DF_1_LOADFLTR   0x00000010      /* Trigger filtee loading at runtime.*/
711 #define DF_1_INITFIRST  0x00000020      /* Set RTLD_INITFIRST for this object*/
712 #define DF_1_NOOPEN     0x00000040      /* Set RTLD_NOOPEN for this object.  */
713
714 /* Version definition sections.  */
715
716 typedef struct
717 {
718   Elf32_Half    vd_version;             /* Version revision */
719   Elf32_Half    vd_flags;               /* Version information */
720   Elf32_Half    vd_ndx;                 /* Version Index */
721   Elf32_Half    vd_cnt;                 /* Number of associated aux entries */
722   Elf32_Word    vd_hash;                /* Version name hash value */
723   Elf32_Word    vd_aux;                 /* Offset in bytes to verdaux array */
724   Elf32_Word    vd_next;                /* Offset in bytes to next verdef
725                                            entry */
726 } Elf32_Verdef;
727
728 typedef struct
729 {
730   Elf64_Half    vd_version;             /* Version revision */
731   Elf64_Half    vd_flags;               /* Version information */
732   Elf64_Half    vd_ndx;                 /* Version Index */
733   Elf64_Half    vd_cnt;                 /* Number of associated aux entries */
734   Elf64_Word    vd_hash;                /* Version name hash value */
735   Elf64_Word    vd_aux;                 /* Offset in bytes to verdaux array */
736   Elf64_Word    vd_next;                /* Offset in bytes to next verdef
737                                            entry */
738 } Elf64_Verdef;
739
740
741 /* Legal values for vd_version (version revision).  */
742 #define VER_DEF_NONE    0               /* No version */
743 #define VER_DEF_CURRENT 1               /* Current version */
744 #define VER_DEF_NUM     2               /* Given version number */
745
746 /* Legal values for vd_flags (version information flags).  */
747 #define VER_FLG_BASE    0x1             /* Version definition of file itself */
748 #define VER_FLG_WEAK    0x2             /* Weak version identifier */
749
750 /* Auxialiary version information.  */
751
752 typedef struct
753 {
754   Elf32_Word    vda_name;               /* Version or dependency names */
755   Elf32_Word    vda_next;               /* Offset in bytes to next verdaux
756                                            entry */
757 } Elf32_Verdaux;
758
759 typedef struct
760 {
761   Elf64_Word    vda_name;               /* Version or dependency names */
762   Elf64_Word    vda_next;               /* Offset in bytes to next verdaux
763                                            entry */
764 } Elf64_Verdaux;
765
766
767 /* Version dependency section.  */
768
769 typedef struct
770 {
771   Elf32_Half    vn_version;             /* Version of structure */
772   Elf32_Half    vn_cnt;                 /* Number of associated aux entries */
773   Elf32_Word    vn_file;                /* Offset of filename for this
774                                            dependency */
775   Elf32_Word    vn_aux;                 /* Offset in bytes to vernaux array */
776   Elf32_Word    vn_next;                /* Offset in bytes to next verneed
777                                            entry */
778 } Elf32_Verneed;
779
780 typedef struct
781 {
782   Elf64_Half    vn_version;             /* Version of structure */
783   Elf64_Half    vn_cnt;                 /* Number of associated aux entries */
784   Elf64_Word    vn_file;                /* Offset of filename for this
785                                            dependency */
786   Elf64_Word    vn_aux;                 /* Offset in bytes to vernaux array */
787   Elf64_Word    vn_next;                /* Offset in bytes to next verneed
788                                            entry */
789 } Elf64_Verneed;
790
791
792 /* Legal values for vn_version (version revision).  */
793 #define VER_NEED_NONE    0              /* No version */
794 #define VER_NEED_CURRENT 1              /* Current version */
795 #define VER_NEED_NUM     2              /* Given version number */
796
797 /* Auxiliary needed version information.  */
798
799 typedef struct
800 {
801   Elf32_Word    vna_hash;               /* Hash value of dependency name */
802   Elf32_Half    vna_flags;              /* Dependency specific information */
803   Elf32_Half    vna_other;              /* Unused */
804   Elf32_Word    vna_name;               /* Dependency name string offset */
805   Elf32_Word    vna_next;               /* Offset in bytes to next vernaux
806                                            entry */
807 } Elf32_Vernaux;
808
809 typedef struct
810 {
811   Elf64_Word    vna_hash;               /* Hash value of dependency name */
812   Elf64_Half    vna_flags;              /* Dependency specific information */
813   Elf64_Half    vna_other;              /* Unused */
814   Elf64_Word    vna_name;               /* Dependency name string offset */
815   Elf64_Word    vna_next;               /* Offset in bytes to next vernaux
816                                            entry */
817 } Elf64_Vernaux;
818
819
820 /* Legal values for vna_flags.  */
821 #define VER_FLG_WEAK    0x2             /* Weak version identifier */
822
823
824 /* Auxiliary vector.  */
825
826 /* This vector is normally only used by the program interpreter.  The
827    usual definition in an ABI supplement uses the name auxv_t.  The
828    vector is not usually defined in a standard <elf.h> file, but it
829    can't hurt.  We rename it to avoid conflicts.  The sizes of these
830    types are an arrangement between the exec server and the program
831    interpreter, so we don't fully specify them here.  */
832
833 typedef struct
834 {
835   int a_type;                   /* Entry type */
836   union
837     {
838       long int a_val;           /* Integer value */
839       void *a_ptr;              /* Pointer value */
840       void (*a_fcn) (void);     /* Function pointer value */
841     } a_un;
842 } Elf32_auxv_t;
843
844 typedef struct
845 {
846   long int a_type;              /* Entry type */
847   union
848     {
849       long int a_val;           /* Integer value */
850       void *a_ptr;              /* Pointer value */
851       void (*a_fcn) (void);     /* Function pointer value */
852     } a_un;
853 } Elf64_auxv_t;
854
855 /* Legal values for a_type (entry type).  */
856
857 #define AT_NULL         0               /* End of vector */
858 #define AT_IGNORE       1               /* Entry should be ignored */
859 #define AT_EXECFD       2               /* File descriptor of program */
860 #define AT_PHDR         3               /* Program headers for program */
861 #define AT_PHENT        4               /* Size of program header entry */
862 #define AT_PHNUM        5               /* Number of program headers */
863 #define AT_PAGESZ       6               /* System page size */
864 #define AT_BASE         7               /* Base address of interpreter */
865 #define AT_FLAGS        8               /* Flags */
866 #define AT_ENTRY        9               /* Entry point of program */
867 #define AT_NOTELF       10              /* Program is not ELF */
868 #define AT_UID          11              /* Real uid */
869 #define AT_EUID         12              /* Effective uid */
870 #define AT_GID          13              /* Real gid */
871 #define AT_EGID         14              /* Effective gid */
872
873 /* Some more special a_type values describing the hardware.  */
874 #define AT_PLATFORM     15              /* String identifying platform.  */
875 #define AT_HWCAP        16              /* Machine dependent hints about
876                                            processor capabilities.  */
877
878 /* This entry gives some information about the FPU initialization
879    performed by the kernel.  */
880 #define AT_FPUCW        17              /* Used FPU control word.  */
881
882
883 /* Note section contents.  Each entry in the note section begins with
884    a header of a fixed form.  */
885
886 typedef struct
887 {
888   Elf32_Word n_namesz;                  /* Length of the note's name.  */
889   Elf32_Word n_descsz;                  /* Length of the note's descriptor.  */
890   Elf32_Word n_type;                    /* Type of the note.  */
891 } Elf32_Nhdr;
892
893 typedef struct
894 {
895   Elf64_Word n_namesz;                  /* Length of the note's name.  */
896   Elf64_Word n_descsz;                  /* Length of the note's descriptor.  */
897   Elf64_Word n_type;                    /* Type of the note.  */
898 } Elf64_Nhdr;
899
900 /* Known names of notes.  */
901
902 /* Solaris entries in the note section have this name.  */
903 #define ELF_NOTE_SOLARIS        "SUNW Solaris"
904
905 /* Note entries for GNU systems have this name.  */
906 #define ELF_NOTE_GNU            "GNU"
907
908
909 /* Defined types of notes for Solaris.  */
910
911 /* Value of descriptor (one word) is desired pagesize for the binary.  */
912 #define ELF_NOTE_PAGESIZE_HINT  1
913
914
915 /* Defined note types for GNU systems.  */
916
917 /* ABI information.  The descriptor consists of words:
918    word 0: OS descriptor
919    word 1: major version of the ABI
920    word 2: minor version of the ABI
921    word 3: subminor version of the ABI
922 */
923 #define ELF_NOTE_ABI            1
924
925 /* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
926    note section entry.  */
927 #define ELF_NOTE_OS_LINUX       0
928 #define ELF_NOTE_OS_GNU         1
929 #define ELF_NOTE_OS_SOLARIS2    2
930
931
932 /* Motorola 68k specific definitions.  */
933
934 /* m68k relocs.  */
935
936 #define R_68K_NONE      0               /* No reloc */
937 #define R_68K_32        1               /* Direct 32 bit  */
938 #define R_68K_16        2               /* Direct 16 bit  */
939 #define R_68K_8         3               /* Direct 8 bit  */
940 #define R_68K_PC32      4               /* PC relative 32 bit */
941 #define R_68K_PC16      5               /* PC relative 16 bit */
942 #define R_68K_PC8       6               /* PC relative 8 bit */
943 #define R_68K_GOT32     7               /* 32 bit PC relative GOT entry */
944 #define R_68K_GOT16     8               /* 16 bit PC relative GOT entry */
945 #define R_68K_GOT8      9               /* 8 bit PC relative GOT entry */
946 #define R_68K_GOT32O    10              /* 32 bit GOT offset */
947 #define R_68K_GOT16O    11              /* 16 bit GOT offset */
948 #define R_68K_GOT8O     12              /* 8 bit GOT offset */
949 #define R_68K_PLT32     13              /* 32 bit PC relative PLT address */
950 #define R_68K_PLT16     14              /* 16 bit PC relative PLT address */
951 #define R_68K_PLT8      15              /* 8 bit PC relative PLT address */
952 #define R_68K_PLT32O    16              /* 32 bit PLT offset */
953 #define R_68K_PLT16O    17              /* 16 bit PLT offset */
954 #define R_68K_PLT8O     18              /* 8 bit PLT offset */
955 #define R_68K_COPY      19              /* Copy symbol at runtime */
956 #define R_68K_GLOB_DAT  20              /* Create GOT entry */
957 #define R_68K_JMP_SLOT  21              /* Create PLT entry */
958 #define R_68K_RELATIVE  22              /* Adjust by program base */
959 /* Keep this the last entry.  */
960 #define R_68K_NUM       23
961
962 /* Intel 80386 specific definitions.  */
963
964 /* i386 relocs.  */
965
966 #define R_386_NONE      0               /* No reloc */
967 #define R_386_32        1               /* Direct 32 bit  */
968 #define R_386_PC32      2               /* PC relative 32 bit */
969 #define R_386_GOT32     3               /* 32 bit GOT entry */
970 #define R_386_PLT32     4               /* 32 bit PLT address */
971 #define R_386_COPY      5               /* Copy symbol at runtime */
972 #define R_386_GLOB_DAT  6               /* Create GOT entry */
973 #define R_386_JMP_SLOT  7               /* Create PLT entry */
974 #define R_386_RELATIVE  8               /* Adjust by program base */
975 #define R_386_GOTOFF    9               /* 32 bit offset to GOT */
976 #define R_386_GOTPC     10              /* 32 bit PC relative offset to GOT */
977 /* Keep this the last entry.  */
978 #define R_386_NUM       11
979
980 /* SUN SPARC specific definitions.  */
981
982 /* Values for Elf64_Ehdr.e_flags.  */
983
984 #define EF_SPARCV9_MM           3
985 #define EF_SPARCV9_TSO          0
986 #define EF_SPARCV9_PSO          1
987 #define EF_SPARCV9_RMO          2
988 #define EF_SPARC_EXT_MASK       0xFFFF00
989 #define EF_SPARC_SUN_US1        0x000200
990 #define EF_SPARC_HAL_R1         0x000400
991
992 /* SPARC relocs.  */
993
994 #define R_SPARC_NONE    0               /* No reloc */
995 #define R_SPARC_8       1               /* Direct 8 bit */
996 #define R_SPARC_16      2               /* Direct 16 bit */
997 #define R_SPARC_32      3               /* Direct 32 bit */
998 #define R_SPARC_DISP8   4               /* PC relative 8 bit */
999 #define R_SPARC_DISP16  5               /* PC relative 16 bit */
1000 #define R_SPARC_DISP32  6               /* PC relative 32 bit */
1001 #define R_SPARC_WDISP30 7               /* PC relative 30 bit shifted */
1002 #define R_SPARC_WDISP22 8               /* PC relative 22 bit shifted */
1003 #define R_SPARC_HI22    9               /* High 22 bit */
1004 #define R_SPARC_22      10              /* Direct 22 bit */
1005 #define R_SPARC_13      11              /* Direct 13 bit */
1006 #define R_SPARC_LO10    12              /* Truncated 10 bit */
1007 #define R_SPARC_GOT10   13              /* Truncated 10 bit GOT entry */
1008 #define R_SPARC_GOT13   14              /* 13 bit GOT entry */
1009 #define R_SPARC_GOT22   15              /* 22 bit GOT entry shifted */
1010 #define R_SPARC_PC10    16              /* PC relative 10 bit truncated */
1011 #define R_SPARC_PC22    17              /* PC relative 22 bit shifted */
1012 #define R_SPARC_WPLT30  18              /* 30 bit PC relative PLT address */
1013 #define R_SPARC_COPY    19              /* Copy symbol at runtime */
1014 #define R_SPARC_GLOB_DAT 20             /* Create GOT entry */
1015 #define R_SPARC_JMP_SLOT 21             /* Create PLT entry */
1016 #define R_SPARC_RELATIVE 22             /* Adjust by program base */
1017 #define R_SPARC_UA32    23              /* Direct 32 bit unaligned */
1018
1019 /* Additional Sparc64 relocs.  */
1020
1021 #define R_SPARC_PLT32   24              /* Direct 32 bit ref to PLT entry */
1022 #define R_SPARC_HIPLT22 25              /* High 22 bit PLT entry */
1023 #define R_SPARC_LOPLT10 26              /* Truncated 10 bit PLT entry */
1024 #define R_SPARC_PCPLT32 27              /* PC rel 32 bit ref to PLT entry */
1025 #define R_SPARC_PCPLT22 28              /* PC rel high 22 bit PLT entry */
1026 #define R_SPARC_PCPLT10 29              /* PC rel trunc 10 bit PLT entry */
1027 #define R_SPARC_10      30              /* Direct 10 bit */
1028 #define R_SPARC_11      31              /* Direct 11 bit */
1029 #define R_SPARC_64      32              /* Direct 64 bit */
1030 #define R_SPARC_OLO10   33              /* ?? */
1031 #define R_SPARC_HH22    34              /* Top 22 bits of direct 64 bit */
1032 #define R_SPARC_HM10    35              /* High middle 10 bits of ... */
1033 #define R_SPARC_LM22    36              /* Low middle 22 bits of ... */
1034 #define R_SPARC_PC_HH22 37              /* Top 22 bits of pc rel 64 bit */
1035 #define R_SPARC_PC_HM10 38              /* High middle 10 bit of ... */
1036 #define R_SPARC_PC_LM22 39              /* Low miggle 22 bits of ... */
1037 #define R_SPARC_WDISP16 40              /* PC relative 16 bit shifted */
1038 #define R_SPARC_WDISP19 41              /* PC relative 19 bit shifted */
1039 #define R_SPARC_7       43              /* Direct 7 bit */
1040 #define R_SPARC_5       44              /* Direct 5 bit */
1041 #define R_SPARC_6       45              /* Direct 6 bit */
1042 #define R_SPARC_DISP64  46              /* PC relative 64 bit */
1043 #define R_SPARC_PLT64   47              /* Direct 64 bit ref to PLT entry */
1044 #define R_SPARC_HIX22   48              /* High 22 bit complemented */
1045 #define R_SPARC_LOX10   49              /* Truncated 11 bit complemented */
1046 #define R_SPARC_H44     50              /* Direct high 12 of 44 bit */
1047 #define R_SPARC_M44     51              /* Direct mid 22 of 44 bit */
1048 #define R_SPARC_L44     52              /* Direct low 10 of 44 bit */
1049 #define R_SPARC_REGISTER 53             /* Global register usage */
1050 #define R_SPARC_UA64    54              /* Direct 64 bit unaligned */
1051 #define R_SPARC_UA16    55              /* Direct 16 bit unaligned */
1052 /* Keep this the last entry.  */
1053 #define R_SPARC_NUM     56
1054
1055 /* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
1056
1057 #define DT_SPARC_REGISTER 0x70000001
1058 #define DT_SPARC_NUM    2
1059
1060 /* Bits present in AT_HWCAP, primarily for Sparc32.  */
1061
1062 #define HWCAP_SPARC_FLUSH       1       /* The cpu supports flush insn.  */
1063 #define HWCAP_SPARC_STBAR       2
1064 #define HWCAP_SPARC_SWAP        4
1065 #define HWCAP_SPARC_MULDIV      8
1066 #define HWCAP_SPARC_V9          16      /* The cpu is v9, so v8plus is ok.  */
1067
1068 /* MIPS R3000 specific definitions.  */
1069
1070 /* Legal values for e_flags field of Elf32_Ehdr.  */
1071
1072 #define EF_MIPS_NOREORDER   1           /* A .noreorder directive was used */
1073 #define EF_MIPS_PIC         2           /* Contains PIC code */
1074 #define EF_MIPS_CPIC        4           /* Uses PIC calling sequence */
1075 #define EF_MIPS_XGOT        8
1076 #define EF_MIPS_64BIT_WHIRL 16
1077 #define EF_MIPS_ABI2        32
1078 #define EF_MIPS_ABI_ON32    64
1079 #define EF_MIPS_ARCH        0xf0000000  /* MIPS architecture level */
1080
1081 /* Legal values for MIPS architecture level.  */
1082
1083 #define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
1084 #define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
1085 #define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
1086 #define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
1087 #define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
1088
1089 /* The following are non-official names and should not be used.  */
1090
1091 #define E_MIPS_ARCH_1     0x00000000    /* -mips1 code.  */
1092 #define E_MIPS_ARCH_2     0x10000000    /* -mips2 code.  */
1093 #define E_MIPS_ARCH_3     0x20000000    /* -mips3 code.  */
1094 #define E_MIPS_ARCH_4     0x30000000    /* -mips4 code.  */
1095 #define E_MIPS_ARCH_5     0x40000000    /* -mips5 code.  */
1096
1097 /* Special section indices.  */
1098
1099 #define SHN_MIPS_ACOMMON 0xff00         /* Allocated common symbols */
1100 #define SHN_MIPS_TEXT    0xff01         /* Allocated test symbols.  */
1101 #define SHN_MIPS_DATA    0xff02         /* Allocated data symbols.  */
1102 #define SHN_MIPS_SCOMMON 0xff03         /* Small common symbols */
1103 #define SHN_MIPS_SUNDEFINED 0xff04      /* Small undefined symbols */
1104
1105 /* Legal values for sh_type field of Elf32_Shdr.  */
1106
1107 #define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
1108 #define SHT_MIPS_MSYM          0x70000001
1109 #define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
1110 #define SHT_MIPS_GPTAB         0x70000003 /* Global data area sizes */
1111 #define SHT_MIPS_UCODE         0x70000004 /* Reserved for SGI/MIPS compilers */
1112 #define SHT_MIPS_DEBUG         0x70000005 /* MIPS ECOFF debugging information*/
1113 #define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
1114 #define SHT_MIPS_PACKAGE       0x70000007
1115 #define SHT_MIPS_PACKSYM       0x70000008
1116 #define SHT_MIPS_RELD          0x70000009
1117 #define SHT_MIPS_IFACE         0x7000000b
1118 #define SHT_MIPS_CONTENT       0x7000000c
1119 #define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
1120 #define SHT_MIPS_SHDR          0x70000010
1121 #define SHT_MIPS_FDESC         0x70000011
1122 #define SHT_MIPS_EXTSYM        0x70000012
1123 #define SHT_MIPS_DENSE         0x70000013
1124 #define SHT_MIPS_PDESC         0x70000014
1125 #define SHT_MIPS_LOCSYM        0x70000015
1126 #define SHT_MIPS_AUXSYM        0x70000016
1127 #define SHT_MIPS_OPTSYM        0x70000017
1128 #define SHT_MIPS_LOCSTR        0x70000018
1129 #define SHT_MIPS_LINE          0x70000019
1130 #define SHT_MIPS_RFDESC        0x7000001a
1131 #define SHT_MIPS_DELTASYM      0x7000001b
1132 #define SHT_MIPS_DELTAINST     0x7000001c
1133 #define SHT_MIPS_DELTACLASS    0x7000001d
1134 #define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
1135 #define SHT_MIPS_DELTADECL     0x7000001f
1136 #define SHT_MIPS_SYMBOL_LIB    0x70000020
1137 #define SHT_MIPS_EVENTS        0x70000021 /* Event section.  */
1138 #define SHT_MIPS_TRANSLATE     0x70000022
1139 #define SHT_MIPS_PIXIE         0x70000023
1140 #define SHT_MIPS_XLATE         0x70000024
1141 #define SHT_MIPS_XLATE_DEBUG   0x70000025
1142 #define SHT_MIPS_WHIRL         0x70000026
1143 #define SHT_MIPS_EH_REGION     0x70000027
1144 #define SHT_MIPS_XLATE_OLD     0x70000028
1145 #define SHT_MIPS_PDR_EXCEPTION 0x70000029
1146
1147 /* Legal values for sh_flags field of Elf32_Shdr.  */
1148
1149 #define SHF_MIPS_GPREL   0x10000000     /* Must be part of global data area */
1150 #define SHF_MIPS_MERGE   0x20000000
1151 #define SHF_MIPS_ADDR    0x40000000
1152 #define SHF_MIPS_STRINGS 0x80000000
1153 #define SHF_MIPS_NOSTRIP 0x08000000
1154 #define SHF_MIPS_LOCAL   0x04000000
1155 #define SHF_MIPS_NAMES   0x02000000
1156 #define SHF_MIPS_NODUPE  0x01000000
1157
1158
1159 /* Symbol tables.  */
1160
1161 /* MIPS specific values for `st_other'.  */
1162 #define STO_MIPS_DEFAULT                0x0
1163 #define STO_MIPS_INTERNAL               0x1
1164 #define STO_MIPS_HIDDEN                 0x2
1165 #define STO_MIPS_PROTECTED              0x3
1166 #define STO_MIPS_SC_ALIGN_UNUSED        0xff
1167
1168 /* MIPS specific values for `st_info'.  */
1169 #define STB_MIPS_SPLIT_COMMON           13
1170
1171 /* Entries found in sections of type SHT_MIPS_GPTAB.  */
1172
1173 typedef union
1174 {
1175   struct
1176     {
1177       Elf32_Word gt_current_g_value;    /* -G value used for compilation */
1178       Elf32_Word gt_unused;             /* Not used */
1179     } gt_header;                        /* First entry in section */
1180   struct
1181     {
1182       Elf32_Word gt_g_value;            /* If this value were used for -G */
1183       Elf32_Word gt_bytes;              /* This many bytes would be used */
1184     } gt_entry;                         /* Subsequent entries in section */
1185 } Elf32_gptab;
1186
1187 /* Entry found in sections of type SHT_MIPS_REGINFO.  */
1188
1189 typedef struct
1190 {
1191   Elf32_Word    ri_gprmask;             /* General registers used */
1192   Elf32_Word    ri_cprmask[4];          /* Coprocessor registers used */
1193   Elf32_Sword   ri_gp_value;            /* $gp register value */
1194 } Elf32_RegInfo;
1195
1196 /* Entries found in sections of type SHT_MIPS_OPTIONS.  */
1197
1198 typedef struct
1199 {
1200   unsigned char kind;           /* Determines interpretation of the
1201                                    variable part of descriptor.  */
1202   unsigned char size;           /* Size of descriptor, including header.  */
1203   Elf32_Section section;        /* Section header index of section affected,
1204                                    0 for global options.  */
1205   Elf32_Word info;              /* Kind-specific information.  */
1206 } Elf_Options;
1207
1208 /* Values for `kind' field in Elf_Options.  */
1209
1210 #define ODK_NULL        0       /* Undefined.  */
1211 #define ODK_REGINFO     1       /* Register usage information.  */
1212 #define ODK_EXCEPTIONS  2       /* Exception processing options.  */
1213 #define ODK_PAD         3       /* Section padding options.  */
1214 #define ODK_HWPATCH     4       /* Hardware workarounds performed */
1215 #define ODK_FILL        5       /* record the fill value used by the linker. */
1216 #define ODK_TAGS        6       /* reserve space for desktop tools to write. */
1217 #define ODK_HWAND       7       /* HW workarounds.  'AND' bits when merging. */
1218 #define ODK_HWOR        8       /* HW workarounds.  'OR' bits when merging.  */
1219
1220 /* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
1221
1222 #define OEX_FPU_MIN     0x1f    /* FPE's which MUST be enabled.  */
1223 #define OEX_FPU_MAX     0x1f00  /* FPE's which MAY be enabled.  */
1224 #define OEX_PAGE0       0x10000 /* page zero must be mapped.  */
1225 #define OEX_SMM         0x20000 /* Force sequential memory mode?  */
1226 #define OEX_FPDBUG      0x40000 /* Force floating point debug mode?  */
1227 #define OEX_PRECISEFP   OEX_FPDBUG
1228 #define OEX_DISMISS     0x80000 /* Dismiss invalid address faults?  */
1229
1230 #define OEX_FPU_INVAL   0x10
1231 #define OEX_FPU_DIV0    0x08
1232 #define OEX_FPU_OFLO    0x04
1233 #define OEX_FPU_UFLO    0x02
1234 #define OEX_FPU_INEX    0x01
1235
1236 /* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
1237
1238 #define OHW_R4KEOP      0x1     /* R4000 end-of-page patch.  */
1239 #define OHW_R8KPFETCH   0x2     /* may need R8000 prefetch patch.  */
1240 #define OHW_R5KEOP      0x4     /* R5000 end-of-page patch.  */
1241 #define OHW_R5KCVTL     0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
1242
1243 #define OPAD_PREFIX     0x1
1244 #define OPAD_POSTFIX    0x2
1245 #define OPAD_SYMBOL     0x4
1246
1247 /* Entry found in `.options' section.  */
1248
1249 typedef struct
1250 {
1251   Elf32_Word hwp_flags1;        /* Extra flags.  */
1252   Elf32_Word hwp_flags2;        /* Extra flags.  */
1253 } Elf_Options_Hw;
1254
1255 /* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
1256
1257 #define OHWA0_R4KEOP_CHECKED    0x00000001
1258 #define OHWA1_R4KEOP_CLEAN      0x00000002
1259
1260 /* MIPS relocs.  */
1261
1262 #define R_MIPS_NONE             0       /* No reloc */
1263 #define R_MIPS_16               1       /* Direct 16 bit */
1264 #define R_MIPS_32               2       /* Direct 32 bit */
1265 #define R_MIPS_REL32            3       /* PC relative 32 bit */
1266 #define R_MIPS_26               4       /* Direct 26 bit shifted */
1267 #define R_MIPS_HI16             5       /* High 16 bit */
1268 #define R_MIPS_LO16             6       /* Low 16 bit */
1269 #define R_MIPS_GPREL16          7       /* GP relative 16 bit */
1270 #define R_MIPS_LITERAL          8       /* 16 bit literal entry */
1271 #define R_MIPS_GOT16            9       /* 16 bit GOT entry */
1272 #define R_MIPS_PC16             10      /* PC relative 16 bit */
1273 #define R_MIPS_CALL16           11      /* 16 bit GOT entry for function */
1274 #define R_MIPS_GPREL32          12      /* GP relative 32 bit */
1275
1276 #define R_MIPS_SHIFT5           16
1277 #define R_MIPS_SHIFT6           17
1278 #define R_MIPS_64               18
1279 #define R_MIPS_GOT_DISP         19
1280 #define R_MIPS_GOT_PAGE         20
1281 #define R_MIPS_GOT_OFST         21
1282 #define R_MIPS_GOT_HI16         22
1283 #define R_MIPS_GOT_LO16         23
1284 #define R_MIPS_SUB              24
1285 #define R_MIPS_INSERT_A         25
1286 #define R_MIPS_INSERT_B         26
1287 #define R_MIPS_DELETE           27
1288 #define R_MIPS_HIGHER           28
1289 #define R_MIPS_HIGHEST          29
1290 #define R_MIPS_CALL_HI16        30
1291 #define R_MIPS_CALL_LO16        31
1292 #define R_MIPS_SCN_DISP         32
1293 #define R_MIPS_REL16            33
1294 #define R_MIPS_ADD_IMMEDIATE    34
1295 #define R_MIPS_PJUMP            35
1296 #define R_MIPS_RELGOT           36
1297 #define R_MIPS_JALR             37
1298 /* Keep this the last entry.  */
1299 #define R_MIPS_NUM              38
1300
1301 /* Legal values for p_type field of Elf32_Phdr.  */
1302
1303 #define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
1304 #define PT_MIPS_RTPROC  0x70000001      /* Runtime procedure table. */
1305 #define PT_MIPS_OPTIONS 0x70000002
1306
1307 /* Special program header types.  */
1308
1309 #define PF_MIPS_LOCAL   0x10000000
1310
1311 /* Legal values for d_tag field of Elf32_Dyn.  */
1312
1313 #define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime linker interface version */
1314 #define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
1315 #define DT_MIPS_ICHECKSUM    0x70000003 /* Checksum */
1316 #define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
1317 #define DT_MIPS_FLAGS        0x70000005 /* Flags */
1318 #define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
1319 #define DT_MIPS_MSYM         0x70000007
1320 #define DT_MIPS_CONFLICT     0x70000008 /* Address of CONFLICT section */
1321 #define DT_MIPS_LIBLIST      0x70000009 /* Address of LIBLIST section */
1322 #define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local GOT entries */
1323 #define DT_MIPS_CONFLICTNO   0x7000000b /* Number of CONFLICT entries */
1324 #define DT_MIPS_LIBLISTNO    0x70000010 /* Number of LIBLIST entries */
1325 #define DT_MIPS_SYMTABNO     0x70000011 /* Number of DYNSYM entries */
1326 #define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
1327 #define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in DYNSYM */
1328 #define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
1329 #define DT_MIPS_RLD_MAP      0x70000016 /* Address of run time loader map.  */
1330 #define DT_MIPS_DELTA_CLASS  0x70000017 /* Delta C++ class definition.  */
1331 #define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
1332                                                 DT_MIPS_DELTA_CLASS.  */
1333 #define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
1334 #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
1335                                                 DT_MIPS_DELTA_INSTANCE.  */
1336 #define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
1337 #define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
1338                                              DT_MIPS_DELTA_RELOC.  */
1339 #define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
1340                                            relocations refer to.  */
1341 #define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
1342                                            DT_MIPS_DELTA_SYM.  */
1343 #define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
1344                                              class declaration.  */
1345 #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
1346                                                 DT_MIPS_DELTA_CLASSSYM.  */
1347 #define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
1348 #define DT_MIPS_PIXIE_INIT   0x70000023
1349 #define DT_MIPS_SYMBOL_LIB   0x70000024
1350 #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
1351 #define DT_MIPS_LOCAL_GOTIDX 0x70000026
1352 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027
1353 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028
1354 #define DT_MIPS_OPTIONS      0x70000029 /* Address of .options.  */
1355 #define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
1356 #define DT_MIPS_DYNSTR_ALIGN 0x7000002b
1357 #define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
1358 #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
1359                                                     function stored in GOT.  */
1360 #define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
1361                                            by rld on dlopen() calls.  */
1362 #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
1363 #define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
1364 #define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
1365 #define DT_MIPS_NUM          0x32
1366
1367 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
1368
1369 #define RHF_NONE                   0            /* No flags */
1370 #define RHF_QUICKSTART             (1 << 0)     /* Use quickstart */
1371 #define RHF_NOTPOT                 (1 << 1)     /* Hash size not power of 2 */
1372 #define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)     /* Ignore LD_LIBRARY_PATH */
1373 #define RHF_NO_MOVE                (1 << 3)
1374 #define RHF_SGI_ONLY               (1 << 4)
1375 #define RHF_GUARANTEE_INIT         (1 << 5)
1376 #define RHF_DELTA_C_PLUS_PLUS      (1 << 6)
1377 #define RHF_GUARANTEE_START_INIT   (1 << 7)
1378 #define RHF_PIXIE                  (1 << 8)
1379 #define RHF_DEFAULT_DELAY_LOAD     (1 << 9)
1380 #define RHF_REQUICKSTART           (1 << 10)
1381 #define RHF_REQUICKSTARTED         (1 << 11)
1382 #define RHF_CORD                   (1 << 12)
1383 #define RHF_NO_UNRES_UNDEF         (1 << 13)
1384 #define RHF_RLD_ORDER_SAFE         (1 << 14)
1385
1386 /* Entries found in sections of type SHT_MIPS_LIBLIST.  */
1387
1388 typedef struct
1389 {
1390   Elf32_Word l_name;            /* Name (string table index) */
1391   Elf32_Word l_time_stamp;      /* Timestamp */
1392   Elf32_Word l_checksum;        /* Checksum */
1393   Elf32_Word l_version;         /* Interface version */
1394   Elf32_Word l_flags;           /* Flags */
1395 } Elf32_Lib;
1396
1397 typedef struct
1398 {
1399   Elf64_Word l_name;            /* Name (string table index) */
1400   Elf64_Word l_time_stamp;      /* Timestamp */
1401   Elf64_Word l_checksum;        /* Checksum */
1402   Elf64_Word l_version;         /* Interface version */
1403   Elf64_Word l_flags;           /* Flags */
1404 } Elf64_Lib;
1405
1406
1407 /* Legal values for l_flags.  */
1408
1409 #define LL_NONE           0
1410 #define LL_EXACT_MATCH    (1 << 0)      /* Require exact match */
1411 #define LL_IGNORE_INT_VER (1 << 1)      /* Ignore interface version */
1412 #define LL_REQUIRE_MINOR  (1 << 2)
1413 #define LL_EXPORTS        (1 << 3)
1414 #define LL_DELAY_LOAD     (1 << 4)
1415 #define LL_DELTA          (1 << 5)
1416
1417 /* Entries found in sections of type SHT_MIPS_CONFLICT.  */
1418
1419 typedef Elf32_Addr Elf32_Conflict;
1420
1421
1422 /* HPPA specific definitions.  */
1423
1424 /* Legal values for e_flags field of Elf32_Ehdr.  */
1425
1426 #define EF_PARISC_TRAPNL        1       /* Trap nil pointer dereference.  */
1427 #define EF_PARISC_EXT           2       /* Program uses arch. extensions.  */
1428 #define EF_PARISC_ARCH          0xffff0000 /* Architecture version.  */
1429 /* Defined values are:
1430                                 0x020b  PA-RISC 1.0 big-endian
1431                                 0x0210  PA-RISC 1.1 big-endian
1432                                 0x028b  PA-RISC 1.0 little-endian
1433                                 0x0290  PA-RISC 1.1 little-endian
1434 */
1435
1436 /* Legal values for sh_type field of Elf32_Shdr.  */
1437
1438 #define SHT_PARISC_GOT          0x70000000 /* GOT for external data.  */
1439 #define SHT_PARISC_ARCH         0x70000001 /* Architecture extensions.  */
1440 #define SHT_PARISC_GLOBAL       0x70000002 /* Definition of $global$.  */
1441 #define SHT_PARISC_MILLI        0x70000003 /* Millicode routines.  */
1442 #define SHT_PARISC_UNWIND       0x70000004 /* Unwind information.  */
1443 #define SHT_PARISC_PLT          0x70000005 /* Procedure linkage table.  */
1444 #define SHT_PARISC_SDATA        0x70000006 /* Short initialized data.  */
1445 #define SHT_PARISC_SBSS         0x70000007 /* Short uninitialized data.  */
1446 #define SHT_PARISC_SYMEXTN      0x70000008 /* Argument/relocation info.  */
1447 #define SHT_PARISC_STUBS        0x70000009 /* Linker stubs.  */
1448
1449 /* Legal values for sh_flags field of Elf32_Shdr.  */
1450
1451 #define SHF_PARISC_GLOBAL       0x10000000 /* Section defines dp.  */
1452 #define SHF_PARISC_SHORT        0x20000000 /* Section with short addressing. */
1453
1454 /* Legal values for ST_TYPE subfield of st_info (symbol type).  */
1455
1456 #define STT_PARISC_MILLICODE    13      /* Millicode function entry point.  */
1457
1458 /* HPPA relocs.  */
1459
1460 #define R_PARISC_NONE           0       /* No reloc.  */
1461 #define R_PARISC_DIR32          1       /* Direct 32-bit reference.  */
1462 #define R_PARISC_DIR21L         2       /* Left 21 bits of eff. address.  */
1463 #define R_PARISC_DIR17R         3       /* Right 17 bits of eff. address.  */
1464 #define R_PARISC_DIR14R         4       /* Right 14 bits of eff. address.  */
1465 #define R_PARISC_PCREL21L       5       /* PC-relative, left 21 bits.  */
1466 #define R_PARISC_PCREL14R       6       /* PC-relative, right 14 bits.  */
1467 #define R_PARISC_PCREL17C       7       /* Conditional PC-relative, ignore
1468                                            if displacement > 17bits.  */
1469 #define R_PARISC_PCREL17F       8       /* Conditional PC-relative, must
1470                                            fit in 17bits.  */
1471 #define R_PARISC_DPREL21L       9       /* DP-relative, left 21 bits.  */
1472 #define R_PARISC_DPREL14R       10      /* DP-relative, right 14 bits.  */
1473 #define R_PARISC_DPREL14F       11      /* DP-relative, must bit in 14 bits. */
1474 #define R_PARISC_DLTREL21L      12      /* DLT-relative, left 21 bits.  */
1475 #define R_PARISC_DLTREL14R      13      /* DLT-relative, right 14 bits.  */
1476 #define R_PARISC_DLTREL14F      14      /* DLT-relative, must fit in 14 bits.*/
1477 #define R_PARISC_DLTIND21L      15      /* DLT-relative indirect, left
1478                                            21 bits.  */
1479 #define R_PARISC_DLTIND14R      16      /* DLT-relative indirect, right
1480                                            14 bits.  */
1481 #define R_PARISC_DLTIND14F      17      /* DLT-relative indirect, must fit
1482                                            int 14 bits.  */
1483 #define R_PARISC_PLABEL32       18      /* Direct 32-bit reference to proc.  */
1484
1485 /* Alpha specific definitions.  */
1486
1487 /* Legal values for e_flags field of Elf64_Ehdr.  */
1488
1489 #define EF_ALPHA_32BIT          1       /* All addresses must be < 2GB.  */
1490 #define EF_ALPHA_CANRELAX       2       /* Relocations for relaxing exist.  */
1491
1492 /* Legal values for sh_type field of Elf64_Shdr.  */
1493
1494 /* These two are primerily concerned with ECOFF debugging info.  */
1495 #define SHT_ALPHA_DEBUG         0x70000001
1496 #define SHT_ALPHA_REGINFO       0x70000002
1497
1498 /* Legal values for sh_flags field of Elf64_Shdr.  */
1499
1500 #define SHF_ALPHA_GPREL         0x10000000
1501
1502 /* Legal values for st_other field of Elf64_Sym.  */
1503 #define STO_ALPHA_NOPV          0x80    /* No PV required.  */
1504 #define STO_ALPHA_STD_GPLOAD    0x88    /* PV only used for initial ldgp.  */
1505
1506 /* Alpha relocs.  */
1507
1508 #define R_ALPHA_NONE            0       /* No reloc */
1509 #define R_ALPHA_REFLONG         1       /* Direct 32 bit */
1510 #define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
1511 #define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
1512 #define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
1513 #define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
1514 #define R_ALPHA_GPDISP          6       /* Add displacement to GP */
1515 #define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
1516 #define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
1517 #define R_ALPHA_SREL16          9       /* PC relative 16 bit */
1518 #define R_ALPHA_SREL32          10      /* PC relative 32 bit */
1519 #define R_ALPHA_SREL64          11      /* PC relative 64 bit */
1520 #define R_ALPHA_OP_PUSH         12      /* OP stack push */
1521 #define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
1522 #define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
1523 #define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
1524 #define R_ALPHA_GPVALUE         16
1525 #define R_ALPHA_GPRELHIGH       17
1526 #define R_ALPHA_GPRELLOW        18
1527 #define R_ALPHA_IMMED_GP_16     19
1528 #define R_ALPHA_IMMED_GP_HI32   20
1529 #define R_ALPHA_IMMED_SCN_HI32  21
1530 #define R_ALPHA_IMMED_BR_HI32   22
1531 #define R_ALPHA_IMMED_LO32      23
1532 #define R_ALPHA_COPY            24      /* Copy symbol at runtime */
1533 #define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
1534 #define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
1535 #define R_ALPHA_RELATIVE        27      /* Adjust by program base */
1536 /* Keep this the last entry.  */
1537 #define R_ALPHA_NUM             28
1538
1539
1540 /* PowerPC specific declarations */
1541
1542 /* PowerPC relocations defined by the ABIs */
1543 #define R_PPC_NONE              0
1544 #define R_PPC_ADDR32            1       /* 32bit absolute address */
1545 #define R_PPC_ADDR24            2       /* 26bit address, 2 bits ignored.  */
1546 #define R_PPC_ADDR16            3       /* 16bit absolute address */
1547 #define R_PPC_ADDR16_LO         4       /* lower 16bit of absolute address */
1548 #define R_PPC_ADDR16_HI         5       /* high 16bit of absolute address */
1549 #define R_PPC_ADDR16_HA         6       /* adjusted high 16bit */
1550 #define R_PPC_ADDR14            7       /* 16bit address, 2 bits ignored */
1551 #define R_PPC_ADDR14_BRTAKEN    8
1552 #define R_PPC_ADDR14_BRNTAKEN   9
1553 #define R_PPC_REL24             10      /* PC relative 26 bit */
1554 #define R_PPC_REL14             11      /* PC relative 16 bit */
1555 #define R_PPC_REL14_BRTAKEN     12
1556 #define R_PPC_REL14_BRNTAKEN    13
1557 #define R_PPC_GOT16             14
1558 #define R_PPC_GOT16_LO          15
1559 #define R_PPC_GOT16_HI          16
1560 #define R_PPC_GOT16_HA          17
1561 #define R_PPC_PLTREL24          18
1562 #define R_PPC_COPY              19
1563 #define R_PPC_GLOB_DAT          20
1564 #define R_PPC_JMP_SLOT          21
1565 #define R_PPC_RELATIVE          22
1566 #define R_PPC_LOCAL24PC         23
1567 #define R_PPC_UADDR32           24
1568 #define R_PPC_UADDR16           25
1569 #define R_PPC_REL32             26
1570 #define R_PPC_PLT32             27
1571 #define R_PPC_PLTREL32          28
1572 #define R_PPC_PLT16_LO          29
1573 #define R_PPC_PLT16_HI          30
1574 #define R_PPC_PLT16_HA          31
1575 #define R_PPC_SDAREL16          32
1576 #define R_PPC_SECTOFF           33
1577 #define R_PPC_SECTOFF_LO        34
1578 #define R_PPC_SECTOFF_HI        35
1579 #define R_PPC_SECTOFF_HA        36
1580 /* Keep this the last entry.  */
1581 #define R_PPC_NUMm              37
1582
1583 /* The remaining relocs are from the Embedded ELF ABI, and are not
1584    in the SVR4 ELF ABI.  */
1585 #define R_PPC_EMB_NADDR32       101
1586 #define R_PPC_EMB_NADDR16       102
1587 #define R_PPC_EMB_NADDR16_LO    103
1588 #define R_PPC_EMB_NADDR16_HI    104
1589 #define R_PPC_EMB_NADDR16_HA    105
1590 #define R_PPC_EMB_SDAI16        106
1591 #define R_PPC_EMB_SDA2I16       107
1592 #define R_PPC_EMB_SDA2REL       108
1593 #define R_PPC_EMB_SDA21         109     /* 16 bit offset in SDA */
1594 #define R_PPC_EMB_MRKREF        110
1595 #define R_PPC_EMB_RELSEC16      111
1596 #define R_PPC_EMB_RELST_LO      112
1597 #define R_PPC_EMB_RELST_HI      113
1598 #define R_PPC_EMB_RELST_HA      114
1599 #define R_PPC_EMB_BIT_FLD       115
1600 #define R_PPC_EMB_RELSDA        116     /* 16 bit relative offset in SDA */
1601
1602 /* Diab tool relocations.  */
1603 #define R_PPC_DIAB_SDA21_LO     180     /* like EMB_SDA21, but lower 16 bit */
1604 #define R_PPC_DIAB_SDA21_HI     181     /* like EMB_SDA21, but high 16 bit */
1605 #define R_PPC_DIAB_SDA21_HA     182     /* like EMB_SDA21, adjusted high 16 */
1606 #define R_PPC_DIAB_RELSDA_LO    183     /* like EMB_RELSDA, but lower 16 bit */
1607 #define R_PPC_DIAB_RELSDA_HI    184     /* like EMB_RELSDA, but high 16 bit */
1608 #define R_PPC_DIAB_RELSDA_HA    185     /* like EMB_RELSDA, adjusted high 16 */
1609
1610 /* This is a phony reloc to handle any old fashioned TOC16 references
1611    that may still be in object files.  */
1612 #define R_PPC_TOC16             255
1613
1614
1615 /* ARM specific declarations */
1616
1617 /* Processor specific flags for the ELF header e_flags field.  */
1618 #define EF_ARM_RELEXEC     0x01
1619 #define EF_ARM_HASENTRY    0x02
1620 #define EF_ARM_INTERWORK   0x04
1621 #define EF_ARM_APCS_26     0x08
1622 #define EF_ARM_APCS_FLOAT  0x10
1623 #define EF_ARM_PIC         0x20
1624 #define EF_ALIGN8          0x40         /* 8-bit structure alignment is in use */
1625 #define EF_NEW_ABI         0x80
1626 #define EF_OLD_ABI         0x100
1627
1628 /* Additional symbol types for Thumb */
1629 #define STT_ARM_TFUNC      0xd
1630
1631 /* ARM-specific values for sh_flags */
1632 #define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
1633 #define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
1634                                            in the input to a link step */
1635
1636 /* ARM-specific program header flags */
1637 #define PF_ARM_SB          0x10000000   /* Segment contains the location
1638                                            addressed by the static base */
1639
1640 /* ARM relocs.  */
1641 #define R_ARM_NONE              0       /* No reloc */
1642 #define R_ARM_PC24              1       /* PC relative 26 bit branch */
1643 #define R_ARM_ABS32             2       /* Direct 32 bit  */
1644 #define R_ARM_REL32             3       /* PC relative 32 bit */
1645 #define R_ARM_PC13              4
1646 #define R_ARM_ABS16             5       /* Direct 16 bit */
1647 #define R_ARM_ABS12             6       /* Direct 12 bit */
1648 #define R_ARM_THM_ABS5          7
1649 #define R_ARM_ABS8              8       /* Direct 8 bit */
1650 #define R_ARM_SBREL32           9
1651 #define R_ARM_THM_PC22          10
1652 #define R_ARM_THM_PC8           11
1653 #define R_ARM_AMP_VCALL9        12
1654 #define R_ARM_SWI24             13
1655 #define R_ARM_THM_SWI8          14
1656 #define R_ARM_XPC25             15
1657 #define R_ARM_THM_XPC22         16
1658 #define R_ARM_COPY              20      /* Copy symbol at runtime */
1659 #define R_ARM_GLOB_DAT          21      /* Create GOT entry */
1660 #define R_ARM_JUMP_SLOT         22      /* Create PLT entry */
1661 #define R_ARM_RELATIVE          23      /* Adjust by program base */
1662 #define R_ARM_GOTOFF            24      /* 32 bit offset to GOT */
1663 #define R_ARM_GOTPC             25      /* 32 bit PC relative offset to GOT */
1664 #define R_ARM_GOT32             26      /* 32 bit GOT entry */
1665 #define R_ARM_PLT32             27      /* 32 bit PLT address */
1666 #define R_ARM_GNU_VTENTRY       100
1667 #define R_ARM_GNU_VTINHERIT     101
1668 #define R_ARM_THM_PC11          102     /* thumb unconditional branch */
1669 #define R_ARM_THM_PC9           103     /* thumb conditional branch */
1670 #define R_ARM_RXPC25            249
1671 #define R_ARM_RSBREL32          250
1672 #define R_ARM_THM_RPC22         251
1673 #define R_ARM_RREL32            252
1674 #define R_ARM_RABS22            253
1675 #define R_ARM_RPC24             254
1676 #define R_ARM_RBASE             255
1677 /* Keep this the last entry.  */
1678 #define R_ARM_NUM               256
1679
1680 /* TMS320C67xx specific declarations */
1681 /* XXX: no ELF standard yet */
1682
1683 /* TMS320C67xx relocs. */
1684 #define R_C60_32       1
1685 #define R_C60_GOT32     3               /* 32 bit GOT entry */
1686 #define R_C60_PLT32     4               /* 32 bit PLT address */
1687 #define R_C60_COPY      5               /* Copy symbol at runtime */
1688 #define R_C60_GLOB_DAT  6               /* Create GOT entry */
1689 #define R_C60_JMP_SLOT  7               /* Create PLT entry */
1690 #define R_C60_RELATIVE  8               /* Adjust by program base */
1691 #define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
1692 #define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
1693
1694 #define R_C60HI16      0x55       // high 16 bit MVKH embedded
1695 #define R_C60LO16      0x54       // low 16 bit MVKL embedded
1696
1697 #endif  /* elf.h */
1698 //---------------------------------------------------------------------------
1699
1700
1701 // njn: inlined stab.h
1702 //#include "stab.h"
1703 //---------------------------------------------------------------------------
1704 #ifndef __GNU_STAB__
1705
1706 /* Indicate the GNU stab.h is in use.  */
1707
1708 #define __GNU_STAB__
1709
1710 #define __define_stab(NAME, CODE, STRING) NAME=CODE,
1711
1712 enum __stab_debug_code
1713 {
1714 // njn: inlined stab.def
1715 //#include "stab.def"
1716 //---------------------------------------------------------------------------
1717 /* Table of DBX symbol codes for the GNU system.
1718    Copyright (C) 1988, 1997 Free Software Foundation, Inc.
1719    This file is part of the GNU C Library.
1720
1721    The GNU C Library is free software; you can redistribute it and/or
1722    modify it under the terms of the GNU Library General Public License as
1723    published by the Free Software Foundation; either version 2 of the
1724    License, or (at your option) any later version.
1725
1726    The GNU C Library is distributed in the hope that it will be useful,
1727    but WITHOUT ANY WARRANTY; without even the implied warranty of
1728    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1729    Library General Public License for more details.
1730
1731    You should have received a copy of the GNU Library General Public
1732    License along with the GNU C Library; see the file COPYING.LIB.  If not,
1733    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1734    Boston, MA 02111-1307, USA.  */
1735
1736 /* This contains contribution from Cygnus Support.  */
1737 \f
1738 /* Global variable.  Only the name is significant.
1739    To find the address, look in the corresponding external symbol.  */
1740 __define_stab (N_GSYM, 0x20, "GSYM")
1741
1742 /* Function name for BSD Fortran.  Only the name is significant.
1743    To find the address, look in the corresponding external symbol.  */
1744 __define_stab (N_FNAME, 0x22, "FNAME")
1745
1746 /* Function name or text-segment variable for C.  Value is its address.
1747    Desc is supposedly starting line number, but GCC doesn't set it
1748    and DBX seems not to miss it.  */
1749 __define_stab (N_FUN, 0x24, "FUN")
1750
1751 /* Data-segment variable with internal linkage.  Value is its address.
1752    "Static Sym".  */
1753 __define_stab (N_STSYM, 0x26, "STSYM")
1754
1755 /* BSS-segment variable with internal linkage.  Value is its address.  */
1756 __define_stab (N_LCSYM, 0x28, "LCSYM")
1757
1758 /* Name of main routine.  Only the name is significant.
1759    This is not used in C.  */
1760 __define_stab (N_MAIN, 0x2a, "MAIN")
1761
1762 /* Global symbol in Pascal.
1763    Supposedly the value is its line number; I'm skeptical.  */
1764 __define_stab (N_PC, 0x30, "PC")
1765
1766 /* Number of symbols:  0, files,,funcs,lines according to Ultrix V4.0. */
1767 __define_stab (N_NSYMS, 0x32, "NSYMS")
1768
1769 /* "No DST map for sym: name, ,0,type,ignored"  according to Ultrix V4.0. */
1770 __define_stab (N_NOMAP, 0x34, "NOMAP")
1771
1772 /* New stab from Solaris.  I don't know what it means, but it
1773    don't seem to contain useful information.  */
1774 __define_stab (N_OBJ, 0x38, "OBJ")
1775
1776 /* New stab from Solaris.  I don't know what it means, but it
1777    don't seem to contain useful information.  Possibly related to the
1778    optimization flags used in this module.  */
1779 __define_stab (N_OPT, 0x3c, "OPT")
1780
1781 /* Register variable.  Value is number of register.  */
1782 __define_stab (N_RSYM, 0x40, "RSYM")
1783
1784 /* Modula-2 compilation unit.  Can someone say what info it contains?  */
1785 __define_stab (N_M2C, 0x42, "M2C")
1786
1787 /* Line number in text segment.  Desc is the line number;
1788    value is corresponding address.  */
1789 __define_stab (N_SLINE, 0x44, "SLINE")
1790
1791 /* Similar, for data segment.  */
1792 __define_stab (N_DSLINE, 0x46, "DSLINE")
1793
1794 /* Similar, for bss segment.  */
1795 __define_stab (N_BSLINE, 0x48, "BSLINE")
1796
1797 /* Sun's source-code browser stabs.  ?? Don't know what the fields are.
1798    Supposedly the field is "path to associated .cb file".  THIS VALUE
1799    OVERLAPS WITH N_BSLINE!  */
1800 __define_stab (N_BROWS, 0x48, "BROWS")
1801
1802 /* GNU Modula-2 definition module dependency.  Value is the modification time
1803    of the definition file.  Other is non-zero if it is imported with the
1804    GNU M2 keyword %INITIALIZE.  Perhaps N_M2C can be used if there
1805    are enough empty fields? */
1806 __define_stab(N_DEFD, 0x4a, "DEFD")
1807
1808 /* THE FOLLOWING TWO STAB VALUES CONFLICT.  Happily, one is for Modula-2
1809    and one is for C++.   Still,... */
1810 /* GNU C++ exception variable.  Name is variable name.  */
1811 __define_stab (N_EHDECL, 0x50, "EHDECL")
1812 /* Modula2 info "for imc":  name,,0,0,0  according to Ultrix V4.0.  */
1813 __define_stab (N_MOD2, 0x50, "MOD2")
1814
1815 /* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
1816    this entry is immediately followed by a CAUGHT stab saying what exception
1817    was caught.  Multiple CAUGHT stabs means that multiple exceptions
1818    can be caught here.  If Desc is 0, it means all exceptions are caught
1819    here.  */
1820 __define_stab (N_CATCH, 0x54, "CATCH")
1821
1822 /* Structure or union element.  Value is offset in the structure.  */
1823 __define_stab (N_SSYM, 0x60, "SSYM")
1824
1825 /* Name of main source file.
1826    Value is starting text address of the compilation.  */
1827 __define_stab (N_SO, 0x64, "SO")
1828
1829 /* Automatic variable in the stack.  Value is offset from frame pointer.
1830    Also used for type descriptions.  */
1831 __define_stab (N_LSYM, 0x80, "LSYM")
1832
1833 /* Beginning of an include file.  Only Sun uses this.
1834    In an object file, only the name is significant.
1835    The Sun linker puts data into some of the other fields.  */
1836 __define_stab (N_BINCL, 0x82, "BINCL")
1837
1838 /* Name of sub-source file (#include file).
1839    Value is starting text address of the compilation.  */
1840 __define_stab (N_SOL, 0x84, "SOL")
1841
1842 /* Parameter variable.  Value is offset from argument pointer.
1843    (On most machines the argument pointer is the same as the frame pointer.  */
1844 __define_stab (N_PSYM, 0xa0, "PSYM")
1845
1846 /* End of an include file.  No name.
1847    This and N_BINCL act as brackets around the file's output.
1848    In an object file, there is no significant data in this entry.
1849    The Sun linker puts data into some of the fields.  */
1850 __define_stab (N_EINCL, 0xa2, "EINCL")
1851
1852 /* Alternate entry point.  Value is its address.  */
1853 __define_stab (N_ENTRY, 0xa4, "ENTRY")
1854
1855 /* Beginning of lexical block.
1856    The desc is the nesting level in lexical blocks.
1857    The value is the address of the start of the text for the block.
1858    The variables declared inside the block *precede* the N_LBRAC symbol.  */
1859 __define_stab (N_LBRAC, 0xc0, "LBRAC")
1860
1861 /* Place holder for deleted include file.  Replaces a N_BINCL and everything
1862    up to the corresponding N_EINCL.  The Sun linker generates these when
1863    it finds multiple identical copies of the symbols from an include file.
1864    This appears only in output from the Sun linker.  */
1865 __define_stab (N_EXCL, 0xc2, "EXCL")
1866
1867 /* Modula-2 scope information.  Can someone say what info it contains?  */
1868 __define_stab (N_SCOPE, 0xc4, "SCOPE")
1869
1870 /* End of a lexical block.  Desc matches the N_LBRAC's desc.
1871    The value is the address of the end of the text for the block.  */
1872 __define_stab (N_RBRAC, 0xe0, "RBRAC")
1873
1874 /* Begin named common block.  Only the name is significant.  */
1875 __define_stab (N_BCOMM, 0xe2, "BCOMM")
1876
1877 /* End named common block.  Only the name is significant
1878    (and it should match the N_BCOMM).  */
1879 __define_stab (N_ECOMM, 0xe4, "ECOMM")
1880
1881 /* End common (local name): value is address.
1882    I'm not sure how this is used.  */
1883 __define_stab (N_ECOML, 0xe8, "ECOML")
1884
1885 /* These STAB's are used on Gould systems for Non-Base register symbols
1886    or something like that.  FIXME.  I have assigned the values at random
1887    since I don't have a Gould here.  Fixups from Gould folk welcome... */
1888 __define_stab (N_NBTEXT, 0xF0, "NBTEXT")
1889 __define_stab (N_NBDATA, 0xF2, "NBDATA")
1890 __define_stab (N_NBBSS,  0xF4, "NBBSS")
1891 __define_stab (N_NBSTS,  0xF6, "NBSTS")
1892 __define_stab (N_NBLCS,  0xF8, "NBLCS")
1893
1894 /* Second symbol entry containing a length-value for the preceding entry.
1895    The value is the length.  */
1896 __define_stab (N_LENG, 0xfe, "LENG")
1897 \f
1898 /* The above information, in matrix format.
1899
1900                         STAB MATRIX
1901         _________________________________________________
1902         | 00 - 1F are not dbx stab symbols              |
1903         | In most cases, the low bit is the EXTernal bit|
1904
1905         | 00 UNDEF  | 02 ABS    | 04 TEXT   | 06 DATA   |
1906         | 01  |EXT  | 03  |EXT  | 05  |EXT  | 07  |EXT  |
1907
1908         | 08 BSS    | 0A INDR   | 0C FN_SEQ | 0E        |
1909         | 09  |EXT  | 0B        | 0D        | 0F        |
1910
1911         | 10        | 12 COMM   | 14 SETA   | 16 SETT   |
1912         | 11        | 13        | 15        | 17        |
1913
1914         | 18 SETD   | 1A SETB   | 1C SETV   | 1E WARNING|
1915         | 19        | 1B        | 1D        | 1F FN     |
1916
1917         |_______________________________________________|
1918         | Debug entries with bit 01 set are unused.     |
1919         | 20 GSYM   | 22 FNAME  | 24 FUN    | 26 STSYM  |
1920         | 28 LCSYM  | 2A MAIN   | 2C        | 2E        |
1921         | 30 PC     | 32 NSYMS  | 34 NOMAP  | 36        |
1922         | 38 OBJ    | 3A        | 3C OPT    | 3E        |
1923         | 40 RSYM   | 42 M2C    | 44 SLINE  | 46 DSLINE |
1924         | 48 BSLINE*| 4A DEFD   | 4C        | 4E        |
1925         | 50 EHDECL*| 52        | 54 CATCH  | 56        |
1926         | 58        | 5A        | 5C        | 5E        |
1927         | 60 SSYM   | 62        | 64 SO     | 66        |
1928         | 68        | 6A        | 6C        | 6E        |
1929         | 70        | 72        | 74        | 76        |
1930         | 78        | 7A        | 7C        | 7E        |
1931         | 80 LSYM   | 82 BINCL  | 84 SOL    | 86        |
1932         | 88        | 8A        | 8C        | 8E        |
1933         | 90        | 92        | 94        | 96        |
1934         | 98        | 9A        | 9C        | 9E        |
1935         | A0 PSYM   | A2 EINCL  | A4 ENTRY  | A6        |
1936         | A8        | AA        | AC        | AE        |
1937         | B0        | B2        | B4        | B6        |
1938         | B8        | BA        | BC        | BE        |
1939         | C0 LBRAC  | C2 EXCL   | C4 SCOPE  | C6        |
1940         | C8        | CA        | CC        | CE        |
1941         | D0        | D2        | D4        | D6        |
1942         | D8        | DA        | DC        | DE        |
1943         | E0 RBRAC  | E2 BCOMM  | E4 ECOMM  | E6        |
1944         | E8 ECOML  | EA        | EC        | EE        |
1945         | F0        | F2        | F4        | F6        |
1946         | F8        | FA        | FC        | FE LENG   |
1947         +-----------------------------------------------+
1948  * 50 EHDECL is also MOD2.
1949  * 48 BSLINE is also BROWS.
1950  */
1951 //---------------------------------------------------------------------------
1952 LAST_UNUSED_STAB_CODE
1953 };
1954
1955 #undef __define_stab
1956
1957 #endif /* __GNU_STAB_ */
1958 //---------------------------------------------------------------------------
1959
1960 #ifndef O_BINARY
1961 #define O_BINARY 0
1962 #endif
1963
1964 // njn: inlined libtcc.h
1965 //#include "libtcc.h"
1966 //---------------------------------------------------------------------------
1967 #ifndef LIBTCC_H
1968 #define LIBTCC_H
1969
1970 #ifdef __cplusplus
1971 extern "C" {
1972 #endif
1973
1974 struct TCCState;
1975
1976 typedef struct TCCState TCCState;
1977
1978 /* create a new TCC compilation context */
1979 TCCState *tcc_new(void);
1980
1981 /* free a TCC compilation context */
1982 void tcc_delete(TCCState *s);
1983
1984 /* add debug information in the generated code */
1985 void tcc_enable_debug(TCCState *s);
1986
1987 /* set error/warning display callback */
1988 void tcc_set_error_func(TCCState *s, void *error_opaque,
1989                         void (*error_func)(void *opaque, const char *msg));
1990
1991 /* set/reset a warning */
1992 int tcc_set_warning(TCCState *s, const char *warning_name, int value);
1993
1994 /*****************************/
1995 /* preprocessor */
1996
1997 /* add include path */
1998 int tcc_add_include_path(TCCState *s, const char *pathname);
1999
2000 /* add in system include path */
2001 int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
2002
2003 /* define preprocessor symbol 'sym'. Can put optional value */
2004 void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
2005
2006 /* undefine preprocess symbol 'sym' */
2007 void tcc_undefine_symbol(TCCState *s, const char *sym);
2008
2009 /*****************************/
2010 /* compiling */
2011
2012 /* add a file (either a C file, dll, an object, a library or an ld
2013    script). Return -1 if error. */
2014 int tcc_add_file(TCCState *s, const char *filename);
2015
2016 /* compile a string containing a C source. Return non zero if
2017    error. */
2018 int tcc_compile_string(TCCState *s, const char *buf);
2019
2020 /*****************************/
2021 /* linking commands */
2022
2023 /* set output type. MUST BE CALLED before any compilation */
2024 #define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
2025                                  output file) (default) */
2026 #define TCC_OUTPUT_EXE      1 /* executable file */
2027 #define TCC_OUTPUT_DLL      2 /* dynamic library */
2028 #define TCC_OUTPUT_OBJ      3 /* object file */
2029 int tcc_set_output_type(TCCState *s, int output_type);
2030
2031 #define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
2032 #define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
2033 #define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
2034
2035 /* equivalent to -Lpath option */
2036 int tcc_add_library_path(TCCState *s, const char *pathname);
2037
2038 /* the library name is the same as the argument of the '-l' option */
2039 int tcc_add_library(TCCState *s, const char *libraryname);
2040
2041 /* add a symbol to the compiled program */
2042 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
2043
2044 /* output an executable, library or object file. DO NOT call
2045    tcc_relocate() before. */
2046 int tcc_output_file(TCCState *s, const char *filename);
2047
2048 /* link and run main() function and return its value. DO NOT call
2049    tcc_relocate() before. */
2050 int tcc_run(TCCState *s, int argc, char **argv);
2051
2052 /* do all relocations (needed before using tcc_get_symbol()). Return
2053    non zero if link error. */
2054 int tcc_relocate(TCCState *s);
2055
2056 /* return symbol value. return 0 if OK, -1 if symbol not found */
2057 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
2058
2059 #ifdef __cplusplus
2060 }
2061 #endif
2062
2063 #endif
2064 //---------------------------------------------------------------------------
2065
2066 /* parser debug */
2067 //#define PARSE_DEBUG
2068 /* preprocessor debug */
2069 //#define PP_DEBUG
2070 /* include file debug */
2071 //#define INC_DEBUG
2072
2073 //#define MEM_DEBUG
2074
2075 /* assembler debug */
2076 //#define ASM_DEBUG
2077
2078 /* target selection */
2079 //#define TCC_TARGET_I386   /* i386 code generator */
2080 //#define TCC_TARGET_ARM    /* ARMv4 code generator */
2081 //#define TCC_TARGET_C67    /* TMS320C67xx code generator */
2082
2083 /* default target is I386 */
2084 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
2085     !defined(TCC_TARGET_C67)
2086 #define TCC_TARGET_I386
2087 #endif
2088
2089 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
2090     !defined(TCC_TARGET_C67)
2091 #define CONFIG_TCC_BCHECK /* enable bound checking code */
2092 #endif
2093
2094 #if defined(WIN32) && !defined(TCC_TARGET_PE)
2095 #define CONFIG_TCC_STATIC
2096 #endif
2097
2098 /* define it to include assembler support */
2099 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
2100 #define CONFIG_TCC_ASM
2101 #endif
2102
2103 /* object format selection */
2104 #if defined(TCC_TARGET_C67)
2105 #define TCC_TARGET_COFF
2106 #endif
2107
2108 #define FALSE 0
2109 #define false 0
2110 #define TRUE 1
2111 #define true 1
2112 typedef int BOOL;
2113
2114 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
2115    executables or dlls */
2116 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
2117
2118 #define INCLUDE_STACK_SIZE  32
2119 #define IFDEF_STACK_SIZE    64
2120 #define VSTACK_SIZE         256
2121 #define STRING_MAX_SIZE     1024
2122 #define PACK_STACK_SIZE     8
2123
2124 #define TOK_HASH_SIZE       8192 /* must be a power of two */
2125 #define TOK_ALLOC_INCR      512  /* must be a power of two */
2126 #define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
2127
2128 /* token symbol management */
2129 typedef struct TokenSym {
2130     struct TokenSym *hash_next;
2131     struct Sym *sym_define; /* direct pointer to define */
2132     struct Sym *sym_label; /* direct pointer to label */
2133     struct Sym *sym_struct; /* direct pointer to structure */
2134     struct Sym *sym_identifier; /* direct pointer to identifier */
2135     int tok; /* token number */
2136     int len;
2137     char str[1];
2138 } TokenSym;
2139
2140 typedef struct CString {
2141     int size; /* size in bytes */
2142     void *data; /* either 'char *' or 'int *' */
2143     int size_allocated;
2144     void *data_allocated; /* if non NULL, data has been malloced */
2145 } CString;
2146
2147 /* type definition */
2148 typedef struct CType {
2149     int t;
2150     struct Sym *ref;
2151 } CType;
2152
2153 /* constant value */
2154 typedef union CValue {
2155     long double ld;
2156     double d;
2157     float f;
2158     int i;
2159     unsigned int ui;
2160     unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
2161     long long ll;
2162     unsigned long long ull;
2163     struct CString *cstr;
2164     void *ptr;
2165     int tab[1];
2166 } CValue;
2167
2168 /* value on stack */
2169 typedef struct SValue {
2170     CType type;      /* type */
2171     unsigned short r;      /* register + flags */
2172     unsigned short r2;     /* second register, used for 'long long'
2173                               type. If not used, set to VT_CONST */
2174     CValue c;              /* constant, if VT_CONST */
2175     struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
2176 } SValue;
2177
2178 /* symbol management */
2179 typedef struct Sym {
2180     long v;    /* symbol token */
2181     long r;    /* associated register */
2182     long c;    /* associated number */
2183     CType type;    /* associated type */
2184     struct Sym *next; /* next related symbol */
2185     struct Sym *prev; /* prev symbol in stack */
2186     struct Sym *prev_tok; /* previous symbol for this token */
2187 } Sym;
2188
2189 /* section definition */
2190 /* XXX: use directly ELF structure for parameters ? */
2191 /* special flag to indicate that the section should not be linked to
2192    the other ones */
2193 #define SHF_PRIVATE 0x80000000
2194
2195 typedef struct Section {
2196     unsigned long data_offset; /* current data offset */
2197     unsigned char *data;       /* section data */
2198     unsigned long data_allocated; /* used for realloc() handling */
2199     int sh_name;             /* elf section name (only used during output) */
2200     int sh_num;              /* elf section number */
2201     int sh_type;             /* elf section type */
2202     int sh_flags;            /* elf section flags */
2203     int sh_info;             /* elf section info */
2204     int sh_addralign;        /* elf section alignment */
2205     int sh_entsize;          /* elf entry size */
2206     unsigned long sh_size;   /* section size (only used during output) */
2207     unsigned long sh_addr;      /* address at which the section is relocated */
2208     unsigned long sh_offset;      /* address at which the section is relocated */
2209     int nb_hashed_syms;      /* used to resize the hash table */
2210     struct Section *link;    /* link to another section */
2211     struct Section *reloc;   /* corresponding section for relocation, if any */
2212     struct Section *hash;     /* hash table for symbols */
2213     struct Section *next;
2214     char name[1];           /* section name */
2215 } Section;
2216
2217 typedef struct DLLReference {
2218     int level;
2219     char name[1];
2220 } DLLReference;
2221
2222 /* GNUC attribute definition */
2223 typedef struct AttributeDef {
2224     int aligned;
2225     int packed; 
2226     Section *section;
2227     unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
2228     unsigned char dllexport; 
2229 } AttributeDef;
2230
2231 #define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
2232 #define SYM_FIELD      0x20000000 /* struct/union field symbol space */
2233 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
2234
2235 /* stored in 'Sym.c' field */
2236 #define FUNC_NEW       1 /* ansi function prototype */
2237 #define FUNC_OLD       2 /* old function prototype */
2238 #define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
2239
2240 /* stored in 'Sym.r' field */
2241 #define FUNC_CDECL     0 /* standard c call */
2242 #define FUNC_STDCALL   1 /* pascal c call */
2243 #define FUNC_FASTCALL1 2 /* first param in %eax */
2244 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
2245 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
2246
2247 /* field 'Sym.t' for macros */
2248 #define MACRO_OBJ      0 /* object like macro */
2249 #define MACRO_FUNC     1 /* function like macro */
2250
2251 /* field 'Sym.r' for C labels */
2252 #define LABEL_DEFINED  0 /* label is defined */
2253 #define LABEL_FORWARD  1 /* label is forward defined */
2254 #define LABEL_DECLARED 2 /* label is declared but never used */
2255
2256 /* type_decl() types */
2257 #define TYPE_ABSTRACT  1 /* type without variable */
2258 #define TYPE_DIRECT    2 /* type with variable */
2259
2260 #define IO_BUF_SIZE 8192
2261
2262 typedef struct BufferedFile {
2263     uint8_t *buf_ptr;
2264     uint8_t *buf_end;
2265     int fd;
2266     int line_num;    /* current line number - here to simplify code */
2267     int ifndef_macro;  /* #ifndef macro / #endif search */
2268     int ifndef_macro_saved; /* saved ifndef_macro */
2269     int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
2270     char inc_type;          /* type of include */
2271     char inc_filename[512]; /* filename specified by the user */
2272     char filename[1024];    /* current filename - here to simplify code */
2273     unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
2274 } BufferedFile;
2275
2276 #define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
2277 #define CH_EOF   (-1)   /* end of file */
2278
2279 /* parsing state (used to save parser state to reparse part of the
2280    source several times) */
2281 typedef struct ParseState {
2282     int *macro_ptr;
2283     int line_num;
2284     int tok;
2285     CValue tokc;
2286 } ParseState;
2287
2288 /* used to record tokens */
2289 typedef struct TokenString {
2290     int *str;
2291     int len;
2292     int allocated_len;
2293     int last_line_num;
2294 } TokenString;
2295
2296 /* include file cache, used to find files faster and also to eliminate
2297    inclusion if the include file is protected by #ifndef ... #endif */
2298 typedef struct CachedInclude {
2299     int ifndef_macro;
2300     int hash_next; /* -1 if none */
2301     char type; /* '"' or '>' to give include type */
2302     char filename[1]; /* path specified in #include */
2303 } CachedInclude;
2304
2305 #define CACHED_INCLUDES_HASH_SIZE 512
2306
2307 /* parser */
2308 static struct BufferedFile *file;
2309 static int ch, tok;
2310 static CValue tokc;
2311 static CString tokcstr; /* current parsed string, if any */
2312 /* additional informations about token */
2313 static int tok_flags;
2314 #define TOK_FLAG_BOL   0x0001 /* beginning of line before */
2315 #define TOK_FLAG_BOF   0x0002 /* beginning of file before */
2316 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
2317
2318 static int *macro_ptr, *macro_ptr_allocated;
2319 static int *unget_saved_macro_ptr;
2320 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
2321 static int unget_buffer_enabled;
2322 static int parse_flags;
2323 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
2324 #define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
2325 #define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
2326                                         token. line feed is also
2327                                         returned at eof */
2328 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
2329  
2330 static Section *text_section, *data_section, *bss_section; /* predefined sections */
2331 static Section *cur_text_section; /* current section where function code is
2332                               generated */
2333 #ifdef CONFIG_TCC_ASM
2334 static Section *last_text_section; /* to handle .previous asm directive */
2335 #endif
2336 /* bound check related sections */
2337 static Section *bounds_section; /* contains global data bound description */
2338 static Section *lbounds_section; /* contains local data bound description */
2339 /* symbol sections */
2340 static Section *symtab_section, *strtab_section;
2341
2342 /* debug sections */
2343 static Section *stab_section, *stabstr_section;
2344
2345 /* loc : local variable index
2346    ind : output code index
2347    rsym: return symbol
2348    anon_sym: anonymous symbol index
2349 */
2350 static long rsym, anon_sym, ind, loc;
2351 /* expression generation modifiers */
2352 static int const_wanted; /* true if constant wanted */
2353 static int nocode_wanted; /* true if no code generation wanted for an expression */
2354 static int global_expr;  /* true if compound literals must be allocated
2355                             globally (used during initializers parsing */
2356 static CType func_vt; /* current function return type (used by return
2357                          instruction) */
2358 static int func_vc;
2359 static long last_line_num, last_ind, func_ind; /* debug last line number and pc */
2360 static int tok_ident;
2361 static TokenSym **table_ident;
2362 static TokenSym *hash_ident[TOK_HASH_SIZE];
2363 static char token_buf[STRING_MAX_SIZE + 1];
2364 static char *funcname;
2365 static Sym *global_stack, *local_stack;
2366 static Sym *define_stack;
2367 static Sym *global_label_stack, *local_label_stack;
2368 /* symbol allocator */
2369 #define SYM_POOL_NB (8192 / sizeof(Sym))
2370 static Sym *sym_free_first;
2371
2372 static SValue vstack[VSTACK_SIZE], *vtop;
2373 /* some predefined types */
2374 static CType char_pointer_type, func_old_type, int_type;
2375 /* true if isid(c) || isnum(c) */
2376 static unsigned char isidnum_table[256];
2377
2378 /* compile with debug symbol (and use them if error during execution) */
2379 static int do_debug = 0;
2380
2381 /* compile with built-in memory and bounds checker */
2382 static int do_bounds_check = 0;
2383
2384 /* display benchmark infos */
2385 #if !defined(LIBTCC)
2386 static int do_bench = 0;
2387 #endif
2388 static int total_lines;
2389 static int total_bytes;
2390
2391 /* use GNU C extensions */
2392 static int gnu_ext = 1;
2393
2394 /* use Tiny C extensions */
2395 static int tcc_ext = 1;
2396
2397 /* max number of callers shown if error */
2398 static int num_callers = 6;
2399 static const char **rt_bound_error_msg;
2400
2401 /* XXX: get rid of this ASAP */
2402 static struct TCCState *tcc_state;
2403
2404 /* give the path of the tcc libraries */
2405 static const char *tcc_lib_path = CONFIG_TCCDIR;
2406
2407 struct TCCState {
2408     int output_type;
2409  
2410     BufferedFile **include_stack_ptr;
2411     int *ifdef_stack_ptr;
2412
2413     /* include file handling */
2414     char **include_paths;
2415     int nb_include_paths;
2416     char **sysinclude_paths;
2417     int nb_sysinclude_paths;
2418     CachedInclude **cached_includes;
2419     int nb_cached_includes;
2420
2421     char **library_paths;
2422     int nb_library_paths;
2423
2424     /* array of all loaded dlls (including those referenced by loaded
2425        dlls) */
2426     DLLReference **loaded_dlls;
2427     int nb_loaded_dlls;
2428
2429     /* sections */
2430     Section **sections;
2431     int nb_sections; /* number of sections, including first dummy section */
2432
2433     /* got handling */
2434     Section *got;
2435     Section *plt;
2436     unsigned long *got_offsets;
2437     int nb_got_offsets;
2438     /* give the correspondance from symtab indexes to dynsym indexes */
2439     int *symtab_to_dynsym;
2440
2441     /* temporary dynamic symbol sections (for dll loading) */
2442     Section *dynsymtab_section;
2443     /* exported dynamic symbol section */
2444     Section *dynsym;
2445
2446     int nostdinc; /* if true, no standard headers are added */
2447     int nostdlib; /* if true, no standard libraries are added */
2448
2449     int nocommon; /* if true, do not use common symbols for .bss data */
2450
2451     /* if true, static linking is performed */
2452     int static_link;
2453
2454     /* if true, all symbols are exported */
2455     int rdynamic;
2456
2457     /* if true, only link in referenced objects from archive */
2458     int alacarte_link;
2459
2460     /* address of text section */
2461     unsigned long text_addr;
2462     int has_text_addr;
2463     
2464     /* output format, see TCC_OUTPUT_FORMAT_xxx */
2465     int output_format;
2466
2467     /* C language options */
2468     int char_is_unsigned;
2469     int leading_underscore;
2470     
2471     /* warning switches */
2472     int warn_write_strings;
2473     int warn_unsupported;
2474     int warn_error;
2475     int warn_none;
2476     int warn_implicit_function_declaration;
2477
2478     /* error handling */
2479     void *error_opaque;
2480     void (*error_func)(void *opaque, const char *msg);
2481     int error_set_jmp_enabled;
2482     jmp_buf error_jmp_buf;
2483     int nb_errors;
2484
2485     /* tiny assembler state */
2486     Sym *asm_labels;
2487
2488     /* see include_stack_ptr */
2489     BufferedFile *include_stack[INCLUDE_STACK_SIZE];
2490
2491     /* see ifdef_stack_ptr */
2492     int ifdef_stack[IFDEF_STACK_SIZE];
2493
2494     /* see cached_includes */
2495     int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
2496
2497     /* pack stack */
2498     int pack_stack[PACK_STACK_SIZE];
2499     int *pack_stack_ptr;
2500 };
2501
2502 /* The current value can be: */
2503 #define VT_VALMASK   0x00ff
2504 #define VT_CONST     0x00f0  /* constant in vc 
2505                               (must be first non register value) */
2506 #define VT_LLOCAL    0x00f1  /* lvalue, offset on stack */
2507 #define VT_LOCAL     0x00f2  /* offset on stack */
2508 #define VT_CMP       0x00f3  /* the value is stored in processor flags (in vc) */
2509 #define VT_JMP       0x00f4  /* value is the consequence of jmp true (even) */
2510 #define VT_JMPI      0x00f5  /* value is the consequence of jmp false (odd) */
2511 #define VT_LVAL      0x0100  /* var is an lvalue */
2512 #define VT_SYM       0x0200  /* a symbol value is added */
2513 #define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
2514                                 char/short stored in integer registers) */
2515 #define VT_MUSTBOUND 0x0800  /* bound checking must be done before
2516                                 dereferencing value */
2517 #define VT_BOUNDED   0x8000  /* value is bounded. The address of the
2518                                 bounding function call point is in vc */
2519 #define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
2520 #define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
2521 #define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
2522 #define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
2523
2524 /* types */
2525 #define VT_INT        0  /* integer type */
2526 #define VT_BYTE       1  /* signed byte type */
2527 #define VT_SHORT      2  /* short type */
2528 #define VT_VOID       3  /* void type */
2529 #define VT_PTR        4  /* pointer */
2530 #define VT_ENUM       5  /* enum definition */
2531 #define VT_FUNC       6  /* function type */
2532 #define VT_STRUCT     7  /* struct/union definition */
2533 #define VT_FLOAT      8  /* IEEE float */
2534 #define VT_DOUBLE     9  /* IEEE double */
2535 #define VT_LDOUBLE   10  /* IEEE long double */
2536 #define VT_BOOL      11  /* ISOC99 boolean type */
2537 #define VT_LLONG     12  /* 64 bit integer */
2538 #define VT_LONG      13  /* long integer (NEVER USED as type, only
2539                             during parsing) */
2540 #define VT_BTYPE      0x000f /* mask for basic type */
2541 #define VT_UNSIGNED   0x0010  /* unsigned type */
2542 #define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
2543 #define VT_BITFIELD   0x0040  /* bitfield modifier */
2544 #define VT_CONSTANT   0x0800  /* const modifier */
2545 #define VT_VOLATILE   0x1000  /* volatile modifier */
2546 #define VT_SIGNED     0x2000  /* signed type */
2547
2548 /* storage */
2549 #define VT_EXTERN  0x00000080  /* extern definition */
2550 #define VT_STATIC  0x00000100  /* static variable */
2551 #define VT_TYPEDEF 0x00000200  /* typedef definition */
2552 #define VT_INLINE  0x00000400  /* inline definition */
2553
2554 #define VT_STRUCT_SHIFT 16   /* shift for bitfield shift values */
2555
2556 /* type mask (except storage) */
2557 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
2558 #define VT_TYPE    (~(VT_STORAGE))
2559
2560 /* token values */
2561
2562 /* warning: the following compare tokens depend on i386 asm code */
2563 #define TOK_ULT 0x92
2564 #define TOK_UGE 0x93
2565 #define TOK_EQ  0x94
2566 #define TOK_NE  0x95
2567 #define TOK_ULE 0x96
2568 #define TOK_UGT 0x97
2569 #define TOK_LT  0x9c
2570 #define TOK_GE  0x9d
2571 #define TOK_LE  0x9e
2572 #define TOK_GT  0x9f
2573
2574 #define TOK_LAND  0xa0
2575 #define TOK_LOR   0xa1
2576
2577 #define TOK_DEC   0xa2
2578 #define TOK_MID   0xa3 /* inc/dec, to void constant */
2579 #define TOK_INC   0xa4
2580 #define TOK_UDIV  0xb0 /* unsigned division */
2581 #define TOK_UMOD  0xb1 /* unsigned modulo */
2582 #define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
2583 #define TOK_CINT   0xb3 /* number in tokc */
2584 #define TOK_CCHAR 0xb4 /* char constant in tokc */
2585 #define TOK_STR   0xb5 /* pointer to string in tokc */
2586 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
2587 #define TOK_LCHAR    0xb7
2588 #define TOK_LSTR     0xb8
2589 #define TOK_CFLOAT   0xb9 /* float constant */
2590 #define TOK_LINENUM  0xba /* line number info */
2591 #define TOK_CDOUBLE  0xc0 /* double constant */
2592 #define TOK_CLDOUBLE 0xc1 /* long double constant */
2593 #define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
2594 #define TOK_ADDC1    0xc3 /* add with carry generation */
2595 #define TOK_ADDC2    0xc4 /* add with carry use */
2596 #define TOK_SUBC1    0xc5 /* add with carry generation */
2597 #define TOK_SUBC2    0xc6 /* add with carry use */
2598 #define TOK_CUINT    0xc8 /* unsigned int constant */
2599 #define TOK_CLLONG   0xc9 /* long long constant */
2600 #define TOK_CULLONG  0xca /* unsigned long long constant */
2601 #define TOK_ARROW    0xcb
2602 #define TOK_DOTS     0xcc /* three dots */
2603 #define TOK_SHR      0xcd /* unsigned shift right */
2604 #define TOK_PPNUM    0xce /* preprocessor number */
2605
2606 #define TOK_SHL   0x01 /* shift left */
2607 #define TOK_SAR   0x02 /* signed shift right */
2608   
2609 /* assignement operators : normal operator or 0x80 */
2610 #define TOK_A_MOD 0xa5
2611 #define TOK_A_AND 0xa6
2612 #define TOK_A_MUL 0xaa
2613 #define TOK_A_ADD 0xab
2614 #define TOK_A_SUB 0xad
2615 #define TOK_A_DIV 0xaf
2616 #define TOK_A_XOR 0xde
2617 #define TOK_A_OR  0xfc
2618 #define TOK_A_SHL 0x81
2619 #define TOK_A_SAR 0x82
2620
2621 #ifndef offsetof
2622 #define offsetof(type, field) ((size_t) &((type *)0)->field)
2623 #endif
2624
2625 #ifndef countof
2626 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
2627 #endif
2628
2629 /* WARNING: the content of this string encodes token numbers */
2630 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2631
2632 #define TOK_EOF       (-1)  /* end of file */
2633 #define TOK_LINEFEED  10    /* line feed */
2634
2635 /* all identificators and strings have token above that */
2636 #define TOK_IDENT 256
2637
2638 /* only used for i386 asm opcodes definitions */
2639 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
2640
2641 #define DEF_BWL(x) \
2642  DEF(TOK_ASM_ ## x ## b, #x "b") \
2643  DEF(TOK_ASM_ ## x ## w, #x "w") \
2644  DEF(TOK_ASM_ ## x ## l, #x "l") \
2645  DEF(TOK_ASM_ ## x, #x)
2646
2647 #define DEF_WL(x) \
2648  DEF(TOK_ASM_ ## x ## w, #x "w") \
2649  DEF(TOK_ASM_ ## x ## l, #x "l") \
2650  DEF(TOK_ASM_ ## x, #x)
2651
2652 #define DEF_FP1(x) \
2653  DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
2654  DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
2655  DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
2656  DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
2657
2658 #define DEF_FP(x) \
2659  DEF(TOK_ASM_ ## f ## x, "f" #x ) \
2660  DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
2661  DEF_FP1(x)
2662
2663 #define DEF_ASMTEST(x) \
2664  DEF_ASM(x ## o) \
2665  DEF_ASM(x ## no) \
2666  DEF_ASM(x ## b) \
2667  DEF_ASM(x ## c) \
2668  DEF_ASM(x ## nae) \
2669  DEF_ASM(x ## nb) \
2670  DEF_ASM(x ## nc) \
2671  DEF_ASM(x ## ae) \
2672  DEF_ASM(x ## e) \
2673  DEF_ASM(x ## z) \
2674  DEF_ASM(x ## ne) \
2675  DEF_ASM(x ## nz) \
2676  DEF_ASM(x ## be) \
2677  DEF_ASM(x ## na) \
2678  DEF_ASM(x ## nbe) \
2679  DEF_ASM(x ## a) \
2680  DEF_ASM(x ## s) \
2681  DEF_ASM(x ## ns) \
2682  DEF_ASM(x ## p) \
2683  DEF_ASM(x ## pe) \
2684  DEF_ASM(x ## np) \
2685  DEF_ASM(x ## po) \
2686  DEF_ASM(x ## l) \
2687  DEF_ASM(x ## nge) \
2688  DEF_ASM(x ## nl) \
2689  DEF_ASM(x ## ge) \
2690  DEF_ASM(x ## le) \
2691  DEF_ASM(x ## ng) \
2692  DEF_ASM(x ## nle) \
2693  DEF_ASM(x ## g)
2694
2695 #define TOK_ASM_int TOK_INT
2696
2697 enum tcc_token {
2698     TOK_LAST = TOK_IDENT - 1,
2699 #define DEF(id, str) id,
2700 // njn: inlined tcctok.h
2701 //#include "tcctok.h"
2702 //---------------------------------------------------------------------------
2703 /* keywords */
2704      DEF(TOK_INT, "int")
2705      DEF(TOK_VOID, "void")
2706      DEF(TOK_CHAR, "char")
2707      DEF(TOK_IF, "if")
2708      DEF(TOK_ELSE, "else")
2709      DEF(TOK_WHILE, "while")
2710      DEF(TOK_BREAK, "break")
2711      DEF(TOK_RETURN, "return")
2712      DEF(TOK_FOR, "for")
2713      DEF(TOK_EXTERN, "extern")
2714      DEF(TOK_STATIC, "static")
2715      DEF(TOK_UNSIGNED, "unsigned")
2716      DEF(TOK_GOTO, "goto")
2717      DEF(TOK_DO, "do")
2718      DEF(TOK_CONTINUE, "continue")
2719      DEF(TOK_SWITCH, "switch")
2720      DEF(TOK_CASE, "case")
2721
2722      DEF(TOK_CONST1, "const")
2723      DEF(TOK_CONST2, "__const") /* gcc keyword */
2724      DEF(TOK_CONST3, "__const__") /* gcc keyword */
2725      DEF(TOK_VOLATILE1, "volatile")
2726      DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
2727      DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
2728      DEF(TOK_LONG, "long")
2729      DEF(TOK_REGISTER, "register")
2730      DEF(TOK_SIGNED1, "signed")
2731      DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
2732      DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
2733      DEF(TOK_AUTO, "auto")
2734      DEF(TOK_INLINE1, "inline")
2735      DEF(TOK_INLINE2, "__inline") /* gcc keyword */
2736      DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
2737      DEF(TOK_RESTRICT1, "restrict")
2738      DEF(TOK_RESTRICT2, "__restrict")
2739      DEF(TOK_RESTRICT3, "__restrict__")
2740      DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
2741      
2742      DEF(TOK_FLOAT, "float")
2743      DEF(TOK_DOUBLE, "double")
2744      DEF(TOK_BOOL, "_Bool")
2745      DEF(TOK_SHORT, "short")
2746      DEF(TOK_STRUCT, "struct")
2747      DEF(TOK_UNION, "union")
2748      DEF(TOK_TYPEDEF, "typedef")
2749      DEF(TOK_DEFAULT, "default")
2750      DEF(TOK_ENUM, "enum")
2751      DEF(TOK_SIZEOF, "sizeof")
2752      DEF(TOK_ATTRIBUTE1, "__attribute")
2753      DEF(TOK_ATTRIBUTE2, "__attribute__")
2754      DEF(TOK_ALIGNOF1, "__alignof")
2755      DEF(TOK_ALIGNOF2, "__alignof__")
2756      DEF(TOK_TYPEOF1, "typeof")
2757      DEF(TOK_TYPEOF2, "__typeof")
2758      DEF(TOK_TYPEOF3, "__typeof__")
2759      DEF(TOK_LABEL, "__label__")
2760      DEF(TOK_ASM1, "asm")
2761      DEF(TOK_ASM2, "__asm")
2762      DEF(TOK_ASM3, "__asm__")
2763
2764 /*********************************************************************/
2765 /* the following are not keywords. They are included to ease parsing */
2766 /* preprocessor only */
2767      DEF(TOK_DEFINE, "define")
2768      DEF(TOK_INCLUDE, "include")
2769      DEF(TOK_INCLUDE_NEXT, "include_next")
2770      DEF(TOK_IFDEF, "ifdef")
2771      DEF(TOK_IFNDEF, "ifndef")
2772      DEF(TOK_ELIF, "elif")
2773      DEF(TOK_ENDIF, "endif")
2774      DEF(TOK_DEFINED, "defined")
2775      DEF(TOK_UNDEF, "undef")
2776      DEF(TOK_ERROR, "error")
2777      DEF(TOK_WARNING, "warning")
2778      DEF(TOK_LINE, "line")
2779      DEF(TOK_PRAGMA, "pragma")
2780      DEF(TOK___LINE__, "__LINE__")
2781      DEF(TOK___FILE__, "__FILE__")
2782      DEF(TOK___DATE__, "__DATE__")
2783      DEF(TOK___TIME__, "__TIME__")
2784      DEF(TOK___FUNCTION__, "__FUNCTION__")
2785      DEF(TOK___VA_ARGS__, "__VA_ARGS__")
2786      
2787 /* special identifiers */
2788      DEF(TOK___FUNC__, "__func__")
2789      
2790 /* attribute identifiers */
2791 /* XXX: handle all tokens generically since speed is not critical */
2792      DEF(TOK_SECTION1, "section")
2793      DEF(TOK_SECTION2, "__section__")
2794      DEF(TOK_ALIGNED1, "aligned")
2795      DEF(TOK_ALIGNED2, "__aligned__")
2796      DEF(TOK_PACKED1, "packed")
2797      DEF(TOK_PACKED2, "__packed__")
2798      DEF(TOK_UNUSED1, "unused")
2799      DEF(TOK_UNUSED2, "__unused__")
2800      DEF(TOK_CDECL1, "cdecl")
2801      DEF(TOK_CDECL2, "__cdecl")
2802      DEF(TOK_CDECL3, "__cdecl__")
2803      DEF(TOK_STDCALL1, "stdcall")
2804      DEF(TOK_STDCALL2, "__stdcall")
2805      DEF(TOK_STDCALL3, "__stdcall__")
2806      DEF(TOK_DLLEXPORT, "dllexport")
2807      DEF(TOK_NORETURN1, "noreturn")
2808      DEF(TOK_NORETURN2, "__noreturn__")
2809      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
2810      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
2811      DEF(TOK_REGPARM1, "regparm")
2812      DEF(TOK_REGPARM2, "__regparm__")
2813
2814 /* pragma */
2815      DEF(TOK_pack, "pack")
2816 #if !defined(TCC_TARGET_I386)
2817      /* already defined for assembler */
2818      DEF(TOK_ASM_push, "push")
2819      DEF(TOK_ASM_pop, "pop")
2820 #endif
2821
2822 /* builtin functions or variables */
2823      DEF(TOK_memcpy, "memcpy")
2824      DEF(TOK_memset, "memset")
2825      DEF(TOK_alloca, "alloca")
2826      DEF(TOK___divdi3, "__divdi3")
2827      DEF(TOK___moddi3, "__moddi3")
2828      DEF(TOK___udivdi3, "__udivdi3")
2829      DEF(TOK___umoddi3, "__umoddi3")
2830 #if defined(TCC_TARGET_ARM)
2831      DEF(TOK___divsi3, "__divsi3")
2832      DEF(TOK___modsi3, "__modsi3")
2833      DEF(TOK___udivsi3, "__udivsi3")
2834      DEF(TOK___umodsi3, "__umodsi3")
2835      DEF(TOK___sardi3, "__ashrdi3")
2836      DEF(TOK___shrdi3, "__lshrdi3")
2837      DEF(TOK___shldi3, "__ashldi3")
2838      DEF(TOK___slltold, "__slltold")
2839      DEF(TOK___fixunssfsi, "__fixunssfsi")
2840      DEF(TOK___fixunsdfsi, "__fixunsdfsi")
2841      DEF(TOK___fixunsxfsi, "__fixunsxfsi")
2842      DEF(TOK___fixsfdi, "__fixsfdi")
2843      DEF(TOK___fixdfdi, "__fixdfdi")
2844      DEF(TOK___fixxfdi, "__fixxfdi")
2845 #elif defined(TCC_TARGET_C67)
2846      DEF(TOK__divi, "_divi")
2847      DEF(TOK__divu, "_divu")
2848      DEF(TOK__divf, "_divf")
2849      DEF(TOK__divd, "_divd")
2850      DEF(TOK__remi, "_remi")
2851      DEF(TOK__remu, "_remu")
2852      DEF(TOK___sardi3, "__sardi3")
2853      DEF(TOK___shrdi3, "__shrdi3")
2854      DEF(TOK___shldi3, "__shldi3")
2855 #else
2856      /* XXX: same names on i386 ? */
2857      DEF(TOK___sardi3, "__sardi3")
2858      DEF(TOK___shrdi3, "__shrdi3")
2859      DEF(TOK___shldi3, "__shldi3")
2860 #endif
2861      DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
2862      DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
2863      DEF(TOK___ulltof, "__ulltof")
2864      DEF(TOK___ulltod, "__ulltod")
2865      DEF(TOK___ulltold, "__ulltold")
2866      DEF(TOK___fixunssfdi, "__fixunssfdi")
2867      DEF(TOK___fixunsdfdi, "__fixunsdfdi")
2868      DEF(TOK___fixunsxfdi, "__fixunsxfdi")
2869      DEF(TOK___chkstk, "__chkstk")
2870
2871 /* bound checking symbols */
2872 #ifdef CONFIG_TCC_BCHECK
2873      DEF(TOK___bound_ptr_add, "__bound_ptr_add")
2874      DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
2875      DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
2876      DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
2877      DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
2878      DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
2879      DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
2880      DEF(TOK___bound_local_new, "__bound_local_new")
2881      DEF(TOK___bound_local_delete, "__bound_local_delete")
2882      DEF(TOK_malloc, "malloc")
2883      DEF(TOK_free, "free")
2884      DEF(TOK_realloc, "realloc")
2885      DEF(TOK_memalign, "memalign")
2886      DEF(TOK_calloc, "calloc")
2887      DEF(TOK_memmove, "memmove")
2888      DEF(TOK_strlen, "strlen")
2889      DEF(TOK_strcpy, "strcpy")
2890 #endif
2891
2892 /* Tiny Assembler */
2893
2894  DEF_ASM(byte)
2895  DEF_ASM(align)
2896  DEF_ASM(skip)
2897  DEF_ASM(space)
2898  DEF_ASM(string)
2899  DEF_ASM(asciz)
2900  DEF_ASM(ascii)
2901  DEF_ASM(globl)
2902  DEF_ASM(global)
2903  DEF_ASM(text)
2904  DEF_ASM(data)
2905  DEF_ASM(bss)
2906  DEF_ASM(previous)
2907  DEF_ASM(fill)
2908  DEF_ASM(org)
2909  DEF_ASM(quad)
2910
2911 #ifdef TCC_TARGET_I386
2912
2913 /* WARNING: relative order of tokens is important. */
2914  DEF_ASM(al)
2915  DEF_ASM(cl)
2916  DEF_ASM(dl)
2917  DEF_ASM(bl)
2918  DEF_ASM(ah)
2919  DEF_ASM(ch)
2920  DEF_ASM(dh)
2921  DEF_ASM(bh)
2922  DEF_ASM(ax)
2923  DEF_ASM(cx)
2924  DEF_ASM(dx)
2925  DEF_ASM(bx)
2926  DEF_ASM(sp)
2927  DEF_ASM(bp)
2928  DEF_ASM(si)
2929  DEF_ASM(di)
2930  DEF_ASM(eax)
2931  DEF_ASM(ecx)
2932  DEF_ASM(edx)
2933  DEF_ASM(ebx)
2934  DEF_ASM(esp)
2935  DEF_ASM(ebp)
2936  DEF_ASM(esi)
2937  DEF_ASM(edi)
2938  DEF_ASM(mm0)
2939  DEF_ASM(mm1)
2940  DEF_ASM(mm2)
2941  DEF_ASM(mm3)
2942  DEF_ASM(mm4)
2943  DEF_ASM(mm5)
2944  DEF_ASM(mm6)
2945  DEF_ASM(mm7)
2946  DEF_ASM(xmm0)
2947  DEF_ASM(xmm1)
2948  DEF_ASM(xmm2)
2949  DEF_ASM(xmm3)
2950  DEF_ASM(xmm4)
2951  DEF_ASM(xmm5)
2952  DEF_ASM(xmm6)
2953  DEF_ASM(xmm7)
2954  DEF_ASM(cr0)
2955  DEF_ASM(cr1)
2956  DEF_ASM(cr2)
2957  DEF_ASM(cr3)
2958  DEF_ASM(cr4)
2959  DEF_ASM(cr5)
2960  DEF_ASM(cr6)
2961  DEF_ASM(cr7)
2962  DEF_ASM(tr0)
2963  DEF_ASM(tr1)
2964  DEF_ASM(tr2)
2965  DEF_ASM(tr3)
2966  DEF_ASM(tr4)
2967  DEF_ASM(tr5)
2968  DEF_ASM(tr6)
2969  DEF_ASM(tr7)
2970  DEF_ASM(db0)
2971  DEF_ASM(db1)
2972  DEF_ASM(db2)
2973  DEF_ASM(db3)
2974  DEF_ASM(db4)
2975  DEF_ASM(db5)
2976  DEF_ASM(db6)
2977  DEF_ASM(db7)
2978  DEF_ASM(dr0)
2979  DEF_ASM(dr1)
2980  DEF_ASM(dr2)
2981  DEF_ASM(dr3)
2982  DEF_ASM(dr4)
2983  DEF_ASM(dr5)
2984  DEF_ASM(dr6)
2985  DEF_ASM(dr7)
2986  DEF_ASM(es)
2987  DEF_ASM(cs)
2988  DEF_ASM(ss)
2989  DEF_ASM(ds)
2990  DEF_ASM(fs)
2991  DEF_ASM(gs)
2992  DEF_ASM(st)
2993
2994  DEF_BWL(mov)
2995
2996  /* generic two operands */
2997  DEF_BWL(add)
2998  DEF_BWL(or)
2999  DEF_BWL(adc)
3000  DEF_BWL(sbb)
3001  DEF_BWL(and)
3002  DEF_BWL(sub)
3003  DEF_BWL(xor)
3004  DEF_BWL(cmp)
3005
3006  /* unary ops */
3007  DEF_BWL(inc)
3008  DEF_BWL(dec)
3009  DEF_BWL(not)
3010  DEF_BWL(neg)
3011  DEF_BWL(mul)
3012  DEF_BWL(imul)
3013  DEF_BWL(div)
3014  DEF_BWL(idiv)
3015
3016  DEF_BWL(xchg)
3017  DEF_BWL(test)
3018
3019  /* shifts */
3020  DEF_BWL(rol)
3021  DEF_BWL(ror)
3022  DEF_BWL(rcl)
3023  DEF_BWL(rcr)
3024  DEF_BWL(shl)
3025  DEF_BWL(shr)
3026  DEF_BWL(sar)
3027
3028  DEF_ASM(shldw)
3029  DEF_ASM(shldl)
3030  DEF_ASM(shld)
3031  DEF_ASM(shrdw)
3032  DEF_ASM(shrdl)
3033  DEF_ASM(shrd)
3034
3035  DEF_ASM(pushw)
3036  DEF_ASM(pushl)
3037  DEF_ASM(push)
3038  DEF_ASM(popw)
3039  DEF_ASM(popl)
3040  DEF_ASM(pop)
3041  DEF_BWL(in)
3042  DEF_BWL(out)
3043
3044  DEF_WL(movzb)
3045
3046  DEF_ASM(movzwl)
3047  DEF_ASM(movsbw)
3048  DEF_ASM(movsbl)
3049  DEF_ASM(movswl)
3050
3051  DEF_WL(lea) 
3052
3053  DEF_ASM(les) 
3054  DEF_ASM(lds) 
3055  DEF_ASM(lss) 
3056  DEF_ASM(lfs) 
3057  DEF_ASM(lgs) 
3058
3059  DEF_ASM(call)
3060  DEF_ASM(jmp)
3061  DEF_ASM(lcall)
3062  DEF_ASM(ljmp)
3063  
3064  DEF_ASMTEST(j)
3065
3066  DEF_ASMTEST(set)
3067  DEF_ASMTEST(cmov)
3068
3069  DEF_WL(bsf)
3070  DEF_WL(bsr)
3071  DEF_WL(bt)
3072  DEF_WL(bts)
3073  DEF_WL(btr)
3074  DEF_WL(btc)
3075
3076  DEF_WL(lsl)
3077
3078  /* generic FP ops */
3079  DEF_FP(add)
3080  DEF_FP(mul)
3081
3082  DEF_ASM(fcom)
3083  DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
3084  DEF_FP1(com)
3085
3086  DEF_FP(comp)
3087  DEF_FP(sub)
3088  DEF_FP(subr)
3089  DEF_FP(div)
3090  DEF_FP(divr)
3091
3092  DEF_BWL(xadd)
3093  DEF_BWL(cmpxchg)
3094
3095  /* string ops */
3096  DEF_BWL(cmps)
3097  DEF_BWL(scmp)
3098  DEF_BWL(ins)
3099  DEF_BWL(outs)
3100  DEF_BWL(lods)
3101  DEF_BWL(slod)
3102  DEF_BWL(movs)
3103  DEF_BWL(smov)
3104  DEF_BWL(scas)
3105  DEF_BWL(ssca)
3106  DEF_BWL(stos)
3107  DEF_BWL(ssto)
3108
3109  /* generic asm ops */
3110
3111 #define ALT(x)
3112 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
3113 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
3114 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
3115 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
3116 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
3117 // njn: inlined i386-asm.h
3118 //#include "i386-asm.h"
3119 //---------------------------------------------------------------------------
3120      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
3121      DEF_ASM_OP0(popa, 0x61)
3122      DEF_ASM_OP0(clc, 0xf8)
3123      DEF_ASM_OP0(cld, 0xfc)
3124      DEF_ASM_OP0(cli, 0xfa)
3125      DEF_ASM_OP0(clts, 0x0f06)
3126      DEF_ASM_OP0(cmc, 0xf5)
3127      DEF_ASM_OP0(lahf, 0x9f)
3128      DEF_ASM_OP0(sahf, 0x9e)
3129      DEF_ASM_OP0(pushfl, 0x9c)
3130      DEF_ASM_OP0(popfl, 0x9d)
3131      DEF_ASM_OP0(pushf, 0x9c)
3132      DEF_ASM_OP0(popf, 0x9d)
3133      DEF_ASM_OP0(stc, 0xf9)
3134      DEF_ASM_OP0(std, 0xfd)
3135      DEF_ASM_OP0(sti, 0xfb)
3136      DEF_ASM_OP0(aaa, 0x37)
3137      DEF_ASM_OP0(aas, 0x3f)
3138      DEF_ASM_OP0(daa, 0x27)
3139      DEF_ASM_OP0(das, 0x2f)
3140      DEF_ASM_OP0(aad, 0xd50a)
3141      DEF_ASM_OP0(aam, 0xd40a)
3142      DEF_ASM_OP0(cbw, 0x6698)
3143      DEF_ASM_OP0(cwd, 0x6699)
3144      DEF_ASM_OP0(cwde, 0x98)
3145      DEF_ASM_OP0(cdq, 0x99)
3146      DEF_ASM_OP0(cbtw, 0x6698)
3147      DEF_ASM_OP0(cwtl, 0x98)
3148      DEF_ASM_OP0(cwtd, 0x6699)
3149      DEF_ASM_OP0(cltd, 0x99)
3150      DEF_ASM_OP0(int3, 0xcc)
3151      DEF_ASM_OP0(into, 0xce)
3152      DEF_ASM_OP0(iret, 0xcf)
3153      DEF_ASM_OP0(rsm, 0x0faa)
3154      DEF_ASM_OP0(hlt, 0xf4)
3155      DEF_ASM_OP0(wait, 0x9b)
3156      DEF_ASM_OP0(nop, 0x90)
3157      DEF_ASM_OP0(xlat, 0xd7)
3158
3159      /* strings */
3160 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3161 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3162
3163 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3164 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3165
3166 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3167 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3168
3169 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3170 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3171
3172 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3173 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3174
3175 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3176 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3177
3178      /* bits */
3179      
3180 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3181 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3182
3183 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3184 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3185
3186 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3187 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3188
3189 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3190 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3191
3192 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3193 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3194
3195      /* prefixes */
3196      DEF_ASM_OP0(aword, 0x67)
3197      DEF_ASM_OP0(addr16, 0x67)
3198      DEF_ASM_OP0(word, 0x66)
3199      DEF_ASM_OP0(data16, 0x66)
3200      DEF_ASM_OP0(lock, 0xf0)
3201      DEF_ASM_OP0(rep, 0xf3)
3202      DEF_ASM_OP0(repe, 0xf3)
3203      DEF_ASM_OP0(repz, 0xf3)
3204      DEF_ASM_OP0(repne, 0xf2)
3205      DEF_ASM_OP0(repnz, 0xf2)
3206              
3207      DEF_ASM_OP0(invd, 0x0f08)
3208      DEF_ASM_OP0(wbinvd, 0x0f09)
3209      DEF_ASM_OP0(cpuid, 0x0fa2)
3210      DEF_ASM_OP0(wrmsr, 0x0f30)
3211      DEF_ASM_OP0(rdtsc, 0x0f31)
3212      DEF_ASM_OP0(rdmsr, 0x0f32)
3213      DEF_ASM_OP0(rdpmc, 0x0f33)
3214      DEF_ASM_OP0(ud2, 0x0f0b)
3215
3216      /* NOTE: we took the same order as gas opcode definition order */
3217 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3218 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3219 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3220 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3221 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3222 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3223
3224 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3225 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3226
3227 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3228 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3229 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3230 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3231 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3232 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3233
3234 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3235 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3236 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3237 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3238 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3239
3240 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3241 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3242 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3243 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3244 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3245
3246 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3247 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3248 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3249
3250 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3251 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3252 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3253 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3254
3255 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3256 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3257 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3258 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3259
3260 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3261 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3262 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3263 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3264
3265 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3266
3267 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3268 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3269 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3270 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3271 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3272
3273      /* arith */
3274 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
3275 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3276 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3277 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3278 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3279
3280 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3281 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3282 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3283 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3284
3285 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3286 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3287 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3288 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3289
3290 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3291 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3292
3293 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3294 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3295
3296 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3297 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3298 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3299 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3300 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3301
3302 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3303 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3304 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3305 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3306
3307      /* shifts */
3308 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3309 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3310 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3311
3312 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3313 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3314 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3315 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3316 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3317 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3318
3319 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3320 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3321 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3322 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3323
3324 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3325 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3326 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3327 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3328
3329 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3330 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3331     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3332     DEF_ASM_OP0(leave, 0xc9)
3333     DEF_ASM_OP0(ret, 0xc3)
3334 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3335     DEF_ASM_OP0(lret, 0xcb)
3336 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3337
3338 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3339     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3340     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3341     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3342     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3343     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3344     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3345      
3346      /* float */
3347      /* specific fcomp handling */
3348 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3349
3350 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3351 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3352 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3353 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3354 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3355 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3356 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3357 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3358 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3359 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3360 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3361
3362      DEF_ASM_OP0(fucompp, 0xdae9)
3363      DEF_ASM_OP0(ftst, 0xd9e4)
3364      DEF_ASM_OP0(fxam, 0xd9e5)
3365      DEF_ASM_OP0(fld1, 0xd9e8)
3366      DEF_ASM_OP0(fldl2t, 0xd9e9)
3367      DEF_ASM_OP0(fldl2e, 0xd9ea)
3368      DEF_ASM_OP0(fldpi, 0xd9eb)
3369      DEF_ASM_OP0(fldlg2, 0xd9ec)
3370      DEF_ASM_OP0(fldln2, 0xd9ed)
3371      DEF_ASM_OP0(fldz, 0xd9ee)
3372
3373      DEF_ASM_OP0(f2xm1, 0xd9f0)
3374      DEF_ASM_OP0(fyl2x, 0xd9f1)
3375      DEF_ASM_OP0(fptan, 0xd9f2)
3376      DEF_ASM_OP0(fpatan, 0xd9f3)
3377      DEF_ASM_OP0(fxtract, 0xd9f4)
3378      DEF_ASM_OP0(fprem1, 0xd9f5)
3379      DEF_ASM_OP0(fdecstp, 0xd9f6)
3380      DEF_ASM_OP0(fincstp, 0xd9f7)
3381      DEF_ASM_OP0(fprem, 0xd9f8)
3382      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3383      DEF_ASM_OP0(fsqrt, 0xd9fa)
3384      DEF_ASM_OP0(fsincos, 0xd9fb)
3385      DEF_ASM_OP0(frndint, 0xd9fc)
3386      DEF_ASM_OP0(fscale, 0xd9fd)
3387      DEF_ASM_OP0(fsin, 0xd9fe)
3388      DEF_ASM_OP0(fcos, 0xd9ff)
3389      DEF_ASM_OP0(fchs, 0xd9e0)
3390      DEF_ASM_OP0(fabs, 0xd9e1)
3391      DEF_ASM_OP0(fninit, 0xdbe3)
3392      DEF_ASM_OP0(fnclex, 0xdbe2)
3393      DEF_ASM_OP0(fnop, 0xd9d0)
3394      DEF_ASM_OP0(fwait, 0x9b)
3395
3396     /* fp load */
3397     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3398     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3399     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3400 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3401     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3402     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3403     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3404     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3405     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3406     
3407     /* fp store */
3408     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
3409     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3410     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3411     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3412 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3413     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3414     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3415     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3416     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3417     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3418
3419     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3420     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3421     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3422     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3423     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3424
3425     /* exchange */
3426     DEF_ASM_OP0(fxch, 0xd9c9)
3427 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3428
3429     /* misc FPU */
3430     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3431     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3432
3433     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3434     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3435     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3436     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3437     DEF_ASM_OP0(fnstsw, 0xdfe0)
3438 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3439 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3440     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3441 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3442 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3443     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3444     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3445     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3446     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3447     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3448     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3449     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3450     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3451     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3452     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3453     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3454
3455     /* segments */
3456     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3457     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3458     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3459     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3460     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3461     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3462 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3463     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3464     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3465     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3466     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3467     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3468     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3469     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3470     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3471
3472     /* 486 */
3473     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3474 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3475 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3476     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3477
3478     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3479     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3480
3481     /* pentium */
3482     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3483     
3484     /* pentium pro */
3485     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3486
3487     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3488     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3489     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3490     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3491     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3492     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3493     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3494     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3495
3496     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3497     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3498     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3499     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3500
3501     /* mmx */
3502     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
3503     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3504 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3505     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3506 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3507     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3508     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3509     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3510     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3511     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3512     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3513     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3514     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3515     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3516     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3517     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3518     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3519     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3520     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3521     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3522     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3523     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3524     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3525     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3526     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3527     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3528     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3529     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3530 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3531     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3532 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3533     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3534 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3535     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3536 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3537     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3538 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3539     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3540 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3541     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3542 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3543     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3544 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3545     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3546     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3547     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3548     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3549     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3550     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3551     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3552     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3553     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3554     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3555     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3556     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3557     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3558     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3559
3560 #undef ALT
3561 #undef DEF_ASM_OP0
3562 #undef DEF_ASM_OP0L
3563 #undef DEF_ASM_OP1
3564 #undef DEF_ASM_OP2
3565 #undef DEF_ASM_OP3
3566 //---------------------------------------------------------------------------
3567
3568 #define ALT(x)
3569 #define DEF_ASM_OP0(name, opcode)
3570 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
3571 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
3572 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
3573 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
3574 // njn: inlined i386-asm.h
3575 //#include "i386-asm.h"
3576 //---------------------------------------------------------------------------
3577      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
3578      DEF_ASM_OP0(popa, 0x61)
3579      DEF_ASM_OP0(clc, 0xf8)
3580      DEF_ASM_OP0(cld, 0xfc)
3581      DEF_ASM_OP0(cli, 0xfa)
3582      DEF_ASM_OP0(clts, 0x0f06)
3583      DEF_ASM_OP0(cmc, 0xf5)
3584      DEF_ASM_OP0(lahf, 0x9f)
3585      DEF_ASM_OP0(sahf, 0x9e)
3586      DEF_ASM_OP0(pushfl, 0x9c)
3587      DEF_ASM_OP0(popfl, 0x9d)
3588      DEF_ASM_OP0(pushf, 0x9c)
3589      DEF_ASM_OP0(popf, 0x9d)
3590      DEF_ASM_OP0(stc, 0xf9)
3591      DEF_ASM_OP0(std, 0xfd)
3592      DEF_ASM_OP0(sti, 0xfb)
3593      DEF_ASM_OP0(aaa, 0x37)
3594      DEF_ASM_OP0(aas, 0x3f)
3595      DEF_ASM_OP0(daa, 0x27)
3596      DEF_ASM_OP0(das, 0x2f)
3597      DEF_ASM_OP0(aad, 0xd50a)
3598      DEF_ASM_OP0(aam, 0xd40a)
3599      DEF_ASM_OP0(cbw, 0x6698)
3600      DEF_ASM_OP0(cwd, 0x6699)
3601      DEF_ASM_OP0(cwde, 0x98)
3602      DEF_ASM_OP0(cdq, 0x99)
3603      DEF_ASM_OP0(cbtw, 0x6698)
3604      DEF_ASM_OP0(cwtl, 0x98)
3605      DEF_ASM_OP0(cwtd, 0x6699)
3606      DEF_ASM_OP0(cltd, 0x99)
3607      DEF_ASM_OP0(int3, 0xcc)
3608      DEF_ASM_OP0(into, 0xce)
3609      DEF_ASM_OP0(iret, 0xcf)
3610      DEF_ASM_OP0(rsm, 0x0faa)
3611      DEF_ASM_OP0(hlt, 0xf4)
3612      DEF_ASM_OP0(wait, 0x9b)
3613      DEF_ASM_OP0(nop, 0x90)
3614      DEF_ASM_OP0(xlat, 0xd7)
3615
3616      /* strings */
3617 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3618 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3619
3620 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3621 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3622
3623 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3624 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3625
3626 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3627 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3628
3629 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3630 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3631
3632 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3633 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3634
3635      /* bits */
3636      
3637 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3638 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3639
3640 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3641 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3642
3643 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3644 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3645
3646 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3647 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3648
3649 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3650 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3651
3652      /* prefixes */
3653      DEF_ASM_OP0(aword, 0x67)
3654      DEF_ASM_OP0(addr16, 0x67)
3655      DEF_ASM_OP0(word, 0x66)
3656      DEF_ASM_OP0(data16, 0x66)
3657      DEF_ASM_OP0(lock, 0xf0)
3658      DEF_ASM_OP0(rep, 0xf3)
3659      DEF_ASM_OP0(repe, 0xf3)
3660      DEF_ASM_OP0(repz, 0xf3)
3661      DEF_ASM_OP0(repne, 0xf2)
3662      DEF_ASM_OP0(repnz, 0xf2)
3663              
3664      DEF_ASM_OP0(invd, 0x0f08)
3665      DEF_ASM_OP0(wbinvd, 0x0f09)
3666      DEF_ASM_OP0(cpuid, 0x0fa2)
3667      DEF_ASM_OP0(wrmsr, 0x0f30)
3668      DEF_ASM_OP0(rdtsc, 0x0f31)
3669      DEF_ASM_OP0(rdmsr, 0x0f32)
3670      DEF_ASM_OP0(rdpmc, 0x0f33)
3671      DEF_ASM_OP0(ud2, 0x0f0b)
3672
3673      /* NOTE: we took the same order as gas opcode definition order */
3674 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3675 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3676 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3677 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3678 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3679 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3680
3681 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3682 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3683
3684 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3685 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3686 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3687 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3688 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3689 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3690
3691 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3692 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3693 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3694 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3695 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3696
3697 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3698 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3699 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3700 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3701 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3702
3703 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3704 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3705 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3706
3707 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3708 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3709 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3710 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3711
3712 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3713 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3714 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3715 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3716
3717 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3718 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3719 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3720 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3721
3722 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3723
3724 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3725 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3726 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3727 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3728 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3729
3730      /* arith */
3731 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
3732 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3733 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3734 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3735 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3736
3737 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3738 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3739 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3740 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3741
3742 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3743 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3744 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3745 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3746
3747 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3748 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3749
3750 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3751 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3752
3753 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3754 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3755 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3756 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3757 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3758
3759 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3760 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3761 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3762 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3763
3764      /* shifts */
3765 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3766 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3767 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3768
3769 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3770 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3771 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3772 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3773 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3774 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3775
3776 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3777 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3778 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3779 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3780
3781 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3782 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3783 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3784 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3785
3786 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3787 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3788     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3789     DEF_ASM_OP0(leave, 0xc9)
3790     DEF_ASM_OP0(ret, 0xc3)
3791 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3792     DEF_ASM_OP0(lret, 0xcb)
3793 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3794
3795 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3796     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3797     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3798     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3799     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3800     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3801     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3802      
3803      /* float */
3804      /* specific fcomp handling */
3805 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3806
3807 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3808 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3809 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3810 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3811 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3812 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3813 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3814 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3815 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3816 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3817 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3818
3819      DEF_ASM_OP0(fucompp, 0xdae9)
3820      DEF_ASM_OP0(ftst, 0xd9e4)
3821      DEF_ASM_OP0(fxam, 0xd9e5)
3822      DEF_ASM_OP0(fld1, 0xd9e8)
3823      DEF_ASM_OP0(fldl2t, 0xd9e9)
3824      DEF_ASM_OP0(fldl2e, 0xd9ea)
3825      DEF_ASM_OP0(fldpi, 0xd9eb)
3826      DEF_ASM_OP0(fldlg2, 0xd9ec)
3827      DEF_ASM_OP0(fldln2, 0xd9ed)
3828      DEF_ASM_OP0(fldz, 0xd9ee)
3829
3830      DEF_ASM_OP0(f2xm1, 0xd9f0)
3831      DEF_ASM_OP0(fyl2x, 0xd9f1)
3832      DEF_ASM_OP0(fptan, 0xd9f2)
3833      DEF_ASM_OP0(fpatan, 0xd9f3)
3834      DEF_ASM_OP0(fxtract, 0xd9f4)
3835      DEF_ASM_OP0(fprem1, 0xd9f5)
3836      DEF_ASM_OP0(fdecstp, 0xd9f6)
3837      DEF_ASM_OP0(fincstp, 0xd9f7)
3838      DEF_ASM_OP0(fprem, 0xd9f8)
3839      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3840      DEF_ASM_OP0(fsqrt, 0xd9fa)
3841      DEF_ASM_OP0(fsincos, 0xd9fb)
3842      DEF_ASM_OP0(frndint, 0xd9fc)
3843      DEF_ASM_OP0(fscale, 0xd9fd)
3844      DEF_ASM_OP0(fsin, 0xd9fe)
3845      DEF_ASM_OP0(fcos, 0xd9ff)
3846      DEF_ASM_OP0(fchs, 0xd9e0)
3847      DEF_ASM_OP0(fabs, 0xd9e1)
3848      DEF_ASM_OP0(fninit, 0xdbe3)
3849      DEF_ASM_OP0(fnclex, 0xdbe2)
3850      DEF_ASM_OP0(fnop, 0xd9d0)
3851      DEF_ASM_OP0(fwait, 0x9b)
3852
3853     /* fp load */
3854     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3855     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3856     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3857 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3858     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3859     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3860     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3861     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3862     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3863     
3864     /* fp store */
3865     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
3866     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3867     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3868     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3869 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3870     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3871     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3872     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3873     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3874     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3875
3876     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3877     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3878     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3879     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3880     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3881
3882     /* exchange */
3883     DEF_ASM_OP0(fxch, 0xd9c9)
3884 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3885
3886     /* misc FPU */
3887     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3888     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3889
3890     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3891     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3892     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3893     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3894     DEF_ASM_OP0(fnstsw, 0xdfe0)
3895 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3896 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3897     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3898 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3899 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3900     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3901     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3902     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3903     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3904     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3905     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3906     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3907     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3908     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3909     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3910     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3911
3912     /* segments */
3913     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3914     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3915     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3916     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3917     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3918     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3919 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3920     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3921     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3922     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3923     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3924     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3925     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3926     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3927     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3928
3929     /* 486 */
3930     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3931 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3932 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3933     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3934
3935     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3936     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3937
3938     /* pentium */
3939     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3940     
3941     /* pentium pro */
3942     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3943
3944     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3945     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3946     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3947     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3948     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3949     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3950     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3951     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3952
3953     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3954     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3955     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3956     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3957
3958     /* mmx */
3959     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
3960     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3961 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3962     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3963 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3964     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3965     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3966     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3967     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3968     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3969     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3970     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3971     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3972     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3973     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3974     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3975     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3976     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3977     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3978     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3979     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3980     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3981     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3982     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3983     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3984     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3985     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3986     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3987 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3988     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3989 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3990     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3991 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3992     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3993 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3994     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3995 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3996     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3997 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3998     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3999 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4000     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4001 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4002     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4003     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4004     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4005     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4006     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4007     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4008     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4009     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4010     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4011     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4012     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4013     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4014     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4015     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4016
4017 #undef ALT
4018 #undef DEF_ASM_OP0
4019 #undef DEF_ASM_OP0L
4020 #undef DEF_ASM_OP1
4021 #undef DEF_ASM_OP2
4022 #undef DEF_ASM_OP3
4023 //---------------------------------------------------------------------------
4024
4025 #endif
4026 //---------------------------------------------------------------------------
4027 #undef DEF
4028 };
4029
4030 static const char tcc_keywords[] = 
4031 #define DEF(id, str) str "\0"
4032 // njn: inlined tcctok.h
4033 //#include "tcctok.h"
4034 //---------------------------------------------------------------------------
4035 /* keywords */
4036      DEF(TOK_INT, "int")
4037      DEF(TOK_VOID, "void")
4038      DEF(TOK_CHAR, "char")
4039      DEF(TOK_IF, "if")
4040      DEF(TOK_ELSE, "else")
4041      DEF(TOK_WHILE, "while")
4042      DEF(TOK_BREAK, "break")
4043      DEF(TOK_RETURN, "return")
4044      DEF(TOK_FOR, "for")
4045      DEF(TOK_EXTERN, "extern")
4046      DEF(TOK_STATIC, "static")
4047      DEF(TOK_UNSIGNED, "unsigned")
4048      DEF(TOK_GOTO, "goto")
4049      DEF(TOK_DO, "do")
4050      DEF(TOK_CONTINUE, "continue")
4051      DEF(TOK_SWITCH, "switch")
4052      DEF(TOK_CASE, "case")
4053
4054      DEF(TOK_CONST1, "const")
4055      DEF(TOK_CONST2, "__const") /* gcc keyword */
4056      DEF(TOK_CONST3, "__const__") /* gcc keyword */
4057      DEF(TOK_VOLATILE1, "volatile")
4058      DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
4059      DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
4060      DEF(TOK_LONG, "long")
4061      DEF(TOK_REGISTER, "register")
4062      DEF(TOK_SIGNED1, "signed")
4063      DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
4064      DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
4065      DEF(TOK_AUTO, "auto")
4066      DEF(TOK_INLINE1, "inline")
4067      DEF(TOK_INLINE2, "__inline") /* gcc keyword */
4068      DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
4069      DEF(TOK_RESTRICT1, "restrict")
4070      DEF(TOK_RESTRICT2, "__restrict")
4071      DEF(TOK_RESTRICT3, "__restrict__")
4072      DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
4073      
4074      DEF(TOK_FLOAT, "float")
4075      DEF(TOK_DOUBLE, "double")
4076      DEF(TOK_BOOL, "_Bool")
4077      DEF(TOK_SHORT, "short")
4078      DEF(TOK_STRUCT, "struct")
4079      DEF(TOK_UNION, "union")
4080      DEF(TOK_TYPEDEF, "typedef")
4081      DEF(TOK_DEFAULT, "default")
4082      DEF(TOK_ENUM, "enum")
4083      DEF(TOK_SIZEOF, "sizeof")
4084      DEF(TOK_ATTRIBUTE1, "__attribute")
4085      DEF(TOK_ATTRIBUTE2, "__attribute__")
4086      DEF(TOK_ALIGNOF1, "__alignof")
4087      DEF(TOK_ALIGNOF2, "__alignof__")
4088      DEF(TOK_TYPEOF1, "typeof")
4089      DEF(TOK_TYPEOF2, "__typeof")
4090      DEF(TOK_TYPEOF3, "__typeof__")
4091      DEF(TOK_LABEL, "__label__")
4092      DEF(TOK_ASM1, "asm")
4093      DEF(TOK_ASM2, "__asm")
4094      DEF(TOK_ASM3, "__asm__")
4095
4096 /*********************************************************************/
4097 /* the following are not keywords. They are included to ease parsing */
4098 /* preprocessor only */
4099      DEF(TOK_DEFINE, "define")
4100      DEF(TOK_INCLUDE, "include")
4101      DEF(TOK_INCLUDE_NEXT, "include_next")
4102      DEF(TOK_IFDEF, "ifdef")
4103      DEF(TOK_IFNDEF, "ifndef")
4104      DEF(TOK_ELIF, "elif")
4105      DEF(TOK_ENDIF, "endif")
4106      DEF(TOK_DEFINED, "defined")
4107      DEF(TOK_UNDEF, "undef")
4108      DEF(TOK_ERROR, "error")
4109      DEF(TOK_WARNING, "warning")
4110      DEF(TOK_LINE, "line")
4111      DEF(TOK_PRAGMA, "pragma")
4112      DEF(TOK___LINE__, "__LINE__")
4113      DEF(TOK___FILE__, "__FILE__")
4114      DEF(TOK___DATE__, "__DATE__")
4115      DEF(TOK___TIME__, "__TIME__")
4116      DEF(TOK___FUNCTION__, "__FUNCTION__")
4117      DEF(TOK___VA_ARGS__, "__VA_ARGS__")
4118      
4119 /* special identifiers */
4120      DEF(TOK___FUNC__, "__func__")
4121      
4122 /* attribute identifiers */
4123 /* XXX: handle all tokens generically since speed is not critical */
4124      DEF(TOK_SECTION1, "section")
4125      DEF(TOK_SECTION2, "__section__")
4126      DEF(TOK_ALIGNED1, "aligned")
4127      DEF(TOK_ALIGNED2, "__aligned__")
4128      DEF(TOK_PACKED1, "packed")
4129      DEF(TOK_PACKED2, "__packed__")
4130      DEF(TOK_UNUSED1, "unused")
4131      DEF(TOK_UNUSED2, "__unused__")
4132      DEF(TOK_CDECL1, "cdecl")
4133      DEF(TOK_CDECL2, "__cdecl")
4134      DEF(TOK_CDECL3, "__cdecl__")
4135      DEF(TOK_STDCALL1, "stdcall")
4136      DEF(TOK_STDCALL2, "__stdcall")
4137      DEF(TOK_STDCALL3, "__stdcall__")
4138      DEF(TOK_DLLEXPORT, "dllexport")
4139      DEF(TOK_NORETURN1, "noreturn")
4140      DEF(TOK_NORETURN2, "__noreturn__")
4141      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
4142      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
4143      DEF(TOK_REGPARM1, "regparm")
4144      DEF(TOK_REGPARM2, "__regparm__")
4145
4146 /* pragma */
4147      DEF(TOK_pack, "pack")
4148 #if !defined(TCC_TARGET_I386)
4149      /* already defined for assembler */
4150      DEF(TOK_ASM_push, "push")
4151      DEF(TOK_ASM_pop, "pop")
4152 #endif
4153
4154 /* builtin functions or variables */
4155      DEF(TOK_memcpy, "memcpy")
4156      DEF(TOK_memset, "memset")
4157      DEF(TOK_alloca, "alloca")
4158      DEF(TOK___divdi3, "__divdi3")
4159      DEF(TOK___moddi3, "__moddi3")
4160      DEF(TOK___udivdi3, "__udivdi3")
4161      DEF(TOK___umoddi3, "__umoddi3")
4162 #if defined(TCC_TARGET_ARM)
4163      DEF(TOK___divsi3, "__divsi3")
4164      DEF(TOK___modsi3, "__modsi3")
4165      DEF(TOK___udivsi3, "__udivsi3")
4166      DEF(TOK___umodsi3, "__umodsi3")
4167      DEF(TOK___sardi3, "__ashrdi3")
4168      DEF(TOK___shrdi3, "__lshrdi3")
4169      DEF(TOK___shldi3, "__ashldi3")
4170      DEF(TOK___slltold, "__slltold")
4171      DEF(TOK___fixunssfsi, "__fixunssfsi")
4172      DEF(TOK___fixunsdfsi, "__fixunsdfsi")
4173      DEF(TOK___fixunsxfsi, "__fixunsxfsi")
4174      DEF(TOK___fixsfdi, "__fixsfdi")
4175      DEF(TOK___fixdfdi, "__fixdfdi")
4176      DEF(TOK___fixxfdi, "__fixxfdi")
4177 #elif defined(TCC_TARGET_C67)
4178      DEF(TOK__divi, "_divi")
4179      DEF(TOK__divu, "_divu")
4180      DEF(TOK__divf, "_divf")
4181      DEF(TOK__divd, "_divd")
4182      DEF(TOK__remi, "_remi")
4183      DEF(TOK__remu, "_remu")
4184      DEF(TOK___sardi3, "__sardi3")
4185      DEF(TOK___shrdi3, "__shrdi3")
4186      DEF(TOK___shldi3, "__shldi3")
4187 #else
4188      /* XXX: same names on i386 ? */
4189      DEF(TOK___sardi3, "__sardi3")
4190      DEF(TOK___shrdi3, "__shrdi3")
4191      DEF(TOK___shldi3, "__shldi3")
4192 #endif
4193      DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
4194      DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
4195      DEF(TOK___ulltof, "__ulltof")
4196      DEF(TOK___ulltod, "__ulltod")
4197      DEF(TOK___ulltold, "__ulltold")
4198      DEF(TOK___fixunssfdi, "__fixunssfdi")
4199      DEF(TOK___fixunsdfdi, "__fixunsdfdi")
4200      DEF(TOK___fixunsxfdi, "__fixunsxfdi")
4201      DEF(TOK___chkstk, "__chkstk")
4202
4203 /* bound checking symbols */
4204 #ifdef CONFIG_TCC_BCHECK
4205      DEF(TOK___bound_ptr_add, "__bound_ptr_add")
4206      DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
4207      DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
4208      DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
4209      DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
4210      DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
4211      DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
4212      DEF(TOK___bound_local_new, "__bound_local_new")
4213      DEF(TOK___bound_local_delete, "__bound_local_delete")
4214      DEF(TOK_malloc, "malloc")
4215      DEF(TOK_free, "free")
4216      DEF(TOK_realloc, "realloc")
4217      DEF(TOK_memalign, "memalign")
4218      DEF(TOK_calloc, "calloc")
4219      DEF(TOK_memmove, "memmove")
4220      DEF(TOK_strlen, "strlen")
4221      DEF(TOK_strcpy, "strcpy")
4222 #endif
4223
4224 /* Tiny Assembler */
4225
4226  DEF_ASM(byte)
4227  DEF_ASM(align)
4228  DEF_ASM(skip)
4229  DEF_ASM(space)
4230  DEF_ASM(string)
4231  DEF_ASM(asciz)
4232  DEF_ASM(ascii)
4233  DEF_ASM(globl)
4234  DEF_ASM(global)
4235  DEF_ASM(text)
4236  DEF_ASM(data)
4237  DEF_ASM(bss)
4238  DEF_ASM(previous)
4239  DEF_ASM(fill)
4240  DEF_ASM(org)
4241  DEF_ASM(quad)
4242
4243 #ifdef TCC_TARGET_I386
4244
4245 /* WARNING: relative order of tokens is important. */
4246  DEF_ASM(al)
4247  DEF_ASM(cl)
4248  DEF_ASM(dl)
4249  DEF_ASM(bl)
4250  DEF_ASM(ah)
4251  DEF_ASM(ch)
4252  DEF_ASM(dh)
4253  DEF_ASM(bh)
4254  DEF_ASM(ax)
4255  DEF_ASM(cx)
4256  DEF_ASM(dx)
4257  DEF_ASM(bx)
4258  DEF_ASM(sp)
4259  DEF_ASM(bp)
4260  DEF_ASM(si)
4261  DEF_ASM(di)
4262  DEF_ASM(eax)
4263  DEF_ASM(ecx)
4264  DEF_ASM(edx)
4265  DEF_ASM(ebx)
4266  DEF_ASM(esp)
4267  DEF_ASM(ebp)
4268  DEF_ASM(esi)
4269  DEF_ASM(edi)
4270  DEF_ASM(mm0)
4271  DEF_ASM(mm1)
4272  DEF_ASM(mm2)
4273  DEF_ASM(mm3)
4274  DEF_ASM(mm4)
4275  DEF_ASM(mm5)
4276  DEF_ASM(mm6)
4277  DEF_ASM(mm7)
4278  DEF_ASM(xmm0)
4279  DEF_ASM(xmm1)
4280  DEF_ASM(xmm2)
4281  DEF_ASM(xmm3)
4282  DEF_ASM(xmm4)
4283  DEF_ASM(xmm5)
4284  DEF_ASM(xmm6)
4285  DEF_ASM(xmm7)
4286  DEF_ASM(cr0)
4287  DEF_ASM(cr1)
4288  DEF_ASM(cr2)
4289  DEF_ASM(cr3)
4290  DEF_ASM(cr4)
4291  DEF_ASM(cr5)
4292  DEF_ASM(cr6)
4293  DEF_ASM(cr7)
4294  DEF_ASM(tr0)
4295  DEF_ASM(tr1)
4296  DEF_ASM(tr2)
4297  DEF_ASM(tr3)
4298  DEF_ASM(tr4)
4299  DEF_ASM(tr5)
4300  DEF_ASM(tr6)
4301  DEF_ASM(tr7)
4302  DEF_ASM(db0)
4303  DEF_ASM(db1)
4304  DEF_ASM(db2)
4305  DEF_ASM(db3)
4306  DEF_ASM(db4)
4307  DEF_ASM(db5)
4308  DEF_ASM(db6)
4309  DEF_ASM(db7)
4310  DEF_ASM(dr0)
4311  DEF_ASM(dr1)
4312  DEF_ASM(dr2)
4313  DEF_ASM(dr3)
4314  DEF_ASM(dr4)
4315  DEF_ASM(dr5)
4316  DEF_ASM(dr6)
4317  DEF_ASM(dr7)
4318  DEF_ASM(es)
4319  DEF_ASM(cs)
4320  DEF_ASM(ss)
4321  DEF_ASM(ds)
4322  DEF_ASM(fs)
4323  DEF_ASM(gs)
4324  DEF_ASM(st)
4325
4326  DEF_BWL(mov)
4327
4328  /* generic two operands */
4329  DEF_BWL(add)
4330  DEF_BWL(or)
4331  DEF_BWL(adc)
4332  DEF_BWL(sbb)
4333  DEF_BWL(and)
4334  DEF_BWL(sub)
4335  DEF_BWL(xor)
4336  DEF_BWL(cmp)
4337
4338  /* unary ops */
4339  DEF_BWL(inc)
4340  DEF_BWL(dec)
4341  DEF_BWL(not)
4342  DEF_BWL(neg)
4343  DEF_BWL(mul)
4344  DEF_BWL(imul)
4345  DEF_BWL(div)
4346  DEF_BWL(idiv)
4347
4348  DEF_BWL(xchg)
4349  DEF_BWL(test)
4350
4351  /* shifts */
4352  DEF_BWL(rol)
4353  DEF_BWL(ror)
4354  DEF_BWL(rcl)
4355  DEF_BWL(rcr)
4356  DEF_BWL(shl)
4357  DEF_BWL(shr)
4358  DEF_BWL(sar)
4359
4360  DEF_ASM(shldw)
4361  DEF_ASM(shldl)
4362  DEF_ASM(shld)
4363  DEF_ASM(shrdw)
4364  DEF_ASM(shrdl)
4365  DEF_ASM(shrd)
4366
4367  DEF_ASM(pushw)
4368  DEF_ASM(pushl)
4369  DEF_ASM(push)
4370  DEF_ASM(popw)
4371  DEF_ASM(popl)
4372  DEF_ASM(pop)
4373  DEF_BWL(in)
4374  DEF_BWL(out)
4375
4376  DEF_WL(movzb)
4377
4378  DEF_ASM(movzwl)
4379  DEF_ASM(movsbw)
4380  DEF_ASM(movsbl)
4381  DEF_ASM(movswl)
4382
4383  DEF_WL(lea) 
4384
4385  DEF_ASM(les) 
4386  DEF_ASM(lds) 
4387  DEF_ASM(lss) 
4388  DEF_ASM(lfs) 
4389  DEF_ASM(lgs) 
4390
4391  DEF_ASM(call)
4392  DEF_ASM(jmp)
4393  DEF_ASM(lcall)
4394  DEF_ASM(ljmp)
4395  
4396  DEF_ASMTEST(j)
4397
4398  DEF_ASMTEST(set)
4399  DEF_ASMTEST(cmov)
4400
4401  DEF_WL(bsf)
4402  DEF_WL(bsr)
4403  DEF_WL(bt)
4404  DEF_WL(bts)
4405  DEF_WL(btr)
4406  DEF_WL(btc)
4407
4408  DEF_WL(lsl)
4409
4410  /* generic FP ops */
4411  DEF_FP(add)
4412  DEF_FP(mul)
4413
4414  DEF_ASM(fcom)
4415  DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
4416  DEF_FP1(com)
4417
4418  DEF_FP(comp)
4419  DEF_FP(sub)
4420  DEF_FP(subr)
4421  DEF_FP(div)
4422  DEF_FP(divr)
4423
4424  DEF_BWL(xadd)
4425  DEF_BWL(cmpxchg)
4426
4427  /* string ops */
4428  DEF_BWL(cmps)
4429  DEF_BWL(scmp)
4430  DEF_BWL(ins)
4431  DEF_BWL(outs)
4432  DEF_BWL(lods)
4433  DEF_BWL(slod)
4434  DEF_BWL(movs)
4435  DEF_BWL(smov)
4436  DEF_BWL(scas)
4437  DEF_BWL(ssca)
4438  DEF_BWL(stos)
4439  DEF_BWL(ssto)
4440
4441  /* generic asm ops */
4442
4443 #define ALT(x)
4444 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
4445 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
4446 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
4447 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
4448 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
4449 // njn: inlined i386-asm.h
4450 //#include "i386-asm.h"
4451 //---------------------------------------------------------------------------
4452      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
4453      DEF_ASM_OP0(popa, 0x61)
4454      DEF_ASM_OP0(clc, 0xf8)
4455      DEF_ASM_OP0(cld, 0xfc)
4456      DEF_ASM_OP0(cli, 0xfa)
4457      DEF_ASM_OP0(clts, 0x0f06)
4458      DEF_ASM_OP0(cmc, 0xf5)
4459      DEF_ASM_OP0(lahf, 0x9f)
4460      DEF_ASM_OP0(sahf, 0x9e)
4461      DEF_ASM_OP0(pushfl, 0x9c)
4462      DEF_ASM_OP0(popfl, 0x9d)
4463      DEF_ASM_OP0(pushf, 0x9c)
4464      DEF_ASM_OP0(popf, 0x9d)
4465      DEF_ASM_OP0(stc, 0xf9)
4466      DEF_ASM_OP0(std, 0xfd)
4467      DEF_ASM_OP0(sti, 0xfb)
4468      DEF_ASM_OP0(aaa, 0x37)
4469      DEF_ASM_OP0(aas, 0x3f)
4470      DEF_ASM_OP0(daa, 0x27)
4471      DEF_ASM_OP0(das, 0x2f)
4472      DEF_ASM_OP0(aad, 0xd50a)
4473      DEF_ASM_OP0(aam, 0xd40a)
4474      DEF_ASM_OP0(cbw, 0x6698)
4475      DEF_ASM_OP0(cwd, 0x6699)
4476      DEF_ASM_OP0(cwde, 0x98)
4477      DEF_ASM_OP0(cdq, 0x99)
4478      DEF_ASM_OP0(cbtw, 0x6698)
4479      DEF_ASM_OP0(cwtl, 0x98)
4480      DEF_ASM_OP0(cwtd, 0x6699)
4481      DEF_ASM_OP0(cltd, 0x99)
4482      DEF_ASM_OP0(int3, 0xcc)
4483      DEF_ASM_OP0(into, 0xce)
4484      DEF_ASM_OP0(iret, 0xcf)
4485      DEF_ASM_OP0(rsm, 0x0faa)
4486      DEF_ASM_OP0(hlt, 0xf4)
4487      DEF_ASM_OP0(wait, 0x9b)
4488      DEF_ASM_OP0(nop, 0x90)
4489      DEF_ASM_OP0(xlat, 0xd7)
4490
4491      /* strings */
4492 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4493 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4494
4495 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4496 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4497
4498 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4499 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4500
4501 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4502 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4503
4504 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4505 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4506
4507 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4508 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4509
4510      /* bits */
4511      
4512 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4513 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4514
4515 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4516 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4517
4518 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4519 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4520
4521 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4522 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4523
4524 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4525 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4526
4527      /* prefixes */
4528      DEF_ASM_OP0(aword, 0x67)
4529      DEF_ASM_OP0(addr16, 0x67)
4530      DEF_ASM_OP0(word, 0x66)
4531      DEF_ASM_OP0(data16, 0x66)
4532      DEF_ASM_OP0(lock, 0xf0)
4533      DEF_ASM_OP0(rep, 0xf3)
4534      DEF_ASM_OP0(repe, 0xf3)
4535      DEF_ASM_OP0(repz, 0xf3)
4536      DEF_ASM_OP0(repne, 0xf2)
4537      DEF_ASM_OP0(repnz, 0xf2)
4538              
4539      DEF_ASM_OP0(invd, 0x0f08)
4540      DEF_ASM_OP0(wbinvd, 0x0f09)
4541      DEF_ASM_OP0(cpuid, 0x0fa2)
4542      DEF_ASM_OP0(wrmsr, 0x0f30)
4543      DEF_ASM_OP0(rdtsc, 0x0f31)
4544      DEF_ASM_OP0(rdmsr, 0x0f32)
4545      DEF_ASM_OP0(rdpmc, 0x0f33)
4546      DEF_ASM_OP0(ud2, 0x0f0b)
4547
4548      /* NOTE: we took the same order as gas opcode definition order */
4549 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
4550 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
4551 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4552 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4553 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
4554 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
4555
4556 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
4557 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
4558
4559 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
4560 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
4561 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
4562 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
4563 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
4564 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
4565
4566 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
4567 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
4568 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4569 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
4570 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4571
4572 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
4573 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4574 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
4575 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
4576 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
4577
4578 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
4579 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4580 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
4581
4582 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
4583 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
4584 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4585 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4586
4587 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
4588 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
4589 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
4590 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
4591
4592 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
4593 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
4594 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
4595 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
4596
4597 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
4598
4599 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4600 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4601 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4602 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4603 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4604
4605      /* arith */
4606 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
4607 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4608 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
4609 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4610 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
4611
4612 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4613 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4614 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
4615 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4616
4617 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
4618 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4619 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
4620 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4621
4622 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4623 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4624
4625 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4626 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4627
4628 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
4629 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
4630 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
4631 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
4632 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
4633
4634 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4635 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4636 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4637 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4638
4639      /* shifts */
4640 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
4641 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
4642 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
4643
4644 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4645 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4646 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4647 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4648 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4649 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4650
4651 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
4652 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
4653 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
4654 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
4655
4656 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
4657 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
4658 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
4659 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
4660
4661 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
4662 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
4663     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
4664     DEF_ASM_OP0(leave, 0xc9)
4665     DEF_ASM_OP0(ret, 0xc3)
4666 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
4667     DEF_ASM_OP0(lret, 0xcb)
4668 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
4669
4670 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
4671     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4672     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4673     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4674     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4675     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
4676     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
4677      
4678      /* float */
4679      /* specific fcomp handling */
4680 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
4681
4682 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4683 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4684 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
4685 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4686 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4687 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
4688 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
4689 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4690 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4691 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4692 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4693
4694      DEF_ASM_OP0(fucompp, 0xdae9)
4695      DEF_ASM_OP0(ftst, 0xd9e4)
4696      DEF_ASM_OP0(fxam, 0xd9e5)
4697      DEF_ASM_OP0(fld1, 0xd9e8)
4698      DEF_ASM_OP0(fldl2t, 0xd9e9)
4699      DEF_ASM_OP0(fldl2e, 0xd9ea)
4700      DEF_ASM_OP0(fldpi, 0xd9eb)
4701      DEF_ASM_OP0(fldlg2, 0xd9ec)
4702      DEF_ASM_OP0(fldln2, 0xd9ed)
4703      DEF_ASM_OP0(fldz, 0xd9ee)
4704
4705      DEF_ASM_OP0(f2xm1, 0xd9f0)
4706      DEF_ASM_OP0(fyl2x, 0xd9f1)
4707      DEF_ASM_OP0(fptan, 0xd9f2)
4708      DEF_ASM_OP0(fpatan, 0xd9f3)
4709      DEF_ASM_OP0(fxtract, 0xd9f4)
4710      DEF_ASM_OP0(fprem1, 0xd9f5)
4711      DEF_ASM_OP0(fdecstp, 0xd9f6)
4712      DEF_ASM_OP0(fincstp, 0xd9f7)
4713      DEF_ASM_OP0(fprem, 0xd9f8)
4714      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
4715      DEF_ASM_OP0(fsqrt, 0xd9fa)
4716      DEF_ASM_OP0(fsincos, 0xd9fb)
4717      DEF_ASM_OP0(frndint, 0xd9fc)
4718      DEF_ASM_OP0(fscale, 0xd9fd)
4719      DEF_ASM_OP0(fsin, 0xd9fe)
4720      DEF_ASM_OP0(fcos, 0xd9ff)
4721      DEF_ASM_OP0(fchs, 0xd9e0)
4722      DEF_ASM_OP0(fabs, 0xd9e1)
4723      DEF_ASM_OP0(fninit, 0xdbe3)
4724      DEF_ASM_OP0(fnclex, 0xdbe2)
4725      DEF_ASM_OP0(fnop, 0xd9d0)
4726      DEF_ASM_OP0(fwait, 0x9b)
4727
4728     /* fp load */
4729     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
4730     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
4731     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
4732 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
4733     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
4734     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
4735     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
4736     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
4737     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
4738     
4739     /* fp store */
4740     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
4741     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
4742     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
4743     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
4744 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
4745     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
4746     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
4747     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
4748     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
4749     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
4750
4751     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
4752     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
4753     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
4754     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
4755     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
4756
4757     /* exchange */
4758     DEF_ASM_OP0(fxch, 0xd9c9)
4759 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
4760
4761     /* misc FPU */
4762     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
4763     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
4764
4765     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
4766     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
4767     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
4768     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
4769     DEF_ASM_OP0(fnstsw, 0xdfe0)
4770 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
4771 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
4772     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
4773 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
4774 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
4775     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
4776     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
4777     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4778     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
4779     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
4780     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4781     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
4782     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
4783     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
4784     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
4785     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
4786
4787     /* segments */
4788     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
4789     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
4790     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
4791     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
4792     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
4793     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
4794 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
4795     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
4796     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
4797     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
4798     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
4799     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
4800     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
4801     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
4802     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
4803
4804     /* 486 */
4805     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
4806 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4807 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4808     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
4809
4810     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
4811     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
4812
4813     /* pentium */
4814     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
4815     
4816     /* pentium pro */
4817     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
4818
4819     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4820     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4821     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4822     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4823     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4824     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4825     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4826     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4827
4828     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4829     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4830     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4831     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4832
4833     /* mmx */
4834     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
4835     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
4836 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
4837     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4838 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
4839     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4840     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4841     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4842     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4843     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4844     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4845     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4846     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4847     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4848     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4849     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4850     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4851     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4852     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4853     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4854     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4855     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4856     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4857     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4858     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4859     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4860     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4861     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4862 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4863     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4864 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4865     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4866 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4867     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4868 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4869     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4870 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4871     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4872 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4873     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4874 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4875     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4876 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4877     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4878     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4879     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4880     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4881     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4882     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4883     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4884     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4885     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4886     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4887     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4888     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4889     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4890     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4891
4892 #undef ALT
4893 #undef DEF_ASM_OP0
4894 #undef DEF_ASM_OP0L
4895 #undef DEF_ASM_OP1
4896 #undef DEF_ASM_OP2
4897 #undef DEF_ASM_OP3
4898 //---------------------------------------------------------------------------
4899
4900 #define ALT(x)
4901 #define DEF_ASM_OP0(name, opcode)
4902 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
4903 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
4904 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
4905 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
4906 // njn: inlined i386-asm.h
4907 //#include "i386-asm.h"
4908 //---------------------------------------------------------------------------
4909      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
4910      DEF_ASM_OP0(popa, 0x61)
4911      DEF_ASM_OP0(clc, 0xf8)
4912      DEF_ASM_OP0(cld, 0xfc)
4913      DEF_ASM_OP0(cli, 0xfa)
4914      DEF_ASM_OP0(clts, 0x0f06)
4915      DEF_ASM_OP0(cmc, 0xf5)
4916      DEF_ASM_OP0(lahf, 0x9f)
4917      DEF_ASM_OP0(sahf, 0x9e)
4918      DEF_ASM_OP0(pushfl, 0x9c)
4919      DEF_ASM_OP0(popfl, 0x9d)
4920      DEF_ASM_OP0(pushf, 0x9c)
4921      DEF_ASM_OP0(popf, 0x9d)
4922      DEF_ASM_OP0(stc, 0xf9)
4923      DEF_ASM_OP0(std, 0xfd)
4924      DEF_ASM_OP0(sti, 0xfb)
4925      DEF_ASM_OP0(aaa, 0x37)
4926      DEF_ASM_OP0(aas, 0x3f)
4927      DEF_ASM_OP0(daa, 0x27)
4928      DEF_ASM_OP0(das, 0x2f)
4929      DEF_ASM_OP0(aad, 0xd50a)
4930      DEF_ASM_OP0(aam, 0xd40a)
4931      DEF_ASM_OP0(cbw, 0x6698)
4932      DEF_ASM_OP0(cwd, 0x6699)
4933      DEF_ASM_OP0(cwde, 0x98)
4934      DEF_ASM_OP0(cdq, 0x99)
4935      DEF_ASM_OP0(cbtw, 0x6698)
4936      DEF_ASM_OP0(cwtl, 0x98)
4937      DEF_ASM_OP0(cwtd, 0x6699)
4938      DEF_ASM_OP0(cltd, 0x99)
4939      DEF_ASM_OP0(int3, 0xcc)
4940      DEF_ASM_OP0(into, 0xce)
4941      DEF_ASM_OP0(iret, 0xcf)
4942      DEF_ASM_OP0(rsm, 0x0faa)
4943      DEF_ASM_OP0(hlt, 0xf4)
4944      DEF_ASM_OP0(wait, 0x9b)
4945      DEF_ASM_OP0(nop, 0x90)
4946      DEF_ASM_OP0(xlat, 0xd7)
4947
4948      /* strings */
4949 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4950 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4951
4952 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4953 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4954
4955 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4956 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4957
4958 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4959 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4960
4961 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4962 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4963
4964 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4965 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4966
4967      /* bits */
4968      
4969 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4970 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4971
4972 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4973 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4974
4975 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4976 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4977
4978 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4979 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4980
4981 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4982 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4983
4984      /* prefixes */
4985      DEF_ASM_OP0(aword, 0x67)
4986      DEF_ASM_OP0(addr16, 0x67)
4987      DEF_ASM_OP0(word, 0x66)
4988      DEF_ASM_OP0(data16, 0x66)
4989      DEF_ASM_OP0(lock, 0xf0)
4990      DEF_ASM_OP0(rep, 0xf3)
4991      DEF_ASM_OP0(repe, 0xf3)
4992      DEF_ASM_OP0(repz, 0xf3)
4993      DEF_ASM_OP0(repne, 0xf2)
4994      DEF_ASM_OP0(repnz, 0xf2)
4995              
4996      DEF_ASM_OP0(invd, 0x0f08)
4997      DEF_ASM_OP0(wbinvd, 0x0f09)
4998      DEF_ASM_OP0(cpuid, 0x0fa2)
4999      DEF_ASM_OP0(wrmsr, 0x0f30)
5000      DEF_ASM_OP0(rdtsc, 0x0f31)
5001      DEF_ASM_OP0(rdmsr, 0x0f32)
5002      DEF_ASM_OP0(rdpmc, 0x0f33)
5003      DEF_ASM_OP0(ud2, 0x0f0b)
5004
5005      /* NOTE: we took the same order as gas opcode definition order */
5006 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
5007 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
5008 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5009 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5010 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
5011 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
5012
5013 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
5014 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
5015
5016 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
5017 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
5018 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
5019 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
5020 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
5021 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
5022
5023 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
5024 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
5025 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5026 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
5027 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5028
5029 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
5030 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5031 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
5032 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
5033 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
5034
5035 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
5036 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5037 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
5038
5039 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
5040 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
5041 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5042 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5043
5044 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
5045 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
5046 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
5047 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
5048
5049 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
5050 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
5051 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
5052 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
5053
5054 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
5055
5056 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5057 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5058 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5059 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5060 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5061
5062      /* arith */
5063 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
5064 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5065 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
5066 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5067 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
5068
5069 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5070 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5071 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
5072 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5073
5074 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
5075 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5076 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
5077 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5078
5079 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5080 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5081
5082 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5083 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5084
5085 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
5086 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
5087 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
5088 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
5089 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
5090
5091 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5092 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5093 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5094 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5095
5096      /* shifts */
5097 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
5098 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
5099 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
5100
5101 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5102 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5103 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5104 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5105 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5106 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5107
5108 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
5109 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
5110 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
5111 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
5112
5113 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
5114 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
5115 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
5116 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
5117
5118 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
5119 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
5120     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
5121     DEF_ASM_OP0(leave, 0xc9)
5122     DEF_ASM_OP0(ret, 0xc3)
5123 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
5124     DEF_ASM_OP0(lret, 0xcb)
5125 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
5126
5127 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
5128     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5129     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5130     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5131     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5132     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
5133     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
5134      
5135      /* float */
5136      /* specific fcomp handling */
5137 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
5138
5139 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5140 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5141 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
5142 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5143 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5144 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
5145 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
5146 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5147 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5148 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5149 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5150
5151      DEF_ASM_OP0(fucompp, 0xdae9)
5152      DEF_ASM_OP0(ftst, 0xd9e4)
5153      DEF_ASM_OP0(fxam, 0xd9e5)
5154      DEF_ASM_OP0(fld1, 0xd9e8)
5155      DEF_ASM_OP0(fldl2t, 0xd9e9)
5156      DEF_ASM_OP0(fldl2e, 0xd9ea)
5157      DEF_ASM_OP0(fldpi, 0xd9eb)
5158      DEF_ASM_OP0(fldlg2, 0xd9ec)
5159      DEF_ASM_OP0(fldln2, 0xd9ed)
5160      DEF_ASM_OP0(fldz, 0xd9ee)
5161
5162      DEF_ASM_OP0(f2xm1, 0xd9f0)
5163      DEF_ASM_OP0(fyl2x, 0xd9f1)
5164      DEF_ASM_OP0(fptan, 0xd9f2)
5165      DEF_ASM_OP0(fpatan, 0xd9f3)
5166      DEF_ASM_OP0(fxtract, 0xd9f4)
5167      DEF_ASM_OP0(fprem1, 0xd9f5)
5168      DEF_ASM_OP0(fdecstp, 0xd9f6)
5169      DEF_ASM_OP0(fincstp, 0xd9f7)
5170      DEF_ASM_OP0(fprem, 0xd9f8)
5171      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
5172      DEF_ASM_OP0(fsqrt, 0xd9fa)
5173      DEF_ASM_OP0(fsincos, 0xd9fb)
5174      DEF_ASM_OP0(frndint, 0xd9fc)
5175      DEF_ASM_OP0(fscale, 0xd9fd)
5176      DEF_ASM_OP0(fsin, 0xd9fe)
5177      DEF_ASM_OP0(fcos, 0xd9ff)
5178      DEF_ASM_OP0(fchs, 0xd9e0)
5179      DEF_ASM_OP0(fabs, 0xd9e1)
5180      DEF_ASM_OP0(fninit, 0xdbe3)
5181      DEF_ASM_OP0(fnclex, 0xdbe2)
5182      DEF_ASM_OP0(fnop, 0xd9d0)
5183      DEF_ASM_OP0(fwait, 0x9b)
5184
5185     /* fp load */
5186     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
5187     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
5188     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
5189 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
5190     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
5191     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
5192     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
5193     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
5194     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
5195     
5196     /* fp store */
5197     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
5198     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
5199     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
5200     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
5201 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
5202     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
5203     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
5204     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
5205     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
5206     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
5207
5208     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
5209     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
5210     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
5211     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
5212     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
5213
5214     /* exchange */
5215     DEF_ASM_OP0(fxch, 0xd9c9)
5216 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
5217
5218     /* misc FPU */
5219     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
5220     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
5221
5222     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
5223     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
5224     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
5225     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
5226     DEF_ASM_OP0(fnstsw, 0xdfe0)
5227 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
5228 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
5229     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
5230 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
5231 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
5232     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
5233     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
5234     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5235     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
5236     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
5237     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5238     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
5239     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
5240     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
5241     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
5242     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
5243
5244     /* segments */
5245     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
5246     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
5247     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
5248     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
5249     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
5250     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
5251 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
5252     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
5253     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
5254     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
5255     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
5256     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
5257     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
5258     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
5259     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
5260
5261     /* 486 */
5262     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
5263 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5264 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5265     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
5266
5267     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
5268     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
5269
5270     /* pentium */
5271     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
5272     
5273     /* pentium pro */
5274     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
5275
5276     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5277     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5278     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5279     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5280     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5281     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5282     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5283     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5284
5285     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5286     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5287     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5288     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5289
5290     /* mmx */
5291     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
5292     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
5293 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
5294     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5295 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
5296     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5297     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5298     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5299     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5300     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5301     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5302     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5303     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5304     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5305     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5306     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5307     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5308     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5309     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5310     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5311     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5312     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5313     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5314     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5315     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5316     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5317     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5318     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5319 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5320     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5321 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5322     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5323 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5324     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5325 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5326     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5327 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5328     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5329 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5330     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5331 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5332     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5333 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5334     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5335     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5336     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5337     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5338     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5339     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5340     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5341     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5342     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5343     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5344     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5345     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5346     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5347     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5348
5349 #undef ALT
5350 #undef DEF_ASM_OP0
5351 #undef DEF_ASM_OP0L
5352 #undef DEF_ASM_OP1
5353 #undef DEF_ASM_OP2
5354 #undef DEF_ASM_OP3
5355 //---------------------------------------------------------------------------
5356
5357 #endif
5358 //---------------------------------------------------------------------------
5359 #undef DEF
5360 ;
5361
5362 #define TOK_UIDENT TOK_DEFINE
5363
5364 #ifdef WIN32
5365 int __stdcall GetModuleFileNameA(void *, char *, int);
5366 void *__stdcall GetProcAddress(void *, const char *);
5367 void *__stdcall GetModuleHandleA(const char *);
5368 void *__stdcall LoadLibraryA(const char *);
5369 int __stdcall FreeConsole(void);
5370
5371 #define snprintf _snprintf
5372 #define vsnprintf _vsnprintf
5373 #ifndef __GNUC__
5374   #define strtold (long double)strtod
5375   #define strtof (float)strtod
5376   #define strtoll (long long)strtol
5377 #endif
5378 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
5379 /* currently incorrect */
5380 long double strtold(const char *nptr, char **endptr)
5381 {
5382     return (long double)strtod(nptr, endptr);
5383 }
5384 float strtof(const char *nptr, char **endptr)
5385 {
5386     return (float)strtod(nptr, endptr);
5387 }
5388 #else
5389 /* XXX: need to define this to use them in non ISOC99 context */
5390 extern float strtof (const char *__nptr, char **__endptr);
5391 extern long double strtold (const char *__nptr, char **__endptr);
5392 #endif
5393
5394 static char *pstrcpy(char *buf, int buf_size, const char *s);
5395 static char *pstrcat(char *buf, int buf_size, const char *s);
5396 static const char *tcc_basename(const char *name);
5397
5398 static void next(void);
5399 static void next_nomacro(void);
5400 static void parse_expr_type(CType *type);
5401 static void expr_type(CType *type);
5402 static void unary_type(CType *type);
5403 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
5404                   int case_reg, int is_expr);
5405 static int expr_const(void);
5406 static void expr_eq(void);
5407 static void gexpr(void);
5408 static void gen_inline_functions(void);
5409 static void decl(int l);
5410 static void decl_initializer(CType *type, Section *sec, unsigned long c, 
5411                              int first, int size_only);
5412 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
5413                                    int has_init, int v, int scope);
5414 int gv(int rc);
5415 void gv2(int rc1, int rc2);
5416 void move_reg(int r, int s);
5417 void save_regs(int n);
5418 void save_reg(int r);
5419 void vpop(void);
5420 void vswap(void);
5421 void vdup(void);
5422 int get_reg(int rc);
5423 int get_reg_ex(int rc,int rc2);
5424
5425 struct macro_level {
5426     struct macro_level *prev;
5427     int *p;
5428 };
5429
5430 static void macro_subst(TokenString *tok_str, Sym **nested_list, 
5431                         const int *macro_str, struct macro_level **can_read_stream);
5432 void gen_op(int op);
5433 void force_charshort_cast(int t);
5434 static void gen_cast(CType *type);
5435 void vstore(void);
5436 static Sym *sym_find(int v);
5437 static Sym *sym_push(int v, CType *type, int r, int c);
5438
5439 /* type handling */
5440 static int type_size(CType *type, int *a);
5441 static inline CType *pointed_type(CType *type);
5442 static int pointed_size(CType *type);
5443 static int lvalue_type(int t);
5444 static int parse_btype(CType *type, AttributeDef *ad);
5445 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
5446 static int is_compatible_types(CType *type1, CType *type2);
5447
5448 int ieee_finite(double d);
5449 void error(const char *fmt, ...);
5450 void vpushi(int v);
5451 void vrott(int n);
5452 void vnrott(int n);
5453 void lexpand_nr(void);
5454 static void vpush_global_sym(CType *type, int v);
5455 void vset(CType *type, int r, int v);
5456 void type_to_str(char *buf, int buf_size, 
5457                  CType *type, const char *varstr);
5458 char *get_tok_str(int v, CValue *cv);
5459 static Sym *get_sym_ref(CType *type, Section *sec, 
5460                         unsigned long offset, unsigned long size);
5461 static Sym *external_global_sym(int v, CType *type, int r);
5462
5463 /* section generation */
5464 static void section_realloc(Section *sec, unsigned long new_size);
5465 static void *section_ptr_add(Section *sec, unsigned long size);
5466 static void put_extern_sym(Sym *sym, Section *section, 
5467                            unsigned long value, unsigned long size);
5468 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
5469 static int put_elf_str(Section *s, const char *sym);
5470 static int put_elf_sym(Section *s, 
5471                        unsigned long value, unsigned long size,
5472                        int info, int other, int shndx, const char *name);
5473 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
5474                        int info, int other, int sh_num, const char *name);
5475 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
5476                           int type, int symbol);
5477 static void put_stabs(const char *str, int type, int other, int desc, 
5478                       unsigned long value);
5479 static void put_stabs_r(const char *str, int type, int other, int desc, 
5480                         unsigned long value, Section *sec, int sym_index);
5481 static void put_stabn(int type, int other, int desc, int value);
5482 static void put_stabd(int type, int other, int desc);
5483 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
5484
5485 #define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
5486 #define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
5487 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
5488
5489 /* tcccoff.c */
5490 int tcc_output_coff(TCCState *s1, FILE *f);
5491
5492 /* tccpe.c */
5493 void *resolve_sym(TCCState *s1, const char *sym, int type);
5494 int pe_load_def_file(struct TCCState *s1, FILE *fp);
5495 void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
5496 unsigned long pe_add_runtime(struct TCCState *s1);
5497 int tcc_output_pe(struct TCCState *s1, const char *filename);
5498
5499 /* tccasm.c */
5500
5501 #ifdef CONFIG_TCC_ASM
5502
5503 typedef struct ExprValue {
5504     uint32_t v;
5505     Sym *sym;
5506 } ExprValue;
5507
5508 #define MAX_ASM_OPERANDS 30
5509
5510 typedef struct ASMOperand {
5511     int id; /* GCC 3 optionnal identifier (0 if number only supported */
5512     char *constraint;
5513     char asm_str[16]; /* computed asm string for operand */
5514     SValue *vt; /* C value of the expression */
5515     int ref_index; /* if >= 0, gives reference to a output constraint */
5516     int input_index; /* if >= 0, gives reference to an input constraint */
5517     int priority; /* priority, used to assign registers */
5518     int reg; /* if >= 0, register number used for this operand */
5519     int is_llong; /* true if double register value */
5520     int is_memory; /* true if memory operand */
5521     int is_rw;     /* for '+' modifier */
5522 } ASMOperand;
5523
5524 static void asm_expr(TCCState *s1, ExprValue *pe);
5525 static int asm_int_expr(TCCState *s1);
5526 static int find_constraint(ASMOperand *operands, int nb_operands, 
5527                            const char *name, const char **pp);
5528
5529 static int tcc_assemble(TCCState *s1, int do_preprocess);
5530
5531 #endif
5532
5533 static void asm_instr(void);
5534 static void asm_global_instr(void);
5535
5536 /* true if float/double/long double type */
5537 static inline int is_float(int t)
5538 {
5539     int bt;
5540     bt = t & VT_BTYPE;
5541     return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
5542 }
5543
5544 #ifdef TCC_TARGET_I386
5545 // njn: inlined i386-gen.c
5546 //#include "i386-gen.c"
5547 //---------------------------------------------------------------------------
5548 /*
5549  *  X86 code generator for TCC
5550  * 
5551  *  Copyright (c) 2001-2004 Fabrice Bellard
5552  *
5553  * This library is free software; you can redistribute it and/or
5554  * modify it under the terms of the GNU Lesser General Public
5555  * License as published by the Free Software Foundation; either
5556  * version 2 of the License, or (at your option) any later version.
5557  *
5558  * This library is distributed in the hope that it will be useful,
5559  * but WITHOUT ANY WARRANTY; without even the implied warranty of
5560  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
5561  * Lesser General Public License for more details.
5562  *
5563  * You should have received a copy of the GNU Lesser General Public
5564  * License along with this library; if not, write to the Free Software
5565  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
5566  */
5567
5568 /* number of available registers */
5569 #define NB_REGS             4
5570
5571 /* a register can belong to several classes. The classes must be
5572    sorted from more general to more precise (see gv2() code which does
5573    assumptions on it). */
5574 #define RC_INT     0x0001 /* generic integer register */
5575 #define RC_FLOAT   0x0002 /* generic float register */
5576 #define RC_EAX     0x0004
5577 #define RC_ST0     0x0008 
5578 #define RC_ECX     0x0010
5579 #define RC_EDX     0x0020
5580 #define RC_IRET    RC_EAX /* function return: integer register */
5581 #define RC_LRET    RC_EDX /* function return: second integer register */
5582 #define RC_FRET    RC_ST0 /* function return: float register */
5583
5584 /* pretty names for the registers */
5585 enum {
5586     TREG_EAX = 0,
5587     TREG_ECX,
5588     TREG_EDX,
5589     TREG_ST0,
5590 };
5591
5592 int reg_classes[NB_REGS] = {
5593     /* eax */ RC_INT | RC_EAX,
5594     /* ecx */ RC_INT | RC_ECX,
5595     /* edx */ RC_INT | RC_EDX,
5596     /* st0 */ RC_FLOAT | RC_ST0,
5597 };
5598
5599 /* return registers for function */
5600 #define REG_IRET TREG_EAX /* single word int return register */
5601 #define REG_LRET TREG_EDX /* second word return register (for long long) */
5602 #define REG_FRET TREG_ST0 /* float return register */
5603
5604 /* defined if function parameters must be evaluated in reverse order */
5605 #define INVERT_FUNC_PARAMS
5606
5607 /* defined if structures are passed as pointers. Otherwise structures
5608    are directly pushed on stack. */
5609 //#define FUNC_STRUCT_PARAM_AS_PTR
5610
5611 /* pointer size, in bytes */
5612 #define PTR_SIZE 4
5613
5614 /* long double size and alignment, in bytes */
5615 #define LDOUBLE_SIZE  12
5616 #define LDOUBLE_ALIGN 4
5617 /* maximum alignment (for aligned attribute support) */
5618 #define MAX_ALIGN     8
5619
5620 /******************************************************/
5621 /* ELF defines */
5622
5623 #define EM_TCC_TARGET EM_386
5624
5625 /* relocation type for 32 bit data relocation */
5626 #define R_DATA_32   R_386_32
5627 #define R_JMP_SLOT  R_386_JMP_SLOT
5628 #define R_COPY      R_386_COPY
5629
5630 #define ELF_START_ADDR 0x08048000
5631 #define ELF_PAGE_SIZE  0x1000
5632
5633 /******************************************************/
5634
5635 static unsigned long func_sub_sp_offset;
5636 static unsigned long func_bound_offset;
5637 static int func_ret_sub;
5638
5639 /* XXX: make it faster ? */
5640 void g(int c)
5641 {
5642     int ind1;
5643     ind1 = ind + 1;
5644     if (ind1 > cur_text_section->data_allocated)
5645         section_realloc(cur_text_section, ind1);
5646     cur_text_section->data[ind] = c;
5647     ind = ind1;
5648 }
5649
5650 void o(unsigned int c)
5651 {
5652     while (c) {
5653         g(c);
5654         c = c >> 8;
5655     }
5656 }
5657
5658 void gen_le32(int c)
5659 {
5660     g(c);
5661     g(c >> 8);
5662     g(c >> 16);
5663     g(c >> 24);
5664 }
5665
5666 /* output a symbol and patch all calls to it */
5667 void gsym_addr(int t, int a)
5668 {
5669     int n, *ptr;
5670     while (t) {
5671         ptr = (int *)(cur_text_section->data + t);
5672         n = *ptr; /* next value */
5673         *ptr = a - t - 4;
5674         t = n;
5675     }
5676 }
5677
5678 void gsym(int t)
5679 {
5680     gsym_addr(t, ind);
5681 }
5682
5683 /* psym is used to put an instruction with a data field which is a
5684    reference to a symbol. It is in fact the same as oad ! */
5685 #define psym oad
5686
5687 /* instruction + 4 bytes data. Return the address of the data */
5688 static int oad(int c, int s)
5689 {
5690     int ind1;
5691
5692     o(c);
5693     ind1 = ind + 4;
5694     if (ind1 > cur_text_section->data_allocated)
5695         section_realloc(cur_text_section, ind1);
5696     *(int *)(cur_text_section->data + ind) = s;
5697     s = ind;
5698     ind = ind1;
5699     return s;
5700 }
5701
5702 /* output constant with relocation if 'r & VT_SYM' is true */
5703 static void gen_addr32(int r, Sym *sym, int c)
5704 {
5705     if (r & VT_SYM)
5706         greloc(cur_text_section, sym, ind, R_386_32);
5707     gen_le32(c);
5708 }
5709
5710 /* generate a modrm reference. 'op_reg' contains the addtionnal 3
5711    opcode bits */
5712 static void gen_modrm(int op_reg, int r, Sym *sym, int c)
5713 {
5714     op_reg = op_reg << 3;
5715     if ((r & VT_VALMASK) == VT_CONST) {
5716         /* constant memory reference */
5717         o(0x05 | op_reg);
5718         gen_addr32(r, sym, c);
5719     } else if ((r & VT_VALMASK) == VT_LOCAL) {
5720         /* currently, we use only ebp as base */
5721         if (c == (char)c) {
5722             /* short reference */
5723             o(0x45 | op_reg);
5724             g(c);
5725         } else {
5726             oad(0x85 | op_reg, c);
5727         }
5728     } else {
5729         g(0x00 | op_reg | (r & VT_VALMASK));
5730     }
5731 }
5732
5733
5734 /* load 'r' from value 'sv' */
5735 void load(int r, SValue *sv)
5736 {
5737     int v, t, ft, fc, fr;
5738     SValue v1;
5739
5740     fr = sv->r;
5741     ft = sv->type.t;
5742     fc = sv->c.ul;
5743
5744     v = fr & VT_VALMASK;
5745     if (fr & VT_LVAL) {
5746         if (v == VT_LLOCAL) {
5747             v1.type.t = VT_INT;
5748             v1.r = VT_LOCAL | VT_LVAL;
5749             v1.c.ul = fc;
5750             load(r, &v1);
5751             fr = r;
5752         }
5753         if ((ft & VT_BTYPE) == VT_FLOAT) {
5754             o(0xd9); /* flds */
5755             r = 0;
5756         } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
5757             o(0xdd); /* fldl */
5758             r = 0;
5759         } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
5760             o(0xdb); /* fldt */
5761             r = 5;
5762         } else if ((ft & VT_TYPE) == VT_BYTE) {
5763             o(0xbe0f);   /* movsbl */
5764         } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
5765             o(0xb60f);   /* movzbl */
5766         } else if ((ft & VT_TYPE) == VT_SHORT) {
5767             o(0xbf0f);   /* movswl */
5768         } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
5769             o(0xb70f);   /* movzwl */
5770         } else {
5771             o(0x8b);     /* movl */
5772         }
5773         gen_modrm(r, fr, sv->sym, fc);
5774     } else {
5775         if (v == VT_CONST) {
5776             o(0xb8 + r); /* mov $xx, r */
5777             gen_addr32(fr, sv->sym, fc);
5778         } else if (v == VT_LOCAL) {
5779             o(0x8d); /* lea xxx(%ebp), r */
5780             gen_modrm(r, VT_LOCAL, sv->sym, fc);
5781         } else if (v == VT_CMP) {
5782             oad(0xb8 + r, 0); /* mov $0, r */
5783             o(0x0f); /* setxx %br */
5784             o(fc);
5785             o(0xc0 + r);
5786         } else if (v == VT_JMP || v == VT_JMPI) {
5787             t = v & 1;
5788             oad(0xb8 + r, t); /* mov $1, r */
5789             o(0x05eb); /* jmp after */
5790             gsym(fc);
5791             oad(0xb8 + r, t ^ 1); /* mov $0, r */
5792         } else if (v != r) {
5793             o(0x89);
5794             o(0xc0 + r + v * 8); /* mov v, r */
5795         }
5796     }
5797 }
5798
5799 /* store register 'r' in lvalue 'v' */
5800 void store(int r, SValue *v)
5801 {
5802     int fr, bt, ft, fc;
5803
5804     ft = v->type.t;
5805     fc = v->c.ul;
5806     fr = v->r & VT_VALMASK;
5807     bt = ft & VT_BTYPE;
5808     /* XXX: incorrect if float reg to reg */
5809     if (bt == VT_FLOAT) {
5810         o(0xd9); /* fsts */
5811         r = 2;
5812     } else if (bt == VT_DOUBLE) {
5813         o(0xdd); /* fstpl */
5814         r = 2;
5815     } else if (bt == VT_LDOUBLE) {
5816         o(0xc0d9); /* fld %st(0) */
5817         o(0xdb); /* fstpt */
5818         r = 7;
5819     } else {
5820         if (bt == VT_SHORT)
5821             o(0x66);
5822         if (bt == VT_BYTE || bt == VT_BOOL)
5823             o(0x88);
5824         else
5825             o(0x89);
5826     }
5827     if (fr == VT_CONST ||
5828         fr == VT_LOCAL ||
5829         (v->r & VT_LVAL)) {
5830         gen_modrm(r, v->r, v->sym, fc);
5831     } else if (fr != r) {
5832         o(0xc0 + fr + r * 8); /* mov r, fr */
5833     }
5834 }
5835
5836 static void gadd_sp(int val)
5837 {
5838     if (val == (char)val) {
5839         o(0xc483);
5840         g(val);
5841     } else {
5842         oad(0xc481, val); /* add $xxx, %esp */
5843     }
5844 }
5845
5846 /* 'is_jmp' is '1' if it is a jump */
5847 static void gcall_or_jmp(int is_jmp)
5848 {
5849     int r;
5850     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
5851         /* constant case */
5852         if (vtop->r & VT_SYM) {
5853             /* relocation case */
5854             greloc(cur_text_section, vtop->sym, 
5855                    ind + 1, R_386_PC32);
5856         } else {
5857             /* put an empty PC32 relocation */
5858             put_elf_reloc(symtab_section, cur_text_section, 
5859                           ind + 1, R_386_PC32, 0);
5860         }
5861         oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
5862     } else {
5863         /* otherwise, indirect call */
5864         r = gv(RC_INT);
5865         o(0xff); /* call/jmp *r */
5866         o(0xd0 + r + (is_jmp << 4));
5867     }
5868 }
5869
5870 static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
5871
5872 /* Generate function call. The function address is pushed first, then
5873    all the parameters in call order. This functions pops all the
5874    parameters and the function address. */
5875 void gfunc_call(int nb_args)
5876 {
5877     int size, align, r, args_size, i, func_call;
5878     Sym *func_sym;
5879     
5880     args_size = 0;
5881     for(i = 0;i < nb_args; i++) {
5882         if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
5883             size = type_size(&vtop->type, &align);
5884             /* align to stack align size */
5885             size = (size + 3) & ~3;
5886             /* allocate the necessary size on stack */
5887             oad(0xec81, size); /* sub $xxx, %esp */
5888             /* generate structure store */
5889             r = get_reg(RC_INT);
5890             o(0x89); /* mov %esp, r */
5891             o(0xe0 + r);
5892             vset(&vtop->type, r | VT_LVAL, 0);
5893             vswap();
5894             vstore();
5895             args_size += size;
5896         } else if (is_float(vtop->type.t)) {
5897             gv(RC_FLOAT); /* only one float register */
5898             if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
5899                 size = 4;
5900             else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
5901                 size = 8;
5902             else
5903                 size = 12;
5904             oad(0xec81, size); /* sub $xxx, %esp */
5905             if (size == 12)
5906                 o(0x7cdb);
5907             else
5908                 o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
5909             g(0x24);
5910             g(0x00);
5911             args_size += size;
5912         } else {
5913             /* simple type (currently always same size) */
5914             /* XXX: implicit cast ? */
5915             r = gv(RC_INT);
5916             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
5917                 size = 8;
5918                 o(0x50 + vtop->r2); /* push r */
5919             } else {
5920                 size = 4;
5921             }
5922             o(0x50 + r); /* push r */
5923             args_size += size;
5924         }
5925         vtop--;
5926     }
5927     save_regs(0); /* save used temporary registers */
5928     func_sym = vtop->type.ref;
5929     func_call = func_sym->r;
5930     /* fast call case */
5931     if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5932         int fastcall_nb_regs;
5933         fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5934         for(i = 0;i < fastcall_nb_regs; i++) {
5935             if (args_size <= 0)
5936                 break;
5937             o(0x58 + fastcall_regs[i]); /* pop r */
5938             /* XXX: incorrect for struct/floats */
5939             args_size -= 4;
5940         }
5941     }
5942     gcall_or_jmp(0);
5943     if (args_size && func_sym->r != FUNC_STDCALL)
5944         gadd_sp(args_size);
5945     vtop--;
5946 }
5947
5948 #ifdef TCC_TARGET_PE
5949 #define FUNC_PROLOG_SIZE 10
5950 #else
5951 #define FUNC_PROLOG_SIZE 9
5952 #endif
5953
5954 /* generate function prolog of type 't' */
5955 void gfunc_prolog(CType *func_type)
5956 {
5957     int addr, align, size, func_call, fastcall_nb_regs;
5958     int param_index, param_addr;
5959     Sym *sym;
5960     CType *type;
5961
5962     sym = func_type->ref;
5963     func_call = sym->r;
5964     addr = 8;
5965     loc = 0;
5966     if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5967         fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5968     } else {
5969         fastcall_nb_regs = 0;
5970     }
5971     param_index = 0;
5972
5973     ind += FUNC_PROLOG_SIZE;
5974     func_sub_sp_offset = ind;
5975     /* if the function returns a structure, then add an
5976        implicit pointer parameter */
5977     func_vt = sym->type;
5978     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5979         /* XXX: fastcall case ? */
5980         func_vc = addr;
5981         addr += 4;
5982         param_index++;
5983     }
5984     /* define parameters */
5985     while ((sym = sym->next) != NULL) {
5986         type = &sym->type;
5987         size = type_size(type, &align);
5988         size = (size + 3) & ~3;
5989 #ifdef FUNC_STRUCT_PARAM_AS_PTR
5990         /* structs are passed as pointer */
5991         if ((type->t & VT_BTYPE) == VT_STRUCT) {
5992             size = 4;
5993         }
5994 #endif
5995         if (param_index < fastcall_nb_regs) {
5996             /* save FASTCALL register */
5997             loc -= 4;
5998             o(0x89);     /* movl */
5999             gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc);
6000             param_addr = loc;
6001         } else {
6002             param_addr = addr;
6003             addr += size;
6004         }
6005         sym_push(sym->v & ~SYM_FIELD, type,
6006                  VT_LOCAL | VT_LVAL, param_addr);
6007         param_index++;
6008     }
6009     func_ret_sub = 0;
6010     /* pascal type call ? */
6011     if (func_call == FUNC_STDCALL)
6012         func_ret_sub = addr - 8;
6013
6014     /* leave some room for bound checking code */
6015     if (do_bounds_check) {
6016         oad(0xb8, 0); /* lbound section pointer */
6017         oad(0xb8, 0); /* call to function */
6018         func_bound_offset = lbounds_section->data_offset;
6019     }
6020 }
6021
6022 /* generate function epilog */
6023 void gfunc_epilog(void)
6024 {
6025     int v, saved_ind;
6026
6027 #ifdef CONFIG_TCC_BCHECK
6028     if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
6029         int saved_ind;
6030         int *bounds_ptr;
6031         Sym *sym, *sym_data;
6032         /* add end of table info */
6033         bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
6034         *bounds_ptr = 0;
6035         /* generate bound local allocation */
6036         saved_ind = ind;
6037         ind = func_sub_sp_offset;
6038         sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
6039                                func_bound_offset, lbounds_section->data_offset);
6040         greloc(cur_text_section, sym_data,
6041                ind + 1, R_386_32);
6042         oad(0xb8, 0); /* mov %eax, xxx */
6043         sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
6044         greloc(cur_text_section, sym, 
6045                ind + 1, R_386_PC32);
6046         oad(0xe8, -4);
6047         ind = saved_ind;
6048         /* generate bound check local freeing */
6049         o(0x5250); /* save returned value, if any */
6050         greloc(cur_text_section, sym_data,
6051                ind + 1, R_386_32);
6052         oad(0xb8, 0); /* mov %eax, xxx */
6053         sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
6054         greloc(cur_text_section, sym, 
6055                ind + 1, R_386_PC32);
6056         oad(0xe8, -4);
6057         o(0x585a); /* restore returned value, if any */
6058     }
6059 #endif
6060     o(0xc9); /* leave */
6061     if (func_ret_sub == 0) {
6062         o(0xc3); /* ret */
6063     } else {
6064         o(0xc2); /* ret n */
6065         g(func_ret_sub);
6066         g(func_ret_sub >> 8);
6067     }
6068     /* align local size to word & save local variables */
6069     
6070     v = (-loc + 3) & -4; 
6071     saved_ind = ind;
6072     ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
6073 #ifdef TCC_TARGET_PE
6074     if (v >= 4096) {
6075         Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
6076         oad(0xb8, v); /* mov stacksize, %eax */
6077         oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
6078         greloc(cur_text_section, sym, ind-4, R_386_PC32);
6079     } else
6080 #endif
6081     {
6082         o(0xe58955);  /* push %ebp, mov %esp, %ebp */
6083         o(0xec81);  /* sub esp, stacksize */
6084         gen_le32(v);
6085 #if FUNC_PROLOG_SIZE == 10
6086         o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
6087 #endif
6088     }
6089     ind = saved_ind;
6090 }
6091
6092 /* generate a jump to a label */
6093 long gjmp(int t)
6094 {
6095     return psym(0xe9, t);
6096 }
6097
6098 /* generate a jump to a fixed address */
6099 void gjmp_addr(int a)
6100 {
6101     int r;
6102     r = a - ind - 2;
6103     if (r == (char)r) {
6104         g(0xeb);
6105         g(r);
6106     } else {
6107         oad(0xe9, a - ind - 5);
6108     }
6109 }
6110
6111 /* generate a test. set 'inv' to invert test. Stack entry is popped */
6112 int gtst(int inv, int t)
6113 {
6114     int v, *p;
6115
6116     v = vtop->r & VT_VALMASK;
6117     if (v == VT_CMP) {
6118         /* fast case : can jump directly since flags are set */
6119         g(0x0f);
6120         t = psym((vtop->c.i - 16) ^ inv, t);
6121     } else if (v == VT_JMP || v == VT_JMPI) {
6122         /* && or || optimization */
6123         if ((v & 1) == inv) {
6124             /* insert vtop->c jump list in t */
6125             p = &vtop->c.i;
6126             while (*p != 0)
6127                 p = (int *)(cur_text_section->data + *p);
6128             *p = t;
6129             t = vtop->c.i;
6130         } else {
6131             t = gjmp(t);
6132             gsym(vtop->c.i);
6133         }
6134     } else {
6135         if (is_float(vtop->type.t)) {
6136             vpushi(0);
6137             gen_op(TOK_NE);
6138         }
6139         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6140             /* constant jmp optimization */
6141             if ((vtop->c.i != 0) != inv) 
6142                 t = gjmp(t);
6143         } else {
6144             v = gv(RC_INT);
6145             o(0x85);
6146             o(0xc0 + v * 9);
6147             g(0x0f);
6148             t = psym(0x85 ^ inv, t);
6149         }
6150     }
6151     vtop--;
6152     return t;
6153 }
6154
6155 /* generate an integer binary operation */
6156 void gen_opi(int op)
6157 {
6158     int r, fr, opc, c;
6159
6160     switch(op) {
6161     case '+':
6162     case TOK_ADDC1: /* add with carry generation */
6163         opc = 0;
6164     gen_op8:
6165         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6166             /* constant case */
6167             vswap();
6168             r = gv(RC_INT);
6169             vswap();
6170             c = vtop->c.i;
6171             if (c == (char)c) {
6172                 /* XXX: generate inc and dec for smaller code ? */
6173                 o(0x83);
6174                 o(0xc0 | (opc << 3) | r);
6175                 g(c);
6176             } else {
6177                 o(0x81);
6178                 oad(0xc0 | (opc << 3) | r, c);
6179             }
6180         } else {
6181             gv2(RC_INT, RC_INT);
6182             r = vtop[-1].r;
6183             fr = vtop[0].r;
6184             o((opc << 3) | 0x01);
6185             o(0xc0 + r + fr * 8); 
6186         }
6187         vtop--;
6188         if (op >= TOK_ULT && op <= TOK_GT) {
6189             vtop->r = VT_CMP;
6190             vtop->c.i = op;
6191         }
6192         break;
6193     case '-':
6194     case TOK_SUBC1: /* sub with carry generation */
6195         opc = 5;
6196         goto gen_op8;
6197     case TOK_ADDC2: /* add with carry use */
6198         opc = 2;
6199         goto gen_op8;
6200     case TOK_SUBC2: /* sub with carry use */
6201         opc = 3;
6202         goto gen_op8;
6203     case '&':
6204         opc = 4;
6205         goto gen_op8;
6206     case '^':
6207         opc = 6;
6208         goto gen_op8;
6209     case '|':
6210         opc = 1;
6211         goto gen_op8;
6212     case '*':
6213         gv2(RC_INT, RC_INT);
6214         r = vtop[-1].r;
6215         fr = vtop[0].r;
6216         vtop--;
6217         o(0xaf0f); /* imul fr, r */
6218         o(0xc0 + fr + r * 8);
6219         break;
6220     case TOK_SHL:
6221         opc = 4;
6222         goto gen_shift;
6223     case TOK_SHR:
6224         opc = 5;
6225         goto gen_shift;
6226     case TOK_SAR:
6227         opc = 7;
6228     gen_shift:
6229         opc = 0xc0 | (opc << 3);
6230         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6231             /* constant case */
6232             vswap();
6233             r = gv(RC_INT);
6234             vswap();
6235             c = vtop->c.i & 0x1f;
6236             o(0xc1); /* shl/shr/sar $xxx, r */
6237             o(opc | r);
6238             g(c);
6239         } else {
6240             /* we generate the shift in ecx */
6241             gv2(RC_INT, RC_ECX);
6242             r = vtop[-1].r;
6243             o(0xd3); /* shl/shr/sar %cl, r */
6244             o(opc | r);
6245         }
6246         vtop--;
6247         break;
6248     case '/':
6249     case TOK_UDIV:
6250     case TOK_PDIV:
6251     case '%':
6252     case TOK_UMOD:
6253     case TOK_UMULL:
6254         /* first operand must be in eax */
6255         /* XXX: need better constraint for second operand */
6256         gv2(RC_EAX, RC_ECX);
6257         r = vtop[-1].r;
6258         fr = vtop[0].r;
6259         vtop--;
6260         save_reg(TREG_EDX);
6261         if (op == TOK_UMULL) {
6262             o(0xf7); /* mul fr */
6263             o(0xe0 + fr);
6264             vtop->r2 = TREG_EDX;
6265             r = TREG_EAX;
6266         } else {
6267             if (op == TOK_UDIV || op == TOK_UMOD) {
6268                 o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
6269                 o(0xf0 + fr);
6270             } else {
6271                 o(0xf799); /* cltd, idiv fr, %eax */
6272                 o(0xf8 + fr);
6273             }
6274             if (op == '%' || op == TOK_UMOD)
6275                 r = TREG_EDX;
6276             else
6277                 r = TREG_EAX;
6278         }
6279         vtop->r = r;
6280         break;
6281     default:
6282         opc = 7;
6283         goto gen_op8;
6284     }
6285 }
6286
6287 /* generate a floating point operation 'v = t1 op t2' instruction. The
6288    two operands are guaranted to have the same floating point type */
6289 /* XXX: need to use ST1 too */
6290 void gen_opf(int op)
6291 {
6292     int a, ft, fc, swapped, r;
6293
6294     /* convert constants to memory references */
6295     if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
6296         vswap();
6297         gv(RC_FLOAT);
6298         vswap();
6299     }
6300     if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
6301         gv(RC_FLOAT);
6302
6303     /* must put at least one value in the floating point register */
6304     if ((vtop[-1].r & VT_LVAL) &&
6305         (vtop[0].r & VT_LVAL)) {
6306         vswap();
6307         gv(RC_FLOAT);
6308         vswap();
6309     }
6310     swapped = 0;
6311     /* swap the stack if needed so that t1 is the register and t2 is
6312        the memory reference */
6313     if (vtop[-1].r & VT_LVAL) {
6314         vswap();
6315         swapped = 1;
6316     }
6317     if (op >= TOK_ULT && op <= TOK_GT) {
6318         /* load on stack second operand */
6319         load(TREG_ST0, vtop);
6320         save_reg(TREG_EAX); /* eax is used by FP comparison code */
6321         if (op == TOK_GE || op == TOK_GT)
6322             swapped = !swapped;
6323         else if (op == TOK_EQ || op == TOK_NE)
6324             swapped = 0;
6325         if (swapped)
6326             o(0xc9d9); /* fxch %st(1) */
6327         o(0xe9da); /* fucompp */
6328         o(0xe0df); /* fnstsw %ax */
6329         if (op == TOK_EQ) {
6330             o(0x45e480); /* and $0x45, %ah */
6331             o(0x40fC80); /* cmp $0x40, %ah */
6332         } else if (op == TOK_NE) {
6333             o(0x45e480); /* and $0x45, %ah */
6334             o(0x40f480); /* xor $0x40, %ah */
6335             op = TOK_NE;
6336         } else if (op == TOK_GE || op == TOK_LE) {
6337             o(0x05c4f6); /* test $0x05, %ah */
6338             op = TOK_EQ;
6339         } else {
6340             o(0x45c4f6); /* test $0x45, %ah */
6341             op = TOK_EQ;
6342         }
6343         vtop--;
6344         vtop->r = VT_CMP;
6345         vtop->c.i = op;
6346     } else {
6347         /* no memory reference possible for long double operations */
6348         if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
6349             load(TREG_ST0, vtop);
6350             swapped = !swapped;
6351         }
6352         
6353         switch(op) {
6354         default:
6355         case '+':
6356             a = 0;
6357             break;
6358         case '-':
6359             a = 4;
6360             if (swapped)
6361                 a++;
6362             break;
6363         case '*':
6364             a = 1;
6365             break;
6366         case '/':
6367             a = 6;
6368             if (swapped)
6369                 a++;
6370             break;
6371         }
6372         ft = vtop->type.t;
6373         fc = vtop->c.ul;
6374         if ((ft & VT_BTYPE) == VT_LDOUBLE) {
6375             o(0xde); /* fxxxp %st, %st(1) */
6376             o(0xc1 + (a << 3));
6377         } else {
6378             /* if saved lvalue, then we must reload it */
6379             r = vtop->r;
6380             if ((r & VT_VALMASK) == VT_LLOCAL) {
6381                 SValue v1;
6382                 r = get_reg(RC_INT);
6383                 v1.type.t = VT_INT;
6384                 v1.r = VT_LOCAL | VT_LVAL;
6385                 v1.c.ul = fc;
6386                 load(r, &v1);
6387                 fc = 0;
6388             }
6389
6390             if ((ft & VT_BTYPE) == VT_DOUBLE)
6391                 o(0xdc);
6392             else
6393                 o(0xd8);
6394             gen_modrm(a, r, vtop->sym, fc);
6395         }
6396         vtop--;
6397     }
6398 }
6399
6400 /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
6401    and 'long long' cases. */
6402 void gen_cvt_itof(int t)
6403 {
6404     save_reg(TREG_ST0);
6405     gv(RC_INT);
6406     if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
6407         /* signed long long to float/double/long double (unsigned case
6408            is handled generically) */
6409         o(0x50 + vtop->r2); /* push r2 */
6410         o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6411         o(0x242cdf); /* fildll (%esp) */
6412         o(0x08c483); /* add $8, %esp */
6413     } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
6414                (VT_INT | VT_UNSIGNED)) {
6415         /* unsigned int to float/double/long double */
6416         o(0x6a); /* push $0 */
6417         g(0x00);
6418         o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6419         o(0x242cdf); /* fildll (%esp) */
6420         o(0x08c483); /* add $8, %esp */
6421     } else {
6422         /* int to float/double/long double */
6423         o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6424         o(0x2404db); /* fildl (%esp) */
6425         o(0x04c483); /* add $4, %esp */
6426     }
6427     vtop->r = TREG_ST0;
6428 }
6429
6430 /* convert fp to int 't' type */
6431 /* XXX: handle long long case */
6432 void gen_cvt_ftoi(int t)
6433 {
6434     int r, r2, size;
6435     Sym *sym;
6436     CType ushort_type;
6437
6438     ushort_type.t = VT_SHORT | VT_UNSIGNED;
6439
6440     gv(RC_FLOAT);
6441     if (t != VT_INT)
6442         size = 8;
6443     else 
6444         size = 4;
6445     
6446     o(0x2dd9); /* ldcw xxx */
6447     sym = external_global_sym(TOK___tcc_int_fpu_control, 
6448                               &ushort_type, VT_LVAL);
6449     greloc(cur_text_section, sym, 
6450            ind, R_386_32);
6451     gen_le32(0);
6452     
6453     oad(0xec81, size); /* sub $xxx, %esp */
6454     if (size == 4)
6455         o(0x1cdb); /* fistpl */
6456     else
6457         o(0x3cdf); /* fistpll */
6458     o(0x24);
6459     o(0x2dd9); /* ldcw xxx */
6460     sym = external_global_sym(TOK___tcc_fpu_control, 
6461                               &ushort_type, VT_LVAL);
6462     greloc(cur_text_section, sym, 
6463            ind, R_386_32);
6464     gen_le32(0);
6465
6466     r = get_reg(RC_INT);
6467     o(0x58 + r); /* pop r */
6468     if (size == 8) {
6469         if (t == VT_LLONG) {
6470             vtop->r = r; /* mark reg as used */
6471             r2 = get_reg(RC_INT);
6472             o(0x58 + r2); /* pop r2 */
6473             vtop->r2 = r2;
6474         } else {
6475             o(0x04c483); /* add $4, %esp */
6476         }
6477     }
6478     vtop->r = r;
6479 }
6480
6481 /* convert from one floating point type to another */
6482 void gen_cvt_ftof(int t)
6483 {
6484     /* all we have to do on i386 is to put the float in a register */
6485     gv(RC_FLOAT);
6486 }
6487
6488 /* computed goto support */
6489 void ggoto(void)
6490 {
6491     gcall_or_jmp(1);
6492     vtop--;
6493 }
6494
6495 /* bound check support functions */
6496 #ifdef CONFIG_TCC_BCHECK
6497
6498 /* generate a bounded pointer addition */
6499 void gen_bounded_ptr_add(void)
6500 {
6501     Sym *sym;
6502
6503     /* prepare fast i386 function call (args in eax and edx) */
6504     gv2(RC_EAX, RC_EDX);
6505     /* save all temporary registers */
6506     vtop -= 2;
6507     save_regs(0);
6508     /* do a fast function call */
6509     sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
6510     greloc(cur_text_section, sym, 
6511            ind + 1, R_386_PC32);
6512     oad(0xe8, -4);
6513     /* returned pointer is in eax */
6514     vtop++;
6515     vtop->r = TREG_EAX | VT_BOUNDED;
6516     /* address of bounding function call point */
6517     vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 
6518 }
6519
6520 /* patch pointer addition in vtop so that pointer dereferencing is
6521    also tested */
6522 void gen_bounded_ptr_deref(void)
6523 {
6524     int func;
6525     int size, align;
6526     Elf32_Rel *rel;
6527     Sym *sym;
6528
6529     size = 0;
6530     /* XXX: put that code in generic part of tcc */
6531     if (!is_float(vtop->type.t)) {
6532         if (vtop->r & VT_LVAL_BYTE)
6533             size = 1;
6534         else if (vtop->r & VT_LVAL_SHORT)
6535             size = 2;
6536     }
6537     if (!size)
6538         size = type_size(&vtop->type, &align);
6539     switch(size) {
6540     case  1: func = TOK___bound_ptr_indir1; break;
6541     case  2: func = TOK___bound_ptr_indir2; break;
6542     case  4: func = TOK___bound_ptr_indir4; break;
6543     case  8: func = TOK___bound_ptr_indir8; break;
6544     case 12: func = TOK___bound_ptr_indir12; break;
6545     case 16: func = TOK___bound_ptr_indir16; break;
6546     default:
6547         error("unhandled size when derefencing bounded pointer");
6548         func = 0;
6549         break;
6550     }
6551
6552     /* patch relocation */
6553     /* XXX: find a better solution ? */
6554     rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
6555     sym = external_global_sym(func, &func_old_type, 0);
6556     if (!sym->c)
6557         put_extern_sym(sym, NULL, 0, 0);
6558     rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
6559 }
6560 #endif
6561
6562 /* end of X86 code generator */
6563 /*************************************************************/
6564
6565 //---------------------------------------------------------------------------
6566 #endif
6567
6568 // njn: commented these out
6569 //#ifdef TCC_TARGET_ARM
6570 //#include "arm-gen.c"
6571 //#endif
6572 //
6573 //#ifdef TCC_TARGET_C67
6574 //#include "c67-gen.c"
6575 //#endif
6576
6577 #ifdef CONFIG_TCC_STATIC
6578
6579 #define RTLD_LAZY       0x001
6580 #define RTLD_NOW        0x002
6581 #define RTLD_GLOBAL     0x100
6582 #define RTLD_DEFAULT    NULL
6583
6584 /* dummy function for profiling */
6585 void *dlopen(const char *filename, int flag)
6586 {
6587     return NULL;
6588 }
6589
6590 const char *dlerror(void)
6591 {
6592     return "error";
6593 }
6594
6595 typedef struct TCCSyms {
6596     char *str;
6597     void *ptr;
6598 } TCCSyms;
6599
6600 #define TCCSYM(a) { #a, &a, },
6601
6602 /* add the symbol you want here if no dynamic linking is done */
6603 static TCCSyms tcc_syms[] = {
6604 #if !defined(CONFIG_TCCBOOT)
6605     TCCSYM(printf)
6606     TCCSYM(fprintf)
6607     TCCSYM(fopen)
6608     TCCSYM(fclose)
6609 #endif
6610     { NULL, NULL },
6611 };
6612
6613 void *resolve_sym(TCCState *s1, const char *symbol, int type)
6614 {
6615     TCCSyms *p;
6616     p = tcc_syms;
6617     while (p->str != NULL) {
6618         if (!strcmp(p->str, symbol))
6619             return p->ptr;
6620         p++;
6621     }
6622     return NULL;
6623 }
6624
6625 #elif !defined(WIN32)
6626
6627 #include <dlfcn.h>
6628
6629 void *resolve_sym(TCCState *s1, const char *sym, int type)
6630 {
6631   assert(0);
6632   return 0; //dlsym(RTLD_DEFAULT, sym);
6633   // jrs: remove need for dlsym
6634 }
6635
6636 #endif
6637
6638 /********************************************************/
6639
6640 /* we use our own 'finite' function to avoid potential problems with
6641    non standard math libs */
6642 /* XXX: endianness dependent */
6643 int ieee_finite(double d)
6644 {
6645     int *p = (int *)&d;
6646     return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
6647 }
6648
6649 /* copy a string and truncate it. */
6650 static char *pstrcpy(char *buf, int buf_size, const char *s)
6651 {
6652     char *q, *q_end;
6653     int c;
6654
6655     if (buf_size > 0) {
6656         q = buf;
6657         q_end = buf + buf_size - 1;
6658         while (q < q_end) {
6659             c = *s++;
6660             if (c == '\0')
6661                 break;
6662             *q++ = c;
6663         }
6664         *q = '\0';
6665     }
6666     return buf;
6667 }
6668
6669 /* strcat and truncate. */
6670 static char *pstrcat(char *buf, int buf_size, const char *s)
6671 {
6672     int len;
6673     len = strlen(buf);
6674     if (len < buf_size) 
6675         pstrcpy(buf + len, buf_size - len, s);
6676     return buf;
6677 }
6678
6679 static int strstart(const char *str, const char *val, const char **ptr)
6680 {
6681     const char *p, *q;
6682     p = str;
6683     q = val;
6684     while (*q != '\0') {
6685         if (*p != *q)
6686             return 0;
6687         p++;
6688         q++;
6689     }
6690     if (ptr)
6691         *ptr = p;
6692     return 1;
6693 }
6694
6695 /* memory management */
6696 #ifdef MEM_DEBUG
6697 int mem_cur_size;
6698 int mem_max_size;
6699 #endif
6700
6701 static inline void tcc_free(void *ptr)
6702 {
6703 #ifdef MEM_DEBUG
6704     mem_cur_size -= malloc_usable_size(ptr);
6705 #endif
6706     free(ptr);
6707 }
6708
6709 static void *tcc_malloc(unsigned long size)
6710 {
6711     void *ptr;
6712     ptr = malloc(size);
6713     if (!ptr && size)
6714         error("memory full");
6715 #ifdef MEM_DEBUG
6716     mem_cur_size += malloc_usable_size(ptr);
6717     if (mem_cur_size > mem_max_size)
6718         mem_max_size = mem_cur_size;
6719 #endif
6720     return ptr;
6721 }
6722
6723 static void *tcc_mallocz(unsigned long size)
6724 {
6725     void *ptr;
6726     ptr = tcc_malloc(size);
6727     memset(ptr, 0, size);
6728     return ptr;
6729 }
6730
6731 static inline void *tcc_realloc(void *ptr, unsigned long size)
6732 {
6733     void *ptr1;
6734 #ifdef MEM_DEBUG
6735     mem_cur_size -= malloc_usable_size(ptr);
6736 #endif
6737     ptr1 = realloc(ptr, size);
6738 #ifdef MEM_DEBUG
6739     /* NOTE: count not correct if alloc error, but not critical */
6740     mem_cur_size += malloc_usable_size(ptr1);
6741     if (mem_cur_size > mem_max_size)
6742         mem_max_size = mem_cur_size;
6743 #endif
6744     return ptr1;
6745 }
6746
6747 static char *tcc_strdup(const char *str)
6748 {
6749     char *ptr;
6750     ptr = tcc_malloc(strlen(str) + 1);
6751     strcpy(ptr, str);
6752     return ptr;
6753 }
6754
6755 #define free(p) use_tcc_free(p)
6756 #define malloc(s) use_tcc_malloc(s)
6757 #define realloc(p, s) use_tcc_realloc(p, s)
6758
6759 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
6760 {
6761     int nb, nb_alloc;
6762     void **pp;
6763     
6764     nb = *nb_ptr;
6765     pp = *ptab;
6766     /* every power of two we double array size */
6767     if ((nb & (nb - 1)) == 0) {
6768         if (!nb)
6769             nb_alloc = 1;
6770         else
6771             nb_alloc = nb * 2;
6772         pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
6773         if (!pp)
6774             error("memory full");
6775         *ptab = pp;
6776     }
6777     pp[nb++] = data;
6778     *nb_ptr = nb;
6779 }
6780
6781 /* symbol allocator */
6782 static Sym *__sym_malloc(void)
6783 {
6784     Sym *sym_pool, *sym, *last_sym;
6785     int i;
6786
6787     sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
6788
6789     last_sym = sym_free_first;
6790     sym = sym_pool;
6791     for(i = 0; i < SYM_POOL_NB; i++) {
6792         sym->next = last_sym;
6793         last_sym = sym;
6794         sym++;
6795     }
6796     sym_free_first = last_sym;
6797     return last_sym;
6798 }
6799
6800 static inline Sym *sym_malloc(void)
6801 {
6802     Sym *sym;
6803     sym = sym_free_first;
6804     if (!sym)
6805         sym = __sym_malloc();
6806     sym_free_first = sym->next;
6807     return sym;
6808 }
6809
6810 static inline void sym_free(Sym *sym)
6811 {
6812     sym->next = sym_free_first;
6813     sym_free_first = sym;
6814 }
6815
6816 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
6817 {
6818     Section *sec;
6819
6820     sec = tcc_mallocz(sizeof(Section) + strlen(name));
6821     strcpy(sec->name, name);
6822     sec->sh_type = sh_type;
6823     sec->sh_flags = sh_flags;
6824     switch(sh_type) {
6825     case SHT_HASH:
6826     case SHT_REL:
6827     case SHT_DYNSYM:
6828     case SHT_SYMTAB:
6829     case SHT_DYNAMIC:
6830         sec->sh_addralign = 4;
6831         break;
6832     case SHT_STRTAB:
6833         sec->sh_addralign = 1;
6834         break;
6835     default:
6836         sec->sh_addralign = 32; /* default conservative alignment */
6837         break;
6838     }
6839
6840     /* only add section if not private */
6841     if (!(sh_flags & SHF_PRIVATE)) {
6842         sec->sh_num = s1->nb_sections;
6843         dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
6844     }
6845     return sec;
6846 }
6847
6848 static void free_section(Section *s)
6849 {
6850     tcc_free(s->data);
6851     tcc_free(s);
6852 }
6853
6854 /* realloc section and set its content to zero */
6855 static void section_realloc(Section *sec, unsigned long new_size)
6856 {
6857     unsigned long size;
6858     unsigned char *data;
6859     
6860     size = sec->data_allocated;
6861     if (size == 0)
6862         size = 1;
6863     while (size < new_size)
6864         size = size * 2;
6865     data = tcc_realloc(sec->data, size);
6866     if (!data)
6867         error("memory full");
6868     memset(data + sec->data_allocated, 0, size - sec->data_allocated);
6869     sec->data = data;
6870     sec->data_allocated = size;
6871 }
6872
6873 /* reserve at least 'size' bytes in section 'sec' from
6874    sec->data_offset. */
6875 static void *section_ptr_add(Section *sec, unsigned long size)
6876 {
6877     unsigned long offset, offset1;
6878
6879     offset = sec->data_offset;
6880     offset1 = offset + size;
6881     if (offset1 > sec->data_allocated)
6882         section_realloc(sec, offset1);
6883     sec->data_offset = offset1;
6884     return sec->data + offset;
6885 }
6886
6887 /* return a reference to a section, and create it if it does not
6888    exists */
6889 Section *find_section(TCCState *s1, const char *name)
6890 {
6891     Section *sec;
6892     int i;
6893     for(i = 1; i < s1->nb_sections; i++) {
6894         sec = s1->sections[i];
6895         if (!strcmp(name, sec->name)) 
6896             return sec;
6897     }
6898     /* sections are created as PROGBITS */
6899     return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
6900 }
6901
6902 #define SECTION_ABS ((void *)1)
6903
6904 /* update sym->c so that it points to an external symbol in section
6905    'section' with value 'value' */
6906 static void put_extern_sym2(Sym *sym, Section *section, 
6907                             unsigned long value, unsigned long size,
6908                             int can_add_underscore)
6909 {
6910     int sym_type, sym_bind, sh_num, info;
6911     Elf32_Sym *esym;
6912     const char *name;
6913     char buf1[256];
6914
6915     if (section == NULL)
6916         sh_num = SHN_UNDEF;
6917     else if (section == SECTION_ABS) 
6918         sh_num = SHN_ABS;
6919     else
6920         sh_num = section->sh_num;
6921     if (!sym->c) {
6922         if ((sym->type.t & VT_BTYPE) == VT_FUNC)
6923             sym_type = STT_FUNC;
6924         else
6925             sym_type = STT_OBJECT;
6926         if (sym->type.t & VT_STATIC)
6927             sym_bind = STB_LOCAL;
6928         else
6929             sym_bind = STB_GLOBAL;
6930         
6931         name = get_tok_str(sym->v, NULL);
6932 #ifdef CONFIG_TCC_BCHECK
6933         if (do_bounds_check) {
6934             char buf[32];
6935
6936             /* XXX: avoid doing that for statics ? */
6937             /* if bound checking is activated, we change some function
6938                names by adding the "__bound" prefix */
6939             switch(sym->v) {
6940 #if 0
6941             /* XXX: we rely only on malloc hooks */
6942             case TOK_malloc: 
6943             case TOK_free: 
6944             case TOK_realloc: 
6945             case TOK_memalign: 
6946             case TOK_calloc: 
6947 #endif
6948             case TOK_memcpy: 
6949             case TOK_memmove:
6950             case TOK_memset:
6951             case TOK_strlen:
6952             case TOK_strcpy:
6953                 strcpy(buf, "__bound_");
6954                 strcat(buf, name);
6955                 name = buf;
6956                 break;
6957             }
6958         }
6959 #endif
6960         if (tcc_state->leading_underscore && can_add_underscore) {
6961             buf1[0] = '_';
6962             pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
6963             name = buf1;
6964         }
6965         info = ELF32_ST_INFO(sym_bind, sym_type);
6966         sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
6967     } else {
6968         esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6969         esym->st_value = value;
6970         esym->st_size = size;
6971         esym->st_shndx = sh_num;
6972     }
6973 }
6974
6975 static void put_extern_sym(Sym *sym, Section *section, 
6976                            unsigned long value, unsigned long size)
6977 {
6978     put_extern_sym2(sym, section, value, size, 1);
6979 }
6980
6981 /* add a new relocation entry to symbol 'sym' in section 's' */
6982 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
6983 {
6984     if (!sym->c) 
6985         put_extern_sym(sym, NULL, 0, 0);
6986     /* now we can add ELF relocation info */
6987     put_elf_reloc(symtab_section, s, offset, type, sym->c);
6988 }
6989
6990 static inline int isid(int c)
6991 {
6992     return (c >= 'a' && c <= 'z') ||
6993         (c >= 'A' && c <= 'Z') ||
6994         c == '_';
6995 }
6996
6997 static inline int isnum(int c)
6998 {
6999     return c >= '0' && c <= '9';
7000 }
7001
7002 static inline int isoct(int c)
7003 {
7004     return c >= '0' && c <= '7';
7005 }
7006
7007 static inline int toup(int c)
7008 {
7009     if (c >= 'a' && c <= 'z')
7010         return c - 'a' + 'A';
7011     else
7012         return c;
7013 }
7014
7015 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
7016 {
7017     int len;
7018     len = strlen(buf);
7019     vsnprintf(buf + len, buf_size - len, fmt, ap);
7020 }
7021
7022 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
7023 {
7024     va_list ap;
7025     va_start(ap, fmt);
7026     strcat_vprintf(buf, buf_size, fmt, ap);
7027     va_end(ap);
7028 }
7029
7030 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
7031 {
7032     char buf[2048];
7033     BufferedFile **f;
7034     
7035     buf[0] = '\0';
7036     if (file) {
7037         for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
7038             strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", 
7039                           (*f)->filename, (*f)->line_num);
7040         if (file->line_num > 0) {
7041             strcat_printf(buf, sizeof(buf), 
7042                           "%s:%d: ", file->filename, file->line_num);
7043         } else {
7044             strcat_printf(buf, sizeof(buf),
7045                           "%s: ", file->filename);
7046         }
7047     } else {
7048         strcat_printf(buf, sizeof(buf),
7049                       "tcc: ");
7050     }
7051     if (is_warning)
7052         strcat_printf(buf, sizeof(buf), "warning: ");
7053     strcat_vprintf(buf, sizeof(buf), fmt, ap);
7054
7055     if (!s1->error_func) {
7056         /* default case: stderr */
7057         fprintf(stderr, "%s\n", buf);
7058     } else {
7059         s1->error_func(s1->error_opaque, buf);
7060     }
7061     if (!is_warning || s1->warn_error)
7062         s1->nb_errors++;
7063 }
7064
7065 #ifdef LIBTCC
7066 void tcc_set_error_func(TCCState *s, void *error_opaque,
7067                         void (*error_func)(void *opaque, const char *msg))
7068 {
7069     s->error_opaque = error_opaque;
7070     s->error_func = error_func;
7071 }
7072 #endif
7073
7074 /* error without aborting current compilation */
7075 void error_noabort(const char *fmt, ...)
7076 {
7077     TCCState *s1 = tcc_state;
7078     va_list ap;
7079
7080     va_start(ap, fmt);
7081     error1(s1, 0, fmt, ap);
7082     va_end(ap);
7083 }
7084
7085 void error(const char *fmt, ...)
7086 {
7087     TCCState *s1 = tcc_state;
7088     va_list ap;
7089
7090     va_start(ap, fmt);
7091     error1(s1, 0, fmt, ap);
7092     va_end(ap);
7093     /* better than nothing: in some cases, we accept to handle errors */
7094     if (s1->error_set_jmp_enabled) {
7095         longjmp(s1->error_jmp_buf, 1);
7096     } else {
7097         /* XXX: eliminate this someday */
7098         exit(1);
7099     }
7100 }
7101
7102 void expect(const char *msg)
7103 {
7104     error("%s expected", msg);
7105 }
7106
7107 void warning(const char *fmt, ...)
7108 {
7109     TCCState *s1 = tcc_state;
7110     va_list ap;
7111
7112     if (s1->warn_none)
7113         return;
7114
7115     va_start(ap, fmt);
7116     error1(s1, 1, fmt, ap);
7117     va_end(ap);
7118 }
7119
7120 void skip(int c)
7121 {
7122     if (tok != c)
7123         error("'%c' expected", c);
7124     next();
7125 }
7126
7127 static void test_lvalue(void)
7128 {
7129     if (!(vtop->r & VT_LVAL))
7130         expect("lvalue");
7131 }
7132
7133 /* allocate a new token */
7134 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
7135 {
7136     TokenSym *ts, **ptable;
7137     int i;
7138
7139     if (tok_ident >= SYM_FIRST_ANOM) 
7140         error("memory full");
7141
7142     /* expand token table if needed */
7143     i = tok_ident - TOK_IDENT;
7144     if ((i % TOK_ALLOC_INCR) == 0) {
7145         ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
7146         if (!ptable)
7147             error("memory full");
7148         table_ident = ptable;
7149     }
7150
7151     ts = tcc_malloc(sizeof(TokenSym) + len);
7152     table_ident[i] = ts;
7153     ts->tok = tok_ident++;
7154     ts->sym_define = NULL;
7155     ts->sym_label = NULL;
7156     ts->sym_struct = NULL;
7157     ts->sym_identifier = NULL;
7158     ts->len = len;
7159     ts->hash_next = NULL;
7160     memcpy(ts->str, str, len);
7161     ts->str[len] = '\0';
7162     *pts = ts;
7163     return ts;
7164 }
7165
7166 #define TOK_HASH_INIT 1
7167 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
7168
7169 /* find a token and add it if not found */
7170 static TokenSym *tok_alloc(const char *str, int len)
7171 {
7172     TokenSym *ts, **pts;
7173     int i;
7174     unsigned int h;
7175     
7176     h = TOK_HASH_INIT;
7177     for(i=0;i<len;i++)
7178         h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
7179     h &= (TOK_HASH_SIZE - 1);
7180
7181     pts = &hash_ident[h];
7182     for(;;) {
7183         ts = *pts;
7184         if (!ts)
7185             break;
7186         if (ts->len == len && !memcmp(ts->str, str, len))
7187             return ts;
7188         pts = &(ts->hash_next);
7189     }
7190     return tok_alloc_new(pts, str, len);
7191 }
7192
7193 /* CString handling */
7194
7195 static void cstr_realloc(CString *cstr, int new_size)
7196 {
7197     int size;
7198     void *data;
7199
7200     size = cstr->size_allocated;
7201     if (size == 0)
7202         size = 8; /* no need to allocate a too small first string */
7203     while (size < new_size)
7204         size = size * 2;
7205     data = tcc_realloc(cstr->data_allocated, size);
7206     if (!data)
7207         error("memory full");
7208     cstr->data_allocated = data;
7209     cstr->size_allocated = size;
7210     cstr->data = data;
7211 }
7212
7213 /* add a byte */
7214 static inline void cstr_ccat(CString *cstr, int ch)
7215 {
7216     int size;
7217     size = cstr->size + 1;
7218     if (size > cstr->size_allocated)
7219         cstr_realloc(cstr, size);
7220     ((unsigned char *)cstr->data)[size - 1] = ch;
7221     cstr->size = size;
7222 }
7223
7224 static void cstr_cat(CString *cstr, const char *str)
7225 {
7226     int c;
7227     for(;;) {
7228         c = *str;
7229         if (c == '\0')
7230             break;
7231         cstr_ccat(cstr, c);
7232         str++;
7233     }
7234 }
7235
7236 /* add a wide char */
7237 static void cstr_wccat(CString *cstr, int ch)
7238 {
7239     int size;
7240     size = cstr->size + sizeof(int);
7241     if (size > cstr->size_allocated)
7242         cstr_realloc(cstr, size);
7243     *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
7244     cstr->size = size;
7245 }
7246
7247 static void cstr_new(CString *cstr)
7248 {
7249     memset(cstr, 0, sizeof(CString));
7250 }
7251
7252 /* free string and reset it to NULL */
7253 static void cstr_free(CString *cstr)
7254 {
7255     tcc_free(cstr->data_allocated);
7256     cstr_new(cstr);
7257 }
7258
7259 #define cstr_reset(cstr) cstr_free(cstr)
7260
7261 /* XXX: unicode ? */
7262 static void add_char(CString *cstr, int c)
7263 {
7264     if (c == '\'' || c == '\"' || c == '\\') {
7265         /* XXX: could be more precise if char or string */
7266         cstr_ccat(cstr, '\\');
7267     }
7268     if (c >= 32 && c <= 126) {
7269         cstr_ccat(cstr, c);
7270     } else {
7271         cstr_ccat(cstr, '\\');
7272         if (c == '\n') {
7273             cstr_ccat(cstr, 'n');
7274         } else {
7275             cstr_ccat(cstr, '0' + ((c >> 6) & 7));
7276             cstr_ccat(cstr, '0' + ((c >> 3) & 7));
7277             cstr_ccat(cstr, '0' + (c & 7));
7278         }
7279     }
7280 }
7281
7282 /* XXX: buffer overflow */
7283 /* XXX: float tokens */
7284 char *get_tok_str(int v, CValue *cv)
7285 {
7286     static char buf[STRING_MAX_SIZE + 1];
7287     static CString cstr_buf;
7288     CString *cstr;
7289     unsigned char *q;
7290     char *p;
7291     int i, len;
7292
7293     /* NOTE: to go faster, we give a fixed buffer for small strings */
7294     cstr_reset(&cstr_buf);
7295     cstr_buf.data = buf;
7296     cstr_buf.size_allocated = sizeof(buf);
7297     p = buf;
7298
7299     switch(v) {
7300     case TOK_CINT:
7301     case TOK_CUINT:
7302         /* XXX: not quite exact, but only useful for testing */
7303         sprintf(p, "%u", cv->ui);
7304         break;
7305     case TOK_CLLONG:
7306     case TOK_CULLONG:
7307         /* XXX: not quite exact, but only useful for testing  */
7308         sprintf(p, "%Lu", cv->ull);
7309         break;
7310     case TOK_CCHAR:
7311     case TOK_LCHAR:
7312         cstr_ccat(&cstr_buf, '\'');
7313         add_char(&cstr_buf, cv->i);
7314         cstr_ccat(&cstr_buf, '\'');
7315         cstr_ccat(&cstr_buf, '\0');
7316         break;
7317     case TOK_PPNUM:
7318         cstr = cv->cstr;
7319         len = cstr->size - 1;
7320         for(i=0;i<len;i++)
7321             add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7322         cstr_ccat(&cstr_buf, '\0');
7323         break;
7324     case TOK_STR:
7325     case TOK_LSTR:
7326         cstr = cv->cstr;
7327         cstr_ccat(&cstr_buf, '\"');
7328         if (v == TOK_STR) {
7329             len = cstr->size - 1;
7330             for(i=0;i<len;i++)
7331                 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7332         } else {
7333             len = (cstr->size / sizeof(int)) - 1;
7334             for(i=0;i<len;i++)
7335                 add_char(&cstr_buf, ((int *)cstr->data)[i]);
7336         }
7337         cstr_ccat(&cstr_buf, '\"');
7338         cstr_ccat(&cstr_buf, '\0');
7339         break;
7340     case TOK_LT:
7341         v = '<';
7342         goto addv;
7343     case TOK_GT:
7344         v = '>';
7345         goto addv;
7346     case TOK_A_SHL:
7347         return strcpy(p, "<<=");
7348     case TOK_A_SAR:
7349         return strcpy(p, ">>=");
7350     default:
7351         if (v < TOK_IDENT) {
7352             /* search in two bytes table */
7353             q = tok_two_chars;
7354             while (*q) {
7355                 if (q[2] == v) {
7356                     *p++ = q[0];
7357                     *p++ = q[1];
7358                     *p = '\0';
7359                     return buf;
7360                 }
7361                 q += 3;
7362             }
7363         addv:
7364             *p++ = v;
7365             *p = '\0';
7366         } else if (v < tok_ident) {
7367             return table_ident[v - TOK_IDENT]->str;
7368         } else if (v >= SYM_FIRST_ANOM) {
7369             /* special name for anonymous symbol */
7370             sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
7371         } else {
7372             /* should never happen */
7373             return NULL;
7374         }
7375         break;
7376     }
7377     return cstr_buf.data;
7378 }
7379
7380 /* push, without hashing */
7381 static Sym *sym_push2(Sym **ps, long v, long t, long c)
7382 {
7383     Sym *s;
7384     s = sym_malloc();
7385     s->v = v;
7386     s->type.t = t;
7387     s->c = c;
7388     s->next = NULL;
7389     /* add in stack */
7390     s->prev = *ps;
7391     *ps = s;
7392     return s;
7393 }
7394
7395 /* find a symbol and return its associated structure. 's' is the top
7396    of the symbol stack */
7397 static Sym *sym_find2(Sym *s, int v)
7398 {
7399     while (s) {
7400         if (s->v == v)
7401             return s;
7402         s = s->prev;
7403     }
7404     return NULL;
7405 }
7406
7407 /* structure lookup */
7408 static inline Sym *struct_find(int v)
7409 {
7410     v -= TOK_IDENT;
7411     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7412         return NULL;
7413     return table_ident[v]->sym_struct;
7414 }
7415
7416 /* find an identifier */
7417 static inline Sym *sym_find(int v)
7418 {
7419     v -= TOK_IDENT;
7420     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7421         return NULL;
7422     return table_ident[v]->sym_identifier;
7423 }
7424
7425 /* push a given symbol on the symbol stack */
7426 static Sym *sym_push(int v, CType *type, int r, int c)
7427 {
7428     Sym *s, **ps;
7429     TokenSym *ts;
7430
7431     if (local_stack)
7432         ps = &local_stack;
7433     else
7434         ps = &global_stack;
7435     s = sym_push2(ps, v, type->t, c);
7436     s->type.ref = type->ref;
7437     s->r = r;
7438     /* don't record fields or anonymous symbols */
7439     /* XXX: simplify */
7440     if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7441         /* record symbol in token array */
7442         ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7443         if (v & SYM_STRUCT)
7444             ps = &ts->sym_struct;
7445         else
7446             ps = &ts->sym_identifier;
7447         s->prev_tok = *ps;
7448         *ps = s;
7449     }
7450     return s;
7451 }
7452
7453 /* push a global identifier */
7454 static Sym *global_identifier_push(int v, int t, int c)
7455 {
7456     Sym *s, **ps;
7457     s = sym_push2(&global_stack, v, t, c);
7458     /* don't record anonymous symbol */
7459     if (v < SYM_FIRST_ANOM) {
7460         ps = &table_ident[v - TOK_IDENT]->sym_identifier;
7461         /* modify the top most local identifier, so that
7462            sym_identifier will point to 's' when popped */
7463         while (*ps != NULL)
7464             ps = &(*ps)->prev_tok;
7465         s->prev_tok = NULL;
7466         *ps = s;
7467     }
7468     return s;
7469 }
7470
7471 /* pop symbols until top reaches 'b' */
7472 static void sym_pop(Sym **ptop, Sym *b)
7473 {
7474     Sym *s, *ss, **ps;
7475     TokenSym *ts;
7476     int v;
7477
7478     s = *ptop;
7479     while(s != b) {
7480         ss = s->prev;
7481         v = s->v;
7482         /* remove symbol in token array */
7483         /* XXX: simplify */
7484         if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7485             ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7486             if (v & SYM_STRUCT)
7487                 ps = &ts->sym_struct;
7488             else
7489                 ps = &ts->sym_identifier;
7490             *ps = s->prev_tok;
7491         }
7492         sym_free(s);
7493         s = ss;
7494     }
7495     *ptop = b;
7496 }
7497
7498 /* I/O layer */
7499
7500 BufferedFile *tcc_open(TCCState *s1, const char *filename)
7501 {
7502     int fd;
7503     BufferedFile *bf;
7504
7505     fd = open(filename, O_RDONLY | O_BINARY);
7506     if (fd < 0)
7507         return NULL;
7508     bf = tcc_malloc(sizeof(BufferedFile));
7509     if (!bf) {
7510         close(fd);
7511         return NULL;
7512     }
7513     bf->fd = fd;
7514     bf->buf_ptr = bf->buffer;
7515     bf->buf_end = bf->buffer;
7516     bf->buffer[0] = CH_EOB; /* put eob symbol */
7517     pstrcpy(bf->filename, sizeof(bf->filename), filename);
7518     bf->line_num = 1;
7519     bf->ifndef_macro = 0;
7520     bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7521     //    printf("opening '%s'\n", filename);
7522     return bf;
7523 }
7524
7525 void tcc_close(BufferedFile *bf)
7526 {
7527     total_lines += bf->line_num;
7528     close(bf->fd);
7529     tcc_free(bf);
7530 }
7531
7532 /* fill input buffer and peek next char */
7533 static int tcc_peekc_slow(BufferedFile *bf)
7534 {
7535     int len;
7536     /* only tries to read if really end of buffer */
7537     if (bf->buf_ptr >= bf->buf_end) {
7538         if (bf->fd != -1) {
7539 #if defined(PARSE_DEBUG)
7540             len = 8;
7541 #else
7542             len = IO_BUF_SIZE;
7543 #endif
7544             len = read(bf->fd, bf->buffer, len);
7545             if (len < 0)
7546                 len = 0;
7547         } else {
7548             len = 0;
7549         }
7550         total_bytes += len;
7551         bf->buf_ptr = bf->buffer;
7552         bf->buf_end = bf->buffer + len;
7553         *bf->buf_end = CH_EOB;
7554     }
7555     if (bf->buf_ptr < bf->buf_end) {
7556         return bf->buf_ptr[0];
7557     } else {
7558         bf->buf_ptr = bf->buf_end;
7559         return CH_EOF;
7560     }
7561 }
7562
7563 /* return the current character, handling end of block if necessary
7564    (but not stray) */
7565 static int handle_eob(void)
7566 {
7567     return tcc_peekc_slow(file);
7568 }
7569
7570 /* read next char from current input file and handle end of input buffer */
7571 static inline void inp(void)
7572 {
7573     ch = *(++(file->buf_ptr));
7574     /* end of buffer/file handling */
7575     if (ch == CH_EOB)
7576         ch = handle_eob();
7577 }
7578
7579 /* handle '\[\r]\n' */
7580 static void handle_stray(void)
7581 {
7582     while (ch == '\\') {
7583         inp();
7584         if (ch == '\n') {
7585             file->line_num++;
7586             inp();
7587         } else if (ch == '\r') {
7588             inp();
7589             if (ch != '\n')
7590                 goto fail;
7591             file->line_num++;
7592             inp();
7593         } else {
7594         fail:
7595             error("stray '\\' in program");
7596         }
7597     }
7598 }
7599
7600 /* skip the stray and handle the \\n case. Output an error if
7601    incorrect char after the stray */
7602 static int handle_stray1(uint8_t *p)
7603 {
7604     int c;
7605
7606     if (p >= file->buf_end) {
7607         file->buf_ptr = p;
7608         c = handle_eob();
7609         p = file->buf_ptr;
7610         if (c == '\\')
7611             goto parse_stray;
7612     } else {
7613     parse_stray:
7614         file->buf_ptr = p;
7615         ch = *p;
7616         handle_stray();
7617         p = file->buf_ptr;
7618         c = *p;
7619     }
7620     return c;
7621 }
7622
7623 /* handle just the EOB case, but not stray */
7624 #define PEEKC_EOB(c, p)\
7625 {\
7626     p++;\
7627     c = *p;\
7628     if (c == '\\') {\
7629         file->buf_ptr = p;\
7630         c = handle_eob();\
7631         p = file->buf_ptr;\
7632     }\
7633 }
7634
7635 /* handle the complicated stray case */
7636 #define PEEKC(c, p)\
7637 {\
7638     p++;\
7639     c = *p;\
7640     if (c == '\\') {\
7641         c = handle_stray1(p);\
7642         p = file->buf_ptr;\
7643     }\
7644 }
7645
7646 /* input with '\[\r]\n' handling. Note that this function cannot
7647    handle other characters after '\', so you cannot call it inside
7648    strings or comments */
7649 static void minp(void)
7650 {
7651     inp();
7652     if (ch == '\\') 
7653         handle_stray();
7654 }
7655
7656
7657 /* single line C++ comments */
7658 static uint8_t *parse_line_comment(uint8_t *p)
7659 {
7660     int c;
7661
7662     p++;
7663     for(;;) {
7664         c = *p;
7665     redo:
7666         if (c == '\n' || c == CH_EOF) {
7667             break;
7668         } else if (c == '\\') {
7669             file->buf_ptr = p;
7670             c = handle_eob();
7671             p = file->buf_ptr;
7672             if (c == '\\') {
7673                 PEEKC_EOB(c, p);
7674                 if (c == '\n') {
7675                     file->line_num++;
7676                     PEEKC_EOB(c, p);
7677                 } else if (c == '\r') {
7678                     PEEKC_EOB(c, p);
7679                     if (c == '\n') {
7680                         file->line_num++;
7681                         PEEKC_EOB(c, p);
7682                     }
7683                 }
7684             } else {
7685                 goto redo;
7686             }
7687         } else {
7688             p++;
7689         }
7690     }
7691     return p;
7692 }
7693
7694 /* C comments */
7695 static uint8_t *parse_comment(uint8_t *p)
7696 {
7697     int c;
7698     
7699     p++;
7700     for(;;) {
7701         /* fast skip loop */
7702         for(;;) {
7703             c = *p;
7704             if (c == '\n' || c == '*' || c == '\\')
7705                 break;
7706             p++;
7707             c = *p;
7708             if (c == '\n' || c == '*' || c == '\\')
7709                 break;
7710             p++;
7711         }
7712         /* now we can handle all the cases */
7713         if (c == '\n') {
7714             file->line_num++;
7715             p++;
7716         } else if (c == '*') {
7717             p++;
7718             for(;;) {
7719                 c = *p;
7720                 if (c == '*') {
7721                     p++;
7722                 } else if (c == '/') {
7723                     goto end_of_comment;
7724                 } else if (c == '\\') {
7725                     file->buf_ptr = p;
7726                     c = handle_eob();
7727                     p = file->buf_ptr;
7728                     if (c == '\\') {
7729                         /* skip '\[\r]\n', otherwise just skip the stray */
7730                         while (c == '\\') {
7731                             PEEKC_EOB(c, p);
7732                             if (c == '\n') {
7733                                 file->line_num++;
7734                                 PEEKC_EOB(c, p);
7735                             } else if (c == '\r') {
7736                                 PEEKC_EOB(c, p);
7737                                 if (c == '\n') {
7738                                     file->line_num++;
7739                                     PEEKC_EOB(c, p);
7740                                 }
7741                             } else {
7742                                 goto after_star;
7743                             }
7744                         }
7745                     }
7746                 } else {
7747                     break;
7748                 }
7749             }
7750         after_star: ;
7751         } else {
7752             /* stray, eob or eof */
7753             file->buf_ptr = p;
7754             c = handle_eob();
7755             p = file->buf_ptr;
7756             if (c == CH_EOF) {
7757                 error("unexpected end of file in comment");
7758             } else if (c == '\\') {
7759                 p++;
7760             }
7761         }
7762     }
7763  end_of_comment:
7764     p++;
7765     return p;
7766 }
7767
7768 #define cinp minp
7769
7770 /* space exlcuding newline */
7771 static inline int is_space(int ch)
7772 {
7773     return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
7774 }
7775
7776 static inline void skip_spaces(void)
7777 {
7778     while (is_space(ch))
7779         cinp();
7780 }
7781
7782 /* parse a string without interpreting escapes */
7783 static uint8_t *parse_pp_string(uint8_t *p,
7784                                 int sep, CString *str)
7785 {
7786     int c;
7787     p++;
7788     for(;;) {
7789         c = *p;
7790         if (c == sep) {
7791             break;
7792         } else if (c == '\\') {
7793             file->buf_ptr = p;
7794             c = handle_eob();
7795             p = file->buf_ptr;
7796             if (c == CH_EOF) {
7797             unterminated_string:
7798                 /* XXX: indicate line number of start of string */
7799                 error("missing terminating %c character", sep);
7800             } else if (c == '\\') {
7801                 /* escape : just skip \[\r]\n */
7802                 PEEKC_EOB(c, p);
7803                 if (c == '\n') {
7804                     file->line_num++;
7805                     p++;
7806                 } else if (c == '\r') {
7807                     PEEKC_EOB(c, p);
7808                     if (c != '\n')
7809                         expect("'\n' after '\r'");
7810                     file->line_num++;
7811                     p++;
7812                 } else if (c == CH_EOF) {
7813                     goto unterminated_string;
7814                 } else {
7815                     if (str) {
7816                         cstr_ccat(str, '\\');
7817                         cstr_ccat(str, c);
7818                     }
7819                     p++;
7820                 }
7821             }
7822         } else if (c == '\n') {
7823             file->line_num++;
7824             goto add_char;
7825         } else if (c == '\r') {
7826             PEEKC_EOB(c, p);
7827             if (c != '\n') {
7828                 if (str)
7829                     cstr_ccat(str, '\r');
7830             } else {
7831                 file->line_num++;
7832                 goto add_char;
7833             }
7834         } else {
7835         add_char:
7836             if (str)
7837                 cstr_ccat(str, c);
7838             p++;
7839         }
7840     }
7841     p++;
7842     return p;
7843 }
7844
7845 /* skip block of text until #else, #elif or #endif. skip also pairs of
7846    #if/#endif */
7847 void preprocess_skip(void)
7848 {
7849     int a, start_of_line, c;
7850     uint8_t *p;
7851
7852     p = file->buf_ptr;
7853     start_of_line = 1;
7854     a = 0;
7855     for(;;) {
7856     redo_no_start:
7857         c = *p;
7858         switch(c) {
7859         case ' ':
7860         case '\t':
7861         case '\f':
7862         case '\v':
7863         case '\r':
7864             p++;
7865             goto redo_no_start;
7866         case '\n':
7867             start_of_line = 1;
7868             file->line_num++;
7869             p++;
7870             goto redo_no_start;
7871         case '\\':
7872             file->buf_ptr = p;
7873             c = handle_eob();
7874             if (c == CH_EOF) {
7875                 expect("#endif");
7876             } else if (c == '\\') {
7877                 /* XXX: incorrect: should not give an error */
7878                 ch = file->buf_ptr[0];
7879                 handle_stray();
7880             }
7881             p = file->buf_ptr;
7882             goto redo_no_start;
7883             /* skip strings */
7884         case '\"':
7885         case '\'':
7886             p = parse_pp_string(p, c, NULL);
7887             break;
7888             /* skip comments */
7889         case '/':
7890             file->buf_ptr = p;
7891             ch = *p;
7892             minp();
7893             p = file->buf_ptr;
7894             if (ch == '*') {
7895                 p = parse_comment(p);
7896             } else if (ch == '/') {
7897                 p = parse_line_comment(p);
7898             }
7899             break;
7900
7901         case '#':
7902             p++;
7903             if (start_of_line) {
7904                 file->buf_ptr = p;
7905                 next_nomacro();
7906                 p = file->buf_ptr;
7907                 if (a == 0 && 
7908                     (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
7909                     goto the_end;
7910                 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
7911                     a++;
7912                 else if (tok == TOK_ENDIF)
7913                     a--;
7914             }
7915             break;
7916         default:
7917             p++;
7918             break;
7919         }
7920         start_of_line = 0;
7921     }
7922  the_end: ;
7923     file->buf_ptr = p;
7924 }
7925
7926 /* ParseState handling */
7927
7928 /* XXX: currently, no include file info is stored. Thus, we cannot display
7929    accurate messages if the function or data definition spans multiple
7930    files */
7931
7932 /* save current parse state in 's' */
7933 void save_parse_state(ParseState *s)
7934 {
7935     s->line_num = file->line_num;
7936     s->macro_ptr = macro_ptr;
7937     s->tok = tok;
7938     s->tokc = tokc;
7939 }
7940
7941 /* restore parse state from 's' */
7942 void restore_parse_state(ParseState *s)
7943 {
7944     file->line_num = s->line_num;
7945     macro_ptr = s->macro_ptr;
7946     tok = s->tok;
7947     tokc = s->tokc;
7948 }
7949
7950 /* return the number of additional 'ints' necessary to store the
7951    token */
7952 static inline int tok_ext_size(int t)
7953 {
7954     switch(t) {
7955         /* 4 bytes */
7956     case TOK_CINT:
7957     case TOK_CUINT:
7958     case TOK_CCHAR:
7959     case TOK_LCHAR:
7960     case TOK_CFLOAT:
7961     case TOK_LINENUM:
7962         return 1;
7963     case TOK_STR:
7964     case TOK_LSTR:
7965     case TOK_PPNUM:
7966         error("unsupported token");
7967         return 1;
7968     case TOK_CDOUBLE:
7969     case TOK_CLLONG:
7970     case TOK_CULLONG:
7971         return 2;
7972     case TOK_CLDOUBLE:
7973         return LDOUBLE_SIZE / 4;
7974     default:
7975         return 0;
7976     }
7977 }
7978
7979 /* token string handling */
7980
7981 static inline void tok_str_new(TokenString *s)
7982 {
7983     s->str = NULL;
7984     s->len = 0;
7985     s->allocated_len = 0;
7986     s->last_line_num = -1;
7987 }
7988
7989 static void tok_str_free(int *str)
7990 {
7991     tcc_free(str);
7992 }
7993
7994 static int *tok_str_realloc(TokenString *s)
7995 {
7996     int *str, len;
7997
7998     if (s->allocated_len == 0) {
7999         len = 8;
8000     } else {
8001         len = s->allocated_len * 2;
8002     }
8003     str = tcc_realloc(s->str, len * sizeof(int));
8004     if (!str)
8005         error("memory full");
8006     s->allocated_len = len;
8007     s->str = str;
8008     return str;
8009 }
8010
8011 static void tok_str_add(TokenString *s, int t)
8012 {
8013     int len, *str;
8014
8015     len = s->len;
8016     str = s->str;
8017     if (len >= s->allocated_len)
8018         str = tok_str_realloc(s);
8019     str[len++] = t;
8020     s->len = len;
8021 }
8022
8023 static void tok_str_add2(TokenString *s, int t, CValue *cv)
8024 {
8025     int len, *str;
8026
8027     len = s->len;
8028     str = s->str;
8029
8030     /* allocate space for worst case */
8031     if (len + TOK_MAX_SIZE > s->allocated_len)
8032         str = tok_str_realloc(s);
8033     str[len++] = t;
8034     switch(t) {
8035     case TOK_CINT:
8036     case TOK_CUINT:
8037     case TOK_CCHAR:
8038     case TOK_LCHAR:
8039     case TOK_CFLOAT:
8040     case TOK_LINENUM:
8041         str[len++] = cv->tab[0];
8042         break;
8043     case TOK_PPNUM:
8044     case TOK_STR:
8045     case TOK_LSTR:
8046         {
8047             int nb_words;
8048             CString *cstr;
8049
8050             nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
8051             while ((len + nb_words) > s->allocated_len)
8052                 str = tok_str_realloc(s);
8053             cstr = (CString *)(str + len);
8054             cstr->data = NULL;
8055             cstr->size = cv->cstr->size;
8056             cstr->data_allocated = NULL;
8057             cstr->size_allocated = cstr->size;
8058             memcpy((char *)cstr + sizeof(CString), 
8059                    cv->cstr->data, cstr->size);
8060             len += nb_words;
8061         }
8062         break;
8063     case TOK_CDOUBLE:
8064     case TOK_CLLONG:
8065     case TOK_CULLONG:
8066 #if LDOUBLE_SIZE == 8
8067     case TOK_CLDOUBLE:
8068 #endif
8069         str[len++] = cv->tab[0];
8070         str[len++] = cv->tab[1];
8071         break;
8072 #if LDOUBLE_SIZE == 12
8073     case TOK_CLDOUBLE:
8074         str[len++] = cv->tab[0];
8075         str[len++] = cv->tab[1];
8076         str[len++] = cv->tab[2];
8077 #elif LDOUBLE_SIZE != 8
8078 #error add long double size support
8079 #endif
8080         break;
8081     default:
8082         break;
8083     }
8084     s->len = len;
8085 }
8086
8087 /* add the current parse token in token string 's' */
8088 static void tok_str_add_tok(TokenString *s)
8089 {
8090     CValue cval;
8091
8092     /* save line number info */
8093     if (file->line_num != s->last_line_num) {
8094         s->last_line_num = file->line_num;
8095         cval.i = s->last_line_num;
8096         tok_str_add2(s, TOK_LINENUM, &cval);
8097     }
8098     tok_str_add2(s, tok, &tokc);
8099 }
8100
8101 #if LDOUBLE_SIZE == 12
8102 #define LDOUBLE_GET(p, cv)                      \
8103         cv.tab[0] = p[0];                       \
8104         cv.tab[1] = p[1];                       \
8105         cv.tab[2] = p[2];
8106 #elif LDOUBLE_SIZE == 8
8107 #define LDOUBLE_GET(p, cv)                      \
8108         cv.tab[0] = p[0];                       \
8109         cv.tab[1] = p[1];
8110 #else
8111 #error add long double size support
8112 #endif
8113
8114
8115 /* get a token from an integer array and increment pointer
8116    accordingly. we code it as a macro to avoid pointer aliasing. */
8117 #define TOK_GET(t, p, cv)                       \
8118 {                                               \
8119     t = *p++;                                   \
8120     switch(t) {                                 \
8121     case TOK_CINT:                              \
8122     case TOK_CUINT:                             \
8123     case TOK_CCHAR:                             \
8124     case TOK_LCHAR:                             \
8125     case TOK_CFLOAT:                            \
8126     case TOK_LINENUM:                           \
8127         cv.tab[0] = *p++;                       \
8128         break;                                  \
8129     case TOK_STR:                               \
8130     case TOK_LSTR:                              \
8131     case TOK_PPNUM:                             \
8132         cv.cstr = (CString *)p;                 \
8133         cv.cstr->data = (char *)p + sizeof(CString);\
8134         p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
8135         break;                                  \
8136     case TOK_CDOUBLE:                           \
8137     case TOK_CLLONG:                            \
8138     case TOK_CULLONG:                           \
8139         cv.tab[0] = p[0];                       \
8140         cv.tab[1] = p[1];                       \
8141         p += 2;                                 \
8142         break;                                  \
8143     case TOK_CLDOUBLE:                          \
8144         LDOUBLE_GET(p, cv);                     \
8145         p += LDOUBLE_SIZE / 4;                  \
8146         break;                                  \
8147     default:                                    \
8148         break;                                  \
8149     }                                           \
8150 }
8151
8152 /* defines handling */
8153 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
8154 {
8155     Sym *s;
8156
8157     s = sym_push2(&define_stack, v, macro_type, (long)str);
8158     s->next = first_arg;
8159     table_ident[v - TOK_IDENT]->sym_define = s;
8160 }
8161
8162 /* undefined a define symbol. Its name is just set to zero */
8163 static void define_undef(Sym *s)
8164 {
8165     int v;
8166     v = s->v;
8167     if (v >= TOK_IDENT && v < tok_ident)
8168         table_ident[v - TOK_IDENT]->sym_define = NULL;
8169     s->v = 0;
8170 }
8171
8172 static inline Sym *define_find(int v)
8173 {
8174     v -= TOK_IDENT;
8175     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8176         return NULL;
8177     return table_ident[v]->sym_define;
8178 }
8179
8180 /* free define stack until top reaches 'b' */
8181 static void free_defines(Sym *b)
8182 {
8183     Sym *top, *top1;
8184     int v;
8185
8186     top = define_stack;
8187     while (top != b) {
8188         top1 = top->prev;
8189         /* do not free args or predefined defines */
8190         if (top->c)
8191             tok_str_free((int *)top->c);
8192         v = top->v;
8193         if (v >= TOK_IDENT && v < tok_ident)
8194             table_ident[v - TOK_IDENT]->sym_define = NULL;
8195         sym_free(top);
8196         top = top1;
8197     }
8198     define_stack = b;
8199 }
8200
8201 /* label lookup */
8202 static Sym *label_find(int v)
8203 {
8204     v -= TOK_IDENT;
8205     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8206         return NULL;
8207     return table_ident[v]->sym_label;
8208 }
8209
8210 static Sym *label_push(Sym **ptop, int v, int flags)
8211 {
8212     Sym *s, **ps;
8213     s = sym_push2(ptop, v, 0, 0);
8214     s->r = flags;
8215     ps = &table_ident[v - TOK_IDENT]->sym_label;
8216     if (ptop == &global_label_stack) {
8217         /* modify the top most local identifier, so that
8218            sym_identifier will point to 's' when popped */
8219         while (*ps != NULL)
8220             ps = &(*ps)->prev_tok;
8221     }
8222     s->prev_tok = *ps;
8223     *ps = s;
8224     return s;
8225 }
8226
8227 /* pop labels until element last is reached. Look if any labels are
8228    undefined. Define symbols if '&&label' was used. */
8229 static void label_pop(Sym **ptop, Sym *slast)
8230 {
8231     Sym *s, *s1;
8232     for(s = *ptop; s != slast; s = s1) {
8233         s1 = s->prev;
8234         if (s->r == LABEL_DECLARED) {
8235             warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
8236         } else if (s->r == LABEL_FORWARD) {
8237                 error("label '%s' used but not defined",
8238                       get_tok_str(s->v, NULL));
8239         } else {
8240             if (s->c) {
8241                 /* define corresponding symbol. A size of
8242                    1 is put. */
8243                 put_extern_sym(s, cur_text_section, (long)s->next, 1);
8244             }
8245         }
8246         /* remove label */
8247         table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
8248         sym_free(s);
8249     }
8250     *ptop = slast;
8251 }
8252
8253 /* eval an expression for #if/#elif */
8254 static int expr_preprocess(void)
8255 {
8256     int c, t;
8257     TokenString str;
8258     
8259     tok_str_new(&str);
8260     while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8261         next(); /* do macro subst */
8262         if (tok == TOK_DEFINED) {
8263             next_nomacro();
8264             t = tok;
8265             if (t == '(') 
8266                 next_nomacro();
8267             c = define_find(tok) != 0;
8268             if (t == '(')
8269                 next_nomacro();
8270             tok = TOK_CINT;
8271             tokc.i = c;
8272         } else if (tok >= TOK_IDENT) {
8273             /* if undefined macro */
8274             tok = TOK_CINT;
8275             tokc.i = 0;
8276         }
8277         tok_str_add_tok(&str);
8278     }
8279     tok_str_add(&str, -1); /* simulate end of file */
8280     tok_str_add(&str, 0);
8281     /* now evaluate C constant expression */
8282     macro_ptr = str.str;
8283     next();
8284     c = expr_const();
8285     macro_ptr = NULL;
8286     tok_str_free(str.str);
8287     return c != 0;
8288 }
8289
8290 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
8291 static void tok_print(int *str)
8292 {
8293     int t;
8294     CValue cval;
8295
8296     while (1) {
8297         TOK_GET(t, str, cval);
8298         if (!t)
8299             break;
8300         printf(" %s", get_tok_str(t, &cval));
8301     }
8302     printf("\n");
8303 }
8304 #endif
8305
8306 /* parse after #define */
8307 static void parse_define(void)
8308 {
8309     Sym *s, *first, **ps;
8310     int v, t, varg, is_vaargs, c;
8311     TokenString str;
8312     
8313     v = tok;
8314     if (v < TOK_IDENT)
8315         error("invalid macro name '%s'", get_tok_str(tok, &tokc));
8316     /* XXX: should check if same macro (ANSI) */
8317     first = NULL;
8318     t = MACRO_OBJ;
8319     /* '(' must be just after macro definition for MACRO_FUNC */
8320     c = file->buf_ptr[0];
8321     if (c == '\\')
8322         c = handle_stray1(file->buf_ptr);
8323     if (c == '(') {
8324         next_nomacro();
8325         next_nomacro();
8326         ps = &first;
8327         while (tok != ')') {
8328             varg = tok;
8329             next_nomacro();
8330             is_vaargs = 0;
8331             if (varg == TOK_DOTS) {
8332                 varg = TOK___VA_ARGS__;
8333                 is_vaargs = 1;
8334             } else if (tok == TOK_DOTS && gnu_ext) {
8335                 is_vaargs = 1;
8336                 next_nomacro();
8337             }
8338             if (varg < TOK_IDENT)
8339                 error("badly punctuated parameter list");
8340             s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
8341             *ps = s;
8342             ps = &s->next;
8343             if (tok != ',')
8344                 break;
8345             next_nomacro();
8346         }
8347         t = MACRO_FUNC;
8348     }
8349     tok_str_new(&str);
8350     next_nomacro();
8351     /* EOF testing necessary for '-D' handling */
8352     while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8353         tok_str_add2(&str, tok, &tokc);
8354         next_nomacro();
8355     }
8356     tok_str_add(&str, 0);
8357 #ifdef PP_DEBUG
8358     printf("define %s %d: ", get_tok_str(v, NULL), t);
8359     tok_print(str.str);
8360 #endif
8361     define_push(v, t, str.str, first);
8362 }
8363
8364 static inline int hash_cached_include(int type, const char *filename)
8365 {
8366     const unsigned char *s;
8367     unsigned int h;
8368
8369     h = TOK_HASH_INIT;
8370     h = TOK_HASH_FUNC(h, type);
8371     s = filename;
8372     while (*s) {
8373         h = TOK_HASH_FUNC(h, *s);
8374         s++;
8375     }
8376     h &= (CACHED_INCLUDES_HASH_SIZE - 1);
8377     return h;
8378 }
8379
8380 /* XXX: use a token or a hash table to accelerate matching ? */
8381 static CachedInclude *search_cached_include(TCCState *s1,
8382                                             int type, const char *filename)
8383 {
8384     CachedInclude *e;
8385     int i, h;
8386     h = hash_cached_include(type, filename);
8387     i = s1->cached_includes_hash[h];
8388     for(;;) {
8389         if (i == 0)
8390             break;
8391         e = s1->cached_includes[i - 1];
8392         if (e->type == type && !strcmp(e->filename, filename))
8393             return e;
8394         i = e->hash_next;
8395     }
8396     return NULL;
8397 }
8398
8399 static inline void add_cached_include(TCCState *s1, int type, 
8400                                       const char *filename, int ifndef_macro)
8401 {
8402     CachedInclude *e;
8403     int h;
8404
8405     if (search_cached_include(s1, type, filename))
8406         return;
8407 #ifdef INC_DEBUG
8408     printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
8409 #endif
8410     e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
8411     if (!e)
8412         return;
8413     e->type = type;
8414     strcpy(e->filename, filename);
8415     e->ifndef_macro = ifndef_macro;
8416     dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
8417     /* add in hash table */
8418     h = hash_cached_include(type, filename);
8419     e->hash_next = s1->cached_includes_hash[h];
8420     s1->cached_includes_hash[h] = s1->nb_cached_includes;
8421 }
8422
8423 static void pragma_parse(TCCState *s1)
8424 {
8425     int val;
8426
8427     next();
8428     if (tok == TOK_pack) {
8429         /*
8430           This may be:
8431           #pragma pack(1) // set
8432           #pragma pack() // reset to default
8433           #pragma pack(push,1) // push & set
8434           #pragma pack(pop) // restore previous
8435         */
8436         next();
8437         skip('(');
8438         if (tok == TOK_ASM_pop) {
8439             next();
8440             if (s1->pack_stack_ptr <= s1->pack_stack) {
8441             stk_error:
8442                 error("out of pack stack");
8443             }
8444             s1->pack_stack_ptr--;
8445         } else {
8446             val = 0;
8447             if (tok != ')') {
8448                 if (tok == TOK_ASM_push) {
8449                     next();
8450                     if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
8451                         goto stk_error;
8452                     s1->pack_stack_ptr++;
8453                     skip(',');
8454                 }
8455                 if (tok != TOK_CINT) {
8456                 pack_error:
8457                     error("invalid pack pragma");
8458                 }
8459                 val = tokc.i;
8460                 if (val < 1 || val > 16 || (val & (val - 1)) != 0)
8461                     goto pack_error;
8462                 next();
8463             }
8464             *s1->pack_stack_ptr = val;
8465             skip(')');
8466         }
8467     }
8468 }
8469
8470 /* is_bof is true if first non space token at beginning of file */
8471 static void preprocess(int is_bof)
8472 {
8473     TCCState *s1 = tcc_state;
8474     int size, i, c, n, saved_parse_flags;
8475     char buf[1024], *q, *p;
8476     char buf1[1024];
8477     BufferedFile *f;
8478     Sym *s;
8479     CachedInclude *e;
8480     
8481     saved_parse_flags = parse_flags;
8482     parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 
8483         PARSE_FLAG_LINEFEED;
8484     next_nomacro();
8485  redo:
8486     switch(tok) {
8487     case TOK_DEFINE:
8488         next_nomacro();
8489         parse_define();
8490         break;
8491     case TOK_UNDEF:
8492         next_nomacro();
8493         s = define_find(tok);
8494         /* undefine symbol by putting an invalid name */
8495         if (s)
8496             define_undef(s);
8497         break;
8498     case TOK_INCLUDE:
8499     case TOK_INCLUDE_NEXT:
8500         ch = file->buf_ptr[0];
8501         /* XXX: incorrect if comments : use next_nomacro with a special mode */
8502         skip_spaces();
8503         if (ch == '<') {
8504             c = '>';
8505             goto read_name;
8506         } else if (ch == '\"') {
8507             c = ch;
8508         read_name:
8509             /* XXX: better stray handling */
8510             minp();
8511             q = buf;
8512             while (ch != c && ch != '\n' && ch != CH_EOF) {
8513                 if ((q - buf) < sizeof(buf) - 1)
8514                     *q++ = ch;
8515                 minp();
8516             }
8517             *q = '\0';
8518             minp();
8519 #if 0
8520             /* eat all spaces and comments after include */
8521             /* XXX: slightly incorrect */
8522             while (ch1 != '\n' && ch1 != CH_EOF)
8523                 inp();
8524 #endif
8525         } else {
8526             /* computed #include : either we have only strings or
8527                we have anything enclosed in '<>' */
8528             next();
8529             buf[0] = '\0';
8530             if (tok == TOK_STR) {
8531                 while (tok != TOK_LINEFEED) {
8532                     if (tok != TOK_STR) {
8533                     include_syntax:
8534                         error("'#include' expects \"FILENAME\" or <FILENAME>");
8535                     }
8536                     pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
8537                     next();
8538                 }
8539                 c = '\"';
8540             } else {
8541                 int len;
8542                 while (tok != TOK_LINEFEED) {
8543                     pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
8544                     next();
8545                 }
8546                 len = strlen(buf);
8547                 /* check syntax and remove '<>' */
8548                 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
8549                     goto include_syntax;
8550                 memmove(buf, buf + 1, len - 2);
8551                 buf[len - 2] = '\0';
8552                 c = '>';
8553             }
8554         }
8555
8556         e = search_cached_include(s1, c, buf);
8557         if (e && define_find(e->ifndef_macro)) {
8558             /* no need to parse the include because the 'ifndef macro'
8559                is defined */
8560 #ifdef INC_DEBUG
8561             printf("%s: skipping %s\n", file->filename, buf);
8562 #endif
8563         } else {
8564             if (c == '\"') {
8565                 /* first search in current dir if "header.h" */
8566                 size = 0;
8567                 p = strrchr(file->filename, '/');
8568                 if (p) 
8569                     size = p + 1 - file->filename;
8570                 if (size > sizeof(buf1) - 1)
8571                     size = sizeof(buf1) - 1;
8572                 memcpy(buf1, file->filename, size);
8573                 buf1[size] = '\0';
8574                 pstrcat(buf1, sizeof(buf1), buf);
8575                 f = tcc_open(s1, buf1);
8576                 if (f) {
8577                     if (tok == TOK_INCLUDE_NEXT)
8578                         tok = TOK_INCLUDE;
8579                     else
8580                         goto found;
8581                 }
8582             }
8583             if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
8584                 error("#include recursion too deep");
8585             /* now search in all the include paths */
8586             n = s1->nb_include_paths + s1->nb_sysinclude_paths;
8587             for(i = 0; i < n; i++) {
8588                 const char *path;
8589                 if (i < s1->nb_include_paths)
8590                     path = s1->include_paths[i];
8591                 else
8592                     path = s1->sysinclude_paths[i - s1->nb_include_paths];
8593                 pstrcpy(buf1, sizeof(buf1), path);
8594                 pstrcat(buf1, sizeof(buf1), "/");
8595                 pstrcat(buf1, sizeof(buf1), buf);
8596                 f = tcc_open(s1, buf1);
8597                 if (f) {
8598                     if (tok == TOK_INCLUDE_NEXT)
8599                         tok = TOK_INCLUDE;
8600                     else
8601                         goto found;
8602                 }
8603             }
8604             error("include file '%s' not found", buf);
8605             f = NULL;
8606         found:
8607 #ifdef INC_DEBUG
8608             printf("%s: including %s\n", file->filename, buf1);
8609 #endif
8610             f->inc_type = c;
8611             pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
8612             /* push current file in stack */
8613             /* XXX: fix current line init */
8614             *s1->include_stack_ptr++ = file;
8615             file = f;
8616             /* add include file debug info */
8617             if (do_debug) {
8618                 put_stabs(file->filename, N_BINCL, 0, 0, 0);
8619             }
8620             tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
8621             ch = file->buf_ptr[0];
8622             goto the_end;
8623         }
8624         break;
8625     case TOK_IFNDEF:
8626         c = 1;
8627         goto do_ifdef;
8628     case TOK_IF:
8629         c = expr_preprocess();
8630         goto do_if;
8631     case TOK_IFDEF:
8632         c = 0;
8633     do_ifdef:
8634         next_nomacro();
8635         if (tok < TOK_IDENT)
8636             error("invalid argument for '#if%sdef'", c ? "n" : "");
8637         if (is_bof) {
8638             if (c) {
8639 #ifdef INC_DEBUG
8640                 printf("#ifndef %s\n", get_tok_str(tok, NULL));
8641 #endif
8642                 file->ifndef_macro = tok;
8643             }
8644         }
8645         c = (define_find(tok) != 0) ^ c;
8646     do_if:
8647         if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
8648             error("memory full");
8649         *s1->ifdef_stack_ptr++ = c;
8650         goto test_skip;
8651     case TOK_ELSE:
8652         if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8653             error("#else without matching #if");
8654         if (s1->ifdef_stack_ptr[-1] & 2)
8655             error("#else after #else");
8656         c = (s1->ifdef_stack_ptr[-1] ^= 3);
8657         goto test_skip;
8658     case TOK_ELIF:
8659         if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8660             error("#elif without matching #if");
8661         c = s1->ifdef_stack_ptr[-1];
8662         if (c > 1)
8663             error("#elif after #else");
8664         /* last #if/#elif expression was true: we skip */
8665         if (c == 1)
8666             goto skip;
8667         c = expr_preprocess();
8668         s1->ifdef_stack_ptr[-1] = c;
8669     test_skip:
8670         if (!(c & 1)) {
8671         skip:
8672             preprocess_skip();
8673             is_bof = 0;
8674             goto redo;
8675         }
8676         break;
8677     case TOK_ENDIF:
8678         if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
8679             error("#endif without matching #if");
8680         s1->ifdef_stack_ptr--;
8681         /* '#ifndef macro' was at the start of file. Now we check if
8682            an '#endif' is exactly at the end of file */
8683         if (file->ifndef_macro &&
8684             s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
8685             file->ifndef_macro_saved = file->ifndef_macro;
8686             /* need to set to zero to avoid false matches if another
8687                #ifndef at middle of file */
8688             file->ifndef_macro = 0;
8689             while (tok != TOK_LINEFEED)
8690                 next_nomacro();
8691             tok_flags |= TOK_FLAG_ENDIF;
8692             goto the_end;
8693         }
8694         break;
8695     case TOK_LINE:
8696         next();
8697         if (tok != TOK_CINT)
8698             error("#line");
8699         file->line_num = tokc.i - 1; /* the line number will be incremented after */
8700         next();
8701         if (tok != TOK_LINEFEED) {
8702             if (tok != TOK_STR)
8703                 error("#line");
8704             pstrcpy(file->filename, sizeof(file->filename), 
8705                     (char *)tokc.cstr->data);
8706         }
8707         break;
8708     case TOK_ERROR:
8709     case TOK_WARNING:
8710         c = tok;
8711         ch = file->buf_ptr[0];
8712         skip_spaces();
8713         q = buf;
8714         while (ch != '\n' && ch != CH_EOF) {
8715             if ((q - buf) < sizeof(buf) - 1)
8716                 *q++ = ch;
8717             minp();
8718         }
8719         *q = '\0';
8720         if (c == TOK_ERROR)
8721             error("#error %s", buf);
8722         else
8723             warning("#warning %s", buf);
8724         break;
8725     case TOK_PRAGMA:
8726         pragma_parse(s1);
8727         break;
8728     default:
8729         if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
8730             /* '!' is ignored to allow C scripts. numbers are ignored
8731                to emulate cpp behaviour */
8732         } else {
8733             if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
8734                 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
8735         }
8736         break;
8737     }
8738     /* ignore other preprocess commands or #! for C scripts */
8739     while (tok != TOK_LINEFEED)
8740         next_nomacro();
8741  the_end:
8742     parse_flags = saved_parse_flags;
8743 }
8744
8745 /* evaluate escape codes in a string. */
8746 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
8747 {
8748     int c, n;
8749     const uint8_t *p;
8750
8751     p = buf;
8752     for(;;) {
8753         c = *p;
8754         if (c == '\0')
8755             break;
8756         if (c == '\\') {
8757             p++;
8758             /* escape */
8759             c = *p;
8760             switch(c) {
8761             case '0': case '1': case '2': case '3':
8762             case '4': case '5': case '6': case '7':
8763                 /* at most three octal digits */
8764                 n = c - '0';
8765                 p++;
8766                 c = *p;
8767                 if (isoct(c)) {
8768                     n = n * 8 + c - '0';
8769                     p++;
8770                     c = *p;
8771                     if (isoct(c)) {
8772                         n = n * 8 + c - '0';
8773                         p++;
8774                     }
8775                 }
8776                 c = n;
8777                 goto add_char_nonext;
8778             case 'x':
8779                 p++;
8780                 n = 0;
8781                 for(;;) {
8782                     c = *p;
8783                     if (c >= 'a' && c <= 'f')
8784                         c = c - 'a' + 10;
8785                     else if (c >= 'A' && c <= 'F')
8786                         c = c - 'A' + 10;
8787                     else if (isnum(c))
8788                         c = c - '0';
8789                     else
8790                         break;
8791                     n = n * 16 + c;
8792                     p++;
8793                 }
8794                 c = n;
8795                 goto add_char_nonext;
8796             case 'a':
8797                 c = '\a';
8798                 break;
8799             case 'b':
8800                 c = '\b';
8801                 break;
8802             case 'f':
8803                 c = '\f';
8804                 break;
8805             case 'n':
8806                 c = '\n';
8807                 break;
8808             case 'r':
8809                 c = '\r';
8810                 break;
8811             case 't':
8812                 c = '\t';
8813                 break;
8814             case 'v':
8815                 c = '\v';
8816                 break;
8817             case 'e':
8818                 if (!gnu_ext)
8819                     goto invalid_escape;
8820                 c = 27;
8821                 break;
8822             case '\'':
8823             case '\"':
8824             case '\\': 
8825             case '?':
8826                 break;
8827             default:
8828             invalid_escape:
8829                 if (c >= '!' && c <= '~')
8830                     warning("unknown escape sequence: \'\\%c\'", c);
8831                 else
8832                     warning("unknown escape sequence: \'\\x%x\'", c);
8833                 break;
8834             }
8835         }
8836         p++;
8837     add_char_nonext:
8838         if (!is_long)
8839             cstr_ccat(outstr, c);
8840         else
8841             cstr_wccat(outstr, c);
8842     }
8843     /* add a trailing '\0' */
8844     if (!is_long)
8845         cstr_ccat(outstr, '\0');
8846     else
8847         cstr_wccat(outstr, '\0');
8848 }
8849
8850 /* we use 64 bit numbers */
8851 #define BN_SIZE 2
8852
8853 /* bn = (bn << shift) | or_val */
8854 void bn_lshift(unsigned int *bn, int shift, int or_val)
8855 {
8856     int i;
8857     unsigned int v;
8858     for(i=0;i<BN_SIZE;i++) {
8859         v = bn[i];
8860         bn[i] = (v << shift) | or_val;
8861         or_val = v >> (32 - shift);
8862     }
8863 }
8864
8865 void bn_zero(unsigned int *bn)
8866 {
8867     int i;
8868     for(i=0;i<BN_SIZE;i++) {
8869         bn[i] = 0;
8870     }
8871 }
8872
8873 /* parse number in null terminated string 'p' and return it in the
8874    current token */
8875 void parse_number(const char *p)
8876 {
8877     int b, t, shift, frac_bits, s, exp_val, ch;
8878     char *q;
8879     unsigned int bn[BN_SIZE];
8880     double d;
8881
8882     /* number */
8883     q = token_buf;
8884     ch = *p++;
8885     t = ch;
8886     ch = *p++;
8887     *q++ = t;
8888     b = 10;
8889     if (t == '.') {
8890         goto float_frac_parse;
8891     } else if (t == '0') {
8892         if (ch == 'x' || ch == 'X') {
8893             q--;
8894             ch = *p++;
8895             b = 16;
8896         } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
8897             q--;
8898             ch = *p++;
8899             b = 2;
8900         }
8901     }
8902     /* parse all digits. cannot check octal numbers at this stage
8903        because of floating point constants */
8904     while (1) {
8905         if (ch >= 'a' && ch <= 'f')
8906             t = ch - 'a' + 10;
8907         else if (ch >= 'A' && ch <= 'F')
8908             t = ch - 'A' + 10;
8909         else if (isnum(ch))
8910             t = ch - '0';
8911         else
8912             break;
8913         if (t >= b)
8914             break;
8915         if (q >= token_buf + STRING_MAX_SIZE) {
8916         num_too_long:
8917             error("number too long");
8918         }
8919         *q++ = ch;
8920         ch = *p++;
8921     }
8922     if (ch == '.' ||
8923         ((ch == 'e' || ch == 'E') && b == 10) ||
8924         ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
8925         if (b != 10) {
8926             /* NOTE: strtox should support that for hexa numbers, but
8927                non ISOC99 libcs do not support it, so we prefer to do
8928                it by hand */
8929             /* hexadecimal or binary floats */
8930             /* XXX: handle overflows */
8931             *q = '\0';
8932             if (b == 16)
8933                 shift = 4;
8934             else 
8935                 shift = 2;
8936             bn_zero(bn);
8937             q = token_buf;
8938             while (1) {
8939                 t = *q++;
8940                 if (t == '\0') {
8941                     break;
8942                 } else if (t >= 'a') {
8943                     t = t - 'a' + 10;
8944                 } else if (t >= 'A') {
8945                     t = t - 'A' + 10;
8946                 } else {
8947                     t = t - '0';
8948                 }
8949                 bn_lshift(bn, shift, t);
8950             }
8951             frac_bits = 0;
8952             if (ch == '.') {
8953                 ch = *p++;
8954                 while (1) {
8955                     t = ch;
8956                     if (t >= 'a' && t <= 'f') {
8957                         t = t - 'a' + 10;
8958                     } else if (t >= 'A' && t <= 'F') {
8959                         t = t - 'A' + 10;
8960                     } else if (t >= '0' && t <= '9') {
8961                         t = t - '0';
8962                     } else {
8963                         break;
8964                     }
8965                     if (t >= b)
8966                         error("invalid digit");
8967                     bn_lshift(bn, shift, t);
8968                     frac_bits += shift;
8969                     ch = *p++;
8970                 }
8971             }
8972             if (ch != 'p' && ch != 'P')
8973                 expect("exponent");
8974             ch = *p++;
8975             s = 1;
8976             exp_val = 0;
8977             if (ch == '+') {
8978                 ch = *p++;
8979             } else if (ch == '-') {
8980                 s = -1;
8981                 ch = *p++;
8982             }
8983             if (ch < '0' || ch > '9')
8984                 expect("exponent digits");
8985             while (ch >= '0' && ch <= '9') {
8986                 exp_val = exp_val * 10 + ch - '0';
8987                 ch = *p++;
8988             }
8989             exp_val = exp_val * s;
8990             
8991             /* now we can generate the number */
8992             /* XXX: should patch directly float number */
8993             d = (double)bn[1] * 4294967296.0 + (double)bn[0];
8994             d = ldexp(d, exp_val - frac_bits);
8995             t = toup(ch);
8996             if (t == 'F') {
8997                 ch = *p++;
8998                 tok = TOK_CFLOAT;
8999                 /* float : should handle overflow */
9000                 tokc.f = (float)d;
9001             } else if (t == 'L') {
9002                 ch = *p++;
9003                 tok = TOK_CLDOUBLE;
9004                 /* XXX: not large enough */
9005                 tokc.ld = (long double)d;
9006             } else {
9007                 tok = TOK_CDOUBLE;
9008                 tokc.d = d;
9009             }
9010         } else {
9011             /* decimal floats */
9012             if (ch == '.') {
9013                 if (q >= token_buf + STRING_MAX_SIZE)
9014                     goto num_too_long;
9015                 *q++ = ch;
9016                 ch = *p++;
9017             float_frac_parse:
9018                 while (ch >= '0' && ch <= '9') {
9019                     if (q >= token_buf + STRING_MAX_SIZE)
9020                         goto num_too_long;
9021                     *q++ = ch;
9022                     ch = *p++;
9023                 }
9024             }
9025             if (ch == 'e' || ch == 'E') {
9026                 if (q >= token_buf + STRING_MAX_SIZE)
9027                     goto num_too_long;
9028                 *q++ = ch;
9029                 ch = *p++;
9030                 if (ch == '-' || ch == '+') {
9031                     if (q >= token_buf + STRING_MAX_SIZE)
9032                         goto num_too_long;
9033                     *q++ = ch;
9034                     ch = *p++;
9035                 }
9036                 if (ch < '0' || ch > '9')
9037                     expect("exponent digits");
9038                 while (ch >= '0' && ch <= '9') {
9039                     if (q >= token_buf + STRING_MAX_SIZE)
9040                         goto num_too_long;
9041                     *q++ = ch;
9042                     ch = *p++;
9043                 }
9044             }
9045             *q = '\0';
9046             t = toup(ch);
9047             errno = 0;
9048             if (t == 'F') {
9049                 ch = *p++;
9050                 tok = TOK_CFLOAT;
9051                 tokc.f = strtof(token_buf, NULL);
9052             } else if (t == 'L') {
9053                 ch = *p++;
9054                 tok = TOK_CLDOUBLE;
9055                 tokc.ld = strtold(token_buf, NULL);
9056             } else {
9057                 tok = TOK_CDOUBLE;
9058                 tokc.d = strtod(token_buf, NULL);
9059             }
9060         }
9061     } else {
9062         unsigned long long n, n1;
9063         int lcount, ucount;
9064
9065         /* integer number */
9066         *q = '\0';
9067         q = token_buf;
9068         if (b == 10 && *q == '0') {
9069             b = 8;
9070             q++;
9071         }
9072         n = 0;
9073         while(1) {
9074             t = *q++;
9075             /* no need for checks except for base 10 / 8 errors */
9076             if (t == '\0') {
9077                 break;
9078             } else if (t >= 'a') {
9079                 t = t - 'a' + 10;
9080             } else if (t >= 'A') {
9081                 t = t - 'A' + 10;
9082             } else {
9083                 t = t - '0';
9084                 if (t >= b)
9085                     error("invalid digit");
9086             }
9087             n1 = n;
9088             n = n * b + t;
9089             /* detect overflow */
9090             /* XXX: this test is not reliable */
9091             if (n < n1)
9092                 error("integer constant overflow");
9093         }
9094         
9095         /* XXX: not exactly ANSI compliant */
9096         if ((n & 0xffffffff00000000LL) != 0) {
9097             if ((n >> 63) != 0)
9098                 tok = TOK_CULLONG;
9099             else
9100                 tok = TOK_CLLONG;
9101         } else if (n > 0x7fffffff) {
9102             tok = TOK_CUINT;
9103         } else {
9104             tok = TOK_CINT;
9105         }
9106         lcount = 0;
9107         ucount = 0;
9108         for(;;) {
9109             t = toup(ch);
9110             if (t == 'L') {
9111                 if (lcount >= 2)
9112                     error("three 'l's in integer constant");
9113                 lcount++;
9114                 if (lcount == 2) {
9115                     if (tok == TOK_CINT)
9116                         tok = TOK_CLLONG;
9117                     else if (tok == TOK_CUINT)
9118                         tok = TOK_CULLONG;
9119                 }
9120                 ch = *p++;
9121             } else if (t == 'U') {
9122                 if (ucount >= 1)
9123                     error("two 'u's in integer constant");
9124                 ucount++;
9125                 if (tok == TOK_CINT)
9126                     tok = TOK_CUINT;
9127                 else if (tok == TOK_CLLONG)
9128                     tok = TOK_CULLONG;
9129                 ch = *p++;
9130             } else {
9131                 break;
9132             }
9133         }
9134         if (tok == TOK_CINT || tok == TOK_CUINT)
9135             tokc.ui = n;
9136         else
9137             tokc.ull = n;
9138     }
9139 }
9140
9141
9142 #define PARSE2(c1, tok1, c2, tok2)              \
9143     case c1:                                    \
9144         PEEKC(c, p);                            \
9145         if (c == c2) {                          \
9146             p++;                                \
9147             tok = tok2;                         \
9148         } else {                                \
9149             tok = tok1;                         \
9150         }                                       \
9151         break;
9152
9153 /* return next token without macro substitution */
9154 static /*inline*/ void next_nomacro1(void)
9155 {
9156     int t, c, is_long;
9157     TokenSym *ts;
9158     uint8_t *p, *p1;
9159     unsigned int h;
9160
9161     p = file->buf_ptr;
9162  redo_no_start:
9163     c = *p;
9164     switch(c) {
9165     case ' ':
9166     case '\t':
9167     case '\f':
9168     case '\v':
9169     case '\r':
9170         p++;
9171         goto redo_no_start;
9172         
9173     case '\\':
9174         /* first look if it is in fact an end of buffer */
9175         if (p >= file->buf_end) {
9176             file->buf_ptr = p;
9177             handle_eob();
9178             p = file->buf_ptr;
9179             if (p >= file->buf_end)
9180                 goto parse_eof;
9181             else
9182                 goto redo_no_start;
9183         } else {
9184             file->buf_ptr = p;
9185             ch = *p;
9186             handle_stray();
9187             p = file->buf_ptr;
9188             goto redo_no_start;
9189         }
9190     parse_eof:
9191         {
9192             TCCState *s1 = tcc_state;
9193             if (parse_flags & PARSE_FLAG_LINEFEED) {
9194                 tok = TOK_LINEFEED;
9195             } else if (s1->include_stack_ptr == s1->include_stack ||
9196                        !(parse_flags & PARSE_FLAG_PREPROCESS)) {
9197                 /* no include left : end of file. */
9198                 tok = TOK_EOF;
9199             } else {
9200                 /* pop include file */
9201                 
9202                 /* test if previous '#endif' was after a #ifdef at
9203                    start of file */
9204                 if (tok_flags & TOK_FLAG_ENDIF) {
9205 #ifdef INC_DEBUG
9206                     printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
9207 #endif
9208                     add_cached_include(s1, file->inc_type, file->inc_filename,
9209                                        file->ifndef_macro_saved);
9210                 }
9211
9212                 /* add end of include file debug info */
9213                 if (do_debug) {
9214                     put_stabd(N_EINCL, 0, 0);
9215                 }
9216                 /* pop include stack */
9217                 tcc_close(file);
9218                 s1->include_stack_ptr--;
9219                 file = *s1->include_stack_ptr;
9220                 p = file->buf_ptr;
9221                 goto redo_no_start;
9222             }
9223         }
9224         break;
9225
9226     case '\n':
9227         if (parse_flags & PARSE_FLAG_LINEFEED) {
9228             tok = TOK_LINEFEED;
9229         } else {
9230             file->line_num++;
9231             tok_flags |= TOK_FLAG_BOL;
9232             p++;
9233             goto redo_no_start;
9234         }
9235         break;
9236
9237     case '#':
9238         /* XXX: simplify */
9239         PEEKC(c, p);
9240         if ((tok_flags & TOK_FLAG_BOL) && 
9241             (parse_flags & PARSE_FLAG_PREPROCESS)) {
9242             file->buf_ptr = p;
9243             preprocess(tok_flags & TOK_FLAG_BOF);
9244             p = file->buf_ptr;
9245             goto redo_no_start;
9246         } else {
9247             if (c == '#') {
9248                 p++;
9249                 tok = TOK_TWOSHARPS;
9250             } else {
9251                 if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
9252                     p = parse_line_comment(p - 1);
9253                     goto redo_no_start;
9254                 } else {
9255                     tok = '#';
9256                 }
9257             }
9258         }
9259         break;
9260
9261     case 'a': case 'b': case 'c': case 'd':
9262     case 'e': case 'f': case 'g': case 'h':
9263     case 'i': case 'j': case 'k': case 'l':
9264     case 'm': case 'n': case 'o': case 'p':
9265     case 'q': case 'r': case 's': case 't':
9266     case 'u': case 'v': case 'w': case 'x':
9267     case 'y': case 'z': 
9268     case 'A': case 'B': case 'C': case 'D':
9269     case 'E': case 'F': case 'G': case 'H':
9270     case 'I': case 'J': case 'K': 
9271     case 'M': case 'N': case 'O': case 'P':
9272     case 'Q': case 'R': case 'S': case 'T':
9273     case 'U': case 'V': case 'W': case 'X':
9274     case 'Y': case 'Z': 
9275     case '_':
9276     parse_ident_fast:
9277         p1 = p;
9278         h = TOK_HASH_INIT;
9279         h = TOK_HASH_FUNC(h, c);
9280         p++;
9281         for(;;) {
9282             c = *p;
9283             if (!isidnum_table[c])
9284                 break;
9285             h = TOK_HASH_FUNC(h, c);
9286             p++;
9287         }
9288         if (c != '\\') {
9289             TokenSym **pts;
9290             int len;
9291
9292             /* fast case : no stray found, so we have the full token
9293                and we have already hashed it */
9294             len = p - p1;
9295             h &= (TOK_HASH_SIZE - 1);
9296             pts = &hash_ident[h];
9297             for(;;) {
9298                 ts = *pts;
9299                 if (!ts)
9300                     break;
9301                 if (ts->len == len && !memcmp(ts->str, p1, len))
9302                     goto token_found;
9303                 pts = &(ts->hash_next);
9304             }
9305             ts = tok_alloc_new(pts, p1, len);
9306         token_found: ;
9307         } else {
9308             /* slower case */
9309             cstr_reset(&tokcstr);
9310
9311             while (p1 < p) {
9312                 cstr_ccat(&tokcstr, *p1);
9313                 p1++;
9314             }
9315             p--;
9316             PEEKC(c, p);
9317         parse_ident_slow:
9318             while (isidnum_table[c]) {
9319                 cstr_ccat(&tokcstr, c);
9320                 PEEKC(c, p);
9321             }
9322             ts = tok_alloc(tokcstr.data, tokcstr.size);
9323         }
9324         tok = ts->tok;
9325         break;
9326     case 'L':
9327         t = p[1];
9328         if (t != '\\' && t != '\'' && t != '\"') {
9329             /* fast case */
9330             goto parse_ident_fast;
9331         } else {
9332             PEEKC(c, p);
9333             if (c == '\'' || c == '\"') {
9334                 is_long = 1;
9335                 goto str_const;
9336             } else {
9337                 cstr_reset(&tokcstr);
9338                 cstr_ccat(&tokcstr, 'L');
9339                 goto parse_ident_slow;
9340             }
9341         }
9342         break;
9343     case '0': case '1': case '2': case '3':
9344     case '4': case '5': case '6': case '7':
9345     case '8': case '9':
9346
9347         cstr_reset(&tokcstr);
9348         /* after the first digit, accept digits, alpha, '.' or sign if
9349            prefixed by 'eEpP' */
9350     parse_num:
9351         for(;;) {
9352             t = c;
9353             cstr_ccat(&tokcstr, c);
9354             PEEKC(c, p);
9355             if (!(isnum(c) || isid(c) || c == '.' ||
9356                   ((c == '+' || c == '-') && 
9357                    (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
9358                 break;
9359         }
9360         /* We add a trailing '\0' to ease parsing */
9361         cstr_ccat(&tokcstr, '\0');
9362         tokc.cstr = &tokcstr;
9363         tok = TOK_PPNUM;
9364         break;
9365     case '.':
9366         /* special dot handling because it can also start a number */
9367         PEEKC(c, p);
9368         if (isnum(c)) {
9369             cstr_reset(&tokcstr);
9370             cstr_ccat(&tokcstr, '.');
9371             goto parse_num;
9372         } else if (c == '.') {
9373             PEEKC(c, p);
9374             if (c != '.')
9375                 expect("'.'");
9376             PEEKC(c, p);
9377             tok = TOK_DOTS;
9378         } else {
9379             tok = '.';
9380         }
9381         break;
9382     case '\'':
9383     case '\"':
9384         is_long = 0;
9385     str_const:
9386         {
9387             CString str;
9388             int sep;
9389
9390             sep = c;
9391
9392             /* parse the string */
9393             cstr_new(&str);
9394             p = parse_pp_string(p, sep, &str);
9395             cstr_ccat(&str, '\0');
9396             
9397             /* eval the escape (should be done as TOK_PPNUM) */
9398             cstr_reset(&tokcstr);
9399             parse_escape_string(&tokcstr, str.data, is_long);
9400             cstr_free(&str);
9401
9402             if (sep == '\'') {
9403                 int char_size;
9404                 /* XXX: make it portable */
9405                 if (!is_long)
9406                     char_size = 1;
9407                 else
9408                     char_size = sizeof(int);
9409                 if (tokcstr.size <= char_size)
9410                     error("empty character constant");
9411                 if (tokcstr.size > 2 * char_size)
9412                     warning("multi-character character constant");
9413                 if (!is_long) {
9414                     tokc.i = *(int8_t *)tokcstr.data;
9415                     tok = TOK_CCHAR;
9416                 } else {
9417                     tokc.i = *(int *)tokcstr.data;
9418                     tok = TOK_LCHAR;
9419                 }
9420             } else {
9421                 tokc.cstr = &tokcstr;
9422                 if (!is_long)
9423                     tok = TOK_STR;
9424                 else
9425                     tok = TOK_LSTR;
9426             }
9427         }
9428         break;
9429
9430     case '<':
9431         PEEKC(c, p);
9432         if (c == '=') {
9433             p++;
9434             tok = TOK_LE;
9435         } else if (c == '<') {
9436             PEEKC(c, p);
9437             if (c == '=') {
9438                 p++;
9439                 tok = TOK_A_SHL;
9440             } else {
9441                 tok = TOK_SHL;
9442             }
9443         } else {
9444             tok = TOK_LT;
9445         }
9446         break;
9447         
9448     case '>':
9449         PEEKC(c, p);
9450         if (c == '=') {
9451             p++;
9452             tok = TOK_GE;
9453         } else if (c == '>') {
9454             PEEKC(c, p);
9455             if (c == '=') {
9456                 p++;
9457                 tok = TOK_A_SAR;
9458             } else {
9459                 tok = TOK_SAR;
9460             }
9461         } else {
9462             tok = TOK_GT;
9463         }
9464         break;
9465         
9466     case '&':
9467         PEEKC(c, p);
9468         if (c == '&') {
9469             p++;
9470             tok = TOK_LAND;
9471         } else if (c == '=') {
9472             p++;
9473             tok = TOK_A_AND;
9474         } else {
9475             tok = '&';
9476         }
9477         break;
9478         
9479     case '|':
9480         PEEKC(c, p);
9481         if (c == '|') {
9482             p++;
9483             tok = TOK_LOR;
9484         } else if (c == '=') {
9485             p++;
9486             tok = TOK_A_OR;
9487         } else {
9488             tok = '|';
9489         }
9490         break;
9491
9492     case '+':
9493         PEEKC(c, p);
9494         if (c == '+') {
9495             p++;
9496             tok = TOK_INC;
9497         } else if (c == '=') {
9498             p++;
9499             tok = TOK_A_ADD;
9500         } else {
9501             tok = '+';
9502         }
9503         break;
9504         
9505     case '-':
9506         PEEKC(c, p);
9507         if (c == '-') {
9508             p++;
9509             tok = TOK_DEC;
9510         } else if (c == '=') {
9511             p++;
9512             tok = TOK_A_SUB;
9513         } else if (c == '>') {
9514             p++;
9515             tok = TOK_ARROW;
9516         } else {
9517             tok = '-';
9518         }
9519         break;
9520
9521     PARSE2('!', '!', '=', TOK_NE)
9522     PARSE2('=', '=', '=', TOK_EQ)
9523     PARSE2('*', '*', '=', TOK_A_MUL)
9524     PARSE2('%', '%', '=', TOK_A_MOD)
9525     PARSE2('^', '^', '=', TOK_A_XOR)
9526         
9527         /* comments or operator */
9528     case '/':
9529         PEEKC(c, p);
9530         if (c == '*') {
9531             p = parse_comment(p);
9532             goto redo_no_start;
9533         } else if (c == '/') {
9534             p = parse_line_comment(p);
9535             goto redo_no_start;
9536         } else if (c == '=') {
9537             p++;
9538             tok = TOK_A_DIV;
9539         } else {
9540             tok = '/';
9541         }
9542         break;
9543         
9544         /* simple tokens */
9545     case '(':
9546     case ')':
9547     case '[':
9548     case ']':
9549     case '{':
9550     case '}':
9551     case ',':
9552     case ';':
9553     case ':':
9554     case '?':
9555     case '~':
9556     case '$': /* only used in assembler */
9557     case '@': /* dito */
9558         tok = c;
9559         p++;
9560         break;
9561     default:
9562         error("unrecognized character \\x%02x", c);
9563         break;
9564     }
9565     file->buf_ptr = p;
9566     tok_flags = 0;
9567 #if defined(PARSE_DEBUG)
9568     printf("token = %s\n", get_tok_str(tok, &tokc));
9569 #endif
9570 }
9571
9572 /* return next token without macro substitution. Can read input from
9573    macro_ptr buffer */
9574 static void next_nomacro(void)
9575 {
9576     if (macro_ptr) {
9577     redo:
9578         tok = *macro_ptr;
9579         if (tok) {
9580             TOK_GET(tok, macro_ptr, tokc);
9581             if (tok == TOK_LINENUM) {
9582                 file->line_num = tokc.i;
9583                 goto redo;
9584             }
9585         }
9586     } else {
9587         next_nomacro1();
9588     }
9589 }
9590
9591 /* substitute args in macro_str and return allocated string */
9592 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
9593 {
9594     int *st, last_tok, t, notfirst;
9595     Sym *s;
9596     CValue cval;
9597     TokenString str;
9598     CString cstr;
9599
9600     tok_str_new(&str);
9601     last_tok = 0;
9602     while(1) {
9603         TOK_GET(t, macro_str, cval);
9604         if (!t)
9605             break;
9606         if (t == '#') {
9607             /* stringize */
9608             TOK_GET(t, macro_str, cval);
9609             if (!t)
9610                 break;
9611             s = sym_find2(args, t);
9612             if (s) {
9613                 cstr_new(&cstr);
9614                 st = (int *)s->c;
9615                 notfirst = 0;
9616                 while (*st) {
9617                     if (notfirst)
9618                         cstr_ccat(&cstr, ' ');
9619                     TOK_GET(t, st, cval);
9620                     cstr_cat(&cstr, get_tok_str(t, &cval));
9621                     notfirst = 1;
9622                 }
9623                 cstr_ccat(&cstr, '\0');
9624 #ifdef PP_DEBUG
9625                 printf("stringize: %s\n", (char *)cstr.data);
9626 #endif
9627                 /* add string */
9628                 cval.cstr = &cstr;
9629                 tok_str_add2(&str, TOK_STR, &cval);
9630                 cstr_free(&cstr);
9631             } else {
9632                 tok_str_add2(&str, t, &cval);
9633             }
9634         } else if (t >= TOK_IDENT) {
9635             s = sym_find2(args, t);
9636             if (s) {
9637                 st = (int *)s->c;
9638                 /* if '##' is present before or after, no arg substitution */
9639                 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
9640                     /* special case for var arg macros : ## eats the
9641                        ',' if empty VA_ARGS variable. */
9642                     /* XXX: test of the ',' is not 100%
9643                        reliable. should fix it to avoid security
9644                        problems */
9645                     if (gnu_ext && s->type.t &&
9646                         last_tok == TOK_TWOSHARPS && 
9647                         str.len >= 2 && str.str[str.len - 2] == ',') {
9648                         if (*st == 0) {
9649                             /* suppress ',' '##' */
9650                             str.len -= 2;
9651                         } else {
9652                             /* suppress '##' and add variable */
9653                             str.len--;
9654                             goto add_var;
9655                         }
9656                     } else {
9657                         int t1;
9658                     add_var:
9659                         for(;;) {
9660                             TOK_GET(t1, st, cval);
9661                             if (!t1)
9662                                 break;
9663                             tok_str_add2(&str, t1, &cval);
9664                         }
9665                     }
9666                 } else {
9667                     /* NOTE: the stream cannot be read when macro
9668                        substituing an argument */
9669                     macro_subst(&str, nested_list, st, NULL);
9670                 }
9671             } else {
9672                 tok_str_add(&str, t);
9673             }
9674         } else {
9675             tok_str_add2(&str, t, &cval);
9676         }
9677         last_tok = t;
9678     }
9679     tok_str_add(&str, 0);
9680     return str.str;
9681 }
9682
9683 static char const ab_month_name[12][4] =
9684 {
9685     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
9686     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
9687 };
9688
9689 /* do macro substitution of current token with macro 's' and add
9690    result to (tok_str,tok_len). 'nested_list' is the list of all
9691    macros we got inside to avoid recursing. Return non zero if no
9692    substitution needs to be done */
9693 static int macro_subst_tok(TokenString *tok_str,
9694                            Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
9695 {
9696     Sym *args, *sa, *sa1;
9697     int mstr_allocated, parlevel, *mstr, t, t1;
9698     TokenString str;
9699     char *cstrval;
9700     CValue cval;
9701     CString cstr;
9702     char buf[32];
9703     
9704     /* if symbol is a macro, prepare substitution */
9705     /* special macros */
9706     if (tok == TOK___LINE__) {
9707         snprintf(buf, sizeof(buf), "%d", file->line_num);
9708         cstrval = buf;
9709         t1 = TOK_PPNUM;
9710         goto add_cstr1;
9711     } else if (tok == TOK___FILE__) {
9712         cstrval = file->filename;
9713         goto add_cstr;
9714     } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
9715         time_t ti;
9716         struct tm *tm;
9717
9718         time(&ti);
9719         tm = localtime(&ti);
9720         if (tok == TOK___DATE__) {
9721             snprintf(buf, sizeof(buf), "%s %2d %d", 
9722                      ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
9723         } else {
9724             snprintf(buf, sizeof(buf), "%02d:%02d:%02d", 
9725                      tm->tm_hour, tm->tm_min, tm->tm_sec);
9726         }
9727         cstrval = buf;
9728     add_cstr:
9729         t1 = TOK_STR;
9730     add_cstr1:
9731         cstr_new(&cstr);
9732         cstr_cat(&cstr, cstrval);
9733         cstr_ccat(&cstr, '\0');
9734         cval.cstr = &cstr;
9735         tok_str_add2(tok_str, t1, &cval);
9736         cstr_free(&cstr);
9737     } else {
9738         mstr = (int *)s->c;
9739         mstr_allocated = 0;
9740         if (s->type.t == MACRO_FUNC) {
9741             /* NOTE: we do not use next_nomacro to avoid eating the
9742                next token. XXX: find better solution */
9743         redo:
9744             if (macro_ptr) {
9745                 t = *macro_ptr;
9746                 if (t == 0 && can_read_stream) {
9747                     /* end of macro stream: we must look at the token
9748                        after in the file */
9749                     struct macro_level *ml = *can_read_stream;
9750                     macro_ptr = NULL;
9751                     if (ml)
9752                     {
9753                         macro_ptr = ml->p;
9754                         ml->p = NULL;
9755                         *can_read_stream = ml -> prev;
9756                     }
9757                     goto redo;
9758                 }
9759             } else {
9760                 /* XXX: incorrect with comments */
9761                 ch = file->buf_ptr[0];
9762                 while (is_space(ch) || ch == '\n')
9763                     cinp();
9764                 t = ch;
9765             }
9766             if (t != '(') /* no macro subst */
9767                 return -1;
9768                     
9769             /* argument macro */
9770             next_nomacro();
9771             next_nomacro();
9772             args = NULL;
9773             sa = s->next;
9774             /* NOTE: empty args are allowed, except if no args */
9775             for(;;) {
9776                 /* handle '()' case */
9777                 if (!args && !sa && tok == ')')
9778                     break;
9779                 if (!sa)
9780                     error("macro '%s' used with too many args",
9781                           get_tok_str(s->v, 0));
9782                 tok_str_new(&str);
9783                 parlevel = 0;
9784                 /* NOTE: non zero sa->t indicates VA_ARGS */
9785                 while ((parlevel > 0 || 
9786                         (tok != ')' && 
9787                          (tok != ',' || sa->type.t))) && 
9788                        tok != -1) {
9789                     if (tok == '(')
9790                         parlevel++;
9791                     else if (tok == ')')
9792                         parlevel--;
9793                     tok_str_add2(&str, tok, &tokc);
9794                     next_nomacro();
9795                 }
9796                 tok_str_add(&str, 0);
9797                 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
9798                 sa = sa->next;
9799                 if (tok == ')') {
9800                     /* special case for gcc var args: add an empty
9801                        var arg argument if it is omitted */
9802                     if (sa && sa->type.t && gnu_ext)
9803                         continue;
9804                     else
9805                         break;
9806                 }
9807                 if (tok != ',')
9808                     expect(",");
9809                 next_nomacro();
9810             }
9811             if (sa) {
9812                 error("macro '%s' used with too few args",
9813                       get_tok_str(s->v, 0));
9814             }
9815
9816             /* now subst each arg */
9817             mstr = macro_arg_subst(nested_list, mstr, args);
9818             /* free memory */
9819             sa = args;
9820             while (sa) {
9821                 sa1 = sa->prev;
9822                 tok_str_free((int *)sa->c);
9823                 sym_free(sa);
9824                 sa = sa1;
9825             }
9826             mstr_allocated = 1;
9827         }
9828         sym_push2(nested_list, s->v, 0, 0);
9829         macro_subst(tok_str, nested_list, mstr, can_read_stream);
9830         /* pop nested defined symbol */
9831         sa1 = *nested_list;
9832         *nested_list = sa1->prev;
9833         sym_free(sa1);
9834         if (mstr_allocated)
9835             tok_str_free(mstr);
9836     }
9837     return 0;
9838 }
9839
9840 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
9841    return the resulting string (which must be freed). */
9842 static /*inline*/ int *macro_twosharps(const int *macro_str)
9843 {
9844     TokenSym *ts;
9845     const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
9846     int t;
9847     const char *p1, *p2;
9848     CValue cval;
9849     TokenString macro_str1;
9850     CString cstr;
9851
9852     start_macro_ptr = macro_str;
9853     /* we search the first '##' */
9854     for(;;) {
9855         macro_ptr1 = macro_str;
9856         TOK_GET(t, macro_str, cval);
9857         /* nothing more to do if end of string */
9858         if (t == 0)
9859             return NULL;
9860         if (*macro_str == TOK_TWOSHARPS)
9861             break;
9862     }
9863
9864     /* we saw '##', so we need more processing to handle it */
9865     cstr_new(&cstr);
9866     tok_str_new(&macro_str1);
9867     tok = t;
9868     tokc = cval;
9869
9870     /* add all tokens seen so far */
9871     for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
9872         TOK_GET(t, ptr, cval);
9873         tok_str_add2(&macro_str1, t, &cval);
9874     }
9875     saved_macro_ptr = macro_ptr;
9876     /* XXX: get rid of the use of macro_ptr here */
9877     macro_ptr = (int *)macro_str;
9878     for(;;) {
9879         while (*macro_ptr == TOK_TWOSHARPS) {
9880             macro_ptr++;
9881             macro_ptr1 = macro_ptr;
9882             t = *macro_ptr;
9883             if (t) {
9884                 TOK_GET(t, macro_ptr, cval);
9885                 /* We concatenate the two tokens if we have an
9886                    identifier or a preprocessing number */
9887                 cstr_reset(&cstr);
9888                 p1 = get_tok_str(tok, &tokc);
9889                 cstr_cat(&cstr, p1);
9890                 p2 = get_tok_str(t, &cval);
9891                 cstr_cat(&cstr, p2);
9892                 cstr_ccat(&cstr, '\0');
9893                 
9894                 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && 
9895                     (t >= TOK_IDENT || t == TOK_PPNUM)) {
9896                     if (tok == TOK_PPNUM) {
9897                         /* if number, then create a number token */
9898                         /* NOTE: no need to allocate because
9899                            tok_str_add2() does it */
9900                         tokc.cstr = &cstr;
9901                     } else {
9902                         /* if identifier, we must do a test to
9903                            validate we have a correct identifier */
9904                         if (t == TOK_PPNUM) {
9905                             const char *p;
9906                             int c;
9907
9908                             p = p2;
9909                             for(;;) {
9910                                 c = *p;
9911                                 if (c == '\0')
9912                                     break;
9913                                 p++;
9914                                 if (!isnum(c) && !isid(c))
9915                                     goto error_pasting;
9916                             }
9917                         }
9918                         ts = tok_alloc(cstr.data, strlen(cstr.data));
9919                         tok = ts->tok; /* modify current token */
9920                     }
9921                 } else {
9922                     const char *str = cstr.data;
9923                     const unsigned char *q;
9924
9925                     /* we look for a valid token */
9926                     /* XXX: do more extensive checks */
9927                     if (!strcmp(str, ">>=")) {
9928                         tok = TOK_A_SAR;
9929                     } else if (!strcmp(str, "<<=")) {
9930                         tok = TOK_A_SHL;
9931                     } else if (strlen(str) == 2) {
9932                         /* search in two bytes table */
9933                         q = tok_two_chars;
9934                         for(;;) {
9935                             if (!*q)
9936                                 goto error_pasting;
9937                             if (q[0] == str[0] && q[1] == str[1])
9938                                 break;
9939                             q += 3;
9940                         }
9941                         tok = q[2];
9942                     } else {
9943                     error_pasting:
9944                         /* NOTE: because get_tok_str use a static buffer,
9945                            we must save it */
9946                         cstr_reset(&cstr);
9947                         p1 = get_tok_str(tok, &tokc);
9948                         cstr_cat(&cstr, p1);
9949                         cstr_ccat(&cstr, '\0');
9950                         p2 = get_tok_str(t, &cval);
9951                         warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
9952                         /* cannot merge tokens: just add them separately */
9953                         tok_str_add2(&macro_str1, tok, &tokc);
9954                         /* XXX: free associated memory ? */
9955                         tok = t;
9956                         tokc = cval;
9957                     }
9958                 }
9959             }
9960         }
9961         tok_str_add2(&macro_str1, tok, &tokc);
9962         next_nomacro();
9963         if (tok == 0)
9964             break;
9965     }
9966     macro_ptr = (int *)saved_macro_ptr;
9967     cstr_free(&cstr);
9968     tok_str_add(&macro_str1, 0);
9969     return macro_str1.str;
9970 }
9971
9972
9973 /* do macro substitution of macro_str and add result to
9974    (tok_str,tok_len). 'nested_list' is the list of all macros we got
9975    inside to avoid recursing. */
9976 static void macro_subst(TokenString *tok_str, Sym **nested_list, 
9977                         const int *macro_str, struct macro_level ** can_read_stream)
9978 {
9979     Sym *s;
9980     int *macro_str1;
9981     const int *ptr;
9982     int t, ret;
9983     CValue cval;
9984     struct macro_level ml;
9985     
9986     /* first scan for '##' operator handling */
9987     ptr = macro_str;
9988     macro_str1 = macro_twosharps(ptr);
9989     if (macro_str1) 
9990         ptr = macro_str1;
9991     while (1) {
9992         /* NOTE: ptr == NULL can only happen if tokens are read from
9993            file stream due to a macro function call */
9994         if (ptr == NULL)
9995             break;
9996         TOK_GET(t, ptr, cval);
9997         if (t == 0)
9998             break;
9999         s = define_find(t);
10000         if (s != NULL) {
10001             /* if nested substitution, do nothing */
10002             if (sym_find2(*nested_list, t))
10003                 goto no_subst;
10004             ml.p = macro_ptr;
10005             if (can_read_stream)
10006                 ml.prev = *can_read_stream, *can_read_stream = &ml;
10007             macro_ptr = (int *)ptr;
10008             tok = t;
10009             ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
10010             ptr = (int *)macro_ptr;
10011             macro_ptr = ml.p;
10012             if (can_read_stream && *can_read_stream == &ml)
10013                     *can_read_stream = ml.prev;
10014             if (ret != 0)
10015                 goto no_subst;
10016         } else {
10017         no_subst:
10018             tok_str_add2(tok_str, t, &cval);
10019         }
10020     }
10021     if (macro_str1)
10022         tok_str_free(macro_str1);
10023 }
10024
10025 /* return next token with macro substitution */
10026 static void next(void)
10027 {
10028     Sym *nested_list, *s;
10029     TokenString str;
10030     struct macro_level *ml;
10031
10032  redo:
10033     next_nomacro();
10034     if (!macro_ptr) {
10035         /* if not reading from macro substituted string, then try
10036            to substitute macros */
10037         if (tok >= TOK_IDENT &&
10038             (parse_flags & PARSE_FLAG_PREPROCESS)) {
10039             s = define_find(tok);
10040             if (s) {
10041                 /* we have a macro: we try to substitute */
10042                 tok_str_new(&str);
10043                 nested_list = NULL;
10044                 ml = NULL;
10045                 if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
10046                     /* substitution done, NOTE: maybe empty */
10047                     tok_str_add(&str, 0);
10048                     macro_ptr = str.str;
10049                     macro_ptr_allocated = str.str;
10050                     goto redo;
10051                 }
10052             }
10053         }
10054     } else {
10055         if (tok == 0) {
10056             /* end of macro or end of unget buffer */
10057             if (unget_buffer_enabled) {
10058                 macro_ptr = unget_saved_macro_ptr;
10059                 unget_buffer_enabled = 0;
10060             } else {
10061                 /* end of macro string: free it */
10062                 tok_str_free(macro_ptr_allocated);
10063                 macro_ptr = NULL;
10064             }
10065             goto redo;
10066         }
10067     }
10068     
10069     /* convert preprocessor tokens into C tokens */
10070     if (tok == TOK_PPNUM &&
10071         (parse_flags & PARSE_FLAG_TOK_NUM)) {
10072         parse_number((char *)tokc.cstr->data);
10073     }
10074 }
10075
10076 /* push back current token and set current token to 'last_tok'. Only
10077    identifier case handled for labels. */
10078 static inline void unget_tok(int last_tok)
10079 {
10080     int i, n;
10081     int *q;
10082     unget_saved_macro_ptr = macro_ptr;
10083     unget_buffer_enabled = 1;
10084     q = unget_saved_buffer;
10085     macro_ptr = q;
10086     *q++ = tok;
10087     n = tok_ext_size(tok) - 1;
10088     for(i=0;i<n;i++)
10089         *q++ = tokc.tab[i];
10090     *q = 0; /* end of token string */
10091     tok = last_tok;
10092 }
10093
10094
10095 void swap(int *p, int *q)
10096 {
10097     int t;
10098     t = *p;
10099     *p = *q;
10100     *q = t;
10101 }
10102
10103 void vsetc(CType *type, int r, CValue *vc)
10104 {
10105     int v;
10106
10107     if (vtop >= vstack + (VSTACK_SIZE - 1))
10108         error("memory full");
10109     /* cannot let cpu flags if other instruction are generated. Also
10110        avoid leaving VT_JMP anywhere except on the top of the stack
10111        because it would complicate the code generator. */
10112     if (vtop >= vstack) {
10113         v = vtop->r & VT_VALMASK;
10114         if (v == VT_CMP || (v & ~1) == VT_JMP)
10115             gv(RC_INT);
10116     }
10117     vtop++;
10118     vtop->type = *type;
10119     vtop->r = r;
10120     vtop->r2 = VT_CONST;
10121     vtop->c = *vc;
10122 }
10123
10124 /* push integer constant */
10125 void vpushi(int v)
10126 {
10127     CValue cval;
10128     cval.i = v;
10129     vsetc(&int_type, VT_CONST, &cval);
10130 }
10131
10132 /* Return a static symbol pointing to a section */
10133 static Sym *get_sym_ref(CType *type, Section *sec, 
10134                         unsigned long offset, unsigned long size)
10135 {
10136     int v;
10137     Sym *sym;
10138
10139     v = anon_sym++;
10140     sym = global_identifier_push(v, type->t | VT_STATIC, 0);
10141     sym->type.ref = type->ref;
10142     sym->r = VT_CONST | VT_SYM;
10143     put_extern_sym(sym, sec, offset, size);
10144     return sym;
10145 }
10146
10147 /* push a reference to a section offset by adding a dummy symbol */
10148 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
10149 {
10150     CValue cval;
10151
10152     cval.ul = 0;
10153     vsetc(type, VT_CONST | VT_SYM, &cval);
10154     vtop->sym = get_sym_ref(type, sec, offset, size);
10155 }
10156
10157 /* define a new external reference to a symbol 'v' of type 'u' */
10158 static Sym *external_global_sym(int v, CType *type, int r)
10159 {
10160     Sym *s;
10161
10162     s = sym_find(v);
10163     if (!s) {
10164         /* push forward reference */
10165         s = global_identifier_push(v, type->t | VT_EXTERN, 0);
10166         s->type.ref = type->ref;
10167         s->r = r | VT_CONST | VT_SYM;
10168     }
10169     return s;
10170 }
10171
10172 /* define a new external reference to a symbol 'v' of type 'u' */
10173 static Sym *external_sym(int v, CType *type, int r)
10174 {
10175     Sym *s;
10176
10177     s = sym_find(v);
10178     if (!s) {
10179         /* push forward reference */
10180         s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
10181         s->type.t |= VT_EXTERN;
10182     } else {
10183         if (!is_compatible_types(&s->type, type))
10184             error("incompatible types for redefinition of '%s'", 
10185                   get_tok_str(v, NULL));
10186     }
10187     return s;
10188 }
10189
10190 /* push a reference to global symbol v */
10191 static void vpush_global_sym(CType *type, int v)
10192 {
10193     Sym *sym;
10194     CValue cval;
10195
10196     sym = external_global_sym(v, type, 0);
10197     cval.ul = 0;
10198     vsetc(type, VT_CONST | VT_SYM, &cval);
10199     vtop->sym = sym;
10200 }
10201
10202 void vset(CType *type, int r, int v)
10203 {
10204     CValue cval;
10205
10206     cval.i = v;
10207     vsetc(type, r, &cval);
10208 }
10209
10210 void vseti(int r, int v)
10211 {
10212     CType type;
10213     type.t = VT_INT;
10214     vset(&type, r, v);
10215 }
10216
10217 void vswap(void)
10218 {
10219     SValue tmp;
10220
10221     tmp = vtop[0];
10222     vtop[0] = vtop[-1];
10223     vtop[-1] = tmp;
10224 }
10225
10226 void vpushv(SValue *v)
10227 {
10228     if (vtop >= vstack + (VSTACK_SIZE - 1))
10229         error("memory full");
10230     vtop++;
10231     *vtop = *v;
10232 }
10233
10234 void vdup(void)
10235 {
10236     vpushv(vtop);
10237 }
10238
10239 /* save r to the memory stack, and mark it as being free */
10240 void save_reg(int r)
10241 {
10242     int l, saved, size, align;
10243     SValue *p, sv;
10244     CType *type;
10245
10246     /* modify all stack values */
10247     saved = 0;
10248     l = 0;
10249     for(p=vstack;p<=vtop;p++) {
10250         if ((p->r & VT_VALMASK) == r ||
10251             (p->r2 & VT_VALMASK) == r) {
10252             /* must save value on stack if not already done */
10253             if (!saved) {
10254                 /* NOTE: must reload 'r' because r might be equal to r2 */
10255                 r = p->r & VT_VALMASK;
10256                 /* store register in the stack */
10257                 type = &p->type;
10258                 if ((p->r & VT_LVAL) || 
10259                     (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
10260                     type = &int_type;
10261                 size = type_size(type, &align);
10262                 loc = (loc - size) & -align;
10263                 sv.type.t = type->t;
10264                 sv.r = VT_LOCAL | VT_LVAL;
10265                 sv.c.ul = loc;
10266                 store(r, &sv);
10267 #ifdef TCC_TARGET_I386
10268                 /* x86 specific: need to pop fp register ST0 if saved */
10269                 if (r == TREG_ST0) {
10270                     o(0xd9dd); /* fstp %st(1) */
10271                 }
10272 #endif
10273                 /* special long long case */
10274                 if ((type->t & VT_BTYPE) == VT_LLONG) {
10275                     sv.c.ul += 4;
10276                     store(p->r2, &sv);
10277                 }
10278                 l = loc;
10279                 saved = 1;
10280             }
10281             /* mark that stack entry as being saved on the stack */
10282             if (p->r & VT_LVAL) {
10283                 /* also clear the bounded flag because the
10284                    relocation address of the function was stored in
10285                    p->c.ul */
10286                 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
10287             } else {
10288                 p->r = lvalue_type(p->type.t) | VT_LOCAL;
10289             }
10290             p->r2 = VT_CONST;
10291             p->c.ul = l;
10292         }
10293     }
10294 }
10295
10296 /* find a register of class 'rc2' with at most one reference on stack.
10297  * If none, call get_reg(rc) */
10298 int get_reg_ex(int rc, int rc2) 
10299 {
10300     int r;
10301     SValue *p;
10302     
10303     for(r=0;r<NB_REGS;r++) {
10304         if (reg_classes[r] & rc2) {
10305             int n;
10306             n=0;
10307             for(p = vstack; p <= vtop; p++) {
10308                 if ((p->r & VT_VALMASK) == r ||
10309                     (p->r2 & VT_VALMASK) == r)
10310                     n++;
10311             }
10312             if (n <= 1)
10313                 return r;
10314         }
10315     }
10316     return get_reg(rc);
10317 }
10318
10319 /* find a free register of class 'rc'. If none, save one register */
10320 int get_reg(int rc)
10321 {
10322     int r;
10323     SValue *p;
10324
10325     /* find a free register */
10326     for(r=0;r<NB_REGS;r++) {
10327         if (reg_classes[r] & rc) {
10328             for(p=vstack;p<=vtop;p++) {
10329                 if ((p->r & VT_VALMASK) == r ||
10330                     (p->r2 & VT_VALMASK) == r)
10331                     goto notfound;
10332             }
10333             return r;
10334         }
10335     notfound: ;
10336     }
10337     
10338     /* no register left : free the first one on the stack (VERY
10339        IMPORTANT to start from the bottom to ensure that we don't
10340        spill registers used in gen_opi()) */
10341     for(p=vstack;p<=vtop;p++) {
10342         r = p->r & VT_VALMASK;
10343         if (r < VT_CONST && (reg_classes[r] & rc))
10344             goto save_found;
10345         /* also look at second register (if long long) */
10346         r = p->r2 & VT_VALMASK;
10347         if (r < VT_CONST && (reg_classes[r] & rc)) {
10348         save_found:
10349             save_reg(r);
10350             return r;
10351         }
10352     }
10353     /* Should never comes here */
10354     return -1;
10355 }
10356
10357 /* save registers up to (vtop - n) stack entry */
10358 void save_regs(int n)
10359 {
10360     int r;
10361     SValue *p, *p1;
10362     p1 = vtop - n;
10363     for(p = vstack;p <= p1; p++) {
10364         r = p->r & VT_VALMASK;
10365         if (r < VT_CONST) {
10366             save_reg(r);
10367         }
10368     }
10369 }
10370
10371 /* move register 's' to 'r', and flush previous value of r to memory
10372    if needed */
10373 void move_reg(int r, int s)
10374 {
10375     SValue sv;
10376
10377     if (r != s) {
10378         save_reg(r);
10379         sv.type.t = VT_INT;
10380         sv.r = s;
10381         sv.c.ul = 0;
10382         load(r, &sv);
10383     }
10384 }
10385
10386 /* get address of vtop (vtop MUST BE an lvalue) */
10387 void gaddrof(void)
10388 {
10389     vtop->r &= ~VT_LVAL;
10390     /* tricky: if saved lvalue, then we can go back to lvalue */
10391     if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
10392         vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
10393 }
10394
10395 #ifdef CONFIG_TCC_BCHECK
10396 /* generate lvalue bound code */
10397 void gbound(void)
10398 {
10399     int lval_type;
10400     CType type1;
10401
10402     vtop->r &= ~VT_MUSTBOUND;
10403     /* if lvalue, then use checking code before dereferencing */
10404     if (vtop->r & VT_LVAL) {
10405         /* if not VT_BOUNDED value, then make one */
10406         if (!(vtop->r & VT_BOUNDED)) {
10407             lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
10408             /* must save type because we must set it to int to get pointer */
10409             type1 = vtop->type;
10410             vtop->type.t = VT_INT;
10411             gaddrof();
10412             vpushi(0);
10413             gen_bounded_ptr_add();
10414             vtop->r |= lval_type;
10415             vtop->type = type1;
10416         }
10417         /* then check for dereferencing */
10418         gen_bounded_ptr_deref();
10419     }
10420 }
10421 #endif
10422
10423 /* store vtop a register belonging to class 'rc'. lvalues are
10424    converted to values. Cannot be used if cannot be converted to
10425    register value (such as structures). */
10426 int gv(int rc)
10427 {
10428     int r, r2, rc2, bit_pos, bit_size, size, align, i;
10429     unsigned long long ll;
10430
10431     /* NOTE: get_reg can modify vstack[] */
10432     if (vtop->type.t & VT_BITFIELD) {
10433         bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
10434         bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
10435         /* remove bit field info to avoid loops */
10436         vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
10437         /* generate shifts */
10438         vpushi(32 - (bit_pos + bit_size));
10439         gen_op(TOK_SHL);
10440         vpushi(32 - bit_size);
10441         /* NOTE: transformed to SHR if unsigned */
10442         gen_op(TOK_SAR);
10443         r = gv(rc);
10444     } else {
10445         if (is_float(vtop->type.t) && 
10446             (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10447             Sym *sym;
10448             int *ptr;
10449             unsigned long offset;
10450             
10451             /* XXX: unify with initializers handling ? */
10452             /* CPUs usually cannot use float constants, so we store them
10453                generically in data segment */
10454             size = type_size(&vtop->type, &align);
10455             offset = (data_section->data_offset + align - 1) & -align;
10456             data_section->data_offset = offset;
10457             /* XXX: not portable yet */
10458             ptr = section_ptr_add(data_section, size);
10459             size = size >> 2;
10460             for(i=0;i<size;i++)
10461                 ptr[i] = vtop->c.tab[i];
10462             sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
10463             vtop->r |= VT_LVAL | VT_SYM;
10464             vtop->sym = sym;
10465             vtop->c.ul = 0;
10466         }
10467 #ifdef CONFIG_TCC_BCHECK
10468         if (vtop->r & VT_MUSTBOUND) 
10469             gbound();
10470 #endif
10471
10472         r = vtop->r & VT_VALMASK;
10473         /* need to reload if:
10474            - constant
10475            - lvalue (need to dereference pointer)
10476            - already a register, but not in the right class */
10477         if (r >= VT_CONST || 
10478             (vtop->r & VT_LVAL) ||
10479             !(reg_classes[r] & rc) ||
10480             ((vtop->type.t & VT_BTYPE) == VT_LLONG && 
10481              !(reg_classes[vtop->r2] & rc))) {
10482             r = get_reg(rc);
10483             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
10484                 /* two register type load : expand to two words
10485                    temporarily */
10486                 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10487                     /* load constant */
10488                     ll = vtop->c.ull;
10489                     vtop->c.ui = ll; /* first word */
10490                     load(r, vtop);
10491                     vtop->r = r; /* save register value */
10492                     vpushi(ll >> 32); /* second word */
10493                 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
10494                            (vtop->r & VT_LVAL)) {
10495                     /* We do not want to modifier the long long
10496                        pointer here, so the safest (and less
10497                        efficient) is to save all the other registers
10498                        in the stack. XXX: totally inefficient. */
10499                     save_regs(1);
10500                     /* load from memory */
10501                     load(r, vtop);
10502                     vdup();
10503                     vtop[-1].r = r; /* save register value */
10504                     /* increment pointer to get second word */
10505                     vtop->type.t = VT_INT;
10506                     gaddrof();
10507                     vpushi(4);
10508                     gen_op('+');
10509                     vtop->r |= VT_LVAL;
10510                 } else {
10511                     /* move registers */
10512                     load(r, vtop);
10513                     vdup();
10514                     vtop[-1].r = r; /* save register value */
10515                     vtop->r = vtop[-1].r2;
10516                 }
10517                 /* allocate second register */
10518                 rc2 = RC_INT;
10519                 if (rc == RC_IRET)
10520                     rc2 = RC_LRET;
10521                 r2 = get_reg(rc2);
10522                 load(r2, vtop);
10523                 vpop();
10524                 /* write second register */
10525                 vtop->r2 = r2;
10526             } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
10527                 int t1, t;
10528                 /* lvalue of scalar type : need to use lvalue type
10529                    because of possible cast */
10530                 t = vtop->type.t;
10531                 t1 = t;
10532                 /* compute memory access type */
10533                 if (vtop->r & VT_LVAL_BYTE)
10534                     t = VT_BYTE;
10535                 else if (vtop->r & VT_LVAL_SHORT)
10536                     t = VT_SHORT;
10537                 if (vtop->r & VT_LVAL_UNSIGNED)
10538                     t |= VT_UNSIGNED;
10539                 vtop->type.t = t;
10540                 load(r, vtop);
10541                 /* restore wanted type */
10542                 vtop->type.t = t1;
10543             } else {
10544                 /* one register type load */
10545                 load(r, vtop);
10546             }
10547         }
10548         vtop->r = r;
10549 #ifdef TCC_TARGET_C67
10550         /* uses register pairs for doubles */
10551         if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 
10552             vtop->r2 = r+1;
10553 #endif
10554     }
10555     return r;
10556 }
10557
10558 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
10559 void gv2(int rc1, int rc2)
10560 {
10561     int v;
10562
10563     /* generate more generic register first. But VT_JMP or VT_CMP
10564        values must be generated first in all cases to avoid possible
10565        reload errors */
10566     v = vtop[0].r & VT_VALMASK;
10567     if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
10568         vswap();
10569         gv(rc1);
10570         vswap();
10571         gv(rc2);
10572         /* test if reload is needed for first register */
10573         if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
10574             vswap();
10575             gv(rc1);
10576             vswap();
10577         }
10578     } else {
10579         gv(rc2);
10580         vswap();
10581         gv(rc1);
10582         vswap();
10583         /* test if reload is needed for first register */
10584         if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
10585             gv(rc2);
10586         }
10587     }
10588 }
10589
10590 /* expand long long on stack in two int registers */
10591 void lexpand(void)
10592 {
10593     int u;
10594
10595     u = vtop->type.t & VT_UNSIGNED;
10596     gv(RC_INT);
10597     vdup();
10598     vtop[0].r = vtop[-1].r2;
10599     vtop[0].r2 = VT_CONST;
10600     vtop[-1].r2 = VT_CONST;
10601     vtop[0].type.t = VT_INT | u;
10602     vtop[-1].type.t = VT_INT | u;
10603 }
10604
10605 #ifdef TCC_TARGET_ARM
10606 /* expand long long on stack */
10607 void lexpand_nr(void)
10608 {
10609     int u,v;
10610
10611     u = vtop->type.t & VT_UNSIGNED;
10612     vdup();
10613     vtop->r2 = VT_CONST;
10614     vtop->type.t = VT_INT | u;
10615     v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
10616     if (v == VT_CONST) {
10617       vtop[-1].c.ui = vtop->c.ull;
10618       vtop->c.ui = vtop->c.ull >> 32;
10619       vtop->r = VT_CONST;
10620     } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
10621       vtop->c.ui += 4;
10622       vtop->r = vtop[-1].r;
10623     } else if (v > VT_CONST) {
10624       vtop--;
10625       lexpand();
10626     } else
10627       vtop->r = vtop[-1].r2;
10628     vtop[-1].r2 = VT_CONST;
10629     vtop[-1].type.t = VT_INT | u;
10630 }
10631 #endif
10632
10633 /* build a long long from two ints */
10634 void lbuild(int t)
10635 {
10636     gv2(RC_INT, RC_INT);
10637     vtop[-1].r2 = vtop[0].r;
10638     vtop[-1].type.t = t;
10639     vpop();
10640 }
10641
10642 /* rotate n first stack elements to the bottom 
10643    I1 ... In -> I2 ... In I1 [top is right]
10644 */
10645 void vrotb(int n)
10646 {
10647     int i;
10648     SValue tmp;
10649
10650     tmp = vtop[-n + 1];
10651     for(i=-n+1;i!=0;i++)
10652         vtop[i] = vtop[i+1];
10653     vtop[0] = tmp;
10654 }
10655
10656 /* rotate n first stack elements to the top 
10657    I1 ... In -> In I1 ... I(n-1)  [top is right]
10658  */
10659 void vrott(int n)
10660 {
10661     int i;
10662     SValue tmp;
10663
10664     tmp = vtop[0];
10665     for(i = 0;i < n - 1; i++)
10666         vtop[-i] = vtop[-i - 1];
10667     vtop[-n + 1] = tmp;
10668 }
10669
10670 #ifdef TCC_TARGET_ARM
10671 /* like vrott but in other direction
10672    In ... I1 -> I(n-1) ... I1 In  [top is right]
10673  */
10674 void vnrott(int n)
10675 {
10676     int i;
10677     SValue tmp;
10678
10679     tmp = vtop[-n + 1];
10680     for(i = n - 1; i > 0; i--)
10681         vtop[-i] = vtop[-i + 1];
10682     vtop[0] = tmp;
10683 }
10684 #endif
10685
10686 /* pop stack value */
10687 void vpop(void)
10688 {
10689     int v;
10690     v = vtop->r & VT_VALMASK;
10691 #ifdef TCC_TARGET_I386
10692     /* for x86, we need to pop the FP stack */
10693     if (v == TREG_ST0 && !nocode_wanted) {
10694         o(0xd9dd); /* fstp %st(1) */
10695     } else
10696 #endif
10697     if (v == VT_JMP || v == VT_JMPI) {
10698         /* need to put correct jump if && or || without test */
10699         gsym(vtop->c.ul);
10700     }
10701     vtop--;
10702 }
10703
10704 /* convert stack entry to register and duplicate its value in another
10705    register */
10706 void gv_dup(void)
10707 {
10708     int rc, t, r, r1;
10709     SValue sv;
10710
10711     t = vtop->type.t;
10712     if ((t & VT_BTYPE) == VT_LLONG) {
10713         lexpand();
10714         gv_dup();
10715         vswap();
10716         vrotb(3);
10717         gv_dup();
10718         vrotb(4);
10719         /* stack: H L L1 H1 */
10720         lbuild(t);
10721         vrotb(3);
10722         vrotb(3);
10723         vswap();
10724         lbuild(t);
10725         vswap();
10726     } else {
10727         /* duplicate value */
10728         rc = RC_INT;
10729         sv.type.t = VT_INT;
10730         if (is_float(t)) {
10731             rc = RC_FLOAT;
10732             sv.type.t = t;
10733         }
10734         r = gv(rc);
10735         r1 = get_reg(rc);
10736         sv.r = r;
10737         sv.c.ul = 0;
10738         load(r1, &sv); /* move r to r1 */
10739         vdup();
10740         /* duplicates value */
10741         vtop->r = r1;
10742     }
10743 }
10744
10745 /* generate CPU independent (unsigned) long long operations */
10746 void gen_opl(int op)
10747 {
10748     int t, a, b, op1, c, i;
10749     int func;
10750     SValue tmp;
10751
10752     switch(op) {
10753     case '/':
10754     case TOK_PDIV:
10755         func = TOK___divdi3;
10756         goto gen_func;
10757     case TOK_UDIV:
10758         func = TOK___udivdi3;
10759         goto gen_func;
10760     case '%':
10761         func = TOK___moddi3;
10762         goto gen_func;
10763     case TOK_UMOD:
10764         func = TOK___umoddi3;
10765     gen_func:
10766         /* call generic long long function */
10767         vpush_global_sym(&func_old_type, func);
10768         vrott(3);
10769         gfunc_call(2);
10770         vpushi(0);
10771         vtop->r = REG_IRET;
10772         vtop->r2 = REG_LRET;
10773         break;
10774     case '^':
10775     case '&':
10776     case '|':
10777     case '*':
10778     case '+':
10779     case '-':
10780         t = vtop->type.t;
10781         vswap();
10782         lexpand();
10783         vrotb(3);
10784         lexpand();
10785         /* stack: L1 H1 L2 H2 */
10786         tmp = vtop[0];
10787         vtop[0] = vtop[-3];
10788         vtop[-3] = tmp;
10789         tmp = vtop[-2];
10790         vtop[-2] = vtop[-3];
10791         vtop[-3] = tmp;
10792         vswap();
10793         /* stack: H1 H2 L1 L2 */
10794         if (op == '*') {
10795             vpushv(vtop - 1);
10796             vpushv(vtop - 1);
10797             gen_op(TOK_UMULL);
10798             lexpand();
10799             /* stack: H1 H2 L1 L2 ML MH */
10800             for(i=0;i<4;i++)
10801                 vrotb(6);
10802             /* stack: ML MH H1 H2 L1 L2 */
10803             tmp = vtop[0];
10804             vtop[0] = vtop[-2];
10805             vtop[-2] = tmp;
10806             /* stack: ML MH H1 L2 H2 L1 */
10807             gen_op('*');
10808             vrotb(3);
10809             vrotb(3);
10810             gen_op('*');
10811             /* stack: ML MH M1 M2 */
10812             gen_op('+');
10813             gen_op('+');
10814         } else if (op == '+' || op == '-') {
10815             /* XXX: add non carry method too (for MIPS or alpha) */
10816             if (op == '+')
10817                 op1 = TOK_ADDC1;
10818             else
10819                 op1 = TOK_SUBC1;
10820             gen_op(op1);
10821             /* stack: H1 H2 (L1 op L2) */
10822             vrotb(3);
10823             vrotb(3);
10824             gen_op(op1 + 1); /* TOK_xxxC2 */
10825         } else {
10826             gen_op(op);
10827             /* stack: H1 H2 (L1 op L2) */
10828             vrotb(3);
10829             vrotb(3);
10830             /* stack: (L1 op L2) H1 H2 */
10831             gen_op(op);
10832             /* stack: (L1 op L2) (H1 op H2) */
10833         }
10834         /* stack: L H */
10835         lbuild(t);
10836         break;
10837     case TOK_SAR:
10838     case TOK_SHR:
10839     case TOK_SHL:
10840         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
10841             t = vtop[-1].type.t;
10842             vswap();
10843             lexpand();
10844             vrotb(3);
10845             /* stack: L H shift */
10846             c = (int)vtop->c.i;
10847             /* constant: simpler */
10848             /* NOTE: all comments are for SHL. the other cases are
10849                done by swaping words */
10850             vpop();
10851             if (op != TOK_SHL)
10852                 vswap();
10853             if (c >= 32) {
10854                 /* stack: L H */
10855                 vpop();
10856                 if (c > 32) {
10857                     vpushi(c - 32);
10858                     gen_op(op);
10859                 }
10860                 if (op != TOK_SAR) {
10861                     vpushi(0);
10862                 } else {
10863                     gv_dup();
10864                     vpushi(31);
10865                     gen_op(TOK_SAR);
10866                 }
10867                 vswap();
10868             } else {
10869                 vswap();
10870                 gv_dup();
10871                 /* stack: H L L */
10872                 vpushi(c);
10873                 gen_op(op);
10874                 vswap();
10875                 vpushi(32 - c);
10876                 if (op == TOK_SHL)
10877                     gen_op(TOK_SHR);
10878                 else
10879                     gen_op(TOK_SHL);
10880                 vrotb(3);
10881                 /* stack: L L H */
10882                 vpushi(c);
10883                 if (op == TOK_SHL)
10884                     gen_op(TOK_SHL);
10885                 else
10886                     gen_op(TOK_SHR);
10887                 gen_op('|');
10888             }
10889             if (op != TOK_SHL)
10890                 vswap();
10891             lbuild(t);
10892         } else {
10893             /* XXX: should provide a faster fallback on x86 ? */
10894             switch(op) {
10895             case TOK_SAR:
10896                 func = TOK___sardi3;
10897                 goto gen_func;
10898             case TOK_SHR:
10899                 func = TOK___shrdi3;
10900                 goto gen_func;
10901             case TOK_SHL:
10902                 func = TOK___shldi3;
10903                 goto gen_func;
10904             }
10905         }
10906         break;
10907     default:
10908         /* compare operations */
10909         t = vtop->type.t;
10910         vswap();
10911         lexpand();
10912         vrotb(3);
10913         lexpand();
10914         /* stack: L1 H1 L2 H2 */
10915         tmp = vtop[-1];
10916         vtop[-1] = vtop[-2];
10917         vtop[-2] = tmp;
10918         /* stack: L1 L2 H1 H2 */
10919         /* compare high */
10920         op1 = op;
10921         /* when values are equal, we need to compare low words. since
10922            the jump is inverted, we invert the test too. */
10923         if (op1 == TOK_LT)
10924             op1 = TOK_LE;
10925         else if (op1 == TOK_GT)
10926             op1 = TOK_GE;
10927         else if (op1 == TOK_ULT)
10928             op1 = TOK_ULE;
10929         else if (op1 == TOK_UGT)
10930             op1 = TOK_UGE;
10931         a = 0;
10932         b = 0;
10933         gen_op(op1);
10934         if (op1 != TOK_NE) {
10935             a = gtst(1, 0);
10936         }
10937         if (op != TOK_EQ) {
10938             /* generate non equal test */
10939             /* XXX: NOT PORTABLE yet */
10940             if (a == 0) {
10941                 b = gtst(0, 0);
10942             } else {
10943 #if defined(TCC_TARGET_I386)
10944                 b = psym(0x850f, 0);
10945 #elif defined(TCC_TARGET_ARM)
10946                 b = ind;
10947                 o(0x1A000000 | encbranch(ind, 0, 1));
10948 #elif defined(TCC_TARGET_C67)
10949                 error("not implemented");
10950 #else
10951 #error not supported
10952 #endif
10953             }
10954         }
10955         /* compare low. Always unsigned */
10956         op1 = op;
10957         if (op1 == TOK_LT)
10958             op1 = TOK_ULT;
10959         else if (op1 == TOK_LE)
10960             op1 = TOK_ULE;
10961         else if (op1 == TOK_GT)
10962             op1 = TOK_UGT;
10963         else if (op1 == TOK_GE)
10964             op1 = TOK_UGE;
10965         gen_op(op1);
10966         a = gtst(1, a);
10967         gsym(b);
10968         vseti(VT_JMPI, a);
10969         break;
10970     }
10971 }
10972
10973 /* handle integer constant optimizations and various machine
10974    independent opt */
10975 void gen_opic(int op)
10976 {
10977     int fc, c1, c2, n;
10978     SValue *v1, *v2;
10979
10980     v1 = vtop - 1;
10981     v2 = vtop;
10982     /* currently, we cannot do computations with forward symbols */
10983     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10984     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10985     if (c1 && c2) {
10986         fc = v2->c.i;
10987         switch(op) {
10988         case '+': v1->c.i += fc; break;
10989         case '-': v1->c.i -= fc; break;
10990         case '&': v1->c.i &= fc; break;
10991         case '^': v1->c.i ^= fc; break;
10992         case '|': v1->c.i |= fc; break;
10993         case '*': v1->c.i *= fc; break;
10994
10995         case TOK_PDIV:
10996         case '/':
10997         case '%':
10998         case TOK_UDIV:
10999         case TOK_UMOD:
11000             /* if division by zero, generate explicit division */
11001             if (fc == 0) {
11002                 if (const_wanted)
11003                     error("division by zero in constant");
11004                 goto general_case;
11005             }
11006             switch(op) {
11007             default: v1->c.i /= fc; break;
11008             case '%': v1->c.i %= fc; break;
11009             case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
11010             case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
11011             }
11012             break;
11013         case TOK_SHL: v1->c.i <<= fc; break;
11014         case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
11015         case TOK_SAR: v1->c.i >>= fc; break;
11016             /* tests */
11017         case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
11018         case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
11019         case TOK_EQ: v1->c.i = v1->c.i == fc; break;
11020         case TOK_NE: v1->c.i = v1->c.i != fc; break;
11021         case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
11022         case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
11023         case TOK_LT: v1->c.i = v1->c.i < fc; break;
11024         case TOK_GE: v1->c.i = v1->c.i >= fc; break;
11025         case TOK_LE: v1->c.i = v1->c.i <= fc; break;
11026         case TOK_GT: v1->c.i = v1->c.i > fc; break;
11027             /* logical */
11028         case TOK_LAND: v1->c.i = v1->c.i && fc; break;
11029         case TOK_LOR: v1->c.i = v1->c.i || fc; break;
11030         default:
11031             goto general_case;
11032         }
11033         vtop--;
11034     } else {
11035         /* if commutative ops, put c2 as constant */
11036         if (c1 && (op == '+' || op == '&' || op == '^' || 
11037                    op == '|' || op == '*')) {
11038             vswap();
11039             swap(&c1, &c2);
11040         }
11041         fc = vtop->c.i;
11042         if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 
11043                      op == TOK_PDIV) && 
11044                     fc == 1) ||
11045                    ((op == '+' || op == '-' || op == '|' || op == '^' || 
11046                      op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 
11047                     fc == 0) ||
11048                    (op == '&' && 
11049                     fc == -1))) {
11050             /* nothing to do */
11051             vtop--;
11052         } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
11053             /* try to use shifts instead of muls or divs */
11054             if (fc > 0 && (fc & (fc - 1)) == 0) {
11055                 n = -1;
11056                 while (fc) {
11057                     fc >>= 1;
11058                     n++;
11059                 }
11060                 vtop->c.i = n;
11061                 if (op == '*')
11062                     op = TOK_SHL;
11063                 else if (op == TOK_PDIV)
11064                     op = TOK_SAR;
11065                 else
11066                     op = TOK_SHR;
11067             }
11068             goto general_case;
11069         } else if (c2 && (op == '+' || op == '-') &&
11070                    (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == 
11071                    (VT_CONST | VT_SYM)) {
11072             /* symbol + constant case */
11073             if (op == '-')
11074                 fc = -fc;
11075             vtop--;
11076             vtop->c.i += fc;
11077         } else {
11078         general_case:
11079             if (!nocode_wanted) {
11080                 /* call low level op generator */
11081                 gen_opi(op);
11082             } else {
11083                 vtop--;
11084             }
11085         }
11086     }
11087 }
11088
11089 /* generate a floating point operation with constant propagation */
11090 void gen_opif(int op)
11091 {
11092     int c1, c2;
11093     SValue *v1, *v2;
11094     long double f1, f2;
11095
11096     v1 = vtop - 1;
11097     v2 = vtop;
11098     /* currently, we cannot do computations with forward symbols */
11099     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11100     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11101     if (c1 && c2) {
11102         if (v1->type.t == VT_FLOAT) {
11103             f1 = v1->c.f;
11104             f2 = v2->c.f;
11105         } else if (v1->type.t == VT_DOUBLE) {
11106             f1 = v1->c.d;
11107             f2 = v2->c.d;
11108         } else {
11109             f1 = v1->c.ld;
11110             f2 = v2->c.ld;
11111         }
11112
11113         /* NOTE: we only do constant propagation if finite number (not
11114            NaN or infinity) (ANSI spec) */
11115         if (!ieee_finite(f1) || !ieee_finite(f2))
11116             goto general_case;
11117
11118         switch(op) {
11119         case '+': f1 += f2; break;
11120         case '-': f1 -= f2; break;
11121         case '*': f1 *= f2; break;
11122         case '/': 
11123             if (f2 == 0.0) {
11124                 if (const_wanted)
11125                     error("division by zero in constant");
11126                 goto general_case;
11127             }
11128             f1 /= f2; 
11129             break;
11130             /* XXX: also handles tests ? */
11131         default:
11132             goto general_case;
11133         }
11134         /* XXX: overflow test ? */
11135         if (v1->type.t == VT_FLOAT) {
11136             v1->c.f = f1;
11137         } else if (v1->type.t == VT_DOUBLE) {
11138             v1->c.d = f1;
11139         } else {
11140             v1->c.ld = f1;
11141         }
11142         vtop--;
11143     } else {
11144     general_case:
11145         if (!nocode_wanted) {
11146             gen_opf(op);
11147         } else {
11148             vtop--;
11149         }
11150     }
11151 }
11152
11153 /* return the pointed type of t */
11154 static inline CType *pointed_type(CType *type)
11155 {
11156     return &type->ref->type;
11157 }
11158
11159 static int pointed_size(CType *type)
11160 {
11161     int align;
11162     return type_size(pointed_type(type), &align);
11163 }
11164
11165 static inline int is_null_pointer(SValue *p)
11166 {
11167     if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
11168         return 0;
11169     return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
11170         ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
11171 }
11172
11173 static inline int is_integer_btype(int bt)
11174 {
11175     return (bt == VT_BYTE || bt == VT_SHORT || 
11176             bt == VT_INT || bt == VT_LLONG);
11177 }
11178
11179 /* check types for comparison or substraction of pointers */
11180 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
11181 {
11182     CType *type1, *type2, tmp_type1, tmp_type2;
11183     int bt1, bt2;
11184     
11185     /* null pointers are accepted for all comparisons as gcc */
11186     if (is_null_pointer(p1) || is_null_pointer(p2))
11187         return;
11188     type1 = &p1->type;
11189     type2 = &p2->type;
11190     bt1 = type1->t & VT_BTYPE;
11191     bt2 = type2->t & VT_BTYPE;
11192     /* accept comparison between pointer and integer with a warning */
11193     if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
11194         warning("comparison between pointer and integer");
11195         return;
11196     }
11197
11198     /* both must be pointers or implicit function pointers */
11199     if (bt1 == VT_PTR) {
11200         type1 = pointed_type(type1);
11201     } else if (bt1 != VT_FUNC) 
11202         goto invalid_operands;
11203
11204     if (bt2 == VT_PTR) {
11205         type2 = pointed_type(type2);
11206     } else if (bt2 != VT_FUNC) { 
11207     invalid_operands:
11208         error("invalid operands to binary %s", get_tok_str(op, NULL));
11209     }
11210     if ((type1->t & VT_BTYPE) == VT_VOID || 
11211         (type2->t & VT_BTYPE) == VT_VOID)
11212         return;
11213     tmp_type1 = *type1;
11214     tmp_type2 = *type2;
11215     tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11216     tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11217     if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11218         /* gcc-like error if '-' is used */
11219         if (op == '-')
11220             goto invalid_operands;
11221         else
11222             warning("comparison of distinct pointer types lacks a cast");
11223     }
11224 }
11225
11226 /* generic gen_op: handles types problems */
11227 void gen_op(int op)
11228 {
11229     int u, t1, t2, bt1, bt2, t;
11230     CType type1;
11231
11232     t1 = vtop[-1].type.t;
11233     t2 = vtop[0].type.t;
11234     bt1 = t1 & VT_BTYPE;
11235     bt2 = t2 & VT_BTYPE;
11236         
11237     if (bt1 == VT_PTR || bt2 == VT_PTR) {
11238         /* at least one operand is a pointer */
11239         /* relationnal op: must be both pointers */
11240         if (op >= TOK_ULT && op <= TOK_GT) {
11241             check_comparison_pointer_types(vtop - 1, vtop, op);
11242             /* pointers are handled are unsigned */
11243             t = VT_INT | VT_UNSIGNED;
11244             goto std_op;
11245         }
11246         /* if both pointers, then it must be the '-' op */
11247         if (bt1 == VT_PTR && bt2 == VT_PTR) {
11248             if (op != '-')
11249                 error("cannot use pointers here");
11250             check_comparison_pointer_types(vtop - 1, vtop, op);
11251             /* XXX: check that types are compatible */
11252             u = pointed_size(&vtop[-1].type);
11253             gen_opic(op);
11254             /* set to integer type */
11255             vtop->type.t = VT_INT; 
11256             vpushi(u);
11257             gen_op(TOK_PDIV);
11258         } else {
11259             /* exactly one pointer : must be '+' or '-'. */
11260             if (op != '-' && op != '+')
11261                 error("cannot use pointers here");
11262             /* Put pointer as first operand */
11263             if (bt2 == VT_PTR) {
11264                 vswap();
11265                 swap(&t1, &t2);
11266             }
11267             type1 = vtop[-1].type;
11268             /* XXX: cast to int ? (long long case) */
11269             vpushi(pointed_size(&vtop[-1].type));
11270             gen_op('*');
11271 #ifdef CONFIG_TCC_BCHECK
11272             /* if evaluating constant expression, no code should be
11273                generated, so no bound check */
11274             if (do_bounds_check && !const_wanted) {
11275                 /* if bounded pointers, we generate a special code to
11276                    test bounds */
11277                 if (op == '-') {
11278                     vpushi(0);
11279                     vswap();
11280                     gen_op('-');
11281                 }
11282                 gen_bounded_ptr_add();
11283             } else
11284 #endif
11285             {
11286                 gen_opic(op);
11287             }
11288             /* put again type if gen_opic() swaped operands */
11289             vtop->type = type1;
11290         }
11291     } else if (is_float(bt1) || is_float(bt2)) {
11292         /* compute bigger type and do implicit casts */
11293         if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
11294             t = VT_LDOUBLE;
11295         } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
11296             t = VT_DOUBLE;
11297         } else {
11298             t = VT_FLOAT;
11299         }
11300         /* floats can only be used for a few operations */
11301         if (op != '+' && op != '-' && op != '*' && op != '/' &&
11302             (op < TOK_ULT || op > TOK_GT))
11303             error("invalid operands for binary operation");
11304         goto std_op;
11305     } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
11306         /* cast to biggest op */
11307         t = VT_LLONG;
11308         /* convert to unsigned if it does not fit in a long long */
11309         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
11310             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
11311             t |= VT_UNSIGNED;
11312         goto std_op;
11313     } else {
11314         /* integer operations */
11315         t = VT_INT;
11316         /* convert to unsigned if it does not fit in an integer */
11317         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
11318             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
11319             t |= VT_UNSIGNED;
11320     std_op:
11321         /* XXX: currently, some unsigned operations are explicit, so
11322            we modify them here */
11323         if (t & VT_UNSIGNED) {
11324             if (op == TOK_SAR)
11325                 op = TOK_SHR;
11326             else if (op == '/')
11327                 op = TOK_UDIV;
11328             else if (op == '%')
11329                 op = TOK_UMOD;
11330             else if (op == TOK_LT)
11331                 op = TOK_ULT;
11332             else if (op == TOK_GT)
11333                 op = TOK_UGT;
11334             else if (op == TOK_LE)
11335                 op = TOK_ULE;
11336             else if (op == TOK_GE)
11337                 op = TOK_UGE;
11338         }
11339         vswap();
11340         type1.t = t;
11341         gen_cast(&type1);
11342         vswap();
11343         /* special case for shifts and long long: we keep the shift as
11344            an integer */
11345         if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
11346             type1.t = VT_INT;
11347         gen_cast(&type1);
11348         if (is_float(t))
11349             gen_opif(op);
11350         else if ((t & VT_BTYPE) == VT_LLONG)
11351             gen_opl(op);
11352         else
11353             gen_opic(op);
11354         if (op >= TOK_ULT && op <= TOK_GT) {
11355             /* relationnal op: the result is an int */
11356             vtop->type.t = VT_INT;
11357         } else {
11358             vtop->type.t = t;
11359         }
11360     }
11361 }
11362
11363 /* generic itof for unsigned long long case */
11364 void gen_cvt_itof1(int t)
11365 {
11366     if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
11367         (VT_LLONG | VT_UNSIGNED)) {
11368
11369         if (t == VT_FLOAT)
11370             vpush_global_sym(&func_old_type, TOK___ulltof);
11371         else if (t == VT_DOUBLE)
11372             vpush_global_sym(&func_old_type, TOK___ulltod);
11373         else
11374             vpush_global_sym(&func_old_type, TOK___ulltold);
11375         vrott(2);
11376         gfunc_call(1);
11377         vpushi(0);
11378         vtop->r = REG_FRET;
11379     } else {
11380         gen_cvt_itof(t);
11381     }
11382 }
11383
11384 /* generic ftoi for unsigned long long case */
11385 void gen_cvt_ftoi1(int t)
11386 {
11387     int st;
11388
11389     if (t == (VT_LLONG | VT_UNSIGNED)) {
11390         /* not handled natively */
11391         st = vtop->type.t & VT_BTYPE;
11392         if (st == VT_FLOAT)
11393             vpush_global_sym(&func_old_type, TOK___fixunssfdi);
11394         else if (st == VT_DOUBLE)
11395             vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
11396         else
11397             vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
11398         vrott(2);
11399         gfunc_call(1);
11400         vpushi(0);
11401         vtop->r = REG_IRET;
11402         vtop->r2 = REG_LRET;
11403     } else {
11404         gen_cvt_ftoi(t);
11405     }
11406 }
11407
11408 /* force char or short cast */
11409 void force_charshort_cast(int t)
11410 {
11411     int bits, dbt;
11412     dbt = t & VT_BTYPE;
11413     /* XXX: add optimization if lvalue : just change type and offset */
11414     if (dbt == VT_BYTE)
11415         bits = 8;
11416     else
11417         bits = 16;
11418     if (t & VT_UNSIGNED) {
11419         vpushi((1 << bits) - 1);
11420         gen_op('&');
11421     } else {
11422         bits = 32 - bits;
11423         vpushi(bits);
11424         gen_op(TOK_SHL);
11425         vpushi(bits);
11426         gen_op(TOK_SAR);
11427     }
11428 }
11429
11430 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
11431 static void gen_cast(CType *type)
11432 {
11433     int sbt, dbt, sf, df, c;
11434
11435     /* special delayed cast for char/short */
11436     /* XXX: in some cases (multiple cascaded casts), it may still
11437        be incorrect */
11438     if (vtop->r & VT_MUSTCAST) {
11439         vtop->r &= ~VT_MUSTCAST;
11440         force_charshort_cast(vtop->type.t);
11441     }
11442
11443     /* bitfields first get cast to ints */
11444     if (vtop->type.t & VT_BITFIELD) {
11445         gv(RC_INT);
11446     }
11447
11448     dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
11449     sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
11450
11451     if (sbt != dbt && !nocode_wanted) {
11452         sf = is_float(sbt);
11453         df = is_float(dbt);
11454         c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11455         if (sf && df) {
11456             /* convert from fp to fp */
11457             if (c) {
11458                 /* constant case: we can do it now */
11459                 /* XXX: in ISOC, cannot do it if error in convert */
11460                 if (dbt == VT_FLOAT && sbt == VT_DOUBLE) 
11461                     vtop->c.f = (float)vtop->c.d;
11462                 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE) 
11463                     vtop->c.f = (float)vtop->c.ld;
11464                 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT) 
11465                     vtop->c.d = (double)vtop->c.f;
11466                 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE) 
11467                     vtop->c.d = (double)vtop->c.ld;
11468                 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT) 
11469                     vtop->c.ld = (long double)vtop->c.f;
11470                 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE) 
11471                     vtop->c.ld = (long double)vtop->c.d;
11472             } else {
11473                 /* non constant case: generate code */
11474                 gen_cvt_ftof(dbt);
11475             }
11476         } else if (df) {
11477             /* convert int to fp */
11478             if (c) {
11479                 switch(sbt) {
11480                 case VT_LLONG | VT_UNSIGNED:
11481                 case VT_LLONG:
11482                     /* XXX: add const cases for long long */
11483                     goto do_itof;
11484                 case VT_INT | VT_UNSIGNED:
11485                     switch(dbt) {
11486                     case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
11487                     case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
11488                     case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
11489                     }
11490                     break;
11491                 default:
11492                     switch(dbt) {
11493                     case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
11494                     case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
11495                     case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
11496                     }
11497                     break;
11498                 }
11499             } else {
11500             do_itof:
11501 #if !defined(TCC_TARGET_ARM)
11502                 gen_cvt_itof1(dbt);
11503 #else
11504                 gen_cvt_itof(dbt);
11505 #endif
11506             }
11507         } else if (sf) {
11508             /* convert fp to int */
11509             /* we handle char/short/etc... with generic code */
11510             if (dbt != (VT_INT | VT_UNSIGNED) &&
11511                 dbt != (VT_LLONG | VT_UNSIGNED) &&
11512                 dbt != VT_LLONG)
11513                 dbt = VT_INT;
11514             if (c) {
11515                 switch(dbt) {
11516                 case VT_LLONG | VT_UNSIGNED:
11517                 case VT_LLONG:
11518                     /* XXX: add const cases for long long */
11519                     goto do_ftoi;
11520                 case VT_INT | VT_UNSIGNED:
11521                     switch(sbt) {
11522                     case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
11523                     case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11524                     case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11525                     }
11526                     break;
11527                 default:
11528                     /* int case */
11529                     switch(sbt) {
11530                     case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
11531                     case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
11532                     case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
11533                     }
11534                     break;
11535                 }
11536             } else {
11537             do_ftoi:
11538                 gen_cvt_ftoi1(dbt);
11539             }
11540             if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
11541                 /* additional cast for char/short/bool... */
11542                 vtop->type.t = dbt;
11543                 gen_cast(type);
11544             }
11545         } else if ((dbt & VT_BTYPE) == VT_LLONG) {
11546             if ((sbt & VT_BTYPE) != VT_LLONG) {
11547                 /* scalar to long long */
11548                 if (c) {
11549                     if (sbt == (VT_INT | VT_UNSIGNED))
11550                         vtop->c.ll = vtop->c.ui;
11551                     else
11552                         vtop->c.ll = vtop->c.i;
11553                 } else {
11554                     /* machine independent conversion */
11555                     gv(RC_INT);
11556                     /* generate high word */
11557                     if (sbt == (VT_INT | VT_UNSIGNED)) {
11558                         vpushi(0);
11559                         gv(RC_INT);
11560                     } else {
11561                         gv_dup();
11562                         vpushi(31);
11563                         gen_op(TOK_SAR);
11564                     }
11565                     /* patch second register */
11566                     vtop[-1].r2 = vtop->r;
11567                     vpop();
11568                 }
11569             }
11570         } else if (dbt == VT_BOOL) {
11571             /* scalar to bool */
11572             vpushi(0);
11573             gen_op(TOK_NE);
11574         } else if ((dbt & VT_BTYPE) == VT_BYTE || 
11575                    (dbt & VT_BTYPE) == VT_SHORT) {
11576             force_charshort_cast(dbt);
11577         } else if ((dbt & VT_BTYPE) == VT_INT) {
11578             /* scalar to int */
11579             if (sbt == VT_LLONG) {
11580                 /* from long long: just take low order word */
11581                 lexpand();
11582                 vpop();
11583             } 
11584             /* if lvalue and single word type, nothing to do because
11585                the lvalue already contains the real type size (see
11586                VT_LVAL_xxx constants) */
11587         }
11588     }
11589     vtop->type = *type;
11590 }
11591
11592 /* return type size. Put alignment at 'a' */
11593 static int type_size(CType *type, int *a)
11594 {
11595     Sym *s;
11596     int bt;
11597
11598     bt = type->t & VT_BTYPE;
11599     if (bt == VT_STRUCT) {
11600         /* struct/union */
11601         s = type->ref;
11602         *a = s->r;
11603         return s->c;
11604     } else if (bt == VT_PTR) {
11605         if (type->t & VT_ARRAY) {
11606             s = type->ref;
11607             return type_size(&s->type, a) * s->c;
11608         } else {
11609             *a = PTR_SIZE;
11610             return PTR_SIZE;
11611         }
11612     } else if (bt == VT_LDOUBLE) {
11613         *a = LDOUBLE_ALIGN;
11614         return LDOUBLE_SIZE;
11615     } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
11616 #ifdef TCC_TARGET_I386
11617         *a = 4;
11618 #else
11619         *a = 8;
11620 #endif
11621         return 8;
11622     } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
11623         *a = 4;
11624         return 4;
11625     } else if (bt == VT_SHORT) {
11626         *a = 2;
11627         return 2;
11628     } else {
11629         /* char, void, function, _Bool */
11630         *a = 1;
11631         return 1;
11632     }
11633 }
11634
11635 /* modify type so that its it is a pointer to type. */
11636 static void mk_pointer(CType *type)
11637 {
11638     Sym *s;
11639     s = sym_push(SYM_FIELD, type, 0, -1);
11640     type->t = VT_PTR | (type->t & ~VT_TYPE);
11641     type->ref = s;
11642 }
11643
11644 /* compare function types. OLD functions match any new functions */
11645 static int is_compatible_func(CType *type1, CType *type2)
11646 {
11647     Sym *s1, *s2;
11648
11649     s1 = type1->ref;
11650     s2 = type2->ref;
11651     if (!is_compatible_types(&s1->type, &s2->type))
11652         return 0;
11653     /* check func_call */
11654     if (s1->r != s2->r)
11655         return 0;
11656     /* XXX: not complete */
11657     if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
11658         return 1;
11659     if (s1->c != s2->c)
11660         return 0;
11661     while (s1 != NULL) {
11662         if (s2 == NULL)
11663             return 0;
11664         if (!is_compatible_types(&s1->type, &s2->type))
11665             return 0;
11666         s1 = s1->next;
11667         s2 = s2->next;
11668     }
11669     if (s2)
11670         return 0;
11671     return 1;
11672 }
11673
11674 /* return true if type1 and type2 are exactly the same (including
11675    qualifiers). 
11676
11677    - enums are not checked as gcc __builtin_types_compatible_p () 
11678  */
11679 static int is_compatible_types(CType *type1, CType *type2)
11680 {
11681     int bt1, t1, t2;
11682
11683     t1 = type1->t & VT_TYPE;
11684     t2 = type2->t & VT_TYPE;
11685     /* XXX: bitfields ? */
11686     if (t1 != t2)
11687         return 0;
11688     /* test more complicated cases */
11689     bt1 = t1 & VT_BTYPE;
11690     if (bt1 == VT_PTR) {
11691         type1 = pointed_type(type1);
11692         type2 = pointed_type(type2);
11693         return is_compatible_types(type1, type2);
11694     } else if (bt1 == VT_STRUCT) {
11695         return (type1->ref == type2->ref);
11696     } else if (bt1 == VT_FUNC) {
11697         return is_compatible_func(type1, type2);
11698     } else {
11699         return 1;
11700     }
11701 }
11702
11703 /* print a type. If 'varstr' is not NULL, then the variable is also
11704    printed in the type */
11705 /* XXX: union */
11706 /* XXX: add array and function pointers */
11707 void type_to_str(char *buf, int buf_size, 
11708                  CType *type, const char *varstr)
11709 {
11710     int bt, v, t;
11711     Sym *s, *sa;
11712     char buf1[256];
11713     const char *tstr;
11714
11715     t = type->t & VT_TYPE;
11716     bt = t & VT_BTYPE;
11717     buf[0] = '\0';
11718     if (t & VT_CONSTANT)
11719         pstrcat(buf, buf_size, "const ");
11720     if (t & VT_VOLATILE)
11721         pstrcat(buf, buf_size, "volatile ");
11722     if (t & VT_UNSIGNED)
11723         pstrcat(buf, buf_size, "unsigned ");
11724     switch(bt) {
11725     case VT_VOID:
11726         tstr = "void";
11727         goto add_tstr;
11728     case VT_BOOL:
11729         tstr = "_Bool";
11730         goto add_tstr;
11731     case VT_BYTE:
11732         tstr = "char";
11733         goto add_tstr;
11734     case VT_SHORT:
11735         tstr = "short";
11736         goto add_tstr;
11737     case VT_INT:
11738         tstr = "int";
11739         goto add_tstr;
11740     case VT_LONG:
11741         tstr = "long";
11742         goto add_tstr;
11743     case VT_LLONG:
11744         tstr = "long long";
11745         goto add_tstr;
11746     case VT_FLOAT:
11747         tstr = "float";
11748         goto add_tstr;
11749     case VT_DOUBLE:
11750         tstr = "double";
11751         goto add_tstr;
11752     case VT_LDOUBLE:
11753         tstr = "long double";
11754     add_tstr:
11755         pstrcat(buf, buf_size, tstr);
11756         break;
11757     case VT_ENUM:
11758     case VT_STRUCT:
11759         if (bt == VT_STRUCT)
11760             tstr = "struct ";
11761         else
11762             tstr = "enum ";
11763         pstrcat(buf, buf_size, tstr);
11764         v = type->ref->v & ~SYM_STRUCT;
11765         if (v >= SYM_FIRST_ANOM)
11766             pstrcat(buf, buf_size, "<anonymous>");
11767         else
11768             pstrcat(buf, buf_size, get_tok_str(v, NULL));
11769         break;
11770     case VT_FUNC:
11771         s = type->ref;
11772         type_to_str(buf, buf_size, &s->type, varstr);
11773         pstrcat(buf, buf_size, "(");
11774         sa = s->next;
11775         while (sa != NULL) {
11776             type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
11777             pstrcat(buf, buf_size, buf1);
11778             sa = sa->next;
11779             if (sa)
11780                 pstrcat(buf, buf_size, ", ");
11781         }
11782         pstrcat(buf, buf_size, ")");
11783         goto no_var;
11784     case VT_PTR:
11785         s = type->ref;
11786         pstrcpy(buf1, sizeof(buf1), "*");
11787         if (varstr)
11788             pstrcat(buf1, sizeof(buf1), varstr);
11789         type_to_str(buf, buf_size, &s->type, buf1);
11790         goto no_var;
11791     }
11792     if (varstr) {
11793         pstrcat(buf, buf_size, " ");
11794         pstrcat(buf, buf_size, varstr);
11795     }
11796  no_var: ;
11797 }
11798
11799 /* verify type compatibility to store vtop in 'dt' type, and generate
11800    casts if needed. */
11801 static void gen_assign_cast(CType *dt)
11802 {
11803     CType *st, *type1, *type2, tmp_type1, tmp_type2;
11804     char buf1[256], buf2[256];
11805     int dbt, sbt;
11806
11807     st = &vtop->type; /* source type */
11808     dbt = dt->t & VT_BTYPE;
11809     sbt = st->t & VT_BTYPE;
11810     if (dt->t & VT_CONSTANT)
11811         warning("assignment of read-only location");
11812     switch(dbt) {
11813     case VT_PTR:
11814         /* special cases for pointers */
11815         /* '0' can also be a pointer */
11816         if (is_null_pointer(vtop))
11817             goto type_ok;
11818         /* accept implicit pointer to integer cast with warning */
11819         if (is_integer_btype(sbt)) {
11820             warning("assignment makes pointer from integer without a cast");
11821             goto type_ok;
11822         }
11823         type1 = pointed_type(dt);
11824         /* a function is implicitely a function pointer */
11825         if (sbt == VT_FUNC) {
11826             if ((type1->t & VT_BTYPE) != VT_VOID &&
11827                 !is_compatible_types(pointed_type(dt), st))
11828                 goto error;
11829             else
11830                 goto type_ok;
11831         }
11832         if (sbt != VT_PTR)
11833             goto error;
11834         type2 = pointed_type(st);
11835         if ((type1->t & VT_BTYPE) == VT_VOID || 
11836             (type2->t & VT_BTYPE) == VT_VOID) {
11837             /* void * can match anything */
11838         } else {
11839             /* exact type match, except for unsigned */
11840             tmp_type1 = *type1;
11841             tmp_type2 = *type2;
11842             tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11843             tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11844             if (!is_compatible_types(&tmp_type1, &tmp_type2))
11845                 goto error;
11846         }
11847         /* check const and volatile */
11848         if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
11849             (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
11850             warning("assignment discards qualifiers from pointer target type");
11851         break;
11852     case VT_BYTE:
11853     case VT_SHORT:
11854     case VT_INT:
11855     case VT_LLONG:
11856         if (sbt == VT_PTR || sbt == VT_FUNC) {
11857             warning("assignment makes integer from pointer without a cast");
11858         }
11859         /* XXX: more tests */
11860         break;
11861     case VT_STRUCT:
11862         tmp_type1 = *dt;
11863         tmp_type2 = *st;
11864         tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
11865         tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
11866         if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11867         error:
11868             type_to_str(buf1, sizeof(buf1), st, NULL);
11869             type_to_str(buf2, sizeof(buf2), dt, NULL);
11870             error("cannot cast '%s' to '%s'", buf1, buf2);
11871         }
11872         break;
11873     }
11874  type_ok:
11875     gen_cast(dt);
11876 }
11877
11878 /* store vtop in lvalue pushed on stack */
11879 void vstore(void)
11880 {
11881     int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
11882
11883     ft = vtop[-1].type.t;
11884     sbt = vtop->type.t & VT_BTYPE;
11885     dbt = ft & VT_BTYPE;
11886     if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
11887         (sbt == VT_INT && dbt == VT_SHORT)) {
11888         /* optimize char/short casts */
11889         delayed_cast = VT_MUSTCAST;
11890         vtop->type.t = ft & VT_TYPE;
11891         /* XXX: factorize */
11892         if (ft & VT_CONSTANT)
11893             warning("assignment of read-only location");
11894     } else {
11895         delayed_cast = 0;
11896         if (!(ft & VT_BITFIELD))
11897             gen_assign_cast(&vtop[-1].type);
11898     }
11899
11900     if (sbt == VT_STRUCT) {
11901         /* if structure, only generate pointer */
11902         /* structure assignment : generate memcpy */
11903         /* XXX: optimize if small size */
11904         if (!nocode_wanted) {
11905             size = type_size(&vtop->type, &align);
11906
11907             vpush_global_sym(&func_old_type, TOK_memcpy);
11908
11909             /* destination */
11910             vpushv(vtop - 2);
11911             vtop->type.t = VT_INT;
11912             gaddrof();
11913             /* source */
11914             vpushv(vtop - 2);
11915             vtop->type.t = VT_INT;
11916             gaddrof();
11917             /* type size */
11918             vpushi(size);
11919             gfunc_call(3);
11920             
11921             vswap();
11922             vpop();
11923         } else {
11924             vswap();
11925             vpop();
11926         }
11927         /* leave source on stack */
11928     } else if (ft & VT_BITFIELD) {
11929         /* bitfield store handling */
11930         bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
11931         bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
11932         /* remove bit field info to avoid loops */
11933         vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
11934
11935         /* duplicate destination */
11936         vdup();
11937         vtop[-1] = vtop[-2];
11938
11939         /* mask and shift source */
11940         vpushi((1 << bit_size) - 1);
11941         gen_op('&');
11942         vpushi(bit_pos);
11943         gen_op(TOK_SHL);
11944         /* load destination, mask and or with source */
11945         vswap();
11946         vpushi(~(((1 << bit_size) - 1) << bit_pos));
11947         gen_op('&');
11948         gen_op('|');
11949         /* store result */
11950         vstore();
11951     } else {
11952 #ifdef CONFIG_TCC_BCHECK
11953         /* bound check case */
11954         if (vtop[-1].r & VT_MUSTBOUND) {
11955             vswap();
11956             gbound();
11957             vswap();
11958         }
11959 #endif
11960         if (!nocode_wanted) {
11961             rc = RC_INT;
11962             if (is_float(ft))
11963                 rc = RC_FLOAT;
11964             r = gv(rc);  /* generate value */
11965             /* if lvalue was saved on stack, must read it */
11966             if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
11967                 SValue sv;
11968                 t = get_reg(RC_INT);
11969                 sv.type.t = VT_INT;
11970                 sv.r = VT_LOCAL | VT_LVAL;
11971                 sv.c.ul = vtop[-1].c.ul;
11972                 load(t, &sv);
11973                 vtop[-1].r = t | VT_LVAL;
11974             }
11975             store(r, vtop - 1);
11976             /* two word case handling : store second register at word + 4 */
11977             if ((ft & VT_BTYPE) == VT_LLONG) {
11978                 vswap();
11979                 /* convert to int to increment easily */
11980                 vtop->type.t = VT_INT;
11981                 gaddrof();
11982                 vpushi(4);
11983                 gen_op('+');
11984                 vtop->r |= VT_LVAL;
11985                 vswap();
11986                 /* XXX: it works because r2 is spilled last ! */
11987                 store(vtop->r2, vtop - 1);
11988             }
11989         }
11990         vswap();
11991         vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
11992         vtop->r |= delayed_cast;
11993     }
11994 }
11995
11996 /* post defines POST/PRE add. c is the token ++ or -- */
11997 void inc(int post, int c)
11998 {
11999     test_lvalue();
12000     vdup(); /* save lvalue */
12001     if (post) {
12002         gv_dup(); /* duplicate value */
12003         vrotb(3);
12004         vrotb(3);
12005     }
12006     /* add constant */
12007     vpushi(c - TOK_MID); 
12008     gen_op('+');
12009     vstore(); /* store value */
12010     if (post)
12011         vpop(); /* if post op, return saved value */
12012 }
12013
12014 /* Parse GNUC __attribute__ extension. Currently, the following
12015    extensions are recognized:
12016    - aligned(n) : set data/function alignment.
12017    - packed : force data alignment to 1
12018    - section(x) : generate data/code in this section.
12019    - unused : currently ignored, but may be used someday.
12020    - regparm(n) : pass function parameters in registers (i386 only)
12021  */
12022 static void parse_attribute(AttributeDef *ad)
12023 {
12024     int t, n;
12025     
12026     while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
12027     next();
12028     skip('(');
12029     skip('(');
12030     while (tok != ')') {
12031         if (tok < TOK_IDENT)
12032             expect("attribute name");
12033         t = tok;
12034         next();
12035         switch(t) {
12036         case TOK_SECTION1:
12037         case TOK_SECTION2:
12038             skip('(');
12039             if (tok != TOK_STR)
12040                 expect("section name");
12041             ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
12042             next();
12043             skip(')');
12044             break;
12045         case TOK_ALIGNED1:
12046         case TOK_ALIGNED2:
12047             if (tok == '(') {
12048                 next();
12049                 n = expr_const();
12050                 if (n <= 0 || (n & (n - 1)) != 0) 
12051                     error("alignment must be a positive power of two");
12052                 skip(')');
12053             } else {
12054                 n = MAX_ALIGN;
12055             }
12056             ad->aligned = n;
12057             break;
12058         case TOK_PACKED1:
12059         case TOK_PACKED2:
12060             ad->packed = 1;
12061             break;
12062         case TOK_UNUSED1:
12063         case TOK_UNUSED2:
12064             /* currently, no need to handle it because tcc does not
12065                track unused objects */
12066             break;
12067         case TOK_NORETURN1:
12068         case TOK_NORETURN2:
12069             /* currently, no need to handle it because tcc does not
12070                track unused objects */
12071             break;
12072         case TOK_CDECL1:
12073         case TOK_CDECL2:
12074         case TOK_CDECL3:
12075             ad->func_call = FUNC_CDECL;
12076             break;
12077         case TOK_STDCALL1:
12078         case TOK_STDCALL2:
12079         case TOK_STDCALL3:
12080             ad->func_call = FUNC_STDCALL;
12081             break;
12082 #ifdef TCC_TARGET_I386
12083         case TOK_REGPARM1:
12084         case TOK_REGPARM2:
12085             skip('(');
12086             n = expr_const();
12087             if (n > 3) 
12088                 n = 3;
12089             else if (n < 0)
12090                 n = 0;
12091             if (n > 0)
12092                 ad->func_call = FUNC_FASTCALL1 + n - 1;
12093             skip(')');
12094             break;
12095 #endif
12096         case TOK_DLLEXPORT:
12097             ad->dllexport = 1;
12098             break;
12099         default:
12100             if (tcc_state->warn_unsupported)
12101                 warning("'%s' attribute ignored", get_tok_str(t, NULL));
12102             /* skip parameters */
12103             /* XXX: skip parenthesis too */
12104             if (tok == '(') {
12105                 next();
12106                 while (tok != ')' && tok != -1)
12107                     next();
12108                 next();
12109             }
12110             break;
12111         }
12112         if (tok != ',')
12113             break;
12114         next();
12115     }
12116     skip(')');
12117     skip(')');
12118     }
12119 }
12120
12121 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
12122 static void struct_decl(CType *type, int u)
12123 {
12124     int a, v, size, align, maxalign, c, offset;
12125     int bit_size, bit_pos, bsize, bt, lbit_pos;
12126     Sym *s, *ss, **ps;
12127     AttributeDef ad;
12128     CType type1, btype;
12129
12130     a = tok; /* save decl type */
12131     next();
12132     if (tok != '{') {
12133         v = tok;
12134         next();
12135         /* struct already defined ? return it */
12136         if (v < TOK_IDENT)
12137             expect("struct/union/enum name");
12138         s = struct_find(v);
12139         if (s) {
12140             if (s->type.t != a)
12141                 error("invalid type");
12142             goto do_decl;
12143         }
12144     } else {
12145         v = anon_sym++;
12146     }
12147     type1.t = a;
12148     /* we put an undefined size for struct/union */
12149     s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
12150     s->r = 0; /* default alignment is zero as gcc */
12151     /* put struct/union/enum name in type */
12152  do_decl:
12153     type->t = u;
12154     type->ref = s;
12155     
12156     if (tok == '{') {
12157         next();
12158         if (s->c != -1)
12159             error("struct/union/enum already defined");
12160         /* cannot be empty */
12161         c = 0;
12162         /* non empty enums are not allowed */
12163         if (a == TOK_ENUM) {
12164             for(;;) {
12165                 v = tok;
12166                 if (v < TOK_UIDENT)
12167                     expect("identifier");
12168                 next();
12169                 if (tok == '=') {
12170                     next();
12171                     c = expr_const();
12172                 }
12173                 /* enum symbols have static storage */
12174                 ss = sym_push(v, &int_type, VT_CONST, c);
12175                 ss->type.t |= VT_STATIC;
12176                 if (tok != ',')
12177                     break;
12178                 next();
12179                 c++;
12180                 /* NOTE: we accept a trailing comma */
12181                 if (tok == '}')
12182                     break;
12183             }
12184             skip('}');
12185         } else {
12186             maxalign = 1;
12187             ps = &s->next;
12188             bit_pos = 0;
12189             offset = 0;
12190             while (tok != '}') {
12191                 parse_btype(&btype, &ad);
12192                 while (1) {
12193                     bit_size = -1;
12194                     v = 0;
12195                     type1 = btype;
12196                     if (tok != ':') {
12197                         type_decl(&type1, &ad, &v, TYPE_DIRECT);
12198                         if ((type1.t & VT_BTYPE) == VT_FUNC ||
12199                             (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
12200                             error("invalid type for '%s'", 
12201                                   get_tok_str(v, NULL));
12202                     }
12203                     if (tok == ':') {
12204                         next();
12205                         bit_size = expr_const();
12206                         /* XXX: handle v = 0 case for messages */
12207                         if (bit_size < 0)
12208                             error("negative width in bit-field '%s'", 
12209                                   get_tok_str(v, NULL));
12210                         if (v && bit_size == 0)
12211                             error("zero width for bit-field '%s'", 
12212                                   get_tok_str(v, NULL));
12213                     }
12214                     size = type_size(&type1, &align);
12215                     if (ad.aligned) {
12216                         if (align < ad.aligned)
12217                             align = ad.aligned;
12218                     } else if (ad.packed) {
12219                         align = 1;
12220                     } else if (*tcc_state->pack_stack_ptr) {
12221                         if (align > *tcc_state->pack_stack_ptr)
12222                             align = *tcc_state->pack_stack_ptr;
12223                     }
12224                     lbit_pos = 0;
12225                     if (bit_size >= 0) {
12226                         bt = type1.t & VT_BTYPE;
12227                         if (bt != VT_INT && 
12228                             bt != VT_BYTE && 
12229                             bt != VT_SHORT &&
12230                             bt != VT_BOOL &&
12231                             bt != VT_ENUM)
12232                             error("bitfields must have scalar type");
12233                         bsize = size * 8;
12234                         if (bit_size > bsize) {
12235                             error("width of '%s' exceeds its type",
12236                                   get_tok_str(v, NULL));
12237                         } else if (bit_size == bsize) {
12238                             /* no need for bit fields */
12239                             bit_pos = 0;
12240                         } else if (bit_size == 0) {
12241                             /* XXX: what to do if only padding in a
12242                                structure ? */
12243                             /* zero size: means to pad */
12244                             if (bit_pos > 0)
12245                                 bit_pos = bsize;
12246                         } else {
12247                             /* we do not have enough room ? */
12248                             if ((bit_pos + bit_size) > bsize)
12249                                 bit_pos = 0;
12250                             lbit_pos = bit_pos;
12251                             /* XXX: handle LSB first */
12252                             type1.t |= VT_BITFIELD | 
12253                                 (bit_pos << VT_STRUCT_SHIFT) |
12254                                 (bit_size << (VT_STRUCT_SHIFT + 6));
12255                             bit_pos += bit_size;
12256                         }
12257                     } else {
12258                         bit_pos = 0;
12259                     }
12260                     if (v) {
12261                         /* add new memory data only if starting
12262                            bit field */
12263                         if (lbit_pos == 0) {
12264                             if (a == TOK_STRUCT) {
12265                                 c = (c + align - 1) & -align;
12266                                 offset = c;
12267                                 c += size;
12268                             } else {
12269                                 offset = 0;
12270                                 if (size > c)
12271                                     c = size;
12272                             }
12273                             if (align > maxalign)
12274                                 maxalign = align;
12275                         }
12276 #if 0
12277                         printf("add field %s offset=%d", 
12278                                get_tok_str(v, NULL), offset);
12279                         if (type1.t & VT_BITFIELD) {
12280                             printf(" pos=%d size=%d", 
12281                                    (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
12282                                    (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
12283                         }
12284                         printf("\n");
12285 #endif
12286                         ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
12287                         *ps = ss;
12288                         ps = &ss->next;
12289                     }
12290                     if (tok == ';' || tok == TOK_EOF)
12291                         break;
12292                     skip(',');
12293                 }
12294                 skip(';');
12295             }
12296             skip('}');
12297             /* store size and alignment */
12298             s->c = (c + maxalign - 1) & -maxalign; 
12299             s->r = maxalign;
12300         }
12301     }
12302 }
12303
12304 /* return 0 if no type declaration. otherwise, return the basic type
12305    and skip it. 
12306  */
12307 static int parse_btype(CType *type, AttributeDef *ad)
12308 {
12309     int t, u, type_found, typespec_found;
12310     Sym *s;
12311     CType type1;
12312
12313     memset(ad, 0, sizeof(AttributeDef));
12314     type_found = 0;
12315     typespec_found = 0;
12316     t = 0;
12317     while(1) {
12318         switch(tok) {
12319         case TOK_EXTENSION:
12320             /* currently, we really ignore extension */
12321             next();
12322             continue;
12323
12324             /* basic types */
12325         case TOK_CHAR:
12326             u = VT_BYTE;
12327         basic_type:
12328             next();
12329         basic_type1:
12330             if ((t & VT_BTYPE) != 0)
12331                 error("too many basic types");
12332             t |= u;
12333             typespec_found = 1;
12334             break;
12335         case TOK_VOID:
12336             u = VT_VOID;
12337             goto basic_type;
12338         case TOK_SHORT:
12339             u = VT_SHORT;
12340             goto basic_type;
12341         case TOK_INT:
12342             next();
12343             typespec_found = 1;
12344             break;
12345         case TOK_LONG:
12346             next();
12347             if ((t & VT_BTYPE) == VT_DOUBLE) {
12348                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12349             } else if ((t & VT_BTYPE) == VT_LONG) {
12350                 t = (t & ~VT_BTYPE) | VT_LLONG;
12351             } else {
12352                 u = VT_LONG;
12353                 goto basic_type1;
12354             }
12355             break;
12356         case TOK_BOOL:
12357             u = VT_BOOL;
12358             goto basic_type;
12359         case TOK_FLOAT:
12360             u = VT_FLOAT;
12361             goto basic_type;
12362         case TOK_DOUBLE:
12363             next();
12364             if ((t & VT_BTYPE) == VT_LONG) {
12365                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12366             } else {
12367                 u = VT_DOUBLE;
12368                 goto basic_type1;
12369             }
12370             break;
12371         case TOK_ENUM:
12372             struct_decl(&type1, VT_ENUM);
12373         basic_type2:
12374             u = type1.t;
12375             type->ref = type1.ref;
12376             goto basic_type1;
12377         case TOK_STRUCT:
12378         case TOK_UNION:
12379             struct_decl(&type1, VT_STRUCT);
12380             goto basic_type2;
12381
12382             /* type modifiers */
12383         case TOK_CONST1:
12384         case TOK_CONST2:
12385         case TOK_CONST3:
12386             t |= VT_CONSTANT;
12387             next();
12388             break;
12389         case TOK_VOLATILE1:
12390         case TOK_VOLATILE2:
12391         case TOK_VOLATILE3:
12392             t |= VT_VOLATILE;
12393             next();
12394             break;
12395         case TOK_SIGNED1:
12396         case TOK_SIGNED2:
12397         case TOK_SIGNED3:
12398             typespec_found = 1;
12399             t |= VT_SIGNED;
12400             next();
12401             break;
12402         case TOK_REGISTER:
12403         case TOK_AUTO:
12404         case TOK_RESTRICT1:
12405         case TOK_RESTRICT2:
12406         case TOK_RESTRICT3:
12407             next();
12408             break;
12409         case TOK_UNSIGNED:
12410             t |= VT_UNSIGNED;
12411             next();
12412             typespec_found = 1;
12413             break;
12414
12415             /* storage */
12416         case TOK_EXTERN:
12417             t |= VT_EXTERN;
12418             next();
12419             break;
12420         case TOK_STATIC:
12421             t |= VT_STATIC;
12422             next();
12423             break;
12424         case TOK_TYPEDEF:
12425             t |= VT_TYPEDEF;
12426             next();
12427             break;
12428         case TOK_INLINE1:
12429         case TOK_INLINE2:
12430         case TOK_INLINE3:
12431             t |= VT_INLINE;
12432             next();
12433             break;
12434
12435             /* GNUC attribute */
12436         case TOK_ATTRIBUTE1:
12437         case TOK_ATTRIBUTE2:
12438             parse_attribute(ad);
12439             break;
12440             /* GNUC typeof */
12441         case TOK_TYPEOF1:
12442         case TOK_TYPEOF2:
12443         case TOK_TYPEOF3:
12444             next();
12445             parse_expr_type(&type1);
12446             goto basic_type2;
12447         default:
12448             if (typespec_found)
12449                 goto the_end;
12450             s = sym_find(tok);
12451             if (!s || !(s->type.t & VT_TYPEDEF))
12452                 goto the_end;
12453             t |= (s->type.t & ~VT_TYPEDEF);
12454             type->ref = s->type.ref;
12455             next();
12456             break;
12457         }
12458         type_found = 1;
12459     }
12460 the_end:
12461     if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
12462       error("signed and unsigned modifier");
12463     if (tcc_state->char_is_unsigned) {
12464         if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
12465             t |= VT_UNSIGNED;
12466     }
12467     t &= ~VT_SIGNED;
12468
12469     /* long is never used as type */
12470     if ((t & VT_BTYPE) == VT_LONG)
12471         t = (t & ~VT_BTYPE) | VT_INT;
12472     type->t = t;
12473     return type_found;
12474 }
12475
12476 /* convert a function parameter type (array to pointer and function to
12477    function pointer) */
12478 static inline void convert_parameter_type(CType *pt)
12479 {
12480     /* remove const and volatile qualifiers (XXX: const could be used
12481        to indicate a const function parameter */
12482     pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
12483     /* array must be transformed to pointer according to ANSI C */
12484     pt->t &= ~VT_ARRAY;
12485     if ((pt->t & VT_BTYPE) == VT_FUNC) {
12486         mk_pointer(pt);
12487     }
12488 }
12489
12490 static void post_type(CType *type, AttributeDef *ad)
12491 {
12492     int n, l, t1;
12493     Sym **plast, *s, *first;
12494     AttributeDef ad1;
12495     CType pt;
12496
12497     if (tok == '(') {
12498         /* function declaration */
12499         next();
12500         l = 0;
12501         first = NULL;
12502         plast = &first;
12503         while (tok != ')') {
12504             /* read param name and compute offset */
12505             if (l != FUNC_OLD) {
12506                 if (!parse_btype(&pt, &ad1)) {
12507                     if (l) {
12508                         error("invalid type");
12509                     } else {
12510                         l = FUNC_OLD;
12511                         goto old_proto;
12512                     }
12513                 }
12514                 l = FUNC_NEW;
12515                 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
12516                     break;
12517                 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
12518                 if ((pt.t & VT_BTYPE) == VT_VOID)
12519                     error("parameter declared as void");
12520             } else {
12521             old_proto:
12522                 n = tok;
12523                 pt.t = VT_INT;
12524                 next();
12525             }
12526             convert_parameter_type(&pt);
12527             s = sym_push(n | SYM_FIELD, &pt, 0, 0);
12528             *plast = s;
12529             plast = &s->next;
12530             if (tok == ',') {
12531                 next();
12532                 if (l == FUNC_NEW && tok == TOK_DOTS) {
12533                     l = FUNC_ELLIPSIS;
12534                     next();
12535                     break;
12536                 }
12537             }
12538         }
12539         /* if no parameters, then old type prototype */
12540         if (l == 0)
12541             l = FUNC_OLD;
12542         skip(')');
12543         t1 = type->t & VT_STORAGE;
12544         /* NOTE: const is ignored in returned type as it has a special
12545            meaning in gcc / C++ */
12546         type->t &= ~(VT_STORAGE | VT_CONSTANT); 
12547         post_type(type, ad);
12548         /* we push a anonymous symbol which will contain the function prototype */
12549         s = sym_push(SYM_FIELD, type, ad->func_call, l);
12550         s->next = first;
12551         type->t = t1 | VT_FUNC;
12552         type->ref = s;
12553     } else if (tok == '[') {
12554         /* array definition */
12555         next();
12556         n = -1;
12557         if (tok != ']') {
12558             n = expr_const();
12559             if (n < 0)
12560                 error("invalid array size");    
12561         }
12562         skip(']');
12563         /* parse next post type */
12564         t1 = type->t & VT_STORAGE;
12565         type->t &= ~VT_STORAGE;
12566         post_type(type, ad);
12567         
12568         /* we push a anonymous symbol which will contain the array
12569            element type */
12570         s = sym_push(SYM_FIELD, type, 0, n);
12571         type->t = t1 | VT_ARRAY | VT_PTR;
12572         type->ref = s;
12573     }
12574 }
12575
12576 /* Parse a type declaration (except basic type), and return the type
12577    in 'type'. 'td' is a bitmask indicating which kind of type decl is
12578    expected. 'type' should contain the basic type. 'ad' is the
12579    attribute definition of the basic type. It can be modified by
12580    type_decl(). 
12581  */
12582 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
12583 {
12584     Sym *s;
12585     CType type1, *type2;
12586     int qualifiers;
12587     
12588     while (tok == '*') {
12589         qualifiers = 0;
12590     redo:
12591         next();
12592         switch(tok) {
12593         case TOK_CONST1:
12594         case TOK_CONST2:
12595         case TOK_CONST3:
12596             qualifiers |= VT_CONSTANT;
12597             goto redo;
12598         case TOK_VOLATILE1:
12599         case TOK_VOLATILE2:
12600         case TOK_VOLATILE3:
12601             qualifiers |= VT_VOLATILE;
12602             goto redo;
12603         case TOK_RESTRICT1:
12604         case TOK_RESTRICT2:
12605         case TOK_RESTRICT3:
12606             goto redo;
12607         }
12608         mk_pointer(type);
12609         type->t |= qualifiers;
12610     }
12611     
12612     /* XXX: clarify attribute handling */
12613     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12614         parse_attribute(ad);
12615
12616     /* recursive type */
12617     /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
12618     type1.t = 0; /* XXX: same as int */
12619     if (tok == '(') {
12620         next();
12621         /* XXX: this is not correct to modify 'ad' at this point, but
12622            the syntax is not clear */
12623         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12624             parse_attribute(ad);
12625         type_decl(&type1, ad, v, td);
12626         skip(')');
12627     } else {
12628         /* type identifier */
12629         if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
12630             *v = tok;
12631             next();
12632         } else {
12633             if (!(td & TYPE_ABSTRACT))
12634                 expect("identifier");
12635             *v = 0;
12636         }
12637     }
12638     post_type(type, ad);
12639     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12640         parse_attribute(ad);
12641     if (!type1.t)
12642         return;
12643     /* append type at the end of type1 */
12644     type2 = &type1;
12645     for(;;) {
12646         s = type2->ref;
12647         type2 = &s->type;
12648         if (!type2->t) {
12649             *type2 = *type;
12650             break;
12651         }
12652     }
12653     *type = type1;
12654 }
12655
12656 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
12657 static int lvalue_type(int t)
12658 {
12659     int bt, r;
12660     r = VT_LVAL;
12661     bt = t & VT_BTYPE;
12662     if (bt == VT_BYTE || bt == VT_BOOL)
12663         r |= VT_LVAL_BYTE;
12664     else if (bt == VT_SHORT)
12665         r |= VT_LVAL_SHORT;
12666     else
12667         return r;
12668     if (t & VT_UNSIGNED)
12669         r |= VT_LVAL_UNSIGNED;
12670     return r;
12671 }
12672
12673 /* indirection with full error checking and bound check */
12674 static void indir(void)
12675 {
12676     if ((vtop->type.t & VT_BTYPE) != VT_PTR)
12677         expect("pointer");
12678     if ((vtop->r & VT_LVAL) && !nocode_wanted)
12679         gv(RC_INT);
12680     vtop->type = *pointed_type(&vtop->type);
12681     /* an array is never an lvalue */
12682     if (!(vtop->type.t & VT_ARRAY)) {
12683         vtop->r |= lvalue_type(vtop->type.t);
12684         /* if bound checking, the referenced pointer must be checked */
12685         if (do_bounds_check) 
12686             vtop->r |= VT_MUSTBOUND;
12687     }
12688 }
12689
12690 /* pass a parameter to a function and do type checking and casting */
12691 static void gfunc_param_typed(Sym *func, Sym *arg)
12692 {
12693     int func_type;
12694     CType type;
12695
12696     func_type = func->c;
12697     if (func_type == FUNC_OLD ||
12698         (func_type == FUNC_ELLIPSIS && arg == NULL)) {
12699         /* default casting : only need to convert float to double */
12700         if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
12701             type.t = VT_DOUBLE;
12702             gen_cast(&type);
12703         }
12704     } else if (arg == NULL) {
12705         error("too many arguments to function");
12706     } else {
12707         type = arg->type;
12708         type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
12709         gen_assign_cast(&type);
12710     }
12711 }
12712
12713 /* parse an expression of the form '(type)' or '(expr)' and return its
12714    type */
12715 static void parse_expr_type(CType *type)
12716 {
12717     int n;
12718     AttributeDef ad;
12719
12720     skip('(');
12721     if (parse_btype(type, &ad)) {
12722         type_decl(type, &ad, &n, TYPE_ABSTRACT);
12723     } else {
12724         expr_type(type);
12725     }
12726     skip(')');
12727 }
12728
12729 static void parse_type(CType *type)
12730 {
12731     AttributeDef ad;
12732     int n;
12733
12734     if (!parse_btype(type, &ad)) {
12735         expect("type");
12736     }
12737     type_decl(type, &ad, &n, TYPE_ABSTRACT);
12738 }
12739
12740 static void vpush_tokc(int t)
12741 {
12742     CType type;
12743     type.t = t;
12744     vsetc(&type, VT_CONST, &tokc);
12745 }
12746
12747 static void unary(void)
12748 {
12749     int n, t, align, size, r;
12750     CType type;
12751     Sym *s;
12752     AttributeDef ad;
12753
12754     /* XXX: GCC 2.95.3 does not generate a table although it should be
12755        better here */
12756  tok_next:
12757     switch(tok) {
12758     case TOK_EXTENSION:
12759         next();
12760         goto tok_next;
12761     case TOK_CINT:
12762     case TOK_CCHAR: 
12763     case TOK_LCHAR:
12764         vpushi(tokc.i);
12765         next();
12766         break;
12767     case TOK_CUINT:
12768         vpush_tokc(VT_INT | VT_UNSIGNED);
12769         next();
12770         break;
12771     case TOK_CLLONG:
12772         vpush_tokc(VT_LLONG);
12773         next();
12774         break;
12775     case TOK_CULLONG:
12776         vpush_tokc(VT_LLONG | VT_UNSIGNED);
12777         next();
12778         break;
12779     case TOK_CFLOAT:
12780         vpush_tokc(VT_FLOAT);
12781         next();
12782         break;
12783     case TOK_CDOUBLE:
12784         vpush_tokc(VT_DOUBLE);
12785         next();
12786         break;
12787     case TOK_CLDOUBLE:
12788         vpush_tokc(VT_LDOUBLE);
12789         next();
12790         break;
12791     case TOK___FUNCTION__:
12792         if (!gnu_ext)
12793             goto tok_identifier;
12794         /* fall thru */
12795     case TOK___FUNC__:
12796         {
12797             void *ptr;
12798             int len;
12799             /* special function name identifier */
12800             len = strlen(funcname) + 1;
12801             /* generate char[len] type */
12802             type.t = VT_BYTE;
12803             mk_pointer(&type);
12804             type.t |= VT_ARRAY;
12805             type.ref->c = len;
12806             vpush_ref(&type, data_section, data_section->data_offset, len);
12807             ptr = section_ptr_add(data_section, len);
12808             memcpy(ptr, funcname, len);
12809             next();
12810         }
12811         break;
12812     case TOK_LSTR:
12813         t = VT_INT;
12814         goto str_init;
12815     case TOK_STR:
12816         /* string parsing */
12817         t = VT_BYTE;
12818     str_init:
12819         if (tcc_state->warn_write_strings)
12820             t |= VT_CONSTANT;
12821         type.t = t;
12822         mk_pointer(&type);
12823         type.t |= VT_ARRAY;
12824         memset(&ad, 0, sizeof(AttributeDef));
12825         decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
12826         break;
12827     case '(':
12828         next();
12829         /* cast ? */
12830         if (parse_btype(&type, &ad)) {
12831             type_decl(&type, &ad, &n, TYPE_ABSTRACT);
12832             skip(')');
12833             /* check ISOC99 compound literal */
12834             if (tok == '{') {
12835                     /* data is allocated locally by default */
12836                 if (global_expr)
12837                     r = VT_CONST;
12838                 else
12839                     r = VT_LOCAL;
12840                 /* all except arrays are lvalues */
12841                 if (!(type.t & VT_ARRAY))
12842                     r |= lvalue_type(type.t);
12843                 memset(&ad, 0, sizeof(AttributeDef));
12844                 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
12845             } else {
12846                 unary();
12847                 gen_cast(&type);
12848             }
12849         } else if (tok == '{') {
12850             /* save all registers */
12851             save_regs(0); 
12852             /* statement expression : we do not accept break/continue
12853                inside as GCC does */
12854             block(NULL, NULL, NULL, NULL, 0, 1);
12855             skip(')');
12856         } else {
12857             gexpr();
12858             skip(')');
12859         }
12860         break;
12861     case '*':
12862         next();
12863         unary();
12864         indir();
12865         break;
12866     case '&':
12867         next();
12868         unary();
12869         /* functions names must be treated as function pointers,
12870            except for unary '&' and sizeof. Since we consider that
12871            functions are not lvalues, we only have to handle it
12872            there and in function calls. */
12873         /* arrays can also be used although they are not lvalues */
12874         if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
12875             !(vtop->type.t & VT_ARRAY))
12876             test_lvalue();
12877         mk_pointer(&vtop->type);
12878         gaddrof();
12879         break;
12880     case '!':
12881         next();
12882         unary();
12883         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
12884             vtop->c.i = !vtop->c.i;
12885         else if ((vtop->r & VT_VALMASK) == VT_CMP)
12886             vtop->c.i = vtop->c.i ^ 1;
12887         else
12888             vseti(VT_JMP, gtst(1, 0));
12889         break;
12890     case '~':
12891         next();
12892         unary();
12893         vpushi(-1);
12894         gen_op('^');
12895         break;
12896     case '+':
12897         next();
12898         /* in order to force cast, we add zero */
12899         unary();
12900         if ((vtop->type.t & VT_BTYPE) == VT_PTR)
12901             error("pointer not accepted for unary plus");
12902         vpushi(0);
12903         gen_op('+');
12904         break;
12905     case TOK_SIZEOF:
12906     case TOK_ALIGNOF1:
12907     case TOK_ALIGNOF2:
12908         t = tok;
12909         next();
12910         if (tok == '(') {
12911             parse_expr_type(&type);
12912         } else {
12913             unary_type(&type);
12914         }
12915         size = type_size(&type, &align);
12916         if (t == TOK_SIZEOF) {
12917             if (size < 0)
12918                 error("sizeof applied to an incomplete type");
12919             vpushi(size);
12920         } else {
12921             vpushi(align);
12922         }
12923         break;
12924
12925     case TOK_builtin_types_compatible_p:
12926         {
12927             CType type1, type2;
12928             next();
12929             skip('(');
12930             parse_type(&type1);
12931             skip(',');
12932             parse_type(&type2);
12933             skip(')');
12934             type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
12935             type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
12936             vpushi(is_compatible_types(&type1, &type2));
12937         }
12938         break;
12939     case TOK_builtin_constant_p:
12940         {
12941             int saved_nocode_wanted, res;
12942             next();
12943             skip('(');
12944             saved_nocode_wanted = nocode_wanted;
12945             nocode_wanted = 1;
12946             gexpr();
12947             res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
12948             vpop();
12949             nocode_wanted = saved_nocode_wanted;
12950             skip(')');
12951             vpushi(res);
12952         }
12953         break;
12954     case TOK_INC:
12955     case TOK_DEC:
12956         t = tok;
12957         next();
12958         unary();
12959         inc(0, t);
12960         break;
12961     case '-':
12962         next();
12963         vpushi(0);
12964         unary();
12965         gen_op('-');
12966         break;
12967     case TOK_LAND:
12968         if (!gnu_ext)
12969             goto tok_identifier;
12970         next();
12971         /* allow to take the address of a label */
12972         if (tok < TOK_UIDENT)
12973             expect("label identifier");
12974         s = label_find(tok);
12975         if (!s) {
12976             s = label_push(&global_label_stack, tok, LABEL_FORWARD);
12977         } else {
12978             if (s->r == LABEL_DECLARED)
12979                 s->r = LABEL_FORWARD;
12980         }
12981         if (!s->type.t) {
12982             s->type.t = VT_VOID;
12983             mk_pointer(&s->type);
12984             s->type.t |= VT_STATIC;
12985         }
12986         vset(&s->type, VT_CONST | VT_SYM, 0);
12987         vtop->sym = s;
12988         next();
12989         break;
12990     default:
12991     tok_identifier:
12992         t = tok;
12993         next();
12994         if (t < TOK_UIDENT)
12995             expect("identifier");
12996         s = sym_find(t);
12997         if (!s) {
12998             if (tok != '(')
12999                 error("'%s' undeclared", get_tok_str(t, NULL));
13000             /* for simple function calls, we tolerate undeclared
13001                external reference to int() function */
13002             if (tcc_state->warn_implicit_function_declaration)
13003                 warning("implicit declaration of function '%s'",
13004                         get_tok_str(t, NULL));
13005             s = external_global_sym(t, &func_old_type, 0); 
13006         }
13007         if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
13008             (VT_STATIC | VT_INLINE | VT_FUNC)) {
13009             /* if referencing an inline function, then we generate a
13010                symbol to it if not already done. It will have the
13011                effect to generate code for it at the end of the
13012                compilation unit. Inline function as always
13013                generated in the text section. */
13014             if (!s->c)
13015                 put_extern_sym(s, text_section, 0, 0);
13016             r = VT_SYM | VT_CONST;
13017         } else {
13018             r = s->r;
13019         }
13020         vset(&s->type, r, s->c);
13021         /* if forward reference, we must point to s */
13022         if (vtop->r & VT_SYM) {
13023             vtop->sym = s;
13024             vtop->c.ul = 0;
13025         }
13026         break;
13027     }
13028     
13029     /* post operations */
13030     while (1) {
13031         if (tok == TOK_INC || tok == TOK_DEC) {
13032             inc(1, tok);
13033             next();
13034         } else if (tok == '.' || tok == TOK_ARROW) {
13035             /* field */ 
13036             if (tok == TOK_ARROW) 
13037                 indir();
13038             test_lvalue();
13039             gaddrof();
13040             next();
13041             /* expect pointer on structure */
13042             if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
13043                 expect("struct or union");
13044             s = vtop->type.ref;
13045             /* find field */
13046             tok |= SYM_FIELD;
13047             while ((s = s->next) != NULL) {
13048                 if (s->v == tok)
13049                     break;
13050             }
13051             if (!s)
13052                 error("field not found");
13053             /* add field offset to pointer */
13054             vtop->type = char_pointer_type; /* change type to 'char *' */
13055             vpushi(s->c);
13056             gen_op('+');
13057             /* change type to field type, and set to lvalue */
13058             vtop->type = s->type;
13059             /* an array is never an lvalue */
13060             if (!(vtop->type.t & VT_ARRAY)) {
13061                 vtop->r |= lvalue_type(vtop->type.t);
13062                 /* if bound checking, the referenced pointer must be checked */
13063                 if (do_bounds_check) 
13064                     vtop->r |= VT_MUSTBOUND;
13065             }
13066             next();
13067         } else if (tok == '[') {
13068             next();
13069             gexpr();
13070             gen_op('+');
13071             indir();
13072             skip(']');
13073         } else if (tok == '(') {
13074             SValue ret;
13075             Sym *sa;
13076             int nb_args;
13077
13078             /* function call  */
13079             if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
13080                 /* pointer test (no array accepted) */
13081                 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
13082                     vtop->type = *pointed_type(&vtop->type);
13083                     if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
13084                         goto error_func;
13085                 } else {
13086                 error_func:
13087                     expect("function pointer");
13088                 }
13089             } else {
13090                 vtop->r &= ~VT_LVAL; /* no lvalue */
13091             }
13092             /* get return type */
13093             s = vtop->type.ref;
13094             next();
13095             sa = s->next; /* first parameter */
13096             nb_args = 0;
13097             /* compute first implicit argument if a structure is returned */
13098             if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
13099                 /* get some space for the returned structure */
13100                 size = type_size(&s->type, &align);
13101                 loc = (loc - size) & -align;
13102                 ret.type = s->type;
13103                 ret.r = VT_LOCAL | VT_LVAL;
13104                 /* pass it as 'int' to avoid structure arg passing
13105                    problems */
13106                 vseti(VT_LOCAL, loc);
13107                 ret.c = vtop->c;
13108                 nb_args++;
13109             } else {
13110                 ret.type = s->type; 
13111                 ret.r2 = VT_CONST;
13112                 /* return in register */
13113                 if (is_float(ret.type.t)) {
13114                     ret.r = REG_FRET; 
13115                 } else {
13116                     if ((ret.type.t & VT_BTYPE) == VT_LLONG)
13117                         ret.r2 = REG_LRET;
13118                     ret.r = REG_IRET;
13119                 }
13120                 ret.c.i = 0;
13121             }
13122             if (tok != ')') {
13123                 for(;;) {
13124                     expr_eq();
13125                     gfunc_param_typed(s, sa);
13126                     nb_args++;
13127                     if (sa)
13128                         sa = sa->next;
13129                     if (tok == ')')
13130                         break;
13131                     skip(',');
13132                 }
13133             }
13134             if (sa)
13135                 error("too few arguments to function");
13136             skip(')');
13137             if (!nocode_wanted) {
13138                 gfunc_call(nb_args);
13139             } else {
13140                 vtop -= (nb_args + 1);
13141             }
13142             /* return value */
13143             vsetc(&ret.type, ret.r, &ret.c);
13144             vtop->r2 = ret.r2;
13145         } else {
13146             break;
13147         }
13148     }
13149 }
13150
13151 static void uneq(void)
13152 {
13153     int t;
13154     
13155     unary();
13156     if (tok == '=' ||
13157         (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
13158         tok == TOK_A_XOR || tok == TOK_A_OR ||
13159         tok == TOK_A_SHL || tok == TOK_A_SAR) {
13160         test_lvalue();
13161         t = tok;
13162         next();
13163         if (t == '=') {
13164             expr_eq();
13165         } else {
13166             vdup();
13167             expr_eq();
13168             gen_op(t & 0x7f);
13169         }
13170         vstore();
13171     }
13172 }
13173
13174 static void expr_prod(void)
13175 {
13176     int t;
13177
13178     uneq();
13179     while (tok == '*' || tok == '/' || tok == '%') {
13180         t = tok;
13181         next();
13182         uneq();
13183         gen_op(t);
13184     }
13185 }
13186
13187 static void expr_sum(void)
13188 {
13189     int t;
13190
13191     expr_prod();
13192     while (tok == '+' || tok == '-') {
13193         t = tok;
13194         next();
13195         expr_prod();
13196         gen_op(t);
13197     }
13198 }
13199
13200 static void expr_shift(void)
13201 {
13202     int t;
13203
13204     expr_sum();
13205     while (tok == TOK_SHL || tok == TOK_SAR) {
13206         t = tok;
13207         next();
13208         expr_sum();
13209         gen_op(t);
13210     }
13211 }
13212
13213 static void expr_cmp(void)
13214 {
13215     int t;
13216
13217     expr_shift();
13218     while ((tok >= TOK_ULE && tok <= TOK_GT) ||
13219            tok == TOK_ULT || tok == TOK_UGE) {
13220         t = tok;
13221         next();
13222         expr_shift();
13223         gen_op(t);
13224     }
13225 }
13226
13227 static void expr_cmpeq(void)
13228 {
13229     int t;
13230
13231     expr_cmp();
13232     while (tok == TOK_EQ || tok == TOK_NE) {
13233         t = tok;
13234         next();
13235         expr_cmp();
13236         gen_op(t);
13237     }
13238 }
13239
13240 static void expr_and(void)
13241 {
13242     expr_cmpeq();
13243     while (tok == '&') {
13244         next();
13245         expr_cmpeq();
13246         gen_op('&');
13247     }
13248 }
13249
13250 static void expr_xor(void)
13251 {
13252     expr_and();
13253     while (tok == '^') {
13254         next();
13255         expr_and();
13256         gen_op('^');
13257     }
13258 }
13259
13260 static void expr_or(void)
13261 {
13262     expr_xor();
13263     while (tok == '|') {
13264         next();
13265         expr_xor();
13266         gen_op('|');
13267     }
13268 }
13269
13270 /* XXX: fix this mess */
13271 static void expr_land_const(void)
13272 {
13273     expr_or();
13274     while (tok == TOK_LAND) {
13275         next();
13276         expr_or();
13277         gen_op(TOK_LAND);
13278     }
13279 }
13280
13281 /* XXX: fix this mess */
13282 static void expr_lor_const(void)
13283 {
13284     expr_land_const();
13285     while (tok == TOK_LOR) {
13286         next();
13287         expr_land_const();
13288         gen_op(TOK_LOR);
13289     }
13290 }
13291
13292 /* only used if non constant */
13293 static void expr_land(void)
13294 {
13295     int t;
13296
13297     expr_or();
13298     if (tok == TOK_LAND) {
13299         t = 0;
13300         for(;;) {
13301             t = gtst(1, t);
13302             if (tok != TOK_LAND) {
13303                 vseti(VT_JMPI, t);
13304                 break;
13305             }
13306             next();
13307             expr_or();
13308         }
13309     }
13310 }
13311
13312 static void expr_lor(void)
13313 {
13314     int t;
13315
13316     expr_land();
13317     if (tok == TOK_LOR) {
13318         t = 0;
13319         for(;;) {
13320             t = gtst(0, t);
13321             if (tok != TOK_LOR) {
13322                 vseti(VT_JMP, t);
13323                 break;
13324             }
13325             next();
13326             expr_land();
13327         }
13328     }
13329 }
13330
13331 /* XXX: better constant handling */
13332 static void expr_eq(void)
13333 {
13334     int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
13335     SValue sv;
13336     CType type, type1, type2;
13337
13338     if (const_wanted) {
13339         int c1, c;
13340         expr_lor_const();
13341         if (tok == '?') {
13342             c = vtop->c.i;
13343             vpop();
13344             next();
13345             if (tok == ':' && gnu_ext) {
13346                 c1 = c;
13347             } else {
13348                 gexpr();
13349                 c1 = vtop->c.i;
13350                 vpop();
13351             }
13352             skip(':');
13353             expr_eq();
13354             if (c)
13355                 vtop->c.i = c1;
13356         }
13357     } else {
13358         expr_lor();
13359         if (tok == '?') {
13360             next();
13361             if (vtop != vstack) {
13362                 /* needed to avoid having different registers saved in
13363                    each branch */
13364                 if (is_float(vtop->type.t))
13365                     rc = RC_FLOAT;
13366                 else
13367                     rc = RC_INT;
13368                     gv(rc);
13369                     save_regs(1);
13370             }
13371             if (tok == ':' && gnu_ext) {
13372                 gv_dup();
13373                 tt = gtst(1, 0);
13374             } else {
13375                 tt = gtst(1, 0);
13376                 gexpr();
13377             }
13378             type1 = vtop->type;
13379             sv = *vtop; /* save value to handle it later */
13380             vtop--; /* no vpop so that FP stack is not flushed */
13381             skip(':');
13382             u = gjmp(0);
13383             gsym(tt);
13384             expr_eq();
13385             type2 = vtop->type;
13386
13387             t1 = type1.t;
13388             bt1 = t1 & VT_BTYPE;
13389             t2 = type2.t;
13390             bt2 = t2 & VT_BTYPE;
13391             /* cast operands to correct type according to ISOC rules */
13392             if (is_float(bt1) || is_float(bt2)) {
13393                 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
13394                     type.t = VT_LDOUBLE;
13395                 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
13396                     type.t = VT_DOUBLE;
13397                 } else {
13398                     type.t = VT_FLOAT;
13399                 }
13400             } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
13401                 /* cast to biggest op */
13402                 type.t = VT_LLONG;
13403                 /* convert to unsigned if it does not fit in a long long */
13404                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
13405                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
13406                     type.t |= VT_UNSIGNED;
13407             } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
13408                 /* XXX: test pointer compatibility */
13409                 type = type1;
13410             } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
13411                 /* XXX: test structure compatibility */
13412                 type = type1;
13413             } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
13414                 /* NOTE: as an extension, we accept void on only one side */
13415                 type.t = VT_VOID;
13416             } else {
13417                 /* integer operations */
13418                 type.t = VT_INT;
13419                 /* convert to unsigned if it does not fit in an integer */
13420                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
13421                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
13422                     type.t |= VT_UNSIGNED;
13423             }
13424                 
13425             /* now we convert second operand */
13426             gen_cast(&type);
13427             rc = RC_INT;
13428             if (is_float(type.t)) {
13429                 rc = RC_FLOAT;
13430             } else if ((type.t & VT_BTYPE) == VT_LLONG) {
13431                 /* for long longs, we use fixed registers to avoid having
13432                    to handle a complicated move */
13433                 rc = RC_IRET; 
13434             }
13435             
13436             r2 = gv(rc);
13437             /* this is horrible, but we must also convert first
13438                operand */
13439             tt = gjmp(0);
13440             gsym(u);
13441             /* put again first value and cast it */
13442             *vtop = sv;
13443             gen_cast(&type);
13444             r1 = gv(rc);
13445             move_reg(r2, r1);
13446             vtop->r = r2;
13447             gsym(tt);
13448         }
13449     }
13450 }
13451
13452 static void gexpr(void)
13453 {
13454     while (1) {
13455         expr_eq();
13456         if (tok != ',')
13457             break;
13458         vpop();
13459         next();
13460     }
13461 }
13462
13463 /* parse an expression and return its type without any side effect. */
13464 static void expr_type(CType *type)
13465 {
13466     int saved_nocode_wanted;
13467
13468     saved_nocode_wanted = nocode_wanted;
13469     nocode_wanted = 1;
13470     gexpr();
13471     *type = vtop->type;
13472     vpop();
13473     nocode_wanted = saved_nocode_wanted;
13474 }
13475
13476 /* parse a unary expression and return its type without any side
13477    effect. */
13478 static void unary_type(CType *type)
13479 {
13480     int a;
13481
13482     a = nocode_wanted;
13483     nocode_wanted = 1;
13484     unary();
13485     *type = vtop->type;
13486     vpop();
13487     nocode_wanted = a;
13488 }
13489
13490 /* parse a constant expression and return value in vtop.  */
13491 static void expr_const1(void)
13492 {
13493     int a;
13494     a = const_wanted;
13495     const_wanted = 1;
13496     expr_eq();
13497     const_wanted = a;
13498 }
13499
13500 /* parse an integer constant and return its value. */
13501 static int expr_const(void)
13502 {
13503     int c;
13504     expr_const1();
13505     if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
13506         expect("constant expression");
13507     c = vtop->c.i;
13508     vpop();
13509     return c;
13510 }
13511
13512 /* return the label token if current token is a label, otherwise
13513    return zero */
13514 static int is_label(void)
13515 {
13516     int last_tok;
13517
13518     /* fast test first */
13519     if (tok < TOK_UIDENT)
13520         return 0;
13521     /* no need to save tokc because tok is an identifier */
13522     last_tok = tok;
13523     next();
13524     if (tok == ':') {
13525         next();
13526         return last_tok;
13527     } else {
13528         unget_tok(last_tok);
13529         return 0;
13530     }
13531 }
13532
13533 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
13534                   int case_reg, int is_expr)
13535 {
13536     int a, b, c, d;
13537     Sym *s;
13538
13539     /* generate line number info */
13540     if (do_debug && 
13541         (last_line_num != file->line_num || last_ind != ind)) {
13542         put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
13543         last_ind = ind;
13544         last_line_num = file->line_num;
13545     }
13546
13547     if (is_expr) {
13548         /* default return value is (void) */
13549         vpushi(0);
13550         vtop->type.t = VT_VOID;
13551     }
13552
13553     if (tok == TOK_IF) {
13554         /* if test */
13555         next();
13556         skip('(');
13557         gexpr();
13558         skip(')');
13559         a = gtst(1, 0);
13560         block(bsym, csym, case_sym, def_sym, case_reg, 0);
13561         c = tok;
13562         if (c == TOK_ELSE) {
13563             next();
13564             d = gjmp(0);
13565             gsym(a);
13566             block(bsym, csym, case_sym, def_sym, case_reg, 0);
13567             gsym(d); /* patch else jmp */
13568         } else
13569             gsym(a);
13570     } else if (tok == TOK_WHILE) {
13571         next();
13572         d = ind;
13573         skip('(');
13574         gexpr();
13575         skip(')');
13576         a = gtst(1, 0);
13577         b = 0;
13578         block(&a, &b, case_sym, def_sym, case_reg, 0);
13579         gjmp_addr(d);
13580         gsym(a);
13581         gsym_addr(b, d);
13582     } else if (tok == '{') {
13583         Sym *llabel;
13584         
13585         next();
13586         /* record local declaration stack position */
13587         s = local_stack;
13588         llabel = local_label_stack;
13589         /* handle local labels declarations */
13590         if (tok == TOK_LABEL) {
13591             next();
13592             for(;;) {
13593                 if (tok < TOK_UIDENT)
13594                     expect("label identifier");
13595                 label_push(&local_label_stack, tok, LABEL_DECLARED);
13596                 next();
13597                 if (tok == ',') {
13598                     next();
13599                 } else {
13600                     skip(';');
13601                     break;
13602                 }
13603             }
13604         }
13605         while (tok != '}') {
13606             decl(VT_LOCAL);
13607             if (tok != '}') {
13608                 if (is_expr)
13609                     vpop();
13610                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13611             }
13612         }
13613         /* pop locally defined labels */
13614         label_pop(&local_label_stack, llabel);
13615         /* pop locally defined symbols */
13616         sym_pop(&local_stack, s);
13617         next();
13618     } else if (tok == TOK_RETURN) {
13619         next();
13620         if (tok != ';') {
13621             gexpr();
13622             gen_assign_cast(&func_vt);
13623             if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
13624                 CType type;
13625                 /* if returning structure, must copy it to implicit
13626                    first pointer arg location */
13627                 type = func_vt;
13628                 mk_pointer(&type);
13629                 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
13630                 indir();
13631                 vswap();
13632                 /* copy structure value to pointer */
13633                 vstore();
13634             } else if (is_float(func_vt.t)) {
13635                 gv(RC_FRET);
13636             } else {
13637                 gv(RC_IRET);
13638             }
13639             vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
13640         }
13641         skip(';');
13642         rsym = gjmp(rsym); /* jmp */
13643     } else if (tok == TOK_BREAK) {
13644         /* compute jump */
13645         if (!bsym)
13646             error("cannot break");
13647         *bsym = gjmp(*bsym);
13648         next();
13649         skip(';');
13650     } else if (tok == TOK_CONTINUE) {
13651         /* compute jump */
13652         if (!csym)
13653             error("cannot continue");
13654         *csym = gjmp(*csym);
13655         next();
13656         skip(';');
13657     } else if (tok == TOK_FOR) {
13658         int e;
13659         next();
13660         skip('(');
13661         if (tok != ';') {
13662             gexpr();
13663             vpop();
13664         }
13665         skip(';');
13666         d = ind;
13667         c = ind;
13668         a = 0;
13669         b = 0;
13670         if (tok != ';') {
13671             gexpr();
13672             a = gtst(1, 0);
13673         }
13674         skip(';');
13675         if (tok != ')') {
13676             e = gjmp(0);
13677             c = ind;
13678             gexpr();
13679             vpop();
13680             gjmp_addr(d);
13681             gsym(e);
13682         }
13683         skip(')');
13684         block(&a, &b, case_sym, def_sym, case_reg, 0);
13685         gjmp_addr(c);
13686         gsym(a);
13687         gsym_addr(b, c);
13688     } else 
13689     if (tok == TOK_DO) {
13690         next();
13691         a = 0;
13692         b = 0;
13693         d = ind;
13694         block(&a, &b, case_sym, def_sym, case_reg, 0);
13695         skip(TOK_WHILE);
13696         skip('(');
13697         gsym(b);
13698         gexpr();
13699         c = gtst(0, 0);
13700         gsym_addr(c, d);
13701         skip(')');
13702         gsym(a);
13703         skip(';');
13704     } else
13705     if (tok == TOK_SWITCH) {
13706         next();
13707         skip('(');
13708         gexpr();
13709         /* XXX: other types than integer */
13710         case_reg = gv(RC_INT);
13711         vpop();
13712         skip(')');
13713         a = 0;
13714         b = gjmp(0); /* jump to first case */
13715         c = 0;
13716         block(&a, csym, &b, &c, case_reg, 0);
13717         /* if no default, jmp after switch */
13718         if (c == 0)
13719             c = ind;
13720         /* default label */
13721         gsym_addr(b, c);
13722         /* break label */
13723         gsym(a);
13724     } else
13725     if (tok == TOK_CASE) {
13726         int v1, v2;
13727         if (!case_sym)
13728             expect("switch");
13729         next();
13730         v1 = expr_const();
13731         v2 = v1;
13732         if (gnu_ext && tok == TOK_DOTS) {
13733             next();
13734             v2 = expr_const();
13735             if (v2 < v1)
13736                 warning("empty case range");
13737         }
13738         /* since a case is like a label, we must skip it with a jmp */
13739         b = gjmp(0);
13740         gsym(*case_sym);
13741         vseti(case_reg, 0);
13742         vpushi(v1);
13743         if (v1 == v2) {
13744             gen_op(TOK_EQ);
13745             *case_sym = gtst(1, 0);
13746         } else {
13747             gen_op(TOK_GE);
13748             *case_sym = gtst(1, 0);
13749             vseti(case_reg, 0);
13750             vpushi(v2);
13751             gen_op(TOK_LE);
13752             *case_sym = gtst(1, *case_sym);
13753         }
13754         gsym(b);
13755         skip(':');
13756         is_expr = 0;
13757         goto block_after_label;
13758     } else 
13759     if (tok == TOK_DEFAULT) {
13760         next();
13761         skip(':');
13762         if (!def_sym)
13763             expect("switch");
13764         if (*def_sym)
13765             error("too many 'default'");
13766         *def_sym = ind;
13767         is_expr = 0;
13768         goto block_after_label;
13769     } else
13770     if (tok == TOK_GOTO) {
13771         next();
13772         if (tok == '*' && gnu_ext) {
13773             /* computed goto */
13774             next();
13775             gexpr();
13776             if ((vtop->type.t & VT_BTYPE) != VT_PTR)
13777                 expect("pointer");
13778             ggoto();
13779         } else if (tok >= TOK_UIDENT) {
13780             s = label_find(tok);
13781             /* put forward definition if needed */
13782             if (!s) {
13783                 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
13784             } else {
13785                 if (s->r == LABEL_DECLARED)
13786                     s->r = LABEL_FORWARD;
13787             }
13788             /* label already defined */
13789             if (s->r & LABEL_FORWARD) 
13790                 s->next = (void *)gjmp((long)s->next);
13791             else
13792                 gjmp_addr((long)s->next);
13793             next();
13794         } else {
13795             expect("label identifier");
13796         }
13797         skip(';');
13798     } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
13799         asm_instr();
13800     } else {
13801         b = is_label();
13802         if (b) {
13803             /* label case */
13804             s = label_find(b);
13805             if (s) {
13806                 if (s->r == LABEL_DEFINED)
13807                     error("duplicate label '%s'", get_tok_str(s->v, NULL));
13808                 gsym((long)s->next);
13809                 s->r = LABEL_DEFINED;
13810             } else {
13811                 s = label_push(&global_label_stack, b, LABEL_DEFINED);
13812             }
13813             s->next = (void *)ind;
13814             /* we accept this, but it is a mistake */
13815         block_after_label:
13816             if (tok == '}') {
13817                 warning("deprecated use of label at end of compound statement");
13818             } else {
13819                 if (is_expr)
13820                     vpop();
13821                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13822             }
13823         } else {
13824             /* expression case */
13825             if (tok != ';') {
13826                 if (is_expr) {
13827                     vpop();
13828                     gexpr();
13829                 } else {
13830                     gexpr();
13831                     vpop();
13832                 }
13833             }
13834             skip(';');
13835         }
13836     }
13837 }
13838
13839 /* t is the array or struct type. c is the array or struct
13840    address. cur_index/cur_field is the pointer to the current
13841    value. 'size_only' is true if only size info is needed (only used
13842    in arrays) */
13843 static void decl_designator(CType *type, Section *sec, unsigned long c, 
13844                             int *cur_index, Sym **cur_field, 
13845                             int size_only)
13846 {
13847     Sym *s, *f;
13848     int notfirst, index, index_last, align, l, nb_elems, elem_size;
13849     CType type1;
13850
13851     notfirst = 0;
13852     elem_size = 0;
13853     nb_elems = 1;
13854     if (gnu_ext && (l = is_label()) != 0)
13855         goto struct_field;
13856     while (tok == '[' || tok == '.') {
13857         if (tok == '[') {
13858             if (!(type->t & VT_ARRAY))
13859                 expect("array type");
13860             s = type->ref;
13861             next();
13862             index = expr_const();
13863             if (index < 0 || (s->c >= 0 && index >= s->c))
13864                 expect("invalid index");
13865             if (tok == TOK_DOTS && gnu_ext) {
13866                 next();
13867                 index_last = expr_const();
13868                 if (index_last < 0 || 
13869                     (s->c >= 0 && index_last >= s->c) ||
13870                     index_last < index)
13871                     expect("invalid index");
13872             } else {
13873                 index_last = index;
13874             }
13875             skip(']');
13876             if (!notfirst)
13877                 *cur_index = index_last;
13878             type = pointed_type(type);
13879             elem_size = type_size(type, &align);
13880             c += index * elem_size;
13881             /* NOTE: we only support ranges for last designator */
13882             nb_elems = index_last - index + 1;
13883             if (nb_elems != 1) {
13884                 notfirst = 1;
13885                 break;
13886             }
13887         } else {
13888             next();
13889             l = tok;
13890             next();
13891         struct_field:
13892             if ((type->t & VT_BTYPE) != VT_STRUCT)
13893                 expect("struct/union type");
13894             s = type->ref;
13895             l |= SYM_FIELD;
13896             f = s->next;
13897             while (f) {
13898                 if (f->v == l)
13899                     break;
13900                 f = f->next;
13901             }
13902             if (!f)
13903                 expect("field");
13904             if (!notfirst)
13905                 *cur_field = f;
13906             /* XXX: fix this mess by using explicit storage field */
13907             type1 = f->type;
13908             type1.t |= (type->t & ~VT_TYPE);
13909             type = &type1;
13910             c += f->c;
13911         }
13912         notfirst = 1;
13913     }
13914     if (notfirst) {
13915         if (tok == '=') {
13916             next();
13917         } else {
13918             if (!gnu_ext)
13919                 expect("=");
13920         }
13921     } else {
13922         if (type->t & VT_ARRAY) {
13923             index = *cur_index;
13924             type = pointed_type(type);
13925             c += index * type_size(type, &align);
13926         } else {
13927             f = *cur_field;
13928             if (!f)
13929                 error("too many field init");
13930             /* XXX: fix this mess by using explicit storage field */
13931             type1 = f->type;
13932             type1.t |= (type->t & ~VT_TYPE);
13933             type = &type1;
13934             c += f->c;
13935         }
13936     }
13937     decl_initializer(type, sec, c, 0, size_only);
13938
13939     /* XXX: make it more general */
13940     if (!size_only && nb_elems > 1) {
13941         unsigned long c_end;
13942         uint8_t *src, *dst;
13943         int i;
13944
13945         if (!sec)
13946             error("range init not supported yet for dynamic storage");
13947         c_end = c + nb_elems * elem_size;
13948         if (c_end > sec->data_allocated)
13949             section_realloc(sec, c_end);
13950         src = sec->data + c;
13951         dst = src;
13952         for(i = 1; i < nb_elems; i++) {
13953             dst += elem_size;
13954             memcpy(dst, src, elem_size);
13955         }
13956     }
13957 }
13958
13959 #define EXPR_VAL   0
13960 #define EXPR_CONST 1
13961 #define EXPR_ANY   2
13962
13963 /* store a value or an expression directly in global data or in local array */
13964 static void init_putv(CType *type, Section *sec, unsigned long c, 
13965                       int v, int expr_type)
13966 {
13967     int saved_global_expr, bt, bit_pos, bit_size;
13968     void *ptr;
13969     unsigned long long bit_mask;
13970     CType dtype;
13971
13972     switch(expr_type) {
13973     case EXPR_VAL:
13974         vpushi(v);
13975         break;
13976     case EXPR_CONST:
13977         /* compound literals must be allocated globally in this case */
13978         saved_global_expr = global_expr;
13979         global_expr = 1;
13980         expr_const1();
13981         global_expr = saved_global_expr;
13982         /* NOTE: symbols are accepted */
13983         if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
13984             error("initializer element is not constant");
13985         break;
13986     case EXPR_ANY:
13987         expr_eq();
13988         break;
13989     }
13990     
13991     dtype = *type;
13992     dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
13993
13994     if (sec) {
13995         /* XXX: not portable */
13996         /* XXX: generate error if incorrect relocation */
13997         gen_assign_cast(&dtype);
13998         bt = type->t & VT_BTYPE;
13999         ptr = sec->data + c;
14000         /* XXX: make code faster ? */
14001         if (!(type->t & VT_BITFIELD)) {
14002             bit_pos = 0;
14003             bit_size = 32;
14004             bit_mask = -1LL;
14005         } else {
14006             bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
14007             bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
14008             bit_mask = (1LL << bit_size) - 1;
14009         }
14010         if ((vtop->r & VT_SYM) &&
14011             (bt == VT_BYTE ||
14012              bt == VT_SHORT ||
14013              bt == VT_DOUBLE ||
14014              bt == VT_LDOUBLE ||
14015              bt == VT_LLONG ||
14016              (bt == VT_INT && bit_size != 32)))
14017             error("initializer element is not computable at load time");
14018         switch(bt) {
14019         case VT_BYTE:
14020             *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14021             break;
14022         case VT_SHORT:
14023             *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14024             break;
14025         case VT_DOUBLE:
14026             *(double *)ptr = vtop->c.d;
14027             break;
14028         case VT_LDOUBLE:
14029             *(long double *)ptr = vtop->c.ld;
14030             break;
14031         case VT_LLONG:
14032             *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
14033             break;
14034         default:
14035             if (vtop->r & VT_SYM) {
14036                 greloc(sec, vtop->sym, c, R_DATA_32);
14037             }
14038             *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14039             break;
14040         }
14041         vtop--;
14042     } else {
14043         vset(&dtype, VT_LOCAL, c);
14044         vswap();
14045         vstore();
14046         vpop();
14047     }
14048 }
14049
14050 /* put zeros for variable based init */
14051 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
14052 {
14053     if (sec) {
14054         /* nothing to do because globals are already set to zero */
14055     } else {
14056         vpush_global_sym(&func_old_type, TOK_memset);
14057         vseti(VT_LOCAL, c);
14058         vpushi(0);
14059         vpushi(size);
14060         gfunc_call(3);
14061     }
14062 }
14063
14064 /* 't' contains the type and storage info. 'c' is the offset of the
14065    object in section 'sec'. If 'sec' is NULL, it means stack based
14066    allocation. 'first' is true if array '{' must be read (multi
14067    dimension implicit array init handling). 'size_only' is true if
14068    size only evaluation is wanted (only for arrays). */
14069 static void decl_initializer(CType *type, Section *sec, unsigned long c, 
14070                              int first, int size_only)
14071 {
14072     int index, array_length, n, no_oblock, nb, parlevel, i;
14073     int size1, align1, expr_type;
14074     Sym *s, *f;
14075     CType *t1;
14076
14077     if (type->t & VT_ARRAY) {
14078         s = type->ref;
14079         n = s->c;
14080         array_length = 0;
14081         t1 = pointed_type(type);
14082         size1 = type_size(t1, &align1);
14083
14084         no_oblock = 1;
14085         if ((first && tok != TOK_LSTR && tok != TOK_STR) || 
14086             tok == '{') {
14087             skip('{');
14088             no_oblock = 0;
14089         }
14090
14091         /* only parse strings here if correct type (otherwise: handle
14092            them as ((w)char *) expressions */
14093         if ((tok == TOK_LSTR && 
14094              (t1->t & VT_BTYPE) == VT_INT) ||
14095             (tok == TOK_STR &&
14096              (t1->t & VT_BTYPE) == VT_BYTE)) {
14097             while (tok == TOK_STR || tok == TOK_LSTR) {
14098                 int cstr_len, ch;
14099                 CString *cstr;
14100
14101                 cstr = tokc.cstr;
14102                 /* compute maximum number of chars wanted */
14103                 if (tok == TOK_STR)
14104                     cstr_len = cstr->size;
14105                 else
14106                     cstr_len = cstr->size / sizeof(int);
14107                 cstr_len--;
14108                 nb = cstr_len;
14109                 if (n >= 0 && nb > (n - array_length))
14110                     nb = n - array_length;
14111                 if (!size_only) {
14112                     if (cstr_len > nb)
14113                         warning("initializer-string for array is too long");
14114                     /* in order to go faster for common case (char
14115                        string in global variable, we handle it
14116                        specifically */
14117                     if (sec && tok == TOK_STR && size1 == 1) {
14118                         memcpy(sec->data + c + array_length, cstr->data, nb);
14119                     } else {
14120                         for(i=0;i<nb;i++) {
14121                             if (tok == TOK_STR)
14122                                 ch = ((unsigned char *)cstr->data)[i];
14123                             else
14124                                 ch = ((int *)cstr->data)[i];
14125                             init_putv(t1, sec, c + (array_length + i) * size1,
14126                                       ch, EXPR_VAL);
14127                         }
14128                     }
14129                 }
14130                 array_length += nb;
14131                 next();
14132             }
14133             /* only add trailing zero if enough storage (no
14134                warning in this case since it is standard) */
14135             if (n < 0 || array_length < n) {
14136                 if (!size_only) {
14137                     init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
14138                 }
14139                 array_length++;
14140             }
14141         } else {
14142             index = 0;
14143             while (tok != '}') {
14144                 decl_designator(type, sec, c, &index, NULL, size_only);
14145                 if (n >= 0 && index >= n)
14146                     error("index too large");
14147                 /* must put zero in holes (note that doing it that way
14148                    ensures that it even works with designators) */
14149                 if (!size_only && array_length < index) {
14150                     init_putz(t1, sec, c + array_length * size1, 
14151                               (index - array_length) * size1);
14152                 }
14153                 index++;
14154                 if (index > array_length)
14155                     array_length = index;
14156                 /* special test for multi dimensional arrays (may not
14157                    be strictly correct if designators are used at the
14158                    same time) */
14159                 if (index >= n && no_oblock)
14160                     break;
14161                 if (tok == '}')
14162                     break;
14163                 skip(',');
14164             }
14165         }
14166         if (!no_oblock)
14167             skip('}');
14168         /* put zeros at the end */
14169         if (!size_only && n >= 0 && array_length < n) {
14170             init_putz(t1, sec, c + array_length * size1, 
14171                       (n - array_length) * size1);
14172         }
14173         /* patch type size if needed */
14174         if (n < 0)
14175             s->c = array_length;
14176     } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
14177                (sec || !first || tok == '{')) {
14178         int par_count;
14179
14180         /* NOTE: the previous test is a specific case for automatic
14181            struct/union init */
14182         /* XXX: union needs only one init */
14183
14184         /* XXX: this test is incorrect for local initializers
14185            beginning with ( without {. It would be much more difficult
14186            to do it correctly (ideally, the expression parser should
14187            be used in all cases) */
14188         par_count = 0;
14189         if (tok == '(') {
14190             AttributeDef ad1;
14191             CType type1;
14192             next();
14193             while (tok == '(') {
14194                 par_count++;
14195                 next();
14196             }
14197             if (!parse_btype(&type1, &ad1))
14198                 expect("cast");
14199             type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
14200 #if 0
14201             if (!is_assignable_types(type, &type1))
14202                 error("invalid type for cast");
14203 #endif
14204             skip(')');
14205         }
14206         no_oblock = 1;
14207         if (first || tok == '{') {
14208             skip('{');
14209             no_oblock = 0;
14210         }
14211         s = type->ref;
14212         f = s->next;
14213         array_length = 0;
14214         index = 0;
14215         n = s->c;
14216         while (tok != '}') {
14217             decl_designator(type, sec, c, NULL, &f, size_only);
14218             index = f->c;
14219             if (!size_only && array_length < index) {
14220                 init_putz(type, sec, c + array_length, 
14221                           index - array_length);
14222             }
14223             index = index + type_size(&f->type, &align1);
14224             if (index > array_length)
14225                 array_length = index;
14226             f = f->next;
14227             if (no_oblock && f == NULL)
14228                 break;
14229             if (tok == '}')
14230                 break;
14231             skip(',');
14232         }
14233         /* put zeros at the end */
14234         if (!size_only && array_length < n) {
14235             init_putz(type, sec, c + array_length, 
14236                       n - array_length);
14237         }
14238         if (!no_oblock)
14239             skip('}');
14240         while (par_count) {
14241             skip(')');
14242             par_count--;
14243         }
14244     } else if (tok == '{') {
14245         next();
14246         decl_initializer(type, sec, c, first, size_only);
14247         skip('}');
14248     } else if (size_only) {
14249         /* just skip expression */
14250         parlevel = 0;
14251         while ((parlevel > 0 || (tok != '}' && tok != ',')) && 
14252                tok != -1) {
14253             if (tok == '(')
14254                 parlevel++;
14255             else if (tok == ')')
14256                 parlevel--;
14257             next();
14258         }
14259     } else {
14260         /* currently, we always use constant expression for globals
14261            (may change for scripting case) */
14262         expr_type = EXPR_CONST;
14263         if (!sec)
14264             expr_type = EXPR_ANY;
14265         init_putv(type, sec, c, 0, expr_type);
14266     }
14267 }
14268
14269 /* parse an initializer for type 't' if 'has_init' is non zero, and
14270    allocate space in local or global data space ('r' is either
14271    VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
14272    variable 'v' of scope 'scope' is declared before initializers are
14273    parsed. If 'v' is zero, then a reference to the new object is put
14274    in the value stack. If 'has_init' is 2, a special parsing is done
14275    to handle string constants. */
14276 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
14277                                    int has_init, int v, int scope)
14278 {
14279     int size, align, addr, data_offset;
14280     int level;
14281     ParseState saved_parse_state;
14282     TokenString init_str;
14283     Section *sec;
14284
14285     size = type_size(type, &align);
14286     /* If unknown size, we must evaluate it before
14287        evaluating initializers because
14288        initializers can generate global data too
14289        (e.g. string pointers or ISOC99 compound
14290        literals). It also simplifies local
14291        initializers handling */
14292     tok_str_new(&init_str);
14293     if (size < 0) {
14294         if (!has_init) 
14295             error("unknown type size");
14296         /* get all init string */
14297         if (has_init == 2) {
14298             /* only get strings */
14299             while (tok == TOK_STR || tok == TOK_LSTR) {
14300                 tok_str_add_tok(&init_str);
14301                 next();
14302             }
14303         } else {
14304             level = 0;
14305             while (level > 0 || (tok != ',' && tok != ';')) {
14306                 if (tok < 0)
14307                     error("unexpected end of file in initializer");
14308                 tok_str_add_tok(&init_str);
14309                 if (tok == '{')
14310                     level++;
14311                 else if (tok == '}') {
14312                     if (level == 0)
14313                         break;
14314                     level--;
14315                 }
14316                 next();
14317             }
14318         }
14319         tok_str_add(&init_str, -1);
14320         tok_str_add(&init_str, 0);
14321         
14322         /* compute size */
14323         save_parse_state(&saved_parse_state);
14324
14325         macro_ptr = init_str.str;
14326         next();
14327         decl_initializer(type, NULL, 0, 1, 1);
14328         /* prepare second initializer parsing */
14329         macro_ptr = init_str.str;
14330         next();
14331         
14332         /* if still unknown size, error */
14333         size = type_size(type, &align);
14334         if (size < 0) 
14335             error("unknown type size");
14336     }
14337     /* take into account specified alignment if bigger */
14338     if (ad->aligned) {
14339         if (ad->aligned > align)
14340             align = ad->aligned;
14341     } else if (ad->packed) {
14342         align = 1;
14343     }
14344     if ((r & VT_VALMASK) == VT_LOCAL) {
14345         sec = NULL;
14346         if (do_bounds_check && (type->t & VT_ARRAY)) 
14347             loc--;
14348         loc = (loc - size) & -align;
14349         addr = loc;
14350         /* handles bounds */
14351         /* XXX: currently, since we do only one pass, we cannot track
14352            '&' operators, so we add only arrays */
14353         if (do_bounds_check && (type->t & VT_ARRAY)) {
14354             unsigned long *bounds_ptr;
14355             /* add padding between regions */
14356             loc--;
14357             /* then add local bound info */
14358             bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
14359             bounds_ptr[0] = addr;
14360             bounds_ptr[1] = size;
14361         }
14362         if (v) {
14363             /* local variable */
14364             sym_push(v, type, r, addr);
14365         } else {
14366             /* push local reference */
14367             vset(type, r, addr);
14368         }
14369     } else {
14370         Sym *sym;
14371
14372         sym = NULL;
14373         if (v && scope == VT_CONST) {
14374             /* see if the symbol was already defined */
14375             sym = sym_find(v);
14376             if (sym) {
14377                 if (!is_compatible_types(&sym->type, type))
14378                     error("incompatible types for redefinition of '%s'", 
14379                           get_tok_str(v, NULL));
14380                 if (sym->type.t & VT_EXTERN) {
14381                     /* if the variable is extern, it was not allocated */
14382                     sym->type.t &= ~VT_EXTERN;
14383                     /* set array size if it was ommited in extern
14384                        declaration */
14385                     if ((sym->type.t & VT_ARRAY) && 
14386                         sym->type.ref->c < 0 &&
14387                         type->ref->c >= 0)
14388                         sym->type.ref->c = type->ref->c;
14389                 } else {
14390                     /* we accept several definitions of the same
14391                        global variable. this is tricky, because we
14392                        must play with the SHN_COMMON type of the symbol */
14393                     /* XXX: should check if the variable was already
14394                        initialized. It is incorrect to initialized it
14395                        twice */
14396                     /* no init data, we won't add more to the symbol */
14397                     if (!has_init)
14398                         goto no_alloc;
14399                 }
14400             }
14401         }
14402
14403         /* allocate symbol in corresponding section */
14404         sec = ad->section;
14405         if (!sec) {
14406             if (has_init)
14407                 sec = data_section;
14408             else if (tcc_state->nocommon)
14409                 sec = bss_section;
14410         }
14411         if (sec) {
14412             data_offset = sec->data_offset;
14413             data_offset = (data_offset + align - 1) & -align;
14414             addr = data_offset;
14415             /* very important to increment global pointer at this time
14416                because initializers themselves can create new initializers */
14417             data_offset += size;
14418             /* add padding if bound check */
14419             if (do_bounds_check)
14420                 data_offset++;
14421             sec->data_offset = data_offset;
14422             /* allocate section space to put the data */
14423             if (sec->sh_type != SHT_NOBITS && 
14424                 data_offset > sec->data_allocated)
14425                 section_realloc(sec, data_offset);
14426             /* align section if needed */
14427             if (align > sec->sh_addralign)
14428                 sec->sh_addralign = align;
14429         } else {
14430             addr = 0; /* avoid warning */
14431         }
14432
14433         if (v) {
14434             if (scope == VT_CONST) {
14435                 if (!sym)
14436                     goto do_def;
14437             } else {
14438             do_def:
14439                 sym = sym_push(v, type, r | VT_SYM, 0);
14440             }
14441             /* update symbol definition */
14442             if (sec) {
14443                 put_extern_sym(sym, sec, addr, size);
14444             } else {
14445                 Elf32_Sym *esym;
14446                 /* put a common area */
14447                 put_extern_sym(sym, NULL, align, size);
14448                 /* XXX: find a nicer way */
14449                 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
14450                 esym->st_shndx = SHN_COMMON;
14451             }
14452         } else {
14453             CValue cval;
14454
14455             /* push global reference */
14456             sym = get_sym_ref(type, sec, addr, size);
14457             cval.ul = 0;
14458             vsetc(type, VT_CONST | VT_SYM, &cval);
14459             vtop->sym = sym;
14460         }
14461
14462         /* handles bounds now because the symbol must be defined
14463            before for the relocation */
14464         if (do_bounds_check) {
14465             unsigned long *bounds_ptr;
14466
14467             greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
14468             /* then add global bound info */
14469             bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
14470             bounds_ptr[0] = 0; /* relocated */
14471             bounds_ptr[1] = size;
14472         }
14473     }
14474     if (has_init) {
14475         decl_initializer(type, sec, addr, 1, 0);
14476         /* restore parse state if needed */
14477         if (init_str.str) {
14478             tok_str_free(init_str.str);
14479             restore_parse_state(&saved_parse_state);
14480         }
14481     }
14482  no_alloc: ;
14483 }
14484
14485 void put_func_debug(Sym *sym)
14486 {
14487     char buf[512];
14488
14489     /* stabs info */
14490     /* XXX: we put here a dummy type */
14491     snprintf(buf, sizeof(buf), "%s:%c1", 
14492              funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
14493     put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
14494                 cur_text_section, sym->c);
14495     last_ind = 0;
14496     last_line_num = 0;
14497 }
14498
14499 /* parse an old style function declaration list */
14500 /* XXX: check multiple parameter */
14501 static void func_decl_list(Sym *func_sym)
14502 {
14503     AttributeDef ad;
14504     int v;
14505     Sym *s;
14506     CType btype, type;
14507
14508     /* parse each declaration */
14509     while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
14510         if (!parse_btype(&btype, &ad)) 
14511             expect("declaration list");
14512         if (((btype.t & VT_BTYPE) == VT_ENUM ||
14513              (btype.t & VT_BTYPE) == VT_STRUCT) && 
14514             tok == ';') {
14515             /* we accept no variable after */
14516         } else {
14517             for(;;) {
14518                 type = btype;
14519                 type_decl(&type, &ad, &v, TYPE_DIRECT);
14520                 /* find parameter in function parameter list */
14521                 s = func_sym->next;
14522                 while (s != NULL) {
14523                     if ((s->v & ~SYM_FIELD) == v)
14524                         goto found;
14525                     s = s->next;
14526                 }
14527                 error("declaration for parameter '%s' but no such parameter",
14528                       get_tok_str(v, NULL));
14529             found:
14530                 /* check that no storage specifier except 'register' was given */
14531                 if (type.t & VT_STORAGE)
14532                     error("storage class specified for '%s'", get_tok_str(v, NULL)); 
14533                 convert_parameter_type(&type);
14534                 /* we can add the type (NOTE: it could be local to the function) */
14535                 s->type = type;
14536                 /* accept other parameters */
14537                 if (tok == ',')
14538                     next();
14539                 else
14540                     break;
14541             }
14542         }
14543         skip(';');
14544     }
14545 }
14546
14547 /* parse a function defined by symbol 'sym' and generate its code in
14548    'cur_text_section' */
14549 static void gen_function(Sym *sym)
14550 {
14551     ind = cur_text_section->data_offset;
14552     /* NOTE: we patch the symbol size later */
14553     put_extern_sym(sym, cur_text_section, ind, 0);
14554     funcname = get_tok_str(sym->v, NULL);
14555     func_ind = ind;
14556     /* put debug symbol */
14557     if (do_debug)
14558         put_func_debug(sym);
14559     /* push a dummy symbol to enable local sym storage */
14560     sym_push2(&local_stack, SYM_FIELD, 0, 0);
14561     gfunc_prolog(&sym->type);
14562     rsym = 0;
14563     block(NULL, NULL, NULL, NULL, 0, 0);
14564     gsym(rsym);
14565     gfunc_epilog();
14566     cur_text_section->data_offset = ind;
14567     label_pop(&global_label_stack, NULL);
14568     sym_pop(&local_stack, NULL); /* reset local stack */
14569     /* end of function */
14570     /* patch symbol size */
14571     ((Elf32_Sym *)symtab_section->data)[sym->c].st_size = 
14572         ind - func_ind;
14573     if (do_debug) {
14574         put_stabn(N_FUN, 0, 0, ind - func_ind);
14575     }
14576     funcname = ""; /* for safety */
14577     func_vt.t = VT_VOID; /* for safety */
14578     ind = 0; /* for safety */
14579 }
14580
14581 static void gen_inline_functions(void)
14582 {
14583     Sym *sym;
14584     CType *type;
14585     int *str, inline_generated;
14586
14587     /* iterate while inline function are referenced */
14588     for(;;) {
14589         inline_generated = 0;
14590         for(sym = global_stack; sym != NULL; sym = sym->prev) {
14591             type = &sym->type;
14592             if (((type->t & VT_BTYPE) == VT_FUNC) &&
14593                 (type->t & (VT_STATIC | VT_INLINE)) == 
14594                 (VT_STATIC | VT_INLINE) &&
14595                 sym->c != 0) {
14596                 /* the function was used: generate its code and
14597                    convert it to a normal function */
14598                 str = (int *)sym->r;
14599                 sym->r = VT_SYM | VT_CONST;
14600                 type->t &= ~VT_INLINE;
14601
14602                 macro_ptr = str;
14603                 next();
14604                 cur_text_section = text_section;
14605                 gen_function(sym);
14606                 macro_ptr = NULL; /* fail safe */
14607
14608                 tok_str_free(str);
14609                 inline_generated = 1;
14610             }
14611         }
14612         if (!inline_generated)
14613             break;
14614     }
14615
14616     /* free all remaining inline function tokens */
14617     for(sym = global_stack; sym != NULL; sym = sym->prev) {
14618         type = &sym->type;
14619         if (((type->t & VT_BTYPE) == VT_FUNC) &&
14620             (type->t & (VT_STATIC | VT_INLINE)) == 
14621             (VT_STATIC | VT_INLINE)) {
14622             str = (int *)sym->r;
14623             tok_str_free(str);
14624             sym->r = 0; /* fail safe */
14625         }
14626     }
14627 }
14628
14629 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
14630 static void decl(int l)
14631 {
14632     int v, has_init, r;
14633     CType type, btype;
14634     Sym *sym;
14635     AttributeDef ad;
14636     
14637     while (1) {
14638         if (!parse_btype(&btype, &ad)) {
14639             /* skip redundant ';' */
14640             /* XXX: find more elegant solution */
14641             if (tok == ';') {
14642                 next();
14643                 continue;
14644             }
14645             if (l == VT_CONST &&
14646                 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
14647                 /* global asm block */
14648                 asm_global_instr();
14649                 continue;
14650             }
14651             /* special test for old K&R protos without explicit int
14652                type. Only accepted when defining global data */
14653             if (l == VT_LOCAL || tok < TOK_DEFINE)
14654                 break;
14655             btype.t = VT_INT;
14656         }
14657         if (((btype.t & VT_BTYPE) == VT_ENUM ||
14658              (btype.t & VT_BTYPE) == VT_STRUCT) && 
14659             tok == ';') {
14660             /* we accept no variable after */
14661             next();
14662             continue;
14663         }
14664         while (1) { /* iterate thru each declaration */
14665             type = btype;
14666             type_decl(&type, &ad, &v, TYPE_DIRECT);
14667 #if 0
14668             {
14669                 char buf[500];
14670                 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
14671                 printf("type = '%s'\n", buf);
14672             }
14673 #endif
14674             if ((type.t & VT_BTYPE) == VT_FUNC) {
14675                 /* if old style function prototype, we accept a
14676                    declaration list */
14677                 sym = type.ref;
14678                 if (sym->c == FUNC_OLD)
14679                     func_decl_list(sym);
14680             }
14681
14682             if (tok == '{') {
14683                 if (l == VT_LOCAL)
14684                     error("cannot use local functions");
14685                 if (!(type.t & VT_FUNC))
14686                     expect("function definition");
14687
14688                 /* reject abstract declarators in function definition */
14689                 sym = type.ref;
14690                 while ((sym = sym->next) != NULL)
14691                     if (!(sym->v & ~SYM_FIELD))
14692                        expect("identifier");
14693                 
14694                 /* XXX: cannot do better now: convert extern line to static inline */
14695                 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
14696                     type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
14697                 
14698                 sym = sym_find(v);
14699                 if (sym) {
14700                     if ((sym->type.t & VT_BTYPE) != VT_FUNC)
14701                         goto func_error1;
14702                     /* specific case: if not func_call defined, we put
14703                        the one of the prototype */
14704                     /* XXX: should have default value */
14705                     if (sym->type.ref->r != FUNC_CDECL &&
14706                         type.ref->r == FUNC_CDECL)
14707                         type.ref->r = sym->type.ref->r;
14708                     if (!is_compatible_types(&sym->type, &type)) {
14709                     func_error1:
14710                         error("incompatible types for redefinition of '%s'", 
14711                               get_tok_str(v, NULL));
14712                     }
14713                     /* if symbol is already defined, then put complete type */
14714                     sym->type = type;
14715                 } else {
14716                     /* put function symbol */
14717                     sym = global_identifier_push(v, type.t, 0);
14718                     sym->type.ref = type.ref;
14719                 }
14720
14721                 /* static inline functions are just recorded as a kind
14722                    of macro. Their code will be emitted at the end of
14723                    the compilation unit only if they are used */
14724                 if ((type.t & (VT_INLINE | VT_STATIC)) == 
14725                     (VT_INLINE | VT_STATIC)) {
14726                     TokenString func_str;
14727                     int block_level;
14728                            
14729                     tok_str_new(&func_str);
14730                     
14731                     block_level = 0;
14732                     for(;;) {
14733                         int t;
14734                         if (tok == TOK_EOF)
14735                             error("unexpected end of file");
14736                         tok_str_add_tok(&func_str);
14737                         t = tok;
14738                         next();
14739                         if (t == '{') {
14740                             block_level++;
14741                         } else if (t == '}') {
14742                             block_level--;
14743                             if (block_level == 0)
14744                                 break;
14745                         }
14746                     }
14747                     tok_str_add(&func_str, -1);
14748                     tok_str_add(&func_str, 0);
14749                     sym->r = (long)func_str.str;
14750                 } else {
14751                     /* compute text section */
14752                     cur_text_section = ad.section;
14753                     if (!cur_text_section)
14754                         cur_text_section = text_section;
14755                     sym->r = VT_SYM | VT_CONST;
14756                     gen_function(sym);
14757 #ifdef TCC_TARGET_PE
14758                     if (ad.dllexport) {
14759                         ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
14760                     }
14761 #endif
14762                 }
14763                 break;
14764             } else {
14765                 if (btype.t & VT_TYPEDEF) {
14766                     /* save typedefed type  */
14767                     /* XXX: test storage specifiers ? */
14768                     sym = sym_push(v, &type, 0, 0);
14769                     sym->type.t |= VT_TYPEDEF;
14770                 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
14771                     /* external function definition */
14772                     /* specific case for func_call attribute */
14773                     if (ad.func_call)
14774                         type.ref->r = ad.func_call;
14775                     external_sym(v, &type, 0);
14776                 } else {
14777                     /* not lvalue if array */
14778                     r = 0;
14779                     if (!(type.t & VT_ARRAY))
14780                         r |= lvalue_type(type.t);
14781                     has_init = (tok == '=');
14782                     if ((btype.t & VT_EXTERN) || 
14783                         ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
14784                          !has_init && l == VT_CONST && type.ref->c < 0)) {
14785                         /* external variable */
14786                         /* NOTE: as GCC, uninitialized global static
14787                            arrays of null size are considered as
14788                            extern */
14789                         external_sym(v, &type, r);
14790                     } else {
14791                         if (type.t & VT_STATIC)
14792                             r |= VT_CONST;
14793                         else
14794                             r |= l;
14795                         if (has_init)
14796                             next();
14797                         decl_initializer_alloc(&type, &ad, r, 
14798                                                has_init, v, l);
14799                     }
14800                 }
14801                 if (tok != ',') {
14802                     skip(';');
14803                     break;
14804                 }
14805                 next();
14806             }
14807         }
14808     }
14809 }
14810
14811 /* better than nothing, but needs extension to handle '-E' option
14812    correctly too */
14813 static void preprocess_init(TCCState *s1)
14814 {
14815     s1->include_stack_ptr = s1->include_stack;
14816     /* XXX: move that before to avoid having to initialize
14817        file->ifdef_stack_ptr ? */
14818     s1->ifdef_stack_ptr = s1->ifdef_stack;
14819     file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
14820
14821     /* XXX: not ANSI compliant: bound checking says error */
14822     vtop = vstack - 1;
14823     s1->pack_stack[0] = 0;
14824     s1->pack_stack_ptr = s1->pack_stack;
14825 }
14826
14827 /* compile the C file opened in 'file'. Return non zero if errors. */
14828 static int tcc_compile(TCCState *s1)
14829 {
14830     Sym *define_start;
14831     char buf[512];
14832     volatile int section_sym;
14833
14834 #ifdef INC_DEBUG
14835     printf("%s: **** new file\n", file->filename);
14836 #endif
14837     preprocess_init(s1);
14838
14839     funcname = "";
14840     anon_sym = SYM_FIRST_ANOM; 
14841
14842     /* file info: full path + filename */
14843     section_sym = 0; /* avoid warning */
14844     if (do_debug) {
14845         section_sym = put_elf_sym(symtab_section, 0, 0, 
14846                                   ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0, 
14847                                   text_section->sh_num, NULL);
14848         dummy_char_star = getcwd(buf, sizeof(buf));
14849         pstrcat(buf, sizeof(buf), "/");
14850         put_stabs_r(buf, N_SO, 0, 0, 
14851                     text_section->data_offset, text_section, section_sym);
14852         put_stabs_r(file->filename, N_SO, 0, 0, 
14853                     text_section->data_offset, text_section, section_sym);
14854     }
14855     /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
14856        symbols can be safely used */
14857     put_elf_sym(symtab_section, 0, 0, 
14858                 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0, 
14859                 SHN_ABS, file->filename);
14860
14861     /* define some often used types */
14862     int_type.t = VT_INT;
14863
14864     char_pointer_type.t = VT_BYTE;
14865     mk_pointer(&char_pointer_type);
14866
14867     func_old_type.t = VT_FUNC;
14868     func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
14869
14870 #if 0
14871     /* define 'void *alloca(unsigned int)' builtin function */
14872     {
14873         Sym *s1;
14874
14875         p = anon_sym++;
14876         sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
14877         s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
14878         s1->next = NULL;
14879         sym->next = s1;
14880         sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
14881     }
14882 #endif
14883
14884     define_start = define_stack;
14885
14886     if (setjmp(s1->error_jmp_buf) == 0) {
14887         s1->nb_errors = 0;
14888         s1->error_set_jmp_enabled = 1;
14889
14890         ch = file->buf_ptr[0];
14891         tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
14892         parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
14893         next();
14894         decl(VT_CONST);
14895         if (tok != TOK_EOF)
14896             expect("declaration");
14897
14898         /* end of translation unit info */
14899         if (do_debug) {
14900             put_stabs_r(NULL, N_SO, 0, 0, 
14901                         text_section->data_offset, text_section, section_sym);
14902         }
14903     }
14904     s1->error_set_jmp_enabled = 0;
14905
14906     /* reset define stack, but leave -Dsymbols (may be incorrect if
14907        they are undefined) */
14908     free_defines(define_start); 
14909
14910     gen_inline_functions();
14911
14912     sym_pop(&global_stack, NULL);
14913
14914     return s1->nb_errors != 0 ? -1 : 0;
14915 }
14916
14917 #ifdef LIBTCC
14918 int tcc_compile_string(TCCState *s, const char *str)
14919 {
14920     BufferedFile bf1, *bf = &bf1;
14921     int ret, len;
14922     char *buf;
14923
14924     /* init file structure */
14925     bf->fd = -1;
14926     /* XXX: avoid copying */
14927     len = strlen(str);
14928     buf = tcc_malloc(len + 1);
14929     if (!buf)
14930         return -1;
14931     memcpy(buf, str, len);
14932     buf[len] = CH_EOB;
14933     bf->buf_ptr = buf;
14934     bf->buf_end = buf + len;
14935     pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
14936     bf->line_num = 1;
14937     file = bf;
14938     
14939     ret = tcc_compile(s);
14940     
14941     tcc_free(buf);
14942
14943     /* currently, no need to close */
14944     return ret;
14945 }
14946 #endif
14947
14948 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
14949 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
14950 {
14951     BufferedFile bf1, *bf = &bf1;
14952
14953     pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
14954     pstrcat(bf->buffer, IO_BUF_SIZE, " ");
14955     /* default value */
14956     if (!value) 
14957         value = "1";
14958     pstrcat(bf->buffer, IO_BUF_SIZE, value);
14959     
14960     /* init file structure */
14961     bf->fd = -1;
14962     bf->buf_ptr = bf->buffer;
14963     bf->buf_end = bf->buffer + strlen(bf->buffer);
14964     *bf->buf_end = CH_EOB;
14965     bf->filename[0] = '\0';
14966     bf->line_num = 1;
14967     file = bf;
14968     
14969     s1->include_stack_ptr = s1->include_stack;
14970
14971     /* parse with define parser */
14972     ch = file->buf_ptr[0];
14973     next_nomacro();
14974     parse_define();
14975     file = NULL;
14976 }
14977
14978 /* undefine a preprocessor symbol */
14979 void tcc_undefine_symbol(TCCState *s1, const char *sym)
14980 {
14981     TokenSym *ts;
14982     Sym *s;
14983     ts = tok_alloc(sym, strlen(sym));
14984     s = define_find(ts->tok);
14985     /* undefine symbol by putting an invalid name */
14986     if (s)
14987         define_undef(s);
14988 }
14989
14990 #ifdef CONFIG_TCC_ASM
14991
14992 #ifdef TCC_TARGET_I386
14993 // njn: inlined i386-asm.c
14994 //#include "i386-asm.c"
14995 //---------------------------------------------------------------------------
14996 /*
14997  *  i386 specific functions for TCC assembler
14998  * 
14999  *  Copyright (c) 2001, 2002 Fabrice Bellard
15000  *
15001  * This library is free software; you can redistribute it and/or
15002  * modify it under the terms of the GNU Lesser General Public
15003  * License as published by the Free Software Foundation; either
15004  * version 2 of the License, or (at your option) any later version.
15005  *
15006  * This library is distributed in the hope that it will be useful,
15007  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15008  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15009  * Lesser General Public License for more details.
15010  *
15011  * You should have received a copy of the GNU Lesser General Public
15012  * License along with this library; if not, write to the Free Software
15013  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15014  */
15015
15016 #define MAX_OPERANDS 3
15017
15018 typedef struct ASMInstr {
15019     uint16_t sym;
15020     uint16_t opcode;
15021     uint16_t instr_type;
15022 #define OPC_JMP       0x01  /* jmp operand */
15023 #define OPC_B         0x02  /* only used zith OPC_WL */
15024 #define OPC_WL        0x04  /* accepts w, l or no suffix */
15025 #define OPC_BWL       (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
15026 #define OPC_REG       0x08 /* register is added to opcode */
15027 #define OPC_MODRM     0x10 /* modrm encoding */
15028 #define OPC_FWAIT     0x20 /* add fwait opcode */
15029 #define OPC_TEST      0x40 /* test opcodes */
15030 #define OPC_SHIFT     0x80 /* shift opcodes */
15031 #define OPC_D16      0x0100 /* generate data16 prefix */
15032 #define OPC_ARITH    0x0200 /* arithmetic opcodes */
15033 #define OPC_SHORTJMP 0x0400 /* short jmp operand */
15034 #define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
15035 #define OPC_GROUP_SHIFT 13
15036
15037 /* in order to compress the operand type, we use specific operands and
15038    we or only with EA  */ 
15039 #define OPT_REG8  0 /* warning: value is hardcoded from TOK_ASM_xxx */
15040 #define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */
15041 #define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */
15042 #define OPT_MMX   3 /* warning: value is hardcoded from TOK_ASM_xxx */
15043 #define OPT_SSE   4 /* warning: value is hardcoded from TOK_ASM_xxx */
15044 #define OPT_CR    5 /* warning: value is hardcoded from TOK_ASM_xxx */
15045 #define OPT_TR    6 /* warning: value is hardcoded from TOK_ASM_xxx */
15046 #define OPT_DB    7 /* warning: value is hardcoded from TOK_ASM_xxx */
15047 #define OPT_SEG   8
15048 #define OPT_ST    9
15049 #define OPT_IM8   10
15050 #define OPT_IM8S  11
15051 #define OPT_IM16  12
15052 #define OPT_IM32  13
15053 #define OPT_EAX   14 /* %al, %ax or %eax register */
15054 #define OPT_ST0   15 /* %st(0) register */
15055 #define OPT_CL    16 /* %cl register */
15056 #define OPT_DX    17 /* %dx register */
15057 #define OPT_ADDR  18 /* OP_EA with only offset */
15058 #define OPT_INDIR 19 /* *(expr) */
15059
15060 /* composite types */ 
15061 #define OPT_COMPOSITE_FIRST   20
15062 #define OPT_IM       20 /* IM8 | IM16 | IM32 */
15063 #define OPT_REG      21 /* REG8 | REG16 | REG32 */ 
15064 #define OPT_REGW     22 /* REG16 | REG32 */
15065 #define OPT_IMW      23 /* IM16 | IM32 */ 
15066
15067 /* can be ored with any OPT_xxx */
15068 #define OPT_EA    0x80
15069
15070     uint8_t nb_ops;
15071     uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
15072 } ASMInstr;
15073
15074 typedef struct Operand {
15075     uint32_t type;
15076 #define OP_REG8   (1 << OPT_REG8)
15077 #define OP_REG16  (1 << OPT_REG16)
15078 #define OP_REG32  (1 << OPT_REG32)
15079 #define OP_MMX    (1 << OPT_MMX)
15080 #define OP_SSE    (1 << OPT_SSE)
15081 #define OP_CR     (1 << OPT_CR)
15082 #define OP_TR     (1 << OPT_TR)
15083 #define OP_DB     (1 << OPT_DB)
15084 #define OP_SEG    (1 << OPT_SEG)
15085 #define OP_ST     (1 << OPT_ST)
15086 #define OP_IM8    (1 << OPT_IM8)
15087 #define OP_IM8S   (1 << OPT_IM8S)
15088 #define OP_IM16   (1 << OPT_IM16)
15089 #define OP_IM32   (1 << OPT_IM32)
15090 #define OP_EAX    (1 << OPT_EAX)
15091 #define OP_ST0    (1 << OPT_ST0)
15092 #define OP_CL     (1 << OPT_CL)
15093 #define OP_DX     (1 << OPT_DX)
15094 #define OP_ADDR   (1 << OPT_ADDR)
15095 #define OP_INDIR  (1 << OPT_INDIR)
15096
15097 #define OP_EA     0x40000000
15098 #define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32)
15099 #define OP_IM     OP_IM32
15100     int8_t  reg; /* register, -1 if none */
15101     int8_t  reg2; /* second register, -1 if none */
15102     uint8_t shift;
15103     ExprValue e;
15104 } Operand;
15105
15106 static const uint8_t reg_to_size[5] = {
15107     [OP_REG8] = 0,
15108     [OP_REG16] = 1,
15109     [OP_REG32] = 2,
15110 };
15111     
15112 #define WORD_PREFIX_OPCODE 0x66
15113
15114 #define NB_TEST_OPCODES 30
15115
15116 static const uint8_t test_bits[NB_TEST_OPCODES] = {
15117  0x00, /* o */
15118  0x01, /* no */
15119  0x02, /* b */
15120  0x02, /* c */
15121  0x02, /* nae */
15122  0x03, /* nb */
15123  0x03, /* nc */
15124  0x03, /* ae */
15125  0x04, /* e */
15126  0x04, /* z */
15127  0x05, /* ne */
15128  0x05, /* nz */
15129  0x06, /* be */
15130  0x06, /* na */
15131  0x07, /* nbe */
15132  0x07, /* a */
15133  0x08, /* s */
15134  0x09, /* ns */
15135  0x0a, /* p */
15136  0x0a, /* pe */
15137  0x0b, /* np */
15138  0x0b, /* po */
15139  0x0c, /* l */
15140  0x0c, /* nge */
15141  0x0d, /* nl */
15142  0x0d, /* ge */
15143  0x0e, /* le */
15144  0x0e, /* ng */
15145  0x0f, /* nle */
15146  0x0f, /* g */
15147 };
15148
15149 static const ASMInstr asm_instrs[] = {
15150 #define ALT(x) x
15151 #define DEF_ASM_OP0(name, opcode)
15152 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
15153 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
15154 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
15155 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
15156 // njn: inlined i386-asm.h
15157 //#include "i386-asm.h"
15158 //---------------------------------------------------------------------------
15159      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
15160      DEF_ASM_OP0(popa, 0x61)
15161      DEF_ASM_OP0(clc, 0xf8)
15162      DEF_ASM_OP0(cld, 0xfc)
15163      DEF_ASM_OP0(cli, 0xfa)
15164      DEF_ASM_OP0(clts, 0x0f06)
15165      DEF_ASM_OP0(cmc, 0xf5)
15166      DEF_ASM_OP0(lahf, 0x9f)
15167      DEF_ASM_OP0(sahf, 0x9e)
15168      DEF_ASM_OP0(pushfl, 0x9c)
15169      DEF_ASM_OP0(popfl, 0x9d)
15170      DEF_ASM_OP0(pushf, 0x9c)
15171      DEF_ASM_OP0(popf, 0x9d)
15172      DEF_ASM_OP0(stc, 0xf9)
15173      DEF_ASM_OP0(std, 0xfd)
15174      DEF_ASM_OP0(sti, 0xfb)
15175      DEF_ASM_OP0(aaa, 0x37)
15176      DEF_ASM_OP0(aas, 0x3f)
15177      DEF_ASM_OP0(daa, 0x27)
15178      DEF_ASM_OP0(das, 0x2f)
15179      DEF_ASM_OP0(aad, 0xd50a)
15180      DEF_ASM_OP0(aam, 0xd40a)
15181      DEF_ASM_OP0(cbw, 0x6698)
15182      DEF_ASM_OP0(cwd, 0x6699)
15183      DEF_ASM_OP0(cwde, 0x98)
15184      DEF_ASM_OP0(cdq, 0x99)
15185      DEF_ASM_OP0(cbtw, 0x6698)
15186      DEF_ASM_OP0(cwtl, 0x98)
15187      DEF_ASM_OP0(cwtd, 0x6699)
15188      DEF_ASM_OP0(cltd, 0x99)
15189      DEF_ASM_OP0(int3, 0xcc)
15190      DEF_ASM_OP0(into, 0xce)
15191      DEF_ASM_OP0(iret, 0xcf)
15192      DEF_ASM_OP0(rsm, 0x0faa)
15193      DEF_ASM_OP0(hlt, 0xf4)
15194      DEF_ASM_OP0(wait, 0x9b)
15195      DEF_ASM_OP0(nop, 0x90)
15196      DEF_ASM_OP0(xlat, 0xd7)
15197
15198      /* strings */
15199 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15200 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15201
15202 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15203 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15204
15205 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15206 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15207
15208 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15209 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15210
15211 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15212 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15213
15214 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15215 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15216
15217      /* bits */
15218      
15219 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15220 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15221
15222 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15223 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15224
15225 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15226 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15227
15228 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15229 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15230
15231 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15232 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15233
15234      /* prefixes */
15235      DEF_ASM_OP0(aword, 0x67)
15236      DEF_ASM_OP0(addr16, 0x67)
15237      DEF_ASM_OP0(word, 0x66)
15238      DEF_ASM_OP0(data16, 0x66)
15239      DEF_ASM_OP0(lock, 0xf0)
15240      DEF_ASM_OP0(rep, 0xf3)
15241      DEF_ASM_OP0(repe, 0xf3)
15242      DEF_ASM_OP0(repz, 0xf3)
15243      DEF_ASM_OP0(repne, 0xf2)
15244      DEF_ASM_OP0(repnz, 0xf2)
15245              
15246      DEF_ASM_OP0(invd, 0x0f08)
15247      DEF_ASM_OP0(wbinvd, 0x0f09)
15248      DEF_ASM_OP0(cpuid, 0x0fa2)
15249      DEF_ASM_OP0(wrmsr, 0x0f30)
15250      DEF_ASM_OP0(rdtsc, 0x0f31)
15251      DEF_ASM_OP0(rdmsr, 0x0f32)
15252      DEF_ASM_OP0(rdpmc, 0x0f33)
15253      DEF_ASM_OP0(ud2, 0x0f0b)
15254
15255      /* NOTE: we took the same order as gas opcode definition order */
15256 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15257 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15258 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15259 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15260 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15261 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15262
15263 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15264 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15265
15266 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15267 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15268 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15269 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15270 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15271 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15272
15273 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15274 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15275 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15276 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15277 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15278
15279 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15280 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15281 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15282 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15283 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15284
15285 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15286 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15287 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15288
15289 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15290 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15291 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15292 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15293
15294 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15295 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15296 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15297 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15298
15299 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15300 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15301 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15302 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15303
15304 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15305
15306 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15307 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15308 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15309 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15310 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15311
15312      /* arith */
15313 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
15314 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15315 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15316 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15317 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15318
15319 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15320 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15321 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15322 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15323
15324 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15325 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15326 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15327 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15328
15329 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15330 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15331
15332 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15333 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15334
15335 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15336 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15337 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15338 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15339 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15340
15341 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15342 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15343 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15344 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15345
15346      /* shifts */
15347 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15348 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15349 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15350
15351 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15352 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15353 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15354 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15355 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15356 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15357
15358 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15359 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15360 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15361 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15362
15363 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15364 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15365 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15366 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15367
15368 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15369 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15370     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15371     DEF_ASM_OP0(leave, 0xc9)
15372     DEF_ASM_OP0(ret, 0xc3)
15373 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15374     DEF_ASM_OP0(lret, 0xcb)
15375 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15376
15377 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15378     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15379     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15380     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15381     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15382     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15383     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15384      
15385      /* float */
15386      /* specific fcomp handling */
15387 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15388
15389 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15390 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15391 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15392 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15393 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15394 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15395 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15396 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15397 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15398 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15399 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15400
15401      DEF_ASM_OP0(fucompp, 0xdae9)
15402      DEF_ASM_OP0(ftst, 0xd9e4)
15403      DEF_ASM_OP0(fxam, 0xd9e5)
15404      DEF_ASM_OP0(fld1, 0xd9e8)
15405      DEF_ASM_OP0(fldl2t, 0xd9e9)
15406      DEF_ASM_OP0(fldl2e, 0xd9ea)
15407      DEF_ASM_OP0(fldpi, 0xd9eb)
15408      DEF_ASM_OP0(fldlg2, 0xd9ec)
15409      DEF_ASM_OP0(fldln2, 0xd9ed)
15410      DEF_ASM_OP0(fldz, 0xd9ee)
15411
15412      DEF_ASM_OP0(f2xm1, 0xd9f0)
15413      DEF_ASM_OP0(fyl2x, 0xd9f1)
15414      DEF_ASM_OP0(fptan, 0xd9f2)
15415      DEF_ASM_OP0(fpatan, 0xd9f3)
15416      DEF_ASM_OP0(fxtract, 0xd9f4)
15417      DEF_ASM_OP0(fprem1, 0xd9f5)
15418      DEF_ASM_OP0(fdecstp, 0xd9f6)
15419      DEF_ASM_OP0(fincstp, 0xd9f7)
15420      DEF_ASM_OP0(fprem, 0xd9f8)
15421      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15422      DEF_ASM_OP0(fsqrt, 0xd9fa)
15423      DEF_ASM_OP0(fsincos, 0xd9fb)
15424      DEF_ASM_OP0(frndint, 0xd9fc)
15425      DEF_ASM_OP0(fscale, 0xd9fd)
15426      DEF_ASM_OP0(fsin, 0xd9fe)
15427      DEF_ASM_OP0(fcos, 0xd9ff)
15428      DEF_ASM_OP0(fchs, 0xd9e0)
15429      DEF_ASM_OP0(fabs, 0xd9e1)
15430      DEF_ASM_OP0(fninit, 0xdbe3)
15431      DEF_ASM_OP0(fnclex, 0xdbe2)
15432      DEF_ASM_OP0(fnop, 0xd9d0)
15433      DEF_ASM_OP0(fwait, 0x9b)
15434
15435     /* fp load */
15436     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15437     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15438     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15439 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15440     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15441     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15442     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15443     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15444     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15445     
15446     /* fp store */
15447     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
15448     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15449     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15450     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15451 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15452     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15453     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15454     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15455     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15456     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15457
15458     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15459     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15460     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15461     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15462     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15463
15464     /* exchange */
15465     DEF_ASM_OP0(fxch, 0xd9c9)
15466 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15467
15468     /* misc FPU */
15469     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15470     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15471
15472     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15473     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15474     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15475     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15476     DEF_ASM_OP0(fnstsw, 0xdfe0)
15477 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15478 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15479     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15480 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15481 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15482     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15483     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15484     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15485     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15486     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15487     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15488     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15489     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15490     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15491     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15492     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15493
15494     /* segments */
15495     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15496     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15497     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15498     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15499     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15500     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15501 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15502     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15503     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15504     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15505     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15506     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15507     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15508     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15509     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15510
15511     /* 486 */
15512     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15513 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15514 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15515     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15516
15517     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15518     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15519
15520     /* pentium */
15521     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15522     
15523     /* pentium pro */
15524     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15525
15526     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15527     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15528     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15529     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15530     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15531     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15532     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15533     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15534
15535     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15536     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15537     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15538     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15539
15540     /* mmx */
15541     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
15542     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
15543 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
15544     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15545 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
15546     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15547     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15548     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15549     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15550     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15551     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15552     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15553     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15554     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15555     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15556     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15557     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15558     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15559     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15560     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15561     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15562     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15563     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15564     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15565     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15566     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15567     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15568     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15569 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15570     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15571 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15572     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15573 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15574     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15575 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15576     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15577 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15578     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15579 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15580     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15581 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15582     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15583 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15584     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15585     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15586     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15587     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15588     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15589     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15590     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15591     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15592     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15593     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15594     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15595     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15596     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15597     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15598
15599 #undef ALT
15600 #undef DEF_ASM_OP0
15601 #undef DEF_ASM_OP0L
15602 #undef DEF_ASM_OP1
15603 #undef DEF_ASM_OP2
15604 #undef DEF_ASM_OP3
15605 //---------------------------------------------------------------------------
15606
15607     /* last operation */
15608     { 0, },
15609 };
15610
15611 static const uint16_t op0_codes[] = {
15612 #define ALT(x)
15613 #define DEF_ASM_OP0(x, opcode) opcode,
15614 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
15615 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
15616 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
15617 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
15618 // njn: inlined i386-asm.h
15619 //#include "i386-asm.h"
15620 //---------------------------------------------------------------------------
15621      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
15622      DEF_ASM_OP0(popa, 0x61)
15623      DEF_ASM_OP0(clc, 0xf8)
15624      DEF_ASM_OP0(cld, 0xfc)
15625      DEF_ASM_OP0(cli, 0xfa)
15626      DEF_ASM_OP0(clts, 0x0f06)
15627      DEF_ASM_OP0(cmc, 0xf5)
15628      DEF_ASM_OP0(lahf, 0x9f)
15629      DEF_ASM_OP0(sahf, 0x9e)
15630      DEF_ASM_OP0(pushfl, 0x9c)
15631      DEF_ASM_OP0(popfl, 0x9d)
15632      DEF_ASM_OP0(pushf, 0x9c)
15633      DEF_ASM_OP0(popf, 0x9d)
15634      DEF_ASM_OP0(stc, 0xf9)
15635      DEF_ASM_OP0(std, 0xfd)
15636      DEF_ASM_OP0(sti, 0xfb)
15637      DEF_ASM_OP0(aaa, 0x37)
15638      DEF_ASM_OP0(aas, 0x3f)
15639      DEF_ASM_OP0(daa, 0x27)
15640      DEF_ASM_OP0(das, 0x2f)
15641      DEF_ASM_OP0(aad, 0xd50a)
15642      DEF_ASM_OP0(aam, 0xd40a)
15643      DEF_ASM_OP0(cbw, 0x6698)
15644      DEF_ASM_OP0(cwd, 0x6699)
15645      DEF_ASM_OP0(cwde, 0x98)
15646      DEF_ASM_OP0(cdq, 0x99)
15647      DEF_ASM_OP0(cbtw, 0x6698)
15648      DEF_ASM_OP0(cwtl, 0x98)
15649      DEF_ASM_OP0(cwtd, 0x6699)
15650      DEF_ASM_OP0(cltd, 0x99)
15651      DEF_ASM_OP0(int3, 0xcc)
15652      DEF_ASM_OP0(into, 0xce)
15653      DEF_ASM_OP0(iret, 0xcf)
15654      DEF_ASM_OP0(rsm, 0x0faa)
15655      DEF_ASM_OP0(hlt, 0xf4)
15656      DEF_ASM_OP0(wait, 0x9b)
15657      DEF_ASM_OP0(nop, 0x90)
15658      DEF_ASM_OP0(xlat, 0xd7)
15659
15660      /* strings */
15661 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15662 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15663
15664 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15665 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15666
15667 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15668 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15669
15670 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15671 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15672
15673 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15674 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15675
15676 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15677 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15678
15679      /* bits */
15680      
15681 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15682 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15683
15684 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15685 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15686
15687 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15688 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15689
15690 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15691 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15692
15693 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15694 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15695
15696      /* prefixes */
15697      DEF_ASM_OP0(aword, 0x67)
15698      DEF_ASM_OP0(addr16, 0x67)
15699      DEF_ASM_OP0(word, 0x66)
15700      DEF_ASM_OP0(data16, 0x66)
15701      DEF_ASM_OP0(lock, 0xf0)
15702      DEF_ASM_OP0(rep, 0xf3)
15703      DEF_ASM_OP0(repe, 0xf3)
15704      DEF_ASM_OP0(repz, 0xf3)
15705      DEF_ASM_OP0(repne, 0xf2)
15706      DEF_ASM_OP0(repnz, 0xf2)
15707              
15708      DEF_ASM_OP0(invd, 0x0f08)
15709      DEF_ASM_OP0(wbinvd, 0x0f09)
15710      DEF_ASM_OP0(cpuid, 0x0fa2)
15711      DEF_ASM_OP0(wrmsr, 0x0f30)
15712      DEF_ASM_OP0(rdtsc, 0x0f31)
15713      DEF_ASM_OP0(rdmsr, 0x0f32)
15714      DEF_ASM_OP0(rdpmc, 0x0f33)
15715      DEF_ASM_OP0(ud2, 0x0f0b)
15716
15717      /* NOTE: we took the same order as gas opcode definition order */
15718 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15719 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15720 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15721 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15722 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15723 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15724
15725 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15726 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15727
15728 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15729 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15730 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15731 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15732 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15733 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15734
15735 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15736 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15737 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15738 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15739 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15740
15741 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15742 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15743 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15744 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15745 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15746
15747 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15748 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15749 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15750
15751 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15752 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15753 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15754 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15755
15756 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15757 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15758 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15759 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15760
15761 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15762 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15763 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15764 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15765
15766 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15767
15768 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15769 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15770 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15771 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15772 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15773
15774      /* arith */
15775 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
15776 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15777 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15778 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15779 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15780
15781 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15782 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15783 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15784 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15785
15786 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15787 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15788 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15789 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15790
15791 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15792 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15793
15794 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15795 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15796
15797 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15798 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15799 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15800 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15801 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15802
15803 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15804 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15805 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15806 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15807
15808      /* shifts */
15809 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15810 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15811 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15812
15813 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15814 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15815 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15816 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15817 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15818 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15819
15820 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15821 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15822 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15823 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15824
15825 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15826 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15827 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15828 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15829
15830 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15831 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15832     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15833     DEF_ASM_OP0(leave, 0xc9)
15834     DEF_ASM_OP0(ret, 0xc3)
15835 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15836     DEF_ASM_OP0(lret, 0xcb)
15837 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15838
15839 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15840     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15841     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15842     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15843     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15844     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15845     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15846      
15847      /* float */
15848      /* specific fcomp handling */
15849 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15850
15851 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15852 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15853 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15854 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15855 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15856 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15857 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15858 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15859 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15860 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15861 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15862
15863      DEF_ASM_OP0(fucompp, 0xdae9)
15864      DEF_ASM_OP0(ftst, 0xd9e4)
15865      DEF_ASM_OP0(fxam, 0xd9e5)
15866      DEF_ASM_OP0(fld1, 0xd9e8)
15867      DEF_ASM_OP0(fldl2t, 0xd9e9)
15868      DEF_ASM_OP0(fldl2e, 0xd9ea)
15869      DEF_ASM_OP0(fldpi, 0xd9eb)
15870      DEF_ASM_OP0(fldlg2, 0xd9ec)
15871      DEF_ASM_OP0(fldln2, 0xd9ed)
15872      DEF_ASM_OP0(fldz, 0xd9ee)
15873
15874      DEF_ASM_OP0(f2xm1, 0xd9f0)
15875      DEF_ASM_OP0(fyl2x, 0xd9f1)
15876      DEF_ASM_OP0(fptan, 0xd9f2)
15877      DEF_ASM_OP0(fpatan, 0xd9f3)
15878      DEF_ASM_OP0(fxtract, 0xd9f4)
15879      DEF_ASM_OP0(fprem1, 0xd9f5)
15880      DEF_ASM_OP0(fdecstp, 0xd9f6)
15881      DEF_ASM_OP0(fincstp, 0xd9f7)
15882      DEF_ASM_OP0(fprem, 0xd9f8)
15883      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15884      DEF_ASM_OP0(fsqrt, 0xd9fa)
15885      DEF_ASM_OP0(fsincos, 0xd9fb)
15886      DEF_ASM_OP0(frndint, 0xd9fc)
15887      DEF_ASM_OP0(fscale, 0xd9fd)
15888      DEF_ASM_OP0(fsin, 0xd9fe)
15889      DEF_ASM_OP0(fcos, 0xd9ff)
15890      DEF_ASM_OP0(fchs, 0xd9e0)
15891      DEF_ASM_OP0(fabs, 0xd9e1)
15892      DEF_ASM_OP0(fninit, 0xdbe3)
15893      DEF_ASM_OP0(fnclex, 0xdbe2)
15894      DEF_ASM_OP0(fnop, 0xd9d0)
15895      DEF_ASM_OP0(fwait, 0x9b)
15896
15897     /* fp load */
15898     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15899     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15900     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15901 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15902     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15903     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15904     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15905     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15906     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15907     
15908     /* fp store */
15909     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
15910     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15911     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15912     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15913 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15914     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15915     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15916     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15917     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15918     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15919
15920     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15921     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15922     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15923     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15924     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15925
15926     /* exchange */
15927     DEF_ASM_OP0(fxch, 0xd9c9)
15928 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15929
15930     /* misc FPU */
15931     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15932     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15933
15934     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15935     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15936     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15937     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15938     DEF_ASM_OP0(fnstsw, 0xdfe0)
15939 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15940 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15941     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15942 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15943 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15944     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15945     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15946     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15947     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15948     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15949     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15950     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15951     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15952     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15953     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15954     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15955
15956     /* segments */
15957     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15958     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15959     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15960     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15961     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15962     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15963 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15964     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15965     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15966     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15967     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15968     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15969     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15970     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15971     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15972
15973     /* 486 */
15974     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15975 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15976 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15977     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15978
15979     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15980     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15981
15982     /* pentium */
15983     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15984     
15985     /* pentium pro */
15986     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15987
15988     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15989     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15990     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15991     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15992     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15993     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15994     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15995     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15996
15997     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15998     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15999     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
16000     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
16001
16002     /* mmx */
16003     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
16004     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
16005 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
16006     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16007 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
16008     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16009     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16010     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16011     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16012     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16013     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16014     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16015     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16016     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16017     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16018     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16019     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16020     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16021     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16022     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16023     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16024     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16025     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16026     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16027     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16028     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16029     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16030     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16031 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16032     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16033 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16034     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16035 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16036     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16037 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16038     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16039 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16040     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16041 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16042     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16043 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16044     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16045 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16046     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16047     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16048     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16049     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16050     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16051     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16052     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16053     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16054     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16055     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16056     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16057     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16058     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16059     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16060
16061 #undef ALT
16062 #undef DEF_ASM_OP0
16063 #undef DEF_ASM_OP0L
16064 #undef DEF_ASM_OP1
16065 #undef DEF_ASM_OP2
16066 #undef DEF_ASM_OP3
16067 //---------------------------------------------------------------------------
16068 };
16069
16070 static inline int get_reg_shift(TCCState *s1)
16071 {
16072     int shift, v;
16073
16074     v = asm_int_expr(s1);
16075     switch(v) {
16076     case 1:
16077         shift = 0;
16078         break;
16079     case 2:
16080         shift = 1;
16081         break;
16082     case 4:
16083         shift = 2;
16084         break;
16085     case 8:
16086         shift = 3;
16087         break;
16088     default:
16089         expect("1, 2, 4 or 8 constant");
16090         shift = 0;
16091         break;
16092     }
16093     return shift;
16094 }
16095
16096 static int asm_parse_reg(void)
16097 {
16098     int reg;
16099     if (tok != '%')
16100         goto error_32;
16101     next();
16102     if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
16103         reg = tok - TOK_ASM_eax;
16104         next();
16105         return reg;
16106     } else {
16107     error_32:
16108         expect("32 bit register");
16109         return 0;
16110     }
16111 }
16112
16113 static void parse_operand(TCCState *s1, Operand *op)
16114 {
16115     ExprValue e;
16116     int reg, indir;
16117     const char *p;
16118
16119     indir = 0;
16120     if (tok == '*') {
16121         next();
16122         indir = OP_INDIR;
16123     }
16124
16125     if (tok == '%') {
16126         next();
16127         if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
16128             reg = tok - TOK_ASM_al;
16129             op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
16130             op->reg = reg & 7;
16131             if ((op->type & OP_REG) && op->reg == TREG_EAX)
16132                 op->type |= OP_EAX;
16133             else if (op->type == OP_REG8 && op->reg == TREG_ECX)
16134                 op->type |= OP_CL;
16135             else if (op->type == OP_REG16 && op->reg == TREG_EDX)
16136                 op->type |= OP_DX;
16137         } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
16138             op->type = OP_DB;
16139             op->reg = tok - TOK_ASM_dr0;
16140         } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
16141             op->type = OP_SEG;
16142             op->reg = tok - TOK_ASM_es;
16143         } else if (tok == TOK_ASM_st) {
16144             op->type = OP_ST;
16145             op->reg = 0;
16146             next();
16147             if (tok == '(') {
16148                 next();
16149                 if (tok != TOK_PPNUM)
16150                     goto reg_error;
16151                 p = tokc.cstr->data;
16152                 reg = p[0] - '0';
16153                 if ((unsigned)reg >= 8 || p[1] != '\0')
16154                     goto reg_error;
16155                 op->reg = reg;
16156                 next();
16157                 skip(')');
16158             }
16159             if (op->reg == 0)
16160                 op->type |= OP_ST0;
16161             goto no_skip;
16162         } else {
16163         reg_error:
16164             error("unknown register");
16165         }
16166         next();
16167     no_skip: ;
16168     } else if (tok == '$') {
16169         /* constant value */
16170         next();
16171         asm_expr(s1, &e);
16172         op->type = OP_IM32;
16173         op->e.v = e.v;
16174         op->e.sym = e.sym;
16175         if (!op->e.sym) {
16176             if (op->e.v == (uint8_t)op->e.v)
16177                 op->type |= OP_IM8;
16178             if (op->e.v == (int8_t)op->e.v)
16179                 op->type |= OP_IM8S;
16180             if (op->e.v == (uint16_t)op->e.v)
16181                 op->type |= OP_IM16;
16182         }
16183     } else {
16184         /* address(reg,reg2,shift) with all variants */
16185         op->type = OP_EA;
16186         op->reg = -1;
16187         op->reg2 = -1;
16188         op->shift = 0;
16189         if (tok != '(') {
16190             asm_expr(s1, &e);
16191             op->e.v = e.v;
16192             op->e.sym = e.sym;
16193         } else {
16194             op->e.v = 0;
16195             op->e.sym = NULL;
16196         }
16197         if (tok == '(') {
16198             next();
16199             if (tok != ',') {
16200                 op->reg = asm_parse_reg();
16201             }
16202             if (tok == ',') {
16203                 next();
16204                 if (tok != ',') {
16205                     op->reg2 = asm_parse_reg();
16206                 } 
16207                 skip(',');
16208                 op->shift = get_reg_shift(s1);
16209             }
16210             skip(')');
16211         }
16212         if (op->reg == -1 && op->reg2 == -1)
16213             op->type |= OP_ADDR;
16214     }
16215     op->type |= indir;
16216 }
16217
16218 /* XXX: unify with C code output ? */
16219 static void gen_expr32(ExprValue *pe)
16220 {
16221     if (pe->sym)
16222         greloc(cur_text_section, pe->sym, ind, R_386_32);
16223     gen_le32(pe->v);
16224 }
16225
16226 /* XXX: unify with C code output ? */
16227 static void gen_disp32(ExprValue *pe)
16228 {
16229     Sym *sym;
16230     sym = pe->sym;
16231     if (sym) {
16232         if (sym->r == cur_text_section->sh_num) {
16233             /* same section: we can output an absolute value. Note
16234                that the TCC compiler behaves differently here because
16235                it always outputs a relocation to ease (future) code
16236                elimination in the linker */
16237             gen_le32(pe->v + (long)sym->next - ind - 4);
16238         } else {
16239             greloc(cur_text_section, sym, ind, R_386_PC32);
16240             gen_le32(pe->v - 4);
16241         }
16242     } else {
16243         /* put an empty PC32 relocation */
16244         put_elf_reloc(symtab_section, cur_text_section, 
16245                       ind, R_386_PC32, 0);
16246         gen_le32(pe->v - 4);
16247     }
16248 }
16249
16250
16251 static void gen_le16(int v)
16252 {
16253     g(v);
16254     g(v >> 8);
16255 }
16256
16257 /* generate the modrm operand */
16258 static inline void asm_modrm(int reg, Operand *op)
16259 {
16260     int mod, reg1, reg2, sib_reg1;
16261
16262     if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
16263         g(0xc0 + (reg << 3) + op->reg);
16264     } else if (op->reg == -1 && op->reg2 == -1) {
16265         /* displacement only */
16266         g(0x05 + (reg << 3));
16267         gen_expr32(&op->e);
16268     } else {
16269         sib_reg1 = op->reg;
16270         /* fist compute displacement encoding */
16271         if (sib_reg1 == -1) {
16272             sib_reg1 = 5;
16273             mod = 0x00;
16274         } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
16275             mod = 0x00;
16276         } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
16277             mod = 0x40;
16278         } else {
16279             mod = 0x80;
16280         }
16281         /* compute if sib byte needed */
16282         reg1 = op->reg;
16283         if (op->reg2 != -1)
16284             reg1 = 4;
16285         g(mod + (reg << 3) + reg1);
16286         if (reg1 == 4) {
16287             /* add sib byte */
16288             reg2 = op->reg2;
16289             if (reg2 == -1)
16290                 reg2 = 4; /* indicate no index */
16291             g((op->shift << 6) + (reg2 << 3) + sib_reg1);
16292         }
16293
16294         /* add offset */
16295         if (mod == 0x40) {
16296             g(op->e.v);
16297         } else if (mod == 0x80 || op->reg == -1) {
16298             gen_expr32(&op->e);
16299         }
16300     }
16301 }
16302
16303 static void asm_opcode(TCCState *s1, int opcode)
16304 {
16305     const ASMInstr *pa;
16306     int i, modrm_index, reg, v, op1, is_short_jmp;
16307     int nb_ops, s, ss;
16308     Operand ops[MAX_OPERANDS], *pop;
16309     int op_type[3]; /* decoded op type */
16310
16311     /* get operands */
16312     pop = ops;
16313     nb_ops = 0;
16314     for(;;) {
16315         if (tok == ';' || tok == TOK_LINEFEED)
16316             break;
16317         if (nb_ops >= MAX_OPERANDS) {
16318             error("incorrect number of operands");
16319         }
16320         parse_operand(s1, pop);
16321         pop++;
16322         nb_ops++;
16323         if (tok != ',')
16324             break;
16325         next();
16326     }
16327
16328     is_short_jmp = 0;
16329     s = 0; /* avoid warning */
16330     
16331     /* optimize matching by using a lookup table (no hashing is needed
16332        !) */
16333     for(pa = asm_instrs; pa->sym != 0; pa++) {
16334         s = 0;
16335         if (pa->instr_type & OPC_FARITH) {
16336             v = opcode - pa->sym;
16337             if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
16338                 continue;
16339         } else if (pa->instr_type & OPC_ARITH) {
16340             if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
16341                 continue;
16342             goto compute_size;
16343         } else if (pa->instr_type & OPC_SHIFT) {
16344             if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
16345                 continue;
16346             goto compute_size;
16347         } else if (pa->instr_type & OPC_TEST) {
16348             if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
16349                 continue;
16350         } else if (pa->instr_type & OPC_B) {
16351             if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
16352                 continue;
16353         compute_size:
16354             s = (opcode - pa->sym) & 3;
16355         } else if (pa->instr_type & OPC_WL) {
16356             if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
16357                 continue;
16358             s = opcode - pa->sym + 1;
16359         } else {
16360             if (pa->sym != opcode)
16361                 continue;
16362         }
16363         if (pa->nb_ops != nb_ops)
16364             continue;
16365         /* now decode and check each operand */
16366         for(i = 0; i < nb_ops; i++) {
16367             int op1, op2;
16368             op1 = pa->op_type[i];
16369             op2 = op1 & 0x1f;
16370             switch(op2) {
16371             case OPT_IM:
16372                 v = OP_IM8 | OP_IM16 | OP_IM32;
16373                 break;
16374             case OPT_REG:
16375                 v = OP_REG8 | OP_REG16 | OP_REG32;
16376                 break;
16377             case OPT_REGW:
16378                 v = OP_REG16 | OP_REG32;
16379                 break;
16380             case OPT_IMW:
16381                 v = OP_IM16 | OP_IM32;
16382                 break;
16383             default:
16384                 v = 1 << op2;
16385                 break;
16386             }
16387             if (op1 & OPT_EA)
16388                 v |= OP_EA;
16389             op_type[i] = v;
16390             if ((ops[i].type & v) == 0)
16391                 goto next;
16392         }
16393         /* all is matching ! */
16394         break;
16395     next: ;
16396     }
16397     if (pa->sym == 0) {
16398         if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
16399             int b;
16400             b = op0_codes[opcode - TOK_ASM_pusha];
16401             if (b & 0xff00) 
16402                 g(b >> 8);
16403             g(b);
16404             return;
16405         } else {
16406             error("unknown opcode '%s'", 
16407                   get_tok_str(opcode, NULL));
16408         }
16409     }
16410     /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
16411     if (s == 3) {
16412         for(i = 0; s == 3 && i < nb_ops; i++) {
16413             if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
16414                 s = reg_to_size[ops[i].type & OP_REG];
16415         }
16416         if (s == 3) {
16417             if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && 
16418                 (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
16419                 s = 2;
16420             else
16421                 error("cannot infer opcode suffix");
16422         }
16423     }
16424
16425     /* generate data16 prefix if needed */
16426     ss = s;
16427     if (s == 1 || (pa->instr_type & OPC_D16))
16428         g(WORD_PREFIX_OPCODE);
16429     else if (s == 2)
16430         s = 1;
16431     /* now generates the operation */
16432     if (pa->instr_type & OPC_FWAIT)
16433         g(0x9b);
16434
16435     v = pa->opcode;
16436     if (v == 0x69 || v == 0x69) {
16437         /* kludge for imul $im, %reg */
16438         nb_ops = 3;
16439         ops[2] = ops[1];
16440     } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
16441         v--; /* int $3 case */
16442         nb_ops = 0;
16443     } else if ((v == 0x06 || v == 0x07)) {
16444         if (ops[0].reg >= 4) {
16445             /* push/pop %fs or %gs */
16446             v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
16447         } else {
16448             v += ops[0].reg << 3;
16449         }
16450         nb_ops = 0;
16451     } else if (v <= 0x05) {
16452         /* arith case */
16453         v += ((opcode - TOK_ASM_addb) >> 2) << 3;
16454     } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
16455         /* fpu arith case */
16456         v += ((opcode - pa->sym) / 6) << 3;
16457     }
16458     if (pa->instr_type & OPC_REG) {
16459         for(i = 0; i < nb_ops; i++) {
16460             if (op_type[i] & (OP_REG | OP_ST)) {
16461                 v += ops[i].reg;
16462                 break;
16463             }
16464         }
16465         /* mov $im, %reg case */
16466         if (pa->opcode == 0xb0 && s >= 1)
16467             v += 7;
16468     }
16469     if (pa->instr_type & OPC_B)
16470         v += s;
16471     if (pa->instr_type & OPC_TEST)
16472         v += test_bits[opcode - pa->sym]; 
16473     if (pa->instr_type & OPC_SHORTJMP) {
16474         Sym *sym;
16475         int jmp_disp;
16476
16477         /* see if we can really generate the jump with a byte offset */
16478         sym = ops[0].e.sym;
16479         if (!sym)
16480             goto no_short_jump;
16481         if (sym->r != cur_text_section->sh_num)
16482             goto no_short_jump;
16483         jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
16484         if (jmp_disp == (int8_t)jmp_disp) {
16485             /* OK to generate jump */
16486             is_short_jmp = 1;
16487             ops[0].e.v = jmp_disp;
16488         } else {
16489         no_short_jump:
16490             if (pa->instr_type & OPC_JMP) {
16491                 /* long jump will be allowed. need to modify the
16492                    opcode slightly */
16493                 if (v == 0xeb)
16494                     v = 0xe9;
16495                 else 
16496                     v += 0x0f10;
16497             } else {
16498                 error("invalid displacement");
16499             }
16500         }
16501     }
16502     op1 = v >> 8;
16503     if (op1)
16504         g(op1);
16505     g(v);
16506         
16507     /* search which operand will used for modrm */
16508     modrm_index = 0;
16509     if (pa->instr_type & OPC_SHIFT) {
16510         reg = (opcode - pa->sym) >> 2; 
16511         if (reg == 6)
16512             reg = 7;
16513     } else if (pa->instr_type & OPC_ARITH) {
16514         reg = (opcode - pa->sym) >> 2;
16515     } else if (pa->instr_type & OPC_FARITH) {
16516         reg = (opcode - pa->sym) / 6;
16517     } else {
16518         reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
16519     }
16520     if (pa->instr_type & OPC_MODRM) {
16521         /* first look for an ea operand */
16522         for(i = 0;i < nb_ops; i++) {
16523             if (op_type[i] & OP_EA)
16524                 goto modrm_found;
16525         }
16526         /* then if not found, a register or indirection (shift instructions) */
16527         for(i = 0;i < nb_ops; i++) {
16528             if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
16529                 goto modrm_found;
16530         }
16531 #ifdef ASM_DEBUG
16532         error("bad op table");
16533 #endif      
16534     modrm_found:
16535         modrm_index = i;
16536         /* if a register is used in another operand then it is
16537            used instead of group */
16538         for(i = 0;i < nb_ops; i++) {
16539             v = op_type[i];
16540             if (i != modrm_index && 
16541                 (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
16542                 reg = ops[i].reg;
16543                 break;
16544             }
16545         }
16546
16547         asm_modrm(reg, &ops[modrm_index]);
16548     }
16549
16550     /* emit constants */
16551     if (pa->opcode == 0x9a || pa->opcode == 0xea) {
16552         /* ljmp or lcall kludge */
16553         gen_expr32(&ops[1].e);
16554         if (ops[0].e.sym)
16555             error("cannot relocate");
16556         gen_le16(ops[0].e.v);
16557     } else {
16558         for(i = 0;i < nb_ops; i++) {
16559             v = op_type[i];
16560             if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
16561                 /* if multiple sizes are given it means we must look
16562                    at the op size */
16563                 if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
16564                     v == (OP_IM16 | OP_IM32)) {
16565                     if (ss == 0)
16566                         v = OP_IM8;
16567                     else if (ss == 1)
16568                         v = OP_IM16;
16569                     else
16570                         v = OP_IM32;
16571                 }
16572                 if (v & (OP_IM8 | OP_IM8S)) {
16573                     if (ops[i].e.sym)
16574                         goto error_relocate;
16575                     g(ops[i].e.v);
16576                 } else if (v & OP_IM16) {
16577                     if (ops[i].e.sym) {
16578                     error_relocate:
16579                         error("cannot relocate");
16580                     }
16581                     gen_le16(ops[i].e.v);
16582                 } else {
16583                     if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
16584                         if (is_short_jmp)
16585                             g(ops[i].e.v);
16586                         else
16587                             gen_disp32(&ops[i].e);
16588                     } else {
16589                         gen_expr32(&ops[i].e);
16590                     }
16591                 }
16592             }
16593         }
16594     }
16595 }
16596
16597 #define NB_SAVED_REGS 3
16598 #define NB_ASM_REGS 8
16599
16600 /* return the constraint priority (we allocate first the lowest
16601    numbered constraints) */
16602 static inline int constraint_priority(const char *str)
16603 {
16604     int priority, c, pr;
16605
16606     /* we take the lowest priority */
16607     priority = 0;
16608     for(;;) {
16609         c = *str;
16610         if (c == '\0')
16611             break;
16612         str++;
16613         switch(c) {
16614         case 'A':
16615             pr = 0;
16616             break;
16617         case 'a':
16618         case 'b':
16619         case 'c':
16620         case 'd':
16621         case 'S':
16622         case 'D':
16623             pr = 1;
16624             break;
16625         case 'q':
16626             pr = 2;
16627             break;
16628         case 'r':
16629             pr = 3;
16630             break;
16631         case 'N':
16632         case 'M':
16633         case 'I':
16634         case 'i':
16635         case 'm':
16636         case 'g':
16637             pr = 4;
16638             break;
16639         default:
16640             error("unknown constraint '%c'", c);
16641             pr = 0;
16642         }
16643         if (pr > priority)
16644             priority = pr;
16645     }
16646     return priority;
16647 }
16648
16649 static const char *skip_constraint_modifiers(const char *p)
16650 {
16651     while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
16652         p++;
16653     return p;
16654 }
16655
16656 #define REG_OUT_MASK 0x01
16657 #define REG_IN_MASK  0x02
16658
16659 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
16660
16661 static void asm_compute_constraints(ASMOperand *operands, 
16662                                     int nb_operands, int nb_outputs, 
16663                                     const uint8_t *clobber_regs,
16664                                     int *pout_reg)
16665 {
16666     ASMOperand *op;
16667     int sorted_op[MAX_ASM_OPERANDS];
16668     int i, j, k, p1, p2, tmp, reg, c, reg_mask;
16669     const char *str;
16670     uint8_t regs_allocated[NB_ASM_REGS];
16671     
16672     /* init fields */
16673     for(i=0;i<nb_operands;i++) {
16674         op = &operands[i];
16675         op->input_index = -1;
16676         op->ref_index = -1;
16677         op->reg = -1;
16678         op->is_memory = 0;
16679         op->is_rw = 0;
16680     }
16681     /* compute constraint priority and evaluate references to output
16682        constraints if input constraints */
16683     for(i=0;i<nb_operands;i++) {
16684         op = &operands[i];
16685         str = op->constraint;
16686         str = skip_constraint_modifiers(str);
16687         if (isnum(*str) || *str == '[') {
16688             /* this is a reference to another constraint */
16689             k = find_constraint(operands, nb_operands, str, NULL);
16690             if ((unsigned)k >= i || i < nb_outputs)
16691                 error("invalid reference in constraint %d ('%s')",
16692                       i, str);
16693             op->ref_index = k;
16694             if (operands[k].input_index >= 0)
16695                 error("cannot reference twice the same operand");
16696             operands[k].input_index = i;
16697             op->priority = 5;
16698         } else {
16699             op->priority = constraint_priority(str);
16700         }
16701     }
16702     
16703     /* sort operands according to their priority */
16704     for(i=0;i<nb_operands;i++)
16705         sorted_op[i] = i;
16706     for(i=0;i<nb_operands - 1;i++) {
16707         for(j=i+1;j<nb_operands;j++) {
16708             p1 = operands[sorted_op[i]].priority; 
16709             p2 = operands[sorted_op[j]].priority;
16710             if (p2 < p1) {
16711                 tmp = sorted_op[i];
16712                 sorted_op[i] = sorted_op[j];
16713                 sorted_op[j] = tmp;
16714             }
16715         }
16716     }
16717
16718     for(i = 0;i < NB_ASM_REGS; i++) {
16719         if (clobber_regs[i])
16720             regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
16721         else
16722             regs_allocated[i] = 0;
16723     }
16724     /* esp cannot be used */
16725     regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK; 
16726     /* ebp cannot be used yet */
16727     regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK; 
16728
16729     /* allocate registers and generate corresponding asm moves */
16730     for(i=0;i<nb_operands;i++) {
16731         j = sorted_op[i];
16732         op = &operands[j];
16733         str = op->constraint;
16734         /* no need to allocate references */
16735         if (op->ref_index >= 0)
16736             continue;
16737         /* select if register is used for output, input or both */
16738         if (op->input_index >= 0) {
16739             reg_mask = REG_IN_MASK | REG_OUT_MASK;
16740         } else if (j < nb_outputs) {
16741             reg_mask = REG_OUT_MASK;
16742         } else {
16743             reg_mask = REG_IN_MASK;
16744         }
16745     try_next:
16746         c = *str++;
16747         switch(c) {
16748         case '=':
16749             goto try_next;
16750         case '+':
16751             op->is_rw = 1;
16752             /* FALL THRU */
16753         case '&':
16754             if (j >= nb_outputs)
16755                 error("'%c' modifier can only be applied to outputs", c);
16756             reg_mask = REG_IN_MASK | REG_OUT_MASK;
16757             goto try_next;
16758         case 'A':
16759             /* allocate both eax and edx */
16760             if (is_reg_allocated(TREG_EAX) || 
16761                 is_reg_allocated(TREG_EDX))
16762                 goto try_next;
16763             op->is_llong = 1;
16764             op->reg = TREG_EAX;
16765             regs_allocated[TREG_EAX] |= reg_mask;
16766             regs_allocated[TREG_EDX] |= reg_mask;
16767             break;
16768         case 'a':
16769             reg = TREG_EAX;
16770             goto alloc_reg;
16771         case 'b':
16772             reg = 3;
16773             goto alloc_reg;
16774         case 'c':
16775             reg = TREG_ECX;
16776             goto alloc_reg;
16777         case 'd':
16778             reg = TREG_EDX;
16779             goto alloc_reg;
16780         case 'S':
16781             reg = 6;
16782             goto alloc_reg;
16783         case 'D':
16784             reg = 7;
16785         alloc_reg:
16786             if (is_reg_allocated(reg))
16787                 goto try_next;
16788             goto reg_found;
16789         case 'q':
16790             /* eax, ebx, ecx or edx */
16791             for(reg = 0; reg < 4; reg++) {
16792                 if (!is_reg_allocated(reg))
16793                     goto reg_found;
16794             }
16795             goto try_next;
16796         case 'r':
16797             /* any general register */
16798             for(reg = 0; reg < 8; reg++) {
16799                 if (!is_reg_allocated(reg))
16800                     goto reg_found;
16801             }
16802             goto try_next;
16803         reg_found:
16804             /* now we can reload in the register */
16805             op->is_llong = 0;
16806             op->reg = reg;
16807             regs_allocated[reg] |= reg_mask;
16808             break;
16809         case 'i':
16810             if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
16811                 goto try_next;
16812             break;
16813         case 'I':
16814         case 'N':
16815         case 'M':
16816             if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
16817                 goto try_next;
16818             break;
16819         case 'm':
16820         case 'g':
16821             /* nothing special to do because the operand is already in
16822                memory, except if the pointer itself is stored in a
16823                memory variable (VT_LLOCAL case) */
16824             /* XXX: fix constant case */
16825             /* if it is a reference to a memory zone, it must lie
16826                in a register, so we reserve the register in the
16827                input registers and a load will be generated
16828                later */
16829             if (j < nb_outputs || c == 'm') {
16830                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
16831                     /* any general register */
16832                     for(reg = 0; reg < 8; reg++) {
16833                         if (!(regs_allocated[reg] & REG_IN_MASK))
16834                             goto reg_found1;
16835                     }
16836                     goto try_next;
16837                 reg_found1:
16838                     /* now we can reload in the register */
16839                     regs_allocated[reg] |= REG_IN_MASK;
16840                     op->reg = reg;
16841                     op->is_memory = 1;
16842                 }
16843             }
16844             break;
16845         default:
16846             error("asm constraint %d ('%s') could not be satisfied", 
16847                   j, op->constraint);
16848             break;
16849         }
16850         /* if a reference is present for that operand, we assign it too */
16851         if (op->input_index >= 0) {
16852             operands[op->input_index].reg = op->reg;
16853             operands[op->input_index].is_llong = op->is_llong;
16854         }
16855     }
16856     
16857     /* compute out_reg. It is used to store outputs registers to memory
16858        locations references by pointers (VT_LLOCAL case) */
16859     *pout_reg = -1;
16860     for(i=0;i<nb_operands;i++) {
16861         op = &operands[i];
16862         if (op->reg >= 0 && 
16863             (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
16864             !op->is_memory) {
16865             for(reg = 0; reg < 8; reg++) {
16866                 if (!(regs_allocated[reg] & REG_OUT_MASK))
16867                     goto reg_found2;
16868             }
16869             error("could not find free output register for reloading");
16870         reg_found2:
16871             *pout_reg = reg;
16872             break;
16873         }
16874     }
16875     
16876     /* print sorted constraints */
16877 #ifdef ASM_DEBUG
16878     for(i=0;i<nb_operands;i++) {
16879         j = sorted_op[i];
16880         op = &operands[j];
16881         printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", 
16882                j,                
16883                op->id ? get_tok_str(op->id, NULL) : "", 
16884                op->constraint,
16885                op->vt->r,
16886                op->reg);
16887     }
16888     if (*pout_reg >= 0)
16889         printf("out_reg=%d\n", *pout_reg);
16890 #endif
16891 }
16892
16893 static void subst_asm_operand(CString *add_str, 
16894                               SValue *sv, int modifier)
16895 {
16896     int r, reg, size, val;
16897     char buf[64];
16898
16899     r = sv->r;
16900     if ((r & VT_VALMASK) == VT_CONST) {
16901         if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
16902             cstr_ccat(add_str, '$');
16903         if (r & VT_SYM) {
16904             cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
16905             if (sv->c.i != 0) {
16906                 cstr_ccat(add_str, '+');
16907             } else {
16908                 return;
16909             }
16910         }
16911         val = sv->c.i;
16912         if (modifier == 'n')
16913             val = -val;
16914         snprintf(buf, sizeof(buf), "%d", sv->c.i);
16915         cstr_cat(add_str, buf);
16916     } else if ((r & VT_VALMASK) == VT_LOCAL) {
16917         snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
16918         cstr_cat(add_str, buf);
16919     } else if (r & VT_LVAL) {
16920         reg = r & VT_VALMASK;
16921         if (reg >= VT_CONST)
16922             error("internal compiler error");
16923         snprintf(buf, sizeof(buf), "(%%%s)", 
16924                  get_tok_str(TOK_ASM_eax + reg, NULL));
16925         cstr_cat(add_str, buf);
16926     } else {
16927         /* register case */
16928         reg = r & VT_VALMASK;
16929         if (reg >= VT_CONST)
16930             error("internal compiler error");
16931
16932         /* choose register operand size */
16933         if ((sv->type.t & VT_BTYPE) == VT_BYTE)
16934             size = 1;
16935         else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
16936             size = 2;
16937         else
16938             size = 4;
16939         if (size == 1 && reg >= 4)
16940             size = 4;
16941
16942         if (modifier == 'b') {
16943             if (reg >= 4)
16944                 error("cannot use byte register");
16945             size = 1;
16946         } else if (modifier == 'h') {
16947             if (reg >= 4)
16948                 error("cannot use byte register");
16949             size = -1;
16950         } else if (modifier == 'w') {
16951             size = 2;
16952         }
16953
16954         switch(size) {
16955         case -1:
16956             reg = TOK_ASM_ah + reg;
16957             break;
16958         case 1:
16959             reg = TOK_ASM_al + reg;
16960             break;
16961         case 2:
16962             reg = TOK_ASM_ax + reg;
16963             break;
16964         default:
16965             reg = TOK_ASM_eax + reg;
16966             break;
16967         }
16968         snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
16969         cstr_cat(add_str, buf);
16970     }
16971 }
16972
16973 /* generate prolog and epilog code for asm statment */
16974 static void asm_gen_code(ASMOperand *operands, int nb_operands, 
16975                          int nb_outputs, int is_output,
16976                          uint8_t *clobber_regs,
16977                          int out_reg)
16978 {
16979     uint8_t regs_allocated[NB_ASM_REGS];
16980     ASMOperand *op;
16981     int i, reg;
16982     static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
16983
16984     /* mark all used registers */
16985     memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
16986     for(i = 0; i < nb_operands;i++) {
16987         op = &operands[i];
16988         if (op->reg >= 0)
16989             regs_allocated[op->reg] = 1;
16990     }
16991     if (!is_output) {
16992         /* generate reg save code */
16993         for(i = 0; i < NB_SAVED_REGS; i++) {
16994             reg = reg_saved[i];
16995             if (regs_allocated[reg]) 
16996                 g(0x50 + reg);
16997         }
16998
16999         /* generate load code */
17000         for(i = 0; i < nb_operands; i++) {
17001             op = &operands[i];
17002             if (op->reg >= 0) {
17003                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
17004                     op->is_memory) {
17005                     /* memory reference case (for both input and
17006                        output cases) */
17007                     SValue sv;
17008                     sv = *op->vt;
17009                     sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17010                     load(op->reg, &sv);
17011                 } else if (i >= nb_outputs || op->is_rw) {
17012                     /* load value in register */
17013                     load(op->reg, op->vt);
17014                     if (op->is_llong) {
17015                         SValue sv;
17016                         sv = *op->vt;
17017                         sv.c.ul += 4;
17018                         load(TREG_EDX, &sv);
17019                     }
17020                 }
17021             }
17022         }
17023     } else {
17024         /* generate save code */
17025         for(i = 0 ; i < nb_outputs; i++) {
17026             op = &operands[i];
17027             if (op->reg >= 0) {
17028                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
17029                     if (!op->is_memory) {
17030                         SValue sv;
17031                         sv = *op->vt;
17032                         sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17033                         load(out_reg, &sv);
17034
17035                         sv.r = (sv.r & ~VT_VALMASK) | out_reg;
17036                         store(op->reg, &sv);
17037                     }
17038                 } else {
17039                     store(op->reg, op->vt);
17040                     if (op->is_llong) {
17041                         SValue sv;
17042                         sv = *op->vt;
17043                         sv.c.ul += 4;
17044                         store(TREG_EDX, &sv);
17045                     }
17046                 }
17047             }
17048         }
17049         /* generate reg restore code */
17050         for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
17051             reg = reg_saved[i];
17052             if (regs_allocated[reg]) 
17053                 g(0x58 + reg);
17054         }
17055     }
17056 }
17057
17058 static void asm_clobber(uint8_t *clobber_regs, const char *str)
17059 {
17060     int reg;
17061     TokenSym *ts;
17062
17063     if (!strcmp(str, "memory") || 
17064         !strcmp(str, "cc"))
17065         return;
17066     ts = tok_alloc(str, strlen(str));
17067     reg = ts->tok;
17068     if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
17069         reg -= TOK_ASM_eax;
17070     } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
17071         reg -= TOK_ASM_ax;
17072     } else {
17073         error("invalid clobber register '%s'", str);
17074     }
17075     clobber_regs[reg] = 1;
17076 }
17077 //---------------------------------------------------------------------------
17078 #endif
17079 // njn: inlined tccasm.c
17080 //#include "tccasm.c"
17081 //---------------------------------------------------------------------------
17082 /*
17083  *  GAS like assembler for TCC
17084  * 
17085  *  Copyright (c) 2001-2004 Fabrice Bellard
17086  *
17087  * This library is free software; you can redistribute it and/or
17088  * modify it under the terms of the GNU Lesser General Public
17089  * License as published by the Free Software Foundation; either
17090  * version 2 of the License, or (at your option) any later version.
17091  *
17092  * This library is distributed in the hope that it will be useful,
17093  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17094  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17095  * Lesser General Public License for more details.
17096  *
17097  * You should have received a copy of the GNU Lesser General Public
17098  * License along with this library; if not, write to the Free Software
17099  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17100  */
17101
17102 static int asm_get_local_label_name(TCCState *s1, unsigned int n)
17103 {
17104     char buf[64];
17105     TokenSym *ts;
17106
17107     snprintf(buf, sizeof(buf), "L..%u", n);
17108     ts = tok_alloc(buf, strlen(buf));
17109     return ts->tok;
17110 }
17111
17112 static void asm_expr(TCCState *s1, ExprValue *pe);
17113
17114 /* We do not use the C expression parser to handle symbols. Maybe the
17115    C expression parser could be tweaked to do so. */
17116
17117 static void asm_expr_unary(TCCState *s1, ExprValue *pe)
17118 {
17119     Sym *sym;
17120     int op, n, label;
17121     const char *p;
17122
17123     switch(tok) {
17124     case TOK_PPNUM:
17125         p = tokc.cstr->data;
17126         n = strtoul(p, (char **)&p, 0);
17127         if (*p == 'b' || *p == 'f') {
17128             /* backward or forward label */
17129             label = asm_get_local_label_name(s1, n);
17130             sym = label_find(label);
17131             if (*p == 'b') {
17132                 /* backward : find the last corresponding defined label */
17133                 if (sym && sym->r == 0)
17134                     sym = sym->prev_tok;
17135                 if (!sym)
17136                     error("local label '%d' not found backward", n);
17137             } else {
17138                 /* forward */
17139                 if (!sym || sym->r) {
17140                     /* if the last label is defined, then define a new one */
17141                     sym = label_push(&s1->asm_labels, label, 0);
17142                     sym->type.t = VT_STATIC | VT_VOID;
17143                 }
17144             }
17145             pe->v = 0;
17146             pe->sym = sym;
17147         } else if (*p == '\0') {
17148             pe->v = n;
17149             pe->sym = NULL;
17150         } else {
17151             error("invalid number syntax");
17152         }
17153         next();
17154         break;
17155     case '+':
17156         next();
17157         asm_expr_unary(s1, pe);
17158         break;
17159     case '-':
17160     case '~':
17161         op = tok;
17162         next();
17163         asm_expr_unary(s1, pe);
17164         if (pe->sym)
17165             error("invalid operation with label");
17166         if (op == '-')
17167             pe->v = -pe->v;
17168         else
17169             pe->v = ~pe->v;
17170         break;
17171     case TOK_CCHAR:
17172     case TOK_LCHAR:
17173         pe->v = tokc.i;
17174         pe->sym = NULL;
17175         next();
17176         break;
17177     case '(':
17178         next();
17179         asm_expr(s1, pe);
17180         skip(')');
17181         break;
17182     default:
17183         if (tok >= TOK_IDENT) {
17184             /* label case : if the label was not found, add one */
17185             sym = label_find(tok);
17186             if (!sym) {
17187                 sym = label_push(&s1->asm_labels, tok, 0);
17188                 /* NOTE: by default, the symbol is global */
17189                 sym->type.t = VT_VOID;
17190             }
17191             if (sym->r == SHN_ABS) {
17192                 /* if absolute symbol, no need to put a symbol value */
17193                 pe->v = (long)sym->next;
17194                 pe->sym = NULL;
17195             } else {
17196                 pe->v = 0;
17197                 pe->sym = sym;
17198             }
17199             next();
17200         } else {
17201             error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
17202         }
17203         break;
17204     }
17205 }
17206     
17207 static void asm_expr_prod(TCCState *s1, ExprValue *pe)
17208 {
17209     int op;
17210     ExprValue e2;
17211
17212     asm_expr_unary(s1, pe);
17213     for(;;) {
17214         op = tok;
17215         if (op != '*' && op != '/' && op != '%' && 
17216             op != TOK_SHL && op != TOK_SAR)
17217             break;
17218         next();
17219         asm_expr_unary(s1, &e2);
17220         if (pe->sym || e2.sym)
17221             error("invalid operation with label");
17222         switch(op) {
17223         case '*':
17224             pe->v *= e2.v;
17225             break;
17226         case '/':  
17227             if (e2.v == 0) {
17228             div_error:
17229                 error("division by zero");
17230             }
17231             pe->v /= e2.v;
17232             break;
17233         case '%':  
17234             if (e2.v == 0)
17235                 goto div_error;
17236             pe->v %= e2.v;
17237             break;
17238         case TOK_SHL:
17239             pe->v <<= e2.v;
17240             break;
17241         default:
17242         case TOK_SAR:
17243             pe->v >>= e2.v;
17244             break;
17245         }
17246     }
17247 }
17248
17249 static void asm_expr_logic(TCCState *s1, ExprValue *pe)
17250 {
17251     int op;
17252     ExprValue e2;
17253
17254     asm_expr_prod(s1, pe);
17255     for(;;) {
17256         op = tok;
17257         if (op != '&' && op != '|' && op != '^')
17258             break;
17259         next();
17260         asm_expr_prod(s1, &e2);
17261         if (pe->sym || e2.sym)
17262             error("invalid operation with label");
17263         switch(op) {
17264         case '&':
17265             pe->v &= e2.v;
17266             break;
17267         case '|':  
17268             pe->v |= e2.v;
17269             break;
17270         default:
17271         case '^':
17272             pe->v ^= e2.v;
17273             break;
17274         }
17275     }
17276 }
17277
17278 static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
17279 {
17280     int op;
17281     ExprValue e2;
17282
17283     asm_expr_logic(s1, pe);
17284     for(;;) {
17285         op = tok;
17286         if (op != '+' && op != '-')
17287             break;
17288         next();
17289         asm_expr_logic(s1, &e2);
17290         if (op == '+') {
17291             if (pe->sym != NULL && e2.sym != NULL)
17292                 goto cannot_relocate;
17293             pe->v += e2.v;
17294             if (pe->sym == NULL && e2.sym != NULL)
17295                 pe->sym = e2.sym;
17296         } else {
17297             pe->v -= e2.v;
17298             /* NOTE: we are less powerful than gas in that case
17299                because we store only one symbol in the expression */
17300             if (!pe->sym && !e2.sym) {
17301                 /* OK */
17302             } else if (pe->sym && !e2.sym) {
17303                 /* OK */
17304             } else if (pe->sym && e2.sym) {
17305                 if (pe->sym == e2.sym) { 
17306                     /* OK */
17307                 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
17308                     /* we also accept defined symbols in the same section */
17309                     pe->v += (long)pe->sym->next - (long)e2.sym->next;
17310                 } else {
17311                     goto cannot_relocate;
17312                 }
17313                 pe->sym = NULL; /* same symbols can be substracted to NULL */
17314             } else {
17315             cannot_relocate:
17316                 error("invalid operation with label");
17317             }
17318         }
17319     }
17320 }
17321
17322 static void asm_expr(TCCState *s1, ExprValue *pe)
17323 {
17324     asm_expr_sum(s1, pe);
17325 }
17326
17327 static int asm_int_expr(TCCState *s1)
17328 {
17329     ExprValue e;
17330     asm_expr(s1, &e);
17331     if (e.sym)
17332         expect("constant");
17333     return e.v;
17334 }
17335
17336 /* NOTE: the same name space as C labels is used to avoid using too
17337    much memory when storing labels in TokenStrings */
17338 static void asm_new_label1(TCCState *s1, int label, int is_local,
17339                            int sh_num, long value)
17340 {
17341     Sym *sym;
17342
17343     sym = label_find(label);
17344     if (sym) {
17345         if (sym->r) {
17346             /* the label is already defined */
17347             if (!is_local) {
17348                 error("assembler label '%s' already defined", 
17349                       get_tok_str(label, NULL));
17350             } else {
17351                 /* redefinition of local labels is possible */
17352                 goto new_label;
17353             }
17354         }
17355     } else {
17356     new_label:
17357         sym = label_push(&s1->asm_labels, label, 0);
17358         sym->type.t = VT_STATIC | VT_VOID;
17359     }
17360     sym->r = sh_num;
17361     sym->next = (void *)value;
17362 }
17363
17364 static void asm_new_label(TCCState *s1, int label, int is_local)
17365 {
17366     asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
17367 }
17368
17369 static void asm_free_labels(TCCState *st)
17370 {
17371     Sym *s, *s1;
17372     Section *sec;
17373     
17374     for(s = st->asm_labels; s != NULL; s = s1) {
17375         s1 = s->prev;
17376         /* define symbol value in object file */
17377         if (s->r) {
17378             if (s->r == SHN_ABS)
17379                 sec = SECTION_ABS;
17380             else
17381                 sec = st->sections[s->r];
17382             put_extern_sym2(s, sec, (long)s->next, 0, 0);
17383         }
17384         /* remove label */
17385         table_ident[s->v - TOK_IDENT]->sym_label = NULL;
17386         sym_free(s);
17387     }
17388     st->asm_labels = NULL;
17389 }
17390
17391 static void use_section1(TCCState *s1, Section *sec)
17392 {
17393     cur_text_section->data_offset = ind;
17394     cur_text_section = sec;
17395     ind = cur_text_section->data_offset;
17396 }
17397
17398 static void use_section(TCCState *s1, const char *name)
17399 {
17400     Section *sec;
17401     sec = find_section(s1, name);
17402     use_section1(s1, sec);
17403 }
17404
17405 static void asm_parse_directive(TCCState *s1)
17406 {
17407     int n, offset, v, size, tok1;
17408     Section *sec;
17409     uint8_t *ptr;
17410
17411     /* assembler directive */
17412     next();
17413     sec = cur_text_section;
17414     switch(tok) {
17415     case TOK_ASM_align:
17416     case TOK_ASM_skip:
17417     case TOK_ASM_space:
17418         tok1 = tok;
17419         next();
17420         n = asm_int_expr(s1);
17421         if (tok1 == TOK_ASM_align) {
17422             if (n < 0 || (n & (n-1)) != 0)
17423                 error("alignment must be a positive power of two");
17424             offset = (ind + n - 1) & -n;
17425             size = offset - ind;
17426             /* the section must have a compatible alignment */
17427             if (sec->sh_addralign < n)
17428                 sec->sh_addralign = n;
17429         } else {
17430             size = n;
17431         }
17432         v = 0;
17433         if (tok == ',') {
17434             next();
17435             v = asm_int_expr(s1);
17436         }
17437     zero_pad:
17438         if (sec->sh_type != SHT_NOBITS) {
17439             sec->data_offset = ind;
17440             ptr = section_ptr_add(sec, size);
17441             memset(ptr, v, size);
17442         }
17443         ind += size;
17444         break;
17445     case TOK_ASM_quad:
17446         next();
17447         for(;;) {
17448             uint64_t vl;
17449             const char *p;
17450
17451             p = tokc.cstr->data;
17452             if (tok != TOK_PPNUM) {
17453             error_constant:
17454                 error("64 bit constant");
17455             }
17456             vl = strtoll(p, (char **)&p, 0);
17457             if (*p != '\0')
17458                 goto error_constant;
17459             next();
17460             if (sec->sh_type != SHT_NOBITS) {
17461                 /* XXX: endianness */
17462                 gen_le32(vl);
17463                 gen_le32(vl >> 32);
17464             } else {
17465                 ind += 8;
17466             }
17467             if (tok != ',')
17468                 break;
17469             next();
17470         }
17471         break;
17472     case TOK_ASM_byte:
17473         size = 1;
17474         goto asm_data;
17475     case TOK_ASM_word:
17476     case TOK_SHORT:
17477         size = 2;
17478         goto asm_data;
17479     case TOK_LONG:
17480     case TOK_INT:
17481         size = 4;
17482     asm_data:
17483         next();
17484         for(;;) {
17485             ExprValue e;
17486             asm_expr(s1, &e);
17487             if (sec->sh_type != SHT_NOBITS) {
17488                 if (size == 4) {
17489                     gen_expr32(&e);
17490                 } else {
17491                     if (e.sym)
17492                         expect("constant");
17493                     if (size == 1)
17494                         g(e.v);
17495                     else
17496                         gen_le16(e.v);
17497                 }
17498             } else {
17499                 ind += size;
17500             }
17501             if (tok != ',')
17502                 break;
17503             next();
17504         }
17505         break;
17506     case TOK_ASM_fill:
17507         {
17508             int repeat, size, val, i, j;
17509             uint8_t repeat_buf[8];
17510             next();
17511             repeat = asm_int_expr(s1);
17512             if (repeat < 0) {
17513                 error("repeat < 0; .fill ignored");
17514                 break;
17515             }
17516             size = 1;
17517             val = 0;
17518             if (tok == ',') {
17519                 next();
17520                 size = asm_int_expr(s1);
17521                 if (size < 0) {
17522                     error("size < 0; .fill ignored");
17523                     break;
17524                 }
17525                 if (size > 8)
17526                     size = 8;
17527                 if (tok == ',') {
17528                     next();
17529                     val = asm_int_expr(s1);
17530                 }
17531             }
17532             /* XXX: endianness */
17533             repeat_buf[0] = val;
17534             repeat_buf[1] = val >> 8;
17535             repeat_buf[2] = val >> 16;
17536             repeat_buf[3] = val >> 24;
17537             repeat_buf[4] = 0;
17538             repeat_buf[5] = 0;
17539             repeat_buf[6] = 0;
17540             repeat_buf[7] = 0;
17541             for(i = 0; i < repeat; i++) {
17542                 for(j = 0; j < size; j++) {
17543                     g(repeat_buf[j]);
17544                 }
17545             }
17546         }
17547         break;
17548     case TOK_ASM_org:
17549         {
17550             unsigned long n;
17551             next();
17552             /* XXX: handle section symbols too */
17553             n = asm_int_expr(s1);
17554             if (n < ind)
17555                 error("attempt to .org backwards");
17556             v = 0;
17557             size = n - ind;
17558             goto zero_pad;
17559         }
17560         break;
17561     case TOK_ASM_globl:
17562     case TOK_ASM_global:
17563         { 
17564             Sym *sym;
17565
17566             next();
17567             sym = label_find(tok);
17568             if (!sym) {
17569                 sym = label_push(&s1->asm_labels, tok, 0);
17570                 sym->type.t = VT_VOID;
17571             }
17572             sym->type.t &= ~VT_STATIC;
17573             next();
17574         }
17575         break;
17576     case TOK_ASM_string:
17577     case TOK_ASM_ascii:
17578     case TOK_ASM_asciz:
17579         {
17580             const uint8_t *p;
17581             int i, size, t;
17582
17583             t = tok;
17584             next();
17585             for(;;) {
17586                 if (tok != TOK_STR)
17587                     expect("string constant");
17588                 p = tokc.cstr->data;
17589                 size = tokc.cstr->size;
17590                 if (t == TOK_ASM_ascii && size > 0)
17591                     size--;
17592                 for(i = 0; i < size; i++)
17593                     g(p[i]);
17594                 next();
17595                 if (tok == ',') {
17596                     next();
17597                 } else if (tok != TOK_STR) {
17598                     break;
17599                 }
17600             }
17601         }
17602         break;
17603     case TOK_ASM_text:
17604     case TOK_ASM_data:
17605     case TOK_ASM_bss:
17606         { 
17607             char sname[64];
17608             tok1 = tok;
17609             n = 0;
17610             next();
17611             if (tok != ';' && tok != TOK_LINEFEED) {
17612                 n = asm_int_expr(s1);
17613                 next();
17614             }
17615             sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
17616             use_section(s1, sname);
17617         }
17618         break;
17619     case TOK_SECTION1:
17620         {
17621             char sname[256];
17622
17623             /* XXX: support more options */
17624             next();
17625             sname[0] = '\0';
17626             while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
17627                 if (tok == TOK_STR)
17628                     pstrcat(sname, sizeof(sname), tokc.cstr->data);
17629                 else
17630                     pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
17631                 next();
17632             }
17633             if (tok == ',') {
17634                 /* skip section options */
17635                 next();
17636                 if (tok != TOK_STR)
17637                     expect("string constant");
17638                 next();
17639             }
17640             last_text_section = cur_text_section;
17641             use_section(s1, sname);
17642         }
17643         break;
17644     case TOK_ASM_previous:
17645         { 
17646             Section *sec;
17647             next();
17648             if (!last_text_section)
17649                 error("no previous section referenced");
17650             sec = cur_text_section;
17651             use_section1(s1, last_text_section);
17652             last_text_section = sec;
17653         }
17654         break;
17655     default:
17656         error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
17657         break;
17658     }
17659 }
17660
17661
17662 /* assemble a file */
17663 static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
17664 {
17665     int opcode;
17666
17667 #if 0
17668     /* print stats about opcodes */
17669     {
17670         const ASMInstr *pa;
17671         int freq[4];
17672         int op_vals[500];
17673         int nb_op_vals, i, j;
17674
17675         nb_op_vals = 0;
17676         memset(freq, 0, sizeof(freq));
17677         for(pa = asm_instrs; pa->sym != 0; pa++) {
17678             freq[pa->nb_ops]++;
17679             for(i=0;i<pa->nb_ops;i++) {
17680                 for(j=0;j<nb_op_vals;j++) {
17681                     if (pa->op_type[i] == op_vals[j])
17682                         goto found;
17683                 }
17684                 op_vals[nb_op_vals++] = pa->op_type[i];
17685             found: ;
17686             }
17687         }
17688         for(i=0;i<nb_op_vals;i++) {
17689             int v = op_vals[i];
17690             if ((v & (v - 1)) != 0)
17691                 printf("%3d: %08x\n", i, v);
17692         }
17693         printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
17694                sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
17695                freq[0], freq[1], freq[2], freq[3]);
17696     }
17697 #endif
17698
17699     /* XXX: undefine C labels */
17700
17701     ch = file->buf_ptr[0];
17702     tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
17703     parse_flags = PARSE_FLAG_ASM_COMMENTS;
17704     if (do_preprocess)
17705         parse_flags |= PARSE_FLAG_PREPROCESS;
17706     next();
17707     for(;;) {
17708         if (tok == TOK_EOF)
17709             break;
17710         parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
17711     redo:
17712         if (tok == '#') {
17713             /* horrible gas comment */
17714             while (tok != TOK_LINEFEED)
17715                 next();
17716         } else if (tok == '.') {
17717             asm_parse_directive(s1);
17718         } else if (tok == TOK_PPNUM) {
17719             const char *p;
17720             int n;
17721             p = tokc.cstr->data;
17722             n = strtoul(p, (char **)&p, 10);
17723             if (*p != '\0')
17724                 expect("':'");
17725             /* new local label */
17726             asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
17727             next();
17728             skip(':');
17729             goto redo;
17730         } else if (tok >= TOK_IDENT) {
17731             /* instruction or label */
17732             opcode = tok;
17733             next();
17734             if (tok == ':') {
17735                 /* new label */
17736                 asm_new_label(s1, opcode, 0);
17737                 next();
17738                 goto redo;
17739             } else if (tok == '=') {
17740                 int n;
17741                 next();
17742                 n = asm_int_expr(s1);
17743                 asm_new_label1(s1, opcode, 0, SHN_ABS, n);
17744                 goto redo;
17745             } else {
17746                 asm_opcode(s1, opcode);
17747             }
17748         }
17749         /* end of line */
17750         if (tok != ';' && tok != TOK_LINEFEED){
17751             expect("end of line");
17752         }
17753         parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
17754         next();
17755     }
17756
17757     asm_free_labels(s1);
17758
17759     return 0;
17760 }
17761
17762 /* Assemble the current file */
17763 static int tcc_assemble(TCCState *s1, int do_preprocess)
17764 {
17765     Sym *define_start;
17766     int ret;
17767
17768     preprocess_init(s1);
17769
17770     /* default section is text */
17771     cur_text_section = text_section;
17772     ind = cur_text_section->data_offset;
17773
17774     define_start = define_stack;
17775
17776     ret = tcc_assemble_internal(s1, do_preprocess);
17777
17778     cur_text_section->data_offset = ind;
17779
17780     free_defines(define_start); 
17781
17782     return ret;
17783 }
17784
17785 /********************************************************************/
17786 /* GCC inline asm support */
17787
17788 /* assemble the string 'str' in the current C compilation unit without
17789    C preprocessing. NOTE: str is modified by modifying the '\0' at the
17790    end */
17791 static void tcc_assemble_inline(TCCState *s1, char *str, int len)
17792 {
17793     BufferedFile *bf, *saved_file;
17794     int saved_parse_flags, *saved_macro_ptr;
17795
17796     bf = tcc_malloc(sizeof(BufferedFile));
17797     memset(bf, 0, sizeof(BufferedFile));
17798     bf->fd = -1;
17799     bf->buf_ptr = str;
17800     bf->buf_end = str + len;
17801     str[len] = CH_EOB;
17802     /* same name as current file so that errors are correctly
17803        reported */
17804     pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
17805     bf->line_num = file->line_num;
17806     saved_file = file;
17807     file = bf;
17808     saved_parse_flags = parse_flags;
17809     saved_macro_ptr = macro_ptr;
17810     macro_ptr = NULL;
17811     
17812     tcc_assemble_internal(s1, 0);
17813
17814     parse_flags = saved_parse_flags;
17815     macro_ptr = saved_macro_ptr;
17816     file = saved_file;
17817     tcc_free(bf);
17818 }
17819
17820 /* find a constraint by its number or id (gcc 3 extended
17821    syntax). return -1 if not found. Return in *pp in char after the
17822    constraint */
17823 static int find_constraint(ASMOperand *operands, int nb_operands, 
17824                            const char *name, const char **pp)
17825 {
17826     int index;
17827     TokenSym *ts;
17828     const char *p;
17829
17830     if (isnum(*name)) {
17831         index = 0;
17832         while (isnum(*name)) {
17833             index = (index * 10) + (*name) - '0';
17834             name++;
17835         }
17836         if ((unsigned)index >= nb_operands)
17837             index = -1;
17838     } else if (*name == '[') {
17839         name++;
17840         p = strchr(name, ']');
17841         if (p) {
17842             ts = tok_alloc(name, p - name);
17843             for(index = 0; index < nb_operands; index++) {
17844                 if (operands[index].id == ts->tok)
17845                     goto found;
17846             }
17847             index = -1;
17848         found:
17849             name = p + 1;
17850         } else {
17851             index = -1;
17852         }
17853     } else {
17854         index = -1;
17855     }
17856     if (pp)
17857         *pp = name;
17858     return index;
17859 }
17860
17861 static void subst_asm_operands(ASMOperand *operands, int nb_operands, 
17862                                int nb_outputs,
17863                                CString *out_str, CString *in_str)
17864 {
17865     int c, index, modifier;
17866     const char *str;
17867     ASMOperand *op;
17868     SValue sv;
17869
17870     cstr_new(out_str);
17871     str = in_str->data;
17872     for(;;) {
17873         c = *str++;
17874         if (c == '%') {
17875             if (*str == '%') {
17876                 str++;
17877                 goto add_char;
17878             }
17879             modifier = 0;
17880             if (*str == 'c' || *str == 'n' ||
17881                 *str == 'b' || *str == 'w' || *str == 'h')
17882                 modifier = *str++;
17883             index = find_constraint(operands, nb_operands, str, &str);
17884             if (index < 0)
17885                 error("invalid operand reference after %%");
17886             op = &operands[index];
17887             sv = *op->vt;
17888             if (op->reg >= 0) {
17889                 sv.r = op->reg;
17890                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL)
17891                     sv.r |= VT_LVAL;
17892             }
17893             subst_asm_operand(out_str, &sv, modifier);
17894         } else {
17895         add_char:
17896             cstr_ccat(out_str, c);
17897             if (c == '\0')
17898                 break;
17899         }
17900     }
17901 }
17902
17903
17904 static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
17905                                int is_output)
17906 {
17907     ASMOperand *op;
17908     int nb_operands;
17909
17910     if (tok != ':') {
17911         nb_operands = *nb_operands_ptr;
17912         for(;;) {
17913             if (nb_operands >= MAX_ASM_OPERANDS)
17914                 error("too many asm operands");
17915             op = &operands[nb_operands++];
17916             op->id = 0;
17917             if (tok == '[') {
17918                 next();
17919                 if (tok < TOK_IDENT)
17920                     expect("identifier");
17921                 op->id = tok;
17922                 next();
17923                 skip(']');
17924             }
17925             if (tok != TOK_STR)
17926                 expect("string constant");
17927             op->constraint = tcc_malloc(tokc.cstr->size);
17928             strcpy(op->constraint, tokc.cstr->data);
17929             next();
17930             skip('(');
17931             gexpr();
17932             if (is_output) {
17933                 test_lvalue();
17934             } else {
17935                 /* we want to avoid LLOCAL case, except when the 'm'
17936                    constraint is used. Note that it may come from
17937                    register storage, so we need to convert (reg)
17938                    case */
17939                 if ((vtop->r & VT_LVAL) &&
17940                     ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
17941                      (vtop->r & VT_VALMASK) < VT_CONST) &&
17942                     !strchr(op->constraint, 'm')) {
17943                     gv(RC_INT);
17944                 }
17945             }
17946             op->vt = vtop;
17947             skip(')');
17948             if (tok == ',') {
17949                 next();
17950             } else {
17951                 break;
17952             }
17953         }
17954         *nb_operands_ptr = nb_operands;
17955     }
17956 }
17957
17958 static void parse_asm_str(CString *astr)
17959 {
17960     skip('(');
17961     /* read the string */
17962     if (tok != TOK_STR)
17963         expect("string constant");
17964     cstr_new(astr);
17965     while (tok == TOK_STR) {
17966         /* XXX: add \0 handling too ? */
17967         cstr_cat(astr, tokc.cstr->data);
17968         next();
17969     }
17970     cstr_ccat(astr, '\0');
17971 }
17972
17973 /* parse the GCC asm() instruction */
17974 static void asm_instr(void)
17975 {
17976     CString astr, astr1;
17977     ASMOperand operands[MAX_ASM_OPERANDS];
17978     int nb_inputs __attribute__((unused));
17979     int nb_outputs, nb_operands, i, must_subst, out_reg;
17980     uint8_t clobber_regs[NB_ASM_REGS];
17981
17982     next();
17983     /* since we always generate the asm() instruction, we can ignore
17984        volatile */
17985     if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
17986         next();
17987     }
17988     parse_asm_str(&astr);
17989     nb_operands = 0;
17990     nb_outputs = 0;
17991     must_subst = 0;
17992     memset(clobber_regs, 0, sizeof(clobber_regs));
17993     if (tok == ':') {
17994         next();
17995         must_subst = 1;
17996         /* output args */
17997         parse_asm_operands(operands, &nb_operands, 1);
17998         nb_outputs = nb_operands;
17999         if (tok == ':') {
18000             next();
18001             /* input args */
18002             parse_asm_operands(operands, &nb_operands, 0);
18003             if (tok == ':') {
18004                 /* clobber list */
18005                 /* XXX: handle registers */
18006                 next();
18007                 for(;;) {
18008                     if (tok != TOK_STR)
18009                         expect("string constant");
18010                     asm_clobber(clobber_regs, tokc.cstr->data);
18011                     next();
18012                     if (tok == ',') {
18013                         next();
18014                     } else {
18015                         break;
18016                     }
18017                 }
18018             }
18019         }
18020     }
18021     skip(')');
18022     /* NOTE: we do not eat the ';' so that we can restore the current
18023        token after the assembler parsing */
18024     if (tok != ';')
18025         expect("';'");
18026     nb_inputs = nb_operands - nb_outputs;
18027     
18028     /* save all values in the memory */
18029     save_regs(0);
18030
18031     /* compute constraints */
18032     asm_compute_constraints(operands, nb_operands, nb_outputs, 
18033                             clobber_regs, &out_reg);
18034
18035     /* substitute the operands in the asm string. No substitution is
18036        done if no operands (GCC behaviour) */
18037 #ifdef ASM_DEBUG
18038     printf("asm: \"%s\"\n", (char *)astr.data);
18039 #endif
18040     if (must_subst) {
18041         subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
18042         cstr_free(&astr);
18043     } else {
18044         astr1 = astr;
18045     }
18046 #ifdef ASM_DEBUG
18047     printf("subst_asm: \"%s\"\n", (char *)astr1.data);
18048 #endif
18049
18050     /* generate loads */
18051     asm_gen_code(operands, nb_operands, nb_outputs, 0, 
18052                  clobber_regs, out_reg);    
18053
18054     /* assemble the string with tcc internal assembler */
18055     tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
18056
18057     /* restore the current C token */
18058     next();
18059
18060     /* store the output values if needed */
18061     asm_gen_code(operands, nb_operands, nb_outputs, 1, 
18062                  clobber_regs, out_reg);
18063     
18064     /* free everything */
18065     for(i=0;i<nb_operands;i++) {
18066         ASMOperand *op;
18067         op = &operands[i];
18068         tcc_free(op->constraint);
18069         vpop();
18070     }
18071     cstr_free(&astr1);
18072 }
18073
18074 static void asm_global_instr(void)
18075 {
18076     CString astr;
18077
18078     next();
18079     parse_asm_str(&astr);
18080     skip(')');
18081     /* NOTE: we do not eat the ';' so that we can restore the current
18082        token after the assembler parsing */
18083     if (tok != ';')
18084         expect("';'");
18085     
18086 #ifdef ASM_DEBUG
18087     printf("asm_global: \"%s\"\n", (char *)astr.data);
18088 #endif
18089     cur_text_section = text_section;
18090     ind = cur_text_section->data_offset;
18091
18092     /* assemble the string with tcc internal assembler */
18093     tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
18094     
18095     cur_text_section->data_offset = ind;
18096
18097     /* restore the current C token */
18098     next();
18099
18100     cstr_free(&astr);
18101 }
18102 //---------------------------------------------------------------------------
18103
18104 #else
18105 static void asm_instr(void)
18106 {
18107     error("inline asm() not supported");
18108 }
18109 static void asm_global_instr(void)
18110 {
18111     error("inline asm() not supported");
18112 }
18113 #endif
18114
18115 // njn: inlined tccelf.c
18116 //#include "tccelf.c"
18117 //---------------------------------------------------------------------------
18118 /*
18119  *  ELF file handling for TCC
18120  * 
18121  *  Copyright (c) 2001-2004 Fabrice Bellard
18122  *
18123  * This library is free software; you can redistribute it and/or
18124  * modify it under the terms of the GNU Lesser General Public
18125  * License as published by the Free Software Foundation; either
18126  * version 2 of the License, or (at your option) any later version.
18127  *
18128  * This library is distributed in the hope that it will be useful,
18129  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18130  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18131  * Lesser General Public License for more details.
18132  *
18133  * You should have received a copy of the GNU Lesser General Public
18134  * License along with this library; if not, write to the Free Software
18135  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18136  */
18137
18138 static int put_elf_str(Section *s, const char *sym)
18139 {
18140     int offset, len;
18141     char *ptr;
18142
18143     len = strlen(sym) + 1;
18144     offset = s->data_offset;
18145     ptr = section_ptr_add(s, len);
18146     memcpy(ptr, sym, len);
18147     return offset;
18148 }
18149
18150 /* elf symbol hashing function */
18151 static unsigned long elf_hash(const unsigned char *name)
18152 {
18153     unsigned long h = 0, g;
18154     
18155     while (*name) {
18156         h = (h << 4) + *name++;
18157         g = h & 0xf0000000;
18158         if (g)
18159             h ^= g >> 24;
18160         h &= ~g;
18161     }
18162     return h;
18163 }
18164
18165 /* rebuild hash table of section s */
18166 /* NOTE: we do factorize the hash table code to go faster */
18167 static void rebuild_hash(Section *s, unsigned int nb_buckets)
18168 {
18169     Elf32_Sym *sym;
18170     int *ptr, *hash, nb_syms, sym_index, h;
18171     char *strtab;
18172
18173     strtab = s->link->data;
18174     nb_syms = s->data_offset / sizeof(Elf32_Sym);
18175
18176     s->hash->data_offset = 0;
18177     ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
18178     ptr[0] = nb_buckets;
18179     ptr[1] = nb_syms;
18180     ptr += 2;
18181     hash = ptr;
18182     memset(hash, 0, (nb_buckets + 1) * sizeof(int));
18183     ptr += nb_buckets + 1;
18184
18185     sym = (Elf32_Sym *)s->data + 1;
18186     for(sym_index = 1; sym_index < nb_syms; sym_index++) {
18187         if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
18188             h = elf_hash(strtab + sym->st_name) % nb_buckets;
18189             *ptr = hash[h];
18190             hash[h] = sym_index;
18191         } else {
18192             *ptr = 0;
18193         }
18194         ptr++;
18195         sym++;
18196     }
18197 }
18198
18199 /* return the symbol number */
18200 static int put_elf_sym(Section *s, 
18201                        unsigned long value, unsigned long size,
18202                        int info, int other, int shndx, const char *name)
18203 {
18204     int name_offset, sym_index;
18205     int nbuckets, h;
18206     Elf32_Sym *sym;
18207     Section *hs;
18208     
18209     sym = section_ptr_add(s, sizeof(Elf32_Sym));
18210     if (name)
18211         name_offset = put_elf_str(s->link, name);
18212     else
18213         name_offset = 0;
18214     /* XXX: endianness */
18215     sym->st_name = name_offset;
18216     sym->st_value = value;
18217     sym->st_size = size;
18218     sym->st_info = info;
18219     sym->st_other = other;
18220     sym->st_shndx = shndx;
18221     sym_index = sym - (Elf32_Sym *)s->data;
18222     hs = s->hash;
18223     if (hs) {
18224         int *ptr, *base;
18225         ptr = section_ptr_add(hs, sizeof(int));
18226         base = (int *)hs->data;
18227         /* only add global or weak symbols */
18228         if (ELF32_ST_BIND(info) != STB_LOCAL) {
18229             /* add another hashing entry */
18230             nbuckets = base[0];
18231             h = elf_hash(name) % nbuckets;
18232             *ptr = base[2 + h];
18233             base[2 + h] = sym_index;
18234             base[1]++;
18235             /* we resize the hash table */
18236             hs->nb_hashed_syms++;
18237             if (hs->nb_hashed_syms > 2 * nbuckets) {
18238                 rebuild_hash(s, 2 * nbuckets);
18239             }
18240         } else {
18241             *ptr = 0;
18242             base[1]++;
18243         }
18244     }
18245     return sym_index;
18246 }
18247
18248 /* find global ELF symbol 'name' and return its index. Return 0 if not
18249    found. */
18250 static int find_elf_sym(Section *s, const char *name)
18251 {
18252     Elf32_Sym *sym;
18253     Section *hs;
18254     int nbuckets, sym_index, h;
18255     const char *name1;
18256     
18257     hs = s->hash;
18258     if (!hs)
18259         return 0;
18260     nbuckets = ((int *)hs->data)[0];
18261     h = elf_hash(name) % nbuckets;
18262     sym_index = ((int *)hs->data)[2 + h];
18263     while (sym_index != 0) {
18264         sym = &((Elf32_Sym *)s->data)[sym_index];
18265         name1 = s->link->data + sym->st_name;
18266         if (!strcmp(name, name1))
18267             return sym_index;
18268         sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
18269     }
18270     return 0;
18271 }
18272
18273 /* return elf symbol value or error */
18274 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
18275 {
18276     int sym_index;
18277     Elf32_Sym *sym;
18278     
18279     sym_index = find_elf_sym(symtab_section, name);
18280     if (!sym_index)
18281         return -1;
18282     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18283     *pval = sym->st_value;
18284     return 0;
18285 }
18286
18287 void *tcc_get_symbol_err(TCCState *s, const char *name)
18288 {
18289     unsigned long val;
18290     if (tcc_get_symbol(s, &val, name) < 0)
18291         error("%s not defined", name);
18292     return (void *)val;
18293 }
18294
18295 /* add an elf symbol : check if it is already defined and patch
18296    it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
18297 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
18298                        int info, int other, int sh_num, const char *name)
18299 {
18300     Elf32_Sym *esym;
18301     int sym_bind, sym_index, sym_type, esym_bind;
18302
18303     sym_bind = ELF32_ST_BIND(info);
18304     sym_type = ELF32_ST_TYPE(info);
18305         
18306     if (sym_bind != STB_LOCAL) {
18307         /* we search global or weak symbols */
18308         sym_index = find_elf_sym(s, name);
18309         if (!sym_index)
18310             goto do_def;
18311         esym = &((Elf32_Sym *)s->data)[sym_index];
18312         if (esym->st_shndx != SHN_UNDEF) {
18313             esym_bind = ELF32_ST_BIND(esym->st_info);
18314             if (sh_num == SHN_UNDEF) {
18315                 /* ignore adding of undefined symbol if the
18316                    corresponding symbol is already defined */
18317             } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
18318                 /* global overrides weak, so patch */
18319                 goto do_patch;
18320             } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
18321                 /* weak is ignored if already global */
18322             } else {
18323 #if 0
18324                 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
18325                        sym_bind, sh_num, esym_bind, esym->st_shndx);
18326 #endif
18327                 /* NOTE: we accept that two DLL define the same symbol */
18328                 if (s != tcc_state->dynsymtab_section)
18329                     error_noabort("'%s' defined twice", name);
18330             }
18331         } else {
18332         do_patch:
18333             esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
18334             esym->st_shndx = sh_num;
18335             esym->st_value = value;
18336             esym->st_size = size;
18337             esym->st_other = other;
18338         }
18339     } else {
18340     do_def:
18341         sym_index = put_elf_sym(s, value, size, 
18342                                 ELF32_ST_INFO(sym_bind, sym_type), other, 
18343                                 sh_num, name);
18344     }
18345     return sym_index;
18346 }
18347
18348 /* put relocation */
18349 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
18350                           int type, int symbol)
18351 {
18352     char buf[256];
18353     Section *sr;
18354     Elf32_Rel *rel;
18355
18356     sr = s->reloc;
18357     if (!sr) {
18358         /* if no relocation section, create it */
18359         snprintf(buf, sizeof(buf), ".rel%s", s->name);
18360         /* if the symtab is allocated, then we consider the relocation
18361            are also */
18362         sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
18363         sr->sh_entsize = sizeof(Elf32_Rel);
18364         sr->link = symtab;
18365         sr->sh_info = s->sh_num;
18366         s->reloc = sr;
18367     }
18368     rel = section_ptr_add(sr, sizeof(Elf32_Rel));
18369     rel->r_offset = offset;
18370     rel->r_info = ELF32_R_INFO(symbol, type);
18371 }
18372
18373 /* put stab debug information */
18374
18375 typedef struct {
18376     unsigned long n_strx;         /* index into string table of name */
18377     unsigned char n_type;         /* type of symbol */
18378     unsigned char n_other;        /* misc info (usually empty) */
18379     unsigned short n_desc;        /* description field */
18380     unsigned long n_value;        /* value of symbol */
18381 } Stab_Sym;
18382
18383 static void put_stabs(const char *str, int type, int other, int desc, 
18384                       unsigned long value)
18385 {
18386     Stab_Sym *sym;
18387
18388     sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
18389     if (str) {
18390         sym->n_strx = put_elf_str(stabstr_section, str);
18391     } else {
18392         sym->n_strx = 0;
18393     }
18394     sym->n_type = type;
18395     sym->n_other = other;
18396     sym->n_desc = desc;
18397     sym->n_value = value;
18398 }
18399
18400 static void put_stabs_r(const char *str, int type, int other, int desc, 
18401                         unsigned long value, Section *sec, int sym_index)
18402 {
18403     put_stabs(str, type, other, desc, value);
18404     put_elf_reloc(symtab_section, stab_section, 
18405                   stab_section->data_offset - sizeof(unsigned long),
18406                   R_DATA_32, sym_index);
18407 }
18408
18409 static void put_stabn(int type, int other, int desc, int value)
18410 {
18411     put_stabs(NULL, type, other, desc, value);
18412 }
18413
18414 static void put_stabd(int type, int other, int desc)
18415 {
18416     put_stabs(NULL, type, other, desc, 0);
18417 }
18418
18419 /* In an ELF file symbol table, the local symbols must appear below
18420    the global and weak ones. Since TCC cannot sort it while generating
18421    the code, we must do it after. All the relocation tables are also
18422    modified to take into account the symbol table sorting */
18423 static void sort_syms(TCCState *s1, Section *s)
18424 {
18425     int *old_to_new_syms;
18426     Elf32_Sym *new_syms;
18427     int nb_syms, i;
18428     Elf32_Sym *p, *q;
18429     Elf32_Rel *rel, *rel_end;
18430     Section *sr;
18431     int type, sym_index;
18432
18433     nb_syms = s->data_offset / sizeof(Elf32_Sym);
18434     new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
18435     old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
18436
18437     /* first pass for local symbols */
18438     p = (Elf32_Sym *)s->data;
18439     q = new_syms;
18440     for(i = 0; i < nb_syms; i++) {
18441         if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
18442             old_to_new_syms[i] = q - new_syms;
18443             *q++ = *p;
18444         }
18445         p++;
18446     }
18447     /* save the number of local symbols in section header */
18448     s->sh_info = q - new_syms;
18449
18450     /* then second pass for non local symbols */
18451     p = (Elf32_Sym *)s->data;
18452     for(i = 0; i < nb_syms; i++) {
18453         if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
18454             old_to_new_syms[i] = q - new_syms;
18455             *q++ = *p;
18456         }
18457         p++;
18458     }
18459     
18460     /* we copy the new symbols to the old */
18461     memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
18462     tcc_free(new_syms);
18463
18464     /* now we modify all the relocations */
18465     for(i = 1; i < s1->nb_sections; i++) {
18466         sr = s1->sections[i];
18467         if (sr->sh_type == SHT_REL && sr->link == s) {
18468             rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18469             for(rel = (Elf32_Rel *)sr->data;
18470                 rel < rel_end;
18471                 rel++) {
18472                 sym_index = ELF32_R_SYM(rel->r_info);
18473                 type = ELF32_R_TYPE(rel->r_info);
18474                 sym_index = old_to_new_syms[sym_index];
18475                 rel->r_info = ELF32_R_INFO(sym_index, type);
18476             }
18477         }
18478     }
18479     
18480     tcc_free(old_to_new_syms);
18481 }
18482
18483 /* relocate common symbols in the .bss section */
18484 static void relocate_common_syms(void)
18485 {
18486     Elf32_Sym *sym, *sym_end;
18487     unsigned long offset, align;
18488     
18489     sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18490     for(sym = (Elf32_Sym *)symtab_section->data + 1; 
18491         sym < sym_end;
18492         sym++) {
18493         if (sym->st_shndx == SHN_COMMON) {
18494             /* align symbol */
18495             align = sym->st_value;
18496             offset = bss_section->data_offset;
18497             offset = (offset + align - 1) & -align;
18498             sym->st_value = offset;
18499             sym->st_shndx = bss_section->sh_num;
18500             offset += sym->st_size;
18501             bss_section->data_offset = offset;
18502         }
18503     }
18504 }
18505
18506 /* relocate symbol table, resolve undefined symbols if do_resolve is
18507    true and output error if undefined symbol. */
18508 static void relocate_syms(TCCState *s1, int do_resolve)
18509 {
18510     Elf32_Sym *sym, *esym, *sym_end;
18511     int sym_bind, sh_num, sym_index;
18512     const char *name;
18513     unsigned long addr;
18514
18515     sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18516     for(sym = (Elf32_Sym *)symtab_section->data + 1; 
18517         sym < sym_end;
18518         sym++) {
18519         sh_num = sym->st_shndx;
18520         if (sh_num == SHN_UNDEF) {
18521             name = strtab_section->data + sym->st_name;
18522             if (do_resolve) {
18523                 name = symtab_section->link->data + sym->st_name;
18524                 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
18525                 if (addr) {
18526                     sym->st_value = addr;
18527                     goto found;
18528                 }
18529             } else if (s1->dynsym) {
18530                 /* if dynamic symbol exist, then use it */
18531                 sym_index = find_elf_sym(s1->dynsym, name);
18532                 if (sym_index) {
18533                     esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
18534                     sym->st_value = esym->st_value;
18535                     goto found;
18536                 }
18537             }
18538             /* XXX: _fp_hw seems to be part of the ABI, so we ignore
18539                it */
18540             if (!strcmp(name, "_fp_hw"))
18541                 goto found;
18542             /* only weak symbols are accepted to be undefined. Their
18543                value is zero */
18544             sym_bind = ELF32_ST_BIND(sym->st_info);
18545             if (sym_bind == STB_WEAK) {
18546                 sym->st_value = 0;
18547             } else {
18548                 error_noabort("undefined symbol '%s'", name);
18549             }
18550         } else if (sh_num < SHN_LORESERVE) {
18551             /* add section base */
18552             sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
18553         }
18554     found: ;
18555     }
18556 }
18557
18558 /* relocate a given section (CPU dependent) */
18559 static void relocate_section(TCCState *s1, Section *s)
18560 {
18561     Section *sr;
18562     Elf32_Rel *rel, *rel_end, *qrel;
18563     Elf32_Sym *sym;
18564     int type, sym_index;
18565     unsigned char *ptr;
18566     unsigned long val, addr;
18567 #if defined(TCC_TARGET_I386)
18568     int esym_index;
18569 #endif
18570
18571     sr = s->reloc;
18572     rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18573     qrel = (Elf32_Rel *)sr->data;
18574     for(rel = qrel;
18575         rel < rel_end;
18576         rel++) {
18577         ptr = s->data + rel->r_offset;
18578
18579         sym_index = ELF32_R_SYM(rel->r_info);
18580         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18581         val = sym->st_value;
18582         type = ELF32_R_TYPE(rel->r_info);
18583         addr = s->sh_addr + rel->r_offset;
18584
18585         /* CPU specific */
18586         switch(type) {
18587 #if defined(TCC_TARGET_I386)
18588         case R_386_32:
18589             if (s1->output_type == TCC_OUTPUT_DLL) {
18590                 esym_index = s1->symtab_to_dynsym[sym_index];
18591                 qrel->r_offset = rel->r_offset;
18592                 if (esym_index) {
18593                     qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
18594                     qrel++;
18595                     break;
18596                 } else {
18597                     qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
18598                     qrel++;
18599                 }
18600             }
18601             *(int *)ptr += val;
18602             break;
18603         case R_386_PC32:
18604             if (s1->output_type == TCC_OUTPUT_DLL) {
18605                 /* DLL relocation */
18606                 esym_index = s1->symtab_to_dynsym[sym_index];
18607                 if (esym_index) {
18608                     qrel->r_offset = rel->r_offset;
18609                     qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
18610                     qrel++;
18611                     break;
18612                 }
18613             }
18614             *(int *)ptr += val - addr;
18615             break;
18616         case R_386_PLT32:
18617             *(int *)ptr += val - addr;
18618             break;
18619         case R_386_GLOB_DAT:
18620         case R_386_JMP_SLOT:
18621             *(int *)ptr = val;
18622             break;
18623         case R_386_GOTPC:
18624             *(int *)ptr += s1->got->sh_addr - addr;
18625             break;
18626         case R_386_GOTOFF:
18627             *(int *)ptr += val - s1->got->sh_addr;
18628             break;
18629         case R_386_GOT32:
18630             /* we load the got offset */
18631             *(int *)ptr += s1->got_offsets[sym_index];
18632             break;
18633 #elif defined(TCC_TARGET_ARM)
18634         case R_ARM_PC24:
18635         case R_ARM_PLT32:
18636             {
18637                 int x;
18638                 x = (*(int *)ptr)&0xffffff;
18639                 (*(int *)ptr) &= 0xff000000;
18640                 if (x & 0x800000)
18641                     x -= 0x1000000;
18642                 x *= 4;
18643                 x += val - addr;
18644                 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
18645                     error("can't relocate value at %x",addr);
18646                 x >>= 2;
18647                 x &= 0xffffff;
18648                 (*(int *)ptr) |= x;
18649             }
18650             break;
18651         case R_ARM_ABS32:
18652             *(int *)ptr += val;
18653             break;
18654         case R_ARM_GOTPC:
18655             *(int *)ptr += s1->got->sh_addr - addr;
18656             break;
18657         case R_ARM_GOT32:
18658             /* we load the got offset */
18659             *(int *)ptr += s1->got_offsets[sym_index];
18660             break;
18661         case R_ARM_COPY:
18662             break;
18663         default:
18664             fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18665                     type,addr,(unsigned int )ptr,val);
18666             break;
18667 #elif defined(TCC_TARGET_C67)
18668         case R_C60_32:
18669             *(int *)ptr += val;
18670             break;
18671         case R_C60LO16:
18672             {
18673                 uint32_t orig;
18674                 
18675                 /* put the low 16 bits of the absolute address */
18676                 // add to what is already there
18677                 
18678                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
18679                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
18680                 
18681                 //patch both at once - assumes always in pairs Low - High
18682                 
18683                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
18684                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
18685             }
18686             break;
18687         case R_C60HI16:
18688             break;
18689         default:
18690             fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18691                     type,addr,(unsigned int )ptr,val);
18692             break;
18693 #else
18694 #error unsupported processor
18695 #endif
18696         }
18697     }
18698     /* if the relocation is allocated, we change its symbol table */
18699     if (sr->sh_flags & SHF_ALLOC)
18700         sr->link = s1->dynsym;
18701 }
18702
18703 /* relocate relocation table in 'sr' */
18704 static void relocate_rel(TCCState *s1, Section *sr)
18705 {
18706     Section *s;
18707     Elf32_Rel *rel, *rel_end;
18708     
18709     s = s1->sections[sr->sh_info];
18710     rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18711     for(rel = (Elf32_Rel *)sr->data;
18712         rel < rel_end;
18713         rel++) {
18714         rel->r_offset += s->sh_addr;
18715     }
18716 }
18717
18718 /* count the number of dynamic relocations so that we can reserve
18719    their space */
18720 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
18721 {
18722     Elf32_Rel *rel, *rel_end;
18723     int sym_index, esym_index, type, count;
18724
18725     count = 0;
18726     rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18727     for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
18728         sym_index = ELF32_R_SYM(rel->r_info);
18729         type = ELF32_R_TYPE(rel->r_info);
18730         switch(type) {
18731         case R_386_32:
18732             count++;
18733             break;
18734         case R_386_PC32:
18735             esym_index = s1->symtab_to_dynsym[sym_index];
18736             if (esym_index)
18737                 count++;
18738             break;
18739         default:
18740             break;
18741         }
18742     }
18743     if (count) {
18744         /* allocate the section */
18745         sr->sh_flags |= SHF_ALLOC;
18746         sr->sh_size = count * sizeof(Elf32_Rel);
18747     }
18748     return count;
18749 }
18750
18751 static void put_got_offset(TCCState *s1, int index, unsigned long val)
18752 {
18753     int n;
18754     unsigned long *tab;
18755
18756     if (index >= s1->nb_got_offsets) {
18757         /* find immediately bigger power of 2 and reallocate array */
18758         n = 1;
18759         while (index >= n)
18760             n *= 2;
18761         tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
18762         if (!tab)
18763             error("memory full");
18764         s1->got_offsets = tab;
18765         memset(s1->got_offsets + s1->nb_got_offsets, 0,
18766                (n - s1->nb_got_offsets) * sizeof(unsigned long));
18767         s1->nb_got_offsets = n;
18768     }
18769     s1->got_offsets[index] = val;
18770 }
18771
18772 /* XXX: suppress that */
18773 static void put32(unsigned char *p, uint32_t val)
18774 {
18775     p[0] = val;
18776     p[1] = val >> 8;
18777     p[2] = val >> 16;
18778     p[3] = val >> 24;
18779 }
18780
18781 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
18782 static uint32_t get32(unsigned char *p)
18783 {
18784     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
18785 }
18786 #endif
18787
18788 static void build_got(TCCState *s1)
18789 {
18790     unsigned char *ptr;
18791
18792     /* if no got, then create it */
18793     s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
18794     s1->got->sh_entsize = 4;
18795     add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), 
18796                 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
18797     ptr = section_ptr_add(s1->got, 3 * sizeof(int));
18798     /* keep space for _DYNAMIC pointer, if present */
18799     put32(ptr, 0);
18800     /* two dummy got entries */
18801     put32(ptr + 4, 0);
18802     put32(ptr + 8, 0);
18803 }
18804
18805 /* put a got entry corresponding to a symbol in symtab_section. 'size'
18806    and 'info' can be modifed if more precise info comes from the DLL */
18807 static void put_got_entry(TCCState *s1,
18808                           int reloc_type, unsigned long size, int info, 
18809                           int sym_index)
18810 {
18811     int index;
18812     const char *name;
18813     Elf32_Sym *sym;
18814     unsigned long offset;
18815     int *ptr;
18816
18817     if (!s1->got)
18818         build_got(s1);
18819
18820     /* if a got entry already exists for that symbol, no need to add one */
18821     if (sym_index < s1->nb_got_offsets &&
18822         s1->got_offsets[sym_index] != 0)
18823         return;
18824     
18825     put_got_offset(s1, sym_index, s1->got->data_offset);
18826
18827     if (s1->dynsym) {
18828         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18829         name = symtab_section->link->data + sym->st_name;
18830         offset = sym->st_value;
18831 #ifdef TCC_TARGET_I386
18832         if (reloc_type == R_386_JMP_SLOT) {
18833             Section *plt;
18834             uint8_t *p;
18835             int modrm;
18836
18837             /* if we build a DLL, we add a %ebx offset */
18838             if (s1->output_type == TCC_OUTPUT_DLL)
18839                 modrm = 0xa3;
18840             else
18841                 modrm = 0x25;
18842
18843             /* add a PLT entry */
18844             plt = s1->plt;
18845             if (plt->data_offset == 0) {
18846                 /* first plt entry */
18847                 p = section_ptr_add(plt, 16);
18848                 p[0] = 0xff; /* pushl got + 4 */
18849                 p[1] = modrm + 0x10;
18850                 put32(p + 2, 4);
18851                 p[6] = 0xff; /* jmp *(got + 8) */
18852                 p[7] = modrm;
18853                 put32(p + 8, 8);
18854             }
18855
18856             p = section_ptr_add(plt, 16);
18857             p[0] = 0xff; /* jmp *(got + x) */
18858             p[1] = modrm;
18859             put32(p + 2, s1->got->data_offset);
18860             p[6] = 0x68; /* push $xxx */
18861             put32(p + 7, (plt->data_offset - 32) >> 1);
18862             p[11] = 0xe9; /* jmp plt_start */
18863             put32(p + 12, -(plt->data_offset));
18864
18865             /* the symbol is modified so that it will be relocated to
18866                the PLT */
18867             if (s1->output_type == TCC_OUTPUT_EXE)
18868                 offset = plt->data_offset - 16;
18869         }
18870 #elif defined(TCC_TARGET_ARM)
18871         if (reloc_type == R_ARM_JUMP_SLOT) {
18872             Section *plt;
18873             uint8_t *p;
18874             
18875             /* if we build a DLL, we add a %ebx offset */
18876             if (s1->output_type == TCC_OUTPUT_DLL)
18877                 error("DLLs unimplemented!");
18878
18879             /* add a PLT entry */
18880             plt = s1->plt;
18881             if (plt->data_offset == 0) {
18882                 /* first plt entry */
18883                 p = section_ptr_add(plt, 16);
18884                 put32(p     , 0xe52de004);
18885                 put32(p +  4, 0xe59fe010);
18886                 put32(p +  8, 0xe08fe00e);
18887                 put32(p + 12, 0xe5bef008);
18888             }
18889
18890             p = section_ptr_add(plt, 16);
18891             put32(p  , 0xe59fc004);
18892             put32(p+4, 0xe08fc00c);
18893             put32(p+8, 0xe59cf000);
18894             put32(p+12, s1->got->data_offset);
18895
18896             /* the symbol is modified so that it will be relocated to
18897                the PLT */
18898             if (s1->output_type == TCC_OUTPUT_EXE)
18899                 offset = plt->data_offset - 16;
18900         }
18901 #elif defined(TCC_TARGET_C67)
18902         error("C67 got not implemented");
18903 #else
18904 #error unsupported CPU
18905 #endif
18906         index = put_elf_sym(s1->dynsym, offset, 
18907                             size, info, 0, sym->st_shndx, name);
18908         /* put a got entry */
18909         put_elf_reloc(s1->dynsym, s1->got, 
18910                       s1->got->data_offset, 
18911                       reloc_type, index);
18912     }
18913     ptr = section_ptr_add(s1->got, sizeof(int));
18914     *ptr = 0;
18915 }
18916
18917 /* build GOT and PLT entries */
18918 static void build_got_entries(TCCState *s1)
18919 {
18920     Section *s, *symtab __attribute__((unused));
18921     Elf32_Rel *rel, *rel_end;
18922     Elf32_Sym *sym;
18923     int i, type, reloc_type, sym_index;
18924
18925     for(i = 1; i < s1->nb_sections; i++) {
18926         s = s1->sections[i];
18927         if (s->sh_type != SHT_REL)
18928             continue;
18929         /* no need to handle got relocations */
18930         if (s->link != symtab_section)
18931             continue;
18932         symtab = s->link;
18933         rel_end = (Elf32_Rel *)(s->data + s->data_offset);
18934         for(rel = (Elf32_Rel *)s->data;
18935             rel < rel_end;
18936             rel++) {
18937             type = ELF32_R_TYPE(rel->r_info);
18938             switch(type) {
18939 #if defined(TCC_TARGET_I386)
18940             case R_386_GOT32:
18941             case R_386_GOTOFF:
18942             case R_386_GOTPC:
18943             case R_386_PLT32:
18944                 if (!s1->got)
18945                     build_got(s1);
18946                 if (type == R_386_GOT32 || type == R_386_PLT32) {
18947                     sym_index = ELF32_R_SYM(rel->r_info);
18948                     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18949                     /* look at the symbol got offset. If none, then add one */
18950                     if (type == R_386_GOT32)
18951                         reloc_type = R_386_GLOB_DAT;
18952                     else
18953                         reloc_type = R_386_JMP_SLOT;
18954                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
18955                                   sym_index);
18956                 }
18957                 break;
18958 #elif defined(TCC_TARGET_ARM)
18959             case R_ARM_GOT32:
18960             case R_ARM_GOTOFF:
18961             case R_ARM_GOTPC:
18962             case R_ARM_PLT32:
18963                 if (!s1->got)
18964                     build_got(s1);
18965                 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
18966                     sym_index = ELF32_R_SYM(rel->r_info);
18967                     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18968                     /* look at the symbol got offset. If none, then add one */
18969                     if (type == R_ARM_GOT32)
18970                         reloc_type = R_ARM_GLOB_DAT;
18971                     else
18972                         reloc_type = R_ARM_JUMP_SLOT;
18973                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
18974                                   sym_index);
18975                 }
18976                 break;
18977 #elif defined(TCC_TARGET_C67)
18978             case R_C60_GOT32:
18979             case R_C60_GOTOFF:
18980             case R_C60_GOTPC:
18981             case R_C60_PLT32:
18982                 if (!s1->got)
18983                     build_got(s1);
18984                 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
18985                     sym_index = ELF32_R_SYM(rel->r_info);
18986                     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18987                     /* look at the symbol got offset. If none, then add one */
18988                     if (type == R_C60_GOT32)
18989                         reloc_type = R_C60_GLOB_DAT;
18990                     else
18991                         reloc_type = R_C60_JMP_SLOT;
18992                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
18993                                   sym_index);
18994                 }
18995                 break;
18996 #else
18997 #error unsupported CPU
18998 #endif
18999             default:
19000                 break;
19001             }
19002         }
19003     }
19004 }
19005
19006 static Section *new_symtab(TCCState *s1,
19007                            const char *symtab_name, int sh_type, int sh_flags,
19008                            const char *strtab_name, 
19009                            const char *hash_name, int hash_sh_flags)
19010 {
19011     Section *symtab, *strtab, *hash;
19012     int *ptr, nb_buckets;
19013
19014     symtab = new_section(s1, symtab_name, sh_type, sh_flags);
19015     symtab->sh_entsize = sizeof(Elf32_Sym);
19016     strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
19017     put_elf_str(strtab, "");
19018     symtab->link = strtab;
19019     put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
19020     
19021     nb_buckets = 1;
19022
19023     hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
19024     hash->sh_entsize = sizeof(int);
19025     symtab->hash = hash;
19026     hash->link = symtab;
19027
19028     ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
19029     ptr[0] = nb_buckets;
19030     ptr[1] = 1;
19031     memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
19032     return symtab;
19033 }
19034
19035 /* put dynamic tag */
19036 static void put_dt(Section *dynamic, int dt, unsigned long val)
19037 {
19038     Elf32_Dyn *dyn;
19039     dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
19040     dyn->d_tag = dt;
19041     dyn->d_un.d_val = val;
19042 }
19043
19044 static void add_init_array_defines(TCCState *s1, const char *section_name)
19045 {
19046     Section *s;
19047     long end_offset;
19048     char sym_start[1024];
19049     char sym_end[1024];
19050     
19051     snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
19052     snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
19053
19054     s = find_section(s1, section_name);
19055     if (!s) {
19056         end_offset = 0;
19057         s = data_section;
19058     } else {
19059         end_offset = s->data_offset;
19060     }
19061
19062     add_elf_sym(symtab_section, 
19063                 0, 0,
19064                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19065                 s->sh_num, sym_start);
19066     add_elf_sym(symtab_section, 
19067                 end_offset, 0,
19068                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19069                 s->sh_num, sym_end);
19070 }
19071
19072 /* add tcc runtime libraries */
19073 static void tcc_add_runtime(TCCState *s1)
19074 {
19075     char buf[1024];
19076
19077 #ifdef CONFIG_TCC_BCHECK
19078     if (do_bounds_check) {
19079         unsigned long *ptr;
19080         Section *init_section;
19081         unsigned char *pinit;
19082         int sym_index;
19083
19084         /* XXX: add an object file to do that */
19085         ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
19086         *ptr = 0;
19087         add_elf_sym(symtab_section, 0, 0, 
19088                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19089                     bounds_section->sh_num, "__bounds_start");
19090         /* add bound check code */
19091         snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
19092         tcc_add_file(s1, buf);
19093 #ifdef TCC_TARGET_I386
19094         if (s1->output_type != TCC_OUTPUT_MEMORY) {
19095             /* add 'call __bound_init()' in .init section */
19096             init_section = find_section(s1, ".init");
19097             pinit = section_ptr_add(init_section, 5);
19098             pinit[0] = 0xe8;
19099             put32(pinit + 1, -4);
19100             sym_index = find_elf_sym(symtab_section, "__bound_init");
19101             put_elf_reloc(symtab_section, init_section, 
19102                           init_section->data_offset - 4, R_386_PC32, sym_index);
19103         }
19104 #endif
19105     }
19106 #endif
19107     /* add libc */
19108     if (!s1->nostdlib) {
19109         tcc_add_library(s1, "c");
19110
19111         snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
19112         tcc_add_file(s1, buf);
19113     }
19114     /* add crt end if not memory output */
19115     if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
19116         tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
19117     }
19118 }
19119
19120 /* add various standard linker symbols (must be done after the
19121    sections are filled (for example after allocating common
19122    symbols)) */
19123 static void tcc_add_linker_symbols(TCCState *s1)
19124 {
19125     char buf[1024];
19126     int i;
19127     Section *s;
19128
19129     add_elf_sym(symtab_section, 
19130                 text_section->data_offset, 0,
19131                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19132                 text_section->sh_num, "_etext");
19133     add_elf_sym(symtab_section, 
19134                 data_section->data_offset, 0,
19135                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19136                 data_section->sh_num, "_edata");
19137     add_elf_sym(symtab_section, 
19138                 bss_section->data_offset, 0,
19139                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19140                 bss_section->sh_num, "_end");
19141     /* horrible new standard ldscript defines */
19142     add_init_array_defines(s1, ".preinit_array");
19143     add_init_array_defines(s1, ".init_array");
19144     add_init_array_defines(s1, ".fini_array");
19145     
19146     /* add start and stop symbols for sections whose name can be
19147        expressed in C */
19148     for(i = 1; i < s1->nb_sections; i++) {
19149         s = s1->sections[i];
19150         if (s->sh_type == SHT_PROGBITS &&
19151             (s->sh_flags & SHF_ALLOC)) {
19152             const char *p;
19153             int ch;
19154
19155             /* check if section name can be expressed in C */
19156             p = s->name;
19157             for(;;) {
19158                 ch = *p;
19159                 if (!ch)
19160                     break;
19161                 if (!isid(ch) && !isnum(ch))
19162                     goto next_sec;
19163                 p++;
19164             }
19165             snprintf(buf, sizeof(buf), "__start_%s", s->name);
19166             add_elf_sym(symtab_section, 
19167                         0, 0,
19168                         ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19169                         s->sh_num, buf);
19170             snprintf(buf, sizeof(buf), "__stop_%s", s->name);
19171             add_elf_sym(symtab_section,
19172                         s->data_offset, 0,
19173                         ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19174                         s->sh_num, buf);
19175         }
19176     next_sec: ;
19177     }
19178 }
19179
19180 /* name of ELF interpreter */
19181 #ifdef __FreeBSD__
19182 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
19183 #else
19184 static char elf_interp[] = "/lib/ld-linux.so.2";
19185 #endif
19186
19187 static void tcc_output_binary(TCCState *s1, FILE *f,
19188                               const int *section_order)
19189 {
19190     Section *s;
19191     int i, offset, size;
19192
19193     offset = 0;
19194     for(i=1;i<s1->nb_sections;i++) {
19195         s = s1->sections[section_order[i]];
19196         if (s->sh_type != SHT_NOBITS &&
19197             (s->sh_flags & SHF_ALLOC)) {
19198             while (offset < s->sh_offset) {
19199                 fputc(0, f);
19200                 offset++;
19201             }
19202             size = s->sh_size;
19203             dummy_size_t = fwrite(s->data, 1, size, f);
19204             offset += size;
19205         }
19206     }
19207 }
19208
19209 /* output an ELF file */
19210 /* XXX: suppress unneeded sections */
19211 int tcc_output_file(TCCState *s1, const char *filename)
19212 {
19213     Elf32_Ehdr ehdr;
19214     FILE *f;
19215     int fd, mode, ret;
19216     int *section_order;
19217     int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
19218     unsigned long addr;
19219     Section *strsec, *s;
19220     Elf32_Shdr shdr, *sh;
19221     Elf32_Phdr *phdr, *ph;
19222     Section *interp, *dynamic, *dynstr;
19223     unsigned long saved_dynamic_data_offset;
19224     Elf32_Sym *sym;
19225     int type, file_type;
19226     unsigned long rel_addr, rel_size;
19227     
19228     file_type = s1->output_type;
19229     s1->nb_errors = 0;
19230
19231     if (file_type != TCC_OUTPUT_OBJ) {
19232         tcc_add_runtime(s1);
19233     }
19234
19235     phdr = NULL;
19236     section_order = NULL;
19237     interp = NULL;
19238     dynamic = NULL;
19239     dynstr = NULL; /* avoid warning */
19240     saved_dynamic_data_offset = 0; /* avoid warning */
19241     
19242     if (file_type != TCC_OUTPUT_OBJ) {
19243         relocate_common_syms();
19244
19245         tcc_add_linker_symbols(s1);
19246
19247         if (!s1->static_link) {
19248             const char *name;
19249             int sym_index, index;
19250             Elf32_Sym *esym, *sym_end;
19251             
19252             if (file_type == TCC_OUTPUT_EXE) {
19253                 char *ptr;
19254                 /* add interpreter section only if executable */
19255                 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
19256                 interp->sh_addralign = 1;
19257                 ptr = section_ptr_add(interp, sizeof(elf_interp));
19258                 strcpy(ptr, elf_interp);
19259             }
19260         
19261             /* add dynamic symbol table */
19262             s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
19263                                     ".dynstr", 
19264                                     ".hash", SHF_ALLOC);
19265             dynstr = s1->dynsym->link;
19266             
19267             /* add dynamic section */
19268             dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 
19269                                   SHF_ALLOC | SHF_WRITE);
19270             dynamic->link = dynstr;
19271             dynamic->sh_entsize = sizeof(Elf32_Dyn);
19272         
19273             /* add PLT */
19274             s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 
19275                                   SHF_ALLOC | SHF_EXECINSTR);
19276             s1->plt->sh_entsize = 4;
19277
19278             build_got(s1);
19279
19280             /* scan for undefined symbols and see if they are in the
19281                dynamic symbols. If a symbol STT_FUNC is found, then we
19282                add it in the PLT. If a symbol STT_OBJECT is found, we
19283                add it in the .bss section with a suitable relocation */
19284             sym_end = (Elf32_Sym *)(symtab_section->data + 
19285                                     symtab_section->data_offset);
19286             if (file_type == TCC_OUTPUT_EXE) {
19287                 for(sym = (Elf32_Sym *)symtab_section->data + 1; 
19288                     sym < sym_end;
19289                     sym++) {
19290                     if (sym->st_shndx == SHN_UNDEF) {
19291                         name = symtab_section->link->data + sym->st_name;
19292                         sym_index = find_elf_sym(s1->dynsymtab_section, name);
19293                         if (sym_index) {
19294                             esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
19295                             type = ELF32_ST_TYPE(esym->st_info);
19296                             if (type == STT_FUNC) {
19297                                 put_got_entry(s1, R_JMP_SLOT, esym->st_size, 
19298                                               esym->st_info, 
19299                                               sym - (Elf32_Sym *)symtab_section->data);
19300                             } else if (type == STT_OBJECT) {
19301                                 unsigned long offset;
19302                                 offset = bss_section->data_offset;
19303                                 /* XXX: which alignment ? */
19304                                 offset = (offset + 16 - 1) & -16;
19305                                 index = put_elf_sym(s1->dynsym, offset, esym->st_size, 
19306                                                     esym->st_info, 0, 
19307                                                     bss_section->sh_num, name);
19308                                 put_elf_reloc(s1->dynsym, bss_section, 
19309                                               offset, R_COPY, index);
19310                                 offset += esym->st_size;
19311                                 bss_section->data_offset = offset;
19312                             }
19313                         } else {
19314                                 /* STB_WEAK undefined symbols are accepted */
19315                                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
19316                                    it */
19317                             if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
19318                                 !strcmp(name, "_fp_hw")) {
19319                             } else {
19320                                 error_noabort("undefined symbol '%s'", name);
19321                             }
19322                         }
19323                     } else if (s1->rdynamic && 
19324                                ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19325                         /* if -rdynamic option, then export all non
19326                            local symbols */
19327                         name = symtab_section->link->data + sym->st_name;
19328                         put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
19329                                     sym->st_info, 0, 
19330                                     sym->st_shndx, name);
19331                     }
19332                 }
19333             
19334                 if (s1->nb_errors)
19335                     goto fail;
19336
19337                 /* now look at unresolved dynamic symbols and export
19338                    corresponding symbol */
19339                 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data + 
19340                                         s1->dynsymtab_section->data_offset);
19341                 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1; 
19342                     esym < sym_end;
19343                     esym++) {
19344                     if (esym->st_shndx == SHN_UNDEF) {
19345                         name = s1->dynsymtab_section->link->data + esym->st_name;
19346                         sym_index = find_elf_sym(symtab_section, name);
19347                         if (sym_index) {
19348                             /* XXX: avoid adding a symbol if already
19349                                present because of -rdynamic ? */
19350                             sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
19351                             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
19352                                         sym->st_info, 0, 
19353                                         sym->st_shndx, name);
19354                         } else {
19355                             if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
19356                                 /* weak symbols can stay undefined */
19357                             } else {
19358                                 warning("undefined dynamic symbol '%s'", name);
19359                             }
19360                         }
19361                     }
19362                 }
19363             } else {
19364                 int nb_syms;
19365                 /* shared library case : we simply export all the global symbols */
19366                 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
19367                 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
19368                 for(sym = (Elf32_Sym *)symtab_section->data + 1; 
19369                     sym < sym_end;
19370                     sym++) {
19371                     if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19372                         name = symtab_section->link->data + sym->st_name;
19373                         index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
19374                                             sym->st_info, 0, 
19375                                             sym->st_shndx, name);
19376                         s1->symtab_to_dynsym[sym - 
19377                                             (Elf32_Sym *)symtab_section->data] = 
19378                             index;
19379                     }
19380                 }
19381             }
19382
19383             build_got_entries(s1);
19384         
19385             /* add a list of needed dlls */
19386             for(i = 0; i < s1->nb_loaded_dlls; i++) {
19387                 DLLReference *dllref = s1->loaded_dlls[i];
19388                 if (dllref->level == 0)
19389                     put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
19390             }
19391             /* XXX: currently, since we do not handle PIC code, we
19392                must relocate the readonly segments */
19393             if (file_type == TCC_OUTPUT_DLL)
19394                 put_dt(dynamic, DT_TEXTREL, 0);
19395
19396             /* add necessary space for other entries */
19397             saved_dynamic_data_offset = dynamic->data_offset;
19398             dynamic->data_offset += 8 * 9;
19399         } else {
19400             /* still need to build got entries in case of static link */
19401             build_got_entries(s1);
19402         }
19403     }
19404
19405     memset(&ehdr, 0, sizeof(ehdr));
19406
19407     /* we add a section for symbols */
19408     strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
19409     put_elf_str(strsec, "");
19410     
19411     /* compute number of sections */
19412     shnum = s1->nb_sections;
19413
19414     /* this array is used to reorder sections in the output file */
19415     section_order = tcc_malloc(sizeof(int) * shnum);
19416     section_order[0] = 0;
19417     sh_order_index = 1;
19418     
19419     /* compute number of program headers */
19420     switch(file_type) {
19421     default:
19422     case TCC_OUTPUT_OBJ:
19423         phnum = 0;
19424         break;
19425     case TCC_OUTPUT_EXE:
19426         if (!s1->static_link)
19427             phnum = 4;
19428         else
19429             phnum = 2;
19430         break;
19431     case TCC_OUTPUT_DLL:
19432         phnum = 3;
19433         break;
19434     }
19435
19436     /* allocate strings for section names and decide if an unallocated
19437        section should be output */
19438     /* NOTE: the strsec section comes last, so its size is also
19439        correct ! */
19440     for(i = 1; i < s1->nb_sections; i++) {
19441         s = s1->sections[i];
19442         s->sh_name = put_elf_str(strsec, s->name);
19443         /* when generating a DLL, we include relocations but we may
19444            patch them */
19445         if (file_type == TCC_OUTPUT_DLL && 
19446             s->sh_type == SHT_REL && 
19447             !(s->sh_flags & SHF_ALLOC)) {
19448             prepare_dynamic_rel(s1, s);
19449         } else if (do_debug || 
19450             file_type == TCC_OUTPUT_OBJ || 
19451             (s->sh_flags & SHF_ALLOC) ||
19452             i == (s1->nb_sections - 1)) {
19453             /* we output all sections if debug or object file */
19454             s->sh_size = s->data_offset;
19455         }
19456     }
19457
19458     /* allocate program segment headers */
19459     phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
19460         
19461     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19462         file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19463     } else {
19464         file_offset = 0;
19465     }
19466     if (phnum > 0) {
19467         /* compute section to program header mapping */
19468         if (s1->has_text_addr) { 
19469             int a_offset, p_offset;
19470             addr = s1->text_addr;
19471             /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
19472                ELF_PAGE_SIZE */
19473             a_offset = addr & (ELF_PAGE_SIZE - 1);
19474             p_offset = file_offset & (ELF_PAGE_SIZE - 1);
19475             if (a_offset < p_offset) 
19476                 a_offset += ELF_PAGE_SIZE;
19477             file_offset += (a_offset - p_offset);
19478         } else {
19479             if (file_type == TCC_OUTPUT_DLL)
19480                 addr = 0;
19481             else
19482                 addr = ELF_START_ADDR;
19483             /* compute address after headers */
19484             addr += (file_offset & (ELF_PAGE_SIZE - 1));
19485         }
19486         
19487         /* dynamic relocation table information, for .dynamic section */
19488         rel_size = 0;
19489         rel_addr = 0;
19490
19491         /* leave one program header for the program interpreter */
19492         ph = &phdr[0];
19493         if (interp)
19494             ph++;
19495
19496         for(j = 0; j < 2; j++) {
19497             ph->p_type = PT_LOAD;
19498             if (j == 0)
19499                 ph->p_flags = PF_R | PF_X;
19500             else
19501                 ph->p_flags = PF_R | PF_W;
19502             ph->p_align = ELF_PAGE_SIZE;
19503             
19504             /* we do the following ordering: interp, symbol tables,
19505                relocations, progbits, nobits */
19506             /* XXX: do faster and simpler sorting */
19507             for(k = 0; k < 5; k++) {
19508                 for(i = 1; i < s1->nb_sections; i++) {
19509                     s = s1->sections[i];
19510                     /* compute if section should be included */
19511                     if (j == 0) {
19512                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
19513                             SHF_ALLOC)
19514                             continue;
19515                     } else {
19516                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
19517                             (SHF_ALLOC | SHF_WRITE))
19518                             continue;
19519                     }
19520                     if (s == interp) {
19521                         if (k != 0)
19522                             continue;
19523                     } else if (s->sh_type == SHT_DYNSYM ||
19524                                s->sh_type == SHT_STRTAB ||
19525                                s->sh_type == SHT_HASH) {
19526                         if (k != 1)
19527                             continue;
19528                     } else if (s->sh_type == SHT_REL) {
19529                         if (k != 2)
19530                             continue;
19531                     } else if (s->sh_type == SHT_NOBITS) {
19532                         if (k != 4)
19533                             continue;
19534                     } else {
19535                         if (k != 3)
19536                             continue;
19537                     }
19538                     section_order[sh_order_index++] = i;
19539
19540                     /* section matches: we align it and add its size */
19541                     tmp = addr;
19542                     addr = (addr + s->sh_addralign - 1) & 
19543                         ~(s->sh_addralign - 1);
19544                     file_offset += addr - tmp;
19545                     s->sh_offset = file_offset;
19546                     s->sh_addr = addr;
19547                     
19548                     /* update program header infos */
19549                     if (ph->p_offset == 0) {
19550                         ph->p_offset = file_offset;
19551                         ph->p_vaddr = addr;
19552                         ph->p_paddr = ph->p_vaddr;
19553                     }
19554                     /* update dynamic relocation infos */
19555                     if (s->sh_type == SHT_REL) {
19556                         if (rel_size == 0)
19557                             rel_addr = addr;
19558                         rel_size += s->sh_size;
19559                     }
19560                     addr += s->sh_size;
19561                     if (s->sh_type != SHT_NOBITS)
19562                         file_offset += s->sh_size;
19563                 }
19564             }
19565             ph->p_filesz = file_offset - ph->p_offset;
19566             ph->p_memsz = addr - ph->p_vaddr;
19567             ph++;
19568             if (j == 0) {
19569                 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19570                     /* if in the middle of a page, we duplicate the page in
19571                        memory so that one copy is RX and the other is RW */
19572                     if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
19573                         addr += ELF_PAGE_SIZE;
19574                 } else {
19575                     addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
19576                     file_offset = (file_offset + ELF_PAGE_SIZE - 1) & 
19577                         ~(ELF_PAGE_SIZE - 1);
19578                 }
19579             }
19580         }
19581
19582         /* if interpreter, then add corresponing program header */
19583         if (interp) {
19584             ph = &phdr[0];
19585             
19586             ph->p_type = PT_INTERP;
19587             ph->p_offset = interp->sh_offset;
19588             ph->p_vaddr = interp->sh_addr;
19589             ph->p_paddr = ph->p_vaddr;
19590             ph->p_filesz = interp->sh_size;
19591             ph->p_memsz = interp->sh_size;
19592             ph->p_flags = PF_R;
19593             ph->p_align = interp->sh_addralign;
19594         }
19595         
19596         /* if dynamic section, then add corresponing program header */
19597         if (dynamic) {
19598             Elf32_Sym *sym_end;
19599
19600             ph = &phdr[phnum - 1];
19601             
19602             ph->p_type = PT_DYNAMIC;
19603             ph->p_offset = dynamic->sh_offset;
19604             ph->p_vaddr = dynamic->sh_addr;
19605             ph->p_paddr = ph->p_vaddr;
19606             ph->p_filesz = dynamic->sh_size;
19607             ph->p_memsz = dynamic->sh_size;
19608             ph->p_flags = PF_R | PF_W;
19609             ph->p_align = dynamic->sh_addralign;
19610
19611             /* put GOT dynamic section address */
19612             put32(s1->got->data, dynamic->sh_addr);
19613
19614             /* relocate the PLT */
19615             if (file_type == TCC_OUTPUT_EXE) {
19616                 uint8_t *p, *p_end;
19617
19618                 p = s1->plt->data;
19619                 p_end = p + s1->plt->data_offset;
19620                 if (p < p_end) {
19621 #if defined(TCC_TARGET_I386)
19622                     put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19623                     put32(p + 8, get32(p + 8) + s1->got->sh_addr);
19624                     p += 16;
19625                     while (p < p_end) {
19626                         put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19627                         p += 16;
19628                     }
19629 #elif defined(TCC_TARGET_ARM)
19630                     int x;
19631                     x=s1->got->sh_addr - s1->plt->sh_addr - 12;
19632                     p +=16;
19633                     while (p < p_end) {
19634                         put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
19635                         p += 16;
19636                     }
19637 #elif defined(TCC_TARGET_C67)
19638                     /* XXX: TODO */
19639 #else
19640 #error unsupported CPU
19641 #endif
19642                 }
19643             }
19644
19645             /* relocate symbols in .dynsym */
19646             sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
19647             for(sym = (Elf32_Sym *)s1->dynsym->data + 1; 
19648                 sym < sym_end;
19649                 sym++) {
19650                 if (sym->st_shndx == SHN_UNDEF) {
19651                     /* relocate to the PLT if the symbol corresponds
19652                        to a PLT entry */
19653                     if (sym->st_value)
19654                         sym->st_value += s1->plt->sh_addr;
19655                 } else if (sym->st_shndx < SHN_LORESERVE) {
19656                     /* do symbol relocation */
19657                     sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
19658                 }
19659             }
19660
19661             /* put dynamic section entries */
19662             dynamic->data_offset = saved_dynamic_data_offset;
19663             put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
19664             put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
19665             put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
19666             put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
19667             put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
19668             put_dt(dynamic, DT_REL, rel_addr);
19669             put_dt(dynamic, DT_RELSZ, rel_size);
19670             put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
19671             put_dt(dynamic, DT_NULL, 0);
19672         }
19673
19674         ehdr.e_phentsize = sizeof(Elf32_Phdr);
19675         ehdr.e_phnum = phnum;
19676         ehdr.e_phoff = sizeof(Elf32_Ehdr);
19677     }
19678
19679     /* all other sections come after */
19680     for(i = 1; i < s1->nb_sections; i++) {
19681         s = s1->sections[i];
19682         if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
19683             continue;
19684         section_order[sh_order_index++] = i;
19685         
19686         file_offset = (file_offset + s->sh_addralign - 1) & 
19687             ~(s->sh_addralign - 1);
19688         s->sh_offset = file_offset;
19689         if (s->sh_type != SHT_NOBITS)
19690             file_offset += s->sh_size;
19691     }
19692     
19693     /* if building executable or DLL, then relocate each section
19694        except the GOT which is already relocated */
19695     if (file_type != TCC_OUTPUT_OBJ) {
19696         relocate_syms(s1, 0);
19697
19698         if (s1->nb_errors != 0) {
19699         fail:
19700             ret = -1;
19701             goto the_end;
19702         }
19703
19704         /* relocate sections */
19705         /* XXX: ignore sections with allocated relocations ? */
19706         for(i = 1; i < s1->nb_sections; i++) {
19707             s = s1->sections[i];
19708             if (s->reloc && s != s1->got)
19709                 relocate_section(s1, s);
19710         }
19711
19712         /* relocate relocation entries if the relocation tables are
19713            allocated in the executable */
19714         for(i = 1; i < s1->nb_sections; i++) {
19715             s = s1->sections[i];
19716             if ((s->sh_flags & SHF_ALLOC) &&
19717                 s->sh_type == SHT_REL) {
19718                 relocate_rel(s1, s);
19719             }
19720         }
19721
19722         /* get entry point address */
19723         if (file_type == TCC_OUTPUT_EXE)
19724             ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
19725         else
19726             ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
19727     }
19728
19729     /* write elf file */
19730     if (file_type == TCC_OUTPUT_OBJ)
19731         mode = 0666;
19732     else
19733         mode = 0777;
19734     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
19735     if (fd < 0) {
19736         error_noabort("could not write '%s'", filename);
19737         goto fail;
19738     }
19739     f = fdopen(fd, "wb");
19740
19741 #ifdef TCC_TARGET_COFF
19742     if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
19743         tcc_output_coff(s1, f);
19744     } else
19745 #endif
19746     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19747         sort_syms(s1, symtab_section);
19748         
19749         /* align to 4 */
19750         file_offset = (file_offset + 3) & -4;
19751     
19752         /* fill header */
19753         ehdr.e_ident[0] = ELFMAG0;
19754         ehdr.e_ident[1] = ELFMAG1;
19755         ehdr.e_ident[2] = ELFMAG2;
19756         ehdr.e_ident[3] = ELFMAG3;
19757         ehdr.e_ident[4] = ELFCLASS32;
19758         ehdr.e_ident[5] = ELFDATA2LSB;
19759         ehdr.e_ident[6] = EV_CURRENT;
19760 #ifdef __FreeBSD__
19761         ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
19762 #endif
19763 #ifdef TCC_TARGET_ARM
19764         ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
19765 #endif
19766         switch(file_type) {
19767         default:
19768         case TCC_OUTPUT_EXE:
19769             ehdr.e_type = ET_EXEC;
19770             break;
19771         case TCC_OUTPUT_DLL:
19772             ehdr.e_type = ET_DYN;
19773             break;
19774         case TCC_OUTPUT_OBJ:
19775             ehdr.e_type = ET_REL;
19776             break;
19777         }
19778         ehdr.e_machine = EM_TCC_TARGET;
19779         ehdr.e_version = EV_CURRENT;
19780         ehdr.e_shoff = file_offset;
19781         ehdr.e_ehsize = sizeof(Elf32_Ehdr);
19782         ehdr.e_shentsize = sizeof(Elf32_Shdr);
19783         ehdr.e_shnum = shnum;
19784         ehdr.e_shstrndx = shnum - 1;
19785         
19786         dummy_size_t = fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
19787         dummy_size_t = fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
19788         offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19789
19790         for(i=1;i<s1->nb_sections;i++) {
19791             s = s1->sections[section_order[i]];
19792             if (s->sh_type != SHT_NOBITS) {
19793                 while (offset < s->sh_offset) {
19794                     fputc(0, f);
19795                     offset++;
19796                 }
19797                 size = s->sh_size;
19798                 dummy_size_t = fwrite(s->data, 1, size, f);
19799                 offset += size;
19800             }
19801         }
19802
19803         /* output section headers */
19804         while (offset < ehdr.e_shoff) {
19805             fputc(0, f);
19806             offset++;
19807         }
19808     
19809         for(i=0;i<s1->nb_sections;i++) {
19810             sh = &shdr;
19811             memset(sh, 0, sizeof(Elf32_Shdr));
19812             s = s1->sections[i];
19813             if (s) {
19814                 sh->sh_name = s->sh_name;
19815                 sh->sh_type = s->sh_type;
19816                 sh->sh_flags = s->sh_flags;
19817                 sh->sh_entsize = s->sh_entsize;
19818                 sh->sh_info = s->sh_info;
19819                 if (s->link)
19820                     sh->sh_link = s->link->sh_num;
19821                 sh->sh_addralign = s->sh_addralign;
19822                 sh->sh_addr = s->sh_addr;
19823                 sh->sh_offset = s->sh_offset;
19824                 sh->sh_size = s->sh_size;
19825             }
19826             dummy_size_t = fwrite(sh, 1, sizeof(Elf32_Shdr), f);
19827         }
19828     } else {
19829         tcc_output_binary(s1, f, section_order);
19830     }
19831     fclose(f);
19832
19833     ret = 0;
19834  the_end:
19835     tcc_free(s1->symtab_to_dynsym);
19836     tcc_free(section_order);
19837     tcc_free(phdr);
19838     tcc_free(s1->got_offsets);
19839     return ret;
19840 }
19841
19842 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
19843 {
19844     void *data;
19845
19846     data = tcc_malloc(size);
19847     lseek(fd, file_offset, SEEK_SET);
19848     dummy_size_t = read(fd, data, size);
19849     return data;
19850 }
19851
19852 typedef struct SectionMergeInfo {
19853     Section *s;            /* corresponding existing section */
19854     unsigned long offset;  /* offset of the new section in the existing section */
19855     uint8_t new_section;       /* true if section 's' was added */
19856     uint8_t link_once;         /* true if link once section */
19857 } SectionMergeInfo;
19858
19859 /* load an object file and merge it with current files */
19860 /* XXX: handle correctly stab (debug) info */
19861 static int tcc_load_object_file(TCCState *s1, 
19862                                 int fd, unsigned long file_offset)
19863
19864     Elf32_Ehdr ehdr;
19865     Elf32_Shdr *shdr, *sh;
19866     int size, i, j, offset, offseti, nb_syms, sym_index, ret;
19867     unsigned char *strsec, *strtab;
19868     int *old_to_new_syms;
19869     char *sh_name, *name;
19870     SectionMergeInfo *sm_table, *sm;
19871     Elf32_Sym *sym, *symtab;
19872     Elf32_Rel *rel, *rel_end;
19873     Section *s;
19874
19875     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
19876         goto fail1;
19877     if (ehdr.e_ident[0] != ELFMAG0 ||
19878         ehdr.e_ident[1] != ELFMAG1 ||
19879         ehdr.e_ident[2] != ELFMAG2 ||
19880         ehdr.e_ident[3] != ELFMAG3)
19881         goto fail1;
19882     /* test if object file */
19883     if (ehdr.e_type != ET_REL)
19884         goto fail1;
19885     /* test CPU specific stuff */
19886     if (ehdr.e_ident[5] != ELFDATA2LSB ||
19887         ehdr.e_machine != EM_TCC_TARGET) {
19888     fail1:
19889         error_noabort("invalid object file");
19890         return -1;
19891     }
19892     /* read sections */
19893     shdr = load_data(fd, file_offset + ehdr.e_shoff, 
19894                      sizeof(Elf32_Shdr) * ehdr.e_shnum);
19895     sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
19896     
19897     /* load section names */
19898     sh = &shdr[ehdr.e_shstrndx];
19899     strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19900
19901     /* load symtab and strtab */
19902     old_to_new_syms = NULL;
19903     symtab = NULL;
19904     strtab = NULL;
19905     nb_syms = 0;
19906     for(i = 1; i < ehdr.e_shnum; i++) {
19907         sh = &shdr[i];
19908         if (sh->sh_type == SHT_SYMTAB) {
19909             if (symtab) {
19910                 error_noabort("object must contain only one symtab");
19911             fail:
19912                 ret = -1;
19913                 goto the_end;
19914             }
19915             nb_syms = sh->sh_size / sizeof(Elf32_Sym);
19916             symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19917             sm_table[i].s = symtab_section;
19918
19919             /* now load strtab */
19920             sh = &shdr[sh->sh_link];
19921             strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19922         }
19923     }
19924         
19925     /* now examine each section and try to merge its content with the
19926        ones in memory */
19927     for(i = 1; i < ehdr.e_shnum; i++) {
19928         /* no need to examine section name strtab */
19929         if (i == ehdr.e_shstrndx)
19930             continue;
19931         sh = &shdr[i];
19932         sh_name = strsec + sh->sh_name;
19933         /* ignore sections types we do not handle */
19934         if (sh->sh_type != SHT_PROGBITS &&
19935             sh->sh_type != SHT_REL && 
19936             sh->sh_type != SHT_NOBITS)
19937             continue;
19938         if (sh->sh_addralign < 1)
19939             sh->sh_addralign = 1;
19940         /* find corresponding section, if any */
19941         for(j = 1; j < s1->nb_sections;j++) {
19942             s = s1->sections[j];
19943             if (!strcmp(s->name, sh_name)) {
19944                 if (!strncmp(sh_name, ".gnu.linkonce", 
19945                              sizeof(".gnu.linkonce") - 1)) {
19946                     /* if a 'linkonce' section is already present, we
19947                        do not add it again. It is a little tricky as
19948                        symbols can still be defined in
19949                        it. */
19950                     sm_table[i].link_once = 1;
19951                     goto next;
19952                 } else {
19953                     goto found;
19954                 }
19955             }
19956         }
19957         /* not found: create new section */
19958         s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
19959         /* take as much info as possible from the section. sh_link and
19960            sh_info will be updated later */
19961         s->sh_addralign = sh->sh_addralign;
19962         s->sh_entsize = sh->sh_entsize;
19963         sm_table[i].new_section = 1;
19964     found:
19965         if (sh->sh_type != s->sh_type) {
19966             error_noabort("invalid section type");
19967             goto fail;
19968         }
19969
19970         /* align start of section */
19971         offset = s->data_offset;
19972         size = sh->sh_addralign - 1;
19973         offset = (offset + size) & ~size;
19974         if (sh->sh_addralign > s->sh_addralign)
19975             s->sh_addralign = sh->sh_addralign;
19976         s->data_offset = offset;
19977         sm_table[i].offset = offset;
19978         sm_table[i].s = s;
19979         /* concatenate sections */
19980         size = sh->sh_size;
19981         if (sh->sh_type != SHT_NOBITS) {
19982             unsigned char *ptr;
19983             lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
19984             ptr = section_ptr_add(s, size);
19985             dummy_size_t = read(fd, ptr, size);
19986         } else {
19987             s->data_offset += size;
19988         }
19989     next: ;
19990     }
19991
19992     /* second short pass to update sh_link and sh_info fields of new
19993        sections */
19994     sm = sm_table;
19995     for(i = 1; i < ehdr.e_shnum; i++) {
19996         s = sm_table[i].s;
19997         if (!s || !sm_table[i].new_section)
19998             continue;
19999         sh = &shdr[i];
20000         if (sh->sh_link > 0)
20001             s->link = sm_table[sh->sh_link].s;
20002         if (sh->sh_type == SHT_REL) {
20003             s->sh_info = sm_table[sh->sh_info].s->sh_num;
20004             /* update backward link */
20005             s1->sections[s->sh_info]->reloc = s;
20006         }
20007     }
20008
20009     /* resolve symbols */
20010     old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
20011
20012     sym = symtab + 1;
20013     for(i = 1; i < nb_syms; i++, sym++) {
20014         if (sym->st_shndx != SHN_UNDEF &&
20015             sym->st_shndx < SHN_LORESERVE) {
20016             sm = &sm_table[sym->st_shndx];
20017             if (sm->link_once) {
20018                 /* if a symbol is in a link once section, we use the
20019                    already defined symbol. It is very important to get
20020                    correct relocations */
20021                 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
20022                     name = strtab + sym->st_name;
20023                     sym_index = find_elf_sym(symtab_section, name);
20024                     if (sym_index)
20025                         old_to_new_syms[i] = sym_index;
20026                 }
20027                 continue;
20028             }
20029             /* if no corresponding section added, no need to add symbol */
20030             if (!sm->s)
20031                 continue;
20032             /* convert section number */
20033             sym->st_shndx = sm->s->sh_num;
20034             /* offset value */
20035             sym->st_value += sm->offset;
20036         }
20037         /* add symbol */
20038         name = strtab + sym->st_name;
20039         sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, 
20040                                 sym->st_info, sym->st_other, 
20041                                 sym->st_shndx, name);
20042         old_to_new_syms[i] = sym_index;
20043     }
20044
20045     /* third pass to patch relocation entries */
20046     for(i = 1; i < ehdr.e_shnum; i++) {
20047         s = sm_table[i].s;
20048         if (!s)
20049             continue;
20050         sh = &shdr[i];
20051         offset = sm_table[i].offset;
20052         switch(s->sh_type) {
20053         case SHT_REL:
20054             /* take relocation offset information */
20055             offseti = sm_table[sh->sh_info].offset;
20056             rel_end = (Elf32_Rel *)(s->data + s->data_offset);
20057             for(rel = (Elf32_Rel *)(s->data + offset);
20058                 rel < rel_end;
20059                 rel++) {
20060                 int type;
20061                 unsigned sym_index;
20062                 /* convert symbol index */
20063                 type = ELF32_R_TYPE(rel->r_info);
20064                 sym_index = ELF32_R_SYM(rel->r_info);
20065                 /* NOTE: only one symtab assumed */
20066                 if (sym_index >= nb_syms)
20067                     goto invalid_reloc;
20068                 sym_index = old_to_new_syms[sym_index];
20069                 if (!sym_index) {
20070                 invalid_reloc:
20071                     error_noabort("Invalid relocation entry");
20072                     goto fail;
20073                 }
20074                 rel->r_info = ELF32_R_INFO(sym_index, type);
20075                 /* offset the relocation offset */
20076                 rel->r_offset += offseti;
20077             }
20078             break;
20079         default:
20080             break;
20081         }
20082     }
20083     
20084     ret = 0;
20085  the_end:
20086     tcc_free(symtab);
20087     tcc_free(strtab);
20088     tcc_free(old_to_new_syms);
20089     tcc_free(sm_table);
20090     tcc_free(strsec);
20091     tcc_free(shdr);
20092     return ret;
20093 }
20094
20095 #define ARMAG  "!<arch>\012"    /* For COFF and a.out archives */
20096
20097 typedef struct ArchiveHeader {
20098     char ar_name[16];           /* name of this member */
20099     char ar_date[12];           /* file mtime */
20100     char ar_uid[6];             /* owner uid; printed as decimal */
20101     char ar_gid[6];             /* owner gid; printed as decimal */
20102     char ar_mode[8];            /* file mode, printed as octal   */
20103     char ar_size[10];           /* file size, printed as decimal */
20104     char ar_fmag[2];            /* should contain ARFMAG */
20105 } ArchiveHeader;
20106
20107 static int get_be32(const uint8_t *b)
20108 {
20109     return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
20110 }
20111
20112 /* load only the objects which resolve undefined symbols */
20113 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
20114 {
20115     int i, bound, nsyms, sym_index, off, ret;
20116     uint8_t *data;
20117     const char *ar_names, *p;
20118     const uint8_t *ar_index;
20119     Elf32_Sym *sym;
20120
20121     data = tcc_malloc(size);
20122     if (read(fd, data, size) != size)
20123         goto fail;
20124     nsyms = get_be32(data);
20125     ar_index = data + 4;
20126     ar_names = ar_index + nsyms * 4;
20127
20128     do {
20129         bound = 0;
20130         for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
20131             sym_index = find_elf_sym(symtab_section, p);
20132             if(sym_index) {
20133                 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
20134                 if(sym->st_shndx == SHN_UNDEF) {
20135                     off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
20136 #if 0
20137                     printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
20138 #endif
20139                     ++bound;
20140                     lseek(fd, off, SEEK_SET);
20141                     if(tcc_load_object_file(s1, fd, off) < 0) {
20142                     fail:
20143                         ret = -1;
20144                         goto the_end;
20145                     }
20146                 }
20147             }
20148         }
20149     } while(bound);
20150     ret = 0;
20151  the_end:
20152     tcc_free(data);
20153     return ret;
20154 }
20155
20156 /* load a '.a' file */
20157 static int tcc_load_archive(TCCState *s1, int fd)
20158 {
20159     ArchiveHeader hdr;
20160     char ar_size[11];
20161     char ar_name[17];
20162     char magic[8];
20163     int size, len, i;
20164     unsigned long file_offset;
20165
20166     /* skip magic which was already checked */
20167     dummy_size_t = read(fd, magic, sizeof(magic));
20168     
20169     for(;;) {
20170         len = read(fd, &hdr, sizeof(hdr));
20171         if (len == 0)
20172             break;
20173         if (len != sizeof(hdr)) {
20174             error_noabort("invalid archive");
20175             return -1;
20176         }
20177         memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
20178         ar_size[sizeof(hdr.ar_size)] = '\0';
20179         size = strtol(ar_size, NULL, 0);
20180         memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
20181         for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
20182             if (ar_name[i] != ' ')
20183                 break;
20184         }
20185         ar_name[i + 1] = '\0';
20186         //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
20187         file_offset = lseek(fd, 0, SEEK_CUR);
20188         /* align to even */
20189         size = (size + 1) & ~1;
20190         if (!strcmp(ar_name, "/")) {
20191             /* coff symbol table : we handle it */
20192             if(s1->alacarte_link)
20193                 return tcc_load_alacarte(s1, fd, size);
20194         } else if (!strcmp(ar_name, "//") ||
20195                    !strcmp(ar_name, "__.SYMDEF") ||
20196                    !strcmp(ar_name, "__.SYMDEF/") ||
20197                    !strcmp(ar_name, "ARFILENAMES/")) {
20198             /* skip symbol table or archive names */
20199         } else {
20200             if (tcc_load_object_file(s1, fd, file_offset) < 0)
20201                 return -1;
20202         }
20203         lseek(fd, file_offset + size, SEEK_SET);
20204     }
20205     return 0;
20206 }
20207
20208 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
20209    is referenced by the user (so it should be added as DT_NEEDED in
20210    the generated ELF file) */
20211 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
20212
20213     Elf32_Ehdr ehdr;
20214     Elf32_Shdr *shdr, *sh, *sh1;
20215     int i, nb_syms, nb_dts, sym_bind, ret;
20216     Elf32_Sym *sym, *dynsym;
20217     Elf32_Dyn *dt, *dynamic;
20218     unsigned char *dynstr;
20219     const char *name, *soname, *p;
20220     DLLReference *dllref;
20221     
20222     dummy_size_t = read(fd, &ehdr, sizeof(ehdr));
20223
20224     /* test CPU specific stuff */
20225     if (ehdr.e_ident[5] != ELFDATA2LSB ||
20226         ehdr.e_machine != EM_TCC_TARGET) {
20227         error_noabort("bad architecture");
20228         return -1;
20229     }
20230
20231     /* read sections */
20232     shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
20233
20234     /* load dynamic section and dynamic symbols */
20235     nb_syms = 0;
20236     nb_dts = 0;
20237     dynamic = NULL;
20238     dynsym = NULL; /* avoid warning */
20239     dynstr = NULL; /* avoid warning */
20240     for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
20241         switch(sh->sh_type) {
20242         case SHT_DYNAMIC:
20243             nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
20244             dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
20245             break;
20246         case SHT_DYNSYM:
20247             nb_syms = sh->sh_size / sizeof(Elf32_Sym);
20248             dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
20249             sh1 = &shdr[sh->sh_link];
20250             dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
20251             break;
20252         default:
20253             break;
20254         }
20255     }
20256     
20257     /* compute the real library name */
20258     soname = filename;
20259     p = strrchr(soname, '/');
20260     if (p)
20261         soname = p + 1;
20262         
20263     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20264         if (dt->d_tag == DT_SONAME) {
20265             soname = dynstr + dt->d_un.d_val;
20266         }
20267     }
20268
20269     /* if the dll is already loaded, do not load it */
20270     for(i = 0; i < s1->nb_loaded_dlls; i++) {
20271         dllref = s1->loaded_dlls[i];
20272         if (!strcmp(soname, dllref->name)) {
20273             /* but update level if needed */
20274             if (level < dllref->level)
20275                 dllref->level = level;
20276             ret = 0;
20277             goto the_end;
20278         }
20279     }
20280     
20281     //    printf("loading dll '%s'\n", soname);
20282
20283     /* add the dll and its level */
20284     dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
20285     dllref->level = level;
20286     strcpy(dllref->name, soname);
20287     dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
20288
20289     /* add dynamic symbols in dynsym_section */
20290     for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
20291         sym_bind = ELF32_ST_BIND(sym->st_info);
20292         if (sym_bind == STB_LOCAL)
20293             continue;
20294         name = dynstr + sym->st_name;
20295         add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
20296                     sym->st_info, sym->st_other, sym->st_shndx, name);
20297     }
20298
20299     /* load all referenced DLLs */
20300     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20301         switch(dt->d_tag) {
20302         case DT_NEEDED:
20303             name = dynstr + dt->d_un.d_val;
20304             for(i = 0; i < s1->nb_loaded_dlls; i++) {
20305                 dllref = s1->loaded_dlls[i];
20306                 if (!strcmp(name, dllref->name))
20307                     goto already_loaded;
20308             }
20309             if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
20310                 error_noabort("referenced dll '%s' not found", name);
20311                 ret = -1;
20312                 goto the_end;
20313             }
20314         already_loaded:
20315             break;
20316         }
20317     }
20318     ret = 0;
20319  the_end:
20320     tcc_free(dynstr);
20321     tcc_free(dynsym);
20322     tcc_free(dynamic);
20323     tcc_free(shdr);
20324     return ret;
20325 }
20326
20327 #define LD_TOK_NAME 256
20328 #define LD_TOK_EOF  (-1)
20329
20330 /* return next ld script token */
20331 static int ld_next(TCCState *s1, char *name, int name_size)
20332 {
20333     int c;
20334     char *q;
20335
20336  redo:
20337     switch(ch) {
20338     case ' ':
20339     case '\t':
20340     case '\f':
20341     case '\v':
20342     case '\r':
20343     case '\n':
20344         inp();
20345         goto redo;
20346     case '/':
20347         minp();
20348         if (ch == '*') {
20349             file->buf_ptr = parse_comment(file->buf_ptr);
20350             ch = file->buf_ptr[0];
20351             goto redo;
20352         } else {
20353             q = name;
20354             *q++ = '/';
20355             goto parse_name;
20356         }
20357         break;
20358     case 'a' ... 'z':
20359     case 'A' ... 'Z':
20360     case '_':
20361     case '\\':
20362     case '.':
20363     case '$':
20364     case '~':
20365         q = name;
20366     parse_name:
20367         for(;;) {
20368             if (!((ch >= 'a' && ch <= 'z') ||
20369                   (ch >= 'A' && ch <= 'Z') ||
20370                   (ch >= '0' && ch <= '9') ||
20371                   strchr("/.-_+=$:\\,~", ch)))
20372                 break;
20373             if ((q - name) < name_size - 1) {
20374                 *q++ = ch;
20375             }
20376             minp();
20377         }
20378         *q = '\0';
20379         c = LD_TOK_NAME;
20380         break;
20381     case CH_EOF:
20382         c = LD_TOK_EOF;
20383         break;
20384     default:
20385         c = ch;
20386         inp();
20387         break;
20388     }
20389 #if 0
20390     printf("tok=%c %d\n", c, c);
20391     if (c == LD_TOK_NAME)
20392         printf("  name=%s\n", name);
20393 #endif
20394     return c;
20395 }
20396
20397 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
20398    files */
20399 static int tcc_load_ldscript(TCCState *s1)
20400 {
20401     char cmd[64];
20402     char filename[1024];
20403     int t;
20404     
20405     ch = file->buf_ptr[0];
20406     ch = handle_eob();
20407     for(;;) {
20408         t = ld_next(s1, cmd, sizeof(cmd));
20409         if (t == LD_TOK_EOF)
20410             return 0;
20411         else if (t != LD_TOK_NAME)
20412             return -1;
20413         if (!strcmp(cmd, "INPUT") ||
20414             !strcmp(cmd, "GROUP")) {
20415             t = ld_next(s1, cmd, sizeof(cmd));
20416             if (t != '(')
20417                 expect("(");
20418             t = ld_next(s1, filename, sizeof(filename));
20419             for(;;) {
20420                 if (t == LD_TOK_EOF) {
20421                     error_noabort("unexpected end of file");
20422                     return -1;
20423                 } else if (t == ')') {
20424                     break;
20425                 } else if (t != LD_TOK_NAME) {
20426                     error_noabort("filename expected");
20427                     return -1;
20428                 } 
20429                 tcc_add_file(s1, filename);
20430                 t = ld_next(s1, filename, sizeof(filename));
20431                 if (t == ',') {
20432                     t = ld_next(s1, filename, sizeof(filename));
20433                 }
20434             }
20435         } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
20436                    !strcmp(cmd, "TARGET")) {
20437             /* ignore some commands */
20438             t = ld_next(s1, cmd, sizeof(cmd));
20439             if (t != '(')
20440                 expect("(");
20441             for(;;) {
20442                 t = ld_next(s1, filename, sizeof(filename));
20443                 if (t == LD_TOK_EOF) {
20444                     error_noabort("unexpected end of file");
20445                     return -1;
20446                 } else if (t == ')') {
20447                     break;
20448                 }
20449             }
20450         } else {
20451             return -1;
20452         }
20453     }
20454     return 0;
20455 }
20456 //---------------------------------------------------------------------------
20457
20458 #ifdef TCC_TARGET_COFF
20459 #include "tcccoff.c"
20460 #endif
20461
20462 #ifdef TCC_TARGET_PE
20463 #include "tccpe.c"
20464 #endif
20465
20466 /* print the position in the source file of PC value 'pc' by reading
20467    the stabs debug information */
20468 static void rt_printline(unsigned long wanted_pc)
20469 {
20470     Stab_Sym *sym, *sym_end;
20471     char func_name[128], last_func_name[128];
20472     unsigned long func_addr, last_pc, pc;
20473     const char *incl_files[INCLUDE_STACK_SIZE];
20474     int incl_index, len, last_line_num, i;
20475     const char *str, *p;
20476
20477     fprintf(stderr, "0x%08lx:", wanted_pc);
20478
20479     func_name[0] = '\0';
20480     func_addr = 0;
20481     incl_index = 0;
20482     last_func_name[0] = '\0';
20483     last_pc = 0xffffffff;
20484     last_line_num = 1;
20485     sym = (Stab_Sym *)stab_section->data + 1;
20486     sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
20487     while (sym < sym_end) {
20488         switch(sym->n_type) {
20489             /* function start or end */
20490         case N_FUN:
20491             if (sym->n_strx == 0) {
20492                 /* we test if between last line and end of function */
20493                 pc = sym->n_value + func_addr;
20494                 if (wanted_pc >= last_pc && wanted_pc < pc)
20495                     goto found;
20496                 func_name[0] = '\0';
20497                 func_addr = 0;
20498             } else {
20499                 str = stabstr_section->data + sym->n_strx;
20500                 p = strchr(str, ':');
20501                 if (!p) {
20502                     pstrcpy(func_name, sizeof(func_name), str);
20503                 } else {
20504                     len = p - str;
20505                     if (len > sizeof(func_name) - 1)
20506                         len = sizeof(func_name) - 1;
20507                     memcpy(func_name, str, len);
20508                     func_name[len] = '\0';
20509                 }
20510                 func_addr = sym->n_value;
20511             }
20512             break;
20513             /* line number info */
20514         case N_SLINE:
20515             pc = sym->n_value + func_addr;
20516             if (wanted_pc >= last_pc && wanted_pc < pc)
20517                 goto found;
20518             last_pc = pc;
20519             last_line_num = sym->n_desc;
20520             /* XXX: slow! */
20521             strcpy(last_func_name, func_name);
20522             break;
20523             /* include files */
20524         case N_BINCL:
20525             str = stabstr_section->data + sym->n_strx;
20526         add_incl:
20527             if (incl_index < INCLUDE_STACK_SIZE) {
20528                 incl_files[incl_index++] = str;
20529             }
20530             break;
20531         case N_EINCL:
20532             if (incl_index > 1)
20533                 incl_index--;
20534             break;
20535         case N_SO:
20536             if (sym->n_strx == 0) {
20537                 incl_index = 0; /* end of translation unit */
20538             } else {
20539                 str = stabstr_section->data + sym->n_strx;
20540                 /* do not add path */
20541                 len = strlen(str);
20542                 if (len > 0 && str[len - 1] != '/')
20543                     goto add_incl;
20544             }
20545             break;
20546         }
20547         sym++;
20548     }
20549
20550     /* second pass: we try symtab symbols (no line number info) */
20551     incl_index = 0;
20552     {
20553         Elf32_Sym *sym, *sym_end;
20554         int type;
20555
20556         sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
20557         for(sym = (Elf32_Sym *)symtab_section->data + 1; 
20558             sym < sym_end;
20559             sym++) {
20560             type = ELF32_ST_TYPE(sym->st_info);
20561             if (type == STT_FUNC) {
20562                 if (wanted_pc >= sym->st_value &&
20563                     wanted_pc < sym->st_value + sym->st_size) {
20564                     pstrcpy(last_func_name, sizeof(last_func_name),
20565                             strtab_section->data + sym->st_name);
20566                     goto found;
20567                 }
20568             }
20569         }
20570     }
20571     /* did not find any info: */
20572     fprintf(stderr, " ???\n");
20573     return;
20574  found:
20575     if (last_func_name[0] != '\0') {
20576         fprintf(stderr, " %s()", last_func_name);
20577     }
20578     if (incl_index > 0) {
20579         fprintf(stderr, " (%s:%d", 
20580                 incl_files[incl_index - 1], last_line_num);
20581         for(i = incl_index - 2; i >= 0; i--)
20582             fprintf(stderr, ", included from %s", incl_files[i]);
20583         fprintf(stderr, ")");
20584     }
20585     fprintf(stderr, "\n");
20586 }
20587
20588 #if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
20589
20590 /* return the PC at frame level 'level'. Return non zero if not found */
20591 static int rt_get_caller_pc(unsigned long *paddr, 
20592                             ucontext_t *uc, int level)
20593 {
20594     unsigned long fp __attribute__((unused));
20595     //int i;
20596
20597     if (level == 0) {
20598         *paddr = 12345; //uc->uc_mcontext.gregs[REG_EIP];
20599         return 0;
20600     } else {
20601         fp = 23456; //uc->uc_mcontext.gregs[REG_EBP];
20602         return 0;
20603     }
20604 }
20605
20606 /* emit a run time error at position 'pc' */
20607 void rt_error(ucontext_t *uc, const char *fmt, ...)
20608 {
20609     va_list ap;
20610     unsigned long pc = 0;  // shut gcc up
20611     int i;
20612
20613     va_start(ap, fmt);
20614     fprintf(stderr, "Runtime error: ");
20615     vfprintf(stderr, fmt, ap);
20616     fprintf(stderr, "\n");
20617     for(i=0;i<num_callers;i++) {
20618         if (rt_get_caller_pc(&pc, uc, i) < 0)
20619             break;
20620         if (i == 0)
20621             fprintf(stderr, "at ");
20622         else
20623             fprintf(stderr, "by ");
20624         rt_printline(pc);
20625     }
20626     exit(255);
20627     va_end(ap);
20628 }
20629
20630 /* signal handler for fatal errors */
20631 static void sig_error(int signum, siginfo_t *siginf, void *puc)
20632 {
20633     ucontext_t *uc = puc;
20634
20635     switch(signum) {
20636     case SIGFPE:
20637         switch(siginf->si_code) {
20638         case FPE_INTDIV:
20639         case FPE_FLTDIV:
20640             rt_error(uc, "division by zero");
20641             break;
20642         default:
20643             rt_error(uc, "floating point exception");
20644             break;
20645         }
20646         break;
20647     case SIGBUS:
20648     case SIGSEGV:
20649         if (rt_bound_error_msg && *rt_bound_error_msg)
20650             rt_error(uc, *rt_bound_error_msg);
20651         else
20652             rt_error(uc, "dereferencing invalid pointer");
20653         break;
20654     case SIGILL:
20655         rt_error(uc, "illegal instruction");
20656         break;
20657     case SIGABRT:
20658         rt_error(uc, "abort() called");
20659         break;
20660     default:
20661         rt_error(uc, "caught signal %d", signum);
20662         break;
20663     }
20664     exit(255);
20665 }
20666 #endif
20667
20668 /* do all relocations (needed before using tcc_get_symbol()) */
20669 int tcc_relocate(TCCState *s1)
20670 {
20671     Section *s;
20672     int i;
20673
20674     s1->nb_errors = 0;
20675     
20676 #ifdef TCC_TARGET_PE
20677     pe_add_runtime(s1);
20678 #else
20679     tcc_add_runtime(s1);
20680 #endif
20681
20682     relocate_common_syms();
20683
20684     tcc_add_linker_symbols(s1);
20685
20686     build_got_entries(s1);
20687     
20688     /* compute relocation address : section are relocated in place. We
20689        also alloc the bss space */
20690     for(i = 1; i < s1->nb_sections; i++) {
20691         s = s1->sections[i];
20692         if (s->sh_flags & SHF_ALLOC) {
20693             if (s->sh_type == SHT_NOBITS)
20694                 s->data = tcc_mallocz(s->data_offset);
20695             s->sh_addr = (unsigned long)s->data;
20696         }
20697     }
20698
20699     relocate_syms(s1, 1);
20700
20701     if (s1->nb_errors != 0)
20702         return -1;
20703
20704     /* relocate each section */
20705     for(i = 1; i < s1->nb_sections; i++) {
20706         s = s1->sections[i];
20707         if (s->reloc)
20708             relocate_section(s1, s);
20709     }
20710     return 0;
20711 }
20712
20713 /* launch the compiled program with the given arguments */
20714 int tcc_run(TCCState *s1, int argc, char **argv)
20715 {
20716     int (*prog_main)(int, char **);
20717
20718     if (tcc_relocate(s1) < 0)
20719         return -1;
20720
20721     prog_main = tcc_get_symbol_err(s1, "main");
20722     
20723     if (do_debug) {
20724 #if defined(WIN32) || defined(CONFIG_TCCBOOT)
20725         error("debug mode currently not available for Windows");
20726 #else        
20727         struct sigaction sigact;
20728         /* install TCC signal handlers to print debug info on fatal
20729            runtime errors */
20730         sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
20731         sigact.sa_sigaction = sig_error;
20732         sigemptyset(&sigact.sa_mask);
20733         sigaction(SIGFPE, &sigact, NULL);
20734         sigaction(SIGILL, &sigact, NULL);
20735         sigaction(SIGSEGV, &sigact, NULL);
20736         sigaction(SIGBUS, &sigact, NULL);
20737         sigaction(SIGABRT, &sigact, NULL);
20738 #endif
20739     }
20740
20741 #ifdef CONFIG_TCC_BCHECK
20742     if (do_bounds_check) {
20743         void (*bound_init)(void);
20744
20745         /* set error function */
20746         rt_bound_error_msg = (void *)tcc_get_symbol_err(s1, 
20747                                                         "__bound_error_msg");
20748
20749         /* XXX: use .init section so that it also work in binary ? */
20750         bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init");
20751         bound_init();
20752     }
20753 #endif
20754     return (*prog_main)(argc, argv);
20755 }
20756
20757 TCCState *tcc_new(void)
20758 {
20759     const char *p, *r;
20760     TCCState *s;
20761     TokenSym *ts __attribute__((unused));
20762     int i, c;
20763
20764     s = tcc_mallocz(sizeof(TCCState));
20765     if (!s)
20766         return NULL;
20767     tcc_state = s;
20768     s->output_type = TCC_OUTPUT_MEMORY;
20769
20770     /* init isid table */
20771     for(i=0;i<256;i++)
20772         isidnum_table[i] = isid(i) || isnum(i);
20773
20774     /* add all tokens */
20775     table_ident = NULL;
20776     memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
20777     
20778     tok_ident = TOK_IDENT;
20779     p = tcc_keywords;
20780     while (*p) {
20781         r = p;
20782         for(;;) {
20783             c = *r++;
20784             if (c == '\0')
20785                 break;
20786         }
20787         ts = tok_alloc(p, r - p - 1);
20788         p = r;
20789     }
20790
20791     /* we add dummy defines for some special macros to speed up tests
20792        and to have working defined() */
20793     define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
20794     define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
20795     define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
20796     define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
20797
20798     /* standard defines */
20799     tcc_define_symbol(s, "__STDC__", NULL);
20800 #if defined(TCC_TARGET_I386)
20801     tcc_define_symbol(s, "__i386__", NULL);
20802 #endif
20803 #if defined(TCC_TARGET_ARM)
20804     tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
20805     tcc_define_symbol(s, "__arm_elf__", NULL);
20806     tcc_define_symbol(s, "__arm_elf", NULL);
20807     tcc_define_symbol(s, "arm_elf", NULL);
20808     tcc_define_symbol(s, "__arm__", NULL);
20809     tcc_define_symbol(s, "__arm", NULL);
20810     tcc_define_symbol(s, "arm", NULL);
20811     tcc_define_symbol(s, "__APCS_32__", NULL);
20812 #endif
20813 #if defined(linux)
20814     tcc_define_symbol(s, "__linux__", NULL);
20815     tcc_define_symbol(s, "linux", NULL);
20816 #endif
20817     /* tiny C specific defines */
20818     tcc_define_symbol(s, "__TINYC__", NULL);
20819
20820     /* tiny C & gcc defines */
20821     tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
20822     tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
20823     tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
20824     
20825     /* default library paths */
20826 #ifdef TCC_TARGET_PE
20827     {
20828         char buf[1024];
20829         snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
20830         tcc_add_library_path(s, buf);
20831     }
20832 #else
20833     tcc_add_library_path(s, "/usr/local/lib");
20834     tcc_add_library_path(s, "/usr/lib");
20835     tcc_add_library_path(s, "/lib");
20836 #endif
20837
20838     /* no section zero */
20839     dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
20840
20841     /* create standard sections */
20842     text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
20843     data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
20844     bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
20845
20846     /* symbols are always generated for linking stage */
20847     symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
20848                                 ".strtab",
20849                                 ".hashtab", SHF_PRIVATE); 
20850     strtab_section = symtab_section->link;
20851     
20852     /* private symbol table for dynamic symbols */
20853     s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
20854                                       ".dynstrtab", 
20855                                       ".dynhashtab", SHF_PRIVATE);
20856     s->alacarte_link = 1;
20857
20858 #ifdef CHAR_IS_UNSIGNED
20859     s->char_is_unsigned = 1;
20860 #endif
20861 #if defined(TCC_TARGET_PE) && 0
20862     /* XXX: currently the PE linker is not ready to support that */
20863     s->leading_underscore = 1;
20864 #endif
20865     return s;
20866 }
20867
20868 void tcc_delete(TCCState *s1)
20869 {
20870     int i, n;
20871
20872     /* free -D defines */
20873     free_defines(NULL);
20874
20875     /* free tokens */
20876     n = tok_ident - TOK_IDENT;
20877     for(i = 0; i < n; i++)
20878         tcc_free(table_ident[i]);
20879     tcc_free(table_ident);
20880
20881     /* free all sections */
20882
20883     free_section(symtab_section->hash);
20884
20885     free_section(s1->dynsymtab_section->hash);
20886     free_section(s1->dynsymtab_section->link);
20887     free_section(s1->dynsymtab_section);
20888
20889     for(i = 1; i < s1->nb_sections; i++)
20890         free_section(s1->sections[i]);
20891     tcc_free(s1->sections);
20892     
20893     /* free loaded dlls array */
20894     for(i = 0; i < s1->nb_loaded_dlls; i++)
20895         tcc_free(s1->loaded_dlls[i]);
20896     tcc_free(s1->loaded_dlls);
20897
20898     /* library paths */
20899     for(i = 0; i < s1->nb_library_paths; i++)
20900         tcc_free(s1->library_paths[i]);
20901     tcc_free(s1->library_paths);
20902
20903     /* cached includes */
20904     for(i = 0; i < s1->nb_cached_includes; i++)
20905         tcc_free(s1->cached_includes[i]);
20906     tcc_free(s1->cached_includes);
20907
20908     for(i = 0; i < s1->nb_include_paths; i++)
20909         tcc_free(s1->include_paths[i]);
20910     tcc_free(s1->include_paths);
20911
20912     for(i = 0; i < s1->nb_sysinclude_paths; i++)
20913         tcc_free(s1->sysinclude_paths[i]);
20914     tcc_free(s1->sysinclude_paths);
20915
20916     tcc_free(s1);
20917 }
20918
20919 int tcc_add_include_path(TCCState *s1, const char *pathname)
20920 {
20921     char *pathname1;
20922     
20923     pathname1 = tcc_strdup(pathname);
20924     dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
20925     return 0;
20926 }
20927
20928 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
20929 {
20930     char *pathname1;
20931     
20932     pathname1 = tcc_strdup(pathname);
20933     dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
20934     return 0;
20935 }
20936
20937 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
20938 {
20939     const char *ext, *filename1;
20940     Elf32_Ehdr ehdr;
20941     int fd, ret;
20942     BufferedFile *saved_file;
20943
20944     /* find source file type with extension */
20945     filename1 = strrchr(filename, '/');
20946     if (filename1)
20947         filename1++;
20948     else
20949         filename1 = filename;
20950     ext = strrchr(filename1, '.');
20951     if (ext)
20952         ext++;
20953
20954     /* open the file */
20955     saved_file = file;
20956     file = tcc_open(s1, filename);
20957     if (!file) {
20958         if (flags & AFF_PRINT_ERROR) {
20959             error_noabort("file '%s' not found", filename);
20960         }
20961         ret = -1;
20962         goto fail1;
20963     }
20964
20965     if (!ext || !strcmp(ext, "c")) {
20966         /* C file assumed */
20967         ret = tcc_compile(s1);
20968     } else 
20969 #ifdef CONFIG_TCC_ASM
20970     if (!strcmp(ext, "S")) {
20971         /* preprocessed assembler */
20972         ret = tcc_assemble(s1, 1);
20973     } else if (!strcmp(ext, "s")) {
20974         /* non preprocessed assembler */
20975         ret = tcc_assemble(s1, 0);
20976     } else 
20977 #endif
20978 #ifdef TCC_TARGET_PE
20979     if (!strcmp(ext, "def")) {
20980         ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
20981     } else
20982 #endif
20983     {
20984         fd = file->fd;
20985         /* assume executable format: auto guess file type */
20986         ret = read(fd, &ehdr, sizeof(ehdr));
20987         lseek(fd, 0, SEEK_SET);
20988         if (ret <= 0) {
20989             error_noabort("could not read header");
20990             goto fail;
20991         } else if (ret != sizeof(ehdr)) {
20992             goto try_load_script;
20993         }
20994
20995         if (ehdr.e_ident[0] == ELFMAG0 &&
20996             ehdr.e_ident[1] == ELFMAG1 &&
20997             ehdr.e_ident[2] == ELFMAG2 &&
20998             ehdr.e_ident[3] == ELFMAG3) {
20999             file->line_num = 0; /* do not display line number if error */
21000             if (ehdr.e_type == ET_REL) {
21001                 ret = tcc_load_object_file(s1, fd, 0);
21002             } else if (ehdr.e_type == ET_DYN) {
21003                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
21004 #ifdef TCC_TARGET_PE
21005                     ret = -1;
21006 #else
21007                     void *h;
21008                     assert(0);
21009                     h = 0;
21010                     //h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
21011                     // jrs: remove need for dlopen
21012                     if (h)
21013                         ret = 0;
21014                     else
21015                         ret = -1;
21016 #endif
21017                 } else {
21018                     ret = tcc_load_dll(s1, fd, filename, 
21019                                        (flags & AFF_REFERENCED_DLL) != 0);
21020                 }
21021             } else {
21022                 error_noabort("unrecognized ELF file");
21023                 goto fail;
21024             }
21025         } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
21026             file->line_num = 0; /* do not display line number if error */
21027             ret = tcc_load_archive(s1, fd);
21028         } else 
21029 #ifdef TCC_TARGET_COFF
21030         if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
21031             ret = tcc_load_coff(s1, fd);
21032         } else
21033 #endif
21034         {
21035             /* as GNU ld, consider it is an ld script if not recognized */
21036         try_load_script:
21037             ret = tcc_load_ldscript(s1);
21038             if (ret < 0) {
21039                 error_noabort("unrecognized file type");
21040                 goto fail;
21041             }
21042         }
21043     }
21044  the_end:
21045     tcc_close(file);
21046  fail1:
21047     file = saved_file;
21048     return ret;
21049  fail:
21050     ret = -1;
21051     goto the_end;
21052 }
21053
21054 int tcc_add_file(TCCState *s, const char *filename)
21055 {
21056     return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
21057 }
21058
21059 int tcc_add_library_path(TCCState *s, const char *pathname)
21060 {
21061     char *pathname1;
21062     
21063     pathname1 = tcc_strdup(pathname);
21064     dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
21065     return 0;
21066 }
21067
21068 /* find and load a dll. Return non zero if not found */
21069 /* XXX: add '-rpath' option support ? */
21070 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
21071 {
21072     char buf[1024];
21073     int i;
21074
21075     for(i = 0; i < s->nb_library_paths; i++) {
21076         snprintf(buf, sizeof(buf), "%s/%s", 
21077                  s->library_paths[i], filename);
21078         if (tcc_add_file_internal(s, buf, flags) == 0)
21079             return 0;
21080     }
21081     return -1;
21082 }
21083
21084 /* the library name is the same as the argument of the '-l' option */
21085 int tcc_add_library(TCCState *s, const char *libraryname)
21086 {
21087     char buf[1024];
21088     int i;
21089     
21090     /* first we look for the dynamic library if not static linking */
21091     if (!s->static_link) {
21092 #ifdef TCC_TARGET_PE
21093         snprintf(buf, sizeof(buf), "%s.def", libraryname);
21094 #else
21095         snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
21096 #endif
21097         if (tcc_add_dll(s, buf, 0) == 0)
21098             return 0;
21099     }
21100
21101     /* then we look for the static library */
21102     for(i = 0; i < s->nb_library_paths; i++) {
21103         snprintf(buf, sizeof(buf), "%s/lib%s.a", 
21104                  s->library_paths[i], libraryname);
21105         if (tcc_add_file_internal(s, buf, 0) == 0)
21106             return 0;
21107     }
21108     return -1;
21109 }
21110
21111 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
21112 {
21113     add_elf_sym(symtab_section, val, 0, 
21114                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
21115                 SHN_ABS, name);
21116     return 0;
21117 }
21118
21119 int tcc_set_output_type(TCCState *s, int output_type)
21120 {
21121     s->output_type = output_type;
21122
21123     if (!s->nostdinc) {
21124         char buf[1024];
21125
21126         /* default include paths */
21127         /* XXX: reverse order needed if -isystem support */
21128 #ifndef TCC_TARGET_PE
21129         tcc_add_sysinclude_path(s, "/usr/local/include");
21130         tcc_add_sysinclude_path(s, "/usr/include");
21131 #endif
21132         snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
21133         tcc_add_sysinclude_path(s, buf);
21134 #ifdef TCC_TARGET_PE
21135         snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
21136         tcc_add_sysinclude_path(s, buf);
21137 #endif
21138     }
21139
21140     /* if bound checking, then add corresponding sections */
21141 #ifdef CONFIG_TCC_BCHECK
21142     if (do_bounds_check) {
21143         /* define symbol */
21144         tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
21145         /* create bounds sections */
21146         bounds_section = new_section(s, ".bounds", 
21147                                      SHT_PROGBITS, SHF_ALLOC);
21148         lbounds_section = new_section(s, ".lbounds", 
21149                                       SHT_PROGBITS, SHF_ALLOC);
21150     }
21151 #endif
21152
21153     if (s->char_is_unsigned) {
21154         tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
21155     }
21156
21157     /* add debug sections */
21158     if (do_debug) {
21159         /* stab symbols */
21160         stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
21161         stab_section->sh_entsize = sizeof(Stab_Sym);
21162         stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
21163         put_elf_str(stabstr_section, "");
21164         stab_section->link = stabstr_section;
21165         /* put first entry */
21166         put_stabs("", 0, 0, 0, 0);
21167     }
21168
21169     /* add libc crt1/crti objects */
21170 #ifndef TCC_TARGET_PE
21171     if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
21172         !s->nostdlib) {
21173         if (output_type != TCC_OUTPUT_DLL)
21174             tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
21175         tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
21176     }
21177 #endif
21178     return 0;
21179 }
21180
21181 #define WD_ALL    0x0001 /* warning is activated when using -Wall */
21182 #define FD_INVERT 0x0002 /* invert value before storing */
21183
21184 typedef struct FlagDef {
21185     uint16_t offset;
21186     uint16_t flags;
21187     const char *name;
21188 } FlagDef;
21189
21190 static const FlagDef warning_defs[] = {
21191     { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
21192     { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
21193     { offsetof(TCCState, warn_error), 0, "error" },
21194     { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
21195       "implicit-function-declaration" },
21196 };
21197
21198 static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
21199                     const char *name, int value)
21200 {
21201     int i;
21202     const FlagDef *p;
21203     const char *r;
21204
21205     r = name;
21206     if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
21207         r += 3;
21208         value = !value;
21209     }
21210     for(i = 0, p = flags; i < nb_flags; i++, p++) {
21211         if (!strcmp(r, p->name))
21212             goto found;
21213     }
21214     return -1;
21215  found:
21216     if (p->flags & FD_INVERT)
21217         value = !value;
21218     *(int *)((uint8_t *)s + p->offset) = value;
21219     return 0;
21220 }
21221
21222
21223 /* set/reset a warning */
21224 int tcc_set_warning(TCCState *s, const char *warning_name, int value)
21225 {
21226     int i;
21227     const FlagDef *p;
21228
21229     if (!strcmp(warning_name, "all")) {
21230         for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
21231             if (p->flags & WD_ALL)
21232                 *(int *)((uint8_t *)s + p->offset) = 1;
21233         }
21234         return 0;
21235     } else {
21236         return set_flag(s, warning_defs, countof(warning_defs),
21237                         warning_name, value);
21238     }
21239 }
21240
21241 static const FlagDef flag_defs[] = {
21242     { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
21243     { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
21244     { offsetof(TCCState, nocommon), FD_INVERT, "common" },
21245     { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
21246 };
21247
21248 /* set/reset a flag */
21249 int tcc_set_flag(TCCState *s, const char *flag_name, int value)
21250 {
21251     return set_flag(s, flag_defs, countof(flag_defs),
21252                     flag_name, value);
21253 }
21254
21255 #if !defined(LIBTCC)
21256
21257 /* extract the basename of a file */
21258 static const char *tcc_basename(const char *name)
21259 {
21260     const char *p;
21261     p = strrchr(name, '/');
21262 #ifdef WIN32
21263     if (!p)
21264         p = strrchr(name, '\\');
21265 #endif    
21266     if (!p)
21267         p = name;
21268     else 
21269         p++;
21270     return p;
21271 }
21272
21273 static int64_t getclock_us(void)
21274 {
21275 #ifdef WIN32
21276     struct _timeb tb;
21277     _ftime(&tb);
21278     return (tb.time * 1000LL + tb.millitm) * 1000LL;
21279 #else
21280     struct timeval tv;
21281     gettimeofday(&tv, NULL);
21282     return tv.tv_sec * 1000000LL + tv.tv_usec;
21283 #endif
21284 }
21285
21286 void help(void)
21287 {
21288     printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2010 Fabrice Bellard\n"
21289            "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
21290            "           [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
21291            "           [infile1 infile2...] [-run infile args...]\n"
21292            "\n"
21293            "General options:\n"
21294            "  -v          display current version\n"
21295            "  -c          compile only - generate an object file\n"
21296            "  -o outfile  set output filename\n"
21297            "  -Bdir       set tcc internal library path\n"
21298            "  -bench      output compilation statistics\n"
21299            "  -run        run compiled source\n"
21300            "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
21301            "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
21302            "  -w          disable all warnings\n"
21303            "Preprocessor options:\n"
21304            "  -Idir       add include path 'dir'\n"
21305            "  -Dsym[=val] define 'sym' with value 'val'\n"
21306            "  -Usym       undefine 'sym'\n"
21307            "Linker options:\n"
21308            "  -Ldir       add library path 'dir'\n"
21309            "  -llib       link with dynamic or static library 'lib'\n"
21310            "  -shared     generate a shared library\n"
21311            "  -static     static linking\n"
21312            "  -rdynamic   export all global symbols to dynamic linker\n"
21313            "  -r          relocatable output\n"
21314            "Debugger options:\n"
21315            "  -g          generate runtime debug info\n"
21316 #ifdef CONFIG_TCC_BCHECK
21317            "  -b          compile with built-in memory and bounds checker (implies -g)\n"
21318 #endif
21319            "  -bt N       show N callers in stack traces\n"
21320            );
21321 }
21322
21323 #define TCC_OPTION_HAS_ARG 0x0001
21324 #define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
21325
21326 typedef struct TCCOption {
21327     const char *name;
21328     uint16_t index;
21329     uint16_t flags;
21330 } TCCOption;
21331
21332 enum {
21333     TCC_OPTION_HELP,
21334     TCC_OPTION_I,
21335     TCC_OPTION_D,
21336     TCC_OPTION_U,
21337     TCC_OPTION_L,
21338     TCC_OPTION_B,
21339     TCC_OPTION_l,
21340     TCC_OPTION_bench,
21341     TCC_OPTION_bt,
21342     TCC_OPTION_b,
21343     TCC_OPTION_g,
21344     TCC_OPTION_c,
21345     TCC_OPTION_static,
21346     TCC_OPTION_shared,
21347     TCC_OPTION_o,
21348     TCC_OPTION_r,
21349     TCC_OPTION_Wl,
21350     TCC_OPTION_W,
21351     TCC_OPTION_O,
21352     TCC_OPTION_m,
21353     TCC_OPTION_f,
21354     TCC_OPTION_nostdinc,
21355     TCC_OPTION_nostdlib,
21356     TCC_OPTION_print_search_dirs,
21357     TCC_OPTION_rdynamic,
21358     TCC_OPTION_run,
21359     TCC_OPTION_v,
21360     TCC_OPTION_w,
21361     TCC_OPTION_pipe,
21362 };
21363
21364 static const TCCOption tcc_options[] = {
21365     { "h", TCC_OPTION_HELP, 0 },
21366     { "?", TCC_OPTION_HELP, 0 },
21367     { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
21368     { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
21369     { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
21370     { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
21371     { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
21372     { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21373     { "bench", TCC_OPTION_bench, 0 },
21374     { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
21375 #ifdef CONFIG_TCC_BCHECK
21376     { "b", TCC_OPTION_b, 0 },
21377 #endif
21378     { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21379     { "c", TCC_OPTION_c, 0 },
21380     { "static", TCC_OPTION_static, 0 },
21381     { "shared", TCC_OPTION_shared, 0 },
21382     { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
21383     { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21384     { "rdynamic", TCC_OPTION_rdynamic, 0 },
21385     { "r", TCC_OPTION_r, 0 },
21386     { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21387     { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21388     { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21389     { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
21390     { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21391     { "nostdinc", TCC_OPTION_nostdinc, 0 },
21392     { "nostdlib", TCC_OPTION_nostdlib, 0 },
21393     { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, 
21394     { "v", TCC_OPTION_v, 0 },
21395     { "w", TCC_OPTION_w, 0 },
21396     { "pipe", TCC_OPTION_pipe, 0},
21397     { NULL },
21398 };
21399
21400 /* convert 'str' into an array of space separated strings */
21401 static int expand_args(char ***pargv, const char *str)
21402 {
21403     const char *s1;
21404     char **argv, *arg;
21405     int argc, len;
21406
21407     argc = 0;
21408     argv = NULL;
21409     for(;;) {
21410         while (is_space(*str))
21411             str++;
21412         if (*str == '\0')
21413             break;
21414         s1 = str;
21415         while (*str != '\0' && !is_space(*str))
21416             str++;
21417         len = str - s1;
21418         arg = tcc_malloc(len + 1);
21419         memcpy(arg, s1, len);
21420         arg[len] = '\0';
21421         dynarray_add((void ***)&argv, &argc, arg);
21422     }
21423     *pargv = argv;
21424     return argc;
21425 }
21426
21427 static char **files;
21428 static int nb_files, nb_libraries;
21429 static int multiple_files;
21430 static int print_search_dirs;
21431 static int output_type;
21432 static int reloc_output;
21433 static const char *outfile;
21434
21435 int parse_args(TCCState *s, int argc, char **argv)
21436 {
21437     int optind;
21438     const TCCOption *popt;
21439     const char *optarg, *p1, *r1;
21440     char *r;
21441
21442     optind = 0;
21443     while (1) {
21444         if (optind >= argc) {
21445             if (nb_files == 0 && !print_search_dirs)
21446                 goto show_help;
21447             else
21448                 break;
21449         }
21450         r = argv[optind++];
21451         if (r[0] != '-') {
21452             /* add a new file */
21453             dynarray_add((void ***)&files, &nb_files, r);
21454             if (!multiple_files) {
21455                 optind--;
21456                 /* argv[0] will be this file */
21457                 break;
21458             }
21459         } else {
21460             /* find option in table (match only the first chars */
21461             popt = tcc_options;
21462             for(;;) {
21463                 p1 = popt->name;
21464                 if (p1 == NULL)
21465                     error("invalid option -- '%s'", r);
21466                 r1 = r + 1;
21467                 for(;;) {
21468                     if (*p1 == '\0')
21469                         goto option_found;
21470                     if (*r1 != *p1)
21471                         break;
21472                     p1++;
21473                     r1++;
21474                 }
21475                 popt++;
21476             }
21477         option_found:
21478             if (popt->flags & TCC_OPTION_HAS_ARG) {
21479                 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
21480                     optarg = r1;
21481                 } else {
21482                     if (optind >= argc)
21483                         error("argument to '%s' is missing", r);
21484                     optarg = argv[optind++];
21485                 }
21486             } else {
21487                 if (*r1 != '\0')
21488                     goto show_help;
21489                 optarg = NULL;
21490             }
21491                 
21492             switch(popt->index) {
21493             case TCC_OPTION_HELP:
21494             show_help:
21495                 help();
21496                 exit(1);
21497             case TCC_OPTION_I:
21498                 if (tcc_add_include_path(s, optarg) < 0)
21499                     error("too many include paths");
21500                 break;
21501             case TCC_OPTION_D:
21502                 {
21503                     char *sym, *value;
21504                     sym = (char *)optarg;
21505                     value = strchr(sym, '=');
21506                     if (value) {
21507                         *value = '\0';
21508                         value++;
21509                     }
21510                     tcc_define_symbol(s, sym, value);
21511                 }
21512                 break;
21513             case TCC_OPTION_U:
21514                 tcc_undefine_symbol(s, optarg);
21515                 break;
21516             case TCC_OPTION_L:
21517                 tcc_add_library_path(s, optarg);
21518                 break;
21519             case TCC_OPTION_B:
21520                 /* set tcc utilities path (mainly for tcc development) */
21521                 tcc_lib_path = optarg;
21522                 break;
21523             case TCC_OPTION_l:
21524                 dynarray_add((void ***)&files, &nb_files, r);
21525                 nb_libraries++;
21526                 break;
21527             case TCC_OPTION_bench:
21528                 do_bench = 1;
21529                 break;
21530             case TCC_OPTION_bt:
21531                 num_callers = atoi(optarg);
21532                 break;
21533 #ifdef CONFIG_TCC_BCHECK
21534             case TCC_OPTION_b:
21535                 do_bounds_check = 1;
21536                 do_debug = 1;
21537                 break;
21538 #endif
21539             case TCC_OPTION_g:
21540                 do_debug = 1;
21541                 break;
21542             case TCC_OPTION_c:
21543                 multiple_files = 1;
21544                 output_type = TCC_OUTPUT_OBJ;
21545                 break;
21546             case TCC_OPTION_static:
21547                 s->static_link = 1;
21548                 break;
21549             case TCC_OPTION_shared:
21550                 output_type = TCC_OUTPUT_DLL;
21551                 break;
21552             case TCC_OPTION_o:
21553                 multiple_files = 1;
21554                 outfile = optarg;
21555                 break;
21556             case TCC_OPTION_r:
21557                 /* generate a .o merging several output files */
21558                 reloc_output = 1;
21559                 output_type = TCC_OUTPUT_OBJ;
21560                 break;
21561             case TCC_OPTION_nostdinc:
21562                 s->nostdinc = 1;
21563                 break;
21564             case TCC_OPTION_nostdlib:
21565                 s->nostdlib = 1;
21566                 break;
21567             case TCC_OPTION_print_search_dirs:
21568                 print_search_dirs = 1;
21569                 break;
21570             case TCC_OPTION_run:
21571                 {
21572                     int argc1;
21573                     char **argv1;
21574                     argc1 = expand_args(&argv1, optarg);
21575                     if (argc1 > 0) {
21576                         parse_args(s, argc1, argv1);
21577                     }
21578                     multiple_files = 0;
21579                     output_type = TCC_OUTPUT_MEMORY;
21580                 }
21581                 break;
21582             case TCC_OPTION_v:
21583                 printf("tcc version %s\n", TCC_VERSION);
21584                 exit(0);
21585             case TCC_OPTION_f:
21586                 if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
21587                     goto unsupported_option;
21588                 break;
21589             case TCC_OPTION_W:
21590                 if (tcc_set_warning(s, optarg, 1) < 0 && 
21591                     s->warn_unsupported)
21592                     goto unsupported_option;
21593                 break;
21594             case TCC_OPTION_w:
21595                 s->warn_none = 1;
21596                 break;
21597             case TCC_OPTION_rdynamic:
21598                 s->rdynamic = 1;
21599                 break;
21600             case TCC_OPTION_Wl:
21601                 {
21602                     const char *p;
21603                     if (strstart(optarg, "-Ttext,", &p)) {
21604                         s->text_addr = strtoul(p, NULL, 16);
21605                         s->has_text_addr = 1;
21606                     } else if (strstart(optarg, "--oformat,", &p)) {
21607                         if (strstart(p, "elf32-", NULL)) {
21608                             s->output_format = TCC_OUTPUT_FORMAT_ELF;
21609                         } else if (!strcmp(p, "binary")) {
21610                             s->output_format = TCC_OUTPUT_FORMAT_BINARY;
21611                         } else
21612 #ifdef TCC_TARGET_COFF
21613                         if (!strcmp(p, "coff")) {
21614                             s->output_format = TCC_OUTPUT_FORMAT_COFF;
21615                         } else
21616 #endif
21617                         {
21618                             error("target %s not found", p);
21619                         }
21620                     } else {
21621                         error("unsupported linker option '%s'", optarg);
21622                     }
21623                 }
21624                 break;
21625             default:
21626                 if (s->warn_unsupported) {
21627                 unsupported_option:
21628                     warning("unsupported option '%s'", r);
21629                 }
21630                 break;
21631             }
21632         }
21633     }
21634     return optind;
21635 }
21636
21637 // njn: renamed main() as main2() in order to repeat it multiple times.
21638 int main2(int argc, char **argv)
21639 {
21640     int i;
21641     TCCState *s;
21642     int nb_objfiles, ret, optind;
21643     char objfilename[1024];
21644     int64_t start_time = 0;
21645
21646 #ifdef WIN32
21647     /* on win32, we suppose the lib and includes are at the location
21648        of 'tcc.exe' */
21649     {
21650         static char path[1024];
21651         char *p, *d;
21652         
21653         GetModuleFileNameA(NULL, path, sizeof path);
21654         p = d = strlwr(path);
21655         while (*d)
21656         {
21657             if (*d == '\\') *d = '/', p = d;
21658             ++d;
21659         }
21660         *p = '\0';
21661         tcc_lib_path = path;
21662     }
21663 #endif
21664
21665     s = tcc_new();
21666     output_type = TCC_OUTPUT_EXE;
21667     outfile = NULL;
21668     multiple_files = 1;
21669     files = NULL;
21670     nb_files = 0;
21671     nb_libraries = 0;
21672     reloc_output = 0;
21673     print_search_dirs = 0;
21674
21675     optind = parse_args(s, argc - 1, argv + 1) + 1;
21676
21677     if (print_search_dirs) {
21678         /* enough for Linux kernel */
21679         printf("install: %s/\n", tcc_lib_path);
21680         return 0;
21681     }
21682
21683     nb_objfiles = nb_files - nb_libraries;
21684
21685     /* if outfile provided without other options, we output an
21686        executable */
21687     if (outfile && output_type == TCC_OUTPUT_MEMORY)
21688         output_type = TCC_OUTPUT_EXE;
21689
21690     /* check -c consistency : only single file handled. XXX: checks file type */
21691     if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21692         /* accepts only a single input file */
21693         if (nb_objfiles != 1)
21694             error("cannot specify multiple files with -c");
21695         if (nb_libraries != 0)
21696             error("cannot specify libraries with -c");
21697     }
21698     
21699     if (output_type != TCC_OUTPUT_MEMORY) {
21700         if (!outfile) {
21701     /* compute default outfile name */
21702             pstrcpy(objfilename, sizeof(objfilename) - 1, 
21703                     /* strip path */
21704                     tcc_basename(files[0]));
21705 #ifdef TCC_TARGET_PE
21706             pe_guess_outfile(objfilename, output_type);
21707 #else
21708             if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21709                 char *ext = strrchr(objfilename, '.');
21710             if (!ext)
21711                 goto default_outfile;
21712                 /* add .o extension */
21713             strcpy(ext + 1, "o");
21714         } else {
21715         default_outfile:
21716             pstrcpy(objfilename, sizeof(objfilename), "a.out");
21717         }
21718 #endif
21719         outfile = objfilename;
21720         }
21721     }
21722
21723     if (do_bench) {
21724         start_time = getclock_us();
21725     }
21726
21727     tcc_set_output_type(s, output_type);
21728
21729     /* compile or add each files or library */
21730     for(i = 0;i < nb_files; i++) {
21731         const char *filename;
21732
21733         filename = files[i];
21734         if (filename[0] == '-') {
21735             if (tcc_add_library(s, filename + 2) < 0)
21736                 error("cannot find %s", filename);
21737         } else {
21738             if (tcc_add_file(s, filename) < 0) {
21739                 ret = 1;
21740                 goto the_end;
21741             }
21742         }
21743     }
21744
21745     /* free all files */
21746     tcc_free(files);
21747
21748     if (do_bench) {
21749         double total_time;
21750         total_time = (double)(getclock_us() - start_time) / 1000000.0;
21751         if (total_time < 0.001)
21752             total_time = 0.001;
21753         if (total_bytes < 1)
21754             total_bytes = 1;
21755         printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", 
21756                tok_ident - TOK_IDENT, total_lines, total_bytes,
21757                total_time, (int)(total_lines / total_time), 
21758                total_bytes / total_time / 1000000.0); 
21759     }
21760
21761     if (s->output_type == TCC_OUTPUT_MEMORY) {
21762         ret = tcc_run(s, argc - optind, argv + optind);
21763     } else
21764 #ifdef TCC_TARGET_PE
21765     if (s->output_type != TCC_OUTPUT_OBJ) {
21766         ret = tcc_output_pe(s, outfile);
21767     } else
21768 #endif
21769     {
21770         tcc_output_file(s, outfile);
21771         ret = 0;
21772     }
21773  the_end:
21774     /* XXX: cannot do it with bound checking because of the malloc hooks */
21775     if (!do_bounds_check)
21776         tcc_delete(s);
21777
21778 #ifdef MEM_DEBUG
21779     if (do_bench) {
21780         printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
21781     }
21782 #endif
21783     return ret;
21784 }
21785
21786 // njn: created this wrapper main() function to execute compilation multiple
21787 // times.  TinyCC is fast!
21788 // Nb: we get a link error, and TinyCC would normally return non-zero.  But
21789 // the link error is not a problem for benchmarking purposes, so we return
21790 // zero here (as required by vg_perf).
21791 int main(int argc, char **argv)
21792 {
21793    #define REPS   30
21794    int i;
21795    for (i = 0; i < REPS; i++) {
21796       main2(argc, argv);
21797    }
21798    return 0;
21799 }
21800
21801 #endif
21802
21803 // njn: copied these in from libtcc1.c to avoid link errors when libtcc1.a
21804 // is not present.
21805 unsigned short __tcc_fpu_control = 0x137f;
21806 unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
21807
21808 #if 0
21809 long long __shldi3(long long a, int b)
21810 {
21811 #ifdef __TINYC__ 
21812     DWunion u;
21813     u.ll = a;
21814     if (b >= 32) {
21815         u.s.high = (unsigned)u.s.low << (b - 32);
21816         u.s.low = 0;
21817     } else if (b != 0) {
21818         u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b));
21819         u.s.low = (unsigned)u.s.low << b;
21820     }
21821     return u.ll;
21822 #else
21823     return a << b;
21824 #endif
21825 }
21826 #endif